944 lines
63 KiB
Markdown
944 lines
63 KiB
Markdown
---
|
||
date: 2026-06-25
|
||
type: design-concept
|
||
project: 한신대학교 AI 심리상담 시뮬레이션 훈련 플랫폼
|
||
tags:
|
||
- 디자인컨셉
|
||
- 디자인시스템
|
||
- UX
|
||
- 아바타
|
||
- 한신대
|
||
status: 통합본 v1
|
||
---
|
||
|
||
# 한신대 AI 심리상담 시뮬레이션 플랫폼 — 통합 디자인 컨셉 문서
|
||
|
||
> **이 문서 하나로 사이트를 만들 수 있다.** 디자인 철학 → 디자인 시스템 토큰(실측값) → 가상 내담자 아바타(상세) → 상담 세션 화면 → 3역할 대시보드 → 컴포넌트·모션 → React 구현 노트 → 안티패턴 체크리스트까지, 추상적 형용사 없이 실제 hex·px·컴포넌트·인터랙션으로 적었다.
|
||
>
|
||
> 5개 영역 설계([design-language] / [design-system] / [avatar] / [session-ux] / [role-dashboards])를 단일 기준 문서로 종합한 것이다. 토큰 충돌 지점은 본 문서가 **단일 진실원본(SSOT)**으로 일원화했다.
|
||
>
|
||
> **재사용 자산 연계**: 윤찬 기존 디자인 시스템(`Resources/50_Tech_Dev/디자인/slide-base.css`)과 동일한 토큰 철학(무채 골격 + accent 교체). slide-base 표의 "한신대/의료" 빈 행을 본 문서의 `--accent`로 채운다.
|
||
|
||
---
|
||
|
||
## 0. 한 문장 컨셉과 SSOT 결정
|
||
|
||
### 0.1 컨셉
|
||
|
||
**"불안한 사람을 다루는 사람을 위한, 차분한 임상 도구."**
|
||
|
||
상담 수련생(학습자)이 가상 내담자 AI와 음성으로 대면하고, 뒤에서 평가 AI가 조용히 관찰한다. 이 화면은 **두 종류의 신뢰**를 동시에 줘야 한다.
|
||
|
||
1. **임상적 신뢰감** — 학습자가 "이건 진지한 임상 훈련 장비다"라고 느낀다.
|
||
2. **교육적 따뜻함** — 연습 중 실수해도 안전하다고 느낀다.
|
||
|
||
자극적·게임적이면 안 되고, 차갑고 행정적이어도 안 된다. 정답은 그 사이의 **"조용한 따뜻함(quiet warmth)"** — 스펙트럼 위 **65% 임상 : 35% 따뜻함** 지점이다.
|
||
|
||
> 화면은 "상담실"이지 "대시보드"가 아니다. 평가 정보는 상담실 벽에 걸린 은은한 시계처럼 곁에 있되, 내담자의 얼굴에서 시선을 빼앗지 않는다.
|
||
|
||
### 0.2 토큰 SSOT 결정 (5개 설계 영역의 색 통일)
|
||
|
||
5개 영역이 각각 미세하게 다른 그린(`#5B7A6B` / `#3E7A6E` / `#4F6B5D` / `#0E7C7B` / `#0F766E`)을 제안했다. 본 문서는 아래로 **확정 일원화**한다.
|
||
|
||
| 용도 | 확정값 | 근거 |
|
||
|---|---|---|
|
||
| **메인 accent (전역 기본)** | `--accent: #3E7A6E` (세이지-틸) | 저채도·차분, 흰 배경 대비 약 5.0:1 (WCAG AA 통과). 흔한 메디컬 블루/형광 틸 회피. slide-base의 `#0F766E`보다 한 톤 더 낮춤. |
|
||
| **역할별 보조 accent** | 학습자 `#3E7A6E` / 교수자 `#3A5BA0` / 관리자 `#5B5F6B` | 같은 골격, accent 한 토큰만 교체. 모두 저채도. |
|
||
| **보조 온기 accent** | `--clay: #B0735C` (테라코타) | 양산형 메디컬 블루를 깨는 "사람이 만든 교육 도구" 온기. 저채도로만, 화면당 1곳. |
|
||
|
||
이유: **세이지-틸**은 임상적 차분함(자연·회복·안정)과 따뜻함(흙·식물)을 동시에 품으면서, 한국 상담/심리 분야에서 과용되지 않아 차별화된다. 의료 블루는 흔하고 차갑다.
|
||
|
||
---
|
||
|
||
## 1. 핵심 디자인 원칙 (신성불가침 5개)
|
||
|
||
### 원칙 1 — One Screen, One Intent (한 화면 한 의도)
|
||
상담 시뮬레이션은 본질적으로 집중을 요구한다. 학습자가 가상 내담자의 말에 귀 기울이는 순간 화면에 버튼 12개·카드 9개가 깔려 있으면 안 된다. 모든 화면은 그 순간의 **단 하나의 주된 행동**(말하기 / 듣기 / 피드백 읽기 / 세션 시작)을 중심으로 설계한다. 부차 정보는 위계 아래로.
|
||
- *적용*: 세션 진행 화면 = 중앙에 내담자 발화 + 음성 비주얼 하나. 평가 피드백은 화면 가장자리 차분한 사이드 패널로, 절대 모달로 튀지 않는다.
|
||
|
||
### 원칙 2 — 위계는 색 블록이 아니라 타이포 weight + 여백으로
|
||
Stripe·Linear의 공통점: 테두리·색 박스로 구역을 나누지 않고 **여백과 글자 굵기로** 나눈다. 강조는 ①font-weight(400→600) ②accent 텍스트/언더라인 ③상단 kicker(소제목) ④accent dot 으로만. **border-left 강조선·좌측 사이드바 강조줄·색 박스 카드 격자 절대 금지.**
|
||
- *적용*: 평가 피드백 "공감 반영: 우수"를 초록 배지로 칠하지 않는다. kicker("공감 반영") + 본문 한 줄 + 미세한 accent dot 한 점으로 위계를 만든다.
|
||
|
||
### 원칙 3 — 임상적 차분함 = 채도를 죽인 중성 베이스 + 절제된 단일 악센트
|
||
Calm/Headspace에서 배울 건 파스텔 그라데이션이 아니라 **고채도·고대비를 의도적으로 피하는 절제**다. 베이스는 따뜻한 회백(off-white)·차분한 슬레이트. 악센트는 **세이지-틸 단 하나**를 화면당 1군데만 배급(Linear의 "accent rationing"). 빨강·주황 경고색은 진짜 오류/위험에만.
|
||
- *근거*: 불안한 내담자를 다루는 훈련 도구이므로 자극적 색은 학습자 정서·임상 톤 양쪽에 해롭다. 녹색은 우울·불안·스트레스 점수를 가장 많이 낮춘 색이며 "go/긍정" 신호로도 조용히 작동한다.
|
||
|
||
### 원칙 4 — 따뜻함은 "둥근 카드"가 아니라 "휴머니스트 타이포 + 따뜻한 중성톤 + 넉넉한 여백"
|
||
따뜻함을 둥근 모서리·말랑한 일러스트로 내면 임상 신뢰가 깨진다(애들 앱처럼 보임). 대신 **헤드라인에 휴머니스트 세리프 한 톤 옵션**(therapy 웹의 정설: serif=신뢰·인간미), 본문은 깔끔한 산세리프. 순백(#FFF) 대신 따뜻한 종이색, 순흑 대신 잉크 네이비-그린. 이 미세한 온기가 "행정 시스템"과 "사람을 위한 도구"를 가른다.
|
||
- *주의*: 한글 본문은 Pretendard 단일 패밀리를 기본으로 한다(국문 상담 도메인 가독·중립). 세리프 헤드라인은 랜딩·표지 같은 희소 지점에서만 선택 적용(본명조). UI 전반은 산세리프 weight 위계로 통일.
|
||
|
||
### 원칙 5 — 평가 AI는 판사가 아니라 조용한 멘토 (Non-judgmental surfacing)
|
||
실시간 피드백이 빨간 X·점수 폭격·"틀렸습니다"로 뜨면 학습자는 위축된다. 피드백은 **관찰("이 지점에서 내담자가 방어적으로 반응했어요") → 제안("열린 질문으로 바꿔볼까요?")** 순서의 **서술형·저채도·비모달**로. 점수는 세션이 끝난 뒤 회고 화면에서만, 절대값이 아니라 성장 추세로.
|
||
|
||
---
|
||
|
||
## 2. 무드 좌표 (임상 ↔ 따뜻함 균형)
|
||
|
||
양 극단(차가운 EHR / 말랑한 명상앱) 사이, **65% 임상 : 35% 따뜻함**.
|
||
|
||
| 축 | 임상 신뢰(차가움) ← | **→ 우리 좌표 ←** | → 따뜻함(부드러움) |
|
||
|---|---|---|---|
|
||
| 베이스색 | 순백·차가운 그레이 | **따뜻한 off-white `#FBFAF8` + 차분한 슬레이트** | 크림·파스텔 |
|
||
| 악센트 | 임상 블루 | **세이지-틸 `#3E7A6E`** | 코랄·더스티 로즈 |
|
||
| 헤드라인 | 기하 산세리프 | **산세리프 weight 위계 (희소 지점만 본명조 옵션)** | 손글씨·라운드 |
|
||
| 모서리 | 직각 | **6~8px (거의 직각, 미세 라운드)** | 16px+ 둥근 |
|
||
| 그림자 | 없음(헤어라인) | **1px 헤어라인 + 아주 약한 그림자** | 부드러운 큰 blur |
|
||
| 모션 | 즉각·없음 | **200~320ms ease-out, 절제** | 느린 호흡 애니메이션 |
|
||
|
||
> 단 하나의 예외 — 음성 듣기 중 마이크/오브의 **느린 호흡 펄스**. 이건 "지금 듣고 있다"는 정서적 안심 신호라 의도적으로 명상앱 호흡 모션을 차용한다.
|
||
|
||
---
|
||
|
||
## 3. 디자인 시스템 토큰 (그대로 `:root`에 붙여 쓰는 실측값)
|
||
|
||
CSS 변수는 primitive(원시값) → semantic(의미 별칭) 2계층. 컴포넌트는 semantic만 참조 → 다크모드 1곳에서 스왑.
|
||
|
||
### 3.1 중성 베이스 (Neutral) — 골격
|
||
|
||
순백/순흑 금지. 따뜻한 종이색 + 잉크 네이비-그린.
|
||
|
||
```css
|
||
:root {
|
||
/* ── Primitive: Neutral (따뜻한 종이 + 쿨 슬레이트) ── */
|
||
--paper: #FBFAF8; /* 본문 배경: 따뜻한 종이색 (순백 아님) */
|
||
--paper-2: #F4F2EE; /* 카드/패널 미세 단차 (테두리 대신 톤차) */
|
||
--surface: #FFFFFF; /* 카드 표면 (캔버스가 종이색이라 분리됨) */
|
||
--neutral-100: #ECEFF1; /* 표면 hover / subtle fill */
|
||
--neutral-150: #E5E1DA; /* 카드 보더 baseline = hairline */
|
||
--neutral-200: #D5DBDE; /* divider 진함 */
|
||
--neutral-400: #98A4A9; /* placeholder / disabled */
|
||
|
||
--ink: #1C2A2A; /* 본문 텍스트: 잉크 네이비-그린 (순흑 아님) */
|
||
--ink-2: #5A6663; /* 보조 텍스트: 슬레이트 */
|
||
--ink-3: #93A09C; /* 캡션/메타 */
|
||
--hair: #E5E1DA; /* 1px 헤어라인 (구역 분리는 이걸로) */
|
||
}
|
||
```
|
||
|
||
### 3.2 악센트 — 1주 + 1보조 (저채도)
|
||
|
||
```css
|
||
:root {
|
||
/* ── Sage-Teal (주 악센트 = 상담/신뢰), 화면당 1곳 배급 ── */
|
||
--accent: #3E7A6E; /* ★ 메인 악센트 (버튼/링크/포커스). 흰 배경 대비 5.0:1 AA */
|
||
--accent-deep: #316257; /* hover / 진한 강조 텍스트 */
|
||
--accent-tint: #EEF4F2; /* 악센트 배경 틴트 (콜아웃·선택·active) */
|
||
--accent-bright:#5F968B; /* dot·진행바 fill (화면 전용) */
|
||
|
||
/* ── Terracotta (보조 악센트 = 학습/온기), 저채도, 화면당 1곳 ── */
|
||
--clay: #B0735C; /* ★ 보조 악센트 (학습자 온기 포인트, 내담자 측 신호) */
|
||
--clay-deep: #94604C;
|
||
--clay-tint: #F6F0EC;
|
||
}
|
||
```
|
||
|
||
`--accent #3E7A6E`는 흰 배경 명도대비 약 5.0:1 → 본문 링크/버튼 텍스트 WCAG AA 통과. **2색을 동시에 큰 면적으로 쓰지 않는다** — sage가 전역 기본, clay는 학습자 모드/온기 포인트에서만 점·언더라인·소형 fill로.
|
||
|
||
### 3.3 의미색 (Semantic feedback) — solid + tint 페어
|
||
|
||
각 의미색은 아이콘/텍스트용 solid + 배경용 tint. tint 위 text는 모두 AA(4.5:1↑).
|
||
|
||
```css
|
||
:root {
|
||
/* 긍정 = 녹색 (상담 진전·라포 형성·가드레일 통과·잘함) */
|
||
--pos-text: #2C6E49; --pos-solid: #3B8C5E; --pos-tint: #E8F3EC;
|
||
|
||
/* 주의 = 앰버 (라포 약화·과도한 침묵·페이싱) — 빨강 대신 머스터드 */
|
||
--warn-text: #8A5A00; --warn-solid:#C28A2C; --warn-tint: #FAF1E0;
|
||
|
||
/* 위험 = 적색 (가드레일 위반·세션 강제중단·임상적 위급) — 오직 진짜 위급만 */
|
||
--crit-text: #A8352C; --crit-solid:#C4453A; --crit-tint: #FAEAE8;
|
||
|
||
/* 정보 = 슬레이트블루 (평가 AI 피드백·시스템 안내, 중립) */
|
||
--info-text: #2E5A7A; --info-solid:#3C7299; --info-tint: #EAF1F6;
|
||
|
||
--neutral-sig:#8895A2; /* 데이터 없음·미평가 */
|
||
}
|
||
```
|
||
|
||
**핵심 원칙: 평가 AI의 실시간 피드백 기본 톤은 `info`(슬레이트블루) 또는 `pos`(녹색)** 으로 — 학습자가 비난받는 느낌을 받지 않게. 빨강은 코칭 피드백에 절대 쓰지 않고, 가드레일/위급에만.
|
||
|
||
### 3.4 시맨틱 별칭 (라이트 모드)
|
||
|
||
컴포넌트는 primitive를 직접 부르지 않고 이 별칭만 참조.
|
||
|
||
```css
|
||
:root {
|
||
--bg-app: var(--paper); /* 앱 캔버스 */
|
||
--bg-surface: var(--surface); /* 카드/패널 */
|
||
--bg-surface-2: var(--paper-2); /* 중첩 표면/입력 */
|
||
--bg-tint: var(--accent-tint); /* 선택·강조 배경 */
|
||
--bg-stage: #1E2724; /* 내담자 아바타 영역 (깊은 차콜그린, 시선 집중) */
|
||
|
||
--text-strong: var(--ink); /* 제목 */
|
||
--text-body: var(--ink-2); /* 본문 보조 */
|
||
--text-muted: var(--ink-3); /* 캡션 */
|
||
--text-on-accent:#FBFAF8; /* accent 버튼 위 텍스트 */
|
||
|
||
--border-subtle: var(--neutral-150);
|
||
--border-strong: var(--neutral-200);
|
||
--border-focus: var(--accent);
|
||
--focus-ring: color-mix(in srgb, var(--accent) 45%, transparent);
|
||
}
|
||
```
|
||
|
||
### 3.5 다크 모드 (gloom 회피 — 충분한 밝은 면 + 절제된 악센트)
|
||
|
||
배경은 한색 슬레이트(순흑 아님). 악센트는 명도를 올려 가독 확보.
|
||
운영 기본 표면은 dark이며, 저장 theme 값이 없거나 API preference가 `system`이면 light로 떨어지지 않고 앱 초기 dark 값을 따른다. dark 화면 안의 대형 카드/섹션은 순백·밝은 베이지 면을 쓰지 않는다.
|
||
|
||
```css
|
||
[data-theme="dark"] {
|
||
--bg-app: #131A1E; --bg-surface: #1A2429; --bg-surface-2: #222E34;
|
||
--bg-tint: #1E2E2A; --bg-stage: #0E1614;
|
||
--text-strong: #EAF0F1; --text-body: #C4CFD3; --text-muted: #88969C;
|
||
--text-on-accent:#0F1A17;
|
||
--border-subtle: #2A363C; --border-strong: #38454C; --border-focus: #6FB3A4;
|
||
--accent: #6FB3A4; --accent-deep: #84C2B4; --accent-tint: #1E2E2A;
|
||
--clay: #CC8F77;
|
||
|
||
--pos-text: #7FD0A0; --pos-solid: #5FB682; --pos-tint: #16271D;
|
||
--warn-text: #E2B566; --warn-solid:#D4A24A; --warn-tint: #2A2415;
|
||
--crit-text: #E89086; --crit-solid:#D86459; --crit-tint: #2A1715;
|
||
--info-text: #79B0D4; --info-solid:#5C97BE; --info-tint: #15222C;
|
||
}
|
||
```
|
||
|
||
### 3.6 타이포그래피
|
||
|
||
| 역할 | 폰트 | 이유 |
|
||
|---|---|---|
|
||
| **본문/UI 기본** | **Pretendard Variable** | 한글 UI 사실상 표준. 9 weight 가변, 숫자 정렬 우수. 임상 데이터·평가 점수 표기에 깔끔. |
|
||
| **숫자·타임코드** | Pretendard + `tabular-nums` | 세션 타이머·점수는 정렬 필요 → `font-variant-numeric: tabular-nums`. |
|
||
| (옵션) 랜딩 헤드라인 | Noto Serif KR (본명조) | 신뢰·인간미. **희소 지점만**(표지·히어로). UI 전반은 산세리프. |
|
||
|
||
```css
|
||
:root {
|
||
--font-sans: "Pretendard Variable", Pretendard, -apple-system,
|
||
"Apple SD Gothic Neo", "Noto Sans KR", system-ui, sans-serif;
|
||
--font-serif:"Noto Serif KR", "Source Serif 4", serif; /* 랜딩 헤드만 */
|
||
--font-num: "Pretendard Variable", "JetBrains Mono", ui-monospace, monospace;
|
||
}
|
||
body { font-family: var(--font-sans); -webkit-font-smoothing: antialiased;
|
||
text-rendering: optimizeLegibility; }
|
||
.tabular { font-variant-numeric: tabular-nums; letter-spacing: -0.01em; }
|
||
```
|
||
|
||
CDN: `https://cdn.jsdelivr.net/gh/orioncactus/pretendard/dist/web/variable/pretendardvariable.min.css`
|
||
|
||
**타입 스케일** (기준 본문 16px / 1.6, 한글 자간 -0.01~-0.02em. 위계는 크기보다 weight로):
|
||
|
||
| 토큰 | px / rem | line-height | weight | letter-spacing | 용도 |
|
||
|---|---|---|---|---|---|
|
||
| `--fs-display` | 40 / 2.5rem | 1.2 | 700 | -0.02em | 표지·랜딩 대제목 (희소) |
|
||
| `--fs-h1` | 30 / 1.875rem | 1.3 | 700 | -0.02em | 페이지 제목 |
|
||
| `--fs-h2` | 24 / 1.5rem | 1.35 | 600 | -0.015em | 섹션 제목 |
|
||
| `--fs-h3` | 20 / 1.25rem | 1.4 | 600 | -0.01em | 카드/패널 제목 |
|
||
| `--fs-lead` | 18 / 1.125rem | 1.6 | 400 | -0.01em | 리드 문장 |
|
||
| `--fs-body` | 16 / 1rem | 1.6 | 400 | -0.01em | 본문 기본 |
|
||
| `--fs-sm` | 14 / 0.875rem | 1.55 | 400 | 0 | 보조·폼 라벨 |
|
||
| `--fs-xs` | 13 / 0.8125rem | 1.5 | 500 | 0.01em | 캡션·메타·배지 |
|
||
| `--fs-kicker` | 12 / 0.75rem | 1.4 | 600 | 0.08em | 상단 kicker 소제목 |
|
||
|
||
**강조 방식(철칙):** 색 블록·border-left 금지. ① weight 400→600 ② accent 텍스트 컬러 ③ 은은한 `--accent-tint` 배경 틴트 ④ 상단 kicker(작은 도트 동반). kicker가 양산형 좌측바를 대체하는 위계 신호다.
|
||
|
||
### 3.7 스페이싱 (8pt 기반, 넉넉하게)
|
||
|
||
```css
|
||
:root {
|
||
--sp-1: 4px; --sp-2: 8px; --sp-3: 12px; --sp-4: 16px;
|
||
--sp-5: 24px; --sp-6: 32px; --sp-7: 48px; --sp-8: 64px; --sp-9: 96px;
|
||
}
|
||
```
|
||
|
||
원칙: **컴포넌트 내부 패딩은 8의 배수, 섹션 간 간격은 48~96px 넉넉히.** 불안 완화의 핵심은 여백. 카드 내부 패딩 기본 `--sp-5`(24px), 패널 `--sp-6`(32px), 읽기 영역 max-width 640~680px.
|
||
|
||
### 3.8 그리드·형태
|
||
|
||
```css
|
||
:root {
|
||
--maxw: 1200px; /* 대시보드 콘텐츠 최대폭 */
|
||
--maxw-read: 680px; /* 읽기 영역 */
|
||
--nav-w: 240px; /* 좌측 네비 펼침 */
|
||
--nav-w-collapsed: 72px; /* 좌측 네비 아이콘 only */
|
||
--radius: 8px; /* 카드/버튼/입력 (거의 직각) */
|
||
--radius-sm: 6px; /* 입력·칩 */
|
||
--radius-lg: 12px; /* 패널 */
|
||
--gutter: 24px;
|
||
}
|
||
```
|
||
|
||
- `border-radius`: 카드 8px, 버튼 8px, 입력 6px (거의 직각, 미세 라운드만). **원형은 음성 오브·아바타·dot만 예외.**
|
||
- **깊이는 1px 헤어라인(`--hair`) + 화면용 아주 약한 그림자.** glow·gradient-text·큰 blur 금지.
|
||
|
||
```css
|
||
:root {
|
||
--shadow-sm: 0 1px 2px rgba(28,42,42,.05);
|
||
--shadow-md: 0 4px 14px rgba(28,42,42,.07); /* 모달·팝오버만 */
|
||
}
|
||
```
|
||
|
||
### 3.9 모션
|
||
|
||
```css
|
||
:root {
|
||
--ease-out: cubic-bezier(.22,.61,.36,1);
|
||
--ease-in-out: cubic-bezier(.45,.05,.55,.95);
|
||
--dur-fast: 120ms; /* hover·포커스 */
|
||
--dur-base: 200ms; /* 버튼·토글·드롭다운 */
|
||
--dur-slow: 320ms; /* 패널 전환·모달 */
|
||
--dur-breathe: 3200ms; /* 음성 호흡 펄스 */
|
||
}
|
||
@media (prefers-reduced-motion: reduce) {
|
||
*,*::before,*::after { animation-duration:.01ms!important; transition-duration:.01ms!important; }
|
||
}
|
||
```
|
||
|
||
원칙: **차분·짧게·자연 이징.** 불안 도구이므로 튀는 스프링/바운스 금지. 화면 전환은 페이드+미세 슬라이드(translateY 8px 이하). 실시간 피드백 칩은 **자리 미리 확보 후 fade**(밀어내기/점프 금지 — 레이아웃 시프트가 불안 유발). `prefers-reduced-motion` 필수 대응.
|
||
|
||
---
|
||
|
||
## 4. 가상 내담자 아바타 (이 플랫폼의 심장)
|
||
|
||
학습자의 시선이 30~50분간 머무는 단 하나의 오브젝트. 산만하면 라포 연습을 방해하고, 과하면 실제 환자로 오인되며, 빈약하면 몰입이 깨진다.
|
||
|
||
### 4.1 추천: "반(半)구상 페르소나 카드 (Semi-figurative Persona Card)"
|
||
|
||
사실적 얼굴도, 추상 오브도 아닌 그 사이. **사실성 35~45%의 양식화 반구상 흉상 + 호흡하는 광배(aura)**.
|
||
|
||
#### 표현 방식 비교 (왜 이걸 골랐나)
|
||
|
||
| 방식 | 몰입 | 제작비용(20주) | 윤리/오인 위험 | 불쾌한 골짜기 | 결론 |
|
||
|---|---|---|---|---|---|
|
||
| A. 추상 오브 / 음성 비주얼라이저 | 낮음 | 매우 낮음(1주) | 없음 | 없음 | **폴백으로만**(미선택/로딩/에러) |
|
||
| **B. 2D 양식화 일러스트(반구상)** | 높음 | 중간(3~6주) | 낮음 | 회피 가능 | **★ 1차 채택** |
|
||
| C. 실사 / AI생성 얼굴 | 매우 높음 | 높음 | **높음** | **직격(최악)** | 탈락 |
|
||
| D. Live2D / 3D | 매우 높음 | 매우 높음(6~10주+) | 중간 | 리깅 품질 의존 | 2차/장기 후보 |
|
||
|
||
- **B를 고른 이유**: 사실성을 의도적으로 35~45%에 고정 → 불쾌한 골짜기 회피. 벡터라 페르소나별 파라미터(피부톤·헤어·눈 형태·연령감)를 **데이터로 찍어내 시스템화 가능**(페르소나 무한 확장). 눈·눈썹·입꼬리·어깨선 4채널만으로 저항/라포/정서를 은은히 표현. 윤찬 미니멀 톤과 정합.
|
||
- **C 탈락**: 80% 사실성에서 미세 립싱크 오차가 더 크게 불쾌. 미성년·취약 내담자를 실사로 그리면 "이 아이 실존?" 윤리 문제 + 데이터 편향.
|
||
- **A를 폴백으로 흡수**: ElevenLabs Orb 같은 성숙한 React 자산을 페르소나 미선택/로딩/에러 화면에 영구 잔존.
|
||
|
||
#### 카드 구조
|
||
|
||
```
|
||
┌─────────────────────────────────────┐
|
||
│ [상단 kicker] 교육용 가상 내담자 │ ← 상시 라벨(오인 차단)
|
||
│ │
|
||
│ ╭───────────────╮ │
|
||
│ │ 양식화 흉상 │ │ ← 어깨~머리, 평면 벡터
|
||
│ │ (얼굴 35% 사실) │ │ 배경에 호흡하는 광배
|
||
│ ╰───────────────╯ │
|
||
│ │
|
||
│ 서연 · 17세 · 고2 │ ← 페르소나 메타 1줄
|
||
│ ────────── │
|
||
│ 지금: 머뭇거리며 듣는 중 │ ← 상태 텍스트 1줄
|
||
└─────────────────────────────────────┘
|
||
```
|
||
|
||
핵심: **얼굴은 양식화하되 "사람"으로 읽히고, 절대 "실존 인물"로는 안 읽히게.** 코·주름·모공 없음. 눈·눈썹·입꼬리·어깨 각도가 정서를 나르는 4개 채널.
|
||
|
||
### 4.2 음성 발화 중 반응 — 상태 모델 (4-state)
|
||
|
||
음성 UI 표준 idle/listening/thinking/speaking을 내담자 맥락으로 재정의.
|
||
|
||
| 상태 | 트리거 | 입 | 눈/눈썹 | 광배(aura) | 어깨 호흡 |
|
||
|---|---|---|---|---|---|
|
||
| **listening (학습자 발화 중)** | 마이크 입력 감지 | 닫힘, 미세 입꼬리 | **학습자 쪽 응시**, 깜빡임 4~6s | 차분 펄스 0.06 opacity, 5.5s | 진폭 1.5px, 4s |
|
||
| **thinking (응답 생성 대기)** | STT 종료~TTS 시작 | 살짝 다묾 | 시선 살짝 아래/옆, 깜빡임 느려짐 | 안쪽 수축, 채도 -8% | 정지에 가깝게 |
|
||
| **speaking (내담자 발화)** | TTS 오디오 재생 | **립싱크 진폭** | 정면 복귀, 눈썹 정서 반영 | 발화 진폭에 약동기(0.04~0.12) | 발화 리듬따라 미세 |
|
||
| **idle (시작 전/일시정지)** | 무입력 | 닫힘 | 천천히 깜빡, 가끔 시선 이동 | 최소 펄스 | 느린 호흡 3.5s |
|
||
|
||
### 4.3 립싱크 — "정밀 음소 매칭 안 함"이 정답
|
||
|
||
35% 사실성 얼굴에 정밀 비짐(viseme) 매핑은 오히려 불쾌. **오디오 진폭(RMS) → 입 열림 높이** 1채널 매핑.
|
||
|
||
```ts
|
||
// Web Audio AnalyserNode → 매 프레임 RMS → 입 SVG path 세로 스케일
|
||
const rms = getRMS(analyser); // 0~1
|
||
const mouthOpen = smooth(rms, 0.18); // 지수평활(튐 방지), τ≈180ms
|
||
// <path class="mouth" style={{ transform:`scaleY(${0.35 + mouthOpen*0.65})` }}/>
|
||
```
|
||
|
||
- 입 모양: 닫힘=얇은 호, 열림=타원. `scaleY`만 변형. **이빨·혀 절대 안 그림.**
|
||
- **데드존**: rms < 0.04는 닫힘 고정 → 무음 구간 입 떨림 제거.
|
||
- 평활 필수: raw RMS 직결하면 입이 경련함. τ=150~200ms.
|
||
|
||
### 4.4 모션 진폭 가이드 (산만함 차단의 핵심)
|
||
|
||
| 모션 | 진폭 | 주기/속도 | 비고 |
|
||
|---|---|---|---|
|
||
| 어깨 호흡(idle) | translateY 1.5~2.5px | 3.5~5.5s ease-in-out 무한 | "있는 줄 모르게" |
|
||
| 깜빡임 | scaleY 1→0.08→1 | 120ms, 간격 4~7s 랜덤 | 생체감의 80%가 여기서 |
|
||
| 광배 펄스 | opacity ±0.04~0.08 | 5~6s | speaking 때만 오디오 동기 |
|
||
| 시선 이동(saccade) | ±3px | 0.3s, 간격 6~10s | thinking에서 빈도↑ |
|
||
| 립싱크 | scaleY 0.35~1.0 | 오디오 실시간 | 데드존+평활 |
|
||
|
||
> 원칙: **동시에 움직이는 채널 ≤ 2개.** speaking이면 입+광배만. listening이면 깜빡임+호흡만.
|
||
|
||
### 4.5 정서 시각화 — 6파라미터 상태머신
|
||
|
||
valence/arousal 축을 아바타 파라미터로 인코딩. **과장 절대 금지**(만화적 눈물·홍조·땀방울 전부 금지). 상담 도구의 정서는 "감지되되 단언되지 않는" 수준.
|
||
|
||
| 내담자 정서 | 눈/눈썹 | 입꼬리 | 자세(어깨선) | 광배 색조 | 호흡 |
|
||
|---|---|---|---|---|---|
|
||
| **중립/라포** | 눈썹 수평, 눈맞춤 | 미세 상향 | 정면, 약간 열림 | 세이지 `#3E7A6E` 4% | 안정 4s |
|
||
| **우울(저각성·부정)** | 눈꺼풀 1~2px 하강, 시선 아래 | 수평~미세 하향 | 어깨 안으로·아래로 | 청회색 `#5B6B73` 5% | 느리고 얕게 5.5s |
|
||
| **불안(고각성·부정)** | 깜빡임↑(2~4s), saccade↑ | 다묾, 긴장 | 약간 들썩 | 차가운 청 `#3B6E8F` 5%, 빠른 펄스 | 빠르고 얕게 3s |
|
||
| **저항/방어** | 시선 회피(옆/아래 고정) | 굳게 닫힘 | 반쯤 돌아선 각도(turn 8°) | 중립 회색, 무펄스 | 정지에 가깝게 |
|
||
|
||
상태머신이 `(eyelidDrop, gazeAvert, shoulderTurn, breathRate, auraHue, blinkInterval)` 6개 숫자만 바꾸면 정서 전환. **라포가 쌓이면(세션 진행) 저항 페르소나가 shoulderTurn 8°→0°, gazeAvert→눈맞춤으로 서서히 완화** → 학습자가 "내가 라포를 만들었다"를 시각적으로 체감. **이게 이 도구의 교육적 핵심.** 정서 전환은 0.8~1.2s ease로 천천히, 동시 변하는 파라미터 ≤3개.
|
||
|
||
### 4.6 페르소나 파라미터 시스템 (새 페르소나 = 새 숫자 묶음)
|
||
|
||
```jsonc
|
||
// persona/seoyeon.json — 청소년 페르소나 예시
|
||
{
|
||
"id": "seoyeon",
|
||
"label": "서연 · 17세 · 고2",
|
||
"appearance": {
|
||
"ageBand": "teen", // teen | youngAdult | adult | senior
|
||
"skinTone": "#E8C9A8",
|
||
"hair": { "style": "long-straight", "color": "#2B2723" },
|
||
"faceRatio": { "eyeSize": 1.15, "jawWidth": 0.92 }, // teen=큰 눈·좁은 턱
|
||
"outfit": "hoodie", // 실루엣만, 디테일 X
|
||
"realism": 0.40 // 0.35~0.45 고정(불쾌한 골짜기 회피)
|
||
},
|
||
"voice": { "provider": "openai", "preset": "soft-young-fem", "rate": 0.96 },
|
||
"baseAffect": "anxious", // 시작 정서
|
||
"resistance": 0.6, // 0~1, 라포로 감소
|
||
"auraHueShift": -6
|
||
}
|
||
```
|
||
|
||
#### 연령대 외형 규칙
|
||
|
||
| ageBand | 눈 크기 | 턱/얼굴 | 실루엣 | 광배 채도 | 음성 톤 |
|
||
|---|---|---|---|---|---|
|
||
| **teen** | 1.1~1.2× | 좁은 턱·둥근 | 후디·체크 | 약간 높음(생기) | 부드럽고 높은 |
|
||
| **youngAdult** | 1.0× | 표준 | 캐주얼 | 중간 | 표준 |
|
||
| **adult** | 0.95× | 각진 턱 | 셔츠·니트 | 낮음(차분) | 낮고 안정 |
|
||
| **senior** | 0.92× | 부드러운 윤곽 | 단정 | 낮고 따뜻 | 느린 |
|
||
|
||
- **미성년 페르소나는 realism을 0.35로 더 낮추고** `교육용 가상 내담자(미성년 시뮬레이션)` 라벨 강화 → 실존 미성년 오인 원천 차단.
|
||
- 외형은 인종·특정 외모 stereotype 회피를 위해 **중립 톤 팔레트 3~4종**만 제공(편향 최소화).
|
||
|
||
### 4.7 아바타 구현 기술 — SVG 1차, Rive 2차
|
||
|
||
| 기술 | 적합 | 근거 |
|
||
|---|---|---|
|
||
| **SVG + CSS/Web Animations + Web Audio** | ★ 1차 | 페르소나=벡터 파라미터, 립싱크=RMS 1채널, 의존성 0, React 친화, 미니멀 정합 |
|
||
| **Rive (상태머신)** | ★ 2차 고도화 | 상태머신이 .riv에 내장, React는 input만 wiring. Lottie 대비 파일 10~15× 작음 |
|
||
| Lottie | 보조 | 정형 애니(로딩·전환)엔 OK, 실시간 오디오 반응엔 부적합 |
|
||
| Live2D/3D | 장기 | 표현력 최고지만 20주·시스템화 불리 |
|
||
|
||
#### 1차안 컴포넌트 구조 (SVG)
|
||
|
||
```
|
||
<ClientAvatar persona state affect analyser/>
|
||
├─ <AuraLayer hue affect state/> // 배경 광배: radial-gradient, opacity 펄스
|
||
├─ <BodySilhouette persona/> // 어깨선, shoulderTurn 각도
|
||
├─ <FaceGroup persona affect>
|
||
│ ├─ <Eyes blink gaze eyelidDrop/>
|
||
│ ├─ <Brows affect/> // 정서별 각도 2~3px
|
||
│ └─ <Mouth analyser state/> // RMS→scaleY 립싱크
|
||
└─ <PersonaLabel/> // "교육용 가상 내담자" 상시
|
||
```
|
||
|
||
```tsx
|
||
// 단일 rAF 루프, 의존성 0
|
||
function useAvatarMotion(state, affect, analyser) {
|
||
const [frame, setFrame] = useState(initFrame(affect));
|
||
useEffect(() => {
|
||
let raf, t0 = performance.now();
|
||
const loop = (t) => {
|
||
const dt = (t - t0) / 1000;
|
||
const breath = Math.sin(dt * (2*Math.PI/affect.breathPeriod)) * affect.breathAmp;
|
||
const mouth = state==='speaking' ? smoothRMS(analyser) : 0;
|
||
const blink = blinkSchedule(t, affect.blinkInterval);
|
||
setFrame({ breath, mouth, blink, gaze: gazeFor(state) });
|
||
raf = requestAnimationFrame(loop);
|
||
};
|
||
raf = requestAnimationFrame(loop);
|
||
return () => cancelAnimationFrame(raf);
|
||
}, [state, affect, analyser]);
|
||
return frame;
|
||
}
|
||
```
|
||
|
||
- **퍼포먼스**: SVG 변형은 `transform`(GPU 합성)만, layout 트리거 속성(width/top) 금지. 단일 rAF, 60fps 여유.
|
||
- **RN 이전 대비**: SVG는 `react-native-svg`, Web Audio는 `react-native-audio-api`로 대체 → 로직 재사용. Rive도 RN 런타임 있음.
|
||
- **접근성**: `prefers-reduced-motion` 켜지면 호흡·광배 정지, 상태는 텍스트로만.
|
||
|
||
---
|
||
|
||
## 5. 상담 세션 화면 (메인 화면)
|
||
|
||
핵심 긴장: **몰입 vs 평가 가시성.** 실시간 피드백이 라포 형성을 방해하면 안 되고, 평가가 사후로만 묶이면 학습 효과가 떨어진다. 해법 = **2단(two-tier) 피드백 모델** — 실시간은 "신호(signal)" 수준, 정밀 평가는 "회기말 리뷰"로.
|
||
|
||
### 5.1 3-column 골격 (데스크탑 ≥1280px)
|
||
|
||
```
|
||
┌──────────────────────────────────────────────────────────────────────────┐
|
||
│ 상단 바 (56px) 좌:세션 제목/시나리오 중앙:회기 단계 우:경과시간·종료 │
|
||
├──────────────────┬──────────────────────────────────┬──────────────────────┤
|
||
│ LEFT (320px) │ CENTER (flexible) │ RIGHT (300px) │
|
||
│ ───────────── │ ───────────────── │ ───────────── │
|
||
│ 회기 단계 트랙커 │ 내담자 아바타 / 음성 STAGE │ 피드백 신호 패널 │
|
||
│ (라포→탐색→ │ (어두운 배경, 중앙 집중) │ (은은한, 평시 접힘) │
|
||
│ 개입→정리) │ │ │
|
||
│ 내담자 컨텍스트 │ [ 아바타 + 음성 오브 ] │ ── 내담자 상태 ── │
|
||
│ 카드 │ │ ── 라이브 신호 ── │
|
||
│ │ 실시간 자막 (아래→위 흐름) │ (최대 1개, 페이드) │
|
||
│ │ │ ── 셀프 노트 ── │
|
||
├──────────────────┴──────────────────────────────────┴──────────────────────┤
|
||
│ 하단 컨트롤 바 (80px) 마이크 · 일시정지 · [몰입│은은│코칭] · 회기 종료 확인 │
|
||
└──────────────────────────────────────────────────────────────────────────┘
|
||
```
|
||
|
||
**비율 의도: 시각적 무게 = 주의 배분.** 내담자 stage 60%, 평가 패널 15%(평시 대부분 접힘). 화면은 대시보드가 아니라 상담실이다.
|
||
|
||
**반응형:**
|
||
- 태블릿(768~1279px): RIGHT 패널이 오버레이 drawer(평시 숨김, 우상단 신호 도트만). LEFT 280px.
|
||
- 모바일/RN(<768px): 단일 컬럼. stage 상단 고정(40vh), 자막 스크롤, 단계는 상단 가는 진행선, 평가는 하단 시트(bottom sheet). 컨트롤 바 하단 고정.
|
||
|
||
### 5.2 중앙 STAGE — 음성 오브 (Voice Orb, 4상태)
|
||
|
||
자극적 막대 파형 대신 **차분한 호흡(breathing) 애니메이션**. 아바타(원형 220px) 둘레 오브 링.
|
||
|
||
| 상태 | 시각 | 색 | 모션 |
|
||
|---|---|---|---|
|
||
| **내담자 말하는 중** | 따뜻한 링, 음량 따라 미세 진동 | `--clay` glow, 두께 4px | 음량 연동 amplitude(0.5~3px), 0% 형광 |
|
||
| **학습자 말하는 중** | 세이지 링, 호흡 펄스 | `--accent` glow | 1.4s ease breathing scale 1.0→1.04 |
|
||
| **대기/침묵(thinking)** | 가는 점선 매우 느리게 회전 | `--ink-3` | 8s/회전, 거의 안 보일 정도 |
|
||
| **일시정지** | 반투명 오버레이 + "일시정지" | `--bg-stage` 60% | 정지 |
|
||
|
||
```css
|
||
.orb {
|
||
position: absolute; inset: -14px; border-radius: 50%;
|
||
box-shadow: 0 0 0 3px var(--ring-color),
|
||
0 0 28px 4px color-mix(in srgb, var(--ring-color) 35%, transparent);
|
||
transition: box-shadow 320ms ease;
|
||
}
|
||
.orb[data-state="learner"] { --ring-color: var(--accent); animation: breathe 1.4s ease-in-out infinite; }
|
||
.orb[data-state="client"] { --ring-color: var(--clay); /* JS가 RMS 음량을 --amp로 주입 */ }
|
||
@keyframes breathe { 0%,100%{ transform: scale(1) } 50%{ transform: scale(1.035) } }
|
||
```
|
||
|
||
음량 연동은 JS `onVolumeChange`/RMS → CSS 변수 `--amp`로 box-shadow blur 미세 모듈레이션. **막대 파형(equalizer) 금지** — 너무 "녹음 앱"스럽고 자극적. 호흡하는 빛이 임상적이다.
|
||
|
||
### 5.3 실시간 자막 (Transcript) — 대본 스타일
|
||
|
||
음성이 주, 자막은 보조. stage 하단, **아래→위 흐름**. 채팅 버블 양산형 회피, 대본(script) 스타일:
|
||
|
||
```
|
||
─────────────────────────────────────
|
||
내담자 14:32
|
||
요즘은 그냥… 아침에 일어나는 게
|
||
제일 힘들어요.
|
||
나(학습자) 14:33
|
||
아침에 일어나는 것조차 버겁게
|
||
느껴지시는군요. 그 마음을 조금
|
||
더 들려주실 수 있을까요?
|
||
─────────────────────────────────────
|
||
```
|
||
|
||
- 화자 라벨 12px 600 메타톤. 내담자 발화는 `--clay-tint` 옅은 배경 틴트 블록, 학습자 발화는 `--accent-tint` 틴트. **버블 외곽선·꼬리·border-left 없음.** 틴트 블록만으로 화자 구분.
|
||
- 진행 중 발화(partial)는 `--ink-3` 흐릿하게 타이핑되다 확정되면 `--ink` 또렷하게.
|
||
- 자동 스크롤, 위로 스크롤하면 자동스크롤 해제 + "최신으로" 작은 칩.
|
||
|
||
### 5.4 회기 단계 표시 (라포 → 탐색 → 개입 → 정리)
|
||
|
||
LEFT 패널 세로 트랙커 + 상단 바 가로 미니. **현재 단계만 또렷, 나머지는 은은히** (단계 압박 방지).
|
||
|
||
```
|
||
회기 진행 ← kicker
|
||
● 라포 형성 09:12 ← 완료: 채워진 sage 도트 + 소요시간
|
||
│
|
||
◉ 탐색 진행중 ← 현재: 링+채움, accent, 굵게
|
||
│
|
||
○ 개입 ← 예정: 빈 도트, ink-3
|
||
│
|
||
○ 정리
|
||
```
|
||
|
||
- 연결선 1px `--hair`, 완료 구간만 `--accent-bright`.
|
||
- **자동 추적 기본, 수동 보정 가능.** 백그라운드 평가 AI가 대화로 현재 단계 추정해 `◉` 이동. 학습자가 직접 "다음 단계로" 가능(자각 촉진). 추정과 인식 어긋나면 회기말 리뷰에서 짚음.
|
||
- **자극 배제:** 단계 전환 시 화면 전환·효과음·축하 애니 없음. 도트가 조용히 채워질 뿐(400ms ease).
|
||
|
||
### 5.5 실시간 피드백 — "거슬리지 않게" (이 설계의 심장)
|
||
|
||
**3단계 강도 모델**을 학습자가 토글로 고른다 (하단 컨트롤 바 segmented control, 기본=은은한 신호):
|
||
|
||
| 모드 | 실시간 표시 | 대상 |
|
||
|---|---|---|
|
||
| **몰입(Immersive)** | 라이브 신호 전혀 없음. 백그라운드 기록만. 모든 피드백 회기말. | 숙련·실전 압박 연습 |
|
||
| **은은한 신호(Ambient)** ★기본 | 우측 패널에 **앰비언트 도트 1개만**, 색으로 톤만. 텍스트 없음(호버 시) | 일반 연습 |
|
||
| **코칭(Coached)** | 발화 직후 짧은 텍스트 힌트 페이드인 | 초보·특정 기법 집중 |
|
||
|
||
#### 앰비언트 신호 (기본 모드 핵심)
|
||
|
||
우측 패널에 **단 하나의 부드러운 도트**가 직전 발화 평가 톤만 색으로 전한다. 점수·숫자·순위 **없음.**
|
||
|
||
```
|
||
라이브 신호 ← kicker
|
||
● 공감적 반영 ← pos 도트 + 한 단어. 6초 후 페이드.
|
||
최근 흐름 · · ● · ◦ · ● ← 최근 6개 발화 톤 미니 시퀀스(클릭 가능)
|
||
```
|
||
|
||
- 도트 색: `--pos-solid`(잘함) / `--warn-solid`(살펴볼 점) / `--ink-3`(중립). **빨강·점수 없음.**
|
||
- 등장: 발화 종료+평가 완료 시 opacity 0→1, 350ms. **6초 후 자동 페이드** — 누적되면 대시보드가 됨.
|
||
- 거슬림 최소화 3원칙: ①한 번에 1개 ②텍스트 기본 숨김(색만) ③시간 제한 페이드. 진동/소리/번쩍임 전무. 주변시로 "느낄" 수준.
|
||
|
||
#### 코칭 모드 텍스트 힌트
|
||
|
||
```
|
||
코칭 힌트 ← kicker
|
||
방금 질문은 '예/아니오'로 닫혀 있었어요.
|
||
내담자가 더 말하도록 열어보면 어떨까요?
|
||
예: "그때 어떤 마음이 드셨는지 들려주세요."
|
||
[ 알겠어요 ] ← 가볍게 dismiss
|
||
```
|
||
- `--accent-tint` 배경 틴트 블록(border 없음), 13~14px. 예시 문장 `--ink-2` 이탤릭. 한 번에 1개, 새 힌트 오면 이전 것 교체(stack 안 함).
|
||
- **위험 신호만 예외적 즉시 표시(모드 무관):** 자해·위기 언급을 학습자가 놓치면 모드 무관하게 우측에 차분한(빨강 아닌 `--warn-solid`) 알림 — "안전 점검: 방금 위기 신호가 있었어요." 교육적으로 놓치면 안 되는 지점이라 항상 노출.
|
||
|
||
#### 내담자 상태 미터 (우측 상단) — "반응 읽기 연습"의 거울
|
||
|
||
```
|
||
내담자 상태
|
||
감정 톤 불안 ▓▓▓▓░░ ← 가로 게이지, clay 계열, 라벨 텍스트
|
||
마음 열림 ▓▓░░░░ ← 라포 진척 대리지표
|
||
```
|
||
게이지는 매우 천천히(2s ease) — 실시간 흔들림이 산만하지 않게. 막대 라운드 없는 사각, 4px 높이.
|
||
|
||
### 5.6 하단 컨트롤 바
|
||
|
||
- **마이크 버튼(주 컨트롤):** 56px 원형. 학습자 말하는 중 = `--accent` 채움 + 호흡. 음소거 = 아웃라인. push-to-talk 또는 토글. 상태 텍스트 한 줄("듣고 있어요" / "마이크 꺼짐").
|
||
- **일시정지:** 타이머·평가·녹음 모두 정지. 정지 중 stage 차분한 오버레이.
|
||
- **종료:** 오발동 방지 — 숨은 제스처가 아니라 명시적 **회기 종료** 버튼 + 확인 다이얼로그. 종료가 유일하게 진한 경고색(`--crit-solid`) 허용 영역.
|
||
- 접근성: 키보드(Space=마이크, P=일시정지), `--focus-ring` 2px. 음성 상태는 색만이 아니라 텍스트 병기(색각 이상 대응).
|
||
|
||
### 5.7 회기 종료 후 리뷰 화면 (진짜 학습이 일어나는 곳)
|
||
|
||
실시간에선 일부러 참았던 정밀 평가를 여기서 푼다. 구조: **타임라인 + 기법 라벨 + 슈퍼바이저 코멘트 + 개선점.**
|
||
리뷰도 라이브 세션과 같은 dark 작업면을 유지한다. 저장된 발화가 없는 빈 상태에서도 흰 카드로 빠지지 않고, 근거 대기/평가 대기/워크시트 대기를 어두운 패널로 보여준다.
|
||
|
||
```
|
||
┌──────────────────────────────────────────────────────────────────────────┐
|
||
│ 리뷰 · 시나리오:우울 호소 20대/회기1 오디오 다시듣기▷ PDF 내보내기 │
|
||
├──────────────────────────────────────────────────────────────────────────┤
|
||
│ 한 줄 요약 (큰 문장 하나, 24px/600 — 에디토리얼 미니멀의 핵심) │
|
||
│ "라포는 안정적으로 형성됐지만, 탐색 단계에서 닫힌 질문이 반복돼 │
|
||
│ 내담자의 자기개방이 일찍 멈췄습니다." │
|
||
├───────────────────────────────────────┬──────────────────────────────────┤
|
||
│ LEFT (62%) 타임라인 + 자막 │ RIGHT (38%) 분석 사이드 │
|
||
│ 회기 타임라인(가로 막대) │ ── 기법 사용 분포 ── │
|
||
│ 라포▏▏탐색▏▏▏▏▏개입▏▏정리▏ │ 반영적 경청 ▓▓▓▓▓▓ │
|
||
│ ▲ 마커(코멘트·기법·하이라이트) │ 개방형 질문 ▓▓ │
|
||
│ ─── 스크롤 자막(마커 연동) ─── │ 닫힌 질문 ⚠ ▓▓▓▓▓ (살펴볼 점) │
|
||
│ 나 14:33 ◆[감정 반영] … │ ── 잘한 순간 ── │
|
||
│ └ 슈퍼바이저: "좋은 반영…" │ ── 다음 회기 개선점(최대 3개) ── │
|
||
└───────────────────────────────────────┴──────────────────────────────────┘
|
||
```
|
||
|
||
- **타임라인(가로):** 4단계 너비 비례 구간으로 색 농담 구분. 마커 = 기법 라벨·살펴볼 순간·잘한 순간·슈퍼바이저 코멘트(이모지 아님, SVG 글리프/도트). 클릭하면 좌측 자막 점프 + 오디오 그 시점으로.
|
||
- **자막 + 인라인 분석:** 학습자 발화마다 기법 라벨 칩(`[반영적 경청]` `[개방형 질문]` `[닫힌 질문]`), `--accent-tint`/`--warn-tint` 배경, border 없음 11px. 라벨 아래 들여쓰기로 슈퍼바이저 코멘트(AI 자동 + 교수자 직접). AI코멘트 `--ink-2`, 사람 코멘트 `--accent` + "교수자" 태그.
|
||
- **분석 사이드:** 기법 사용 분포(가로 게이지, 점수 아님 빈도+적절성, 과다·과소만 `--warn` 라벨). 잘한 것 먼저, 개선점 **최대 3개**(실행 가능 구체적, 각 항목 타임라인 마커 연결). 다음 회기 개선점은 "다음에 시도할 한 문장" 형태.
|
||
- **톤:** 점수·등급·합불 **없음.** 상담 역량은 성장 곡선이지 시험이 아니다. 추세는 별도 "학습자 성장" 화면에서만, 단일 리뷰엔 절대점수 안 보임. PDF 내보내기(슈퍼바이저 제출), 오디오 다시듣기, 클립 공유.
|
||
|
||
---
|
||
|
||
## 6. 3역할 대시보드 (학습자 / 교수자 / 관리자)
|
||
|
||
### 6.1 4가지 설계 결정 (근거)
|
||
|
||
| 결정 | 근거 |
|
||
|---|---|
|
||
| **레이더차트 금지, small-multiples 라인 채택** | 레이더는 항목 순서로 모양 왜곡 + 범주선 "증가/감소" 착시. Tufte small-multiples + 공통 축이 정확. 윤찬 "카드덤프 금지"와도 정합. |
|
||
| **신뢰·차분 = 단일 accent + 넉넉한 여백 + 위계** | 의료 UI: blue=신뢰, green=정상범위, **red는 진짜 임상 긴급에만 예약**. whitespace·typography로 불안 완화. |
|
||
| **교수자 화면은 "인지"가 아니라 "개입"까지** | 교사용 LA 대시보드 대부분이 awareness만 주고 actionable intervention이 없다는 비판 → 첫 화면을 "개입 필요 학생" 액션 큐로. |
|
||
| **역할 전환 = 컨텍스트 라벨 + accent 토큰** | 과한 색·뱃지 남용은 양산형. 좌상단 역할 라벨 + accent 한 토큰 교체로 "지금 누구의 화면인지"만 조용히. |
|
||
|
||
### 6.2 역할별 accent 오버라이드
|
||
|
||
```css
|
||
body[data-role="learner"] { --accent:#3E7A6E; --accent-bright:#5F968B; --accent-tint:#EEF4F2; } /* 세이지-틸: 성장 */
|
||
body[data-role="instructor"] { --accent:#3A5BA0; --accent-bright:#5478C4; --accent-tint:#EAEFF7; } /* 인디고-블루: 감독 */
|
||
body[data-role="admin"] { --accent:#5B5F6B; --accent-bright:#7D818E; --accent-tint:#EEEFF1; } /* 슬레이트: 운영 */
|
||
```
|
||
|
||
세 역할 모두 채도를 낮춰 자극 없게. red(`--crit-solid`)는 어느 역할에서도 장식으로 안 쓴다 — 오직 "지금 개입해야 하는 학생/세션" 단 한 곳.
|
||
|
||
### 6.3 공통 앱 셸 (Shell)
|
||
|
||
같은 골격 공유, 좌측 네비 항목 + 좌상단 컨텍스트 라벨만 차이. 역할 전환 시 화면 리셋이 아니라 메뉴·accent만 바뀜.
|
||
|
||
- 톱바 56px `background:var(--surface); border-bottom:1px solid var(--hair);` (그림자 없음).
|
||
- 좌측 네비 기본 72px 아이콘 전용(Lucide stroke 1.75), hover/포커스 시 220px 슬라이드(160ms). 활성 = 아이콘 `color:var(--accent)` + **3px 강조바 금지** → 아이콘 배경 `var(--accent-tint)` `border-radius:8px` 알약형(네비 알약만 8px 관용).
|
||
- **역할 컨텍스트 라벨**: 톱바 좌측, `font-family:var(--font-num); font-size:13px; letter-spacing:0.04em; color:var(--accent);` — "학습 대시보드"/"교수 콘솔"/"운영 콘솔". "지금 누구로 보고 있나"의 유일하고 조용한 신호.
|
||
- **권한 표현 원칙: 권한 없으면 DOM에서 제거.** disabled 회색처리도 안 함 — 존재를 숨김. 화면이 깨끗해지고 "내가 못 하는 것" 노이즈 제거. 임상 데이터 프라이버시(관리자는 학생 개별 성장곡선·transcript 기본 접근 불가, 메뉴 자체 렌더 안 함).
|
||
|
||
### 6.4 학습자 대시보드 (홈 = "당신은 나아지고 있다")
|
||
|
||
```
|
||
COUNSELING PRACTICE · 4주차 ← kicker
|
||
수련생님, 지금까지 12회 연습했어요. ← h1 28px/700
|
||
최근 라포 형성이 눈에 띄게 안정됐습니다. ← lead, accent .em
|
||
|
||
┌─────────────────────────────┐ ┌───────────────────────────┐ ← cols 7:5 비대칭
|
||
│ 종합 상담 역량 │ │ 다음 연습 │
|
||
│ ╭───────╮ │ │ ▸ 불안 호소 내담자·중급 │
|
||
│ │ 72 │ +6 ▲ │ │ 이전 약점: 침묵 다루기 │
|
||
│ ╰───────╯ 지난주 대비 │ │ [ 연습 시작 → ] │
|
||
│ (단일 게이지, 둘레 progress)│ │ 추천 이유: 라포는 올랐지만 │
|
||
└─────────────────────────────┘ │ 위기개입 정확도 정체 │
|
||
└───────────────────────────┘
|
||
역량별 추이 (최근 8회) ← kicker
|
||
┌────────┐┌────────┐┌────────┐┌────────┐ ← small multiples 4열, 공통 y축 0-100
|
||
│라포형성 ││기법사용 ││개입정확도││공감반영 │
|
||
│ ╱╲__╱ ││ __╱╲╱ ││ ╲__╱╲ ││ __╱╱ │
|
||
│ 82 ▲ ││ 68 → ││ 61 ▼ ││ 75 ▲ │
|
||
└────────┘└────────┘└────────┘└────────┘
|
||
최근 피드백 모아보기 (테이블, 카드 아님) ← kicker
|
||
6/24 불안 내담자 │ "침묵 견디지 못하고 성급히 해결책 제시…" — 개입 ▸
|
||
6/22 분노 내담자 │ "반영 정확. 다만 감정 명명이 늦음." — 공감 ▸
|
||
```
|
||
|
||
- **종합 게이지(radar 대체):** 단일 원형. SVG `<circle>` 트랙 `stroke:var(--neutral-150)`, fill arc `stroke:var(--accent); stroke-linecap:round`. 중앙 숫자 48px/700. 변화량 `+6 ▲` = `--pos-solid`, 하락이면 `--warn-solid`(앰버, 빨강 아님). 아래 한 문장 자연어 요약.
|
||
- **역량별 추이 = small multiples:** 4개 동일 크기 미니 라인. **공통 y축 0-100**(첫 카드만 0/50/100 옅게 표기). 라인 `stroke:var(--ink-2); stroke-width:1.5`. 마지막 점만 `r:3; fill:var(--accent)`. 카드 `background:var(--surface); border:1px solid var(--hair); border-radius:8px; padding:16px`. **상단 강조선·좌측바 금지.** 우하단 최신값+추세 화살표(▲`--pos`, →`--ink-3`, ▼`--warn`). 호버 툴팁, 클릭 시 세션 상세.
|
||
- **피드백 모아보기 = 테이블, 카드 아님:** 날짜/내담자유형/인용 코멘트/태그/`▸`. zebra 없이 행 `border-bottom:1px solid` `--paper-2`. 행 hover `background:var(--accent-tint)`. 카드 격자로 흩뿌리지 않고 시간순 한 컬럼 위계.
|
||
|
||
### 6.5 교수자 콘솔 (홈 = "누구를 먼저 도와야 하는가")
|
||
|
||
핵심: **awareness가 아니라 triage.** 첫 화면 최상단이 "개입 필요 학생" 액션 큐.
|
||
|
||
```
|
||
상담실습 II · 28명 담당 ← kicker
|
||
이번 주, 3명에게 개입이 필요합니다. ← h1, accent .em
|
||
|
||
┌──────────────────────────────────────────────────────────────┐ ← 개입 큐(최우선, 풀폭)
|
||
│ ● 박서연 개입정확도 3주 연속 하락(61→52→44) 미연습 5일 ▸ │ 좌측 dot = --crit-solid
|
||
│ ● 이도현 위기상담 시뮬 중도이탈 2회 마지막 6/20 ▸ │
|
||
│ ● 최민준 라포 점수 급락, 피드백 미열람 7건 ▸ │
|
||
└──────────────────────────────────────────────────────────────┘
|
||
|
||
학생별 현황 [정렬: 위험도▾] [영역: 전체▾]
|
||
학생 세션 라포 기법 개입 공감 추세 마지막 상태
|
||
김수련 12 82↗ 68→ 61↘ 75↗ ▁▃▅▆▇ 6/24 양호
|
||
박서연 8 55↘ 49↘ 44↘ 58↘ ▇▅▃▂▁ 6/19 ● 개입
|
||
이도현 14 88↗ 79↗ 71→ 84↗ ▅▆▆▇▇ 6/23 양호
|
||
```
|
||
|
||
- **개입 큐(triage):** 풀폭 패널. 각 행 좌측 dot `8px; background:var(--crit-solid)`(red의 유일한 정당한 사용처). 사유 = 수치 변화 + 행동 신호(미연습일·미열람·중도이탈)를 자연어로. 알고리즘이 뽑되 교수가 최종 판단하도록 "왜"를 노출.
|
||
- **반 평균 역량 분포 = 가로 막대**(레이더 아님): fill `var(--accent)`, 트랙 `var(--paper-2)`. **최저 항목만** 우측 `← 취약` `color:var(--warn-solid)`. 나머지 차분한 무채.
|
||
- **학생별 테이블:** sparkline(▁▃▅▆▇, 셀 안 7px SVG, 최근 8회 종합점수). 역량 셀 `82↗`(화살표 색만 시맨틱). 정렬 기본 위험도 순. 상태 "양호"는 `--ink-3` 무채, "● 개입"만 `--crit-solid` dot. red를 한 곳에 집중. 행 클릭 → 학생 드릴다운(학습자 화면 + 세션별 utterance-level 평가 타임라인).
|
||
|
||
### 6.6 관리자 콘솔 (홈 = "시스템이 건강한가 · 누가 무엇을 했는가")
|
||
|
||
핵심: **운영 신뢰성 + 감사.** 학습 내용엔 개입 안 하고 시스템·사용·교수활동 감사에 집중. 무채 슬레이트로 가장 차분.
|
||
|
||
- **운영 KPI 5:** 사용자/강좌/세션주/가동%/API오류. mono 32px. 오류 0 초과 시 해당 KPI만 `--warn-solid`, 임계 초과 `--crit-solid`. 정상 땐 전부 무채 — "조용한 게 정상".
|
||
- **세션 추이 = 단일 라인차트**(막대 아님). 피크 1점만 라벨.
|
||
- **음성·AI 사용 + 비용:** OpenAI 음성 분/평가 토큰/추정 비용/예산 대비 게이지(80% 넘으면 `--warn-solid`). 운영비 가시화(윤찬 graphify 비용 통제 문화).
|
||
- **교수 활동 감사 테이블:** 교수별 피드백 열람률(품질 신호)·시나리오 발행·마지막 활동. 저조 지표만 `← 저조` `--warn`. "⚠ 점검" = 관리자 리마인드 대상.
|
||
- **Audit log:** 시간순 한 컬럼. 행위자·행위·대상. 색 없음(감사는 중립). 클릭 시 상세.
|
||
|
||
### 6.7 데이터 시각화 하드룰 (전 역할 공통)
|
||
|
||
| 상황 | 채택 | 금지 |
|
||
|---|---|---|
|
||
| 한 사람 여러 역량 **추이** | small multiples 라인(공통 y축) | 레이더/스파이더 |
|
||
| 여러 역량 **현재값 비교** | 가로 막대(공통 0-100), 최저값만 강조 | 레이더, 전항목 색칠 |
|
||
| 한 지표 **시간 추이** | 단일 라인(피크/최신 1점만 라벨) | 3D·면적 그라데이션 |
|
||
| 테이블 안 **추세 압축** | sparkline(7px) + 화살표 | 셀마다 미니 도넛 |
|
||
| **종합 한 숫자** | 단일 원형 게이지 + 변화량 | 여러 도넛 격자 |
|
||
|
||
**차트 공통 스타일:** 격자선 최소(y축 0/50/100 옅은 점선만, 세로 격자 없음). 라인 `stroke-width:1.5`, 점은 최신/이상치만. 색은 데이터 의미에만(추세 ↗`--pos`/↘`--warn`/→무채, 평상시 라인 `--ink-2` 무채 → 색 인플레이션 방지). 진입 라인 draw 280ms, 게이지 arc 400ms ease-out 1회만. 깜빡임·펄스·glow 없음. 모든 수치 `tabular-nums`.
|
||
|
||
---
|
||
|
||
## 7. 컴포넌트 원칙 (요약 카탈로그)
|
||
|
||
공통: **border-radius 절제(6~12px, 알약 금지), 그림자 절제(헤어라인 우선), border는 `--hair`.** 카드는 쓰되 균등 4-4-4 격자 남용 금지 → 비대칭·표·도식.
|
||
|
||
### 7.1 버튼 (위계 3단, 알약형 금지 radius 8px)
|
||
|
||
| 종류 | 배경 | 텍스트 | 보더 | 용도 |
|
||
|---|---|---|---|---|
|
||
| Primary | `--accent` | `--text-on-accent` | none | 세션 시작·저장 (화면당 1~2개) |
|
||
| Secondary | `--bg-surface` | `--accent` | 1px `--accent` | 보조 액션 |
|
||
| Ghost | transparent | `--text-body` | none | 취소·텍스트 액션 |
|
||
| Danger | `--crit-solid` | #fff | none | 세션 강제 종료 등 위급만 |
|
||
|
||
```css
|
||
.btn { font: 600 var(--fs-sm)/1 var(--font-sans); padding: 10px 18px;
|
||
border-radius: var(--radius); border:1px solid transparent;
|
||
transition: background .16s ease, transform .12s ease; cursor:pointer; }
|
||
.btn-primary { background: var(--accent); color: var(--text-on-accent); }
|
||
.btn-primary:hover { background: var(--accent-deep); }
|
||
.btn:active { transform: translateY(.5px); } /* 미세 누름, 과한 모션 X */
|
||
.btn:focus-visible { outline:none; box-shadow: 0 0 0 3px var(--focus-ring); }
|
||
```
|
||
|
||
### 7.2 입력 (radius 6px, 포커스 시 보더색 + 얇은 ring, 좌측바 X)
|
||
|
||
```css
|
||
.input { width:100%; background: var(--bg-surface-2); color: var(--text-body);
|
||
border:1px solid var(--border-strong); border-radius: var(--radius-sm);
|
||
padding:10px 12px; font:var(--fs-body)/1.5 var(--font-sans);
|
||
transition:border-color .15s, box-shadow .15s; }
|
||
.input:focus { border-color: var(--border-focus); outline:none; box-shadow: 0 0 0 3px var(--focus-ring); }
|
||
.input[aria-invalid="true"] { border-color: var(--crit-solid); }
|
||
```
|
||
|
||
### 7.3 카드 / 패널 (헤어라인 + 미세 그림자, 상단 강조선 금지)
|
||
|
||
```css
|
||
.card { background: var(--bg-surface); border:1px solid var(--border-subtle);
|
||
border-radius: var(--radius); padding: var(--sp-5); box-shadow: var(--shadow-sm); }
|
||
.panel { background: var(--bg-surface); border:1px solid var(--border-subtle);
|
||
border-radius: var(--radius-lg); padding: var(--sp-6); }
|
||
.panel-tint { background: var(--bg-tint); border-color: transparent; } /* 강조 패널: 틴트 배경 */
|
||
```
|
||
|
||
### 7.4 평가 피드백 콜아웃 (이 플랫폼 핵심, 좌측 컬러바 금지 → 배경 틴트 + 도트 + kicker)
|
||
|
||
```css
|
||
.callout { border-radius: var(--radius); padding: var(--sp-4) var(--sp-5);
|
||
font-size: var(--fs-sm); line-height:1.6; }
|
||
.callout .clh { font: 600 var(--fs-xs)/1.4; letter-spacing:.04em;
|
||
display:flex; align-items:center; gap:8px; margin-bottom:6px; }
|
||
.callout .clh::before { content:""; width:7px; height:7px; border-radius:50%; } /* dot, 바 아님 */
|
||
.callout.pos { background:var(--pos-tint); color:var(--pos-text); }
|
||
.callout.pos .clh::before { background:var(--pos-solid); }
|
||
.callout.info { background:var(--info-tint); color:var(--info-text); }
|
||
.callout.info .clh::before { background:var(--info-solid); }
|
||
.callout.warn { background:var(--warn-tint); color:var(--warn-text); }
|
||
.callout.warn .clh::before { background:var(--warn-solid); }
|
||
.callout.crit { background:var(--crit-tint); color:var(--crit-text); } /* 가드레일 위반만 */
|
||
.callout.crit .clh::before { background:var(--crit-solid); }
|
||
```
|
||
|
||
피드백 강도 매핑: **잘함→`pos`(녹색), 일반 코칭/관찰→`info`(슬레이트), 페이싱·라포 주의→`warn`(앰버), 가드레일/위급→`crit`(적색).** 학습자 화면 기본 피드백은 info/pos가 다수가 되도록.
|
||
|
||
### 7.5 라이브 음성 오브 (§5.2 참조)
|
||
|
||
내담자 발화=sage, 학습자 발화=clay로 화자 구분(채도 낮게). 깜빡이는 빨강 금지 → 호흡 펄스.
|
||
|
||
---
|
||
|
||
## 8. React 구현 노트
|
||
|
||
### 8.1 컴포넌트 트리
|
||
|
||
```
|
||
<AppShell role={role}> // body[data-role] 설정, 네비·톱바
|
||
<RoleNav items={navByRole}/> // 권한 없는 항목 필터링 후 렌더(DOM 제거)
|
||
<ContextLabel/> // mono accent 라벨
|
||
<Outlet/>
|
||
├ <LearnerHome> Hero1줄 + cols(Gauge, NextPractice) + MiniMultiples×4 + FeedbackTable
|
||
├ <InstructorHome> InterventionQueue + KPIs + ClassDistribution + StudentTable(sparkline)
|
||
└ <AdminHome> OpsKPIs + SessionTrend + UsageCost + FacultyAudit + AuditLog
|
||
|
||
<SessionScreen>
|
||
├ <SessionTopBar scenario stage elapsed onEnd/>
|
||
├ <SessionLayout> // CSS grid 320/1fr/300, RN은 Flex
|
||
│ ├ <StagePanel> <StageTracker/> <ClientContextCard/> // LEFT
|
||
│ ├ <ClientStage> // CENTER
|
||
│ │ ├ <ClientAvatar persona state affect analyser/> // §4 아바타
|
||
│ │ ├ <VoiceOrb state amplitude/>
|
||
│ │ └ <LiveTranscript turns partial/>
|
||
│ └ <FeedbackRail mode> // RIGHT
|
||
│ ├ <ClientStateMeter tone openness/>
|
||
│ ├ <AmbientSignal latest recentSequence/> // 은은한 신호
|
||
│ ├ <CoachHint hint onDismiss/> // 코칭 모드만
|
||
│ └ <SelfNote/>
|
||
└ <ControlBar mic paused mode onMic onPause onModeChange onEnd/>
|
||
|
||
<ReviewScreen>
|
||
├ <ReviewHeader scenario onExportPdf onReplay/>
|
||
├ <ReviewHeadline summary/> // 큰 한 문장
|
||
├ <SessionTimeline phases markers onSeek/>
|
||
├ <AnnotatedTranscript turns techniqueLabels supervisorComments audioSync/>
|
||
└ <AnalysisSide techniqueDistribution highlights improvements/>
|
||
```
|
||
|
||
### 8.2 상태 관리
|
||
|
||
- 음성 이벤트(`onModeChange`/`onVolumeChange`/partial transcript)는 OpenAI Realtime 스트림 → 단일 `SessionStore`(Zustand 권장)로 모아 `VoiceOrb`·`LiveTranscript`·`FeedbackRail`·`ClientAvatar` 구독.
|
||
- 평가 AI는 **별도 채널(백그라운드)**로 발화 단위 신호를 throttle해서 push. `FeedbackRail`이 6초 페이드 큐로 소비. 평가와 음성 상태 표시는 분리(평가가 음성 UX를 막지 않게).
|
||
- 차트 프리미티브 4종 먼저 구축: `<Gauge>` `<SparkLine>` `<MiniMultiple>` `<HBar>` (§6.7 룰 내장, props=data+role토큰). 학습자 컴포넌트가 교수 드릴다운에서 재사용됨.
|
||
|
||
### 8.3 구현 순서
|
||
|
||
1. `tokens.css`(§3) + 앱 셸(§6.3) — 셸은 3역할 공통이므로 1회만.
|
||
2. 차트 프리미티브 4종.
|
||
3. 학습자 홈 → 교수 홈 → 관리자 홈 순(재사용 극대화).
|
||
4. 세션 화면: 폴백 추상 오브 먼저(음성 파이프라인·4-state 배선 검증) → 반구상 SVG 아바타 → 정서 6파라미터 → 페르소나 JSON.
|
||
5. 리뷰 화면 + utterance-level 평가 타임라인.
|
||
6. 역할 가드: 라우터에서 `role` 기반 메뉴·라우트 **렌더 제외**(disable 아님).
|
||
7. (여유) Rive 아바타 고도화. 안 되면 SVG 1차안으로 출시(폴백 안전).
|
||
|
||
### 8.4 RN 전환 대비
|
||
|
||
레이아웃 토큰은 절대 px 의존 최소화(rem·flex 우선). SVG→`react-native-svg`, Web Audio→`react-native-audio-api`, Rive→RN 런타임. 브레이크포인트 sm:640/md:768/lg:1024/xl:1280.
|
||
|
||
---
|
||
|
||
## 9. 안티패턴 체크리스트 (HARD NO — 출시 전 자가검증)
|
||
|
||
1. **border-left 강조선 / 좌측 사이드바 형태 강조줄** — 피드백·콜아웃·카드·활성표시에 색 막대 금지. 위계는 kicker+weight+여백+dot+배경틴트.
|
||
2. **이모지** — UI·일러스트·SVG 내부 장식까지 전부 금지. 아이콘은 Lucide(stroke 2, 직각). 평가 결과에 체크/엑스 이모지 금지. 추세는 ▲▼→ 기하 화살표.
|
||
3. **카드 덤프 / 균등 그리드 무한반복(4-4-4)** — 비대칭(7:5) 레이아웃·데이터 테이블·도식으로. 학습자 홈은 게이지+small-multiples+테이블, 교수 홈은 triage 큐+KPI+테이블.
|
||
4. **양산형 SaaS 랜딩** — "그라데이션 히어로 + 떠다니는 mockup + 3컬럼 feature 카드 + 보라 그라데이션 CTA" 공식 금지.
|
||
5. **과한 그라데이션·glow·gradient-text·큰 blur** — 깊이는 1px 헤어라인.
|
||
6. **둥근 모서리 과다(16px+)·말랑 일러스트** — 거의 직각(6~12px). 원형은 오브·아바타·dot만.
|
||
7. **게임화 폭격** — 점수 팡파레, 빨간 X, 레벨업 배지, 별점 5개 즉시. 평가는 서술형·비모달·회고 시점.
|
||
8. **순흑(#000)·순백(#FFF)** — `--ink:#1C2A2A` / `--paper:#FBFAF8`.
|
||
9. **고채도 메디컬 블루 단독 의존** — 세이지-틸로 차별화 + 온기.
|
||
10. **실시간 피드백 모달** — 상담 흐름 중 팝업 금지. 차분한 사이드 패널로.
|
||
11. **레이더/스파이더 차트** — small-multiples 라인 + 단일 게이지로.
|
||
12. **권한 없는 메뉴 disabled 회색 나열** — DOM에서 제거.
|
||
13. **빨강 장식 사용** — `--crit-solid`는 (교수)개입 큐·"개입" 상태·(관리자)임계 오류에만.
|
||
14. **One screen, one message 위반** — 각 화면 최상단 h1이 그 화면 단일 메시지("나아지고 있다"/"3명 개입 필요"/"정상 운영"/"듣고 있어요").
|
||
|
||
---
|
||
|
||
## 10. 핵심 의사결정 5줄 (윤찬이 기억할 것)
|
||
|
||
1. **컬러: 세이지-틸 `#3E7A6E` 단일 accent + 테라코타 `#B0735C` 온기 보조.** 의료 블루 회피, 저채도로 임상+따뜻함 동시. 역할별 accent 한 토큰만 교체.
|
||
2. **아바타: 사실적 얼굴(오인·불쾌한 골짜기·편향)도 추상 오브(비언어 연습 불가)도 답 아님 → 사실성 35~45% 양식화 반구상 흉상 + 호흡 광배.** 눈·눈썹·입·어깨 4채널 × 정서 6파라미터. SVG 1차 → Rive 2차. 미성년은 realism 더 낮추고 `교육용 가상 내담자` 라벨 상시.
|
||
3. **세션 화면: 실시간 피드백은 "신호(색 도트, 6초 페이드, 1개)"까지만, 정밀 평가는 회기말 리뷰로.** 학습자가 모드(몰입/은은/코칭)를 고른다. 음성 상태는 막대 파형이 아니라 빛의 호흡(sage=학습자, clay=내담자).
|
||
4. **시각적 무게 = 주의 배분.** 내담자 stage 60%, 평가 패널 15%·평시 접힘. 화면은 대시보드가 아니라 상담실.
|
||
5. **대시보드: 레이더 금지 → small-multiples 라인 + 단일 게이지.** 점수·합불 없음(성장 추세만). 교수자 첫 화면은 triage 큐. 권한 없으면 DOM 제거.
|
||
|
||
---
|
||
|
||
## 참고 (실조사 출처)
|
||
|
||
**디자인 언어·시스템**
|
||
- Linear Brand Guidelines / Stripe Design / Calm·Headspace 색 (accent rationing, 저채도, 호흡 모션)
|
||
- Fuzzy Math — Color Palettes of Mental Healthcare UI / Villa Healing Center — Calming Colors
|
||
- Halo Lab — Digital Healthcare UX Trends 2026 / Progress — Color Psychology in Healthcare
|
||
- Pretendard (orioncactus/pretendard) / az-loc — Best Fonts for CJK Websites 2026
|
||
- Aufait UX — Accessible Color Tokens / WCAG Contrast Guide 2026
|
||
|
||
**아바타**
|
||
- Behavioral Sciences 2026 — Human-like/Animal-like/Object-like LLM Virtual Doctor Avatar
|
||
- arXiv 2506.11890 — Graduated Realism (AI Avatars in VR Teacher Training)
|
||
- PMC12692777 — AI Physician Avatars (윤리·편향·오인 위험)
|
||
- NYU Steinhardt — AI Avatar for Social Work Counseling Practice
|
||
- ElevenLabs UI Orb / orb-ui (4-state) / Rive vs Lottie 2026 / arXiv 2502.16038 (Valence-Arousal-Dominance)
|
||
|
||
**세션·대시보드**
|
||
- arXiv 2502.18673 — Scaffolding Empathy (utterance-level 피드백 학습효과 vs 인지부하) ← 2단 피드백 모델 근거
|
||
- arXiv 2505.02428 — LLM-Simulated Practice/Feedback for Counselors
|
||
- assistant-ui / Vocalis / Agora (음성 상태 시각화)
|
||
- Scott Logic·Observable — Radar Charts 비판 (small-multiples 대체 근거)
|
||
- GoReact — Counseling Skills Rubric / Springer Open — LA Dashboard actionable intervention 비판
|
||
- Eleken·Fuselab — Healthcare UI/UX 2026
|
||
|
||
**vault 연계 자산**
|
||
- `Resources/50_Tech_Dev/디자인/slide-base.css` (무채 골격·강조 위계 계승)
|
||
- `Resources/50_Tech_Dev/디자인/[디자인 시스템] HTML 슬라이드·보고서 베이스 (2026-06).md` (한신대/의료 행에 `--accent:#3E7A6E` 채움)
|