  :root {
    --bg: #05050a;
    --surface: rgba(15, 15, 25, 0.45);
    --surface-solid: #0d0d14;
    --surface-2: rgba(255, 255, 255, 0.04);
    --border: rgba(255, 255, 255, 0.08);
    --border-soft: rgba(255, 255, 255, 0.03);
    --accent: #818cf8;
    --accent-dim: rgba(129, 140, 248, 0.15);
    --found: #34d399;
    --found-dim: rgba(52, 211, 153, 0.15);
    --clue: #fbbf24;
    --clue-dim: rgba(251, 191, 36, 0.15);
    --danger: #f87171;
    --danger-dim: rgba(248, 113, 113, 0.15);
    --text-1: #f8fafc;
    --text-2: #94a3b8;
    --text-3: #64748b;
    --player-bg: linear-gradient(135deg, #6366f1 0%, #4338ca 100%);
    --player-text: #ffffff;
    --npc-bg: rgba(255, 255, 255, 0.05);
    --font-base: 16px;
    --shadow-sm: 0 4px 6px -1px rgba(0, 0, 0, 0.2);
    --shadow-md: 0 10px 15px -3px rgba(0, 0, 0, 0.3);
    --shadow-lg: 0 20px 25px -5px rgba(0, 0, 0, 0.4), 0 10px 10px -5px rgba(0, 0, 0, 0.2);
    --glass-blur: blur(24px);
  }

  * {
    box-sizing: border-box;
    margin: 0;
    padding: 0;
  }

  body {
    font-family: 'Pretendard Variable', Pretendard, -apple-system, BlinkMacSystemFont, system-ui, Roboto, 'Helvetica Neue', 'Segoe UI', 'Apple SD Gothic Neo', 'Noto Sans KR', 'Malgun Gothic', sans-serif;
    background: var(--bg);
    background-image: 
      radial-gradient(circle at 15% 50%, rgba(67, 56, 202, 0.12), transparent 45%),
      radial-gradient(circle at 85% 30%, rgba(99, 102, 241, 0.12), transparent 45%),
      radial-gradient(circle at 50% -20%, #151426 0%, #080811 40%, var(--bg) 80%);
    background-attachment: fixed;
    color: var(--text-1);
    height: 100vh;
    display: flex;
    flex-direction: column;
    overflow: hidden;
  }

  ::-webkit-scrollbar {
    width: 6px;
    height: 6px;
  }

  ::-webkit-scrollbar-track {
    background: transparent;
  }

  ::-webkit-scrollbar-thumb {
    background: var(--border);
    border-radius: 3px;
  }

  ::-webkit-scrollbar-thumb:hover {
    background: var(--text-3);
  }

  /* 헤더 */
  header {
    padding: 11px 20px;
    background: var(--surface);
    backdrop-filter: var(--glass-blur);
    border-bottom: 1px solid var(--border);
    display: flex;
    align-items: center;
    gap: 14px;
    z-index: 50;
  }

  /* 뒤로가기 버튼 + header-text(제목+상황설명)를 한 줄로 묶는 래퍼.
     align-items: stretch로 버튼 높이가 옆 블록(제목 행 + 설명 문단)
     전체 높이만큼 늘어나게 함 */
  .header-top-row {
    display: flex;
    align-items: stretch;
    gap: 10px;
    flex: 1;
    min-width: 0;
  }

  .header-text {
    flex: 1;
    min-width: 0;
  }

  .header-title-row {
    display: flex;
    align-items: center;
    gap: 8px;
  }

  /* 목록으로 나가기 버튼: 게임 진행 중(buildGameUI 이후)에만 표시,
     goToTitle()에서 다시 숨김. 클릭 시 exitToEpisodeList()가 confirm()으로
     진행상황 미저장을 경고한 뒤 goToTitle() 호출.
     높이는 고정값 대신 .header-top-row의 stretch로 옆 header-text와 맞춤 */
  .back-to-list-btn {
    display: none;
    align-items: center;
    justify-content: center;
    width: 33px;
    flex-shrink: 0;
    background: transparent;
    border: 1px solid var(--border);
    border-radius: 6px;
    color: var(--text-2);
    font-size: 16px;
    line-height: 1;
    cursor: pointer;
    font-family: inherit;
    transition: color 0.15s, border-color 0.15s;
  }

  .back-to-list-btn.show {
    display: flex;
  }

  .back-to-list-btn:hover {
    color: var(--text-1);
    border-color: var(--accent);
  }

  header h1 {
    font-size: 15px;
    font-weight: 600;
    color: var(--text-1);
    letter-spacing: 0.3px;
  }

  header p {
    font-size: 13px;
    color: #b4bcd4;
  }

  /* 플레이어 역할 뱃지 */
  .role-badge {
    display: none;
    font-size: 11px;
    padding: 2px 9px;
    background: var(--accent-dim);
    color: var(--accent);
    border: 1px solid rgba(123, 140, 255, 0.35);
    border-radius: 999px;
    font-weight: 500;
    white-space: nowrap;
    flex-shrink: 0;
  }

  .role-badge.visible {
    display: inline-block;
  }

  /* 레이아웃 */
  .main {
    display: flex;
    flex: 1;
    overflow: hidden;
  }

  /* 사이드바 */
  .sidebar {
    width: 220px;
    background: var(--surface);
    backdrop-filter: var(--glass-blur);
    border-right: 1px solid var(--border);
    display: flex;
    flex-direction: column;
    padding: 18px 14px;
    gap: 22px;
    overflow-y: auto;
    flex-shrink: 0;
  }

  .sidebar h2 {
    font-size: 12px;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 1.2px;
    color: var(--text-2);
    margin-bottom: 10px;
  }

  .info-section {
    flex: 1;
  }

  .info-char {
    margin-bottom: 14px;
  }

  .info-char-name {
    font-size: 13px;
    font-weight: 600;
    color: var(--accent);
    margin-bottom: 6px;
    letter-spacing: 0.3px;
  }

  .info-node {
    display: flex;
    align-items: flex-start;
    gap: 7px;
    font-size: calc(var(--font-base) - 1px);
    color: var(--text-2);
    padding: 4px 0;
    line-height: 1.5;
  }

  .info-node.revealed {
    color: var(--found);
  }

  /* 발굴의 손맛 (2026-09-10 §3-8) — 이번 턴에 채워진 칸만 한 번 은은히 번쩍인다 */
  .info-node.just-filled {
    animation: found-pulse 1.8s ease-out 1;
    border-radius: 4px;
  }

  @keyframes found-pulse {
    0% { background: rgba(126, 200, 145, 0.22); }
    60% { background: rgba(126, 200, 145, 0.08); }
    100% { background: transparent; }
  }

  .info-node.unrevealed {
    color: var(--text-3);
  }

  .info-node .dot {
    flex-shrink: 0;
    margin-top: 4px;
    font-size: 9px;
  }

  .evidence-tag {
    display: inline-block;
    vertical-align: baseline;
    margin-right: 6px;
    padding: 1px 6px;
    border-radius: 5px;
    font-size: 10px;
    line-height: 1.5;
    font-weight: 700;
    color: var(--text-1);
    border: 1px solid var(--border);
    background: var(--surface-2);
    white-space: nowrap;
  }

  .evidence-tag.claim {
    color: #f8d98f;
    border-color: rgba(245, 200, 66, 0.35);
    background: rgba(245, 200, 66, 0.10);
    box-shadow: 0 0 8px rgba(245, 200, 66, 0.2);
  }

  .evidence-tag.witness {
    color: #8ed8ff;
    border-color: rgba(142, 216, 255, 0.35);
    background: rgba(142, 216, 255, 0.10);
    box-shadow: 0 0 8px rgba(142, 216, 255, 0.2);
  }

  .evidence-tag.record {
    color: #a7b4ff;
    border-color: rgba(167, 180, 255, 0.35);
    background: rgba(167, 180, 255, 0.10);
    box-shadow: 0 0 8px rgba(167, 180, 255, 0.2);
  }

  .evidence-tag.verified {
    color: var(--found);
    border-color: rgba(61, 214, 140, 0.35);
    background: var(--found-dim);
    box-shadow: 0 0 8px rgba(61, 214, 140, 0.2);
  }

  .evidence-tag.inference {
    color: #f9a8d4;
    border-color: rgba(249, 168, 212, 0.35);
    background: rgba(249, 168, 212, 0.10);
    box-shadow: 0 0 8px rgba(249, 168, 212, 0.2);
  }

  .evidence-tag.risk {
    color: var(--danger);
    border-color: rgba(248, 113, 113, 0.35);
    background: var(--danger-dim);
    box-shadow: 0 0 8px rgba(248, 113, 113, 0.2);
  }

  /* 연결 단서 */
  .connection-hint {
    background: var(--clue-dim);
    border: 1px solid rgba(245, 200, 66, 0.25);
    border-radius: 8px;
    padding: 10px 12px;
    font-size: calc(var(--font-base) - 2px);
    color: var(--clue);
    line-height: 1.6;
  }

  /* 대화 영역 */
  .chat-area {
    flex: 1;
    display: flex;
    flex-direction: column;
    overflow: hidden;
    background: transparent;
  }

  /* NPC 탭 — .npc-tabs-row(래퍼)/.tab-save-btn은 파일 하단 "저장/불러오기" 섹션에서 정의.
     래퍼 안에서 이 탭 스크롤러가 남는 폭을 전부 차지하도록 flex:1;min-width:0을 준다(모바일
     overflow-x:auto가 래퍼 폭 안에서만 스크롤되고, 저장 버튼은 스크롤과 무관하게 고정됨). */
  .npc-tabs {
    display: flex;
    align-items: center;
    background: var(--surface);
    backdrop-filter: var(--glass-blur);
    border-bottom: 1px solid var(--border);
    /* flex-shrink:0(세로 방향 보호)은 이제 래퍼 .npc-tabs-row가 담당한다. 여기서 다시 쓰면
       바로 아래 flex 단축 속성이 덮어써 죽은 선언이 되고, 순서를 바꾸는 순간 가로 스크롤이
       깨지므로 두지 않는다. */
    flex: 1;      /* = grow:1 shrink:1 basis:0 — 래퍼에서 저장 버튼을 뺀 나머지 폭을 전부 차지 */
    min-width: 0; /* 스크롤 컨테이너의 필수 조건 — 없으면 min-width:auto라 내용보다 작아지지 못한다 */
    padding: 10px 14px;
    gap: 8px;
    z-index: 10;
  }

  .tab-btn {
    padding: 6px 18px;
    border: 1px solid var(--border);
    border-radius: 999px;
    background: transparent;
    color: var(--text-2);
    font-size: 13px;
    font-family: inherit;
    cursor: pointer;
    transition: color 0.15s, background 0.15s, border-color 0.15s;
    white-space: nowrap;
  }

  .tab-btn:hover {
    color: var(--text-1);
    background: var(--surface-2);
  }

  .tab-btn.active {
    color: var(--accent);
    background: var(--accent-dim);
    border-color: rgba(123, 140, 255, 0.4);
    font-weight: 600;
  }

  .tab-avatar {
    width: 26px;
    height: 26px;
    border-radius: 50%;
    object-fit: cover;
    margin-right: 6px;
    vertical-align: middle;
    border: 1.5px solid var(--border);
    transition: border-color 0.15s;
  }

  .tab-btn.active .tab-avatar {
    border-color: var(--accent);
  }

  /* 캐릭터 잠금(unlockedBy) — 연락처를 대화로 알아내기 전의 상대. 흐리게 + 흑백, 클릭 시 안내만 */
  .tab-btn.locked {
    opacity: 0.45;
    filter: grayscale(1);
    cursor: not-allowed;
  }

  .tab-btn.locked:hover {
    color: var(--text-2);
    background: transparent;
  }

  .tab-avatar.lock-hidden {
    visibility: hidden;
  }

  /* NPC 경계심 상태 표시 — 간접 시각화(수치 비노출), hardened 단계에 따라 점 색만 변함 */
  .npc-mood-dot {
    display: inline-block;
    width: 6px;
    height: 6px;
    border-radius: 50%;
    margin-left: 7px;
    vertical-align: middle;
    background: transparent;
    transition: background 0.3s, box-shadow 0.3s;
  }

  .npc-mood-dot.tier-1 {
    background: var(--clue);
    opacity: 0.6;
  }

  .npc-mood-dot.tier-2 {
    background: var(--clue);
    box-shadow: 0 0 5px var(--clue);
  }

  .npc-mood-dot.tier-3 {
    background: var(--danger);
    box-shadow: 0 0 5px var(--danger);
  }

  /* 메시지 등장 애니메이션 */
  @keyframes messageFadeUp {
    0% { opacity: 0; transform: translateY(20px); }
    100% { opacity: 1; transform: translateY(0); }
  }

  /* 메시지 컨테이너 */
  .messages {
    flex: 1;
    overflow-y: auto;
    padding: 32px 40px;
    display: flex;
    flex-direction: column;
    gap: 8px; /* 같은 화자 연속 발화 시 기본 간격 */
  }

  .messages.hidden {
    display: none;
  }

  /* 메시지 버블 — .message-wrapper/.msg-avatar-container/.msg-content 레이아웃은
     파일 하단 "카카오톡 스타일 메시지 구조" 섹션에서 정의(중복 정의 금지) */
  .message {
    padding: 14px 20px;
    border-radius: 18px;
    font-size: var(--font-base);
    line-height: 1.7;
    word-break: keep-all;
    white-space: pre-line;
    box-shadow: var(--shadow-sm);
    animation: messageFadeUp 0.8s cubic-bezier(0.2, 0.8, 0.2, 1) forwards;
  }

  .message.player {
    background: var(--player-bg);
    color: var(--player-text);
    border-bottom-right-radius: 4px;
    box-shadow: var(--shadow-sm);
  }

  .message.npc {
    background: var(--npc-bg);
    backdrop-filter: var(--glass-blur);
    color: var(--text-1);
    border: 1px solid var(--border-soft);
    box-shadow: var(--shadow-sm);
    /* 말풍선 "꼬리" 모서리는 하단 카카오톡 스타일 섹션의 .message-wrapper .message.npc가
       border-top-left-radius로 지정. 여기서 border-bottom-left-radius까지 같이 주면
       좌측 위/아래가 동시에 깎여 모양이 이상해지므로 중복 지정하지 않음. */
  }


  .message.system {
    background: var(--found-dim);
    color: var(--found);
    font-size: calc(var(--font-base) - 2px);
    padding: 5px 14px;
    border-radius: 20px;
    border: 1px solid rgba(61, 214, 140, 0.2);
    max-width: 85%;
    text-align: center;
  }

  /* NPC 감정 상태 간접 시각화 — 왜곡 강화(hardened) 발생 시 노출되는 상태 알림 */
  .message.system.warn {
    background: var(--clue-dim);
    color: var(--clue);
    border-color: rgba(245, 200, 66, 0.25);
  }

  .message.system.danger {
    background: var(--danger-dim);
    color: var(--danger);
    border-color: rgba(248, 113, 113, 0.25);
  }

  /* 루프 회차 재시작 안내 — 단서 발굴(초록)이 아니라 상황 서술이라 톤을 낮춘다 */
  .message.system.loop-intro {
    background: transparent;
    color: var(--text-2);
    border: 1px dashed var(--border-soft);
    max-width: 92%;
    text-align: left;
    padding: 8px 14px;
    border-radius: 12px;
    line-height: 1.55;
  }

  /* 동적 힌트(내면의 목소리) — 플레이어의 독백. NPC 대사와 구분되게 기울임 + 다른 톤 */
  .message.inner-voice {
    max-width: 68%;
    background: transparent;
    border: 1px dashed var(--border-soft);
    color: var(--text-2);
    font-style: italic;
    font-size: calc(var(--font-base) - 1px);
    border-radius: 14px;
  }

  /* 엔딩 준비 메시지 (채팅 내 결과 보기 버튼) */
  .message.ending-ready {
    align-self: center;
    display: flex;
    align-items: center;
    gap: 12px;
    background: var(--accent-dim);
    color: var(--accent);
    font-size: calc(var(--font-base) - 2px);
    padding: 7px 10px 7px 16px;
    border-radius: 20px;
    border: 1px solid rgba(123, 140, 255, 0.35);
    max-width: 85%;
  }

  .message.ending-ready button {
    background: var(--accent);
    color: #fff;
    border: none;
    border-radius: 12px;
    padding: 5px 14px;
    font-size: calc(var(--font-base) - 3px);
    font-family: inherit;
    font-weight: 600;
    cursor: pointer;
    white-space: nowrap;
    flex-shrink: 0;
    transition: opacity 0.15s;
  }

  .message.ending-ready button:hover {
    opacity: 0.85;
  }

  .message.error {
    max-width: 68%;
    color: #f87171;
    font-size: calc(var(--font-base) - 2px);
  }

  .message-meta {
    font-size: calc(var(--font-base) - 3px);
    color: var(--text-2);
    margin-bottom: 3px;
    font-weight: 500;
  }

  /* 전달 버튼 (deliveryAction) — 조건이 갖춰지면 입력창 위에 뜨는, 클릭 한 번으로 정해진
     행동 문구를 보내는 버튼. loop-hold-btn(EP10, 강제 대기)과 달리 눌러도 자동 진행되지 않고
     일반 전송과 동일하게 LLM 턴을 소모한다 — 급함을 알리는 펄스 애니메이션은 쓰지 않는다. */
  #delivery-action-area {
    padding: 0 20px;
  }

  /* 루프 홀드 버튼 — 채팅 영역 아래, 입력창 위에 표시 (사이드바에서 이동, 2026-07-26) */
  #loop-hold-area {
    padding: 8px 20px 0;
  }

  .delivery-action-btn {
    width: 100%; margin: 10px 0 0; padding: 10px 16px; cursor: pointer;
    background: var(--accent-dim); color: var(--accent); border: 1px solid var(--accent);
    border-radius: 8px; font-size: 14px; font-weight: 600; font-family: inherit;
    transition: opacity 0.15s;
  }

  .delivery-action-btn:hover {
    opacity: 0.85;
  }

  /* 입력창 */
  .input-area {
    padding: 16px 20px;
    border-top: 1px solid var(--border);
    background: var(--surface);
    backdrop-filter: var(--glass-blur);
    display: flex;
    gap: 12px;
    flex-shrink: 0;
    z-index: 10;
  }

  .input-area input {
    flex: 1;
    min-width: 0;
    background: var(--surface-2);
    border: 1px solid var(--border);
    color: var(--text-1);
    padding: 10px 14px;
    border-radius: 8px;
    font-size: 14px;
    font-family: inherit;
    outline: none;
    transition: border-color 0.15s, background 0.15s;
  }

  .input-area input:focus {
    border-color: var(--accent);
    background: var(--accent-dim);
  }

  .input-area input::placeholder {
    color: var(--text-3);
  }

  .input-area button {
    padding: 10px 20px;
    background: var(--accent);
    color: #fff;
    border: none;
    border-radius: 8px;
    font-size: 14px;
    font-weight: 500;
    cursor: pointer;
    font-family: inherit;
    transition: opacity 0.15s;
    white-space: nowrap;
    flex-shrink: 0;
  }

  .input-area button:hover {
    opacity: 0.85;
  }

  .input-area button:disabled {
    background: var(--surface-2);
    color: var(--text-3);
    cursor: not-allowed;
  }

  /* 에피소드 선택 오버레이 */
  .episode-overlay {
    display: flex;
    position: fixed;
    inset: 0;
    background: rgba(9, 9, 11, 0.85);
    backdrop-filter: var(--glass-blur);
    z-index: 300;
    align-items: center;
    justify-content: center;
    padding-right: 160px;
    /* 데스크탑 우측 광고 영역 확보 */
  }

  .episode-overlay.hide {
    display: none;
  }

  .episode-box {
    background: var(--surface-solid);
    border: 1px solid var(--border);
    border-radius: 20px;
    padding: 36px;
    max-width: 500px;
    width: 90%;
    max-height: 90dvh;
    overflow-y: auto;
    box-shadow: var(--shadow-lg);
  }

  .episode-box h2 {
    font-size: 18px;
    font-weight: 600;
    color: var(--text-1);
    margin-bottom: 20px;
  }

  .episode-list {
    display: flex;
    flex-direction: column;
    gap: 10px;
  }

  .episode-card {
    background: var(--surface-2);
    border: 1px solid var(--border);
    border-radius: 10px;
    padding: 14px 18px;
    cursor: pointer;
    text-align: left;
    font-family: inherit;
    width: 100%;
    transition: border-color 0.15s, background 0.15s;
    display: flex;
    align-items: center;
    gap: 14px;
  }

  .episode-thumb {
    width: 80px;
    height: 80px;
    border-radius: 10px;
    object-fit: cover;
    flex-shrink: 0;
    border: 1px solid var(--border);
  }

  .episode-card-body {
    flex: 1;
    min-width: 0;
  }

  .episode-card:hover {
    border-color: var(--accent);
    background: var(--accent-dim);
  }

  .episode-card.locked {
    cursor: not-allowed;
    opacity: 0.45;
  }

  .episode-card.locked .episode-thumb {
    filter: grayscale(1) brightness(0.4);
  }

  .episode-card.locked:hover {
    border-color: var(--border);
    background: var(--surface-2);
  }

  .episode-lock-badge {
    font-size: 11px;
    color: var(--text-3);
    margin-bottom: 6px;
  }

  .episode-card h3 {
    font-size: 14px;
    font-weight: 600;
    color: var(--text-1);
    margin-bottom: 6px;
  }

  .episode-card-meta {
    display: flex;
    align-items: center;
    gap: 8px;
    margin-bottom: 8px;
  }

  .episode-time-badge {
    font-size: 11px;
    font-weight: 700;
    padding: 2px 9px;
    border-radius: 10px;
    border: 1px solid;
  }

  .episode-time-badge.easy {
    color: #6fcf97;
    background: rgba(111, 207, 151, 0.12);
    border-color: rgba(111, 207, 151, 0.35);
  }

  .episode-time-badge.medium {
    color: #f2c94c;
    background: rgba(242, 201, 76, 0.12);
    border-color: rgba(242, 201, 76, 0.35);
  }

  .episode-time-badge.hard {
    color: #ff8a8a;
    background: rgba(255, 138, 138, 0.12);
    border-color: rgba(255, 138, 138, 0.35);
  }

  .episode-card-skills {
    display: flex;
    flex-wrap: wrap;
    gap: 5px;
  }

  .episode-skill-tag {
    font-size: 11px;
    padding: 2px 8px;
    background: var(--accent-dim);
    color: var(--accent);
    border-radius: 10px;
    border: 1px solid rgba(123, 140, 255, 0.25);
  }

  /* 인트로 오버레이 */
  .intro-overlay {
    display: flex;
    position: fixed;
    inset: 0;
    background: rgba(9, 9, 11, 0.85);
    backdrop-filter: var(--glass-blur);
    z-index: 200;
    align-items: center;
    justify-content: center;
    overflow-y: auto;
    padding: 24px 0;
  }

  .intro-overlay.hide {
    display: none;
  }

  .intro-box {
    background: var(--surface-solid);
    border: 1px solid var(--border);
    border-radius: 20px;
    padding: 40px;
    max-width: 480px;
    width: 90%;
    text-align: center;
    box-shadow: var(--shadow-lg);
    margin: auto;
  }

  .intro-box h2 {
    color: var(--text-1);
    font-size: 20px;
    font-weight: 600;
    margin-bottom: 20px;
  }

  .intro-box p {
    color: var(--text-2);
    font-size: 14px;
    line-height: 1.8;
    margin-bottom: 28px;
    word-break: keep-all;
    white-space: pre-line;
  }

  .intro-box button {
    padding: 11px 32px;
    background: var(--accent);
    color: #fff;
    border: none;
    border-radius: 8px;
    font-size: 14px;
    font-weight: 500;
    cursor: pointer;
    font-family: inherit;
    transition: opacity 0.15s;
  }

  .intro-box button:hover {
    opacity: 0.85;
  }

  /* 엔딩 오버레이 */
  .ending-overlay {
    display: none;
    position: fixed;
    inset: 0;
    background: rgba(9, 9, 11, 0.85);
    backdrop-filter: var(--glass-blur);
    z-index: 100;
    align-items: center;
    justify-content: center;
    /* @AX:NOTE 내용이 뷰포트보다 길면 오버레이 자체를 스크롤 — 모바일에서 버튼 잘림 방지 */
    overflow-y: auto;
    padding: 24px 0;
  }

  .ending-overlay.show {
    display: flex;
  }

  .ending-box {
    background: var(--surface-solid);
    border: 1px solid var(--border);
    border-radius: 20px;
    padding: 36px;
    max-width: 460px;
    width: 90%;
    text-align: center;
    box-shadow: var(--shadow-lg);
    /* @AX:NOTE margin auto: 박스가 뷰포트보다 길 때 flex center의 상단 잘림 방지(safe centering) */
    margin: auto;
  }

  .ending-box h2 {
    color: var(--text-1);
    font-size: 18px;
    font-weight: 600;
    margin-bottom: 14px;
  }

  .ending-box p {
    color: var(--text-2);
    font-size: 14px;
    line-height: 1.75;
    margin-bottom: 22px;
    word-break: keep-all;
  }

  /* 엔딩 에필로그 개인화: 비동기 도착 후에만 표시 (app.js: requestEpilogue) */
  @keyframes epilogue-fade-in {
    from { opacity: 0; transform: translateY(6px); }
    to   { opacity: 1; transform: translateY(0); }
  }

  .ending-epilogue {
    margin-bottom: 22px;
    animation: epilogue-fade-in 0.6s ease;
  }

  .epilogue-divider {
    font-size: 11px;
    color: var(--text-3);
    letter-spacing: 2px;
    margin-bottom: 12px;
  }

  .ending-box .epilogue-narration {
    font-style: italic;
    color: var(--text-2);
    font-size: 13px;
    line-height: 1.8;
    margin-bottom: 10px;
  }

  .ending-box .epilogue-npc-line {
    font-size: 13px;
    color: var(--text-1);
    line-height: 1.7;
    margin-bottom: 0;
  }

  .epilogue-npc-name {
    color: var(--text-3);
    font-size: 12px;
  }

  .ending-stats {
    text-align: left;
    background: var(--surface-2);
    border-radius: 10px;
    padding: 16px;
    margin-bottom: 22px;
    border: 1px solid var(--border-soft);
  }

  .ending-stats h3 {
    font-size: 10px;
    color: var(--text-3);
    text-transform: uppercase;
    letter-spacing: 1.2px;
    margin-bottom: 10px;
  }

  .ending-stat-row {
    font-size: 13px;
    padding: 4px 0;
    color: var(--found);
  }

  .ending-buttons {
    display: flex;
    gap: 10px;
    justify-content: center;
  }

  .ending-box button {
    padding: 10px 24px;
    background: var(--surface-2);
    color: var(--text-1);
    border: 1px solid var(--border);
    border-radius: 8px;
    font-size: 14px;
    cursor: pointer;
    font-family: inherit;
    transition: background 0.15s;
  }

  .ending-box button:hover {
    background: var(--accent-dim);
    border-color: var(--accent);
  }

  .ending-box button:disabled {
    color: var(--text-3);
    cursor: not-allowed;
  }

  .ending-box button:disabled:hover {
    background: var(--surface-2);
    border-color: var(--border);
  }

  .btn-back-chat {
    display: block;
    width: 100%;
    background: transparent !important;
    border: none !important;
    color: var(--text-3) !important;
    font-size: 12px !important;
    cursor: pointer;
    font-family: inherit;
    margin-top: 12px;
    padding: 4px 0 !important;
    text-decoration: underline;
    text-underline-offset: 3px;
    text-align: center;
  }

  .btn-back-chat:hover {
    color: var(--text-2) !important;
    background: transparent !important;
  }

  .verification-box {
    max-width: 720px;
    width: 95%;
    text-align: left;
    padding: 28px;
  }

  .verification-box h2 {
    text-align: center;
    margin-bottom: 8px;
    color: var(--accent);
  }

  .verification-lead {
    text-align: center;
    font-size: 13px;
    color: var(--text-2);
    margin-bottom: 20px;
    word-break: keep-all;
  }

  .verification-items {
    display: flex;
    flex-direction: column;
    gap: 12px;
    max-height: 52dvh;
    overflow-y: auto;
    padding-right: 4px;
    margin-bottom: 18px;
  }

  .verification-item {
    background: var(--surface-2);
    border: 1px solid var(--border);
    border-radius: 8px;
    padding: 12px;
  }

  .verification-item p {
    margin: 0 0 8px;
    color: var(--text-1);
    font-size: 13px;
    line-height: 1.5;
  }

  .verification-item select {
    width: 100%;
    background: var(--surface);
    border: 1px solid var(--border);
    color: var(--text-1);
    padding: 7px 10px;
    border-radius: 6px;
    font-size: 13px;
    font-family: inherit;
    outline: none;
  }

  /* 네이티브 드롭다운 팝업은 select의 반투명 배경을 그대로 쓰지 못해
     불투명 배경을 따로 지정해야 함. 안 하면 옵션 목록이 흰 배경에
     흰 글씨(--text-1)로 렌더링되어 안 보이는 문제가 생김. */
  select option {
    background: var(--surface-solid);
    color: var(--text-1);
  }

  .verification-item select.report-wrong {
    border-color: rgba(248, 113, 113, 0.7);
    background: var(--danger-dim);
  }

  .verification-feedback {
    min-height: 20px;
    margin-bottom: 14px;
    color: var(--danger);
    font-size: 13px;
    text-align: center;
  }

  /* 피드백 버튼 (헤더) */
  .feedback-btn {
    background: var(--surface-2);
    border: 1px solid var(--border);
    color: var(--text-2);
    padding: 4px 12px;
    border-radius: 6px;
    font-size: 12px;
    font-family: inherit;
    font-weight: 600;
    cursor: pointer;
    white-space: nowrap;
    flex-shrink: 0;
    transition: color 0.15s, border-color 0.15s;
  }

  .feedback-btn:hover {
    color: var(--text-1);
    border-color: var(--accent);
  }

  /* 피드백 오버레이 */
  .feedback-overlay {
    display: none;
    position: fixed;
    inset: 0;
    background: rgba(0, 0, 0, 0.75);
    backdrop-filter: blur(4px);
    z-index: 200;
    align-items: center;
    justify-content: center;
  }

  .feedback-overlay.show {
    display: flex;
  }

  .feedback-box {
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: 16px;
    padding: 28px;
    max-width: 420px;
    width: 90%;
    max-height: 85vh;
    overflow-y: auto;
    box-shadow: 0 24px 64px rgba(0, 0, 0, 0.5);
  }

  .feedback-box h2 {
    color: var(--text-1);
    font-size: 17px;
    font-weight: 600;
    margin-bottom: 18px;
  }

  .feedback-box label {
    display: block;
    font-size: 12px;
    color: var(--text-2);
    margin: 14px 0 6px;
  }

  .feedback-box select,
  .feedback-box textarea,
  .feedback-box input[type="email"] {
    width: 100%;
    background: var(--surface-2);
    border: 1px solid var(--border);
    color: var(--text-1);
    border-radius: 8px;
    padding: 9px 11px;
    font-size: 13px;
    font-family: inherit;
    resize: vertical;
  }

  .feedback-check {
    display: flex !important;
    align-items: center;
    gap: 7px;
    font-size: 12px !important;
    color: var(--text-2);
    cursor: pointer;
  }

  .feedback-check input {
    flex-shrink: 0;
  }

  .feedback-note {
    font-size: 11px;
    color: var(--text-3);
    margin-top: 12px;
    line-height: 1.5;
  }

  .feedback-status {
    font-size: 12px;
    color: var(--accent);
    min-height: 16px;
    margin-top: 8px;
  }

  .feedback-buttons {
    display: flex;
    gap: 10px;
    justify-content: flex-end;
    margin-top: 18px;
  }

  .feedback-box button {
    padding: 9px 20px;
    background: var(--surface-2);
    color: var(--text-1);
    border: 1px solid var(--border);
    border-radius: 8px;
    font-size: 13px;
    cursor: pointer;
    font-family: inherit;
    transition: background 0.15s;
  }

  .feedback-box button:hover {
    background: var(--accent-dim);
    border-color: var(--accent);
  }

  .feedback-box button:disabled {
    color: var(--text-3);
    cursor: not-allowed;
  }

  /* 로딩 */
  .loading-dots::after {
    content: "";
    animation: dots 1.2s steps(3, end) infinite;
  }

  /* 타이핑 버블 (2026-09-10 §3-8) — 응답 대기의 공백을 "상대가 말하려는 중"으로 번역한다.
     점 3개가 차례로 뜨는 메신저 규약; NPC 말풍선 틀(이름·아바타)은 addMessage가 붙여준다. */
  .typing-bubble {
    display: flex;
    align-items: center;
    min-height: 1.4em;
  }

  .typing-dots {
    display: inline-flex;
    gap: 5px;
    padding: 3px 0;
  }

  .typing-dots i {
    width: 7px;
    height: 7px;
    border-radius: 50%;
    background: var(--text-2);
    opacity: 0.5;
    animation: typing-bounce 1.3s ease-in-out infinite;
  }

  .typing-dots i:nth-child(2) { animation-delay: 0.16s; }
  .typing-dots i:nth-child(3) { animation-delay: 0.32s; }

  @keyframes typing-bounce {

    0%,
    60%,
    100% {
      transform: translateY(0);
      opacity: 0.45;
    }

    30% {
      transform: translateY(-4px);
      opacity: 1;
    }
  }

  @keyframes dots {

    0%,
    100% {
      content: "";
    }

    33% {
      content: ".";
    }

    66% {
      content: "..";
    }

    99% {
      content: "...";
    }
  }

  /* 스크롤바 */
  ::-webkit-scrollbar {
    width: 3px;
  }

  ::-webkit-scrollbar-track {
    background: transparent;
  }

  ::-webkit-scrollbar-thumb {
    background: var(--border);
    border-radius: 2px;
  }

  /* 남은 기회(턴 예산) 표시 — endings.timeout이 있을 때만 노출 */
  .turn-indicator {
    display: none;
    margin-left: auto;
    font-size: 12px;
    font-weight: 600;
    color: var(--clue);
    background: var(--clue-dim);
    border: 1px solid var(--border);
    border-radius: 999px;
    padding: 3px 10px;
    white-space: nowrap;
  }

  .turn-indicator.urgent {
    color: #ff8a8a;
    background: rgba(255, 138, 138, 0.12);
  }

  /* 배드/시간초과 엔딩은 색조를 달리해 결과의 무게를 전달 */
  .ending-box.ending-down #ending-title {
    color: #ff8a8a;
  }

  /* 글씨 크기 조절 */
  .font-size-ctrl {
    display: flex;
    gap: 3px;
    flex-shrink: 0;
  }

  .font-size-ctrl button {
    background: var(--surface-2);
    border: 1px solid var(--border);
    color: var(--text-2);
    padding: 4px 9px;
    border-radius: 5px;
    font-size: 12px;
    font-family: inherit;
    font-weight: 600;
    cursor: pointer;
    line-height: 1;
    transition: color 0.15s, border-color 0.15s;
  }

  .font-size-ctrl button:hover:not(:disabled) {
    color: var(--text-1);
    border-color: var(--accent);
  }

  .font-size-ctrl button:disabled {
    opacity: 0.3;
    cursor: not-allowed;
  }

  /* 사이드바 토글 버튼 (데스크탑에서는 숨김) */
  .sidebar-toggle {
    display: none;
  }

  /* 사이드바 백드롭 */
  .sidebar-backdrop {
    display: none;
    position: fixed;
    inset: 0;
    z-index: 49;
    background: rgba(0, 0, 0, 0.55);
  }

  /* 데스크탑 세로 광고 래퍼 */
  #ad-desktop-wrapper {
    position: relative;
    z-index: 310;
    width: 160px;
    height: 600px;
    flex-shrink: 0;
    display: flex;
    align-items: center;
    justify-content: center;
    background: var(--surface);
    border-left: 1px solid var(--border);
    margin-top: auto;
    margin-bottom: auto;
  }

  /* 모바일 가로 광고 래퍼 (최상단) — 320x50 유닛 고정 (2026-07-19, 320x100은 테스트 중 미사용) */
  #ad-mobile-wrapper {
    position: relative;
    z-index: 310;
    width: 100%;
    height: 50px;
    background: var(--bg);
    border-bottom: 1px solid var(--border);
    display: flex;
    align-items: center;
    justify-content: center;
    flex-shrink: 0;
  }

  /* 768px 초과 1100px 이하 구간에서 데스크탑 광고 가리기 */
  @media (max-width: 1100px) and (min-width: 769px) {
    #ad-desktop-wrapper {
      display: none;
    }

    .episode-overlay {
      padding-right: 0;
    }
  }

  /* ── 모바일 반응형 ── */
  @media (max-width: 768px) {
    #ad-desktop-wrapper {
      display: none;
    }

    .episode-overlay {
      padding-right: 0;
      padding-top: 50px;
      /* 모바일 상단 광고 영역(50px) 확보 */
    }

    .episode-box {
      max-height: calc(100dvh - 90px);
      /* 상단 광고(50px) + 상하 여백(40px) 확보 */
      padding: 24px;
    }

    /* iOS Safari 100vh 버그 대응 */
    body {
      height: 100dvh;
    }

    /* 모바일 반응형 헤더 구조 개선 */
    header {
      flex-wrap: wrap;
      gap: 10px 8px;
      padding: 12px 16px;
    }

    .header-top-row {
      flex: 1 1 100%;
      margin-bottom: 2px;
    }

    /* 헤더 상황 텍스트: 모바일에서 폰트 축소 */
    header p {
      font-size: 12px;
    }

    #turn-indicator {
      margin-left: 0;
      order: 2;
    }

    .font-size-ctrl {
      margin-left: auto;
      order: 3;
    }

    /* 피드백 버튼: 사용 빈도가 가장 높은 발굴 정보(오른쪽 끝)와 반대로
       왼쪽 끝에 배치, 테두리 없는 보조 링크 스타일로 차별화 */
    .feedback-btn {
      order: 1;
      flex-shrink: 0;
      background: transparent;
      border: none;
      color: var(--text-3);
      text-decoration: underline;
      text-underline-offset: 3px;
      padding: 4px 0;
    }

    .feedback-btn:hover {
      color: var(--text-2);
      border-color: transparent;
    }

    /* 사이드바 토글 버튼 표시 */
    .sidebar-toggle {
      display: block;
      position: relative;
      margin-left: 0;
      order: 5;
      flex-shrink: 0;
      background: var(--surface-2);
      border: 1px solid var(--border);
      color: var(--text-2);
      padding: 6px 12px;
      border-radius: 6px;
      font-size: 12px;
      font-family: inherit;
      cursor: pointer;
      white-space: nowrap;
    }

    /* 길잡이 알림 배지: 사이드바 닫힌 상태에서 새 길잡이가 뜨면 표시 */
    .sidebar-toggle.has-alert::after {
      content: "";
      position: absolute;
      top: -3px;
      right: -3px;
      width: 10px;
      height: 10px;
      border-radius: 50%;
      background: #ff5555;
      box-shadow: 0 0 0 2px var(--surface);
    }

    /* 사이드바: 왼쪽에서 슬라이드인 드로어 */
    .sidebar {
      position: fixed;
      top: 0;
      left: -240px;
      bottom: 0;
      z-index: 50;
      width: 240px;
      padding-top: 56px;
      /* 헤더 높이만큼 여백 */
      transition: left 0.24s ease;
      box-shadow: 4px 0 20px rgba(0, 0, 0, 0.45);
    }

    .sidebar.open {
      left: 0;
    }

    .sidebar-backdrop.open {
      display: block;
    }

    /* 채팅 영역이 전체 너비 사용 */
    .chat-area {
      width: 100%;
    }

    /* NPC 탭 가로 스크롤 */
    .npc-tabs {
      overflow-x: auto;
      -webkit-overflow-scrolling: touch;
    }

    .tab-btn {
      flex-shrink: 0;
      padding: 11px 16px;
    }

    .tab-avatar {
      width: 22px;
      height: 22px;
    }


    .episode-thumb {
      width: 80px;
      height: 80px;
    }

    /* 메시지 버블 */
    .messages {
      padding: 14px 12px;
      gap: 8px;
    }

    /* NPC 말풍선 폭은 .msg-content가 담당(하단 "카카오톡 스타일 메시지 구조" 섹션),
       player는 폭 상한이 없어 별도 처리 불필요 */
    .msg-content,
    .message.inner-voice,
    .message.error {
      max-width: 88%;
    }

    /* 입력창: font-size 16px → iOS 자동 확대 방지 */
    .input-area {
      padding: 10px 12px;
      gap: 8px;
    }

    .input-area input {
      font-size: 16px;
      padding: 10px 12px;
    }

    .input-area button {
      padding: 10px 16px;
      font-size: 14px;
    }

    /* 오버레이 박스 패딩 축소 */
    .episode-box {
      padding: 24px 18px;
    }

    .intro-box {
      padding: 28px 18px;
    }

    .ending-box {
      padding: 24px 18px;
    }

    /* @AX:NOTE 엔딩/인트로 오버레이는 자체 스크롤이므로 max-height 대신 top 오프셋 사용 —
       상단 광고(50px, z-index 310)가 fixed 오버레이 위에 떠 있어, 오버레이 시작점을
       광고 아래로 내려야 스크롤 중에도 내용이 광고에 가려지지 않음. 광고가 항상 50px
       고정이라(2026-07-19) 키보드 표시 여부와 무관하게 동일한 오프셋을 사용함. */
    .ending-overlay,
    .intro-overlay {
      top: 50px;
    }

    /* 엔딩 버튼: 세로 배치 */
    .ending-buttons {
      flex-direction: column;
      align-items: stretch;
    }

    .ending-box button {
      text-align: center;
    }

    /* 저장/불러오기: 모바일에서 슬롯 카드는 좁은 폭에 맞춰 액션 버튼을 가로로 나란히 둔다
       (기본은 세로 — .slot-actions 정의는 파일 하단 "저장/불러오기" 섹션 참고) */
    .slot-box {
      padding: 20px 16px;
    }

    .slot-card {
      flex-wrap: wrap;
    }

    .slot-actions {
      flex-direction: row;
      margin-left: auto;
    }

    .episode-box-header {
      flex-wrap: wrap;
      gap: 8px;
    }
  }
