// ───────────────────────────────────────────────────────────── // /chat — 메인 실시간 채팅 (d2-community §⑤, roomKey=main) // 색/치수는 app/styles/tokens 변수만 사용 (하드코딩 금지) // Twitch 스타일: border-radius 0, 선 기반 깔끔한 UI // 채팅 도크(우측 고정) + 팝업(/chat-popup) 공용 스타일 // ───────────────────────────────────────────────────────────── #chat-room { display: flex; flex-direction: column; height: 100%; min-height: 0; padding: var(--sp-4) var(--sp-5); gap: var(--sp-3); @media (max-width: 767.98px) { padding: var(--sp-3); } // ── 헤더: 참여자 수(클릭→목록) + 상태 + 컨트롤 ── .chat-room__head { display: flex; align-items: center; justify-content: space-between; flex-wrap: wrap; gap: var(--sp-2); } // 참여자 수 버튼 (실시간 채팅 label 위치) .chat-room__count { display: inline-flex; align-items: center; gap: var(--sp-2); padding: var(--sp-1) var(--sp-2); background: transparent; border: none; cursor: pointer; font-size: var(--fs-sm); color: var(--text-secondary); font-variant-numeric: tabular-nums; // --bg-icon(다크)은 양 테마 공통 → 라이트에서 어두운 텍스트가 안 보이므로 흰색 고정 // (옆 .chat-room__icon-btn 알림/설정 버튼과 동일). 숫자/caret/아이콘까지 함께 밝게. &:hover, &:focus-visible { background: var(--bg-icon); color: #fff; .chat-room__count-num, .chat-room__count-caret, > svg:first-child { color: #fff; } } > svg:first-child { color: var(--text-muted); } } .chat-room__count-num { font-weight: 700; color: var(--text-primary); } .chat-room__count-caret { font-size: var(--fs-2xs); color: var(--text-muted); transition: transform 0.15s ease; &.is-open { transform: rotate(180deg); } } .chat-room__meta { display: flex; align-items: center; gap: var(--sp-2); font-size: var(--fs-sm); color: var(--text-secondary); } .chat-room__state { color: var(--text-muted); white-space: nowrap; &--warn { color: var(--az-accent); } &--error { color: var(--color-danger); } } .chat-room__notice { display: flex; align-items: center; gap: var(--sp-3); padding: var(--sp-3) var(--sp-4); background: var(--bg-subtle); border: 1px solid var(--border-default); border-radius: 0; font-size: var(--fs-sm); color: var(--text-secondary); svg { flex-shrink: 0; color: var(--az-accent); } } .chat-room__body { position: relative; display: flex; flex: 1; min-height: 0; } .chat-room__messages { flex: 1; min-height: 0; overflow-y: auto; padding: var(--sp-3); background: var(--bg-elevated); border: 1px solid var(--border-default); border-radius: 0; } .chat-room__empty { padding: var(--sp-6) var(--sp-4); text-align: center; font-size: var(--fs-sm); color: var(--text-muted); } .chat-room__message { display: flex; align-items: baseline; gap: var(--sp-3); padding: var(--sp-2) var(--sp-3); // 글씨 크게/작게 — --chat-fs 배율 (이름·내용 상속) font-size: calc(var(--fs-base) * var(--chat-fs, 1)); line-height: 1.5; border-radius: 0; &:hover { background: var(--bg-subtle-hover); } } .chat-room__time { flex-shrink: 0; font-size: var(--fs-2xs); color: var(--text-muted); font-variant-numeric: tabular-nums; } .chat-room__badge { flex-shrink: 0; align-self: center; width: var(--sp-5); height: var(--sp-5); object-fit: contain; } .chat-room__name { flex-shrink: 0; font-weight: 600; color: var(--title-color, var(--text-secondary)); } .chat-room__content { color: var(--text-primary); word-break: break-word; overflow-wrap: anywhere; } // 시스템 메시지 — 일반 메시지와 스타일 구분 .chat-room__system { padding: var(--sp-2) var(--sp-3); text-align: center; font-size: var(--fs-xs); font-style: italic; color: var(--text-muted); } // 참여자 목록 오버레이 — 본체(.chat-room__body) 를 덮음 .chat-room__participants { position: absolute; inset: 0; z-index: 20; display: flex; } // "새 메시지 ↓" 점프 버튼 — 위로 스크롤 중 새 메시지 도착 시 노출 .chat-room__jump { position: absolute; bottom: var(--sp-4); left: 50%; transform: translateX(-50%); display: inline-flex; align-items: center; gap: var(--sp-2); padding: var(--sp-2) var(--sp-4); background: var(--az-accent); color: var(--btn-primary-text); font-size: var(--fs-sm); font-weight: 600; border: none; border-radius: 0; cursor: pointer; box-shadow: 0 var(--sp-1) var(--sp-3) var(--shadow-color); &:hover { background: var(--az-accent-hover); } } .chat-room__footer { position: relative; display: flex; flex-direction: column; gap: var(--sp-2); } .chat-room__input-row { display: flex; align-items: stretch; gap: var(--sp-2); } .chat-room__input { flex: 1; min-width: 0; padding: var(--sp-3) var(--sp-4); background: var(--bg-input); color: var(--text-primary); font-size: var(--fs-base); border: 1px solid var(--border-strong); border-radius: 0; &::placeholder { color: var(--text-muted); } &:disabled { opacity: 0.6; cursor: not-allowed; } } .chat-room__send { flex-shrink: 0; display: inline-flex; align-items: center; justify-content: center; min-width: var(--sp-7); padding: 0 var(--sp-4); background: var(--az-accent); color: var(--btn-primary-text); font-size: var(--fs-base); font-weight: 600; border: none; border-radius: 0; cursor: pointer; &:hover:not(:disabled) { background: var(--az-accent-hover); } &:disabled { background: var(--bg-subtle); color: var(--text-muted); cursor: not-allowed; } } .chat-room__cooldown { font-variant-numeric: tabular-nums; } // 푸터 이모지 버튼 — 입력창·전송과 높이 정렬(선 기반 아이콘 버튼) #emojiPicker { flex-shrink: 0; position: static; // 팝업(aside)의 위치 기준을 .chat-room__footer 로 이동 > button { display: inline-flex; align-items: center; justify-content: center; width: var(--sp-7); height: 100%; min-height: var(--sp-7); background: var(--bg-subtle); border: 1px solid var(--border-strong); color: var(--text-secondary); cursor: pointer; &:hover, &:focus, &:active { background: var(--bg-subtle-hover); color: var(--text-link); } } // 좁은 도크 폭 안에서 위로 열림 — footer 폭에 맞춰 span, 화면 밖 클리핑 방지 > aside { position: absolute; top: auto; bottom: calc(100% + var(--sp-2)); left: var(--sp-3); right: var(--sp-3); width: auto !important; height: min(340px, 50vh) !important; max-width: none; // Twitch 플랫: 이모지 팝업도 라운드 제거 (라이브러리 기본 8px 상쇄) border-radius: 0; --epr-width: auto; --epr-height: 340px; --epr-picker-border-radius: 0; } } .chat-room__blocked { padding: var(--sp-4); text-align: center; background: var(--color-danger-bg); border: 1px solid var(--color-danger-border); border-radius: 0; font-size: var(--fs-sm); color: var(--color-danger); } // 팝업(/chat-popup) — 전체 창 채움 &.chat-room--popup { flex: 1; min-height: 0; } } // ── 공용 아이콘 버튼 (헤더 수신설정 · 설정 트리거 · 닫기) ── .chat-room__icon-btn, .chat-menu__trigger, .chat-participants__close, .chat-modal__close { display: inline-flex; align-items: center; justify-content: center; width: var(--sp-6); height: var(--sp-6); background: transparent; border: none; cursor: pointer; color: var(--text-secondary); font-size: var(--fs-base); border-radius: 0; &:hover { background: var(--bg-icon); color: #fff; // --bg-icon(다크)은 양 테마 공통 → 라이트에서 --text-primary(어두움)가 안 보이므로 흰색 고정 } } // ── 접속 참여자 목록 ── .chat-participants { display: flex; flex: 1; min-width: 0; flex-direction: column; background: var(--bg-elevated); border: 1px solid var(--border-default); &__head { display: flex; align-items: center; justify-content: space-between; padding: var(--sp-3); border-bottom: 1px solid var(--border-default); } &__title { font-size: var(--fs-sm); font-weight: 600; color: var(--text-primary); } &__body { flex: 1; min-height: 0; overflow-y: auto; } &__empty { padding: var(--sp-6) var(--sp-4); text-align: center; font-size: var(--fs-sm); color: var(--text-muted); } &__list { display: flex; flex-direction: column; } &__item { display: flex; align-items: center; gap: var(--sp-3); padding: var(--sp-2) var(--sp-3); &:hover { background: var(--bg-subtle-hover); } } &__avatar { flex-shrink: 0; display: inline-flex; align-items: center; justify-content: center; width: var(--sp-6); height: var(--sp-6); background: var(--bg-subtle); color: var(--text-muted); overflow: hidden; img { width: 100%; height: 100%; object-fit: cover; } } &__info { display: flex; flex-direction: column; flex: 1; min-width: 0; } &__name { font-size: var(--fs-sm); font-weight: 600; color: var(--text-primary); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; } &__sid { font-size: var(--fs-2xs); color: var(--text-muted); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; } &__level { flex-shrink: 0; padding: 0 var(--sp-2); font-size: var(--fs-2xs); font-weight: 600; color: var(--az-accent); border: 1px solid var(--border-default); } } // ── 설정 dropdown (톱니바퀴) ── .chat-menu { position: relative; display: inline-flex; &__dropdown { position: absolute; top: calc(100% + var(--sp-2)); right: 0; z-index: 30; min-width: 160px; padding: var(--sp-2) 0; background: var(--bg-elevated); border: 1px solid var(--border-default); box-shadow: 0 var(--sp-1) var(--sp-3) var(--shadow-color); } &__item { display: flex; align-items: center; gap: var(--sp-3); width: 100%; padding: var(--sp-2) var(--sp-4); background: transparent; border: none; cursor: pointer; font-size: var(--fs-sm); color: var(--text-secondary); text-align: left; svg { width: var(--sp-4); color: var(--text-muted); } &:hover { background: var(--bg-subtle-hover); color: var(--text-primary); svg { color: var(--az-accent); } } } &__divider { height: 1px; margin: var(--sp-2) 0; background: var(--border-default); } } // ── 수신설정 modal (portal → body) ── .chat-modal { position: fixed; inset: 0; z-index: 1200; display: flex; align-items: center; justify-content: center; padding: var(--sp-4); background: var(--overlay-color); &__panel { display: flex; flex-direction: column; width: min(420px, 100%); max-height: min(560px, calc(100dvh - 2rem)); background: var(--bg-page); border: 1px solid var(--border-default); box-shadow: 0 var(--sp-2) var(--sp-5) var(--shadow-color); } &__head { display: flex; align-items: center; justify-content: space-between; padding: var(--sp-4); border-bottom: 1px solid var(--border-default); } &__title { font-size: var(--fs-lg); font-weight: 700; color: var(--text-primary); } &__body { display: flex; flex-direction: column; gap: var(--sp-4); padding: var(--sp-4); overflow-y: auto; } &__loading { padding: var(--sp-5); text-align: center; font-size: var(--fs-sm); color: var(--text-muted); } &__error { font-size: var(--fs-sm); color: var(--color-danger); } &__foot { display: flex; justify-content: flex-end; gap: var(--sp-3); padding: var(--sp-4); border-top: 1px solid var(--border-default); } &__btn { padding: var(--sp-2) var(--sp-5); font-size: var(--fs-sm); font-weight: 600; border: 1px solid transparent; border-radius: 0; cursor: pointer; &--ghost { background: transparent; border-color: var(--border-strong); color: var(--text-secondary); &:hover:not(:disabled) { background: var(--bg-subtle-hover); color: var(--text-primary); } } &--primary { background: var(--az-accent); color: var(--btn-primary-text); &:hover:not(:disabled) { background: var(--az-accent-hover); } } &:disabled { opacity: 0.6; cursor: not-allowed; } } } // ── 토글 스위치 (초대/귓속말/팔로잉 접속 표시) — 선 기반 사각 스위치 ── .chat-toggle { display: flex; align-items: center; justify-content: space-between; gap: var(--sp-4); cursor: pointer; &__text { display: flex; flex-direction: column; gap: var(--sp-1); min-width: 0; } &__label { font-size: var(--fs-base); font-weight: 600; color: var(--text-primary); } &__desc { font-size: var(--fs-2xs); color: var(--text-muted); } &__switch { position: relative; flex-shrink: 0; width: 44px; height: 24px; input { position: absolute; inset: 0; z-index: 1; margin: 0; opacity: 0; cursor: pointer; &:disabled { cursor: not-allowed; } } } &__slider { position: absolute; inset: 0; background: var(--bg-subtle); border: 1px solid var(--border-strong); transition: background 0.15s ease, border-color 0.15s ease; &::before { content: ''; position: absolute; top: 2px; left: 2px; width: 18px; height: 18px; background: var(--text-muted); transition: transform 0.15s ease, background 0.15s ease; } } input:checked + &__slider { background: var(--az-accent); border-color: var(--az-accent); &::before { transform: translateX(20px); background: var(--btn-primary-text); } } input:focus-visible + &__slider { outline: 2px solid var(--az-accent); outline-offset: 2px; } } // ── 채팅 팝업 창(/chat-popup) 래퍼 — 전체 뷰포트 ── .chat-popup { display: flex; height: 100vh; height: 100dvh; }