feat(docs): 전체 페이지 레이아웃 시안 추가
- login/learner-home/session-review/professor/admin/settings - session-v2(밝은 에디토리얼 톤으로 재제작, 기존 어두운 stage 대체) - 전부 동일 디자인 토큰(세이지틸+테라코타), 윤찬 철칙 준수
This commit is contained in:
parent
204726f707
commit
d5b86c5f89
8 changed files with 3723 additions and 486 deletions
563
docs/mockups/admin.html
Normal file
563
docs/mockups/admin.html
Normal file
|
|
@ -0,0 +1,563 @@
|
|||
<!DOCTYPE html>
|
||||
<html lang="ko">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Vignette — 관리자 콘솔</title>
|
||||
<link rel="stylesheet" href="https://cdn.jsdelivr.net/gh/orioncactus/pretendard/dist/web/variable/pretendardvariable.min.css">
|
||||
<style>
|
||||
/* =====================================================================
|
||||
Vignette — 관리자(Admin) 콘솔 와이어
|
||||
토큰: DESIGN_CONCEPT.md §3 그대로. 역할 accent = 슬레이트(§6.2 admin).
|
||||
철칙: 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:#5B5F6B; --accent-deep:#494C57; --accent-tint:#EEEFF1; --accent-bright:#7D818E;
|
||||
/* 보조 온기 */
|
||||
--clay:#B0735C; --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(91,95,107,.40);
|
||||
/* 폰트 */
|
||||
--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;
|
||||
--radius:8px; --radius-sm:6px; --radius-lg:12px;
|
||||
--maxw:1200px;
|
||||
--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);
|
||||
}
|
||||
*{margin:0;padding:0;box-sizing:border-box;}
|
||||
html{scroll-behavior:smooth;}
|
||||
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;}
|
||||
|
||||
/* ============ 공통 헤더 (톱바) ============ */
|
||||
.topbar{
|
||||
position:sticky; top:0; z-index:20; height:56px;
|
||||
background:var(--surface); border-bottom:1px solid var(--hair);
|
||||
display:flex; align-items:center; gap:var(--sp-6); padding:0 var(--sp-6);
|
||||
}
|
||||
.brand{display:flex; align-items:center; gap:10px;}
|
||||
.brand .mark{width:22px; height:22px; flex:none;}
|
||||
.brand .wm{font-size:17px; font-weight:700; letter-spacing:-0.02em; color:var(--ink);}
|
||||
.brand .role{
|
||||
margin-left:6px; font-family:var(--font-num); font-size:11px; font-weight:600;
|
||||
letter-spacing:0.08em; text-transform:uppercase; color:var(--accent);
|
||||
background:var(--accent-tint); padding:4px 9px; border-radius:5px;
|
||||
}
|
||||
.nav{display:flex; align-items:center; gap:2px; margin-left:var(--sp-4);}
|
||||
.nav a{
|
||||
font-size:14px; font-weight:500; color:var(--ink-3); text-decoration:none;
|
||||
padding:8px 12px; border-radius:6px;
|
||||
}
|
||||
.nav a.on{color:var(--ink); font-weight:600; background:var(--accent-tint);}
|
||||
.nav a:hover{color:var(--ink-2);}
|
||||
.topbar .right{margin-left:auto; display:flex; align-items:center; gap:var(--sp-5);}
|
||||
.envtag{font-family:var(--font-num); font-size:12px; color:var(--ink-3); display:flex; align-items:center; gap:7px;}
|
||||
.envtag .d{width:6px; height:6px; border-radius:50%; background:var(--pos-solid);}
|
||||
.who{display:flex; align-items:center; gap:9px;}
|
||||
.who .av{width:30px; height:30px; border-radius:50%; background:var(--accent); color:var(--text-on-accent);
|
||||
display:flex; align-items:center; justify-content:center; font-size:12px; font-weight:600;}
|
||||
.who .nm{font-size:13px; font-weight:600; color:var(--ink); line-height:1.2;}
|
||||
.who .sub{font-size:11px; color:var(--ink-3);}
|
||||
|
||||
/* ============ 페이지 ============ */
|
||||
.page{max-width:var(--maxw); margin:0 auto; padding:var(--sp-7) var(--sp-6) var(--sp-7);}
|
||||
.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; margin-bottom:var(--sp-3);
|
||||
}
|
||||
.kicker .dot{width:6px; height:6px; border-radius:50%; background:var(--accent-bright);}
|
||||
|
||||
/* 페이지 헤드 */
|
||||
.pagehead{display:flex; align-items:flex-end; justify-content:space-between; gap:var(--sp-5); margin-bottom:var(--sp-3);}
|
||||
.pagehead h1{font-size:30px; font-weight:700; letter-spacing:-0.02em; color:var(--ink); line-height:1.25;}
|
||||
.pagehead .lead{font-size:16px; color:var(--ink-2); margin-top:6px; max-width:600px;}
|
||||
.pagehead .when{font-family:var(--font-num); font-size:13px; color:var(--ink-3); white-space:nowrap; text-align:right;}
|
||||
.pagehead .when b{display:block; color:var(--ink-2); font-weight:600;}
|
||||
|
||||
/* 섹션 위계 */
|
||||
.section{margin-top:var(--sp-7);}
|
||||
.sechead{display:flex; align-items:baseline; justify-content:space-between; gap:var(--sp-4); margin-bottom:var(--sp-5);}
|
||||
.sechead h2{font-size:20px; font-weight:600; letter-spacing:-0.01em; color:var(--ink);}
|
||||
.sechead .meta{font-size:13px; color:var(--ink-3);}
|
||||
.sechead .link{font-size:13px; font-weight:500; color:var(--accent); text-decoration:none; display:inline-flex; align-items:center; gap:6px;}
|
||||
.sechead .link svg{width:14px; height:14px; stroke:var(--accent);}
|
||||
|
||||
/* ============ 1. 시스템 현황 ============ */
|
||||
/* 한 줄 상태 요약 (큰 문장 하나 — 에디토리얼) */
|
||||
.statusline{
|
||||
display:flex; align-items:center; gap:14px;
|
||||
padding:var(--sp-5) var(--sp-6); background:var(--surface);
|
||||
border:1px solid var(--hair); border-radius:var(--radius-lg);
|
||||
}
|
||||
.statusline .pulse{width:11px; height:11px; border-radius:50%; background:var(--pos-solid); flex:none;
|
||||
box-shadow:0 0 0 0 rgba(59,140,94,.4); animation:pulse 3.2s ease-in-out infinite;}
|
||||
@keyframes pulse{0%,100%{box-shadow:0 0 0 0 rgba(59,140,94,.35)}50%{box-shadow:0 0 0 8px rgba(59,140,94,0)}}
|
||||
.statusline .msg{font-size:18px; font-weight:500; color:var(--ink); line-height:1.5;}
|
||||
.statusline .msg b{font-weight:700;}
|
||||
.statusline .ts{margin-left:auto; font-family:var(--font-num); font-size:12px; color:var(--ink-3); white-space:nowrap;}
|
||||
|
||||
/* 핵심 지표 인라인 행 (카드덤프 아님 — 헤어라인 구분, 숫자 위계) */
|
||||
.kpis{
|
||||
display:grid; grid-template-columns:repeat(4,1fr); margin-top:var(--sp-5);
|
||||
background:var(--surface); border:1px solid var(--hair); border-radius:var(--radius-lg);
|
||||
overflow:hidden;
|
||||
}
|
||||
.kpi{padding:var(--sp-5) var(--sp-6); }
|
||||
.kpi + .kpi{border-left:1px solid var(--hair);} /* 셀 divider — 강조선 아님, 칼럼 구분 헤어라인 */
|
||||
.kpi .l{font-size:13px; color:var(--ink-3); font-weight:500;}
|
||||
.kpi .n{font-size:34px; font-weight:700; color:var(--ink); letter-spacing:-0.02em; margin-top:8px; line-height:1;}
|
||||
.kpi .n .u{font-size:15px; font-weight:500; color:var(--ink-3); margin-left:4px; letter-spacing:0;}
|
||||
.kpi .d{font-size:12px; color:var(--ink-3); margin-top:9px; display:flex; align-items:center; gap:6px;}
|
||||
.kpi .d .up{color:var(--pos-text); font-weight:600;}
|
||||
.kpi .d .dn{color:var(--info-text); font-weight:600;}
|
||||
|
||||
/* 헬스 라인 (엔진/음성/DB — 절제된 상태 행) */
|
||||
.health{margin-top:var(--sp-5); background:var(--surface); border:1px solid var(--hair); border-radius:var(--radius-lg);}
|
||||
.hrow{display:grid; grid-template-columns:200px 1fr auto auto; align-items:center;
|
||||
gap:var(--sp-4); padding:14px var(--sp-6);}
|
||||
.hrow + .hrow{border-top:1px solid var(--hair);}
|
||||
.hrow .svc{display:flex; align-items:center; gap:11px;}
|
||||
.hrow .svc .d{width:8px; height:8px; border-radius:50%; flex:none;}
|
||||
.hrow .svc .d.ok{background:var(--pos-solid);}
|
||||
.hrow .svc .d.warn{background:var(--warn-solid);}
|
||||
.hrow .svc .d.crit{background:var(--crit-solid);}
|
||||
.hrow .svc .nm{font-size:15px; font-weight:600; color:var(--ink);}
|
||||
.hrow .svc .sub{font-size:12px; color:var(--ink-3); display:block; font-weight:400;}
|
||||
.hrow .gauge{height:5px; background:var(--paper-2); border-radius:3px; overflow:hidden; max-width:280px;}
|
||||
.hrow .gauge .fill{height:100%; border-radius:3px;}
|
||||
.hrow .gauge .fill.ok{background:var(--accent-bright);}
|
||||
.hrow .gauge .fill.warn{background:var(--warn-solid);}
|
||||
.hrow .num{font-family:var(--font-num); font-size:14px; font-weight:600; color:var(--ink-2); text-align:right; min-width:74px;}
|
||||
.hrow .stat{font-size:12px; font-weight:600; padding:3px 10px; border-radius:5px; white-space:nowrap;}
|
||||
.hrow .stat.ok{background:var(--pos-tint); color:var(--pos-text);}
|
||||
.hrow .stat.warn{background:var(--warn-tint); color:var(--warn-text);}
|
||||
.hrow .stat.crit{background:var(--crit-tint); color:var(--crit-text);}
|
||||
|
||||
/* ============ 2. 수집 현황 (분포) ============ */
|
||||
.collect{display:grid; grid-template-columns:1.4fr 1fr; gap:var(--sp-6);}
|
||||
.panel{background:var(--surface); border:1px solid var(--hair); border-radius:var(--radius-lg); padding:var(--sp-6);}
|
||||
.panel .ph{font-size:16px; font-weight:600; color:var(--ink); margin-bottom:var(--sp-2);}
|
||||
.panel .psub{font-size:13px; color:var(--ink-3); margin-bottom:var(--sp-5);}
|
||||
|
||||
/* 진행 세션/누적 분포 — 가로 게이지 목록 (카드 격자 회피) */
|
||||
.distrib{display:flex; flex-direction:column; gap:var(--sp-5);}
|
||||
.dist{display:grid; grid-template-columns:130px 1fr 56px; align-items:center; gap:var(--sp-4);}
|
||||
.dist .dl{font-size:14px; color:var(--ink-2); font-weight:500;}
|
||||
.dist .db{height:8px; background:var(--paper-2); border-radius:4px; overflow:hidden;}
|
||||
.dist .db .f{height:100%; border-radius:4px; background:var(--accent-bright);}
|
||||
.dist .db .f.clay{background:var(--clay);}
|
||||
.dist .db .f.warn{background:var(--warn-solid);}
|
||||
.dist .dv{font-family:var(--font-num); font-size:14px; font-weight:600; color:var(--ink); text-align:right;}
|
||||
|
||||
/* 역할 수집 요약 — 작은 행 목록 */
|
||||
.rolelist{display:flex; flex-direction:column;}
|
||||
.rr{display:flex; align-items:center; justify-content:space-between; padding:14px 0;}
|
||||
.rr + .rr{border-top:1px solid var(--paper-2);}
|
||||
.rr .rl{display:flex; align-items:center; gap:11px;}
|
||||
.rr .rl .rd{width:9px; height:9px; border-radius:2px; flex:none;}
|
||||
.rr .rl .nm{font-size:14px; color:var(--ink); font-weight:500;}
|
||||
.rr .rl .nm .sub{display:block; font-size:12px; color:var(--ink-3); font-weight:400;}
|
||||
.rr .rv{font-family:var(--font-num); font-size:18px; font-weight:700; color:var(--ink);}
|
||||
.rr .rv .delta{font-size:12px; font-weight:600; color:var(--pos-text); margin-left:8px;}
|
||||
|
||||
/* ============ 3. 감사 로그 (교수자 활동) ============ */
|
||||
.audit{background:var(--surface); border:1px solid var(--hair); border-radius:var(--radius-lg); overflow:hidden;}
|
||||
.audit .toolbar{display:flex; align-items:center; gap:var(--sp-3); padding:var(--sp-4) var(--sp-5);
|
||||
border-bottom:1px solid var(--hair);}
|
||||
.audit .toolbar .search{flex:1; max-width:320px; display:flex; align-items:center; gap:9px;
|
||||
background:var(--paper-2); border:1px solid var(--hair); border-radius:var(--radius-sm); padding:8px 12px;}
|
||||
.audit .toolbar .search svg{width:15px; height:15px; stroke:var(--ink-3); flex:none;}
|
||||
.audit .toolbar .search input{border:none; background:none; outline:none; font-family:var(--font-sans);
|
||||
font-size:14px; color:var(--ink); width:100%;}
|
||||
.audit .toolbar .search input::placeholder{color:var(--ink-3);}
|
||||
.chip{font-size:13px; font-weight:500; color:var(--ink-2); padding:7px 13px; border-radius:6px;
|
||||
border:1px solid var(--hair); background:var(--surface); cursor:pointer; white-space:nowrap;}
|
||||
.chip.on{background:var(--accent-tint); color:var(--accent-deep); border-color:transparent; font-weight:600;}
|
||||
.audit .spacer{flex:1;}
|
||||
|
||||
table{width:100%; border-collapse:collapse;}
|
||||
thead th{
|
||||
font-family:var(--font-num); font-size:11px; font-weight:600; letter-spacing:0.06em;
|
||||
text-transform:uppercase; color:var(--ink-3); text-align:left;
|
||||
padding:11px var(--sp-5); background:var(--paper-2); border-bottom:1px solid var(--hair);
|
||||
}
|
||||
tbody td{padding:14px var(--sp-5); border-bottom:1px solid var(--paper-2); font-size:14px; color:var(--ink-2); vertical-align:middle;}
|
||||
tbody tr:last-child td{border-bottom:none;}
|
||||
tbody tr:hover{background:var(--paper);}
|
||||
td .actor{display:flex; align-items:center; gap:10px;}
|
||||
td .actor .av{width:28px; height:28px; border-radius:50%; flex:none; display:flex; align-items:center; justify-content:center;
|
||||
font-size:11px; font-weight:600; background:var(--accent-tint); color:var(--accent-deep);}
|
||||
td .actor .nm{font-size:14px; font-weight:600; color:var(--ink); line-height:1.3;}
|
||||
td .actor .nm .sub{display:block; font-size:11px; color:var(--ink-3); font-weight:400;}
|
||||
td.time{font-family:var(--font-num); font-size:13px; color:var(--ink-3); white-space:nowrap;}
|
||||
td .act{display:inline-flex; align-items:center; gap:8px;}
|
||||
td .act .g{width:7px; height:7px; border-radius:50%; flex:none; background:var(--accent-bright);}
|
||||
td .act .g.view{background:var(--info-solid);}
|
||||
td .act .g.export{background:var(--clay);}
|
||||
td .act .g.grade{background:var(--pos-solid);}
|
||||
td .act .g.edit{background:var(--warn-solid);}
|
||||
td .target{color:var(--ink); font-weight:500;}
|
||||
td .target .meta{display:block; font-size:12px; color:var(--ink-3); font-weight:400;}
|
||||
td .scope{font-size:12px; font-weight:600; padding:3px 9px; border-radius:5px; background:var(--accent-tint); color:var(--accent-deep);}
|
||||
td .scope.sens{background:var(--warn-tint); color:var(--warn-text);}
|
||||
.audit .footer{display:flex; align-items:center; justify-content:space-between; padding:13px var(--sp-5); border-top:1px solid var(--hair);}
|
||||
.audit .footer .cnt{font-size:13px; color:var(--ink-3);}
|
||||
.audit .footer .pg{display:flex; gap:6px;}
|
||||
.audit .footer .pg button{font-family:var(--font-num); font-size:13px; color:var(--ink-2); border:1px solid var(--hair);
|
||||
background:var(--surface); width:30px; height:30px; border-radius:6px; cursor:pointer;}
|
||||
.audit .footer .pg button.on{background:var(--accent); color:var(--text-on-accent); border-color:transparent; font-weight:600;}
|
||||
|
||||
/* ============ 4. 관리 진입 ============ */
|
||||
.mgmt{display:grid; grid-template-columns:repeat(4,1fr); gap:var(--sp-4);}
|
||||
.entry{
|
||||
display:flex; flex-direction:column; gap:11px; padding:var(--sp-5);
|
||||
background:var(--surface); border:1px solid var(--hair); border-radius:var(--radius-lg);
|
||||
text-decoration:none; color:inherit; transition:border-color .16s var(--ease-out), transform .16s var(--ease-out);
|
||||
}
|
||||
.entry:hover{border-color:var(--accent-bright); transform:translateY(-1px);}
|
||||
.entry .ico{width:34px; height:34px; border-radius:8px; background:var(--accent-tint);
|
||||
display:flex; align-items:center; justify-content:center;}
|
||||
.entry .ico svg{width:18px; height:18px; stroke:var(--accent-deep); fill:none;}
|
||||
.entry .t{font-size:15px; font-weight:600; color:var(--ink);}
|
||||
.entry .d{font-size:13px; color:var(--ink-3); line-height:1.5;}
|
||||
.entry .go{margin-top:auto; font-size:12px; font-weight:600; color:var(--accent); display:flex; align-items:center; gap:5px; padding-top:4px;}
|
||||
.entry .go svg{width:13px; height:13px; stroke:var(--accent);}
|
||||
.entry .badge{font-family:var(--font-num); font-size:11px; font-weight:600; color:var(--warn-text);
|
||||
background:var(--warn-tint); padding:2px 7px; border-radius:4px; margin-left:auto;}
|
||||
|
||||
footer.foot{max-width:var(--maxw); margin:0 auto; padding:var(--sp-6); border-top:1px solid var(--hair);
|
||||
margin-top:var(--sp-7); display:flex; align-items:center; justify-content:space-between;
|
||||
font-size:12px; color:var(--ink-3);}
|
||||
|
||||
@media (prefers-reduced-motion: reduce){
|
||||
*,*::before,*::after{animation-duration:.01ms!important; transition-duration:.01ms!important;}
|
||||
}
|
||||
@media (max-width:1080px){
|
||||
.kpis{grid-template-columns:repeat(2,1fr);}
|
||||
.kpi:nth-child(3){border-left:none; border-top:1px solid var(--hair);}
|
||||
.kpi:nth-child(4){border-top:1px solid var(--hair);}
|
||||
.collect{grid-template-columns:1fr;}
|
||||
.mgmt{grid-template-columns:repeat(2,1fr);}
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<!-- ============ 공통 헤더 ============ -->
|
||||
<header class="topbar">
|
||||
<div class="brand">
|
||||
<svg class="mark" viewBox="0 0 24 24" fill="none" aria-hidden="true">
|
||||
<rect x="3" y="3" width="18" height="18" rx="5" stroke="#5B5F6B" stroke-width="2"/>
|
||||
<circle cx="12" cy="12" r="4.2" fill="#5B5F6B"/>
|
||||
</svg>
|
||||
<span class="wm">Vignette</span>
|
||||
<span class="role">Admin</span>
|
||||
</div>
|
||||
<nav class="nav">
|
||||
<a href="#" class="on">대시보드</a>
|
||||
<a href="#audit">감사 로그</a>
|
||||
<a href="#mgmt">데이터·페르소나</a>
|
||||
<a href="#">공지</a>
|
||||
</nav>
|
||||
<div class="right">
|
||||
<div class="envtag"><span class="d"></span>운영 환경 · v2.4.1</div>
|
||||
<div class="who">
|
||||
<div class="av">박</div>
|
||||
<div>
|
||||
<div class="nm">박운영</div>
|
||||
<div class="sub">시스템 관리자</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</header>
|
||||
|
||||
<div class="page">
|
||||
|
||||
<!-- 페이지 헤드 -->
|
||||
<div class="pagehead">
|
||||
<div>
|
||||
<div class="kicker"><span class="dot"></span>운영 콘솔</div>
|
||||
<h1>시스템 현황</h1>
|
||||
<p class="lead">플랫폼 가동 상태와 전체 사용·세션 흐름을 한눈에. 교수자가 무엇을 열람했는지까지 추적합니다.</p>
|
||||
</div>
|
||||
<div class="when">
|
||||
<b>2026-06-25 21:14 KST</b>
|
||||
최근 동기화 22초 전
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 한 줄 상태 요약 -->
|
||||
<div class="statusline">
|
||||
<span class="pulse"></span>
|
||||
<span class="msg">모든 핵심 서비스가 <b>정상 가동</b> 중입니다. 음성 합성 지연만 평소보다 약간 높습니다.</span>
|
||||
<span class="ts tab-num">uptime 47d 12h</span>
|
||||
</div>
|
||||
|
||||
<!-- 핵심 지표 -->
|
||||
<div class="kpis">
|
||||
<div class="kpi">
|
||||
<div class="l">진행 중 세션</div>
|
||||
<div class="n tab-num">14<span class="u">건</span></div>
|
||||
<div class="d"><span class="up">+5</span> 지난 1시간 대비</div>
|
||||
</div>
|
||||
<div class="kpi">
|
||||
<div class="l">오늘 완료 세션</div>
|
||||
<div class="n tab-num">186<span class="u">건</span></div>
|
||||
<div class="d"><span class="up">+12%</span> 전일 동시간 대비</div>
|
||||
</div>
|
||||
<div class="kpi">
|
||||
<div class="l">활성 사용자 (24h)</div>
|
||||
<div class="n tab-num">312<span class="u">명</span></div>
|
||||
<div class="d">학습 287 · 교수 21 · 관리 4</div>
|
||||
</div>
|
||||
<div class="kpi">
|
||||
<div class="l">평균 평가 지연</div>
|
||||
<div class="n tab-num">1.8<span class="u">초</span></div>
|
||||
<div class="d"><span class="dn">목표 2.0초</span> 이내</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 헬스 라인 -->
|
||||
<div class="section" style="margin-top:var(--sp-5)">
|
||||
<div class="sechead">
|
||||
<h2>서비스 헬스</h2>
|
||||
<span class="meta">엔진 · 음성 · DB · 큐 · 스토리지</span>
|
||||
</div>
|
||||
<div class="health">
|
||||
<div class="hrow">
|
||||
<div class="svc"><span class="d ok"></span><span><span class="nm">내담자 대화 엔진</span><span class="sub">LLM 추론 · 가드레일</span></span></div>
|
||||
<div class="gauge"><div class="fill ok" style="width:42%"></div></div>
|
||||
<div class="num tab-num">42% 부하</div>
|
||||
<span class="stat ok">정상</span>
|
||||
</div>
|
||||
<div class="hrow">
|
||||
<div class="svc"><span class="d warn"></span><span><span class="nm">음성 합성 (TTS)</span><span class="sub">스트리밍 · 8개 보이스</span></span></div>
|
||||
<div class="gauge"><div class="fill warn" style="width:78%"></div></div>
|
||||
<div class="num tab-num">P95 1.4s</div>
|
||||
<span class="stat warn">지연 주의</span>
|
||||
</div>
|
||||
<div class="hrow">
|
||||
<div class="svc"><span class="d ok"></span><span><span class="nm">음성 인식 (STT)</span><span class="sub">실시간 스트림</span></span></div>
|
||||
<div class="gauge"><div class="fill ok" style="width:36%"></div></div>
|
||||
<div class="num tab-num">P95 0.6s</div>
|
||||
<span class="stat ok">정상</span>
|
||||
</div>
|
||||
<div class="hrow">
|
||||
<div class="svc"><span class="d ok"></span><span><span class="nm">세션·평가 DB</span><span class="sub">PostgreSQL 기본</span></span></div>
|
||||
<div class="gauge"><div class="fill ok" style="width:51%"></div></div>
|
||||
<div class="num tab-num">conn 51/200</div>
|
||||
<span class="stat ok">정상</span>
|
||||
</div>
|
||||
<div class="hrow">
|
||||
<div class="svc"><span class="d ok"></span><span><span class="nm">평가 작업 큐</span><span class="sub">회기말 리뷰 생성</span></span></div>
|
||||
<div class="gauge"><div class="fill ok" style="width:18%"></div></div>
|
||||
<div class="num tab-num">대기 3건</div>
|
||||
<span class="stat ok">정상</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- ============ 2. 수집 현황 ============ -->
|
||||
<div class="section">
|
||||
<div class="sechead">
|
||||
<h2>사용·세션 수집 현황</h2>
|
||||
<span class="meta">최근 7일 기준</span>
|
||||
</div>
|
||||
<div class="collect">
|
||||
<div class="panel">
|
||||
<div class="ph">시나리오별 세션 분포</div>
|
||||
<div class="psub">이번 주 누적 1,284회기 · 가장 많이 연습된 사례 순</div>
|
||||
<div class="distrib">
|
||||
<div class="dist"><span class="dl">우울 호소 청소년</span><div class="db"><div class="f clay" style="width:88%"></div></div><span class="dv tab-num">412</span></div>
|
||||
<div class="dist"><span class="dl">불안·공황 20대</span><div class="db"><div class="f" style="width:64%"></div></div><span class="dv tab-num">298</span></div>
|
||||
<div class="dist"><span class="dl">관계 갈등 성인</span><div class="db"><div class="f" style="width:48%"></div></div><span class="dv tab-num">221</span></div>
|
||||
<div class="dist"><span class="dl">학업 스트레스 고3</span><div class="db"><div class="f" style="width:37%"></div></div><span class="dv tab-num">174</span></div>
|
||||
<div class="dist"><span class="dl">위기 개입 시뮬</span><div class="db"><div class="f warn" style="width:25%"></div></div><span class="dv tab-num">112</span></div>
|
||||
<div class="dist"><span class="dl">기타</span><div class="db"><div class="f" style="width:14%"></div></div><span class="dv tab-num">67</span></div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="panel">
|
||||
<div class="ph">역할별 사용 현황</div>
|
||||
<div class="psub">전체 등록 계정 대비 활성</div>
|
||||
<div class="rolelist">
|
||||
<div class="rr">
|
||||
<div class="rl"><span class="rd" style="background:#3E7A6E"></span><span class="nm">학습자<span class="sub">상담 수련생 · 등록 248</span></span></div>
|
||||
<div class="rv tab-num">231<span class="delta">+18</span></div>
|
||||
</div>
|
||||
<div class="rr">
|
||||
<div class="rl"><span class="rd" style="background:#3A5BA0"></span><span class="nm">교수자<span class="sub">슈퍼바이저 · 등록 34</span></span></div>
|
||||
<div class="rv tab-num">29<span class="delta">+2</span></div>
|
||||
</div>
|
||||
<div class="rr">
|
||||
<div class="rl"><span class="rd" style="background:#5B5F6B"></span><span class="nm">관리자<span class="sub">운영 · 등록 6</span></span></div>
|
||||
<div class="rv tab-num">4</div>
|
||||
</div>
|
||||
<div class="rr">
|
||||
<div class="rl"><span class="rd" style="background:var(--clay)"></span><span class="nm">페르소나<span class="sub">가상 내담자 풀</span></span></div>
|
||||
<div class="rv tab-num">23<span class="delta">+3</span></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- ============ 3. 교수자 활동 감사 로그 ============ -->
|
||||
<div class="section" id="audit">
|
||||
<div class="sechead">
|
||||
<h2>교수자 활동 감사 로그</h2>
|
||||
<a href="#" class="link">전체 로그 내보내기
|
||||
<svg viewBox="0 0 24 24" fill="none" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4"/><polyline points="7 10 12 15 17 10"/><line x1="12" y1="15" x2="12" y2="3"/></svg>
|
||||
</a>
|
||||
</div>
|
||||
<div class="audit">
|
||||
<div class="toolbar">
|
||||
<div class="search">
|
||||
<svg viewBox="0 0 24 24" fill="none" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><circle cx="11" cy="11" r="7"/><line x1="21" y1="21" x2="16.65" y2="16.65"/></svg>
|
||||
<input placeholder="교수자·학습자·세션 ID로 검색">
|
||||
</div>
|
||||
<span class="chip on">전체</span>
|
||||
<span class="chip">세션 열람</span>
|
||||
<span class="chip">오디오 재생</span>
|
||||
<span class="chip">PDF 내보내기</span>
|
||||
<span class="chip">평가 수정</span>
|
||||
<div class="spacer"></div>
|
||||
<span class="chip">최근 24시간</span>
|
||||
</div>
|
||||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
<th style="width:120px">시각</th>
|
||||
<th style="width:200px">교수자</th>
|
||||
<th style="width:160px">행위</th>
|
||||
<th>대상</th>
|
||||
<th style="width:120px">범위</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td class="time">21:08:42</td>
|
||||
<td><div class="actor"><span class="av">김</span><span class="nm">김상담<span class="sub">슈퍼바이저</span></span></div></td>
|
||||
<td><span class="act"><span class="g view"></span>회기 리뷰 열람</span></td>
|
||||
<td><span class="target">서연 사례 · 회기 1 리뷰<span class="meta">학습자 이수민 · 세션 #S-20448</span></span></td>
|
||||
<td><span class="scope sens">학습자 식별</span></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="time">20:51:17</td>
|
||||
<td><div class="actor"><span class="av">정</span><span class="nm">정교수<span class="sub">슈퍼바이저</span></span></div></td>
|
||||
<td><span class="act"><span class="g export"></span>리뷰 PDF 내보내기</span></td>
|
||||
<td><span class="target">불안·공황 20대 · 회기 3<span class="meta">학습자 박지훈 · 세션 #S-20431</span></span></td>
|
||||
<td><span class="scope sens">원본 포함</span></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="time">20:39:05</td>
|
||||
<td><div class="actor"><span class="av">김</span><span class="nm">김상담<span class="sub">슈퍼바이저</span></span></div></td>
|
||||
<td><span class="act"><span class="g grade"></span>슈퍼바이저 코멘트 작성</span></td>
|
||||
<td><span class="target">감정 반영 구간에 코멘트 3건<span class="meta">학습자 이수민 · 세션 #S-20448</span></span></td>
|
||||
<td><span class="scope">평가 작성</span></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="time">20:22:48</td>
|
||||
<td><div class="actor"><span class="av">한</span><span class="nm">한지도<span class="sub">슈퍼바이저</span></span></div></td>
|
||||
<td><span class="act"><span class="g view"></span>오디오 다시듣기</span></td>
|
||||
<td><span class="target">관계 갈등 성인 · 회기 2<span class="meta">학습자 최영아 · 세션 #S-20419</span></span></td>
|
||||
<td><span class="scope sens">음성 원본</span></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="time">19:57:31</td>
|
||||
<td><div class="actor"><span class="av">정</span><span class="nm">정교수<span class="sub">슈퍼바이저</span></span></div></td>
|
||||
<td><span class="act"><span class="g edit"></span>평가 항목 수정</span></td>
|
||||
<td><span class="target">'닫힌 질문' 라벨 1건 해제<span class="meta">학습자 박지훈 · 세션 #S-20431</span></span></td>
|
||||
<td><span class="scope">평가 수정</span></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="time">19:40:12</td>
|
||||
<td><div class="actor"><span class="av">한</span><span class="nm">한지도<span class="sub">슈퍼바이저</span></span></div></td>
|
||||
<td><span class="act"><span class="g view"></span>학습자 성장 곡선 열람</span></td>
|
||||
<td><span class="target">담당 그룹 12명 추세<span class="meta">2026 봄학기 상담실습 A반</span></span></td>
|
||||
<td><span class="scope">집계 조회</span></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="time">19:12:55</td>
|
||||
<td><div class="actor"><span class="av">김</span><span class="nm">김상담<span class="sub">슈퍼바이저</span></span></div></td>
|
||||
<td><span class="act"><span class="g view"></span>실시간 세션 관찰</span></td>
|
||||
<td><span class="target">우울 호소 청소년 · 진행 중<span class="meta">학습자 이수민 · 세션 #S-20448</span></span></td>
|
||||
<td><span class="scope sens">실시간 열람</span></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
<div class="footer">
|
||||
<span class="cnt">최근 24시간 248건 중 1–7 표시 · 모든 열람은 위·변조 불가 로그로 보존됩니다</span>
|
||||
<div class="pg">
|
||||
<button class="on">1</button>
|
||||
<button>2</button>
|
||||
<button>3</button>
|
||||
<button>›</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- ============ 4. 관리 진입 ============ -->
|
||||
<div class="section" id="mgmt">
|
||||
<div class="sechead">
|
||||
<h2>관리</h2>
|
||||
<span class="meta">데이터 · 페르소나 · 공지 · 정책</span>
|
||||
</div>
|
||||
<div class="mgmt">
|
||||
<a href="#" class="entry">
|
||||
<div class="ico"><svg viewBox="0 0 24 24" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"><ellipse cx="12" cy="5" rx="8" ry="3"/><path d="M4 5v14c0 1.66 3.58 3 8 3s8-1.34 8-3V5"/><path d="M4 12c0 1.66 3.58 3 8 3s8-1.34 8-3"/></svg></div>
|
||||
<div class="t">데이터 관리</div>
|
||||
<div class="d">세션 기록·평가 데이터 보존, 익명화, 내보내기 정책.</div>
|
||||
<div class="go">바로가기 <svg viewBox="0 0 24 24" fill="none" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><polyline points="9 18 15 12 9 6"/></svg></div>
|
||||
</a>
|
||||
<a href="#" class="entry">
|
||||
<div class="ico"><svg viewBox="0 0 24 24" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"><circle cx="12" cy="8" r="4"/><path d="M4 21c0-4 3.6-6 8-6s8 2 8 6"/></svg></div>
|
||||
<div class="t">페르소나 관리 <span class="badge">신규 3</span></div>
|
||||
<div class="d">가상 내담자 풀, 정서 파라미터, 미성년 라벨 검수.</div>
|
||||
<div class="go">바로가기 <svg viewBox="0 0 24 24" fill="none" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><polyline points="9 18 15 12 9 6"/></svg></div>
|
||||
</a>
|
||||
<a href="#" class="entry">
|
||||
<div class="ico"><svg viewBox="0 0 24 24" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"><path d="M3 11l18-5v12L3 14v-3z"/><path d="M11.6 16.8a3 3 0 1 1-5.8-1.6"/></svg></div>
|
||||
<div class="t">공지 관리</div>
|
||||
<div class="d">학기 일정, 점검 안내, 역할별 배너 공지 발행.</div>
|
||||
<div class="go">바로가기 <svg viewBox="0 0 24 24" fill="none" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><polyline points="9 18 15 12 9 6"/></svg></div>
|
||||
</a>
|
||||
<a href="#" class="entry">
|
||||
<div class="ico"><svg viewBox="0 0 24 24" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"><path d="M12 2l8 3v6c0 5-3.5 8.5-8 10-4.5-1.5-8-5-8-10V5l8-3z"/><path d="M9 12l2 2 4-4"/></svg></div>
|
||||
<div class="t">정책·가드레일</div>
|
||||
<div class="d">위기 개입 규칙, 안전 점검 임계치, 권한 정책.</div>
|
||||
<div class="go">바로가기 <svg viewBox="0 0 24 24" fill="none" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><polyline points="9 18 15 12 9 6"/></svg></div>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<footer class="foot">
|
||||
<span>Vignette · AI 심리상담 시뮬레이션 훈련 플랫폼 · 한신대학교 산학협력</span>
|
||||
<span class="tab-num">운영 환경 · v2.4.1</span>
|
||||
</footer>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
459
docs/mockups/learner-home.html
Normal file
459
docs/mockups/learner-home.html
Normal file
|
|
@ -0,0 +1,459 @@
|
|||
<!DOCTYPE html>
|
||||
<html lang="ko">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>한신대 AI 심리상담 시뮬레이션 — 학습자 홈 시안</title>
|
||||
<link rel="stylesheet" href="https://cdn.jsdelivr.net/gh/orioncactus/pretendard/dist/web/variable/pretendardvariable.min.css">
|
||||
<style>
|
||||
/* =====================================================================
|
||||
한신대 AI 심리상담 시뮬레이션 — 학습자 홈 (단일 파일, 인라인 CSS)
|
||||
토큰: DESIGN_CONCEPT.md §3 그대로. 외부 의존 = Pretendard CDN 1개.
|
||||
철칙 준수: border-left 0 · 이모지 0 (아이콘 inline SVG) · 카드격자 덤프 0
|
||||
순흑/순백 금지 · 강조는 weight/tint/kicker/dot로만 · 넉넉한 여백.
|
||||
역할 = 학습자(세이지-틸 accent).
|
||||
===================================================================== */
|
||||
: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:1120px;
|
||||
--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);
|
||||
}
|
||||
*{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;}
|
||||
|
||||
/* ============ 공통 헤더 (앱 셸 톱바) ============ */
|
||||
.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:10;
|
||||
}
|
||||
.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;}
|
||||
.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-7) var(--sp-6) var(--sp-8);}
|
||||
|
||||
/* ── (1) 인사 + 이번주 현황 한 줄 ── */
|
||||
.hero{margin-bottom:var(--sp-7);}
|
||||
.hero .greet{font-size:30px; font-weight:700; letter-spacing:-0.02em; line-height:1.3; color:var(--ink);}
|
||||
.hero .greet .name{color:var(--accent-deep);}
|
||||
.weekline{
|
||||
margin-top:var(--sp-4); display:flex; align-items:center; flex-wrap:wrap;
|
||||
gap:var(--sp-5); font-size:15px; color:var(--ink-2);
|
||||
}
|
||||
.weekline .k{
|
||||
font-family:var(--font-num); font-size:12px; font-weight:600; letter-spacing:0.08em;
|
||||
color:var(--accent); display:inline-flex; align-items:center; gap:7px;
|
||||
}
|
||||
.weekline .k .dot{width:6px; height:6px; border-radius:50%; background:var(--accent-bright);}
|
||||
.weekline .stat{display:inline-flex; align-items:baseline; gap:6px;}
|
||||
.weekline .stat .num{font-size:19px; font-weight:700; color:var(--ink); font-variant-numeric:tabular-nums;}
|
||||
.weekline .stat .lab{font-size:14px; color:var(--ink-3);}
|
||||
.weekline .vsep{width:1px; height:16px; background:var(--hair);}
|
||||
|
||||
/* 섹션 공통 */
|
||||
.section{margin-top:var(--sp-8);}
|
||||
.sec-head{display:flex; align-items:flex-end; justify-content:space-between; margin-bottom:var(--sp-5);}
|
||||
.sec-head .ttl{font-size:20px; font-weight:600; letter-spacing:-0.01em; color:var(--ink);}
|
||||
.sec-head .sub{font-size:13px; color:var(--ink-3); margin-top:3px;}
|
||||
.sec-head .link{
|
||||
font-size:13px; font-weight:500; color:var(--accent-deep); text-decoration:none;
|
||||
display:inline-flex; align-items:center; gap:5px;
|
||||
}
|
||||
.sec-head .link svg{width:13px; height:13px; stroke:var(--accent-deep);}
|
||||
.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; margin-bottom:8px;
|
||||
}
|
||||
.kicker .dot{width:6px; height:6px; border-radius:50%; background:var(--accent-bright);}
|
||||
|
||||
/* ── (2) 내 상담 세션 목록 (리스트/테이블형) ── */
|
||||
.sessions{
|
||||
background:var(--surface); border:1px solid var(--hair); border-radius:var(--radius-lg);
|
||||
overflow:hidden;
|
||||
}
|
||||
.s-head, .s-row{
|
||||
display:grid;
|
||||
grid-template-columns:108px 1.4fr 64px 1fr 1.5fr 96px;
|
||||
align-items:center; gap:var(--sp-4);
|
||||
padding:var(--sp-4) var(--sp-5);
|
||||
}
|
||||
.s-head{
|
||||
background:var(--paper-2); border-bottom:1px solid var(--hair);
|
||||
font-size:12px; font-weight:600; letter-spacing:0.02em; color:var(--ink-3);
|
||||
}
|
||||
.s-row{border-bottom:1px solid var(--paper-2); transition:background .14s var(--ease-out);}
|
||||
.s-row:last-child{border-bottom:none;}
|
||||
.s-row:hover{background:var(--paper);}
|
||||
.s-row .date{font-family:var(--font-num); font-size:13px; color:var(--ink-2); font-variant-numeric:tabular-nums;}
|
||||
.s-row .date .wd{display:block; font-size:11px; color:var(--ink-3); margin-top:1px;}
|
||||
/* 내담자 페르소나 */
|
||||
.persona{display:flex; align-items:center; gap:10px;}
|
||||
.persona .pf{
|
||||
width:30px; height:30px; border-radius:50%; flex:none;
|
||||
display:flex; align-items:center; justify-content:center;
|
||||
font-size:12px; font-weight:700;
|
||||
}
|
||||
.persona .pf.a{background:var(--clay-tint); color:var(--clay-deep);}
|
||||
.persona .pf.b{background:var(--accent-tint); color:var(--accent-deep);}
|
||||
.persona .pf.c{background:var(--info-tint); color:var(--info-text);}
|
||||
.persona .pn{font-size:14px; font-weight:600; color:var(--ink); line-height:1.35;}
|
||||
.persona .pn .meta{display:block; font-size:12px; font-weight:400; color:var(--ink-3); margin-top:1px;}
|
||||
.sess{font-family:var(--font-num); font-size:13px; color:var(--ink-2); font-variant-numeric:tabular-nums;}
|
||||
/* 단계 도달 (인라인 미니 트랙) */
|
||||
.reach{display:flex; flex-direction:column; gap:6px;}
|
||||
.reach .rl{font-size:13px; color:var(--ink); font-weight:500;}
|
||||
.reach .seg{display:flex; align-items:center; gap:4px;}
|
||||
.reach .seg span{height:4px; flex:1; border-radius:2px; background:var(--neutral-150);}
|
||||
.reach .seg span.done{background:var(--accent-bright);}
|
||||
.reach .seg span.cur{background:var(--accent);}
|
||||
/* 피드백 요약 */
|
||||
.fb{display:flex; align-items:flex-start; gap:9px;}
|
||||
.fb .fd{width:8px; height:8px; border-radius:50%; flex:none; margin-top:6px;}
|
||||
.fb .fd.pos{background:var(--pos-solid);}
|
||||
.fb .fd.warn{background:var(--warn-solid);}
|
||||
.fb .fd.info{background:var(--info-solid);}
|
||||
.fb .fd.neu{background:var(--neutral-sig);}
|
||||
.fb .ft{font-size:13px; color:var(--ink-2); line-height:1.5;}
|
||||
/* 상태 칩 (배경 틴트 + 텍스트, border 없음) */
|
||||
.status{
|
||||
display:inline-flex; align-items:center; gap:6px; justify-self:start;
|
||||
font-size:12px; font-weight:600; padding:4px 10px; border-radius:100px; white-space:nowrap;
|
||||
}
|
||||
.status .sd{width:6px; height:6px; border-radius:50%;}
|
||||
.status.done{background:var(--pos-tint); color:var(--pos-text);} .status.done .sd{background:var(--pos-solid);}
|
||||
.status.review{background:var(--info-tint); color:var(--info-text);} .status.review .sd{background:var(--info-solid);}
|
||||
.status.draft{background:var(--paper-2); color:var(--ink-3);} .status.draft .sd{background:var(--neutral-sig);}
|
||||
|
||||
/* ── (3) 성장 한눈에 (small-multiples 라인 3개) ── */
|
||||
.growth-grid{display:grid; grid-template-columns:repeat(3,1fr); gap:var(--sp-5);}
|
||||
.spark{
|
||||
background:var(--surface); border:1px solid var(--hair); border-radius:var(--radius-lg);
|
||||
padding:var(--sp-5);
|
||||
}
|
||||
.spark .label{font-size:14px; font-weight:600; color:var(--ink); letter-spacing:-0.01em;}
|
||||
.spark .now{display:flex; align-items:baseline; gap:8px; margin-top:6px;}
|
||||
.spark .now .v{font-size:26px; font-weight:700; color:var(--ink); font-variant-numeric:tabular-nums; letter-spacing:-0.02em;}
|
||||
.spark .now .delta{font-size:12px; font-weight:600; display:inline-flex; align-items:center; gap:3px;}
|
||||
.spark .now .delta.up{color:var(--pos-text);}
|
||||
.spark .now .delta.flat{color:var(--ink-3);}
|
||||
.spark .now .delta svg{width:11px; height:11px;}
|
||||
.spark .chart{margin-top:var(--sp-4); width:100%; height:56px; display:block;}
|
||||
.spark .axis{display:flex; justify-content:space-between; margin-top:8px; font-size:11px; color:var(--ink-3); font-variant-numeric:tabular-nums;}
|
||||
|
||||
/* ── (4) 다음 연습 시작 CTA ── */
|
||||
.cta{
|
||||
margin-top:var(--sp-8);
|
||||
background:var(--accent-tint); border-radius:var(--radius-lg);
|
||||
padding:var(--sp-6) var(--sp-7);
|
||||
display:flex; align-items:center; gap:var(--sp-6); flex-wrap:wrap;
|
||||
}
|
||||
.cta .body{flex:1; min-width:280px;}
|
||||
.cta .body .kk{
|
||||
font-family:var(--font-num); font-size:12px; font-weight:600; letter-spacing:0.08em;
|
||||
color:var(--accent-deep); display:flex; align-items:center; gap:8px; margin-bottom:8px;
|
||||
}
|
||||
.cta .body .kk .dot{width:6px; height:6px; border-radius:50%; background:var(--accent);}
|
||||
.cta .body h3{font-size:22px; font-weight:700; color:var(--ink); letter-spacing:-0.02em; line-height:1.35;}
|
||||
.cta .body p{font-size:14px; color:var(--ink-2); margin-top:6px; max-width:520px;}
|
||||
.cta .body .tags{display:flex; gap:8px; margin-top:14px; flex-wrap:wrap;}
|
||||
.cta .body .tag{
|
||||
font-size:12px; font-weight:500; color:var(--accent-deep);
|
||||
background:var(--surface); padding:5px 11px; border-radius:100px;
|
||||
}
|
||||
.btn-primary{
|
||||
font-family:var(--font-sans); font-size:15px; font-weight:600; color:var(--text-on-accent);
|
||||
background:var(--accent); border:none; padding:14px 26px; border-radius:var(--radius);
|
||||
cursor:pointer; display:inline-flex; align-items:center; gap:9px; flex:none;
|
||||
transition:background .16s var(--ease-out);
|
||||
}
|
||||
.btn-primary:hover{background:var(--accent-deep);}
|
||||
.btn-primary svg{width:18px; height:18px; stroke:var(--text-on-accent);}
|
||||
.cta .alt{
|
||||
font-size:13px; font-weight:500; color:var(--ink-2); text-decoration:none;
|
||||
margin-top:10px; display:inline-flex; align-items:center; gap:5px;
|
||||
}
|
||||
.cta .alt svg{width:13px; height:13px; stroke:var(--ink-2);}
|
||||
.cta-actions{display:flex; flex-direction:column; align-items:flex-end; flex:none;}
|
||||
|
||||
@media (max-width:920px){
|
||||
.growth-grid{grid-template-columns:1fr;}
|
||||
.s-head{display:none;}
|
||||
.s-row{grid-template-columns:1fr 1fr; row-gap:var(--sp-3); padding:var(--sp-5);}
|
||||
.nav{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="#" class="on">홈</a>
|
||||
<a href="#">연습실</a>
|
||||
<a href="#">내 회기</a>
|
||||
<a href="#">성장 기록</a>
|
||||
</nav>
|
||||
<span class="spacer"></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">
|
||||
|
||||
<!-- ── (1) 인사 + 이번주 현황 ── -->
|
||||
<section class="hero">
|
||||
<h1 class="greet">안녕하세요 <span class="name">도윤</span>님, 오늘도 한 회기 들어가 볼까요.</h1>
|
||||
<div class="weekline">
|
||||
<span class="k"><span class="dot"></span>이번 주 연습</span>
|
||||
<span class="stat"><span class="num">3</span><span class="lab">회기 완료</span></span>
|
||||
<span class="vsep"></span>
|
||||
<span class="stat"><span class="num">2</span><span class="lab">리뷰 확인 대기</span></span>
|
||||
<span class="vsep"></span>
|
||||
<span class="stat"><span class="num">주 4회</span><span class="lab">목표까지 1회</span></span>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<!-- ── (2) 내 상담 세션 목록 ── -->
|
||||
<section class="section">
|
||||
<div class="sec-head">
|
||||
<div>
|
||||
<div class="ttl">내 상담 세션</div>
|
||||
<div class="sub">최근 진행한 회기와 받은 피드백을 한눈에 봅니다</div>
|
||||
</div>
|
||||
<a href="#" class="link">전체 보기
|
||||
<svg viewBox="0 0 24 24" fill="none" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><polyline points="9 18 15 12 9 6"/></svg>
|
||||
</a>
|
||||
</div>
|
||||
|
||||
<div class="sessions">
|
||||
<div class="s-head">
|
||||
<span>날짜</span>
|
||||
<span>내담자 (페르소나)</span>
|
||||
<span>회기</span>
|
||||
<span>단계 도달</span>
|
||||
<span>받은 피드백 요약</span>
|
||||
<span>상태</span>
|
||||
</div>
|
||||
|
||||
<!-- row 1 -->
|
||||
<div class="s-row">
|
||||
<div class="date tab-num">06.24<span class="wd">화 · 어제</span></div>
|
||||
<div class="persona">
|
||||
<span class="pf a">서</span>
|
||||
<span class="pn">서연<span class="meta">17세 · 우울 호소 청소년</span></span>
|
||||
</div>
|
||||
<div class="sess">회기 1</div>
|
||||
<div class="reach">
|
||||
<span class="rl">탐색까지</span>
|
||||
<span class="seg"><span class="done"></span><span class="cur"></span><span></span><span></span></span>
|
||||
</div>
|
||||
<div class="fb"><span class="fd warn"></span><span class="ft">라포는 좋았으나 닫힌 질문이 반복돼 자기개방이 일찍 멈췄어요</span></div>
|
||||
<span class="status review"><span class="sd"></span>리뷰 도착</span>
|
||||
</div>
|
||||
|
||||
<!-- row 2 -->
|
||||
<div class="s-row">
|
||||
<div class="date tab-num">06.22<span class="wd">일</span></div>
|
||||
<div class="persona">
|
||||
<span class="pf b">민</span>
|
||||
<span class="pn">민준<span class="meta">24세 · 불안·공황 호소</span></span>
|
||||
</div>
|
||||
<div class="sess">회기 2</div>
|
||||
<div class="reach">
|
||||
<span class="rl">개입까지</span>
|
||||
<span class="seg"><span class="done"></span><span class="done"></span><span class="cur"></span><span></span></span>
|
||||
</div>
|
||||
<div class="fb"><span class="fd pos"></span><span class="ft">반영적 경청이 안정적이었고 개입 시점 판단이 적절했어요</span></div>
|
||||
<span class="status done"><span class="sd"></span>완료</span>
|
||||
</div>
|
||||
|
||||
<!-- row 3 -->
|
||||
<div class="s-row">
|
||||
<div class="date tab-num">06.19<span class="wd">목</span></div>
|
||||
<div class="persona">
|
||||
<span class="pf c">하</span>
|
||||
<span class="pn">하은<span class="meta">16세 · 또래관계·등교 거부</span></span>
|
||||
</div>
|
||||
<div class="sess">회기 1</div>
|
||||
<div class="reach">
|
||||
<span class="rl">라포까지</span>
|
||||
<span class="seg"><span class="cur"></span><span></span><span></span><span></span></span>
|
||||
</div>
|
||||
<div class="fb"><span class="fd info"></span><span class="ft">초반 침묵을 견디는 호흡이 좋았어요. 개방형 질문 연결을 더 연습해 보세요</span></div>
|
||||
<span class="status done"><span class="sd"></span>완료</span>
|
||||
</div>
|
||||
|
||||
<!-- row 4 -->
|
||||
<div class="s-row">
|
||||
<div class="date tab-num">06.17<span class="wd">화</span></div>
|
||||
<div class="persona">
|
||||
<span class="pf a">서</span>
|
||||
<span class="pn">서연<span class="meta">17세 · 우울 호소 청소년</span></span>
|
||||
</div>
|
||||
<div class="sess">회기 1·중단</div>
|
||||
<div class="reach">
|
||||
<span class="rl">라포 진행 중</span>
|
||||
<span class="seg"><span class="cur"></span><span></span><span></span><span></span></span>
|
||||
</div>
|
||||
<div class="fb"><span class="fd neu"></span><span class="ft">8분에 일시정지 후 종료 — 이어서 다시 시도해 볼 수 있어요</span></div>
|
||||
<span class="status draft"><span class="sd"></span>이어하기</span>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<!-- ── (3) 성장 한눈에 (small-multiples 라인 3개, 레이더 금지) ── -->
|
||||
<section class="section">
|
||||
<div class="sec-head">
|
||||
<div>
|
||||
<div class="ttl">성장 한눈에</div>
|
||||
<div class="sub">최근 8회기 추이 — 점수가 아니라 흐름으로 봅니다</div>
|
||||
</div>
|
||||
<a href="#" class="link">상세 추이
|
||||
<svg viewBox="0 0 24 24" fill="none" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><polyline points="9 18 15 12 9 6"/></svg>
|
||||
</a>
|
||||
</div>
|
||||
|
||||
<div class="growth-grid">
|
||||
<!-- 라포 형성 -->
|
||||
<div class="spark">
|
||||
<div class="label">라포 형성</div>
|
||||
<div class="now">
|
||||
<span class="v">안정</span>
|
||||
<span class="delta up"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.4" stroke-linecap="round" stroke-linejoin="round"><polyline points="6 14 12 8 18 14"/></svg>꾸준히 향상</span>
|
||||
</div>
|
||||
<svg class="chart" viewBox="0 0 240 56" preserveAspectRatio="none" aria-label="라포 형성 추이">
|
||||
<line x1="0" y1="55" x2="240" y2="55" stroke="#E5E1DA" stroke-width="1"/>
|
||||
<polyline points="4,42 38,40 72,34 106,33 140,26 174,22 208,18 236,14" fill="none" stroke="#5F968B" stroke-width="2.2" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
<circle cx="236" cy="14" r="3.2" fill="#3E7A6E"/>
|
||||
</svg>
|
||||
<div class="axis"><span>1회기</span><span>8회기</span></div>
|
||||
</div>
|
||||
|
||||
<!-- 기법 사용 -->
|
||||
<div class="spark">
|
||||
<div class="label">기법 사용 (개방형 질문)</div>
|
||||
<div class="now">
|
||||
<span class="v">늘어남</span>
|
||||
<span class="delta up"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.4" stroke-linecap="round" stroke-linejoin="round"><polyline points="6 14 12 8 18 14"/></svg>닫힌 질문 감소</span>
|
||||
</div>
|
||||
<svg class="chart" viewBox="0 0 240 56" preserveAspectRatio="none" aria-label="기법 사용 추이">
|
||||
<line x1="0" y1="55" x2="240" y2="55" stroke="#E5E1DA" stroke-width="1"/>
|
||||
<polyline points="4,44 38,46 72,38 106,40 140,32 174,30 208,24 236,20" fill="none" stroke="#5F968B" stroke-width="2.2" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
<circle cx="236" cy="20" r="3.2" fill="#3E7A6E"/>
|
||||
</svg>
|
||||
<div class="axis"><span>1회기</span><span>8회기</span></div>
|
||||
</div>
|
||||
|
||||
<!-- 개입 정확도 -->
|
||||
<div class="spark">
|
||||
<div class="label">개입 정확도 (시점·기법)</div>
|
||||
<div class="now">
|
||||
<span class="v">발전 중</span>
|
||||
<span class="delta flat"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.4" stroke-linecap="round" stroke-linejoin="round"><line x1="6" y1="12" x2="18" y2="12"/></svg>최근 평탄</span>
|
||||
</div>
|
||||
<svg class="chart" viewBox="0 0 240 56" preserveAspectRatio="none" aria-label="개입 정확도 추이">
|
||||
<line x1="0" y1="55" x2="240" y2="55" stroke="#E5E1DA" stroke-width="1"/>
|
||||
<polyline points="4,40 38,34 72,36 106,28 140,30 174,27 208,28 236,26" fill="none" stroke="#5F968B" stroke-width="2.2" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
<circle cx="236" cy="26" r="3.2" fill="#3E7A6E"/>
|
||||
</svg>
|
||||
<div class="axis"><span>1회기</span><span>8회기</span></div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<!-- ── (4) 다음 연습 시작 CTA ── -->
|
||||
<section class="cta">
|
||||
<div class="body">
|
||||
<div class="kk"><span class="dot"></span>다음 연습 추천</div>
|
||||
<h3>서연 회기 2 — 탐색 단계 이어가기</h3>
|
||||
<p>지난 회기에서 닫힌 질문이 반복됐어요. 이번엔 개방형 질문으로 자기개방을 끌어내는 데 집중해 보세요.</p>
|
||||
<div class="tags">
|
||||
<span class="tag">우울 호소 청소년</span>
|
||||
<span class="tag">탐색 단계</span>
|
||||
<span class="tag">목표: 개방형 질문</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="cta-actions">
|
||||
<button class="btn-primary">
|
||||
연습 시작
|
||||
<svg viewBox="0 0 24 24" fill="none" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><polyline points="9 18 15 12 9 6"/></svg>
|
||||
</button>
|
||||
<a href="#" class="alt">
|
||||
<svg viewBox="0 0 24 24" fill="none" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><circle cx="12" cy="12" r="9"/><path d="M12 8v4l3 2"/></svg>
|
||||
다른 페르소나 고르기
|
||||
</a>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
</main>
|
||||
</body>
|
||||
</html>
|
||||
341
docs/mockups/login.html
Normal file
341
docs/mockups/login.html
Normal file
|
|
@ -0,0 +1,341 @@
|
|||
<!DOCTYPE html>
|
||||
<html lang="ko">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Vignette — 로그인</title>
|
||||
<link rel="stylesheet" href="https://cdn.jsdelivr.net/gh/orioncactus/pretendard/dist/web/variable/pretendardvariable.min.css">
|
||||
<style>
|
||||
/* =====================================================================
|
||||
Vignette — AI 심리상담 시뮬레이션 훈련 플랫폼 · 로그인 시안 (단일 파일)
|
||||
토큰: DESIGN_CONCEPT.md §3 그대로. 외부 의존 = Pretendard CDN 1개.
|
||||
철칙: border-left 0 · 이모지 0(아이콘 inline SVG) · 카드덤프 0 ·
|
||||
순흑/순백 금지 · 강조는 weight/tint/kicker/dot로 · 넉넉한 여백.
|
||||
레이아웃: 좌(브랜드+가치제안 1문장) / 우(OAuth 진입). 에디토리얼 미니멀.
|
||||
===================================================================== */
|
||||
:root{
|
||||
/* 중성 베이스 (따뜻한 종이 + 잉크 네이비-그린) */
|
||||
--paper:#FBFAF8; --paper-2:#F4F2EE; --surface:#FFFFFF;
|
||||
--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;
|
||||
/* 의미색 */
|
||||
--info-text:#2E5A7A; --info-solid:#3C7299; --info-tint:#EAF1F6;
|
||||
/* stage / 좌측 브랜드 패널 */
|
||||
--bg-stage:#1E2724;
|
||||
/* 별칭 */
|
||||
--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-2:8px; --sp-3:12px; --sp-4:16px; --sp-5:24px; --sp-6:32px; --sp-7:48px; --sp-8:64px; --sp-9:96px;
|
||||
--radius:8px; --radius-sm:6px; --radius-lg:12px;
|
||||
--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);
|
||||
}
|
||||
*{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;}
|
||||
|
||||
/* ============ 공통 헤더 ============ */
|
||||
.topbar{
|
||||
height:56px; flex:none; background:var(--surface);
|
||||
border-bottom:1px solid var(--hair);
|
||||
display:flex; align-items:center; gap:var(--sp-5);
|
||||
padding:0 var(--sp-7);
|
||||
}
|
||||
.wordmark{display:flex; align-items:baseline; gap:9px; text-decoration:none;}
|
||||
.wordmark .nm{font-size:18px; font-weight:700; color:var(--ink); letter-spacing:-0.02em;}
|
||||
.wordmark .dot{width:6px; height:6px; border-radius:50%; background:var(--accent); align-self:center;}
|
||||
.wordmark .sub{font-family:var(--font-num); font-size:11px; font-weight:600; letter-spacing:0.1em; text-transform:uppercase; color:var(--ink-3);}
|
||||
.topbar .role{
|
||||
margin-left:auto; display:flex; align-items:center; gap:8px;
|
||||
font-size:12px; color:var(--ink-3); font-weight:500;
|
||||
}
|
||||
.topbar .role .pill{
|
||||
display:inline-flex; align-items:center; gap:7px;
|
||||
background:var(--accent-tint); color:var(--accent-deep);
|
||||
font-size:12px; font-weight:600; padding:5px 11px; border-radius:999px;
|
||||
}
|
||||
.topbar .role .pill .d{width:6px; height:6px; border-radius:50%; background:var(--accent);}
|
||||
.topbar .nav{display:flex; align-items:center; gap:var(--sp-5);}
|
||||
.topbar .nav a{font-size:13px; color:var(--ink-3); text-decoration:none; font-weight:500;}
|
||||
.topbar .nav a:hover{color:var(--ink-2);}
|
||||
.topbar .nav a.cur{color:var(--ink); font-weight:600;}
|
||||
|
||||
/* ============ 본문: 2분할 (좌 브랜드 / 우 진입) ============ */
|
||||
.shell{min-height:calc(100vh - 56px); display:grid; grid-template-columns:1.05fr 1fr;}
|
||||
|
||||
/* ---- LEFT: 브랜드 / 한 문장 가치제안 ---- */
|
||||
.brand{
|
||||
background:var(--bg-stage); color:#E8EEF2; position:relative; overflow:hidden;
|
||||
display:flex; flex-direction:column; justify-content:space-between;
|
||||
padding:var(--sp-9) var(--sp-8);
|
||||
}
|
||||
/* 은은한 광배 — 깊은 차콜그린 위 세이지/클레이 라디얼, 자극 없이 */
|
||||
.brand::before{
|
||||
content:""; position:absolute; width:520px; height:520px; border-radius:50%;
|
||||
top:-160px; right:-180px;
|
||||
background:radial-gradient(circle, rgba(95,150,139,.20) 0%, transparent 68%);
|
||||
animation:auraB 9s ease-in-out infinite;
|
||||
}
|
||||
.brand::after{
|
||||
content:""; position:absolute; width:380px; height:380px; border-radius:50%;
|
||||
bottom:-140px; left:-120px;
|
||||
background:radial-gradient(circle, rgba(176,115,92,.13) 0%, transparent 70%);
|
||||
}
|
||||
@keyframes auraB{0%,100%{opacity:.85; transform:scale(1)} 50%{opacity:1; transform:scale(1.04)}}
|
||||
|
||||
.brand .top{position:relative; z-index:1;}
|
||||
.brand .kicker{
|
||||
font-family:var(--font-num); font-size:12px; font-weight:600;
|
||||
letter-spacing:0.12em; text-transform:uppercase; color:rgba(232,238,242,.62);
|
||||
display:flex; align-items:center; gap:9px;
|
||||
}
|
||||
.brand .kicker .d{width:6px; height:6px; border-radius:50%; background:var(--accent-bright);}
|
||||
|
||||
.brand .lede{position:relative; z-index:1; max-width:480px;}
|
||||
.brand .lede h1{
|
||||
font-size:38px; line-height:1.32; font-weight:700; letter-spacing:-0.02em;
|
||||
color:#F2F6F6;
|
||||
}
|
||||
.brand .lede h1 .em{color:var(--accent-bright); font-weight:700;}
|
||||
.brand .lede p{
|
||||
margin-top:var(--sp-5); font-size:16px; line-height:1.7;
|
||||
color:rgba(232,238,242,.7); max-width:420px;
|
||||
}
|
||||
|
||||
/* 좌측 하단 메타 — 3역할 한 줄, 조용히 */
|
||||
.brand .foot{position:relative; z-index:1; display:flex; flex-direction:column; gap:var(--sp-4);}
|
||||
.brand .roles{display:flex; align-items:center; gap:var(--sp-5);}
|
||||
.brand .roles .r{display:flex; align-items:center; gap:9px; font-size:13px; color:rgba(232,238,242,.66);}
|
||||
.brand .roles .r .d{width:7px; height:7px; border-radius:50%;}
|
||||
.brand .roles .r .d.learner{background:var(--accent-bright);}
|
||||
.brand .roles .r .d.instructor{background:#5478C4;}
|
||||
.brand .roles .r .d.admin{background:#9DA1AE;}
|
||||
.brand .roles .sep{width:1px; height:13px; background:rgba(232,238,242,.18);}
|
||||
.brand .ethic{
|
||||
font-size:13px; line-height:1.6; color:rgba(232,238,242,.5);
|
||||
border-top:1px solid rgba(232,238,242,.12); padding-top:var(--sp-4); max-width:440px;
|
||||
}
|
||||
|
||||
/* ---- RIGHT: OAuth 진입 ---- */
|
||||
.enter{
|
||||
background:var(--paper);
|
||||
display:flex; align-items:center; justify-content:center;
|
||||
padding:var(--sp-8) var(--sp-7);
|
||||
}
|
||||
.panel{width:100%; max-width:392px;}
|
||||
|
||||
.panel .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; margin-bottom:var(--sp-4);
|
||||
}
|
||||
.panel .kicker .d{width:6px; height:6px; border-radius:50%; background:var(--accent-bright);}
|
||||
.panel h2{font-size:24px; font-weight:700; letter-spacing:-0.015em; color:var(--ink);}
|
||||
.panel .lead{margin-top:10px; font-size:15px; line-height:1.65; color:var(--ink-2); max-width:340px;}
|
||||
|
||||
/* OAuth 버튼 묶음 */
|
||||
.oauth{margin-top:var(--sp-7); display:flex; flex-direction:column; gap:var(--sp-3);}
|
||||
.oauth .obtn{
|
||||
width:100%; display:flex; align-items:center; gap:14px;
|
||||
padding:14px 18px; border-radius:var(--radius);
|
||||
font-family:var(--font-sans); font-size:15px; font-weight:600; cursor:pointer;
|
||||
transition:border-color .16s var(--ease-out), background .16s var(--ease-out), box-shadow .16s var(--ease-out);
|
||||
text-align:left;
|
||||
}
|
||||
/* 한신대 계정 = 주 경로 (accent, primary) */
|
||||
.oauth .obtn.primary{
|
||||
background:var(--accent); border:1px solid var(--accent); color:var(--text-on-accent);
|
||||
}
|
||||
.oauth .obtn.primary:hover{background:var(--accent-deep); border-color:var(--accent-deep);}
|
||||
.oauth .obtn.primary:focus-visible{outline:none; box-shadow:0 0 0 3px var(--focus-ring);}
|
||||
.oauth .obtn.primary .ic{background:rgba(251,250,248,.16);}
|
||||
.oauth .obtn.primary .ic svg{stroke:var(--text-on-accent);}
|
||||
.oauth .obtn.primary .sub{color:rgba(251,250,248,.72);}
|
||||
/* Google = 보조 경로 (surface, secondary) */
|
||||
.oauth .obtn.secondary{
|
||||
background:var(--surface); border:1px solid var(--neutral-150); color:var(--ink);
|
||||
}
|
||||
.oauth .obtn.secondary:hover{border-color:var(--neutral-200); background:#FCFCFB;}
|
||||
.oauth .obtn.secondary:focus-visible{outline:none; box-shadow:0 0 0 3px var(--focus-ring); border-color:var(--accent);}
|
||||
|
||||
.oauth .obtn .ic{
|
||||
width:34px; height:34px; border-radius:8px; flex:none;
|
||||
display:flex; align-items:center; justify-content:center;
|
||||
background:var(--paper-2);
|
||||
}
|
||||
.oauth .obtn .ic svg{width:19px; height:19px;}
|
||||
.oauth .obtn .txt{display:flex; flex-direction:column; gap:1px; line-height:1.4;}
|
||||
.oauth .obtn .sub{font-size:12px; font-weight:500; color:var(--ink-3);}
|
||||
.oauth .obtn .arrow{margin-left:auto; display:flex; align-items:center;}
|
||||
.oauth .obtn .arrow svg{width:18px; height:18px;}
|
||||
.oauth .obtn.primary .arrow svg{stroke:rgba(251,250,248,.8);}
|
||||
.oauth .obtn.secondary .arrow svg{stroke:var(--ink-3);}
|
||||
|
||||
/* 구분선 (텍스트 라벨, 좌측바 없음) */
|
||||
.divider{display:flex; align-items:center; gap:var(--sp-4); margin:var(--sp-5) 0;}
|
||||
.divider .ln{flex:1; height:1px; background:var(--hair);}
|
||||
.divider .lb{font-size:12px; color:var(--ink-3); font-weight:500; letter-spacing:0.02em;}
|
||||
|
||||
/* 비치료 도구 고지 (info tint, dot+kicker — 좌측바 금지) */
|
||||
.notice{
|
||||
background:var(--info-tint); border-radius:var(--radius);
|
||||
padding:14px 16px; display:flex; gap:11px; align-items:flex-start;
|
||||
}
|
||||
.notice .ic{flex:none; margin-top:1px;}
|
||||
.notice .ic svg{width:16px; height:16px; stroke:var(--info-solid); display:block;}
|
||||
.notice .tx{font-size:12.5px; line-height:1.6; color:var(--info-text);}
|
||||
.notice .tx b{font-weight:600;}
|
||||
|
||||
/* 하단 보조 링크 */
|
||||
.panel .help{
|
||||
margin-top:var(--sp-6); font-size:13px; color:var(--ink-3); line-height:1.7;
|
||||
}
|
||||
.panel .help a{color:var(--accent-deep); text-decoration:none; font-weight:600;}
|
||||
.panel .help a:hover{text-decoration:underline;}
|
||||
|
||||
/* ============ 반응형 ============ */
|
||||
@media (max-width:920px){
|
||||
.shell{grid-template-columns:1fr;}
|
||||
.brand{padding:var(--sp-8) var(--sp-7) var(--sp-7); min-height:auto; gap:var(--sp-7);}
|
||||
.brand .lede h1{font-size:30px;}
|
||||
.enter{padding:var(--sp-8) var(--sp-5);}
|
||||
.topbar{padding:0 var(--sp-5);}
|
||||
.topbar .nav{display:none;}
|
||||
}
|
||||
@media (max-width:520px){
|
||||
.brand .lede h1{font-size:26px;}
|
||||
.brand .roles{flex-wrap:wrap; gap:var(--sp-3) var(--sp-4);}
|
||||
.brand .roles .sep{display:none;}
|
||||
}
|
||||
@media (prefers-reduced-motion: reduce){
|
||||
*,*::before,*::after{animation-duration:.01ms!important; transition-duration:.01ms!important;}
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<!-- ============ 공통 헤더 ============ -->
|
||||
<header class="topbar">
|
||||
<a class="wordmark" href="#">
|
||||
<span class="nm">Vignette</span>
|
||||
<span class="dot"></span>
|
||||
<span class="sub">상담 시뮬레이션</span>
|
||||
</a>
|
||||
<nav class="nav">
|
||||
<a href="#" class="cur">로그인</a>
|
||||
<a href="#">소개</a>
|
||||
<a href="#">도움말</a>
|
||||
</nav>
|
||||
<div class="role">
|
||||
<span class="pill"><span class="d"></span>로그인 전</span>
|
||||
</div>
|
||||
</header>
|
||||
|
||||
<!-- ============ 본문 ============ -->
|
||||
<div class="shell">
|
||||
|
||||
<!-- LEFT: 브랜드 + 한 문장 가치제안 -->
|
||||
<section class="brand">
|
||||
<div class="top">
|
||||
<div class="kicker"><span class="d"></span>한신대학교 산학협력</div>
|
||||
</div>
|
||||
|
||||
<div class="lede">
|
||||
<h1>불안한 사람을 마주하는 연습을,<br><span class="em">안전한 자리</span>에서.</h1>
|
||||
<p>가상 내담자와 음성으로 상담을 나누고, 회기가 끝나면 조용히 관찰하던 평가 AI가 당신의 다음 한 마디를 함께 돌아봅니다.</p>
|
||||
</div>
|
||||
|
||||
<div class="foot">
|
||||
<div class="roles">
|
||||
<div class="r"><span class="d learner"></span>학습자</div>
|
||||
<span class="sep"></span>
|
||||
<div class="r"><span class="d instructor"></span>교수자</div>
|
||||
<span class="sep"></span>
|
||||
<div class="r"><span class="d admin"></span>관리자</div>
|
||||
</div>
|
||||
<div class="ethic">교육·훈련을 위한 시뮬레이션 도구입니다. 실제 심리치료나 임상 진단을 대체하지 않습니다.</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<!-- RIGHT: OAuth 진입 -->
|
||||
<section class="enter">
|
||||
<div class="panel">
|
||||
<div class="kicker"><span class="d"></span>계정으로 시작</div>
|
||||
<h2>다시 오셨네요.</h2>
|
||||
<p class="lead">학교 계정으로 들어오면 역할에 맞는 화면으로 바로 안내합니다.</p>
|
||||
|
||||
<div class="oauth">
|
||||
<!-- 한신대 계정 = 주 경로 -->
|
||||
<button class="obtn primary">
|
||||
<span class="ic">
|
||||
<svg viewBox="0 0 24 24" fill="none" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round">
|
||||
<path d="M3 9.5 12 4l9 5.5"/><path d="M5 11v7h14v-7"/><path d="M9 18v-4h6v4"/>
|
||||
</svg>
|
||||
</span>
|
||||
<span class="txt">
|
||||
한신대학교 계정으로 계속
|
||||
<span class="sub">@hs.ac.kr 통합 로그인</span>
|
||||
</span>
|
||||
<span class="arrow">
|
||||
<svg viewBox="0 0 24 24" fill="none" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><polyline points="9 6 15 12 9 18"/></svg>
|
||||
</span>
|
||||
</button>
|
||||
|
||||
<!-- Google = 보조 경로 -->
|
||||
<button class="obtn secondary">
|
||||
<span class="ic">
|
||||
<svg viewBox="0 0 24 24" aria-hidden="true">
|
||||
<path fill="#4285F4" d="M22.56 12.25c0-.78-.07-1.53-.2-2.25H12v4.26h5.92a5.06 5.06 0 0 1-2.2 3.32v2.76h3.56c2.08-1.92 3.28-4.74 3.28-8.09Z"/>
|
||||
<path fill="#34A853" d="M12 23c2.97 0 5.46-.98 7.28-2.66l-3.56-2.76c-.98.66-2.24 1.06-3.72 1.06-2.86 0-5.29-1.93-6.16-4.53H2.18v2.84A11 11 0 0 0 12 23Z"/>
|
||||
<path fill="#FBBC05" d="M5.84 14.11a6.6 6.6 0 0 1 0-4.22V7.05H2.18a11 11 0 0 0 0 9.9l3.66-2.84Z"/>
|
||||
<path fill="#EA4335" d="M12 5.38c1.62 0 3.06.56 4.21 1.64l3.15-3.15C17.45 2.09 14.97 1 12 1A11 11 0 0 0 2.18 7.05l3.66 2.84C6.71 7.29 9.14 5.38 12 5.38Z"/>
|
||||
</svg>
|
||||
</span>
|
||||
<span class="txt">
|
||||
Google 계정으로 계속
|
||||
<span class="sub">개인 Google 워크스페이스</span>
|
||||
</span>
|
||||
<span class="arrow">
|
||||
<svg viewBox="0 0 24 24" fill="none" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><polyline points="9 6 15 12 9 18"/></svg>
|
||||
</span>
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<div class="divider">
|
||||
<span class="ln"></span><span class="lb">안내</span><span class="ln"></span>
|
||||
</div>
|
||||
|
||||
<!-- 교육용 비치료 도구 고지 -->
|
||||
<div class="notice">
|
||||
<span class="ic">
|
||||
<svg viewBox="0 0 24 24" fill="none" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round">
|
||||
<circle cx="12" cy="12" r="9"/><line x1="12" y1="11" x2="12" y2="16"/><line x1="12" y1="8" x2="12" y2="8"/>
|
||||
</svg>
|
||||
</span>
|
||||
<span class="tx"><b>교육용 비치료 도구</b>입니다. 본 플랫폼의 가상 내담자·피드백은 상담 역량 훈련을 위한 것으로, 실제 치료·진단·위기 개입을 제공하지 않습니다.</span>
|
||||
</div>
|
||||
|
||||
<div class="help">
|
||||
계정 연결에 문제가 있나요? <a href="#">관리자에게 문의</a><br>
|
||||
처음이라면 담당 교수자에게 초대 코드를 받으세요.
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
</div>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
511
docs/mockups/professor.html
Normal file
511
docs/mockups/professor.html
Normal file
|
|
@ -0,0 +1,511 @@
|
|||
<!DOCTYPE html>
|
||||
<html lang="ko">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Vignette — 교수자 콘솔 (개입 필요 학생 triage)</title>
|
||||
<link rel="stylesheet" href="https://cdn.jsdelivr.net/gh/orioncactus/pretendard/dist/web/variable/pretendardvariable.min.css">
|
||||
<style>
|
||||
/* =====================================================================
|
||||
Vignette — 교수자 콘솔 (Instructor Console) 와이어
|
||||
토큰: DESIGN_CONCEPT.md §3 그대로. 역할 accent 오버라이드 §6.2 = 인디고-블루.
|
||||
화면 의도(§6.5): awareness가 아니라 triage. 최상단 = "개입 필요 학생" 액션 큐.
|
||||
철칙: 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 오버라이드: 교수자 = 인디고-블루(감독) */
|
||||
--accent:#3A5BA0; --accent-deep:#2E4A85; --accent-tint:#EAEFF7; --accent-bright:#5478C4;
|
||||
/* 보조 온기 (테라코타) — 화면당 1곳 */
|
||||
--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(58,91,160,.40);
|
||||
/* 폰트 */
|
||||
--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:1200px;
|
||||
--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);
|
||||
}
|
||||
*{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;}
|
||||
|
||||
/* ============ 공통 앱 셸: 톱바 ============ */
|
||||
.topbar{
|
||||
height:56px; background:var(--surface); border-bottom:1px solid var(--hair);
|
||||
display:flex; align-items:center; gap:var(--sp-6); padding:0 var(--sp-6);
|
||||
position:sticky; top:0; z-index:20;
|
||||
}
|
||||
.brand{display:flex; align-items:center; gap:10px;}
|
||||
.brand .mark{display:flex; align-items:center; justify-content:center; width:26px; height:26px;}
|
||||
.brand .mark svg{width:24px; height:24px;}
|
||||
.brand .wm{font-size:17px; font-weight:700; letter-spacing:-0.02em; color:var(--ink);}
|
||||
/* 역할 컨텍스트 라벨 (mono accent, 조용한 유일 신호) */
|
||||
.rolelabel{
|
||||
font-family:var(--font-num); font-size:13px; font-weight:600;
|
||||
letter-spacing:0.04em; color:var(--accent);
|
||||
padding-left:var(--sp-4); margin-left:var(--sp-2);
|
||||
border-left:1px solid var(--hair); /* 셸 구획 디바이더(강조선 아님) */
|
||||
}
|
||||
.nav{display:flex; align-items:center; gap:2px; margin-left:auto;}
|
||||
.nav a{
|
||||
font-size:13.5px; font-weight:500; color:var(--ink-3); text-decoration:none;
|
||||
padding:7px 12px; border-radius:var(--radius); transition:all .15s var(--ease-out);
|
||||
display:flex; align-items:center; gap:7px;
|
||||
}
|
||||
.nav a svg{width:16px; height:16px; stroke:currentColor; fill:none;}
|
||||
.nav a:hover{color:var(--ink-2); background:var(--neutral-100);}
|
||||
.nav a.on{color:var(--accent); background:var(--accent-tint); font-weight:600;}
|
||||
.topbar .me{display:flex; align-items:center; gap:9px; margin-left:var(--sp-4);}
|
||||
.topbar .me .av{width:30px; height:30px; border-radius:50%; background:var(--accent-tint);
|
||||
color:var(--accent); font-size:12px; font-weight:700; display:flex; align-items:center; justify-content:center;}
|
||||
.topbar .me .nm{font-size:13px; font-weight:600; color:var(--ink-2);}
|
||||
|
||||
/* ============ 본문 래퍼 ============ */
|
||||
.wrap{max-width:var(--maxw); margin:0 auto; padding:var(--sp-7) var(--sp-6) var(--sp-8);}
|
||||
.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);}
|
||||
|
||||
/* 페이지 헤드라인 (한 화면 한 메시지) */
|
||||
.head{margin-bottom:var(--sp-7);}
|
||||
.head .kicker{margin-bottom:var(--sp-3);}
|
||||
.head h1{font-size:30px; font-weight:700; letter-spacing:-0.02em; color:var(--ink); line-height:1.3;}
|
||||
.head h1 em{font-style:normal; color:var(--accent);}
|
||||
.head .sub{font-size:15px; color:var(--ink-3); margin-top:6px;}
|
||||
|
||||
/* 섹션 헤더(라벨 + 우측 컨트롤) */
|
||||
.sechead{display:flex; align-items:flex-end; justify-content:space-between; margin-bottom:var(--sp-4);}
|
||||
.sechead .lt .kicker{margin-bottom:5px;}
|
||||
.sechead .lt .desc{font-size:13px; color:var(--ink-3);}
|
||||
.sechead .rt{display:flex; gap:var(--sp-2);}
|
||||
.pill{
|
||||
font-size:12.5px; font-weight:500; color:var(--ink-2);
|
||||
background:var(--surface); border:1px solid var(--hair); border-radius:var(--radius);
|
||||
padding:6px 12px; display:inline-flex; align-items:center; gap:6px; cursor:pointer;
|
||||
transition:border-color .15s;
|
||||
}
|
||||
.pill:hover{border-color:var(--neutral-200);}
|
||||
.pill strong{color:var(--ink); font-weight:600;}
|
||||
.pill svg{width:13px; height:13px; stroke:var(--ink-3); fill:none;}
|
||||
|
||||
.block{margin-bottom:var(--sp-8);}
|
||||
|
||||
/* ============ 1. 개입 큐 (triage, 최우선 풀폭) ============ */
|
||||
.queue{
|
||||
background:var(--surface); border:1px solid var(--hair); border-radius:var(--radius-lg);
|
||||
box-shadow:var(--shadow-sm); overflow:hidden;
|
||||
}
|
||||
.qrow{
|
||||
display:grid; grid-template-columns:18px 150px 1fr 132px 22px;
|
||||
align-items:center; column-gap:var(--sp-4);
|
||||
padding:var(--sp-5) var(--sp-5); cursor:pointer;
|
||||
border-top:1px solid var(--paper-2); transition:background .14s var(--ease-out);
|
||||
}
|
||||
.qrow:first-child{border-top:none;}
|
||||
.qrow:hover{background:var(--accent-tint);}
|
||||
.qrow .dot{width:8px; height:8px; border-radius:50%; background:var(--crit-solid);}
|
||||
.qrow .who{display:flex; flex-direction:column; gap:2px;}
|
||||
.qrow .who .nm{font-size:16px; font-weight:700; color:var(--ink); letter-spacing:-0.01em;}
|
||||
.qrow .who .yr{font-size:12px; color:var(--ink-3);}
|
||||
.qrow .why{font-size:14px; color:var(--ink-2); line-height:1.5;}
|
||||
.qrow .why b{font-weight:600; color:var(--ink);}
|
||||
.qrow .why .num{font-family:var(--font-num); font-variant-numeric:tabular-nums; color:var(--crit-text); font-weight:600;}
|
||||
.qrow .last{font-size:12.5px; color:var(--ink-3); text-align:right;}
|
||||
.qrow .last .em{display:block; color:var(--warn-text); font-weight:600; font-size:12px; margin-top:2px;}
|
||||
.qrow .go{display:flex; justify-content:flex-end;}
|
||||
.qrow .go svg{width:18px; height:18px; stroke:var(--ink-3); fill:none; transition:stroke .14s, transform .14s var(--ease-out);}
|
||||
.qrow:hover .go svg{stroke:var(--accent); transform:translateX(2px);}
|
||||
|
||||
/* ============ 2. 학생별 현황 테이블 ============ */
|
||||
.tbl{width:100%; border-collapse:collapse; font-size:14px;}
|
||||
.tbl thead th{
|
||||
font-size:12px; font-weight:600; color:var(--ink-3); letter-spacing:0.02em;
|
||||
text-align:left; padding:0 var(--sp-3) var(--sp-3); border-bottom:1px solid var(--neutral-200);
|
||||
white-space:nowrap;
|
||||
}
|
||||
.tbl thead th.n{text-align:right;}
|
||||
.tbl tbody td{padding:var(--sp-4) var(--sp-3); border-bottom:1px solid var(--paper-2); vertical-align:middle;}
|
||||
.tbl tbody tr{cursor:pointer; transition:background .14s var(--ease-out);}
|
||||
.tbl tbody tr:hover{background:var(--accent-tint);}
|
||||
.tbl .st-nm{font-weight:600; color:var(--ink); white-space:nowrap;}
|
||||
.tbl .st-nm .id{display:block; font-size:11.5px; font-weight:400; color:var(--ink-3); margin-top:1px;}
|
||||
.tbl td.n{text-align:right; font-family:var(--font-num); font-variant-numeric:tabular-nums; color:var(--ink-2);}
|
||||
.tbl td.metric{text-align:right; font-family:var(--font-num); font-variant-numeric:tabular-nums; white-space:nowrap; color:var(--ink);}
|
||||
.tbl td.metric .ar{font-size:11px; margin-left:2px;}
|
||||
.ar.up{color:var(--pos-solid);} .ar.down{color:var(--warn-solid);} .ar.flat{color:var(--ink-3);}
|
||||
.tbl td.spark{width:78px;}
|
||||
.tbl td.spark svg{display:block;}
|
||||
.tbl td.last{color:var(--ink-3); font-family:var(--font-num); font-variant-numeric:tabular-nums; font-size:12.5px; white-space:nowrap;}
|
||||
.tbl td.state{white-space:nowrap;}
|
||||
.statetag{display:inline-flex; align-items:center; gap:7px; font-size:13px;}
|
||||
.statetag.ok{color:var(--ink-3);}
|
||||
.statetag.warn{color:var(--warn-text); font-weight:500;}
|
||||
.statetag.crit{color:var(--crit-text); font-weight:600;}
|
||||
.statetag .d{width:7px; height:7px; border-radius:50%;}
|
||||
.statetag.crit .d{background:var(--crit-solid);}
|
||||
.statetag.warn .d{background:var(--warn-solid);}
|
||||
.statetag.ok .d{background:var(--neutral-150);}
|
||||
|
||||
/* ============ 3. 반 전체 취약 영역 비교 (가로 막대) ============ */
|
||||
.compare{
|
||||
display:grid; grid-template-columns:1.35fr 1fr; gap:var(--sp-8); align-items:start;
|
||||
}
|
||||
.hbar-list{display:flex; flex-direction:column; gap:var(--sp-5);}
|
||||
.hbar .top{display:flex; align-items:baseline; justify-content:space-between; margin-bottom:8px;}
|
||||
.hbar .top .lb{font-size:14px; color:var(--ink); font-weight:500;}
|
||||
.hbar .top .tag{font-size:12px; font-weight:600; color:var(--warn-solid); display:inline-flex; align-items:center; gap:5px;}
|
||||
.hbar .top .tag svg{width:12px; height:12px; stroke:var(--warn-solid); fill:none;}
|
||||
.hbar .top .vv{font-family:var(--font-num); font-variant-numeric:tabular-nums; font-size:13px; color:var(--ink-2); font-weight:600;}
|
||||
.hbar .track{height:8px; background:var(--paper-2); border-radius:4px; overflow:hidden;}
|
||||
.hbar .track .fill{height:100%; border-radius:4px; background:var(--accent);}
|
||||
.hbar .track .fill.weak{background:var(--warn-solid);}
|
||||
.hbar .note{font-size:12px; color:var(--ink-3); margin-top:7px; line-height:1.5;}
|
||||
|
||||
/* 우측: 취약 영역 코칭 콜아웃 (info, 좌측바 없음 → tint+dot+kicker) */
|
||||
.insight{
|
||||
background:var(--accent-tint); border-radius:var(--radius-lg); padding:var(--sp-6);
|
||||
}
|
||||
.insight .clh{font-size:12px; font-weight:600; letter-spacing:0.04em; color:var(--accent-deep);
|
||||
display:flex; align-items:center; gap:8px; margin-bottom:var(--sp-3);}
|
||||
.insight .clh::before{content:""; width:7px; height:7px; border-radius:50%; background:var(--accent);}
|
||||
.insight h3{font-size:18px; font-weight:600; color:var(--ink); line-height:1.5; letter-spacing:-0.01em; margin-bottom:var(--sp-3);}
|
||||
.insight h3 em{font-style:normal; color:var(--accent-deep);}
|
||||
.insight p{font-size:13.5px; color:var(--ink-2); line-height:1.65;}
|
||||
.insight .act{
|
||||
margin-top:var(--sp-5); display:inline-flex; align-items:center; gap:7px;
|
||||
font-size:13.5px; font-weight:600; color:var(--text-on-accent);
|
||||
background:var(--accent); border:none; border-radius:var(--radius); padding:10px 16px; cursor:pointer;
|
||||
transition:background .16s;
|
||||
}
|
||||
.insight .act:hover{background:var(--accent-deep);}
|
||||
.insight .act svg{width:15px; height:15px; stroke:currentColor; fill:none;}
|
||||
|
||||
@media (prefers-reduced-motion: reduce){
|
||||
*,*::before,*::after{animation-duration:.01ms!important; transition-duration:.01ms!important;}
|
||||
}
|
||||
@media (max-width:980px){
|
||||
.compare{grid-template-columns:1fr;}
|
||||
.nav a span{display:none;}
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<!-- ============ 공통 앱 셸: 톱바 ============ -->
|
||||
<header class="topbar">
|
||||
<div class="brand">
|
||||
<span class="mark">
|
||||
<!-- 워드마크: 비네트(조리개) — inline SVG, 이모지 아님 -->
|
||||
<svg viewBox="0 0 24 24" fill="none" stroke="#3A5BA0" stroke-width="1.6">
|
||||
<circle cx="12" cy="12" r="9"/>
|
||||
<circle cx="12" cy="12" r="3.4" fill="#3A5BA0" stroke="none"/>
|
||||
<path d="M12 3.2 L12 8.6 M20.8 12 L15.4 12 M12 20.8 L12 15.4 M3.2 12 L8.6 12" stroke-linecap="round"/>
|
||||
</svg>
|
||||
</span>
|
||||
<span class="wm">Vignette</span>
|
||||
</div>
|
||||
<span class="rolelabel">교수 콘솔</span>
|
||||
|
||||
<nav class="nav">
|
||||
<a href="#" class="on">
|
||||
<svg viewBox="0 0 24 24" stroke-width="1.75"><path d="M3 13h8V3H3zM13 21h8V8h-8zM3 21h8v-5H3zM13 4h8V3h-8z" stroke-linecap="round" stroke-linejoin="round"/></svg>
|
||||
<span>대시보드</span>
|
||||
</a>
|
||||
<a href="#">
|
||||
<svg viewBox="0 0 24 24" stroke-width="1.75"><path d="M16 21v-2a4 4 0 0 0-4-4H6a4 4 0 0 0-4 4v2M9 11a4 4 0 1 0 0-8 4 4 0 0 0 0 8zM22 21v-2a4 4 0 0 0-3-3.87" stroke-linecap="round" stroke-linejoin="round"/></svg>
|
||||
<span>학습자</span>
|
||||
</a>
|
||||
<a href="#">
|
||||
<svg viewBox="0 0 24 24" stroke-width="1.75"><path d="M4 19.5A2.5 2.5 0 0 1 6.5 17H20M6.5 2H20v20H6.5A2.5 2.5 0 0 1 4 19.5v-15A2.5 2.5 0 0 1 6.5 2z" stroke-linecap="round" stroke-linejoin="round"/></svg>
|
||||
<span>시나리오</span>
|
||||
</a>
|
||||
<a href="#">
|
||||
<svg viewBox="0 0 24 24" stroke-width="1.75"><path d="M12 20V10M18 20V4M6 20v-4" stroke-linecap="round" stroke-linejoin="round"/></svg>
|
||||
<span>리포트</span>
|
||||
</a>
|
||||
</nav>
|
||||
|
||||
<div class="me">
|
||||
<span class="av">한교</span>
|
||||
<span class="nm">한지윤 교수</span>
|
||||
</div>
|
||||
</header>
|
||||
|
||||
<!-- ============ 본문 ============ -->
|
||||
<div class="wrap">
|
||||
|
||||
<!-- 페이지 헤드라인: 한 화면 한 메시지 -->
|
||||
<div class="head">
|
||||
<div class="kicker"><span class="dot"></span>상담실습 II · 28명 담당 · 4주차</div>
|
||||
<h1>이번 주, <em>3명에게 개입이 필요</em>합니다.</h1>
|
||||
<div class="sub">정체·하락 신호가 잡힌 학생을 먼저 보여드립니다. 나머지 25명은 안정 범위입니다.</div>
|
||||
</div>
|
||||
|
||||
<!-- 1. 개입 큐 (triage, 최우선) -->
|
||||
<section class="block">
|
||||
<div class="sechead">
|
||||
<div class="lt">
|
||||
<div class="kicker"><span class="dot"></span>개입 필요 학생</div>
|
||||
<div class="desc">수치 변화와 행동 신호로 정렬했습니다. 왜 올라왔는지 한 줄로 확인하고 바로 들어가세요.</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="queue">
|
||||
<div class="qrow">
|
||||
<span class="dot"></span>
|
||||
<div class="who"><span class="nm">박서연</span><span class="yr">상담심리 3학년</span></div>
|
||||
<div class="why">개입정확도 <b>3주 연속 하락</b> <span class="num">61 → 52 → 44</span> · 위기 신호 탐색에서 매번 화제를 돌림</div>
|
||||
<div class="last">최근 연습 6/19<span class="em">5일째 미연습</span></div>
|
||||
<div class="go"><svg viewBox="0 0 24 24" stroke-width="2"><polyline points="9 18 15 12 9 6" stroke-linecap="round" stroke-linejoin="round"/></svg></div>
|
||||
</div>
|
||||
<div class="qrow">
|
||||
<span class="dot"></span>
|
||||
<div class="who"><span class="nm">이도현</span><span class="yr">상담심리 3학년</span></div>
|
||||
<div class="why"><b>위기상담 시뮬 중도이탈 2회</b> · 자해 언급 장면에서 세션 강제 종료, 회피 패턴 반복</div>
|
||||
<div class="last">최근 연습 6/20<span class="em">이탈 직후 미복귀</span></div>
|
||||
<div class="go"><svg viewBox="0 0 24 24" stroke-width="2"><polyline points="9 18 15 12 9 6" stroke-linecap="round" stroke-linejoin="round"/></svg></div>
|
||||
</div>
|
||||
<div class="qrow">
|
||||
<span class="dot"></span>
|
||||
<div class="who"><span class="nm">최민준</span><span class="yr">상담심리 4학년</span></div>
|
||||
<div class="why">라포 점수 <b>급락</b> <span class="num">79 → 58</span> · 슈퍼바이저 <b>피드백 7건 미열람</b>, 같은 실수 반복</div>
|
||||
<div class="last">최근 연습 6/22<span class="em">피드백 7건 대기</span></div>
|
||||
<div class="go"><svg viewBox="0 0 24 24" stroke-width="2"><polyline points="9 18 15 12 9 6" stroke-linecap="round" stroke-linejoin="round"/></svg></div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<!-- 2. 담당 학습자 전체 현황 (테이블) -->
|
||||
<section class="block">
|
||||
<div class="sechead">
|
||||
<div class="lt">
|
||||
<div class="kicker"><span class="dot"></span>담당 학습자 현황</div>
|
||||
<div class="desc">행을 클릭하면 학습자별 세션·utterance 단위 평가로 들어갑니다.</div>
|
||||
</div>
|
||||
<div class="rt">
|
||||
<span class="pill">정렬 <strong>위험도</strong>
|
||||
<svg viewBox="0 0 24 24" stroke-width="2"><polyline points="6 9 12 15 18 9" stroke-linecap="round" stroke-linejoin="round"/></svg>
|
||||
</span>
|
||||
<span class="pill">영역 <strong>전체</strong>
|
||||
<svg viewBox="0 0 24 24" stroke-width="2"><polyline points="6 9 12 15 18 9" stroke-linecap="round" stroke-linejoin="round"/></svg>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<table class="tbl">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>학습자</th>
|
||||
<th class="n">세션</th>
|
||||
<th class="n">라포</th>
|
||||
<th class="n">기법</th>
|
||||
<th class="n">개입</th>
|
||||
<th class="n">공감</th>
|
||||
<th>추세 (최근 8회)</th>
|
||||
<th>최근 연습</th>
|
||||
<th>상태</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<!-- 개입 대상: red dot, 하향 화살표 위주 -->
|
||||
<tr>
|
||||
<td><span class="st-nm">박서연<span class="id">20231148</span></span></td>
|
||||
<td class="n">8</td>
|
||||
<td class="metric">55<span class="ar down">▼</span></td>
|
||||
<td class="metric">49<span class="ar down">▼</span></td>
|
||||
<td class="metric">44<span class="ar down">▼</span></td>
|
||||
<td class="metric">58<span class="ar down">▼</span></td>
|
||||
<td class="spark">
|
||||
<svg width="70" height="22" viewBox="0 0 70 22" fill="none">
|
||||
<polyline points="2,4 12,7 22,9 32,12 42,15 52,17 62,19 68,20" stroke="#C28A2C" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
<circle cx="68" cy="20" r="2.4" fill="#C4453A"/>
|
||||
</svg>
|
||||
</td>
|
||||
<td class="last">6/19</td>
|
||||
<td class="state"><span class="statetag crit"><span class="d"></span>개입</span></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><span class="st-nm">이도현<span class="id">20231152</span></span></td>
|
||||
<td class="n">14</td>
|
||||
<td class="metric">71<span class="ar flat">→</span></td>
|
||||
<td class="metric">66<span class="ar down">▼</span></td>
|
||||
<td class="metric">52<span class="ar down">▼</span></td>
|
||||
<td class="metric">70<span class="ar flat">→</span></td>
|
||||
<td class="spark">
|
||||
<svg width="70" height="22" viewBox="0 0 70 22" fill="none">
|
||||
<polyline points="2,8 12,6 22,9 32,7 42,11 52,9 62,14 68,12" stroke="#C28A2C" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
<circle cx="68" cy="12" r="2.4" fill="#C4453A"/>
|
||||
</svg>
|
||||
</td>
|
||||
<td class="last">6/20</td>
|
||||
<td class="state"><span class="statetag crit"><span class="d"></span>개입</span></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><span class="st-nm">최민준<span class="id">20221073</span></span></td>
|
||||
<td class="n">11</td>
|
||||
<td class="metric">58<span class="ar down">▼</span></td>
|
||||
<td class="metric">70<span class="ar flat">→</span></td>
|
||||
<td class="metric">64<span class="ar flat">→</span></td>
|
||||
<td class="metric">67<span class="ar down">▼</span></td>
|
||||
<td class="spark">
|
||||
<svg width="70" height="22" viewBox="0 0 70 22" fill="none">
|
||||
<polyline points="2,5 12,4 22,7 32,6 42,10 52,9 62,13 68,15" stroke="#C28A2C" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
<circle cx="68" cy="15" r="2.4" fill="#C4453A"/>
|
||||
</svg>
|
||||
</td>
|
||||
<td class="last">6/22</td>
|
||||
<td class="state"><span class="statetag crit"><span class="d"></span>개입</span></td>
|
||||
</tr>
|
||||
<!-- 살펴볼 점: warn -->
|
||||
<tr>
|
||||
<td><span class="st-nm">정유나<span class="id">20231130</span></span></td>
|
||||
<td class="n">9</td>
|
||||
<td class="metric">74<span class="ar up">▲</span></td>
|
||||
<td class="metric">62<span class="ar flat">→</span></td>
|
||||
<td class="metric">59<span class="ar down">▼</span></td>
|
||||
<td class="metric">71<span class="ar up">▲</span></td>
|
||||
<td class="spark">
|
||||
<svg width="70" height="22" viewBox="0 0 70 22" fill="none">
|
||||
<polyline points="2,14 12,12 22,13 32,10 42,11 52,9 62,8 68,9" stroke="#5A6663" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
<circle cx="68" cy="9" r="2.4" fill="#C28A2C"/>
|
||||
</svg>
|
||||
</td>
|
||||
<td class="last">6/23</td>
|
||||
<td class="state"><span class="statetag warn"><span class="d"></span>관찰</span></td>
|
||||
</tr>
|
||||
<!-- 양호: 무채 -->
|
||||
<tr>
|
||||
<td><span class="st-nm">김수련<span class="id">20221089</span></span></td>
|
||||
<td class="n">12</td>
|
||||
<td class="metric">82<span class="ar up">▲</span></td>
|
||||
<td class="metric">68<span class="ar flat">→</span></td>
|
||||
<td class="metric">61<span class="ar down">▼</span></td>
|
||||
<td class="metric">75<span class="ar up">▲</span></td>
|
||||
<td class="spark">
|
||||
<svg width="70" height="22" viewBox="0 0 70 22" fill="none">
|
||||
<polyline points="2,16 12,14 22,12 32,11 42,8 52,7 62,5 68,4" stroke="#5A6663" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
<circle cx="68" cy="4" r="2.4" fill="#3A5BA0"/>
|
||||
</svg>
|
||||
</td>
|
||||
<td class="last">6/24</td>
|
||||
<td class="state"><span class="statetag ok"><span class="d"></span>양호</span></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><span class="st-nm">한가람<span class="id">20231115</span></span></td>
|
||||
<td class="n">15</td>
|
||||
<td class="metric">88<span class="ar up">▲</span></td>
|
||||
<td class="metric">79<span class="ar up">▲</span></td>
|
||||
<td class="metric">71<span class="ar flat">→</span></td>
|
||||
<td class="metric">84<span class="ar up">▲</span></td>
|
||||
<td class="spark">
|
||||
<svg width="70" height="22" viewBox="0 0 70 22" fill="none">
|
||||
<polyline points="2,12 12,11 22,9 32,9 42,6 52,7 62,4 68,3" stroke="#5A6663" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
<circle cx="68" cy="3" r="2.4" fill="#3A5BA0"/>
|
||||
</svg>
|
||||
</td>
|
||||
<td class="last">6/24</td>
|
||||
<td class="state"><span class="statetag ok"><span class="d"></span>양호</span></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><span class="st-nm">오세진<span class="id">20221061</span></span></td>
|
||||
<td class="n">10</td>
|
||||
<td class="metric">79<span class="ar flat">→</span></td>
|
||||
<td class="metric">73<span class="ar up">▲</span></td>
|
||||
<td class="metric">68<span class="ar up">▲</span></td>
|
||||
<td class="metric">77<span class="ar flat">→</span></td>
|
||||
<td class="spark">
|
||||
<svg width="70" height="22" viewBox="0 0 70 22" fill="none">
|
||||
<polyline points="2,13 12,12 22,10 32,11 42,8 52,8 62,6 68,6" stroke="#5A6663" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
<circle cx="68" cy="6" r="2.4" fill="#3A5BA0"/>
|
||||
</svg>
|
||||
</td>
|
||||
<td class="last">6/23</td>
|
||||
<td class="state"><span class="statetag ok"><span class="d"></span>양호</span></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
<div style="margin-top:var(--sp-4); font-size:13px; color:var(--ink-3);">전체 28명 중 7명 표시 · <span style="color:var(--accent); font-weight:600; cursor:pointer;">21명 더 보기</span></div>
|
||||
</section>
|
||||
|
||||
<!-- 3. 반 전체 취약 영역 비교 -->
|
||||
<section class="block">
|
||||
<div class="sechead">
|
||||
<div class="lt">
|
||||
<div class="kicker"><span class="dot"></span>반 전체 취약 영역</div>
|
||||
<div class="desc">반 평균 역량을 비교합니다. 다 같이 못하는 기법이 다음 수업의 표적입니다.</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="compare">
|
||||
<!-- 가로 막대: 최저 항목만 강조, 나머지 무채 -->
|
||||
<div class="hbar-list">
|
||||
<div class="hbar">
|
||||
<div class="top"><span class="lb">반영적 경청</span><span class="vv">78</span></div>
|
||||
<div class="track"><div class="fill" style="width:78%"></div></div>
|
||||
</div>
|
||||
<div class="hbar">
|
||||
<div class="top"><span class="lb">라포 형성</span><span class="vv">74</span></div>
|
||||
<div class="track"><div class="fill" style="width:74%"></div></div>
|
||||
</div>
|
||||
<div class="hbar">
|
||||
<div class="top"><span class="lb">공감 반영</span><span class="vv">71</span></div>
|
||||
<div class="track"><div class="fill" style="width:71%"></div></div>
|
||||
</div>
|
||||
<div class="hbar">
|
||||
<div class="top"><span class="lb">개방형 질문</span><span class="vv">63</span></div>
|
||||
<div class="track"><div class="fill" style="width:63%"></div></div>
|
||||
</div>
|
||||
<div class="hbar">
|
||||
<div class="top">
|
||||
<span class="lb">위기 개입 정확도</span>
|
||||
<span class="tag">
|
||||
<svg viewBox="0 0 24 24" stroke-width="2"><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" stroke-linecap="round" stroke-linejoin="round"/></svg>
|
||||
가장 취약
|
||||
</span>
|
||||
</div>
|
||||
<div class="track"><div class="fill weak" style="width:47%"></div></div>
|
||||
<div class="note">28명 중 19명이 자해·위기 신호 장면에서 화제 전환 또는 성급한 안심시키기로 대응. 반 평균 47점.</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 우측 인사이트 콜아웃 (info tint, 좌측바 없음) -->
|
||||
<div class="insight">
|
||||
<div class="clh">이번 주 코칭 포커스</div>
|
||||
<h3>위기 개입에서 <em>침묵을 견디는 훈련</em>이 반 전체에 필요합니다.</h3>
|
||||
<p>자해 언급 직후 19명이 평균 1.8초 안에 화제를 돌렸습니다. 박서연·이도현·최민준의 하락도 모두 이 지점에서 시작됩니다. 위기 시나리오를 다음 합동 실습 과제로 배정하시겠어요?</p>
|
||||
<button class="act">
|
||||
위기 시나리오 과제 배정
|
||||
<svg viewBox="0 0 24 24" stroke-width="2"><polyline points="9 18 15 12 9 6" stroke-linecap="round" stroke-linejoin="round"/></svg>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
508
docs/mockups/session-review.html
Normal file
508
docs/mockups/session-review.html
Normal file
|
|
@ -0,0 +1,508 @@
|
|||
<!DOCTYPE html>
|
||||
<html lang="ko">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>한신대 AI 심리상담 시뮬레이션 — 회기 종료 리뷰 시안</title>
|
||||
<link rel="stylesheet" href="https://cdn.jsdelivr.net/gh/orioncactus/pretendard/dist/web/variable/pretendardvariable.min.css">
|
||||
<style>
|
||||
/* =====================================================================
|
||||
한신대 AI 심리상담 시뮬레이션 — 회기 종료 리뷰 화면 시안 (단일 파일)
|
||||
토큰: DESIGN_CONCEPT.md §3 그대로. 외부 의존 = Pretendard CDN 1개.
|
||||
철칙 준수: border-left 0 · 이모지 0 · 카드덤프 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;
|
||||
--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;
|
||||
--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);
|
||||
--maxw:1180px;
|
||||
}
|
||||
*{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;}
|
||||
.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; margin-bottom:var(--sp-4);
|
||||
}
|
||||
.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-6); padding:0 var(--sp-6);
|
||||
position:sticky; top:0; z-index:10;
|
||||
}
|
||||
.brand{display:flex; align-items:center; gap:10px; font-weight:700; font-size:16px; letter-spacing:-0.02em; color:var(--ink);}
|
||||
.brand .mk{width:22px; height:22px; display:flex; align-items:center; justify-content:center;}
|
||||
.nav{display:flex; align-items:center; gap:2px; margin-left:var(--sp-4);}
|
||||
.nav a{
|
||||
font-size:13px; font-weight:500; color:var(--ink-3); text-decoration:none;
|
||||
padding:7px 12px; border-radius:var(--radius-sm);
|
||||
}
|
||||
.nav a.on{color:var(--ink); font-weight:600; background:var(--accent-tint);}
|
||||
.topbar .spacer{flex:1;}
|
||||
.role{
|
||||
display:flex; align-items:center; gap:8px; font-size:12px; color:var(--ink-2); font-weight:500;
|
||||
padding:6px 12px; border:1px solid var(--hair); border-radius:999px;
|
||||
}
|
||||
.role .d{width:7px; height:7px; border-radius:50%; background:var(--accent);}
|
||||
|
||||
/* ============ 본문 래퍼 ============ */
|
||||
.wrap{max-width:var(--maxw); margin:0 auto; padding:var(--sp-7) var(--sp-6) var(--sp-8);}
|
||||
|
||||
/* ---- (1) 회기 요약 헤더 ---- */
|
||||
.review-head{margin-bottom:var(--sp-7);}
|
||||
.review-head .meta-row{
|
||||
display:flex; align-items:center; gap:var(--sp-4); flex-wrap:wrap;
|
||||
font-size:13px; color:var(--ink-3); margin-bottom:var(--sp-4);
|
||||
}
|
||||
.review-head .meta-row .scn{color:var(--ink-2); font-weight:600;}
|
||||
.review-head .meta-row .sep{width:3px; height:3px; border-radius:50%; background:var(--neutral-200);}
|
||||
.review-head .meta-row .tag{
|
||||
display:inline-flex; align-items:center; gap:7px;
|
||||
font-size:12px; font-weight:600; color:var(--accent-deep);
|
||||
background:var(--accent-tint); padding:4px 11px; border-radius:999px;
|
||||
}
|
||||
.review-head .meta-row .tag .d{width:6px; height:6px; border-radius:50%; background:var(--accent);}
|
||||
.review-head .summary{
|
||||
font-size:26px; line-height:1.45; font-weight:600; letter-spacing:-0.02em;
|
||||
color:var(--ink); max-width:880px; margin-bottom:var(--sp-5);
|
||||
}
|
||||
.review-head .summary .hl{color:var(--accent-deep);}
|
||||
.review-head .actions{display:flex; align-items:center; gap:var(--sp-3);}
|
||||
.btn-ghost{
|
||||
font-family:var(--font-sans); font-size:13px; font-weight:500; color:var(--ink-2);
|
||||
border:1px solid var(--hair); background:var(--surface); padding:9px 16px; border-radius:var(--radius);
|
||||
cursor:pointer; display:inline-flex; align-items:center; gap:8px;
|
||||
}
|
||||
.btn-ghost svg{width:15px; height:15px; stroke:var(--ink-2); fill:none;}
|
||||
.btn-ghost:hover{border-color:var(--neutral-200); color:var(--ink);}
|
||||
|
||||
/* ---- 2단 레이아웃 ---- */
|
||||
.cols{display:grid; grid-template-columns:1fr 360px; gap:var(--sp-7); align-items:start;}
|
||||
|
||||
/* ---- 가로 회기 타임라인 (단계 비례 막대) ---- */
|
||||
.phasebar{margin-bottom:var(--sp-6);}
|
||||
.phasebar .track{
|
||||
display:flex; height:38px; border-radius:var(--radius); overflow:hidden;
|
||||
border:1px solid var(--hair);
|
||||
}
|
||||
.phasebar .ph{
|
||||
display:flex; align-items:center; justify-content:center; gap:8px;
|
||||
font-size:12px; font-weight:600; color:var(--ink-2);
|
||||
position:relative; border-right:1px solid var(--hair);
|
||||
}
|
||||
.phasebar .ph:last-child{border-right:none;}
|
||||
.phasebar .ph.p1{background:var(--accent-tint);}
|
||||
.phasebar .ph.p2{background:color-mix(in srgb,var(--accent-tint) 60%, var(--surface));}
|
||||
.phasebar .ph.p3{background:color-mix(in srgb,var(--accent-tint) 35%, var(--surface));}
|
||||
.phasebar .ph.p4{background:var(--surface);}
|
||||
.phasebar .ph .pt{width:6px; height:6px; border-radius:50%; background:var(--accent-bright);}
|
||||
.phasebar .axis{
|
||||
display:flex; justify-content:space-between; margin-top:7px;
|
||||
font-family:var(--font-num); font-size:11px; color:var(--ink-3); letter-spacing:0.02em;
|
||||
}
|
||||
|
||||
/* ---- (2) 발화 타임라인 (대본 + 기법 라벨 + 코멘트) ---- */
|
||||
.timeline{display:flex; flex-direction:column;}
|
||||
.tl-turn{
|
||||
display:grid; grid-template-columns:64px 1fr; column-gap:var(--sp-4);
|
||||
padding:var(--sp-4) 0;
|
||||
}
|
||||
.tl-turn + .tl-turn{border-top:1px solid var(--paper-2);}
|
||||
.tl-rail{display:flex; flex-direction:column; align-items:center; gap:6px; padding-top:3px;}
|
||||
.tl-rail .ts{font-family:var(--font-num); font-size:11px; color:var(--ink-3); letter-spacing:0.02em;}
|
||||
.tl-rail .node{width:11px; height:11px; border-radius:50%; flex:none;}
|
||||
.tl-rail .node.learner{background:var(--accent-bright);}
|
||||
.tl-rail .node.client{background:var(--clay); opacity:.8;}
|
||||
.tl-rail .stem{width:2px; flex:1; min-height:8px; background:var(--hair);}
|
||||
|
||||
.tl-body .who{
|
||||
font-size:12px; font-weight:600; letter-spacing:0.02em; margin-bottom:5px;
|
||||
display:flex; align-items:center; gap:10px; flex-wrap:wrap;
|
||||
}
|
||||
.tl-body .who.learner{color:var(--accent-deep);}
|
||||
.tl-body .who.client{color:var(--clay-deep);}
|
||||
/* 기법 라벨 칩 (배경 틴트, border 없음) */
|
||||
.chip{
|
||||
display:inline-flex; align-items:center; gap:6px;
|
||||
font-size:11px; font-weight:600; letter-spacing:0; padding:2px 9px; border-radius:999px;
|
||||
}
|
||||
.chip .d{width:5px; height:5px; border-radius:50%;}
|
||||
.chip.empathy{background:var(--pos-tint); color:var(--pos-text);} .chip.empathy .d{background:var(--pos-solid);}
|
||||
.chip.explore{background:var(--accent-tint); color:var(--accent-deep);} .chip.explore .d{background:var(--accent);}
|
||||
.chip.reflect{background:var(--info-tint); color:var(--info-text);} .chip.reflect .d{background:var(--info-solid);}
|
||||
.chip.confront{background:var(--clay-tint); color:var(--clay-deep);} .chip.confront .d{background:var(--clay);}
|
||||
.chip.closed{background:var(--warn-tint); color:var(--warn-text);} .chip.closed .d{background:var(--warn-solid);}
|
||||
.tl-body .said{font-size:15px; line-height:1.6; color:var(--ink); max-width:600px;}
|
||||
.tl-body .said.client{color:var(--ink-2);}
|
||||
|
||||
/* 슈퍼바이저 코멘트 (들여쓰기, 좌측바 없음 → tint 블록 + kicker dot) */
|
||||
.sv{
|
||||
margin-top:var(--sp-3); padding:var(--sp-3) var(--sp-4); border-radius:var(--radius);
|
||||
max-width:600px;
|
||||
}
|
||||
.sv.good{background:var(--accent-tint);}
|
||||
.sv.grow{background:var(--warn-tint);}
|
||||
.sv .lab{
|
||||
font-size:11px; font-weight:600; letter-spacing:0.04em; margin-bottom:5px;
|
||||
display:flex; align-items:center; gap:7px;
|
||||
}
|
||||
.sv .lab .d{width:6px; height:6px; border-radius:50%;}
|
||||
.sv.good .lab{color:var(--accent-deep);} .sv.good .lab .d{background:var(--accent);}
|
||||
.sv.grow .lab{color:var(--warn-text);} .sv.grow .lab .d{background:var(--warn-solid);}
|
||||
.sv .lab .by{
|
||||
font-family:var(--font-num); font-size:10px; font-weight:600; letter-spacing:0.04em;
|
||||
color:var(--ink-3); margin-left:auto; text-transform:uppercase;
|
||||
}
|
||||
.sv .txt{font-size:13px; line-height:1.6; color:var(--ink-2);}
|
||||
.sv .txt .ex{color:var(--ink); font-style:italic;}
|
||||
|
||||
/* ---- 우측 분석 사이드 ---- */
|
||||
.side{display:flex; flex-direction:column; gap:var(--sp-7); position:sticky; top:88px;}
|
||||
.panel{}
|
||||
|
||||
/* 지표 변화 (라포 0.4 → 0.7) — 점수 아님, 서술+화살표 */
|
||||
.shift{display:flex; flex-direction:column; gap:var(--sp-5);}
|
||||
.shift .item .top{display:flex; align-items:baseline; justify-content:space-between; margin-bottom:9px;}
|
||||
.shift .item .nm{font-size:14px; font-weight:600; color:var(--ink);}
|
||||
.shift .item .delta{
|
||||
font-size:12px; font-weight:600; color:var(--pos-text);
|
||||
display:inline-flex; align-items:center; gap:6px;
|
||||
}
|
||||
.shift .item .delta svg{width:13px; height:13px; stroke:var(--pos-solid); fill:none;}
|
||||
.shift .item .delta.flat{color:var(--ink-3);} .shift .item .delta.flat svg{stroke:var(--ink-3);}
|
||||
/* 비교 막대: 시작(연함) → 종료(진함) 겹쳐 표현 */
|
||||
.shift .gauge{position:relative; height:6px; background:var(--paper-2); border-radius:3px; overflow:hidden;}
|
||||
.shift .gauge .start{position:absolute; left:0; top:0; height:100%; background:var(--neutral-150); border-radius:3px;}
|
||||
.shift .gauge .end{position:absolute; left:0; top:0; height:100%; background:var(--accent-bright); border-radius:3px;}
|
||||
.shift .gauge.clay .end{background:var(--clay);}
|
||||
.shift .item .lvl{
|
||||
display:flex; justify-content:space-between; margin-top:7px;
|
||||
font-size:11px; color:var(--ink-3);
|
||||
}
|
||||
.shift .item .lvl .now{color:var(--ink-2); font-weight:600;}
|
||||
|
||||
/* 잘한 점 / 개선점 리스트 */
|
||||
.points{display:flex; flex-direction:column; gap:var(--sp-3);}
|
||||
.points .pt{display:grid; grid-template-columns:auto 1fr; column-gap:11px; align-items:start;}
|
||||
.points .pt .mk{margin-top:6px; width:7px; height:7px; border-radius:50%; flex:none;}
|
||||
.points.good .mk{background:var(--pos-solid);}
|
||||
.points.grow .mk{background:var(--warn-solid);}
|
||||
.points .pt .body{}
|
||||
.points .pt .body .h{font-size:14px; font-weight:600; color:var(--ink); margin-bottom:2px;}
|
||||
.points .pt .body .d{font-size:13px; color:var(--ink-2); line-height:1.55;}
|
||||
.points .pt .body .d .at{font-family:var(--font-num); font-size:11px; color:var(--accent); font-weight:600; margin-left:6px;}
|
||||
|
||||
/* 다음 회기 한 문장 */
|
||||
.nextline{
|
||||
background:var(--accent-tint); border-radius:var(--radius); padding:var(--sp-4) var(--sp-5);
|
||||
margin-top:var(--sp-2);
|
||||
}
|
||||
.nextline .lab{
|
||||
font-family:var(--font-num); font-size:11px; font-weight:600; letter-spacing:0.06em;
|
||||
color:var(--accent-deep); margin-bottom:7px; text-transform:uppercase;
|
||||
}
|
||||
.nextline .q{font-size:14px; line-height:1.6; color:var(--ink); font-weight:500;}
|
||||
|
||||
hr.sep{border:none; border-top:1px solid var(--hair); margin:var(--sp-6) 0;}
|
||||
|
||||
@media (max-width:1080px){
|
||||
.cols{grid-template-columns:1fr;}
|
||||
.side{position:static;}
|
||||
}
|
||||
@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="mk">
|
||||
<svg viewBox="0 0 24 24" width="22" height="22" fill="none"><circle cx="12" cy="12" r="9" stroke="#3E7A6E" stroke-width="2"/><circle cx="12" cy="12" r="3.4" fill="#B0735C"/></svg>
|
||||
</span>
|
||||
Vignette
|
||||
</div>
|
||||
<nav class="nav">
|
||||
<a href="#">세션</a>
|
||||
<a href="#" class="on">리뷰</a>
|
||||
<a href="#">성장 기록</a>
|
||||
<a href="#">시나리오</a>
|
||||
</nav>
|
||||
<div class="spacer"></div>
|
||||
<div class="role"><span class="d"></span>학습자 · 김도현</div>
|
||||
</header>
|
||||
|
||||
<main class="wrap">
|
||||
|
||||
<!-- ============ (1) 회기 요약 헤더 ============ -->
|
||||
<header class="review-head">
|
||||
<div class="meta-row">
|
||||
<span class="kicker" style="margin:0;"><span class="dot"></span>회기 리뷰</span>
|
||||
<span class="sep"></span>
|
||||
<span class="scn">서연 · 17세 · 우울 호소 청소년</span>
|
||||
<span class="sep"></span>
|
||||
<span>회기 1 · 32분 14초 · 2026-06-25</span>
|
||||
<span class="tag"><span class="d"></span>탐색 단계까지 진행</span>
|
||||
</div>
|
||||
<h1 class="summary">
|
||||
라포는 <span class="hl">안정적으로 형성</span>됐어요. 다만 탐색 단계에서 닫힌 질문이 몇 차례 반복되면서,
|
||||
서연이 막 열기 시작한 자기개방이 잠깐씩 멈췄습니다.
|
||||
</h1>
|
||||
<div class="actions">
|
||||
<button class="btn-ghost">
|
||||
<svg viewBox="0 0 24 24" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><polygon points="5 3 19 12 5 21 5 3"/></svg>
|
||||
오디오 다시듣기
|
||||
</button>
|
||||
<button class="btn-ghost">
|
||||
<svg viewBox="0 0 24 24" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"/><polyline points="14 2 14 8 20 8"/></svg>
|
||||
PDF 내보내기
|
||||
</button>
|
||||
</div>
|
||||
</header>
|
||||
|
||||
<div class="cols">
|
||||
|
||||
<!-- ============ (2) 발화 타임라인 ============ -->
|
||||
<section>
|
||||
<!-- 가로 단계 타임라인 (너비 = 소요 비례) -->
|
||||
<div class="phasebar">
|
||||
<div class="kicker"><span class="dot"></span>회기 흐름</div>
|
||||
<div class="track">
|
||||
<div class="ph p1" style="flex:1.4"><span class="pt"></span>라포 형성</div>
|
||||
<div class="ph p2" style="flex:2.6"><span class="pt"></span>탐색</div>
|
||||
<div class="ph p3" style="flex:1.0"><span class="pt"></span>개입</div>
|
||||
<div class="ph p4" style="flex:0.8"><span class="pt"></span>정리</div>
|
||||
</div>
|
||||
<div class="axis tab-num"><span>00:00</span><span>09:12</span><span>24:30</span><span>32:14</span></div>
|
||||
</div>
|
||||
|
||||
<div class="kicker" style="margin-top:var(--sp-6);"><span class="dot"></span>발화 타임라인</div>
|
||||
<div class="timeline">
|
||||
|
||||
<!-- 턴 1: 학습자 개방형 질문 + 잘한 점 -->
|
||||
<div class="tl-turn">
|
||||
<div class="tl-rail">
|
||||
<span class="ts">10:42</span>
|
||||
<span class="node learner"></span>
|
||||
<span class="stem"></span>
|
||||
</div>
|
||||
<div class="tl-body">
|
||||
<div class="who learner">나 (학습자)
|
||||
<span class="chip explore"><span class="d"></span>탐색 · 개방형 질문</span>
|
||||
</div>
|
||||
<div class="said">학교에 가는 게 많이 버겁게 느껴지는 것 같아요. 혹시 어떤 순간이 가장 힘든지 조금 더 들려줄 수 있을까요?</div>
|
||||
<div class="sv good">
|
||||
<div class="lab"><span class="d"></span>잘한 점<span class="by">교수자</span></div>
|
||||
<div class="txt">서연이 먼저 꺼내기 어려워하던 지점을 압박 없이 열어줬어요. 시간 여유를 둔 표현("조금 더")이 안전감을 만들었습니다.</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 턴 2: 내담자 자기개방 -->
|
||||
<div class="tl-turn">
|
||||
<div class="tl-rail">
|
||||
<span class="ts">11:05</span>
|
||||
<span class="node client"></span>
|
||||
<span class="stem"></span>
|
||||
</div>
|
||||
<div class="tl-body">
|
||||
<div class="who client">서연 (내담자)</div>
|
||||
<div class="said client">아침에… 눈을 뜨면요. 그냥 천장만 보고 있어요. 일어나야 하는 건 아는데, 몸이 안 움직여요. 그게 제일… 무서워요.</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 턴 3: 학습자 공감 반영 + 잘한 점 -->
|
||||
<div class="tl-turn">
|
||||
<div class="tl-rail">
|
||||
<span class="ts">11:28</span>
|
||||
<span class="node learner"></span>
|
||||
<span class="stem"></span>
|
||||
</div>
|
||||
<div class="tl-body">
|
||||
<div class="who learner">나 (학습자)
|
||||
<span class="chip empathy"><span class="d"></span>공감 · 반영적 경청</span>
|
||||
</div>
|
||||
<div class="said">눈을 떠도 몸이 따라주지 않는 그 무력감이, 무섭게까지 느껴지는군요.</div>
|
||||
<div class="sv good">
|
||||
<div class="lab"><span class="d"></span>잘한 점<span class="by">AI 코멘트</span></div>
|
||||
<div class="txt">내담자의 단어("무서워요")를 그대로 반영하며 감정의 강도까지 받아냈어요. 직후 서연의 자기개방이 한 단계 깊어졌습니다.</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 턴 4: 학습자 닫힌 질문 (개선점) -->
|
||||
<div class="tl-turn">
|
||||
<div class="tl-rail">
|
||||
<span class="ts">16:54</span>
|
||||
<span class="node learner"></span>
|
||||
<span class="stem"></span>
|
||||
</div>
|
||||
<div class="tl-body">
|
||||
<div class="who learner">나 (학습자)
|
||||
<span class="chip closed"><span class="d"></span>닫힌 질문</span>
|
||||
</div>
|
||||
<div class="said">그럼 학교는 그냥 가기 싫은 거예요?</div>
|
||||
<div class="sv grow">
|
||||
<div class="lab"><span class="d"></span>살펴볼 점<span class="by">교수자</span></div>
|
||||
<div class="txt">'예/아니오'로 닫히는 질문이라 서연이 "그런 건 아니고요…" 하고 짧게 답했어요. 같은 의도를
|
||||
<span class="ex">"학교를 떠올리면 어떤 마음이 먼저 드는지 들려줄래요?"</span> 처럼 열어두면 자기개방이 이어졌을 거예요.</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 턴 5: 내담자 위축 반응 -->
|
||||
<div class="tl-turn">
|
||||
<div class="tl-rail">
|
||||
<span class="ts">17:10</span>
|
||||
<span class="node client"></span>
|
||||
<span class="stem"></span>
|
||||
</div>
|
||||
<div class="tl-body">
|
||||
<div class="who client">서연 (내담자)</div>
|
||||
<div class="said client">…그런 건 아니고요. 그냥… 모르겠어요.</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 턴 6: 학습자 회복 (직면 후 다시 탐색) -->
|
||||
<div class="tl-turn">
|
||||
<div class="tl-rail">
|
||||
<span class="ts">21:36</span>
|
||||
<span class="node learner"></span>
|
||||
<span class="stem" style="background:transparent;"></span>
|
||||
</div>
|
||||
<div class="tl-body">
|
||||
<div class="who learner">나 (학습자)
|
||||
<span class="chip reflect"><span class="d"></span>반영</span>
|
||||
<span class="chip explore"><span class="d"></span>탐색</span>
|
||||
</div>
|
||||
<div class="said">방금 잠깐 말문이 막혔던 것 같아요. 괜찮아요, 천천히 해도 돼요. 요즘 친구들과 함께 있을 때는 어떤 느낌이 드는지 궁금해요.</div>
|
||||
<div class="sv good">
|
||||
<div class="lab"><span class="d"></span>잘한 점<span class="by">AI 코멘트</span></div>
|
||||
<div class="txt">닫힌 질문 뒤 위축을 알아채고 페이스를 늦춘 회복이 좋았어요. 곧바로 열린 질문으로 전환해 대화가 다시 흐르기 시작했습니다.</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<!-- ============ 우측 분석 사이드 ============ -->
|
||||
<aside class="side">
|
||||
|
||||
<!-- (4) 이번 회기 지표 변화 -->
|
||||
<section class="panel">
|
||||
<div class="kicker"><span class="dot"></span>이번 회기 변화</div>
|
||||
<div class="shift">
|
||||
|
||||
<div class="item">
|
||||
<div class="top">
|
||||
<span class="nm">라포 형성</span>
|
||||
<span class="delta"><svg viewBox="0 0 24 24" stroke-width="2.4" stroke-linecap="round" stroke-linejoin="round"><line x1="7" y1="17" x2="17" y2="7"/><polyline points="9 7 17 7 17 15"/></svg>뚜렷이 깊어짐</span>
|
||||
</div>
|
||||
<div class="gauge">
|
||||
<div class="start" style="width:40%"></div>
|
||||
<div class="end" style="width:70%"></div>
|
||||
</div>
|
||||
<div class="lvl"><span>시작: 조심스러움</span><span class="now">종료: 신뢰가 자람</span></div>
|
||||
</div>
|
||||
|
||||
<div class="item">
|
||||
<div class="top">
|
||||
<span class="nm">자기개방</span>
|
||||
<span class="delta"><svg viewBox="0 0 24 24" stroke-width="2.4" stroke-linecap="round" stroke-linejoin="round"><line x1="7" y1="17" x2="17" y2="7"/><polyline points="9 7 17 7 17 15"/></svg>조금 열림</span>
|
||||
</div>
|
||||
<div class="gauge">
|
||||
<div class="start" style="width:25%"></div>
|
||||
<div class="end" style="width:52%"></div>
|
||||
</div>
|
||||
<div class="lvl"><span>시작: 단답 위주</span><span class="now">종료: 감정 단어 등장</span></div>
|
||||
</div>
|
||||
|
||||
<div class="item">
|
||||
<div class="top">
|
||||
<span class="nm">정서 안정</span>
|
||||
<span class="delta flat"><svg viewBox="0 0 24 24" stroke-width="2.4" stroke-linecap="round" stroke-linejoin="round"><line x1="6" y1="12" x2="18" y2="12"/></svg>비슷함</span>
|
||||
</div>
|
||||
<div class="gauge clay">
|
||||
<div class="start" style="width:38%"></div>
|
||||
<div class="end" style="width:42%"></div>
|
||||
</div>
|
||||
<div class="lvl"><span>시작: 위축·불안</span><span class="now">종료: 여전히 조심스러움</span></div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<hr class="sep">
|
||||
|
||||
<!-- (3) 슈퍼바이저 종합 — 잘한 점 -->
|
||||
<section class="panel">
|
||||
<div class="kicker"><span class="dot"></span>잘한 점</div>
|
||||
<div class="points good">
|
||||
<div class="pt"><span class="mk"></span><div class="body">
|
||||
<div class="h">감정을 그대로 받아낸 반영</div>
|
||||
<div class="d">서연의 표현을 빌려 무력감을 비춰줬고, 직후 자기개방이 깊어졌어요.<span class="at">11:28</span></div>
|
||||
</div></div>
|
||||
<div class="pt"><span class="mk"></span><div class="body">
|
||||
<div class="h">위축을 알아챈 회복</div>
|
||||
<div class="d">닫힌 질문 뒤 멈춤을 감지하고 페이스를 늦춰 안전감을 되찾았어요.<span class="at">21:36</span></div>
|
||||
</div></div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<!-- (3) 개선점 (최대 3, 빨강 남발 금지) -->
|
||||
<section class="panel">
|
||||
<div class="kicker"><span class="dot"></span>다음 회기 개선점</div>
|
||||
<div class="points grow">
|
||||
<div class="pt"><span class="mk"></span><div class="body">
|
||||
<div class="h">닫힌 질문을 열어두기</div>
|
||||
<div class="d">탐색 단계에서 '예/아니오' 질문이 3회 반복됐어요. 의도는 같아도 열린 형태로 바꿔보면 좋겠어요.<span class="at">16:54</span></div>
|
||||
</div></div>
|
||||
<div class="pt"><span class="mk"></span><div class="body">
|
||||
<div class="h">침묵을 조금 더 견디기</div>
|
||||
<div class="d">서연이 망설일 때 바로 다음 질문을 채우기보다, 잠깐의 여백을 두면 스스로 더 말할 공간이 생겨요.</div>
|
||||
</div></div>
|
||||
</div>
|
||||
<div class="nextline">
|
||||
<div class="lab">다음에 시도할 한 문장</div>
|
||||
<div class="q">"그 마음을 떠올리면, 가장 먼저 어떤 장면이 생각나는지 들려줄래요?"</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
</aside>
|
||||
</div>
|
||||
</main>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
635
docs/mockups/session-v2.html
Normal file
635
docs/mockups/session-v2.html
Normal 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>
|
||||
|
|
@ -1,486 +0,0 @@
|
|||
<!DOCTYPE html>
|
||||
<html lang="ko">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>한신대 AI 심리상담 시뮬레이션 — 상담 세션 화면 시안</title>
|
||||
<link rel="stylesheet" href="https://cdn.jsdelivr.net/gh/orioncactus/pretendard/dist/web/variable/pretendardvariable.min.css">
|
||||
<style>
|
||||
/* =====================================================================
|
||||
한신대 AI 심리상담 시뮬레이션 — 상담 세션 화면 시안 (단일 파일)
|
||||
토큰: DESIGN_CONCEPT.md §3 그대로 적용. 외부 의존 = Pretendard CDN 1개.
|
||||
철칙 준수: border-left 0 · 이모지 0 · 카드덤프 0 · 에디토리얼 미니멀 ·
|
||||
순흑/순백 금지 · 강조는 weight/tint/kicker/dot로.
|
||||
===================================================================== */
|
||||
:root{
|
||||
/* 중성 베이스 (따뜻한 종이 + 잉크 네이비-그린) */
|
||||
--paper:#FBFAF8; --paper-2:#F4F2EE; --surface:#FFFFFF;
|
||||
--neutral-150:#E5E1DA;
|
||||
--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;
|
||||
/* stage */
|
||||
--bg-stage:#1E2724;
|
||||
/* 별칭 */
|
||||
--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-2:8px; --sp-3:12px; --sp-4:16px; --sp-5:24px; --sp-6:32px;
|
||||
--radius:8px; --radius-sm:6px; --radius-lg:12px;
|
||||
--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);
|
||||
}
|
||||
*{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; overflow:hidden;
|
||||
}
|
||||
.tab-num{font-variant-numeric:tabular-nums;}
|
||||
|
||||
/* ============ 앱 셸 ============ */
|
||||
.app{display:flex; flex-direction:column; height:100vh; min-height:640px;}
|
||||
|
||||
/* 상단 바 */
|
||||
.topbar{
|
||||
height:56px; flex:none; background:var(--surface);
|
||||
border-bottom:1px solid var(--hair);
|
||||
display:flex; align-items:center; gap:var(--sp-5);
|
||||
padding:0 var(--sp-6);
|
||||
}
|
||||
.topbar .scn{display:flex; flex-direction:column; gap:1px;}
|
||||
.topbar .scn .k{
|
||||
font-family:var(--font-num); font-size:11px; font-weight:600;
|
||||
letter-spacing:0.1em; text-transform:uppercase; color:var(--accent);
|
||||
}
|
||||
.topbar .scn .t{font-size:14px; font-weight:600; color:var(--ink); letter-spacing:-0.01em;}
|
||||
.topbar .stagebar{
|
||||
margin:0 auto; display:flex; align-items:center; gap:var(--sp-4);
|
||||
}
|
||||
.topbar .stagebar .seg{display:flex; align-items:center; gap:7px;}
|
||||
.topbar .stagebar .seg .pt{width:7px; height:7px; border-radius:50%; background:var(--neutral-150);}
|
||||
.topbar .stagebar .seg.done .pt{background:var(--accent-bright);}
|
||||
.topbar .stagebar .seg.cur .pt{background:var(--accent); box-shadow:0 0 0 3px var(--accent-tint);}
|
||||
.topbar .stagebar .seg .lb{font-size:12px; color:var(--ink-3); font-weight:500;}
|
||||
.topbar .stagebar .seg.cur .lb{color:var(--ink); font-weight:600;}
|
||||
.topbar .stagebar .ln{width:18px; height:1px; background:var(--hair);}
|
||||
.topbar .right{display:flex; align-items:center; gap:var(--sp-5);}
|
||||
.topbar .elapsed{font-family:var(--font-num); font-size:14px; font-weight:600; color:var(--ink-2); letter-spacing:0.02em;}
|
||||
.topbar .elapsed .sub{font-size:11px; color:var(--ink-3); font-weight:500; margin-left:4px;}
|
||||
.topbar .obs{display:flex; align-items:center; gap:7px; font-size:12px; color:var(--ink-3);}
|
||||
.topbar .obs .d{width:6px; height:6px; border-radius:50%; background:var(--info-solid);}
|
||||
|
||||
/* 본문 3컬럼 */
|
||||
.main{flex:1; display:grid; grid-template-columns:320px 1fr 300px; min-height:0;}
|
||||
|
||||
/* ---- LEFT ---- */
|
||||
.left{
|
||||
background:var(--surface); border-right:1px solid var(--hair);
|
||||
padding:var(--sp-6) var(--sp-5); display:flex; flex-direction:column; gap:var(--sp-6);
|
||||
overflow:auto;
|
||||
}
|
||||
.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; margin-bottom:var(--sp-4);
|
||||
}
|
||||
.kicker .dot{width:6px; height:6px; border-radius:50%; background:var(--accent-bright);}
|
||||
|
||||
/* 회기 단계 세로 트랙커 */
|
||||
.tracker{display:flex; flex-direction:column;}
|
||||
.tk{display:grid; grid-template-columns:24px 1fr auto; align-items:center; column-gap:var(--sp-3); min-height:30px;}
|
||||
.tk .mk{position:relative; display:flex; justify-content:center;}
|
||||
.tk .mk .o{width:14px; height:14px; border-radius:50%; border:2px solid var(--neutral-150); background:var(--surface); z-index:1;}
|
||||
.tk.done .mk .o{background:var(--accent-bright); border-color:var(--accent-bright);}
|
||||
.tk.cur .mk .o{border-color:var(--accent); box-shadow:0 0 0 4px var(--accent-tint);}
|
||||
.tk.cur .mk .o::after{content:""; position:absolute; top:5px; left:50%; transform:translateX(-50%); width:6px; height:6px; border-radius:50%; background:var(--accent);}
|
||||
.tk .nm{font-size:15px; color:var(--ink-3); font-weight:500;}
|
||||
.tk.done .nm{color:var(--ink-2);}
|
||||
.tk.cur .nm{color:var(--ink); font-weight:700;}
|
||||
.tk .tm{font-family:var(--font-num); font-size:12px; color:var(--ink-3); letter-spacing:0.02em;}
|
||||
.tk.cur .tm{color:var(--accent); font-weight:600;}
|
||||
.tkline{grid-column:1; width:2px; height:14px; margin-left:11px; background:var(--hair);}
|
||||
.tkline.done{background:var(--accent-bright);}
|
||||
|
||||
/* 내담자 컨텍스트 카드 */
|
||||
.ctx .row{display:flex; flex-direction:column; gap:3px; padding:var(--sp-3) 0; border-bottom:1px solid var(--paper-2);}
|
||||
.ctx .row:last-child{border-bottom:none;}
|
||||
.ctx .row .l{font-size:12px; color:var(--ink-3); font-weight:500;}
|
||||
.ctx .row .v{font-size:14px; color:var(--ink); font-weight:500; line-height:1.5;}
|
||||
.ctx .row .v.em{font-weight:700;}
|
||||
|
||||
/* ---- CENTER STAGE ---- */
|
||||
.stage{
|
||||
background:var(--bg-stage); position:relative;
|
||||
display:flex; flex-direction:column; align-items:center;
|
||||
padding:var(--sp-6) var(--sp-6) 0;
|
||||
min-height:0;
|
||||
}
|
||||
.stage .label{
|
||||
position:absolute; top:18px; left:50%; transform:translateX(-50%);
|
||||
font-family:var(--font-num); font-size:11px; font-weight:600;
|
||||
letter-spacing:0.12em; text-transform:uppercase; color:rgba(232,238,242,.55);
|
||||
display:flex; align-items:center; gap:8px;
|
||||
}
|
||||
.stage .label .d{width:6px; height:6px; border-radius:50%; background:var(--clay);}
|
||||
|
||||
/* 아바타 + 오브 */
|
||||
.avatarwrap{
|
||||
margin-top:44px; position:relative; width:240px; height:240px;
|
||||
display:flex; align-items:center; justify-content:center; flex:none;
|
||||
}
|
||||
.orb{
|
||||
position:absolute; inset:6px; border-radius:50%;
|
||||
box-shadow:0 0 0 3px var(--ring), 0 0 30px 6px var(--ring-glow);
|
||||
--ring:rgba(176,115,92,.55); --ring-glow:rgba(176,115,92,.30);
|
||||
animation:orbpulse 4.2s ease-in-out infinite;
|
||||
}
|
||||
@keyframes orbpulse{0%,100%{transform:scale(1); opacity:.9} 50%{transform:scale(1.03); opacity:1}}
|
||||
.avatar{width:200px; height:200px; border-radius:50%; overflow:visible; display:block;}
|
||||
/* 호흡: 어깨 미세 상하 */
|
||||
.av-body{animation:breathe 3.6s ease-in-out infinite; transform-origin:center bottom;}
|
||||
@keyframes breathe{0%,100%{transform:translateY(0)} 50%{transform:translateY(2px)}}
|
||||
/* 깜빡임 */
|
||||
.av-eyes{animation:blink 6s steps(1) infinite; transform-origin:center; transform-box:fill-box;}
|
||||
@keyframes blink{0%,95%,100%{transform:scaleY(1)} 97.5%{transform:scaleY(0.1)}}
|
||||
|
||||
/* 페르소나 메타 */
|
||||
.persona{margin-top:26px; text-align:center; color:#E8EEF2;}
|
||||
.persona .nm{font-size:19px; font-weight:600; letter-spacing:-0.01em;}
|
||||
.persona .meta{font-size:13px; color:rgba(232,238,242,.6); margin-top:4px;}
|
||||
.persona .div{width:36px; height:1px; background:rgba(232,238,242,.2); margin:12px auto;}
|
||||
.persona .state{font-size:14px; color:rgba(232,238,242,.78); display:flex; align-items:center; gap:8px; justify-content:center;}
|
||||
.persona .state .d{width:6px; height:6px; border-radius:50%; background:var(--clay); animation:orbpulse 4.2s ease-in-out infinite;}
|
||||
|
||||
/* 자막 (대본 스타일) */
|
||||
.transcript{
|
||||
width:100%; max-width:680px; flex:1; min-height:0; margin-top:22px;
|
||||
overflow:auto; display:flex; flex-direction:column; gap:var(--sp-4);
|
||||
padding-bottom:var(--sp-6); -webkit-mask-image:linear-gradient(to bottom,transparent 0,#000 28px);
|
||||
}
|
||||
.turn{padding:var(--sp-3) var(--sp-4); border-radius:var(--radius);}
|
||||
.turn.client{background:rgba(176,115,92,.14);}
|
||||
.turn.learner{background:rgba(95,150,139,.16);}
|
||||
.turn .head{display:flex; justify-content:space-between; align-items:baseline; margin-bottom:5px;}
|
||||
.turn .who{font-size:12px; font-weight:600; letter-spacing:0.02em;}
|
||||
.turn.client .who{color:#E2B79F;}
|
||||
.turn.learner .who{color:#A9D2C6;}
|
||||
.turn .ts{font-family:var(--font-num); font-size:11px; color:rgba(232,238,242,.45);}
|
||||
.turn .tx{font-size:16px; line-height:1.65; color:#DDE5E4;}
|
||||
.turn .tx.partial{color:rgba(221,229,228,.5);}
|
||||
.turn .tx .cursor{display:inline-block; width:2px; height:1.05em; background:#A9D2C6; vertical-align:-2px; margin-left:2px; animation:cur 1s steps(1) infinite;}
|
||||
@keyframes cur{0%,50%{opacity:1}50.01%,100%{opacity:0}}
|
||||
|
||||
/* ---- RIGHT (피드백 레일) ---- */
|
||||
.right{
|
||||
background:var(--surface); border-left:1px solid var(--hair);
|
||||
padding:var(--sp-6) var(--sp-5); display:flex; flex-direction:column; gap:var(--sp-6);
|
||||
overflow:auto;
|
||||
}
|
||||
/* 내담자 상태 미터 */
|
||||
.meter{display:flex; flex-direction:column; gap:var(--sp-4);}
|
||||
.meter .m .top{display:flex; justify-content:space-between; align-items:baseline; margin-bottom:7px;}
|
||||
.meter .m .nm{font-size:13px; color:var(--ink-2); font-weight:500;}
|
||||
.meter .m .val{font-size:13px; color:var(--ink); font-weight:600;}
|
||||
.meter .m .bar{height:4px; background:var(--paper-2); border-radius:2px; overflow:hidden;}
|
||||
.meter .m .bar .fill{height:100%; border-radius:2px; transition:width 2s var(--ease-out);}
|
||||
.meter .m .bar .fill.clay{background:var(--clay);}
|
||||
.meter .m .bar .fill.sage{background:var(--accent-bright);}
|
||||
|
||||
/* 라이브 신호 (앰비언트) */
|
||||
.signal{display:flex; flex-direction:column; gap:var(--sp-4);}
|
||||
.signal .live{
|
||||
display:flex; align-items:center; gap:10px;
|
||||
padding:var(--sp-3) 0;
|
||||
animation:fadein .4s var(--ease-out);
|
||||
}
|
||||
@keyframes fadein{from{opacity:0; transform:translateY(3px)}to{opacity:1; transform:none}}
|
||||
.signal .live .d{width:9px; height:9px; border-radius:50%; flex:none;}
|
||||
.signal .live .d.pos{background:var(--pos-solid);}
|
||||
.signal .live .d.warn{background:var(--warn-solid);}
|
||||
.signal .live .nm{font-size:14px; color:var(--ink); font-weight:500;}
|
||||
.signal .live .nm .sub{font-size:12px; color:var(--ink-3); font-weight:400; display:block; margin-top:1px;}
|
||||
.signal .seq{display:flex; align-items:center; gap:9px; padding-top:var(--sp-2); border-top:1px solid var(--paper-2);}
|
||||
.signal .seq .sl{font-size:11px; color:var(--ink-3); font-weight:500; letter-spacing:0.02em;}
|
||||
.signal .seq .dots{display:flex; gap:7px; align-items:center;}
|
||||
.signal .seq .dots span{width:7px; height:7px; border-radius:50%;}
|
||||
.signal .seq .dots .pos{background:var(--pos-solid);}
|
||||
.signal .seq .dots .warn{background:var(--warn-solid);}
|
||||
.signal .seq .dots .neu{background:var(--neutral-150);}
|
||||
|
||||
/* 안전 점검 콜아웃 (warn, 좌측바 없음 → dot+kicker+tint) */
|
||||
.callout{border-radius:var(--radius); padding:var(--sp-4); background:var(--warn-tint);}
|
||||
.callout .clh{font-size:12px; font-weight:600; letter-spacing:0.04em; color:var(--warn-text); display:flex; align-items:center; gap:8px; margin-bottom:6px;}
|
||||
.callout .clh::before{content:""; width:7px; height:7px; border-radius:50%; background:var(--warn-solid);}
|
||||
.callout .cl{font-size:13px; color:var(--warn-text); line-height:1.55;}
|
||||
|
||||
/* 셀프 노트 */
|
||||
.note textarea{
|
||||
width:100%; min-height:78px; resize:none;
|
||||
background:var(--paper-2); border:1px solid var(--hair); border-radius:var(--radius-sm);
|
||||
padding:10px 12px; font-family:var(--font-sans); font-size:13px; color:var(--ink); line-height:1.6;
|
||||
}
|
||||
.note textarea::placeholder{color:var(--ink-3);}
|
||||
.note textarea:focus{outline:none; border-color:var(--accent); box-shadow:0 0 0 3px var(--focus-ring);}
|
||||
|
||||
/* ============ 하단 컨트롤 바 ============ */
|
||||
.controls{
|
||||
height:84px; flex:none; background:var(--surface); border-top:1px solid var(--hair);
|
||||
display:grid; grid-template-columns:1fr auto 1fr; align-items:center;
|
||||
padding:0 var(--sp-6); gap:var(--sp-5);
|
||||
}
|
||||
.controls .mic{display:flex; align-items:center; gap:var(--sp-4);}
|
||||
.controls .mic .btn{
|
||||
width:52px; height:52px; border-radius:50%; flex:none; border:none; cursor:pointer;
|
||||
background:var(--accent); display:flex; align-items:center; justify-content:center;
|
||||
animation:micbreath 1.5s ease-in-out infinite;
|
||||
}
|
||||
@keyframes micbreath{0%,100%{box-shadow:0 0 0 0 rgba(62,122,110,.35)}50%{box-shadow:0 0 0 7px rgba(62,122,110,0)}}
|
||||
.controls .mic .btn svg{width:22px; height:22px; stroke:var(--text-on-accent);}
|
||||
.controls .mic .lbl{display:flex; flex-direction:column; gap:1px;}
|
||||
.controls .mic .lbl .s{font-size:14px; font-weight:600; color:var(--ink);}
|
||||
.controls .mic .lbl .h{font-size:12px; color:var(--ink-3);}
|
||||
|
||||
/* segmented control (피드백 모드) */
|
||||
.modeseg{display:flex; background:var(--paper-2); border-radius:var(--radius); padding:3px; gap:2px; justify-self:center;}
|
||||
.modeseg button{
|
||||
font-family:var(--font-sans); font-size:13px; font-weight:500; color:var(--ink-2);
|
||||
border:none; background:transparent; padding:8px 16px; border-radius:6px; cursor:pointer;
|
||||
transition:all .16s var(--ease-out);
|
||||
}
|
||||
.modeseg button.on{background:var(--surface); color:var(--ink); font-weight:600; box-shadow:var(--shadow-sm);}
|
||||
|
||||
.controls .rightc{display:flex; align-items:center; gap:var(--sp-4); justify-self:end;}
|
||||
.btn-ghost{
|
||||
font-family:var(--font-sans); font-size:14px; font-weight:500; color:var(--ink-2);
|
||||
border:1px solid var(--hair); background:var(--surface); padding:9px 16px; border-radius:var(--radius); cursor:pointer;
|
||||
display:flex; align-items:center; gap:8px;
|
||||
}
|
||||
.btn-ghost svg{width:16px; height:16px; stroke:var(--ink-2);}
|
||||
/* 밀어서 종료 */
|
||||
.slide-end{
|
||||
position:relative; width:148px; height:40px; border-radius:var(--radius);
|
||||
background:var(--crit-tint); overflow:hidden; cursor:pointer; user-select:none;
|
||||
}
|
||||
.slide-end .track{position:absolute; inset:0; display:flex; align-items:center; justify-content:center;
|
||||
font-size:13px; font-weight:600; color:var(--crit-text); letter-spacing:0.01em;}
|
||||
.slide-end .knob{position:absolute; top:3px; left:3px; width:34px; height:34px; border-radius:6px;
|
||||
background:var(--crit-solid); display:flex; align-items:center; justify-content:center;}
|
||||
.slide-end .knob svg{width:16px; height:16px; stroke:#fff;}
|
||||
|
||||
@media (prefers-reduced-motion: reduce){
|
||||
*,*::before,*::after{animation-duration:.01ms!important; transition-duration:.01ms!important;}
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="app">
|
||||
|
||||
<!-- ============ 상단 바 ============ -->
|
||||
<header class="topbar">
|
||||
<div class="scn">
|
||||
<span class="k">LIVE SESSION</span>
|
||||
<span class="t">우울 호소 청소년 · 회기 1</span>
|
||||
</div>
|
||||
<div class="stagebar">
|
||||
<div class="seg done"><span class="pt"></span><span class="lb">라포</span></div>
|
||||
<span class="ln"></span>
|
||||
<div class="seg cur"><span class="pt"></span><span class="lb">탐색</span></div>
|
||||
<span class="ln"></span>
|
||||
<div class="seg"><span class="pt"></span><span class="lb">개입</span></div>
|
||||
<span class="ln"></span>
|
||||
<div class="seg"><span class="pt"></span><span class="lb">정리</span></div>
|
||||
</div>
|
||||
<div class="right">
|
||||
<div class="obs"><span class="d"></span>교수자 관찰 중</div>
|
||||
<div class="elapsed tab-num">12:41<span class="sub">경과</span></div>
|
||||
</div>
|
||||
</header>
|
||||
|
||||
<!-- ============ 본문 3컬럼 ============ -->
|
||||
<div class="main">
|
||||
|
||||
<!-- LEFT: 회기 단계 + 내담자 컨텍스트 -->
|
||||
<aside class="left">
|
||||
<section>
|
||||
<div class="kicker"><span class="dot"></span>회기 진행</div>
|
||||
<div class="tracker">
|
||||
<div class="tk done"><div class="mk"><span class="o"></span></div><div class="nm">라포 형성</div><div class="tm tab-num">09:12</div></div>
|
||||
<div class="tkline done"></div>
|
||||
<div class="tk cur"><div class="mk"><span class="o"></span></div><div class="nm">탐색</div><div class="tm">진행중</div></div>
|
||||
<div class="tkline"></div>
|
||||
<div class="tk"><div class="mk"><span class="o"></span></div><div class="nm">개입</div><div class="tm"></div></div>
|
||||
<div class="tkline"></div>
|
||||
<div class="tk"><div class="mk"><span class="o"></span></div><div class="nm">정리</div><div class="tm"></div></div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section class="ctx">
|
||||
<div class="kicker"><span class="dot"></span>내담자 정보</div>
|
||||
<div class="row"><span class="l">호소 문제</span><span class="v em">2주째 무기력 · 등교 거부</span></div>
|
||||
<div class="row"><span class="l">시작 정서</span><span class="v">위축 · 방어적, 자기개방 낮음</span></div>
|
||||
<div class="row"><span class="l">배경</span><span class="v">고2 · 최근 성적 하락 · 또래 관계 위축</span></div>
|
||||
<div class="row"><span class="l">연습 목표</span><span class="v em">개방형 질문으로 자기개방 끌어내기</span></div>
|
||||
</section>
|
||||
</aside>
|
||||
|
||||
<!-- CENTER: 내담자 아바타 + 음성 오브 + 자막 -->
|
||||
<main class="stage">
|
||||
<div class="label"><span class="d"></span>교육용 가상 내담자</div>
|
||||
|
||||
<div class="avatarwrap">
|
||||
<div class="orb"></div>
|
||||
<!-- 반구상 양식화 흉상 (사실성 ~40%): 코·주름·모공 없음, 눈/눈썹/입/어깨 4채널 -->
|
||||
<svg class="avatar" viewBox="0 0 200 200" aria-label="가상 내담자 서연">
|
||||
<defs>
|
||||
<radialGradient id="aura" cx="50%" cy="42%" r="58%">
|
||||
<stop offset="0%" stop-color="#2E3A36"/>
|
||||
<stop offset="100%" stop-color="#1E2724"/>
|
||||
</radialGradient>
|
||||
<clipPath id="head"><circle cx="100" cy="100" r="96"/></clipPath>
|
||||
</defs>
|
||||
<g clip-path="url(#head)">
|
||||
<rect width="200" height="200" fill="url(#aura)"/>
|
||||
<g class="av-body">
|
||||
<!-- 어깨/상체 실루엣 (후디, 디테일 없음) -->
|
||||
<path d="M44 200 C44 168 66 150 100 150 C134 150 156 168 156 200 Z" fill="#3C4A45"/>
|
||||
<!-- 목 -->
|
||||
<rect x="88" y="120" width="24" height="26" rx="11" fill="#E8C9A8"/>
|
||||
<!-- 머리카락 뒤 -->
|
||||
<path d="M58 96 C58 64 76 50 100 50 C124 50 142 64 142 96 L142 124 C142 122 138 110 132 108 L132 92 C132 76 118 70 100 70 C82 70 68 76 68 92 L68 108 C62 110 58 122 58 124 Z" fill="#2B2723"/>
|
||||
<!-- 얼굴 -->
|
||||
<path d="M70 92 C70 74 83 64 100 64 C117 64 130 74 130 92 L130 108 C130 126 117 138 100 138 C83 138 70 126 70 108 Z" fill="#E8C9A8"/>
|
||||
<!-- 눈썹 (정서: 약간 안쪽 하강 = 위축/불안) -->
|
||||
<path d="M80 92 q9 -3 18 0" stroke="#3A322C" stroke-width="2.4" fill="none" stroke-linecap="round"/>
|
||||
<path d="M102 92 q9 -3 18 0" stroke="#3A322C" stroke-width="2.4" fill="none" stroke-linecap="round"/>
|
||||
<!-- 눈 (큰 눈 = teen, 시선 살짝 아래) -->
|
||||
<g class="av-eyes">
|
||||
<ellipse cx="89" cy="102" rx="6.2" ry="5" fill="#FBFAF8"/>
|
||||
<ellipse cx="111" cy="102" rx="6.2" ry="5" fill="#FBFAF8"/>
|
||||
<circle cx="88.5" cy="103.5" r="3.1" fill="#3A2E26"/>
|
||||
<circle cx="110.5" cy="103.5" r="3.1" fill="#3A2E26"/>
|
||||
</g>
|
||||
<!-- 입 (닫힘 호 = listening 상태, 미세 긴장) -->
|
||||
<path d="M91 120 q9 4 18 0" stroke="#9A6A56" stroke-width="2.2" fill="none" stroke-linecap="round"/>
|
||||
<!-- 앞머리 -->
|
||||
<path d="M68 92 L68 86 C68 72 82 66 100 66 C118 66 132 72 132 86 L132 92 C128 80 116 78 108 80 C104 81 100 84 96 84 C88 84 76 82 68 92 Z" fill="#2B2723"/>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
</div>
|
||||
|
||||
<div class="persona">
|
||||
<div class="nm">서연</div>
|
||||
<div class="meta">17세 · 고2</div>
|
||||
<div class="div"></div>
|
||||
<div class="state"><span class="d"></span>머뭇거리며 말하는 중</div>
|
||||
</div>
|
||||
|
||||
<!-- 자막 (대본 스타일, 아래→위 흐름) -->
|
||||
<div class="transcript">
|
||||
<div class="turn learner">
|
||||
<div class="head"><span class="who">나 (학습자)</span><span class="ts tab-num">12:33</span></div>
|
||||
<div class="tx">학교에 가는 게 많이 버겁게 느껴지는 것 같네요. 혹시 어떤 순간이 가장 힘든지 조금 더 들려줄 수 있을까요?</div>
|
||||
</div>
|
||||
<div class="turn client">
|
||||
<div class="head"><span class="who">서연 (내담자)</span><span class="ts tab-num">12:34</span></div>
|
||||
<div class="tx">아침에… 눈을 뜨면요. 그냥 천장만 보고 있어요. 일어나야 하는 건 아는데, 몸이 안 움직여요. 그게 제일… 무서워요.</div>
|
||||
</div>
|
||||
<div class="turn learner">
|
||||
<div class="head"><span class="who">나 (학습자)</span><span class="ts tab-num">12:35</span></div>
|
||||
<div class="tx">눈을 떠도 몸이 따라주지 않는 그 무력감이, 무섭게까지 느껴지는군요.</div>
|
||||
</div>
|
||||
<div class="turn client">
|
||||
<div class="head"><span class="who">서연 (내담자)</span><span class="ts tab-num">12:36</span></div>
|
||||
<div class="tx partial">네… 그리고 요즘은 친구들이랑 있어도 자꾸 혼자인 것 같고<span class="cursor"></span></div>
|
||||
</div>
|
||||
</div>
|
||||
</main>
|
||||
|
||||
<!-- RIGHT: 피드백 레일 (은은한 신호 모드) -->
|
||||
<aside class="right">
|
||||
<section class="meter">
|
||||
<div class="kicker"><span class="dot"></span>내담자 상태</div>
|
||||
<div class="m">
|
||||
<div class="top"><span class="nm">감정 톤</span><span class="val">불안 · 위축</span></div>
|
||||
<div class="bar"><div class="fill clay" style="width:68%"></div></div>
|
||||
</div>
|
||||
<div class="m">
|
||||
<div class="top"><span class="nm">마음 열림</span><span class="val">조금씩 열림</span></div>
|
||||
<div class="bar"><div class="fill sage" style="width:34%"></div></div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section class="signal">
|
||||
<div class="kicker"><span class="dot"></span>라이브 신호</div>
|
||||
<div class="live">
|
||||
<span class="d pos"></span>
|
||||
<span class="nm">공감적 반영<span class="sub">방금 반영이 자기개방을 열었어요</span></span>
|
||||
</div>
|
||||
<div class="seq">
|
||||
<span class="sl">최근 흐름</span>
|
||||
<span class="dots">
|
||||
<span class="neu"></span><span class="pos"></span><span class="warn"></span><span class="pos"></span><span class="pos"></span>
|
||||
</span>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section>
|
||||
<div class="callout">
|
||||
<span class="clh">안전 점검</span>
|
||||
<span class="cl">내담자가 무기력·무력감을 반복해 표현하고 있어요. 위험 신호 여부를 자연스럽게 탐색해 보세요.</span>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section class="note">
|
||||
<div class="kicker"><span class="dot"></span>이번 회기 메모</div>
|
||||
<textarea placeholder="떠오른 가설·다음에 시도할 질문을 적어두세요. 회기말 리뷰에 함께 보여집니다."></textarea>
|
||||
</section>
|
||||
</aside>
|
||||
</div>
|
||||
|
||||
<!-- ============ 하단 컨트롤 바 ============ -->
|
||||
<footer class="controls">
|
||||
<div class="mic">
|
||||
<button class="btn" aria-label="마이크 켜짐">
|
||||
<svg viewBox="0 0 24 24" fill="none" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
|
||||
<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>
|
||||
<div class="lbl"><span class="s">듣고 있어요</span><span class="h">말하면 자동으로 전달돼요</span></div>
|
||||
</div>
|
||||
|
||||
<div class="modeseg" role="tablist" aria-label="피드백 모드">
|
||||
<button role="tab">몰입</button>
|
||||
<button role="tab" class="on" aria-selected="true">은은한 신호</button>
|
||||
<button role="tab">코칭</button>
|
||||
</div>
|
||||
|
||||
<div class="rightc">
|
||||
<button class="btn-ghost">
|
||||
<svg viewBox="0 0 24 24" fill="none" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><rect x="6" y="5" width="4" height="14"/><rect x="14" y="5" width="4" height="14"/></svg>
|
||||
일시정지
|
||||
</button>
|
||||
<div class="slide-end" title="밀어서 세션 종료">
|
||||
<div class="track">밀어서 종료</div>
|
||||
<div class="knob">
|
||||
<svg viewBox="0 0 24 24" fill="none" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><polyline points="9 18 15 12 9 6"/></svg>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</footer>
|
||||
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
706
docs/mockups/settings.html
Normal file
706
docs/mockups/settings.html
Normal file
|
|
@ -0,0 +1,706 @@
|
|||
<!DOCTYPE html>
|
||||
<html lang="ko">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Vignette — 설정 시안</title>
|
||||
<link rel="stylesheet" href="https://cdn.jsdelivr.net/gh/orioncactus/pretendard/dist/web/variable/pretendardvariable.min.css">
|
||||
<style>
|
||||
/* =====================================================================
|
||||
Vignette — 설정(Settings) 화면 시안 (단일 파일, 인라인 CSS)
|
||||
토큰: DESIGN_CONCEPT.md §3 그대로 적용. 외부 의존 = Pretendard CDN 1개.
|
||||
철칙: 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;
|
||||
--bg-stage:#1E2724;
|
||||
/* 별칭 */
|
||||
--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;
|
||||
--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);
|
||||
--maxw:1080px;
|
||||
}
|
||||
/* 교수자 역할 accent 오버라이드 (인디고-블루: 감독) */
|
||||
body[data-role="instructor"]{ --accent:#3A5BA0; --accent-deep:#2F4A86; --accent-bright:#5478C4; --accent-tint:#EAEFF7; --focus-ring:rgba(58,91,160,.40);}
|
||||
*{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;}
|
||||
|
||||
/* ============ 공통 헤더 (톱바) ============ */
|
||||
.topbar{
|
||||
height:56px; background:var(--surface); border-bottom:1px solid var(--hair);
|
||||
display:flex; align-items:center; gap:var(--sp-6);
|
||||
padding:0 var(--sp-7); position:sticky; top:0; z-index:10;
|
||||
}
|
||||
.wordmark{display:flex; align-items:center; gap:10px; flex:none;}
|
||||
.wordmark .gl{width:24px; height:24px; flex:none;}
|
||||
.wordmark .nm{font-size:18px; font-weight:700; letter-spacing:-0.02em; color:var(--ink);}
|
||||
.wordmark .nm .dot{color:var(--accent);}
|
||||
.topnav{display:flex; align-items:center; gap:var(--sp-2); margin-left:var(--sp-5);}
|
||||
.topnav a{
|
||||
font-size:14px; font-weight:500; color:var(--ink-3); text-decoration:none;
|
||||
padding:7px 12px; border-radius:var(--radius-sm);
|
||||
}
|
||||
.topnav a:hover{color:var(--ink-2); background:var(--paper-2);}
|
||||
.topnav a.on{color:var(--ink); font-weight:600;}
|
||||
.topbar .spacer{flex:1;}
|
||||
.role{
|
||||
display:flex; align-items:center; gap:8px; font-size:13px; color:var(--ink-2);
|
||||
padding:6px 12px; border-radius:999px; background:var(--accent-tint); font-weight:500;
|
||||
}
|
||||
.role .d{width:6px; height:6px; border-radius:50%; background:var(--accent);}
|
||||
.who{display:flex; align-items:center; gap:10px;}
|
||||
.who .av{
|
||||
width:32px; height:32px; border-radius:50%; background:var(--accent);
|
||||
display:flex; align-items:center; justify-content:center;
|
||||
color:var(--text-on-accent); font-size:13px; font-weight:600;
|
||||
}
|
||||
.who .nm{font-size:14px; font-weight:600; color:var(--ink);}
|
||||
|
||||
/* ============ 페이지 헤더 ============ */
|
||||
.pagehead{max-width:var(--maxw); margin:0 auto; padding:var(--sp-7) var(--sp-7) 0;}
|
||||
.pagehead .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; margin-bottom:10px;
|
||||
}
|
||||
.pagehead .kicker .dot{width:6px; height:6px; border-radius:50%; background:var(--accent-bright);}
|
||||
.pagehead h1{font-size:30px; font-weight:700; letter-spacing:-0.02em; color:var(--ink); line-height:1.3;}
|
||||
.pagehead p{font-size:16px; color:var(--ink-2); margin-top:8px; max-width:560px;}
|
||||
|
||||
/* ============ 레이아웃: 좌측 섹션 내비 + 우측 폼 ============ */
|
||||
.shell{max-width:var(--maxw); margin:0 auto; padding:var(--sp-6) var(--sp-7) var(--sp-8);
|
||||
display:grid; grid-template-columns:228px 1fr; gap:var(--sp-7); align-items:start;}
|
||||
|
||||
/* 좌측 섹션 내비 (sticky) */
|
||||
.sectnav{position:sticky; top:88px; display:flex; flex-direction:column; gap:2px;}
|
||||
.sectnav .gk{
|
||||
font-family:var(--font-num); font-size:11px; font-weight:600; letter-spacing:0.08em;
|
||||
color:var(--ink-3); padding:0 12px var(--sp-3); text-transform:uppercase;
|
||||
}
|
||||
.sectnav a{
|
||||
display:flex; align-items:center; gap:11px; text-decoration:none;
|
||||
font-size:14.5px; font-weight:500; color:var(--ink-2);
|
||||
padding:10px 12px; border-radius:var(--radius); transition:background .14s var(--ease-out);
|
||||
}
|
||||
.sectnav a:hover{background:var(--paper-2);}
|
||||
.sectnav a.on{background:var(--accent-tint); color:var(--accent-deep); font-weight:600;}
|
||||
.sectnav a svg{width:18px; height:18px; flex:none; stroke:currentColor; opacity:.85;}
|
||||
|
||||
/* 우측 폼 컬럼 */
|
||||
.forms{display:flex; flex-direction:column; gap:var(--sp-7); min-width:0;}
|
||||
|
||||
/* 폼 그룹 (카드 = 톤차로만 분리, border 헤어라인만) */
|
||||
.group{
|
||||
background:var(--surface); border:1px solid var(--hair); border-radius:var(--radius-lg);
|
||||
padding:var(--sp-6); box-shadow:var(--shadow-sm);
|
||||
}
|
||||
.group > .gh{margin-bottom:var(--sp-5);}
|
||||
.group .gh .gt{font-size:20px; font-weight:600; letter-spacing:-0.01em; color:var(--ink);}
|
||||
.group .gh .gd{font-size:14px; color:var(--ink-2); margin-top:5px;}
|
||||
|
||||
/* 폼 필드 한 줄 (라벨 좌 / 입력 우, 넉넉한 행간) */
|
||||
.field{
|
||||
display:grid; grid-template-columns:200px 1fr; gap:var(--sp-5);
|
||||
padding:var(--sp-5) 0; border-top:1px solid var(--paper-2);
|
||||
}
|
||||
.field:first-of-type{border-top:none; padding-top:var(--sp-2);}
|
||||
.field .flab{display:flex; flex-direction:column; gap:4px;}
|
||||
.field .flab .l{font-size:14.5px; font-weight:600; color:var(--ink);}
|
||||
.field .flab .h{font-size:13px; color:var(--ink-3); line-height:1.5;}
|
||||
.field .fin{display:flex; flex-direction:column; gap:8px; min-width:0;}
|
||||
|
||||
input[type=text], input[type=email], select, textarea{
|
||||
width:100%; font-family:var(--font-sans); font-size:14.5px; color:var(--ink);
|
||||
background:var(--paper-2); border:1px solid var(--hair); border-radius:var(--radius-sm);
|
||||
padding:11px 13px; line-height:1.5;
|
||||
}
|
||||
textarea{resize:vertical; min-height:84px;}
|
||||
input:focus, select:focus, textarea:focus{
|
||||
outline:none; border-color:var(--accent); background:var(--surface);
|
||||
box-shadow:0 0 0 3px var(--focus-ring);
|
||||
}
|
||||
input::placeholder, textarea::placeholder{color:var(--ink-3);}
|
||||
select{appearance:none; -webkit-appearance:none; cursor:pointer;
|
||||
background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%2393A09C' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpolyline points='6 9 12 15 18 9'/%3E%3C/svg%3E");
|
||||
background-repeat:no-repeat; background-position:right 12px center; background-size:16px; padding-right:38px;}
|
||||
|
||||
/* 프로필 헤더 (아바타 + 이름 + 역할 배지) */
|
||||
.profile{display:flex; align-items:center; gap:var(--sp-5);}
|
||||
.profile .big{
|
||||
width:64px; height:64px; border-radius:50%; flex:none;
|
||||
background:var(--accent); display:flex; align-items:center; justify-content:center;
|
||||
color:var(--text-on-accent); font-size:24px; font-weight:600;
|
||||
}
|
||||
.profile .meta{display:flex; flex-direction:column; gap:4px;}
|
||||
.profile .meta .n{font-size:18px; font-weight:600; color:var(--ink);}
|
||||
.profile .meta .e{font-size:14px; color:var(--ink-2);}
|
||||
.profile .meta .badges{display:flex; gap:8px; margin-top:5px;}
|
||||
.tag{
|
||||
display:inline-flex; align-items:center; gap:6px;
|
||||
font-size:12px; font-weight:600; letter-spacing:0.02em;
|
||||
padding:4px 10px; border-radius:999px; background:var(--accent-tint); color:var(--accent-deep);
|
||||
}
|
||||
.tag .d{width:5px; height:5px; border-radius:50%; background:var(--accent);}
|
||||
.tag.muted{background:var(--paper-2); color:var(--ink-2);}
|
||||
.tag.muted .d{background:var(--ink-3);}
|
||||
|
||||
/* 버튼 */
|
||||
.btn{
|
||||
font-family:var(--font-sans); font-size:14px; font-weight:600; cursor:pointer;
|
||||
border-radius:var(--radius); padding:10px 18px; border:1px solid transparent;
|
||||
display:inline-flex; align-items:center; gap:8px; transition:all .14s var(--ease-out);
|
||||
}
|
||||
.btn svg{width:16px; height:16px; stroke:currentColor;}
|
||||
.btn.primary{background:var(--accent); color:var(--text-on-accent);}
|
||||
.btn.primary:hover{background:var(--accent-deep);}
|
||||
.btn.ghost{background:var(--surface); color:var(--ink-2); border-color:var(--hair);}
|
||||
.btn.ghost:hover{background:var(--paper-2); color:var(--ink);}
|
||||
.btn.danger{background:var(--surface); color:var(--crit-text); border-color:var(--crit-tint);}
|
||||
.btn.danger:hover{background:var(--crit-tint);}
|
||||
.btn.sm{padding:8px 14px; font-size:13px;}
|
||||
|
||||
/* 라디오/세그먼트형 역할 표시 (읽기전용 스타일) */
|
||||
.rolepick{display:flex; gap:10px; flex-wrap:wrap;}
|
||||
.rolepick .opt{
|
||||
flex:1; min-width:130px; border:1px solid var(--hair); border-radius:var(--radius);
|
||||
padding:13px 15px; cursor:pointer; background:var(--surface);
|
||||
}
|
||||
.rolepick .opt.on{border-color:var(--accent); background:var(--accent-tint);}
|
||||
.rolepick .opt .t{font-size:14px; font-weight:600; color:var(--ink); display:flex; align-items:center; gap:8px;}
|
||||
.rolepick .opt .t .d{width:7px; height:7px; border-radius:50%; background:var(--neutral-200);}
|
||||
.rolepick .opt.on .t .d{background:var(--accent);}
|
||||
.rolepick .opt .h{font-size:12px; color:var(--ink-3); margin-top:4px;}
|
||||
|
||||
/* 토글 스위치 */
|
||||
.toggle{position:relative; width:42px; height:24px; flex:none; cursor:pointer;}
|
||||
.toggle input{position:absolute; opacity:0; width:100%; height:100%; margin:0; cursor:pointer;}
|
||||
.toggle .tr{position:absolute; inset:0; background:var(--neutral-200); border-radius:999px; transition:background .16s var(--ease-out);}
|
||||
.toggle .kn{position:absolute; top:3px; left:3px; width:18px; height:18px; border-radius:50%; background:#fff; box-shadow:var(--shadow-sm); transition:transform .16s var(--ease-out);}
|
||||
.toggle input:checked + .tr{background:var(--accent);}
|
||||
.toggle input:checked + .tr + .kn{transform:translateX(18px);}
|
||||
.toggle input:focus-visible + .tr{box-shadow:0 0 0 3px var(--focus-ring);}
|
||||
|
||||
/* 알림 행 (라벨 + 설명 + 토글) */
|
||||
.optrow{display:flex; align-items:center; gap:var(--sp-4); padding:var(--sp-4) 0; border-top:1px solid var(--paper-2);}
|
||||
.optrow:first-of-type{border-top:none;}
|
||||
.optrow .ot{flex:1;}
|
||||
.optrow .ot .l{font-size:14.5px; font-weight:600; color:var(--ink);}
|
||||
.optrow .ot .h{font-size:13px; color:var(--ink-3); margin-top:3px; line-height:1.5;}
|
||||
|
||||
/* 페르소나 진입 — 리스트 (격자 아님, 세로 행) */
|
||||
.personalist{display:flex; flex-direction:column; gap:10px;}
|
||||
.pcard{
|
||||
display:flex; align-items:center; gap:var(--sp-4);
|
||||
padding:var(--sp-4); border:1px solid var(--hair); border-radius:var(--radius);
|
||||
background:var(--surface);
|
||||
}
|
||||
.pcard:hover{border-color:var(--neutral-200);}
|
||||
.pcard .face{
|
||||
width:48px; height:48px; border-radius:50%; flex:none; overflow:hidden; background:var(--bg-stage);
|
||||
}
|
||||
.pcard .pinfo{flex:1; min-width:0;}
|
||||
.pcard .pinfo .pn{font-size:15px; font-weight:600; color:var(--ink);}
|
||||
.pcard .pinfo .pm{font-size:13px; color:var(--ink-2); margin-top:2px;}
|
||||
.pcard .pinfo .ptags{display:flex; gap:7px; margin-top:7px; flex-wrap:wrap;}
|
||||
.pchip{font-size:11.5px; font-weight:500; color:var(--ink-2); background:var(--paper-2); padding:3px 9px; border-radius:999px;}
|
||||
.pchip.clay{background:var(--clay-tint); color:var(--clay-deep);}
|
||||
.pcard .pact{display:flex; gap:8px; flex:none;}
|
||||
.iconbtn{
|
||||
width:34px; height:34px; border-radius:var(--radius-sm); border:1px solid var(--hair);
|
||||
background:var(--surface); cursor:pointer; display:flex; align-items:center; justify-content:center;
|
||||
}
|
||||
.iconbtn svg{width:16px; height:16px; stroke:var(--ink-2);}
|
||||
.iconbtn:hover{background:var(--paper-2);}
|
||||
|
||||
/* 새 페르소나 만들기 진입 행 */
|
||||
.addrow{
|
||||
display:flex; align-items:center; gap:var(--sp-4); margin-top:14px;
|
||||
padding:var(--sp-4); border:1px dashed var(--neutral-200); border-radius:var(--radius);
|
||||
background:var(--paper-2); cursor:pointer; text-decoration:none;
|
||||
}
|
||||
.addrow:hover{border-color:var(--accent); background:var(--accent-tint);}
|
||||
.addrow .pl{
|
||||
width:36px; height:36px; border-radius:50%; flex:none; background:var(--accent);
|
||||
display:flex; align-items:center; justify-content:center;
|
||||
}
|
||||
.addrow .pl svg{width:18px; height:18px; stroke:var(--text-on-accent);}
|
||||
.addrow .at{font-size:14.5px; font-weight:600; color:var(--ink);}
|
||||
.addrow .ah{font-size:13px; color:var(--ink-3); margin-top:2px;}
|
||||
|
||||
/* 페르소나 파라미터 슬라이더 (난이도) */
|
||||
.slider{display:flex; flex-direction:column; gap:8px;}
|
||||
.slider .track{height:5px; border-radius:3px; background:var(--paper-2); position:relative;}
|
||||
.slider .track .fill{position:absolute; left:0; top:0; height:100%; border-radius:3px; background:var(--accent-bright);}
|
||||
.slider .track .knob{position:absolute; top:50%; transform:translate(-50%,-50%); width:16px; height:16px; border-radius:50%; background:var(--surface); border:2px solid var(--accent); box-shadow:var(--shadow-sm);}
|
||||
.slider .scale{display:flex; justify-content:space-between; font-size:12px; color:var(--ink-3);}
|
||||
.slider .scale .on{color:var(--accent-deep); font-weight:600;}
|
||||
|
||||
/* 음성 선택 (라디오 행) */
|
||||
.voicelist{display:flex; flex-direction:column; gap:8px;}
|
||||
.voice{
|
||||
display:flex; align-items:center; gap:var(--sp-4);
|
||||
padding:13px var(--sp-4); border:1px solid var(--hair); border-radius:var(--radius);
|
||||
cursor:pointer; background:var(--surface);
|
||||
}
|
||||
.voice.on{border-color:var(--accent); background:var(--accent-tint);}
|
||||
.voice .rad{width:18px; height:18px; border-radius:50%; border:2px solid var(--neutral-200); flex:none; position:relative;}
|
||||
.voice.on .rad{border-color:var(--accent);}
|
||||
.voice.on .rad::after{content:""; position:absolute; inset:3px; border-radius:50%; background:var(--accent);}
|
||||
.voice .vinfo{flex:1;}
|
||||
.voice .vinfo .vn{font-size:14.5px; font-weight:600; color:var(--ink);}
|
||||
.voice .vinfo .vd{font-size:12.5px; color:var(--ink-3); margin-top:2px;}
|
||||
.voice .play{
|
||||
width:34px; height:34px; border-radius:50%; flex:none; border:1px solid var(--hair); background:var(--surface);
|
||||
display:flex; align-items:center; justify-content:center; cursor:pointer;
|
||||
}
|
||||
.voice .play svg{width:15px; height:15px; stroke:var(--accent); fill:var(--accent);}
|
||||
.voice .play:hover{background:var(--accent-tint);}
|
||||
|
||||
/* 동의/개인정보 행 (상태 텍스트 + 동작) */
|
||||
.consent{display:flex; align-items:flex-start; gap:var(--sp-4); padding:var(--sp-5) 0; border-top:1px solid var(--paper-2);}
|
||||
.consent:first-of-type{border-top:none; padding-top:var(--sp-2);}
|
||||
.consent .ci{flex:1;}
|
||||
.consent .ci .ct{font-size:14.5px; font-weight:600; color:var(--ink); display:flex; align-items:center; gap:9px;}
|
||||
.consent .ci .ct .st{font-size:11.5px; font-weight:600; padding:3px 9px; border-radius:999px;}
|
||||
.consent .ci .ct .st.ok{background:var(--pos-tint); color:var(--pos-text);}
|
||||
.consent .ci .ct .st.pending{background:var(--warn-tint); color:var(--warn-text);}
|
||||
.consent .ci .ch{font-size:13px; color:var(--ink-2); margin-top:6px; line-height:1.55; max-width:480px;}
|
||||
|
||||
/* 콜아웃 (정보/주의, 좌측바 없음) */
|
||||
.callout{border-radius:var(--radius); padding:var(--sp-4) var(--sp-5); display:flex; gap:12px;}
|
||||
.callout.info{background:var(--info-tint);}
|
||||
.callout .ico{flex:none; width:18px; height:18px; margin-top:1px;}
|
||||
.callout .ico svg{width:18px; height:18px;}
|
||||
.callout.info .ico svg{stroke:var(--info-solid);}
|
||||
.callout .ct{font-size:13.5px; line-height:1.6;}
|
||||
.callout.info .ct{color:var(--info-text);}
|
||||
.callout .ct strong{font-weight:600;}
|
||||
|
||||
/* 그룹 푸터 (저장) */
|
||||
.gfoot{display:flex; justify-content:flex-end; gap:10px; margin-top:var(--sp-6); padding-top:var(--sp-5); border-top:1px solid var(--paper-2);}
|
||||
|
||||
/* 위험 구역 (로그아웃/탈퇴) */
|
||||
.group.peril{border-color:var(--crit-tint);}
|
||||
|
||||
@media (max-width:880px){
|
||||
.shell{grid-template-columns:1fr;}
|
||||
.sectnav{position:static; flex-direction:row; flex-wrap:wrap; gap:6px;}
|
||||
.sectnav .gk{display:none;}
|
||||
.field{grid-template-columns:1fr; gap:10px;}
|
||||
.topnav{display:none;}
|
||||
}
|
||||
@media (prefers-reduced-motion: reduce){
|
||||
*,*::before,*::after{animation-duration:.01ms!important; transition-duration:.01ms!important;}
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body data-role="instructor">
|
||||
|
||||
<!-- ============ 공통 헤더 ============ -->
|
||||
<header class="topbar">
|
||||
<div class="wordmark">
|
||||
<svg class="gl" viewBox="0 0 24 24" fill="none">
|
||||
<circle cx="12" cy="12" r="10" stroke="#3A5BA0" stroke-width="2"/>
|
||||
<circle cx="12" cy="12" r="4" fill="#3A5BA0"/>
|
||||
</svg>
|
||||
<span class="nm">Vignette<span class="dot">.</span></span>
|
||||
</div>
|
||||
<nav class="topnav">
|
||||
<a href="#">세션</a>
|
||||
<a href="#">내담자</a>
|
||||
<a href="#">리뷰</a>
|
||||
<a href="#" class="on">설정</a>
|
||||
</nav>
|
||||
<div class="spacer"></div>
|
||||
<span class="role"><span class="d"></span>교수자</span>
|
||||
<div class="who">
|
||||
<span class="av">정</span>
|
||||
<span class="nm">정민서</span>
|
||||
</div>
|
||||
</header>
|
||||
|
||||
<!-- ============ 페이지 헤더 ============ -->
|
||||
<div class="pagehead">
|
||||
<div class="kicker"><span class="dot"></span>설정</div>
|
||||
<h1>계정과 시뮬레이션 환경을 관리합니다</h1>
|
||||
<p>프로필, 알림, 가상 내담자 페르소나, 음성, 개인정보 동의를 한곳에서 조정하세요.</p>
|
||||
</div>
|
||||
|
||||
<!-- ============ 레이아웃 ============ -->
|
||||
<div class="shell">
|
||||
|
||||
<!-- 좌측 섹션 내비 -->
|
||||
<nav class="sectnav" aria-label="설정 섹션">
|
||||
<div class="gk">설정</div>
|
||||
<a href="#account" class="on">
|
||||
<svg viewBox="0 0 24 24" fill="none" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"><circle cx="12" cy="8" r="4"/><path d="M4 21c0-4 4-6 8-6s8 2 8 6"/></svg>
|
||||
계정
|
||||
</a>
|
||||
<a href="#notify">
|
||||
<svg viewBox="0 0 24 24" fill="none" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"><path d="M18 8a6 6 0 1 0-12 0c0 7-3 9-3 9h18s-3-2-3-9"/><path d="M10.3 21a2 2 0 0 0 3.4 0"/></svg>
|
||||
알림
|
||||
</a>
|
||||
<a href="#persona">
|
||||
<svg viewBox="0 0 24 24" fill="none" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"><circle cx="9" cy="8" r="3.2"/><path d="M3.5 20c0-3 2.5-5 5.5-5s5.5 2 5.5 5"/><path d="M17 9h4M19 7v4"/></svg>
|
||||
페르소나
|
||||
</a>
|
||||
<a href="#voice">
|
||||
<svg viewBox="0 0 24 24" fill="none" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"><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>
|
||||
음성
|
||||
</a>
|
||||
<a href="#privacy">
|
||||
<svg viewBox="0 0 24 24" fill="none" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"><path d="M12 3l7 3v5c0 5-3 8-7 10-4-2-7-5-7-10V6z"/><path d="M9 12l2 2 4-4"/></svg>
|
||||
개인정보
|
||||
</a>
|
||||
</nav>
|
||||
|
||||
<!-- 우측 폼 -->
|
||||
<div class="forms">
|
||||
|
||||
<!-- (1) 계정 -->
|
||||
<section class="group" id="account">
|
||||
<div class="gh">
|
||||
<div class="gt">계정</div>
|
||||
<div class="gd">프로필과 역할, 로그인 정보를 관리합니다.</div>
|
||||
</div>
|
||||
|
||||
<div class="profile" style="margin-bottom:var(--sp-5);">
|
||||
<div class="big">정</div>
|
||||
<div class="meta">
|
||||
<div class="n">정민서</div>
|
||||
<div class="e">minseo.jung@hanshin.ac.kr</div>
|
||||
<div class="badges">
|
||||
<span class="tag"><span class="d"></span>교수자</span>
|
||||
<span class="tag muted"><span class="d"></span>심리상담학과</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="field">
|
||||
<div class="flab"><span class="l">표시 이름</span><span class="h">학습자·동료에게 보이는 이름입니다.</span></div>
|
||||
<div class="fin"><input type="text" value="정민서"></div>
|
||||
</div>
|
||||
<div class="field">
|
||||
<div class="flab"><span class="l">이메일</span><span class="h">로그인 및 알림 수신 주소.</span></div>
|
||||
<div class="fin"><input type="email" value="minseo.jung@hanshin.ac.kr"></div>
|
||||
</div>
|
||||
<div class="field">
|
||||
<div class="flab"><span class="l">소속</span><span class="h">학과·기관 표기.</span></div>
|
||||
<div class="fin"><input type="text" value="한신대학교 심리상담학과"></div>
|
||||
</div>
|
||||
<div class="field">
|
||||
<div class="flab"><span class="l">역할</span><span class="h">권한 범위가 달라집니다. 변경은 관리자 승인이 필요합니다.</span></div>
|
||||
<div class="fin">
|
||||
<div class="rolepick">
|
||||
<div class="opt"><div class="t"><span class="d"></span>학습자</div><div class="h">상담 연습·내 리뷰</div></div>
|
||||
<div class="opt on"><div class="t"><span class="d"></span>교수자</div><div class="h">페르소나 제작·학습자 감독</div></div>
|
||||
<div class="opt"><div class="t"><span class="d"></span>관리자</div><div class="h">기관 운영·계정 관리</div></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="gfoot">
|
||||
<button class="btn ghost">변경 취소</button>
|
||||
<button class="btn primary">저장</button>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<!-- 로그인 / 위험 구역 -->
|
||||
<section class="group peril">
|
||||
<div class="gh">
|
||||
<div class="gt">로그인 및 세션</div>
|
||||
<div class="gd">현재 기기와 보안을 관리합니다.</div>
|
||||
</div>
|
||||
<div class="optrow">
|
||||
<div class="ot"><div class="l">비밀번호 변경</div><div class="h">마지막 변경: 2026년 3월 12일</div></div>
|
||||
<button class="btn ghost sm">변경</button>
|
||||
</div>
|
||||
<div class="optrow">
|
||||
<div class="ot"><div class="l">다른 기기에서 로그아웃</div><div class="h">현재 3개 기기에서 로그인 중입니다.</div></div>
|
||||
<button class="btn ghost sm">전체 로그아웃</button>
|
||||
</div>
|
||||
<div class="optrow">
|
||||
<div class="ot"><div class="l">로그아웃</div><div class="h">이 기기에서 Vignette를 종료합니다.</div></div>
|
||||
<button class="btn danger sm">
|
||||
<svg viewBox="0 0 24 24" fill="none" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M9 21H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h4"/><polyline points="16 17 21 12 16 7"/><line x1="21" y1="12" x2="9" y2="12"/></svg>
|
||||
로그아웃
|
||||
</button>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<!-- (2) 알림 -->
|
||||
<section class="group" id="notify">
|
||||
<div class="gh">
|
||||
<div class="gt">알림</div>
|
||||
<div class="gd">언제, 무엇을 받을지 정합니다. 과한 알림은 끄는 편을 권합니다.</div>
|
||||
</div>
|
||||
<div class="optrow">
|
||||
<div class="ot"><div class="l">학습자 세션 완료</div><div class="h">담당 학습자가 회기를 마치면 알립니다.</div></div>
|
||||
<label class="toggle"><input type="checkbox" checked><span class="tr"></span><span class="kn"></span></label>
|
||||
</div>
|
||||
<div class="optrow">
|
||||
<div class="ot"><div class="l">안전 신호 감지</div><div class="h">세션 중 위기 신호가 포착되면 즉시 알립니다.</div></div>
|
||||
<label class="toggle"><input type="checkbox" checked><span class="tr"></span><span class="kn"></span></label>
|
||||
</div>
|
||||
<div class="optrow">
|
||||
<div class="ot"><div class="l">주간 리뷰 요약</div><div class="h">매주 월요일, 담당 학습자 진척 요약을 메일로 보냅니다.</div></div>
|
||||
<label class="toggle"><input type="checkbox"><span class="tr"></span><span class="kn"></span></label>
|
||||
</div>
|
||||
<div class="optrow">
|
||||
<div class="ot"><div class="l">제품 소식</div><div class="h">기능 업데이트·연구 노트.</div></div>
|
||||
<label class="toggle"><input type="checkbox"><span class="tr"></span><span class="kn"></span></label>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<!-- (3) 페르소나 설정 진입 (교수자) -->
|
||||
<section class="group" id="persona">
|
||||
<div class="gh">
|
||||
<div class="gt">가상 내담자 페르소나</div>
|
||||
<div class="gd">학습자가 상담 연습할 가상 내담자를 만들고 편집합니다. 외형·음성·성격·난이도를 조정해 시나리오를 설계하세요.</div>
|
||||
</div>
|
||||
|
||||
<div class="personalist">
|
||||
<div class="pcard">
|
||||
<div class="face">
|
||||
<svg viewBox="0 0 48 48" width="48" height="48" aria-hidden="true">
|
||||
<rect width="48" height="48" fill="#2E3A36"/>
|
||||
<path d="M10 48 C10 39 16 34 24 34 C32 34 38 39 38 48 Z" fill="#3C4A45"/>
|
||||
<path d="M15 22 C15 14 19 11 24 11 C29 11 33 14 33 22 L33 30 C33 38 29 41 24 41 C19 41 15 38 15 30 Z" fill="#E8C9A8"/>
|
||||
<path d="M14 23 C14 14 18 10 24 10 C30 10 34 14 34 23 C31 18 27 17 24 17 C21 17 17 18 14 23 Z" fill="#2B2723"/>
|
||||
<circle cx="20.5" cy="24" r="1.5" fill="#3A2E26"/><circle cx="27.5" cy="24" r="1.5" fill="#3A2E26"/>
|
||||
</svg>
|
||||
</div>
|
||||
<div class="pinfo">
|
||||
<div class="pn">서연</div>
|
||||
<div class="pm">17세 · 고2 · 우울 호소 청소년</div>
|
||||
<div class="ptags"><span class="pchip">teen</span><span class="pchip clay">방어적</span><span class="pchip">난이도 중상</span></div>
|
||||
</div>
|
||||
<div class="pact">
|
||||
<button class="iconbtn" aria-label="편집">
|
||||
<svg viewBox="0 0 24 24" fill="none" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M12 20h9"/><path d="M16.5 3.5a2.1 2.1 0 0 1 3 3L7 19l-4 1 1-4z"/></svg>
|
||||
</button>
|
||||
<button class="iconbtn" aria-label="복제">
|
||||
<svg viewBox="0 0 24 24" fill="none" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><rect x="9" y="9" width="11" height="11" rx="2"/><path d="M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1"/></svg>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="pcard">
|
||||
<div class="face">
|
||||
<svg viewBox="0 0 48 48" width="48" height="48" aria-hidden="true">
|
||||
<rect width="48" height="48" fill="#2E3A36"/>
|
||||
<path d="M10 48 C10 39 16 34 24 34 C32 34 38 39 38 48 Z" fill="#46504C"/>
|
||||
<path d="M16 22 C16 15 19 12 24 12 C29 12 32 15 32 22 L32 29 C32 36 29 39 24 39 C19 39 16 36 16 29 Z" fill="#D8B594"/>
|
||||
<path d="M16 19 C16 13 19 11 24 11 C29 11 32 13 32 19 C29 16 27 16 24 16 C21 16 19 16 16 19 Z" fill="#3A332C"/>
|
||||
<circle cx="20.5" cy="24" r="1.5" fill="#3A2E26"/><circle cx="27.5" cy="24" r="1.5" fill="#3A2E26"/>
|
||||
</svg>
|
||||
</div>
|
||||
<div class="pinfo">
|
||||
<div class="pn">강현우</div>
|
||||
<div class="pm">34세 · 직장인 · 번아웃·불안</div>
|
||||
<div class="ptags"><span class="pchip">adult</span><span class="pchip">회피적</span><span class="pchip">난이도 상</span></div>
|
||||
</div>
|
||||
<div class="pact">
|
||||
<button class="iconbtn" aria-label="편집">
|
||||
<svg viewBox="0 0 24 24" fill="none" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M12 20h9"/><path d="M16.5 3.5a2.1 2.1 0 0 1 3 3L7 19l-4 1 1-4z"/></svg>
|
||||
</button>
|
||||
<button class="iconbtn" aria-label="복제">
|
||||
<svg viewBox="0 0 24 24" fill="none" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><rect x="9" y="9" width="11" height="11" rx="2"/><path d="M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1"/></svg>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<a href="#" class="addrow">
|
||||
<span class="pl"><svg viewBox="0 0 24 24" fill="none" stroke-width="2.2" stroke-linecap="round" stroke-linejoin="round"><line x1="12" y1="5" x2="12" y2="19"/><line x1="5" y1="12" x2="19" y2="12"/></svg></span>
|
||||
<div>
|
||||
<div class="at">새 가상 내담자 만들기</div>
|
||||
<div class="ah">외형·음성·성격·난이도를 설계해 시나리오를 추가합니다.</div>
|
||||
</div>
|
||||
</a>
|
||||
|
||||
<!-- 편집 진입 시 보이는 파라미터 미리보기 (서연 편집 펼침 예시) -->
|
||||
<div style="margin-top:var(--sp-6); padding-top:var(--sp-5); border-top:1px solid var(--paper-2);">
|
||||
<div class="kicker" style="font-family:var(--font-num); font-size:11px; font-weight:600; letter-spacing:0.08em; color:var(--accent); display:flex; align-items:center; gap:8px; margin-bottom:var(--sp-5);">
|
||||
<span style="width:6px;height:6px;border-radius:50%;background:var(--accent-bright);"></span>편집 중 · 서연
|
||||
</div>
|
||||
|
||||
<div class="field">
|
||||
<div class="flab"><span class="l">연령대 외형</span><span class="h">눈 크기·턱선·실루엣이 연령대에 맞춰 조정됩니다.</span></div>
|
||||
<div class="fin">
|
||||
<select>
|
||||
<option>청소년 (teen)</option>
|
||||
<option>청년 (young adult)</option>
|
||||
<option>성인 (adult)</option>
|
||||
<option>노년 (senior)</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
<div class="field">
|
||||
<div class="flab"><span class="l">시작 정서</span><span class="h">세션 초반의 기본 정서 상태.</span></div>
|
||||
<div class="fin">
|
||||
<select>
|
||||
<option>불안 (고각성·부정)</option>
|
||||
<option>우울 (저각성·부정)</option>
|
||||
<option>중립·라포</option>
|
||||
<option>저항·방어</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
<div class="field">
|
||||
<div class="flab"><span class="l">호소 문제</span><span class="h">학습자에게 제시될 배경 시나리오.</span></div>
|
||||
<div class="fin"><textarea>2주째 지속되는 무기력과 등교 거부. 최근 성적 하락과 또래 관계 위축을 경험. 자기개방에 소극적이며 방어적.</textarea></div>
|
||||
</div>
|
||||
<div class="field">
|
||||
<div class="flab"><span class="l">저항 강도</span><span class="h">높을수록 라포 형성이 어렵습니다. 라포가 쌓이면 세션 중 점차 완화됩니다.</span></div>
|
||||
<div class="fin">
|
||||
<div class="slider">
|
||||
<div class="track"><div class="fill" style="width:60%"></div><div class="knob" style="left:60%"></div></div>
|
||||
<div class="scale"><span>낮음</span><span class="on">중상</span><span>높음</span></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="field">
|
||||
<div class="flab"><span class="l">음성 (voice_id)</span><span class="h">내담자 발화에 사용할 목소리.</span></div>
|
||||
<div class="fin">
|
||||
<select>
|
||||
<option>soft-young-fem · 부드럽고 높은 톤</option>
|
||||
<option>calm-adult-fem · 차분한 여성</option>
|
||||
<option>steady-adult-male · 안정적 남성</option>
|
||||
<option>warm-senior · 느리고 따뜻한</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="gfoot">
|
||||
<button class="btn ghost">미리듣기</button>
|
||||
<button class="btn primary">페르소나 저장</button>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<!-- (4) 음성 -->
|
||||
<section class="group" id="voice">
|
||||
<div class="gh">
|
||||
<div class="gt">음성</div>
|
||||
<div class="gd">시연·미리듣기에 쓰이는 기본 목소리를 고릅니다. 페르소나별 음성은 위에서 따로 지정합니다.</div>
|
||||
</div>
|
||||
|
||||
<div class="voicelist">
|
||||
<label class="voice on">
|
||||
<span class="rad"></span>
|
||||
<div class="vinfo"><div class="vn">서린 · soft-young-fem</div><div class="vd">부드럽고 높은 톤 · 청소년 내담자에 적합</div></div>
|
||||
<span class="play" aria-label="미리듣기"><svg viewBox="0 0 24 24" stroke-width="0"><polygon points="6 4 20 12 6 20"/></svg></span>
|
||||
</label>
|
||||
<label class="voice">
|
||||
<span class="rad"></span>
|
||||
<div class="vinfo"><div class="vn">하경 · calm-adult-fem</div><div class="vd">차분한 여성 · 표준 성인 톤</div></div>
|
||||
<span class="play" aria-label="미리듣기"><svg viewBox="0 0 24 24" stroke-width="0"><polygon points="6 4 20 12 6 20"/></svg></span>
|
||||
</label>
|
||||
<label class="voice">
|
||||
<span class="rad"></span>
|
||||
<div class="vinfo"><div class="vn">도현 · steady-adult-male</div><div class="vd">낮고 안정적 · 남성 내담자</div></div>
|
||||
<span class="play" aria-label="미리듣기"><svg viewBox="0 0 24 24" stroke-width="0"><polygon points="6 4 20 12 6 20"/></svg></span>
|
||||
</label>
|
||||
<label class="voice">
|
||||
<span class="rad"></span>
|
||||
<div class="vinfo"><div class="vn">정인 · warm-senior</div><div class="vd">느리고 따뜻한 · 노년 내담자</div></div>
|
||||
<span class="play" aria-label="미리듣기"><svg viewBox="0 0 24 24" stroke-width="0"><polygon points="6 4 20 12 6 20"/></svg></span>
|
||||
</label>
|
||||
</div>
|
||||
|
||||
<div class="field" style="margin-top:var(--sp-5); border-top:1px solid var(--paper-2);">
|
||||
<div class="flab"><span class="l">말하기 속도</span><span class="h">기본 발화 속도(rate). 1.0이 표준입니다.</span></div>
|
||||
<div class="fin">
|
||||
<div class="slider">
|
||||
<div class="track"><div class="fill" style="width:46%"></div><div class="knob" style="left:46%"></div></div>
|
||||
<div class="scale"><span>0.8×</span><span class="on">0.96×</span><span>1.2×</span></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<!-- (5) 개인정보 / 동의 관리 -->
|
||||
<section class="group" id="privacy">
|
||||
<div class="gh">
|
||||
<div class="gt">개인정보 및 동의</div>
|
||||
<div class="gd">상담 연습 기록의 보관과 활용 범위를 직접 관리합니다.</div>
|
||||
</div>
|
||||
|
||||
<div class="callout info" style="margin-bottom:var(--sp-5);">
|
||||
<span class="ico"><svg viewBox="0 0 24 24" fill="none" stroke-width="1.9" stroke-linecap="round" stroke-linejoin="round"><circle cx="12" cy="12" r="9"/><line x1="12" y1="11" x2="12" y2="16"/><circle cx="12" cy="8" r="0.6" fill="currentColor"/></svg></span>
|
||||
<span class="ct">세션 음성·자막은 <strong>학습 목적 슈퍼비전</strong>에만 쓰이며, 가상 내담자와의 대화이므로 실제 내담자 개인정보는 포함되지 않습니다. 보관 기간이 지나면 자동 삭제됩니다.</span>
|
||||
</div>
|
||||
|
||||
<div class="consent">
|
||||
<div class="ci">
|
||||
<div class="ct">슈퍼비전용 녹음 보관 <span class="st ok">동의함</span></div>
|
||||
<div class="ch">담당 교수자가 회기말 리뷰에서 음성을 다시 들을 수 있도록 회기 녹음을 보관합니다.</div>
|
||||
</div>
|
||||
<label class="toggle"><input type="checkbox" checked><span class="tr"></span><span class="kn"></span></label>
|
||||
</div>
|
||||
<div class="consent">
|
||||
<div class="ci">
|
||||
<div class="ct">연구·모델 개선 활용 <span class="st pending">검토 필요</span></div>
|
||||
<div class="ch">비식별화된 대화 데이터를 평가 AI 개선 연구에 활용합니다. 동의는 선택이며 언제든 철회할 수 있습니다.</div>
|
||||
</div>
|
||||
<label class="toggle"><input type="checkbox"><span class="tr"></span><span class="kn"></span></label>
|
||||
</div>
|
||||
|
||||
<div class="field" style="border-top:1px solid var(--paper-2);">
|
||||
<div class="flab"><span class="l">기록 보관 기간</span><span class="h">기간이 지난 회기 기록은 자동 삭제됩니다.</span></div>
|
||||
<div class="fin">
|
||||
<select>
|
||||
<option>90일 (권장)</option>
|
||||
<option>30일</option>
|
||||
<option>180일</option>
|
||||
<option>학기 종료 시</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="optrow">
|
||||
<div class="ot"><div class="l">내 데이터 내보내기</div><div class="h">내 모든 세션·리뷰 기록을 PDF·JSON으로 받습니다.</div></div>
|
||||
<button class="btn ghost sm">
|
||||
<svg viewBox="0 0 24 24" fill="none" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4"/><polyline points="7 10 12 15 17 10"/><line x1="12" y1="15" x2="12" y2="3"/></svg>
|
||||
내보내기
|
||||
</button>
|
||||
</div>
|
||||
<div class="optrow">
|
||||
<div class="ot"><div class="l">모든 기록 삭제</div><div class="h">복구할 수 없습니다. 진행 전 한 번 더 확인합니다.</div></div>
|
||||
<button class="btn danger sm">기록 삭제</button>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
Loading…
Add table
Add a link
Reference in a new issue