/* ============ ���� ������ �г� (����ũž) ============ */
/* @AX:NOTE 2026-07-12: .large-portrait-panel CSS removed (panel deleted from index.html).
   Character images now arrive as photo-share chat bubbles - single UI for desktop+mobile. */

.message.npc.photo-message {
  padding: 6px;
}

.photo-message img {
  display: block;
  max-width: 240px;
  width: 100%;
  border-radius: 8px;
  cursor: zoom-in;
}

.photo-caption {
  font-size: calc(var(--font-base) - 1px);
  color: var(--text-2);
  padding: 6px 4px 2px;
}

.lightbox-overlay {
  position: fixed;
  inset: 0;
  background: rgba(0, 0, 0, 0.85);
  display: flex;
  align-items: center;
  justify-content: center;
  z-index: 1000;
  cursor: zoom-out;
}

.lightbox-overlay img {
  max-width: 92vw;
  max-height: 92vh;
  border-radius: 8px;
  box-shadow: var(--shadow-md);
}

/* ============ 저장/불러오기 (2026-08-23) ============ */

/* NPC 탭 줄 우측 고정 저장 버튼 — .npc-tabs(overflow-x:auto, 위쪽 정의)의 스크롤러 바깥에
   형제로 둬서 모바일 가로 스크롤과 무관하게 항상 보이게 한다(계획서 §7-a). */
