init: company-haness 설계

This commit is contained in:
DongHyeonka
2026-07-23 17:49:00 +09:00
parent 57d1bab894
commit f668d6a158
962 changed files with 98989 additions and 1 deletions
+24
View File
@@ -0,0 +1,24 @@
# Organization Design System
이 디렉터리는 조직 차원의 디자인 원칙·취향·토큰·컴포넌트·패턴·페이지 아키타입과 릴리스 이력을 보존하는 정본이다. 프로젝트는 전체를 복제하지 않고 `releases/<version>.yaml`의 정확한 릴리스와 필요한 component/pattern subset, 그리고 명시적 delta만 연결한다.
`generated/DESIGN.md`, `registry.json`, `tokens.css`, `tailwind.tokens.json`, `tokens.dtcg.json`은 어댑터 산출물이다. 편집하지 않는다. 제품 전략·IA·와이어프레임의 정본은 각 프로젝트의 승인된 `experience-blueprint``wireframe-set`이며, DESIGN.md가 이를 대신하지 않는다.
상태 승격은 `experimental → candidate → stable → deprecated`만 허용한다. 컴파일:
```bash
python3 .claude/hooks/compile_design_system.py
python3 .claude/hooks/compile_design_system.py --check
python3 .claude/hooks/compile_design_system.py --diff path/to/DESIGN.md
python3 .claude/hooks/design_registry.py --surface public-web --state stable
python3 .claude/hooks/design_registry.py --surface interactive-learning --state candidate
```
`interactive-learning`은 일반 public page의 별칭이 아니다. Atlas 탐색, 인과 학습 루프,
피드백·복귀 상태를 위한 별도 pattern/page-archetype 집합이며 workload profile에서도 독립
surface archetype으로 분류한다.
`--diff`는 전달된 DESIGN.md와 정본에서 다시 생성한 DESIGN.md의 unified diff를 출력한다.
프로젝트 구현은 `lint_design_system_adherence.py`에서 raw color뿐 아니라 동일 local component-id의
중복과 조직 release에 이미 있는 component의 무신고 로컬 재구현도 거부한다. 정당한 프로젝트 전용
확장은 `ui-design.design-system-bindings[].delta.components`에 명시한다.
@@ -0,0 +1,9 @@
component-recipe:
id: button
anatomy: [label, optional-leading-icon, focus-ring]
variants: [primary, secondary, destructive]
states: [default, hover, focus-visible, disabled, loading]
rules:
- primary는 화면의 지배적 작업 하나에만 사용한다.
- 아이콘 단독 버튼은 접근 가능한 이름을 제공한다.
- loading은 레이블 폭과 사용자 맥락을 보존한다.
@@ -0,0 +1,8 @@
component-recipe:
id: status-panel
anatomy: [status-title, explanation, evidence, recovery-action]
states: [loading, empty, error, partial, completed]
rules:
- 상태 원인과 다음 행동을 함께 설명한다.
- 부분 성공은 성공한 것과 실패한 것을 분리한다.
- 무기한 spinner만 표시하지 않는다.
@@ -0,0 +1,8 @@
component-recipe:
id: field
anatomy: [persistent-label, control, optional-help, validation-message]
states: [default, focus-visible, disabled, invalid, valid]
rules:
- placeholder는 레이블을 대체하지 않는다.
- 오류는 색과 함께 텍스트 및 의미 연결을 제공한다.
- 도움말과 오류의 id 연결을 유지한다.
+24
View File
@@ -0,0 +1,24 @@
design-components:
version: 1
components:
- id: button
state: stable
surfaces: [public-web, product-app, interactive-learning, developer-platform]
recipe: actions/button.yaml
examples: [primary-task, secondary-task, destructive-confirmation]
anti-examples: [multiple-primary-actions, icon-without-name]
tokens: [color.accent, color.danger, radius.control, motion.fast]
- id: field
state: stable
surfaces: [public-web, product-app, interactive-learning, developer-platform]
recipe: forms/field.yaml
examples: [labeled-input, inline-validation]
anti-examples: [placeholder-as-label, error-by-color-only]
tokens: [color.text, color.text-muted, color.border, radius.control]
- id: status-panel
state: candidate
surfaces: [product-app, interactive-learning, developer-platform]
recipe: feedback/status-panel.yaml
examples: [empty, loading, error, partial, completed]
anti-examples: [blank-screen, spinner-without-context]
tokens: [color.surface, color.text, color.danger, radius.surface]
@@ -0,0 +1,14 @@
design-engine-adapters:
version: 1
kernel-contract: .claude/schemas/design-engine-output.artifact.schema.json
required-output-fields: [screen-refs, editable-source, preview-url, screenshots, design-system-ref, source-provenance, verification]
adapters:
local-html: { mode: local, editable-formats: [html-css-js, react, vue, svelte], preview: local-url }
stitch: { mode: external, editable-formats: [stitch-project], preview: remote-url }
figma: { mode: external, editable-formats: [figma-file], preview: remote-url }
v0: { mode: external, editable-formats: [react-source], preview: remote-url }
framer: { mode: external, editable-formats: [framer-project], preview: remote-url }
policy:
- 커널은 특정 도구 호출 성공이 아니라 공통 output contract만 신뢰한다.
- 외부 엔진이 없거나 실패하면 local-html adapter로 동일 screen contract를 완성한다.
- 모든 결과는 승인된 design-system release exact ref와 source provenance를 포함한다.
+89
View File
@@ -0,0 +1,89 @@
# DESIGN.md (generated)
> Adapter generated from `org-os/08-design`. Do not edit. This is not a product-strategy, IA, or wireframe source.
## Taste thesis
절제된 구조, 명확한 정보 향기, 높은 상태 가시성으로 신뢰를 만든다.
## Principles
- **Task before decoration** — 핵심 작업과 정보 위계를 먼저 증명하고 장식은 그 이후에 추가한다. Anti-example: 색·그림자·타이포만 바꾼 채 흐름과 IA 결함을 숨긴다.
- **Evidence before taste** — 표준 관행과 차별화는 named competitive evidence 및 실제 캡처에 연결한다. Anti-example: modern, clean 같은 형용사만으로 시장 적합성을 주장한다.
- **States are the product** — default/loading/empty/error/partial/completed 상태를 기본 화면과 동등하게 설계한다. Anti-example: happy path 스크린샷 하나를 완성된 경험으로 간주한다.
- **Responsive priority, not shrinkage** — 모바일은 축소판이 아니라 우선순위와 탐색 모델을 재표현한다. Anti-example: 데스크톱 그리드를 단순 축소해 정보와 액션을 잘라낸다.
- **Accessible by construction** — 의미 구조·키보드·포커스·대비·동작 감소를 토큰과 recipe 단계에서 강제한다. Anti-example: 최종 검수에서 ARIA만 덧붙인다.
## Preferred signals
- 크기보다 간격·정렬·그룹화로 위계를 먼저 만든다.
- 작업 빈도와 판단 복잡도에 맞춰 밀도를 의도적으로 선택한다.
- 한 화면의 지배적 액션은 하나이며 보조 액션은 명확히 후퇴한다.
- 진행·저장·오류·부분 완료를 사용자가 추론하지 않게 표시한다.
## Anti-signals
- 무근거 hero gradient와 과도한 glassmorphism
- 동일 카드 셸을 반복하고 색만 바꾼 방향 탐색
- 모든 텍스트와 컨테이너를 pill로 만드는 습관
- 낮은 대비의 회색으로 비활성·보조·설명을 구분하는 방식
- 실제 콘텐츠보다 장식용 대시보드 수치를 우선하는 화면
## Token boundaries
- `color.canvas` = `#ffffff` — 최상위 배경에만 사용
- `color.surface` = `#f7f8fa` — 구획된 표면
- `color.text` = `#16181d` — 기본 본문
- `color.text-muted` = `#596170` — 보조 설명; 작은 본문 AA 대비 유지
- `color.border` = `#d9dde5` — 경계와 구분
- `color.accent` = `#2457d6` — primary action과 focus에만 사용
- `color.danger` = `#b42318` — 파괴적 액션과 오류
- `space.xs` = `0.25rem` — 아이콘 내부 간격
- `space.sm` = `0.5rem` — 밀접 요소 간격
- `space.md` = `1rem` — 기본 그룹 간격
- `space.lg` = `1.5rem` — 섹션 내부 간격
- `space.xl` = `2.5rem` — 주요 섹션 분리
- `radius.control` = `0.5rem` — 입력·버튼
- `radius.surface` = `0.75rem` — 카드·패널
- `typography.body-size` = `1rem` — 기본 본문 크기
- `typography.body-line` = `1.5` — 기본 본문 행간
- `typography.label-size` = `0.875rem` — 레이블 최소 크기
- `motion.fast` = `120ms` — 직접 조작 피드백
- `motion.standard` = `200ms` — 상태 전환
## Components
- `button` (stable) — surfaces: public-web, product-app, interactive-learning, developer-platform; anti: multiple-primary-actions, icon-without-name
- `field` (stable) — surfaces: public-web, product-app, interactive-learning, developer-platform; anti: placeholder-as-label, error-by-color-only
- `status-panel` (candidate) — surfaces: product-app, interactive-learning, developer-platform; anti: blank-screen, spinner-without-context
## Patterns
- `task-entry` (stable) — surfaces: public-web, product-app; anti: cta-before-value, competing-primary-actions
- `resilient-status` (candidate) — surfaces: product-app, developer-platform; anti: generic-error-toast-only, indefinite-spinner
- `content-discovery` (candidate) — surfaces: interactive-learning; anti: single-article-dead-end, topic-list-without-status, decorative-catalog
- `causal-learning-loop` (candidate) — surfaces: interactive-learning; anti: stepper-with-unrelated-content, answer-before-prediction, progress-without-evidence
- `learning-feedback-recovery` (candidate) — surfaces: interactive-learning; anti: wrong-answer-only, spoiler-first-hint, lost-return-state
## Page Archetypes
- `public-value-entry` (candidate) — surfaces: public-web; anti: see source
- `operational-workspace` (candidate) — surfaces: product-app, developer-platform; anti: see source
- `interactive-learning-atlas` (candidate) — surfaces: interactive-learning; anti: see source
- `interactive-learning-deep-dive` (candidate) — surfaces: interactive-learning; anti: see source
## Source hashes
- `org-os/08-design/components/actions/button.yaml`: `1c1f2ee50a36ac759303d958903409c6c82d79b749807b316c2dced18b5df73f`
- `org-os/08-design/components/feedback/status-panel.yaml`: `22dbd0bcf7f1dd2166563ce8691cf961ec0e1173bf3d0bb4cbb9cb9a19ec5064`
- `org-os/08-design/components/forms/field.yaml`: `e478891c6b999395d78e22f5ceda4acac22d1ff1450accc5be0a68fe35adc5c3`
- `org-os/08-design/components/registry.yaml`: `877700537510f7bdd5326338236d3055b84db4d18ccdee1d5367f860bf28c5bd`
- `org-os/08-design/design-engine-adapters.yaml`: `ee6a771488e7fe8342498aac96cb957ffc9c0736f9dab5617e5abd6669433542`
- `org-os/08-design/page-archetypes/registry.yaml`: `10faf739beb565455f55f69562e300ab17aeb6ab34ca07ac6100f3b992e53bee`
- `org-os/08-design/patterns/registry.yaml`: `cccc39f78e3c1bb370e201059b8d548e44255c04e246e46901cccdb741af2b40`
- `org-os/08-design/principles.yaml`: `cb00612da40377647cb886da3fa23097deabfa8776173626f1c363639bc0c97b`
- `org-os/08-design/releases/0.1.0.yaml`: `53bfaa503e4a1b34af0930c55393e70f982379317ba17dac9966b19b942df504`
- `org-os/08-design/releases/0.2.0.yaml`: `f569559cadadb57448f24650c11e8fc1b5431de602338d305a159702eb24e7c9`
- `org-os/08-design/releases/index.yaml`: `430a06a0f57c5d8ca938d82e8af26df172097a2d1d252b0fbc9dddf72b7385ad`
- `org-os/08-design/taste-profile.yaml`: `cea0ab83541c56911735239ec158ea48c140eddf898194d94d026a8a26759450`
- `org-os/08-design/tokens.yaml`: `11601f38cb0b2dba146129f8e1a9177c4376e77d7f93d96811bd9846592be38d`
+303
View File
@@ -0,0 +1,303 @@
{
"components": [
{
"anti-examples": [
"multiple-primary-actions",
"icon-without-name"
],
"examples": [
"primary-task",
"secondary-task",
"destructive-confirmation"
],
"id": "button",
"recipe": "actions/button.yaml",
"state": "stable",
"surfaces": [
"public-web",
"product-app",
"interactive-learning",
"developer-platform"
],
"tokens": [
"color.accent",
"color.danger",
"radius.control",
"motion.fast"
]
},
{
"anti-examples": [
"placeholder-as-label",
"error-by-color-only"
],
"examples": [
"labeled-input",
"inline-validation"
],
"id": "field",
"recipe": "forms/field.yaml",
"state": "stable",
"surfaces": [
"public-web",
"product-app",
"interactive-learning",
"developer-platform"
],
"tokens": [
"color.text",
"color.text-muted",
"color.border",
"radius.control"
]
},
{
"anti-examples": [
"blank-screen",
"spinner-without-context"
],
"examples": [
"empty",
"loading",
"error",
"partial",
"completed"
],
"id": "status-panel",
"recipe": "feedback/status-panel.yaml",
"state": "candidate",
"surfaces": [
"product-app",
"interactive-learning",
"developer-platform"
],
"tokens": [
"color.surface",
"color.text",
"color.danger",
"radius.surface"
]
}
],
"current-release": "org-design-0.2.0",
"generated-by": ".claude/hooks/compile_design_system.py",
"page-archetypes": [
{
"id": "public-value-entry",
"patterns": [
"task-entry"
],
"purpose": "누구를 위한 무엇인지 설명하고 핵심 작업 또는 다음 정보로 진입시킨다.",
"required-states": [
"default",
"loading",
"error"
],
"state": "candidate",
"surfaces": [
"public-web"
]
},
{
"id": "operational-workspace",
"patterns": [
"task-entry",
"resilient-status"
],
"purpose": "상태를 이해하며 반복 작업을 완료하고 실패에서 회복한다.",
"required-states": [
"default",
"loading",
"empty",
"error",
"partial",
"completed"
],
"state": "candidate",
"surfaces": [
"product-app",
"developer-platform"
]
},
{
"id": "interactive-learning-atlas",
"patterns": [
"content-discovery",
"task-entry"
],
"purpose": "제품 약속·활성 Deep Dive·학습 방법·신뢰 경계·전체 Atlas 상태를 보여주고 학습 진입을 돕는다.",
"required-states": [
"default",
"loading",
"empty",
"error",
"partial",
"completed"
],
"state": "candidate",
"surfaces": [
"interactive-learning"
]
},
{
"id": "interactive-learning-deep-dive",
"patterns": [
"causal-learning-loop",
"learning-feedback-recovery",
"resilient-status"
],
"purpose": "하나의 공유 시나리오에서 예측·관찰·비교·설명·전이를 수행하고 다음 메커니즘으로 연결한다.",
"required-states": [
"default",
"loading",
"empty",
"error",
"partial",
"completed"
],
"state": "candidate",
"surfaces": [
"interactive-learning"
]
}
],
"patterns": [
{
"anti-examples": [
"cta-before-value",
"competing-primary-actions"
],
"avoid-when": "비교·탐색이 핵심인 다중 선택 화면이다.",
"components": [
"button",
"field"
],
"id": "task-entry",
"state": "stable",
"surfaces": [
"public-web",
"product-app"
],
"use-when": "사용자가 한 가지 핵심 작업을 시작한다."
},
{
"anti-examples": [
"generic-error-toast-only",
"indefinite-spinner"
],
"avoid-when": "즉시 완료되는 로컬 조작이다.",
"components": [
"status-panel",
"button"
],
"id": "resilient-status",
"state": "candidate",
"surfaces": [
"product-app",
"developer-platform"
],
"use-when": "비동기 또는 부분 성공 작업의 상태를 설명하고 회복 경로를 제공한다."
},
{
"anti-examples": [
"single-article-dead-end",
"topic-list-without-status",
"decorative-catalog"
],
"avoid-when": "단일 작업을 즉시 수행하는 운영 화면이다.",
"components": [
"button"
],
"id": "content-discovery",
"state": "candidate",
"surfaces": [
"interactive-learning"
],
"use-when": "사용자가 전체 학습 지도에서 현재·다음 메커니즘의 관계를 파악하고 진입한다."
},
{
"anti-examples": [
"stepper-with-unrelated-content",
"answer-before-prediction",
"progress-without-evidence"
],
"avoid-when": "읽기 전용 참고 문서이거나 단계 간 상태·증거 결속이 없다.",
"components": [
"button",
"status-panel"
],
"id": "causal-learning-loop",
"state": "candidate",
"surfaces": [
"interactive-learning"
],
"use-when": "Predict→Observe→Compare→Explain→Transfer의 동일 시나리오를 단계별 상태와 함께 진행한다."
},
{
"anti-examples": [
"wrong-answer-only",
"spoiler-first-hint",
"lost-return-state"
],
"avoid-when": "단순 성공 알림처럼 복구 행동이 필요 없는 순간이다.",
"components": [
"status-panel",
"button"
],
"id": "learning-feedback-recovery",
"state": "candidate",
"surfaces": [
"interactive-learning"
],
"use-when": "오답·부분 완료·힌트·복귀 상태에서 다음 학습 행동과 근거를 제시한다."
}
],
"principles": [
{
"anti-example": "색·그림자·타이포만 바꾼 채 흐름과 IA 결함을 숨긴다.",
"id": "task-before-decoration",
"rule": "핵심 작업과 정보 위계를 먼저 증명하고 장식은 그 이후에 추가한다.",
"title": "Task before decoration"
},
{
"anti-example": "modern, clean 같은 형용사만으로 시장 적합성을 주장한다.",
"id": "evidence-before-taste",
"rule": "표준 관행과 차별화는 named competitive evidence 및 실제 캡처에 연결한다.",
"title": "Evidence before taste"
},
{
"anti-example": "happy path 스크린샷 하나를 완성된 경험으로 간주한다.",
"id": "states-are-the-product",
"rule": "default/loading/empty/error/partial/completed 상태를 기본 화면과 동등하게 설계한다.",
"title": "States are the product"
},
{
"anti-example": "데스크톱 그리드를 단순 축소해 정보와 액션을 잘라낸다.",
"id": "responsive-priority",
"rule": "모바일은 축소판이 아니라 우선순위와 탐색 모델을 재표현한다.",
"title": "Responsive priority, not shrinkage"
},
{
"anti-example": "최종 검수에서 ARIA만 덧붙인다.",
"id": "accessible-by-construction",
"rule": "의미 구조·키보드·포커스·대비·동작 감소를 토큰과 recipe 단계에서 강제한다.",
"title": "Accessible by construction"
}
],
"source-sha256": {
"org-os/08-design/components/actions/button.yaml": "1c1f2ee50a36ac759303d958903409c6c82d79b749807b316c2dced18b5df73f",
"org-os/08-design/components/feedback/status-panel.yaml": "22dbd0bcf7f1dd2166563ce8691cf961ec0e1173bf3d0bb4cbb9cb9a19ec5064",
"org-os/08-design/components/forms/field.yaml": "e478891c6b999395d78e22f5ceda4acac22d1ff1450accc5be0a68fe35adc5c3",
"org-os/08-design/components/registry.yaml": "877700537510f7bdd5326338236d3055b84db4d18ccdee1d5367f860bf28c5bd",
"org-os/08-design/design-engine-adapters.yaml": "ee6a771488e7fe8342498aac96cb957ffc9c0736f9dab5617e5abd6669433542",
"org-os/08-design/page-archetypes/registry.yaml": "10faf739beb565455f55f69562e300ab17aeb6ab34ca07ac6100f3b992e53bee",
"org-os/08-design/patterns/registry.yaml": "cccc39f78e3c1bb370e201059b8d548e44255c04e246e46901cccdb741af2b40",
"org-os/08-design/principles.yaml": "cb00612da40377647cb886da3fa23097deabfa8776173626f1c363639bc0c97b",
"org-os/08-design/releases/0.1.0.yaml": "53bfaa503e4a1b34af0930c55393e70f982379317ba17dac9966b19b942df504",
"org-os/08-design/releases/0.2.0.yaml": "f569559cadadb57448f24650c11e8fc1b5431de602338d305a159702eb24e7c9",
"org-os/08-design/releases/index.yaml": "430a06a0f57c5d8ca938d82e8af26df172097a2d1d252b0fbc9dddf72b7385ad",
"org-os/08-design/taste-profile.yaml": "cea0ab83541c56911735239ec158ea48c140eddf898194d94d026a8a26759450",
"org-os/08-design/tokens.yaml": "11601f38cb0b2dba146129f8e1a9177c4376e77d7f93d96811bd9846592be38d"
},
"version": 1
}
@@ -0,0 +1,21 @@
{
"color-accent": "#2457d6",
"color-border": "#d9dde5",
"color-canvas": "#ffffff",
"color-danger": "#b42318",
"color-surface": "#f7f8fa",
"color-text": "#16181d",
"color-text-muted": "#596170",
"motion-fast": "120ms",
"motion-standard": "200ms",
"radius-control": "0.5rem",
"radius-surface": "0.75rem",
"space-lg": "1.5rem",
"space-md": "1rem",
"space-sm": "0.5rem",
"space-xl": "2.5rem",
"space-xs": "0.25rem",
"typography-body-line": "1.5",
"typography-body-size": "1rem",
"typography-label-size": "0.875rem"
}
+22
View File
@@ -0,0 +1,22 @@
/* generated from org-os/08-design/tokens.yaml; do not edit */
:root {
--org-color-canvas: #ffffff;
--org-color-surface: #f7f8fa;
--org-color-text: #16181d;
--org-color-text-muted: #596170;
--org-color-border: #d9dde5;
--org-color-accent: #2457d6;
--org-color-danger: #b42318;
--org-space-xs: 0.25rem;
--org-space-sm: 0.5rem;
--org-space-md: 1rem;
--org-space-lg: 1.5rem;
--org-space-xl: 2.5rem;
--org-radius-control: 0.5rem;
--org-radius-surface: 0.75rem;
--org-typography-body-size: 1rem;
--org-typography-body-line: 1.5;
--org-typography-label-size: 0.875rem;
--org-motion-fast: 120ms;
--org-motion-standard: 200ms;
}
+100
View File
@@ -0,0 +1,100 @@
{
"$schema": "https://design-tokens.github.io/community-group/format/",
"tokens": {
"color.accent": {
"$description": "primary action과 focus에만 사용",
"$type": "color",
"$value": "#2457d6"
},
"color.border": {
"$description": "경계와 구분",
"$type": "color",
"$value": "#d9dde5"
},
"color.canvas": {
"$description": "최상위 배경에만 사용",
"$type": "color",
"$value": "#ffffff"
},
"color.danger": {
"$description": "파괴적 액션과 오류",
"$type": "color",
"$value": "#b42318"
},
"color.surface": {
"$description": "구획된 표면",
"$type": "color",
"$value": "#f7f8fa"
},
"color.text": {
"$description": "기본 본문",
"$type": "color",
"$value": "#16181d"
},
"color.text-muted": {
"$description": "보조 설명; 작은 본문 AA 대비 유지",
"$type": "color",
"$value": "#596170"
},
"motion.fast": {
"$description": "직접 조작 피드백",
"$type": "duration",
"$value": "120ms"
},
"motion.standard": {
"$description": "상태 전환",
"$type": "duration",
"$value": "200ms"
},
"radius.control": {
"$description": "입력·버튼",
"$type": "dimension",
"$value": "0.5rem"
},
"radius.surface": {
"$description": "카드·패널",
"$type": "dimension",
"$value": "0.75rem"
},
"space.lg": {
"$description": "섹션 내부 간격",
"$type": "dimension",
"$value": "1.5rem"
},
"space.md": {
"$description": "기본 그룹 간격",
"$type": "dimension",
"$value": "1rem"
},
"space.sm": {
"$description": "밀접 요소 간격",
"$type": "dimension",
"$value": "0.5rem"
},
"space.xl": {
"$description": "주요 섹션 분리",
"$type": "dimension",
"$value": "2.5rem"
},
"space.xs": {
"$description": "아이콘 내부 간격",
"$type": "dimension",
"$value": "0.25rem"
},
"typography.body-line": {
"$description": "기본 본문 행간",
"$type": "number",
"$value": "1.5"
},
"typography.body-size": {
"$description": "기본 본문 크기",
"$type": "dimension",
"$value": "1rem"
},
"typography.label-size": {
"$description": "레이블 최소 크기",
"$type": "dimension",
"$value": "0.875rem"
}
}
}
@@ -0,0 +1,27 @@
design-page-archetypes:
version: 1
page-archetypes:
- id: public-value-entry
state: candidate
surfaces: [public-web]
patterns: [task-entry]
purpose: 누구를 위한 무엇인지 설명하고 핵심 작업 또는 다음 정보로 진입시킨다.
required-states: [default, loading, error]
- id: operational-workspace
state: candidate
surfaces: [product-app, developer-platform]
patterns: [task-entry, resilient-status]
purpose: 상태를 이해하며 반복 작업을 완료하고 실패에서 회복한다.
required-states: [default, loading, empty, error, partial, completed]
- id: interactive-learning-atlas
state: candidate
surfaces: [interactive-learning]
patterns: [content-discovery, task-entry]
purpose: 제품 약속·활성 Deep Dive·학습 방법·신뢰 경계·전체 Atlas 상태를 보여주고 학습 진입을 돕는다.
required-states: [default, loading, empty, error, partial, completed]
- id: interactive-learning-deep-dive
state: candidate
surfaces: [interactive-learning]
patterns: [causal-learning-loop, learning-feedback-recovery, resilient-status]
purpose: 하나의 공유 시나리오에서 예측·관찰·비교·설명·전이를 수행하고 다음 메커니즘으로 연결한다.
required-states: [default, loading, empty, error, partial, completed]
+38
View File
@@ -0,0 +1,38 @@
design-patterns:
version: 1
patterns:
- id: task-entry
state: stable
surfaces: [public-web, product-app]
components: [button, field]
use-when: 사용자가 한 가지 핵심 작업을 시작한다.
avoid-when: 비교·탐색이 핵심인 다중 선택 화면이다.
anti-examples: [cta-before-value, competing-primary-actions]
- id: resilient-status
state: candidate
surfaces: [product-app, developer-platform]
components: [status-panel, button]
use-when: 비동기 또는 부분 성공 작업의 상태를 설명하고 회복 경로를 제공한다.
avoid-when: 즉시 완료되는 로컬 조작이다.
anti-examples: [generic-error-toast-only, indefinite-spinner]
- id: content-discovery
state: candidate
surfaces: [interactive-learning]
components: [button]
use-when: 사용자가 전체 학습 지도에서 현재·다음 메커니즘의 관계를 파악하고 진입한다.
avoid-when: 단일 작업을 즉시 수행하는 운영 화면이다.
anti-examples: [single-article-dead-end, topic-list-without-status, decorative-catalog]
- id: causal-learning-loop
state: candidate
surfaces: [interactive-learning]
components: [button, status-panel]
use-when: Predict→Observe→Compare→Explain→Transfer의 동일 시나리오를 단계별 상태와 함께 진행한다.
avoid-when: 읽기 전용 참고 문서이거나 단계 간 상태·증거 결속이 없다.
anti-examples: [stepper-with-unrelated-content, answer-before-prediction, progress-without-evidence]
- id: learning-feedback-recovery
state: candidate
surfaces: [interactive-learning]
components: [status-panel, button]
use-when: 오답·부분 완료·힌트·복귀 상태에서 다음 학습 행동과 근거를 제시한다.
avoid-when: 단순 성공 알림처럼 복구 행동이 필요 없는 순간이다.
anti-examples: [wrong-answer-only, spoiler-first-hint, lost-return-state]
+23
View File
@@ -0,0 +1,23 @@
design-principles:
version: 1
principles:
- id: task-before-decoration
title: Task before decoration
rule: 핵심 작업과 정보 위계를 먼저 증명하고 장식은 그 이후에 추가한다.
anti-example: 색·그림자·타이포만 바꾼 채 흐름과 IA 결함을 숨긴다.
- id: evidence-before-taste
title: Evidence before taste
rule: 표준 관행과 차별화는 named competitive evidence 및 실제 캡처에 연결한다.
anti-example: modern, clean 같은 형용사만으로 시장 적합성을 주장한다.
- id: states-are-the-product
title: States are the product
rule: default/loading/empty/error/partial/completed 상태를 기본 화면과 동등하게 설계한다.
anti-example: happy path 스크린샷 하나를 완성된 경험으로 간주한다.
- id: responsive-priority
title: Responsive priority, not shrinkage
rule: 모바일은 축소판이 아니라 우선순위와 탐색 모델을 재표현한다.
anti-example: 데스크톱 그리드를 단순 축소해 정보와 액션을 잘라낸다.
- id: accessible-by-construction
title: Accessible by construction
rule: 의미 구조·키보드·포커스·대비·동작 감소를 토큰과 recipe 단계에서 강제한다.
anti-example: 최종 검수에서 ARIA만 덧붙인다.
+11
View File
@@ -0,0 +1,11 @@
design-system-release:
release-id: org-design-0.1.0
version: 0.1.0
state: candidate
principles: [task-before-decoration, evidence-before-taste, states-are-the-product, responsive-priority, accessible-by-construction]
components: [button, field, status-panel]
patterns: [task-entry, resilient-status]
page-archetypes: [public-value-entry, operational-workspace]
compatibility:
surfaces: [public-web, product-app, developer-platform]
migration-notes: [초기 candidate 릴리스]
+11
View File
@@ -0,0 +1,11 @@
design-system-release:
release-id: org-design-0.2.0
version: 0.2.0
state: candidate
principles: [task-before-decoration, evidence-before-taste, states-are-the-product, responsive-priority, accessible-by-construction]
components: [button, field, status-panel]
patterns: [task-entry, resilient-status, content-discovery, causal-learning-loop, learning-feedback-recovery]
page-archetypes: [public-value-entry, operational-workspace, interactive-learning-atlas, interactive-learning-deep-dive]
compatibility:
surfaces: [public-web, product-app, interactive-learning, developer-platform]
migration-notes: [0.1.0 호환, interactive-learning atlas/deep-dive 패턴 추가]
+6
View File
@@ -0,0 +1,6 @@
design-system-releases:
version: 1
current: org-design-0.2.0
releases:
- { release-id: org-design-0.1.0, version: 0.1.0, state: candidate, ref: releases/0.1.0.yaml }
- { release-id: org-design-0.2.0, version: 0.2.0, state: candidate, ref: releases/0.2.0.yaml }
+18
View File
@@ -0,0 +1,18 @@
taste-profile:
version: 1
thesis: 절제된 구조, 명확한 정보 향기, 높은 상태 가시성으로 신뢰를 만든다.
preferred-signals:
- id: hierarchy-through-spacing
signal: 크기보다 간격·정렬·그룹화로 위계를 먼저 만든다.
- id: purposeful-density
signal: 작업 빈도와 판단 복잡도에 맞춰 밀도를 의도적으로 선택한다.
- id: one-dominant-action
signal: 한 화면의 지배적 액션은 하나이며 보조 액션은 명확히 후퇴한다.
- id: visible-system-status
signal: 진행·저장·오류·부분 완료를 사용자가 추론하지 않게 표시한다.
anti-signals:
- 무근거 hero gradient와 과도한 glassmorphism
- 동일 카드 셸을 반복하고 색만 바꾼 방향 탐색
- 모든 텍스트와 컨테이너를 pill로 만드는 습관
- 낮은 대비의 회색으로 비활성·보조·설명을 구분하는 방식
- 실제 콘텐츠보다 장식용 대시보드 수치를 우선하는 화면
+27
View File
@@ -0,0 +1,27 @@
design-tokens:
version: 1
tokens:
color:
canvas: { value: "#ffffff", type: color, description: 최상위 배경에만 사용 }
surface: { value: "#f7f8fa", type: color, description: 구획된 표면 }
text: { value: "#16181d", type: color, description: 기본 본문 }
text-muted: { value: "#596170", type: color, description: 보조 설명; 작은 본문 AA 대비 유지 }
border: { value: "#d9dde5", type: color, description: 경계와 구분 }
accent: { value: "#2457d6", type: color, description: primary action과 focus에만 사용 }
danger: { value: "#b42318", type: color, description: 파괴적 액션과 오류 }
space:
xs: { value: "0.25rem", type: dimension, description: 아이콘 내부 간격 }
sm: { value: "0.5rem", type: dimension, description: 밀접 요소 간격 }
md: { value: "1rem", type: dimension, description: 기본 그룹 간격 }
lg: { value: "1.5rem", type: dimension, description: 섹션 내부 간격 }
xl: { value: "2.5rem", type: dimension, description: 주요 섹션 분리 }
radius:
control: { value: "0.5rem", type: dimension, description: 입력·버튼 }
surface: { value: "0.75rem", type: dimension, description: 카드·패널 }
typography:
body-size: { value: "1rem", type: dimension, description: 기본 본문 크기 }
body-line: { value: "1.5", type: number, description: 기본 본문 행간 }
label-size: { value: "0.875rem", type: dimension, description: 레이블 최소 크기 }
motion:
fast: { value: "120ms", type: duration, description: 직접 조작 피드백 }
standard: { value: "200ms", type: duration, description: 상태 전환 }