/* Pretendard (self-hosted, variable) — 프리미엄 한국어 UI 표준 폰트 */
@font-face {
  font-family: 'Pretendard Variable';
  font-weight: 45 920;
  font-style: normal;
  font-display: swap;
  src: url('/fonts/PretendardVariable.woff2') format('woff2-variations');
}
:root {
  --font-sans: 'Pretendard Variable', -apple-system, BlinkMacSystemFont, system-ui,
    'Apple SD Gothic Neo', 'Noto Sans KR', 'Segoe UI', Roboto, sans-serif;

  /* 간격 토큰 — 4px 그리드. 패딩·마진·갭은 전부 이 스케일만 사용(크기·라운드는 예외). */
  --sp-1: 4px;  --sp-2: 8px;  --sp-3: 12px; --sp-4: 16px;
  --sp-5: 20px; --sp-6: 24px; --sp-8: 32px; --sp-10: 40px;
  --hairline: 1px; /* 디바이더 두께 */
  --hdr-title-h: 52px; --hdr-chip-h: 44px; /* 헤더 제목줄 / 필터 칩줄 고정 높이 */

  /* 모션 토큰 — 모든 모션은 이 변수만 쓴다. 새 duration·곡선 즉흥 생성 금지. */
  --dur-instant: 120ms;   /* 탭 눌림 등 미세 반응 */
  --dur-fast:    200ms;   /* 작은 전환 */
  --dur-base:    300ms;   /* 표준 전환 */
  --dur-slow:    480ms;   /* 등장 / 큰 이동 */
  --ease-out:    cubic-bezier(0.16, 1, 0.3, 1);      /* 들어오고 안착 — 기본값 */
  --ease-spring: cubic-bezier(0.34, 1.45, 0.45, 1);  /* 살짝 튕김 — 강조 / 등장 */
  --ease-in-out: cubic-bezier(0.65, 0, 0.35, 1);     /* 이동 / 재배치 */
  --stagger-step: 70ms;   /* 리스트 항목 간 지연 */
  /* 누름 깊이 토큰 — 버튼류 :active scale 의 단일 소스. strong=작은/표준 버튼, soft=큰 CTA.
     (리스트 행·테마옵션·완성도 카드 등은 별도 튜닝값 .9776/.992 유지) */
  --press-strong: .94;
  --press-soft:   .97;
}

/* 멀미·접근성: reduced-motion이면 전역으로 모션 제거(사용자 OS 설정일 때만 발동). */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: 0.001ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.001ms !important;
    scroll-behavior: auto !important;
  }
}
/* 하단 탭바 전환 시 패널 등장 — transform+opacity만. */
@keyframes lm-tab-in {
  from { opacity: 0; transform: translateY(10px); }
  to   { opacity: 1; transform: none; }
}

/* 인디고 블룸 오로라 드리프트 키프레임 — 적용은 다크 테마의 .screen.active(앱 컬럼)에서.
   오로라는 .app-bg 풀뷰포트가 아니라 컬럼(.screen) 배경으로 옮겨, 데스크탑 풀윈도우에서 안 늘어남. */
@keyframes aurora-drift {
  from { background-position: 0% 0%, 0% 0%, 0% 0%, 0 0; }
  to   { background-position: 6% 4%, -5% 3%, 3% -4%, 0 0; }
}

/* 웹(데스크탑)에서도 아이폰 비율 유지 — 390×844 컬럼을 테마 정렬(가운데)로 띄운다.
   단, 앱을 감싼 외곽 카드 프레임(테두리·라운드·그림자)은 제거해 "박스 없는" 모습으로.
   html body .screen.active(0,2,2) 가 테마 데스크탑 프레임(.screen.active 0,2,0)을 덮는다.
   모바일(<600px)은 디바이스 폭 그대로(풀블리드). */
@media (min-width: 600px) {
  html body .screen.active {
    width: 390px;
    max-width: 390px;
    height: min(844px, calc(100dvh - 40px));
    min-height: 0;
    border: none;
    /* 폰 화면처럼 모서리 곡률만(테두리·그림자 없음). overflow:hidden(테마)이 콘텐츠를 둥글게 클립.
       테마별 기존 라운드 토큰 재사용: 다크 28 / 모노 22 / 라이트 24. */
    border-radius: var(--r-xl, var(--r-lg, var(--radius-lg, 28px)));
    box-shadow: none;
  }
}

