feat(docs): 전체 페이지 레이아웃 시안 추가

- login/learner-home/session-review/professor/admin/settings
- session-v2(밝은 에디토리얼 톤으로 재제작, 기존 어두운 stage 대체)
- 전부 동일 디자인 토큰(세이지틸+테라코타), 윤찬 철칙 준수
This commit is contained in:
Yun Chan 2026-06-25 21:27:24 +09:00
parent 204726f707
commit d5b86c5f89
8 changed files with 3723 additions and 486 deletions

View file

@ -0,0 +1,635 @@
<!DOCTYPE html>
<html lang="ko">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Vignette — 상담 세션 (밝은 에디토리얼 톤 v2)</title>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/gh/orioncactus/pretendard/dist/web/variable/pretendardvariable.min.css">
<style>
/* =====================================================================
Vignette — 상담 세션 화면 v2 (밝은 에디토리얼 대시보드 톤, 단일 파일)
토큰: DESIGN_CONCEPT.md §3 + learner-home/professor/settings.html 그대로 계승.
역할 = 학습자(세이지-틸 accent). 어두운 stage 폐기 → 밝은 패널 + 은은한 광배.
철칙: border-left 0 · 이모지 0(아이콘 inline SVG) · 카드격자 덤프 0 ·
순흑/순백 금지 · 둥근모서리 과다 금지 · 강조는 weight/tint/kicker/dot ·
한 화면 한 목적(= 가상 내담자와 듣고 말하기). 빨강은 종료에만.
===================================================================== */
:root{
/* 중성 베이스 */
--paper:#FBFAF8; --paper-2:#F4F2EE; --surface:#FFFFFF;
--neutral-100:#ECEFF1; --neutral-150:#E5E1DA; --neutral-200:#D5DBDE; --neutral-400:#98A4A9;
--ink:#1C2A2A; --ink-2:#5A6663; --ink-3:#93A09C; --hair:#E5E1DA;
/* 악센트 (학습자 = 세이지-틸) */
--accent:#3E7A6E; --accent-deep:#316257; --accent-tint:#EEF4F2; --accent-bright:#5F968B;
--clay:#B0735C; --clay-deep:#94604C; --clay-tint:#F6F0EC;
/* 의미색 */
--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;
--info-text:#2E5A7A; --info-solid:#3C7299; --info-tint:#EAF1F6;
--neutral-sig:#8895A2;
/* 별칭 */
--text-on-accent:#FBFAF8;
--focus-ring:rgba(62,122,110,.45);
/* 폰트 */
--font-sans:"Pretendard Variable",Pretendard,-apple-system,"Apple SD Gothic Neo","Noto Sans KR",system-ui,sans-serif;
--font-num:"Pretendard Variable","JetBrains Mono",ui-monospace,monospace;
/* spacing */
--sp-1:4px; --sp-2:8px; --sp-3:12px; --sp-4:16px; --sp-5:24px; --sp-6:32px; --sp-7:48px; --sp-8:64px;
--radius:8px; --radius-sm:6px; --radius-lg:12px;
--maxw:1240px;
--shadow-sm:0 1px 2px rgba(28,42,42,.05);
--shadow-md:0 4px 14px rgba(28,42,42,.07);
--ease-out:cubic-bezier(.22,.61,.36,1);
--dur-breathe:3600ms;
}
*{margin:0;padding:0;box-sizing:border-box;}
html,body{height:100%;}
body{
font-family:var(--font-sans); background:var(--paper); color:var(--ink);
-webkit-font-smoothing:antialiased; text-rendering:optimizeLegibility;
letter-spacing:-0.01em; line-height:1.6;
}
.tab-num{font-variant-numeric:tabular-nums; letter-spacing:-0.01em;}
.kicker{
font-family:var(--font-num); font-size:12px; font-weight:600; letter-spacing:0.08em;
color:var(--accent); display:flex; align-items:center; gap:8px;
}
.kicker .dot{width:6px; height:6px; border-radius:50%; background:var(--accent-bright);}
/* ============ 공통 헤더 (다른 페이지와 동일) ============ */
.topbar{
height:56px; background:var(--surface); border-bottom:1px solid var(--hair);
display:flex; align-items:center; gap:var(--sp-7);
padding:0 var(--sp-6); position:sticky; top:0; z-index:30;
}
.brand{display:flex; align-items:center; gap:10px; flex:none;}
.brand .mark{display:flex; align-items:center; justify-content:center; width:26px; height:26px;}
.brand .mark svg{width:26px; height:26px;}
.brand .wm{font-size:17px; font-weight:700; letter-spacing:-0.02em; color:var(--ink);}
.brand .wm .v{color:var(--accent);}
.nav{display:flex; align-items:center; gap:2px; margin-left:var(--sp-2);}
.nav a{
font-size:14px; font-weight:500; color:var(--ink-3); text-decoration:none;
padding:7px 14px; border-radius:var(--radius-sm); transition:color .16s var(--ease-out);
}
.nav a:hover{color:var(--ink-2);}
.nav a.on{color:var(--ink); font-weight:600; background:var(--accent-tint);}
.topbar .spacer{flex:1;}
/* 라이브 표시(녹음·경과) — 헤더 우측, 조용하게 */
.livechip{
display:inline-flex; align-items:center; gap:8px; font-size:12.5px; font-weight:600;
color:var(--accent-deep); background:var(--accent-tint); padding:6px 12px; border-radius:100px;
font-variant-numeric:tabular-nums;
}
.livechip .rec{width:7px; height:7px; border-radius:50%; background:var(--accent); position:relative;}
.livechip .rec::after{content:""; position:absolute; inset:-4px; border-radius:50%;
background:var(--accent); opacity:.28; animation:livepulse var(--dur-breathe) var(--ease-out) infinite;}
@keyframes livepulse{0%,100%{transform:scale(1);opacity:.28;}50%{transform:scale(1.7);opacity:0;}}
.role{display:flex; align-items:center; gap:8px; font-size:13px; color:var(--ink-2); font-weight:500;}
.role .dot{width:7px; height:7px; border-radius:50%; background:var(--accent);}
.role .sep{width:1px; height:16px; background:var(--hair); margin:0 4px;}
.role .who{font-weight:600; color:var(--ink);}
.avatar-chip{
width:30px; height:30px; border-radius:50%; background:var(--accent-tint);
display:flex; align-items:center; justify-content:center;
font-size:12px; font-weight:700; color:var(--accent-deep); flex:none;
}
/* ============ 본문 래퍼 ============ */
.wrap{max-width:var(--maxw); margin:0 auto; padding:var(--sp-6) var(--sp-6) var(--sp-8);}
/* 페이지 헤드라인: 한 화면 한 목적 */
.head{margin-bottom:var(--sp-6); display:flex; align-items:flex-end; justify-content:space-between; gap:var(--sp-5); flex-wrap:wrap;}
.head .lt .kicker{margin-bottom:8px;}
.head .lt h1{font-size:26px; font-weight:700; letter-spacing:-0.02em; color:var(--ink); line-height:1.3;}
.head .lt h1 em{font-style:normal; color:var(--accent-deep);}
.head .lt .sub{font-size:14px; color:var(--ink-3); margin-top:5px;}
/* 회기 단계 트랙커 (가로, 헤드 우측) */
.phases{display:flex; align-items:center; gap:0; flex:none;}
.ph{display:flex; align-items:center; gap:9px; padding:0 2px;}
.ph .pdot{width:11px; height:11px; border-radius:50%; flex:none; position:relative;
background:var(--surface); border:2px solid var(--neutral-200);}
.ph.done .pdot{background:var(--accent-bright); border-color:var(--accent-bright);}
.ph.cur .pdot{border-color:var(--accent); background:var(--surface);}
.ph.cur .pdot::after{content:""; position:absolute; inset:2px; border-radius:50%; background:var(--accent);}
.ph .pmeta{display:flex; flex-direction:column; line-height:1.2;}
.ph .pmeta .pn{font-size:13px; font-weight:500; color:var(--ink-3);}
.ph.done .pmeta .pn{color:var(--ink-2);}
.ph.cur .pmeta .pn{color:var(--ink); font-weight:700;}
.ph .pmeta .pt{font-size:10.5px; color:var(--ink-3); font-family:var(--font-num); font-variant-numeric:tabular-nums; margin-top:1px;}
.ph.cur .pmeta .pt{color:var(--accent);}
.ph .link{width:30px; height:1px; background:var(--hair); margin:0 4px; align-self:center; margin-top:-12px;}
.ph .link.fill{background:var(--accent-bright);}
/* ============ 3-region 그리드 (밝은 톤) ============ */
.stage-grid{
display:grid; grid-template-columns:268px 1fr 296px; gap:var(--sp-5); align-items:start;
}
.panel{
background:var(--surface); border:1px solid var(--hair); border-radius:var(--radius-lg);
box-shadow:var(--shadow-sm);
}
.panel .ph-head{padding:var(--sp-5) var(--sp-5) var(--sp-4); border-bottom:1px solid var(--paper-2);}
.panel .ph-head .kicker{margin-bottom:0;}
/* ── LEFT: 회기 단계 세로 트랙 + 내담자 컨텍스트 ── */
.col-left{display:flex; flex-direction:column; gap:var(--sp-5);}
.track{padding:var(--sp-5);}
.track .kicker{margin-bottom:var(--sp-4);}
.vstep{display:grid; grid-template-columns:14px 1fr; column-gap:13px;}
.vstep .rail{display:flex; flex-direction:column; align-items:center;}
.vstep .node{width:13px; height:13px; border-radius:50%; flex:none; position:relative; z-index:1;
background:var(--surface); border:2px solid var(--neutral-200);}
.vstep .line{width:2px; flex:1; min-height:24px; background:var(--hair);}
.vstep.done .node{background:var(--accent-bright); border-color:var(--accent-bright);}
.vstep.done .line{background:var(--accent-bright);}
.vstep.cur .node{border-color:var(--accent);}
.vstep.cur .node::after{content:""; position:absolute; inset:2px; border-radius:50%; background:var(--accent);}
.vstep .body{padding-bottom:var(--sp-5);}
.vstep:last-child .body{padding-bottom:0;}
.vstep .sl{font-size:14.5px; font-weight:500; color:var(--ink-3); display:flex; align-items:baseline; justify-content:space-between; gap:8px;}
.vstep.done .sl{color:var(--ink-2);}
.vstep.cur .sl{color:var(--ink); font-weight:700;}
.vstep .sl .tt{font-size:11.5px; font-family:var(--font-num); font-variant-numeric:tabular-nums; color:var(--ink-3); font-weight:400;}
.vstep.cur .sl .tt{color:var(--accent); font-weight:600;}
.vstep .sd{font-size:12px; color:var(--ink-3); margin-top:3px; line-height:1.5;}
/* 내담자 컨텍스트 카드 */
.ctx{padding:var(--sp-5);}
.ctx .kicker{margin-bottom:var(--sp-4);}
.ctx .who{display:flex; align-items:center; gap:12px;}
.ctx .who .pf{
width:40px; height:40px; border-radius:50%; flex:none;
display:flex; align-items:center; justify-content:center;
font-size:15px; font-weight:700; background:var(--clay-tint); color:var(--clay-deep);
}
.ctx .who .nm{font-size:16px; font-weight:700; color:var(--ink);}
.ctx .who .mt{font-size:12.5px; color:var(--ink-3); margin-top:1px;}
.ctx .meta{margin-top:var(--sp-4); display:flex; flex-direction:column; gap:0;}
.ctx .mrow{display:flex; align-items:flex-start; gap:10px; padding:9px 0; border-top:1px solid var(--paper-2); font-size:13px;}
.ctx .mrow:first-child{border-top:none;}
.ctx .mrow .ml{font-size:11.5px; font-weight:600; color:var(--ink-3); width:52px; flex:none; padding-top:1px;}
.ctx .mrow .mv{color:var(--ink-2); line-height:1.55;}
.ctx .chips{display:flex; flex-wrap:wrap; gap:6px; margin-top:var(--sp-4);}
.ctx .chip{font-size:11.5px; font-weight:500; color:var(--ink-2); background:var(--paper-2); padding:4px 10px; border-radius:100px;}
.ctx .chip.clay{background:var(--clay-tint); color:var(--clay-deep);}
/* ── CENTER: 밝은 아바타 패널 + 자막 ── */
.col-center{display:flex; flex-direction:column; gap:var(--sp-5);}
.stage{
position:relative; overflow:hidden;
background:linear-gradient(180deg,#FFFFFF 0%,#FAFCFB 100%);
border:1px solid var(--hair); border-radius:var(--radius-lg); box-shadow:var(--shadow-sm);
padding:var(--sp-6) var(--sp-6) var(--sp-7);
display:flex; flex-direction:column; align-items:center;
}
.stage .toplabel{
align-self:flex-start; display:inline-flex; align-items:center; gap:8px;
font-size:11.5px; font-weight:600; letter-spacing:0.02em; color:var(--ink-3);
background:var(--paper-2); padding:5px 11px; border-radius:100px;
}
.stage .toplabel .gd{width:6px; height:6px; border-radius:50%; background:var(--clay);}
.stage .speaking{
align-self:flex-start; margin-top:var(--sp-4); display:inline-flex; align-items:center; gap:7px;
font-size:12px; font-weight:600; color:var(--clay-deep);
}
.stage .speaking .sd{width:7px; height:7px; border-radius:50%; background:var(--clay);}
/* 밝은 광배 + 흉상 */
.avatar-zone{position:relative; width:300px; height:300px; margin:var(--sp-3) 0 var(--sp-5); display:flex; align-items:center; justify-content:center;}
.aura{position:absolute; inset:0; border-radius:50%;
background:radial-gradient(circle at 50% 46%,
color-mix(in srgb,var(--clay) 16%,transparent) 0%,
color-mix(in srgb,var(--clay) 7%,transparent) 38%,
transparent 68%);
animation:breathe var(--dur-breathe) var(--ease-out) infinite;}
.aura.ring{
background:none; border:1px solid color-mix(in srgb,var(--clay) 22%,transparent);
inset:24px; animation-delay:200ms;}
@keyframes breathe{0%,100%{transform:scale(1);opacity:.9;}50%{transform:scale(1.05);opacity:1;}}
.bust{position:relative; width:188px; height:188px; z-index:1;}
.bust svg{display:block; width:188px; height:188px;}
.stage .meta-line{font-size:15px; font-weight:600; color:var(--ink);}
.stage .meta-line .sub{font-weight:400; color:var(--ink-3);}
.stage .now-line{font-size:13.5px; color:var(--ink-2); margin-top:6px;}
/* 실시간 자막 (대본 스타일) */
.transcript{
background:var(--surface); border:1px solid var(--hair); border-radius:var(--radius-lg);
box-shadow:var(--shadow-sm); padding:var(--sp-5);
}
.transcript .th{display:flex; align-items:center; justify-content:space-between; margin-bottom:var(--sp-4);}
.transcript .th .kicker{margin-bottom:0;}
.transcript .th .live{font-size:11.5px; color:var(--ink-3); display:inline-flex; align-items:center; gap:6px; font-family:var(--font-num); font-variant-numeric:tabular-nums;}
.transcript .th .live .ld{width:6px; height:6px; border-radius:50%; background:var(--pos-solid);}
.utt{display:flex; flex-direction:column; gap:4px; padding:var(--sp-3) 0;}
.utt .ul{display:flex; align-items:baseline; gap:8px;}
.utt .ul .spk{font-size:12px; font-weight:600;}
.utt .ul .tc{font-size:11px; color:var(--ink-3); font-family:var(--font-num); font-variant-numeric:tabular-nums;}
.utt .line{font-size:14.5px; line-height:1.65; padding:9px 13px; border-radius:var(--radius); max-width:88%;}
.utt.client .ul .spk{color:var(--clay-deep);}
.utt.client .line{background:var(--clay-tint); color:var(--ink);}
.utt.learner{align-items:flex-end;}
.utt.learner .ul{flex-direction:row-reverse;}
.utt.learner .ul .spk{color:var(--accent-deep);}
.utt.learner .line{background:var(--accent-tint); color:var(--ink);}
.utt.partial .line{color:var(--ink-3); font-style:normal;}
.utt.partial .line .cur{display:inline-block; width:2px; height:1em; background:var(--ink-3); margin-left:2px; vertical-align:-2px; animation:caret 1s steps(1) infinite;}
@keyframes caret{50%{opacity:0;}}
/* ── RIGHT: 평가 신호 + 내담자 상태 ── */
.col-right{display:flex; flex-direction:column; gap:var(--sp-5);}
.signal{padding:var(--sp-5);}
.signal .kicker{margin-bottom:var(--sp-4);}
.signal .live-one{display:flex; align-items:center; gap:10px; padding:11px 13px; background:var(--paper-2); border-radius:var(--radius);}
.signal .live-one .sd{width:10px; height:10px; border-radius:50%; flex:none; background:var(--pos-solid);}
.signal .live-one .st{font-size:14px; font-weight:600; color:var(--ink);}
.signal .live-one .sm{font-size:11.5px; color:var(--ink-3); margin-left:auto; font-family:var(--font-num);}
.signal .seq{display:flex; align-items:center; gap:7px; margin-top:var(--sp-4);}
.signal .seq .sl{font-size:11px; color:var(--ink-3); font-family:var(--font-num); letter-spacing:0.04em;}
.signal .seq .dots{display:flex; align-items:center; gap:6px;}
.signal .seq .dots i{width:7px; height:7px; border-radius:50%; background:var(--neutral-sig);}
.signal .seq .dots i.pos{background:var(--pos-solid);}
.signal .seq .dots i.warn{background:var(--warn-solid);}
.signal .seq .dots i.now{box-shadow:0 0 0 3px var(--accent-tint); background:var(--pos-solid);}
.signal .defer{font-size:12px; color:var(--ink-3); line-height:1.55; margin-top:var(--sp-4); padding-top:var(--sp-4); border-top:1px solid var(--paper-2);}
.signal .defer b{font-weight:600; color:var(--ink-2);}
/* 내담자 상태 미터 */
.meters{padding:var(--sp-5);}
.meters .kicker{margin-bottom:var(--sp-4);}
.meter{margin-top:var(--sp-4);}
.meter:first-of-type{margin-top:0;}
.meter .mt{display:flex; align-items:baseline; justify-content:space-between; margin-bottom:7px;}
.meter .mt .ml{font-size:13.5px; color:var(--ink); font-weight:500;}
.meter .mt .mv{font-size:12px; font-weight:600; font-family:var(--font-num);}
.meter .mt .mv.clay{color:var(--clay-deep);}
.meter .mt .mv.accent{color:var(--accent-deep);}
.meter .gauge{height:4px; background:var(--paper-2); border-radius:2px; overflow:hidden;}
.meter .gauge .fill{height:100%; border-radius:2px; transition:width 2s var(--ease-out);}
.meter .gauge .fill.clay{background:var(--clay);}
.meter .gauge .fill.accent{background:var(--accent-bright);}
.meters .note{font-size:11.5px; color:var(--ink-3); line-height:1.55; margin-top:var(--sp-4); padding-top:var(--sp-4); border-top:1px solid var(--paper-2);}
/* 안전 점검 콜아웃 (warn, 빨강 아님) */
.safety{display:flex; gap:10px; padding:var(--sp-4); background:var(--warn-tint); border-radius:var(--radius);}
.safety .ico{flex:none; width:17px; height:17px; margin-top:1px;}
.safety .ico svg{width:17px; height:17px; stroke:var(--warn-solid); fill:none;}
.safety .sc{font-size:12.5px; line-height:1.55; color:var(--warn-text);}
.safety .sc b{font-weight:600;}
/* ============ 하단 컨트롤 바 ============ */
.controlbar{
position:sticky; bottom:0; z-index:20; margin-top:var(--sp-6);
background:var(--surface); border:1px solid var(--hair); border-radius:var(--radius-lg);
box-shadow:var(--shadow-md); padding:var(--sp-4) var(--sp-5);
display:flex; align-items:center; gap:var(--sp-5);
}
/* 마이크 (주 컨트롤, 음성 호흡 펄스) */
.mic-block{display:flex; align-items:center; gap:13px; flex:none;}
.mic{
width:52px; height:52px; border-radius:50%; flex:none; border:none; cursor:pointer; position:relative;
background:var(--accent); display:flex; align-items:center; justify-content:center;
}
.mic::after{content:""; position:absolute; inset:0; border-radius:50%; border:2px solid var(--accent);
opacity:.35; animation:micbreathe 1.6s var(--ease-out) infinite;}
@keyframes micbreathe{0%,100%{transform:scale(1);opacity:.35;}50%{transform:scale(1.22);opacity:0;}}
.mic svg{width:22px; height:22px; stroke:var(--text-on-accent); fill:none; z-index:1;}
.mic-block .ms{display:flex; flex-direction:column; line-height:1.25;}
.mic-block .ms .l{font-size:13.5px; font-weight:600; color:var(--ink);}
.mic-block .ms .h{font-size:11.5px; color:var(--ink-3);}
.cb-sep{width:1px; height:34px; background:var(--hair); flex:none;}
/* 피드백 모드 segmented */
.seg-block{display:flex; flex-direction:column; gap:5px; flex:none;}
.seg-block .sgl{font-size:10.5px; font-weight:600; letter-spacing:0.06em; color:var(--ink-3); font-family:var(--font-num);}
.segmented{display:inline-flex; background:var(--paper-2); border-radius:var(--radius); padding:3px; gap:2px;}
.segmented button{
font-family:var(--font-sans); font-size:13px; font-weight:500; color:var(--ink-2);
background:transparent; border:none; padding:7px 14px; border-radius:6px; cursor:pointer;
transition:all .14s var(--ease-out);
}
.segmented button:hover{color:var(--ink);}
.segmented button.on{background:var(--surface); color:var(--accent-deep); font-weight:600; box-shadow:var(--shadow-sm);}
.cb-spacer{flex:1;}
/* 일시정지 + 종료 */
.cb-actions{display:flex; align-items:center; gap:10px; flex:none;}
.btn-ghost{
font-family:var(--font-sans); font-size:14px; font-weight:600; color:var(--ink-2);
background:var(--surface); border:1px solid var(--hair); border-radius:var(--radius);
padding:10px 16px; cursor:pointer; display:inline-flex; align-items:center; gap:8px;
transition:all .14s var(--ease-out);
}
.btn-ghost:hover{background:var(--paper-2); color:var(--ink);}
.btn-ghost svg{width:15px; height:15px; stroke:var(--ink-2); fill:none;}
/* 종료 = 유일한 진한 경고색 영역 */
.btn-end{
font-family:var(--font-sans); font-size:14px; font-weight:600; color:var(--crit-text);
background:var(--surface); border:1px solid var(--crit-tint); border-radius:var(--radius);
padding:10px 16px; cursor:pointer; display:inline-flex; align-items:center; gap:8px;
transition:all .14s var(--ease-out);
}
.btn-end:hover{background:var(--crit-tint);}
.btn-end svg{width:15px; height:15px; stroke:var(--crit-text); fill:none;}
@media (max-width:1180px){
.stage-grid{grid-template-columns:248px 1fr;}
.col-right{grid-column:1 / -1; flex-direction:row; flex-wrap:wrap;}
.col-right > *{flex:1; min-width:280px;}
}
@media (max-width:880px){
.stage-grid{grid-template-columns:1fr;}
.col-right{flex-direction:column;}
.nav{display:none;}
.head{flex-direction:column; align-items:flex-start;}
.phases{flex-wrap:wrap; gap:4px;}
.controlbar{flex-wrap:wrap; gap:var(--sp-4);}
.cb-spacer{display:none;}
}
@media (prefers-reduced-motion: reduce){
*,*::before,*::after{animation-duration:.01ms!important; transition-duration:.01ms!important;}
}
</style>
</head>
<body>
<!-- ============ 공통 헤더 (다른 페이지와 동일) ============ -->
<header class="topbar">
<div class="brand">
<span class="mark">
<svg viewBox="0 0 26 26" fill="none" aria-hidden="true">
<circle cx="13" cy="13" r="11" stroke="#3E7A6E" stroke-width="2"/>
<path d="M8 14.5c1.4 1.7 3 2.5 5 2.5s3.6-.8 5-2.5" stroke="#3E7A6E" stroke-width="2" stroke-linecap="round"/>
<circle cx="13" cy="9" r="1.6" fill="#B0735C"/>
</svg>
</span>
<span class="wm"><span class="v">Vignette</span></span>
</div>
<nav class="nav">
<a href="#"></a>
<a href="#" class="on">연습실</a>
<a href="#">내 회기</a>
<a href="#">성장 기록</a>
</nav>
<span class="spacer"></span>
<span class="livechip"><span class="rec"></span>연습 진행 중 · <span class="tab-num">14:32</span></span>
<div class="role">
<span class="dot"></span>학습자
<span class="sep"></span>
<span class="who">김도윤</span>
</div>
<div class="avatar-chip"></div>
</header>
<main class="wrap">
<!-- 페이지 헤드라인 + 회기 단계 트랙커 -->
<div class="head">
<div class="lt">
<div class="kicker"><span class="dot"></span>상담 연습 · 우울 호소 청소년 · 2주차</div>
<h1>지금은 <em>탐색 단계</em>입니다.</h1>
<div class="sub">서연의 말에 귀를 기울이세요. 정밀 평가는 회기가 끝난 뒤 리뷰에서 함께 봅니다.</div>
</div>
<div class="phases" aria-label="회기 진행 단계">
<div class="ph done">
<span class="pdot"></span>
<span class="pmeta"><span class="pn">라포 형성</span><span class="pt">09:12</span></span>
</div>
<span class="link fill"></span>
<div class="ph cur">
<span class="pdot"></span>
<span class="pmeta"><span class="pn">탐색</span><span class="pt">진행 중</span></span>
</div>
<span class="link"></span>
<div class="ph">
<span class="pdot"></span>
<span class="pmeta"><span class="pn">개입</span><span class="pt">예정</span></span>
</div>
<span class="link"></span>
<div class="ph">
<span class="pdot"></span>
<span class="pmeta"><span class="pn">정리</span><span class="pt">예정</span></span>
</div>
</div>
</div>
<!-- ============ 3-region 그리드 ============ -->
<div class="stage-grid">
<!-- ── LEFT: 세로 단계 트랙 + 내담자 컨텍스트 ── -->
<div class="col-left">
<section class="panel track">
<div class="kicker"><span class="dot"></span>회기 진행</div>
<div class="vstep done">
<div class="rail"><span class="node"></span><span class="line"></span></div>
<div class="body">
<div class="sl">라포 형성 <span class="tt">09:12</span></div>
<div class="sd">첫인사와 안전감 형성을 마쳤어요</div>
</div>
</div>
<div class="vstep cur">
<div class="rail"><span class="node"></span><span class="line"></span></div>
<div class="body">
<div class="sl">탐색 <span class="tt">진행 중</span></div>
<div class="sd">호소 문제와 일상을 함께 살펴보는 중</div>
</div>
</div>
<div class="vstep">
<div class="rail"><span class="node"></span><span class="line"></span></div>
<div class="body">
<div class="sl">개입 <span class="tt">예정</span></div>
<div class="sd">감정·생각을 다루는 기법 적용</div>
</div>
</div>
<div class="vstep">
<div class="rail"><span class="node"></span></div>
<div class="body">
<div class="sl">정리 <span class="tt">예정</span></div>
<div class="sd">오늘의 대화 정리와 다음 약속</div>
</div>
</div>
</section>
<section class="panel ctx">
<div class="kicker"><span class="dot"></span>내담자 컨텍스트</div>
<div class="who">
<span class="pf"></span>
<span>
<span class="nm">서연</span>
<div class="mt">17세 · 고2 · 교육용 가상 내담자</div>
</span>
</div>
<div class="meta">
<div class="mrow"><span class="ml">호소</span><span class="mv">2주째 지속되는 우울감과 무기력, 등교 거부</span></div>
<div class="mrow"><span class="ml">최근</span><span class="mv">성적 하락과 또래 관계 위축, 자퇴를 입에 올림</span></div>
<div class="mrow"><span class="ml">태도</span><span class="mv">자기개방에 소극적·방어적. 라포가 쌓이면 점차 완화</span></div>
</div>
<div class="chips">
<span class="chip">teen</span>
<span class="chip clay">방어적</span>
<span class="chip">우울(저각성)</span>
<span class="chip">난이도 중상</span>
</div>
</section>
</div>
<!-- ── CENTER: 밝은 아바타 패널 + 자막 ── -->
<div class="col-center">
<section class="stage">
<span class="toplabel"><span class="gd"></span>교육용 가상 내담자</span>
<div class="avatar-zone">
<div class="aura"></div>
<div class="aura ring"></div>
<div class="bust">
<!-- 반구상 흉상: 코·주름·모공 없음. 눈·눈썹·입꼬리·어깨가 정서 채널. (양식화 35~40%) -->
<svg viewBox="0 0 188 188" aria-label="가상 내담자 서연 (양식화 흉상)">
<!-- 어깨/실루엣 (후디, 약간 안으로 — 우울 저각성) -->
<path d="M30 188 C30 152 52 138 94 138 C136 138 158 152 158 188 Z" fill="#E7D9CE"/>
<path d="M30 188 C30 156 52 142 94 142 C136 142 158 156 158 188" fill="none" stroke="#D9C7B8" stroke-width="1.5"/>
<!---->
<path d="M83 128 C83 140 86 146 94 146 C102 146 105 140 105 128 Z" fill="#E3C6A6"/>
<!-- 얼굴 (좁은 턱, 둥근 — teen) -->
<path d="M64 72 C64 50 76 42 94 42 C112 42 124 50 124 72 L124 92 C124 116 112 126 94 126 C76 126 64 116 64 92 Z" fill="#EACBAA"/>
<!-- 머리카락 (long-straight, 진한 갈) -->
<path d="M62 78 C60 50 72 36 94 36 C116 36 128 50 126 78 C122 60 116 54 110 52 C112 62 112 70 110 78 L110 60 C104 56 100 55 94 55 C88 55 84 56 78 60 L78 78 C76 70 76 62 78 52 C72 54 66 60 62 78 Z" fill="#2B2723"/>
<!-- 옆머리 흐름 -->
<path d="M64 76 C62 100 66 116 70 124 C66 110 66 92 68 80 Z" fill="#332E29"/>
<path d="M124 76 C126 100 122 116 118 124 C122 110 122 92 120 80 Z" fill="#332E29"/>
<!-- 눈썹 (수평·미세 하향 — 우울) -->
<path d="M74 80 q9 -2 17 1" stroke="#6E5C4C" stroke-width="2.4" fill="none" stroke-linecap="round"/>
<path d="M97 81 q9 -3 17 -1" stroke="#6E5C4C" stroke-width="2.4" fill="none" stroke-linecap="round"/>
<!-- 눈 (눈꺼풀 살짝 하강, 시선 아래 — 우울 저각성) -->
<path d="M76 90 q7 4 15 0" stroke="#3A2E26" stroke-width="2.6" fill="none" stroke-linecap="round"/>
<path d="M97 90 q7 4 15 0" stroke="#3A2E26" stroke-width="2.6" fill="none" stroke-linecap="round"/>
<circle cx="83.5" cy="92" r="1.7" fill="#3A2E26"/>
<circle cx="104.5" cy="92" r="1.7" fill="#3A2E26"/>
<!-- 입 (닫힘, 수평~미세 하향) -->
<path d="M85 110 q9 3 18 0" stroke="#B07F6A" stroke-width="2.6" fill="none" stroke-linecap="round"/>
</svg>
</div>
</div>
<div class="meta-line">서연 <span class="sub">· 17세 · 고2</span></div>
<div class="now-line">지금: 잠시 시선을 내리고 말을 고르는 중</div>
<div class="speaking"><span class="sd"></span>서연이 말하는 중</div>
</section>
<section class="transcript">
<div class="th">
<div class="kicker"><span class="dot"></span>실시간 자막</div>
<span class="live"><span class="ld"></span>받아쓰는 중</span>
</div>
<div class="utt client">
<div class="ul"><span class="spk">서연</span><span class="tc">14:30</span></div>
<div class="line">요즘은… 그냥 아침에 학교 가는 게 너무 버거워요. 일어나는 것부터가 힘들고.</div>
</div>
<div class="utt learner">
<div class="ul"><span class="spk">나 (학습자)</span><span class="tc">14:31</span></div>
<div class="line">아침에 일어나는 것조차 버겁게 느껴지는구나. 그 마음을 조금 더 들려줄 수 있을까?</div>
</div>
<div class="utt client">
<div class="ul"><span class="spk">서연</span><span class="tc">14:31</span></div>
<div class="line">사실… 그냥 자퇴하면 안 되나 싶기도 해요. 가도 어차피 멍하니 앉아만 있거든요.</div>
</div>
<div class="utt learner">
<div class="ul"><span class="spk">나 (학습자)</span><span class="tc">14:32</span></div>
<div class="line">학교에 있어도 마음이 거기 없는 것 같았겠다. 자퇴를 떠올릴 만큼 지쳐 있었구나.</div>
</div>
<div class="utt client partial">
<div class="ul"><span class="spk">서연</span><span class="tc">14:32</span></div>
<div class="line">네… 근데 막상 그만두면 또 뭘 해야 할지<span class="cur"></span></div>
</div>
</section>
</div>
<!-- ── RIGHT: 평가 신호 + 내담자 상태 ── -->
<div class="col-right">
<section class="panel signal">
<div class="kicker"><span class="dot"></span>라이브 신호</div>
<div class="live-one">
<span class="sd"></span>
<span class="st">공감적 반영</span>
<span class="sm">방금</span>
</div>
<div class="seq">
<span class="sl">최근 흐름</span>
<span class="dots">
<i></i><i class="pos"></i><i class="warn"></i><i class="pos"></i><i class="pos"></i><i class="now"></i>
</span>
</div>
<div class="defer">실시간엔 <b>톤 신호 하나</b>만 비춥니다. 점수·정밀 평가는 회기가 끝난 뒤 리뷰에서 함께 봐요.</div>
</section>
<section class="panel meters">
<div class="kicker"><span class="dot"></span>내담자 상태</div>
<div class="meter">
<div class="mt"><span class="ml">저항감</span><span class="mv clay">완화되는 중</span></div>
<div class="gauge"><span class="fill clay" style="width:46%"></span></div>
</div>
<div class="meter">
<div class="mt"><span class="ml">불안 · 위축</span><span class="mv clay">중간</span></div>
<div class="gauge"><span class="fill clay" style="width:58%"></span></div>
</div>
<div class="meter">
<div class="mt"><span class="ml">마음 열림 (라포)</span><span class="mv accent">조금씩 ↑</span></div>
<div class="gauge"><span class="fill accent" style="width:42%"></span></div>
</div>
<div class="note">반응은 천천히 움직입니다. 서연의 표정과 어깨에서 변화를 함께 읽어 보세요.</div>
</section>
<section class="safety">
<span class="ico"><svg viewBox="0 0 24 24" stroke-width="1.9" stroke-linecap="round" stroke-linejoin="round"><path d="M12 9v4M12 17h.01M10.3 3.9 1.8 18a2 2 0 0 0 1.7 3h17a2 2 0 0 0 1.7-3L13.7 3.9a2 2 0 0 0-3.4 0z"/></svg></span>
<span class="sc"><b>안전 점검</b> · 방금 '자퇴' 언급이 있었어요. 위축의 신호일 수 있으니 머무르며 더 들어 보세요.</span>
</section>
</div>
</div>
<!-- ============ 하단 컨트롤 바 ============ -->
<div class="controlbar">
<div class="mic-block">
<button class="mic" aria-label="마이크">
<svg viewBox="0 0 24 24" stroke-width="2"><rect x="9" y="3" width="6" height="11" rx="3"/><path d="M5 11a7 7 0 0 0 14 0"/><line x1="12" y1="18" x2="12" y2="21"/></svg>
</button>
<span class="ms"><span class="l">듣고 있어요</span><span class="h">눌러서 말하기 · Space</span></span>
</div>
<span class="cb-sep"></span>
<div class="seg-block">
<span class="sgl">피드백 모드</span>
<div class="segmented" role="group" aria-label="피드백 모드">
<button>몰입</button>
<button class="on">은은한 신호</button>
<button>코칭</button>
</div>
</div>
<span class="cb-spacer"></span>
<div class="cb-actions">
<button class="btn-ghost">
<svg viewBox="0 0 24 24" stroke-width="2" stroke-linecap="round"><line x1="9" y1="4" x2="9" y2="20"/><line x1="15" y1="4" x2="15" y2="20"/></svg>
일시정지
</button>
<button class="btn-end">
<svg viewBox="0 0 24 24" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><rect x="5" y="5" width="14" height="14" rx="2"/></svg>
회기 종료
</button>
</div>
</div>
</main>
</body>
</html>