.npc-tabs-row {
  display: flex;
  align-items: stretch;
  flex-shrink: 0;
  background: var(--surface);
  backdrop-filter: var(--glass-blur);
  border-bottom: 1px solid var(--border);
}

.npc-tabs-row .npc-tabs {
  border-bottom: none; /* 테두리는 래퍼가 담당 — 중복 방지 */
}

.tab-save-btn {
  flex-shrink: 0;
  position: relative;
  background: transparent;
  border: none;
  border-left: 1px solid var(--border);
  color: var(--text-2);
  font-size: 17px;
  padding: 0 16px;
  cursor: pointer;
  font-family: inherit;
  transition: color 0.15s, background 0.15s;
}

.tab-save-btn:hover:not(:disabled) {
  color: var(--text-1);
  background: var(--surface-2);
}

.tab-save-btn:disabled {
  opacity: 0.4;
  cursor: not-allowed;
}

/* 자동저장 실패 경고 점 — .sidebar-toggle.has-alert::after와 같은 패턴 재사용 */
.tab-save-btn.has-alert::after {
  content: "";
  position: absolute;
  top: 6px;
  right: 8px;
  width: 8px;
  height: 8px;
  border-radius: 50%;
  background: #ff5555;
  box-shadow: 0 0 0 2px var(--surface);
}

/* 에피소드 목록 헤더 — 제목 + 불러오기 버튼 */
.episode-box-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  margin-bottom: 20px;
}

.episode-box-header h2 {
  margin-bottom: 0;
}

.load-save-btn {
  display: none; /* 저장된 슬롯이 있을 때만 app.js: updateLoadButtonVisibility()가 보여줌 */
  align-items: center;
  gap: 4px;
  background: var(--surface-2);
  border: 1px solid var(--border);
  color: var(--text-2);
  padding: 6px 12px;
  border-radius: 6px;
  font-size: 12px;
  font-family: inherit;
  font-weight: 600;
  cursor: pointer;
  white-space: nowrap;
  transition: color 0.15s, border-color 0.15s;
}

.load-save-btn:hover {
  color: var(--text-1);
  border-color: var(--accent);
}

/* 저장/불러오기 슬롯 모달 — .ending-overlay/.ending-box 패턴을 따르되 목록형이라 폭을 넓힌다 */
.slot-overlay {
  display: none;
  position: fixed;
  inset: 0;
  background: rgba(9, 9, 11, 0.85);
  backdrop-filter: var(--glass-blur);
  z-index: 400; /* 에피소드 목록(300) 위에서도 열릴 수 있어야 함 */
  align-items: center;
  justify-content: center;
  overflow-y: auto;
  padding: 24px 0;
}

.slot-overlay.show {
  display: flex;
}

.slot-box {
  background: var(--surface-solid);
  border: 1px solid var(--border);
  border-radius: 20px;
  padding: 28px;
  max-width: 480px;
  width: 92%;
  max-height: 85dvh;
  overflow-y: auto;
  box-shadow: var(--shadow-lg);
  margin: auto;
}

.slot-box-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  margin-bottom: 16px;
}

.slot-box-header h2 {
  color: var(--text-1);
  font-size: 18px;
  font-weight: 600;
}

.slot-close-btn {
  background: transparent;
  border: none;
  color: var(--text-2);
  font-size: 18px;
  cursor: pointer;
  padding: 2px 6px;
  line-height: 1;
  font-family: inherit;
}

.slot-close-btn:hover {
  color: var(--text-1);
}

.slot-list {
  display: flex;
  flex-direction: column;
  gap: 10px;
}

/* 저장 범위 안내 — 불러오기 화면에서만 표시(app.js: openSaveModal) */
.slot-scope-note {
  margin: 14px 2px 0;
  padding-top: 12px;
  border-top: 1px solid var(--border);
  font-size: 12px;
  line-height: 1.6;
  color: var(--text-3);
  word-break: keep-all;
}

.slot-card {
  display: flex;
  align-items: center;
  gap: 12px;
  background: var(--surface-2);
  border: 1px solid var(--border);
  border-radius: 10px;
  padding: 12px 14px;
}

.slot-card.slot-invalid {
  border-color: rgba(248, 113, 113, 0.4);
}

.slot-card.slot-empty {
  color: var(--text-3);
  font-size: 13px;
}

.slot-thumb {
  width: 44px;
  height: 44px;
  border-radius: 8px;
  object-fit: cover;
  flex-shrink: 0;
}

.slot-thumb-empty {
  background: var(--surface);
  border: 1px dashed var(--border-soft);
}

.slot-body {
  flex: 1;
  min-width: 0;
}

.slot-title {
  font-size: 13px;
  font-weight: 600;
  color: var(--text-1);
  margin-bottom: 2px;
}

.slot-meta {
  font-size: 11px;
  color: var(--text-2);
  line-height: 1.5;
}

.slot-trimmed {
  color: var(--clue);
  font-size: 10px;
}

.slot-warn {
  font-size: 12px;
  color: var(--danger);
}

.slot-actions {
  display: flex;
  flex-direction: column;
  gap: 6px;
  flex-shrink: 0;
}

.slot-actions button {
  padding: 6px 12px;
  background: var(--surface);
  color: var(--text-1);
  border: 1px solid var(--border);
  border-radius: 6px;
  font-size: 12px;
  font-family: inherit;
  cursor: pointer;
  white-space: nowrap;
  transition: background 0.15s, border-color 0.15s;
}

.slot-actions button:hover:not(:disabled) {
  background: var(--accent-dim);
  border-color: var(--accent);
}

.slot-actions button:disabled {
  color: var(--text-3);
  cursor: not-allowed;
}

.slot-delete-btn:hover:not(:disabled) {
  background: var(--danger-dim) !important;
  border-color: var(--danger) !important;
}

/* 자동저장 덮어쓰기 경고 — .ending-overlay 재사용, 에피소드 목록(300) 위에서 열려야 하므로
   z-index만 올린다 */
#autosave-warn-overlay {
  z-index: 350;
}

/* 저장 실패 안내 토스트 */
.save-toast {
  display: none;
  position: fixed;
  bottom: 20px;
  left: 50%;
  transform: translateX(-50%);
  background: var(--surface-solid);
  border: 1px solid rgba(248, 113, 113, 0.4);
  color: var(--text-1);
  padding: 12px 18px;
  border-radius: 10px;
  font-size: 13px;
  max-width: 90%;
  box-shadow: var(--shadow-lg);
  z-index: 500;
  text-align: center;
  line-height: 1.5;
}

.save-toast.show {
  display: block;
}

.save-toast a {
  color: var(--accent);
  text-decoration: underline;
  text-underline-offset: 2px;
}

/* ============ ����� ���� ============ */

/* ============ īī���� ��Ÿ�� �޽��� ���� ============ */
.message-wrapper {
  display: flex;
  align-items: flex-start;
  width: 100%;
  max-width: 100%;
  margin-bottom: 8px;
}

.message-wrapper.npc-wrapper {
  justify-content: flex-start;
}

.message-wrapper.player-wrapper {
  justify-content: flex-end;
}

.message-wrapper.system-wrapper,
.message-wrapper.error-wrapper {
  justify-content: center;
}

.msg-avatar-container {
  width: 44px;
  height: 44px;
  border-radius: 50%;
  overflow: hidden;
  margin-right: 12px;
  flex-shrink: 0;
  box-shadow: var(--shadow-sm);
  background: var(--surface-1);
}

.msg-avatar {
  width: 100%;
  height: 100%;
  object-fit: cover;
}

.message-wrapper.no-avatar {
  padding-left: 56px; /* �ƹ�Ÿ ������ŭ �鿩���� */
}

.msg-content {
  display: flex;
  flex-direction: column;
  max-width: 75%;
}

.msg-content .message-meta {
  font-size: calc(var(--font-base) - 2px);
  color: var(--text-2);
  margin-bottom: 4px;
  margin-left: 4px;
}

.message-wrapper .message.npc {
  align-self: flex-start;
  background: var(--npc-bg);
  backdrop-filter: var(--glass-blur);
  color: var(--text-1);
  border: 1px solid var(--border-soft);
  border-top-left-radius: 4px;
  max-width: 100%; /* �θ�(msg-content) �ʺ� ���� */
}

.message-wrapper .message.player {
  align-self: flex-end;
  max-width: 100%;
}

.message-wrapper.player-wrapper + .message-wrapper.npc-wrapper,
.message-wrapper.npc-wrapper + .message-wrapper.player-wrapper,
.message-wrapper.system-wrapper + .message-wrapper.player-wrapper,
.message-wrapper.system-wrapper + .message-wrapper.npc-wrapper,
.message-wrapper.player-wrapper + .message-wrapper.system-wrapper,
.message-wrapper.npc-wrapper + .message-wrapper.system-wrapper {
  margin-top: 16px;
}