/* 우상단 액션 클러스터 (검색 + 알림 벨) */
.top-actions { position: absolute; top: calc(16px + env(safe-area-inset-top, 0px)); right: 16px; z-index: 30; display: flex; gap: 8px; }
/* Soft Glass Minimal: 유리는 랜덤 통화 CTA 단 하나 → 검색·알림 버튼은 플랫(블러·그림자 제거). */
.top-action-btn { position: relative; width: 40px; height: 40px; border-radius: 50%;
  border: 1px solid var(--line, rgba(128,128,128,.2));
  background: color-mix(in srgb, var(--text, var(--ink, #888)) 5%, transparent);
  color: var(--text, inherit); display: flex; align-items: center; justify-content: center; cursor: pointer;
  box-shadow: none; transition: transform .1s ease, background-color .15s ease; -webkit-tap-highlight-color: transparent; }
.top-action-btn:active { transform: scale(.92); }
.top-action-btn svg { width: 20px; height: 20px; }
/* 벨 배지 — 1자리는 완전한 원(min-width=height, 좌우 패딩 최소), 벨 글리프 우상단 코너에 정확히.
   색/그림자/라운드는 글래스 배지 통일 규칙이 담당. */
.notif-badge { position: absolute; top: -2px; right: -2px; min-width: 16px; height: 16px; padding: 0 4px;
  color: #fff; font-size: 10px; line-height: 16px; text-align: center; }
.notif-list .list-row { border-radius: 12px; }
/* 검색·알림 전체화면(.screen)의 스크롤 리스트 영역 */
.screen-list { flex: 1; min-height: 0; overflow-y: auto; -webkit-overflow-scrolling: touch; overscroll-behavior: contain; padding: 8px 16px 16px; }
/* 레이아웃 계약 ② — flex column 안의 스크롤 컨테이너는 flex:1 + min-height:0 이라야
   콘텐츠가 많아도 화면(100dvh)을 안 밀어내고 내부에서만 스크롤된다. (overflow:hidden/auto 가
   자동최소높이를 0으로 눌러주지만, 규칙대로 명시해 미래 변경에도 안 깨지게 한다.) */
body #tab-panels { min-height: 0; }
/* 레이아웃 계약 ③(가로 안전영역) — dark 만 갖고 있던 .screen 좌우 safe 패딩을 오버라이드 레이어로
   끌어올려 3테마 동일 지오메트리. 세로(포트레이트)·데스크탑은 좌우 인셋 0 → 무변화, 랜드스케이프에서만
   노치/아일랜드 옆으로 컬럼을 비켜낸다. (dark.css 의 중복 선언은 제거됨.) */
body .screen { padding-left: env(safe-area-inset-left, 0px); padding-right: env(safe-area-inset-right, 0px); }

/* ============================================================
   하위페이지(상세·대화·알림) = 앱 위에 떠 있는 오버레이 레이어 (인스타/X 푸시 내비).
   베이스(#screen-app)는 그대로 떠 있고, 레이어가 오른쪽에서 슬라이드 인 / 오른쪽으로 슬라이드 아웃.
   왼쪽 가장자리 → 오른쪽 스와이프로 뒤로 가기(nav.js 가 transform 을 손가락에 붙임).
   transform 만 애니메이트(레이아웃·페인트 안 건드림).
   · 진입(.lm-entering) = CSS "애니메이션" — display:none→flex 로 나타나도 0% 키프레임부터 확실히 재생.
     (트랜지션은 막 나타난 요소에선 안 걸려 점프함. 정적 화면 #screen-conversation/notifications 가 특히.)
   · 나가기·드래그 복귀(.lm-anim) = 트랜지션 — 이미 보이는 요소라 확실. nav.js 가 토글.
   ============================================================ */
@keyframes lm-subpage-in { from { transform: translateX(100%); } to { transform: translateX(0); } }
body .lm-subpage {
  position: fixed;
  inset: 0;                 /* 모바일: 풀폭 컬럼(뷰포트) */
  z-index: 40;              /* 탭바·글래스 캡(20)·우상단 액션(30) 위 */
  display: flex;
  flex-direction: column;
  transform: translateX(100%);   /* 기본 = 화면 밖 오른쪽 */
  /* will-change 는 안착(rest) 상태에 두지 않는다 — iOS WebKit 에선 transform/will-change:transform
     을 가진 조상이 자손의 backdrop-filter 를 무력화한다(헤더 글래스·상단 캡이 평평해짐). 슬라이드
     중(entering/anim)에만 켜고, 안착 땐 transform:none 으로 둬 헤더/캡 블러가 iOS 에서도 살아난다. */
  /* 배경은 .screen 에서 상속(불투명) → 아래 베이스를 덮음. */
}
body .lm-subpage.lm-in       { transform: none; }    /* 안착 상태(= translateX(0) 와 동일, 단 transform 제거로 iOS backdrop-filter 살림) */
body .lm-subpage.lm-entering { will-change: transform; animation: lm-subpage-in var(--dur-base, .28s) var(--ease-out, cubic-bezier(.2,.7,.2,1)) both; }
body .lm-subpage.lm-anim     { will-change: transform; transition: transform var(--dur-base, .28s) var(--ease-out, cubic-bezier(.2,.7,.2,1)); }
/* 테마가 #screen-conversation 에 ID 로 걸어둔 lm-slide-in(16px) 은 오버레이 슬라이드와 겹치므로,
   ID 포함 셀렉터로 끄고(쉴 때) / 진입 땐 우리 애니메이션이 이기게 덮는다. */
body #screen-conversation.lm-subpage,
body #screen-notifications.lm-subpage { animation: none; }
body #screen-conversation.lm-subpage.lm-entering,
body #screen-notifications.lm-subpage.lm-entering { animation: lm-subpage-in var(--dur-base, .28s) var(--ease-out, cubic-bezier(.2,.7,.2,1)) both; }
@media (min-width: 600px) {
  /* 데스크탑: 390 컬럼을 가운데 고정(센터링은 margin 으로 — transform 은 슬라이드 전용). */
  body .lm-subpage {
    inset: auto;
    left: 50%;
    top: 50%;
    width: 390px;
    height: min(844px, calc(100dvh - 40px));
    margin-left: -195px;
    margin-top: calc(min(844px, calc(100dvh - 40px)) * -0.5);
    border-radius: var(--r-xl, var(--r-lg, var(--radius-lg, 28px)));
    overflow: hidden;
  }
}
@media (prefers-reduced-motion: reduce) {
  body .lm-subpage.lm-entering,
  body #screen-conversation.lm-subpage.lm-entering,
  body #screen-notifications.lm-subpage.lm-entering { animation: none; } /* 모션 끄기: 즉시 열림 */
  body .lm-subpage.lm-anim { transition: none; }                          /* 즉시 닫힘 */
}
/* 하위페이지에서 탭으로 "복귀"할 때는 패널 슬라이드업(lm-msg) 억제(nav.js가 .no-panel-anim 토글).
   탭 전환 시의 애니메이션은 그대로 둔다. */
body .no-panel-anim .panel.active { animation: none; }
/* 하단 탭바로 탭 전환 시 패널 등장 — 모션 토큰 기반(테마의 lm-msg .2s ease 를 덮음).
   transform+opacity만 애니메이트. 복귀(.no-panel-anim)는 위 억제 규칙이 더 구체적이라 그대로 무애니메이션. */
body .panel.active { animation: lm-tab-in var(--dur-base) var(--ease-out) both; }
/* 말풍선 등장(lm-msg)은 "새로 도착/전송된" 메시지에만. 대화 첫 진입 땐 화면이 lm-subpage-in 으로
   통째 슬라이드돼 들어오는데, 그 안의 메시지·시스템 배너(.msg.system "아직 메시지가 없어요…")가
   각자 또 lm-msg 로 떠오르면 "배너까지 같이 애니메이션"처럼 이중으로 움직여 보였다(사용자 보고).
   → 초기 일괄 렌더 메시지는 무애니메이션(슬라이드와 함께 정적으로 따라 들어옴). appendMessage 가
   라이브 수신/전송 행에만 붙이는 .lm-pop 만 lm-msg 로 떠오른다. body 접두 → 3테마 공통(테마 덮음). */
body .messages > .msg,
body .msg-row { animation: none; }
body .msg-row.lm-pop { animation: lm-msg .18s ease both; }
.pf-actions { display: flex; flex-direction: column; gap: 8px; margin-top: 24px; }

/* 오버스크롤 정책:
   · 문서(html/body) = none → 페이지 전체 바운스 차단.
   · .panel = none → sticky 헤더(.section-head)가 패널 "안"에 있어, top 오버스크롤(네이티브 고무줄
     바운스)이 헤더까지 끌고 내려온다(특히 Safari에서 눈에 띔). contain 은 체이닝만 막고 자기 바운스는
     허용하므로 none 으로 바운스 자체를 차단해야 헤더가 고정된다. (당겨서 새로고침은 ptr.js 의 JS
     transform 이라 네이티브 바운스 없이도 동작.)
   · .messages/.screen-list = contain 유지 → 헤더(.conv-header)가 스크롤러 "밖" 형제라 로컬 바운스에
     안 끌린다. 바운스의 자연스러운 give 는 살린다. */
html, body { overscroll-behavior: none; }
body .panel { overscroll-behavior: none; }
body .messages,
body .screen-list { overscroll-behavior: contain; }

/* 채팅 = 아래서부터 쌓임(인스타/iMessage식): 메시지가 적으면 하단(입력바 쪽)에 붙고, 늘어나면 위로 채워진다.
   첫 자식의 margin-top:auto 가 남는 세로 공간을 전부 위로 밀어 하단 정렬 → 콘텐츠가 넘치면 auto 가 0 으로
   풀려 일반 스크롤(위 히스토리까지 다 보임)로 동작. justify-content:flex-end 의 오버플로 잘림 버그 회피.
   .messages 는 flex column 이라 스크롤·정렬 모두 그대로. 3테마 공통(레이아웃이라 여기 한 곳에서). */
body .messages > :first-child { margin-top: auto; }

/* 스크롤바 숨김 — 데스크탑 웹에서 오른쪽에 뜨는 스크롤 막대를 감춘다(스크롤 기능은 그대로).
   폰 프레임 UI라 막대가 보이면 짜쳐서. 모든 스크롤 영역 공통(현재/미래 스크롤러 모두 커버). */
* { scrollbar-width: none; -ms-overflow-style: none; }
*::-webkit-scrollbar { width: 0; height: 0; display: none; }

/* 채팅 날짜 구분선 (오늘/어제/날짜) */
.date-sep { align-self: center; margin: 16px auto 8px; padding: 8px 16px; border-radius: 999px;
  font-size: 11.5px; font-weight: 500; color: var(--text-dim, #8a8a96);
  background: color-mix(in srgb, var(--text, var(--ink, #888)) 6%, var(--bg, #14151c));
  border: 1px solid var(--line, rgba(128,128,128,.18)); }
/* 맨 아래로 버튼 (대화에서 위로 스크롤했을 때) */
.scroll-down { position: absolute; right: 16px; bottom: 84px; z-index: 6; width: 40px; height: 40px;
  border-radius: 50%; border: 1px solid var(--line-strong, var(--line, rgba(128,128,128,.22))); cursor: pointer;
  background: var(--card, var(--surface, #17181f)); color: var(--text, inherit);
  box-shadow: 0 2px 8px -4px rgba(0,0,0,.25); display: flex; align-items: center; justify-content: center; font-size: 18px;
  transition: transform .12s ease, opacity .15s ease; }
.scroll-down:active { transform: scale(.92); }
/* sd-badge 위치/크기만 — 색/라운드/그림자는 아래 글래스 배지 통일 규칙이 담당.
   (옛 background/border-radius 를 두면 .scroll-down .sd-badge 의 (0,2,0) 특정성이 글래스 규칙을 이겨 안 먹음) */
.scroll-down .sd-badge { position: absolute; top: -4px; right: -4px; min-width: 16px; height: 16px; padding: 0 4px;
  color: #fff; font-size: 10px; line-height: 16px; }

/* 당겨서 새로고침 — 패널 최상단에서 아래로 당기면 도는 인디케이터.
   #tab-panels(position:relative) 기준 상단 중앙에 고정, 패널이 transform 으로 내려오며 드러난다. */
.ptr-ind { position: absolute; top: 10px; left: 50%; transform: translateX(-50%); z-index: 2;
  opacity: 0; pointer-events: none; transition: opacity .15s ease; }
.ptr-spinner { width: 24px; height: 24px; border-radius: 50%;
  border: 2.5px solid color-mix(in srgb, var(--text, #888) 16%, transparent);
  border-top-color: var(--accent, #7b6bff); }
.ptr-ind.spin .ptr-spinner { animation: ptr-rot .7s linear infinite; }
@keyframes ptr-rot { to { transform: rotate(360deg); } }

/* 랜덤 탭: 별도 전체화면이 아니라 일반 탭 패널 — 아래 탭 메뉴는 그대로 보인다.
   패널을 세로 flex 로 채워 홈/검색/대화 뷰가 탭바 위 영역에 자연스럽게 배치되게. */
#panel-random.active { display: flex; flex-direction: column; height: 100%; overflow: hidden; }
/* 매칭 플로우는 전체화면 오버레이(#screen-random-call)에서도 동일하게 세로 flex 로 채운다.
   (.screen.active/.lm-subpage 가 이미 flex column → 자식 채움 규칙만 같이 걸어준다.) */
#screen-random-call.active { overflow: hidden; }
#panel-random > .card,
#panel-random > .chatview,
#screen-random-call > .card,
#screen-random-call > .chatview { flex: 1 1 auto; min-height: 0; }
#panel-random > .chatview,
#screen-random-call > .chatview { display: flex; flex-direction: column; }
#panel-random > .chatview > .messages,
#screen-random-call > .chatview > .messages { flex: 1 1 auto; min-height: 0; }

/* 말풍선 줄바꿈: 한국어는 음절 중간이 아니라 띄어쓰기에서 끊기게(keep-all),
   긴 URL 등 끊을 데 없는 문자열만 강제 줄바꿈(anywhere). DM·랜덤 채팅 공통. */
body .msg { word-break: keep-all; overflow-wrap: anywhere; }
/* DM 말풍선은 행(row)이 너비를 제한 — 말풍선 자체의 %max-width 가 콘텐츠 기준 행에 걸려
   찌부러지는 순환 축소를 막는다. (랜덤 채팅의 .msg 는 .msg-row 밖이라 영향 없음) */
body .msg-row .msg { max-width: 100%; }

/* 토스트("저장됐어요" 등)는 상단에서 내려오게 — 하단 탭 메뉴를 가리지 않도록.
   body .toast(0,1,1) / body .toast:not(.hidden)(0,2,1) 가 테마 규칙보다 우선. */
/* 등장 모션은 최종 위치보다 아래에서 살짝 올라오게 — 미리보기에서 애니메이션이 멈춰도(초기 프레임 고정) 잘리지 않음 */
@keyframes lm-toast-top { from { transform: translate(-50%, 10px); } to { transform: translate(-50%, 0); } }
body .toast { top: calc(14px + env(safe-area-inset-top, 0px)); bottom: auto; }
body .toast:not(.hidden) { animation: lm-toast-top .25s ease both; }

/* ───────────────────────────────────────────────────────────────
   Soft Glass Minimal + 사용자 요구 글래스 바.
   유리는 기본적으로 랜덤 통화 CTA(hero) 하나지만, 사용자가 명시적으로 원한
   "비치는 글래스 바" 2종은 예외로 유지: 상단 sticky 헤더 + 하단 탭바 →
   콘텐츠가 바 뒤로 스크롤되며 비치는 see-through 글래스.
   나머지(컴포저·모달·토스트·작은 버튼)는 전부 플랫.
   ─────────────────────────────────────────────────────────────── */
@supports ((-webkit-backdrop-filter: blur(1px)) or (backdrop-filter: blur(1px))) {
  /* 랜덤 통화 채팅 헤더만 상시 글래스 — 섹션/대화 헤더는 아래 "연속 헤더"로 분리(평소 평평). */
  body .chat-header {
    background: color-mix(in srgb, var(--card, var(--surface, #17181f)) 70%, transparent);
    /* saturate() 제거 — 스크롤되는 메시지 위에 떠 있는 바는 매 프레임 재샘플되는데 saturate 는
       블러 위에 컬러매트릭스 패스를 더해 iOS 에서 비싸다. 블러 반경(18px)은 그대로 → 지오메트리·룩 유지. */
    -webkit-backdrop-filter: blur(18px);
    backdrop-filter: blur(18px);
    border-color: color-mix(in srgb, var(--text, var(--ink, #fff)) 9%, transparent);
  }
}

/* ── 연속 헤더 — 평소엔 본문과 같은 면(투명·평평), 스크롤로 콘텐츠가 헤더 밑에 들어갈 때만 글래스.
   glass.js 가 스크롤 컨테이너 scrollTop>0 일 때 .header-scrolled 를 토글한다.
   글래스는 floating surface(떠오른 헤더·FAB)에만. 전환은 배경/보더 색 160ms 만. */
body .section-head,
body .conv-header {
  background: transparent;
  -webkit-backdrop-filter: none;
  backdrop-filter: none;
  border-bottom: var(--hairline) solid transparent;
  transition: background-color .16s ease, border-color .16s ease;
}
/* 헤더 글래스 = iOS 머티리얼(단일 균일 블러 + 다크 틴트) — 아래 가장자리만 짧게 마스크 페이드로 콘텐츠와
   부드럽게 만난다(하드 1px 라인 없음). 헤더 안 .header-fade 오버레이가 블러 전담: 헤더 본체는 투명 유지
   (글자/아이콘은 안 흐려짐 — backdrop-filter 는 뒤 콘텐츠만 흐림). .header-fade 는 glass.js 가 헤더 첫
   자식으로 주입(단일 div). */
body .section-head > :not(.header-fade),
body .conv-header > :not(.header-fade) { position: relative; z-index: 1; }   /* 글자·버튼을 블러 오버레이 위로 */
body .section-head,
body .conv-header {
  text-shadow: 0 1px 3px rgba(0, 0, 0, .4);   /* 가독성 보험(틴트 제거 → 그림자로) — 상시 블러라 항상 적용. 텍스트만 */
}

@supports ((-webkit-backdrop-filter: blur(1px)) or (backdrop-filter: blur(1px))) {
  /* 차분한 progressive blur 9겹 + 분리된 어두운 베일 (사용자 스펙). 핵심 = 부스트(saturate>100%·brightness>1)
     절대 금지 — 발광(bloom)의 원인이 부스트라, 순수 블러만 쓰면 밝은 아바타·흰 글자가 빛나지 않고 차분하게 뭉개진다.
     발광 억제는 별개의 단일 "어두운 베일"(.hf-veil)이 담당(블러와 분리).
     · 블러 9겹: 반경 = 17.68*(i/9)^2 (maxBlur 17.68 = 이전 20.8 × 0.85, 높이/세기 15% 균일 축소 — 9겹 비율 동일; 아래 약→위 강, backdrop-filter 형제 누적). 마스크는 cut=100*(10-i)/9 까지,
       38% 길이 페이드(cut-38 → cut)로 레이어끼리 충분히 겹쳐 이음새·하단 경계가 안 보이게(cut-38<0 이면 0%부터 페이드).
       .header-fade = 블러 존 calc(100% + 10.2px) = 제목헤더 + 10.2px 꼬리(헤더 기준이라 노치 자동 커버). 칩은 헤더 밖이라
       쉴 땐 존 밖(선명), 스크롤로 헤더 밑에 들어갈 때만 블러. 마스크가 % 라 존 높이 바뀌어도 페이드 같은 비율 스케일.
     · 베일(.hf-veil, 다크 전용): 위 진하고 아래 0 으로 녹는 그라디언트 1겹을 블러 위에 얹어 발광 제거.
     · 모든 backdrop-filter·mask 에 -webkit- 동시(iOS). 텍스트는 z:1(위 text-shadow 로 가독성).
     · ⚠ iOS 깜빡임용 translateZ(0) 은 일부러 뺐다 — 이 프로젝트 확인된 iOS 버그상 조상 transform 이 자손
       backdrop-filter 를 죽이고(CLAUDE.md), 레이어별 transform 은 형제 누적을 깨뜨릴 수 있어 위험. 깜빡이면 on-device 로 추가. */
  body .header-fade {
    position: absolute; left: 0; right: 0; top: 0; height: calc(100% + 10.2px);
    z-index: 0; pointer-events: none;
  }
  body .header-fade > div { position: absolute; inset: 0; pointer-events: none; }
  body .header-fade .hf1 {
    -webkit-backdrop-filter: blur(0.22px); backdrop-filter: blur(0.22px);
    -webkit-mask-image: linear-gradient(to bottom, #000 0%, #000 62%, transparent 100%);
            mask-image: linear-gradient(to bottom, #000 0%, #000 62%, transparent 100%);
  }
  body .header-fade .hf2 {
    -webkit-backdrop-filter: blur(0.87px); backdrop-filter: blur(0.87px);
    -webkit-mask-image: linear-gradient(to bottom, #000 0%, #000 50.89%, transparent 88.89%);
            mask-image: linear-gradient(to bottom, #000 0%, #000 50.89%, transparent 88.89%);
  }
  body .header-fade .hf3 {
    -webkit-backdrop-filter: blur(1.96px); backdrop-filter: blur(1.96px);
    -webkit-mask-image: linear-gradient(to bottom, #000 0%, #000 39.78%, transparent 77.78%);
            mask-image: linear-gradient(to bottom, #000 0%, #000 39.78%, transparent 77.78%);
  }
  body .header-fade .hf4 {
    -webkit-backdrop-filter: blur(3.49px); backdrop-filter: blur(3.49px);
    -webkit-mask-image: linear-gradient(to bottom, #000 0%, #000 28.67%, transparent 66.67%);
            mask-image: linear-gradient(to bottom, #000 0%, #000 28.67%, transparent 66.67%);
  }
  body .header-fade .hf5 {
    -webkit-backdrop-filter: blur(5.46px); backdrop-filter: blur(5.46px);
    -webkit-mask-image: linear-gradient(to bottom, #000 0%, #000 17.56%, transparent 55.56%);
            mask-image: linear-gradient(to bottom, #000 0%, #000 17.56%, transparent 55.56%);
  }
  body .header-fade .hf6 {
    -webkit-backdrop-filter: blur(7.86px); backdrop-filter: blur(7.86px);
    -webkit-mask-image: linear-gradient(to bottom, #000 0%, #000 6.44%, transparent 44.44%);
            mask-image: linear-gradient(to bottom, #000 0%, #000 6.44%, transparent 44.44%);
  }
  body .header-fade .hf7 {
    -webkit-backdrop-filter: blur(10.70px); backdrop-filter: blur(10.70px);
    -webkit-mask-image: linear-gradient(to bottom, #000 0%, transparent 33.33%);
            mask-image: linear-gradient(to bottom, #000 0%, transparent 33.33%);
  }
  body .header-fade .hf8 {
    -webkit-backdrop-filter: blur(13.97px); backdrop-filter: blur(13.97px);
    -webkit-mask-image: linear-gradient(to bottom, #000 0%, transparent 22.22%);
            mask-image: linear-gradient(to bottom, #000 0%, transparent 22.22%);
  }
  body .header-fade .hf9 {
    -webkit-backdrop-filter: blur(17.68px); backdrop-filter: blur(17.68px);
    -webkit-mask-image: linear-gradient(to bottom, #000 0%, transparent 11.11%);
            mask-image: linear-gradient(to bottom, #000 0%, transparent 11.11%);
  }
  /* 어두운 베일 — 다크 전용. 발광 제거 담당(블러와 분리, 블러 위에 얹음). 위 0.42 → 45% 0.23 → 아래 0(경계가
     콘텐츠에 녹음). 발광이 남으면 이 상단 알파(0.42)만 0.5~0.6 으로. 라이트·모노는 베일 없이 순수 블러만(발광 없음). */
  html[data-theme="dark"] body .header-fade .hf-veil {
    background: linear-gradient(to bottom, rgba(14, 12, 22, 0.42) 0%, rgba(14, 12, 22, 0.23) 45%, rgba(14, 12, 22, 0) 100%);
  }
}
/* 프로필 헤더도 동일한 iOS 머티리얼 적용(모든 탭 동일 — 사용자 요청). 옛날엔 14겹 프로그레시브 블러가
   오로라를 탁하게 뭉개 "검은 톤 띠"로 보여 껐었지만, 단일 균일 블러 + 다크 틴트는 iOS 설정/프로필 화면처럼
   깔끔한 프로스트 바라 그대로 둔다(프로필 콘텐츠도 스크롤되므로 자연스러움). */
/* 댓글 입력바·모달·토스트는 플랫(글래스 아님). 모달 딤도 블러 없음. */
body .composer-inline {
  background: var(--bg);
  -webkit-backdrop-filter: none; backdrop-filter: none;
  border-color: color-mix(in srgb, var(--text, var(--ink, #fff)) 9%, transparent);
}
body .modal-card,
body .toast {
  background: var(--card, var(--surface, #17181f));
  -webkit-backdrop-filter: none;
  backdrop-filter: none;
}
body .modal { -webkit-backdrop-filter: none; backdrop-filter: none; }

/* ───────────────────────────────────────────────────────────────
   하단 "리퀴드 글래스" — 위 sticky 헤더가 그렇듯, 하단 탭바를 콘텐츠 위로
   띄워서 리스트가 탭바 뒤로 스크롤되며 반투명 유리에 비쳐 보이게 한다.
   (탭바는 별도 행이었어서 그 뒤로 콘텐츠가 안 지나가 비칠 게 없었음 → 오버레이로)
   • 탭바 absolute → #screen-app 바닥에 떠서 패널 위를 덮음
   • 리스트 패널엔 탭바 높이만큼 스크롤 여백 → 끝까지 올리면 마지막 항목이 바 위로 빠져나옴
   • 탭바 배경 불투명도를 낮춰(--glass 보다 더 투명) 콘텐츠가 또렷이 비치게
   미지원 브라우저는 평소대로(탭바 인-플로우 유지).
   ─────────────────────────────────────────────────────────────── */
@supports ((-webkit-backdrop-filter: blur(1px)) or (backdrop-filter: blur(1px))) {
  body #screen-app.active { position: relative; }
  body #tabbar {
    position: absolute;
    left: 0; right: 0; bottom: 0;
    z-index: 20;
    /* 사용자 요구: 비치는 글래스 탭바 — 콘텐츠가 바 뒤로 스크롤되며 비친다.
       --card 60% 로 투명도↑ → see-through, 강한 블러 + 상단 1px 헤어라인. */
    background: color-mix(in srgb, var(--card, var(--surface, #17181f)) 60%, transparent);
    /* saturate() 제거 — 탭바는 모든 리스트 위에 상시 떠 있어 스크롤마다 backdrop 재샘플 → iOS
       에서 가장 비싼 위치. 블러 20px 유지(see-through 글래스 그대로), 컬러매트릭스 패스만 컷. */
    -webkit-backdrop-filter: blur(20px);
    backdrop-filter: blur(20px);
    border-top: 1px solid color-mix(in srgb, var(--text, var(--ink, #fff)) 8%, transparent);
  }
  /* 콘텐츠가 탭바 뒤로 스크롤되되, 맨 끝에서 마지막 항목이 바 위로 빠져나오도록 여백.
     리스트 패널(파트너·채팅·모먼트·프로필)은 스크롤 컨테이너라 패딩이 스크롤 안쪽에 더해짐. */
  body #panel-partners,
  body #panel-chats,
  body #panel-moments,
  body #panel-profile {
    padding-bottom: calc(64px + var(--safe-bottom, env(safe-area-inset-bottom, 0px)));
  }
  /* 모먼트만: 글쓰기 FAB가 마지막 카드(하트/댓글)를 가리지 않게 FAB 높이만큼 더 비운다.
     FAB bottom 78(=18+60) + 높이 46 + 여백 16 = 140 → 끝까지 내리면 마지막 카드가 FAB 위로 빠져나옴. */
  body #panel-moments {
    /* 상수 162 = FAB bottom 100 + FAB 높이 46 + 여백 16 → 끝까지 내리면 마지막 카드가 FAB 위로 빠져나옴.
       FAB 와 함께 env(safe-bottom) 결합을 끊어 상·하단 시소 제거(탭바 32px 상수 디커플과 동일 원칙). */
    padding-bottom: 162px;
  }
  /* 랜덤 로비(홈/검색)는 탭바 뒤까지 화면을 꽉 채운다 → 배경 오로라가 하단 글래스
     탭바에도 비친다. 카드 콘텐츠는 justify-content:center 라 탭바에 안 가림.
     입력바가 있는 채팅뷰만 탭바 높이만큼 띄워 입력바가 탭바 뒤로 숨지 않게. */
  body #panel-random > .chatview {
    padding-bottom: calc(60px + var(--safe-bottom, env(safe-area-inset-bottom, 0px)));
  }

  /* 모먼트 글쓰기 FAB — 이제 스크롤 컨테이너 밖 #tab-panels 직속이라 화면에 고정.
     모먼트 탭일 때만 보이게(기본 숨김), 위치는 하단 탭바 위로 띄운다. */
  body #tab-panels > .fab { display: none; }
  body #panel-moments.active ~ .fab {
    display: flex;
    /* 상수 100 = 탭바 시각 높이(버튼 52 + 패딩 32 = 84) + 16 여백 → 인셋과 무관하게 항상 탭바 위 16px.
       env(safe-bottom) 결합 제거(데스크탑선 탭바에 가려지고 아이폰선 28px 떠 보이던 시소 해소). */
    bottom: 100px;
  }
}

/* ============================================================
   절제(Restraint) 레이어 — 모든 테마 공통.
   싸 보이는 신호(과한 색·그라데이션·진한 그림자·글로우)를 덜어내고
   흑백+액센트 하나, 타이포 위계, 여백, 미묘한 깊이를 강화한다.
   body 접두 → 테마 규칙보다 우선.
   ============================================================ */
/* ── Ambient 글로우 상수 (여기 한 군데서 색·불투명·위치·크기 조절) ──
   색은 앱 기존 강조색 계열: 인디고=학습자(레벨바), 골드=원어민(LEVEL_GOLD). */
body {
  --amb-indigo: 124, 117, 255;   /* 상단 글로우 색 (R,G,B) — 학습자 인디고 */
  --amb-gold:   245, 179, 1;     /* 하단 글로우 색 (R,G,B) — 원어민 골드 */
  --amb-top-op:    0.10;         /* 상단 글로우 불투명도 — "있는 듯 없는 듯" 수준으로 낮춤 */
  --amb-bottom-op: 0.08;         /* 하단 골드 글로우 — 특히 약하게(다크 톤이 주인공) */
  --amb-top-pos:    50% -6%;     /* 상단 글로우 중심 위치 */
  --amb-bottom-pos: 50% 106%;    /* 하단 글로우 중심 위치 */
  --amb-size: 88% 58%;           /* 글로우 덩어리 크기 (가로 세로 반경) */
  --amb-fade: 70%;               /* 이 지점에서 투명으로 페이드아웃 */
}
/* 배경: 어두운 베이스 + 은은한 ambient 컬러 글로우 (위 --amb-* 상수로 조절).
   글래스(backdrop-blur) 표면이 색을 머금게 — 평평한 검정이면 블러할 게 없어 회색 칩처럼 보임. */
html body, body .screen {
  background:
    radial-gradient(var(--amb-size) at var(--amb-top-pos),    rgba(var(--amb-indigo), var(--amb-top-op)),    transparent var(--amb-fade)),
    radial-gradient(var(--amb-size) at var(--amb-bottom-pos), rgba(var(--amb-gold),   var(--amb-bottom-op)), transparent var(--amb-fade)),
    var(--bg);
}

/* 브랜드 워드마크: 그라데이션 텍스트 → 단색, 강한 위계 */
body .brand h1 {
  background: none; -webkit-text-fill-color: currentColor; color: var(--text);
  font-weight: 730; letter-spacing: -0.035em;
}

/* 기본 버튼: 그라데이션·글로우 → 단색 액센트 (그림자 없음) */
body .btn.btn-primary { background: var(--accent); box-shadow: none; }
/* 내 말풍선·FAB 도 단색 액센트 (교정 말풍선의 초록은 유지) */
body .msg.me:not(.correction) { background: var(--accent); }
body .fab { background: var(--accent); }

/* 태그/언어칩 등은 중립(흑백). 색은 액센트 하나만 */
body .tag {
  background: color-mix(in srgb, var(--text) 8%, transparent);
  color: var(--text-dim); font-weight: 600;
}

/* 깊은 그림자 → 은은하게 (얇은 보더로 레이어링) */
body .modal-card { box-shadow: 0 14px 36px -20px rgba(0,0,0,.45); }
body .toast { box-shadow: 0 10px 26px -16px rgba(0,0,0,.38); }
body .fab { box-shadow: 0 6px 16px -8px rgba(0,0,0,.4); }
body #tabbar { box-shadow: none; }

/* 타이포 위계: 헤딩은 또렷하게(굵게+좁은 자간), 본문은 차분하게 */
body .section-head h2 { font-weight: 730; letter-spacing: -0.03em; }
body .row-title { letter-spacing: -0.01em; }
body .msg { line-height: 1.5; }

/* ── 헤더 통일(A) — 탭/뒤로 헤더가 같은 컴팩트 바: 같은 제목(17px)·같은 바 높이(64+노치)·같은 패딩(상단 노치+16, 좌우/하단 16). 검색은 삭제, 알림 벨은 모먼트 헤더에만.
   제목 아래 칩(내 언어·최신순)은 honest 한 별도 필터 줄 — 파트너·모먼트만 그만큼 더 길어진다. */
/* 헤더 = 제목줄(고정 --hdr-title-h) + (칩 있으면) 필터 칩줄(고정 --hdr-chip-h). 상단 노치만 패딩.
   고정 행 높이라 칩 있는 3개 리스트 탭(파트너·채팅·모먼트) 헤더 높이가 픽셀 단위로 동일.
   칩 없는 화면(프로필)은 칩줄 자체가 없어 제목줄만 — 빈 높이 안 남김. */
body .section-head { box-sizing: border-box; padding: env(safe-area-inset-top, 0px) 16px 0; gap: 0; border-bottom-width: var(--hairline); }
body .conv-header { box-sizing: border-box; min-height: calc(64px + env(safe-area-inset-top, 0px)); }

/* DM 대화 헤더 = 떠 있는 see-through 글래스 — 일반 탭 헤더처럼 메시지가 헤더 뒤로 스크롤돼 비친다.
   헤더를 절대배치로 메시지 위에 띄우고(메시지는 헤더 뒤 풀높이로 채움), 메시지에 헤더 높이(81+노치)만큼
   top 패딩 → 맨 위 메시지도 헤더에 안 가리고, 스크롤하면 콘텐츠가 헤더 뒤로 들어가 프로스티드로 비침.
   글래스 자체는 flat-until-scroll(glass.js) 그대로: 맨 위(뒤에 콘텐츠 없음)=평평, 스크롤 시=글래스. */
body #screen-conversation > .conv-header { position: absolute; top: 0; left: 0; right: 0; z-index: 5; }
body #screen-conversation .messages { padding-top: calc(81px + env(safe-area-inset-top, 0px)); }
body .section-head > h2,
body .section-head > .sh-bar { min-height: var(--hdr-title-h); display: flex; align-items: center; }
body .section-head .sh-bar { gap: var(--sp-2); }
body .section-head .sh-bar h2 { flex: 1; min-width: 0; }
/* 필터 칩 줄 — 헤더 밖, 스크롤되는 콘텐츠 맨 위(.panel 직속). 좌우 인셋 정렬 + 작은 상하 여백.
   스크롤하면 sticky 제목 헤더 밑으로 들어가며 블러됨. (옛날엔 헤더 안 2번째 행 → 분리해 헤더는 제목줄만.)
   이로써 4탭 모두 헤더=제목줄(~52)로 동일 → 프로필 칩-높이 매칭 패딩 불필요(제거). */
body .panel > .chips { padding: 8px 16px; align-items: center; }
body .conv-header .row-title { font-size: 17px; font-weight: 600; }
/* 헤더 고스트 아이콘(알림 벨) — 배경/테두리 없이 글리프만, hover 시 밝게. */
.hdr-icon { position: relative; width: 44px; height: 44px; flex-shrink: 0; display: inline-flex; align-items: center; justify-content: center; background: none; border: none; padding: 0; color: var(--text-dim, var(--ink-2, #8a8a96)); cursor: pointer; -webkit-tap-highlight-color: transparent; transition: color .15s ease; }
.hdr-icon svg { width: 30px; height: 30px; }
/* 프로필 헤더 더보기(⋯) — 글리프만 15% 작게(30→25.5). 벨엔 영향 없음. */
body .hdr-icon.pf-more svg { width: 25.5px; height: 25.5px; }
/* 알림 벨(모먼트 헤더) — 종 글리프만 15% 크게(30→34.5). 다른 헤더 아이콘엔 영향 없음. */
body .notif-bell svg { width: 34.5px; height: 34.5px; }
.hdr-icon:hover { color: var(--text, var(--ink, inherit)); }
/* 알림 벨만 제목줄 기준에서 살짝 아래로 (정적 오프셋, 레이아웃 안 건드림) */
.notif-bell { transform: translateY(16px); }
/* 필터 칩 줄은 이제 헤더(.section-head) 안 2단째 — 별도 배경/고정 없이 헤더 글래스에 얹혀,
   제목·아이콘과 한 sticky 블록으로 함께 떠 있다. (section-head 의 padding 16·gap 이 인셋/간격 담당) */
body .panel { padding-bottom: var(--sp-2); }

/* 모먼트 카드: 패딩 16, 내부 리듬 균일 — 헤더↔본문↔액션 모두 12로 통일.
   (테마별 post-head margin 8/16 불일치를 여기서 한 번에 바로잡음) */
body .post { padding: var(--sp-4); border-bottom-width: var(--hairline); }
body .post-head { margin-bottom: var(--sp-3); }
body .post-actions { gap: var(--sp-6); margin-top: var(--sp-3); }

/* 카드/블록 공통 — pf-block 패딩·갭 통일(라이트·모노 누락 보정), 프로필 본문/헤더, 댓글 */
body .pf-block { padding: var(--sp-4); gap: var(--sp-2); }
body .profile-body { padding: var(--sp-2) var(--sp-6) var(--sp-8); gap: var(--sp-6); }
body .profile-head { gap: var(--sp-4); padding: var(--sp-8) var(--sp-6) var(--sp-4); }
body .comment { gap: var(--sp-2); padding: var(--sp-2) 0; }
body .comment .row-main { gap: var(--sp-2); }

/* ── 리스트 행 정렬 시스템 (파트너·채팅·팔로우·차단 등) ──────────────
   좌우 인셋 16 · 아바타 44 · 아바타↔텍스트 12 · 이름↔언어칩 6 · 이름↔보조줄 2 ·
   상하 패딩 14 → 행 높이 72 고정(box-sizing:border-box → 내부 44 = 아바타). 모든 행 같은 피치.
   구분선: 인셋 72(텍스트 시작점)에서 우측 16까지, 1px·텍스트 6%로 아주 옅게.
   (알림은 카드형 행이라 인셋 구분선 제외) */
body .list-row {
  position: relative;
  gap: var(--sp-3);
  height: 80px;
  padding: var(--sp-4);
  border-bottom: none;
}
body .row-title { gap: var(--sp-2); }
body .row-main { gap: var(--sp-1); }
/* 구분선: 모든 행 동일하게. 불투명(var(--bg) 와 6% 믹스)으로 그려 뒤의 글로우·행 상태배경(hover/active)
   을 머금지 않게 → 어떤 행이든 구분선 자체는 항상 같은 톤(≈ rgba(255,255,255,0.06)). */
body .list-row::after {
  content: ""; position: absolute; left: 72px; right: var(--sp-4); bottom: 0; height: var(--hairline); z-index: 1;
  background: color-mix(in srgb, var(--text, var(--ink, #fff)) 6%, var(--bg));
  pointer-events: none;
}
body .list-row:last-child::after { display: none; }
body .notif-list .list-row::after { display: none; }
/* 리스트 행 소프트 프레스 — 누를 때 빠르게 축소, 놓을 때 스프링 복귀(액션 버튼보다 약하고 부드럽게).
   transform 모션만 여기서(테마 무관). 색(:active 배경 틴트)은 각 테마 CSS 그대로 — 공존. */
body .list-row{
  transform-origin: center;
  -webkit-tap-highlight-color: transparent;
  transition: transform .26s cubic-bezier(.34,1.56,.4,1), background .18s ease;
  /* will-change 제거: 행마다 상시 컴포지터 레이어를 만들면 iOS 에서 레이어 폭증→메모리 압박→
     스크롤 중 레이어 깜빡임. 누름 트랜지션은 0.26s 잠깐이라 상시 힌트가 이득 없이 비용만 든다. */
}
body .list-row:active{
  transform: scale(.9776);          /* 눌림 깊이 0.028 → 0.0224 (강도 20% 감소) */
  transition: transform .08s ease; /* 누르는 순간은 즉각 반응 */
}
@media (prefers-reduced-motion: reduce){
  body .list-row, body .list-row:active{ transition: background .18s ease; transform: none; }
}

/* 빠른 채팅 버튼(.row-quick)·프로필 링크(.pf-link = 아바타·닉네임)를 hover/누를 때 행(프로필 박스)에
   선택 배경/축소가 같이 안 뜨게. :hover·:active 는 이벤트 전파와 무관히 조상(행)에도 적용돼
   stopPropagation 으론 못 막음 → :has 로 행만 평소 상태로(아바타·닉네임 탭 시 박스 소프트프레스 제거).
   :hover 까지 덮어야: ① 데스크톱서 요소에 마우스 올렸을 때 행 hover, ② iOS 탭 후 들러붙는 sticky hover 둘 다 제거.
   transform:none 으로 행 소프트프레스 축소도 억제(요소는 자기 :active 피드백 유지 → 누름이 그 요소에만 국한).
   transition:none 으로 잔상 페이드도 없앰. 행 본문(버튼·링크 아닌 곳) hover/press 는 영향 없음(:has 가 매칭될 때만). */
body .list-row:has(.row-quick:hover),
body .list-row:has(.row-quick:active),
body .list-row:has(.pf-link:hover),
body .list-row:has(.pf-link:active) { background: transparent; transform: none; transition: none; }

/* ── 채팅·파트너 리스트 = 둥근 통통 "알약" 행, 강조 없음 (핸드오프 chat-no-highlight.html) ──
   #panel-chats·#panel-partners 의 행에만 스코프 → 알림(.notif-list)·프로필 차단목록(.list)·설정 행은 불변.
   ① 리스트 좌우 인셋 10 → 행이 알약처럼 양옆 떠 보임. ② 행 = radius 18·padding 13/14·gap 16, 고정높이 해제.
   ③ 구분선(::after) 제거 — 알약은 칸막이 대신 간격으로 구분. ④ hover/active 배경 틴트 제거(색 강조 없음),
   누름은 축소(scale)만. ID 스코프라 (1,3,1) > 테마의 .list-row:hover/:active (0,2,0) → 3테마 전부 덮음. */
body :is(#panel-chats, #panel-partners) .list { padding: 0 10px; }
body :is(#panel-chats, #panel-partners) .list-row {
  height: auto;
  padding: 13px 14px;
  border-radius: 18px;
  gap: 16px;
}
body :is(#panel-chats, #panel-partners) .list-row::after { display: none; }
body :is(#panel-chats, #panel-partners) .list-row:hover,
body :is(#panel-chats, #panel-partners) .list-row:active { background: transparent; }
body :is(#panel-chats, #panel-partners) .list-row:active { transform: scale(.97); }

/* 하단 탭바: 좌우 8px 인셋(탭이 양옆으로 더 넓게 퍼짐) + 아이콘 +~15%(23→26). 3테마 공통(테마 .tabi 23px를 덮음). */
body #tabbar { padding-left: 8px; padding-right: 8px; }
body .tabi { width: 26px; height: 26px; }
/* 탭바 = 떠 있는 글래스 바. 버튼을 바닥에서 "고정 32px" 띄우고, 그 아래 공백은
   바의 글래스(배경 + backdrop blur)가 화면 끝(bottom:0)까지 덮어 같은 블러로 채운다.
   ※ 일부러 env(safe-area-inset-bottom)에 안 묶는다 — 상단 풀블리드(아일랜드 글래스)가
   safe-bottom 을 0↔34 로 토글해도 하단이 절대 안 흔들리게 상수로 고정(상·하 완전 디커플).
   32px > 홈 인디케이터(~13px)라 버튼이 홈 바에 안 가림. */
body #tabbar { padding-bottom: 32px; }
/* 상단 좌우 곡률 — 풀폭 글래스 바의 위쪽 두 모서리만 둥글려 직사각형 느낌을 던다.
   non-color geometry 라 3테마 공통(여기 한 곳). overflow:hidden 은 주지 않는다
   — #tab-slider 스프링 오버슈트(cubic-bezier .5,1.5)가 잘려 끊겨 보임. */
body #tabbar { border-top-left-radius: 22px; border-top-right-radius: 22px; }

/* ── iOS 리퀴드 글래스 탭 필 ───────────────────────────────────────────
   활성 강조 = 활성 탭 뒤 캡슐 슬라이더(#tab-slider). 위치/드래그는 nav.js.
   지오메트리·모션은 3테마 공통(여기) — 색만 각 테마 CSS(다크=글래스, 라이트·모노=플랫).
   #tabbar 는 이미 absolute(위 @supports)라 슬라이더의 컨테이닝 블록 → position:relative 불필요.
   옛 활성 표시(아이콘 확대·글로우 .tabi / 라디얼 핀 ::before)는 여기서 무력화(3테마 일괄). */
body #tab-slider {
  position: absolute; left: 0; top: 1px; height: 52px; border-radius: 16px; z-index: 0;
  transform-origin: center; will-change: transform, width; pointer-events: none;
  transition: transform .5s cubic-bezier(.5,1.5,.4,1), width .5s cubic-bezier(.5,1.5,.4,1);
}
body .tabbtn { position: relative; z-index: 1; touch-action: none; }
body .tabbtn .tabi, body .tabbtn .ti { position: relative; z-index: 2; }
body .tabbtn.active .tabi {
  transform: translateY(-1px); filter: none;
  transition: transform .3s cubic-bezier(.5,1.3,.4,1);
}
/* 비활성 탭 누름 축소 — 라이트(.88)/모노·다크(.9) 불일치를 다크 기준 .9 로 3테마 통일(transform-only). */
body .tabbtn:active .tabi { transform: scale(.9); }
body .tabbtn.active::before { display: none; }

/* ── 베벨 글래스 선 아이콘 (다크 전용) ─────────────────────────────────────
   탭 아이콘(.tabi.out=비활성 아웃라인 / .tabi.fillico=활성 채움)·알림 벨(.notif-bell svg)의
   stroke/fill 을 currentColor 대신 세로 그라데이션(#lgStroke: 위 밝고 아래 흐림)으로 → "유리관" 선.
   currentColor 단색 토글이 안 먹으니 활성/비활성은 opacity + 활성 그라데이션(#lgStrokeActive, 라벤더)으로.
   흰 그라데이션·흰 베벨은 어두운 배경 전제 → 다크에서만(라이트·모노는 기존 플랫 currentColor 유지).
   defs 는 index.html body 직속(1회). 라벨(.ti) 색은 안 건드림. ───────────────────────────────── */
html[data-theme="dark"] body :is(.tabbtn .tabi.out, .notif-bell svg) :is(path, rect, circle):not([stroke="none"]) {
  stroke: url(#lgStroke); fill: none; stroke-linecap: round; stroke-linejoin: round;
}
/* 채움 악센트(하트·눈·반짝임·벨 손잡이 점 — markup 에서 stroke="none") 는 같은 그라데이션으로 채움 */
html[data-theme="dark"] body :is(.tabbtn .tabi.out, .notif-bell svg) [stroke="none"] { fill: url(#lgStroke); }
/* 활성 탭(채움 글리프)은 더 밝고 살짝 라벤더 */
html[data-theme="dark"] body .tabbtn.active .tabi.fillico :is(path, rect, circle) { fill: url(#lgStrokeActive); }
/* 베벨(유리관 입체) — 위 밝은 빛 / 아래 어두운 그림자. 활성의 filter:none(위 .tabi 규칙)도 덮어 유지 */
html[data-theme="dark"] body :is(.tabbtn .tabi, .notif-bell svg),
html[data-theme="dark"] body .tabbtn.active .tabi {
  filter: drop-shadow(0 .8px .4px rgba(255,255,255,.6)) drop-shadow(0 -.6px .4px rgba(0,0,0,.45));
}
/* 활성/비활성 = 밝기(그라데이션 stroke 라 색 토글 대신 opacity) */
html[data-theme="dark"] body .tabbtn .tabi { opacity: .7; transition: opacity .18s ease, transform .22s cubic-bezier(.2,.7,.2,1); }
html[data-theme="dark"] body .tabbtn.active .tabi { opacity: 1; }
/* 대비 모드: 선이 너무 흐리지 않게 비활성 하한 상향 */
@media (prefers-contrast: more) {
  html[data-theme="dark"] body .tabbtn .tabi { opacity: .92; }
}

/* ── 파트너 행 변별 정보 — 이름+마지막접속(1줄) / 레벨막대+언어쌍(2줄) + 빠른채팅 ── */
/* 1줄: 이름(왼쪽) + 마지막 접속(오른쪽 끝) */
body .row-title { align-items: baseline; gap: var(--sp-2); }
.rt-name { flex: 0 1 auto; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.rt-seen { flex-shrink: 0; margin-left: auto; font-size: 11.5px; font-weight: 500; white-space: nowrap;
  color: var(--text-faint, var(--ink-3, #8a8a96)); font-variant-numeric: tabular-nums; }
.rt-seen.seen-online { color: var(--accent-strong, var(--accent, #7b6bff)); font-weight: 600; }
/* 2줄: 언어 약칭 + 신호막대 그룹들 (모국어=5칸 꽉, 배우는 언어=레벨). "PT ▮▮▮▮▮  EN ▮▯▯▯▯" */
/* 한 줄 고정: 언어가 많아도 줄바꿈 없이 한 줄. 넘치면 우측이 살짝 페이드되며 잘림. */
.row-sub2 { display: flex; align-items: center; gap: 6px; min-width: 0;
  flex-wrap: nowrap; overflow: hidden;
  -webkit-mask: linear-gradient(90deg, #000 calc(100% - 18px), transparent);
          mask: linear-gradient(90deg, #000 calc(100% - 18px), transparent); }
/* 각 언어 = 알약(테두리+옅은 배경). 동글게(999) · 모국어=골드, 배우는 언어=중립. */
.lang-bar { display: inline-flex; align-items: center; gap: 4px; flex-shrink: 0;
  padding: 3px 9px; border-radius: 999px;
  border: 1px solid color-mix(in srgb, var(--text, #fff) 13%, transparent);
  background: color-mix(in srgb, var(--text, #fff) 5%, transparent); }
.lang-abbr { font-size: 11px; font-weight: 500; letter-spacing: 0.03em;
  color: var(--text-dim, var(--ink-2, #8a8a96)); font-variant-numeric: tabular-nums; }
/* 배우는 언어 = 색-등급 인디고 알약 + 큰 숫자 (신호막대 폐기). 칩 폭은 tabular-nums 로 일정. */
.lang-num { font-size: 12px; font-weight: 800; line-height: 1; font-variant-numeric: tabular-nums; }
.lang-bar[class*="lvl-"] .lang-abbr,
.lang-bar[class*="lvl-"] .lang-num { color: var(--accent-strong, var(--accent, #9d92ff)); }
/* 레벨↑ = 인디고 배경/테두리 진해짐 (색-등급) */
.lang-bar.lvl-1 { background: color-mix(in srgb, var(--accent) 10%, transparent); border-color: color-mix(in srgb, var(--accent) 22%, transparent); }
.lang-bar.lvl-2 { background: color-mix(in srgb, var(--accent) 14%, transparent); border-color: color-mix(in srgb, var(--accent) 32%, transparent); }
.lang-bar.lvl-3 { background: color-mix(in srgb, var(--accent) 20%, transparent); border-color: color-mix(in srgb, var(--accent) 44%, transparent); }
.lang-bar.lvl-4 { background: color-mix(in srgb, var(--accent) 28%, transparent); border-color: color-mix(in srgb, var(--accent) 58%, transparent); }
.lang-bar.lvl-5 { background: color-mix(in srgb, var(--accent) 38%, transparent); border-color: color-mix(in srgb, var(--accent) 74%, transparent); }
/* 원어민: 꽉 찬 골드 알약 + ★ */
.lang-bar.native { background: color-mix(in srgb, #f5b301 32%, transparent); border-color: color-mix(in srgb, #f5b301 72%, transparent); }
.lang-bar.native .lang-abbr { color: #f5b301; }
.lang-star { font-size: 10px; line-height: 1; color: #f5b301; }
/* 라이트 테마: 코랄 틴트 칩 위에서 --accent-strong(#d8412c)이 진한 칩(lvl-4/5)에선 대비 부족
   → 라이트에서만 더 진한 코랄로 숫자/약칭 보정(가독성). */
html[data-theme="light"] .lang-bar[class*="lvl-"] .lang-abbr,
html[data-theme="light"] .lang-bar[class*="lvl-"] .lang-num { color: #a02814; }
/* mono 도 동일: --accent-strong 미정의 → 러스트 텍스트가 러스트 틴트 칩에서 대비 부족.
   mono 의 진한 토큰(--accent-deep)으로 보정. */
html[data-theme="mono"] .lang-bar[class*="lvl-"] .lang-abbr,
html[data-theme="mono"] .lang-bar[class*="lvl-"] .lang-num { color: #7a2c19; }
/* ── 아바타 접속 링 잠정 제거 ──────────────────────────────────────────────
   링은 지금 presence(접속)를 그리지만, 추후 프리미엄(월정액) 전용 표시로 재사용 예정.
   지금은 끄고 접속 상태는 우하단 점(.online-dot)만으로 표시. .avatar 자체 테두리/그림자는 유지.
   테마 파일은 손대지 않고 여기(오버라이드 레이어)에서 끔.
   - dark·mono: 링 = .av-wrap::before 밴드 → display:none.
   - dark: .av-wrap 박스섀도(간격+글로우) → none.
   - light: 링 = .avatar 박스섀도 레이어 → light에서만(html[data-theme=light]) 기본값으로 복원. */
body .av-wrap::before { display: none; }
body .av-wrap:has(.online-dot:not(.off)),
body .av-wrap:has(.online-dot.off) { box-shadow: none; }
html[data-theme="light"] .av-wrap:has(.online-dot:not(.off)) .avatar,
html[data-theme="light"] .av-wrap:has(.online-dot.off) .avatar {
  box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.28), 0 0 0 2px var(--surface), var(--shadow-sm); }

/* 텍스트 블록을 아바타 중심 쪽으로 살짝 내림 */
body .list-row .row-main { position: relative; top: 2px; }
/* 모먼트 게시물 헤더 — 파트너 행과 동일한 아바타↔텍스트 간격(12) */
body .post-head { gap: var(--sp-3); }

/* 모먼트 좋아요/댓글 — 텍스트 라벨 대신 아웃라인 아이콘 + 숫자(미니멀). */
body .post-act.pa-icon { display: inline-flex; align-items: center; gap: 6px; }
.post-act.pa-icon svg { width: 23px; height: 23px; }  /* 댓글 아이콘 +15% — 왼쪽 좋아요 하트(22px)와 조화 */
.post-act.pa-icon .pa-count { font-size: 13px; font-weight: 500; font-variant-numeric: tabular-nums; }
/* 활성 = 액센트색 (외곽선만; 가운데 채움은 제거 — 댓글 아이콘이 파랗게 차던 것 없앰) */
body .post-act.pa-icon.on { color: var(--accent); }
.post-act.pa-icon.on svg { fill: none; }

/* 프로필 헤더 접속 상태 줄 — 이름 바로 아래에 작은 초록 점(8px) + 13px 회색 텍스트 한 줄.
   .online-dot 은 원래 아바타용(absolute)이라 인라인(static)으로 흐르게 + 8px·보더 제거.
   margin-top 음수로 이름에 더 붙임(헤더 gap 16 → 약 8). */
body .pf-online { margin-top: -8px; }
body .pf-online .online-dot { position: relative; flex: none; width: 8px; height: 8px; border: none; box-shadow: none; }
body .pf-online .muted { font-size: 13px; }

/* 타인 프로필 본문 — .screen-list 가 block(gap 0)이라 카드들이 딱 붙어 겹쳐 보임.
   세로 flex + gap 으로 카드(헤더·팔로우·언어·모먼트·액션) 사이를 띄운다. */
body .pf-view { display: flex; flex-direction: column; gap: 14px; }

/* 언어 카드 — 위쪽 여백 줄여 라벨·뱃지가 카드 상단에 붙게(빈 공간 제거). */
body .pf-lang-block { padding-top: 12px; }

/* 카드 라벨('언어'·'모먼트' 등) — 12px · 흐린 회색으로 본문과 확실히 구분. */
body .pf-label { font-size: 12px; color: #71717A; }

/* 프로필로 진입 가능한 요소(아바타·닉네임) — 손가락 커서 + 탭 시 살짝 반응 */
.pf-link { cursor: pointer; -webkit-tap-highlight-color: transparent; }
/* :hover 는 실제 포인터(데스크탑)에서만 — iOS 는 탭 후 :hover 가 다음 탭까지 들러붙어 밑줄/색이
   남는다(아이폰-데스크탑 불일치). @media (hover: hover) 로 게이트해 터치에선 안 붙고 데스크탑은 그대로. */
@media (hover: hover) and (pointer: fine) {
  .rt-name.pf-link:hover,
  .comment .row-title.pf-link:hover,
  .conv-header .row-title.pf-link:hover { text-decoration: underline; text-underline-offset: 2px; }
}
.av-wrap.pf-link:active,
.avatar.pf-link:active { opacity: .85; }
/* 닉네임 링크 누름 피드백 — 박스가 아니라 이름 글자만 살짝 흐려져 "이름을 눌렀다"는 게 국소적으로 보이게
   (아바타 .85 보다 텍스트는 더 또렷이 눌려야 읽혀 .55). 색 무관(opacity)이라 3테마 공통. */
.rt-name.pf-link:active { opacity: .55; }

/* ── 채팅 리스트 — 미리보기 구분 · 안읽음 · 빈상태 · 대화 상대 추천 ── */
/* 미리보기 없음 안내: 흐림 + 이탤릭(실제 메시지와 구분) */
.row-sub.empty-hint { color: var(--text-faint, var(--ink-3, #8a8a96)); font-style: italic; }
/* 안읽음: 이름·미리보기 밝게/진하게, 시간 인디고 (읽음은 기본값 그대로) */
body .list-row.unread .row-title { color: var(--text, var(--ink, #fff)); font-weight: 700; }
body .list-row.unread .row-sub { color: var(--text, var(--ink, #fff)); }
body .list-row.unread .row-time { color: var(--accent-strong, var(--accent, #7b6bff)); font-weight: 600; }

/* 빈 상태: 화면 중앙 + CTA 버튼 */
.empty.empty-center { display: flex; flex-direction: column; align-items: center; justify-content: center;
  min-height: 58vh; padding: 24px 32px; }
.empty-center .empty-cta { width: auto; margin-top: 20px; padding: 0 22px; }
/* 빈 상태 메인 텍스트 — faint 기본보다 대비 높게(서브는 muted 유지) */
body .empty-center .empty-title { color: var(--text, var(--ink, #fff)); font-size: 16px; font-weight: 600; }
/* 빈 상태 아이콘 20% 키움 (테마 기본 46 → 55) */
body .empty-center svg { width: 55px; height: 55px; }

/* 대화 상대 추천 섹션 */
.sugg { margin-top: 8px; }
.sugg-head { display: flex; align-items: center; justify-content: space-between; padding: 16px 16px 6px; }
.sugg-title { font-size: 13px; font-weight: 500; color: var(--text-dim, var(--ink-2, #8a8a96)); }
.sugg-all { background: none; border: none; cursor: pointer; font-family: inherit; font-size: 13px; font-weight: 600;
  letter-spacing: -0.005em; padding: 0; -webkit-tap-highlight-color: transparent;
  color: var(--accent-strong, var(--accent, #7b6bff)); }
.sugg-all:active { opacity: .7; }
/* 추천 행 2줄: 막대(맨 앞) + 언어쌍 텍스트 */
.sugg-row .row-sub2 { gap: 8px; }
.sugg-row .row-sub2 .lvl-bars { margin-bottom: 1px; }
.sugg-row .rs-langpair { font-size: 12.5px; line-height: 1.45; color: var(--text-dim, var(--ink-2, #8a8a96));
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
/* 인사하기 알약 — 인디고 옅은 배경 + 인디고 글자 (활성칩과 같은 톤) */
.say-hi { flex-shrink: 0; border: none; cursor: pointer; font-family: inherit; font-size: 12.5px; font-weight: 600;
  letter-spacing: -0.005em; padding: 8px 16px; border-radius: 999px; -webkit-tap-highlight-color: transparent;
  background: color-mix(in srgb, var(--accent, #7b6bff) 14%, transparent);
  color: var(--accent-strong, var(--accent, #7b6bff));
  transition: transform .08s ease, background .15s ease; }
.say-hi:active { transform: scale(.95); }

/* ── 파트너 '오늘의 추천' (시안 2: 추천 강조) — 맨 위 1명을 히어로 카드로, 나머지는 리스트로 ──
   섹션 라벨(오늘의 추천/더 보기) + 액센트 틴트 글래스 카드. 색은 토큰(--accent…)으로 3테마 적응
   (다크 인디고 / 라이트 코랄 / 모노 벽돌). 라이트·모노에 없는 토큰(--accent-strong/--accent-grad)은 폴백. */
body .pl-sec { display: flex; align-items: center; gap: 8px; padding: 18px 20px 8px; }
body .pl-sec .pl-sec-t { font-size: 13px; font-weight: 700; color: var(--text-dim); letter-spacing: .01em; }

body .pl-rec {
  margin: 6px 16px 4px; padding: 18px; border-radius: 20px;
  background: linear-gradient(150deg,
    color-mix(in srgb, var(--accent) 16%, transparent),
    color-mix(in srgb, var(--accent) 5%, transparent));
  border: 1px solid color-mix(in srgb, var(--accent) 28%, transparent);
}
body .pl-rec-top { display: flex; align-items: center; gap: 14px; }
body .pl-rec-id { min-width: 0; }
body .pl-rec-name { font-size: 18px; font-weight: 700; letter-spacing: -.01em; }
body .pl-rec-meta { margin-top: 3px; font-size: 12.5px; color: var(--text-dim); }
body .pl-rec-reason { margin-top: 13px; font-size: 13px; line-height: 1.5; color: var(--text-dim); }
body .pl-rec-reason b { color: var(--accent-strong, var(--accent)); font-weight: 600; }
body .pl-rec-cta {
  margin-top: 14px; width: 100%; height: 44px; padding: 0; border: none; border-radius: 13px;
  font-family: inherit; font-size: 14px; font-weight: 600; color: #fff; cursor: pointer;
  background: var(--accent-grad, linear-gradient(135deg, var(--accent), var(--accent-strong, var(--accent))));
  -webkit-tap-highlight-color: transparent;
  transition: transform .12s ease, filter .12s ease;
}
body .pl-rec-cta:active { transform: scale(.985); filter: brightness(.97); }

/* ── 배우는 언어 다중 에디터 (프로필 편집) ── */
.learns-edit { display: flex; flex-direction: column; gap: 8px; }
.learns-rows { display: flex; flex-direction: column; gap: 8px; }
.learns-row { display: flex; align-items: center; gap: 8px; }
.learns-row .learns-lang { flex: 1 1 auto; min-width: 0; }
.learns-row .learns-lvl { flex: 0 0 36%; }
.learns-rm { flex: none; width: 38px; height: 38px; border-radius: 999px; cursor: pointer;
  border: 1px solid var(--line, rgba(128,128,128,.22)); background: transparent;
  color: var(--text-faint, var(--ink-3, #8a8a96)); font-size: 18px; line-height: 1;
  -webkit-tap-highlight-color: transparent; transition: transform .08s ease, color .15s ease; }
.learns-rm:active { transform: scale(.92); }
.learns-rm:hover { color: var(--danger, #e2574c); }
.learns-add { align-self: flex-start; background: none; border: none; cursor: pointer; font-family: inherit;
  font-size: 13px; font-weight: 600; letter-spacing: -0.005em; padding: 4px 2px;
  color: var(--accent-strong, var(--accent, #7b6bff)); -webkit-tap-highlight-color: transparent; }

/* 프로필 언어 블록 — 그룹 여러 개면 줄바꿈 */
/* 프로필 언어 블록은 공간이 충분 — 줄바꿈 허용, 페이드/잘림 없음. */
.pf-langs { flex-wrap: wrap; overflow: visible; -webkit-mask: none; mask: none; row-gap: 8px; }

/* ── 언어 레벨 신호막대 (휴대폰 신호 모양) ──
   폭 3px · 간격 2px · 높이 5/8/11/14/17(인라인) · 아래 정렬 · 살짝 둥글게(1px).
   채운 칸 = 인디고, 빈 칸 = #2c3140. 색조 단계 없이 "채운 개수"로만 레벨 표현.
   색은 --lvl-fill / --lvl-empty 변수(또는 levelBars opts)로 교체 가능. */
.lvl-bars { display: inline-flex; align-items: flex-end; gap: 2px; flex-shrink: 0; height: 14px;
  --lvl-fill: #7c75ff; --lvl-empty: #2c3140; }
.lvl-bar { width: 2.5px; border-radius: 1px; background: var(--lvl-empty); }
.lvl-bar.on { background: var(--lvl-fill); }
/* 빠른 채팅 아이콘 — 행 우측 세로 중앙, 행 탭(프로필)과 분리 */
.row-quick { flex-shrink: 0; width: 36px; height: 36px; border-radius: 999px;
  display: flex; align-items: center; justify-content: center;
  border: 1px solid var(--line, rgba(128,128,128,.2)); background: transparent;
  color: var(--text-dim, var(--ink-2, #8a8a96)); cursor: pointer; -webkit-tap-highlight-color: transparent;
  transition: background .15s ease, color .15s ease, border-color .15s ease, transform .08s ease; }
.row-quick svg { width: 18px; height: 18px; }
.row-quick:hover { color: var(--accent-strong, var(--accent, #7b6bff));
  border-color: color-mix(in srgb, var(--accent, #7b6bff) 40%, transparent); }
.row-quick:active { transform: scale(var(--press-strong)); } /* .9 → 토큰(.94): 옆 버튼들보다 과하게 깊던 것 정렬 */

/* ── 활성 필터 칩: 솔리드 보라 → 옅은 보라 배경 + 보라 글자 (미니멀 톤) ── */
body .chip.on {
  background: color-mix(in srgb, var(--accent, #7b6bff) 14%, transparent);
  color: var(--accent-strong, var(--accent, #7b6bff));
  border-color: color-mix(in srgb, var(--accent, #7b6bff) 30%, transparent);
  box-shadow: none;
}

/* ── 헤더 정렬 토글 (제목 줄 오른쪽) ── */
.sh-title-row { display: flex; align-items: center; justify-content: space-between; gap: 8px; }
.sort-btn { display: inline-flex; align-items: center; gap: 6px; flex-shrink: 0;
  padding: 7px 12px; border-radius: 999px; font-family: inherit; font-size: 12.5px; font-weight: 600;
  letter-spacing: -0.005em; cursor: pointer; -webkit-tap-highlight-color: transparent;
  border: 1px solid var(--line, rgba(128,128,128,.2));
  background: color-mix(in srgb, var(--text, var(--ink, #fff)) 5%, transparent);
  color: var(--text-dim, var(--ink-2, #8a8a96));
  transition: color .15s ease, border-color .15s ease, transform .08s ease; }
.sort-btn svg { width: 15px; height: 15px; }
.sort-btn:active { transform: scale(.96); }

/* 상단 액션 버튼(검색·알림) — 44에서 살짝 축소(42). 터치 타깃은 여전히 충분. */
body .top-action-btn { width: 42px; height: 42px; }
body .top-action-btn svg { width: 20px; height: 20px; }

/* 테마 선택 UI — 모든 테마가 공유 (각 테마의 토큰을 var() 폴백과 함께 사용) */
.theme-opts { display: flex; flex-direction: column; }
.theme-opt {
  display: flex; align-items: center; gap: 16px; width: 100%; text-align: left; cursor: pointer;
  padding: 12px 0; font-family: inherit;
  border: none; border-radius: 0;
  background: transparent; color: var(--text, inherit);
  transform-origin: center;
  transition: transform .26s cubic-bezier(.34,1.56,.4,1), opacity .15s ease;
  -webkit-tap-highlight-color: transparent;
}
/* 테마 버튼 소프트 프레스 — 리스트 행과 동일: 누를 때 빠르게 축소, 놓을 때 스프링 복귀 */
.theme-opt:active { transform: scale(.9776); transition: transform .08s ease; }  /* 눌림 깊이 0.028 → 0.0224 (강도 20% 감소) */
@media (prefers-reduced-motion: reduce){
  .theme-opt, .theme-opt:active { transition: opacity .15s ease; transform: none; }
}
.theme-opt + .theme-opt { border-top: 1px solid color-mix(in srgb, var(--text, #fff) 8%, transparent); }
.theme-opt[aria-pressed="true"] .to-name { color: var(--accent, #7b6bff); }
.theme-opt .sw { width: 36px; height: 36px; border-radius: 10px; flex-shrink: 0; box-shadow: inset 0 0 0 1px rgba(127,127,127,.25); }
.theme-opt .to-main { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 8px; }
.theme-opt .to-name { font-weight: 650; font-size: 15px; letter-spacing: -0.01em; }
.theme-opt .to-desc { font-size: 12.5px; color: var(--text-dim, #8a8a96); }
.theme-opt .to-check { width: 22px; height: 22px; flex-shrink: 0; color: var(--accent, #7b6bff); opacity: 0; transition: opacity .15s ease; }
.theme-opt[aria-pressed="true"] .to-check { opacity: 1; }

/* 설정 페이지 — 섹션 카드 사이 여백. 카드 글래스는 아래 통합 규칙(프로필·설정·편집 공용 다크 틴트). */
.settings-list { display: flex; flex-direction: column; gap: var(--sp-4, 16px); }

/* ============================================================
   LINEAR-FEEL 레이어 — 위의 "절제 레이어"를 이어받아 Linear.app 문법으로 진화.
   (이제부터 모든 디자인 문법의 기준) 테마 3종(dark/light/mono)은 절대 수정하지 않음.
   원리: 라운드는 body 토큰 재정의(:root 아님 — fonts.css가 테마보다 먼저 로드되므로
   :root끼리는 동률→소스순서로 테마가 이김. body는 <body>에 값을 심어 모든 UI가 상속).
   버튼 등 비(非)토큰 속성은 body .btn 패턴(0,1,1 > 테마 .btn 0,1,0)으로 우선 적용.
   주의 ① 라운드 네임스페이스 2종(dark/mono=--r-*, light=--radius-*) 둘 다 설정.
        ② --r-pill / 999px 리터럴은 건드리지 않음(칩·뱃지·아바타·날짜칸 둥글게 유지).
        ③ .tab 안쪽 라운드는 토큰이 아니라 리터럴(12/10/7px)이라 직접 6px로 덮음.
   ============================================================ */

/* ── 라운드 토큰 (Linear의 6·7·8·10·12 사다리) ── */
body {
  /* dark + mono 네임스페이스 */
  --r-xs: 6px;   /* micro/inputs */
  --r-sm: 7px;   /* 컨트롤(버튼·인풋·아이콘버튼) — 핵심 */
  --r-md: 8px;   /* 카드·패널·.tabs 컨테이너 */
  --r-lg: 10px;  /* 모달 등 큰 표면 */
  --r-xl: 12px;  /* 데스크톱 프레임 천장 — 그 이상 금지 */
  --r:    8px;
  /* light 네임스페이스 (이름이 다름) */
  --radius-xs: 6px;
  --radius-sm: 7px;
  --radius:    8px;
  --radius-lg: 10px;
  /* --r-pill / 999px 리터럴은 일부러 두지 않음 → 칩·뱃지·아바타·스위치는 둥글게 */
}

/* ── 버튼 ── */
/* 모양·높이·타입은 아래 "버튼 디자인 언어 통일" 블록(:is(...))이 단일 소스로 강제(height 40 등).
   여기선 트랜지션만 — height/font-size/weight/letter-spacing 은 통일 블록이 덮으므로 중복 선언 안 함
   (과거의 height:44px 'iOS HIG' 선언은 통일 블록 40px 에 밀린 死코드라 제거). */
body .btn {
  transition: background-color .1s ease, border-color .1s ease, color .1s ease,
              box-shadow .1s ease, opacity .1s ease, transform .08s ease;
}

/* Primary: 위 절제 레이어(단색 액센트·그림자 없음) 확장. 글로우/그라데이션 없이 단색 하나.
   hover=밝기 +8%(데스크톱), active=92% 어둡게(모바일은 hover 없음). 온-액센트 텍스트/보더 고정. */
body .btn.btn-primary { background: var(--accent); box-shadow: none; color: #fff; border-color: transparent; }
body .btn.btn-primary:hover { filter: brightness(1.08); box-shadow: none; }
body .btn.btn-primary:active { background: color-mix(in srgb, var(--accent) 92%, #000); filter: none; box-shadow: none; }

/* Ghost/secondary: 반투명 채움 + 1px 헤어라인(라이트의 불투명 박스·모노의 투명 모두 통일).
   색은 텍스트 토큰 폴백 체인(모노엔 --text 없음 → --ink). hover/active는 알파 한 단계씩. */
body .btn.btn-ghost {
  background: color-mix(in srgb, var(--text, var(--ink, #fff)) 5%, transparent);
  border: 1px solid color-mix(in srgb, var(--text, var(--ink, #fff)) 9%, transparent);
  color: var(--text-dim, var(--ink-2, #8a8a96));
  box-shadow: none;
}
body .btn.btn-ghost:hover  { background: color-mix(in srgb, var(--text, var(--ink, #fff)) 9%, transparent); box-shadow: none; }
body .btn.btn-ghost:active { background: color-mix(in srgb, var(--text, var(--ink, #fff)) 12%, transparent); }

/* 컴포저 전송(보내기) 48px → 38px / 댓글 등록 44px → 36px. 라운드는 --r-sm(7px) 상속.
   (모노엔 .composer-inline .btn 규칙이 없어 52px 기본을 상속 → 아래 규칙이 도달해 통일) */
body .composer .btn         { height: 38px; font-size: 13px;   padding: 0 16px; }
body .composer-inline .btn  { height: 36px; font-size: 12.5px; padding: 0 16px; }

/* FAB(모먼트 작성 +) 56/54px → 46px. 절제 레이어의 단색 액센트 유지 + 타이트한 저알파 그림자.
   원은 그대로(원/필은 라운드 축소 제외). '+' 글리프 27 → 24px. */
body .fab { width: 46px; height: 46px; font-size: 24px; box-shadow: 0 4px 12px -6px rgba(0,0,0,.45); }

/* 하단 탭바 60/62px → 52px(데스크톱 포함, 아래 @media에서 한 번 더). 셀은 flex:1라 52px로 충분. */
body .tabbtn { height: 52px; font-size: 10px; }
/* 아이콘+텍스트(+배지)를 통째로 정확히 2px 아래로 — 크기·간격 그대로 유지(정적 transform이라
   서브픽셀 왜곡 없음). 가로 위치/폭은 불변이라 슬라이더(moveTabSlider .left/.width) 계산에 영향 없음. */
body .tabbtn { transform: translateY(2px); }

/* 세그먼트 토글(.tab) 42/40px → 36px. 안쪽 라운드는 리터럴이라 토큰이 못 닿음 → 직접 6px.
   컨테이너 .tabs는 --r-md(8px)로 이미 줄어듦. active 그림자 제거(Linear=평평한 채움 스왑). */
body .tab {
  height: 36px;
  font-size: 13px;
  font-weight: 600;
  border-radius: 999px;
  letter-spacing: -0.006em;
  transition: background-color .1s ease, color .1s ease, box-shadow .1s ease;
}
body .tab.active { box-shadow: none; }

/* 칩: '너무 큼' 대상 아님 + 알약(999px) 유지. 라운드 미설정(둥글게 유지). 타이포만 정렬. */
body .chip {
  font-size: 12px;
  font-weight: 600;
  letter-spacing: -0.004em;
  transition: background-color .1s ease, color .1s ease, border-color .1s ease, box-shadow .1s ease;
}

/* ── 입력 필드 ── */
/* 일반 입력칸(검색·프로필·국가·관심사·셀렉트)은 슬림하게 38px — 44px는 너무 뚱뚱해서 채팅 입력바처럼 날씬하게.
   font-size는 16px 유지(이하로 줄이면 iOS 포커스 시 자동 줌 — 크로스플랫폼 회귀). 라운드는 알약(아래).
   ⚠️ 로그인·회원가입 입력칸은 .pill-field(44px)로 감싸므로 여기 height 영향 안 받음(input 은 height:100%). */
body input, body select { height: 38px; }
body .composer-inline input { height: 36px; }   /* 댓글 등록(36px)과 정렬 */
/* (DM/랜덤 .composer 입력칸은 아래 "채팅 입력바" 섹션에서 투명 pill-glass 로 따로 스타일) */

/* 입력칸은 둥글게 — 버튼은 Linear식으로 각지게(7px) 두되 입력바만 의도적으로 둥글림.
   한 줄 입력/셀렉트 = 알약(고정 높이라 999px면 양끝이 완전 둥근 바). 검색·닉네임·국가·셀렉트 공통.
   여러 줄 입력(textarea: 자기소개·글쓰기)은 알약이 어색하니 넉넉한 라운드(18px)만. */
body input, body select { border-radius: 999px; }
body textarea { border-radius: 18px; }

/* ⚠️ Safari 전용 버그: 입력칸에 포커스되고 자동완성(열쇠 아이콘)이 뜨면 Safari 가
   author 의 -webkit-appearance:none 을 무시하고 UA 기본 텍스트필드 외형(둥근 사각형)으로
   되돌려 입력칸이 "네모"로 보인다. 포커스/자동완성/내부선택 상태에서 appearance·라운드를
   !important 로 다시 못박아 어떤 상태에서도 알약을 유지. (Chromium 미리보기엔 안 보이는 증상) */
body input, body select,
body input:focus, body select:focus,
body input:focus-visible, body select:focus-visible,
body input:-webkit-autofill,
body input:-internal-autofill-selected {
  -webkit-appearance: none !important;
  appearance: none !important;
  border-radius: 999px !important;
}

/* 브라우저 자동완성(저장된 로그인 정보) 시에도 알약 + 테마색 유지.
   크롬/사파리는 자동완성 입력에 UA 배경(연한 파랑/노랑)을 강제로 칠해 입력칸이
   네모·다른 색으로 보이게 만든다 — inset box-shadow 트릭으로 테마 표면색을 덮고,
   text-fill-color 로 글자색을, 라운드를 다시 못박는다. (로그인/회원가입에서 주로 발생) */
body input:-webkit-autofill,
body input:-webkit-autofill:hover,
body input:-webkit-autofill:focus,
body input:-webkit-autofill:active {
  border-radius: 999px;
  -webkit-text-fill-color: var(--text, var(--ink, inherit));
  caret-color: var(--text, var(--ink, inherit));
  -webkit-box-shadow: 0 0 0 1000px var(--bg-elev, var(--surface, var(--card, #14161f))) inset;
  box-shadow: 0 0 0 1000px var(--bg-elev, var(--surface, var(--card, #14161f))) inset;
  transition: background-color 9999s ease-out 0s;   /* 자동완성 배경 플래시 방지 */
}
/* 메시지/댓글 입력'바'는 전송 버튼도 같이 둥글려 바가 한 벌로 보이게(이 둘만 예외, 나머지 버튼은 7px). */
body .composer .btn, body .composer-inline .btn { border-radius: 999px; }

/* 채팅 말풍선 — 둥글게(밤티 탈출). 두 가지를 고침:
   ① 다크는 .msg가 var(--r-md)라 위 토큰 축소(17→8px)로 각져버렸음 → 토큰 무관 고정값으로.
   ② 세 테마 공통의 뾰족한 "꼬리"(border-bottom-*-radius:6px)가 싸 보임 → 꼬리도 둥글게 펴서 균일하게. */
body .msg { border-radius: 20px; }
body .msg.them { border-bottom-left-radius: 20px; }
body .msg.me   { border-bottom-right-radius: 20px; }

/* 버튼 전부 둥글게(알약) — 입력바·말풍선과 톤 통일. 각진 7px 폐기.
   로그인/회원가입/저장/매칭시작/수락·거절/게시/차단 등 .btn 전부. (FAB·아이콘버튼은 이미 원형) */
body .btn { border-radius: 999px; }
/* 세그먼트 토글(채팅/음성)도 알약 컨테이너+알약 세그먼트로 */
body .tabs { border-radius: 999px; }

/* 박스/카드칸 전부 둥글게 — 알약 인풋·버튼·말풍선과 톤 통일. 각진 8~14px 카드 폐기.
   인풋 높이(38~44px)의 알약 코너(≈19~22px)와 맞춰 20px. 아바타(50%)·뱃지·칩·인풋은 그대로. */
body .pf-block,
body .card,
body .modal-card,
body .voice-status,
body .comments-area,
body .post-edit,
body .empty,
body .notif-list .list-row,
body textarea { border-radius: 20px; }

/* ── 타이포그래피 (위 절제 레이어 값 in-place 재튜닝) ── */
/* 섹션 헤딩: 730/-0.03em → 600/-0.014em. Linear 510→600, 한글 과밀 자간 완화. */
body .section-head h2 { font-size: 17px; font-weight: 600; letter-spacing: -0.014em; }
/* 워드마크: 730/-0.035em → 620/-0.022em. color는 폴백 체인으로 3테마(모노 --ink) 모두 해결. */
body .brand h1 {
  background: none; -webkit-text-fill-color: currentColor;
  color: var(--text, var(--ink, inherit));
  font-weight: 620; letter-spacing: -0.022em;
}

/* ── 데스크톱 보정: 테마의 .tabbtn 62px(0,1,0)를 명시적으로 덮기 ── */
@media (min-width: 600px) {
  body .tabbtn { height: 52px; }
}

/* ============================================================
   회원가입 위저드 (여러 단계, 친절한 화면)
   - 4개 단계를 한 .wiz-track(가로 flex)에 모두 마운트, translateX 로 슬라이드(transform-only).
   - .wiz-viewport 높이는 JS가 활성 단계 높이에 맞춰(높이 점프 방지).
   - 색/토큰은 3테마 폴백 체인 사용. 둥근 컨트롤 언어 유지.
   ============================================================ */
/* 위저드 2단계(언어)는 키가 커서 세로 중앙정렬이면 프레임에서 잘림.
   safe center = 내용이 짧으면 중앙(로그인 화면 그대로), 넘치면 위 정렬 + 스크롤 → 잘림 방지. */
body .auth-wrap { justify-content: safe center; overflow-y: auto; }

.wiz-head { display: flex; align-items: center; gap: 16px; margin-bottom: 16px; }
.wiz-progress { flex: 1; display: flex; align-items: center; gap: 8px; }
.wiz-segs { flex: 1; display: flex; gap: 8px; }
.wiz-seg { flex: 1; height: 4px; border-radius: 999px;
  background: color-mix(in srgb, var(--text, var(--ink, #888)) 14%, transparent);
  transition: background-color .22s ease; }
.wiz-seg.on { background: var(--accent, #7b6bff); }
.wiz-count { font-size: 12px; color: var(--text-faint, var(--ink-3, #8a8a96)); font-variant-numeric: tabular-nums; }

/* 한 번에 한 단계만 보임(자연스러운 높이 → 잘림/스크롤 버그 없음). 들어오는 단계만 슬라이드 인.
   transform-only(opacity:0 시작 금지 — preview document.hidden 대비). */
.wiz-viewport { position: relative; }
.wiz-track { display: block; }
.wiz-step { display: none; flex-direction: column; gap: 16px; margin: 0; padding: 8px 8px; }
.wiz-step.is-active { display: flex; }
@keyframes wiz-in-fwd  { from { transform: translateX(22px); }  to { transform: translateX(0); } }
@keyframes wiz-in-back { from { transform: translateX(-22px); } to { transform: translateX(0); } }
.wiz-step.is-active.from-fwd  { animation: wiz-in-fwd .24s cubic-bezier(.22,.61,.36,1); }
.wiz-step.is-active.from-back { animation: wiz-in-back .24s cubic-bezier(.22,.61,.36,1); }

.wiz-h { font-size: 22px; font-weight: 700; letter-spacing: -0.02em; line-height: 1.32; margin: 0; }
.wiz-sub { font-size: 13.5px; line-height: 1.5; color: var(--text-dim, var(--ink-2, #8a8a96)); margin: -8px 0 8px; }
.wiz-cap { font-size: 12.5px; font-weight: 650; letter-spacing: -0.01em; color: var(--text-dim, var(--ink-2, #8a8a96)); }
.wiz-langsec { display: flex; flex-direction: column; gap: 8px; }
.lang-chips { display: flex; flex-wrap: wrap; gap: 8px; }
.lang-chip { font-size: 13px; }
.lang-chip.chip-disabled { opacity: .35; pointer-events: none; }

.wiz-err { min-height: 17px; font-size: 12.5px; line-height: 1.35; color: var(--danger, #e2574c); }

/* 로그인·회원가입 입력칸 — 알약을 바깥 .pill-field(span)에 입히고 input 은 투명·무테두리.
   Safari 가 자동완성(열쇠 아이콘) 뜬 input 을 자기 기본 외형(둥근 네모)으로 그려도,
   보이는 건 바깥 알약뿐이라 절대 네모로 안 보임. (채팅 컴포저와 같은 방식, span 은 자동완성 영향 없음) */
.pill-field {
  display: flex; align-items: center; width: 100%; box-sizing: border-box;
  height: 44px; padding: 0 16px; border-radius: 999px;
  background: var(--bg-elev, var(--surface, var(--card, #14161f)));
  border: 1px solid var(--line-strong, var(--line-2, var(--line, rgba(128,128,128,.22))));
  transition: border-color .16s ease, box-shadow .16s ease;
}
.pill-field:focus-within {
  border-color: var(--accent);
  box-shadow: 0 0 0 4px color-mix(in srgb, var(--accent) 12%, transparent);
}
body .pill-field > input {
  flex: 1; min-width: 0; height: 100%; padding: 0; margin: 0;
  background: transparent !important; border: none !important;
  border-radius: 0 !important; box-shadow: none !important; outline: none;
  -webkit-appearance: none; appearance: none;
  font-family: inherit; font-size: 16px; font-weight: 460;
  color: var(--text, var(--ink, inherit));
}
body .pill-field > input::placeholder { color: var(--text-faint, var(--ink-4, #8a8a96)); }
/* 자동완성돼도: 글자색 유지 + 바깥 알약과 같은 색으로 채워 네모 흔적 안 보이게 */
body .pill-field > input:-webkit-autofill,
body .pill-field > input:-webkit-autofill:hover,
body .pill-field > input:-webkit-autofill:focus {
  -webkit-text-fill-color: var(--text, var(--ink, inherit));
  -webkit-box-shadow: 0 0 0 1000px var(--bg-elev, var(--surface, var(--card, #14161f))) inset;
  border-radius: 0 !important;
  transition: background-color 9999s ease 0s;
}
/* 닉네임 카운터 / 비번 토글: 알약 안의 flex 자식(절대배치 아님) */
.wiz-counter { flex: none; margin-left: 8px; font-size: 12px; pointer-events: none;
  color: var(--text-faint, var(--ink-3, #8a8a96)); font-variant-numeric: tabular-nums; }
.wiz-counter.near { color: var(--accent, #7b6bff); }
.pw-toggle { flex: none; margin-left: 8px; background: none; border: none; cursor: pointer;
  -webkit-tap-highlight-color: transparent;
  color: var(--text-dim, var(--ink-2, #8a8a96)); font-size: 13px; font-weight: 600; padding: 8px; }

@keyframes wiz-shake { 0%,100% { transform: translateX(0); } 25% { transform: translateX(-6px); } 75% { transform: translateX(6px); } }
.wiz-shake { animation: wiz-shake .18s ease; }

/* 로그인 폼: 비밀번호 입력칸 ↔ 로그인 버튼 간격을 입력칸끼리 간격(이메일↔비밀번호 ≈42px)과 같게.
   입력칸 사이는 라벨이 끼어 42px이고 버튼 앞은 폼 gap(15px)뿐이라, 차이(27px)만큼 margin-top 보충. */
#form-login > .btn-primary { margin-top: 16px; }

/* 로그인 화면의 조용한 보조 링크(계정 찾기 등) */
.link-quiet {
  width: 100%; background: none; border: none; cursor: pointer;
  -webkit-tap-highlight-color: transparent;
  color: var(--text-dim, var(--ink-2, #8a8a96));
  font-family: inherit; font-size: 13px; font-weight: 500; letter-spacing: -0.01em;
  padding: 8px; text-align: center;
  transition: color .12s ease;
}
.link-quiet:hover { color: var(--text, var(--ink, inherit)); }

/* ============================================================
   채팅 메시지 입력바 (.composer) — 리퀴드 글래스 (시안 1:1). DM 채팅 + 랜덤 매칭 공유.
   구조: dock(트레이 + 폼). 폼 = 자체 프로스트(backdrop-filter) + 레이어(렌즈/틴트/발광/정반사 림) + .composer-row.
   iOS 글래스 보존 핵심: 프로스트를 .composer "자기 자신"에 둔다 → 같은 요소의 transform(리프트·플렉스·흔들림)과
   공존해도 글래스가 안 깨짐(iOS 는 *조상*-transform 만 자식 backdrop 을 무력화; 자기-transform 은 OK).
   가장자리 굴절 렌즈(url(#liquidLens))만 별도 .lg-lens 레이어 — iOS Safari 는 url() 미지원이라 거기서만 무동작
   (프로스트·리프트/플렉스·발광·정반사는 iOS 도 동작). 모션은 시안 값 그대로(--lg-out/--lg-spring, scoped).
   색만 3테마 적응(다크=시안 그대로, 라이트/모노는 틴트만 밝게) — 지오메트리·모션은 3테마 동일. ============== */

/* dock — 트레이 + 폼 래퍼. 시안 모션 토큰을 여기 스코프(다른 곳 프로젝트 토큰 안 건드림). */
body .composer-dock {
  flex: none; display: block;
  --lg-out: cubic-bezier(.22,.61,.36,1);
  --lg-spring: cubic-bezier(.34,1.56,.64,1);
}

/* 첨부 트레이 — 입력바 위로 슬라이드/페이드(시안). 닫히면 높이 0. */
body .composer-tray {
  display: flex; gap: 9px; margin: 0 16px; padding: 0 4px;
  max-height: 0; opacity: 0; overflow: hidden; transform: translateY(8px);
  transition: max-height .42s var(--lg-out), opacity .3s var(--lg-out), transform .42s var(--lg-out), margin .42s var(--lg-out);
}
body .composer-tray.open { max-height: 60px; opacity: 1; transform: translateY(0); margin-bottom: 9px; }
body .composer-ti {
  flex: none; display: inline-flex; align-items: center; gap: 7px;
  padding: 9px 14px; border-radius: 15px; cursor: pointer;
  font-family: inherit; font-size: 13px; font-weight: 460;
  -webkit-tap-highlight-color: transparent;
  color: color-mix(in srgb, var(--text, var(--ink, #fff)) 72%, transparent);
  background: color-mix(in srgb, var(--text, var(--ink, #fff)) 7%, transparent);
  border: 1px solid color-mix(in srgb, var(--text, var(--ink, #fff)) 12%, transparent);
  box-shadow: inset 1px 1px 1px -.5px color-mix(in srgb, #fff 40%, transparent);
  transition: transform .3s var(--lg-spring), background-color .2s var(--lg-out);
}
body .composer-ti svg { width: 17px; height: 17px; flex: none; }
body .composer-ti:active { transform: scale(.93); }

/* 리퀴드 글래스 바 — 프로스트를 자기 자신에 두고(아래 backdrop-filter) 시안 그대로 리프트/플렉스. */
body .composer {
  position: relative; isolation: isolate;
  margin: 8px 16px calc(8px + env(safe-area-inset-bottom, 0px));
  border-radius: 21px;   /* 바 높이 ~52→42(−20%)에 맞춰 알약 반경도 26→21 */
  background: none; border: none; padding: 0;       /* 테마 .composer{glass/border-top/padding} 차단 */
  -webkit-backdrop-filter: blur(5px) saturate(80%) brightness(.97);
          backdrop-filter: blur(5px) saturate(80%) brightness(.97);  /* 프로스트(시안) — 자기 요소라 iOS transform 과 공존 */
  box-shadow: 0 10px 30px -12px rgba(0,0,0,.55), 0 2px 8px -2px rgba(0,0,0,.4);
  transition: transform .45s var(--lg-spring), box-shadow .4s var(--lg-out);
}
/* 포커스: 살짝 떠오름(시안). 누름: 플렉스(시안). 흔들림: 빈 전송. — 전부 자기-transform 이라 iOS 글래스 유지. */
body .composer.focused { transform: translateY(-2px) scale(1.012); box-shadow: 0 16px 40px -14px rgba(0,0,0,.6); }
body .composer.pressed { transform: scale(1.035); box-shadow: 0 22px 52px -16px rgba(0,0,0,.66); }
@keyframes composer-shake { 0%,100%{transform:translateX(0)} 25%{transform:translateX(-5px)} 50%{transform:translateX(5px)} 75%{transform:translateX(-3px)} }
body .composer.shake { animation: composer-shake .28s ease; }

/* 레이어 ① 가장자리 렌즈 — SVG 변위맵(시안). iOS Safari 는 url() 미지원 → 여기만 무동작(자체 프로스트는 유지). */
body .composer .lg-lens {
  position: absolute; inset: 0; border-radius: inherit; z-index: 0; overflow: hidden;
  -webkit-backdrop-filter: url(#liquidLens); backdrop-filter: url(#liquidLens);
}
/* 레이어 ② 틴트 — 살짝 불투명한 바디(시안: 다크 퍼플그레이). 라이트/모노는 맨 아래에서 밝게 덮음. */
body .composer .lg-tint {
  position: absolute; inset: 0; border-radius: inherit; z-index: 1; pointer-events: none;
  background: linear-gradient(180deg, rgba(28,26,38,.34), rgba(22,20,30,.42));
}
/* 레이어 ③ 내부 발광 — 손끝에서 빛이 번짐(JS). screen 블렌드(컨테이너 isolation 으로 바 안에서만). */
body .composer .lg-illum {
  position: absolute; inset: 0; border-radius: inherit; z-index: 2; overflow: hidden; pointer-events: none;
  mix-blend-mode: screen;
}
body .composer .lg-illum-core {
  position: absolute; left: var(--tx, 50%); top: var(--ty, 50%); width: 340px; height: 340px; margin: -170px 0 0 -170px;
  border-radius: 50%; opacity: 0; transform: scale(.12); filter: blur(9px);
  background: radial-gradient(closest-side, rgba(255,255,255,.3), rgba(255,255,255,.11) 42%, transparent 72%);
}
body .composer .lg-illum-core.bloom { animation: composer-illum-bloom .85s var(--lg-out) forwards; }
@keyframes composer-illum-bloom { 0%{opacity:0; transform:scale(.12)} 26%{opacity:1} 100%{opacity:0; transform:scale(1.6)} }
/* 레이어 ④ 정반사 림 — 좌상단 밝은 모서리·우하단 부드러운·헤어라인(시안). 포커스 때 밝아지고 강조 림. */
body .composer .lg-shine {
  position: absolute; inset: 0; border-radius: inherit; z-index: 2; pointer-events: none;
  box-shadow:
    inset 1px 1px 1.2px -.8px rgba(255,255,255,.7),
    inset -1px -1px 1.2px -.8px rgba(255,255,255,.32),
    inset 0 0 0 1px rgba(255,255,255,.055);
  transition: box-shadow .4s var(--lg-out);
}
body .composer.focused .lg-shine {
  box-shadow:
    inset 1.5px 1.5px 2px -1px rgba(255,255,255,.95),
    inset -1.5px -1.5px 2px -1px rgba(190,200,255,.5),
    inset 0 0 0 1px color-mix(in srgb, var(--accent) 40%, rgba(255,255,255,.1));
}

/* 컨트롤 행 — 실제 +/입력/마이크/보내기 (레이어 위, z-index:3). */
body .composer .composer-row {
  position: relative; z-index: 3; flex: 1; min-width: 0; display: flex; align-items: center; gap: 8px; padding: 4px 4px 4px 8px;
}   /* 세로 7→4 (바 높이 −20%) · 오른쪽 8→4 (작아진 보내기 버튼을 그만큼 우측에 밀착) · 왼쪽 8 유지.
       flex:1 — .composer(부모 flex)에서 행이 폭을 꽉 채워 입력이 늘고 보내기가 우측 끝(패딩 4)에 밀착(이전엔 content-width 라 우측에 빈 ~30px 가 남아 떠 보였음). */

/* + 첨부 — 36 원형 + 정반사(시안). 누르면 스프링 squish + 45° 회전(X) + 강조 틴트. */
body .composer .composer-plus {
  flex: none; width: 32px; height: 32px; padding: 0; border-radius: 50%; cursor: pointer;
  display: flex; align-items: center; justify-content: center;
  -webkit-tap-highlight-color: transparent;
  color: var(--text, var(--ink, #fff));
  background: color-mix(in srgb, var(--text, var(--ink, #fff)) 12%, transparent);
  border: 1px solid color-mix(in srgb, var(--text, var(--ink, #fff)) 16%, transparent);
  box-shadow: inset 1px 1px 1px -.5px color-mix(in srgb, #fff 60%, transparent);
  transition: transform .45s var(--lg-spring), background-color .25s var(--lg-out);
}
body .composer .composer-plus svg { width: 17px; height: 17px; transition: transform .45s var(--lg-spring); }
body .composer .composer-plus:active { transform: scale(.88); }
body .composer .composer-plus.open { background: color-mix(in srgb, var(--accent) 28%, transparent); }
body .composer .composer-plus.open svg { transform: rotate(45deg); }

/* 입력 필드 — 투명·무테두리·16px(폰 줌 방지) */
body .composer .composer-input {
  flex: 1; min-width: 0; height: 28px; line-height: 28px;
  background: transparent; border: none; outline: none; box-shadow: none;
  color: var(--text, var(--ink, inherit));
  font-family: inherit; font-size: 16px; font-weight: 450; padding: 0 2px;
}
body .composer .composer-input::placeholder { color: color-mix(in srgb, var(--text, var(--ink, #888)) 50%, transparent); }

/* 트레일링 마이크 — 흐린 회색(장식). 입력 있으면 너비 0 으로 접힘. */
body .composer .composer-mic {
  flex: none; width: 30px; height: 30px; padding: 0; border: none; background: none;
  display: flex; align-items: center; justify-content: center; overflow: hidden;
  color: color-mix(in srgb, var(--text, var(--ink, #fff)) 60%, transparent);
  transition: width .36s var(--lg-out), opacity .26s var(--lg-out), margin .36s var(--lg-out);
}
body .composer .composer-mic svg { width: 18px; height: 18px; flex: none; }
body .composer.has-text .composer-mic { width: 0; opacity: 0; margin-left: -8px; }

/* 보내기 — 원형 38px + 정반사. 유휴=흐린 회색(웨이브) / 입력 있으면 강조 그라데이션 차오름 + 글로우(화살표). */
body .composer .composer-send {
  flex: none; width: 34px; height: 34px; padding: 0; border: none; border-radius: 50%; position: relative; overflow: hidden;
  display: flex; align-items: center; justify-content: center; cursor: pointer;
  -webkit-tap-highlight-color: transparent;
  background: color-mix(in srgb, var(--text, var(--ink, #fff)) 16%, transparent);
  color: color-mix(in srgb, var(--text, var(--ink, #fff)) 70%, transparent);
  box-shadow: inset 1px 1px 1px -.5px color-mix(in srgb, #fff 70%, transparent);
  transition: background .34s var(--lg-out), color .3s var(--lg-out), transform .45s var(--lg-spring), box-shadow .35s var(--lg-out);
}
body .composer .composer-send .ico {
  position: absolute; inset: 0; display: flex; align-items: center; justify-content: center;
  transition: opacity .26s var(--lg-out), transform .32s var(--lg-spring);
}
body .composer .composer-send .ico svg { width: 18px; height: 18px; }
body .composer .composer-send .wave  { opacity: 1; transform: scale(1); }
body .composer .composer-send .arrow { opacity: 0; transform: translateY(7px) scale(.7); }
/* 입력 있으면 강조 그라데이션으로 차오르고 화살표로 모핑 + 강조 글로우 (다크=시안 그라데이션, 라이트/모노=솔리드) */
body .composer.has-text .composer-send {
  background: var(--accent-grad, var(--accent)); color: #fff;
  box-shadow: inset 1px 1px 1px -.5px rgba(255,255,255,.55),
              0 5px 16px -4px color-mix(in srgb, var(--accent) 80%, transparent);
}
body .composer.has-text .composer-send .wave  { opacity: 0; transform: translateY(-7px) scale(.7); }
body .composer.has-text .composer-send .arrow { opacity: 1; transform: translateY(0) scale(1); }
body .composer .composer-send:active { transform: scale(.84); }
/* 전송 시 톡 튀는 pop + 리플 (transform/opacity-only) */
@keyframes composer-send-pop { 0%{transform:scale(.82)} 55%{transform:scale(1.14)} 100%{transform:scale(1)} }
body .composer .composer-send.pop { animation: composer-send-pop .5s var(--lg-spring); }
body .composer .composer-ripple {
  position: absolute; left: 50%; top: 50%; width: 8px; height: 8px; border-radius: 50%;
  background: rgba(255,255,255,.6);
  transform: translate(-50%, -50%) scale(0); opacity: 0; pointer-events: none;
}
body .composer .composer-send.pop .composer-ripple { animation: composer-ripple .55s var(--lg-out); }
@keyframes composer-ripple { 0%{transform:translate(-50%,-50%) scale(0); opacity:.7} 100%{transform:translate(-50%,-50%) scale(9); opacity:0} }

/* 라이트·모노: 다크 퍼플그레이 틴트 대신 밝은 틴트(색만, 지오메트리·모션 동일) */
html[data-theme="light"] body .composer .lg-tint,
html[data-theme="mono"] body .composer .lg-tint {
  background: linear-gradient(180deg, color-mix(in srgb, #fff 55%, transparent), color-mix(in srgb, #fff 42%, transparent));
}

/* iOS 소프트 키보드: 올라온 높이(--kb)만큼 대화 화면을 올려 입력바가 키보드 위에.
   chat.js 가 visualViewport 로 --kb 설정. 키보드 없음/데스크톱이면 0 → 무동작. */
#screen-conversation { box-sizing: border-box; padding-bottom: var(--kb, 0px); }
/* 키보드가 떠 있을 때(--kb>0, chat.js 가 .kb-open 토글)는 키보드가 홈 인디케이터 영역을 덮으므로
   컴포저의 safe-area 하단 마진을 0(8px)으로 빼서 입력바가 키보드 위에 딱 붙게 한다(--kb 가 이미 바닥까지
   포함 → env(safe-bottom)까지 더하면 키보드 위로 ~34px 들뜸=이중 카운트). margin 은 트랜지션 대상이 아님(즉시). */
body #screen-conversation.kb-open .composer { margin-bottom: 8px; }

/* ───────────────────────────────────────────────────────────────
   랜덤 매칭 배경 오로라 — 로비(랜덤 홈/검색) 뒤에서 은은히 흐른다.
   큰 소프트 radial 블롭 두 겹이 서로 반대로 느리게 드리프트 → 자연스러운 흐름.
   콘텐츠(z-index:1)는 위로, overflow:hidden 으로 화면 가장자리에 맞춰 클립.
   실제 채팅 뷰(#random-chatview)엔 없음(가독성). 색은 쿨 톤(액센트+민트+블루) = 오로라.
   미리보기(document.hidden)에선 애니메이션이 멈춰도 0% 프레임 자체가 오로라 구도라 OK.
   ─────────────────────────────────────────────────────────────── */
#random-home, #random-search { position: relative; overflow: hidden; isolation: isolate; }
#random-home > *, #random-search > * { position: relative; z-index: 1; }

#random-home::before, #random-search::before,
#random-home::after, #random-search::after {
  content: ""; position: absolute; inset: -35%; z-index: 0; pointer-events: none;
  /* blur 30→20: ~170% 뷰포트 크기 레이어의 가우시안 블러는 iOS GPU 에서 가장 비싼 페인트 중 하나이고
     블러 비용은 반경에 초선형이라 30→20 으로 ~절반. 거대한 소프트 블롭이라 시각 차이는 거의 없음.
     will-change:transform: scale 애니가 도는 동안 컴포지터가 레이어를 캐시해 매 프레임 재래스터 방지. */
  filter: blur(20px); opacity: .85; will-change: transform;
}
#random-home::before, #random-search::before {
  background:
    radial-gradient(38% 46% at 28% 32%, rgba(170,142,255,.42), transparent 68%),
    radial-gradient(42% 40% at 78% 70%, rgba(255,150,210,.28), transparent 68%);
  animation: aurora-drift-a 24s ease-in-out infinite alternate;
}
#random-home::after, #random-search::after {
  background:
    radial-gradient(46% 42% at 72% 26%, rgba(150,170,255,.30), transparent 68%),
    radial-gradient(38% 44% at 24% 76%, rgba(170,142,255,.30), transparent 68%);
  animation: aurora-drift-b 30s ease-in-out infinite alternate;
}
@keyframes aurora-drift-a {
  from { transform: translate3d(-6%, -4%, 0) scale(1.05) rotate(-5deg); }
  to   { transform: translate3d(7%, 6%, 0)  scale(1.2)  rotate(6deg); }
}
@keyframes aurora-drift-b {
  from { transform: translate3d(6%, 5%, 0)   scale(1.18) rotate(5deg); }
  to   { transform: translate3d(-7%, -5%, 0) scale(1.02) rotate(-6deg); }
}
@media (prefers-reduced-motion: reduce) {
  #random-home::before, #random-home::after,
  #random-search::before, #random-search::after { animation: none; }
}

/* 프로필 모달 — 팔로우 블록(팔로워/팔로잉 카운트 + 팔로우 버튼) */
.pf-follow { display: flex; align-items: center; justify-content: space-between; gap: var(--sp-4); margin-top: var(--sp-2); }
.pf-stats { display: flex; gap: var(--sp-6); }
.pf-stat { display: flex; flex-direction: column; align-items: center; gap: var(--sp-1); padding: 0;
  background: none; border: none; cursor: pointer; font-family: inherit; -webkit-tap-highlight-color: transparent;
  color: var(--text, var(--ink, inherit)); }
.pf-stat b { font-size: 16px; font-weight: 700; font-variant-numeric: tabular-nums; letter-spacing: -0.01em; }
.pf-stat-label { font-size: 12px; font-weight: 500; color: var(--text-dim, var(--ink-2, #8a8a96)); }
.pf-follow > .btn { width: auto; flex: none; padding: 0 var(--sp-6); }

/* ── 프로필 강화: 가입일 배지 · 본인 통계 행 · 완성도 미터 · 프로필 모먼트 ── */
/* 가입 N일째 배지 */
.pf-since { margin-top: var(--sp-2); font-size: 12px; font-weight: 600; color: var(--text-dim, #8a8a96);
  background: color-mix(in srgb, var(--text, var(--ink, #fff)) 7%, transparent);
  padding: var(--sp-1) var(--sp-3); border-radius: 999px; }
/* 본인 프로필 통계 행(팔로워/팔로잉/모먼트) — 상대 프로필(.pf-statbar)처럼 폭 꽉 채워 3등분 균등 (구분선 없음) */
.own-stats { width: 100%; gap: 0; padding: var(--sp-1) var(--sp-6) var(--sp-4); }
.own-stats .pf-stat { flex: 1; }

/* 프로필 완성도 미터 */
.cm-head { display: flex; align-items: center; justify-content: space-between; }
.cm-pct { font-size: 13px; font-weight: 700; letter-spacing: -0.01em; font-variant-numeric: tabular-nums;
  color: var(--accent, #7b6bff); }
.cm-bar { height: 8px; border-radius: 999px; margin-top: var(--sp-2); overflow: hidden;
  background: color-mix(in srgb, var(--text, var(--ink, #fff)) 10%, transparent); }
.cm-fill { height: 100%; border-radius: 999px; background: var(--accent, #7b6bff);
  transition: width .45s cubic-bezier(.2,.7,.2,1); }
.cm-hint { margin-top: var(--sp-2); font-size: 12.5px; line-height: 1.5; }

/* 프로필에 표시되는 모먼트 — pf-block 안의 가벼운 행(카드 중첩 회피), 헤어라인 구분 */
.pf-posts { display: flex; flex-direction: column; margin-top: var(--sp-2); }
body .pf-post { padding: var(--sp-3) 0;
  border-bottom: var(--hairline) solid color-mix(in srgb, var(--text, var(--ink, #fff)) 8%, transparent); }
body .pf-post:first-child { padding-top: var(--sp-1); }
body .pf-post:last-child { border-bottom: none; padding-bottom: 0; }
.pf-post .post-body { font-size: 14px; line-height: 1.55; white-space: pre-wrap;
  word-break: keep-all; overflow-wrap: anywhere; }
.pf-post-meta { display: flex; flex-wrap: wrap; align-items: center; gap: var(--sp-3); margin-top: var(--sp-2);
  font-size: 11.5px; }
.pf-post-meta .tag { margin-left: auto; }
/* 관심사 칩 에디터 — 선택 상태는 기존 .chip.on 재사용 (별도 스타일 불필요) */
.interest-edit { margin-top: 0; }

/* 설정 진입 행 — pf-block(글래스 카드)을 가로 버튼으로. 톱니 + '설정' + 우측 셰브런 */
body .pf-settings-entry { flex-direction: row; align-items: center; gap: var(--sp-3); width: 100%;
  text-align: left; cursor: pointer; font-family: inherit; -webkit-tap-highlight-color: transparent;
  transition: transform .08s ease, background .15s ease; }
body .pf-settings-entry:active { transform: scale(.992); }  /* 눌림 깊이 0.01 → 0.008 (강도 20% 감소) */
.pf-settings-entry svg { width: 22px; height: 22px; flex-shrink: 0; }
.pf-settings-entry .gear { color: var(--text-dim, var(--ink-2, #8a8a96)); }
.pf-settings-entry .chev { color: var(--text-faint, var(--ink-3, #8a8a96)); margin-left: auto; }
.pf-settings-label { font-weight: 650; font-size: 15px; letter-spacing: -0.01em; color: var(--text, var(--ink, inherit)); }

/* ───────────────────────────────────────────────────────────────
   프로필 탭 — 어두운 보라-파랑 오로라 배경 + 글래스모피즘.
   오로라는 #panel-profile(스크롤 컨테이너)가 아니라 스크롤되지 않는
   부모 #tab-panels 에 깐다(absolute 자식은 스크롤을 따라가므로 — 랜덤 로비
   오로라와 같은 패턴). 프로필 탭이 active 일 때만 :has() 로 켜고,
   콘텐츠는 z-index:1 로 오로라 위로 띄운다.
   그 위 카드(.pf-block)·입력창(input/select/textarea)은 반투명 흰색 글래스.
   ─────────────────────────────────────────────────────────────── */
body #tab-panels:has(#panel-profile.active) { isolation: isolate; }
body #tab-panels:has(#panel-profile.active)::before,
body #tab-panels:has(#panel-profile.active)::after {
  content: ""; position: absolute; inset: -30%; z-index: 0; pointer-events: none;
  /* blur 34→22 + will-change:transform (랜덤 로비 오로라와 동일 이유 — iOS 블러 페인트 비용↓ + 레이어 캐시). */
  filter: blur(22px); opacity: .9; will-change: transform;
}
/* 보라(액센트) + 파랑/인디고 블롭 두 겹이 반대로 느리게 드리프트 */
body #tab-panels:has(#panel-profile.active)::before {
  background:
    radial-gradient(40% 44% at 26% 24%, rgba(170,142,255,.40), transparent 70%),
    radial-gradient(44% 42% at 80% 30%, rgba(255,150,210,.26), transparent 70%);
  animation: aurora-drift-a 26s ease-in-out infinite alternate;
}
body #tab-panels:has(#panel-profile.active)::after {
  background:
    radial-gradient(46% 44% at 74% 80%, rgba(150,170,255,.30), transparent 70%),
    radial-gradient(40% 46% at 22% 78%, rgba(170,142,255,.28), transparent 70%);
  animation: aurora-drift-b 32s ease-in-out infinite alternate;
}
/* 프로필 콘텐츠를 오로라 위로(오로라는 z-index:0) */
body #panel-profile { position: relative; z-index: 1; }

@media (prefers-reduced-motion: reduce) {
  body #tab-panels:has(#panel-profile.active)::before,
  body #tab-panels:has(#panel-profile.active)::after { animation: none; }
}

/* 프로필·설정·편집 카드 = 다크 틴트 프로스티드 글래스. 오로라가 카드 뒤로 비치되 배경이 어두워 글자 또렷.
   글래스·블러·오로라 비침 유지. 모먼트 피드 카드(.moments-feed > .post)도 "완전히 똑같은" 유리로 공유. */
body :is(#panel-profile, .settings-list, .pf-edit-list) .pf-block,
body .moments-feed > .post {
  background: rgba(12,13,20,.52);
  -webkit-backdrop-filter: blur(18px) saturate(150%);
          backdrop-filter: blur(18px) saturate(150%);
  border: 1px solid rgba(255,255,255,.11);
  box-shadow: inset 0 1px 0 rgba(255,255,255,.09);
}
/* 라이트·모노는 글자가 어두운 색 → 카드도 밝은 틴트라야 또렷(다크 틴트면 글자 묻힘). 색만 테마별, 블러·글래스 동일. */
[data-theme="light"] body :is(#panel-profile, .settings-list, .pf-edit-list) .pf-block,
[data-theme="mono"]  body :is(#panel-profile, .settings-list, .pf-edit-list) .pf-block,
[data-theme="light"] body .moments-feed > .post,
[data-theme="mono"]  body .moments-feed > .post {
  background: rgba(255,255,255,.07);
  border-color: rgba(255,255,255,.12);
  box-shadow: inset 0 1px 0 rgba(255,255,255,.14);
}
body #panel-profile input,
body #panel-profile select,
body #panel-profile textarea {
  background: color-mix(in srgb, var(--text, var(--ink, #888)) 5%, var(--bg, #14151c));
  -webkit-backdrop-filter: none;
  backdrop-filter: none;
  border: 1px solid color-mix(in srgb, var(--text, var(--ink, #fff)) 11%, transparent);
  box-shadow: none;
}
body #panel-profile input:focus,
body #panel-profile select:focus,
body #panel-profile textarea:focus {
  border-color: var(--accent);
  box-shadow: 0 0 0 4px color-mix(in srgb, var(--accent) 12%, transparent);
}

/* ============================================================
   SOFT GLASS MINIMAL — 타이포 굵기 절제 (오직 400 / 500).
   헤비(600~820) 전부 Medium(500)로. 본문은 Regular(420~440).
   body .sel (0,1,1) 가 테마 (0,1,0) 보다 우선. fonts.css 자체 600 규칙도
   파일 뒤쪽이라 동률에서 이김. 작은 상태 뱃지 숫자만 가독 위해 600 유지.
   ============================================================ */
/* 문서 기본 = Regular(430). 강조만 Medium(500). */
html body { font-weight: 430; }
body .brand h1,
body .tagline,
body .section-head h2,
body .row-title, body .rt-name, body .rt-seen, body .rt-seen.seen-online,
body .list-row.unread .row-title, body .row-time,
body .peer-name, body .peer-langs,
body .modal-title, body .profile-name,
body .voice-status, body .vs-end,
body .tab, body .chip, body .tag,
body .btn, body .btn-primary, body .btn-ghost,
body .icon-btn, body .chat-actions,
body .field > span, body .consent b,
body .online span,
body .wiz-h, body .wiz-cap, body .pw-toggle,
body .theme-opt .to-name, body .pf-settings-label,
body .sugg-all, body .sugg-title, body .learns-add, body .sort-btn, body .say-hi,
body .cm-pct, body .pf-since, body .pf-stat b, body .pf-stat-label,
body .corr-head, body .read-mark, body .lang-abbr,
body .empty, body .search-text {
  font-weight: 500;
}
/* 본문/플레이스홀더 등 약한 텍스트는 Regular 쪽 */
body .row-sub, body .row-sub2, body .msg, body .pf-post .post-body { font-weight: 440; }
/* ── 글래스 알림 배지 (4곳 통일: 탭 카운트 .badge / 벨 .notif-badge / 채팅목록 .row-unread / 스크롤다운 .sd-badge) ──
   기존 단색 빨강(var(--danger))·강조 그라데이션·글로우·불투명 2px 링을 반투명 로즈 글래스로 교체.
   position/top/right/min-width/height/padding/카운트(99+·hidden) 로직은 기존 그대로 — 색·블러·그림자·무게만 교체.
   3테마 동일. ⚠ .row-unread 는 행마다 1개라 안읽음 대화가 아주 많으면 backdrop-filter 비용↑(보통은 희소) —
   긴 목록에서 iOS 잰크 시 .row-unread 만 backdrop-filter:none 으로 빼면 됨([[ios-perf-parity]]). */
body :is(.badge, .notif-badge, .sd-badge, .row-unread) {
  background: rgba(255,120,140,.34);
  -webkit-backdrop-filter: blur(6px) saturate(150%);
          backdrop-filter: blur(6px) saturate(150%);
  color: #fff;
  border-radius: 999px;
  box-shadow:
    0 0 0 1.5px rgba(255,120,140,.5),       /* 컬러 림(옛 bg색 2px 링 대체) */
    inset 0 1px 0 rgba(255,255,255,.55),     /* 상단 광택 */
    0 2px 6px rgba(0,0,0,.3);                /* 띄움 그림자 */
  text-shadow: 0 1px 1px rgba(120,20,40,.4);
  font-weight: 700;                          /* 글래스라 800→700(가벼운 무게가 깔끔) */
  display: flex; align-items: center; justify-content: center;   /* 숫자 정중앙(원/알약 공통) */
  z-index: 10;                               /* 아이콘 글리프(z:2)보다 앞 — 배지가 항상 맨 위로 */
}
/* ── 배지 = 완전한 동그라미 + 아이콘 비례 크기 + 정확한 위치 (지오메트리는 3테마 동일 — body 프리픽스로 테마값 덮음) ──
   1자리는 min-width=height 라 정사각 → border-radius:999 로 완전한 원. 2자리↑만 가로로 늘어 알약. */
body .badge {           /* 탭 카운트(채팅) — 14px, 26px 아이콘 우상단 코너(중심이 아이콘 오른쪽 끝) */
  min-width: 14px; height: 14px; padding: 0 4px; font-size: 9px; line-height: 1;
  top: 0; left: calc(50% + 6px); margin-left: 0;
}
body .row-unread {      /* 채팅 목록 안읽음 — 흐름 배치, 원형만(아바타 44 옆 비례 18) */
  min-width: 18px; height: 18px; padding: 0 5px; font-size: 11px; line-height: 1;
}
/* 등장/증가 시 톡 튀는 pop — 배지는 작은 leaf 라 transform 줘도 글래스 무력화 이슈 없음 */
@keyframes badge-pop { 0%{transform:scale(.4); opacity:0} 60%{transform:scale(1.12)} 100%{transform:scale(1); opacity:1} }
body :is(.badge, .notif-badge, .sd-badge, .row-unread).badge-pop {
  animation: badge-pop .3s var(--ease-spring, cubic-bezier(.34,1.45,.45,1));
}
/* 라이트·모노: 밝은 배경 위 옅은 로즈 글래스는 흰 글자 대비가 부족(~1.4:1) → 더 진하고 불투명한 로즈로(흰 글자 AA). */
html[data-theme="light"] body :is(.badge, .notif-badge, .sd-badge, .row-unread),
html[data-theme="mono"]  body :is(.badge, .notif-badge, .sd-badge, .row-unread) {
  background: rgba(200,48,72,.96);
  box-shadow:
    0 0 0 1.5px rgba(200,48,72,.5),
    inset 0 1px 0 rgba(255,255,255,.45),
    0 2px 6px rgba(0,0,0,.18);
}
/* .row-unread 는 채팅 목록 행마다 1개 → 긴 안읽음 목록의 per-row backdrop-filter 비용 회피([[ios-perf-parity]]).
   블러만 빼고(19px 작은 배지라 시각 차 거의 없음) 로즈를 조금 더 진하게 — 림·광택은 유지(다크). 라이트/모노는 위 규칙이 색 담당. */
body .row-unread { -webkit-backdrop-filter: none; backdrop-filter: none; background: rgba(255,120,140,.5); }
/* 투명도 줄이기 선호 시: 글래스 대신 불투명 폴백(가독성 보장). 맨 뒤라 위 규칙들을 모두 덮음.
   #fff 글자 AA(>=4.5:1) 위해 살짝 진한 로즈(#d23a4e). row-unread 의 반투명도 여기서 불투명으로 덮임. */
@media (prefers-reduced-transparency: reduce) {
  body :is(.badge, .notif-badge, .sd-badge, .row-unread),
  body .row-unread {
    background: #d23a4e;
    -webkit-backdrop-filter: none; backdrop-filter: none;
  }
}

/* ============================================================
   랜덤 홈 hero — 앱 전체에서 유일한 유리 요소.
   원형 유리 통화 CTA(.rnd-call) + 플랫 알약 채팅 버튼(.rnd-chat).
   유리가 색을 머금도록 뒤에 오로라 블롭(#random-home::before/after)이 흐른다.
   ============================================================ */
.rnd-cta { display: flex; flex-direction: column; align-items: center; }
/* 주 CTA = 원형 유리(132). 액센트 전화 아이콘 + 액센트 머금은 컬러 섀도우. */
.rnd-call {
  width: 132px; height: 132px; border-radius: 50%;
  display: flex; align-items: center; justify-content: center;
  border: 1px solid rgba(255, 255, 255, .16);
  background: rgba(255, 255, 255, .10);
  -webkit-backdrop-filter: blur(20px) saturate(140%);
  backdrop-filter: blur(20px) saturate(140%);
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, .30),
              0 16px 42px -12px color-mix(in srgb, var(--accent) 50%, transparent);
  color: var(--accent);
  cursor: pointer; -webkit-tap-highlight-color: transparent;
  transition: transform .16s ease, box-shadow .16s ease;
}
.rnd-call svg { width: 50px; height: 50px; }
.rnd-call:active {
  transform: scale(.97);
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, .26),
              0 10px 26px -12px color-mix(in srgb, var(--accent) 42%, transparent);
}
/* 라이트·모노(밝은 배경) = 흰 유리 0.5 + 또렷한 흰 보더(스펙). */
html[data-theme="light"] .rnd-call,
html[data-theme="mono"] .rnd-call {
  border: 1px solid rgba(255, 255, 255, .7);
  background: rgba(255, 255, 255, .5);
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, .6),
              0 14px 38px -12px color-mix(in srgb, var(--accent) 32%, transparent);
}
/* 통화 라벨 (CTA 아래, Medium) */
.rnd-call-label { margin-top: 18px; font-size: 15px; font-weight: 500;
  letter-spacing: -0.01em; color: var(--text, var(--ink, inherit)); }
/* 보조 = 플랫 알약 채팅 버튼(헤어라인 + 액센트 아이콘). 유리 아님. */
.rnd-chat {
  margin-top: 30px;
  display: inline-flex; align-items: center; gap: 8px;
  height: 48px; padding: 0 24px; border-radius: 999px;
  border: 1px solid color-mix(in srgb, var(--text, var(--ink, #fff)) 12%, transparent);
  background: color-mix(in srgb, var(--text, var(--ink, #888)) 4%, transparent);
  color: var(--text, var(--ink, inherit));
  font-family: inherit; font-size: 14px; font-weight: 500; letter-spacing: -0.01em;
  cursor: pointer; -webkit-tap-highlight-color: transparent;
  transition: background-color .15s ease, transform .08s ease;
}
.rnd-chat svg { width: 20px; height: 20px; color: var(--accent); }
.rnd-chat:hover { background: color-mix(in srgb, var(--text, var(--ink, #888)) 8%, transparent); }
.rnd-chat:active { transform: scale(.97); }
/* 매칭 검색 상태 스피너의 컬러 글로우 제거(플랫). + 3테마 회전 속도/이징 통일(라이트 .85s·큐빅,
   모노 .9s·큐빅 → 다크 기준 .9s linear). 동일 @keyframes spin 이 3테마 모두에 정의돼 있고 transform
   (rotate)만 애니메이트 → 모션 규칙 준수, prefers-reduced-motion 전역 가드가 그대로 끈다. */
body .spinner { box-shadow: none; animation: spin .9s linear infinite; }

/* ============================================================
   GlassButton 전면 적용 — 앱의 모든 액션 버튼을 글래스 + 누름 모션으로.
   (사용자 요청으로 Soft Glass Minimal '유리 하나' 규칙 해제. glass-button.js 스펙을 앱에 이식.)
   • 유리 틴트 = 테마 적응형(--text 기반): 다크=흰유리 / 라이트·모노=잉크유리 → 3테마 다 유리로 보임
     (스펙의 리터럴 흰색은 밝은 배경에서 안 보여서 color-mix 로 테마화. 블러·하이라이트·모션은 스펙 그대로.)
   • 블러 14, 상단 inset 하이라이트, OS 기본 터치효과 off.
   • 누름 모션 = :active(CSS-only): press-in scale .97 + 밝아짐 120ms / release 200ms,
     cubic-bezier(.16,1,.3,1), 오버슈트 없음. (모션 줄이기면 scale 빼고 밝기만.)
   • 둥근 모서리(알약/원)는 앱 톤대로 유지. primary 는 액센트 틴트 글래스로 위계 유지.
   대상: .btn 군 · .icon-btn · .top-action-btn · .fab · .back-btn · .row-quick · .say-hi · .sort-btn.
   (필터칩·하단탭·세그먼트·스탯은 제외 — 글래스 떡칠 방지.)
   ============================================================ */
body .btn,
body .icon-btn,
body .top-action-btn,
body .fab,
body .back-btn,
body .row-quick,
body .say-hi,
body .sort-btn {
  -webkit-tap-highlight-color: transparent;
  -webkit-user-select: none; user-select: none;
  transition:
    transform var(--dur-fast) var(--ease-out),
    background-color var(--dur-fast) var(--ease-out),
    border-color var(--dur-fast) var(--ease-out),
    box-shadow var(--dur-fast) var(--ease-out);
}
/* 글래스 블러는 다크 전용(라이트·모노는 평면 — glass-is-dark-only 규칙). 라이트/모노는 fill 이 거의 불투명이라 시각차 없음. */
html[data-theme="dark"] body :is(.btn, .icon-btn, .top-action-btn, .fab, .back-btn, .row-quick, .say-hi, .sort-btn) {
  -webkit-backdrop-filter: blur(14px);
          backdrop-filter: blur(14px);
}
/* press-in: 120ms + scale .97 (release 는 위 200ms 로 복귀)
   ※ 실제 누름 깊이는 아래 "전역 버튼 press: 스프링 백" 블록이 덮는다(동일 명시도·더 뒤) — 강도 조절은 거기서. */
body .btn:active,
body .icon-btn:active,
body .top-action-btn:active,
body .fab:active,
body .back-btn:active,
body .row-quick:active,
body .say-hi:active,
body .sort-btn:active {
  transition-duration: 120ms;
  transform: scale(0.97);
}

/* 기본/보조 버튼 = 테마 적응형 유리 + 상단 하이라이트. */
body .btn,
body .icon-btn,
body .top-action-btn,
body .back-btn,
body .row-quick,
body .sort-btn {
  background: color-mix(in srgb, var(--text, var(--ink, #fff)) 13%, transparent);
  border: 1px solid color-mix(in srgb, var(--text, var(--ink, #fff)) 30%, transparent);
  box-shadow: inset 0 1px 0 color-mix(in srgb, var(--text, var(--ink, #fff)) 25%, transparent);
  color: var(--text, var(--ink, inherit));
}
body .btn:active,
body .icon-btn:active,
body .top-action-btn:active,
body .back-btn:active,
body .row-quick:active,
body .sort-btn:active {
  background: color-mix(in srgb, var(--text, var(--ink, #fff)) 20%, transparent);
  border-color: color-mix(in srgb, var(--text, var(--ink, #fff)) 42%, transparent);
}

/* Primary CTA = 브랜드 그라데이션 채움 (fill 통일: 1차 CTA 는 .pf-edit-btn/.pl-rec-cta 와 동일한 그라데이션).
   --accent-grad 다크 전용 → 라이트·모노는 토큰 폴백 그라데이션. 흰 글자 + 옅은 액센트 글로우. */
body .btn.btn-primary {
  background: var(--accent-grad, linear-gradient(135deg, var(--accent), var(--accent-strong, var(--accent))));
  border: none;
  box-shadow: 0 6px 16px -10px color-mix(in srgb, var(--accent) 70%, transparent),
              inset 0 1px 0 rgba(255, 255, 255, 0.22);
  color: #fff;
}
body .btn.btn-primary:active { filter: brightness(.97); }
body .btn.btn-primary:hover { filter: brightness(1.06); }

/* FAB = 액센트 틴트 글래스 원형. */
body .fab {
  background: color-mix(in srgb, var(--accent) 42%, transparent);
  border: 1px solid color-mix(in srgb, var(--accent) 60%, transparent);
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.28);
}
body .fab:active { background: color-mix(in srgb, var(--accent) 54%, transparent); }
/* FAB 호버(데스크탑)도 가라앉힌 유리로 — 다크 테마 CSS 의 강한 인디고 글로우 대신 살짝 밝아지기만(글로우 없음).
   터치 sticky-hover 까지 덮으려 @media 게이트 없이(다크 테마 .fab:hover 글로우를 항상 무력화). */
html[data-theme="dark"] body .fab:hover {
  background: color-mix(in srgb, var(--accent) 52%, transparent);
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.28);
}

/* 밝은 테마(라이트·모노) FAB: 42% 액센트 글래스는 밝은 배경에서 너무 옅어 → 거의 불투명으로 올려 가독성 유지.
   (btn-primary 는 이제 그라데이션 채움이라 여기서 제외 — 그라데이션이 불투명이라 별도 보정 불필요.) */
html[data-theme="light"] body .fab,
html[data-theme="mono"] body .fab {
  background: color-mix(in srgb, var(--accent) 90%, transparent);
  border-color: color-mix(in srgb, var(--accent) 96%, transparent);
}
html[data-theme="light"] body .fab:active,
html[data-theme="mono"] body .fab:active {
  background: color-mix(in srgb, var(--accent) 97%, transparent);
}

/* 인사하기 알약 = 액센트 옅은 유리(원래 톤 유지하며 글래스화). */
body .say-hi { box-shadow: inset 0 1px 0 color-mix(in srgb, var(--accent) 22%, transparent); }

/* 키보드 포커스 링(접근성) — 글래스 버튼들. */
body .btn:focus-visible,
body .icon-btn:focus-visible,
body .top-action-btn:focus-visible,
body .fab:focus-visible,
body .back-btn:focus-visible {
  outline: none;
  box-shadow: inset 0 1px 0 color-mix(in srgb, var(--text, var(--ink, #fff)) 25%, transparent),
              0 0 0 3px color-mix(in srgb, var(--accent) 45%, transparent);
}

/* OS '모션 줄이기' — scale 애니메이션 제거, 밝기 변화만 유지. */
@media (prefers-reduced-motion: reduce) {
  body .btn, body .icon-btn, body .top-action-btn, body .fab,
  body .back-btn, body .row-quick, body .say-hi, body .sort-btn {
    transition: background-color 120ms linear, border-color 120ms linear;
  }
  body .btn:active, body .icon-btn:active, body .top-action-btn:active, body .fab:active,
  body .back-btn:active, body .row-quick:active, body .say-hi:active, body .sort-btn:active {
    transform: none;
  }
}

/* ============================================================
   우측 원형 채팅 아이콘(.row-quick) — 프로스티드 글래스 (평면형, 시안 1번).
   ============================================================ */
body .row-quick {
  position: relative;
  border: 1px solid transparent;
  color: color-mix(in srgb, var(--text, var(--ink, #fff)) 88%, transparent);
  background: color-mix(in srgb, var(--text, var(--ink, #fff)) 8%, transparent);
  /* backdrop-filter 제거 — 리스트 행마다 1개씩(파트너 40+) 스크롤되는 컨테이너 안에 들어가
     iOS 가 매 프레임 40+개의 backdrop 블러를 재래스터 → 최대 스크롤 잰크 원인. 36px 작은 원이라
     거의 균일한 행 배경을 블러해봐야 시각 효과는 사실상 0(반투명 채움+테두리+상단 하이라이트로
     글래스 룩 유지). 데스크탑/아이폰 양쪽에서 룩 동일하게 보존되며 레이어 40+개 제거. */
  -webkit-backdrop-filter: none;
          backdrop-filter: none;
  box-shadow:
    inset 0 1px 0 color-mix(in srgb, var(--text, var(--ink, #fff)) 22%, transparent),
    inset 0 0 0 1px color-mix(in srgb, var(--text, var(--ink, #fff)) 10%, transparent),
    0 4px 12px -6px rgba(0, 0, 0, 0.45);
  -webkit-tap-highlight-color: transparent;
}
body .row-quick::after {            /* 44px 히트영역 유지 */
  content: ""; position: absolute; z-index: 2;
  top: 50%; left: 50%; width: 44px; height: 44px; transform: translate(-50%, -50%);
}
body .row-quick svg { position: relative; z-index: 1; }
body .row-quick:hover {
  background: color-mix(in srgb, var(--text, var(--ink, #fff)) 13%, transparent);
  color: var(--text, var(--ink, #fff));
}
body .row-quick:active {
  background: color-mix(in srgb, var(--text, var(--ink, #fff)) 13%, transparent);
  border-color: transparent;
}

/* ============================================================
   헤더 유틸 아이콘(검색/알림) = 고스트. "글래스는 floating surface 한정" 원칙 —
   헤더는 떠 있는 면이 아니므로 원형 배경·테두리·글래스/백드롭 블러 전부 제거, 글리프만.
   히트영역 40×40 / 아이콘 20 / 흐린 화이트(보조 텍스트 톤) / hover·focus 때만 살짝 밝아짐.
   그 외 트랜지션·애니메이션 없음. (위 글래스 레이어가 .top-action-btn 에 글래스를 입히므로
   파일 끝의 이 블록이 그걸 덮어 고스트로 되돌린다.) gap 8·right 16·aria-label 은 기존 그대로.
   ============================================================ */
body .top-action-btn {
  width: 40px; height: 40px;
  background: none; border: none; box-shadow: none;
  -webkit-backdrop-filter: none; backdrop-filter: none;
  color: var(--text-dim, var(--ink-2, #8a8a96));   /* 흐린 화이트 = 보조 텍스트 톤 */
  -webkit-tap-highlight-color: transparent;
  transition: none;                                 /* 그 외 트랜지션 추가 금지 */
}
body .top-action-btn svg { width: 20px; height: 20px; }
/* hover/focus 일 때만 아주 살짝 밝아짐(배경/링/그림자 일절 추가 없음) */
body .top-action-btn:hover,
body .top-action-btn:focus-visible {
  color: var(--text, var(--ink, inherit));
  background: none; border: none; box-shadow: none; outline: none;
}
/* 누름 애니메이션(scale)·press 배경 전부 제거 */
body .top-action-btn:active {
  transform: none; background: none; border: none; box-shadow: none;
}

/* 뒤로가기 버튼(.back-btn) — 헤더 유틸 아이콘과 동일하게 고스트로 통일.
   원형 배경·테두리·글래스/블러 전부 제거, ← 글리프만. 흐린 화이트, hover/focus 때만 살짝 밝게.
   그 외 트랜지션·애니메이션 없음. (글래스 레이어가 .back-btn 에 글래스를 입히므로 여기서 덮음) */
body .back-btn {
  background: none; border: none; box-shadow: none;
  -webkit-backdrop-filter: none; backdrop-filter: none;
  width: 32px; height: 32px; font-size: 20px;   /* 컴팩트 바(콘텐츠 32)에 맞춤 */
  color: var(--text-dim, var(--ink-2, #8a8a96));   /* 흐린 화이트 = 보조 텍스트 톤 */
  -webkit-tap-highlight-color: transparent;
  transition: none;
}
body .back-btn:hover,
body .back-btn:focus-visible {
  color: var(--text, var(--ink, inherit));
  background: none; border: none; box-shadow: none; outline: none;
}
body .back-btn:active {
  transform: none; background: none; border: none; box-shadow: none;
}

/* 뒤로가기 아이콘 = 통통 화살표(꼬리). ← 글리프 숨기고 SVG 마스크로 교체 */
body .back-btn {
  font-size: 0 !important;
  display: inline-flex; align-items: center; justify-content: center;
}
body .back-btn::before {
  content: ""; display: block; width: 22px; height: 22px;
  background-color: currentColor;
  -webkit-mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='3' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M18.5 12H7'/%3E%3Cpath d='M12 6.5 6.5 12 12 17.5'/%3E%3C/svg%3E") center / contain no-repeat;
          mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='3' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M18.5 12H7'/%3E%3Cpath d='M12 6.5 6.5 12 12 17.5'/%3E%3C/svg%3E") center / contain no-repeat;
}

/* 프로필 편집 버튼만 브랜드 인디고 단독 CTA. .btn-ghost(글래스 통일)에서 제외하고 채움.
   --accent-grad 는 다크에만 정의 → 라이트·모노는 폴백 그라데이션(토큰 기반)으로 fill 유지(없으면 투명+흰 글자로 안 보임). */
body #panel-profile .pf-edit-btn,
body .btn.btn-ghost.pf-edit-btn {
  background: var(--accent-grad, linear-gradient(135deg, var(--accent), var(--accent-strong, var(--accent))));
  border: none;
  color: #fff;
  font-weight: 600;
  box-shadow: 0 8px 22px -10px color-mix(in srgb, var(--accent) 70%, transparent),
              inset 0 1px 0 rgba(255,255,255,.25);
  -webkit-backdrop-filter: none; backdrop-filter: none;
}
body #panel-profile .pf-edit-btn:hover,
body .btn.btn-ghost.pf-edit-btn:hover { filter: brightness(1.06); background: var(--accent-grad, linear-gradient(135deg, var(--accent), var(--accent-strong, var(--accent)))); }
body #panel-profile .pf-edit-btn:active,
body .btn.btn-ghost.pf-edit-btn:active { transform: scale(.99); filter: brightness(.97); }
/* 팔로잉(이미 팔로우 중): 옆 '메시지 보내기'(밝은 인디고 CTA)보다 한 톤 가라앉혀 "완료/보조"로 —
   밝은 그라데이션·글로우 제거, 납작한 반투명 인디고 채움 + 흐린 글자(weight 500). 색만 다름(3테마 토큰), 누름 scale 은 유지. */
body .btn.btn-ghost.pf-edit-btn.is-following {
  background: color-mix(in srgb, var(--accent) 16%, transparent);
  color: color-mix(in srgb, var(--text, var(--ink, #fff)) 70%, transparent);
  box-shadow: none;
  font-weight: 500;
}
body .btn.btn-ghost.pf-edit-btn.is-following:hover {
  background: color-mix(in srgb, var(--accent) 22%, transparent);
  filter: none;
}

/* ── 모먼트 좋아요: 흐린 회색 하트 → 테마 강조색이 아래에서 차오름 + 반짝 버스트 ──────────
   .like-btn 에 .liked 토글로 상태. 버스트는 마스크에 안 잘리게 하트와 형제(.like-ico 안)로.
   색만 다른 규칙: 차오름색(--like-1/2)·쉬는색(--like-rest) 모두 테마별. 구조·마스크·애니는 동일. */
/* 좋아요(채워진) 색 — 테마 강조색 */
:root              { --like-1:#8E86FF; --like-2:#5B7CFF; }  /* dark: 인디고~블루 */
[data-theme="light"]{ --like-1:#ff6a52; --like-2:#e8462f; } /* light: 코랄 */
[data-theme="mono"] { --like-1:#c0573b; --like-2:#a23d24; } /* mono: 브릭 */

/* 쉬는 하트(안 누른 상태) — 흐린 회색 채움 */
:root              { --like-rest:#565a6b; }  /* dark: 차분한 쿨그레이 */
[data-theme="light"]{ --like-rest:#c4c7d1; } /* light: 라이트 그레이 */
[data-theme="mono"] { --like-rest:#bdb8b2; } /* mono: 웜 그레이 */
.like-ico { position: relative; display: inline-flex; width: 22px; height: 22px; flex: none; }
.like-heart {
  position: absolute; inset: 0; display: block; overflow: hidden;
  --lh-mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M12 20.5C5.4 16 2.5 12.4 2.5 8.8A4.6 4.6 0 0 1 12 6.3a4.6 4.6 0 0 1 9.5 2.5c0 3.6-2.9 7.2-9.5 11.7z'/%3E%3C/svg%3E");
  -webkit-mask: var(--lh-mask) center / contain no-repeat;
          mask: var(--lh-mask) center / contain no-repeat;
}
.lh-white { position: absolute; inset: 0; background: var(--like-rest, #fff); }
.lh-fill {
  position: absolute; inset: 0;
  background: linear-gradient(180deg, var(--like-1), var(--like-2));
  transform: scaleY(0); transform-origin: bottom;
  transition: transform .5s cubic-bezier(.6, 0, .2, 1);
}
.liked .like-heart { animation: lh-pop .42s cubic-bezier(.3, 1.4, .5, 1); }
.liked .lh-fill { transform: scaleY(1); }
@keyframes lh-pop { 0% { transform: scale(1) } 40% { transform: scale(1.32) } 70% { transform: scale(.92) } 100% { transform: scale(1) } }

.like-burst { position: absolute; left: 50%; top: 50%; width: 0; height: 0; pointer-events: none; opacity: 0; }
.liked .like-burst { animation: lh-burst .6s ease forwards; }
.like-burst i { position: absolute; width: 4px; height: 4px; border-radius: 50%; background: var(--like-1); }
.like-burst i:nth-child(1) { transform: rotate(0deg)   translateY(-16px) }
.like-burst i:nth-child(2) { transform: rotate(60deg)  translateY(-16px) }
.like-burst i:nth-child(3) { transform: rotate(120deg) translateY(-16px) }
.like-burst i:nth-child(4) { transform: rotate(180deg) translateY(-16px) }
.like-burst i:nth-child(5) { transform: rotate(240deg) translateY(-16px) }
.like-burst i:nth-child(6) { transform: rotate(300deg) translateY(-16px) }
@keyframes lh-burst { 0% { opacity: 0; transform: scale(.4) } 30% { opacity: 1 } 100% { opacity: 0; transform: scale(1.25) } }

/* 초기 렌더(이미 좋아요한 글)는 채움만, 팝/버스트는 탭할 때만 */
.no-pop .like-heart, .no-pop .like-burst { animation: none !important; }

/* 프로필·설정·편집 한정 글자 강화 — 다크 틴트 글래스 위에서 라벨/본문 또렷하게(다른 화면 영향 없음) */
body :is(#panel-profile, .settings-list, .pf-edit-list) .pf-label { color: var(--text-dim); font-weight: 600; }
body :is(#panel-profile, .settings-list, .pf-edit-list) .cm-hint,
body :is(#panel-profile, .settings-list, .pf-edit-list) .muted { color: var(--text-dim); }
body :is(#panel-profile, .settings-list, .pf-edit-list) .pf-post .post-body,
body :is(#panel-profile, .settings-list, .pf-edit-list) .lg,
body :is(#panel-profile, .settings-list, .pf-edit-list) .tag { color: var(--text); }

/* 카운트 롤링 숫자(.pa-count → .roll). 자릿수마다 0~9 스택을 translateY로 굴린다.
   .digit 는 absolute .stack 만 담아 고유 너비가 0이므로 width:1ch 로 한 칸 폭 확보(tabular-nums). */
.roll { display: inline-flex; height: 1.25em; line-height: 1.25em; overflow: hidden; vertical-align: -.22em; }
.roll .digit { position: relative; display: block; width: 1ch; height: 1.25em; overflow: hidden; }
.roll .digit .stack { position: absolute; left: 0; top: 0; width: 100%; }
.roll .digit .stack span { display: block; height: 1.25em; line-height: 1.25em; text-align: center; }

/* 프로필 편집 — 필드를 4개 섹션 카드(.edit-sec = .pf-block)로 묶음. 글래스는 .pf-edit-list .pf-block 규칙 재사용. */
/* 섹션 카드 사이 간격 — 프로필 보기(.profile-body)와 동일 24px. screen-list 기본 block이라 안 주면 카드가 서로 붙음. */
body .pf-edit-list { display: flex; flex-direction: column; gap: var(--sp-6); }
body .pf-edit-list .edit-sec { gap: var(--sp-3); }
body .pf-edit-list .edit-sec .sec-t {
  font-size: 11px; font-weight: 700; letter-spacing: .04em; text-transform: uppercase;
  color: var(--accent-strong, var(--accent));
}
/* 사진 섹션은 가운데 정렬(아바타 헤더) */
body .pf-edit-list .edit-sec:first-child { align-items: center; }

/* ── 전역 버튼 press: 스프링 백 ── */
body :is(.btn, .btn-primary, .btn-ghost, .fab, .chip, .icon-btn, .post-act, .back-btn,
         .row-quick, .sort-btn, .say-hi, .top-action-btn, .msg-tool, .learns-rm,
         .composer-send, .rnd-chat, .rnd-call, .pf-settings-entry, .pf-edit-btn) {
  transition: transform .3s cubic-bezier(.34,1.4,.64,1),
              background-color .2s ease, color .2s ease,
              box-shadow .2s ease, border-color .2s ease;
}
body :is(.btn, .btn-primary, .btn-ghost, .fab, .chip, .icon-btn, .post-act, .back-btn,
         .row-quick, .sort-btn, .say-hi, .top-action-btn, .msg-tool, .learns-rm,
         .composer-send, .rnd-chat, .rnd-call, .pf-settings-entry, .pf-edit-btn):active {
  transform: scale(var(--press-strong));  /* 버튼류 누름 깊이 단일 토큰(=.94, 기존 .9405 와 사실상 동일) */
  transition-duration: .07s;   /* 누를 땐 빠르게 / 뗄 땐 위 .3s 스프링으로 통통 복귀 */
}

@media (prefers-reduced-motion: reduce){
  /* 모션 줄이기 = 누름 scale 전면 제거(none). 이 블록이 가장 뒤라 앞 블록(:1662)·전역 * duration 가드와
     충돌 없이 최종값을 잡는다. (* 가드는 duration 만 0 으로 만들 뿐 transform 값은 안 지우므로 여기서
     transform:none 을 명시해야 실제로 안 움직임.) 버튼 패밀리 전체 커버 — 누락 버튼이 즉시 스냅하던 것 해소. */
  body :is(.btn,.btn-primary,.btn-ghost,.fab,.chip,.icon-btn,.post-act,.back-btn,.row-quick,.sort-btn,
           .say-hi,.top-action-btn,.pf-edit-btn,.pf-settings-entry,.composer-send,.csend,.notif-fbtn,
           .pl-rec-cta,.scroll-down,.rnd-chat,.rnd-call,.rnd-continue-btn,.like-btn,.cmt-like,.cmt-reply-btn,
           .reply-toggle):active{
    transform: none; transition-duration:.08s;
  }
}

/* ── 버튼 디자인 언어 통일 ("저장 버튼" 기준): 모양·높이·굵기·라운드·focus 공유, 색만 역할별 3톤 ── */
/* 1) 공통 베이스 */
body :is(.btn, .btn-primary, .btn-ghost, .fab, .chip, .icon-btn, .sort-btn,
         .row-quick, .say-hi, .top-action-btn, .pf-edit-btn, .pf-settings-entry) {
  border-radius: 999px;
  font-family: inherit;
  font-weight: 600;
  font-size: 14px;
  letter-spacing: -.01em;
  -webkit-tap-highlight-color: transparent;
}
/* 높이: 기본 40 / 작은 칩·인라인 32. (.icon-btn 은 텍스트 버튼이라 정원 대신 알약 40 — 글자 안 잘리게) */
body :is(.btn, .btn-primary, .btn-ghost, .pf-edit-btn, .icon-btn) { height: 40px; padding: 0 18px; }
body :is(.chip, .sort-btn, .say-hi) { height: 32px; padding: 0 14px; font-size: 13px; }
/* 컴팩트 버튼 — 헤더 우측 CTA·인라인 액션(34px). 과거 JS 인라인 지오메트리 문자열을 클래스로 대체(드리프트 방지).
   .push-right = flex 헤더에서 우측 정렬. .btn-sm = 댓글 편집 등 더 좁은 패딩(14). */
body .btn.btn-compact { width: auto; height: 34px; padding: 0 16px; flex-shrink: 0; }
body .btn.btn-compact.push-right { margin-left: auto; }
body .btn.btn-sm { height: 34px; padding: 0 14px; }
/* 원형 아이콘 버튼은 정원 40 (.icon-btn 제외 — 위에서 알약 처리) */
body :is(.top-action-btn, .row-quick, .fab) { width: 40px; height: 40px; padding: 0; border-radius: 50%; }

/* 2) 역할별 색 톤 */
/* (a) 주요 = 강조색 채움 (저장·보내기). FAB(모먼트 작성)은 제외 — 위 "FAB = 액센트 틴트 글래스 원형"
   규칙으로 가라앉힌다(솔리드 그라데이션·컬러 글로우가 모먼트에서 시선을 너무 뺏어서). 다크에서만 유리로
   바뀌고, 라이트·모노 FAB 은 이미 html[data-theme] 규칙이 거의 불투명으로 고정(가독성) — 그대로. */
body .btn-primary {
  background: var(--accent-grad); color: #fff; border: none;
  box-shadow: 0 6px 16px -10px color-mix(in srgb, var(--accent) 70%, transparent), inset 0 1px 0 rgba(255,255,255,.22);
}
/* (b) 보조 = 글래스 알약. 배경·보더를 텍스트색 틴트(color-mix)로 → 다크는 흰끼, 라이트·모노는 검정끼로 자동(테마별 색만). */
body :is(.btn-ghost, .chip, .sort-btn, .say-hi, .icon-btn, .row-quick, .top-action-btn, .pf-settings-entry) {
  background: color-mix(in srgb, var(--text) 6%, transparent);
  border: 1px solid color-mix(in srgb, var(--text) 12%, transparent);
  color: var(--text-dim);
}
/* 버튼류 hover 재색칠도 실제 포인터에서만 — 터치에선 탭 후 색이 들러붙음(:active 누름 피드백은 유지). */
@media (hover: hover) and (pointer: fine) {
  body :is(.btn-ghost, .chip, .sort-btn, .say-hi, .icon-btn, .row-quick):hover {
    background: color-mix(in srgb, var(--text) 11%, transparent); color: var(--text);
  }
}
/* 위험(신고 등)은 빨강 유지 */
body .icon-btn.danger { color: var(--danger, #e2574c); }
/* 텍스트 버튼 위험(로그아웃·삭제·차단) — JS 인라인 color 대신 클래스로. --danger 는 3테마 정의됨. */
body .btn.danger { color: var(--danger, #e2574c); }
/* 선택된 칩만 강조색 틴트 (라이트·모노 baseline — 평면 accent 틴트 + accent 글자) */
body .chip.on { background: color-mix(in srgb, var(--accent) 16%, transparent); border-color: color-mix(in srgb, var(--accent) 40%, transparent); color: var(--accent-strong, var(--accent)); }
/* 선택칩 추천 버전(다크 전용) — 핸드오프 chip-recommended: accent 26% 틴트 글래스 + accent-strong 보더 +
   흰 글자 + 소프트 글로우 + 안쪽 하이라이트 → on/off 또렷. (글로우/글래스는 다크 전용, 라이트·모노는 위 baseline.) */
html[data-theme="dark"] body .chip.on {
  background: color-mix(in srgb, var(--accent) 26%, transparent);
  border-color: var(--accent-strong);
  color: #fff;
  box-shadow: var(--glow-soft), inset 0 1px 0 rgba(255, 255, 255, .18);
}
/* 알림 필터(전체·좋아요·댓글·팔로우) 칩만 라벨 대비 ↑(흰색). 모먼트 정렬·파트너 '내 언어' 칩은
   기본 톤(흐린 회색 var(--text-dim), 선택칩은 accent)으로 되돌림 — 사용자 요청. */
body .chip.notif-seg,
body .chip.notif-seg.on {
  color: var(--text, var(--ink, #fff));
}

/* 파트너 '내 언어' · 모먼트 정렬 · 채팅 필터(전체/안 읽음) 칩 = 프로필 박스(.pf-block)와 같은 다크 틴트 프로스티드 글래스
   — 글래스 타입만 교체(알약 모양·높이 유지). 선택칩(.on)은 기존 accent 틴트로 구분하므로 :not(.on) 에만.
   라이트·모노는 흰 틴트(색만 테마별, blur18·saturate150 동일). */
body #panel-partners > .chips .chip:not(.on),
body #panel-moments > .chips .chip:not(.on),
body #panel-chats > .chips .chip:not(.on) {
  background: rgba(12,13,20,.52);
  border: 1px solid rgba(255,255,255,.14);
  box-shadow: inset 0 1px 0 rgba(255,255,255,.09);
  -webkit-backdrop-filter: blur(18px) saturate(150%);
          backdrop-filter: blur(18px) saturate(150%);
}
[data-theme="light"] body #panel-partners > .chips .chip:not(.on),
[data-theme="light"] body #panel-moments > .chips .chip:not(.on),
[data-theme="light"] body #panel-chats > .chips .chip:not(.on),
[data-theme="mono"]  body #panel-partners > .chips .chip:not(.on),
[data-theme="mono"]  body #panel-moments > .chips .chip:not(.on),
[data-theme="mono"]  body #panel-chats > .chips .chip:not(.on) {
  background: rgba(255,255,255,.07);
  border-color: rgba(255,255,255,.12);
  box-shadow: inset 0 1px 0 rgba(255,255,255,.14);
}

/* 3) focus 통일 (강조색 링) */
body :is(.btn, .btn-primary, .btn-ghost, .fab, .chip, .icon-btn, .sort-btn, .row-quick):focus-visible {
  outline: none;
  box-shadow: 0 0 0 4px color-mix(in srgb, var(--accent) 14%, transparent);
}

/* ── 상대 프로필: 컴팩트 플랫 (카드 없음, 스탯 구분선 없음) ── */
body .pf-view .pf-hero {
  display: flex; flex-direction: column; align-items: center; text-align: center;
  gap: 6px; padding: 8px 0 14px;
}
body .pf-view .pf-hero .profile-name { margin-top: 6px; }
body .pf-view .pf-hero .pf-pair { font-size: 14px; }

/* 스탯바: 3등분 균등, 위·아래/스탯끼리 어떤 구분선도 없음 */
body .pf-view .pf-statbar {
  display: flex; width: 100%;
}
body .pf-view .pf-statbar .pf-stat {
  flex: 1; padding: 13px 0; border: none;     /* ← 세로 구분선 없음 */
}

/* 액션 행: 팔로우(좌) + 메시지 보내기(우) 를 스탯바 아래 한 줄 50/50. 둘 다 .pf-edit-btn 인디고 CTA,
   .btn 공통 높이(40px)라 별도 지정 없이 같은 높이로 정렬됨. */
body .pf-view .pf-actions.pf-actions-2 {
  flex-direction: row;
  gap: 10px;
  margin-top: 14px;
}
body .pf-view .pf-actions.pf-actions-2 > .btn {
  flex: 1; min-width: 0; padding: 0;
}

/* 정보 섹션: 납작한 행 + 행 사이 헤어라인 */
body .pf-view .pf-sections { display: flex; flex-direction: column; margin-top: 6px; }
body .pf-view .pf-srow {
  display: flex; flex-direction: column; gap: 8px; padding: 15px 2px;
}
body .pf-view .pf-srow + .pf-srow {
  border-top: 1px solid var(--line, rgba(255,255,255,.06));
}
/* 짧은 섹션: 라벨 왼쪽 + 값 오른쪽 한 줄 */
body .pf-view .pf-srow-inline {
  flex-direction: row; align-items: center; gap: 12px;
}
body .pf-view .pf-srow-inline > :last-child { margin-left: auto; }

/* ── 프로필 편집: 사진 헤더 = 커버 배너 ── */
/* 사진 카드(편집 리스트의 첫 섹션)는 풀블리드 커버를 위해 패딩 제거 + 모서리 클립 */
body .pf-edit-list .edit-sec:first-child {
  padding: 0;
  overflow: hidden;
  /* overflow:hidden 이 flex item 의 자동 min-height:auto 를 0 으로 풀어버려,
     스크롤(flex column) 리스트에서 이 카드가 보더만 남고 찌그러지는 것 방지 */
  flex-shrink: 0;
}
body .pf-edit-list .edit-sec:first-child .profile-head {
  padding: 0 0 20px;
  gap: 0;
  width: 100%;
}
/* 오로라 커버 띠 */
body .pf-photo-cover {
  width: 100%;
  height: 96px;
  background:
    radial-gradient(60% 120% at 25% 10%, rgba(170,142,255,.55), transparent 60%),
    radial-gradient(70% 130% at 85% 30%, rgba(255,150,210,.42), transparent 62%),
    linear-gradient(120deg, #2b2350, #1b1736);
}
/* 아바타가 커버에 반쯤 걸침 */
body .pf-photo-avwrap {
  position: relative;
  width: 96px;
  margin: -50px auto 0;
}
body .pf-photo-avwrap .avatar {
  box-shadow:
    inset 0 0 0 1px rgba(255,255,255,.16),
    0 8px 22px -8px rgba(0,0,0,.7),
    0 0 0 4px var(--bg, #0c0d12);   /* 카드 본문과 분리되는 링 */
}
/* 카메라 뱃지 */
body .pf-cam {
  position: absolute; right: -2px; bottom: -2px;
  width: 34px; height: 34px; border-radius: 50%;
  display: grid; place-items: center; color: #fff; border: none; cursor: pointer; padding: 0;
  background: var(--accent-grad, linear-gradient(135deg,#8a73ff,#5f8bff));
  box-shadow:
    0 6px 16px -6px color-mix(in srgb, var(--accent) 80%, transparent),
    inset 0 1px 0 rgba(255,255,255,.3),
    0 0 0 3px var(--bg, #0c0d12);
}
body .pf-cam svg { width: 17px; height: 17px; }
/* 이름 */
body .pf-photo-name { margin-top: 12px; font-size: 18px; font-weight: 700; text-align: center; }

/* 피드의 모먼트 카드 — 카드 전체가 탭 영역(누르면 상세). 누름 피드백은 파트너·채팅 행과 동일한
   소프트 프레스: 카드 전체가 살짝 축소(스프링 복귀) + 투명 선택 틴트(테마 적응형).
   단, 내부 버튼·프로필 링크·수정 입력을 누를 땐 :has 로 카드 프레스를 억제 → "다른 버튼 제외"
   (행의 :has(.row-quick:active) 와 동일 패턴). */
body .post.post-open {
  cursor: pointer;
  transform-origin: center;
  -webkit-tap-highlight-color: transparent;
  transition: transform .26s cubic-bezier(.34, 1.56, .4, 1);
}
body .post.post-open:active {
  transform: scale(.9776);     /* 누름 피드백 = 스쿼시만(유리 면은 그대로 — 흰 틴트가 다크 글래스를 깨서 제거) */
  transition: transform .08s ease;
}
body .post.post-open:has(:is(button, .pf-link, .post-edit):active) {
  transform: none; transition: none;   /* 내부 버튼 누름엔 카드 스쿼시 끔 */
}
@media (prefers-reduced-motion: reduce) {
  body .post.post-open,
  body .post.post-open:active { transition: none; transform: none; }
}

/* ══ 알림 화면(#screen-notifications) 리디자인: 필터 칩(F) + 타입 배지·시간 그룹(B) ══
   색은 4색(#ff5d8f 하트 / --accent 댓글 / #f5b301 팔로우 / --online 인사) + 기존 토큰만. */

/* 필터 칩 줄 — 헤더 바로 아래 고정 밴드(스크롤 안 됨). 칩은 기존 .chip / .chip.on 재사용. */
body .notif-segs {
  flex: none; display: flex; gap: 8px; padding: 6px 16px 12px;
  overflow-x: auto; -webkit-overflow-scrolling: touch;
}
body .notif-segs::-webkit-scrollbar { width: 0; height: 0; }
body .notif-seg { flex: none; display: inline-flex; align-items: center; gap: 6px; }
body .notif-seg-cnt { font-size: 11px; font-weight: 700; font-variant-numeric: tabular-nums; opacity: .65; }
body .notif-seg.on .notif-seg-cnt { opacity: .9; }

/* 시간 그룹 헤더 */
body .notif-grp { padding: 14px 4px 6px; font-size: 12px; font-weight: 700; color: var(--text-faint); letter-spacing: .02em; }

/* 행 — .list-row 재사용(소프트 프레스 유지, 구분선은 .notif-list 규칙이 이미 제거).
   고정 72px 높이를 풀어 댓글 미리보기 줄까지 담고, 좌우 인셋은 screen-list(16px)에 4px만 더함. */
body .notif-row { height: auto; padding: 11px 4px; gap: 13px; align-items: center; }
body .notif-row.unread { background: color-mix(in srgb, var(--accent) 7%, transparent); }
body .notif-row:hover { background: color-mix(in srgb, var(--text) 3%, transparent); }
body .notif-row.unread:hover { background: color-mix(in srgb, var(--accent) 10%, transparent); }
body .notif-list .notif-grp.hide,
body .notif-list .notif-row.hide { display: none; }

/* 아바타 + 타입 배지 — avx 는 아바타 크기로 딱 맞춤(display:flex).
   block 이면 inline-flex 아바타의 라인-스트럿 때문에 box 가 64px(아바타+20)로 커져
   bottom:-3px 배지가 아바타 밑으로 떨어졌었음 → flex 로 라인박스 제거해 44px 로 수축. */
body .notif-avx { position: relative; flex: none; display: flex; }
body .notif-tb {
  position: absolute; right: -3px; bottom: -3px; width: 20px; height: 20px; border-radius: 50%;
  display: grid; place-items: center; border: 2.5px solid var(--bg); color: #fff;
}
body .notif-tb svg { width: 12px; height: 12px; display: block; }
/* 모디파이어는 'tb-' 네임스페이스(notify.js BADGE_CLS) — 옛 .cmt/.like 등은
   무관한 전역 클래스(.cmt=댓글 행)와 충돌해 배지 position 을 덮었음. */
body .notif-tb.tb-like { background: #ff5d8f; }
body .notif-tb.tb-cmt  { background: var(--accent); }
body .notif-tb.tb-fol  { background: #f5b301; }
body .notif-tb.tb-hi   { background: var(--online); }

/* 본문(닉네임 + 동작 + 미리보기 + 시간) */
body .notif-meta { flex: 1; min-width: 0; }
body .notif-tx { font-size: 14.5px; line-height: 1.45; }
body .notif-nm { font-weight: 700; color: var(--text); }
body .notif-vb { color: var(--text-dim); font-weight: 400; }
body .notif-qt {
  font-size: 12.5px; color: var(--text-dim); margin-top: 3px; line-height: 1.4;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
body .notif-tm { font-size: 11.5px; color: var(--text-faint); margin-top: 3px; font-variant-numeric: tabular-nums; }

/* 오른쪽 — 안읽음 점 / 맞팔로우 버튼 / (이미지 있을 때만) 썸네일 */
body .notif-dot {
  flex: none; width: 8px; height: 8px; border-radius: 50%; background: var(--accent);
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--accent) 18%, transparent);
}
body .notif-thumb {
  flex: none; width: 44px; height: 44px; border-radius: 11px;
  background-size: cover; background-position: center; border: 1px solid var(--line-strong);
}
body .notif-fbtn {
  flex: none; font-size: 12px; font-weight: 650; padding: 8px 14px; border-radius: 999px; cursor: pointer;
  /* 1차 CTA fill 통일 = 그라데이션 (맞팔로우). 다크 전용 토큰 → 라이트·모노 폴백 그라데이션. */
  background: var(--accent-grad, linear-gradient(135deg, var(--accent), var(--accent-strong, var(--accent))));
  color: #fff; white-space: nowrap; border: none;
  transition: transform var(--dur-fast) var(--ease-out), filter var(--dur-fast) var(--ease-out);
}
body .notif-fbtn:active { transform: scale(.94); }
body .notif-fbtn.done {
  background: color-mix(in srgb, var(--text) 7%, transparent); color: var(--text-dim); border: 1px solid var(--line-strong);
}

/* 빈 상태 */
body .notif-empty { display: none; flex-direction: column; align-items: center; gap: 8px; padding: 80px 30px; text-align: center; }
body .notif-empty.show { display: flex; }
body .notif-empty-ic {
  width: 54px; height: 54px; border-radius: 50%; display: grid; place-items: center;
  background: color-mix(in srgb, var(--text) 5%, transparent); color: var(--text-faint);
}
body .notif-empty-ic svg { width: 26px; height: 26px; }
body .notif-empty-t { font-size: 14px; color: var(--text-dim); font-weight: 500; }

/* ── 모먼트 사진 그리드 (피드 카드, 표시 전용) ─────────────────────────────
   renderPost 의 post-body 아래·post-actions 위. 사진 개수(data-n=1~4)에 따라 자동.
   gap 3px / radius 14px / 1px 헤어라인 보더 / 타일 object-fit:cover. 3테마 공통(색 토큰만 분기). */
body .post-media {
  display: grid;
  gap: 3px;
  margin-top: var(--sp-3);
  border-radius: 14px;
  overflow: hidden;
  border: 1px solid var(--line-strong);
  cursor: pointer;
}
body .post-media .pm-tile {
  position: relative;
  overflow: hidden;
  min-width: 0;
  min-height: 0;
  background: color-mix(in srgb, var(--text) 6%, var(--bg)); /* 로딩 중 플레이스홀더 */
}
body .post-media .pm-tile img {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
}

/* n=1: 단일, 가로 꽉 채우고 4:3 */
body .post-media[data-n="1"] { grid-template-columns: 1fr; aspect-ratio: 4 / 3; }

/* n=2: 2열 1행, 각 칸 정사각 (컨테이너 2:1 → 칸 높이 = (폭-gap)/2) */
body .post-media[data-n="2"] { grid-template-columns: 1fr 1fr; aspect-ratio: 2 / 1; }

/* n=3: 모자이크 — 왼쪽 1칸이 세로 2행 span(1.3fr) + 오른쪽 2칸 세로 스택 */
body .post-media[data-n="3"] {
  grid-template-columns: 1.3fr 1fr;
  grid-template-rows: 1fr 1fr;
  aspect-ratio: 1 / 1;
}
body .post-media[data-n="3"] .pm-tile:first-child { grid-row: 1 / 3; grid-column: 1; }

/* n>=4: 2×2 정사각 그리드 — 컨테이너 정사각(aspect-ratio:1) → 각 타일도 정사각 */
body .post-media[data-n="4"] {
  grid-template-columns: 1fr 1fr;
  grid-template-rows: 1fr 1fr;
  aspect-ratio: 1 / 1;
}

/* 5장 이상: 4번째 타일에 "+N" 반투명 스크림(사진 위 가독용 흰 글자) */
body .post-media .pm-more {
  position: absolute;
  inset: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  background: rgba(0, 0, 0, 0.46);
  color: #fff;
  font-size: 22px;
  font-weight: 600;
  letter-spacing: -0.01em;
}

/* 랜덤 종료 후 '채팅에서 이어가기' CTA (랜덤 메시지 영역에 삽입). 알림 CTA(.notif-fbtn)와 동일 톤. */
body .rnd-continue { display: flex; justify-content: center; padding: 12px 0 4px; }
body .rnd-continue button {
  font-size: 13.5px; font-weight: 600; padding: 9px 18px; border-radius: 999px; cursor: pointer;
  /* 1차 CTA fill 통일 = 그라데이션. 다크 전용 토큰 → 라이트·모노 폴백 그라데이션. */
  background: var(--accent-grad, linear-gradient(135deg, var(--accent), var(--accent-strong, var(--accent))));
  color: #fff; border: none; white-space: nowrap;
  transition: transform var(--dur-fast) var(--ease-out), filter var(--dur-fast) var(--ease-out);
}
body .rnd-continue button:active { transform: scale(.95); }

/* 모먼트 글쓰기 FAB 아이콘(네모+연필 SVG). '+' 글리프용 font-size 는 SVG엔 무의미 → 크기 명시.
   색은 stroke=currentColor → .fab 의 color:#fff 를 따름(새 색 없음). 이 FAB 하나만(탭바 + 아이콘 무관). */
body .fab svg { width: 24px; height: 24px; display: block; }
/* FAB 원형 버튼만 살짝 키움(40→52). row-quick·top-action-btn(line 1679 그룹)은 그대로 — 이 규칙이 뒤라 FAB만 덮음. 3테마 공통. */
body .fab { width: 52px; height: 52px; display: flex; align-items: center; justify-content: center; } /* 센터링 hoist: mono.css 의 .fab 는 align/justify 누락 → 아이콘 좌상단 쏠림이었음. 3테마 공통 보정. */

/* ══ 모먼트 카드: 작성 언어 칩 + 번역 보기/박스 (시안 B · 언어·번역 강조) ══
   색은 기존 토큰만(accent/accent-strong/text). post-head 아래·본문 위에 칩, 본문 아래에 번역. */
body .post-langtag {
  display: inline-flex; align-items: center; gap: 5px;
  margin: 0 0 8px; padding: 3px 9px; border-radius: 999px;
  background: color-mix(in srgb, var(--accent) 12%, transparent);
  color: var(--accent-strong); font-size: 12px; font-weight: 600; line-height: 1;
}
body .post-langtag svg { width: 13px; height: 13px; flex: none; }

/* ══ 모먼트 카드 — 작성자 바이라인(조연): 아바타30 + "이름 · 시간" 회색 한 줄. 본문이 주인공 ══
   (이전 .post-head = 파트너 행 판박이라 "사람 목록"처럼 읽힘 → 바이라인으로 낮춤.)
   색은 토큰만(테마별 자동 적응), 비색상 지오메트리는 3테마 공통이라 여기 한 곳에. */
.post-byline { display: flex; align-items: center; gap: 9px; margin-bottom: 12px; }
.by-name { flex: 0 1 auto; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
  font-size: 13px; font-weight: 600; letter-spacing: -0.01em; color: var(--text, var(--ink, #fff)); }
.by-sep { flex: none; font-size: 13px; opacity: .6; color: var(--text-faint, var(--ink-3, #7c7f93)); }
.by-time { flex: none; white-space: nowrap; font-size: 12px; font-variant-numeric: tabular-nums;
  color: var(--text-faint, var(--ink-3, #7c7f93)); }
/* 작성 언어칩을 바이라인 우측 끝으로(작게) — 기존 .post-langtag 하단 margin 제거 */
.post-langtag.byline-chip { margin: 0 0 0 auto; flex: none; }

/* ══ 모먼트 "피드" 카드 = 떠 있는 둥근 카드(간격+radius18) — 시안 개선안 ══
   파트너·채팅은 납작한 행, 모먼트는 머무는 콘텐츠라 카드로 구분(레버1). 여긴 지오메트리만(3테마 공통);
   유리(면·보더·블러(18)·inset 하이라이트)는 프로필 박스(.pf-block)와 동일 규칙 공유 — 위쪽 "다크 틴트
   프로스티드 글래스" 블록 참고. 상세(.moment-detail .post)는 평평 유지(댓글 구분선 보존). */
body .moments-feed > .post {
  margin: 10px 14px;
  padding: 16px;
  border-radius: 18px;
}

body .post-tr-wrap { margin-top: 8px; }
body .post-tr-link {
  background: none; border: none; padding: 0; cursor: pointer; font-family: inherit;
  font-size: 13px; font-weight: 600; color: var(--accent-strong);
}
body .post-tr-link:active { opacity: .7; }
body .post-tr-box {
  margin-top: 8px; padding: 10px 12px; border-radius: 12px;
  background: color-mix(in srgb, var(--text) 3.5%, transparent);
}
body .post-tr-label {
  font-size: 11px; font-weight: 700; letter-spacing: .02em; color: var(--text-faint); margin-bottom: 4px;
}
body .post-tr-text { font-size: 14px; line-height: 1.55; color: var(--text); white-space: pre-wrap; word-break: break-word; }

/* ══ 랜덤 매칭: 수락 전 프로필 확인 카드(#random-review) ══
   매칭되면 바로 시작하지 않고 상대 프로필을 보여주고 양쪽 수락 시 시작. 기존 토큰만 사용. */
body #random-review { overflow-y: auto; }
body .rnd-review-title { font-size: 20px; font-weight: 700; letter-spacing: -.02em; }
body .rnd-review-sub { margin-top: 6px; font-size: 13.5px; color: var(--text-dim); }
body .rnd-review-sub b { color: var(--text); font-weight: 600; }
body .rnd-review-card {
  margin-top: 20px; width: 100%; max-width: 320px;
  display: flex; flex-direction: column; align-items: center; gap: 9px;
  padding: 22px 18px; border-radius: 20px;
  background: color-mix(in srgb, var(--text) 4%, transparent);
  border: 1px solid var(--line);
}
body .rnd-review-card .avatar {
  box-shadow: 0 0 0 4px var(--bg), inset 0 0 0 1px color-mix(in srgb, var(--text) 14%, transparent);
}
body .rrc-name { font-size: 19px; font-weight: 700; letter-spacing: -.02em; }
body .rrc-meta { margin-top: -3px; font-size: 12.5px; color: var(--text-faint); }
body .rrc-langs { display: flex; flex-wrap: wrap; gap: 6px; justify-content: center; }
body .rrc-bio { margin-top: 3px; font-size: 13.5px; line-height: 1.5; color: var(--text-dim); text-align: center; }
body .rrc-tags { display: flex; flex-wrap: wrap; gap: 6px; justify-content: center; margin-top: 3px; }
body .rrc-tag {
  font-size: 11.5px; font-weight: 600; padding: 4px 10px; border-radius: 999px;
  background: color-mix(in srgb, var(--accent) 12%, transparent); color: var(--accent-strong);
}
body .rnd-review-status { margin-top: 14px; font-size: 13px; font-weight: 600; color: var(--accent-strong); }
body .rnd-review-actions { margin-top: 18px; display: flex; gap: 10px; width: 100%; max-width: 320px; }
/* 랜덤 빈 상태(no_match) 액션 — 파트너 찾기(1차)·계속 매칭(2차) 세로 스택. */
body .rnd-nomatch-actions { margin-top: 16px; display: flex; flex-direction: column; gap: 10px; width: 100%; max-width: 300px; }
body .rnd-nomatch-actions .btn { width: 100%; }
/* 온라인 인디케이터 초록불 — 랜덤 홈 "N명 온라인" 앞 점(+소프트 헤일로). 색은 presence 토큰 --online.
   flex 로 점·텍스트 수직 중앙 정렬(vertical-align 어긋남 방지). 0명이면 회색(.off, 헤일로 없음). */
body .online { display: flex; align-items: center; justify-content: center; }
body .online .online-led {
  display: inline-block; width: 7px; height: 7px; border-radius: 50%;
  margin-right: 6px;
  background: var(--online, #34d77f);
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--online, #34d77f) 22%, transparent);
}
body .online .online-led.off { background: var(--text-faint, #8a8d9a); box-shadow: none; }
/* B2-b: 첨부 트레이(사진/번역/음성)·여는 + 버튼 미구현(탭하면 no-op) → 어포던스 숨김. 실제 기능 붙으면 이 줄 삭제.
   (+버튼은 body .composer .composer-plus(1294) 가 display 지정 → 같은 구체도·뒤 순서로 덮음.) */
body .composer-tray, body .composer .composer-plus { display: none; }
body #rnd-accept { flex: 1; height: 46px; }
body #rnd-decline { flex: 0 0 auto; height: 46px; padding: 0 22px; }

/* ════════ 모먼트 상세: 댓글 / 대댓글 (시안 v3) ════════ */
body { --like: #ff5d8f; }   /* 댓글 하트(시안) — 앱 토큰에 없어 한 곳에서 정의 */

/* 폭 꽉 채움: 스크롤 컨테이너의 좌우 패딩 제거(요소 자체 패딩 18로만 인셋 — 시안과 동일, 이중 패딩 해소) */
body .moment-detail { padding-left: 0; padding-right: 0; }
body .moment-detail .post { padding-left: 18px; padding-right: 18px; }

/* 액션줄 ↔ 댓글 구분선은 .post 의 border-bottom 하나로(별도 .hr 줄 없음 — 이중선 방지) */
body .moment-detail .cmt-head { display: flex; align-items: center; gap: 8px; padding: 15px 18px 4px; }
body .moment-detail .cmt-head .ct { font-size: 13.5px; font-weight: 700; color: var(--text); }
body .moment-detail .cmt-head .cc { font-size: 13.5px; font-weight: 700; color: var(--accent-strong, var(--accent)); }

body .comments-list { display: flex; flex-direction: column; }
body .comments-list .cmt-empty { padding: 18px; font-size: 13.5px; }

/* 스레드(최상위 + 답글). 댓글 사이는 선 없이 여백만. */
body .thread { padding: 12px 18px; }
body .cmt { display: flex; gap: 11px; position: relative; }
body .cmt .meta { flex: 1; min-width: 0; }
body .crow { display: flex; align-items: center; gap: 7px; flex-wrap: wrap; }
body .cnm { font-size: 12.5px; font-weight: 650; color: var(--text); }
body .dotm { font-size: 11px; color: var(--text-faint, var(--text-dim, #8a8a96)); }
body .dotm::before { content: "·"; margin-right: 7px; }
body .author-tag { font-size: 9px; font-weight: 700; color: var(--accent-strong, var(--accent)); padding: 1.5px 6px; border-radius: 999px;
  background: color-mix(in srgb, var(--accent) 14%, transparent); }
body .ctx { font-size: 13.5px; line-height: 1.5; color: var(--text-dim, var(--ink-2, #8a8a96)); margin-top: 3px; white-space: pre-wrap; word-break: break-word; }

/* 푸터: 하트 · 답글 한 줄. 하트 0이면 숫자 숨김, 누르면 핑크 채움. */
body .cfoot { display: flex; align-items: center; gap: 18px; margin-top: 8px; }
body .clike { display: inline-flex; align-items: center; gap: 5px; cursor: pointer; user-select: none; -webkit-tap-highlight-color: transparent;
  color: var(--text-faint, var(--text-dim, #8a8a96)); font-size: 11.5px; font-weight: 600; font-variant-numeric: tabular-nums; }
body .clike svg { width: 15px; height: 15px; }
body .clike .n:empty { display: none; }
body .clike.on { color: var(--like); }
body .clike.on svg { fill: var(--like); stroke: var(--like); }
body .clike:active { transform: scale(var(--press-strong)); } /* .9 → 토큰(.94) */
body .cbtn { font-size: 11.5px; font-weight: 600; cursor: pointer; user-select: none; -webkit-tap-highlight-color: transparent;
  color: var(--text-faint, var(--text-dim, #8a8a96)); }
body .cbtn:hover { color: var(--text-dim, var(--ink-2, #8a8a96)); }

/* ⋯ 메뉴 버튼 + 드롭다운 (한 번에 하나·바깥클릭/스크롤 닫힘은 JS) */
body .cmenu-btn { flex: none; width: 26px; height: 26px; display: grid; place-items: center; cursor: pointer; border-radius: 7px;
  margin-top: -2px; color: var(--text-faint, var(--text-dim, #8a8a96)); -webkit-tap-highlight-color: transparent; }
body .cmenu-btn:hover { color: var(--text-dim, var(--ink-2, #8a8a96)); background: color-mix(in srgb, var(--text, #fff) 5%, transparent); }
body .cmenu-btn svg { width: 18px; height: 18px; }
body .cmenu { position: absolute; right: 0; top: 26px; z-index: 20; min-width: 156px; display: none; flex-direction: column; padding: 5px;
  background: var(--card, var(--bg-elev, var(--bg))); border: 1px solid var(--line-strong, var(--line)); border-radius: 14px;
  box-shadow: 0 18px 44px -18px rgba(0,0,0,.6); transform-origin: top right; }
body .cmt.menu-open .cmenu { display: flex; animation: cmenu-pop .14s ease; }
@keyframes cmenu-pop { from { opacity: 0; transform: scale(.94); } to { opacity: 1; transform: none; } }
body .cmi { display: flex; align-items: center; gap: 11px; padding: 9px 11px; border-radius: 9px; cursor: pointer;
  font-size: 13px; font-weight: 500; color: var(--text-dim, var(--ink-2, #8a8a96)); }
body .cmi:hover { background: color-mix(in srgb, var(--text, #fff) 5%, transparent); color: var(--text); }
body .cmi svg { width: 16px; height: 16px; flex: none; }
body .cmi.danger { color: var(--danger, #ff6f7a); }
body .cmi.danger:hover { background: color-mix(in srgb, var(--danger, #ff6f7a) 12%, transparent); color: var(--danger, #ff6f7a); }
body .cmi-sep { height: 1px; background: var(--line); margin: 4px 6px; }

/* "답글 N개 보기" 토글 (옆 장식선 없음) */
body .more-replies { margin: 9px 0 2px 52px; font-size: 12px; font-weight: 600; cursor: pointer; -webkit-tap-highlight-color: transparent;
  color: var(--text-dim, var(--ink-2, #8a8a96)); display: inline-flex; align-items: center; gap: 9px; }
body .more-replies:hover { color: var(--accent-strong, var(--accent)); }

/* 대댓글 펼침 — grid 높이(콘텐츠 실제 높이에 정확히 맞아 끝에서 안 튐). 높이+opacity 만, transform/will-change/contain 금지. */
body .reply-wrap { display: grid; grid-template-rows: 0fr; opacity: 0; margin-left: 46px;
  transition: grid-template-rows .3s cubic-bezier(.2,.8,.2,1), opacity .2s ease; }
body .thread.open .reply-wrap { grid-template-rows: 1fr; opacity: 1; margin-top: 10px; }
body .reply-wrap > .replies { overflow: hidden; min-height: 0; display: flex; flex-direction: column; gap: 14px; }
@media (prefers-reduced-motion: reduce) { body .reply-wrap { transition: none; } }

/* 인라인 답글 입력박스 (.thread.replying) */
body .reply-box { display: none; margin: 11px 0 2px 39px; align-items: center; gap: 8px; }
body .thread.replying .reply-box { display: flex; }
body .reply-box .rinp { flex: 1; min-width: 0; height: 34px; border-radius: 999px; padding: 0 13px; font-size: 12.5px;
  color: var(--text); background: var(--bg-elev, var(--bg)); border: 1px solid var(--line-strong, var(--line)); }
body .reply-box .rgo { flex: none; background: none; border: none; cursor: pointer; font-size: 12px; font-weight: 700; color: var(--accent-strong, var(--accent)); }

/* 댓글 인라인 수정 */
body .cmt-edit { margin-top: 6px; display: flex; flex-direction: column; gap: 8px; }
body .cmt-edit input { width: 100%; }
body .cmt-edit-actions { display: flex; gap: 8px; justify-content: flex-end; }

/* 하단 고정 입력바 — 플랫(글래스 아님, CLAUDE 규칙) + 아바타 + 알약 입력 + 둥근 전송 */
body .moment-composer { flex: none; display: flex; align-items: center; gap: 9px; background: var(--bg);
  padding: 11px 16px calc(11px + var(--safe-bottom, 0px)); border-top: 1px solid var(--line); }
body .moment-composer .avatar { flex: none; }
body .moment-composer .cinp { flex: 1; min-width: 0; height: 40px; border-radius: 999px; padding: 0 16px; font-size: 13.5px;
  color: var(--text); background: var(--bg-elev, var(--bg)); border: 1px solid var(--line-strong, var(--line)); }
/* 전송 버튼 = .composer-send 와 동일 모델: 평소 중립 회색 → 입력 있을 때만 accent 점등(.has-text 는 form 에). */
body .moment-composer .csend { flex: none; width: 40px; height: 40px; border-radius: 50%; display: grid; place-items: center;
  background: color-mix(in srgb, var(--text, var(--ink, #fff)) 12%, transparent); color: var(--text-dim); border: none; cursor: pointer;
  transition: background var(--dur-fast) var(--ease-out), color var(--dur-fast) var(--ease-out), transform .08s ease; }
body .moment-composer.has-text .csend { background: var(--accent); color: #fff; }
body .moment-composer .csend svg { width: 18px; height: 18px; }
body .moment-composer .csend:active { transform: scale(.94); }

/* 신고 바텀시트 (.cmt-sheet) — 슬라이드 업 */
body .cmt-scrim { position: fixed; inset: 0; z-index: 60; background: rgba(0,0,0,.5); opacity: 0; transition: opacity .25s ease; }
body .cmt-scrim.on { opacity: 1; }
body .cmt-sheet { position: fixed; left: 0; right: 0; bottom: 0; z-index: 61; max-width: 390px; margin: 0 auto;
  background: var(--card, var(--bg-elev, var(--bg))); border-top: 1px solid var(--line-strong, var(--line)); border-radius: 24px 24px 0 0;
  padding: 0 0 calc(16px + var(--safe-bottom, 0px)); transform: translateY(100%); transition: transform .3s cubic-bezier(.2,.85,.25,1); }
/* 보임/숨김 transform 은 JS 가 인라인으로 제어(translateY 0 ↔ 100%) — 클래스 캐스케이드 의존 안 함 */
body .cmt-sheet .grab { width: 38px; height: 4px; border-radius: 999px; background: var(--line-strong, var(--line)); margin: 10px auto 4px; }
body .cmt-sheet .sh-title { font-size: 15px; font-weight: 700; padding: 10px 20px 2px; color: var(--text); }
body .cmt-sheet .sh-sub { font-size: 12px; color: var(--text-faint, var(--text-dim, #8a8a96)); padding: 0 20px 6px; line-height: 1.45; }
body .cmt-sheet .sh-opt { display: flex; align-items: center; gap: 12px; padding: 14px 20px; font-size: 14px; color: var(--text); cursor: pointer; }
body .cmt-sheet .sh-opt:hover { background: color-mix(in srgb, var(--text, #fff) 4%, transparent); }
body .cmt-sheet .sh-opt .chev { margin-left: auto; display: inline-flex; color: var(--text-faint, var(--text-dim, #8a8a96)); }
body .cmt-sheet .sh-opt .chev svg { width: 16px; height: 16px; }
body .cmt-sheet .sh-cancel { margin: 10px 16px 0; text-align: center; padding: 14px; border-radius: 13px; cursor: pointer; color: var(--text);
  background: color-mix(in srgb, var(--text, #fff) 6%, transparent); font-weight: 650; font-size: 14px; }

/* ── 하단 탭바 활성 강조: 채움 아이콘 토글 ──────────────────────────────────
   평소엔 아웃라인(.out), 활성 탭만 채움(.fillico) + 굵은 라벨 + 살짝 확대.
   다크에선 활성 글리프·라벨을 흰색으로(인디고 글래스 필 위 인디고 대비 문제 해결) + 필 한 단계 또렷.
   라이트·모노는 활성 색 그대로(흰색 강제 X) — 채움 글리프 전환만으로 강조. */
body .tabbtn .fillico { display: none; }
body .tabbtn.active .out { display: none; }
body .tabbtn.active .fillico { display: block; }
/* 활성 라벨 굵게 + 아이콘 살짝 확대(기존 .tabbtn.active .tabi translateY 유지하고 scale 만 합침) */
body .tabbtn.active { font-weight: 700; }
body .tabbtn.active .tabi { transform: translateY(-1px) scale(1.05); }
/* 다크 전용: 활성 글리프·라벨 흰색 + 슬라이더 필 또렷(.is-moving/.is-dragging 의 backdrop-filter:none 은 안 건드려 유지). */
html[data-theme="dark"] body .tabbtn.active { color: #fff; }
html[data-theme="dark"] body #tab-slider {
  background: color-mix(in srgb, var(--accent) 26%, transparent);
  border: 1px solid color-mix(in srgb, var(--accent-strong, var(--accent)) 50%, transparent);
  box-shadow: inset 0 1px 0 rgba(255,255,255,.24), 0 6px 18px -6px color-mix(in srgb, var(--accent) 70%, transparent);
}
