feat: 운영 안정성과 세션 음성 경험 개선
This commit is contained in:
parent
facc4ad2d9
commit
c788343467
95 changed files with 8431 additions and 1785 deletions
|
|
@ -83,6 +83,7 @@
|
|||
background:var(--bg-surface-2);
|
||||
}
|
||||
.lh-tabs button{
|
||||
position:relative;
|
||||
flex:1 1 0;
|
||||
min-width:0;
|
||||
padding:9px 12px;
|
||||
|
|
@ -94,8 +95,27 @@
|
|||
font-weight:700;
|
||||
cursor:pointer;
|
||||
}
|
||||
/* D6(탭 구분 강화): 비활성 탭이 배경과 같아 "여러 개 중 하나"로 안 읽혔다.
|
||||
비활성 탭 사이에만 세로 구분선을 넣는다. 활성 탭은 자체 배경/테두리로
|
||||
이미 구분되므로 활성 탭에 붙는 구분선은 숨겨 이중 경계선을 막는다. */
|
||||
.lh-tabs button + button::before{
|
||||
content:"";
|
||||
position:absolute;
|
||||
left:-4px;
|
||||
top:22%;
|
||||
bottom:22%;
|
||||
width:1px;
|
||||
background:var(--border-strong);
|
||||
opacity:.55;
|
||||
pointer-events:none;
|
||||
}
|
||||
.lh-tabs button.is-active::before,
|
||||
.lh-tabs button.is-active + button::before{
|
||||
opacity:0;
|
||||
}
|
||||
.lh-tabs button:hover{
|
||||
color:var(--text-strong);
|
||||
background:color-mix(in srgb,var(--text-strong) 5%,transparent);
|
||||
}
|
||||
.lh-tabs button:focus-visible{
|
||||
outline:2px solid var(--focus-ring);
|
||||
|
|
@ -190,11 +210,25 @@
|
|||
justify-content:space-between;
|
||||
gap:var(--sp-4);
|
||||
}
|
||||
/* 페르소나 제목이 페이지 h1(.lh-title)보다 커서 위계가 역전돼 있었다(2026-07-27).
|
||||
크기는 h1 아래로 낮추고 강조는 weight 로만 준다. */
|
||||
.lh-session-focus__head h2{
|
||||
margin:8px 0 0;
|
||||
color:var(--text-strong);
|
||||
font-size:clamp(24px,2.3vw,34px);
|
||||
line-height:1.12;
|
||||
font-size:clamp(19px,1.7vw,24px);
|
||||
font-weight:820;
|
||||
line-height:1.18;
|
||||
letter-spacing:0;
|
||||
word-break:keep-all;
|
||||
}
|
||||
/* D3: 제목에서 떼어낸 주호소 조각. 크기를 낮춰 제목 한 줄에 가운뎃점이 1개만 남게 한다. */
|
||||
.lh-title-tail{
|
||||
display:block;
|
||||
margin-top:4px;
|
||||
color:var(--text-body);
|
||||
font-size:.64em;
|
||||
font-weight:740;
|
||||
line-height:1.34;
|
||||
letter-spacing:0;
|
||||
word-break:keep-all;
|
||||
}
|
||||
|
|
@ -278,6 +312,9 @@
|
|||
.lh-recap__avatar{
|
||||
min-width:0;
|
||||
display:grid;
|
||||
/* L3: 암시적 auto 트랙이면 자식(고정 196px)의 max-content 로 트랙이 부풀어
|
||||
컨테이너(폭 320px 에서 148px) 밖으로 나간다. 트랙을 명시해 컨테이너에 묶는다. */
|
||||
grid-template-columns:minmax(0,1fr);
|
||||
place-items:center;
|
||||
min-height:156px;
|
||||
border:1px solid var(--border-subtle);
|
||||
|
|
@ -285,8 +322,24 @@
|
|||
background:var(--bg-surface);
|
||||
overflow:hidden;
|
||||
}
|
||||
/* L3(2026-07-27): ClientAvatar 는 size prop 을 인라인 style(width/height:196px)로 박는다.
|
||||
실측 /learn — 폭 320px 에서 컨테이너 148px, 폭 360px 에서 188px 이라
|
||||
자식 figure(196px)가 오른쪽으로 각각 48px / 8px 잘려 나갔다
|
||||
(.lh-recap__avatar 의 overflow:hidden 에 걸림).
|
||||
→ 자식 폭을 컨테이너에 맞춰 줄인다. */
|
||||
.lh-recap__avatar .vg-avatar{
|
||||
margin:0;
|
||||
/* min-width:auto(기본) 이면 인라인 width 196px 가 그리드 트랙의 자동 최소값이 돼
|
||||
트랙 자체가 196px 로 부풀고 컨테이너(148px) 밖으로 삐져나온다. 0 으로 풀어야
|
||||
아래 max-width 가 실제로 걸린다. */
|
||||
min-width:0;
|
||||
max-width:100%;
|
||||
}
|
||||
/* 폭만 줄이면 인라인 height(고정 196px) 때문에 원형 마스크가 타원이 되므로
|
||||
높이를 폭에서 다시 계산한다. 인라인 스타일이라 !important 없이는 못 이긴다. */
|
||||
.lh-recap__avatar .vg-avatar__stage{
|
||||
height:auto !important;
|
||||
aspect-ratio:1;
|
||||
}
|
||||
.lh-recap__body{
|
||||
min-width:0;
|
||||
|
|
@ -796,16 +849,27 @@
|
|||
text-overflow:ellipsis;
|
||||
white-space:nowrap;
|
||||
}
|
||||
/* D3: "코드 · 단계 · 날짜"에서 날짜를 오른쪽 컬럼으로 떼어 가운뎃점을 1개로 줄인다. */
|
||||
.lh-compact-list__body small{
|
||||
min-width:0;
|
||||
display:flex;
|
||||
align-items:baseline;
|
||||
justify-content:space-between;
|
||||
gap:10px;
|
||||
color:var(--text-muted);
|
||||
font-family:var(--font-num);
|
||||
font-size:11.5px;
|
||||
line-height:1.25;
|
||||
}
|
||||
.lh-compact-list__body small > span{
|
||||
min-width:0;
|
||||
overflow:hidden;
|
||||
text-overflow:ellipsis;
|
||||
white-space:nowrap;
|
||||
}
|
||||
.lh-compact-list__body small > span:last-child{
|
||||
flex:none;
|
||||
}
|
||||
.lh-compact-list__action,
|
||||
.lh-compact-list__status{
|
||||
min-height:28px;
|
||||
|
|
@ -861,11 +925,29 @@
|
|||
.lh-feedback-mini__row:hover{
|
||||
color:var(--accent-deep);
|
||||
}
|
||||
/* D3: "코드 · 단계 · 점수"에서 점수를 오른쪽 컬럼으로 분리 */
|
||||
.lh-feedback-mini__row b{
|
||||
display:flex;
|
||||
align-items:baseline;
|
||||
justify-content:space-between;
|
||||
gap:10px;
|
||||
color:var(--text-strong);
|
||||
font-size:13.5px;
|
||||
line-height:1.35;
|
||||
}
|
||||
.lh-feedback-mini__row b > span:first-child{
|
||||
min-width:0;
|
||||
color:var(--text-strong);
|
||||
font-size:inherit;
|
||||
overflow:hidden;
|
||||
text-overflow:ellipsis;
|
||||
white-space:nowrap;
|
||||
}
|
||||
.lh-feedback-mini__row b > span:last-child{
|
||||
flex:none;
|
||||
color:var(--text-body);
|
||||
font-size:inherit;
|
||||
}
|
||||
.lh-feedback-mini__row span{
|
||||
color:var(--text-body);
|
||||
font-size:12.5px;
|
||||
|
|
@ -990,14 +1072,49 @@
|
|||
-webkit-line-clamp:2;
|
||||
-webkit-box-orient:vertical;
|
||||
}
|
||||
/* D3: 이름줄에서 떼어낸 주호소. 이름과 다른 층으로 읽히게 색·굵기를 낮춘다. */
|
||||
.lh-persona__concern{
|
||||
min-width:0;
|
||||
color:var(--text-body);
|
||||
font-size:12.5px;
|
||||
font-weight:700;
|
||||
line-height:1.35;
|
||||
word-break:keep-all;
|
||||
overflow:hidden;
|
||||
display:-webkit-box;
|
||||
-webkit-line-clamp:2;
|
||||
-webkit-box-orient:vertical;
|
||||
}
|
||||
.lh-persona__meta{
|
||||
min-width:0;
|
||||
display:flex;
|
||||
align-items:center;
|
||||
gap:6px;
|
||||
color:var(--text-muted);
|
||||
font-size:12px;
|
||||
line-height:1.45;
|
||||
}
|
||||
.lh-persona__meta > span{
|
||||
min-width:0;
|
||||
overflow:hidden;
|
||||
text-overflow:ellipsis;
|
||||
white-space:nowrap;
|
||||
}
|
||||
/* D3: "· 사용 불가"를 이어 붙이면 가운뎃점이 늘어나므로 별도 칩으로 뺀다. */
|
||||
.lh-persona__flag{
|
||||
flex:none;
|
||||
display:inline-flex;
|
||||
align-items:center;
|
||||
min-height:20px;
|
||||
padding:0 6px;
|
||||
border:1px solid var(--border-subtle);
|
||||
border-radius:var(--radius-sm);
|
||||
background:var(--bg-surface);
|
||||
color:var(--warn-text);
|
||||
font-size:11px;
|
||||
font-weight:800;
|
||||
white-space:nowrap;
|
||||
}
|
||||
.lh-persona__summary{
|
||||
min-width:0;
|
||||
color:var(--text-body);
|
||||
|
|
@ -1044,14 +1161,23 @@
|
|||
align-content:start;
|
||||
padding:var(--sp-5);
|
||||
}
|
||||
/* L1(2026-07-27): 이전 `grid-template-columns:minmax(0,1fr) minmax(220px,auto)` 는
|
||||
우측 액션 열이 max-content(=.lh-actions__note 의 max-width 280px)까지 먼저 자라고
|
||||
좌측 신원 열은 최소 0 이라 남은 폭을 전부 빼앗겼다.
|
||||
실측(폭 1181px): 프리뷰 히어로 423px → 열이 "127px 280px" 로 잡혀 제목 열이 47px,
|
||||
폭 1280px 에서도 146px 밖에 안 돼 26~28px 제목이 글자 단위로 쪼개져 흘러내렸다.
|
||||
→ 액션을 "줄바꿈되는 항목"으로 바꾼다. 신원 열이 340px 를 못 받는 폭에서는
|
||||
액션이 통째로 아랫줄로 내려가고 제목 열은 히어로 폭을 다 쓴다. */
|
||||
.lh-preview__hero{
|
||||
min-width:0;
|
||||
display:grid;
|
||||
grid-template-columns:minmax(0,1fr) minmax(220px,auto);
|
||||
display:flex;
|
||||
flex-wrap:wrap;
|
||||
gap:var(--sp-4);
|
||||
align-items:start;
|
||||
align-items:flex-start;
|
||||
}
|
||||
.lh-preview__identity{
|
||||
/* 340px 미만이면 같은 줄에 액션을 두지 않는다(=제목 열 최소 260px 확보) */
|
||||
flex:1 1 340px;
|
||||
min-width:0;
|
||||
display:grid;
|
||||
grid-template-columns:auto minmax(0,1fr);
|
||||
|
|
@ -1090,7 +1216,10 @@
|
|||
line-height:1.2;
|
||||
letter-spacing:0;
|
||||
word-break:keep-all;
|
||||
overflow-wrap:anywhere;
|
||||
/* L1: `anywhere` 는 min-content 를 "한 글자"로 만들어 부모 flex/grid 가 제목 열을
|
||||
0 까지 줄여도 되는 것처럼 계산한다. `break-word` 는 줄바꿈 결과는 같지만
|
||||
min-content 가 "가장 긴 단어"라서 열이 통째로 붕괴하는 걸 구조적으로 막는다. */
|
||||
overflow-wrap:break-word;
|
||||
}
|
||||
.lh-preview__copy p{
|
||||
margin:7px 0 0;
|
||||
|
|
@ -1100,6 +1229,11 @@
|
|||
word-break:keep-all;
|
||||
}
|
||||
.lh-actions{
|
||||
/* L1: 히어로가 좁으면 늘어나지도 억지로 버티지도 말고 아랫줄로 내려간다.
|
||||
아랫줄로 내려갔을 때도 margin-left:auto 로 카드 오른쪽에 붙여
|
||||
한 줄일 때(=넓은 폭)와 같은 "액션은 오른쪽" 규칙을 유지한다. */
|
||||
flex:0 1 auto;
|
||||
margin-left:auto;
|
||||
min-width:0;
|
||||
display:grid;
|
||||
justify-items:end;
|
||||
|
|
@ -1209,6 +1343,9 @@
|
|||
display:grid;
|
||||
gap:10px;
|
||||
background:transparent;
|
||||
/* L2: 카드가 깨지는 기준은 뷰포트가 아니라 "카드 폭"이라 컨테이너 질의를 쓴다.
|
||||
같은 1181px 뷰포트에서도 목록 위치에 따라 카드 폭이 391px~794px 로 갈린다. */
|
||||
container:lh-session-list / inline-size;
|
||||
}
|
||||
.lh-session-list li{
|
||||
min-width:0;
|
||||
|
|
@ -1221,6 +1358,26 @@
|
|||
border-radius:var(--radius);
|
||||
background:var(--bg-surface);
|
||||
}
|
||||
/* L2(2026-07-27): 3열을 끝까지 붙들면 중앙 본문이 뭉개졌다.
|
||||
실측(폭 1181px, /learn/practice): 카드 391px 에서 열이
|
||||
"140px 67.27px 131.73px" 로 잡혀 본문이 67px, 제목 b("서연")가 24px,
|
||||
"라포 단계 · 0턴 / 날짜"가 4줄로 접혔다(폭 1280px 에서도 본문 166px).
|
||||
좌 140 + 본문 180 + 액션 132 + 갭 24 + 패딩 26 ≈ 500px 이 3열의 손익분기라
|
||||
여유를 둔 600px 아래에서는 액션을 아랫줄로 내리고 본문에 최소 180px 을 준다. */
|
||||
@container lh-session-list (max-width:600px){
|
||||
.lh-session-list li{
|
||||
grid-template-columns:140px minmax(180px,1fr);
|
||||
}
|
||||
.lh-session-actions{
|
||||
grid-column:1 / -1;
|
||||
}
|
||||
}
|
||||
/* 2열(140+180+갭12+패딩26=358px)조차 못 넣는 폭에서는 완전 세로 스택 */
|
||||
@container lh-session-list (max-width:380px){
|
||||
.lh-session-list li{
|
||||
grid-template-columns:minmax(0,1fr);
|
||||
}
|
||||
}
|
||||
.lh-session-card:hover{
|
||||
border-color:var(--border-strong);
|
||||
background:color-mix(in srgb,var(--bg-surface) 78%,var(--bg-surface-2));
|
||||
|
|
@ -1302,6 +1459,13 @@
|
|||
font-size:12px;
|
||||
line-height:1.45;
|
||||
}
|
||||
/* D3: "단계 · 턴 · 날짜"를 한 줄에 붙이면 가운뎃점이 2개다. 날짜를 컬럼으로 분리. */
|
||||
.lh-session-card__body p{
|
||||
display:flex;
|
||||
flex-wrap:wrap;
|
||||
align-items:baseline;
|
||||
gap:2px 14px;
|
||||
}
|
||||
.lh-session-card__progress{
|
||||
width:100%;
|
||||
height:5px;
|
||||
|
|
@ -1433,13 +1597,25 @@
|
|||
line-height:1.35;
|
||||
}
|
||||
.lh-persona-progress__title em,
|
||||
.lh-persona-progress__meta,
|
||||
.lh-persona-progress__latest{
|
||||
min-width:0;
|
||||
overflow:hidden;
|
||||
text-overflow:ellipsis;
|
||||
white-space:nowrap;
|
||||
}
|
||||
/* D3: "N회 · N회 진행 · N회 리뷰 · 평균 N턴"은 가운뎃점이 3개였다.
|
||||
두 줄로 확정 분리해 줄마다 가운뎃점이 1개만 남게 한다. */
|
||||
.lh-persona-progress__meta{
|
||||
min-width:0;
|
||||
display:grid;
|
||||
gap:2px;
|
||||
}
|
||||
.lh-persona-progress__meta > span{
|
||||
min-width:0;
|
||||
overflow:hidden;
|
||||
text-overflow:ellipsis;
|
||||
white-space:nowrap;
|
||||
}
|
||||
.lh-persona-progress__title em{
|
||||
font-style:normal;
|
||||
font-weight:720;
|
||||
|
|
@ -1585,10 +1761,11 @@
|
|||
.lh-history-filter{
|
||||
justify-content:flex-start;
|
||||
}
|
||||
.lh-preview__hero{
|
||||
grid-template-columns:1fr;
|
||||
}
|
||||
/* L1: 히어로가 flex-wrap 로 바뀌어 grid-template-columns 는 더 이상 쓰이지 않는다.
|
||||
이 구간은 폭과 무관하게 항상 액션을 아랫줄에 두던 기존 동작을 유지한다. */
|
||||
.lh-actions{
|
||||
flex-basis:100%;
|
||||
margin-left:0;
|
||||
justify-items:start;
|
||||
}
|
||||
.lh-actions__note{
|
||||
|
|
@ -2205,8 +2382,11 @@
|
|||
position: relative;
|
||||
z-index: 1;
|
||||
}
|
||||
/* 위계 복구(2026-07-27): 이전 clamp(30px,3vw,38px)은 h1(clamp(29px,2.7vw,36px))보다
|
||||
커서 페르소나 이름이 페이지 제목을 눌렀다. h1 아래 단계로 내린다. */
|
||||
.vg-shell--learner-dashboard .lh-session-focus__head h2 {
|
||||
font-size: clamp(30px, 3vw, 38px);
|
||||
font-size: clamp(21px, 1.95vw, 28px);
|
||||
font-weight: 820;
|
||||
}
|
||||
.vg-shell--learner-dashboard .lh-recap {
|
||||
grid-template-columns: 224px minmax(0, 1fr);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue