/* 기본 글꼴은 앱에 들어 있는 Pretendard(fonts.css), 자간은 --ls-base. 둘 다 설정 > 글꼴 설정에서 바꿀 수 있다(services/display-prefs.js). */
:root{--font-sys:'Pretendard Variable',system-ui,-apple-system,BlinkMacSystemFont,'Apple SD Gothic Neo','Malgun Gothic',sans-serif;--ls-base:-.03em;}
/* 홈 오늘의 질문 이름표 글자만 Pretendard SemiBold(OFL, assets/fonts/pretendard/LICENSE.txt). 제작자가 나눠 배포한 조각 중
   이름표 글자(오늘의 질문, 답변 완료!)가 든 것만 넣었다. 다른 글자는 기기 글꼴로 넘어간다. */
@font-face{font-family:"Pretendard";font-weight:600;font-display:swap;src:url("../fonts/pretendard/Pretendard-SemiBold.subset.87.woff2") format("woff2");unicode-range:U+23, U+25, U+5f, U+a9, U+ac08, U+ac78, U+aca8, U+acac, U+ace8, U+ad70, U+adc0, U+addc, U+b137, U+b140, U+b208, U+b290, U+b2f5, U+b3c5, U+b3cc, U+b420, U+b429, U+b529, U+b530, U+b77d, U+b79c, U+b7a8, U+b7c9, U+b7f0, U+b7fc, U+b828, U+b860, U+b9ad, U+b9c1, U+b9c9, U+b9dd-b9de, U+b9e8, U+ba38-ba39, U+babb, U+bc00, U+bc8c, U+bca0, U+bca4, U+bcd1, U+bcfc, U+bd09, U+bdf0, U+be60, U+c0ad, U+c0b4, U+c0bc, U+c190, U+c1fc, U+c220, U+c288, U+c2b9, U+c2f6, U+c528, U+c545, U+c558, U+c5bc, U+c5d4, U+c600, U+c644, U+c6c0, U+c6c3, U+c721, U+c798, U+c7a1, U+c811, U+c838, U+c871, U+c904, U+c990, U+c9dc, U+cc38, U+cc44, U+cca0, U+cd1d, U+cd95, U+cda9, U+ce5c, U+cf00, U+cf58, U+d150, U+d22c, U+d305, U+d328, U+d37c, U+d3f0, U+d551, U+d5a5, U+d5c8, U+d5d8, U+d63c, U+d64d, U+d669, U+d734, U+d76c;}
@font-face{font-family:"Pretendard";font-weight:600;font-display:swap;src:url("../fonts/pretendard/Pretendard-SemiBold.subset.88.woff2") format("woff2");unicode-range:U+26, U+2b, U+3e, U+40, U+7e, U+ac01, U+ac19, U+ac1d, U+aca0, U+aca9, U+acb0, U+ad8c, U+ae09, U+ae38, U+ae40, U+aed8, U+b09c, U+b0a0, U+b108, U+b204, U+b298, U+b2d8, U+b2eb-b2ec, U+b2f4, U+b313, U+b358, U+b450, U+b4e0, U+b54c, U+b610, U+b780, U+b78c, U+b791, U+b8e8, U+b958, U+b974, U+b984, U+b9b0, U+b9bc-b9bd, U+b9ce, U+ba70, U+bbfc, U+bc0f, U+bc15, U+bc1b, U+bc31, U+bc95, U+bcc0, U+bcc4, U+bd81, U+bd88, U+c0c8, U+c11d, U+c13c, U+c158, U+c18d, U+c1a1, U+c21c, U+c4f0, U+c54a, U+c560, U+c5b8, U+c5c8, U+c5f4, U+c628, U+c62c, U+c678, U+c6cc, U+c808, U+c810, U+c885, U+c88b, U+c900, U+c988, U+c99d, U+c9c8, U+cc3d-cc3e, U+cc45, U+cd08, U+ce20, U+cee4, U+d074, U+d0a4, U+d0dd, U+d2b9, U+d3b8, U+d3c9, U+d488, U+d544, U+d559, U+d56d, U+d588, U+d615, U+d648, U+d655, U+d658, U+d65c;}
@font-face{font-family:"Pretendard";font-weight:600;font-display:swap;src:url("../fonts/pretendard/Pretendard-SemiBold.subset.89.woff2") format("woff2");unicode-range:U+d, U+7c, U+ac10, U+ac15, U+ac74, U+ac80, U+ac83, U+acc4, U+ad11, U+ad50, U+ad6d, U+adfc, U+ae00, U+ae08, U+ae4c, U+b0a8, U+b124, U+b144, U+b178, U+b274, U+b2a5, U+b2e8, U+b2f9, U+b354, U+b370, U+b418, U+b41c, U+b4f1, U+b514, U+b798, U+b808, U+b824-b825, U+b8cc, U+b978, U+b9d0, U+b9e4, U+baa9, U+bb3c, U+bc18, U+bc1c, U+bc30, U+bc84, U+bcf5, U+bcf8, U+bd84, U+be0c, U+be14, U+c0b0, U+c0c9, U+c0dd, U+c124, U+c2dd, U+c2e4, U+c2ec, U+c54c, U+c57c-c57d, U+c591, U+c5c5-c5c6, U+c5ed, U+c608, U+c640, U+c6b8, U+c6d4, U+c784, U+c7ac, U+c800-c801, U+c9c1, U+c9d1, U+cc28, U+cc98, U+cc9c, U+ccad, U+cd5c, U+cd94, U+cd9c, U+cde8, U+ce68, U+cf54, U+d0dc, U+d14c, U+d1a0, U+d1b5, U+d2f0, U+d30c, U+d310, U+d398, U+d45c, U+d50c, U+d53c, U+d560, U+d568, U+d589, U+d604, U+d6c4, U+d788;}
@font-face{font-family:"Pretendard";font-weight:600;font-display:swap;src:url("../fonts/pretendard/Pretendard-SemiBold.subset.90.woff2") format("woff2");unicode-range:U+ac04, U+ac1c, U+ac70, U+ac8c, U+acbd, U+acf5, U+acfc, U+ad00, U+ad6c, U+adf8, U+b098, U+b0b4, U+b294, U+b2c8, U+b300, U+b3c4, U+b3d9, U+b4dc, U+b4e4, U+b77c, U+b7ec, U+b85d, U+b97c, U+b9c8, U+b9cc, U+ba54, U+ba74, U+ba85, U+baa8, U+bb34, U+bb38, U+bbf8, U+bc14, U+bc29, U+bc88, U+bcf4, U+bd80, U+be44, U+c0c1, U+c11c, U+c120, U+c131, U+c138, U+c18c, U+c218, U+c2b5, U+c2e0, U+c544, U+c548, U+c5b4, U+c5d0, U+c5ec, U+c5f0, U+c601, U+c624, U+c694, U+c6a9, U+c6b0, U+c6b4, U+c6d0, U+c704, U+c720, U+c73c, U+c740, U+c744, U+c74c, U+c758, U+c77c, U+c785, U+c788, U+c790-c791, U+c7a5, U+c804, U+c815, U+c81c, U+c870, U+c8fc, U+c911, U+c9c4, U+ccb4, U+ce58, U+ce74, U+d06c, U+d0c0, U+d130, U+d2b8, U+d3ec, U+d504, U+d55c, U+d569, U+d574, U+d638, U+d654, U+d68c;}
@font-face{font-family:"Pretendard";font-weight:600;font-display:swap;src:url("../fonts/pretendard/Pretendard-SemiBold.subset.91.woff2") format("woff2");unicode-range:U+20-22, U+27-2a, U+2c-39, U+3a-3b, U+3f, U+41-4e, U+4f-5d, U+61-7b, U+7d, U+a0-a1, U+ab, U+ad-ae, U+b7, U+bb, U+bf, U+2013-2014, U+201c-201d, U+2122, U+ac00, U+ace0, U+ae30, U+b2e4, U+b85c, U+b9ac, U+c0ac, U+c2a4, U+c2dc, U+c774, U+c778, U+c9c0, U+d558;}
:root{
  /* 디자인 토큰. 크로스 플랫폼 앱으로 옮길 때 이 값들을 그대로 가져간다(§design/tokens.json과 같은 값).
     색, 굵기, 글자 크기는 아래 토큰만 쓰고 새 숫자를 직접 적지 않는다. */
  /* 회색 단계: 모노는 무채색 브랜드라 이 12단계로 배경, 선, 글자를 모두 표현한다.
     450은 흐린 글자(--text-light) 전용이다. 400(#a3a3a3)은 흰 바탕에서 대비가 2.5:1이라 글자로는 너무 옅고, 어두운 카드 위 글자와 장식에만 쓴다. */
  --gray-0:#ffffff; --gray-50:#f6f6f7; --gray-100:#eeeeef; --gray-200:#e6e6e7; --gray-300:#d6d6da;
  --gray-400:#a3a3a3; --gray-450:#8a8a8a; --gray-500:#6c6c6c; --gray-600:#4a4a50; --gray-700:#2b2b2b; --gray-800:#1a1a1a; --gray-900:#000000;
  /* 굵기는 두 단계만 쓴다(§design/mono-tone-clean.md 원칙 8). 본문 400, 강조와 제목 600. */
  --fw-regular:400; --fw-bold:600;
  /* 글자 크기 단계. 26px 이상 큰 제목 몇 곳만 예외로 직접 적는다. 16px(--fs-xl)은 iOS 입력창 자동 확대를 막는 최소 크기다.
     모든 단계에 설정의 글꼴 크기 배율(--fs-scale, services/display-prefs.js)을 곱하되, --fs-xl은 작게 골라도 16px 아래로 내려가지 않는다. */
  --fs-scale:1;
  --fs-3xs:calc(9px * var(--fs-scale)); --fs-2xs:calc(10px * var(--fs-scale)); --fs-xs:calc(11px * var(--fs-scale)); --fs-sm:calc(12px * var(--fs-scale)); --fs-md:calc(13px * var(--fs-scale)); --fs-base:calc(14px * var(--fs-scale)); --fs-lg:calc(15px * var(--fs-scale));
  --fs-xl:max(16px, calc(16px * var(--fs-scale))); --fs-2xl:calc(17px * var(--fs-scale)); --fs-3xl:calc(20px * var(--fs-scale)); --fs-4xl:calc(22px * var(--fs-scale)); --fs-5xl:calc(24px * var(--fs-scale));
  /* 역할별 이름. 화면 코드는 되도록 이 이름을 쓴다. */
  --bg1:var(--gray-0); --bg2:var(--gray-50); --card:var(--gray-0);
  --primary:var(--gray-700); --primary-dark:var(--gray-900); --primary-soft:var(--gray-100); --primary-light:var(--gray-50);
  --pink:var(--gray-100); --pink-dark:var(--gray-800); --mint:var(--gray-100); --mint-dark:var(--gray-800);
  --yellow:var(--gray-100); --text:var(--gray-800); --text-mid:var(--gray-500); --text-light:var(--gray-450);
  --border:var(--gray-200); --danger:var(--gray-700);
  /* 알림(안 읽은 메시지) 전용 빨강. 모노톤 원칙의 예외: 의미가 분명한 알림에만 쓴다(§design/mono-tone-clean.md 2번) */
  --alert:#f2412f;
  --shadow:0 8px 20px rgba(30,30,36,.10);
  --shadow-sm:0 2px 8px rgba(30,30,36,.06); --shadow-pop:0 18px 40px -12px rgba(0,0,0,.42),0 2px 6px rgba(0,0,0,.12);
  --radius-full:999px; --radius-xl:26px; --radius:22px; --radius-lg:18px; --radius-xs:10px; --radius-2xs:4px; --radius-sm:14px;
  /* transitions-dev motion tokens (https://transitions.dev) — shared scale used by
     .notif-row, .mypage-card, .skeleton-avatar/.skeleton-bar, .toast, .center-modal below. */
  --duration-quick:150ms; --duration-fast:250ms; --duration-medium:350ms;
  --ease-smooth-out:cubic-bezier(.22,1,.36,1); --ease-linear:linear; --ease-bounce:cubic-bezier(.34,1.36,.64,1);
  /* docs/animation.md 3절의 곡선 이름. 예전에는 같은 값을 자리마다 손으로 적었다 */
  --ease-out:cubic-bezier(.23,1,.32,1); --ease-in-out:cubic-bezier(.77,0,.175,1); --ease-drawer:cubic-bezier(.32,.72,0,1);
  --modal-open-dur:250ms; --modal-close-dur:150ms; --modal-scale:.96;
  --toast-open:350ms; --toast-close:250ms; --toast-distance:16px; --toast-blur:2px; --toast-scale:.97;
  --resize-dur:300ms; --resize-ease:var(--ease-smooth-out);
  --shake-distance:6px; --shake-overshoot:4px; --shake-dur-a:80ms; --shake-dur-b:60ms; --shake-ease:var(--ease-smooth-out);
  /* transitions-dev "Page side-by-side"(08) 토큰. easing만 스킬 기본값
     (--page-slide-ease: cubic-bezier(.22,1,.36,1))이 아니라 이 프로젝트가 이미 실험 후
     확정한 cubic-bezier(.4,0,.2,1)을 그대로 쓴다 — 바로 아래 §wizContentSlideRight/Left
     주석에 그 경위가 적혀 있다(스킬 기본 이징으로 먼저 써봤다가 "쫀득함" 대신 "갑자기
     바뀐다"는 느낌이라 되돌린 이력). distance/blur는 스킬 값 그대로, duration은 사용자
     요청으로 스킬 기본값(250ms)의 2배로 더 느리고 부드럽게 늘렸다. */
  --page-slide-dur:500ms; --page-slide-distance:8px; --page-blur:3px;
  /* transitions-dev "Tooltip open/close"(17) 토큰 — §Notice 팝오버(.group-info-popover)에
     적용. 다만 스킬 원본은 호버로 여러 트리거를 오가며 한 줄짜리 말풍선이 "여행"하는
     구조라(트리거 그룹 공유, translate로 이동) 지금처럼 클릭으로 열고 X/바깥클릭/자동닫힘
     으로 닫히는 여러 줄 팝오버엔 이동(travel) 부분은 해당이 없다 — 그래서 이 프로젝트에
     실제로 맞는 부분만 그대로 가져온다: 뜰 때는 약간 지연 후 fade+scale로 부드럽게,
     닫을 때는 지연 없이 즉시 사라지는 비대칭 타이밍과 스케일 값(.98). */
  --tt-in-dur:150ms; --tt-out-dur:50ms; --tt-scale:.98; --tt-delay:80ms;
  --tt-in-ease:ease-out; --tt-out-ease:ease-out;
}
/* squircle(iOS 같은 부드러운 모서리). 같은 값이면 덜 둥글어 보여서 지원 브라우저에서만 반지름을 키워 체감 둥글기를 맞춘다. 미지원(사파리)은 기존 둥근 모서리 */
@supports (corner-shape:squircle){:root{--radius-xl:34px;--radius:29px;--radius-lg:24px;--radius-sm:18px;--radius-xs:13px;}}

*{box-sizing:border-box; -webkit-tap-highlight-color:transparent;}
/* 앱처럼: 누를 때 글자가 선택되거나 복사 메뉴가 뜨지 않게. 입력칸은 그대로 */
body{-webkit-user-select:none;user-select:none;-webkit-touch-callout:none;}
input,textarea,[contenteditable]{-webkit-user-select:text;user-select:text;-webkit-touch-callout:default;}
html,body{margin:0;padding:0;height:100%; overscroll-behavior-y:none;}
body{
  font-family:var(--font-sys); letter-spacing:var(--ls-base); font-weight:var(--fw-regular);
  background:linear-gradient(180deg,var(--bg1),var(--bg2) 60%);
  color:var(--text); min-height:100vh; min-height:100dvh;
  /* 한글 기본 줄바꿈은 음절 사이 아무 데서나 끊기는데, keep-all은 어절(단어) 단위로만 끊어서
     읽기 훨씬 자연스럽다. break-word는 한 단어가 그 자체로 박스보다 길 때(URL 등)의 보루. */
  word-break:keep-all; overflow-wrap:break-word;
}
#root{width:100%;max-width:480px;height:100dvh;min-height:0;margin:0 auto;position:fixed;left:50%;top:0;transform:translateX(-50%);overflow:hidden;background:linear-gradient(180deg,var(--bg1),var(--bg2) 60%);
  /* min-height used to be 100dvh ("dynamic" viewport height, which changes value the instant
     the mobile browser's address bar shows/hides). On a screen whose content is SHORTER than
     one viewport (마이페이지, 알림, 채팅 목록 — but not 홈, whose card list is already taller
     than the viewport and scrolls regardless), min-height:100dvh actively controls #root's box
     height. Any tap near the bottom of a short screen can trigger the browser chrome to
     show/hide, dvh recalculates, and #root's height changes with it — which reflows the
     flex:1 .main area and the sticky header, i.e. exactly the "탭 누르면 화면이 아래로 꺼지는"
     symptom, and only on the short screens. 100svh ("small" viewport height = the height with
     the browser chrome always assumed visible) never changes value, so it can't trigger this
     reflow at all; the only cost is some unused space at the very bottom on a tall phone once
     the chrome auto-hides, which is far less jarring than the whole layout visibly resettling. */
  box-shadow:0 0 40px rgba(30,30,36,.08); display:flex; flex-direction:column;}
button{font-family:inherit; letter-spacing:inherit; cursor:pointer;}
input,select,textarea{font-family:inherit; letter-spacing:inherit;}
/* 브라우저는 버튼과 입력창의 굵기를 normal로 되돌린다. 굵기 설정이 따라오게 본문 굵기를 준다(:where라 각 화면 지정이 우선). */
:where(button,input,select,textarea){font-weight:var(--fw-regular);}
.chat-markdown{min-width:0;overflow-wrap:anywhere;}
/* 채팅 사진. 세로로 긴 사진(낙서 릴레이 이야기)은 WhatsApp, 텔레그램처럼 위쪽만 보이게 자르고, 누르면 펼친다 */
.chat-img{display:block;padding:0;border:none;background:none;font:inherit;cursor:pointer;}
.chat-img img{display:block;width:240px;max-width:100%;height:auto;max-height:360px;object-fit:cover;object-position:top;border-radius:var(--radius-lg);corner-shape:squircle;}
.chat-img.is-open img{max-height:none;}
.chat-markdown>:first-child{margin-top:0;}
.chat-markdown>:last-child{margin-bottom:0;}
.chat-markdown p{margin:0 0 .6em;}
.chat-markdown a{color:inherit;text-decoration:underline;text-underline-offset:3px;}
.chat-markdown ul,.chat-markdown ol{padding-left:1.5em;margin:.5em 0;}
.chat-markdown blockquote{margin:.5em 0;padding-left:.8em;border-left:3px solid currentColor;}
.chat-markdown pre{max-width:100%;overflow-x:auto;white-space:pre;padding:10px;border-radius:var(--radius-xs);corner-shape:squircle;background:rgba(128,128,128,.18);margin:.5em 0;touch-action:pan-x pan-y;}
#root .chat-markdown code{font-family:Consolas,monospace!important;font-size:.9em;}
.chat-markdown :not(pre)>code{padding:2px 4px;border-radius:var(--radius-2xs);background:rgba(128,128,128,.18);white-space:break-spaces;}
.chat-markdown h1,.chat-markdown h2,.chat-markdown h3,.chat-markdown h4,.chat-markdown h5,.chat-markdown h6{font-size:1.1em;line-height:1.4;margin:.6em 0 .3em;}
.chat-markdown hr{border:0;border-top:1px solid currentColor;opacity:.3;}
/* MONO 텍스트 효과 8종(§utils/chat-markdown.js) — 보내는 말풍선(어두운 배경)과 받는
   말풍선(흰 배경) 둘 다에서 써야 해서, 배경색은 전부 code/pre가 이미 쓰던 것과 같은
   rgba(128,128,128,.__) 중간 회색 반투명으로 통일한다(고정 밝은색은 흰 배경에서 안 보이고,
   고정 어두운색은 어두운 배경에서 묻힌다). */
.chat-markdown .md-small{font-size:.78em;}
/* 크게(++): 글자만 커지고 말풍선의 세로 높이는 일반 글자와 똑같다(크게 글자의 줄 높이를 0으로 두면 그 조각은 줄 상자를 키우지 못하고, 줄 상자 높이는 언제나 본문 줄 높이가 정한다. 여러 줄이어도 줄 간격이 일반 글자와 같다). 가로는 커진 글자만큼 자연스럽게 늘어나고, 말풍선 최대 폭에서만 줄이 바뀐다.
   예전에는 큰 글자를 일반 크기로 쳐서 폭만 재는 숨은 복사본으로 말풍선 가로를 묶었는데(.chat-md-fit), 그러면 몇 글자든 두세 글자마다 줄이 바뀌어서 없앴다. */
.chat-markdown .md-big{font-size:1.32em;font-weight:var(--fw-bold);line-height:0;}
.chat-markdown .md-shake{display:inline-block;}
.chat-markdown .md-shake.is-animating{animation:mdShakeOnce .5s cubic-bezier(.36,.07,.19,.97) both;}
@keyframes mdShakeOnce{10%,90%{transform:translateX(-1px);}20%,80%{transform:translateX(2px);}30%,50%,70%{transform:translateX(-3px);}40%,60%{transform:translateX(3px);}100%{transform:translateX(0);}}
@media(prefers-reduced-motion:reduce){.chat-markdown .md-shake.is-animating{animation:none!important;}}
/* 형광펜은 실제 형광펜처럼 노란 배경에 항상 어두운 글자 — 보내는(어두운) 말풍선이든
   받는(흰) 말풍선이든 색이 그대로 노랗게 보이고 대비도 항상 유지된다. 줄이 바뀌어도 칠이 끊기지 않는다 */
.chat-markdown .md-highlight{background:#fde98a;color:var(--gray-800);padding:0 3px;border-radius:3px;-webkit-box-decoration-break:clone;box-decoration-break:clone;}
.chat-markdown .md-underline{text-decoration:underline;text-underline-offset:3px;}
/* 스포일러: 글자는 흐린 그림자로만 두고 위에 점 무늬를 얹어 "가려진 글, 눌러서 보기"를 알린다(iOS 비밀 잉크, 텔레그램) */
.chat-markdown .md-spoiler{position:relative;border-radius:4px;padding:0 3px;cursor:pointer;color:transparent;text-shadow:0 0 6px rgba(128,128,128,.95);background:rgba(128,128,128,.16);transition:color .18s ease,text-shadow .18s ease,background-color .18s ease;}
.chat-markdown .md-spoiler::after{content:"";position:absolute;inset:0;border-radius:inherit;background-image:radial-gradient(rgba(128,128,128,.85) .8px,transparent 1.1px);background-size:4px 4px;opacity:.9;pointer-events:none;}
.chat-markdown .md-spoiler.is-revealed{color:inherit;text-shadow:none;background:transparent;}
.chat-markdown .md-spoiler.is-revealed::after{display:none;}
@media(prefers-reduced-motion:reduce){.chat-markdown .md-spoiler{transition:none;}}
/* 끄덕, 물결: 받을 때 한 번만. transform만 쓴다 */
.chat-markdown .md-nod{display:inline-block;animation:mdNod .6s cubic-bezier(.23,1,.32,1) both;}
@keyframes mdNod{0%{transform:none;}25%{transform:translateY(-4px);}55%{transform:translateY(2px);}80%{transform:translateY(-1px);}100%{transform:none;}}
.chat-markdown .md-wave>span{display:inline-block;animation:mdWave .5s cubic-bezier(.77,0,.175,1) both;animation-delay:calc(var(--i) * 60ms);}
@keyframes mdWave{0%,100%{transform:none;}40%{transform:translateY(-4px);}70%{transform:translateY(1px);}}
@media(prefers-reduced-motion:reduce){.chat-markdown .md-nod,.chat-markdown .md-wave>span{animation:none!important;}}
/* *별표* 행동 묘사는 한글을 억지로 기울이지 않고 옅은 글자로(결정 14). 취소선은 조금 옅게, 링크는 바깥 링크 표시로 밑줄과 구별 */
.chat-markdown em{font-style:normal;opacity:.6;}
.chat-markdown s{text-decoration-thickness:1.5px;opacity:.72;}
.chat-markdown a::after{content:"";display:inline-block;width:.8em;height:.8em;margin-left:3px;vertical-align:-.04em;background:currentColor;opacity:.7;-webkit-mask:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M11 6a1 1 0 1 1 0 2H5v11h11v-6a1 1 0 1 1 2 0v6a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2zm9-3a1 1 0 0 1 1 1v5a1 1 0 1 1-2 0V6.414l-8.293 8.293a1 1 0 0 1-1.414-1.414L17.586 5H15a1 1 0 1 1 0-2Z'/%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'%3E%3Cpath d='M11 6a1 1 0 1 1 0 2H5v11h11v-6a1 1 0 1 1 2 0v6a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2zm9-3a1 1 0 0 1 1 1v5a1 1 0 1 1-2 0V6.414l-8.293 8.293a1 1 0 0 1-1.414-1.414L17.586 5H15a1 1 0 1 1 0-2Z'/%3E%3C/svg%3E") center/contain no-repeat;}
#chatInput::placeholder{white-space:nowrap;}
html,body,#root,#root *,button,input,select,textarea{font-family:var(--font-sys)!important;}
.bottom-nav,.bottom-nav *,.sheet,.sheet *,.wizard-scroll,.wizard-scroll *{font-family:var(--font-sys)!important;}
.logout-leaving{opacity:0;transform:translateY(8px);transition:opacity .16s ease,transform .16s ease;}
a{color:inherit;text-decoration:none;}
::-webkit-scrollbar{width:0;height:0;}
body.app-shell{overflow:hidden;}
#appSplash{position:fixed;inset:0;z-index:9999;background:var(--gray-900);opacity:1;transition:opacity 420ms var(--ease-smooth-out);}
#appSplash.is-hidden{opacity:0;pointer-events:none;}
#appSplash iframe{display:block;width:100%;height:100%;border:0;}
#root{height:100svh !important; min-height:0 !important;}
/* 모바일 브라우저의 주소창/하단 툴바가 나타나도 문서 자체가 움직이지 않도록 앱을 viewport에 고정하고, 실제 스크롤은 .main 내부에서만 한다. */
.mypage-fixed{min-height:100%; height:auto; overflow:visible; display:block; padding-bottom:8px;}
/* --trait-reserve / overflow-anchor:none — §actions/profile.js animateContentResize 주석 참고
   (성격↔MBTI 탭 전환 중 스크롤 범위가 줄어 슬라이더 줄이 아래위로 밀리던 문제). */
.main.mypage-main{overflow-y:auto; overflow-x:hidden; -webkit-overflow-scrolling:touch; padding-bottom:calc(96px + env(safe-area-inset-bottom) + var(--trait-reserve, 0px)) !important; overflow-anchor:none;}
/* 설정 화면 맨 아래 여백을 기본값(96px)보다 10px만 줄인다. */
.main.mypage-settings-main{padding-bottom:calc(86px + env(safe-area-inset-bottom));}
.mypage-scrollless{overflow:visible; display:block; min-height:0;}
/* 마이페이지에서 여는 프로필/이상형 수정 화면도 같은 main 스크롤을 사용한다.
   내부 wizard를 별도의 스크롤 컨테이너로 만들지 않아 스크롤이 한 번만 움직이게 한다. */
.wizard-scroll{
  height:100% !important;
  min-height:0 !important;
  overflow-y:auto !important;
  overflow-x:hidden !important;
  -webkit-overflow-scrolling:touch;
  overscroll-behavior-y:contain;
  box-sizing:border-box;
  padding-bottom:32px;
}
/* 프로필/조건 수정 화면은 wizard 하나만 스크롤한다.
   바깥 main까지 함께 움직이면 모바일에서 스크롤 제스처가 서로 충돌할 수 있다. */
.main.wizard-editor-main{
  overflow:hidden !important;
  min-height:0 !important;
}
.contact-platform-btn{flex:1; min-width:0; text-align:center; border:1px solid var(--border); background:rgba(255,255,255,.72); border-radius:var(--radius-full); padding:12px 8px; font-weight:var(--fw-bold); color:var(--text-mid);}
.contact-platform-btn.selected{color:var(--gray-700); border-color:transparent;}
.contact-platform-btn.band.selected{background:rgba(150,220,120,.48);}
.contact-platform-btn.discord.selected{background:rgba(190,165,245,.46);}
.contact-platform-btn.imessage.selected{background:rgba(130,205,255,.42);}
.contact-choice-row{display:flex; gap:8px; justify-content:center; align-items:stretch; width:100%;}

/* ---------- layout ---------- */
.header-sticky{
  /* 헤더 자체는 완전 불투명(반투명+블러였을 땐 스크롤되는 카드 텍스트가 헤더 아래로
     비쳐 보이는 "고스트" 현상이 있었다 — 그래서 헤더는 딱 잘라 불투명하게 두고, 그
     아래로 번지는 그라데이션만 별도의 얇은 .header-fade 조각으로 분리했다. 이 래퍼가
     sticky를 맡아 헤더+페이드 조각이 항상 같이 붙어 다니게 한다. */
  /* top:-4px — .main의 padding-top(4px)만큼 위로. 브라우저는 sticky 기준 사각형을 스크롤
     컨테이너의 content box로 잡아서 top:0이면 4px 아래에 붙고, 그 4px 틈으로 스크롤되는
     내용이 헤더 위에 비쳐 보였다(홈/매칭/채팅/마이페이지 전부). */
  position:sticky; top:-4px; z-index:30;
}
.header{
  /* 앱(캐파시터)은 화면이 상단바 밑까지 그려진다. 상단바 높이만큼 머리를 키워 불투명 배경이 상단바 뒤를 덮게 한다(웹은 0) */
  display:flex; align-items:center; gap:10px; position:relative;
  margin:-4px -18px 0; padding:calc(10px + env(safe-area-inset-top)) 18px 8px; background:var(--bg1);
}
/* 오른쪽 버튼은 머리 전체가 아니라 상단바 아래 줄의 가운데에 둔다. 위 여백에 상단바 높이가 더해져 있어 그 절반만큼 더 내린다 */
.header .icon-btn{position:absolute; right:18px; top:calc(50% - 22px + env(safe-area-inset-top) / 2); box-shadow:none;border:none;}
.header-fade{
  height:14px; margin:0 -18px; background:linear-gradient(180deg,var(--bg1),transparent); pointer-events:none;
}
/* 다른 탭 로고 이미지는 182px 높이 안에서 m 아랫선이 137px에 있고 30px로 표시된다(아랫선은 헤더 위에서 10+22.58=32.58px).
   홈 로고 이미지는 m 높이에 맞춰 잘려 있어(453x91, 아랫선 87px) 15px로 표시하면 m 크기가 다른 탭과 같다(30/182 배율). 위 마진 8.26px로 아랫선을
   같은 위치에 두고, 아래 마진 6.74px로 헤더 높이를 다른 탭과 같은 48px로 맞춘다(안쪽 여백 위 10px, 아래 8px. 예전엔 16px, 12px라 흰 상자가 넓어 보였다). */
.header .header-logo{display:block;height:15px;width:auto;margin:8.26px 0 6.74px;}
.header .header-logo--sm{height:30px;margin:0;}
.icon-btn{
  width:44px;height:44px;border-radius:50%;border:none;background:var(--gray-0);
  display:flex;align-items:center;justify-content:center;font-size:var(--fs-2xl);box-shadow:var(--shadow-sm);position:relative;
  transition:opacity .15s var(--ease-smooth-out),transform .15s var(--ease-smooth-out);
  flex-shrink:0; /* a plain flex row (esp. the chat input bar) otherwise squishes this
    circle into an oval as its sibling <input> grows with typed text — width:38px alone doesn't
    protect against the default flex-shrink:1, only this does */
}
.icon-btn:active{opacity:1; transform:none;}
/* 뒤로 가기: 동그라미와 그림자 없이 화살표 아이콘만. 누르는 영역은 44px를 유지하고, 화살표 왼쪽 끝이 화면 여백선보다 약 4px 안쪽에 오도록 당긴다(아이콘 안쪽 여백 3.6px 포함, 바짝 붙으면 답답해 보인다). */
.icon-btn.back-btn{background:none;box-shadow:none;border-radius:0;color:var(--text);margin:0 -10px;}
.icon-btn.back-btn svg{position:relative;top:1px;}
/* 하위 화면 머리(§ui/components/sub-header.js): 뒤로 + 제목(17px) + 오른쪽 하나. 모든 하위 화면이 이것 하나만 쓴다 */
.subhead{display:flex;align-items:center;gap:10px;min-height:44px;margin-bottom:14px;padding-top:env(safe-area-inset-top);}
.subhead--room{padding-top:calc(env(safe-area-inset-top) + 14px);margin-bottom:10px;}
.subhead-title{flex:1;min-width:0;}
.subhead-title h1{margin:0;font-size:var(--fs-2xl);font-weight:var(--fw-bold);white-space:nowrap;overflow:hidden;text-overflow:ellipsis;}
.subhead-title p{margin:2px 0 0;font-size:var(--fs-xs);color:var(--text-light);white-space:nowrap;overflow:hidden;text-overflow:ellipsis;}
.subhead-text-btn{min-height:44px;padding:0 6px;border:0;background:none;color:var(--text-mid);font:inherit;font-size:var(--fs-base);font-weight:var(--fw-bold);}
.subhead-text-btn:active{opacity:.55;}
/* 만들기 전체 화면 머리: 닫기(✕) + 가운데 제목. 만들기 버튼은 화면 아래 고정 */
.modhead{display:grid;grid-template-columns:44px 1fr 44px;align-items:center;min-height:44px;margin-bottom:10px;padding-top:env(safe-area-inset-top);}
.modhead h1{margin:0;text-align:center;font-size:var(--fs-2xl);font-weight:var(--fw-bold);}
.icon-btn.modhead-close{background:none;box-shadow:none;color:var(--text);margin-left:-10px;} /* 한글 글자 몸통이 줄 상자 중심보다 1.5px 아래라 옆 제목과 같은 높이로 보이게 1px 내린다 */
/* 매칭 탭 맨 위의 "지금 접속 중"(§ui/online-strip.js): 제목 줄과 아바타 한 줄. 카드 배경 없이 바탕 위에 그대로 놓인다. */
.online-strip{margin:0 0 22px;}
/* 높이를 고정한다: 불러오는 중(회색 원), 인원이 있을 때(아바타), 아무도 없을 때(안내 한 줄)가 모두 같은 높이라서, 상태가 바뀌어도 아래 상대 목록이 위아래로 움직이지 않는다. */
.online-strip .os-row{display:flex;align-items:baseline;justify-content:space-between;height:22px;}
.online-strip h2{margin:0;font-size:var(--fs-2xl);line-height:22px;font-weight:var(--fw-bold);letter-spacing:var(--ls-base);color:var(--gray-800);}
.online-strip h2 small{margin-left:8px;font-size:var(--fs-lg);font-weight:var(--fw-regular);color:var(--gray-500);}
.online-strip .os-more{padding:0;border:0;background:none;font-family:inherit;font-size:var(--fs-sm);color:var(--gray-500);cursor:pointer;-webkit-tap-highlight-color:transparent;}
.online-strip .os-people{display:flex;align-items:center;gap:12px;width:100%;height:52px;margin-top:10px;padding:0;border:0;background:none;font-family:inherit;text-align:left;cursor:pointer;-webkit-tap-highlight-color:transparent;}
.online-strip .ph{position:relative;flex:none;width:52px;height:52px;border-radius:50%;}
.online-strip .ph .avatar{width:52px;height:52px;}
.online-strip .ph:not(.more):not(.skeleton)::after{content:"";position:absolute;right:1px;bottom:1px;width:12px;height:12px;border-radius:50%;background:#3ccf6a;border:2px solid var(--gray-0);}
.online-strip .ph.more{display:grid;place-items:center;background:var(--gray-200);color:var(--gray-600);font-size:var(--fs-md);font-weight:var(--fw-bold);}
.online-strip .ph.skeleton{background:var(--gray-200);}
.online-strip .os-empty{margin:0;padding:0;font-size:var(--fs-md);line-height:52px;color:var(--gray-500);}
/* 매칭 탭 헤더의 필터 버튼: 동그라미 배경 없이 아이콘만, 워드마크와 같은 줄(글자 중심이 헤더 정중앙보다 1px 아래라 그만큼 내린다) 오른쪽 끝. 누르는 영역은 44px이고, 아이콘 오른쪽 끝이 화면 여백선(18px)에 오도록 당긴다. */
.header .header-filter{position:absolute;right:6px;top:calc(50% + 1px + env(safe-area-inset-top) / 2);transform:translateY(-50%);width:44px;height:44px;padding:0;border:0;background:none;color:var(--gray-700);display:flex;align-items:center;justify-content:center;-webkit-tap-highlight-color:transparent;transition:transform .12s var(--ease-out);}
.header .header-filter svg{display:block;}
.header .header-filter:active{transform:translateY(-50%) scale(.9);}
@media(prefers-reduced-motion:reduce){.header .header-filter{transition:none;}.header .header-filter:active{transform:translateY(-50%);}}
.header-likes .dot{top:9px;right:8px;}
.icon-btn .dot,.header-likes .dot{position:absolute;top:5px;right:6px;width:9px;height:9px;border-radius:50%;background:var(--danger);border:2px solid var(--card);animation:badgePulse 2s ease-in-out infinite;}
@keyframes badgePulse{0%,100%{transform:scale(1);}50%{transform:scale(1.15);}}
@media(prefers-reduced-motion:reduce){.icon-btn .dot,.header-likes .dot,.nav-orb .badge{animation:none;}}
/* IMPORTANT: no animation on the bare .main rule. It used to live here, which meant every
   single re-render — including ones from a background Firestore sync that has nothing to
   do with navigation — recreated this element and replayed a fade-in, which is a big part
   of why the screen looked like it kept "flickering" even while just sitting on a tab doing
   nothing. The animation classes below are now applied by paint() ONLY when the screen
   actually changed; a same-screen re-render gets no animation class at all. */
.main{flex:1; min-height:0; overflow-y:auto; overflow-x:hidden; -webkit-overflow-scrolling:touch; overscroll-behavior-y:contain; padding:4px 18px calc(96px + env(safe-area-inset-bottom));}

/* Glass spheres are a CSS treatment of real profile photos. */
.main.online-main{--online-surface:var(--gray-50);--online-ink:#24282d;--online-muted:#656b73;position:relative;padding:0;overflow:hidden;color:var(--online-ink);background:radial-gradient(ellipse at 50% 35%,#fff9,transparent 65%),var(--online-surface);}
.main.online-main::after{content:"";position:absolute;inset:auto 0 0;height:calc(140px + env(safe-area-inset-bottom));z-index:1;pointer-events:none;background:linear-gradient(to top,var(--online-surface) 20%,transparent);}
.online-page{height:100%;min-height:0;position:relative;display:flex;flex-direction:column;}
.cloud-chevron{z-index:2;}
.online-count{display:flex;align-items:center;gap:.4375rem;margin:0;color:var(--online-muted);font-size:var(--fs-xs);line-height:1.6;}
.online-count::before{content:"";flex:none;width:.375rem;height:.375rem;border-radius:50%;background:var(--gray-900);}
.cloud-viewport{flex:1;min-height:0;overflow-y:auto;overflow-x:hidden;overscroll-behavior-y:contain;overflow-anchor:none;touch-action:pan-y;-webkit-overflow-scrolling:touch;margin-bottom:calc(84px + env(safe-area-inset-bottom));padding-bottom:1.5rem;scroll-padding-block:1rem;}
.profile-cloud{position:relative;width:100%;max-width:480px;margin:0 auto;}
.cloud-profile{position:absolute;display:block;padding:0;border:0;border-radius:50%;background:transparent;color:var(--gray-0);touch-action:pan-y;}
.cloud-motion,.cloud-lens{display:block;position:relative;width:100%;height:100%;border-radius:50%;}
.cloud-motion{transform:translate3d(0,0,0);}
.is-scrolling .cloud-motion{will-change:transform;}
.is-entering .cloud-profile{will-change:transform,opacity;}
.is-scrolling .cloud-profile{will-change:transform;}
.cloud-lens{isolation:isolate;overflow:hidden;background:var(--gray-100);box-shadow:0 0 0 3px var(--gray-0),0 10px 18px -12px rgba(0,0,0,.45);transition:transform 160ms var(--ease-out);}
.cloud-lens img{display:block;width:100%;height:100%;object-fit:cover;position:absolute;inset:0;}
.cloud-lens img[hidden]{display:none;}
.cloud-placeholder{position:absolute;inset:0;display:flex;align-items:center;justify-content:center;color:var(--gray-400);}
.cloud-name{position:absolute;z-index:4;bottom:11%;left:0;width:100%;padding:0 13%;display:block;color:#24313b;-webkit-text-stroke:.1em var(--gray-0);paint-order:stroke fill;font-size:var(--name-size,.75rem);font-weight:var(--fw-bold);line-height:1.4;text-align:center;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;}
.cloud-profile.is-pressed .cloud-lens{transform:scale(.97);}
.cloud-profile:focus-visible,.cloud-viewport:focus-visible{outline:2px solid var(--online-ink);outline-offset:4px;}
.online-page:has(.empty-state) .online-count::before{background:var(--gray-400);}
.cloud-chevron{position:absolute;bottom:calc(92px + env(safe-area-inset-bottom));left:calc(50% - 14px);width:28px;height:24px;display:grid;place-items:center;color:var(--online-muted);opacity:0;pointer-events:none;transition:opacity 200ms ease;}
.show-hint .cloud-chevron{opacity:.45;}
@media(hover:hover) and (pointer:fine){.cloud-profile:hover .cloud-lens{transform:translateY(-2px);}.cloud-profile.is-pressed .cloud-lens{transform:scale(.97);}}
@media(prefers-reduced-motion:reduce){
  .cloud-profile,.cloud-motion,.cloud-lens{animation:none!important;transition-property:opacity!important;}
  .cloud-profile:hover .cloud-lens,.cloud-profile.is-pressed .cloud-lens{transform:none;}
}
.group-categories{display:flex;gap:4px;padding:4px;background:var(--bg2);border-radius:var(--radius-full);}
.group-categories label{flex:1;position:relative;cursor:pointer;text-align:center;}
.group-categories input{position:absolute;opacity:0;width:1px;height:1px;}
.group-categories span{display:block;padding:10px 2px;border-radius:var(--radius-full);font-size:var(--fs-sm);white-space:nowrap;color:var(--text-mid);}
.group-categories input:checked+span{background:var(--bg1);color:var(--text);font-weight:var(--fw-bold);box-shadow:0 0 4px #00000012;}
.trait-tab-switcher{position:relative;}
.trait-tab-switcher .segment-indicator{position:absolute;top:4px;bottom:4px;left:4px;border-radius:var(--radius-full);background:var(--bg1);box-shadow:0 0 4px #00000012;transition:transform .32s var(--ease-bounce);}
.trait-tab-switcher label,.trait-tab-switcher label span{position:relative;z-index:1;}
.trait-tab-switcher input:checked+span{background:none;box-shadow:none;}
@media(prefers-reduced-motion:reduce){.trait-tab-switcher .segment-indicator{transition:none!important;}}
/* transitions-dev — Card resize: #traitTabContent/#mbtiTabContent(§screens/mypage.js)의 높이가
   탭 전환으로 바뀔 때(성격 8축 ↔ MBTI 4축, 편집 모드 안내 문구 등) auto 높이끼리 곧장
   점프하지 않고 부드럽게 늘었다 줄었다 한다. §actions/profile.js animateContentResize가
   전환 직후 높이를 px로 고정했다가 도착 높이로 옮겨 붙여서 이 transition이 실제로 탄다. */
.t-resize{transition:width var(--resize-dur) var(--resize-ease),height var(--resize-dur) var(--resize-ease); will-change:width,height;}
@media(prefers-reduced-motion:reduce){.t-resize{transition:none!important;}}
.group-categories input:focus-visible+span{outline:2px solid var(--primary);outline-offset:2px;}
.wizard-step{text-align:center;padding-bottom:190px;}
.wizard-step.has-tabbar{padding-bottom:150px;}
.wizard-step .chip-row{justify-content:center;}
.wizard-step>.field,.wizard-step form,.wizard-step textarea{margin-left:auto;margin-right:auto;}
.wizard-step .field label,.wizard-step .field .hint{text-align:center;}
.wizard-step .btn-sm{margin-left:auto;margin-right:auto;}
.wizard-step .slider-row label{justify-content:center;}
.wizard-progress-wrap{position:relative;margin:0 -4px 18px;padding-top:6px;flex:none;overflow:visible;}
.wizard-progress{position:relative;display:grid;grid-template-columns:repeat(6,minmax(0,1fr));gap:10px 0;overflow:visible;padding:0 2px 12px;margin:0;}
.wizard-progress:not(.required) .wizard-stage{min-width:0;padding:5px 1px 6px;font-size:var(--fs-3xs);}
.wizard-progress.profile-all{grid-template-columns:repeat(7,minmax(0,1fr));}
/* OPTIONAL_PROFILE_STEPS(§screens/auth.js)는 문장 부호가 필수 구간으로 옮겨가면서 7개에서
   6개(나이/신분/지역/통화/실연/말풍선)로 줄었다 — 열 개수를 실제 항목 수와 맞추지 않으면
   grid가 7칸을 잡아 놓고 6개만 채워서 오른쪽에 빈 칸이 남아 전체가 왼쪽으로 쏠려 보인다. */
.wizard-progress.optional{grid-template-columns:repeat(6,minmax(0,1fr));}
.wizard-progress.required{width:100%;box-sizing:border-box;overflow:hidden;padding:0 2px 12px;}
.wizard-progress.required .wizard-stage{flex:1;min-width:0;padding:5px 1px 6px;font-size:var(--fs-3xs);}
/* 각 단계는 "진행 표시"가 아니라 "눌러서 바로 이동하는 버튼"이라는 걸 자연스럽게 알리는 게
   목적이다 — 보이는 원/글자 크기는 그대로 두고, 터치 영역만 padding으로 키운다(위아래
   +5px/+6px). 원 위치가 그만큼 아래로 밀리니 연결선(::before)의 top도 7px→12px로 같이
   옮겨서 여전히 원 한가운데를 지나가게 한다. hover/active/focus 배경은 ::after로 원 중심에
   깔아 dot·라벨과 겹치지 않게 z-index로 눕힌다(::before는 이미 연결선이 쓰고 있다). */
.wizard-stage{position:relative;z-index:1;min-width:64px;padding:5px 3px 6px;border:0;background:transparent;color:var(--text-mid);font-size:var(--fs-2xs);line-height:1.25;scroll-snap-align:center;cursor:pointer;transition:color .15s ease;}
.wizard-stage::before{content:"";position:absolute;top:12px;right:0;left:0;height:2px;background:var(--border);z-index:-1;}
.wizard-stage:first-child::before{left:50%;}.wizard-stage:last-child::before{right:50%;}
.wizard-progress:not(.required):not(.profile-all):not(.optional) .wizard-stage:nth-child(6)::before{right:50%;}
.wizard-progress:not(.required):not(.profile-all):not(.optional) .wizard-stage:nth-child(7)::before{left:50%;}
.wizard-progress.profile-all .wizard-stage:nth-child(7)::before{right:50%;}
.wizard-progress.profile-all .wizard-stage:nth-child(8)::before{left:50%;}
.wizard-stage::after{content:"";position:absolute;top:1px;left:50%;width:42px;height:42px;transform:translate(-50%,0) scale(.001);border-radius:var(--radius-full);background:rgba(0,0,0,.05);opacity:0;z-index:0;pointer-events:none;transition:opacity .15s ease,transform .15s ease;}
@media(hover:hover){
  .wizard-stage:hover:not(:disabled)::after{opacity:1;transform:translate(-50%,0) scale(1);}
  .wizard-stage:hover:not(:disabled):not(.done):not(.current){color:var(--text);}
}
.wizard-stage:active:not(:disabled)::after{opacity:1;transform:translate(-50%,0) scale(1);background:rgba(0,0,0,.09);}
.wizard-stage:active:not(:disabled) span{transform:scale(.97);}
.wizard-stage:focus-visible{outline:none;}
.wizard-stage:focus-visible::after{opacity:1;transform:translate(-50%,0) scale(1);}
/* 아직 값이 없는 단계도 "누를 수 있다"는 게 보여야 한다 — 예전 var(--border)(#e6e6e7)
   외곽선은 거의 안 보일 정도로 옅었다. text-light(#8a8a8a) 테두리 + 흰 배경으로 대비를
   올린다(연결선은 여전히 --border라 이제 원이 선보다 뚜렷하다). */
.wizard-stage span{position:relative;z-index:1;display:block;width:16px;height:16px;margin:0 auto 6px;border:2px solid var(--text-light);background:var(--bg1);border-radius:50%;transition:background-color .15s ease,border-color .15s ease,box-shadow .15s ease,transform .1s ease;}
.wizard-stage.done{color:var(--text);}
.wizard-stage.done span{border-color:var(--primary-dark);background:var(--primary-dark);}
/* 현재 단계는 값이 있든 없든 항상 이중 원(채워진 중앙 + 검정 외곽 링)으로 최우선 표시된다. */
.wizard-stage.current,.wizard-stage.current.done{color:var(--primary-dark);font-weight:var(--fw-bold);}
.wizard-stage.current span{background:var(--primary-dark);border-color:var(--primary-dark);box-shadow:0 0 0 3px var(--bg1),0 0 0 5px var(--primary-dark);}
.wizard-stage:disabled{cursor:not-allowed;opacity:.45;}
.wizard-stage:disabled::after{display:none;}
/* 마법사에 처음 들어왔을 때만 한 번 보여주는 "눌러서 이동 가능" 안내 — §screens/auth.js
   stepProgressHintHtml/§actions/auth-profile.js dismissStepHint. 닫으면 localStorage에
   기록해 다시 안 뜬다. */
/* 인디케이터를 따라다니는 게 아니라, "여기 눌러서 이동할 수 있다"는 걸 알려주는 고정된
   안내 표지다 — "current"(지금 단계)가 아니라 항상 3번째 칸 위를 가리킨다(왼쪽 첫 칸은
   화면 맨 위 뒤로가기 버튼과 겹친다). 인디케이터를 눌러 다른 단계로 옮겨도 3번째 칸 자체는
   안 움직이니 깜빡이지 않는다 — §screens/auth.js stepProgressHintHtml가 이 마법사 세션에서
   처음 뜰 때만 .is-first로 페이드인도 한 번만 재생한다. left:104px는 §ui/wizard-step-hint.js
   positionStepHint가 렌더 직후 3번째 칸의 실제 중앙으로 덮어쓰기 전까지의 대략값일 뿐이다
   (그리드 폭이 화면마다 달라 정확한 값은 JS로 한 번 잰다). */
.wizard-step-hint{position:absolute;bottom:100%;left:104px;margin-bottom:10px;z-index:15;width:max-content;box-sizing:border-box;padding:9px 26px 9px 12px;background:var(--gray-800);border-radius:var(--radius-xs);corner-shape:squircle;box-shadow:var(--shadow-sm);}
.wizard-step-hint.is-first{animation:wizardStepHintIn 1.4s ease both;}
@keyframes wizardStepHintIn{from{opacity:0;}to{opacity:1;}}
.wizard-step-hint::after{content:"";position:absolute;bottom:-4px;left:18px;width:9px;height:9px;background:var(--gray-800);transform:rotate(45deg);border-radius:0 0 var(--radius-2xs) 0;}
.wizard-step-hint p{margin:0;font-size:var(--fs-2xs);line-height:1.4;color:var(--gray-0);white-space:nowrap;}
.wizard-step-hint-close{position:absolute;top:0;bottom:0;right:4px;margin:auto 0;width:18px;height:18px;display:flex;align-items:center;justify-content:center;padding:0;border:none;border-radius:50%;background:none;color:rgba(255,255,255,.55);}
.wizard-step-hint-close:active{background:rgba(255,255,255,.15);color:var(--gray-0);}
@media(prefers-reduced-motion:reduce){.wizard-stage,.wizard-stage span,.wizard-stage::after{transition:none!important;}.wizard-step-hint.is-first{animation:none!important;}}
.wizard-back{align-self:flex-start;flex:0 0 40px;width:40px;min-width:40px;max-width:40px;height:40px;min-height:40px;max-height:40px;box-sizing:border-box;margin:-18px 0 14px;padding:0;border:0;border-radius:0;background:none;color:var(--text);font-size:var(--fs-3xl);line-height:1;}
/* 다음/이전 버튼은 화면 내용의 높이와 무관하게 늘 같은 자리(하단, 탭 바로 위)에 고정한다 —
   스텝마다 내용 길이가 달라 .wizard-step의 흐름 안에 있으면 버튼 위치도 따라 움직였다. 버튼
   바로 위에 배경색 그라데이션을 깔아서, 내용이 버튼 아래로 스크롤되어 지나갈 때 "더 내려갈
   내용이 있다"는 걸 암시한다(§.group-options-wrap::after와 같은 결). */
.wizard-nav-fixed{position:absolute;left:50%;bottom:calc(20px + env(safe-area-inset-bottom));transform:translateX(-50%);width:calc(100% - 32px);max-width:448px;z-index:25;}
.wizard-nav-fixed.has-tabbar{bottom:calc(88px + env(safe-area-inset-bottom));}
.wizard-nav-fixed::before{content:"";position:absolute;left:-16px;right:-16px;top:-44px;bottom:-100px;background:linear-gradient(to bottom,transparent,var(--bg2) 44px);pointer-events:none;z-index:-1;}
/* 단계를 넘길 때 질문 영역만 옆에서 미끄러져 들어오게 한다 — 다음/이전 버튼(.wizard-nav-fixed)은
   위치가 absolute라 형제로 둔 이상 이 transform에 같이 끌려가지 않는다. 공용 slideRight/
   slideLeft와 똑같이 쓰지 않고 위저드 전용 키프레임을 따로 두는 이유는 다른 화면 전환에
   영향을 주지 않기 위해서다.
   transitions-dev "Page side-by-side"(08) 적용 — 다만 그 스킬의 기본 모양 그대로는 못
   가져왔다: 원래 스니펫은 이전/다음 두 페이지를 동시에 DOM에 두고 position:absolute로
   겹쳐 슬라이드시키는데, 이 위저드는 스텝마다 내용 높이가 다 달라서(§.wizard-nav-fixed
   주석) absolute로 겹치면 감싸는 요소 높이가 무너진다 — 그래서 지금처럼 "새 내용 하나만
   들어올 때 슬라이드 + 페이드"하는 구조는 유지하고, 대신 duration/거리/블러는 스킬의
   --page-slide-dur/--page-slide-distance/--page-blur 토큰 값을 그대로 쓴다. easing만
   스킬 기본값(cubic-bezier(.22,1,.36,1))을 쓰지 않는다 — 처음에 그 커브로 써 봤더니
   초반에 이동을 거의 다 끝내 버려서 "쫀득"이 아니라 "갑자기 바뀐다"는 느낌이었다(버튼
   팝인처럼 튕기는 연출은 여기엔 안 맞았다). 이 전환은 처음부터 끝까지 일정하게 흘러야
   스무스해 보여서 표준 이징(cubic-bezier(.4,0,.2,1))으로 남겨 뒀다. */
@keyframes wizContentSlideRight{from{opacity:0; filter:blur(var(--page-blur)); transform:translate3d(var(--page-slide-distance),0,0);} to{opacity:1; filter:blur(0); transform:translate3d(0,0,0);}}
@keyframes wizContentSlideLeft{from{opacity:0; filter:blur(var(--page-blur)); transform:translate3d(calc(var(--page-slide-distance) * -1),0,0);} to{opacity:1; filter:blur(0); transform:translate3d(0,0,0);}}
.wizard-step-content.slide-right{animation:wizContentSlideRight var(--page-slide-dur) cubic-bezier(.4,0,.2,1);}
.wizard-step-content.slide-left{animation:wizContentSlideLeft var(--page-slide-dur) cubic-bezier(.4,0,.2,1);}
@media(prefers-reduced-motion:reduce){.wizard-step-content.slide-right,.wizard-step-content.slide-left{animation:none!important;}}
/* 그룹+임관 합친 1단계에서 "그룹 고르기"(토글+그리드, 더 큼)↔"임관 고르기"(도킹된 칩+목록,
   더 짧음) 사이를 오갈 때 아래쪽 내용의 높이가 달라지면 .wizard-step의 justify-content:center가
   전체 블록을 다시 가운데 맞추면서 위에 있는 제목/문구까지 같이 움직여 보였다 — 그룹 고르기
   쪽(토글+3열4행 그리드)의 자연 높이만큼 두 상태 모두 min-height로 예약해 둬서, 무엇이 보이든
   블록 전체 높이가 같게 만든다. 제목/문구는 이 zone 위에 있어서 이제 자리를 지킨다. */
/* 도킹된 그룹 칩을 눌러 취소하면(§actions/auth-profile.js wizClearGroup) 그룹 그리드가
   paint()로 통째로 다시 그려지는데, 예전엔 애니메이션 없이 그냥 툭 나타났다 — 다른
   "쫀득한" 등장(도킹 칩, 이전/다음 버튼)과 같은 오버슈트 곡선으로 살짝 튕기며 들어오게
   맞췄다. */
@keyframes wizGroupZonePopIn{from{opacity:0; transform:scale(.92) translateY(8px);} to{opacity:1; transform:scale(1) translateY(0);}}
.wizard-group-zone{min-height:276px; animation:wizGroupZonePopIn .38s cubic-bezier(.34,1.7,.64,1) both;}
@media(prefers-reduced-motion:reduce){.wizard-group-zone{animation:none!important;}}
/* 그룹+임관 합친 1단계에서 그룹을 고르면 그 아래 임관 목록이 나타난다(§screens/auth.js
   stepGroupMember) — 갓 그려진 새 엘리먼트라 애니메이션이 자동 재생된다. 원래는 튕기는
   스케일 팝(scale+overshoot)이었는데, 온보딩·조건 수정·새 프로필 만들기에서 내용이
   새로 나타날 때는 전부 튕기지 않고 담백하게 위로 스르륵 올라오는 쪽으로 통일했다 —
   §.wizard-field-rise와 같은 커브(wizFieldRiseIn)를 그대로 쓴다. */
@keyframes wizFieldRiseIn{from{opacity:0; transform:translateY(10px);} to{opacity:1; transform:translateY(0);}}
.wizard-member-reveal{animation:wizFieldRiseIn .3s var(--ease-smooth-out) both;}
@media(prefers-reduced-motion:reduce){.wizard-member-reveal{animation:none!important;}}
.wizard-field-rise{animation:wizFieldRiseIn .3s cubic-bezier(.4,0,.2,1) both;}
@media(prefers-reduced-motion:reduce){.wizard-field-rise{animation:none!important;}}
/* 그룹을 확정 지은 뒤(§actions/auth-profile.js wizPickGroup) 검색칸에 다른 글자를 쳐서
   확정이 풀리면(§wizGroupInput) 임관 입력 영역이 사라진다 — 지금까지는 .remove()로 바로
   지워서 뚝 끊겨 없어졌다. 나타날 때(wizFieldRiseIn)와 대칭으로, 사라질 때도 위로 살짝
   슬라이드하며 옅어지게 한다(요구사항: 다른 그룹 입력 시 사라지는 부분에 트랜지션 적용).
   transitions-dev 모션 토큰의 --duration-quick/--ease-smooth-out을 쓴다 — "빠르게 사라짐"
   쪽 용도와 맞다. */
@keyframes wizFieldRiseOut{from{opacity:1; transform:translateY(0);} to{opacity:0; transform:translateY(-6px);}}
.wizard-field-rise.is-exit{animation:wizFieldRiseOut var(--duration-quick) var(--ease-smooth-out) both;}
@media(prefers-reduced-motion:reduce){.wizard-field-rise.is-exit{animation:none!important;}}
/* "이전"이 나타나거나 사라질 때 "다음"의 가로 폭이 쫀득하게 늘거나 줄어든다 — 원래는
   grid-template-columns 자체를 @keyframes로 애니메이션했는데, 실측해보니(getComputedStyle을
   여러 프레임에 걸쳐 찍어 봄) 이 환경에서 grid-template-columns는 애니메이션 도중 값이
   전혀 안 바뀌고 처음부터 최종값으로 툭 튀어 있었다 — grid 트랙 크기 보간이 안 먹힌 것.
   그래서 grid 대신 flexbox로 바꾸고, JS(§actions/auth-profile.js animateNavRowPrevChange)가
   flex-basis를 직접 두 프레임에 걸쳐 옮기는 FLIP 방식을 쓴다 — width/flex-basis 전환은
   훨씬 널리 지원돼서 안전하다. white-space:nowrap이 핵심이다 — 이게 없으면 "이전" 폭이
   좁아지는 도중 글자가 두 줄로 줄바꿈되면서 행 높이가 순간 커졌다 줄어들어 "다음" 버튼이
   세로로 살짝 튀어 보였다. */
.wizard-nav-row{display:flex;gap:10px;}
.wizard-nav-row .nav-col-prev{flex:1 1 0;width:auto;min-width:0;overflow:hidden;white-space:nowrap;}
.wizard-nav-row .btn-primary{flex:2 1 0;min-width:0;}
@media(prefers-reduced-motion:reduce){.wizard-editor-main{animation:none!important;}}
.main.fade-in{animation:fadeIn var(--duration-fast) var(--ease-smooth-out); will-change:opacity;}
@keyframes fadeIn{from{opacity:0;} to{opacity:1;}}
/* 메시지 불러오는 점은 0.3초 넘게 걸릴 때만 나타난다(캐시에서 바로 뜨는 방에서 깜빡이지 않게). */
.chat-loading{animation:fadeIn .2s ease-out .3s both;}
/* 탭 전환(페이지 슬라이드, transitions-dev --duration-fast 250ms). will-change를 두지 않는다: 효과가 끝난 뒤에도 남아
   .main이 position:fixed의 기준이 되어 버려, 화면에 고정해야 하는 요소가 스크롤을 따라 움직였다. */
.main.slide-right{animation:slideRight var(--duration-fast) var(--ease-smooth-out);}
.main.slide-left{animation:slideLeft var(--duration-fast) var(--ease-smooth-out);}
/* 탭끼리 전환(§app-paint-runtime.js crossfade): 이전 화면이 새 화면(.fade-in) 위에 겹쳐 사라진다. 하단 탭(z-index 30)보다는 아래라 유리 탭 바는 그대로 살아 있다 */
.main.main-leaving{position:absolute;inset:0;z-index:29;pointer-events:none;animation:fadeOut var(--duration-fast) var(--ease-smooth-out) forwards;}
@media(prefers-reduced-motion:reduce){.main.main-leaving{display:none;}}
/* 연결 끊김 꼬리표(§main.js netOff): 화면 위 가운데, 누름은 아래로 통과 */
.net-off{position:fixed;top:calc(8px + env(safe-area-inset-top));left:50%;transform:translateX(-50%);z-index:9999;padding:4px 10px;border-radius:999px;background:var(--gray-900);color:var(--gray-0);font-size:var(--fs-xs);font-weight:600;pointer-events:none;}
.net-off[hidden]{display:none;}
.chat-contact-hint{
  position:absolute;right:14px;bottom:78px;z-index:8;
  display:flex;align-items:center;gap:7px;
  padding:8px 11px;border-radius:var(--radius-xs);corner-shape:squircle;
  background:var(--gray-0);box-shadow:var(--shadow);
  color:var(--text-mid);font-size:var(--fs-xs);font-weight:var(--fw-bold);
  animation:chatHintIn .28s ease-out,chatHintOut .3s var(--ease-smooth-out) 4s forwards;
  pointer-events:none;
}
.chat-contact-hint-arrow{font-size:var(--fs-2xl);color:var(--primary-dark);line-height:1;}
@keyframes chatHintIn{from{opacity:0;transform:translateY(5px)}to{opacity:1;transform:none}}
@keyframes chatHintOut{from{opacity:1}to{opacity:0;visibility:hidden}}



.first-chat-guide{
  width:min(330px, calc(100% - 36px));
  margin:auto;
  padding:20px 18px 18px;
  box-sizing:border-box;
  display:flex;
  flex-direction:column;
  align-items:stretch;
  gap:12px;
  background:var(--gray-0);
  border:1px solid var(--border);
  border-radius:var(--radius-lg);corner-shape:squircle;
  box-shadow:var(--shadow);
  animation:firstChatGuideIn .32s var(--ease-smooth-out);
  flex:0 0 auto;
}
@keyframes firstChatGuideIn{
  from{opacity:0;transform:translateY(14px) scale(.98)}
  to{opacity:1;transform:none}
}
/* "만약에" 질문 카드(채팅에 실제로 남는 메시지 형태) — .first-chat-guide와 같은 폭/정렬
   규칙을 써서 두 종류의 안내 카드가 한 세트처럼 보이게 한다. */
.if-question-msg-card{
  width:min(330px, calc(100% - 36px));
  margin:0 auto;
  padding:18px;
  box-sizing:border-box;
  background:var(--gray-0);
  border:1px solid var(--border);
  border-radius:var(--radius-lg);corner-shape:squircle;
  box-shadow:var(--shadow-sm);
}
/* "만약에" 질문 제목/본문 공용 스타일 — 미리보기 카드/시트/채팅 카드가 전부 같은 규칙을
   쓴다. 본문은 제목(만약에 💭)보다 가볍게(600) + 진회색, 중앙 정렬 + word-break:keep-all
   (어절 단위로만 줄바꿈, 한글 단어 중간이 안 잘리게)로 정리했다. */
.if-q-title{
  font-size:var(--fs-md);
  font-weight:var(--fw-bold);
  color:var(--text);
  text-align:center;
}
/* 질문 길이(1~3줄)에 따라 "다른 질문 보기" 버튼 위치가 매번 오르내리지 않도록, 본문 영역에
   최소 높이를 줘서 짧은 질문일 땐 위아래로 여백이 고르게 남고 버튼은 항상 같은 자리에
   온다. 가장 긴 질문 기준으로 잡되(78px ≈ 3줄), 예전보다 낮춰 카드 세로 공백을 줄였다. */
.if-q-text-wrap{
  min-height:78px;
  display:flex;
  align-items:center;
}
.if-q-text{
  width:100%;
  padding:0 6px;
  box-sizing:border-box;
  font-size:var(--fs-base);
  font-weight:var(--fw-bold);
  line-height:1.65;
  color:var(--gray-700);
  text-align:center;
  white-space:pre-line;
  word-break:keep-all;
  overflow-wrap:break-word;
  animation:ifQuestionFadeIn .22s ease;
}
@keyframes ifQuestionFadeIn{
  from{opacity:0; transform:translateY(4px);}
  to{opacity:1; transform:none;}
}
.left-chat-status{
  color:var(--gray-400);
  font-size:var(--fs-2xs);
  font-weight:var(--fw-bold);
  white-space:nowrap;
}
.match-action-btn{
  min-width:78px;
  height:30px;
  padding:0 10px;
  display:inline-flex;
  align-items:center;
  justify-content:center;
  box-sizing:border-box;
  white-space:nowrap;
}
.match-block-btn{min-width:54px!important;width:54px!important;padding:0 6px!important;}
.chatroom-transition{animation:chatRoomIn var(--duration-fast) var(--ease-smooth-out);}
@keyframes chatRoomIn{from{opacity:0;transform:translateX(var(--page-slide-distance))}to{opacity:1;transform:none}}

/* 첫 화면(운영자 2026-10-14 21번 다듬기 A): 화면을 꽉 채운 흑백 크롬 사진(Unsplash 3cct2HPsNbA, Unsplash License) 가운데 흰 세리프 mono., 아래 흰 "초대 코드 입력"과 테두리 "로그인".
   사진은 아주 천천히 커졌다 돌아온다(움직임 줄이기면 멈춤). 가장자리를 눌러 깊이를 주고 mono. 뒤만 은은하게 어둡게 해 글자를 살린다 */

/* 1:1 첫 대화 물꼬 선반(결정 75, 시안 chat-shelf-v7-1 가, §screens/chat.js ifQuestionPreviewCardHtml): 가로로 긴 카드를 옆으로 넘기는 줄, 그림 없음.
   꼬리표는 작게, 본문은 크게, 하는 일은 아래 흰 알약 하나. 다음 카드가 조금 보여 넘길 수 있음을 알린다 */
.chat-shelf{width:100%;margin:auto 0;align-self:stretch;display:flex;flex-direction:column;align-items:center;gap:12px;animation:firstChatGuideIn .32s var(--ease-smooth-out);flex:0 0 auto;}
.chat-shelf-title{margin:0;font-size:var(--fs-sm);font-weight:var(--fw-bold);color:var(--text-light);}
.chat-shelf-row{display:flex;gap:12px;width:100%;overflow-x:auto;scroll-snap-type:x mandatory;scrollbar-width:none;padding:0 44px;box-sizing:border-box;scroll-padding:0 44px;overscroll-behavior-x:contain;}
.chat-shelf-row::-webkit-scrollbar{display:none;}
.shelf-card{flex:0 0 268px;min-height:172px;box-sizing:border-box;display:flex;flex-direction:column;gap:12px;padding:16px 18px;border-radius:18px;corner-shape:squircle;background:var(--gray-100);scroll-snap-align:start;}
.shelf-card[hidden]{display:none;}
.shelf-tag{display:flex;align-items:center;gap:5px;font-size:var(--fs-xs);color:var(--text-mid);}
.shelf-tag span{min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;}
.shelf-side{margin-left:auto;display:grid;place-items:center;width:28px;height:28px;padding:0;border:0;border-radius:50%;background:none;color:var(--text-mid);cursor:pointer;}
.shelf-ai{margin-left:4px;padding:1px 5px;border-radius:var(--radius-full);background:var(--gray-0);font-size:10px;font-style:normal;font-weight:var(--fw-bold);color:var(--text-mid);}
.shelf-tag .shelf-ai{margin-left:auto;}
.shelf-body{flex:1;font-size:var(--fs-lg);line-height:1.5;color:var(--text);display:-webkit-box;-webkit-line-clamp:3;-webkit-box-orient:vertical;overflow:hidden;word-break:keep-all;}
.shelf-song{display:flex;flex-direction:column;gap:2px;}
.shelf-song b{font-size:22px;font-weight:var(--fw-bold);line-height:1.25;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;}
.shelf-song span{font-size:var(--fs-md);color:var(--text-mid);}
.shelf-act{align-self:flex-start;display:inline-flex;align-items:center;gap:5px;height:32px;padding:0 13px;border:0;border-radius:var(--radius-full);background:var(--gray-0);font:inherit;font-size:var(--fs-sm);font-weight:var(--fw-bold);color:var(--text);cursor:pointer;box-shadow:0 0 0 .5px rgba(0,0,0,.06);}
.shelf-act:active{transform:scale(.97);}
.chat-shelf-dots{display:flex;gap:6px;}
.chat-shelf-dots i{width:6px;height:6px;border-radius:50%;background:var(--gray-200);}
.chat-shelf-dots i.on{background:var(--gray-800);}
.chat-shelf-dots i[hidden]{display:none;}
.auth-landing{position:relative;width:100%;height:100svh;overflow:hidden;background:#080808;isolation:isolate;}
/* 첫 화면 확정안(design/landing-motion-v4.html 고친 판): scale로 키우지 않고 사진 칸을 화면보다 12% 크게 잡아 옮기기와 기울이기만 한다(scale은 처음 크기 그림을 늘려 흐려진다).
   --x, --y(-1~1)는 §ui/landing-tilt.js가 폰 기울기, 손가락 끌기, 혼자 도는 순서로 바꾼다. 로고는 반대로 조금 옮긴다 */
.auth-landing-stage{position:absolute;inset:0;z-index:0;overflow:hidden;perspective:1100px;}
.auth-landing-frame{position:absolute;inset:-6%;transform:translate3d(calc(var(--x,0) * -14px),calc(var(--y,0) * -12px),0) rotateX(calc(var(--y,0) * -6deg)) rotateY(calc(var(--x,0) * 8deg));transition:transform 1.1s cubic-bezier(.22,1,.36,1);}
.auth-landing-photo{position:absolute;inset:0;width:100%;height:100%;object-fit:cover;object-position:50% 30%;}
.auth-landing-grain{position:absolute;inset:0;width:100%;height:100%;opacity:.09;mix-blend-mode:overlay;pointer-events:none;}
.auth-landing::before{content:"";position:absolute;inset:0;z-index:1;pointer-events:none;box-shadow:inset 0 0 140px 30px rgba(0,0,0,.65);background:radial-gradient(150px 90px at 50% 49%,rgba(0,0,0,.55),transparent),linear-gradient(rgba(0,0,0,.5),transparent 15%,transparent 58%,rgba(0,0,0,.9) 86%);}
.auth-landing-mark{position:absolute;left:50%;top:49%;z-index:2;width:160px;height:auto;overflow:visible;transform:translate(calc(-50% + var(--x,0) * -6px),calc(-50% + var(--y,0) * -5px));transition:transform 1.1s cubic-bezier(.22,1,.36,1);filter:drop-shadow(0 2px 10px rgba(0,0,0,.6));}
@media(prefers-reduced-motion:reduce){.auth-landing-frame,.auth-landing-mark{transition:none;}}
.auth-landing-action{position:absolute;right:0;bottom:0;left:0;padding:24px 22px calc(16px + env(safe-area-inset-bottom));}
/* 첫 화면 맨 아래 사업자 정보와 약관 링크(전자상거래법 제10조 1항, 포트원 본인인증 계약 점검) */
.auth-landing-biz{margin-top:20px;color:var(--gray-450);font-size:var(--fs-2xs);line-height:1.5;text-align:center;}
.auth-landing-biz nav{display:flex;justify-content:center;gap:12px;margin-bottom:4px;}
.auth-landing-biz a{color:var(--gray-400);font-size:var(--fs-xs);font-weight:var(--fw-bold);text-decoration:none;}
.auth-landing-biz p{margin:0;}
.auth-landing-action{z-index:2;display:flex;flex-direction:column;gap:10px;}
.auth-btn-light{background:var(--gray-0);color:var(--gray-900);}
.auth-btn-ghost{background:rgba(255,255,255,.06);color:var(--gray-0);box-shadow:inset 0 0 0 1.5px rgba(255,255,255,.24);-webkit-backdrop-filter:blur(8px);backdrop-filter:blur(8px);}
.auth-form-page{position:relative;min-height:100svh;padding:calc(84px + env(safe-area-inset-top)) 22px calc(30px + env(safe-area-inset-bottom));display:flex;align-items:flex-start;justify-content:center;overflow-y:auto;background:var(--bg1);animation:authPageIn .3s cubic-bezier(.16,1,.3,1);}
.auth-form-shell{width:100%;max-width:390px;margin:0;}
.auth-form-mark{display:block;width:56px;height:56px;margin:0 auto 18px;}
/* 로그인, 회원가입, 찾기, 초대 코드는 첫 화면과 같은 어두운 판으로 잇는다(운영자 2026-10-14, 참고 Cosmos 로그인과 초대 코드). 색 토큰만 이 안에서 바꿔 안쪽 부품이 그대로 따라온다 */
.auth-form-page{background:#080808;color:#fff;--text:#fff;--text-mid:rgba(255,255,255,.62);--text-light:rgba(255,255,255,.42);--border:rgba(255,255,255,.12);--bg2:#151515;--primary:#fff;--primary-dark:#fff;}
.auth-band{position:absolute;left:0;right:0;top:0;height:420px;pointer-events:none;}
.auth-band::before,.auth-band::after{content:"";position:absolute;inset:0;}
.auth-band::before{background:url("../images/auth/chrome.webp") 50% 30%/cover;opacity:.32;}
.auth-band::after{background:linear-gradient(rgba(8,8,8,.2),#080808 92%);}
.auth-form-page .auth-form-shell{position:relative;z-index:1;}
.auth-form-page .auth-form-back{z-index:2;}
.auth-form-page .auth-form-title,.auth-form-page .auth-form-sub{text-align:center;}
.auth-form-page .field input:not([type=checkbox]):not([type=radio]){background:#151515;border-color:rgba(255,255,255,.08);color:#fff;}
.auth-form-page .field input::placeholder{color:rgba(255,255,255,.35);}
.auth-form-page .field input:not([type=checkbox]):not([type=radio]):focus{border-color:rgba(255,255,255,.5);}
.auth-form-page .btn-primary{background:var(--gray-0);color:var(--gray-900);}
.auth-form-page .btn-outline{background:rgba(255,255,255,.1);color:#fff;}
/* 초대 코드 6칸: 보이지 않는 입력칸 하나를 칸 위에 겹쳐 붙여넣기와 자동 채우기를 그대로 받는다 */
.invite-boxes{position:relative;display:grid;grid-template-columns:repeat(6,1fr);gap:8px;margin:8px 0 14px;}
.invite-boxes span{height:58px;border-radius:var(--radius-sm);corner-shape:squircle;background:#141414;box-shadow:inset 0 0 0 1px rgba(255,255,255,.1);display:grid;place-items:center;font-size:24px;font-weight:var(--fw-bold);color:#fff;}
.invite-boxes span.on{box-shadow:inset 0 0 0 1.5px rgba(255,255,255,.55),0 0 18px rgba(255,255,255,.18);}
.invite-boxes span.cur::after{content:"";width:2px;height:26px;border-radius:1px;background:#fff;}
.invite-boxes input{position:absolute;inset:0;width:100%;height:100%;opacity:0;border:0;font-size:16px;}
.auth-form-title{margin:0 0 8px;text-align:left;}
.auth-form-sub{margin-bottom:30px;}
.auth-form-back{position:absolute;top:calc(18px + env(safe-area-inset-top));left:18px;width:40px;height:40px;padding:0;border:0;border-radius:0;background:none;color:var(--text);font-size:var(--fs-3xl);line-height:1;}
.auth-platform-option{flex:1;display:flex!important;align-items:center;gap:7px;margin:0!important;padding:11px 12px;border:1px solid var(--border);border-radius:var(--radius-sm);corner-shape:squircle;color:var(--text)!important;}
.auth-notice{margin:-4px 0 18px;font-size:var(--fs-sm);line-height:1.65;color:var(--text-mid);}
.auth-notice summary{cursor:pointer;font-weight:var(--fw-bold);color:var(--text);}
.auth-notice div{padding-top:8px;}
.auth-switch-copy{margin:22px 0 0;text-align:center;color:var(--text-mid);font-size:var(--fs-md);}
.auth-switch-copy button{padding:2px 4px;border:0;background:none;color:var(--text);font-size:inherit;font-weight:var(--fw-bold);text-decoration:underline;text-underline-offset:3px;}
.auth-field-label-row{display:flex;align-items:center;justify-content:space-between;gap:10px;margin-bottom:7px;}
.auth-field-label-row label{margin:0;}
.auth-code-button{width:auto;padding:7px 11px;font-size:var(--fs-sm);}
.auth-code-status{margin-top:6px;font-size:var(--fs-xs);color:var(--primary-dark);}
.auth-invite-hint{margin:6px 0 0;font-size:var(--fs-xs);color:var(--text-light);line-height:1.5;}
.auth-phone-notice{margin:-4px 0 18px;color:var(--text-light);font-size:var(--fs-2xs);line-height:1.55;}
.auth-recovery-links{display:flex;align-items:center;justify-content:center;gap:12px;margin:18px 0 0;}
.auth-recovery-links button{padding:2px 4px;border:0;background:none;color:var(--text-mid);font-size:var(--fs-sm);}
.auth-recovery-links span{width:1px;height:12px;background:var(--border);}
.auth-found-id{margin:0 0 22px;padding:24px;border:1px solid var(--border);border-radius:var(--radius-sm);background:var(--bg2);text-align:center;}
.auth-found-id span{display:block;margin-bottom:8px;color:var(--text-mid);font-size:var(--fs-sm);}
.auth-found-id strong{display:block;color:var(--primary-dark);font-size:var(--fs-2xl);font-weight:var(--fw-bold);letter-spacing:.02em;word-break:break-all;}
#phoneRecaptcha{min-height:0;}
@keyframes authPageIn{from{opacity:0;transform:translateY(18px)}to{opacity:1;transform:translateY(0)}}
.auth-page-no-anim{animation:none;}
@media(prefers-reduced-motion:reduce){.auth-page,.auth-landing-photo{animation:none}}
@media(prefers-reduced-transparency:reduce){.auth-btn-ghost{background:var(--gray-800);backdrop-filter:none;-webkit-backdrop-filter:none;}}

/* 화면 넘김 거리는 하위 화면, 대화방, 가입 단계 모두 --page-slide-distance(8px) 하나(운영자 2026-10-13) */
@keyframes slideRight{from{opacity:0; transform:translate3d(var(--page-slide-distance),0,0);} 70%{opacity:1;} to{opacity:1; transform:translate3d(0,0,0);}}
@keyframes slideLeft{from{opacity:0; transform:translate3d(calc(var(--page-slide-distance) * -1),0,0);} 70%{opacity:1;} to{opacity:1; transform:translate3d(0,0,0);}}
/* 로딩 문구 옆에 붙는 타이핑 점 3개 — 화면이 멈춘 게 아니라 계속 불러오는 중임을 보여준다. */
.loading-dots{display:inline-flex; gap:3px; margin-left:3px; vertical-align:baseline;}
.loading-dots span{width:4px; height:4px; border-radius:50%; background:currentColor; opacity:.25; animation:loadingDotPulse 1.2s ease-in-out infinite;}
.loading-dots span:nth-child(2){animation-delay:.15s;}
.loading-dots span:nth-child(3){animation-delay:.3s;}
@keyframes loadingDotPulse{0%,60%,100%{opacity:.25; transform:translateY(0);} 30%{opacity:1; transform:translateY(-2px);}}
/* 리스트 로딩 중 스피너+텍스트 대신 실제 카드 모양을 흐릿하게 먼저 보여준다 — 로딩이 끝나도
   레이아웃이 튀지 않는다(uiplaybook.dev/play/motion 스켈레톤 로더 패턴, §design/mono-tone-clean.md). */
.skeleton-avatar,.skeleton-bar{background:linear-gradient(90deg,var(--bg2) 25%,var(--gray-100) 37%,var(--bg2) 63%); background-size:400% 100%; animation:skeletonShimmer 1.4s var(--ease-linear) infinite; border-radius:var(--radius-2xs);}
.skeleton-avatar{width:52px; height:52px; border-radius:50%; flex-shrink:0;}
@keyframes skeletonShimmer{0%{background-position:100% 50%;} 100%{background-position:0 50%;}}
@media(prefers-reduced-motion:reduce){.skeleton-avatar,.skeleton-bar{animation:none;}}
/* 상대 목록 카드 거절(§actions/matching.js confirmMatchReject): 카드가 오른쪽으로 밀려 나가고, 자리는 높이와 아래 여백이 함께 접힌다.
   clip-path는 위아래만 자르고 좌우는 열어 둬서(카드가 화면 밖으로 밀려 나가도록) 접히는 동안 카드 내용이 아래 카드 위로 넘치지 않는다. */
.card-swipe.is-rejecting{
  pointer-events:none;
  clip-path:inset(-6px -120vw 0 -20px);
  transition:height .32s var(--ease-smooth-out) .1s, margin-bottom .32s var(--ease-smooth-out) .1s;
}
.card-swipe.is-rejecting > .match-card{animation:cardRejectOut .3s var(--ease-smooth-out) forwards;}
.card-swipe.is-rejecting .card-swipe-action{opacity:0 !important;transition:opacity .1s;}
@keyframes cardRejectOut{
  from{opacity:1; transform:translateX(0);}
  to{opacity:0; transform:translateX(calc(100% + 40px));}
}
@media(prefers-reduced-motion:reduce){.card-swipe.is-rejecting,.card-swipe.is-rejecting > .match-card{transition:none;animation:none;}}


.bottom-nav{
  /* position:fixed (not sticky) anchored straight to the visual viewport, exactly like
     #chatInputBar below — sticky's "stuck" offset is computed against the flex column's
     height, which is itself driven by 100dvh, and 100dvh changes value the instant the mobile
     browser's address/toolbar chrome hides or reappears (which a tap/scroll right on this bar
     routinely triggers). That recalculation is what looked like "탭을 누르면 화면이 아래로
     꺼지는" — the whole bar (and the section above it) visibly re-settles a beat after the tap.
     position:fixed is computed straight off the real-time visual viewport instead, so it never
     has to "catch up" to a dvh change. */
  position:absolute; left:50%; bottom:calc(14px + env(safe-area-inset-bottom)); transform:translateX(-50%);
  z-index:30; display:flex; align-items:center; max-width:448px; width:calc(100% - 32px);
}
.nav-item{flex:1; min-width:0; display:flex; flex-direction:column; align-items:center; justify-content:center; gap:3px; height:100%; border:none; background:none; color:var(--text-light); font-size:var(--fs-3xs); font-weight:var(--fw-bold); white-space:nowrap; position:relative; transition:opacity .1s ease-out;}
.nav-item .nav-ic{width:22px; height:22px; object-fit:contain; opacity:.5; transition:opacity .1s ease-out;}
.nav-item.active .nav-ic{opacity:1;}
.nav-item.active{color:var(--primary-dark);}
.nav-item:active{opacity:.6;}
.nav-orb .badge{position:absolute; top:-8px; left:14px; background:var(--danger); color:var(--gray-0); font-size:var(--fs-sm); font-weight:var(--fw-bold); min-width:18px; height:18px; border-radius:var(--radius-full); display:flex; align-items:center; justify-content:center; padding:0 5px; animation:badgePulse 2s ease-in-out infinite;}

/* 말풍선 길게 누르기(§actions/chat.js msgPressStart)가 폰에서도 동작하게 브라우저 기본 길게 누르기(글자 선택, iOS 링크
   미리보기)를 끈다 — 글자 복사는 메뉴의 "복사하기"로 한다. 링크는 여전히 눌린다. */
/* 채팅 목록의 프로필 사진(말풍선 옆 아바타, 같은 묶음의 빈 자리, 입력 중 표시가 같은 폭을 쓴다) */
.chat-msg-list{--chat-av:28px;}
/* 사진 없는 글자 아바타는 avatar.js가 글자 수로 font-size를 인라인으로 정해서, 28px에 맞게 덮어쓴다 */
.chat-msg-list .avatar.sm{width:var(--chat-av);height:var(--chat-av);font-size:8px!important;padding:0 2px!important;}
/* 묶음(같은 사람, 10분 안) 안은 목록 gap 2px, 묶음이 바뀌는 첫 줄만 더 띄운다(§screens/chat.js renderChatRoom data-first) */
.chat-msg-list [data-first]{margin-top:10px;}
.chat-msg-list [data-key^="m:"]{-webkit-touch-callout:none;-webkit-user-select:none;user-select:none;}
/* 말풍선 옆 "전송 중"(§screens/chat.js renderBubble). 행이 align-items:flex-end라 말풍선 아래쪽에 정렬된다. */
.msg-meta{display:flex;align-items:center;gap:2px;flex:0 0 auto;font-size:var(--fs-2xs);color:var(--text-light);white-space:nowrap;padding-bottom:3px;}
/* 읽은 자리 얼굴(§screens/chat.js seenFacesHtml): 내 말풍선 왼쪽 아래 16px, 여럿이면 겹치고 +숫자 */
.msg-seen{display:flex;align-items:center;flex:0 0 auto;margin-bottom:3px;}
.chat-msg-list .msg-seen .avatar.sm{width:16px;height:16px;font-size:0!important;color:transparent;border:1.5px solid var(--bg1);box-sizing:content-box;}
.msg-seen .avatar+.avatar{margin-left:-6px;}
button.msg-seen{padding:0;border:none;background:none;cursor:pointer;}
.msg-seen-more{margin-left:2px;padding:0 4px;height:16px;line-height:16px;border-radius:var(--radius-full);background:var(--gray-100);font-size:var(--fs-2xs);font-weight:var(--fw-bold);color:var(--text-mid);}
/* 표정(§actions/chat.js reactToMessage) — 배경 없이 이모지만, 말풍선 오른쪽 위 모서리에 얹힌다(§screens/chat.js bubbleCol). 자리를 차지하지 않아서 표정을 달아도 옆의 시간이 밀리지 않는다 */
.msg-reactions{position:absolute;top:0;left:100%;margin-left:-8px;display:flex;gap:1px;}
.msg-reactions.is-mine{left:auto;right:-6px;margin-left:0;} /* 내 메시지는 오른쪽에 아바타가 있어서 말풍선과 아바타 사이 여백(6px) 안에 들어오게 안쪽으로 당긴다 */
/* 길게 누르기 메뉴 카드(§screens/chat.js messageSheetHtml) — 화면 가운데 흰 카드: 표정 한 줄, 가는 구분선,
   글자만 있는 작업 목록. 딤(center-modal-overlay)을 누르면 닫힌다. 표정은 기기 이모지 글꼴 그대로. */
.msg-menu{width:100%;max-width:280px;border-radius:var(--radius);corner-shape:squircle;background:var(--gray-0);box-shadow:var(--shadow-sm);padding:0 0 6px;animation:modalScaleIn var(--modal-open-dur) var(--ease-smooth-out);}
.center-modal-overlay.closing .msg-menu{animation:modalScaleOut var(--modal-close-dur) var(--ease-smooth-out) forwards;}
.reaction-row{display:flex;justify-content:space-between;align-items:center;padding:10px;border-bottom:1px solid var(--border);margin-bottom:4px;}
.reaction-btn{width:28px;height:28px;border:none;background:none;padding:0;border-radius:50%;cursor:pointer;display:flex;align-items:center;justify-content:center;transition:transform .12s;}
.reaction-btn:active{transform:scale(.86);}
.reaction-btn.is-active{background:var(--gray-200);} /* 내가 누른 표정: 검은 테두리 대신 이모지 아래에 채운 회색 동그라미 */
.reaction-emoji{font-family:"Apple Color Emoji","Segoe UI Emoji","Noto Color Emoji",sans-serif;line-height:1;}
.msg-menu-item{display:block;width:100%;box-sizing:border-box;text-align:left;background:none;border:none;padding:12px 20px;font-family:inherit;font-size:var(--fs-lg);font-weight:var(--fw-regular);color:var(--text);cursor:pointer;}
.msg-menu-item:active{background:var(--bg2);}
.msg-menu-item.danger{color:var(--danger);}
.room-menu-title{padding:16px 20px 8px; font-size:var(--fs-md); font-weight:var(--fw-bold); color:var(--text-mid); white-space:nowrap; overflow:hidden; text-overflow:ellipsis;}
@media(prefers-reduced-motion:reduce){.reaction-btn{transition:none!important;}.msg-menu{animation:none!important;}}

/* ---------- chat room layout ---------- */
/* 채팅방은 문서 전체가 아니라 메시지 영역만 스크롤해야 한다. 입력창은 화면 하단에 고정하고,
   메시지 목록에는 입력창 높이만큼의 여백을 예약해 마지막 메시지가 입력창 바로 위에 오도록 한다. */
.chatroom-main{display:flex; flex-direction:column; overflow:hidden !important; padding-bottom:0 !important;}
/* 대화방은 흰 바탕(아이메시지처럼). 상대 말풍선이 연회색 면이라 회색 바탕 위에서는 묻힌다 */
body:has(.chatroom-main),body:has(.chatroom-main) #root{background:var(--bg1);}
.chatroom-main .chatroom-header{flex:0 0 auto;}
/* 대화방 머리: 바 없이 유리 버튼만 떠 있고, 메시지가 그 밑으로 흐려지며 지나간다(시안 A, X 채팅과 카카오톡 새 대화방 참고).
   머리는 아래로 60px 겹치고(margin-bottom) 그만큼 #msgList 위 여백을 둔다. 흰 그라데이션 부분은 눌림을 통과시킨다 */
.chat-glass-head{display:flex;align-items:center;gap:8px;position:relative;z-index:20;padding:calc(env(safe-area-inset-top) + 10px) 0 22px;margin-bottom:-60px;pointer-events:none;background:linear-gradient(var(--bg1) 62%,rgba(255,255,255,0));}
.chat-glass-head>*{pointer-events:auto;}
.chat-glass{border:none;background:rgba(255,255,255,.72);-webkit-backdrop-filter:blur(18px) saturate(1.6);backdrop-filter:blur(18px) saturate(1.6);box-shadow:inset 0 1px 0 rgba(255,255,255,.9),0 4px 16px rgba(0,0,0,.08),0 0 0 .5px rgba(0,0,0,.06);}
.chat-glass-head .icon-btn{width:44px;height:44px;border-radius:50%;color:var(--text);flex:none;}
.chat-head-pill{margin:0 auto;display:flex;align-items:center;gap:8px;min-width:0;height:44px;padding:4px 14px 4px 5px;border-radius:var(--radius-full);font:inherit;color:inherit;text-align:left;cursor:pointer;}
.chat-head-pill:disabled{cursor:default;opacity:1;}
.chat-head-pill .avatar.sm{width:34px;height:34px;flex:none;font-size:9px!important;padding:0 2px!important;}
.chat-head-text{display:flex;flex-direction:column;min-width:0;line-height:1.25;}
.chat-head-text b{font-size:var(--fs-lg);font-weight:var(--fw-bold);white-space:nowrap;overflow:hidden;text-overflow:ellipsis;}
.chat-head-text small{display:flex;align-items:center;gap:4px;font-size:var(--fs-xs);color:var(--text-light);white-space:nowrap;overflow:hidden;text-overflow:ellipsis;}
/* 접속 중: 매칭 탭 "지금 접속 중"과 같은 검은 점(.online-count) */
.chat-head-text small.is-online{color:var(--text-mid);}
.chat-head-text small.is-online::before{content:"";flex:none;width:6px;height:6px;border-radius:50%;background:var(--gray-900);}
.chat-head-actions{display:flex;gap:8px;flex:none;}
/* 방 안 대화 검색(§actions/chat.js openRoomSearch): 머리 자리에 유리 검색칸, 결과 위아래, 취소 */
.chat-glass-head.is-search{gap:6px;}
.chat-search-pill{flex:1;min-width:0;display:flex;align-items:center;gap:8px;height:44px;padding:0 14px;border-radius:var(--radius-full);color:var(--text-light);}
.chat-search-pill input{flex:1;min-width:0;border:none;outline:none;background:none;font:inherit;font-size:16px;color:var(--text);}
.chat-search-pill input::-webkit-search-cancel-button{display:none;}
.chat-search-pill span{flex:none;font-size:var(--fs-sm);font-weight:var(--fw-bold);color:var(--text-mid);}
.chat-search-cancel{flex:none;padding:0 4px;height:44px;border:none;background:none;font:inherit;font-size:var(--fs-lg);font-weight:var(--fw-bold);color:var(--text);cursor:pointer;}
/* 맨 아래로(§runtime/app-paint-runtime.js syncJump): 입력 바 오른쪽 위에 유리 동그라미. 위를 읽는 중에 새 말이 오면 "새 메시지" 알약으로 늘어난다 */
.chat-jump{position:absolute;right:16px;bottom:calc(100% + 8px);display:flex;align-items:center;gap:4px;height:40px;min-width:40px;padding:0 10px;border-radius:var(--radius-full);color:var(--text);font:inherit;cursor:pointer;opacity:0;transform:translateY(6px) scale(.96);pointer-events:none;transition:opacity 150ms ease-out,transform 200ms var(--ease-smooth-out);}
.chat-jump span{display:none;font-size:var(--fs-sm);font-weight:var(--fw-bold);}
.chat-jump.has-new span{display:inline;}
.chat-jump.is-shown{opacity:1;transform:none;pointer-events:auto;}
@media(prefers-reduced-motion:reduce){.chat-jump{transform:none;}}
/* overflow-anchor:none — 이전 메시지가 위에 끼어들 때의 위치 보정은 §runtime/app-paint-runtime.js patchChatRoom이
   직접 하므로(Safari에는 이 기능이 없다) 브라우저 보정과 겹쳐 두 번 밀리지 않게 끈다. */
.chatroom-main #msgList{flex:1 1 auto; min-height:0; overflow-y:auto; overflow-x:hidden; -webkit-overflow-scrolling:touch; overscroll-behavior-y:contain; overflow-anchor:none; padding:64px 0 96px; margin:0 -8px !important;} /* 양옆 여백 18px를 10px로 */
.chatroom-main #chatInputBar{flex:0 0 auto;}
/* 입력 바에는 배경 상자도 그라데이션도 없다 — +, 입력창, 보내기 버튼만 메시지 목록 위에 떠 있다. */
.chat-input-bar{position:relative;--ease-spring:cubic-bezier(.34,1.7,.64,1);} /* +메뉴(.attach-goo)와 같은 튕김 곡선 */
.chat-input-row{display:flex;align-items:center;padding:10px 18px calc(10px + env(safe-area-inset-bottom));}
.chat-input-row .chat-input-wrap{margin-left:8px;}
/* 보내기 버튼은 글이 있을 때만 나온다(§actions/chat.js autoGrowChatInput이 .has-text를 토글). 자리(slot)가
   0에서 44px로 열리며 입력창을 밀고, 버튼은 --ease-bounce로 튕기듯 커진다. 사라질 땐 더 빠르고 튕김 없이. */
.chat-send-slot{flex:0 0 auto;display:flex;width:0;margin-left:0;transition:width var(--duration-quick) var(--ease-smooth-out),margin-left var(--duration-quick) var(--ease-smooth-out);}
.chat-input-row.has-text .chat-send-slot{width:38px;margin-left:8px;transition-duration:var(--duration-fast);}
.chat-send-slot .chat-send{width:38px;height:38px;opacity:0;transform:scale(.4);visibility:hidden;pointer-events:none;transition:transform var(--duration-quick) var(--ease-smooth-out),opacity var(--duration-quick) var(--ease-smooth-out),visibility 0s linear var(--duration-quick);}
.chat-input-row.has-text .chat-send-slot .chat-send{opacity:1;transform:none;visibility:visible;pointer-events:auto;transition:transform var(--duration-medium) var(--ease-spring),opacity var(--duration-quick) var(--ease-smooth-out),visibility 0s;}
.chat-input-row.has-text .chat-send-slot .chat-send:active{transform:scale(.92);}
/* "+" 메뉴(§screens/chat.js attachGooHtml, 시안 1a). transform과 opacity만 움직인다(docs/animation.md).
   열 때: 항목마다 40ms씩 늦게 + 자리에서 제자리로 살짝 튕기며(--ease-bounce 250ms). 닫을 때: 한꺼번에 150ms로 + 자리로 돌아간다.
   뒤 흐림(.attach-fan-veil)은 position:fixed지만 #chatInputBar에 transform이 있어 입력 바를 기준으로 잡힌다: 입력 바 바닥에서 화면 높이만큼 덮는다 */
.attach-fan{position:relative;width:38px;height:38px;flex-shrink:0;}
.attach-trigger{position:relative;z-index:2;width:38px;height:38px;color:var(--gray-500);transition:transform var(--duration-fast) var(--ease-bounce),background-color 150ms ease,color 150ms ease;}
.attach-fan.open .attach-trigger{transform:rotate(45deg);background:rgba(255,255,255,.85);color:var(--text);}
.attach-fan-veil{position:fixed;left:0;right:0;bottom:0;height:100dvh;z-index:0;background:rgba(214,214,220,.42);-webkit-backdrop-filter:blur(14px) saturate(1.4);backdrop-filter:blur(14px) saturate(1.4);opacity:0;pointer-events:none;transition:opacity 200ms ease-out;}
.attach-fan.open .attach-fan-veil{opacity:1;pointer-events:auto;}
.chat-input-row .chat-input-wrap{position:relative;z-index:1;}
.attach-fan-items{position:absolute;left:19px;top:19px;width:0;height:0;z-index:1;}
.attach-fan-item{position:absolute;left:0;top:0;display:flex;align-items:center;gap:10px;padding:0;border:none;background:none;font:inherit;color:var(--text);cursor:pointer;opacity:0;pointer-events:none;transform:translate(-23px,-50%) scale(.5);transform-origin:23px 50%;transition:transform 150ms var(--ease-smooth-out),opacity 120ms ease-out;}
.attach-fan.open .attach-fan-item{opacity:1;pointer-events:auto;transform:translate(calc(-23px + var(--x)),calc(-50% + var(--y))) scale(1);transition:transform var(--duration-fast) var(--ease-bounce),opacity 150ms ease-out;transition-delay:calc(var(--i) * 40ms);}
.attach-fan-item i{width:46px;height:46px;border-radius:50%;display:grid;place-items:center;flex:none;transition:transform 120ms ease-out;}
.attach-fan-item i.chat-glass{background:rgba(255,255,255,.82);box-shadow:inset 0 1px 0 rgba(255,255,255,.95),0 8px 24px rgba(0,0,0,.16),0 0 0 .5px rgba(0,0,0,.1);}
.attach-fan-item:active i{transform:scale(.94);}
.attach-fan-item span{font-size:var(--fs-lg);font-weight:var(--fw-bold);white-space:nowrap;text-shadow:0 1px 8px rgba(255,255,255,.9);}
/* + 메뉴의 [게임]: 키보드 자리에 여는 게임 칸(게임 피죤의 iMessage 게임 칸처럼). 열려 있으면 +가 돌아가 ✕가 된다 */
.game-drawer{display:none;padding:12px 14px calc(14px + env(safe-area-inset-bottom));background:var(--bg2);border-top:1px solid var(--border);}
.chat-input-bar.game-open .game-drawer{display:block;}
.chat-input-bar.game-open .chat-input-row{padding-bottom:10px;}
.chat-input-bar.game-open .attach-trigger{transform:rotate(45deg);}
.game-drawer-head{display:flex;align-items:baseline;gap:8px;margin:0 2px 10px;}
.game-drawer-head b{font-size:var(--fs-lg);font-weight:var(--fw-bold);color:var(--text);}
.game-drawer-head span{font-size:var(--fs-sm);color:var(--text-mid);}
@media(prefers-reduced-motion:reduce){.attach-fan-item,.attach-fan.open .attach-fan-item{transform:translate(calc(-23px + var(--x)),calc(-50% + var(--y)));transition:opacity 150ms ease-out;transition-delay:0s;}.attach-trigger{transition:background-color 150ms ease,color 150ms ease;}}

/* 글자 꾸미기(시안 나1, §screens/chat.js aaToolbarHtml, §actions/chat.js toggleAaPanel). 토글은 입력칸 안쪽 오른쪽의 회색 Aa
   (textarea가 padding-right로 자리를 비워 둔다). 패널을 연 동안은 같은 자리가 검은 키보드 단추가 된다 */
.chat-input-wrap{position:relative;flex:1;min-width:0;}
.chat-input-wrap textarea{display:block;} /* 인라인이면 아래에 글줄 틈이 생겨 상자가 입력창보다 커지고 Aa가 아래로 처진다 */
/* 닫혀 있으면 알약 없이 Aa 글자만, 열면 검정 알약(대표 확정 10/16, design/aa-pill.png). 누르는 자리 38x30은 그대로 */
.aa-toggle-label{position:absolute;right:8px;top:50%;transform:translateY(-50%);display:grid;place-items:center;height:30px;min-width:30px;padding:0 4px;border:0;border-radius:var(--radius-full);background:transparent;font:inherit;font-size:15px;font-weight:600;letter-spacing:-.02em;color:var(--gray-500);cursor:pointer;line-height:1;}
.aa-toggle-label:active{opacity:.7;}
.aa-toggle-label.is-active{background:var(--gray-900);color:var(--gray-0);}
/* 윗줄 글자 도구는 글자 자체에 효과를 입힌다. 전송된 말풍선은 markdown-it 표준 태그(strong/s)라 여기 클래스는 단추용 */
.md-bold{font-weight:var(--fw-bold);}
.md-underline{text-decoration:underline;text-underline-offset:3px;}
.md-strike{text-decoration:line-through;}
/* 패널: 키보드 자리를 채운다. 높이 --aa-slot은 기억한 키보드 높이(처음 291)에서 지금 키보드가 덮은 만큼을 뺀 값이라(§runtime/chat-input-runtime.js)
   키보드와 맞바꾸는 내내 입력줄은 제자리다. 내용은 위에 붙어 있고 키보드가 비킨 만큼 드러난다. 여는 순간 내용만 120ms 흐리게 들어온다 */
.aa-panel{display:none;box-sizing:border-box;height:var(--aa-slot,var(--aa-kb,291px));padding:14px 12px max(21px,env(safe-area-inset-bottom));background:var(--gray-100);overflow-y:auto;transition:opacity 120ms ease-out;}
.chat-input-bar.aa-open .aa-panel,.chat-input-bar.aa-closing .aa-panel{display:block;}
.chat-input-bar.aa-closing .aa-panel{overflow:hidden;}
@starting-style{.chat-input-bar.aa-open .aa-panel{opacity:0;}}
@media(prefers-reduced-motion:reduce){.aa-panel{transition:none;}}
/* 맨 위 줄: 왼쪽 키보드 아이콘 동그라미 36(글자 없음, 패널 바탕보다 한 단계 진한 회색), 오른쪽 내 말풍선 미리보기(§actions/chat.js aaRefreshPreview) */
.aa-top{display:flex;align-items:center;justify-content:space-between;gap:8px;height:36px;}
.aa-kbd{display:grid;place-items:center;flex:none;width:36px;height:36px;padding:0;border:0;border-radius:50%;background:var(--gray-200);color:var(--gray-900);cursor:pointer;}
.aa-group{margin-top:16px;}
.aa-group+.aa-group{margin-top:14px;}
.aa-label{margin:0 4px 7px;font-size:12px;font-weight:600;color:var(--text-mid);}
/* 흰 카드: 모노 카드와 같은 재질(squircle 18, 아주 옅은 그림자) */
.aa-card{background:var(--gray-0);border-radius:18px;corner-shape:squircle;box-shadow:0 1px 2px rgba(0,0,0,.06);}
/* 모양: 일곱 자리 같은 폭, 동그라미 34 아래 이름 11px. 고른 것은 검정 동그라미와 진한 이름, 빼기 앞 얇은 구분선 */
.aa-tools{display:grid;grid-template-columns:repeat(7,1fr);padding:7px 2px 6px;}
.aa-tool{position:relative;display:flex;flex-direction:column;align-items:center;gap:3px;min-width:0;padding:0;border:0;background:none;font:inherit;font-size:11px;color:var(--text-mid);cursor:pointer;}
.aa-ic{display:grid;place-items:center;width:34px;height:34px;border-radius:50%;color:var(--gray-900);}
.aa-tool.is-on{color:var(--gray-900);font-weight:600;}
.aa-tool.is-on .aa-ic{background:var(--gray-900);color:var(--gray-0);}
.aa-clear::before{content:"";position:absolute;left:0;top:9px;width:1px;height:18px;background:var(--gray-200);}
.aa-glyph{font-family:var(--font-sys);font-size:18px;font-weight:600;line-height:1;}
.aa-glyph.md-underline{text-underline-offset:3px;}
/* 움직임: 같은 크기 다섯 칸 한 줄. 칸의 글자(고른 글자, 없으면 가나다)가 그 효과로 패널을 연 동안 되풀이 */
.aa-cells{display:grid;grid-template-columns:repeat(5,1fr);gap:6px;}
.aa-cell{display:flex;flex-direction:column;align-items:center;justify-content:center;gap:6px;height:76px;min-width:0;padding:0;border:0;font:inherit;font-size:11px;color:var(--text-mid);cursor:pointer;}
.aa-cell.is-on{background:var(--gray-900);color:rgba(255,255,255,.72);}
.aa-cell.is-on .aa-pv{color:var(--gray-0);}
.aa-pv{display:flex;align-items:center;height:26px;max-width:100%;overflow:hidden;font-size:17px;font-weight:600;line-height:1;white-space:nowrap;color:var(--gray-900);}
.aa-pv .md-big{font-size:23px;line-height:1;}
.aa-pv .md-small{font-size:12px;}
.aa-pv .md-shake{display:inline-block;animation:mdShakePreview 2s cubic-bezier(.36,.07,.19,.97) infinite;}
.aa-pv .md-nod{animation-duration:1.6s;animation-iteration-count:infinite;}
.aa-pv .md-wave>span{animation-duration:1.4s;animation-iteration-count:infinite;}
/* 내 말풍선 미리보기: 대화 화면의 내 말풍선과 같은 쪽(오른쪽). 흔들림은 되풀이, 스포일러는 작성자가 읽게 옅게 */
.aa-live-preview{min-width:0;max-width:200px;padding:7px 13px;border-radius:18px 4px 18px 18px;corner-shape:squircle;background:var(--gray-900);color:var(--gray-0);font-size:14px;line-height:1.45;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;}
.aa-live-preview[hidden]{display:none;}
.aa-live-preview p{margin:0;}
.aa-live-preview .md-shake.is-animating{animation:mdShakePreview 2s cubic-bezier(.36,.07,.19,.97) infinite;}
@keyframes mdShakePreview{2.5%,22.5%{transform:translateX(-1px);}5%,20%{transform:translateX(2px);}7.5%,12.5%,17.5%{transform:translateX(-3px);}10%,15%{transform:translateX(3px);}25%,100%{transform:translateX(0);}}
.aa-live-preview .md-spoiler{color:inherit;text-shadow:none;}
.aa-live-preview .md-spoiler::after{opacity:.35;}
@media(prefers-reduced-motion:reduce){.aa-pv .md-shake,.aa-pv .md-nod,.aa-pv .md-wave>span,.aa-live-preview .md-shake.is-animating{animation:none!important;}}

.match-card-info{flex:1;min-width:0}.match-card-bottom{display:flex;flex-wrap:nowrap;align-items:center;justify-content:space-between;gap:clamp(6px,3vw,16px);margin-top:5px}.match-score-lines{display:flex;flex-direction:column;gap:2px;min-width:0;font-size:var(--fs-2xs);line-height:1.35;color:var(--text-mid)}.match-score-lines span{display:block;white-space:nowrap}.match-card-actions{display:flex;flex-wrap:nowrap;align-items:center;justify-content:flex-end;gap:6px;flex-shrink:0}
.mini-bars{display:flex;flex-direction:column;justify-content:center;gap:8px;flex:1;min-width:0;}
.mini-bar-row{display:flex;align-items:center;gap:4px;height:4px;}
.mini-bar-label{font-size:var(--fs-3xs);font-weight:var(--fw-bold);color:var(--text-light);width:18px;white-space:nowrap;flex-shrink:0;}
.mini-bar-track{display:block;flex:1;min-width:18px;height:4px;border-radius:var(--radius-2xs);background:var(--primary-soft);overflow:hidden;box-sizing:border-box;flex-shrink:0;}
.mini-bar-fill{display:block;height:4px;border-radius:var(--radius-2xs);background:var(--gray-600);box-sizing:border-box;}
.mini-bar-pct{font-size:var(--fs-3xs);font-weight:var(--fw-bold);color:var(--text);width:26px;white-space:nowrap;flex-shrink:0;}
.match-card .match-action-btn.compact{min-width:0 !important;padding:0 clamp(8px,2.6vw,14px);font-size:clamp(10.5px,2.8vw,12.5px);}


/* ---------- generic ---------- */
.card{display:block; width:100%; box-sizing:border-box; background:var(--gray-0); border-radius:var(--radius);corner-shape:squircle; padding:18px; box-shadow:var(--shadow-sm); margin-bottom:14px; text-align:left; border:none; font-family:inherit; transition:opacity .15s var(--ease-smooth-out),transform .15s var(--ease-smooth-out);}
/* 채팅 목록(§screens/chat.js renderChatList): 매칭 목록과 같은 납작한 줄. 줄은 화면 끝까지 닿고(본문 좌우 여백 18px만큼 바깥으로),
   구분선은 이름이 시작하는 곳(18px + 사진 48px + 간격 12px)부터 긋는다. 옆으로 밀면 뒤의 나가기, 고정 아이콘이 드러난다. */
.chat-list{margin:4px -18px 0;}
.chat-room-row{position:relative;}
.chat-room-row[hidden]{display:none;}
.chat-room-card{position:relative;display:flex;align-items:center;gap:12px;padding:12px 18px;cursor:pointer;user-select:none;background:transparent;}
.chat-room-row + .chat-room-row .chat-room-card::before{content:"";position:absolute;top:0;left:78px;right:0;height:1px;background:var(--border);pointer-events:none;}
.chat-room-card .avatar{width:48px;height:48px;}
.chat-room-text{flex:1;min-width:0;}
.chat-room-top,.chat-room-bottom{display:flex;align-items:center;justify-content:space-between;gap:8px;}
.chat-room-bottom{margin-top:3px;}
.chat-room-name{display:flex;align-items:center;gap:6px;min-width:0;}
.chat-room-name b{font-size:var(--fs-base);font-weight:var(--fw-bold);color:var(--text);white-space:nowrap;overflow:hidden;text-overflow:ellipsis;min-width:0;}
.chat-room-name small{flex:none;font-size:var(--fs-xs);font-weight:var(--fw-bold);color:var(--text-mid);white-space:nowrap;}
.chat-room-pin{flex:none;display:inline-flex;color:var(--text-light);}
.chat-room-time{flex:none;font-size:var(--fs-xs);color:var(--text-light);}
.chat-room-card:active{background:rgba(0,0,0,.04);}
/* 채팅방 가운데 시간 줄: 날짜가 바뀌면 굵은 날짜와 시간, 1시간 넘게 비면 시간만(§screens/chat.js renderChatRoom) */
.chat-day{align-self:center;margin:14px 0 6px;}
.chat-day span{font-size:var(--fs-xs);color:var(--text-light);}
.chat-day b{font-weight:var(--fw-bold);color:var(--text-mid);}
.chatroom-menu-btn{flex:none;color:var(--gray-700);}
/* 안 읽은 수: 검은 알약(모노톤이라 빨강 대신 명도로 강조). 스타일이 없어 숫자만 보이던 것을 채웠다. */
.chat-room-bottom .badge{flex:none;display:inline-flex;align-items:center;justify-content:center;min-width:18px;height:18px;padding:0 5px;box-sizing:border-box;border-radius:var(--radius-full);background:var(--gray-900);color:var(--gray-0);font-size:var(--fs-2xs);font-weight:var(--fw-bold);font-variant-numeric:tabular-nums;line-height:1;}
.chat-room-preview{min-width:0;font-size:var(--fs-md);color:var(--text-light);white-space:nowrap;overflow:hidden;text-overflow:ellipsis;}
/* 안 읽은 방: 미리보기를 진하게, 시간도 한 단계 진하게(명도로만 강조) */
.chat-room-row.is-unread .chat-room-preview{color:var(--text);font-weight:var(--fw-bold);}
.chat-room-row.is-unread .chat-room-time{color:var(--text-mid);}
/* 채팅 찾기 입력칸 */
.chat-search-empty{margin:28px 0 0;text-align:center;font-size:var(--fs-md);color:var(--text-light);}
/* 좌우로 밀어 나가기/상단 고정을 여는 카드(§actions/chat.js roomPress*). 세로 스크롤만 브라우저에 맡기고 가로 움직임은 우리가 받아야 한다. 이 설정이 없으면(auto) 손가락이 옆으로 움직이는 순간 브라우저가 터치를 가로채 pointercancel이 오고 밀기가 시작도 못 한다. 메시지 줄(§screens/chat.js rowAttrs)은 인라인으로 이미 pan-y다. */
.chat-room-card{touch-action:pan-y;}
.card:active{opacity:.85; transform:scale(.99);}
/* 답장 띠(결정 75, 시안 chat-shelf-v8-2 가, §screens/chat.js replyBannerHtml): 입력칸 위에 떠 있는 흰 카드, 왼쪽 얼굴 동그라미 */
.reply-card{display:flex;align-items:center;gap:10px;margin:0 12px 8px;padding:9px 10px 9px 10px;border-radius:16px;corner-shape:squircle;background:var(--gray-0);box-shadow:0 4px 18px rgba(0,0,0,.08),0 0 0 .5px rgba(0,0,0,.08);}
.reply-card-face{flex:none;display:flex;}
.reply-card-icon{flex:none;display:grid;place-items:center;width:32px;height:32px;border-radius:50%;background:var(--bg2);color:var(--text-mid);}
.reply-card-text{flex:1;min-width:0;display:flex;flex-direction:column;gap:1px;}
.reply-card-text b{font-size:var(--fs-sm);font-weight:var(--fw-bold);color:var(--text);}
.reply-card-text span{font-size:var(--fs-sm);color:var(--text-mid);white-space:nowrap;overflow:hidden;text-overflow:ellipsis;}
.reply-card-x{flex:none;display:grid;place-items:center;width:24px;height:24px;padding:0;border:0;border-radius:50%;background:var(--gray-100);color:var(--text-mid);cursor:pointer;}
/* + 메뉴 동그라미(결정 75, 시안 chat-shelf-v8-3 나): 흰 바탕은 두고 그림자를 줄이고 얇은 테두리 */
.attach-fan-item i.chat-glass{background:rgba(255,255,255,.92);box-shadow:0 2px 10px rgba(0,0,0,.08),0 0 0 .5px rgba(0,0,0,.12);}
.attach-fan-item span .shelf-ai{background:var(--gray-100);text-shadow:none;}

/* 편지(#312 편지 5판, 시안 premium-312.html?s=letter, 값은 LT6_CSS, LT7_CSS). 전체 화면, 상단바까지 덮음 */
.lt-screen{position:fixed;inset:0;z-index:160;background:radial-gradient(120% 70% at 20% 0%,#f3e9e2 0%,transparent 60%),radial-gradient(100% 60% at 90% 100%,#e6e4ee 0%,transparent 65%),#efedea;overflow:hidden;animation:ltIn 240ms ease-out both;}
@keyframes ltIn{from{opacity:0;}}
.lt-top{position:absolute;top:calc(env(safe-area-inset-top) + 8px);left:12px;right:16px;height:44px;display:flex;align-items:center;justify-content:space-between;z-index:3;transition:opacity 200ms;}
.lt-top b{font-size:var(--fs-lg);font-weight:var(--fw-bold);color:var(--text);}
.lt-close{display:grid;place-items:center;width:40px;height:40px;padding:0;border:0;background:none;color:var(--text);cursor:pointer;}
.lt-send{height:36px;padding:0 16px;border:0;border-radius:var(--radius-full);background:var(--gray-900);color:var(--gray-0);font:inherit;font-size:var(--fs-md);font-weight:var(--fw-bold);cursor:pointer;}
.lt-send:disabled{opacity:.4;}
.lt-paper,.lt-under{position:absolute;left:30px;right:30px;top:calc(env(safe-area-inset-top) + 78px);bottom:156px;box-sizing:border-box;border-radius:3px;background:var(--lt-paper);color:var(--lt-ink);}
.lt-paper{z-index:2;display:flex;flex-direction:column;padding:30px 26px 60px;box-shadow:0 1px 1px rgba(0,0,0,.05),0 22px 44px rgba(60,40,20,.12);transition:opacity 200ms;}
.lt-under{left:34px;right:26px;top:calc(env(safe-area-inset-top) + 84px);transform:rotate(-1.6deg);box-shadow:0 1px 2px rgba(0,0,0,.05),0 10px 24px rgba(60,40,20,.08);transition:opacity 200ms;}
.lt-paper.is-lined .lt-txt{background-image:repeating-linear-gradient(transparent 0 30px,rgba(120,100,70,.18) 30px 31px);background-attachment:local;}
.lt-date{margin:0;text-align:right;font-size:13px;color:var(--lt-sub);letter-spacing:.04em;}
.lt-to{margin:18px 0 0;font-size:22px;font-weight:600;letter-spacing:-.01em;}
.lt-txt{flex:1;min-height:0;margin:16px 0 0;padding:0;border:0;outline:none;resize:none;background:transparent;color:inherit;font:inherit;font-size:17px;line-height:31px;white-space:pre-wrap;overflow-y:auto;}
.lt-txt::placeholder{color:var(--lt-sub);}
.lt-from{position:absolute;right:26px;bottom:28px;margin:0;font-size:16px;font-weight:600;}
.lt-time{position:absolute;left:26px;bottom:30px;margin:0;font-size:12px;color:var(--lt-sub);}
.lt-picks{position:absolute;left:0;right:0;bottom:calc(env(safe-area-inset-bottom) + 24px);padding:0 20px;transition:opacity 200ms;}
.lt-ph{margin:0 0 10px;font-size:var(--fs-sm);font-weight:var(--fw-bold);color:var(--text);}
.lt-row{display:flex;justify-content:space-between;}
.lt-pk{display:flex;flex-direction:column;align-items:center;gap:6px;width:56px;padding:0;border:0;background:none;font:inherit;cursor:pointer;}
.lt-pk i{position:relative;width:48px;height:60px;border-radius:3px;box-shadow:0 0 0 .5px rgba(0,0,0,.1),0 2px 6px rgba(0,0,0,.06);transition:transform 160ms ease-out,box-shadow 160ms ease-out;}
.lt-pk em{position:absolute;right:3px;bottom:3px;width:16px;height:16px;border-radius:50%;display:grid;place-items:center;background:rgba(255,255,255,.9);color:var(--text);}
.lt-pk b{font-size:12px;font-weight:var(--fw-regular);color:var(--text-light);}
.lt-pk.is-on i{transform:translateY(-4px);box-shadow:0 0 0 .5px rgba(0,0,0,.12),0 8px 16px rgba(0,0,0,.14);}
.lt-pk.is-on b{font-weight:var(--fw-bold);color:var(--text);}
/* 읽기: 세 칸 접힌 자국, 종이가 올라와 펼쳐짐 */
.lt-paper.is-read{bottom:calc(env(safe-area-inset-bottom) + 60px);background-image:linear-gradient(transparent calc(33.3% - 6px),rgba(90,70,40,.06) 33.3%,rgba(255,255,255,.5) calc(33.3% + 1px),transparent calc(33.3% + 8px),transparent calc(66.6% - 6px),rgba(90,70,40,.06) 66.6%,rgba(255,255,255,.5) calc(66.6% + 1px),transparent calc(66.6% + 8px));transform-origin:50% 0;animation:ltOpen 520ms cubic-bezier(.2,.8,.2,1) both;}
@keyframes ltOpen{0%{opacity:0;transform:translateY(80px) scaleY(.34);}60%{opacity:1;}100%{transform:none;}}
/* 보내기: 쓰기 화면을 걷고 3D 접기(§ui/letter3d.js)를 그 자리에, 끝나면 화면이 흐려지며 대화방으로 */
.lt-stage{position:absolute;inset:0;z-index:4;}
.lt-screen.is-sending .lt-top,.lt-screen.is-sending .lt-picks,.lt-screen.is-sending .lt-under{opacity:0;pointer-events:none;}
.lt-screen.is-sending .lt-paper{opacity:0;transition-delay:120ms;}
.lt-screen.is-done{animation:ltOut 320ms ease-in both;}
@keyframes ltOut{to{opacity:0;transform:scale(.96);}}
/* 대화방 봉투 카드 196x122 */
.lt-card{display:flex;flex-direction:column;gap:6px;padding:0;border:0;background:none;font:inherit;text-align:left;cursor:pointer;}
.lt-card.is-mine{align-items:flex-end;}
.lt-card.is-mine .lt-cap{text-align:right;}
.lt-env{position:relative;display:block;width:196px;height:122px;}
.lt-env i{position:absolute;inset:0;display:block;border-radius:4px;}
.lt-env .e-back{background:#d9c9ad;box-shadow:0 10px 24px rgba(60,40,20,.14);}
.lt-env .e-front{background:#e8dcc6;clip-path:polygon(0 1%,50% 60.5%,100% 1%,100% 100%,0 100%);}
.lt-env .e-flap{height:60%;background:#dfd1b7;clip-path:polygon(0 0,100% 0,50% 100%);}
.lt-env .e-stamp{position:absolute;right:10px;bottom:10px;width:26px;height:32px;padding:3px;box-sizing:border-box;background:#fff;transform:rotate(3deg);box-shadow:0 1px 2px rgba(0,0,0,.14);}
.lt-env .e-stamp img{display:block;width:100%;height:100%;object-fit:cover;}
.lt-env .e-to{position:absolute;left:12px;bottom:12px;font-size:13px;font-weight:600;color:#3a3229;}
.lt-cap{display:flex;flex-direction:column;gap:1px;padding:0 4px;}
.lt-cap b{font-size:var(--fs-md);font-weight:var(--fw-bold);color:var(--text);}
.lt-cap small{font-size:12px;color:var(--text-light);}
@media(prefers-reduced-motion:reduce){.lt-screen,.lt-paper.is-read{animation:none;}}
/* 손가락 뽀뽀(#312, 시안 premium-312.html?s=kiss 13~16차 .v9~.v13, .v16-mark). 전체 화면, 상단바까지 물듦 */
.kiss-screen{position:fixed;inset:0;z-index:160;display:flex;flex-direction:column;overflow:hidden;background:var(--bg1);-webkit-user-select:none;user-select:none;-webkit-touch-callout:none;animation:kissIn 200ms ease-out both;}
@keyframes kissIn{from{opacity:0;}}
.kiss-bloom{position:absolute;inset:0;z-index:0;opacity:var(--o,0);overflow:hidden;pointer-events:none;background:linear-gradient(165deg,#ff7a6b 0%,#ff4d5e 45%,#d23aa6 100%);-webkit-mask:radial-gradient(circle at var(--cx,50%) var(--cy,55%),#000 var(--r,0px),transparent calc(var(--r,0px) + 260px));mask:radial-gradient(circle at var(--cx,50%) var(--cy,55%),#000 var(--r,0px),transparent calc(var(--r,0px) + 260px));}
.kiss-bloom i{position:absolute;border-radius:50%;filter:blur(46px);animation:kissDrift 7s ease-in-out infinite alternate;}
.kiss-bloom i:nth-child(1){width:110%;height:60%;left:-30%;bottom:-12%;background:#ff3d57;}
.kiss-bloom i:nth-child(2){width:100%;height:55%;right:-35%;bottom:8%;background:#c92fb0;animation-duration:9s;animation-direction:alternate-reverse;}
.kiss-bloom i:nth-child(3){width:90%;height:50%;left:10%;top:-14%;background:#ff9a6b;animation-duration:8s;}
.kiss-bloom b{position:absolute;inset:0;opacity:.16;mix-blend-mode:overlay;background:url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='160' height='160'><filter id='n'><feTurbulence type='fractalNoise' baseFrequency='.9' numOctaves='2' stitchTiles='stitch'/></filter><rect width='100%' height='100%' filter='url(%23n)'/></svg>");}
.kiss-bloom.is-beat{animation:kissBeat 300ms ease-out;}
@keyframes kissDrift{to{transform:translate(8%,-6%) scale(1.12);}}
@keyframes kissBeat{40%{transform:scale(1.035);}}
.kiss-flash{position:absolute;left:50%;top:55%;z-index:1;width:260px;height:260px;margin:-130px 0 0 -130px;border-radius:50%;background:radial-gradient(circle,rgba(255,255,255,.95),rgba(255,236,240,.6) 40%,rgba(255,255,255,0) 70%);opacity:0;pointer-events:none;}
.kiss-flash.is-pop{animation:kissFlash 450ms cubic-bezier(.16,1,.3,1);}
@keyframes kissFlash{0%{opacity:1;transform:scale(.7);}100%{opacity:0;transform:scale(3.4);}}
.kiss-stage{position:relative;z-index:2;flex:1;display:flex;flex-direction:column;padding-top:env(safe-area-inset-top);transform-origin:50% 55%;}
.kiss-stage.is-pop{animation:kissShake 420ms linear;}
@keyframes kissShake{16%{transform:translate(-9px,3px) rotate(-1.3deg) scale(1.03);}35%{transform:translate(9px,-3px) rotate(1.3deg) scale(1.03);}54%{transform:translate(-6px,2px) rotate(-.8deg) scale(1.02);}73%{transform:translate(4px,-1px) rotate(.5deg);}90%{transform:translate(-2px,0);}}
.kiss-top{display:flex;align-items:center;justify-content:space-between;flex:none;height:48px;padding:0 8px;}
.kiss-close{display:grid;place-items:center;width:44px;height:44px;padding:0;border:0;background:none;color:var(--gray-900);cursor:pointer;transition:color .4s;}
.kiss-tag{margin-right:10px;height:26px;padding:0 10px;border-radius:var(--radius-full);background:var(--gray-100);color:var(--gray-700);font-size:13px;font-weight:var(--fw-bold);display:inline-flex;align-items:center;transition:background .4s,color .4s;}
.kiss-tag[hidden]{display:none;}
.kiss-head{padding:6px 20px 0;}
.kiss-head h1{margin:0;font-size:30px;font-weight:var(--fw-bold);line-height:1.2;letter-spacing:-.02em;color:var(--gray-900);transition:color .4s;}
.kiss-head p{margin:6px 0 0;font-size:16px;line-height:1.45;letter-spacing:-.01em;color:var(--gray-600);transition:color .4s;}
.kiss-head p.is-swap{animation:kissSwap 320ms ease-out;}
@keyframes kissSwap{from{opacity:0;}}
.kiss-screen.is-on .kiss-head h1,.kiss-screen.is-on .kiss-close{color:#fff;}
.kiss-screen.is-on .kiss-head p{color:rgba(255,255,255,.85);}
.kiss-screen.is-on .kiss-tag{background:rgba(255,255,255,.22);color:#fff;}
.kiss-pad{position:relative;flex:1;touch-action:none;}
.kiss-at{position:absolute;width:0;height:0;pointer-events:none;}
.kiss-at[hidden]{display:none;}
.kiss-fp{position:absolute;left:-40px;top:-40px;width:80px;height:80px;}
.kiss-fp-svg{display:block;width:80px;height:80px;}
.kiss-fp.is-me{color:var(--gray-900);transition:color .4s;}
.kiss-screen.is-on .kiss-fp.is-me{color:#fff;}
.kiss-fp.is-you{filter:drop-shadow(0 6px 14px rgba(226,60,120,.3));}
.kiss-ring{position:absolute;width:96px;height:96px;left:-48px;top:-48px;border-radius:50%;box-shadow:0 0 0 1.5px rgba(26,26,26,.35);opacity:0;}
.kiss-ring.is-you{box-shadow:0 0 0 1.5px rgba(226,60,120,.55);}
/* 손을 대면 그 자리에 톡 맺히고 고리 한 겹, 쿵쿵마다 지문도 같이 뜀 */
.kiss-at.is-new .kiss-fp{animation:kissDrop 320ms cubic-bezier(.34,1.56,.64,1);}
.kiss-at.is-new .kiss-ring{animation:kissRing 600ms cubic-bezier(.16,1,.3,1);}
.kiss-at.is-beat .kiss-fp{animation:kissThump 300ms ease-out;}
@keyframes kissDrop{0%{transform:scale(.4);opacity:0;}60%{transform:scale(1.08);opacity:1;}}
@keyframes kissRing{0%{transform:scale(.4);opacity:.9;}100%{transform:scale(2.1);opacity:0;}}
@keyframes kissThump{40%{transform:scale(1.14);}}
/* 다 물들면 하트가 풍선처럼 부풀며 떨다가(0.8초) 팡: 하트 모양 그대로의 입자 220개와 빛살 여덟 줄 */
.kiss-burst{position:absolute;width:0;height:0;pointer-events:none;}
.kiss-heart{position:absolute;width:150px;height:150px;left:-75px;top:-75px;opacity:0;filter:drop-shadow(0 18px 30px rgba(120,0,40,.35));}
.kiss-burst.is-inflate .kiss-heart{animation:kissInflate 800ms both;}
.kiss-burst.is-pop .kiss-heart{opacity:0;}
@keyframes kissInflate{0%{transform:scale(0);opacity:0;}37%{transform:scale(.92);opacity:1;animation-timing-function:cubic-bezier(.34,1.56,.64,1);}46%{transform:scale(1) rotate(0);}56%{transform:scale(1.07,1.03) rotate(-1.5deg);}65%{transform:scale(1.1,1.13) rotate(1.5deg);}74%{transform:scale(1.18,1.15) rotate(-2deg);}80%{transform:scale(1.2,1.24) rotate(2deg);}86%{transform:scale(1.28,1.25) rotate(-2.5deg);}100%{transform:scale(1.34);opacity:1;}}
.kiss-dots{position:absolute;left:0;top:0;}
.kiss-dot{position:absolute;left:0;top:0;width:var(--z);height:var(--z);margin:calc(var(--z) / -2) 0 0 calc(var(--z) / -2);border-radius:50%;background:var(--c);opacity:0;}
.kiss-spark{position:absolute;left:-1.5px;top:-11px;width:3px;height:22px;border-radius:2px;background:#fff;opacity:0;rotate:var(--a);}
.kiss-burst.is-pop .kiss-dot{animation:kissDot 1.2s linear both;}
.kiss-burst.is-pop .kiss-spark{animation:kissSpark 550ms cubic-bezier(.16,1,.3,1) both;}
@keyframes kissDot{0%{translate:calc(var(--x)*1.3) calc(var(--y)*1.3);scale:1;opacity:0;}2%{opacity:1;animation-timing-function:cubic-bezier(.16,1,.3,1);}60%{translate:calc(var(--x)*1.95) calc(var(--y)*1.95 + 10px);scale:.8;opacity:.9;animation-timing-function:ease-in;}100%{translate:calc(var(--x)*2.15) calc(var(--y)*2.15 + 40px);scale:.3;opacity:0;}}
@keyframes kissSpark{0%{translate:0 0;scale:1 0;opacity:0;}5%{opacity:1;}55%{translate:calc(sin(var(--a)) * 120px) calc(cos(var(--a)) * -120px);scale:1 1;opacity:.9;}100%{translate:calc(sin(var(--a)) * 150px) calc(cos(var(--a)) * -150px);scale:1 0;opacity:0;}}
@media(prefers-reduced-motion:reduce){.kiss-screen,.kiss-screen *{animation:none!important;}}
/* 대화방 카드: 열린 판(기다리는 중, 들어가기), 끝난 판(뽀뽀 자국 / 연속 N번, 3D 하트가 왼쪽 위로 52px -10도) */
.kiss-card{display:flex;align-items:center;gap:10px;padding:10px 12px 10px 10px;border:0;border-radius:20px;background:var(--bg2);font:inherit;text-align:left;color:var(--text);cursor:pointer;}
.kiss-card b{display:block;font-size:var(--fs-md);font-weight:var(--fw-bold);}
.kiss-card small{font-size:var(--fs-xs);color:var(--text-mid);}
.kiss-card.is-over{cursor:default;opacity:.7;}
.kiss-card-ic{flex:none;width:36px;height:36px;border-radius:50%;background:var(--gray-0);display:grid;place-items:center;color:var(--text);}
.kiss-card-ic .kiss-fp-svg{width:22px;height:22px;}
.kiss-live-dot{display:inline-block;width:6px;height:6px;margin:0 5px 1px 0;border-radius:50%;background:var(--gray-900);vertical-align:middle;}
.kiss-go{flex:none;margin-left:4px;height:30px;padding:0 12px;border-radius:var(--radius-full);background:var(--gray-900);color:var(--gray-0);font-size:var(--fs-sm);font-weight:var(--fw-bold);display:inline-flex;align-items:center;}
.kiss-card.is-mark{position:relative;gap:12px;padding:11px 16px 11px 64px;min-height:62px;box-sizing:border-box;background:var(--gray-100);overflow:visible;cursor:default;}
.kiss-card.is-mark img{position:absolute;left:8px;top:-9px;width:52px;height:52px;rotate:-10deg;filter:drop-shadow(0 4px 6px rgba(160,20,60,.22));}
.kiss-card.is-mark b{font-size:var(--fs-lg);line-height:1.3;}
.kiss-card.is-mark small{display:block;margin-top:1px;font-size:var(--fs-sm);}
/* 멘트 추천 다(대기열 22, design/ai-ment.html?s=d 5판 값 그대로): 대화 끝 나만 보는 카드(§ui/ai-ment-card.js) */
.mt-wrap{margin:14px 0 14px;}
.mt-c{position:relative;padding:12px 10px 14px 16px;border-radius:22px;corner-shape:squircle;background:var(--bg2);}
.mt-c::before{content:"";position:absolute;left:0;top:14px;bottom:14px;width:3px;border-radius:0 3px 3px 0;background:var(--gray-800);}
.mt-ch{display:flex;align-items:center;gap:6px;height:30px;padding-right:2px;color:var(--text);}
.mt-ch b{font-size:var(--fs-md);font-weight:var(--fw-bold);}
.mt-ai{display:inline-flex;align-items:center;height:18px;padding:0 6px;border-radius:999px;background:var(--gray-100);color:var(--text-mid);font-style:normal;font-size:10px;font-weight:var(--fw-bold);}
.mt-ch .mt-left{margin-left:auto;margin-right:4px;font-size:var(--fs-sm);color:var(--text-light);}
.mt-ic{flex:none;width:32px;height:32px;padding:0;border:0;border-radius:50%;display:grid;place-items:center;background:none;cursor:pointer;}
.mt-ic{color:var(--text);}
/* 6판: 글은 카드 왼쪽 선 하나, 제목 한 줄, 값 단추(무료, 20C)는 고지 줄 오른쪽 검정 알약 */
.mt-lead{margin:8px 0 0;font-size:var(--fs-xl);line-height:1.45;font-weight:var(--fw-bold);letter-spacing:-.02em;color:var(--text);white-space:nowrap;overflow:hidden;text-overflow:ellipsis;}
.mt-fine{display:flex;gap:6px;margin:10px 10px 0 0;font-size:var(--fs-sm);line-height:1.5;color:var(--text-mid);}
.mt-fine svg{flex:none;margin-top:3px;}
.mt-act{display:flex;align-items:flex-end;gap:14px;margin-top:10px;}
.mt-act .mt-fine{flex:1;margin:0;font-size:var(--fs-xs);}
.mt-go{flex:none;display:inline-flex;align-items:center;gap:5px;height:36px;padding:0 15px 0 12px;border:0;border-radius:999px;background:var(--gray-900);color:var(--gray-0);font:inherit;font-size:15px;font-weight:600;cursor:pointer;}
.mt-go:active{transform:scale(.92);}
.mt-list{display:flex;flex-direction:column;gap:0;margin-top:2px;}
.mt-li{display:flex;align-items:flex-start;gap:6px;padding:12px 2px 12px 0;}
.mt-li+.mt-li{border-top:.5px solid var(--gray-200);}
.mt-li p{flex:1;margin:0;font-size:var(--fs-lg);line-height:1.5;color:var(--text);}
.mt-n{flex:none;min-width:16px;margin-top:1px;font-size:var(--fs-md);font-weight:var(--fw-bold);color:var(--text-light);text-align:center;}
/* 10/17: 줄 전체가 단추(누르면 입력창에), 아래 안내 한 줄 */
button.mt-li{width:100%;margin:0;border:0;border-radius:0;background:none;font:inherit;text-align:left;color:inherit;cursor:pointer;-webkit-tap-highlight-color:transparent;}
button.mt-li:active p{color:var(--text-mid);}
.mt-list+.mt-fine{margin-top:2px;font-size:var(--fs-xs);}
/* 8판: 받는 중 번호와 회색 막대 두 줄(글 두 줄 줄 높이에 맞춰 받기 전후 카드 높이가 같게), 머리 오른쪽 "고르는 중"은 회색 글자에 빛이 지나감(Meta AI Show thinking) */
.mt-sk .mt-n{color:var(--gray-300);}
.mt-bars{flex:1;display:flex;flex-direction:column;padding:0 40px 0 0;}
.mt-bars i{display:block;height:12px;margin:calc((var(--fs-lg) * 1.5 - 12px) / 2) 0;border-radius:7px;background:linear-gradient(90deg,var(--gray-200) 25%,var(--gray-100) 50%,var(--gray-200) 75%);background-size:300% 100%;animation:mtSk 1.4s linear infinite;}
.mt-bars i+i{width:62%;}
.mt-ic-ph{flex:none;width:32px;height:32px;}
.mt-status{font-weight:600;background:linear-gradient(90deg,var(--gray-400) 35%,var(--gray-900) 50%,var(--gray-400) 65%);background-size:300% 100%;-webkit-background-clip:text;background-clip:text;color:transparent!important;animation:mtSk 1.6s linear infinite;}
@keyframes mtSk{from{background-position:100% 0;}to{background-position:0 0;}}
/* 받으면 줄이 0.2초 간격으로 흐림에서 올라옴 */
.mt-list.is-in .mt-li{animation:mtLine 420ms cubic-bezier(.2,.8,.2,1) both;}
.mt-list.is-in .mt-li:nth-child(2){animation-delay:200ms;}
.mt-list.is-in .mt-li:nth-child(3){animation-delay:400ms;}
@keyframes mtLine{from{opacity:0;transform:translateY(6px);filter:blur(4px);}}
@media(prefers-reduced-motion:reduce){.mt-bars i,.mt-status,.mt-list.is-in .mt-li{animation:none;}.mt-status{color:var(--text-light)!important;background:none;}}
.mt-only{display:flex;align-items:center;gap:5px;margin:8px 10px 0 16px;font-size:var(--fs-xs);color:var(--text-light);}
.mt-only button{margin-left:auto;padding:0;border:0;background:none;font:inherit;font-weight:var(--fw-bold);color:var(--text-mid);cursor:pointer;}
/* 반짝이 단추(진입): Aa 왼쪽 30px, 평소 회색, 상대가 마지막으로 말했으면 검정과 점 */
.ai-ment-spark{position:absolute;right:50px;top:50%;transform:translateY(-50%);width:30px;height:30px;padding:0;border:0;background:none;display:grid;place-items:center;color:var(--gray-500);cursor:pointer;}
.ai-ment-spark i{display:none;}
.ai-ment-spark.on{color:var(--gray-800);}
.ai-ment-spark.on i{display:block;position:absolute;top:4px;right:3px;width:6px;height:6px;border-radius:50%;background:var(--gray-800);box-shadow:0 0 0 1.5px var(--bg1);}
.chat-input-wrap:has(.ai-ment-spark:not([hidden])) textarea{padding-right:84px!important;}
/* 칸 안 오른쪽 아이콘(대표 10/18, frontend-queue 38 시안 2c564aa0): 왼쪽부터 반짝이, Aa, 스티커. 30px 칸, 오른쪽에서 60, 34, 8(가운데 간격 26px), 색 gray-500, 선 1.6 */
.ai-ment-spark{right:60px;}
.st-toggle{position:absolute;right:8px;top:50%;transform:translateY(-50%);width:30px;height:30px;padding:0;border:0;background:none;display:grid;place-items:center;color:var(--gray-500);cursor:pointer;}
/* 판이 열린 키보드 단추도 회색, 열린 Aa만 검정 알약 */
.chat-input-wrap:has(.st-toggle) .aa-toggle-label{right:34px;}
.chat-input-wrap:has(.st-toggle) textarea{padding-right:72px!important;}
.chat-input-wrap:has(.st-toggle):has(.ai-ment-spark:not([hidden])) textarea{padding-right:98px!important;}
/* 판: 키보드 자리 흰 판, 손잡이, 아이콘 탭, 칸 바탕 없는 4열 */
.sticker-drawer{display:none;}
.chat-input-bar.sticker-open .sticker-drawer{display:block;}
.st-ks{box-sizing:border-box;height:var(--aa-kb,291px);padding:6px 12px max(21px,env(safe-area-inset-bottom));background:var(--bg1);box-shadow:0 -.5px 0 rgba(0,0,0,.08);display:flex;flex-direction:column;overflow:hidden;}
@starting-style{.chat-input-bar.sticker-open .st-ks{transform:translateY(100%);}}
.st-ks{transition:transform 240ms var(--ease-smooth-out);}
.st-grab{align-self:center;width:36px;height:4px;border-radius:2px;background:var(--gray-200);margin-bottom:8px;flex:none;}
.st-tabs{display:flex;align-items:center;gap:6px;flex:none;margin:0 0 6px;}
.st-tab{width:40px;height:34px;padding:0;border:0;border-radius:999px;display:grid;place-items:center;background:none;color:var(--text-mid);cursor:pointer;}
.st-tab.on{background:var(--gray-100);color:var(--text);}
.st-grid{display:grid;grid-template-columns:repeat(4,1fr);row-gap:6px;overflow-y:auto;overscroll-behavior:contain;}
.st-cell{display:grid;place-items:center;height:72px;padding:0;border:0;border-radius:14px;background:none;cursor:pointer;}
.st-cell:active{transform:scale(.88);}
.st-empty{margin:24px 0 0;text-align:center;font-size:var(--fs-sm);color:var(--text-light);}
.st-img{display:block;object-fit:contain;mix-blend-mode:multiply;}
/* 고른 스티커: 입력칸 위 밝은 회색 유리 카드 208x168, 별 즐겨찾기, X 닫기 */
#stickerPreview{position:relative;height:0;}
.st-pv{position:absolute;left:50%;bottom:8px;transform:translateX(-50%);width:208px;height:168px;border-radius:18px;background:rgba(236,236,239,.9);box-shadow:0 8px 28px rgba(0,0,0,.12);-webkit-backdrop-filter:blur(18px) saturate(1.3);backdrop-filter:blur(18px) saturate(1.3);display:grid;place-items:center;z-index:27;animation:stPop 320ms var(--ease-smooth-out) both;}
.st-pv-star,.st-pv-x{position:absolute;top:8px;width:30px;height:30px;padding:0;border:0;background:none;display:grid;place-items:center;color:var(--gray-700);cursor:pointer;}
.st-pv-star{left:8px;}.st-pv-x{right:8px;}
/* 대화 속 스티커: 말풍선 없이 그림만 132. 막 보낸 것만 톡 */
.st-msg{display:block;}
.st-msg.is-new{animation:stPopIn 320ms var(--ease-smooth-out) both;transform-origin:100% 100%;}
@keyframes stPop{0%{opacity:0;transform:translateX(-50%) scale(.6);}60%{opacity:1;transform:translateX(-50%) scale(1.04);}100%{transform:translateX(-50%) scale(1);}}
@keyframes stPopIn{0%{opacity:0;transform:scale(.6);}60%{opacity:1;transform:scale(1.04);}100%{transform:scale(1);}}
@media(prefers-reduced-motion:reduce){.st-ks{transition:none;}.st-pv,.st-msg.is-new{animation:none;}}

/* 같이 그리기 남긴 판 카드(#312, 시안 .v6-dcard 정사각): 그림과 왼쪽 아래 두 사람 사진 "같이 그림" */
.draw-card{position:relative;display:block;width:210px;height:210px;border-radius:20px;overflow:hidden;background:#fffefb;box-shadow:0 0 0 .5px rgba(0,0,0,.12),0 2px 8px rgba(0,0,0,.05);}
.draw-card-img{display:block;width:100%;height:100%;object-fit:cover;}
.draw-by{position:absolute;left:8px;bottom:8px;display:flex;align-items:center;gap:6px;height:28px;padding:0 10px 0 4px;border-radius:var(--radius-full);background:rgba(255,255,255,.88);box-shadow:0 0 0 .5px rgba(0,0,0,.08);font-size:12px;font-weight:var(--fw-bold);color:var(--text);}
.draw-faces{display:flex;}
.draw-faces i{width:20px;height:20px;border-radius:50%;overflow:hidden;display:grid;place-items:center;background:var(--gray-200);font-style:normal;font-size:10px;}
.draw-faces i+i{margin-left:-6px;box-shadow:0 0 0 1.5px #fff;}
.draw-faces img{width:100%;height:100%;object-fit:cover;display:block;}

/* 쓰는 동안 접기와 여러 줄(대표 10/18, frontend-queue 38, 시안 2c564aa0 design/chat-collapse.html). 1:1과 단체 같은 줄.
   .is-typing(한 자라도 있음)이면 칸 안 사진과 반짝이를 줄이며 흐리고, +는 보이는 폭 14px의 > 로 접는다(누르는 자리 44x44).
   > 를 누르면 .is-open으로 + 가 돌아온다. 모션은 SwiftUI 기본 스프링(반응 .35s, 감쇠 .82)을 linear()로 0.38초 */
.chat-input-row{--spring-ios:linear(0,0.0228,0.0805,0.1598,0.2505,0.3452,0.4385,0.5269,0.6082,0.6809,0.7448,0.7997,0.8462,0.8847,0.9163,0.9416,0.9615,0.9769,0.9885,0.997,1.003,1.0069,1.0094,1.0107,1.0111,1.0109,1.0103,1.0095,1.0085,1.0074,1);position:relative;padding-left:12px;padding-right:12px;}
.chat-input-row.has-text .chat-send-slot{margin-left:6px;}
.attach-fan,.attach-trigger,.attach-chev,.chat-input-row .chat-input-wrap,.chat-input-face,.ai-ment-spark,.chat-input-wrap textarea{transition-timing-function:var(--spring-ios);}
.attach-fan{transition:width .38s var(--spring-ios);}
.chat-input-row .chat-input-wrap{transition:margin-left .38s var(--spring-ios);}
.attach-trigger{transition:transform .38s var(--spring-ios),opacity .38s var(--spring-ios),filter .38s var(--spring-ios),background-color 150ms ease,color 150ms ease;}
.attach-chev{position:absolute;left:-12px;top:-3px;z-index:3;width:44px;height:44px;padding:0 0 0 7px;border:0;background:none;display:grid;align-items:center;justify-items:start;color:var(--gray-500);cursor:pointer;opacity:0;filter:blur(4px);transform:scale(.5);pointer-events:none;transition:transform .38s var(--spring-ios),opacity .38s var(--spring-ios),filter .38s var(--spring-ios);}
.chat-input-face,.ai-ment-spark{transition:transform .38s var(--spring-ios),opacity .38s var(--spring-ios),filter .38s var(--spring-ios);}
.chat-input-wrap textarea{transition:padding .38s var(--spring-ios);}
.chat-input-row.is-typing:not(.is-open) .attach-fan{width:14px;}
.chat-input-row.is-typing:not(.is-open) .chat-input-wrap{margin-left:4px;}
.chat-input-row.is-typing:not(.is-open) .attach-trigger{opacity:0;filter:blur(4px);transform:rotate(-90deg) scale(.6);pointer-events:none;}
.chat-input-row.is-typing:not(.is-open) .attach-chev{opacity:1;filter:none;transform:none;pointer-events:auto;}
.chat-input-row.is-typing .chat-input-face{opacity:0;filter:blur(4px);transform:scale(.5);pointer-events:none;}
.chat-input-row.is-typing .ai-ment-spark{opacity:0;filter:blur(4px);transform:translateY(-50%) scale(.5);pointer-events:none;}
.chat-input-row.is-typing .chat-input-wrap.has-face #chatInput,.chat-input-row.is-typing .chat-input-wrap.has-face #partyInput{padding-left:14px!important;}
.chat-input-row.is-typing .chat-input-wrap:has(.st-toggle) textarea{padding-right:72px!important;}
/* 여러 줄: >, 보내기, 칸 안 아이콘은 아래 줄에 붙는다. 입력 줄 뒤 흰 판 대신 화면 아래쪽만 부드럽게 흐려지는 막(줄 높이 + 34px) */
.chat-input-row{align-items:flex-end;}
.chat-input-row .attach-fan,.chat-input-row .chat-send-slot{margin-bottom:3px;}
.chat-input-wrap :is(.aa-toggle-label,.st-toggle,.ai-ment-spark,.chat-input-at){top:auto;bottom:7px;transform:none;}
.chat-input-wrap .chat-input-at{height:30px;}
.chat-input-row.is-typing .ai-ment-spark{transform:scale(.5);}
.chat-input-row::before{content:"";position:absolute;left:0;right:0;bottom:0;top:-34px;z-index:-1;pointer-events:none;background:linear-gradient(to bottom,rgba(255,255,255,0),rgba(255,255,255,.82) 45%,var(--bg1) 75%);-webkit-backdrop-filter:blur(6px);backdrop-filter:blur(6px);-webkit-mask:linear-gradient(to bottom,transparent,#000 40%);mask:linear-gradient(to bottom,transparent,#000 40%);}
@media(prefers-reduced-motion:reduce){
  .attach-trigger,.attach-chev,.chat-input-face,.ai-ment-spark{filter:none!important;transition:opacity .2s ease!important;}
  .chat-input-row.is-typing:not(.is-open) .attach-trigger,.attach-chev{transform:none!important;}
  .chat-input-row.is-typing .chat-input-face{transform:none;}
  .chat-input-row.is-typing .ai-ment-spark{transform:none;}
  .attach-fan,.chat-input-row .chat-input-wrap,.chat-input-wrap textarea{transition:none!important;}
}
/* grouped settings list: several rows in ONE card (one shadow, one radius) instead of a
   separate .card per row — much less vertical weight, so screens like mypage fit without
   scrolling on typical phone heights. */
.list-card{background:var(--gray-0); border-radius:var(--radius);corner-shape:squircle; box-shadow:var(--shadow-sm); margin-bottom:12px; overflow:hidden;}
.list-row{display:flex; align-items:center; justify-content:space-between; gap:10px; width:100%; padding:13px 16px; background:none; border:none; text-align:left; font-family:inherit; color:inherit; transition:opacity .15s var(--ease-smooth-out);}
.list-row:not(:last-child){border-bottom:1px solid var(--border);}
.list-row:active{opacity:.6;}
.list-row .menu-row{font-weight:var(--fw-bold); font-size:var(--fs-md);}
.notif-row{display:flex; gap:12px; align-items:flex-start; width:100%; padding:14px; border-radius:var(--radius-lg);corner-shape:squircle; background:var(--bg2); border:none; text-align:left; font-family:inherit; color:inherit; transition:opacity var(--duration-quick) var(--ease-smooth-out), transform var(--duration-quick) var(--ease-smooth-out);}
.notif-row:active{opacity:.6; transform:scale(.98);}
.notif-avatar{width:40px; height:40px; border-radius:50%; flex-shrink:0; position:relative;}
.notif-avatar .avatar, .notif-avatar .avatar-photo{width:40px; height:40px;}
.notif-avatar .notif-type-badge{position:absolute; right:-3px; bottom:-3px; width:18px; height:18px; border-radius:50%; background:var(--gray-0); box-shadow:var(--shadow-sm); display:flex; align-items:center; justify-content:center; color:var(--primary-dark);}
/* mypage: grouped list rows used to stack one-per-line and ran long enough that the page
   needed scrolling on typical phone heights — that extra scroll is also what made the page's
   height (and with it 100dvh-driven elements) visibly resettle right after opening the tab.
   A 2-up grid of short cards fits the same items in about half the vertical space. */
/* icon-옆-텍스트(가로) 배치 — 아이콘 위에 글자를 쌓는 세로 배치보다 카드 높이가 훨씬 낮아져서
   2열 그리드 전체가 스크롤 없이 한 화면에 들어온다. */
.mypage-card{display:flex;flex-direction:row;align-items:center;justify-content:flex-start;gap:9px;background:var(--gray-0);border-radius:var(--radius-sm);corner-shape:squircle;box-shadow:var(--shadow-sm);padding:10px 12px;border:none;text-align:left;font-family:inherit;color:inherit;transition:opacity var(--duration-quick) var(--ease-smooth-out),transform var(--duration-quick) var(--ease-smooth-out);width:100%;height:76px;min-height:76px;max-height:76px;box-sizing:border-box;align-self:stretch}
.mypage-card{cursor:pointer;}
.mypage-card:active{opacity:.6; transform:scale(.97);}
.mypage-card .mypage-card-ic{width:32px;height:32px;border-radius:var(--radius-xs);corner-shape:squircle;background:var(--primary-soft);display:flex;align-items:center;justify-content:center;color:var(--primary-dark);flex-shrink:0}.mypage-card .mypage-card-label{font-weight:var(--fw-bold);font-size:var(--fs-md);line-height:1.3;min-width:0;text-align:left}.mypage-card .mypage-card-sub{font-size:var(--fs-2xs);line-height:1.3;color:var(--text-light);font-weight:var(--fw-bold);text-align:left}.mypage-account-grid{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:12px;margin-top:4px}.mypage-account-card{display:flex;align-items:center;justify-content:center;gap:7px;min-height:50px;padding:12px 10px;border:0;border-radius:var(--radius-lg);corner-shape:squircle;background:var(--gray-0);box-shadow:var(--shadow-sm);font:inherit;font-size:var(--fs-md);font-weight:var(--fw-bold);color:var(--text);cursor:pointer}.mypage-account-card.danger{color:var(--danger)}.mypage-account-card:active{opacity:.65;transform:scale(.98)}
.title-lg{font-size:var(--fs-4xl); font-weight:var(--fw-bold); margin:6px 0 4px;}
.title-md{font-size:var(--fs-2xl); font-weight:var(--fw-bold); margin:0 0 10px;}
.sub{color:var(--text-mid); font-size:var(--fs-md); line-height:1.5; margin:0 0 18px;}
/* 버튼 높이는 세 단계(design/mono-tone-clean.md §9): 넓은 버튼 50, 팝업과 시트의 두 버튼 줄 44, 작은 알약 32. 선이 있는 버튼도 테두리 대신 안쪽 그림자로 선을 그려 높이가 같다(1.5px 테두리는 화면에서 반올림돼 1px씩 어긋났다) */
.btn{display:block; width:100%; text-align:center; padding:16px 14px; line-height:18px; border-radius:var(--radius-full); border:none; font-weight:var(--fw-bold); font-size:var(--fs-lg); transition:opacity .15s var(--ease-smooth-out),transform .15s var(--ease-smooth-out);}
.btn:disabled{opacity:.32;cursor:not-allowed;transform:none;}
.btn:active{opacity:.75; transform:scale(.98);}
.btn-primary{background:var(--gray-900); color:var(--gray-0);}
.btn-primary:disabled{opacity:.45;}
/* 버튼은 모두 알약. 중요도는 모양이 아니라 채움으로 나눈다(검정 > 회색 > 글자만, design/mono-tone-clean.md §7) */
.btn-outline{background:var(--gray-100); color:var(--primary-dark);}
.btn-ghost{background:none; color:var(--text-mid); font-weight:var(--fw-bold);}
.btn-ghost:active{background:rgba(0,0,0,.05); border-radius:var(--radius-full);}
.btn-sm{width:auto; padding:7px 14px; font-size:var(--fs-md); display:inline-block;}
.field{margin-bottom:16px;}
.field label{display:block; font-size:var(--fs-sm); font-weight:var(--fw-bold); color:var(--text-mid); margin-bottom:7px;}
/* 필터 시트의 그룹 선택기(전체/남자/여자/기타)는 .field 안에 있어서 위 라벨 규칙이 네 개 label에 얹혔다 — 위저드와 같은 모양으로 되돌린다. */
.field .group-categories label{margin:0; font-weight:var(--fw-regular);}
.field input[type=text],.field input[type=search],.field input[type=email],.field input[type=password],.field input[type=number],.field input[type=tel],.field input[type=time],.field select{
  width:100%; padding:13px 14px; border-radius:var(--radius-sm);corner-shape:squircle; border:1.5px solid var(--border); background:var(--gray-0); font-size:var(--fs-xl); color:var(--text); outline:none;
  transition:border-color .12s;
}
.auth-field-label-row .auth-code-button{display:inline-block;width:auto;flex:0 0 auto;padding:7px 11px;font-size:var(--fs-sm);}
.field input:focus,.field select:focus{border-color:var(--primary);}
/* 고르기 칸은 휴대폰 기본 상자 모양 대신 다른 입력칸과 같게, 오른쪽에 아래 꺾쇠 하나(누르면 휴대폰 기본 목록은 그대로) */
.field select{-webkit-appearance:none;appearance:none;padding-right:40px;background:var(--gray-0) url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' viewBox='0 0 24 24' fill='none' stroke='%238e8e93' stroke-width='2.2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='m6 9 6 6 6-6'/%3E%3C/svg%3E") no-repeat right 14px center;}
.field select:invalid,.field select:has(option[value=""]:checked){color:var(--text-light);}
.hint{font-size:var(--fs-sm); color:var(--text-light); margin-top:6px;}
/* 그룹/임관 자동완성(§screens/auth.js groupSearchFieldHtml·memberSearchFieldHtml, §actions/
   auth-profile.js renderGroupSuggestions·renderMemberSuggestions) — 아이폰 텍스트 자동완성처럼
   입력칸 바로 아래 조용한 텍스트 한두 줄만 보여준다. 카드/그림자/아이콘 없이 배경조차
   투명하다가, 눌리는 순간에만 살짝 배경이 들어온다. */
/* 자동완성으로 확정됐거나(§actions/auth-profile.js wizPickGroup/wizPickMember) 입력값이
   기존 그룹·임관과 정확히 같아 자동 확정된 상태(§screens/auth.js groupSearchFieldHtml)를
   아주 옅게만 표시한다 — 흑백 톤을 벗어나는 색이나 칩 없이, 작은 체크 글자 하나만. */
/* width/height/overflow:hidden을 명시적으로 고정해서, 아이콘 svg가 무슨 이유로든 자기
   칸보다 커지는 일이 있어도 입력창 밖으로 튀어나가지 않고 이 16x16 상자 안에서 잘리게
   막아 둔다. */
.field-resolved-mark{position:absolute;right:14px;top:50%;transform:translateY(-50%);width:16px;height:16px;display:flex;align-items:center;justify-content:center;color:var(--text-mid);pointer-events:none;overflow:hidden;}
.field-resolved-mark svg{width:100%;height:100%;}
/* 기존 목록과 안 맞는 자유 입력(§actions/auth-profile.js updateFieldResolvedMark) — 여전히
   진행은 되니 경고색(빨강)까지는 아니고, 체크보다 한 단계 옅은 색으로만 구분한다. */
.field-unresolved-mark{color:var(--text-light);}
/* 그룹/임관 검색칸의 placeholder 글자만 1px 더 줄인다 — 입력칸 자체(실제 타이핑되는 글자)의
   font-size는 iOS가 포커스 시 자동으로 화면을 확대하는 걸 막기 위해 16px을 유지해야 해서
   (§screens/auth.js groupSearchFieldHtml 주석) 손대지 않고, ::placeholder 가상요소만 별도로
   줄인다. */
#groupSearchInput::placeholder,#memberSearchInput::placeholder,#customMemberInput::placeholder{font-size:var(--fs-lg);}
/* 자동완성 후보를 세로 목록이 아니라 입력칸 폭만큼 가로로 나열되는 태그 줄로 보여준다 —
   가운데 정렬하고, 입력칸 폭 오른쪽 밖으로 넘치는 태그는 잘리는 자리를 그라데이션으로
   흐릿하게 처리해서 "더 있다"는 걸 암시한다(mask-image, 오른쪽에만 — 왼쪽은 필요 없다는
   요청). overflow-x:auto라 실제로 가로 스크롤도 되고, 태그 줄 아래로 스크롤바가 그대로
   보인다(숨기지 않음) — 그 자리를 가리지 않게 아래쪽에 패딩을 살짝 둔다. */
.quiet-suggest{display:flex;flex-wrap:nowrap;justify-content:center;gap:6px;overflow-x:auto;overflow-y:hidden;margin-top:6px;padding:2px 0 8px;-webkit-overflow-scrolling:touch;mask-image:linear-gradient(to right,black 0,black calc(100% - 14px),transparent 100%);-webkit-mask-image:linear-gradient(to right,black 0,black calc(100% - 14px),transparent 100%);}
/* 태그 전체 폭이 입력칸 폭보다 넓어 넘칠 때는(§renderSuggestBox가 매김) 가운데 정렬 대신
   왼쪽 정렬로 바꾼다 — 안 넘칠 때만 가운데가 자연스럽다. */
.quiet-suggest.is-overflowing{justify-content:flex-start;}
.quiet-suggest:empty{display:none;}
/* renderGroupSuggestions/renderMemberSuggestions(§actions/auth-profile.js)가 타이핑마다
   이 목록의 innerHTML을 통째로 새로 그리므로, 개별 항목에 등장 애니메이션을 걸면 키를 칠
   때마다 매번 다시 재생돼 깜빡이는 것처럼 보였다 — 그래서 항목 자체엔 애니메이션을 주지
   않는다(요구사항: 자동완성 렌더링 깜빡임 수정). 대신 목록이 "비어있다가 생기거나(is-enter)
   있다가 완전히 없어질 때만(is-exit)" §renderSuggestBox가 컨테이너 전체에 트랜지션 토큰
   기반 fade+scale을 태운다 — 타이핑 중 후보가 다른 후보로 바뀌는 보통의 경우는 그대로
   애니메이션 없이 즉시 바뀌어서 깜빡임 버그가 다시 생기지 않는다. */
@keyframes quietSuggestBoxIn{from{opacity:0;transform:scale(.97);}to{opacity:1;transform:scale(1);}}
@keyframes quietSuggestBoxOut{from{opacity:1;transform:scale(1);}to{opacity:0;transform:scale(.97);}}
.quiet-suggest.is-enter{animation:quietSuggestBoxIn var(--duration-quick) var(--ease-smooth-out);}
.quiet-suggest.is-exit{animation:quietSuggestBoxOut var(--duration-quick) var(--ease-smooth-out) forwards;}
@media(prefers-reduced-motion:reduce){.quiet-suggest.is-enter,.quiet-suggest.is-exit{animation:none!important;}}
.quiet-suggest-item{flex:0 0 auto;display:inline-flex;align-items:center;white-space:nowrap;padding:7px 13px;border:none;border-radius:var(--radius-full);background:var(--bg2);font-family:inherit;font-size:var(--fs-md);color:var(--text-mid);transition:background-color .18s ease,color .18s ease;}
.quiet-suggest-item:active{background:var(--border);color:var(--text);}
/* 검색 결과 태그를 누르면 그 자리에서 바로 선택 상태로 바뀐다(다른 칸에 새 칩이 생기는
   게 아니라) — 커지거나 튀는 애니메이션 없이 배경/글자색만 전환한다(§actions/
   navigation-matching.js filterToggleGroup류). */
.quiet-suggest-item.selected{background:var(--gray-800);color:var(--gray-0);}
.quiet-suggest-item.selected:active{background:var(--gray-800);color:var(--gray-0);opacity:.8;}
/* "많이 선택된 그룹" — Transitions.dev "Text states swap" 패턴(§ui/popular-group-hint.js).
   높이를 고정해 글자 길이가 바뀌어도 아래가 밀리지 않게 하고, 한 줄로만 흐르게 해서
   (white-space:nowrap+ellipsis) 넓게 벌어져도 가로로 화면이 흔들리지 않는다. 입력칸
   바로 다음, 자동완성 태그 줄(§quiet-suggest)보다 앞자리에 둔다(§screens/auth.js
   groupSearchFieldHtml/prefStepGroupMembers) — 그래야 태그 줄이 나타나거나 애니메이션과
   함께 접힐 때(quietSuggestBoxIn/Out) 그 높이 변화가 힌트보다 "뒤"에서만 일어나서 힌트
   자신의 위치는 입력칸 높이에만 의존해 흔들리지 않는다. */
.popular-group-hint{display:flex;flex-direction:column;align-items:center;justify-content:center;gap:4px;height:44px;margin-top:14px;max-width:100%;overflow:hidden;}
.popular-group-label{flex:0 0 auto;font-size:var(--fs-sm);color:var(--text-light);}
.popular-group-name{flex:0 0 auto;max-width:100%;display:inline-flex;align-items:center;justify-content:center;padding:8px 10px;margin:-8px -10px;border:none;background:none;font-family:inherit;font-size:var(--fs-xl);font-weight:var(--fw-bold);color:var(--text-mid);text-decoration:underline;text-decoration-color:var(--text-light);text-underline-offset:2px;transition:text-decoration-color .15s ease,color .15s ease;}
.popular-group-name:focus-visible{color:var(--text);text-decoration-color:var(--text-mid);}
/* 터치 기기는 누른 뒤 :hover가 남아 색이 바뀐 채로 멈추므로, 마우스가 있을 때만 적용한다. */
@media(hover:hover){.popular-group-name:hover{color:var(--text);text-decoration-color:var(--text-mid);}}
.popular-group-name .t-text-swap{max-width:100%;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;}
:root{--text-swap-dur:150ms;--text-swap-translate-y:4px;--text-swap-blur:2px;--text-swap-ease:ease-in-out;}
.t-text-swap{display:inline-block;transform:translateY(0);filter:blur(0);opacity:1;transition:transform var(--text-swap-dur) var(--text-swap-ease),filter var(--text-swap-dur) var(--text-swap-ease),opacity var(--text-swap-dur) var(--text-swap-ease);will-change:transform,filter,opacity;}
.t-text-swap.is-exit{transform:translateY(calc(var(--text-swap-translate-y) * -1));filter:blur(var(--text-swap-blur));opacity:0;}
.t-text-swap.is-enter-start{transform:translateY(var(--text-swap-translate-y));filter:blur(var(--text-swap-blur));opacity:0;transition:none;}
@media(prefers-reduced-motion:reduce){.t-text-swap{transition:none!important;}}
/* Notice 트리거(§groupInfoNoticeTriggerHtml) — 이제 "다음" 버튼 바로 위, 아이콘+"Notice"
   글자로 된 알약 모양 버튼이다. 누르면 배경 딤 없이 그 위로 작은 흰 팝오버가 뜬다
   (§App.toggleGroupInfoNotice/closeGroupInfoNotice). 화면 아래쪽이라 다른 입력칸을 가릴
   일이 없어서 화면 경계에 맞춰 위치/너비를 계산하지 않고 트리거 왼쪽에 그냥 띄운다.
   본문 글자는 아이폰에서도 안 깨지는 선에서 가장 작게(10.5px) 줄였다. X 클릭, 바깥 클릭,
   10초 경과 중 무엇이든 먼저 닫힌다. */
.group-info-wrap{position:relative;display:flex;justify-content:flex-start;margin-bottom:8px;}
.group-info-notice{display:inline-flex;align-items:center;gap:5px;margin:0;padding:6px 12px;border:none;border-radius:var(--radius-full);background:var(--bg2);color:var(--text-mid);font-size:var(--fs-xs);font-weight:var(--fw-bold);font-family:inherit;}
.group-info-notice:active{background:var(--border);}
.group-info-popover{position:absolute;left:0;bottom:calc(100% + 8px);transform:translateY(4px) scale(var(--tt-scale));transform-origin:bottom left;width:min(220px,80vw);max-height:min(280px,70vh);box-sizing:border-box;padding:12px 14px;background:var(--gray-0);border-radius:var(--radius-sm);corner-shape:squircle;box-shadow:var(--shadow-sm);opacity:0;pointer-events:none;text-align:left;z-index:20;overflow-y:auto;transition:opacity var(--tt-out-dur) var(--tt-out-ease),transform var(--tt-out-dur) var(--tt-out-ease);}
.group-info-popover.is-open{opacity:1;pointer-events:auto;transform:translateY(0) scale(1);transition:opacity var(--tt-in-dur) var(--tt-in-ease) var(--tt-delay),transform var(--tt-in-dur) var(--tt-in-ease) var(--tt-delay);}
/* 코너에 position:absolute로 겹치되, 문구 전체에 오른쪽 여백을 주지는 않는다 — 모든
   줄이 똑같이 좁아져 버튼 근처가 아닌 줄까지 오른쪽이 휑하게 비었다. 대신 float:right로
   띄워서 버튼과 겹치는 첫 줄만 자연스럽게 둘러 흐르고, 나머지 줄은 원래 폭을 그대로
   쓴다. */
.group-info-popover-close{float:right;margin:-4px -4px 0 4px;display:flex;align-items:center;justify-content:center;width:22px;height:22px;padding:0;border:none;border-radius:50%;background:none;color:var(--text-light);}
.group-info-popover-close:active{background:var(--bg2);color:var(--text-mid);}
.group-info-popover p{margin:0;font-size:var(--fs-2xs);line-height:1.6;color:var(--text-mid);}
@media(prefers-reduced-motion:reduce){.group-info-popover{transition:none!important;}}
.trait-live-hint{font-size:var(--fs-2xs); font-weight:var(--fw-bold); color:var(--text-light); text-align:center; margin:1px 0 8px;}
/* hidden 속성을 display:none 대신 visibility:hidden으로 바꿔서, 슬라이더를 중앙값 밖으로
   움직여도 이 줄이 차지하던 공간이 사라지지 않게 한다 — 공간이 없어지면 드래그 중에
   아래 슬라이더가 위로 튀어 올라 보이는 문제(레이아웃이 밀리는 것)가 있었다. */
.trait-live-hint[hidden]{display:block!important; visibility:hidden;}
.error-text{font-size:var(--fs-sm); color:var(--danger); margin-top:6px; font-weight:var(--fw-bold); animation:inputShake .35s ease-in-out;}
@keyframes inputShake{10%,90%{transform:translateX(-1px);}20%,80%{transform:translateX(2px);}30%,50%,70%{transform:translateX(-3px);}40%,60%{transform:translateX(3px);}}
@media(prefers-reduced-motion:reduce){.error-text{animation:none;}}
/* transitions-dev "Error state shake" — 내 MBTI 슬라이더를 중앙값에 놓으려 하면(§actions/
   auth-profile.js wizGuardMbtiMedian, §actions/profile.js guardMbtiMedian) 값을 옆 칸으로
   튕겨내면서 이 줄 전체를 흔들어 "여기 그대로 두면 안 돼요"를 알려준다. */
.slider-row.trait-row-shake,.trait-dots.trait-row-shake{animation:t-trait-shake calc(var(--shake-dur-a) * 2 + var(--shake-dur-b) * 2) linear;}
@keyframes t-trait-shake{
  0%      { transform:translateX(0); animation-timing-function:var(--shake-ease); }
  28.57%  { transform:translateX(var(--shake-distance)); animation-timing-function:var(--shake-ease); }
  57.14%  { transform:translateX(calc(var(--shake-distance) * -1)); animation-timing-function:var(--shake-ease); }
  78.57%  { transform:translateX(var(--shake-overshoot)); animation-timing-function:var(--shake-ease); }
  100%    { transform:translateX(0); }
}
@media(prefers-reduced-motion:reduce){.slider-row.trait-row-shake,.trait-dots.trait-row-shake{animation:none!important;}}
.chip-row{display:flex; flex-wrap:wrap; gap:8px;}
/* 칩은 단체 분류 칩(.group-chip)과 같은 모양 하나: 높이 32 회색 채움, 고르면 검정 채움(design/mono-tone-clean.md §7, §9). 흰 바탕 테두리 칩과 시트, 마법사 안 38 칩을 없앰 */
.chip{display:inline-flex; align-items:center; justify-content:center; min-height:32px; padding:0 14px; border:0; border-radius:var(--radius-full); background:var(--bg2); font-size:var(--fs-md); font-weight:var(--fw-bold); line-height:1.2; color:var(--gray-600); transition:opacity .15s var(--ease-smooth-out),transform .15s var(--ease-smooth-out),background-color .32s cubic-bezier(.4,0,.2,1),border-color .32s cubic-bezier(.4,0,.2,1),color .22s ease;}
.chip:active{opacity:.75; transform:scale(.95);}
.chip.selected{background:var(--gray-900); color:var(--gray-0);}
/* 그룹·임관 칩을 고르거나 해제할 때 gooey 느낌 — 색이 툭 바뀌는 대신(위 background-color
   전환으로 스며들고) 칩 자체가 눌린 방향으로 찌부러졌다가 반대로 늘어나며 제자리를 찾는
   squash & stretch. §actions/auth-profile.js gooChip이 누른 칩에만 클래스를 다시 붙여
   재생한다 — 선택·해제 양쪽 다 같은 동작이라 방향 구분 없이 한 키프레임으로 충분하다. */
@keyframes chipGoo{0%{transform:scale(1);} 28%{transform:scale(1.12,.86);} 56%{transform:scale(.94,1.07);} 78%{transform:scale(1.03,.98);} 100%{transform:scale(1);}}
.chip.chip-goo{animation:chipGoo .46s cubic-bezier(.4,0,.2,1);}
@media(prefers-reduced-motion:reduce){.chip.chip-goo{animation:none;} .chip{transition:none;}}
.divider{height:1px; background:var(--border); margin:18px 0;}
.avatar{width:52px;height:52px;border-radius:50%; display:flex;align-items:center;justify-content:center; font-weight:var(--fw-bold); color:var(--gray-0); font-size:var(--fs-2xl); flex-shrink:0;}
.avatar.lg{width:84px;height:84px; font-size:26px;}
.avatar.sm{width:28px;height:28px; font-size:var(--fs-xs);}
.progress-wrap{display:flex; gap:5px; margin-bottom:22px;}
.progress-seg{flex:1; height:5px; border-radius:var(--radius-2xs); background:var(--border);}
.progress-seg.done{background:var(--gray-800);}
.toast-wrap{position:fixed; bottom:calc(env(safe-area-inset-bottom) + 96px); left:50%; transform:translateX(-50%); z-index:200; display:flex; flex-direction:column-reverse; gap:8px; width:calc(100% - 40px); max-width:440px; pointer-events:none; align-items:center;}
.toast{display:flex; align-items:center; gap:7px; max-width:100%; padding:7px 15px; border-radius:var(--radius-full); background:rgba(26,26,26,.78); -webkit-backdrop-filter:blur(20px) saturate(180%); backdrop-filter:blur(20px) saturate(180%); color:var(--gray-0); font-size:var(--fs-md); font-weight:var(--fw-bold); line-height:1.4; box-shadow:0 10px 30px -10px rgba(0,0,0,.45); animation:toastIn var(--toast-open) var(--ease-smooth-out); pointer-events:auto; cursor:pointer;}
.toast svg{flex:none; width:15px; height:15px; opacity:.9;}
@media(prefers-reduced-transparency:reduce){.toast{background:var(--gray-800); -webkit-backdrop-filter:none; backdrop-filter:none;}}
.toast.closing{animation:toastOut var(--toast-close) var(--ease-smooth-out) forwards;}
.toast-text{min-width:0;}
.toast-action{flex:none; margin-right:-4px; padding:2px 4px; border:0; background:none; color:var(--gray-400); font:inherit; cursor:pointer;}
@keyframes toastIn{from{opacity:0; transform:translateY(var(--toast-distance)) scale(var(--toast-scale));} to{opacity:1; transform:translateY(0) scale(1);}}
@keyframes toastOut{from{opacity:1; transform:translateY(0) scale(1);} to{opacity:0; transform:translateY(var(--toast-distance)) scale(var(--toast-scale));}}
@media(prefers-reduced-motion:reduce){.toast,.toast.closing{animation:none!important;}}
.sheet-overlay{position:fixed; inset:0; background:rgba(0,0,0,.35); z-index:100; display:flex; align-items:flex-end; justify-content:center; animation:fadeIn .2s ease;}
.sheet{background:var(--bg1); width:100%; max-width:480px; border-radius:var(--radius-xl) var(--radius-xl) 0 0;corner-shape:squircle; padding:20px 18px calc(20px + env(safe-area-inset-bottom)); max-height:88vh; max-height:calc(100dvh - 64px - env(safe-area-inset-top,0px)); overflow-y:auto; animation:sheetUp .25s cubic-bezier(.25,.9,.35,1);}
@keyframes sheetUp{from{transform:translateY(30px); opacity:.6;} to{transform:translateY(0); opacity:1;}}
.sheet-overlay.closing,.center-modal-overlay.closing{animation:fadeOut .2s ease forwards;}
.sheet-overlay.closing .sheet{animation:sheetDown .2s cubic-bezier(.25,.9,.35,1) forwards;}
@keyframes fadeOut{from{opacity:1;} to{opacity:0;}}
@keyframes sheetDown{from{transform:translateY(0); opacity:1;} to{transform:translateY(30px); opacity:.6;}}
/* 시트는 기본으로 화면 가운데 팝업으로 뜬다(모달과 같은 크기 변화 모션). 아래에서 올라오는 방식은 매칭 필터와 신고만(.sheet-bottom) 남긴다.
   아래 버튼 줄(.sheet-actions)은 팝업에서 안전 영역을 뺀 여백에 맞춘다. */
.sheet-overlay:not(.sheet-bottom){align-items:center;padding:24px 16px;}
.sheet-overlay:not(.sheet-bottom) .sheet{max-width:440px;border-radius:var(--radius-xl);corner-shape:squircle;padding-bottom:20px;max-height:calc(100dvh - 48px - env(safe-area-inset-top,0px) - env(safe-area-inset-bottom,0px));box-shadow:var(--shadow);animation:modalScaleIn var(--modal-open-dur) var(--ease-smooth-out);}
.sheet-overlay.closing:not(.sheet-bottom) .sheet{animation:modalScaleOut var(--modal-close-dur) var(--ease-smooth-out) forwards;}
.sheet-overlay:not(.sheet-bottom) .sheet-handle{display:none;}
/* 누르는 영역(44px): 보이는 크기는 그대로 두고 투명한 영역만 넓힌다. 위치 기준(position)은 원래 값이 없을 때만 준다(:where는 우선순위 0).
   표정 반응처럼 촘촘히 붙은 버튼은 옆 버튼을 덮지 않게 세로로만 넓힌다. */
:where(.duo-howto-x,.duo-howto-link,.duo-stepper button,.duo-seg button,.duo-code-b,.duo-code-ic,.duo-color,.duo-tool,.duo-idea,.duo-accuse,.duo-yb-p,.reaction-btn,.group-info-popover-close,.legal-modal-head .icon-btn,.match-action-btn,.ob-sheet-x,.ob-back,.wizard-back,.auth-form-back,.fb-back,.fb-x,.tap-44){position:relative;}
:is(.duo-howto-x,.duo-howto-link,.duo-stepper button,.duo-seg button,.duo-code-b,.duo-code-ic,.duo-color,.duo-tool,.duo-idea,.duo-accuse,.duo-yb-p,.reaction-btn,.group-info-popover-close,.wizard-step-hint-close,.legal-modal-head .icon-btn,.home-q-close,.match-action-btn,.ob-sheet-x,.ob-back,.wizard-back,.auth-form-back,.fb-back,.fb-x,.tap-44)::before{content:"";position:absolute;left:50%;top:50%;width:max(100%,44px);height:max(100%,44px);transform:translate(-50%,-50%);}
/* 세로로만 넓히는 덮어쓰기는 위 :is 규칙(.legal-modal-head .icon-btn 때문에 클래스 둘 무게)보다 무거워야 먹어서 부모를 붙인다.
   그림 도구막대 색 동그라미도 5px 간격이라 같은 방식이다 */
.reaction-row .reaction-btn::before,.duo-toolbar .duo-color::before{width:100%;}
.sheet-overlay:not(.sheet-bottom) .sheet-actions{bottom:-20px;margin-bottom:-20px;padding-bottom:12px;}
/* 시트 아래쪽 버튼 줄: 스크롤 위치와 상관없이 하단에 떠 있다가, 끝까지 내리면 원래 자리(맨 아래)에 놓인다. 음수 마진은 시트의 아래 패딩(20px + 안전 영역)을 메워 항상 하단에 붙게 한다. */
.sheet-actions{position:sticky;bottom:calc(-20px - env(safe-area-inset-bottom));z-index:2;display:grid;grid-template-columns:1fr 1fr;gap:10px;margin:0 -18px calc(-20px - env(safe-area-inset-bottom));padding:22px 18px calc(12px + env(safe-area-inset-bottom));background:linear-gradient(to top,var(--bg1) 68%,transparent);}
.sheet-actions .btn{padding:13px;font-size:var(--fs-base);}
.sheet-handle{width:40px; height:5px; background:var(--border); border-radius:var(--radius-2xs); margin:0 auto 14px;}
/* AI 멘트 도우미(§actions/ai-ment.js): 켜지기 전엔 숨긴다. 안내 3개는 누르는 것이 아니라 읽는 글이라 버튼 모양 없이 회색 칸 */
[data-ai-ment][hidden]{display:none !important;}
.ai-ment-ideas{list-style:none; margin:0 0 12px; padding:0; display:flex; flex-direction:column; gap:8px;}
.ai-ment-idea{padding:12px 14px; border-radius:var(--radius-sm); corner-shape:squircle; background:var(--bg2); color:var(--text); font-size:var(--fs-md); line-height:1.5; user-select:text;}
.segmented{display:flex; background:var(--primary-soft); border-radius:var(--radius-full); padding:4px;}
.segmented button{flex:1; border:none; background:none; padding:10px 0; border-radius:var(--radius-full); font-weight:var(--fw-bold); font-size:var(--fs-md); color:var(--primary-dark); transition:opacity .15s var(--ease-smooth-out),transform .15s var(--ease-smooth-out),background-color .2s var(--ease-smooth-out);}
.segmented button.active{background:var(--gray-0); box-shadow:var(--shadow-sm);}
.segmented button:active{opacity:.8; transform:scale(.96);}
.match-tag{font-size:var(--fs-2xs); font-weight:var(--fw-bold); padding:3px 9px; border-radius:var(--radius-full);}
.match-tag.exact{background:var(--gray-800); color:var(--gray-0);}
.match-tag.high{background:var(--gray-500); color:var(--gray-0);}
.match-tag.low{background:var(--primary-soft); color:var(--text-mid);}
.slider-row{margin-bottom:20px; min-height:38px;}
/* 성격, MBTI 라벨: PM 확정 시안 09 Satin Aluminium(2026-10-15)의 라벨 줄 그대로. 가운데 화살표 없이 양 끝에 두 낱말만 둔다.
   명도는 값(--v, 1~7)을 따라 연속으로 바뀐다. 가까운 쪽은 진하게(알파 .92), 먼 쪽은 흐리게(.37). 끄는 동안 손가락을 따라 부드럽게 바뀌도록 --v는 §ui/trait-slider.js가 .slider-row에 맞춘다. */
.slider-row .labels{--v:4;display:flex;justify-content:space-between;align-items:center;gap:8px;width:100%;font-size:12px;font-weight:490;letter-spacing:-.05em;color:#abb1b5;margin-bottom:11px;}
.slider-row .labels .trait-axis{display:none;}
.slider-row .labels>span{white-space:nowrap;transition:color .2s ease,opacity .2s ease;}
.slider-row .labels>[data-trait-side="left"]{color:rgb(33 38 43 / calc(.37 + .55 * (7 - var(--v)) / 6));}
.slider-row .labels>[data-trait-side="right"]{text-align:right;color:rgb(33 38 43 / calc(.37 + .55 * (var(--v) - 1) / 6));}
/* MBTI 글자 배지: 괄호 대신 동그란 배지로 글자를 단어 바깥쪽에 두어 좌우 대칭을 맞춘다. 색은 span의 명도를 그대로 따르고, 위아래 음수 여백으로 줄 높이를 늘리지 않아 성격 카드와 높이가 같다. */
.trait-letter{display:inline-flex; align-items:center; justify-content:center; width:18px; height:18px; margin:-4px 5px -4px 0; border-radius:50%; background:var(--gray-100); font-size:var(--fs-2xs); vertical-align:middle;}
[data-trait-side="right"] .trait-letter{margin:-4px 0 -4px 5px;}
.slider-row input[type=range]{display:block; width:100%; margin:0; accent-color:var(--primary-dark); height:6px;}
/* 이상형 나이 범위(§screens/auth.js prefStepAge) — 슬라이더 두 개를 같은 자리에 겹쳐서
   하나의 트랙에 동그라미 두 개가 있는 것처럼 보이게 한다. 각 input 자체의 트랙은
   투명하게 지우고 손잡이(thumb)만 보이게 해서, 뒤에 깔린 .dual-range-track/-fill이
   실제로 보이는 트랙 역할을 한다. 손잡이 자체는 일반 슬라이더(§.slider-row
   input[type=range]의 accent-color:var(--primary-dark))가 네이티브로 그리는 손잡이와
   같은 색·모양(진한 색 원)이 되도록 맞췄다 — 흰 배경에 테두리를 두르는 대신 단색 원으로. */
/* 2026-10-15: 나이 범위도 성격 패널(§.trait-panel) 안에 둔다. 레일과 손잡이는 성격 슬라이더(시안 09)와 같고, 고른 범위는 레일 위 가는 그래파이트 선으로 보인다.
   채움(.dual-range-fill)은 손잡이 중심이 오가는 칸(.dual-range-rail, 양쪽 3px + 손잡이 반지름 14.5px 안쪽) 기준 퍼센트라 선 끝이 손잡이 가운데에 맞는다.
   입력 상자는 44px로 키워 손잡이 위아래 어디를 잡아도 잡힌다. 손잡이만 눌리고 나머지는 겹친 다른 입력으로 지나간다 */
.dual-range{position:relative; height:29px; margin:2px 0 6px;}
.dual-range-track{position:absolute; left:3px; right:3px; top:50%; height:8px; margin-top:-4px; border-radius:40px; background:linear-gradient(#b9bec1,#ededed,#afb5b9); box-shadow:inset 0 1px 3px #7e878c66,0 1px 0 rgba(255,255,255,.85);}
.dual-range-rail{position:absolute; left:17.5px; right:17.5px; top:50%; height:2px; margin-top:-1px; pointer-events:none;}
.dual-range-fill{position:absolute; top:0; bottom:0; border-radius:1px; background:rgba(41,43,46,.55);}
.dual-range-input{position:absolute; left:3px; right:3px; top:50%; width:calc(100% - 6px); height:44px; margin:-22px 0 0; background:none; -webkit-appearance:none; appearance:none; pointer-events:none; -webkit-tap-highlight-color:transparent;}
.dual-range-input::-webkit-slider-runnable-track{background:transparent; height:44px;}
.dual-range-input::-webkit-slider-thumb{-webkit-appearance:none; appearance:none; pointer-events:auto; width:27px; height:27px; margin-top:7.5px; border-radius:50%; border:1px solid #9ba2a7; background:linear-gradient(180deg,rgba(255,255,255,.32),rgba(255,255,255,0) 48%,rgba(40,44,48,.05)),conic-gradient(from 0deg,#ddd,#aab1b4,#fefefe,#939da2,#efefef,#a3aaad,#ddd); box-shadow:inset 0 0 0 1px rgba(255,255,255,.42),0 1px 1px rgba(40,44,48,.16),0 2px 5px #66666640; cursor:grab;}
.dual-range-input::-moz-range-track{background:transparent; height:44px; border:none;}
.dual-range-input::-moz-range-thumb{pointer-events:auto; width:27px; height:27px; border-radius:50%; border:1px solid #9ba2a7; background:linear-gradient(180deg,rgba(255,255,255,.32),rgba(255,255,255,0) 48%,rgba(40,44,48,.05)),conic-gradient(from 0deg,#ddd,#aab1b4,#fefefe,#939da2,#efefef,#a3aaad,#ddd); box-shadow:inset 0 0 0 1px rgba(255,255,255,.42),0 1px 1px rgba(40,44,48,.16),0 2px 5px #66666640; cursor:grab;}
.dual-range-input:focus-visible::-webkit-slider-thumb{outline:3px solid #9aaebc; outline-offset:2px;}
.trait-value-slot{position:relative; display:flex; align-items:center; min-height:26px;}
/* 탭 전환에서 슬라이더↔"상관없음"이 바뀔 때의 크로스페이드(§actions/profile.js crossfadeSliderSlots).
   나가는 쪽(ghost)은 150ms로 빠르게, 들어오는 쪽은 250ms로 여유 있게. */
.trait-slot-ghost{position:absolute; inset:0; display:flex; align-items:center; pointer-events:none; animation:traitSlotOut var(--duration-quick) var(--ease-smooth-out) forwards;}
.trait-slot-in{animation:traitSlotIn var(--duration-fast) var(--ease-smooth-out);}
@keyframes traitSlotIn{from{opacity:0; transform:scale(.94);} to{opacity:1; transform:none;}}
@keyframes traitSlotOut{from{opacity:1; transform:none;} to{opacity:0; transform:scale(.94);}}
.trait-value-slot input[type=range]{flex:1;}
/* 성격, MBTI 슬라이더(§ui/trait-slider.js): PM 확정 시안 09 Satin Aluminium(2026-10-15, 노션 PM 할 일 "성격 테스트 진입 화면과 결과 확인 화면 시안").
   레일과 손잡이 값은 시안 원본(.slider-unit, .satin)을 그대로 옮겼다. 레일은 8px 브러시드 실버 그라데이션, 손잡이는 27px 매트 실버(원뿔 그라데이션 금속 결).
   레일 칸(.trait-range-wrap)은 시안의 .rail-wrap과 같은 26px 높이, 좌우 3px 여백이다. 읽기 전용(마이페이지, 상세, 상대 프로필)도 같은 모습이고 누를 수만 없다.
   값은 1~7 일곱 칸이고 숫자는 보이지 않는다. 끄는 동안에는 소수 값으로 손가락을 따라가고, 손을 떼면 가장 가까운 칸으로 200ms 동안 미끄러져 멈춘다(§ui/trait-slider.js settleTraitSlider). */
.trait-range{position:relative;--v:4;}
.trait-range-wrap{display:flex;align-items:center;height:26px;padding:0 3px;}
.trait-value-slot.trait-range{padding:0 3px;}
/* 레일은 입력 자체가 아니라 트랙(::-webkit-slider-runnable-track, ::-moz-range-track)에 그린다. 그래야 입력 상자를 44px로 키워 레일 위아래 어디를 잡아도 손잡이가 잡힌다(모바일 사파리).
   위아래 -9px 여백으로 레이아웃 높이는 예전과 같은 26px이다. 모습(8px 레일, 27px 손잡이, 그라데이션 값)은 시안 09 그대로이고, 손잡이에는 위에서 비치는 빛과 테두리 안쪽 모따기만 아주 옅게 더했다 */
.trait-range input[type=range]{position:relative;z-index:1;display:block;width:100%;height:44px;margin:-9px 0;-webkit-appearance:none;appearance:none;outline:none;background:transparent;cursor:grab;touch-action:none;-webkit-tap-highlight-color:transparent;}
.trait-range input[type=range]:active{cursor:grabbing;}
.trait-range input[type=range]:disabled{cursor:default;}
.trait-range input[type=range]::-webkit-slider-runnable-track{height:8px;border:0;border-radius:40px;background:linear-gradient(#b9bec1,#ededed,#afb5b9);box-shadow:inset 0 1px 3px #7e878c66;}
.trait-range input[type=range]::-webkit-slider-thumb{-webkit-appearance:none;appearance:none;width:27px;height:27px;margin-top:-10.5px;border-radius:50%;border:1px solid #9ba2a7;background:linear-gradient(180deg,rgba(255,255,255,.32),rgba(255,255,255,0) 48%,rgba(40,44,48,.05)),conic-gradient(from 0deg,#ddd,#aab1b4,#fefefe,#939da2,#efefef,#a3aaad,#ddd);box-shadow:inset 0 0 0 1px rgba(255,255,255,.42),0 1px 1px rgba(40,44,48,.16),0 2px 5px #66666640;transition:box-shadow .2s ease,filter .2s ease;}
.trait-range input[type=range]:not(:disabled):active::-webkit-slider-thumb{box-shadow:inset 0 0 0 1px rgba(255,255,255,.42),0 1px 1px rgba(40,44,48,.2),0 1px 3px #66666633;}
.trait-range input[type=range]:focus-visible::-webkit-slider-thumb{outline:3px solid #9aaebc;outline-offset:2px;}
.trait-range input[type=range]::-moz-range-track{height:8px;border:0;border-radius:40px;background:linear-gradient(#b9bec1,#ededed,#afb5b9);box-shadow:inset 0 1px 3px #7e878c66;}
.trait-range input[type=range]::-moz-range-progress{background:transparent;}
.trait-range input[type=range]::-moz-range-thumb{width:27px;height:27px;border-radius:50%;border:1px solid #9ba2a7;background:linear-gradient(180deg,rgba(255,255,255,.32),rgba(255,255,255,0) 48%,rgba(40,44,48,.05)),conic-gradient(from 0deg,#ddd,#aab1b4,#fefefe,#939da2,#efefef,#a3aaad,#ddd);box-shadow:inset 0 0 0 1px rgba(255,255,255,.42),0 1px 1px rgba(40,44,48,.16),0 2px 5px #66666640;}
@media(prefers-reduced-motion:reduce){.slider-row .labels>span,.trait-range input[type=range]::-webkit-slider-thumb{transition:none;}}
.trait-value-slot .hint{flex:1; text-align:center;}
/* 빈 화면(2026-10-04): 아이콘은 연한 바탕의 둥근 칸, 제목은 진하게, 설명은 한 단계 연하게, 다음 할 일은 검은 알약 버튼(노션 레퍼런스 UI 비포/애프터 17 "빈 화면에 다음 한 수") */
.empty-state{text-align:center; padding:56px 24px; color:var(--text-mid); font-size:var(--fs-base); line-height:1.6;}
/* §ui/components/state-view.js 공용 빈 화면, 로딩 표시 */
.empty-state .empty-title{font-size:var(--fs-xl); font-weight:var(--fw-bold); color:var(--text); line-height:1.45; word-break:keep-all;}
.empty-state[role=status] .empty-title{font-size:var(--fs-base); font-weight:var(--fw-regular); color:var(--text-mid);}
.empty-state .hint{margin-top:6px; font-size:var(--fs-md); color:var(--text-mid); word-break:keep-all;}
/* 공용 빈 화면(emptyStateHtml): 화면 한가운데에 입체 그림, 회색 제목, 더 옅은 설명, 할 일이 있을 때만 작은 검정 알약(운영자 2026-10-13 C안, Linear 받은 알림 참고) */
.empty-view{display:flex; flex-direction:column; align-items:center; justify-content:center; min-height:max(260px, calc(100dvh - 340px)); padding:24px 32px 64px;}
.empty-view .big img{display:block; width:120px; height:120px; margin:0 0 10px; object-fit:contain;}
.empty-view .empty-title{font-size:var(--fs-lg); font-weight:var(--fw-regular); color:var(--text-mid); line-height:1.4;}
.empty-view .hint{max-width:280px; margin-top:2px; font-size:var(--fs-md); line-height:1.45; color:var(--text-light);}
.empty-view .empty-action{display:inline-flex; align-items:center; justify-content:center; width:auto; min-height:44px; margin:18px 0 0; padding:0 20px; font-size:var(--fs-base);}
.sheet .empty-view{min-height:0; padding:28px 16px;}
.sheet .empty-view .big img{width:88px; height:88px;}
.sr-only{position:absolute; width:1px; height:1px; padding:0; margin:-1px; overflow:hidden; clip:rect(0,0,0,0); white-space:nowrap; border:0;}
.link-btn{color:var(--primary-dark); font-weight:var(--fw-bold); font-size:var(--fs-md); background:none; border:none;}
.age-tag{font-size:var(--fs-2xs); font-weight:var(--fw-bold); padding:3px 9px; border-radius:var(--radius-full); display:inline-block; white-space:nowrap; flex:0 0 auto;}
.icon-btn svg{display:block;}
/* 배너와 시트의 작은 닫기(X): 흰 원과 그림자 없이 회색 글자 모양만, 보이는 칸 26, 누르는 영역은 .tap-44로 44 */
.icon-btn.icon-x{width:26px;height:26px;background:none;box-shadow:none;color:var(--text-mid);}
.icon-btn.icon-x svg{width:16px;height:16px;}
.icon-btn .settings-ic{width:22px;height:22px;object-fit:contain;display:block;}
#traitTabContent .title-md,#detailTraitBox .title-md{display:none;}
.trait-card-flat .card{display:grid; grid-template-columns:1fr 1fr; gap:4px 16px;}
.trait-card-flat .card .title-md{grid-column:1/-1; margin-bottom:18px;}
.trait-card-flat .card .sub{grid-column:1/-1;}
.trait-card-flat .card .slider-row{min-width:0;}
.trait-card-flat .card .slider-row .labels{grid-template-columns:minmax(0,1fr) 26px minmax(0,1fr); column-gap:4px; font-size:var(--fs-xs);}
.trait-card-flat .card .slider-row .labels .trait-axis{width:26px;}

/* ---- 성격 조절 패널(§ui/trait-panel.js, 2026-10-15) ----
   시안 09 슬라이더를 그대로 두고, 슬라이더가 들어앉을 한 장의 조작 패널을 만든다. 8축을 카드로 나누지 않고 같은 간격으로 한 패널에 놓는다.
   1. 패널: 브러시드 실버 알루미늄(Bang & Olufsen Beocenter 9000). 바탕 #e6e6e6 위에 가로 결 노이즈(SVG feTurbulence, 가로로 길게 늘인 결)를 아주 옅게 깔고,
      위에서 비치는 빛만 한 겹 더한다. 테두리는 0.5px 선과 위쪽 1px 하이라이트(모따기)뿐이고, 바깥 그림자는 바닥에 붙은 정도로만 둔다.
   2. 모노 글자: 따로 띠를 두지 않고 패널 금속에 검은 글자로 바로 찍는다. 글자 아래 1px 밝은 모서리로 눌려 들어간 듯 보이게 하고, 오른쪽에는 범례 같은 짧은 꼬리표만 둔다. 디지털 숫자 표시는 넣지 않는다.
   3. 레일과 손잡이: 시안 09 그대로(Marantz 1122DC). 레일 아래에 일곱 칸 눈금(Pioneer SG-9500)을 1px로 새기고, 손잡이에 가까운 눈금만 조금 진해진다(--v와 --i의 거리).
   4. 색은 이 패널 안에서만 쓰는 재질 값이다(§design/mono-tone-clean.md 토큰 6, 재질 그림자는 토큰으로 묶지 않음). 글자는 #17181a에서 #a0a2a6 사이로만 움직인다 */
.trait-panel{
  --tp-silver:#e6e6e6;
  --tp-ink:23 24 26;
  --tp-grain:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='360' height='240'%3E%3Cfilter id='w'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.0022 .82' numOctaves='2' seed='11' stitchTiles='stitch'/%3E%3CfeColorMatrix values='0 0 0 0 1 0 0 0 0 1 0 0 0 0 1 .52 0 0 0 -.21'/%3E%3C/filter%3E%3Cfilter id='k'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.003 .6' numOctaves='2' seed='4' stitchTiles='stitch'/%3E%3CfeColorMatrix values='0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 .13 0 0 -.05'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23w)'/%3E%3Crect width='100%25' height='100%25' filter='url(%23k)'/%3E%3C/svg%3E");
  position:relative;padding:6px;border-radius:var(--radius);text-align:left;
  background:linear-gradient(180deg,rgba(255,255,255,.5),rgba(255,255,255,0) 26%,rgba(255,255,255,0) 72%,rgba(30,32,36,.035)),var(--tp-grain) 0 0/360px 240px,var(--tp-silver);
  box-shadow:inset 0 0 0 .5px rgba(30,32,36,.14),inset 0 1px 0 rgba(255,255,255,.95),inset 0 -1px 0 rgba(30,32,36,.05),0 1px 1px rgba(30,32,36,.05),0 12px 28px -16px rgba(30,32,36,.22);
}
.tp-plate{display:flex;align-items:center;justify-content:space-between;gap:12px;min-height:20px;padding:12px 14px 0 16px;}
/* 찍힌 글자: 검은 글자(::before, 모노 글자 그림을 마스크로)에 부모의 drop-shadow로 아래 1px 밝은 모서리를 붙인다. 마스크가 그림자까지 자르지 않도록 둘을 나눴다 */
.tp-mark{flex:none;width:46px;height:10px;filter:drop-shadow(0 1px 0 rgba(255,255,255,.9));}
.tp-mark::before{content:"";display:block;width:100%;height:100%;background:#1d1e21;-webkit-mask:url("../images/mono-serif.png") left center/contain no-repeat;mask:url("../images/mono-serif.png") left center/contain no-repeat;}
.tp-cap{display:flex;align-items:center;font-size:var(--fs-2xs);font-weight:var(--fw-bold);letter-spacing:.02em;color:rgb(var(--tp-ink) / .5);white-space:nowrap;}
.tp-body{padding:14px 12px 2px;}
.trait-panel .tp-body>.slider-row{min-height:0;margin:0 0 4px;}
.trait-panel .tp-body>.slider-row:last-child{margin-bottom:0;}
.trait-panel .slider-row .labels{margin-bottom:7px;padding:0 4px;}
/* 손잡이 쪽 라벨은 진하고 굵게(650), 반대쪽은 흐리고 가늘게(420). 가변 글꼴이라 끄는 동안 굵기도 명도와 같이 이어서 바뀐다 */
.trait-panel .slider-row .labels>[data-trait-side="left"]{color:rgb(var(--tp-ink) / calc(.36 + .58 * (7 - var(--v)) / 6));font-weight:calc(420 + 230 * (7 - var(--v)) / 6);}
.trait-panel .slider-row .labels>[data-trait-side="right"]{color:rgb(var(--tp-ink) / calc(.36 + .58 * (var(--v) - 1) / 6));font-weight:calc(420 + 230 * (var(--v) - 1) / 6);}
.trait-panel .trait-letter{background:rgba(255,255,255,.6);box-shadow:inset 0 0 0 .5px rgba(30,32,36,.12);}
/* 레일이 패널에 파여 들어간 것처럼 레일 바로 아래에 1px 밝은 모서리를 둔다 */
.trait-panel .trait-range input[type=range]::-webkit-slider-runnable-track{box-shadow:inset 0 1px 3px #7e878c66,0 1px 0 rgba(255,255,255,.85);}
.trait-panel .trait-range input[type=range]::-moz-range-track{box-shadow:inset 0 1px 3px #7e878c66,0 1px 0 rgba(255,255,255,.85);}
.trait-panel .trait-range-wrap{margin-bottom:10px;}
/* 눈금: 손잡이 중심이 지나는 자리(좌우 3px 여백 + 손잡이 반지름 14.5px)에 맞춘다. 가운데(4)만 조금 길다 */
.tp-ticks{display:none;}
.trait-panel .tp-ticks{position:absolute;left:17px;right:17px;top:30px;display:flex;justify-content:space-between;align-items:flex-start;pointer-events:none;}
.tp-ticks>i{flex:none;width:1px;height:3px;border-radius:.5px;background:rgb(var(--tp-ink) / calc(.15 + .45 * clamp(0, 1 - max(var(--v) - var(--i), var(--i) - var(--v)), 1)));}
.tp-ticks>i:nth-child(4){height:5px;}
.ob-sheet .trait-panel{margin:0 2px;}
/* 읽기 전용(상대 프로필, 대화방, 마이페이지 보기, 대화 스타일)도 같은 패널이다. 칸 높이와 눈금 자리를 고치는 줄과 맞추고, "상관없음"은 금속에 찍힌 글자처럼 둔다 */
.trait-panel-card>.title-md{margin:0 0 12px;}
.trait-panel .trait-value-slot{margin-bottom:10px;}
.trait-panel .trait-value-slot .hint{margin:0;font-size:var(--fs-sm);font-weight:var(--fw-bold);color:rgb(var(--tp-ink) / .42);text-shadow:0 1px 0 rgba(255,255,255,.8);}
/* 예전 2열 슬라이더 칸(.wizard-trait-grid)의 격자는 패널에서 쓰지 않는다. 이름은 §ui/wizard-nav-animations.js가 찾는 데만 남긴다 */
.trait-panel.wizard-trait-grid{display:block;min-height:0;}
/* 성격이 아닌 슬라이더(나이 범위, 자유 구함 올려 둘 시간)도 같은 패널에 담는다. 줄이 하나라 아래 여백만 줄인다 */
.trait-panel.tp-range .tp-body{padding:12px 12px 8px;}
.trait-slider-list+.trait-slider-list{margin-top:12px;}

/* 테스트로 다시 알아보기 결과: 지금(작은 그래파이트 손잡이)과 테스트(새틴 알루미늄 손잡이)를 한 레일에 같이 둔다.
   줄 전체가 체크박스 라벨이다. 고르면 라벨 명도와 눈금이 테스트 값으로 옮겨 가고(--tp-at), 지금에서 테스트까지 레일 위에 가는 선이 그어진다.
   고르지 않으면 테스트 손잡이가 흐려지고 라벨은 지금 값을 따른다. 손잡이 자리는 움직이지 않고 밝기만 바뀐다 */
@property --tp-at{syntax:'<number>';inherits:true;initial-value:4;}
.tp-cmp{--tp-at:var(--cur);display:grid;grid-template-columns:minmax(0,1fr) 40px;align-items:center;column-gap:4px;padding:12px 0 2px;cursor:pointer;-webkit-tap-highlight-color:transparent;transition:--tp-at .28s var(--ease-in-out);}
.tp-cmp:has(.tp-pick:checked){--tp-at:var(--next);}
.trait-panel .tp-body>.tp-cmp{margin:0;}
.trait-panel .tp-body>.tp-cmp:first-child{padding-top:0;}
.tp-body>.tp-cmp+.tp-cmp{border-top:.5px solid rgba(30,32,36,.12);box-shadow:inset 0 1px 0 rgba(255,255,255,.7);}
.tp-cmp-main{display:block;min-width:0;}
.tp-cmp .labels,.tp-cmp .trait-range{--v:var(--tp-at);}
.tp-cmp-track{display:block;position:relative;height:26px;}
.tp-cmp-track>.tp-rail{position:absolute;left:3px;right:3px;top:9px;height:8px;border-radius:40px;background:linear-gradient(#b9bec1,#ededed,#afb5b9);box-shadow:inset 0 1px 3px #7e878c66,0 1px 0 rgba(255,255,255,.85);}
.tp-cmp-track>.tp-travel{position:absolute;top:12px;height:2px;border-radius:1px;left:calc(17.5px + (100% - 35px) * (var(--lo) - 1) / 6);width:calc((100% - 35px) * (var(--hi) - var(--lo)) / 6);background:rgba(41,43,46,.5);opacity:0;transition:opacity .2s ease;}
.tp-cmp:has(.tp-pick:checked) .tp-travel{opacity:1;}
.tp-knob{position:absolute;top:50%;border-radius:50%;transform:translate(-50%,-50%);}
.tp-knob.is-next,.tp-dot.is-next{border:1px solid #9ba2a7;background:linear-gradient(180deg,rgba(255,255,255,.32),rgba(255,255,255,0) 48%,rgba(40,44,48,.05)),conic-gradient(from 0deg,#ddd,#aab1b4,#fefefe,#939da2,#efefef,#a3aaad,#ddd);}
.tp-knob.is-cur,.tp-dot.is-cur{border:1px solid #1f2124;background:linear-gradient(180deg,rgba(255,255,255,.18),rgba(255,255,255,0) 50%),conic-gradient(from 0deg,#5a5e63,#383b3f,#8a8e93,#2f3236,#71757a,#3f4246,#5a5e63);}
.tp-knob.is-next{z-index:2;width:27px;height:27px;left:calc(17.5px + (100% - 35px) * (var(--next) - 1) / 6);box-shadow:inset 0 0 0 1px rgba(255,255,255,.42),0 1px 1px rgba(40,44,48,.16),0 2px 5px #66666640;transition:opacity .2s ease;}
.tp-knob.is-cur{z-index:1;width:15px;height:15px;left:calc(17.5px + (100% - 35px) * (var(--cur) - 1) / 6);box-shadow:inset 0 0 0 .5px rgba(255,255,255,.18),0 1px 2px rgba(0,0,0,.28);}
.tp-cmp:not(:has(.tp-pick:checked)) .tp-knob.is-next{opacity:.38;}
.tp-legend{display:flex;align-items:center;gap:5px;}
.tp-dot{display:block;flex:none;width:9px;height:9px;border-radius:50%;}
.tp-dot.is-next{margin-left:9px;border-color:#7d8388;}
/* 고르기: 패널에 얕게 파인 둥근 홈. 고르면 검은 유리 단추가 들어앉는다. 보이는 크기는 24px이고 누르는 영역은 줄 전체다 */
.tp-pick{-webkit-appearance:none;appearance:none;justify-self:end;width:24px;height:24px;margin:0 4px 0 0;border:0;border-radius:50%;cursor:pointer;
  background:linear-gradient(180deg,#d3d4d7,#ebebec);box-shadow:inset 0 1px 2px rgba(0,0,0,.2),inset 0 0 0 .5px rgba(30,32,36,.14),0 1px 0 rgba(255,255,255,.9);
  transition:transform .12s var(--ease-out);}
.tp-pick:checked{background:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 12 12'%3E%3Cpath d='M2.6 6.3l2.2 2.2 4.6-4.9' fill='none' stroke='%23f2f2f3' stroke-width='1.5' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E") center/12px no-repeat,linear-gradient(180deg,#3a3c40,#232528);box-shadow:inset 0 1px 0 rgba(255,255,255,.12),0 0 0 .5px rgba(0,0,0,.55),0 1px 2px rgba(0,0,0,.18);}
.tp-cmp:active .tp-pick{transform:scale(.92);}
.tp-pick:focus-visible{outline:2px solid #737a89;outline-offset:3px;}
@media(prefers-reduced-motion:reduce){.tp-cmp:active .tp-pick{transform:none;}}
/* 프로필 소개 말풍선 — 팽팽하게 부푼 얇은 반투명 캡슐 재질. 입체감은 형태, 투명도 차이, 가장자리의 아주 얇은 빛,
   하단의 약한 안쪽 그림자 순으로만 만든다(큰 그림자, 뚜렷한 테두리, 무지개빛, 강한 blur는 쓰지 않는다).
   값은 전부 아래 --bubble-* 토큰이다. 꼬리는 삼각형(::after)이고 ::before는 가장자리 빛이다. */
:root{--bubble-radius:16px; --bubble-ink:var(--text); --bubble-background:rgba(255,255,255,.74); --bubble-tint:rgba(22,26,34,.045); --bubble-border:rgba(22,26,34,.10); --bubble-highlight:rgba(255,255,255,.85); --bubble-side-light:rgba(255,255,255,.28); --bubble-inner-shadow:rgba(22,26,34,.09); --bubble-blur:3px;}
.profile-speech-bubble{position:absolute; bottom:100%; left:50%; transform:translateX(-30%); margin-bottom:12px; max-width:170px; width:max-content; padding:8px 13px; border-radius:var(--bubble-radius); font-size:var(--fs-xs); font-weight:var(--fw-bold); color:var(--bubble-ink); text-align:center; line-height:1.4; animation:bubbleFloat 2.6s ease-in-out infinite; z-index:2; background:linear-gradient(var(--bubble-tint),var(--bubble-tint)),var(--bubble-background); -webkit-backdrop-filter:blur(var(--bubble-blur)) saturate(1.1); backdrop-filter:blur(var(--bubble-blur)) saturate(1.1); box-shadow:inset 0 0 0 .5px var(--bubble-border),inset 0 -2px 3px -2px var(--bubble-inner-shadow);}
.profile-speech-bubble::before{content:""; position:absolute; inset:0; border-radius:inherit; pointer-events:none; background:linear-gradient(180deg,var(--bubble-highlight) 0,rgba(255,255,255,0) 2px),linear-gradient(180deg,rgba(255,255,255,.2) 0,rgba(255,255,255,0) 8px),linear-gradient(90deg,var(--bubble-side-light) 0,rgba(255,255,255,0) 6px,rgba(255,255,255,0) calc(100% - 6px),var(--bubble-side-light) 100%);}
.profile-speech-bubble::after{content:""; position:absolute; bottom:-7px; left:56%; width:12px; height:8px; margin-left:-6px; pointer-events:none; clip-path:polygon(0 0,100% 0,50% 100%); background:linear-gradient(var(--bubble-tint),var(--bubble-tint)),var(--bubble-background);}
/* 매칭 카드용 — 여전히 카드 레이아웃을 조금도 밀지 않는 오버레이(position:absolute)다. 다만
   기준점을 카드 모서리가 아니라 임관·그룹 태그 span 자신(position:relative)으로 옮겨서
   left:100%로 그 태그 바로 옆에 항상 따라붙게 한다. 태그
   글자와 꼬리(두 원) 사이에 여백이 남도록 margin-left를 태그 여백(6px)보다 넉넉히 크게
   잡아 꼬리 맨 왼쪽 점이 글자를 침범하지 않게 한다. 너무 긴 말풍선이 카드를 더 가리지
   않도록 한 줄로 자르고 ...으로 줄인다 — 말줄임은 안쪽 span에만 걸어야 한다(바깥에 걸면
   바깥으로 튀어나온 꼬리까지 잘려서 말풍선처럼 안 보인다). 둥둥 뜨는 효과는 기본
   bubbleFloat 그대로 쓰면 translateX(-30%)가 섞여 있어(§.profile-speech-bubble) 옆으로도
   같이 밀리므로, 세로 bob만 있는 전용 키프레임을 쓴다.
   지금은 프로필 카드 사진 옆(§ui/components/profile-card.js)과 처음 설정의 말풍선 미리보기에서 쓴다. */
.profile-speech-bubble.card-overlay-bubble{position:absolute; bottom:auto; top:50%; left:100%; right:auto; transform:translateY(-50%); margin:0 0 0 14px; max-width:172px; display:block; animation:cardBubbleFloat 2.6s ease-in-out infinite;}
.profile-speech-bubble.card-overlay-bubble>span{display:block; overflow:hidden; text-overflow:ellipsis; white-space:nowrap;}
.profile-speech-bubble.card-overlay-bubble::after{bottom:auto; top:50%; left:-7px; width:8px; height:12px; margin:-6px 0 0 0; clip-path:polygon(100% 0,100% 100%,0 50%);}
/* 매칭 카드 말풍선은 유리 생각 말풍선 SVG(§assets/images/glass-bubble-capsule.svg)를 border-image로 쓴다 — 좌우 둥근 끝(17px)은 그대로 두고 가운데만 늘어나서 글이 짧으면 짧게, 길면 길게 맞는다. 높이 31.4px 기준 SVG 배율이 0.106이라 끝 폭이 17px다. 꼬리는 진주 두 알(glass-bubble-pearls.svg)이 ::after로 말풍선 왼쪽 측면 아래쪽에 붙고, 말풍선은 진주 무리의 세로 중심이 태그 글자 중심에 오도록 10.5px 위로 올려 둔다(카드 밖으로 살짝 튀어나와도 됨, 레이아웃은 안 민다). ::after 기준은 테두리 안쪽이라 left에 테두리 17px을 더 뺀다. */
.profile-speech-bubble.card-overlay-bubble{padding:8px 2px; border-style:solid; border-width:0 17px; border-image:url(../images/glass-bubble-capsule.svg) 0 159 0 162 fill / 0 17px / 0 stretch; border-radius:0; margin-left:16px; transform:translateY(calc(-50% - 10.5px)); background:none; box-shadow:none; -webkit-backdrop-filter:none; backdrop-filter:none;}
.profile-speech-bubble.card-overlay-bubble::before{display:none;}
.profile-speech-bubble.card-overlay-bubble::after{bottom:auto; top:var(--pearl-top,20px); left:var(--pearl-left,-28px); width:14px; height:11px; margin:0; clip-path:none; background:url(../images/glass-bubble-pearls.svg) no-repeat 0 0/100% 100%;}
@keyframes bubbleFloat{0%,100%{transform:translateX(-30%) translateY(0);}50%{transform:translateX(-30%) translateY(-5px);}}
@keyframes cardBubbleFloat{0%,100%{transform:translateY(calc(-50% - 10.5px));}50%{transform:translateY(calc(-50% - 15.5px));}}
/* 프로필 전환 시 이 카드가 직육면체처럼 옆으로 90도 도는 애니메이션(§actions/profile.js
   switchProfile)을 쓴다 — rotateY가 납작하게 짜부라지지 않고 실제로 입체로 돌아 보이려면
   부모(.mypage-scrollless)에 perspective가 있어야 한다. */
.mypage-scrollless{perspective:900px;}
.mypage-info-card{position:relative; display:block; width:100%; box-sizing:border-box; background:var(--gray-0); border-radius:var(--radius);corner-shape:squircle; padding:18px; box-shadow:var(--shadow-sm); -webkit-touch-callout:none; -webkit-user-select:none; user-select:none; transition:background-color .2s ease;}
@media(prefers-reduced-motion:reduce){.mypage-info-card{transition:none;}}
/* 성격(8축)은 2열 4행, MBTI(4축)는 1열 4행으로 줄 수를 맞춰 두 화면 높이가 같다. min-height와
   align-content:start는 줄 높이가 조금 달라도 위에서부터 채우게 둔다(§screens/auth.js stepPersonality, 내 조건/상대 조건 공통). */
.wizard-trait-grid{display:grid; grid-template-columns:1fr 1fr; gap:4px 16px; min-height:244px; align-content:start;}
.wizard-trait-grid .slider-row{min-width:0;}
.wizard-trait-grid .slider-row .labels{grid-template-columns:minmax(0,1fr) 26px minmax(0,1fr); column-gap:4px; font-size:var(--fs-xs);}
.wizard-trait-grid .slider-row .labels .trait-axis{width:26px;}
.wizard-trait-grid.mbti-card,.trait-card-flat .card.mbti-card{grid-template-columns:1fr;}
.center-modal-overlay{position:fixed; inset:0; background:rgba(0,0,0,.35); z-index:150; display:flex; align-items:center; justify-content:center; animation:fadeIn .2s ease; padding:24px;}
.center-modal{width:100%; max-width:260px; border-radius:var(--radius-xl);corner-shape:squircle; overflow:hidden; background:var(--gray-0); box-shadow:var(--shadow-sm); animation:modalScaleIn var(--modal-open-dur) var(--ease-smooth-out);}
/* 확인 팝업(§ui/components/confirm-popup.js) — 화면 꽉 채운 구분선 버튼 두 개(예전 스타일)
   대신, 라운딩 스퀘어 버튼 두 개를 간격을 두고 나란히 둔다. 라벨이 "네, 저장할게요"처럼
   길어도 줄바꿈되지 않도록 이 모달만 기본 260px보다 넉넉하게 넓힌다. */
.confirm-modal{max-width:300px;}
.confirm-modal-body{text-align:center; padding:22px 20px 6px;}
.confirm-modal-body .title-md{margin-bottom:6px;}
.confirm-modal-body .sub{margin-bottom:0;}
.confirm-modal-actions{display:flex; gap:8px; padding:16px;}
.confirm-modal-actions .btn{flex:1; width:auto; height:44px; padding:0 10px; font-size:var(--fs-lg); white-space:nowrap;}
.ask-text-input{display:block;width:100%;box-sizing:border-box;height:48px;margin-top:14px;padding:0 14px;border:1.5px solid var(--border);border-radius:var(--radius-sm);corner-shape:squircle;background:var(--bg2);color:var(--text);font:inherit;font-size:var(--fs-xl);text-align:left;outline:none;transition:border-color 150ms var(--ease-smooth-out);}
.ask-text-input:focus{border-color:var(--primary-dark);background:var(--gray-0);}
.confirm-modal-cancel{background:var(--bg2); color:var(--text); font-weight:var(--fw-bold);}
.confirm-modal-cancel:active{opacity:.7;}
.legal-modal{width:100%; max-width:440px; height:85vh; border-radius:var(--radius-lg);corner-shape:squircle; overflow:hidden; background:var(--bg1); box-shadow:var(--shadow); display:flex; flex-direction:column; animation:modalScaleIn var(--modal-open-dur) var(--ease-smooth-out);}
@keyframes modalScaleIn{from{opacity:0; transform:scale(var(--modal-scale));} to{opacity:1; transform:scale(1);}}
@keyframes modalScaleOut{from{opacity:1; transform:scale(1);} to{opacity:0; transform:scale(var(--modal-scale));}}
.center-modal-overlay.closing .center-modal,.center-modal-overlay.closing .legal-modal{animation:modalScaleOut var(--modal-close-dur) var(--ease-smooth-out) forwards;}
@media(prefers-reduced-motion:reduce){.center-modal,.legal-modal,.center-modal-overlay.closing .center-modal,.center-modal-overlay.closing .legal-modal{animation:none!important;}}
.legal-modal-head{display:flex; align-items:center; justify-content:space-between; padding:8px 10px 8px 14px; border-bottom:1px solid var(--border); flex:none;}
.legal-modal-head .title-md{font-size:var(--fs-md); font-weight:var(--fw-bold); margin:0;}
.legal-modal-head .icon-btn{width:30px; height:30px; font-size:var(--fs-sm);}
.legal-modal iframe{flex:1; width:100%; border:0; min-height:0;}
/* 채팅 목록 밀기 칸(#98, 결정 55-A, §screens/chat.js swipeHtml): 줄 높이를 채운 폭 74 칸, 글자와 아이콘. 나가기만 빨강, 고정은 검정, 알림은 회색 */
.room-swipe-actions{position:absolute; top:0; bottom:0; display:flex; opacity:0; pointer-events:none;}
.room-swipe-actions.swipe-active{pointer-events:auto;}
.room-swipe-end{right:0;}
.room-swipe-start{left:0;}
.room-swipe-btn{width:74px; padding:0; border:0; display:flex; flex-direction:column; align-items:center; justify-content:center; gap:5px; color:var(--gray-0); font:inherit; font-size:var(--fs-sm); font-weight:var(--fw-bold); cursor:pointer;}
.room-swipe-btn.is-gray{background:var(--gray-600);}
.room-swipe-btn.is-danger{background:#ff3b30;}
.room-swipe-btn.is-dark{background:var(--gray-900);}
.chat-room-row .chat-room-card{background:var(--bg1);}
/* 상대 목록 카드 좌우 밀기(§ui/card-swipe.js): 카드 뒤에 아이콘이 깔려 있고 카드가 옆으로 밀리면 드러난다. 채팅방 목록 카드와 같은 폭(52px)과 색이다. */
.card-swipe{position:relative;margin-bottom:14px;}
.card-swipe > .match-card{margin-bottom:0;touch-action:pan-y;}
.card-swipe-action{position:absolute;top:0;bottom:0;width:52px;display:flex;align-items:center;justify-content:center;opacity:0;pointer-events:none;color:var(--gray-600);}
.card-swipe-action.swipe-active{pointer-events:auto;}
.card-swipe-action button{display:flex;align-items:center;justify-content:center;width:40px;height:40px;padding:0;border:none;background:none;color:inherit;cursor:pointer;}
.card-swipe-chat{right:0;}
.card-swipe-reject{left:0;}
.toggle-switch{position:relative; display:inline-flex; width:44px; height:26px; flex-shrink:0; cursor:pointer;}
.toggle-switch input{position:absolute; inset:0; opacity:0; margin:0; cursor:pointer;}
.toggle-switch .toggle-track{position:absolute; inset:0; background:var(--border); border-radius:var(--radius-full); transition:background .2s;}
.toggle-switch .toggle-thumb{position:absolute; top:2px; left:2px; width:22px; height:22px; background:var(--gray-0); border-radius:50%; box-shadow:0 1px 3px rgba(0,0,0,.25); transition:transform .2s;}
.toggle-switch input:checked~.toggle-track,.toggle-switch.is-on .toggle-track{background:var(--primary);}
.toggle-switch input:checked~.toggle-track .toggle-thumb,.toggle-switch.is-on .toggle-thumb{transform:translateX(18px);}
.trait-card-flat .card{box-shadow:none; padding:0; margin:4px 0 0; border-radius:0; background:transparent;}
.trait-card-flat .card:active{opacity:1; transform:none;}
.settings-group-label{font-size:var(--fs-sm); font-weight:var(--fw-bold); color:var(--text-light); margin:20px 4px 8px;}
.settings-group-label:first-of-type{margin-top:0;}
.settings-card{background:var(--gray-0); border-radius:var(--radius-lg);corner-shape:squircle; box-shadow:var(--shadow-sm); overflow:hidden;}
.settings-row{display:flex; align-items:center; gap:12px; width:100%; box-sizing:border-box; padding:14px 16px; border:none; background:none; font:inherit; text-align:left; color:var(--text); cursor:pointer;}
.settings-row+.settings-row{border-top:1px solid var(--border);}
.settings-row .settings-row-ic{width:22px; height:22px; display:flex; align-items:center; justify-content:center; color:var(--gray-600); flex-shrink:0;}
.settings-row .settings-row-label{flex:1; font-weight:var(--fw-bold); font-size:var(--fs-base); min-width:0;}
/* 스위치 줄: 이름 바로 옆에 물음표, 스위치는 오른쪽 끝 */
.settings-row.is-toggle{cursor:default;}
.settings-row.is-toggle .settings-row-label{flex:0 1 auto;}
.settings-switch{margin-left:auto; padding:0; border:0; background:none; display:flex; cursor:pointer;}
.settings-switch:disabled{opacity:.5;}
.settings-row .settings-row-value{font-size:var(--fs-md); color:var(--text-light); flex-shrink:0;}
.settings-row .settings-row-chevron{color:var(--text-light); font-size:var(--fs-xl); flex-shrink:0;}
.settings-row.danger{color:var(--danger);}
.settings-row.accent{color:var(--primary-dark); font-weight:var(--fw-bold);}
/* 설정 맨 위 프로필 카드(애플 계정 배너처럼), 이름표 없는 묶음 사이 간격 */
.settings-profile-card{display:flex; align-items:center; gap:14px; width:100%; margin-top:14px; padding:14px 16px; border:none; font:inherit; text-align:left; color:var(--text); cursor:pointer;}
.settings-profile-text{flex:1; min-width:0; display:flex; flex-direction:column; gap:2px;}
.settings-profile-text b{font-size:var(--fs-3xl); font-weight:var(--fw-bold);}
.settings-profile-text span{font-size:var(--fs-sm); color:var(--text-light);}
.settings-card+.settings-card{margin-top:20px;}
/* 마이페이지: 매칭받기를 꺼 두면 인스타그램 조용한 모드의 상태 글자처럼 태그 줄에 하나 더 */
.age-tag.paused-tag{display:inline-flex; align-items:center; gap:4px; background:var(--gray-100); color:var(--gray-500);}
/* 채팅 목록 위 알림 켜기 띠(§screens/chat.js renderChatList) */
.notice-bar{display:flex; align-items:center; gap:12px; margin:0 0 10px; padding:12px 14px; border-radius:var(--radius-lg); corner-shape:squircle; background:var(--bg2);}
.notice-bar span{flex:1; min-width:0; font-size:var(--fs-sm); line-height:1.5; color:var(--text-mid);}
.notice-bar b{display:block; font-size:var(--fs-base); color:var(--text);}
.settings-row.is-soon{cursor:default; color:var(--text-light);}
/* 이상형을 건너뛴 프로필의 이상형 탭 빈 화면(§screens/mypage.js preferenceSkipped). 카드 안이라 위아래만 줄이고, 아래 중앙값 안내는 숨긴다 */
#traitTabContent .empty-state{min-height:0; padding:36px 8px 12px;}
#traitTabContent:has(.empty-state)+div{display:none;}
/* 설정 화면은 iOS 설정의 묶음 목록처럼: 옅은 회색 바탕에 그림자 없는 흰 카드, Threads·인스타그램처럼 칸 없는 선 아이콘, 본문 굵기 이름, 글자 앞에서 시작하는 구분선, 얇은 화살표 */
.main.mypage-settings-main{background:var(--bg2);}
.mypage-settings-main .settings-card{box-shadow:none;}
/* 시트 안 고르기 목록(신고 사유 등): iOS 묶음 목록처럼 회색 칸 하나에 줄을 모으고, 고른 줄 오른쪽에 체크. 줄마다 떨어진 카드를 쓰지 않는다 */
.sheet .settings-card{margin:14px 0;background:var(--bg2);box-shadow:none;}
.settings-row .settings-row-check{display:flex;flex-shrink:0;color:var(--text);}
.mypage-settings-main .settings-group-label{margin:28px 16px 8px; font-size:var(--fs-md); font-weight:var(--fw-regular);}
.mypage-settings-main .settings-row{position:relative; min-height:54px; padding:10px 16px; gap:14px;}
.mypage-settings-main .settings-row+.settings-row{border-top:0;}
.mypage-settings-main .settings-row+.settings-row::before{content:""; position:absolute; top:0; left:52px; right:0; height:1px; background:var(--border);}
.mypage-settings-main .settings-row .settings-row-ic{color:var(--text);}
.mypage-settings-main .settings-row.is-soon .settings-row-ic{color:var(--gray-300);}
.mypage-settings-main .settings-row .settings-row-label{font-size:var(--fs-lg); font-weight:var(--fw-regular);}
.mypage-settings-main .settings-row .settings-row-value{font-size:var(--fs-lg);}
.mypage-settings-main .settings-row .settings-row-chevron{display:flex; color:var(--gray-400);}
/* Premium은 애플 iCloud+ 자리처럼 맨 위에 또렷하게 두고, 준비 중은 알약으로만 알린다 */
.mypage-settings-main .settings-premium .settings-row.is-soon{color:var(--text);}
.mypage-settings-main .settings-premium .settings-row.is-soon .settings-row-ic{color:var(--text);}
.settings-soon{flex-shrink:0; padding:3px 9px; border-radius:var(--radius-full); background:var(--bg2); color:var(--text-light); font-size:var(--fs-xs); font-weight:var(--fw-bold);}
.mypage-settings-main .settings-row.is-center{justify-content:center;}
.mypage-settings-main .settings-row.is-center::before{left:0;}
.mypage-settings-main .settings-row.is-center .settings-row-ic{display:none;}
.mypage-settings-main .settings-row.is-center .settings-row-label{flex:0 0 auto;}
.settings-profile-card .avatar{width:60px; height:60px; font-size:var(--fs-2xl);}
.mypage-legal-footer{margin-top:28px; padding-top:16px; border-top:1px solid var(--border); text-align:right;}
.mypage-legal-links{display:flex; gap:16px; flex-wrap:wrap; justify-content:flex-end; margin-bottom:10px;}
.mypage-legal-links button{font-size:var(--fs-xs); color:var(--text-light); font-weight:var(--fw-regular); background:none; border:none; padding:0; font-family:inherit;}
/* 사업자 정보 하위 시트: 내용은 맨 아래 12px 회색(§ui/biz-info.js) */
.biz-sheet{min-height:60vh;display:flex;flex-direction:column;}
.biz-sheet-body{margin-top:auto;padding-top:24px;font-size:12px;line-height:1.5;color:var(--text-light);}
.biz-sheet-body p{margin:0;}
.biz-sheet-body a{color:inherit;text-decoration:underline;text-underline-offset:2px;}
.meta-row{display:flex; align-items:center; gap:6px; flex-wrap:wrap; color:var(--text-mid); font-size:var(--fs-md);}
.avatar-photo{width:100%;height:100%;object-fit:cover;border-radius:50%;display:block;}
.menu-row{display:flex; align-items:center; gap:10px;}

.match-action-btn{
  display:inline-flex !important;
  align-items:center !important;
  justify-content:center !important;
  text-align:center !important;
}

.match-card{
  position:relative !important;
  isolation:isolate;
  transition:transform .22s var(--ease-smooth-out),box-shadow .22s var(--ease-smooth-out);
}
/* 설정 묶음 아래 한 줄 안내(보기 "민감한 콘텐츠") */
.settings-note{margin:8px 4px 0;font-size:var(--fs-xs);line-height:1.5;color:var(--text-light);}
/* 누를 수 있다는 신호: 누르는 순간(스크롤 중 손가락이 닿을 때 포함) 카드와 안의 요소가 같이 살짝 어두워진다(말풍선은 제외).
   filter는 자식인 말풍선까지 어둡게 해서 쓰지 않고, 말풍선 아래에 깔리는 반투명 검정 막(::after)을 쓴다. 채팅 중인 상대는 카드는 흰색으로 두고 안의 내용만 흐리게 한다(카드 경계 유지, 말풍선은 제외). */
.match-card::after,.mypage-info-card::after{content:"";position:absolute;inset:0;z-index:0;border-radius:inherit;background:rgba(0,0,0,0);pointer-events:none;transition:background-color .3s ease;}
.match-card .profile-speech-bubble,.mypage-info-card .profile-speech-bubble{z-index:1;}
.mypage-info-card{position:relative;isolation:isolate;}
.match-card{-webkit-touch-callout:none;-webkit-user-select:none;user-select:none;}
.match-card:active{opacity:1;}
/* 상대 목록 줄(§screens/matching.js): 사진, 이름과 둘째 줄(성향, 나이), 오른쪽은 적합도 꼬리표와 그 아래 접속 시간(design/matching-compat-polish.html "다듬은 1", 2026-10-13 운영자).
   꼬리표는 숫자를 굵게, "맞음"을 작고 흐리게. 85% 이상 검정, 70% 이상 회색, 그 아래는 얇은 테두리만. 폭을 고정해서 숫자가 줄마다 같은 자리에 온다. */
.match-card .avatar{width:44px;height:44px;font-size:var(--fs-lg);}
.match-row{display:flex;align-items:center;gap:12px;}
.match-text{flex:1;min-width:0;}
.match-card-name{font-size:var(--fs-lg);font-weight:var(--fw-bold);white-space:nowrap;overflow:hidden;text-overflow:ellipsis;}
.match-fit-col{flex:none;display:grid;grid-template-rows:22px 16px;row-gap:3px;justify-items:end;align-items:center;}
.fit-chip{display:inline-flex;align-items:center;justify-content:center;gap:3px;height:22px;min-width:68px;padding:0 8px;border-radius:var(--radius-full);background:var(--gray-100);color:var(--text);font-variant-numeric:tabular-nums;white-space:nowrap;}
.fit-chip b{font-size:var(--fs-sm);font-weight:var(--fw-bold);letter-spacing:-.01em;}
.fit-chip i{font-style:normal;font-size:var(--fs-xs);font-weight:var(--fw-regular);opacity:.72;}
.fit-chip.hi{background:var(--gray-900);color:var(--gray-0);}
.fit-chip.lo{background:none;color:var(--text-light);box-shadow:inset 0 0 0 1px var(--border);}
.fit-time{font-size:var(--fs-sm);color:var(--text-light);white-space:nowrap;}
.fit-time.is-online{color:var(--text);font-weight:var(--fw-bold);}
@keyframes matchCardBubbleBob{0%,100%{transform:translateY(0);}50%{transform:translateY(-5px);}} /* 원래 말풍선의 위아래 흔들림(5px)과 같다. 프로필 카드 말풍선이 쓴다 */
.compat-gauge{position:relative;width:var(--gw);aspect-ratio:104/56;}
.compat-gauge svg{display:block;width:100%;height:100%;overflow:visible;}
.compat-gauge .cg-track,.compat-gauge .cg-fill{fill:none;stroke-width:7.5;stroke-linecap:round;} /* viewBox 단위: 66px 폭에서 화면 기준 약 4.8px */
.compat-gauge .cg-track{stroke:var(--gray-200);}
.compat-gauge .cg-fill{stroke:var(--gray-500);}
.compat-gauge .cg-text{position:absolute;left:0;right:0;bottom:1px;display:flex;flex-direction:column;align-items:center;line-height:1;pointer-events:none;}
.compat-gauge .cg-value{display:inline-flex;align-items:baseline;color:var(--gray-800);}
/* 숫자 칸은 목표값의 자릿수만큼 고정(우측 정렬, 탭 숫자)이라 올라가는 동안 가운데 정렬과 % 위치가 흔들리지 않는다. 100%도 잘리지 않는다. */
.compat-gauge .cg-num{display:inline-block;min-width:calc(var(--cg-digits,2) * 1ch);text-align:right;font-size:calc(var(--gw) * .27);font-weight:var(--fw-bold);font-variant-numeric:tabular-nums;letter-spacing:-.03em;}
.compat-gauge .cg-pct{margin-left:1px;font-size:max(9px,calc(var(--gw) * .14));font-weight:var(--fw-bold);color:var(--gray-500);}
@media(max-width:380px){.match-card>div:first-child{gap:10px;}.match-card .meta-row{gap:4px;}.match-card .age-tag{padding:2px 7px;}}
.match-card{padding:12px;} /* 사진 바깥 여백이 위, 아래, 왼쪽 모두 12px */
/* 목록 카드의 태그는 색 대신 명도로만 나눈다(태그마다 인라인 색이 들어와서 !important). 성향은 탑 검정, 무성향 회색, 바텀 흰색 쪽으로,
   나이는 연상 진회색, 동갑 중간, 연하 옅은 회색으로 여섯 태그가 서로 다른 단계를 쓴다. 가장 옅은 칩은 흰 카드 위에서 보이게 얇은 테두리를 둔다. */
.match-card.is-pressed::after{background:rgba(0,0,0,.08);transition-duration:.06s;}
/* 상대 목록 카드를 누르면 바로 살짝 작아지고 더 어두워진다(누른 티가 확실히 나게). 손가락을 떼면 원래 크기로 돌아온다. */
.match-card.is-pressed{transform:scale(.97);transition-duration:.09s;}
.match-card.is-pressed::after{background:rgba(0,0,0,.14);}
@media(prefers-reduced-motion:reduce){.match-card.is-pressed{transform:none;}}
.match-card.is-chatted :is(.avatar,.match-card-name,.match-card-ori,.match-fit-col){opacity:.6;}
/* 상대 목록(§screens/matching.js .match-list): iOS 묶음 목록처럼 흰 카드 한 장 안에 줄을 쌓는다(design/matching-list-mock.html A안, 2026-10-13 운영자).
   줄은 화면 끝까지 닿고(본문 좌우 여백 18px만큼 바깥으로), 줄 사이는 이름이 시작하는 곳(18px + 사진 48px + 간격 14px)부터 긋는 구분선.
   줄은 투명해서 화면 원래 바탕(흰색에서 옅은 회색으로 바뀌는 그라데이션)이 그대로 보인다. 옆으로 밀 때 드러나는 아이콘은 평소엔 투명하고
   미는 만큼 나타나며, 그때는 사진이 이미 비켜나 있어 겹치지 않는다(§ui/card-swipe.js). 반원 게이지는 그대로. */
.match-list{margin:0 0 14px;background:var(--card);border-radius:var(--radius);corner-shape:squircle;overflow:hidden;}
.match-list .card-swipe{margin-bottom:0;}
.match-list .match-card{margin:0;padding:11px 14px;border-radius:0;box-shadow:none;background:transparent;}
.match-list .card-swipe + .card-swipe .match-card::before{content:"";position:absolute;z-index:1;top:0;left:70px;right:0;height:1px;background:var(--border);pointer-events:none;}
.match-list .match-card.is-pressed,.match-list .match-card.pp-anchor{transform:none;box-shadow:none;}
.match-list .match-card.pp-anchor::after{background:rgba(0,0,0,.05);}
/* 상대 목록 둘째 줄: 성향과 나이 관계를 같은 작은 중간 회색 글자로(§screens/matching.js). 줄바꿈 없이 한 줄, 넘치면 말줄임. */
.match-card-ori{margin-top:3px;font-size:var(--fs-xs);font-weight:var(--fw-regular);line-height:1.3;color:var(--text-mid);white-space:nowrap;overflow:hidden;text-overflow:ellipsis;}
/* 성향과 나이 관계 사이 얇은 세로선(가운뎃점 대신) */
.match-card-ori span + span::before{content:"";display:inline-block;width:1px;height:9px;margin:0 6px;background:var(--gray-300);vertical-align:-1px;}
.match-list .meta-row:empty{display:none;}
/* 상대 더 보기: 목록 흐름을 끊지 않는 글자 버튼 */
.match-load-more{display:flex;align-items:center;justify-content:center;width:100%;min-height:48px;margin-top:2px;padding:0;border:0;background:none;font:inherit;font-size:var(--fs-base);font-weight:var(--fw-bold);color:var(--text-mid);cursor:pointer;transition:opacity 120ms var(--ease-smooth-out),transform 120ms var(--ease-smooth-out);}
.match-load-more:active{opacity:.6;transform:scale(.98);}
.match-load-more:disabled{opacity:.4;cursor:default;}
@media (prefers-reduced-motion:reduce){.match-card:active{transform:none;}}
.match-card .match-action-btn{
  display:inline-flex !important;
  align-items:center !important;
  justify-content:center !important;
  text-align:center !important;
  min-width:78px !important;
  height:30px !important;
  opacity:1 !important;
  pointer-events:auto !important;
}
.nav-unread-dot{position:absolute;top:7px;right:calc(50% - 17px);width:8px;height:8px;border-radius:50%;background:var(--danger);border:2px solid var(--bg1);box-sizing:content-box}
/* 활동 정지 화면(§screens/app-shell.js renderSuspended): 빈 화면과 같은 제목과 한 줄, 아래 문의하기(검정)와 로그아웃(회색) */
.suspended-account{min-height:80vh;display:flex;flex-direction:column;align-items:center;justify-content:center}
.suspended-actions{display:flex;gap:8px}

/* ===== 프로필 팝오버(한 번 누르면 뜨는 작은 카드)와 상세 정보 시트 =====
   §ui/profile-popover.js, §screens/matching.js profilePopoverHtml/openDetailHtml.
   모션은 docs/animation.md를 따른다: 팝오버는 누른 곳에서 커지며 200ms에 열리고 150ms에 닫힌다.
   LP와 재생 막대만 끝없이 도는 장식이라 모션 줄이기를 켜면 멈춘다. */
#profilePopoverHolder{position:fixed;inset:0;z-index:90;}
#profilePopoverHolder:empty{display:none;}
/* 팝오버가 열린 동안 눌린 카드는 검은 테두리 대신 살짝 떠오른다(커지고 그림자가 깊어진다). 프로필 방울 같은 다른 트리거는 자체 눌림 모션이 있어 표시를 더하지 않는다. */
.match-card.pp-anchor{transform:scale(1.02);box-shadow:var(--shadow);z-index:1;}
@media (prefers-reduced-motion:reduce){.match-card.pp-anchor{transform:none;}}
/* 열 때: 누른 카드 쪽(transform-origin)에서 흐림이 걷히며 커진다. 예전의 크게 튕기는 스프링(480ms) 대신 절제된 ease-out 300ms. */
.pp{will-change:transform;position:fixed;opacity:0;transform:scale(.92);filter:blur(2px);transition:opacity 160ms var(--ease-smooth-out),transform 300ms var(--ease-smooth-out),filter 200ms var(--ease-smooth-out);}
.pp.open{opacity:1;transform:none;filter:none;}
.pp.closing{opacity:0;transform:scale(.94);transition:opacity 130ms var(--ease-smooth-out),transform 150ms var(--ease-smooth-out);}
.pp-card{container-type:inline-size;background:var(--gray-50);border-radius:var(--radius);corner-shape:squircle;overflow:hidden;outline:none;box-shadow:var(--shadow-pop);}
/* 미리 보기 한 줄: 적합도 숫자, 잘 맞는 점 두 개, 더 보기. 누르면 펼친다. */
.pp-more{display:flex;align-items:center;gap:10px;width:100%;min-height:52px;margin:12px 0 0;padding:0 7px 0 14px;border:0;border-radius:var(--radius-lg);corner-shape:squircle;background:var(--gray-0);color:var(--text);font:inherit;text-align:left;cursor:pointer;transition:transform 120ms var(--ease-smooth-out),background-color 150ms var(--ease-smooth-out);}
.pp-more:active{transform:scale(.98);}
.pp-more-fit{flex:none;display:grid;line-height:1.1;}
.pp-more-fit small{font-size:var(--fs-2xs);color:var(--text-light);}
.pp-more-fit b{font-size:var(--fs-3xl);font-weight:var(--fw-bold);letter-spacing:var(--ls-base);font-variant-numeric:tabular-nums;color:var(--primary-dark);}
.pp-more-fit i{font-style:normal;font-size:var(--fs-sm);margin-left:1px;}
/* 태그는 들어가는 만큼만 통째로 보인다: 넘치는 태그는 다음 줄로 밀려나고 한 줄 높이만 보여서 글자 중간이 잘리지 않는다 */
.pp-more-tags{flex:1;min-width:0;display:flex;justify-content:center;flex-wrap:wrap;gap:5px;height:24px;overflow:hidden;}
.pp-more-tags span{flex:none;padding:4px 9px;line-height:16px;border-radius:var(--radius-full);background:var(--gray-50);font-size:var(--fs-xs);font-weight:var(--fw-bold);color:var(--text-mid);white-space:nowrap;}
/* 펼치기 표시: 위쪽 하트, 보내기 버튼과 같은 흰 네모(§.pp-like)라 한 세트로 읽힌다. 버튼은 줄 전체(.pp-more) */
.pp-more-go{flex:none;display:grid;place-items:center;width:38px;height:38px;border-radius:var(--radius-lg);corner-shape:squircle;border:1.5px solid var(--gray-50);background:var(--gray-0);color:var(--text);}
.pp-more-go svg{display:block;}
.pp-detail{display:none;}
.pp .pp-collapse{display:none;position:absolute;z-index:2;top:8px;left:8px;}
/* 펼친 프로필: 같은 팝오버가 앱 본문 전체를 채운다. 배너, 사진, 이름은 그대로 이어지고 아래로 상세 내용이 차례로 떠오른다. */
.pp.is-full{height:100dvh;filter:none;}
.pp.is-full .pp-card{height:100%;overflow-y:auto;overscroll-behavior:contain;border-radius:0;box-shadow:none;}
.pp.is-full .pp-banner{height:120px;}
.pp.is-full .pp-ic-btn.pp-collapse{display:grid;}
.pp.is-full .pp-more{display:none;}
.pp.is-full .pp-detail{display:block;padding:18px 18px calc(28px + env(safe-area-inset-bottom));}
.pp.is-full .pp-detail > *{animation:ppRise 400ms var(--ease-smooth-out) both;}
.pp.is-full .pp-detail > :nth-child(1){animation-delay:80ms;}.pp.is-full .pp-detail > :nth-child(2){animation-delay:120ms;}.pp.is-full .pp-detail > :nth-child(3){animation-delay:160ms;}.pp.is-full .pp-detail > :nth-child(n+4){animation-delay:200ms;}
.pp.is-morphing{transition:transform 380ms var(--ease-drawer),clip-path 380ms var(--ease-drawer);}
.pp.is-morphing.is-from{transition:none;}
.pp.is-closing-full{transition:transform 300ms var(--ease-smooth-out),clip-path 300ms var(--ease-smooth-out);}
.pp.is-closing-full .pp-detail{opacity:0;transition:opacity 150ms var(--ease-smooth-out);}
@keyframes ppRise{from{opacity:0;transform:translateY(12px);filter:blur(3px);}to{opacity:1;transform:none;filter:none;}}
.pp-banner{position:relative;height:92px;overflow:hidden;background:var(--gray-300);}
.pp-banner-img,.pp-banner-fill{position:absolute;inset:0;display:block;width:100%;height:100%;object-fit:cover;}
.pp-banner-fill{background:var(--gray-400);}
.pp-banner::after{content:"";position:absolute;inset:0;pointer-events:none;background:linear-gradient(180deg,#00000052,#00000000 40%);}
.pp-ic{position:absolute;z-index:2;top:8px;right:8px;display:flex;}
.pp-ic-btn{width:40px;height:40px;padding:0;border:0;background:none;display:grid;place-items:center;color:var(--gray-0);filter:drop-shadow(0 1px 3px #0009);transition:opacity .15s var(--ease-smooth-out),transform .15s var(--ease-smooth-out);}
.pp-ic-btn svg{display:block;}
.pp-ic-btn:active{opacity:.7;transform:scale(.92);}
.pp-ic-btn:disabled{opacity:.45;cursor:not-allowed;transform:none;}
.pp-body{position:relative;padding:56px 16px 16px;}
.pp-actions{position:absolute;z-index:2;right:16px;bottom:80px;display:flex;gap:8px;}
.pp-send,.pp-like{display:grid;place-items:center;width:38px;height:38px;padding:0;border-radius:50%;transition:opacity .15s var(--ease-smooth-out),transform .15s var(--ease-smooth-out);}
.pp-send{border:0;background:var(--gray-900);color:var(--gray-0);}
.pp-like{border:1.5px solid var(--gray-0);background:var(--gray-0);color:var(--text);}
.pp-send svg,.pp-like svg{display:block;}
.pp-send:active,.pp-like:active{opacity:.75;transform:scale(.94);}
.pp-send:disabled{opacity:.32;cursor:not-allowed;transform:none;}
.pp-av{position:absolute;z-index:2;left:16px;top:-30px;}
.pp-av .avatar.lg{width:80px;height:80px;font-size:var(--fs-3xl);box-shadow:0 6px 14px -8px #0008;}
.pp-id{display:flex;align-items:center;gap:6px;min-width:0;min-height:38px;padding-right:96px;}
.pp-name{flex:none;max-width:60%;font-size:var(--fs-2xl);font-weight:var(--fw-bold);letter-spacing:var(--ls-base);line-height:1.25;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;}
.pp-group{min-width:0;font-size:var(--fs-md);font-weight:var(--fw-bold);color:var(--text-mid);white-space:nowrap;overflow:hidden;text-overflow:ellipsis;}
/* 소개(멘트)는 사진 오른쪽, 배너 아래 빈칸(좋아요와 보내기 버튼 왼쪽)에 유리 말풍선(진주 두 알 꼬리)으로 뜬다. 진주가 사진 쪽으로 이어진다.
   상대 목록 줄에는 없고 눌러서 연 프로필에만 나온다(2026-10-13 운영자 2안). 하트와 보내기는 이름 줄 오른쪽(결정 95-나)이라 폭은 카드 폭에서 사진 쪽(16 + 80 + 12)과 오른쪽 16만 뺀다.
   두 줄까지, 펼친 프로필에서는 세 줄까지. 유리 몸통 그림의 둥근 끝(--cap)은 높이의 절반(§ui/bubble-cap.js), 뗀 반사광, 음영, 밝은 선은 늘 같은 두께로 얹는다(design/popover-bubble.html 다듬은 판) */
.pp-av .pp-bubble{top:26px;bottom:auto;left:100%;margin:0 0 0 12px;width:max-content;max-width:calc(100cqw - 124px);transform:none;animation-name:matchCardBubbleBob;font-size:var(--fs-sm);font-weight:var(--fw-regular);line-height:1.4;text-align:left;
  border-width:0;border-radius:999px;padding:8px calc(17px + var(--pad,2px));
  border-image:url(../images/glass-bubble-capsule-body.svg) 147 159 147 162 fill / var(--cap,17px) / 0 stretch;
  background:linear-gradient(to top,rgba(255,255,255,.6) 0,rgba(153,153,153,.11) 4px,rgba(153,153,153,0) 9px);
  box-shadow:inset 0 -1.6px 0 -.1px rgba(255,255,255,.9),inset 0 -.4px 0 rgba(143,143,143,.45);--pearl-left:-11px;}
.pp-av .pp-bubble::before{display:block;content:"";position:absolute;inset:0;border-radius:999px;pointer-events:none;
  background:linear-gradient(90deg,rgba(255,255,255,0),rgba(255,255,255,.95) 10%,rgba(255,255,255,.95) 90%,rgba(255,255,255,0)) no-repeat 50% .9px/calc(100% - var(--cap,17px)*.84) 3.4px;}
.pp-av .pp-bubble>span{display:-webkit-box;-webkit-box-orient:vertical;-webkit-line-clamp:2;white-space:normal;word-break:keep-all;overflow-wrap:anywhere;}
.pp.is-full .pp-av .pp-bubble>span{-webkit-line-clamp:3;}

/* 내 프로필 탭: 남이 보는 팝오버와 같은 카드(§ui/components/profile-card.js). 바닥에 붙은 카드라 그림자만 낮춘다.
   오른쪽 위 "프로필 편집"은 X 프로필의 Edit profile처럼 테두리만 있는 알약 */
.my-pp{margin-top:14px;box-shadow:var(--shadow-sm);}
.my-pp-edit{position:absolute;z-index:2;right:14px;top:12px;padding:7px 14px;border:1px solid var(--border);border-radius:var(--radius-full);background:var(--gray-0);color:var(--text);font:inherit;font-size:var(--fs-md);font-weight:var(--fw-bold);transition:transform .15s var(--ease-smooth-out);}
.my-pp-edit:active{transform:scale(.95);}
/* 프로필 편집(Threads 프로필 편집처럼 카드 한 장): 배경과 사진은 카메라 표시를 눌러 고르고, 아래로 이름, 아이디, 소개, 노래 줄 */
.pe-pick{cursor:pointer;}
.pp-banner.pe-pick{display:block;} /* label이라 기본이 inline이면 높이가 0이 된다 */
.pe-pick input{position:absolute;width:1px;height:1px;opacity:0;pointer-events:none;}
.pe-cam{position:absolute;z-index:3;display:grid;place-items:center;border-radius:50%;color:var(--gray-0);pointer-events:none;}
.pe-cam-banner{top:10px;right:10px;width:32px;height:32px;background:#0007;backdrop-filter:blur(8px);-webkit-backdrop-filter:blur(8px);border:1.5px solid #fff8;}
.pe-cam-av{right:-2px;bottom:-2px;width:28px;height:28px;background:var(--gray-800);border:2.5px solid var(--gray-0);}
.pe-card{position:relative;}
.pe-banner-remove{position:absolute;z-index:3;top:58px;right:10px;padding:5px 10px;border:0;border-radius:var(--radius-full);background:#0007;backdrop-filter:blur(8px);-webkit-backdrop-filter:blur(8px);color:var(--gray-0);font:inherit;font-size:var(--fs-sm);font-weight:var(--fw-bold);}
.pe-banner-remove:active{transform:scale(.95);}
.pe-body{padding:44px 0 4px;}
.pe-row{display:block;width:100%;box-sizing:border-box;padding:12px 18px;border:0;background:none;text-align:left;font:inherit;color:var(--text);}
.pe-row+.pe-row{border-top:1px solid var(--gray-100);}
.pe-label{display:block;margin-bottom:4px;font-size:var(--fs-sm);font-weight:var(--fw-bold);color:var(--text-mid);}
.pe-lock{display:flex;align-items:center;gap:6px;min-width:0;font-size:var(--fs-base);}
.pe-lock svg{flex:none;color:var(--text-light);}
.pe-lock small{margin-left:auto;font-size:var(--fs-xs);color:var(--text-light);white-space:nowrap;}
.pe-bio{display:block;width:100%;padding:0;border:0;background:none;resize:none;outline:none;font:inherit;font-size:var(--fs-xl);line-height:1.4;color:var(--text);}
.pe-song-main{display:flex;align-items:center;gap:10px;}
.pe-song-cover{flex:none;width:40px;height:40px;border-radius:var(--radius-xs);corner-shape:squircle;object-fit:cover;}
.pe-song-text{flex:1;min-width:0;display:grid;}
.pe-song-text b{font-size:var(--fs-base);white-space:nowrap;overflow:hidden;text-overflow:ellipsis;}
.pe-song-text small{font-size:var(--fs-sm);color:var(--text-mid);white-space:nowrap;overflow:hidden;text-overflow:ellipsis;}
.pe-empty{font-size:var(--fs-base);font-weight:var(--fw-bold);color:var(--text-mid);}
.pe-chev{display:grid;color:var(--text-light);}
.pe-done{min-height:44px;padding:0 4px;border:0;background:none;font:inherit;font-size:var(--fs-lg);font-weight:var(--fw-bold);color:var(--text);}
/* 배경 자리 맞추기(Instagram Edit cover): 4:1 틀 안에서 끌어 보일 자리를 고른다 */
.bc-overlay{position:fixed;inset:0;z-index:160;display:flex;flex-direction:column;padding-top:env(safe-area-inset-top);background:var(--gray-900);color:var(--gray-0);animation:fadeIn .2s ease;}
.bc-overlay.closing{opacity:0;transition:opacity .15s ease;}
.bc-head{display:flex;align-items:center;justify-content:space-between;padding:6px 8px;}
.bc-head b{font-size:var(--fs-2xl);}
.bc-btn{min-height:44px;padding:0 12px;border:0;background:none;color:inherit;font:inherit;font-size:var(--fs-lg);}
.bc-done{font-weight:var(--fw-bold);}
.bc-frame{width:calc(100% - 32px);max-width:448px;margin:auto auto 0;aspect-ratio:4/1;overflow:hidden;border-radius:var(--radius-lg);corner-shape:squircle;outline:2px solid var(--gray-0);touch-action:none;cursor:grab;}
.bc-frame img{display:block;width:100%;height:100%;object-fit:cover;object-position:50% 50%;pointer-events:none;user-select:none;}
.bc-hint{margin:14px 0 auto;text-align:center;font-size:var(--fs-md);color:var(--gray-400);}
/* 노래 고르기 시트 */
.music-title{margin-bottom:12px;}
.music-title:has(+.music-note){margin-bottom:2px;}
.music-note{margin:0 0 12px;font-size:var(--fs-sm);color:var(--text-mid);}
.music-search{display:flex;align-items:center;gap:8px;padding:0 12px;border-radius:var(--radius-sm);corner-shape:squircle;background:var(--bg2);color:var(--text-light);}
.music-search input{flex:1;min-width:0;padding:12px 0;border:0;background:none;outline:none;font:inherit;font-size:var(--fs-xl);color:var(--text);}
.music-results{min-height:260px;margin-top:6px;}
.music-msg{margin:32px 0;text-align:center;font-size:var(--fs-md);color:var(--text-mid);}
.music-item{display:flex;align-items:center;gap:6px;}
.music-pick{flex:1;min-width:0;display:flex;align-items:center;gap:12px;padding:8px 0;border:0;background:none;font:inherit;color:var(--text);text-align:left;}
.music-cover{flex:none;display:grid;place-items:center;width:46px;height:46px;overflow:hidden;border-radius:var(--radius-xs);corner-shape:squircle;background:var(--gray-200);color:var(--text-light);}
.music-cover img{width:100%;height:100%;object-fit:cover;}
.music-text{min-width:0;display:grid;}
.music-text b{font-size:var(--fs-base);white-space:nowrap;overflow:hidden;text-overflow:ellipsis;}
.music-text small{font-size:var(--fs-sm);color:var(--text-mid);white-space:nowrap;overflow:hidden;text-overflow:ellipsis;}
.music-play{flex:none;display:grid;place-items:center;width:44px;height:44px;padding:0;border:0;border-radius:50%;background:none;color:var(--text);}
.music-play svg{box-sizing:content-box;padding:9px;border-radius:50%;background:var(--bg2);}
.music-remove{display:block;width:100%;margin-top:12px;padding:14px;border:0;border-radius:var(--radius-full);background:var(--bg2);color:var(--text);font:inherit;font-weight:var(--fw-bold);}

/* 지금 듣는 음악: 앨범 커버를 많이 흐린 배경 + 커버와 도는 LP + 노래명, 가수명. 마우스를 따라 기운다. */
.pp-tilt{margin:12px 0 0 -8px;}
.pp-music{position:relative;overflow:hidden;isolation:isolate;padding:8px 14px 8px 8px;border-radius:var(--radius-lg);corner-shape:squircle;background:var(--gray-100);color:var(--text);box-shadow:0 12px 22px -14px #0009;transform:perspective(1000px) rotateX(var(--tilt-rx,0deg)) rotateY(var(--tilt-ry,0deg));transition:transform 300ms var(--ease-smooth-out);will-change:transform;}
.pp-music.is-tilting{transition-duration:120ms;}
/* 흐린 바탕도 표지 가운데 정사각형만(YouTube 표지 양옆 회색 띠 빼기, 대표 10/18): 정사각 상자를 카드 가운데에 두고 가운데 띠만 보인다 */
.pp-music-bg{position:absolute;z-index:-2;left:-30px;top:50%;width:calc(100% + 60px);height:auto;aspect-ratio:1;max-width:none;object-fit:cover;transform:translateY(-50%);filter:blur(26px) saturate(1.4);}
/* 커버 밝기를 아직 못 쟀거나 못 읽으면 흰 막을 얹고 어두운 글씨로 둔다. 재면 흰 막 없이 글씨만 바꾼다. */
.pp-music[data-tone=wash]::before{content:"";position:absolute;z-index:-1;inset:0;background:rgba(255,255,255,.55);}
.pp-music[data-tone=light]{color:var(--gray-0);}
.pp-music-row{display:flex;align-items:center;gap:12px;}
.pp-disc{position:relative;width:52px;height:52px;flex:none;}
.pp-cover{position:absolute;z-index:2;left:0;top:0;display:grid;place-items:center;width:52px;height:52px;overflow:hidden;border-radius:var(--radius-xs);corner-shape:squircle;background:var(--gray-300);box-shadow:0 8px 14px -6px #000a;}
/* 표지가 정사각이 아니어도(16:9, 9:16, 4:3) 가운데 기준 정사각으로 채운다(대표 10/18). 격자 칸 안에선 height:100%가 그림 비율로 늘어나 위만 보여서 칸에 못 박는다 */
.pp-cover-img{position:absolute;inset:0;display:block;width:100%;height:100%;object-fit:cover;}
.pp-case{position:absolute;inset:0;width:100%;height:100%;object-fit:contain;pointer-events:none;}
/* 케이스를 받은 뒤 카드(대표 10/18 깨짐 고침, 시안 80dd8319): 닫힌 케이스 안 판에 표지가 원으로 비친다 */
/* 케이스 썸네일은 둥근 네모 틀(바탕, 모서리 자르기, 그림자) 없이 카드 위에 바로 놓인다(대표 10/19 "쓸데없는 둥근 네모를 없애라고") */
.pp-cover.has-case{overflow:visible;border-radius:0;corner-shape:round;background:none;box-shadow:none;}
.pp-cover.has-case .pp-cover-img{inset:8%;width:84%;height:84%;border-radius:50%;}
.pp-cover-empty{font-size:var(--fs-4xl);color:var(--text-mid);}
.pp-music-text{min-width:0;flex:1;display:grid;gap:2px;}
.pp-music-text b{font-size:var(--fs-base);font-weight:var(--fw-bold);letter-spacing:var(--ls-base);line-height:1.3;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;}
.pp-music-text span{font-size:var(--fs-sm);opacity:.82;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;}
.pp-eq{display:flex;align-items:flex-end;gap:2px;height:14px;flex:none;}
.pp-eq i{width:3px;height:100%;border-radius:var(--radius-2xs);background:currentColor;transform-origin:bottom;animation:ppEq 1s ease-in-out infinite;}
.pp-eq i:nth-child(2){animation-delay:-.35s;}
.pp-eq i:nth-child(3){animation-delay:-.7s;}
.pp-eq i:nth-child(4){animation-delay:-.15s;}
.pp-glare{position:absolute;z-index:3;inset:0;pointer-events:none;opacity:0;mix-blend-mode:screen;background:radial-gradient(circle 95px at var(--tilt-gx,50%) var(--tilt-gy,50%),rgba(255,255,255,.48),rgba(255,255,255,.06) 52%,rgba(255,255,255,0) 84%),radial-gradient(circle 200px at var(--tilt-gx,50%) var(--tilt-gy,50%),rgba(255,255,255,.22),rgba(255,255,255,.04) 58%,rgba(255,255,255,0) 78%);transition:opacity 200ms var(--ease-smooth-out);}
.pp-tilt.is-hover .pp-glare{opacity:.32;}
@keyframes ppSpin{to{transform:rotate(360deg);}}
@keyframes ppEq{0%,100%{transform:scaleY(.3);}50%{transform:scaleY(1);}}

/* 점 세 개 메뉴: 점 세 개 바로 아래에 뜬다 */
.pp-menu{--ease-spring:linear(0, 0.047, 0.164, 0.317, 0.481, 0.638, 0.775, 0.888, 0.974, 1.034, 1.071, 1.09, 1.095, 1.089, 1.078, 1.063, 1.048, 1.033, 1.02, 1.01, 1.002, 0.996, 0.993, 0.991, 1);position:absolute;right:8px;top:52px;z-index:3;min-width:150px;padding:6px;border-radius:var(--radius-lg);corner-shape:squircle;background:var(--gray-0);box-shadow:var(--shadow-pop);opacity:0;visibility:hidden;transform:scale(.88);transform-origin:top right;transition:opacity 130ms var(--ease-smooth-out),transform 150ms var(--ease-smooth-out),visibility 0s linear 150ms;}
.pp-menu.open{opacity:1;visibility:visible;transform:none;transition:opacity 150ms var(--ease-smooth-out),transform 400ms var(--ease-spring),visibility 0s;}
.pp-menu button{display:block;width:100%;padding:12px 16px;border:0;border-radius:var(--radius-xs);corner-shape:squircle;background:none;font:inherit;font-size:var(--fs-lg);font-weight:var(--fw-bold);color:var(--text);text-align:left;white-space:nowrap;}
.pp-menu button:active{background:var(--bg2);}

/* 상세 정보 시트: 팝오버에 없는 정보만 */
.di-list{padding:4px 16px;border-radius:var(--radius);corner-shape:squircle;background:var(--bg2);}
.di-row{display:flex;align-items:center;justify-content:space-between;gap:12px;min-height:46px;font-size:var(--fs-base);}
.di-row+.di-row{border-top:1px solid var(--border);}
/* 상세 정보의 대화 스타일(오늘의 질문 답으로 본 모습). 성격 카드와 같은 모양에 제목 줄과 "나와 몇 개 잘 맞는지"만 더한다. */
.di-qa{margin-top:28px;}
.di-qa-head{display:flex;align-items:baseline;justify-content:space-between;gap:12px;}
.di-qa-head .title-md{margin:0;}
.di-qa-agree{font-size:var(--fs-sm);color:var(--text-mid);}
.di-qa-agree b{font-weight:var(--fw-bold);color:var(--primary-dark);font-variant-numeric:tabular-nums;}
.di-qa-sub{margin:4px 0 0;font-size:var(--fs-sm);color:var(--text-light);}
.di-row>span{color:var(--text-mid);}
.di-row b{font-weight:var(--fw-bold);}
.di-fit{display:flex;align-items:center;margin:36px 0 34px;}
.di-score{flex:none;width:104px;padding-right:14px;text-align:center;}
.di-score strong{display:block;font-size:52px;font-weight:var(--fw-bold);letter-spacing:-.05em;line-height:1;}
.di-score strong small{margin-left:1px;font-size:var(--fs-xl);letter-spacing:0;}
.di-score>small{display:block;margin-top:5px;font-size:var(--fs-md);font-weight:var(--fw-bold);}
.di-bars{flex:1;min-width:0;display:grid;gap:14px;padding-left:16px;border-left:1px solid var(--border);}
.di-bar{display:grid;grid-template-columns:34px 1fr auto;align-items:center;gap:8px;font-size:var(--fs-md);}
.di-track{height:8px;overflow:hidden;border-radius:var(--radius-2xs);background:var(--primary-soft);}
.di-track i{display:block;height:100%;border-radius:var(--radius-2xs);background:var(--gray-800);transform:scaleX(0);transform-origin:left;animation:diFill 650ms var(--ease-smooth-out) 120ms forwards;} /* 목표를 지나치지 않고 차오르며 끝으로 갈수록 느려진다 */
.di-bar:nth-child(2) .di-track i{animation-delay:160ms;}
.di-bar b{min-width:34px;text-align:right;font-weight:var(--fw-bold);}
.di-any{font-size:var(--fs-sm);color:var(--text-light);}
/* 추천 이유 카드(§ui/spec-render.js, §domain/match-reasons.js): 상세 정보 시트의 적합도와 성격 토글 사이. 정적 내용이라 움직임은 없다. */
.rs-card{margin:0 0 28px;}
.rs-card .title-md{margin:0 0 10px;}
.rs-text{margin:0 0 12px;font-size:var(--fs-base);line-height:1.5;}
.rs-strong{font-weight:var(--fw-bold);color:var(--gray-600);}
.rs-soft{color:var(--text-mid);}
.rs-tags{display:flex;align-items:flex-start;gap:6px;margin:0 0 10px;}
.rs-label{flex:none;width:52px;font-size:var(--fs-sm);line-height:20px;color:var(--text-mid);}
.rs-items{flex:1;min-width:0;display:flex;flex-wrap:wrap;gap:6px;}
.rs-card>:last-child{margin-bottom:0;}
@keyframes diFill{to{transform:scaleX(var(--p));}}

@media(prefers-reduced-motion:reduce){
  .pp,.pp.closing{transform:none;filter:none;}
  .pp.is-full .pp-detail > *{animation:none;}
  .pp-menu,.pp-menu.open{transform:none;}
  .pp-music,.pp-music.is-tilting{transform:none;transition:none;}
  .pp-eq i{animation:none;}
  .di-track i{animation:none;transform:scaleX(var(--p));}
}

/* ---------- 지갑(§screens/wallet.js, 시안 wallet-preview.html) ---------- */
/* 금속 카드: 크레딧만 있으면 은색, Premium 이용 중이면 금색. 누르면 뒤집혀 이름, 잔액, Premium 기간이 보인다.
   카드 재질(금속 결, 칩, 그림자)은 높이가 아니라 재질이라 그림자 토큰으로 묶지 않는다(§design/mono-tone-clean.md) */
/* 카드는 화면 폭을 다 쓰지 않고 300px까지만 쓴다(2026-10-15 실제 폰에서 카드가 크다는 의견) */
.wallet-card-stage{max-width:300px;margin:18px auto 0;perspective:1100px;}
.wallet-card{position:relative;width:100%;aspect-ratio:1.586;border-radius:14px;transform-style:preserve-3d;transition:transform 280ms cubic-bezier(.77,0,.175,1);cursor:pointer;-webkit-tap-highlight-color:transparent;}
.wallet-card.is-flipped{transform:rotateY(180deg);}
.wallet-card:focus-visible{outline:2px solid var(--gray-500);outline-offset:6px;}
.wallet-card-face{position:absolute;inset:0;overflow:hidden;border-radius:14px;backface-visibility:hidden;-webkit-backface-visibility:hidden;border:1px solid #8c7746;color:#40351f;background:conic-gradient(from 22deg at 46% 45%,#9d8246,#d7bc78 14%,#fff1c5 23%,#b79a57 31%,#8d7137 47%,#ceb16b 64%,#fff0bd 73%,#b79c5c 82%,#9d8246);box-shadow:inset 0 1px 1px #fff1c9,inset 2px 0 2px #f3dea7,inset -2px 0 2px #685429,inset 0 -2px 1px #6f5b31,0 3px 0 #8a7447,0 13px 22px #3c321d24;}
.wallet-card:not(.is-premium) .wallet-card-face{filter:grayscale(1);}
.wallet-card.is-premium .wallet-card-face{background:conic-gradient(from 22deg at 46% 45%,#a38d5f,#d8c799 14%,#fff1ce 23%,#b9a470 31%,#998252 47%,#cbbb8d 64%,#f8ebc8 73%,#baa77b 82%,#a38d5f);}
.wallet-card-face::before{content:"";position:absolute;inset:0;pointer-events:none;background:repeating-radial-gradient(circle at 46% 45%,#fff8dc30 0 .3px,#62481818 .5px .8px,transparent 1px 1.55px);opacity:.68;}
.wallet-card-back{transform:rotateY(180deg);color:#262b31;border-color:#8f959c;box-shadow:inset 0 1px #fff,inset 0 -2px #696f77,0 3px 0 #858b92,0 13px 22px #22283124;}
.wallet-card.is-premium .wallet-card-back{color:#403520;border-color:#a39168;}
.wallet-card-chip{position:absolute;left:31px;top:65px;width:44px;height:35px;overflow:hidden;border-radius:7px;border:1px solid #967637;background:linear-gradient(125deg,#e4c778,#fbebae 23%,#c3a04e 48%,#ecd48f 73%,#aa843b);box-shadow:inset 0 1px #fff4c7,inset 0 -1px #8c692d,0 1px #ffffff60;}
.wallet-card-chip::before,.wallet-card-chip::after{content:"";position:absolute;left:0;right:0;height:1px;background:#99783c;box-shadow:0 1px #fff0b670;}
.wallet-card-chip::before{top:11px;}
.wallet-card-chip::after{bottom:11px;}
.wallet-card-chip i{position:absolute;top:0;bottom:0;width:1px;background:linear-gradient(#99783c 0 31%,transparent 31% 69%,#99783c 69%);}
.wallet-card-chip i:nth-child(1){left:25%;}
.wallet-card-chip i:nth-child(2){left:50%;}
.wallet-card-chip i:nth-child(3){left:75%;}
/* 앱 머리와 같은 로고 그림(mono-serif.png). 금속에 새긴 것처럼 곱하기로 얹는다 */
.wallet-card-brand{position:absolute;top:27px;right:27px;height:22px;width:auto;mix-blend-mode:multiply;opacity:.82;pointer-events:none;}
/* 뒷면: 위에 마그네틱 띠, 서명란, 잔액, Premium 기간, 오른쪽 아래 모노 심볼 */
.wallet-card-back::after{content:"";position:absolute;top:19px;left:0;right:0;height:32px;background:linear-gradient(180deg,#27282a,#353638 45%,#252628);box-shadow:inset 0 1px #ffffff18,inset 0 -1px #0005;pointer-events:none;}
.wallet-card-signature{position:absolute;top:63px;left:24px;right:114px;height:26px;padding:2px 10px;overflow:hidden;white-space:nowrap;text-overflow:ellipsis;line-height:22px;border-radius:1px;background:repeating-linear-gradient(0deg,#ffffff60 0 1px,#e7e4da50 1px 3px);box-shadow:inset 0 0 0 1px #ffffff25;font:italic 18px Georgia,'Apple SD Gothic Neo',serif;color:#484744;letter-spacing:-.05em;}
.wallet-card-kicker{position:absolute;top:64px;right:24px;font:var(--fw-regular) 9px var(--font-sys);letter-spacing:.1em;text-shadow:0 1px #fff6;opacity:.65;}
.wallet-card-total{position:absolute;top:105px;left:24px;right:24px;display:grid;gap:5px;text-shadow:0 1px #ffffff65;}
.wallet-card-total span,.wallet-card-meta span{display:block;font:var(--fw-regular) 8px var(--font-sys);letter-spacing:.1em;opacity:.7;}
.wallet-card-total strong{font:400 25px 'SFMono-Regular',Consolas,monospace;font-variant-numeric:tabular-nums;letter-spacing:.035em;line-height:1.15;}
.wallet-card-meta{position:absolute;left:24px;right:126px;bottom:23px;text-shadow:0 1px #ffffff65;}
.wallet-card-meta strong{display:block;margin-top:7px;font:400 11px 'SFMono-Regular',Consolas,monospace;font-variant-numeric:tabular-nums;letter-spacing:.015em;white-space:nowrap;line-height:1.2;}
.wallet-card-symbol{position:absolute;right:24px;bottom:22px;width:62px;height:62px;overflow:hidden;mix-blend-mode:multiply;line-height:0;}
.wallet-card-symbol img{position:absolute;display:block;width:108px;max-width:none;height:108px;left:-23px;top:-23px;}
/* 300px 카드에 맞춘 크기와 자리. 위의 값을 덮는다 */
.wallet-card-chip{left:25px;top:56px;width:39px;height:32px;}
/* 앞면 로고는 카드에 비해 작게(2026-10-15 로고가 크다는 의견, 19px에서 14px) */
.wallet-card-brand{top:22px;right:22px;height:14px;}
.wallet-card-back::after{top:15px;height:26px;}
.wallet-card-signature{top:51px;left:18px;right:96px;height:22px;line-height:18px;font-size:16px;}
.wallet-card-kicker{top:51px;right:18px;font-size:8px;}
.wallet-card-total{left:18px;right:18px;top:86px;gap:4px;}
.wallet-card-total strong{font-size:21px;}
.wallet-card-total span,.wallet-card-meta span{font-size:7px;}
.wallet-card-meta{left:18px;right:104px;bottom:18px;}
.wallet-card-meta strong{font-size:9px;margin-top:6px;}
.wallet-card-symbol{right:18px;bottom:18px;width:52px;height:52px;}
.wallet-card-symbol img{width:90px;height:90px;left:-19px;top:-19px;}
@media(prefers-reduced-motion:reduce){.wallet-card{transition:none;}}
.wallet-card-hint{margin:17px 0 0;text-align:center;font-size:var(--fs-xs);color:var(--text-light);}
.wallet-card-stage{position:relative;touch-action:pan-x;}
.wallet-tabs{margin:6px 0 0;background:var(--gray-100);}
.wallet-tabs .segment-indicator{background:var(--gray-0);}
.wallet-charge{margin-top:20px;}
.wallet-test-note{margin:8px 0 0;text-align:center;font-size:var(--fs-xs);color:var(--text-light);}
.wallet-history-toggle{display:block;width:100%;margin:12px 0 0;padding:14px 0 10px;border:0;background:none;font:inherit;font-size:var(--fs-xs);color:var(--text-mid);cursor:pointer;}
.wallet-history-toggle span{display:block;margin-bottom:4px;font-size:var(--fs-3xl);line-height:1;}
.wallet-section-title{margin:14px 4px 10px;font-size:var(--fs-lg);font-weight:var(--fw-bold);}
#walletHistory .empty-state{padding:28px 16px;}
.wallet-history-row{display:flex;align-items:center;gap:12px;padding:13px 16px;}
.wallet-history-row+.wallet-history-row{border-top:1px solid var(--border);}
.wallet-history-icon{display:grid;place-items:center;flex-shrink:0;width:32px;height:32px;border-radius:var(--radius-xs);corner-shape:squircle;background:var(--bg2);font-size:var(--fs-xl);color:var(--text-mid);}
.wallet-history-text{flex:1;min-width:0;display:flex;flex-direction:column;gap:3px;}
.wallet-history-text b{font-size:var(--fs-base);font-weight:var(--fw-regular);overflow:hidden;white-space:nowrap;text-overflow:ellipsis;}
.wallet-history-text small{font-size:var(--fs-xs);color:var(--text-light);}
.wallet-history-row strong{flex-shrink:0;font-size:var(--fs-base);font-weight:var(--fw-bold);font-variant-numeric:tabular-nums;color:var(--text-mid);}
.wallet-history-row strong.is-plus{color:var(--primary-dark);}
/* Premium 탭 */
.mypage-settings-main .wallet-subscription{margin-top:20px;padding:16px;}
.wallet-subscription-head{display:flex;align-items:center;justify-content:space-between;gap:12px;}
.wallet-wordmark{font:24px Georgia,serif;letter-spacing:-.02em;}
.wallet-wordmark i{font-size:20px;color:var(--text-mid);}
.wallet-badge{padding:4px 10px;border-radius:var(--radius-full);background:var(--bg2);font-size:var(--fs-xs);font-weight:var(--fw-bold);color:var(--text-mid);}
.wallet-badge.is-on{background:var(--gray-900);color:var(--gray-0);}
.wallet-subscription p{margin:10px 0 0;font-size:var(--fs-sm);color:var(--text-mid);}
.wallet-premium-hero{padding:30px 0 22px;text-align:center;}
.wallet-eyebrow{font:10px Georgia,serif;letter-spacing:.12em;color:var(--text-light);}
.wallet-chrome-heart{margin:10px auto 6px;font:96px Georgia,serif;line-height:1.15;color:#7c8591;text-shadow:0 1px #fff,0 2px #b4bbc5;}
.wallet-premium-hero h2{margin:0;font-size:var(--fs-4xl);font-weight:var(--fw-bold);line-height:1.5;letter-spacing:-.04em;}
.wallet-benefit{display:flex;gap:16px;padding:16px;}
.wallet-benefit+.wallet-benefit{border-top:1px solid var(--border);}
.wallet-benefit-no{padding-top:1px;font:italic 15px Georgia,serif;color:var(--text-light);}
.wallet-benefit b{display:block;font-size:var(--fs-base);font-weight:var(--fw-bold);}
.wallet-benefit small{display:block;margin-top:5px;font-size:var(--fs-sm);color:var(--text-mid);}
.wallet-price{margin:20px 0 8px;padding:18px 16px 16px;border:1px solid var(--border);border-radius:var(--radius-xl);corner-shape:squircle;background:linear-gradient(135deg,var(--gray-0),var(--bg2));}
.wallet-price-row{display:flex;align-items:center;justify-content:space-between;margin-bottom:16px;}
.wallet-price-row span{font-size:var(--fs-sm);color:var(--text-mid);}
.wallet-price-row strong{font-size:26px;font-weight:var(--fw-regular);letter-spacing:-.04em;}
.wallet-price-row small{margin-left:3px;font-size:var(--fs-xs);letter-spacing:0;color:var(--text-mid);}
.wallet-price p{margin:12px 0 0;font-size:var(--fs-xs);line-height:1.6;color:var(--text-light);}
/* 충전 시트의 상품 */
.wallet-packs{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:8px;margin-bottom:16px;}
.wallet-pack{position:relative;display:flex;flex-direction:column;gap:4px;padding:14px;border:1.5px solid var(--border);border-radius:var(--radius-sm);corner-shape:squircle;cursor:pointer;}
.wallet-pack:has(input:checked){border:2px solid var(--gray-800);}
.wallet-pack input{position:absolute;opacity:0;width:1px;height:1px;}
.wallet-pack strong{font-size:var(--fs-xl);font-variant-numeric:tabular-nums;}
.wallet-pack small{font-size:var(--fs-sm);color:var(--text-mid);}
/* 충전 단말기: 아래 투입구로 카드의 칩 쪽이 들어간다(§ui/wallet-motion.js playCardCharge). 충전할 때만 보인다 */
.wallet-reader{position:absolute;z-index:5;left:17%;top:-17%;width:38%;height:76%;display:none;opacity:0;pointer-events:none;border-radius:18px 18px 13px 13px;border:1px solid #555b5d;color:#b9c0bf;transform:rotate(-28deg);background:radial-gradient(ellipse at 28% 0%,#ffffff14,transparent 55%),radial-gradient(#ffffff0c .45px,transparent .8px),linear-gradient(100deg,#353a3c,#222729 22%,#292e30 74%,#191d20);background-size:auto,2px 2px,auto;box-shadow:inset 1px 1px 1px #b6bdbd60,inset -2px -2px 3px #080b0d,3px 4px 0 #8c9294,5px 7px 0 #454c50,6px 9px 0 #202628,10px 17px 19px #0004;}
.wallet-reader::before{content:"";position:absolute;inset:5px 5px 10px;border:1px solid #131819;border-radius:13px 13px 9px 9px;box-shadow:inset 0 1px #ffffff12,0 1px #ffffff0c;pointer-events:none;}
.wallet-reader::after{content:"";position:absolute;left:20%;right:20%;top:12px;height:4px;border-radius:1px;background:#0e1213;box-shadow:0 1px #62696b70;pointer-events:none;}
.wallet-reader-led{position:absolute;top:12px;right:13px;width:3px;height:3px;border-radius:50%;background:#899b8f;}
.wallet-reader.is-approved .wallet-reader-led{background:#9de4bf;box-shadow:0 0 5px #9de4bf90;}
.wallet-reader-brand{position:absolute;bottom:11px;left:12px;height:7px;width:auto;filter:invert(1);opacity:.7;}
.wallet-reader-display{position:absolute;top:16%;left:10%;right:10%;height:33%;display:grid;place-items:center;border:5px solid #111718;border-radius:4px;background:linear-gradient(145deg,#d0d9d4,#a4b9b1);color:#233c36;font:7px monospace;text-align:center;box-shadow:0 0 0 1px #535c5d,inset 0 2px 3px #0004,0 2px 2px #0008;}
.wallet-reader-display::after{content:"";position:absolute;inset:0;background:linear-gradient(125deg,#ffffff45,transparent 35%,transparent 75%,#ffffff14);pointer-events:none;}
.wallet-reader-keypad{position:absolute;top:54%;bottom:17%;left:13%;right:13%;display:grid;grid-template-columns:repeat(3,1fr);gap:3px;padding:3px;border-radius:5px;background:#12191b;box-shadow:inset 0 1px 3px #000b,0 1px #ffffff20;}
.wallet-reader-keypad i{display:grid;place-items:center;font:normal 7px var(--font-sys);border:1px solid #777d7e;border-radius:3px;background:linear-gradient(155deg,#b9bdbb,#8e9593);box-shadow:inset 0 1px #ffffff75,0 2px 1px #000b;color:#1d2829;text-shadow:0 1px #ffffff45;}
.wallet-reader-keypad .key-cancel{position:relative;background:linear-gradient(#ae6259,#813e36);border-color:#9a5d55;}
.wallet-reader-keypad .key-confirm{position:relative;background:linear-gradient(#72a27c,#46734e);border-color:#6d9777;}
.wallet-reader-keypad .key-cancel::after{content:'×';font:9px sans-serif;color:#fff9;}
.wallet-reader-keypad .key-confirm::after{content:'↵';font:9px sans-serif;color:#fff9;}
.wallet-reader-slot{position:absolute;left:8%;right:8%;bottom:1px;height:6px;border-radius:1px;background:#030607;box-shadow:0 -2px 1px #090d10,0 1px #b8bebd80;}
.wallet-card-stage.is-charging{pointer-events:none;}
.wallet-card-stage.is-charging .wallet-reader{display:block;}
.wallet-card-stage.is-charging .wallet-card{transition:none;}
/* Premium 시작: 금색이 칩 근처에서 번지고 빛이 한 번 지나간다(§ui/wallet-motion.js playPremiumBloom) */
.wallet-card-stage.is-blooming{pointer-events:none;}
/* 은색은 회색 필터로 만든 것이라, 번지는 금색까지 회색이 되지 않게 그동안만 필터 대신 은색 바탕을 직접 깐다 */
.is-blooming .wallet-card:not(.is-premium) .wallet-card-front{overflow:hidden;filter:none;background:conic-gradient(from 22deg at 46% 45%,#888,#c2c2c2 14%,#eee 23%,#aaa 31%,#777 47%,#bbb 64%,#eee 73%,#aaa 82%,#888);}
.is-blooming .wallet-card-front>.wallet-card-chip{filter:grayscale(1);}
.wallet-gold-bloom{position:absolute;inset:0;z-index:4;overflow:hidden;border-radius:inherit;pointer-events:none;opacity:0;background:conic-gradient(from 22deg at 46% 45%,#a38d5f,#d8c799 14%,#fff1ce 23%,#b9a470 31%,#998252 47%,#cbbb8d 64%,#f8ebc8 73%,#baa77b 82%,#a38d5f);}
.wallet-gold-bloom::before{content:'';position:absolute;inset:0;opacity:.5;background:repeating-radial-gradient(circle at 46% 45%,#fff8dc30 0 .3px,#62481818 .5px .8px,transparent 1px 1.55px);}
.wallet-card-flash{position:absolute;z-index:7;top:-35%;bottom:-35%;left:0;width:27%;opacity:0;pointer-events:none;mix-blend-mode:screen;background:linear-gradient(90deg,transparent,#fff9e999 50%,transparent);}
.wallet-premium-arrival{position:absolute;z-index:4;top:calc(100% + 13px);left:0;right:0;text-align:center;font:italic 17px Georgia,serif;color:#74613b;pointer-events:none;}
.wallet-card-stage:has(.wallet-premium-arrival)+.wallet-card-hint{visibility:hidden;}
@media(prefers-reduced-motion:reduce){.wallet-card-stage.is-charging .wallet-reader,.wallet-card-flash{display:none;}}
/* 프로필 노래 링크 넣기(이슈 #194, §actions/profile-look.js): 미리보기 줄의 넣기 버튼과 서비스 고르기 줄 */
.music-add{flex:none;width:auto;height:36px;padding:0 16px;font-size:var(--fs-md);}
.music-service{display:flex;align-items:center;justify-content:space-between;width:100%;height:52px;padding:0 4px;border:0;border-bottom:1px solid var(--border);background:none;font:inherit;font-size:var(--fs-lg);color:var(--text);cursor:pointer;}
.music-service:last-child{border-bottom:0;}
.pp-tilt[role="button"]{cursor:pointer;}
/* 프로필 노래 서비스 공식 아이콘(#194). Spotify, Apple Music은 21px, YouTube는 원본 둘레 여백까지 넣어 몸통이 비슷한 크기 */
.pp-svc,.music-svc{flex:none;width:21px;height:21px;object-fit:contain;}
.pp-svc[data-svc=youtubeMusic],.music-svc[data-svc=youtubeMusic]{width:35px;height:30px;margin:-4px -7px;}
.music-service-name{display:flex;align-items:center;gap:12px;}
/* 프로필 편집 사진 옆 "사진 바꾸기"(회색)와 "보정 프로필"(검정, #312, 시안 premium-312 EDIT) */
.pe-photo-btns{position:absolute;z-index:2;left:112px;top:8px;display:flex;gap:6px;}
.pe-pill{position:relative;display:inline-flex;align-items:center;gap:4px;height:30px;padding:0 12px;border-radius:var(--radius-full);background:var(--gray-100);font-size:var(--fs-sm);font-weight:var(--fw-bold);color:var(--text);}
.pe-pill.is-dark{background:var(--gray-900);color:var(--gray-0);}
.pe-pill:active{transform:scale(.96);}
/* CD 케이스 열 때 알림 한 줄(frontend-queue 37, 시안 cd3d.html ?fb=1): 고른 앱에 없는 곡이면 케이스 바로 밑 가운데, 평소는 아래 검은 알약 */
.cd-note{position:fixed;z-index:9002;left:16px;right:16px;top:calc(690 / 812 * 100%);display:flex;align-items:center;justify-content:center;gap:8px;font-size:var(--fs-md);font-weight:var(--fw-bold);color:var(--text);white-space:nowrap;opacity:0;pointer-events:none;}
.cd-note.is-pill{left:50%;right:auto;top:auto;bottom:calc(28px + env(safe-area-inset-bottom));height:40px;padding:0 16px;border-radius:var(--radius-full);background:var(--gray-900);color:var(--gray-0);font-size:var(--fs-sm);}
.cd-note-svc{width:24px;height:22px;object-fit:contain;}
.cd-note.is-pill .cd-note-svc{width:20px;height:20px;}
/* ---------- 파티(Party) ---------- */
/* 하단 내비: iOS 26 Liquid Glass 탭 바를 따라 했다(HIG Tab bars, WWDC25 "Meet Liquid Glass", 애플 Shazam의 iOS 26 탭 바).
   .bottom-nav는 자리만 잡는 틀이다. 그 안에 탭 네 개가 든 유리 알약(.nav-pill)과 메시지 유리 동그라미(.nav-orb)를 나란히 둔다. 동그라미는 Shazam의 검색 동그라미 자리이고 높이가 알약과 같다.
   1. 유리: iOS 26 Clear(Apple 뮤직, Shazam). 흰 막은 위 30%에서 아래 15%로 옅게만 깔고 흐림도 7px로 낮춰 뒤 화면이 비친다. 채도는 비치는 색이 형광처럼 번지지 않을 만큼만 올린다.
   2. 두께: 왼쪽 위 가장자리에 진한 흰 반사선, 오른쪽 아래에 옅은 반사선, 안쪽 둘레에 흰 빛. 알약은 ::after의 대각선 테두리로 반사광을 더한다.
   3. 아이콘: iOS 탭 바처럼 채운 모양. 꺼진 탭도 진한 회색이고, 복잡한 배경 위에서도 읽히게 둘레에 옅은 흰 번짐을 둔다.
   4. 메시지 화면에 있으면(.nav-chat) 애플 뮤직 검색 탭처럼 알약이 접히고 동그라미가 넓어져 대화 검색칸이 된다(아래 .nav-chat). 안 읽은 수는 iOS 기본처럼 테두리 없이 아이콘 오른쪽 위에 붙는다.
   5. 화면 아래 가장자리: 탭 바 뒤로 콘텐츠가 아래로 갈수록 살짝 흐려진다(iOS 26 scroll edge effect, ::before).
   선택 캡슐(.nav-lens)은 알약 안에서만 움직이고, 위치는 --i(활성 탭 번호), --n(탭 개수), --pad(안쪽 여백)로만 정한다.
   흐림(backdrop-filter)은 알약과 동그라미 자신에 건다. 탭 전환 때도 탭 바는 그대로 두고 화면(.main)만 크로스페이드한다(§app-paint-runtime.js crossfade).
   바닥 여백(bottom)은 아래 가장자리 종류에 따라 다르다.
   1. 홈 막대(iOS 34px, 갤럭시 제스처 막대 약 24px): 투명한 띠라 iOS 26 탭 바처럼 그 띠에 살짝 걸쳐 내려앉는다(인셋에서 8px 덜, 최소 16px).
   2. 갤럭시 버튼 세 개(뒤로, 홈, 최근, 48px): 실제 버튼이 있는 띠라 그 위로 8px 띄운다. 인셋이 40px 넘으면 버튼 띠로 본다. 세 번째 항이 그 분기다(40px 넘으면 인셋+8px, 아니면 아주 작은 값).
   3. 인셋이 없는 브라우저와 옛 웹뷰(앱이 버튼 띠 위까지만 그린다): 16px. */
.bottom-nav{--n:4;--pad:4px;--i:0;--sab:env(safe-area-inset-bottom,0px);gap:8px;bottom:max(16px,calc(var(--sab) - 8px),min(calc(var(--sab) + 8px),calc((var(--sab) - 40px) * 999)));touch-action:none;}
.bottom-nav::before{content:"";position:absolute;z-index:-1;left:50%;bottom:calc(-40px - var(--sab));width:100vw;max-width:480px;height:calc(150px + var(--sab));transform:translateX(-50%);pointer-events:none;
  background:linear-gradient(to top,#ffffff40,#fff0);backdrop-filter:blur(2px);-webkit-backdrop-filter:blur(2px);
  -webkit-mask:linear-gradient(to top,#000 35%,#0000);mask:linear-gradient(to top,#000 35%,#0000);}
.nav-pill,.nav-orb{position:relative;height:58px;border:0;
  background:linear-gradient(180deg,#ffffff4d,#ffffff26);
  backdrop-filter:blur(7px) saturate(135%) brightness(1.08);-webkit-backdrop-filter:blur(7px) saturate(135%) brightness(1.08);
  box-shadow:inset 1.5px 1.5px 0 -.5px #ffffffe6,inset -1px -1px 0 -.5px #ffffffa6,inset 0 0 0 .5px #ffffff80,inset 0 0 14px #ffffff4d,0 0 0 .5px #0000000f,0 10px 26px -10px #00000047;}
.nav-pill{flex:1 1 0%;min-width:0;display:flex;align-items:center;padding:0 var(--pad);border-radius:29px;transition:flex .52s var(--ease-drawer);}
.nav-pill::after{content:"";position:absolute;inset:0;z-index:2;border-radius:inherit;padding:1px;pointer-events:none;
  background:linear-gradient(135deg,#fffffff2,#ffffff26 30%,#ffffff00 50%,#ffffff26 70%,#ffffffcc);
  -webkit-mask:linear-gradient(#000 0 0) content-box,linear-gradient(#000 0 0);-webkit-mask-composite:xor;mask:linear-gradient(#000 0 0) content-box exclude,linear-gradient(#000 0 0);}
.nav-orb{flex:0 0 58px;min-width:0;padding:0;border-radius:29px;overflow:hidden;color:var(--gray-600);transition:flex .52s var(--ease-drawer),color .25s ease,transform .1s ease-out;}
.bottom-nav:not(.nav-chat) .nav-orb:active{transform:scale(.94);}
/* 동그라미 전체가 누르는 자리(.nav-orb-btn)이고, 메시지 화면에서는 그 위에 대화 검색칸(.nav-orb-input)이 놓인다 */
.nav-orb-btn{position:absolute;inset:0;padding:0;border:0;background:none;border-radius:inherit;}
.nav-orb-ic{pointer-events:none;}
.nav-orb-ic{position:absolute;left:17px;top:17px;display:grid;}
.nav-orb .nav-ic{width:24px;height:24px;}
/* 선택 캡슐(.nav-lens, §ui/nav-lens.js): 쉴 때는 옅은 회색 알약이고 위치는 --i가 정한다. 누르면 JS가 transform과 --p(0에서 1)를 직접 움직이고, ::after의 흰 유리막과 반사광, 그림자가 --p만큼 드러나 렌즈가 된다 */
.nav-lens{--p:0;position:absolute;z-index:0;top:var(--pad);left:var(--pad);width:calc((100% - var(--pad) * 2) / var(--n));height:calc(100% - var(--pad) * 2);border-radius:25px;background:#7676801c;box-shadow:inset 0 .5px 0 #ffffff80;transform:translateX(calc(var(--i) * 100%));transition:transform .42s var(--ease-drawer),opacity .2s ease-out;pointer-events:none;will-change:transform;}
.nav-lens::after{content:"";position:absolute;inset:0;border-radius:inherit;opacity:var(--p);background:linear-gradient(180deg,#ffffffc7,#ffffff73);box-shadow:inset 0 1px 1px #fff,inset 0 -1px 1px #ffffffa6,inset 0 0 0 .5px #ffffffd9,0 0 0 .5px #0000001a,0 8px 20px #00000029,0 2px 4px #00000014;}
/* 렌즈 아래 아이콘은 돋보기처럼 커진다(살짝 튕기는 곡선) */
.bottom-nav .nav-item > svg{transition:transform .28s cubic-bezier(.34,1.56,.64,1),opacity .2s ease .26s;}
.bottom-nav .nav-item.under-lens > svg{transform:scale(1.16);}
.bottom-nav.nav-none .nav-lens{opacity:0;}
/* 메시지 화면(.nav-chat, §screens/app-shell.js renderBottomNav): 알약은 마지막으로 있던 탭(.is-last) 하나만 남은 동그라미로 접히고, 동그라미는 넓어져 대화 검색칸이 된다.
   아이콘은 사라지지 않는다. 남는 탭 아이콘은 접히는 알약을, 말풍선은 넓어지는 유리의 왼쪽 끝을 따라가며 돋보기로 바뀐다.
   나머지 탭, 렌즈, 글자는 크기가 거의 다 바뀐 뒤에 나타나서 미끄러지는 모습이 보이지 않는다 */
.nav-lens{transition:transform .42s var(--ease-drawer),opacity .2s ease-out .26s;}
.nav-chat .nav-lens{opacity:0;transition:opacity .1s ease;}
.nav-chat .nav-pill{flex:0 0 58px;}
.nav-chat .nav-item:not(.is-last){flex:0 0 0%;visibility:hidden;transition:flex .52s var(--ease-drawer),visibility 0s .1s;}
.nav-chat .nav-item:not(.is-last) > svg{opacity:0;transition:opacity .1s ease;}
.nav-chat .nav-orb{flex:1 1 0%;color:var(--gray-900);}
.nav-chat .nav-orb .badge{display:none;}
.nav-orb-ic > .nav-ic{transition:opacity .2s ease .1s,scale .36s cubic-bezier(.34,1.56,.64,1) .1s;}
.nav-orb-search{position:absolute;inset:0;display:grid;place-items:center;opacity:0;scale:.5;transition:opacity .12s ease,scale .2s ease;}
.nav-chat .nav-orb-ic > .nav-ic{opacity:0;scale:.5;transition:opacity .12s ease,scale .2s ease;}
.nav-chat .nav-orb-search{opacity:1;scale:1;transition:opacity .2s ease .1s,scale .36s cubic-bezier(.34,1.56,.64,1) .1s;}
/* 글자 크기 16px: iOS가 입력칸을 누를 때 화면을 확대하지 않는 크기 */
.nav-orb-input{position:absolute;left:51px;right:14px;top:0;height:100%;padding:0;border:0;background:none;outline:none;font:inherit;font-size:16px;color:var(--gray-900);opacity:0;visibility:hidden;transition:opacity .12s ease,visibility 0s .12s;}
.nav-orb-input::placeholder{color:var(--gray-450);}
.nav-orb-input::-webkit-search-cancel-button{filter:grayscale(1);opacity:.5;} /* 크롬 기본 지우기 x는 파란색이라 회색으로 */
.nav-chat .nav-orb-input{opacity:1;visibility:visible;transition:opacity .2s ease .3s,visibility 0s;}
/* 탭은 아이콘만(글자 없음, 이름은 aria-label). 꺼진 탭은 진한 회색, 켜진 탭은 검정 */
.bottom-nav .nav-item{z-index:1;padding:0;color:var(--gray-600);transition:flex .52s var(--ease-drawer),color .25s ease,opacity .1s ease-out;}
.bottom-nav .nav-item.active{color:var(--gray-900);}
.bottom-nav .nav-item .nav-ic{width:24px;height:24px;opacity:1;}
.bottom-nav .nav-item svg,.nav-orb:not(.active) svg{filter:drop-shadow(0 0 4px #ffffffa6);}
@media(prefers-reduced-transparency:reduce){.nav-pill,.nav-orb{background:var(--gray-50);backdrop-filter:none;-webkit-backdrop-filter:none;}.nav-orb.active{background:var(--gray-900);}.bottom-nav::before{display:none;}}
@media (prefers-reduced-motion:reduce){.nav-lens,.nav-pill,.bottom-nav .nav-item,.bottom-nav .nav-item > svg,.nav-orb,.nav-orb-ic > .nav-ic,.nav-orb-search,.nav-orb-input{transition:none!important;}}

.party-category-row{margin:2px 0 16px;overflow-x:auto;flex-wrap:nowrap;padding-bottom:2px;-webkit-overflow-scrolling:touch}
.party-category-row::-webkit-scrollbar{display:none}
.party-category-row .chip{flex:0 0 auto}
.party-card{padding:16px}
.party-card-top{display:flex;align-items:center;gap:6px;margin-bottom:8px}
.party-card-top .spacer{flex:1}
.party-chip{padding:3px 9px;border-radius:var(--radius-full);background:var(--primary-soft);color:var(--text-mid);font-size:var(--fs-2xs);font-weight:var(--fw-bold);white-space:nowrap}
.party-chip-mine{background:var(--gray-800);color:var(--gray-0)}
.party-remain{font-size:var(--fs-2xs);font-weight:var(--fw-bold);color:var(--text-light);white-space:nowrap}
.party-card-title{font-size:var(--fs-lg);font-weight:var(--fw-bold);line-height:1.35;word-break:break-word}
.party-card-purpose{margin-top:5px;font-size:var(--fs-sm);line-height:1.5;color:var(--text-mid);display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden}
.party-card-foot{display:flex;align-items:center;gap:8px;margin-top:12px}
.party-count{display:inline-flex;align-items:center;gap:4px;font-size:var(--fs-xs);font-weight:var(--fw-bold);color:var(--text-mid);white-space:nowrap}
.party-host{font-size:var(--fs-xs);font-weight:var(--fw-bold);color:var(--text-light);white-space:nowrap;overflow:hidden;text-overflow:ellipsis;max-width:90px}
.party-badge{padding:3px 8px;border-radius:var(--radius-full);background:var(--primary-soft);color:var(--text-mid);font-size:var(--fs-2xs);font-weight:var(--fw-bold);white-space:nowrap}
.party-gauge{flex:1;min-width:24px;height:4px;border-radius:var(--radius-full);background:var(--primary-soft);overflow:hidden;display:block}
.party-gauge-fill{display:block;height:100%;border-radius:var(--radius-full);background:var(--gray-800)}
.party-gauge-lg{height:6px;margin-top:16px}

/* 개설 버튼은 바텀 네비 위에 뜬다 — 네비 높이(60px)와 아래 여백을 피해 배치한다. */
.party-fab{position:absolute;right:20px;bottom:calc(88px + env(safe-area-inset-bottom));z-index:29;display:inline-flex;align-items:center;gap:6px;padding:13px 18px;border:0;border-radius:var(--radius-full);background:var(--gray-800);color:var(--gray-0);font:inherit;font-size:var(--fs-md);font-weight:var(--fw-bold);box-shadow:var(--shadow-pop)}
.party-fab:active{opacity:.85;transform:scale(.97)}

.party-member-list{display:flex;flex-direction:column;gap:2px;margin-bottom:22px;border-radius:var(--radius-lg);corner-shape:squircle;background:var(--gray-0);box-shadow:var(--shadow-sm);overflow:hidden}
.party-member-row{display:flex;align-items:center;gap:10px;padding:12px 14px;width:100%;border:0;background:none;font:inherit;color:inherit;text-align:left}
.party-member-row:not(:last-child){border-bottom:1px solid var(--border)}
.party-member-photo{width:32px;height:32px;border-radius:50%;object-fit:cover;flex:0 0 auto}
.party-member-initials{display:flex;align-items:center;justify-content:center;color:var(--gray-0);font-size:var(--fs-sm);font-weight:var(--fw-bold)}
.party-member-name{flex:1;min-width:0;font-size:var(--fs-md);font-weight:var(--fw-bold);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.party-member-pick:active{background:var(--primary-light)}
/* 방장 도구(§screens/party-host.js): 멤버 줄의 마지막으로 말한 날, 새 단체로 옮기기 고르기, 받은 초대 */
.party-member-text{flex:1;min-width:0;display:flex;flex-direction:column;gap:2px}
.party-member-text .party-member-name{flex:none}
.party-member-sub{font-size:var(--fs-sm);font-weight:var(--fw-regular);color:var(--text-mid)}
.party-move-list{max-height:52vh;overflow-y:auto;margin-bottom:14px}
.party-move-face{flex:none;display:flex}
.party-move-check{flex:none;display:grid;place-items:center;width:24px;height:24px;border-radius:50%;border:1.5px solid var(--border);color:transparent;transition:background-color 100ms ease-out,border-color 100ms ease-out}
.party-move-check.is-on{background:var(--primary);border-color:var(--primary);color:var(--gray-0)}
.party-move-count{margin-left:6px;font-size:var(--fs-md);font-weight:var(--fw-regular);color:var(--text-light)}
.party-invite:active{transform:none;background:none}
.party-invite-acts{flex:none;display:flex;gap:6px}

.party-form{display:flex;flex-direction:column;gap:0}
.party-form-label{display:block;margin:18px 2px 8px;font-size:var(--fs-sm);font-weight:var(--fw-bold);color:var(--text-mid)}
/* placeholder는 값을 넣는 순간 사라져서 한도를 다시 확인할 수 없다 — 라벨 옆에 남겨 둔다. */
.party-form input,.party-form textarea{width:100%;box-sizing:border-box;padding:14px;border:1.5px solid var(--border);border-radius:var(--radius-sm);corner-shape:squircle;background:var(--gray-0);font:inherit;font-size:var(--fs-base);color:inherit;margin:8px 0 0}
.party-form textarea{resize:vertical;line-height:1.6}
.party-form .chip-row{margin-bottom:2px}
.party-form .hint{margin:8px 2px 0;line-height:1.55}
.party-form-error{color:var(--text-mid);font-weight:var(--fw-bold)}
.party-cost-row{display:flex;align-items:center;justify-content:space-between;gap:12px;margin:22px 0 14px;padding:15px 16px;border-radius:var(--radius-sm);corner-shape:squircle;background:var(--primary-soft);font-size:var(--fs-md);font-weight:var(--fw-bold);color:var(--text-mid)}
.party-cost-row b{font-size:var(--fs-base);color:var(--text)}
.party-form .btn{margin-top:10px}

/* ---------- 파티방(그룹 채팅) ---------- */
/* 1:1 대화방과 같은 틀(.chatroom-main, 유리 머리, 같은 말풍선, 떠 있는 입력 바, §screens/party.js renderPartyRoom).
   다른 점은 상대 묶음 위 이름 한 줄과 머리의 단체 사진뿐이다. */
/* 상대 묶음 맨 위(카카오톡식, design/chat-room-mock7.html A): 이름은 말풍선 글 시작에 맞추고, 얼굴은 그 왼쪽에서 아래로 첫 말풍선 옆까지 내려온다 */
.chat-msg-list{--chat-av-top:36px;}
.chat-who{position:relative;align-self:flex-start;margin:10px 0 3px calc(var(--chat-av-top) + 8px);font-size:var(--fs-sm);color:var(--text-mid);}
.chat-who-face{position:absolute;top:0;left:calc(-1 * var(--chat-av-top) - 8px);padding:0;border:none;background:none;cursor:pointer;}
.chat-msg-list .chat-who-face .avatar.sm{width:var(--chat-av-top);height:var(--chat-av-top);font-size:9px!important;}
.chat-head-cover{width:34px;height:34px;border-radius:var(--radius-xs);}
.party-input-bar{position:absolute;bottom:0;left:50%;transform:translateX(-50%);width:100%;max-width:480px;box-sizing:border-box;display:flex;flex-direction:column;z-index:25}
#partyInput{width:100%;height:44px;min-height:44px;max-height:120px;box-sizing:border-box;padding:11px 72px 11px 14px;border-radius:var(--radius-sm);corner-shape:squircle;border:1.5px solid var(--border);outline:none;resize:none;overflow-y:auto;line-height:20px;font:inherit;font-size:var(--fs-base)}
/* 단체 @멘션(§screens/party.js, 운영자 선택 시안 C). 입력칸 안쪽 오른쪽, 글자 꾸미기 Aa 왼쪽의 @ 버튼(textarea가 두 버튼 자리만큼 오른쪽을 비워 둔다) */
.chat-input-at{position:absolute;right:34px;top:0;bottom:0;width:30px;display:flex;align-items:center;justify-content:center;border:0;background:none;color:var(--gray-500);cursor:pointer}
.chat-input-at:active{opacity:.7}
/* 말풍선 안 @이름: 다른 사람을 부른 것은 굵게, 나를 부른 것은 검은 알약(운영자 선택 다, design/party-mention-mock.html 다-2) */
.chat-markdown .chat-mention{font-weight:var(--fw-bold)}
.chat-markdown .chat-mention.is-me{padding:1px 7px;margin:0 1px;border-radius:var(--radius-full);background:var(--gray-900);color:var(--gray-0);-webkit-box-decoration-break:clone;box-decoration-break:clone}
/* 떠 있는 시트(부를 사람, 단체 알림): 화면 가장자리에서 8 띄우고 바깥 38, 안쪽 묶음 22(38 - 16), 버튼은 알약으로 모서리를 평행하게 맞춘다
   (디자인 노트 9항, 운영자 "라운딩 개선"). 인스타그램 공유 시트처럼 찾기 알약, 둥근 얼굴, 동그라미 체크 */
.sheet-overlay.sheet-float .sheet{width:calc(100% - 16px);max-width:464px;margin:0 8px calc(8px + env(safe-area-inset-bottom));border-radius:38px;corner-shape:squircle;background:var(--bg2);padding:8px 16px 16px;box-shadow:var(--shadow-pop)}
.sheet-float .sheet-handle{margin:0 auto 4px}
.sheet-float-title{margin:6px 0 14px;text-align:center;font-size:var(--fs-xl);font-weight:var(--fw-bold);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.sheet-float-group{margin-bottom:12px;border-radius:22px;corner-shape:squircle;background:var(--bg1);overflow:hidden}
.sheet-float-btn{width:100%;border-radius:var(--radius-full)}
.mention-search{display:flex;align-items:center;gap:8px;height:44px;margin-bottom:12px;padding:0 16px;border-radius:var(--radius-full);background:var(--bg1);color:var(--text-light)}
.mention-search input{flex:1;min-width:0;border:0;outline:none;background:none;font:inherit;font-size:16px;color:var(--text)}
.mention-list{max-height:min(300px,40dvh);overflow-y:auto}
.mention-row,.notify-row{position:relative;display:flex;align-items:center;gap:12px;width:100%;min-height:60px;padding:0 16px;border:0;background:none;font:inherit;color:var(--text);text-align:left;cursor:pointer}
.mention-row[hidden]{display:none}
.mention-row+.mention-row::before,.notify-row+.notify-row::before{content:"";position:absolute;top:0;left:68px;right:0;border-top:.5px solid var(--border)}
.mention-row:active,.notify-row:active{background:var(--gray-100)}
.mention-row-text{flex:1;min-width:0;display:flex;flex-direction:column}
.mention-row-text b{font-size:var(--fs-lg);font-weight:var(--fw-bold);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.mention-row-text small{font-size:var(--fs-sm);color:var(--text-light)}
.mention-all-face{flex:none;width:40px;height:40px;border-radius:50%;background:var(--gray-900);color:var(--gray-0);display:flex;align-items:center;justify-content:center}
.mention-check{flex:none;width:24px;height:24px;border-radius:50%;box-shadow:inset 0 0 0 1.5px var(--gray-300);color:transparent;display:flex;align-items:center;justify-content:center;transition:background-color 100ms ease-out,box-shadow 100ms ease-out}
.mention-row[aria-pressed="true"] .mention-check{background:var(--gray-900);box-shadow:none;color:var(--gray-0)}
.mention-empty{margin:4px 0 14px;text-align:center;font-size:var(--fs-sm);color:var(--text-light)}
.notify-row{min-height:56px}
.notify-row+.notify-row::before{left:52px}
.notify-row-ic{flex:none;width:24px;display:flex;justify-content:center;color:var(--gray-700)}
.notify-row-label{flex:1;font-size:var(--fs-lg)}
.notify-row-check{display:flex;color:var(--gray-900)}
.party-input-closed{padding:16px 18px calc(16px + env(safe-area-inset-bottom));background:var(--bg1);text-align:center;color:var(--text-light);font-size:var(--fs-md);font-weight:var(--fw-bold);line-height:1.6}
/* 메시지 정보 시트(§screens/party.js partyMessageInfoHtml, X 채팅 메시지 정보 참고) */
.msg-info-title{text-align:center;}
.msg-info-quote{display:flex;flex-direction:column;gap:4px;margin:4px 0 6px;padding:12px 14px;border-radius:var(--radius);corner-shape:squircle;background:var(--bg2);font-size:var(--fs-md);line-height:1.45;}
.msg-info-quote span{display:-webkit-box;-webkit-line-clamp:3;-webkit-box-orient:vertical;overflow:hidden;word-break:break-word;}
.msg-info-quote small{font-size:var(--fs-xs);color:var(--text-light);}
.msg-info-label{margin:14px 0 4px;font-size:var(--fs-sm);font-weight:var(--fw-bold);color:var(--text-light);}
.msg-info-person{display:flex;align-items:center;gap:12px;padding:7px 0;font-size:var(--fs-lg);text-align:left;}
.msg-info-person span{flex:1;min-width:0;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;}
.msg-info-person time{font-size:var(--fs-sm);color:var(--text-light);}
.msg-info-unread .msg-info-person{color:var(--text-light);}
.party-card-preview{margin-top:5px;font-size:var(--fs-sm);line-height:1.5;color:var(--text-mid);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.party-card-preview b{color:var(--text);font-weight:var(--fw-bold)}
.party-card-unread{box-shadow:0 2px 8px rgba(30,30,36,.06),0 0 0 1.5px var(--gray-800)}
.party-unread-dot{display:inline-block;width:7px;height:7px;border-radius:50%;background:var(--danger);flex:0 0 auto;vertical-align:middle}

/* ---------- 파티 기간 연장 ---------- */
.party-list-head{display:flex;align-items:center;justify-content:space-between;gap:10px;margin:0 2px 10px}
.party-expired-note{margin:14px 0;padding:16px;border-radius:var(--radius-lg);corner-shape:squircle;background:var(--primary-soft);display:flex;flex-direction:column;gap:4px}
.party-expired-note b{font-size:var(--fs-md)}
.party-expired-note span{font-size:var(--fs-sm);color:var(--text-mid);line-height:1.5}
.party-expired-note .btn{margin-top:4px}

/* ---------- 파티 모금 ---------- */
.party-funding-card{padding:18px}
.party-funding-empty{padding:16px;display:flex;flex-direction:column;gap:4px;text-align:left}
.party-funding-empty b{font-size:var(--fs-base)}
.party-funding-empty span{font-size:var(--fs-sm);color:var(--text-mid);line-height:1.5}
.party-funding-head{display:flex;align-items:baseline;justify-content:space-between;gap:10px;margin-bottom:12px}
.party-funding-head b{font-size:var(--fs-base)}
.party-funding-head span{font-size:var(--fs-sm);font-weight:var(--fw-bold);color:var(--text-mid);white-space:nowrap}
.party-funding-card .party-gauge-lg{margin-top:0}
.party-funding-foot{display:flex;align-items:center;justify-content:space-between;gap:10px;margin-top:10px;font-size:var(--fs-xs);font-weight:var(--fw-bold);color:var(--text-light)}
.party-funding-done{display:inline-flex;align-items:center;gap:4px;color:var(--text)}
.party-funding-list{margin-top:14px;display:flex;flex-direction:column;gap:7px}
.party-funding-row{display:flex;align-items:center;justify-content:space-between;gap:10px;font-size:var(--fs-sm)}
.party-funding-row span{color:var(--text-mid);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.party-funding-row b{white-space:nowrap}
.party-funding-card .btn{margin-top:14px}

/* ---------- 미팅 개설(파티 폼과 같은 타이포로) ---------- */
.meeting-condition-list{display:flex;flex-direction:column;margin-top:8px;border:1.5px solid var(--border);border-radius:var(--radius-sm);corner-shape:squircle;background:var(--gray-0);overflow:hidden}
.meeting-condition-row{padding:12px 14px}
.meeting-condition-row+.meeting-condition-row{border-top:1px solid var(--border)}

.meeting-condition-toggle{display:flex;align-items:center;justify-content:space-between;gap:10px;margin:0;font-size:var(--fs-base);font-weight:var(--fw-bold);color:var(--text);cursor:pointer}
/* .party-form input의 width:100%·padding:14px이 체크박스까지 늘려서 이름을 오른쪽 끝으로
   밀어냈다 — 조건 줄 안의 입력은 여기서 따로 잡는다(위 입력칸들과 같은 톤 유지). */
.party-form .toggle-switch input{width:100%;height:100%;padding:0;border:0}
.meeting-condition-body{display:flex;align-items:center;gap:8px;margin-top:12px;padding-top:12px;border-top:1px solid var(--border)}
.party-form .meeting-condition-num{width:72px;margin:0;padding:10px 12px;border-radius:var(--radius-xs);corner-shape:squircle;font-size:var(--fs-base);text-align:center}
.meeting-condition-unit{font-size:var(--fs-md);font-weight:var(--fw-bold);color:var(--text-mid)}

/* 새 미팅 나이 두 바퀴(결정 81-가, §ui/year-wheel.js). 다섯 줄이 보이고 가운데 줄에 회색 띠, 위아래는 흐려진다. 줄 높이 34는 YEAR_ROW와 같다 */
.meeting-condition-note{margin-left:auto;font-size:var(--fs-md);font-weight:var(--fw-regular);color:var(--text-mid)}
.meeting-year-wheels{justify-content:center;gap:6px}
.meeting-year-col{flex:1;max-width:140px;display:flex;flex-direction:column;align-items:center;gap:6px}
.meeting-year-col small{font-size:var(--fs-xs);color:var(--text-mid)}
.meeting-year-tilde{align-self:flex-end;margin-bottom:76px;color:var(--text-mid)}
.year-wheel{position:relative;width:100%;height:170px;overflow-y:auto;scroll-snap-type:y mandatory;scrollbar-width:none;overscroll-behavior:contain;padding:68px 0;box-sizing:border-box;-webkit-mask-image:linear-gradient(transparent,#000 35%,#000 65%,transparent);mask-image:linear-gradient(transparent,#000 35%,#000 65%,transparent);background:linear-gradient(transparent 68px,var(--gray-100) 68px,var(--gray-100) 102px,transparent 102px);border-radius:var(--radius-xs)}
.year-wheel::-webkit-scrollbar{display:none}
.year-wheel button{display:block;width:100%;height:34px;padding:0;border:0;background:none;font:inherit;font-size:var(--fs-lg);color:var(--text-light);scroll-snap-align:center;cursor:pointer}
.year-wheel button.is-on{font-size:20px;font-weight:var(--fw-bold);color:var(--text)}
/* 참여 조건 나이 슬라이더(§user-controls.css .dual-range)는 글 입력칸이 아니다. 위의 .party-form input(안쪽 여백 14px, 테두리, 꽉 찬 폭)을 풀어야
   손잡이 중심이 레일 위 채움 선 끝과 맞는다 */
.party-form .dual-range-input{width:calc(100% - 6px);margin:-22px 0 0;padding:0;border:0;border-radius:0;corner-shape:round;background:none;}
/* 당겨서 새로고침(§ui/pull-to-refresh.js, 단체 탭) */
.ptr{position:fixed;left:50%;top:calc(env(safe-area-inset-top) - 30px);z-index:60;width:36px;height:36px;display:flex;align-items:center;justify-content:center;border-radius:50%;background:var(--gray-0);color:var(--text-light);box-shadow:var(--shadow);opacity:0;transform:translate(-50%,0);pointer-events:none;}
.ptr.is-ready{color:var(--text);}
.ptr.is-settling{transition:transform var(--duration-fast) var(--ease-smooth-out),opacity var(--duration-quick) var(--ease-smooth-out);}
.ptr.is-spinning{color:var(--text);transition:transform var(--duration-quick) var(--ease-smooth-out);}
.ptr .ptr-ring{transform:rotate(-90deg);}
.ptr.is-spinning .ptr-ring{animation:ptrSpin .8s linear infinite;}
.ptr.is-spinning circle{stroke-dasharray:60 100;}
@keyframes ptrSpin{to{transform:rotate(270deg);}}
@media(prefers-reduced-motion:reduce){.ptr.is-spinning .ptr-ring{animation:none;}.ptr.is-settling,.ptr.is-spinning{transition:opacity var(--duration-quick) linear;}}
/* ---------- 홈 화면(§screens/home.js, §ui/home-parts.js) ----------
   회색 바탕 위에 출석 체크(밝은 카드), 오늘의 질문(검정 카드)이 서로 떨어진 독립 조각으로 놓이고, 그 아래로 접속 중, 오늘의 추천, 글 피드(모놀로그), 보조 카드 2열이 이어진다.
   서비스 인사이트는 카드가 아니라 로고 아래 한 줄이고, CSS 애니메이션으로 한 줄씩 위로 바뀐다(글 줄이 3개라 한 바퀴 10.8초). 모션 줄이기를 켜면 첫 줄에서 멈춘다.
   헤더(로고)와 내비는 다른 탭과 같은 것을 그대로 쓴다. 헤더 바탕만 이 화면의 회색에 맞춘다. */
.main.home-main{word-break:keep-all;}
/* 홈 버튼 초기화는 :where()로 우선순위를 0으로 낮춰, 아래 클래스 규칙이 !important 없이 이기게 한다. */
:where(.home-main,.home-q-pop) button{font-family:inherit;line-height:inherit;color:inherit;background:none;border:0;padding:0;cursor:pointer;-webkit-tap-highlight-color:transparent;}
.home-main h2{font-size:var(--fs-2xl);font-weight:var(--fw-bold);letter-spacing:var(--ls-base);color:var(--gray-800);}
.home-page{display:flex;flex-direction:column;gap:12px;padding-top:0;}
.home-page > section{margin:0;}

.home-insight{display:flex;align-items:center;height:18px;margin-top:-6px;font-size:var(--fs-sm);color:var(--gray-600);text-align:center;}
.home-ticker{flex:1;min-width:0;height:18px;overflow:hidden;}
.home-ticker ul{list-style:none;margin:0;padding:0;animation:homeTick 10.8s infinite var(--ease-drawer);}
.home-ticker li{height:18px;line-height:18px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;}
@keyframes homeTick{0%,30%{transform:translateY(0);}33.333%,63.333%{transform:translateY(-18px);}66.667%,96.667%{transform:translateY(-36px);}100%{transform:translateY(-54px);}}

.home-attend{background:var(--card);border-radius:var(--radius-xl);corner-shape:squircle;padding:16px;box-shadow:var(--shadow-sm);}
.home-attend-top{display:flex;align-items:center;justify-content:space-between;gap:12px;}
.home-attend-top h2{font-size:var(--fs-lg);}
.home-streak{margin:2px 0 0;font-size:var(--fs-sm);color:var(--gray-600);}
.home-streak b{color:var(--gray-800);font-weight:var(--fw-bold);}
.home-attend-btn{flex:none;height:32px;padding:0 12px;border-radius:var(--radius-full);background:var(--gray-800);color:var(--gray-0);font-size:var(--fs-sm);font-weight:var(--fw-bold);transition:background .25s,color .25s,transform .12s;}
.home-attend-btn:active{transform:scale(.97);}
.home-attend-btn[disabled]{background:var(--gray-200);color:var(--gray-600);cursor:default;transform:none;}
.home-days{list-style:none;display:grid;grid-template-columns:repeat(7,1fr);gap:4px;margin:12px 0 0;padding:0;}
.home-days li{display:flex;flex-direction:column;align-items:center;gap:4px;font-size:var(--fs-xs);color:var(--gray-500);}
.home-days .c{width:26px;height:26px;border-radius:50%;display:grid;place-items:center;border:1.5px solid var(--gray-200);transition:background .3s,border-color .3s,color .3s;}
.home-days .c svg{width:12px;height:12px;opacity:0;transition:opacity .25s;}
.home-days .c i{font-style:normal;grid-area:1/1;display:none;font-size:var(--fs-3xs);font-weight:var(--fw-bold);}
.home-days .c svg{grid-area:1/1;}
.home-days .done .c{background:var(--gray-800);border-color:var(--gray-800);color:var(--gray-0);}
.home-days .done .c svg{opacity:1;}
.home-days .today{color:var(--gray-800);font-weight:var(--fw-bold);}
.home-days .today .c{border-color:var(--gray-800);color:var(--gray-800);}
.home-days .today .c i{display:block;}
.home-days li:not(.done):not(.today) .c{border-color:transparent;background:var(--gray-100);}

/* 오늘의 질문 팝업 카드(위젯에서 열림). 흰 바탕, 명도로만 강조, 굵기 400/600 두 단계.
   질문은 크게, 답은 세로로 넓게 쌓은 두 줄. 고르면 내 답은 검정으로 뒤집히고 모든 줄에 비율 막대가 차오른다. */
.home-qp{position:relative;background:var(--gray-0);color:var(--text);border-radius:var(--radius-xl);corner-shape:squircle;padding:24px 22px 20px;box-shadow:var(--shadow);word-break:keep-all;}
.home-qp-eyebrow{display:flex;align-items:baseline;gap:8px;margin:0;padding-right:36px;font-size:var(--fs-sm);font-weight:var(--fw-bold);color:var(--text);}
.home-qp-eyebrow span{font-weight:var(--fw-regular);color:var(--text-light);}
.home-qp-tabs{display:flex;gap:6px;margin-top:16px;}
.home-qp-tab{min-height:30px;padding:0 13px;border-radius:var(--radius-full);background:var(--bg2);color:var(--text-mid);font-size:var(--fs-sm);font-weight:var(--fw-bold);transition:background-color 200ms var(--ease-smooth-out),color 200ms var(--ease-smooth-out),opacity 200ms var(--ease-smooth-out);}
.home-qp-tab[aria-selected="true"]{background:var(--primary-dark);color:var(--gray-0);}
.home-qp-tab:disabled{opacity:.4;cursor:default;}
/* 두 쪽을 같은 칸에 겹쳐 두어 높이가 흔들리지 않게 한다(transitions-dev page side-by-side의 absolute 대신 grid). */
/* transitions-dev 08 Page side-by-side (원본 그대로). 오늘의 질문 팝업의 "나는" 쪽과 "상대는" 쪽을 오간다. */
:root{--page-slide-dur:250ms;--page-fade-dur:250ms;--page-slide-distance:8px;--page-blur:3px;--page-stagger:0ms;--page-exit-enabled:1;--page-slide-ease:var(--ease-smooth-out);--page-fade-ease:var(--ease-smooth-out);}
.t-page-slide{position:relative;}
.t-page-slide .t-page[data-page-id="1"]{--t-page-from-x:calc(var(--page-slide-distance) * -1);}
.t-page-slide .t-page[data-page-id="2"]{--t-page-from-x:var(--page-slide-distance);}
.t-page-slide .t-page{position:absolute;inset:0;opacity:0;pointer-events:none;transform:translateX(calc(var(--t-page-from-x, 0px) * var(--page-exit-enabled)));filter:blur(calc(var(--page-blur) * var(--page-exit-enabled)));transition:opacity var(--page-fade-dur) var(--page-fade-ease),transform var(--page-slide-dur) var(--page-slide-ease),filter var(--page-slide-dur) var(--page-slide-ease);will-change:opacity, transform, filter;}
.t-page-slide[data-page="1"] .t-page[data-page-id="1"],.t-page-slide[data-page="2"] .t-page[data-page-id="2"]{opacity:1;pointer-events:auto;transform:translateX(0);filter:blur(0);transition-delay:var(--page-stagger);}
@media (prefers-reduced-motion:reduce){.t-page-slide .t-page{transition:none !important;}}
.home-qp-steps.t-page-slide{display:grid;}
.home-qp-steps .t-page{position:relative;inset:auto;grid-area:1 / 1;}
.home-qp-text{margin:14px 0 0;font-size:var(--fs-5xl);font-weight:var(--fw-bold);line-height:1.34;letter-spacing:-.035em;color:var(--primary-dark);}
.home-qp-answers{display:flex;flex-direction:column;gap:8px;margin-top:26px;}
.home-qp .home-ans{position:relative;overflow:hidden;display:flex;align-items:center;justify-content:space-between;gap:12px;min-height:56px;padding:0 18px;border-radius:var(--radius-lg);corner-shape:squircle;background:var(--bg2);color:var(--text);font-size:var(--fs-lg);font-weight:var(--fw-regular);letter-spacing:-.02em;text-align:left;transition:background-color 200ms var(--ease-smooth-out),color 200ms var(--ease-smooth-out),transform 120ms var(--ease-smooth-out);}
.home-qp .home-ans:active{transform:scale(.98);}
.home-qp .home-ans .fill{position:absolute;inset:0;background:var(--gray-100);transform:scaleX(0);transform-origin:left;transition:transform 600ms var(--ease-smooth-out);}
.home-qp .home-ans + .home-ans .fill{transition-delay:40ms;}
.home-qp .home-ans .t,.home-qp .home-ans .p{position:relative;}
.home-qp .home-ans .p{font-size:var(--fs-md);font-weight:var(--fw-bold);font-variant-numeric:tabular-nums;opacity:0;transition:opacity 200ms var(--ease-smooth-out) 120ms;}
.home-qp-part.answered .home-ans .p{opacity:1;}
.home-qp-part.answered .home-ans{color:var(--text-mid);}
.home-qp .home-ans.mine{background:var(--primary-dark);color:var(--gray-0);}
.home-qp .home-ans.mine .fill{background:#ffffff24;}
.home-q-foot{margin:14px 0 0;text-align:center;font-size:var(--fs-xs);color:var(--text-light);}
/* 오늘의 질문 위젯: 내비 바로 위에 떠 있는 하트. 하트는 천천히 좌우로 조금 흔들리고, 뒤에 옅은 검은 halo가 있다.
   끌어서 옮기면 놓은 뒤 가까운 쪽 가장자리로 붙는다(.is-left). 누르면 오늘의 질문 팝업이 열린다. 아래 태그는 오늘 안 답했으면 "오늘의 질문", 답했으면 "답변 완료!"다. */
.home-page{padding-bottom:84px;}
.home-q-dock{position:sticky;z-index:25;bottom:-10px;height:0;pointer-events:none;}
.home-q-float{position:absolute;right:-12px;bottom:0;padding:0;border:none;background:none;pointer-events:auto;display:flex;flex-direction:column;align-items:center;width:76px;touch-action:none;transition:transform 380ms var(--ease-drawer);}
.home-q-float.is-left{right:auto;left:-12px;}
.home-q-float.is-dragging{transition:none;}
.home-q-float .heart{position:relative;display:block;width:76px;height:76px;opacity:0;transition:transform 120ms var(--ease-smooth-out),opacity 200ms var(--ease-smooth-out);}
.home-q-float .heart.is-ready{opacity:1;}
.home-q-float:active .heart{transform:scale(.95);}
.home-q-float .halo{position:absolute;inset:16px;border-radius:50%;background:#00000033;filter:blur(12px);}
.home-q-float model-viewer{position:relative;display:block;width:100%;height:100%;background:transparent;pointer-events:none;--poster-color:transparent;}
/* 태그는 하트 아래 작은 유리 이름표. 하단 탭(.bottom-nav)과 같은 유리: 흰 반투명, 흐림, 위쪽 흰 반사선, 옅은 테두리.
   상태는 글씨 명도로만 보인다: 답하기 전에는 진한 글씨, 답한 뒤에는 연한 글씨. */
.home-q-float .tag{flex:none;margin-top:-7px;padding:2px 7px;border-radius:var(--radius-full);background:linear-gradient(#ffffffb8,#fafafaa6);border:1px solid #ffffffd9;backdrop-filter:blur(7px) saturate(160%);-webkit-backdrop-filter:blur(7px) saturate(160%);box-shadow:inset 0 1px 0 #fffffff2,inset 0 -1px 0 #ffffffb3,0 0 0 .5px #0000001a,0 3px 6px #00000024;color:var(--gray-900);font-family:"Pretendard",var(--font-sys);font-size:var(--fs-2xs);font-weight:var(--fw-bold);line-height:1.3;letter-spacing:-.01em;white-space:nowrap;transition:color 200ms var(--ease-smooth-out);}
.home-q-float .tag.is-done{color:var(--gray-500);}
@media(prefers-reduced-transparency:reduce){.home-q-float .tag{background:var(--gray-0);backdrop-filter:none;-webkit-backdrop-filter:none;}}
/* 팝업은 하트 위젯 자리에서 커지며 가운데로 날아오고(transitions-dev plus→menu morph의 커짐, 조금 튕김),
   닫을 때는 같은 길로 하트 자리로 줄어든다. --fx, --fy는 열 때 JS가 넣는 "하트 중심까지의 거리"다.
   안의 글(라벨, 질문, 답)은 40ms씩 늦게 12px 아래에서 떠오른다. */
.home-q-pop{--morph-ease:cubic-bezier(.34,1.25,.64,1);position:relative;width:100%;max-width:340px;transition:transform var(--duration-medium) var(--morph-ease),opacity var(--duration-quick) var(--ease-smooth-out),filter var(--duration-quick) var(--ease-smooth-out);}
.home-q-pop.is-from,.center-modal-overlay.closing .home-q-pop{transform:translate(var(--fx,0px),var(--fy,0px)) scale(.16);opacity:0;filter:blur(2px);}
.home-q-pop.is-from{transition:none;}
.center-modal-overlay.closing .home-q-pop{transition:transform var(--duration-fast) var(--ease-smooth-out),opacity var(--duration-quick) var(--ease-smooth-out) 60ms,filter var(--duration-quick) var(--ease-smooth-out);}
.home-q-pop .home-qp-eyebrow,.home-q-pop .home-qp-tabs,.home-q-pop .home-qp-steps,.home-q-pop .home-q-foot{animation:homeQRise var(--duration-slow,400ms) var(--ease-smooth-out) both;}
.home-q-pop .home-qp-eyebrow{animation-delay:80ms;}.home-q-pop .home-qp-tabs{animation-delay:120ms;}.home-q-pop .home-qp-steps{animation-delay:160ms;}.home-q-pop .home-q-foot{animation-delay:200ms;}
@keyframes homeQRise{from{opacity:0;transform:translateY(12px);filter:blur(3px);}to{opacity:1;transform:none;filter:none;}}
.home-q-close{position:absolute;top:16px;right:14px;display:grid;place-items:center;width:32px;height:32px;border:0;border-radius:50%;background:none;color:var(--text-light);cursor:pointer;transition:transform 120ms var(--ease-smooth-out);}
.home-q-close svg{width:18px;height:18px;}
.home-q-close:active{transform:scale(.92);}
@media (prefers-reduced-motion:reduce){.home-q-pop.is-from,.center-modal-overlay.closing .home-q-pop{transform:none;filter:none;}.home-q-pop .home-qp-eyebrow,.home-q-pop .home-qp-tabs,.home-q-pop .home-qp-steps,.home-q-pop .home-q-foot{animation:none;}.home-qp .home-ans .fill,.home-qp .home-ans .p{transition:none;}}

.home-row{display:flex;align-items:baseline;justify-content:space-between;}
.home-row h2 small{margin-left:8px;font-size:var(--fs-lg);font-weight:var(--fw-regular);color:var(--gray-500);}
.home-more{padding:0 4px;border:0;background:none;font-size:var(--fs-sm);font-weight:var(--fw-bold);color:var(--gray-500);}

.home-rec-card{position:relative;margin-top:10px;border-radius:var(--radius-xl);corner-shape:squircle;overflow:hidden;background:radial-gradient(120% 90% at 85% 0%,var(--gray-700),var(--gray-800) 62%);color:var(--gray-0);box-shadow:var(--shadow-pop);transition:opacity .15s ease-out;}
.home-rec-card.is-swapping{opacity:0;}
.home-rec-card .rec-body{position:relative;padding:16px;}
.home-rec-card .rec-body.has-cover{padding-top:14px;}
.home-rec-card .rec-body.has-cover .rec-head{position:relative;display:block;}
.home-rec-card .rec-body.has-cover .rec-head>div:first-child{margin:40px 0 0 4px;padding-right:calc(var(--gw) + 12px);}
.home-rec-card .rec-body.has-cover .rec-name{display:flex;align-items:baseline;gap:6px;font-size:var(--fs-2xl);line-height:1.25;}
.home-rec-card .rec-body.has-cover .rec-name small{margin:0;font-size:var(--fs-md);font-weight:var(--fw-bold);color:var(--gray-400);}
.home-rec-card .rec-body.has-cover .rec-meta{margin:4px 0 0;font-size:var(--fs-md);line-height:1.4;}
/* 적합도 반원 게이지는 이름과 칩 두 줄의 가운데, 오른쪽 빈 곳. 상대 목록과 같은 모양을 어두운 카드에 맞춰 밝게 칠한다.
   칩은 한 줄 높이로 잘라서 게이지 앞에 다 못 들어가는 칩은 다음 줄로 넘어가 안 보인다 */
.home-rec-card{--gw:84px;}
.home-rec-card .rec-body.has-cover .rec-head{min-height:52px;}
.home-rec-card .rec-head .compat-gauge{position:absolute;right:2px;top:calc(50% - var(--gw) * 28 / 104);flex:none;}
.home-rec-card .compat-gauge .cg-track{stroke:#ffffff26;}
.home-rec-card .compat-gauge .cg-fill{stroke:var(--gray-200);}
.home-rec-card .compat-gauge .cg-value{color:var(--gray-0);}
.home-rec-card .compat-gauge .cg-pct{color:var(--gray-400);}
.home-rec-card .rec-body.has-cover .tags{max-height:calc(var(--fs-sm) * 1.4 + 10px);overflow:hidden;row-gap:8px;}
.home-rec-card .rec-body.has-cover .tags span{line-height:1.4;white-space:nowrap;}
/* 말풍선: 배너 색이 밝으면 유리 말풍선의 어두운 글자가 묻혀서, 이 카드에서만 유리 안쪽을 어둡게 깔고 글자를 흰색으로 */
/* 말풍선은 카드 오른쪽 끝 16px 앞까지 길게(사진 오른쪽 끝 92px + 말풍선 앞 여백 16px + 오른쪽 여백 16px) */
.home-rec-card{container-type:inline-size;}
.home-rec-card .profile-speech-bubble.card-overlay-bubble{max-width:calc(100cqw - 124px);color:var(--gray-0);background:#0000004d;border-radius:var(--radius-full);-webkit-backdrop-filter:blur(10px);backdrop-filter:blur(10px);}
.home-rec-card .rec-body.has-cover .tags{margin-top:8px;}
.home-rec-card .rec-body.has-cover .rec-name,.home-rec-card .rec-body.has-cover .rec-meta{white-space:nowrap;overflow:hidden;text-overflow:ellipsis;}
.home-rec-card .rec-head{display:flex;align-items:flex-end;justify-content:space-between;}
.home-rec-card .rec-name{font-size:var(--fs-3xl);font-weight:var(--fw-bold);letter-spacing:var(--ls-base);}
.home-rec-card .rec-name small{margin-left:5px;font-size:var(--fs-lg);color:var(--gray-400);font-weight:var(--fw-regular);}
.home-rec-card .rec-meta{margin:1px 0 0;font-size:var(--fs-sm);color:var(--gray-400);}
.home-rec-card .tags{display:flex;gap:6px;margin-top:10px;flex-wrap:wrap;}
.home-rec-card .tags span{padding:5px 11px;border-radius:var(--radius-full);background:#ffffff1f;font-size:var(--fs-sm);color:var(--gray-200);}
.home-rec-card .rec-act{display:flex;gap:8px;margin-top:16px;}
/* 지금 듣는 음악 한 줄(Airbuds처럼). 팝오버의 음악 카드와 같은 막대 움직임(.pp-eq)을 쓴다 */
.home-rec-card .rec-music{display:flex;align-items:center;gap:10px;margin-top:14px;padding:8px 12px 8px 8px;border-radius:var(--radius-sm);corner-shape:squircle;background:#ffffff14;color:var(--gray-300);}
.home-rec-card .rec-music-cover,.home-rec-card .rec-music-empty{width:32px;height:32px;flex:none;border-radius:var(--radius-2xs);object-fit:cover;display:grid;place-items:center;background:#ffffff1f;}
.home-rec-card .rec-music>div{flex:1;min-width:0;}
.home-rec-card .rec-music b,.home-rec-card .rec-music span:not(.pp-eq){display:block;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;}
.home-rec-card .rec-music b{font-size:var(--fs-md);font-weight:var(--fw-bold);color:var(--gray-0);}
.home-rec-card .rec-music div span{font-size:var(--fs-sm);color:var(--gray-400);}
.home-rec-card .why{flex:1;height:42px;border-radius:var(--radius-full);background:var(--gray-100);color:var(--gray-800);font-size:var(--fs-base);font-weight:var(--fw-bold);}
.home-rec-card .heart{width:42px;height:42px;border-radius:50%;box-shadow:inset 0 0 0 1.5px #ffffff59;display:grid;place-items:center;color:var(--gray-0);}
.home-rec-card .heart svg{width:19px;height:19px;}

/* ===== 모놀로그 (§screens/monologue.js, design/monologue-mock8-L1.png, L2.png) =====
   Queue(팟캐스트) 목록과 글 화면의 짜임새: 큰 제목, 선 없이 여백으로 나눈 줄, 남은 시간 알약, 글 화면의 큰 제목과 남은 시간 막대.
   바닥에 떠 있는 버튼 둘은 일기 앱 Kin. 색은 토큰만 써서 다크 모드를 만들면 그대로 바뀐다 */
.ml-page,.ml-layer,.ml-menu-overlay,.ml-entry{--ml-ink:var(--gray-800);--ml-body:var(--gray-700);--ml-mute:var(--text-light);--ml-faint:var(--gray-400);--ml-fill:var(--gray-100);--ml-fill2:var(--gray-200);--ml-line:var(--gray-100);--ml-me:var(--gray-800);--ml-me-ink:var(--gray-0);}
.ml-page{padding-bottom:120px;color:var(--ml-ink);}
.ml-page .subhead{margin-bottom:4px;}
.ml-h1{margin:6px 0 0;font-size:32px;font-weight:var(--fw-bold);line-height:1.18;letter-spacing:-.02em;color:var(--gray-900);word-break:keep-all;text-wrap:balance;}
.ml-h1.is-read{font-size:28px;line-height:1.28;}
.ml-h1.is-small{font-size:26px;}
.ml-sub{margin:6px 0 0;font-size:16px;color:var(--gray-600);}
.ml-list{display:flex;flex-direction:column;gap:30px;margin-top:34px;}
.ml-list .empty-state{margin-top:24px;}
.ml-item{display:flex;flex-direction:column;align-items:flex-start;gap:6px;width:100%;padding:0;border:0;background:none;font:inherit;text-align:left;color:var(--ml-ink);cursor:pointer;-webkit-tap-highlight-color:transparent;}
.ml-item:active{opacity:.6;}
.ml-meta{display:flex;align-items:center;gap:8px;margin:0;font-size:13px;font-weight:var(--fw-bold);color:var(--gray-500);white-space:pre;}
.ml-meta span{color:var(--ml-faint);}
.ml-title{font-size:var(--fs-2xl);font-weight:var(--fw-bold);line-height:1.35;letter-spacing:-.02em;word-break:keep-all;text-wrap:balance;display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden;}
.ml-pills{display:flex;flex-wrap:wrap;gap:6px;margin-top:4px;}
.ml-pill{display:inline-flex;align-items:center;gap:5px;height:28px;padding:0 11px 0 9px;border-radius:var(--radius-full);background:var(--ml-fill);font-size:var(--fs-sm);color:var(--ml-mute);white-space:nowrap;}
.ml-pill svg{color:var(--ml-ink);}
.ml-pill b{font-weight:var(--fw-bold);color:var(--ml-ink);}
.ml-pill.is-soon{background:none;box-shadow:inset 0 0 0 1.5px var(--ml-ink);}
.ml-pill.is-on{background:var(--ml-me);color:var(--gray-400);}
.ml-pill.is-on svg,.ml-pill.is-on b{color:var(--ml-me-ink);}
.ml-skeleton{pointer-events:none;gap:9px;}
.ml-skeleton i{display:block;height:12px;border-radius:var(--radius-2xs);background:var(--ml-fill);}
.ml-skeleton i:nth-child(1){width:60px;}.ml-skeleton i:nth-child(2){width:72%;height:18px;}.ml-skeleton i:nth-child(3){width:96px;height:28px;border-radius:var(--radius-full);}
/* 바닥에 떠 있는 버튼 둘(쓰기, 내 글) */
.ml-dock{position:fixed;left:50%;bottom:calc(30px + env(safe-area-inset-bottom));z-index:40;display:flex;gap:10px;padding:8px;border-radius:var(--radius-full);background:rgba(244,244,246,.78);-webkit-backdrop-filter:blur(22px) saturate(160%);backdrop-filter:blur(22px) saturate(160%);box-shadow:inset 0 1px 0 rgba(255,255,255,.35),var(--shadow-pop);transform:translateX(-50%);}
.ml-dock button{position:relative;display:grid;place-items:center;width:58px;height:58px;padding:0;border:0;border-radius:50%;background:var(--bg1);color:var(--ml-ink);box-shadow:var(--shadow-sm);cursor:pointer;}
.ml-dock button:active{transform:scale(.95);}
.ml-dock i{position:absolute;top:6px;right:6px;min-width:18px;height:18px;padding:0 5px;box-sizing:border-box;border-radius:9px;background:var(--ml-me);color:var(--ml-me-ink);font-style:normal;font-size:var(--fs-xs);font-weight:var(--fw-bold);line-height:18px;text-align:center;}
.ml-layer .ml-dock{position:absolute;}
/* 글, 내 글, 문답, 쓰기 층: 화면 전체를 덮는다(.fb-thread-layer와 같은 바탕) */
.ml-sheet{position:relative;display:flex;flex-direction:column;width:100%;max-width:480px;height:100%;margin:0 auto;padding-top:env(safe-area-inset-top);background:var(--bg1);box-sizing:border-box;color:var(--ml-ink);}
.ml-top{display:flex;align-items:center;justify-content:space-between;flex:none;height:48px;padding:0 8px;}
.ml-ic{display:grid;place-items:center;width:44px;height:44px;padding:0;border:0;background:none;color:var(--ml-ink);cursor:pointer;}
/* 남은 시간은 회색 꼬리표(머리글 공통 개선, 대표 확정 10/16, design/premium-312-mlhead.png) */
.ml-count{display:inline-flex;align-items:center;height:26px;margin-right:10px;padding:0 10px;border-radius:var(--radius-full);background:var(--gray-100);font-size:13px;font-weight:var(--fw-bold);color:var(--gray-700);}
.ml-scroll{flex:1;min-height:0;overflow-y:auto;-webkit-overflow-scrolling:touch;padding:0 20px 28px;}
.ml-body{margin:22px 0 0;font-size:var(--fs-xl);line-height:1.72;color:var(--ml-body);white-space:pre-wrap;word-break:keep-all;overflow-wrap:anywhere;-webkit-user-select:text;user-select:text;}
.ml-gone{margin:24px 0 0;font-size:var(--fs-sm);color:var(--ml-mute);}
.ml-bar{margin-top:30px;}
.ml-track{position:relative;height:4px;border-radius:2px;background:var(--ml-fill2);}
.ml-track i{position:absolute;left:0;top:0;bottom:0;border-radius:2px;background:var(--ml-ink);}
.ml-track i::after{content:"";position:absolute;right:-5px;top:50%;width:10px;height:10px;border-radius:50%;background:var(--ml-ink);transform:translateY(-50%);}
.ml-times{display:flex;justify-content:space-between;margin-top:8px;font-size:var(--fs-xs);font-weight:var(--fw-bold);color:var(--ml-mute);font-variant-numeric:tabular-nums;}
.ml-private{display:flex;align-items:center;justify-content:center;gap:5px;margin:30px 0 14px;font-size:var(--fs-xs);color:var(--ml-mute);text-align:center;}
.ml-chat{display:flex;flex-direction:column;gap:12px;}
.ml-msg{display:flex;flex-direction:column;align-items:flex-start;max-width:80%;}
.ml-msg.is-mine{align-self:flex-end;align-items:flex-end;}
.ml-msg p{margin:0;padding:9px 14px;border-radius:20px;background:var(--ml-fill);font-size:var(--fs-lg);line-height:1.5;color:var(--ml-ink);white-space:pre-wrap;word-break:keep-all;overflow-wrap:anywhere;-webkit-user-select:text;user-select:text;}
.ml-msg.is-mine p{background:var(--ml-me);color:var(--ml-me-ink);}
.ml-msg small{margin:4px 6px 0;font-size:var(--fs-2xs);color:var(--ml-faint);}
/* 문답 안 티켓: 앱 티켓(§actions/chat-ticket.js) 모양을 작게 */
.ml-ticket{--ticket-mono:"Courier Prime",ui-monospace,SFMono-Regular,Menlo,Consolas,monospace;width:236px;}
.ml-ticket .ticket{background:var(--ml-fill);-webkit-mask:radial-gradient(circle 10px at 0 calc(100% - 44px),#0000 96%,#000) left/51% 100% no-repeat,radial-gradient(circle 10px at 100% calc(100% - 44px),#0000 96%,#000) right/51% 100% no-repeat;mask:radial-gradient(circle 10px at 0 calc(100% - 44px),#0000 96%,#000) left/51% 100% no-repeat,radial-gradient(circle 10px at 100% calc(100% - 44px),#0000 96%,#000) right/51% 100% no-repeat;}
.ml-ticket .ticket-top{padding:16px 16px 18px;}
.ml-ticket .ticket-kind{margin:0;font-size:var(--fs-xs);color:var(--ml-mute);}
.ml-ticket .ticket-code{margin-top:8px;min-height:0;font-size:26px;line-height:32px;color:var(--ml-ink);}
.ml-ticket .ticket-stub{height:44px;font-size:var(--fs-xs);color:var(--ml-mute);}
.ml-ticket .ticket-tear{bottom:44px;border-color:var(--ml-fill2);}
.ml-start{width:100%;height:42px;margin-top:8px;border:0;border-radius:var(--radius-full);background:var(--ml-me);color:var(--ml-me-ink);font:inherit;font-size:var(--fs-md);font-weight:var(--fw-bold);cursor:pointer;}
.ml-start:active{transform:scale(.97);}
/* 바닥 질문 칸 */
.ml-foot{flex:none;padding:10px 16px calc(14px + env(safe-area-inset-bottom));background:var(--bg1);}
.ml-input{display:flex;align-items:flex-end;gap:8px;min-height:50px;padding:6px 6px 6px 16px;box-sizing:border-box;border-radius:var(--radius-sm);corner-shape:squircle;background:var(--bg2);box-shadow:inset 0 0 0 1px var(--border);}
.ml-input-lock{display:grid;place-items:center;height:38px;color:var(--ml-mute);}
.ml-input textarea{flex:1;min-width:0;max-height:120px;padding:9px 0;border:0;background:none;resize:none;font:inherit;font-size:16px;line-height:1.35;color:var(--ml-ink);}
.ml-input textarea:focus{outline:none;}
.ml-input textarea::placeholder{color:var(--ml-mute);}
.ml-send{display:grid;place-items:center;flex:none;width:38px;height:38px;padding:0;border:0;border-radius:50%;background:var(--ml-me);color:var(--ml-me-ink);cursor:pointer;}
.ml-send:active{transform:scale(.95);}
.ml-note{margin:7px 0 0;text-align:center;font-size:var(--fs-xs);color:var(--ml-mute);}
/* 내 글: 문답 상대 */
.ml-h2{display:flex;align-items:baseline;gap:8px;margin:34px 0 4px;font-size:var(--fs-3xl);font-weight:var(--fw-bold);letter-spacing:-.03em;}
.ml-h2 span{font-size:var(--fs-lg);font-weight:var(--fw-regular);color:var(--ml-mute);}
.ml-askers{display:flex;flex-direction:column;gap:22px;margin-top:16px;}
.ml-asker{position:relative;display:flex;flex-direction:column;align-items:flex-start;gap:4px;width:100%;padding:0 20px 0 0;border:0;background:none;font:inherit;text-align:left;color:var(--ml-ink);cursor:pointer;}
.ml-asker:active{opacity:.6;}
.ml-asker .ml-meta b{font-weight:var(--fw-bold);color:var(--ml-ink);}
.ml-asker-t{font-size:var(--fs-lg);line-height:1.45;color:var(--ml-body);word-break:keep-all;display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden;}
.ml-asker i{position:absolute;right:2px;top:6px;width:8px;height:8px;border-radius:50%;background:var(--ml-ink);}
.ml-none{margin:4px 0;font-size:var(--fs-md);color:var(--ml-mute);}
/* 쓰기 */
.ml-write{display:flex;flex-direction:column;}
.ml-title-in,.ml-text-in{display:block;width:100%;box-sizing:border-box;padding:0;border:0;background:none;resize:none;font:inherit;color:var(--ml-ink);}
.ml-title-in{margin-top:6px;font-size:30px;font-weight:var(--fw-bold);line-height:1.2;letter-spacing:-.045em;}
.ml-text-in{flex:1;margin-top:22px;font-size:var(--fs-xl);line-height:1.72;color:var(--ml-body);}
.ml-title-in:focus,.ml-text-in:focus{outline:none;}
.ml-title-in::placeholder,.ml-text-in::placeholder{color:var(--ml-faint);}
.ml-postbar{display:flex;align-items:center;justify-content:space-between;gap:10px;flex:none;padding:8px 12px calc(10px + env(safe-area-inset-bottom)) 18px;font-size:var(--fs-sm);color:var(--ml-mute);}
.ml-postbar>span{display:inline-flex;align-items:center;gap:5px;min-width:0;}
.ml-postbar button{flex:none;height:38px;padding:0 18px;border:0;border-radius:var(--radius-full);background:var(--ml-me);color:var(--ml-me-ink);font:inherit;font-size:var(--fs-md);font-weight:var(--fw-bold);cursor:pointer;}
.ml-postbar button:disabled{opacity:.5;}
/* 점 세 개 메뉴와 신고 사유: 층 위에 뜨는 바닥 시트 */
.ml-menu-overlay{position:fixed;inset:0;z-index:160;display:flex;align-items:flex-end;justify-content:center;background:rgba(0,0,0,.4);animation:fadeIn .2s ease;}
.ml-menu-overlay.closing{opacity:0;transition:opacity .2s ease;}
.ml-menu{width:100%;max-width:464px;margin:0 8px calc(10px + env(safe-area-inset-bottom));padding:8px 10px 14px;box-sizing:border-box;border-radius:var(--radius-xl);corner-shape:squircle;background:var(--bg2);animation:sheetUp .25s cubic-bezier(.25,.9,.35,1);}
.ml-grab{width:36px;height:5px;margin:0 auto 6px;border-radius:3px;background:var(--ml-faint);}
.ml-menu-t{margin:6px 8px 4px;font-size:var(--fs-xl);font-weight:var(--fw-bold);color:var(--ml-ink);}
.ml-menu-t small{display:block;margin-top:2px;font-size:var(--fs-xs);font-weight:var(--fw-regular);color:var(--ml-mute);}
.ml-group{margin-top:8px;border-radius:var(--radius-lg);corner-shape:squircle;background:var(--bg1);overflow:hidden;}
.ml-group button{display:flex;align-items:center;gap:14px;width:100%;min-height:52px;padding:12px 16px;border:0;background:none;font:inherit;text-align:left;color:var(--ml-ink);cursor:pointer;}
.ml-group button+button{border-top:1px solid var(--ml-line);}
.ml-group button:active{background:var(--ml-fill);}
.ml-group span{flex:1;display:flex;flex-direction:column;gap:2px;}
.ml-group b{font-size:var(--fs-lg);font-weight:var(--fw-regular);}
.ml-group small{font-size:var(--fs-xs);color:var(--ml-mute);}
.ml-group.is-list svg{color:var(--ml-faint);}
/* 홈 입구 카드(미니 게임 카드와 같은 모양). 글 내용 없이 떠 있는 글 수를 오른쪽에 크게, 새 질문은 검은 꼬리표 */
.ml-entry{width:100%;border:0;text-align:left;cursor:pointer;}
.ml-stat{position:absolute;right:20px;top:50%;transform:translateY(-50%);text-align:right;}
.ml-stat b{display:block;font-size:28px;line-height:1;font-weight:var(--fw-bold);font-variant-numeric:tabular-nums;color:var(--text);}
.ml-stat small{display:block;margin-top:4px;font-size:var(--fs-sm);color:var(--text-mid);}
.ml-new{align-self:flex-start;margin-top:6px;padding:3px 9px;border-radius:999px;background:var(--gray-900);color:var(--gray-0);font-size:var(--fs-xs);font-weight:var(--fw-bold);}
@media(prefers-reduced-motion:reduce){.ml-menu,.ml-menu-overlay{animation:none;}}

.home-duo{display:grid;grid-template-columns:1fr 1fr;gap:12px;}
/* 흰 카드에 옅은 그림자(운영자 2차 시안 2026-10-13). 작은 카드는 3D 그림 위, 이름과 설명 아래 가운데 */
.home-mini{position:relative;display:flex;flex-direction:column;justify-content:center;align-items:center;gap:2px;height:150px;padding:14px;border-radius:var(--radius-xl);corner-shape:squircle;background:var(--card);box-shadow:var(--shadow-sm);text-align:center;}
.home-mini .top{display:flex;align-items:center;font-size:var(--fs-lg);font-weight:var(--fw-bold);letter-spacing:var(--ls-base);color:var(--gray-800);}
.home-mini .top svg{width:13px;height:13px;color:var(--gray-400);flex:none;}
.home-mini .art{width:60px;height:60px;margin:0 0 8px;object-fit:contain;mix-blend-mode:multiply;pointer-events:none;}
.home-mini .art.hp{width:68px;height:68px;margin:-4px 0 4px;filter:brightness(1.08);-webkit-mask-image:radial-gradient(closest-side,var(--gray-900) 68%,transparent 100%);mask-image:radial-gradient(closest-side,var(--gray-900) 68%,transparent 100%);}
/* 미니게임 긴 카드: 글은 왼쪽, 컨트롤러는 오른쪽에 크게. 화살표는 제목 바로 옆(오른쪽 끝은 그림 자리). */
.home-game{height:100px;padding:16px;justify-content:flex-start;align-items:stretch;gap:4px;text-align:left;}
.home-game .top{gap:2px;}
.home-game .cap{max-width:52%;font-size:var(--fs-md);}
.home-mini .art.game{position:absolute;right:16px;top:50%;width:88px;height:88px;margin:-44px 0 0;}
.home-mini .cap{font-size:var(--fs-sm);line-height:1.4;color:var(--text-mid);}
.home-mini .cap .svc{display:flex;align-items:center;gap:6px;margin-top:2px;font-size:var(--fs-md);color:var(--text);}
@media (prefers-reduced-motion:reduce){.home-ticker ul{animation:none;}.home-q-float{transition:none;}.home-rec-card,.home-days .c,.home-attend-btn{transition:none;}}

/* 모션 줄이기(docs/animation.md 4절): 움직임은 빼고 opacity는 남긴다. 탭 전환, 바텀시트, 채팅방과 로그인 화면 들어오기는 제자리에서 흐려졌다 나타나게,
   끝없이 떠 있는 소개 말풍선은 멈춘다. 앞의 규칙들보다 우선하도록 파일 맨 끝에 둔다. */
@media (prefers-reduced-motion:reduce){
  .main.slide-right,.main.slide-left,.chatroom-transition,.auth-form-page,.sheet{animation-name:fadeIn;}
  .sheet-overlay.closing .sheet{animation-name:fadeOut;}
  .profile-speech-bubble,.profile-speech-bubble.card-overlay-bubble,.pp-av .pp-bubble{animation:none;}
}

/* ===== 알약 정리 (2026-09-28, design/mono-tone-clean.md 7항) =====
   알약(완전히 둥근 모양)은 "지금 누를 주요 동작"과 조작 부품(토글, 슬라이더, 게이지 막대)에만 쓴다.
   정보 태그는 배경 없이 글자로(굵기와 명도로 구분), 탭은 글자와 밑줄로, 안내 문구는 연한 글자로, 여러 개 고르는 칩과 보조 버튼은 각진 사각형으로 바꾼다.
   태그 도우미(§main.js ageTagHtml, orientationTagHtml)가 인라인 배경색을 넣으므로 여기서 !important로 덮는다. */

/* 정보 태그: 글자만 */
.age-tag,.match-tag,.party-chip,.party-badge{padding:0 !important;border-radius:0 !important;background:none !important;box-shadow:none !important;color:var(--text-mid) !important;}
.age-tag[data-ori="top_butch"],.age-tag[data-rel="연상"],.match-tag.exact{color:var(--text) !important;}
.age-tag[data-rel="연하"],.match-tag.low{color:var(--text-light) !important;}
.meta-row{column-gap:8px;}


/* 안내 문구: 배경 없이 연한 글자 */
.group-info-notice{padding:4px 0;border-radius:0;background:none;color:var(--text-light);}


/* ===== 미니게임 (§screens/games.js, §actions/games.js) =====
   같이 하기 큰 이미지 카드(가로로 밀기)가 맨 위, 혼자 하기 2×2 이미지 타일이 아래.
   이미지는 실제 게임 화면이라 색이 있어도 되고, 틀(글자, 버튼)만 모노 톤이다. */
.games-page{padding-bottom:24px;}
.games-rank-btn{background:none;box-shadow:none;color:var(--text);}
.games-section-head{display:flex;justify-content:space-between;align-items:baseline;margin:0 0 10px;font-size:var(--fs-lg);font-weight:var(--fw-bold);color:var(--text);}
.games-section-note{font-size:var(--fs-xs);font-weight:var(--fw-regular);color:var(--text-light);}
.games-rank-note{font-size:var(--fs-sm);color:var(--text-mid);margin:0 0 14px;}
.games-rank-row{display:flex;justify-content:space-between;align-items:center;padding:14px 0;border-bottom:1px solid var(--border);font-size:var(--fs-md);color:var(--text);}
.games-rank-row b{font-weight:var(--fw-bold);}

/* 게임 틀은 그 게임의 바탕색(--game-bg)과 글자색(--game-ink)을 따른다(§config/games.js tint, ink).
   흰 틀과 카드 모서리 없이 게임이 화면 끝까지 차고, 버튼은 게임 바탕 위에 뜨는 반투명 유리 동그라미다 */
.game-player{position:fixed;inset:0;z-index:900;background:var(--game-bg,var(--bg1));color:var(--game-ink,var(--text));display:flex;flex-direction:column;padding:calc(env(safe-area-inset-top) + 6px) 0 env(safe-area-inset-bottom);opacity:0;transform:scale(.98);transition:opacity .25s var(--ease-smooth-out),transform .25s var(--ease-smooth-out);}
.game-player.is-open{opacity:1;transform:none;}
.game-player-bar{display:grid;grid-template-columns:1fr auto 1fr;align-items:center;gap:8px;min-height:56px;padding:0 12px;}
.game-player-score{display:flex;flex-direction:column;align-items:center;gap:3px;line-height:1;}
.game-player-score b{font-size:30px;font-weight:var(--fw-bold);letter-spacing:-.02em;font-variant-numeric:tabular-nums;}
.game-player-score span{font-size:var(--fs-xs);font-weight:var(--fw-bold);opacity:.6;}
.game-player-score i{font-style:normal;font-variant-numeric:tabular-nums;}
.gp-tools{display:flex;gap:6px;justify-self:end;}
.gp-btn{width:38px;height:38px;flex:none;border:none;border-radius:50%;display:flex;align-items:center;justify-content:center;color:var(--game-ink,var(--text));background:#ffffff80;backdrop-filter:blur(8px) saturate(160%);-webkit-backdrop-filter:blur(8px) saturate(160%);box-shadow:inset 0 1px 0 #ffffffd9,0 0 0 .5px #00000014,0 2px 6px #00000014;transition:transform .15s var(--ease-smooth-out),opacity .15s;}
.gp-btn:active{transform:scale(.92);}
.gp-btn[aria-pressed="false"]{opacity:.5;}
.game-player-frame{flex:1;min-height:0;width:100%;border:0;background:transparent;}
.game-pause-layer{position:absolute;inset:0;z-index:2;background:color-mix(in srgb,var(--game-bg,#fff) 70%,transparent);backdrop-filter:blur(16px) saturate(120%);-webkit-backdrop-filter:blur(16px) saturate(120%);display:flex;flex-direction:column;align-items:center;justify-content:center;padding:0 32px;text-align:center;}
.game-pause-layer[hidden],.game-result[hidden],.game-result-art[hidden]{display:none;}
.game-pause-resume{position:absolute;inset:0;display:flex;align-items:center;justify-content:center;padding:0;border:0;background:transparent;cursor:pointer;-webkit-tap-highlight-color:transparent;}
.game-pause-play{display:grid;place-items:center;width:88px;height:88px;border-radius:50%;background:var(--game-ink,var(--gray-900));color:#fff;box-shadow:0 14px 30px -12px color-mix(in srgb,var(--game-ink,#000) 70%,transparent);transition:transform .15s var(--ease-out);}
.game-pause-play svg{margin-left:3px;}
.game-pause-resume:active .game-pause-play{transform:scale(.94);}
.game-pause-resume:focus-visible .game-pause-play{outline:3px solid var(--game-ink,var(--text));outline-offset:4px;}
/* 새 메시지처럼 멈춘 까닭이 있을 때만 재생 버튼 아래에 한 줄 */
.game-pause-note{position:relative;z-index:1;pointer-events:none;transform:translateY(80px);font-size:var(--fs-sm);font-weight:var(--fw-bold);color:var(--game-ink,var(--text-mid));opacity:.7;margin:0;}
.game-pause-layer .btn{max-width:260px;margin-top:10px;}
/* 첫 판 손가락 안내(2026-10-10 A, LEGO Builder, WishWish처럼): 판 가운데에서 손가락이 동작을 되풀이하고 아래에 한 줄.
   누르기는 판으로 그대로 통과하고, 판을 처음 만지면 앱이 걷는다. 손끝은 그림(64px)의 (25, 4) 자리라 그림을 14px 내려 손끝을 (25, 18)에 둔다.
   drag: 점선 상자가 손끝을 따라 늘어남(사과 게임), swipe: 손이 지나간 줄(2048), tap: 손끝에 퍼지는 동그라미(과일 합치기) */
.game-hint{position:absolute;inset:0;z-index:1;display:flex;flex-direction:column;align-items:center;justify-content:center;gap:22px;pointer-events:none;animation:gameHintIn .3s .4s var(--ease-out) both;}
.game-hint p{margin:0;padding:10px 16px;border-radius:var(--radius-full);background:var(--game-ink,var(--gray-900));color:#fff;font-size:var(--fs-lg);font-weight:var(--fw-bold);white-space:nowrap;box-shadow:var(--shadow-pop);}
.game-hint-hand{position:relative;width:150px;height:80px;}
.game-hint-hand img{position:absolute;left:0;top:14px;filter:drop-shadow(0 8px 10px rgba(0,0,0,.25));}
.game-hint-hand i{position:absolute;transform-origin:left center;}
.game-hint.is-drag i{left:8px;top:-1px;width:105px;height:38px;box-sizing:border-box;border:2.5px dashed var(--game-ink,var(--gray-900));border-radius:12px;background:rgba(255,255,255,.4);animation:gameHintBox 1.8s var(--ease-in-out) infinite;}
.game-hint.is-drag img,.game-hint.is-swipe img{animation:gameHintMove 1.8s var(--ease-in-out) infinite;}
.game-hint.is-swipe i{left:25px;top:16px;width:88px;height:4px;border-radius:2px;background:var(--game-ink,var(--gray-900));opacity:.35;animation:gameHintLine 1.8s var(--ease-in-out) infinite;}
.game-hint.is-tap .game-hint-hand{width:64px;}
.game-hint.is-tap img{animation:gameHintTap 1.4s var(--ease-out) infinite;}
.game-hint.is-tap i{left:3px;top:-4px;width:44px;height:44px;box-sizing:border-box;border:3px solid var(--game-ink,var(--gray-900));border-radius:50%;transform-origin:center;animation:gameHintRing 1.4s var(--ease-out) infinite;}
@keyframes gameHintIn{from{opacity:0;}}
@keyframes gameHintMove{0%{transform:none;opacity:0;}12%{transform:none;opacity:1;}60%,82%{transform:translateX(88px);opacity:1;}100%{transform:translateX(88px);opacity:0;}}
@keyframes gameHintBox{0%{transform:scaleX(.16);opacity:0;}12%{transform:scaleX(.16);opacity:1;}60%,82%{transform:none;opacity:1;}100%{transform:none;opacity:0;}}
@keyframes gameHintLine{0%,12%{transform:scaleX(0);}60%,82%{transform:none;opacity:.35;}100%{transform:none;opacity:0;}}
@keyframes gameHintTap{0%,60%,100%{transform:none;}30%{transform:translateY(4px) scale(.92);}}
@keyframes gameHintRing{0%,28%{transform:scale(.3);opacity:0;}38%{opacity:.7;}100%{transform:scale(1.4);opacity:0;}}
@media (prefers-reduced-motion:reduce){.game-hint *{animation:none !important;}}
/* 결과와 그만하기 카드도 게임 톤: 뒤는 검게 덮지 않고 게임 바탕색을 반투명하게 깔아 흐리게, 카드는 바탕색이 살짝 섞인
   밝은 면, 글자와 주 버튼은 게임 글자색(--game-ink) */
.game-result{position:absolute;inset:0;z-index:3;background:color-mix(in srgb,var(--game-bg,#fff) 55%,transparent);backdrop-filter:blur(10px) saturate(140%);-webkit-backdrop-filter:blur(10px) saturate(140%);display:flex;align-items:center;justify-content:center;padding:0 28px;opacity:0;transition:opacity .2s var(--ease-smooth-out);}
.game-result.is-open{opacity:1;}
.game-result-card{width:100%;max-width:320px;background:color-mix(in srgb,#fff 84%,var(--game-bg,#fff));border:1px solid #ffffffb3;border-radius:var(--radius-xl);corner-shape:squircle;box-shadow:inset 0 1px 0 #fff,0 24px 48px -22px color-mix(in srgb,var(--game-ink,#000) 55%,transparent);padding:24px 20px 12px;color:var(--game-ink,var(--text));text-align:center;transform:scale(.96);transition:transform .25s var(--ease-smooth-out);}
.game-result.is-open .game-result-card{transform:none;}
.game-result-title{font-size:var(--fs-md);font-weight:var(--fw-bold);opacity:.75;margin:0;}
.game-result-score{font-size:48px;font-weight:var(--fw-bold);margin:6px 0 4px;letter-spacing:-.02em;line-height:1;font-variant-numeric:tabular-nums;}
.game-result-sub{font-size:var(--fs-sm);opacity:.6;margin:0 0 18px;}
.game-result-score:empty,.game-result-sub:empty{display:none;}
.game-result-art{display:block;width:120px;height:120px;box-sizing:content-box;margin:14px auto 4px;padding:8px;border-radius:var(--radius-xs);corner-shape:squircle;background:var(--gray-0);image-rendering:pixelated;}
.game-player.is-local .game-player-score{visibility:hidden;}
/* 점수 없는 게임은 하는 법을 게임 안(연습)에서 알려 주니 위의 한 줄 설명을 숨긴다 */
.game-player.is-local .game-player-how{display:none;}
/* 게임 화면(z 900)이 떠 있는 동안에는 토스트가 그 위에 보이게 한다 */
body:has(.game-player) .toast-wrap{z-index:950;}
:is(.game-result-card,.game-pause-layer) .btn-primary{background:var(--game-ink,var(--gray-900));color:#fff;border:none;box-shadow:0 6px 14px -8px color-mix(in srgb,var(--game-ink,#000) 70%,transparent);}
:is(.game-result-card,.game-pause-layer) .btn-outline{background:transparent;color:var(--game-ink,var(--text));box-shadow:inset 0 0 0 1.5px color-mix(in srgb,var(--game-ink,#000) 30%,transparent);}
.game-result-card .btn{margin-top:8px;}
.game-result-duel{display:flex!important;align-items:center;justify-content:center;gap:6px;}
.game-result-close{margin-top:6px;background:none;border:none;color:var(--game-ink,var(--text-light));opacity:.55;font-size:var(--fs-md);font-weight:var(--fw-bold);padding:10px 20px;}
@media (prefers-reduced-motion: reduce){.game-player,.game-result,.game-result-card{transition:opacity .2s;transform:none!important;}}
.game-player-how{margin:2px 16px 6px;font-size:var(--fs-xs);font-weight:var(--fw-bold);color:var(--game-ink,var(--text-light));opacity:.55;text-align:center;}
@media(prefers-reduced-transparency:reduce){.gp-btn{background:#fff;backdrop-filter:none;-webkit-backdrop-filter:none;}}
.games-rank-tabs{display:flex;gap:18px;border-bottom:1px solid var(--border);margin:0 0 8px;overflow-x:auto;scrollbar-width:none;}
.games-rank-tab{background:none;border:none;padding:10px 0;font-size:var(--fs-md);color:var(--text-light);white-space:nowrap;box-shadow:inset 0 -2px 0 transparent;}
.games-rank-tab.is-on{color:var(--text);font-weight:var(--fw-bold);box-shadow:inset 0 -2px 0 var(--text);}
.games-rank-week{font-size:var(--fs-xs);color:var(--text-light);margin:0 0 6px;}
.games-rank-row{gap:12px;justify-content:flex-start!important;}
.games-rank-row.is-me{background:var(--bg2);margin:0 -16px;padding-left:16px;padding-right:16px;}
.games-rank-no{width:24px;text-align:center;color:var(--text-mid);font-variant-numeric:tabular-nums;}
.games-rank-face{width:32px;height:32px;border-radius:50%;overflow:hidden;background:var(--gray-200);display:flex;align-items:center;justify-content:center;font-size:var(--fs-sm);color:var(--text-mid);flex:none;}
.games-rank-face img{width:100%;height:100%;object-fit:cover;}
.games-rank-name{flex:1;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;}
.games-rank-score{font-variant-numeric:tabular-nums;}
.games-rank-mine{position:sticky;bottom:calc(env(safe-area-inset-bottom) + 84px);background:var(--bg1);border-top:1px solid var(--border);margin-top:8px;}
.games-rank-retry{background:none;border:none;padding:0;color:var(--text);text-decoration:underline;font-size:inherit;}
.game-result-actions .btn{margin-top:8px;}
.game-pick{position:absolute;inset:0;z-index:4;background:rgba(0,0,0,.4);display:flex;align-items:center;justify-content:center;padding:0 28px;opacity:0;transition:opacity .2s var(--ease-smooth-out);}
.game-pick.is-open{opacity:1;}
.game-pick[hidden]{display:none;}
.game-pick-card{width:100%;max-width:340px;max-height:80vh;display:flex;flex-direction:column;background:var(--bg1);border-radius:var(--radius-xl);corner-shape:squircle;box-shadow:var(--shadow-pop);padding:22px 18px 12px;}
.game-pick-title{font-size:var(--fs-xl);font-weight:var(--fw-bold);color:var(--text);margin:0;text-align:center;}
.game-pick-sub{font-size:var(--fs-sm);color:var(--text-mid);margin:4px 0 14px;text-align:center;}
.game-pick-list{overflow-y:auto;display:flex;flex-direction:column;}
.game-pick-row{display:flex;align-items:center;gap:12px;min-height:60px;padding:10px 4px;background:none;border:none;border-bottom:1px solid var(--border);text-align:left;font-size:var(--fs-md);color:var(--text);}
.game-pick-name{flex:1;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;}
/* 메신저 공유 목록처럼 줄마다 [보내기] */
.game-pick-send{flex:none;padding:7px 14px;border-radius:var(--radius-full);background:var(--gray-900);color:var(--gray-0);font-size:var(--fs-sm);font-weight:var(--fw-bold);}
.game-pick[aria-busy="true"] button{opacity:.5;}
.game-pick-row:active{background:var(--bg2);}
.game-pick-empty{text-align:center;color:var(--text-mid);font-size:var(--fs-sm);margin:10px 0;}
.game-pick-card .game-result-close{align-self:center;}
/* 게임 안에서 뜰 때는 결과 카드처럼 게임 톤 */
.game-player .game-pick{background:color-mix(in srgb,var(--game-bg) 55%,transparent);backdrop-filter:blur(10px) saturate(140%);-webkit-backdrop-filter:blur(10px) saturate(140%);}
.game-player .game-pick-card{background:color-mix(in srgb,#fff 84%,var(--game-bg));border:1px solid #ffffffb3;box-shadow:inset 0 1px 0 #fff,0 24px 48px -22px color-mix(in srgb,var(--game-ink) 55%,transparent);color:var(--game-ink);}
.game-player :is(.game-pick-title,.game-pick-row){color:var(--game-ink);}
.game-player :is(.game-pick-sub,.game-pick-empty){color:var(--game-ink);opacity:.6;}
.game-player .game-pick-row{border-bottom-color:color-mix(in srgb,var(--game-ink) 12%,transparent);}
/* 채팅 기록 대결 카드 */
/* 채팅 대결 카드(iOS Apple Games 도전 카드처럼). 채팅 목록(#msgList)은 세로 flex라, overflow:hidden인 카드는 flex:none이 없으면 납작해진다 */
.game-duel-card{position:relative;flex:none;width:min(262px,80%);border-radius:24px;corner-shape:squircle;overflow:hidden;isolation:isolate;color:#fff;margin:2px 0;background:linear-gradient(180deg,var(--deep),color-mix(in srgb,var(--deep) 88%,#000));box-shadow:0 10px 28px -16px rgba(0,0,0,.55);}
/* 채팅 말풍선과 같은 줄에 맞춘다: 프로필 칸(--chat-av)과 간격 6px만큼 들여 쓴다 */
.chat-msg-list .game-duel-card{margin-left:calc(var(--chat-av) + 6px);}
.game-duel-card.mine{align-self:flex-end;}
.chat-msg-list .game-duel-card.mine{margin-left:0;margin-right:calc(var(--chat-av) + 6px);}
.game-duel-card.is-over{filter:saturate(.15);}
/* 게임 그림이 카드 전체에 깔리고, 아래 띠 근처에서만 카드 색으로 옅게 이어진다 */
.gdc-art{position:absolute;inset:0;z-index:-1;background-size:cover;background-position:center top;-webkit-mask-image:linear-gradient(to bottom,#000 72%,transparent);mask-image:linear-gradient(to bottom,#000 72%,transparent);}
.gdc-tag{position:absolute;left:12px;top:12px;display:flex;align-items:center;gap:4px;max-width:calc(100% - 24px);padding:4px 10px 4px 8px;border-radius:999px;background:rgba(0,0,0,.28);backdrop-filter:blur(12px);-webkit-backdrop-filter:blur(12px);box-shadow:inset 0 0 0 1px rgba(255,255,255,.16);font-size:var(--fs-xs);font-weight:var(--fw-bold);color:#fff;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;}
/* 가운데: 나와 상대 얼굴, 아래 점수(안 했으면 –). 이긴 쪽은 노란 테두리와 왕관, 진 쪽 점수는 흐리게 */
.gdc-faces{display:flex;justify-content:center;gap:22px;padding:78px 0 16px;}
.gdc-p{display:flex;flex-direction:column;align-items:center;gap:5px;}
.gdc-face{position:relative;border-radius:50%;box-shadow:0 6px 18px rgba(0,0,0,.3),0 0 0 2px rgba(255,255,255,.4);}
.gdc-face .avatar{display:flex;}
.gdc-p.is-win .gdc-face{box-shadow:0 6px 18px rgba(0,0,0,.3),0 0 0 3px #ffd43b;}
.gdc-crown{position:absolute;z-index:1;top:-15px;left:50%;transform:translateX(-50%) rotate(-8deg);color:#ffd43b;display:flex;filter:drop-shadow(0 1px 2px rgba(0,0,0,.35));}
.gdc-p b{font-size:var(--fs-md);font-weight:var(--fw-bold);font-variant-numeric:tabular-nums;line-height:1;text-shadow:0 1px 3px rgba(0,0,0,.35);}
.gdc-p.is-lose b{color:rgba(255,255,255,.62);}
/* 아래 띠: 게임 아이콘과 이름, 오른쪽 작은 유리 동그라미 버튼 */
.gdc-foot{display:flex;align-items:center;gap:8px;padding:9px 10px 9px 12px;background:rgba(0,0,0,.2);}
.gdc-icon{flex:none;width:26px;height:26px;border-radius:7px;background-size:cover;background-position:center top;box-shadow:inset 0 0 0 1px rgba(255,255,255,.2);}
.gdc-game{flex:1;min-width:0;font-size:var(--fs-sm);font-weight:var(--fw-bold);color:rgba(255,255,255,.92);overflow:hidden;text-overflow:ellipsis;white-space:nowrap;}
.gdc-btn{flex:none;width:36px;height:36px;padding:0;display:grid;place-items:center;border:none;border-radius:999px;background:rgba(255,255,255,.2);backdrop-filter:blur(14px);-webkit-backdrop-filter:blur(14px);box-shadow:inset 0 0 0 1px rgba(255,255,255,.22),inset 0 1px 0 rgba(255,255,255,.35);font-size:var(--fs-sm);font-weight:var(--fw-bold);color:#fff;transition:transform .15s var(--ease-smooth-out);}
/* 지금 할 일(재생): iOS 유리 동그라미. 하단 탭 바(.nav-orb)와 같은 유리 값 */
.gdc-btn.is-main{background:linear-gradient(180deg,#ffffff4d,#ffffff26);backdrop-filter:blur(7px) saturate(135%) brightness(1.08);-webkit-backdrop-filter:blur(7px) saturate(135%) brightness(1.08);box-shadow:inset 1.5px 1.5px 0 -.5px #ffffffe6,inset -1px -1px 0 -.5px #ffffffa6,inset 0 0 0 .5px #ffffff80,inset 0 0 14px #ffffff4d,0 0 0 .5px #0000000f,0 6px 16px -8px #00000047;color:#fff;}
.gdc-btn:active{transform:scale(.94);}
@media (prefers-reduced-transparency: reduce){.gdc-tag,.gdc-btn,.gdc-btn.is-main{backdrop-filter:none;-webkit-backdrop-filter:none;background:rgba(0,0,0,.45);}.gh-card-play{backdrop-filter:none;-webkit-backdrop-filter:none;background:var(--gray-0);}.gh-duel-go{backdrop-filter:none;-webkit-backdrop-filter:none;background:rgba(255,255,255,.2);}}
/* 결과 알림 한 줄: 시스템 안내처럼 가운데 알약 */
.game-duel-result{flex:none;align-self:center;display:inline-flex;align-items:center;gap:5px;margin:8px auto;padding:8px 14px;border-radius:var(--radius-full);background:var(--gray-100);color:var(--text-mid);font-size:var(--fs-sm);}
.game-duel-result b{font-weight:var(--fw-bold);color:var(--text);}
.games-licenses{margin-top:28px;font-size:var(--fs-xs);color:var(--text-light);}
.games-licenses summary{cursor:pointer;padding:8px 0;list-style:none;}
.games-licenses summary::-webkit-details-marker{display:none;}
.games-licenses ul{margin:4px 0 10px;padding:0;list-style:none;display:flex;flex-direction:column;gap:8px;}
.games-licenses b{color:var(--text-mid);font-weight:var(--fw-bold);margin-right:4px;}
.games-licenses p{margin:0;line-height:1.5;}

.game-pick-layer{position:fixed;inset:0;z-index:950;}
@media (prefers-reduced-motion: reduce){.game-card-art img{transition:none;}}

/* 미니게임 화면(2026-09-30 재설계, §screens/games.js). 애플 아케이드식: 그림이 카드를 채우고 아래에 유리 막대.
   모서리: 카드 --radius-xl, 버튼 알약. 색은 게임 그림에서만 나오고 틀은 무채색. */
/* 받은 대결: 가로로 넘긴다. 여러 장이면 다음 카드가 살짝 보이게 좁히고, 넘길 때 카드가 Y축으로 돌아간다(플립).
   플립은 스크롤 위치에 묶인 애니메이션이라 손가락에 그대로 붙고, 지원하지 않는 브라우저는 넘기기만 한다 */
.gh-duels{display:flex;gap:10px;overflow-x:auto;scroll-snap-type:x mandatory;scrollbar-width:none;margin:0 -16px 22px;padding:0 16px;scroll-padding:0 16px;perspective:900px;}
.gh-duels::-webkit-scrollbar{display:none;}
.gh-duels>*{flex:0 0 100%;scroll-snap-align:start;scroll-snap-stop:always;}
.gh-duels:has(>.gh-duel+.gh-duel)>.gh-duel{flex-basis:calc(100% - 28px);}
@supports (animation-timeline:view()){
  .gh-duels>.gh-duel{animation:gh-duel-flip linear both;animation-timeline:view(inline);}
  @keyframes gh-duel-flip{0%{transform:rotateY(-28deg) scale(.94);opacity:.55;}35%,65%{transform:none;opacity:1;}100%{transform:rotateY(28deg) scale(.94);opacity:.55;}}
}
.gh-duel{position:relative;overflow:hidden;isolation:isolate;min-height:80px;box-sizing:border-box;display:flex;align-items:center;gap:12px;padding:14px 14px 14px 12px;border-radius:var(--radius-xl);corner-shape:squircle;background:var(--gray-900);color:var(--gray-0);}
.gh-duel-sk{display:block;height:80px;border-radius:var(--radius-xl);}
.gh-duel-bg{position:absolute;inset:-6px;width:calc(100% + 12px);height:calc(100% + 12px);object-fit:cover;opacity:.7;filter:blur(1.5px);z-index:-1;pointer-events:none;}
/* 글씨가 있는 왼쪽은 어둡게, 도전 버튼 쪽은 그림이 더 비치게 */
.gh-duel::after{content:"";position:absolute;inset:0;z-index:-1;background:linear-gradient(90deg,rgba(0,0,0,.8),rgba(0,0,0,.55) 60%,rgba(0,0,0,.3));pointer-events:none;}
.gh-duel-faces{display:flex;align-items:center;flex:none;}
.gh-duel-vs{font-size:9px;font-weight:var(--fw-bold);letter-spacing:.5px;color:var(--gray-400);margin:0 -2px;z-index:1;background:var(--gray-900);padding:2px 3px;border-radius:var(--radius-full);}
.gh-duel-me{width:36px;height:36px;border-radius:50%;background:var(--gray-700);display:flex;align-items:center;justify-content:center;font-size:var(--fs-xs);font-weight:var(--fw-bold);color:var(--gray-0);}
.gh-duel-text{flex:1;min-width:0;}
.gh-duel-kicker{font-size:var(--fs-2xs);color:var(--gray-400);margin:0 0 3px;}
.gh-duel-title{font-size:var(--fs-sm);color:var(--gray-200);margin:0;line-height:1.35;}
.gh-duel-title b{color:var(--gray-0);font-weight:var(--fw-bold);}
/* 도전: 채팅방 대결 카드의 재생 버튼과 같은 iOS 유리 */
.gh-duel-go{flex:none;border:none;border-radius:var(--radius-full);background:linear-gradient(180deg,#ffffff4d,#ffffff26);backdrop-filter:blur(7px) saturate(135%) brightness(1.08);-webkit-backdrop-filter:blur(7px) saturate(135%) brightness(1.08);box-shadow:inset 1.5px 1.5px 0 -.5px #ffffffe6,inset -1px -1px 0 -.5px #ffffffa6,inset 0 0 0 .5px #ffffff80,inset 0 0 14px #ffffff4d,0 0 0 .5px #0000000f,0 6px 16px -8px #00000047;color:#fff;width:36px;height:36px;padding:0;display:grid;place-items:center;transition:transform .15s var(--ease-smooth-out);}
.gh-duel-go:active{transform:scale(.95);}
.gh-rank{display:flex;align-items:center;gap:5px;flex:none;height:38px;padding:0 13px;border:none;border-radius:var(--radius-full);background:var(--gray-100);color:var(--text);font-size:var(--fs-sm);font-weight:var(--fw-bold);transition:transform .15s var(--ease-smooth-out);}
.gh-rank:active{transform:scale(.95);}
/* 게임 카드: 두 줄 격자. 미리보기 영상과 같은 7:6이라 잘리는 곳이 없다 */
.gh-cards{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:12px;}
.gh-card{position:relative;aspect-ratio:7/6;border-radius:var(--radius-lg);corner-shape:squircle;overflow:hidden;background:var(--tint);box-shadow:0 14px 28px -20px rgba(40,34,28,.5);isolation:isolate;}
.gh-card-art{position:absolute;inset:0;z-index:0;border:none;padding:0;background:none;}
.gh-card-art :is(img,video){width:100%;height:100%;object-fit:cover;object-position:center top;display:block;transition:transform .5s var(--ease-smooth-out);}
.gh-card-art:active :is(img,video){transform:scale(1.03);}
/* 묶음(같이 하기, 혼자 하기): 제목과 한 줄 설명 아래 카드 */
.gh-group{margin:0 0 28px;}
.gh-group h2{margin:0;font-size:var(--fs-xl);font-weight:var(--fw-bold);color:var(--text);letter-spacing:-.3px;}
.gh-group p{margin:2px 0 12px;font-size:var(--fs-xs);color:var(--text-mid);}
/* 카드 위 조작(iOS Liquid Glass처럼): 뒤가 비치는 유리. 이름은 밝은 유리에 짙은 글자, 기록과 대결은 살짝 그을린 유리에 밝은 글자라
   밝은 영상 위에서도 읽힌다. 시작은 하단 탭 바와 같은 맑은 유리 동그라미 */
.gh-card-name,.gh-card-people,.gh-card-best,.gh-card-play,.gh-card-soon{backdrop-filter:blur(14px) saturate(180%);-webkit-backdrop-filter:blur(14px) saturate(180%);}
.gh-card-name{position:absolute;top:7px;left:7px;z-index:2;max-width:calc(100% - 14px);padding:5px 10px;border-radius:var(--radius-full);background:rgba(255,255,255,.5);box-shadow:inset 0 0 0 1px rgba(255,255,255,.55),inset 0 1px 0 rgba(255,255,255,.9),0 4px 12px rgba(0,0,0,.1);font-size:var(--fs-sm);font-weight:var(--fw-bold);letter-spacing:-.2px;color:var(--gray-900);overflow:hidden;text-overflow:ellipsis;white-space:nowrap;pointer-events:none;}
.gh-card-bar{position:absolute;left:7px;right:7px;bottom:7px;z-index:2;display:flex;align-items:center;gap:5px;pointer-events:none;}
/* 그을린 유리: 비치는 어두운 막과 위쪽 빛 테두리 */
.gh-card-people,.gh-card-best,.gh-card-soon{background:rgba(24,24,24,.34);box-shadow:inset 0 0 0 1px rgba(255,255,255,.28),inset 0 1px 0 rgba(255,255,255,.5),0 4px 12px rgba(0,0,0,.14);color:var(--gray-0);}
/* 최고 기록: 노란 왕관과 노란 점수 */
.gh-card-best{display:flex;align-items:center;gap:3px;min-width:0;height:30px;padding:0 9px 0 7px;border-radius:var(--radius-full);color:#ffd84d;font-size:var(--fs-xs);font-weight:var(--fw-bold);font-variant-numeric:tabular-nums;text-shadow:0 1px 2px rgba(0,0,0,.35);}
.gh-card-best svg{flex:none;filter:drop-shadow(0 1px 1px rgba(0,0,0,.3));}
.gh-card-acts{margin-left:auto;display:flex;align-items:center;gap:5px;flex:none;}
.gh-card-play{pointer-events:auto;flex:none;width:34px;height:34px;padding:0;border:none;border-radius:50%;display:grid;place-items:center;transition:transform .15s var(--ease-smooth-out);}
.gh-card-play{background:linear-gradient(180deg,#ffffff4d,#ffffff26);backdrop-filter:blur(7px) saturate(135%) brightness(1.08);-webkit-backdrop-filter:blur(7px) saturate(135%) brightness(1.08);box-shadow:inset 1.5px 1.5px 0 -.5px #ffffffe6,inset -1px -1px 0 -.5px #ffffffa6,inset 0 0 0 .5px #ffffff80,inset 0 0 14px #ffffff4d,0 0 0 .5px #0000000f,0 6px 16px -8px #00000047;color:var(--gray-900);}
.gh-card-play:active{transform:scale(.92);}
.gh-card-soon{padding:6px 10px;border-radius:var(--radius-full);font-size:var(--fs-2xs);font-weight:var(--fw-bold);}
.gh-card.is-soon .gh-card-art img{filter:saturate(.6);}
/* 같이 하기 카드 오른쪽 위: 할 수 있는 인원 */
.gh-card-people{position:absolute;top:7px;right:7px;z-index:2;padding:5px 9px;border-radius:var(--radius-full);font-size:var(--fs-xs);font-weight:var(--fw-bold);white-space:nowrap;}
.gh-card:has(.gh-card-people) .gh-card-name{max-width:calc(100% - 80px);}
@media (prefers-reduced-transparency: reduce){.gh-card-people,.gh-card-name,.gh-card-best,.gh-card-soon{background:rgba(20,20,20,.86);color:var(--gray-0);backdrop-filter:none;-webkit-backdrop-filter:none;}.gh-card-best{color:#ffd84d;}}
@media (prefers-reduced-motion: reduce){.gh-card-art :is(img,video){transition:none;}}
/* 대결 보내기 줄(Apple Games 친구 탭처럼 사람 먼저): 대화 상대 얼굴, 오른쪽 아래 검은 ⚔ 배지. 넘치면 옆으로 민다 */
.gh-faces{display:flex;gap:14px;overflow-x:auto;scrollbar-width:none;margin:0 -16px;padding:2px 16px 4px;}
.gh-faces::-webkit-scrollbar{display:none;}
.gh-face{flex:none;display:flex;flex-direction:column;align-items:center;gap:5px;width:60px;border:none;padding:0;background:none;transition:transform .15s var(--ease-smooth-out);}
.gh-face:active{transform:scale(.94);}
.gh-face-pic{position:relative;display:flex;}
.gh-face-badge{position:absolute;right:-2px;bottom:-2px;width:22px;height:22px;border-radius:50%;display:grid;place-items:center;background:var(--gray-900);color:var(--gray-0);border:2px solid var(--bg1);}
.gh-face .sk:last-child{width:36px;margin:2px 0;}
.gh-face-name{line-height:18px;max-width:100%;font-size:var(--fs-sm);color:var(--text-mid);overflow:hidden;text-overflow:ellipsis;white-space:nowrap;}
/* 게임 칸(§ui/components/duel-tiles.js): 채팅방 게임 칸과 얼굴 줄 시트가 같이 쓴다. 기록은 점수 겨루기, 차례는 주고받기 */
.duel-sheet-title{margin:0;font-size:var(--fs-2xl);font-weight:var(--fw-bold);color:var(--text);}
.duel-sheet-sub{margin:2px 0 14px;font-size:var(--fs-md);color:var(--text-mid);}
.duel-tiles{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:10px;}
.duel-tile{border:none;padding:0;background:none;text-align:center;font-size:var(--fs-sm);font-weight:var(--fw-bold);color:var(--text);transition:transform .15s var(--ease-smooth-out);}
.duel-tile:active{transform:scale(.95);}
.duel-tile-art{position:relative;display:block;aspect-ratio:1;margin-bottom:5px;border-radius:var(--radius-lg);corner-shape:squircle;background-size:cover;background-position:center top;box-shadow:0 6px 14px -8px rgba(0,0,0,.35);}
.duel-tile-art em{position:absolute;left:6px;bottom:6px;padding:2px 7px;border-radius:var(--radius-full);background:rgba(0,0,0,.45);backdrop-filter:blur(8px);-webkit-backdrop-filter:blur(8px);color:var(--gray-0);font-size:var(--fs-2xs);font-style:normal;}
@media (prefers-reduced-motion: reduce){.gh-face,.duel-tile{transition:none;}.gh-duels>.gh-duel{animation:none;}}

/* 온보딩 길 고르기(§screens/auth.js stepPath): 매칭받기와 나중에. 카드 안에 고르면 달라지는 점을 바로 적고,
   고른 카드는 색 대신 진한 테두리와 검은 아이콘, 체크로 보인다 */
.path-step{display:flex;flex-direction:column;}
.path-cards{display:flex;flex-direction:column;gap:12px;margin:22px 0 24px;}
.path-card{display:flex;align-items:flex-start;gap:14px;width:100%;padding:18px 16px;text-align:left;border:1.5px solid var(--border);border-radius:var(--radius-lg);corner-shape:squircle;background:var(--card);box-shadow:var(--shadow-sm);color:var(--text);font:inherit;transition:border-color .15s ease-out,box-shadow .15s ease-out,transform .1s ease-out;}
.path-card:active{transform:scale(.98);}
.path-card.is-on{border-color:var(--primary-dark);box-shadow:0 0 0 1px var(--primary-dark),var(--shadow-sm);}
.path-card-ic{flex:none;width:44px;height:44px;border-radius:50%;display:flex;align-items:center;justify-content:center;background:var(--bg2);color:var(--text);transition:background-color .15s ease-out,color .15s ease-out;}
.path-card.is-on .path-card-ic{background:var(--primary-dark);color:var(--gray-0);}
.path-card-body{flex:1;min-width:0;display:flex;flex-direction:column;gap:8px;padding-top:2px;}
.path-card-body b{font-size:var(--fs-lg);font-weight:var(--fw-bold);letter-spacing:-.01em;}
.path-card-sub{font-size:var(--fs-sm);line-height:1.45;color:var(--text-mid);}
.path-card-check{flex:none;width:22px;height:22px;margin-top:2px;border:1.5px solid var(--border);border-radius:50%;display:flex;align-items:center;justify-content:center;color:transparent;transition:background-color .15s ease-out,border-color .15s ease-out;}
.path-card.is-on .path-card-check{background:var(--primary-dark);border-color:var(--primary-dark);color:var(--gray-0);}
.path-step .btn-primary:disabled{opacity:.35;}
.path-help{display:flex;justify-content:center;margin:-8px 0 20px;}
/* 물음표 설명(§ui/components/match-help.js). 브라우저 기본 popover라 화면 가운데에 뜨고 바깥을 누르면 닫힌다 */
.help-btn{display:inline-flex;align-items:center;gap:4px;margin:0 0 0 4px;padding:2px;border:0;background:none;font:inherit;font-size:var(--fs-sm);color:var(--text-light);cursor:pointer;}
.help-pop{width:min(300px,calc(100vw - 48px));box-sizing:border-box;margin:auto;padding:18px 18px 16px;border:0;border-radius:var(--radius-lg);corner-shape:squircle;background:var(--card);color:var(--text);box-shadow:var(--shadow-pop);}
.help-pop::backdrop{background:rgb(0 0 0 / .25);}
.help-pop b{display:block;margin-bottom:8px;font-size:var(--fs-base);font-weight:var(--fw-bold);}
.help-pop ul{margin:0 0 10px;padding-left:18px;font-size:var(--fs-sm);line-height:1.6;color:var(--text-mid);}
.help-pop p{margin:0;font-size:var(--fs-sm);line-height:1.5;color:var(--text-light);}

/* 매칭 쉬는 중(§screens/matching.js matchingPausedHtml) */
.match-paused{display:flex;flex-direction:column;align-items:center;padding:48px 20px 24px;text-align:center;}
.match-paused-ic{width:64px;height:64px;margin-bottom:18px;border-radius:50%;display:flex;align-items:center;justify-content:center;background:var(--bg2);color:var(--text);}
.match-paused-title{margin:0 0 8px;font-size:var(--fs-2xl);font-weight:var(--fw-bold);color:var(--text);}
.match-paused .btn{max-width:280px;}
.match-paused-hint{margin:10px 0 0;font-size:var(--fs-xs);color:var(--text-light);}
.match-paused-alt{margin-top:18px;}
@media (prefers-reduced-motion: reduce){.path-card,.path-card-ic,.path-card-check{transition:none;}}
/* 온보딩 7화면과 이상형 한 장(§screens/auth.js renderOnboarding, preferencePage). 시안 design/onboarding-mock.html A안,
   성격과 MBTI는 B안. 위쪽은 뒤로 화살표, 얇은 진행 막대, "3/7"이 한 줄이고(틴더, 클러키) 아래 버튼은 하나다 */
.ob-top,.ob-mhd{display:flex;align-items:center;gap:12px;flex:none;margin:-14px 0 0;}
.ob-back{flex:none;width:32px;height:40px;display:flex;align-items:center;justify-content:flex-start;padding:0;border:0;background:none;color:var(--text);}
.ob-bar{flex:1;height:4px;border-radius:var(--radius-full);background:var(--gray-100);overflow:hidden;}
.ob-bar>i{display:block;height:100%;border-radius:inherit;background:var(--gray-800);transition:width .3s cubic-bezier(.4,0,.2,1);}
.ob-count{flex:none;min-width:24px;text-align:right;font-size:var(--fs-sm);font-weight:var(--fw-bold);color:var(--text-light);}
.ob-mhd>b{flex:1;text-align:center;font-size:var(--fs-2xl);font-weight:var(--fw-bold);}
.ob-form{text-align:left;}
.ob-form .chip-row{justify-content:flex-start;gap:7px;}
.ob-form .chip[hidden]{display:none!important;}
.ob-h1{margin:0 0 6px;font-size:26px;line-height:1.25;font-weight:var(--fw-bold);letter-spacing:-.04em;color:var(--text);}
.ob-lead{margin:0 0 4px;font-size:var(--fs-base);line-height:1.5;color:var(--text-mid);}
.ob-sec{margin:18px 0 8px;font-size:var(--fs-md);font-weight:var(--fw-bold);color:var(--text-mid);}
.ob-sec-row{display:flex;align-items:baseline;justify-content:space-between;}
.ob-sec-row>b{font-size:var(--fs-base);font-weight:var(--fw-bold);color:var(--text);}
.ob-skip-row{display:flex;justify-content:flex-end;margin:-8px 0 2px;}
.ob-skip{padding:4px 0;border:0;background:none;font:inherit;font-size:var(--fs-md);font-weight:var(--fw-bold);color:var(--text-light);}
.ob-range{display:block;width:100%;margin:6px 0 0;accent-color:var(--gray-800);}
.ob-link{display:block;margin:6px 0 0;padding:0;font-size:var(--fs-sm);color:var(--text-light);}
.ob-kick{margin:26px 0 8px;font-size:var(--fs-md);font-weight:var(--fw-bold);color:var(--text-light);text-align:left;}
.ob-xl{margin:0 0 26px;font-size:30px;line-height:1.25;font-weight:var(--fw-bold);letter-spacing:-.04em;color:var(--text);text-align:left;}
.ob-poles{display:flex;justify-content:space-between;gap:12px;margin:40px 2px 18px;font-size:18px;color:var(--text);}
.ob-poles>b{font-weight:var(--fw-bold);}
.trait-dots{display:flex;align-items:center;justify-content:space-between;height:44px;padding:0 2px;}
.trait-dot{position:relative;flex:none;width:var(--d);height:var(--d);padding:0;border-radius:50%;border:2px solid var(--gray-300);background:var(--gray-0);transition:background-color .12s ease-out,border-color .12s ease-out,transform .1s ease-out;}
.trait-dot::before{content:"";position:absolute;left:50%;top:50%;width:44px;height:44px;transform:translate(-50%,-50%);}
.trait-dot:active{transform:scale(.9);}
.trait-dot.on{background:var(--gray-800);border-color:var(--gray-800);box-shadow:0 0 0 6px rgba(26,26,26,.1);}
.trait-dots-mid{margin-top:10px;font-size:var(--fs-sm);color:var(--text-light);text-align:center;}
.ob-note{text-align:center;}
.ob-note::before{display:none;}
.ob-opts{display:grid;gap:10px;}
.ob-opt{display:flex;align-items:center;justify-content:space-between;width:100%;padding:18px 20px;border:1px solid var(--gray-100);border-radius:var(--radius-lg);corner-shape:squircle;background:var(--gray-0);box-shadow:var(--shadow-sm);font:inherit;font-size:17px;font-weight:var(--fw-bold);color:var(--text);text-align:left;transition:background-color .12s ease-out,color .12s ease-out,transform .1s ease-out;}
.ob-opt>svg{flex:none;opacity:0;}
.ob-opt:active{transform:scale(.98);}
.ob-opt.on{background:var(--gray-800);border-color:var(--gray-800);color:var(--gray-0);}
.ob-opt.on>svg{opacity:1;}
.ob-blk{padding:16px 2px;border-bottom:1px solid var(--gray-100);}
.ob-bh{display:flex;align-items:baseline;justify-content:space-between;gap:12px;margin-bottom:12px;font-size:var(--fs-base);}
.ob-bh>span{font-weight:var(--fw-bold);color:var(--text);}
.ob-bh>b{font-weight:var(--fw-bold);color:var(--text-mid);}
.ob-segs{display:grid;gap:10px;}
.ob-segs-gap{margin-top:22px;}
.ob-group-zone{margin-top:20px;min-height:0;}
.ob-form .field label,.ob-form .field .hint{text-align:left;}
.ob-seg-row{display:flex;align-items:center;justify-content:space-between;gap:12px;font-size:var(--fs-md);color:var(--text-mid);}
.ob-seg{display:flex;padding:3px;border-radius:var(--radius-xs);corner-shape:squircle;background:var(--gray-100);}
.ob-seg>button{padding:6px 11px;border:0;border-radius:8px;background:none;font:inherit;font-size:var(--fs-sm);color:var(--text-mid);transition:background-color .12s ease-out,color .12s ease-out;}
.ob-seg>button.selected{background:var(--gray-0);color:var(--text);font-weight:var(--fw-bold);box-shadow:var(--shadow-sm);}
.ob-list{margin:16px 0 4px;border:1px solid var(--gray-100);border-radius:var(--radius-lg);corner-shape:squircle;background:var(--card);box-shadow:var(--shadow-sm);overflow:hidden;}
.ob-row{display:flex;align-items:center;gap:10px;width:100%;min-height:50px;padding:0 14px;border:0;border-bottom:1px solid var(--gray-100);background:none;font:inherit;color:var(--text);text-align:left;}
.ob-row:last-child{border-bottom:0;}
.ob-row>span{flex:none;font-size:var(--fs-base);font-weight:var(--fw-bold);}
.ob-row>b{flex:1;min-width:0;text-align:right;font-size:var(--fs-md);font-weight:var(--fw-regular);color:var(--text-mid);white-space:nowrap;overflow:hidden;text-overflow:ellipsis;}
.ob-row>svg{flex:none;color:var(--text-light);}
.ob-row:active{background:var(--bg2);}
@media (prefers-reduced-motion: reduce){.ob-bar>i,.trait-dot,.ob-opt,.ob-seg>button{transition:none;}}
/* 내 조건 수정 목록(§screens/auth.js renderEditProfile, 틴더 Edit Info). 칸 이름, 흰 목록 카드, 줄 안의 토글 */
.ob-edit{padding-bottom:calc(120px + env(safe-area-inset-bottom));}
.ob-save{flex:none;min-width:32px;height:40px;padding:0;border:0;background:none;font:inherit;font-size:var(--fs-xl);font-weight:var(--fw-bold);color:var(--text);text-align:right;}
.ob-edit-list{margin-top:6px;}
.ob-edit-list .ob-sec{margin:22px 4px 8px;}
.ob-edit-list .ob-list{margin:0;}
.ob-row-static{cursor:default;}
.ob-row-static:active{background:none;}
.ob-row-static>span{flex:1;}
/* 나이 안내(§screens/auth.js AGE_NOTICE). 온보딩은 흰 상자 한 줄, 내 조건 수정은 칸 아래 작은 한 줄 */
.ob-note{display:flex;gap:8px;align-items:flex-start;margin:14px 0 0;padding:11px 12px;border:1px solid var(--gray-100);border-radius:var(--radius-sm);corner-shape:squircle;background:var(--card);font-size:var(--fs-sm);line-height:1.45;color:var(--text-mid);}
.ob-note>svg{flex:none;margin-top:1px;color:var(--text);}
.ob-foot{display:flex;gap:6px;align-items:flex-start;margin:8px 6px 0;font-size:var(--fs-sm);line-height:1.45;color:var(--text-mid);}
.ob-foot>svg{flex:none;margin-top:2px;}
.ob-row-static>b+svg{flex:none;color:var(--text-light);}
.ob-row>.ob-row-thumb{flex:none;width:30px;height:30px;border-radius:50%;object-fit:cover;}
/* 가운데 정렬 시트(Omio, Drinkit). 손잡이, 가운데 제목, 오른쪽 위 닫기, 아래 완료 버튼 하나 */
.ob-sheet{position:relative;text-align:center;padding-top:12px;padding-bottom:calc(12px + env(safe-area-inset-bottom));}
.ob-sliders{text-align:left;margin-top:6px;}
.ob-sliders .slider-row{margin-bottom:18px;}
.ob-sliders .slider-row:last-child{margin-bottom:6px;}
.ob-sheet-x{position:absolute;top:14px;right:14px;width:36px;height:36px;display:flex;align-items:center;justify-content:center;padding:0;border:0;border-radius:50%;background:none;color:var(--text-mid);}
.ob-sheet-title{margin:10px 40px 14px;font-size:var(--fs-3xl);font-weight:var(--fw-bold);letter-spacing:-.03em;color:var(--text);}
.ob-pager{display:flex;justify-content:center;gap:5px;margin:-4px 0 4px;}
.ob-pager>i{width:6px;height:6px;border-radius:var(--radius-full);background:var(--gray-300);transition:width .2s ease-out,background-color .2s ease-out;}
.ob-pager>i.on{width:16px;background:var(--gray-800);}
.ob-sheet-dots .ob-poles{margin-top:22px;}
.ob-chips-center{justify-content:center;gap:8px;}
.ob-sheet-left{text-align:left;margin-top:4px;}
.ob-sheet-text{width:100%;box-sizing:border-box;padding:12px 14px;border:1.5px solid var(--border);border-radius:var(--radius-sm);corner-shape:squircle;outline:none;font-family:inherit;font-size:var(--fs-base);resize:none;text-align:left;}
.ob-sheet-cta{margin-top:24px;}
/* 성격처럼 긴 시트는 목록만 스크롤되고 완료 버튼은 시트 아래에 붙어 있다. 버튼 둘레를 시트 바탕색으로 덮어 뒤 내용이 비치지 않게 한다 */
.ob-sheet .ob-sheet-cta{position:sticky;bottom:0;z-index:2;box-shadow:0 10px 0 10px var(--bg1),0 -14px 14px -2px var(--bg1);}
/* 조건 수정의 성격, MBTI 고르기(§screens/auth.js traitLineRowHtml, 시안 design/trait-c3-mock.html). 가는 선 위의 점 7개,
   고른 점만 크게, 점 아래에 고른 칸 이름(Calm). 가운데 점은 점선 동그라미. 흑백만 쓴다 */
.tl-list{text-align:left;}
.tl-row{padding:10px 0 2px;border-bottom:1px solid var(--gray-100);}
.tl-row:last-child{border-bottom:0;}
.tl-labels{display:flex;justify-content:space-between;gap:12px;margin-bottom:8px;font-size:var(--fs-sm);color:var(--text-light);}
.tl-labels>.on{color:var(--text);font-weight:var(--fw-bold);}
.tl-line{position:relative;height:40px;margin:0 9px;}
.tl-rail{position:absolute;left:0;right:0;top:9px;height:1.5px;background:var(--gray-200);pointer-events:none;}
.tl-dot{position:absolute;top:5px;width:10px;height:10px;margin-left:-5px;padding:0;border-radius:50%;border:1.5px solid var(--gray-300);background:var(--gray-0);transition:transform .1s ease-out;}
.tl-dot::before{content:"";position:absolute;left:50%;top:50%;width:40px;height:40px;transform:translate(-50%,-50%);}
.tl-dot.mid{border-style:dashed;}
.tl-dot.on{top:1px;width:18px;height:18px;margin-left:-9px;border-color:var(--gray-800);background:var(--gray-800);box-shadow:0 0 0 5px rgba(26,26,26,.08);}
.tl-dot:active{transform:scale(.9);}
.tl-pick{position:absolute;top:24px;transform:translateX(-50%);font-style:normal;font-size:var(--fs-xs);font-weight:var(--fw-bold);color:var(--text);white-space:nowrap;pointer-events:none;}
.tl-pick.mid{font-weight:var(--fw-regular);color:var(--text-light);}
.tl-pick.is-start{transform:translateX(-9px);}
.tl-pick.is-end{transform:translateX(calc(-100% + 9px));}
.ob-trait-note{margin:12px 0 0;text-align:left;}
/* 마이페이지 성격 요약(§screens/mypage.js myTraitContentHtml). MBTI 네 글자와 두 줄 칩(Glow, Nooka), 가운데인 축은 개수만 */
.trait-summary{padding:0 2px 4px;}
.ts-blk:last-child{padding-bottom:0;}
.ts-blk{padding:4px 0 14px;}
.ts-blk+.ts-blk{padding-top:14px;border-top:1px solid var(--gray-100);}
.ts-lbl{margin:0 0 6px;font-size:var(--fs-sm);font-weight:var(--fw-bold);color:var(--text-mid);}
.ts-mbti{margin:0;font-size:34px;font-weight:var(--fw-bold);letter-spacing:.06em;line-height:1.1;color:var(--text);}
.ts-blank{color:var(--gray-300);}
.ts-none{margin:0;font-size:var(--fs-md);color:var(--text-mid);}
.ts-chips{display:flex;flex-wrap:wrap;gap:6px;}
.ts-chip{display:flex;flex-direction:column;gap:1px;padding:7px 12px 8px;border:1px solid var(--gray-200);border-radius:var(--radius-sm);corner-shape:squircle;background:var(--card);}
.ts-chip>small{font-size:var(--fs-2xs);color:var(--text-light);}
.ts-chip>b{font-size:var(--fs-md);font-weight:var(--fw-bold);color:var(--text);}
@media (prefers-reduced-motion: reduce){.tl-dot{transition:none;}}
/* 말풍선 미리보기는 1:1 탭 오늘의 추천 카드 그대로 보여 주기만 한다(버튼은 눌리지 않는다) */
.ob-rec-preview{margin:4px 0 12px;text-align:left;pointer-events:none;}
@media (prefers-reduced-motion: reduce){.ob-pager>i{transition:none;}}

/* 설정 > 글꼴 설정 시트. 글꼴 이름은 각자 자기 글꼴로 보여 줘서 고르기 전에 모양을 알 수 있게 한다. */
.display-set-hint{margin:0 0 18px;font-size:var(--fs-md);color:var(--text-mid);}
.display-set-label{margin:0 0 8px;font-size:var(--fs-md);font-weight:var(--fw-bold);color:var(--text-mid);}
.display-font-list{display:flex;flex-direction:column;gap:8px;margin-bottom:20px;}
.display-font-opt{position:relative;display:flex;flex-direction:column;align-items:flex-start;gap:2px;width:100%;padding:12px 14px;border:1.5px solid var(--border);border-radius:var(--radius-sm);background:var(--gray-0);color:var(--text);text-align:left;transition:transform .1s ease-out;}
.display-font-opt:active{transform:scale(.98);}
.display-font-opt.active{border-color:var(--primary-dark);}
.display-font-name{font-size:var(--fs-xl);font-weight:var(--fw-bold);line-height:24px;}
.display-font-desc{font-size:var(--fs-md);line-height:18px;color:var(--text-mid);}
.display-font-dl{position:absolute;top:14px;right:14px;font-size:var(--fs-xs);line-height:18px;color:var(--text-light);}
.sheet .display-font-dl{font-family:var(--font-sys)!important;}
.display-font-opt.downloading{opacity:.6;}
/* .sheet *의 --font-sys 지정보다 구체적인 선택자로, 각 항목을 자기 글꼴(--opt-font)로 그린다. */
.sheet .display-font-opt,.sheet .display-font-opt *{font-family:var(--opt-font)!important;}
.display-spacing{display:flex;gap:6px;margin-bottom:16px;}
/* 고르는 버튼은 크기 설정을 따라 커지지 않게 둔다(작은 화면에서 넘치지 않게). 효과는 아래 미리보기로 본다. */
.display-spacing button{flex:1;min-width:0;padding:8px 0;white-space:nowrap;border:0;border-radius:var(--radius-full);background:var(--bg2);color:var(--text-mid);font-size:calc(var(--fs-md) / var(--fs-scale));transition:transform .1s ease-out;}
.display-spacing button:active{transform:scale(.95);}
.display-spacing button.active{background:var(--gray-900);color:var(--gray-0);font-weight:var(--fw-bold);} /* 고른 칸은 칩(§user-controls.css .chip.selected)과 같은 검정 채움 */
.display-spacing-value{margin:-8px 0 12px;font-size:var(--fs-sm);color:var(--text-light);font-variant-numeric:tabular-nums;}
/* 채팅 설정 시트 한도 칸(§ui/chat-settings-sheet.js): 이름 아래, 쓴 수 크게 /전체 작게 */
.cs-stats{display:grid;grid-template-columns:1fr 1fr;gap:8px;}
.cs-stats>div{padding:12px 14px;border-radius:var(--radius-sm);corner-shape:squircle;background:var(--gray-50);}
.cs-stats b{font-size:22px;font-variant-numeric:tabular-nums;}
.cs-stats b small{margin-left:2px;font-size:var(--fs-md);font-weight:var(--fw-regular);color:var(--text-light);}
.cs-stats span{display:block;margin-top:2px;font-size:var(--fs-sm);color:var(--text-mid);}
.display-preview{padding:14px 16px;border-radius:var(--radius-sm);background:var(--bg2);font-size:var(--fs-lg);line-height:1.5;color:var(--text);}
.display-preview b{font-weight:var(--fw-bold);}
@media (prefers-reduced-motion:reduce){.display-font-opt,.display-spacing button{transition:none;}}
/* 친구 초대 화면(§screens/mypage.js renderInvites). 남은 장수만 --primary-dark 굵은 숫자로 강조한다. */
.invite-summary{background:var(--gray-0);border-radius:var(--radius-lg);corner-shape:squircle;box-shadow:var(--shadow-sm);padding:20px 18px 18px;text-align:center;}
.invite-summary-label{font-size:var(--fs-sm);font-weight:var(--fw-bold);color:var(--text-light);}
.invite-summary-count{display:flex;align-items:baseline;justify-content:center;gap:6px;margin:6px 0 2px;font-size:var(--fs-xl);font-weight:var(--fw-bold);color:var(--primary-dark);}
.invite-summary-count strong{font-size:40px;line-height:1.1;letter-spacing:-.02em;}
.invite-summary-count span{font-size:var(--fs-md);color:var(--text-mid);}
.invite-summary-sub{font-size:var(--fs-sm);color:var(--text-mid);margin-bottom:16px;}
.invite-rules{margin:12px 4px 0;line-height:1.5;}
.invite-row{display:flex;align-items:center;gap:12px;padding:14px 16px;}
.invite-row+.invite-row{border-top:1px solid var(--border);}
.invite-row-main{flex:1;min-width:0;}
.invite-code{font-size:var(--fs-xl);font-weight:var(--fw-bold);letter-spacing:.14em;color:var(--primary-dark);font-variant-numeric:tabular-nums;}
.invite-row-detail{margin-top:2px;font-size:var(--fs-xs);color:var(--text-light);}
.invite-row.is-inactive .invite-code{color:var(--text-light);text-decoration:line-through;text-decoration-thickness:1px;}
.invite-state{flex-shrink:0;font-size:var(--fs-sm);font-weight:var(--fw-bold);color:var(--text-mid);}
.invite-copy{display:inline-flex;align-items:center;gap:4px;flex-shrink:0;}
/* 건의/신고 게시판(§screens/mypage.js renderSupportBoard) */
.support-intro{display:flex;align-items:flex-start;gap:6px;margin:0 4px 14px;line-height:1.5;}
.support-intro svg{flex-shrink:0;margin-top:2px;}
.support-row{display:block;width:100%;box-sizing:border-box;padding:14px 16px;border:none;background:none;font:inherit;text-align:left;color:var(--text);cursor:pointer;}
.support-row+.support-row{border-top:1px solid var(--border);}
.support-row-meta{display:flex;align-items:center;gap:6px;flex-wrap:wrap;font-size:var(--fs-xs);color:var(--text-light);}
.support-tag{font-weight:var(--fw-bold);color:var(--text-mid);}
.support-status{font-weight:var(--fw-bold);color:var(--primary-dark);}
.support-status.is-done{color:var(--text-light);}
.support-date{margin-left:auto;}
.support-row-title{margin-top:4px;font-size:var(--fs-base);font-weight:var(--fw-bold);overflow:hidden;text-overflow:ellipsis;white-space:nowrap;}
.support-categories{display:flex;gap:8px;}
.support-post{background:var(--gray-0);border-radius:var(--radius-lg);corner-shape:squircle;box-shadow:var(--shadow-sm);padding:16px 18px;}
.support-post-title{margin-top:8px;font-size:var(--fs-lg);font-weight:var(--fw-bold);}
.support-post-body,.support-comment-body{margin-top:8px;font-size:var(--fs-base);line-height:1.6;white-space:pre-wrap;word-break:break-word;}
.support-comment{background:var(--gray-0);border-radius:var(--radius-lg);corner-shape:squircle;box-shadow:var(--shadow-sm);padding:14px 16px;margin-bottom:10px;}
.support-comment-head{display:flex;align-items:center;justify-content:space-between;font-size:var(--fs-sm);}
.support-comment-head span{color:var(--text-light);font-size:var(--fs-xs);}
.support-photo-count{display:inline-flex;align-items:center;gap:2px;}
.support-label-row{display:flex;align-items:baseline;justify-content:space-between;gap:8px;margin-bottom:7px;}
.support-label-row label{margin:0;}
.support-count{font-size:var(--fs-xs);color:var(--text-light);font-variant-numeric:tabular-nums;}
.field input.support-title-input{font-weight:var(--fw-bold);}
.field input.support-title-input::placeholder{font-weight:var(--fw-regular);}
.support-thumbs{display:flex;gap:8px;overflow-x:auto;margin:0 -8px;padding:8px 8px 4px;scrollbar-width:none;-webkit-overflow-scrolling:touch;}
.support-thumbs::-webkit-scrollbar{display:none;}
.support-thumb{position:relative;flex:0 0 76px;width:76px;height:76px;box-sizing:border-box;border-radius:var(--radius-sm);corner-shape:squircle;}
.support-thumb:not(.skeleton-bar){background:var(--bg2);}
.support-thumb img{display:block;width:100%;height:100%;object-fit:cover;object-position:center top;border-radius:inherit;corner-shape:squircle;}
.support-thumb-remove{position:absolute;top:-6px;right:-6px;width:22px;height:22px;display:grid;place-items:center;padding:0;border:2px solid var(--gray-0);border-radius:50%;background:var(--gray-800);color:var(--gray-0);cursor:pointer;}
.support-thumbs .support-thumb-add{display:flex;flex-direction:column;align-items:center;justify-content:center;gap:2px;margin:0;border:1.5px solid var(--border);background:var(--gray-0);color:var(--text-mid);font-size:var(--fs-xs);font-weight:var(--fw-regular);font-variant-numeric:tabular-nums;cursor:pointer;}
.support-thumb-add strong{font-weight:var(--fw-bold);color:var(--text);}
.support-thumb-add.is-full{cursor:default;color:var(--text-light);}
.support-thumb-add.is-full strong{color:var(--text-light);}
.support-thumb-add input{display:none;}
.support-attach-hint{margin-top:6px;}
.support-textarea{width:100%;box-sizing:border-box;padding:13px 14px;border-radius:var(--radius-sm);corner-shape:squircle;border:1.5px solid var(--border);background:var(--gray-0);font-family:inherit;font-size:var(--fs-xl);color:var(--text);line-height:1.55;resize:vertical;outline:none;transition:border-color .12s;}
.support-textarea:focus{border-color:var(--primary);}
.support-images{display:grid;grid-template-columns:repeat(3,1fr);gap:6px;margin-top:14px;}
.support-image{display:block;aspect-ratio:1;padding:0;border:none;border-radius:var(--radius-xs);corner-shape:squircle;overflow:hidden;cursor:pointer;}
.support-image:not(.skeleton-bar){background:var(--bg2);}
.support-image img{display:block;width:100%;height:100%;object-fit:cover;object-position:center top;}
.support-image.is-missing{display:grid;place-items:center;padding:6px;font-size:var(--fs-xs);color:var(--text-light);text-align:center;cursor:default;}
.center-modal-overlay.support-viewer{padding:0;flex-direction:column;background:var(--gray-900);z-index:160;}
.support-viewer-top{position:absolute;top:0;left:0;right:0;display:flex;align-items:center;justify-content:space-between;padding:calc(env(safe-area-inset-top) + 10px) 12px 10px 20px;color:var(--gray-0);}
.support-viewer-count{font-size:var(--fs-md);font-variant-numeric:tabular-nums;}
.support-viewer-close{width:40px;height:40px;display:grid;place-items:center;padding:0;border:none;background:none;color:var(--gray-0);cursor:pointer;}
.support-viewer-stage{flex:1;min-height:0;width:100%;display:flex;align-items:center;justify-content:center;padding:64px 0 calc(env(safe-area-inset-bottom) + 24px);box-sizing:border-box;}
.support-viewer-stage img{display:block;max-width:100%;max-height:100%;object-fit:contain;}
.support-viewer-missing{font-size:var(--fs-base);color:var(--gray-400);}
.support-viewer-nav{position:absolute;top:50%;width:44px;height:44px;margin-top:-22px;display:grid;place-items:center;padding:0;border:none;border-radius:50%;background:rgba(74,74,80,.85);color:var(--gray-0);cursor:pointer;}
.support-viewer-nav.is-prev{left:8px;}
.support-viewer-nav.is-next{right:8px;}
.support-viewer-nav.is-next svg{transform:scaleX(-1);}
.support-viewer-nav:disabled{opacity:0;pointer-events:none;}


/* 성격, MBTI 고르기 슬라이더(시안 09, §screens/auth.js traitSliderRowHtml). 온보딩 한 축 화면은 패널 하나에 한 축을 담아 제목 아래 넉넉히 띄우고,
   조건 수정 목록은 줄 사이를 시안의 간격(라벨 11px, 레일 26px, 줄 사이 17px)에 맞춘다 */
.ob-trait-panel{margin:40px 2px 0;}
.ob-trait-step-note{margin:0 6px 12px;text-align:left;}
.trait-slider-list .slider-row{min-height:0;margin-bottom:17px;}
.trait-slider-list .slider-row:last-child{margin-bottom:4px;}
/* ===== 1:1 탭 (2026-10-04) ===== */
/* 헤더 오른쪽 알약 스위치(§ui/components/header.js). Bumble의 Date와 BFF 전환처럼 모드를 바꾸는 자리 */
.one-header{display:flex;align-items:center;gap:6px;}
.one-header .spacer{flex:1;}
/* 매칭, 자유 구함 스위치(34)가 로고(30)보다 높아 1:1 탭 머리만 52로 커지고 로고가 2px 내려가 탭을 옮길 때 튀었다. 위아래로 2px씩 머리 밖으로 내보내 다른 탭과 같은 48에 맞춘다 */
.one-header .one-switch{margin:-2px 0;}
.one-switch{position:relative;display:inline-grid;grid-template-columns:1fr 1fr;padding:3px;border-radius:var(--radius-full);background:var(--gray-100);}
.one-switch::before{content:"";position:absolute;top:3px;bottom:3px;left:3px;width:calc(50% - 3px);border-radius:var(--radius-full);background:var(--gray-900);transform:translateX(calc(var(--i,0) * 100%));transition:transform .26s var(--ease-smooth-out);}
.one-switch button{position:relative;z-index:1;min-width:58px;padding:7px 12px;border:0;background:none;font:inherit;font-size:var(--fs-sm);font-weight:var(--fw-bold);color:var(--text-mid);transition:color .2s ease;}
.one-switch button.is-on{color:var(--gray-0);}
.one-switch button:active{transform:scale(.95);}


/* 1:1 매칭: 홈에서 옮겨 온 오늘의 추천(§screens/matching.js) 아래 목록 머리.
   구획 제목(지금 접속 중, 오늘의 추천, 매칭 목록, 지금 올라온 글)은 홈 구획 제목과 같은 크기, 색, 왼쪽 선으로 맞춘다 */
.one-rec{margin:0 0 22px;}
:is(.one-rec,.one-list-bar,.one-sec-head) h2{margin:0;font-size:var(--fs-2xl);font-weight:var(--fw-bold);letter-spacing:var(--ls-base);color:var(--gray-800);}
.one-sec-head{margin:0 0 12px;}
.one-list-bar{display:flex;align-items:center;justify-content:space-between;margin:0 0 4px;}
/* 오늘의 추천(§ui/daily-picks-card.js, 이슈 #87, design/receive-match11 A안): 어두운 카드 안 세로 바퀴. iOS 시계 알람 휠처럼 촘촘하게, 가운데는 테두리 없는 회색 띠, 사진 테두리 없음.
   줄 자리(transform, opacity)는 JS가 style로 넣고, 옮길 때는 같은 줄의 값만 바꿔 아래 전환으로 움직인다 */
.dp-card{position:relative;margin-top:2px;padding:14px 0 12px;border-radius:var(--radius-xl);corner-shape:squircle;overflow:hidden;background:var(--gray-900);color:var(--gray-0);box-shadow:var(--shadow-pop)}
.dp-bg{position:absolute;inset:-30px;width:calc(100% + 60px);height:calc(100% + 60px);object-fit:cover;filter:grayscale(1) blur(24px) brightness(.75);transform:scale(1.15)}
.dp-shade{position:absolute;inset:0;background:linear-gradient(#00000073,#00000026 50%,#00000080)}
.dp-head{position:relative;display:flex;justify-content:space-between;align-items:baseline;padding:0 16px}
.dp-head b{font-size:var(--fs-lg);font-weight:var(--fw-bold);letter-spacing:var(--ls-base)}
.dp-head b small{margin-left:6px;font-size:var(--fs-md);font-weight:var(--fw-regular);color:#ffffff8c}
.dp-head>span{font-size:var(--fs-sm);font-variant-numeric:tabular-nums;color:#ffffff99}
.dp-wheel{position:relative;height:170px;margin-top:6px;perspective:480px;touch-action:pan-x;-webkit-mask-image:linear-gradient(#0000,#000 20%,#000 80%,#0000);mask-image:linear-gradient(#0000,#000 20%,#000 80%,#0000)}
.dp-band{position:absolute;left:8px;right:8px;top:calc(50% - 36px);height:72px;border-radius:var(--radius-sm);corner-shape:squircle;background:#ffffff1f}
.dp-row{position:absolute;left:18px;right:18px;top:calc(50% - 30px);height:60px;display:flex;align-items:center;gap:12px;transform-origin:0 50%;transition:transform .3s var(--ease-smooth-out),opacity .3s var(--ease-smooth-out)}
.dp-row:not(.is-center){cursor:pointer}
.dp-top{gap:0;font-size:var(--fs-md);color:#ffffffbf}
.dp-top b,.dp-day{font-weight:var(--fw-bold);letter-spacing:var(--ls-base)}
.dp-face{position:relative;flex:none;width:52px;height:52px;border-radius:50%;overflow:hidden;background:#000}
.dp-face .avatar{width:100%;height:100%;margin:0}
.dp-face img{width:100%;height:100%;object-fit:cover;display:block;filter:grayscale(1) contrast(1.06)}
.dp-row.is-accepted .dp-face img{filter:none}
.dp-badge{position:absolute;left:38px;top:40px;width:17px;height:17px;border-radius:50%;display:grid;place-items:center;background:var(--gray-0);color:var(--gray-900)}
.dp-text{flex:1;min-width:0;display:flex;flex-direction:column}
.dp-text b{display:flex;align-items:baseline;gap:5px;font-size:var(--fs-xl);font-weight:var(--fw-bold);letter-spacing:var(--ls-base);white-space:nowrap}
.dp-text b small{font-size:var(--fs-sm);font-weight:var(--fw-regular);color:#ffffff8c}
.dp-sub,.dp-next{margin-top:1px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;font-size:var(--fs-sm);color:#ffffffbf}
.dp-sub:empty{display:none}
.dp-text em{margin-top:2px;font-style:normal;font-size:var(--fs-xs);color:#ffffff80;white-space:pre}
.dp-text em strong{font-weight:var(--fw-bold);color:var(--gray-0)}
.dp-row.is-center .dp-next,.dp-row:not(.is-center) :is(.dp-sub,em,.dp-act){display:none}
/* 거절, 수락: 띠 안 오른쪽. 보이는 크기는 34, 누르는 영역은 44(.tap-44) */
.dp-act{flex:none;display:flex;gap:8px}
.dp-no,.dp-yes{width:34px;height:34px;border:0;border-radius:50%;display:grid;place-items:center;transition:transform .1s}
.dp-no:active,.dp-yes:active{transform:scale(.95)}
.dp-no{background:#ffffff2e;color:var(--gray-0)}
.dp-yes{background:var(--gray-0);color:var(--gray-900)}
.dp-chat{height:34px;padding:0 14px;border:0;border-radius:var(--radius-full);background:var(--gray-0);color:var(--gray-900);font:inherit;font-size:var(--fs-sm);font-weight:var(--fw-bold)}
.dp-day{position:relative;margin:14px 16px 0;font-size:var(--fs-md);color:#ffffffbf}
.dp-empty{position:relative;display:flex;align-items:center;justify-content:center;min-height:120px;padding:0 16px;font-size:var(--fs-md);color:#ffffffbf}
@media(prefers-reduced-motion:reduce){.dp-row{transition:opacity .3s var(--ease-smooth-out)}}
/* 줄글 대신 짧은 사실을 한 줄씩(쉬는 중 화면, 글쓰기 시트) */
.one-facts{display:flex;flex-direction:column;gap:6px;margin:0 0 24px;padding:0;list-style:none;font-size:var(--fs-md);color:var(--text-mid);}
.one-facts li::before{content:"";display:inline-block;width:4px;height:4px;margin:0 8px 0 0;border-radius:50%;background:var(--gray-400);vertical-align:middle;}
.one-filter-btn{position:relative;display:inline-flex;align-items:center;gap:5px;min-height:32px;padding:0 12px;border:0;border-radius:var(--radius-full);background:var(--bg2);font:inherit;font-size:var(--fs-sm);font-weight:var(--fw-bold);color:var(--gray-600);transition:transform .12s var(--ease-smooth-out);}
.one-filter-btn:active{transform:scale(.96);}
.one-filter-btn.is-on{background:var(--gray-900);color:var(--gray-0);}

/* 자유 구함(§screens/friends.js, design/freeboard-ios-mock.html, freeboard-time2-mock.html D). iOS 목록처럼 촘촘한 한 줄,
   남은 시간은 줄 오른쪽 위(iOS 메일처럼), 그 아래 채팅 알약. 글자: 이름 15 굵게, 보조 13 회색, 글 15, 안내 12. 구분선은 글이 시작하는 곳부터 */
.fb-av{display:inline-flex;align-items:center;justify-content:center;flex:0 0 auto;border-radius:50%;object-fit:cover;background:var(--gray-100);color:var(--text-light);overflow:hidden;letter-spacing:-.04em;}
.fb-av-initials{color:var(--gray-0);font-weight:var(--fw-bold);}
.fb-av-icon img{width:82%;height:82%;object-fit:contain;}
.fb-compose{display:flex;align-items:center;gap:12px;width:100%;min-height:52px;margin:0 0 18px;padding:0;border:0;background:none;font:inherit;color:inherit;text-align:left;cursor:pointer;}
.fb-compose-hint{flex:1;min-width:0;font-size:var(--fs-md);color:var(--text-light);}
.fb-compose.is-off{cursor:default;}
.fb-compose-two{flex:1;min-width:0;display:flex;flex-direction:column;gap:1px;}
.fb-compose-two b{font-size:var(--fs-md);font-weight:var(--fw-bold);color:var(--text);}
.fb-compose-two small{font-size:var(--fs-xs);color:var(--text-light);}
.fb-compose-btn{flex:none;display:inline-flex;align-items:center;height:32px;padding:0 14px;border-radius:var(--radius-full);background:var(--gray-800);color:var(--gray-0);font-size:var(--fs-sm);font-weight:var(--fw-bold);}
.fb-quota{margin:2px 0 6px 46px;font-size:var(--fs-xs);line-height:1.45;color:var(--text-light);}
.fb-head{margin:0 0 2px;}
.fb-mine-label{display:flex;align-items:baseline;gap:5px;margin:0 2px 8px;font-size:var(--fs-sm);font-weight:var(--fw-bold);}
.fb-mine-label small{font-size:var(--fs-sm);font-weight:var(--fw-regular);color:var(--text-light);}
.fb-mine-row{margin:0 0 24px;}
/* 내 글이 둘 이상이면 옆으로 넘긴다. 다음 카드가 조금 보여 넘길 수 있다는 게 드러난다 */
.fb-mine-row.is-many{display:flex;gap:10px;overflow-x:auto;scroll-snap-type:x mandatory;scrollbar-width:none;}
.fb-mine-row.is-many::-webkit-scrollbar{display:none;}
.fb-mine-row.is-many .fb-mine{flex:0 0 86%;display:flex;flex-direction:column;scroll-snap-align:start;}
.fb-mine-row.is-many .fb-mine-text{display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden;flex:1;}
.fb-group-gap{height:20px;}
.fb-mine{display:block;margin:0;padding:14px 16px;border-radius:var(--radius-lg);corner-shape:squircle;background:var(--bg2);cursor:pointer;}
.fb-mine+.fb-quota{margin-left:4px;}
.fb-mine-head{display:flex;align-items:center;gap:6px;min-width:0;}
.fb-mine-head b{font-size:var(--fs-sm);font-weight:var(--fw-bold);}
.fb-mine-head small{font-size:var(--fs-xs);color:var(--text-light);white-space:pre;}
.fb-mine-act{margin-left:auto;padding:4px 2px;border:0;background:none;font:inherit;font-size:var(--fs-sm);font-weight:var(--fw-bold);color:var(--text);cursor:pointer;}
.fb-mine-text{display:block;margin:8px 0 12px;font-size:var(--fs-md);line-height:1.45;word-break:keep-all;overflow-wrap:anywhere;}
.fb-mine-foot{display:flex;align-items:center;justify-content:space-between;}
.fb-new{display:inline-flex;align-items:center;gap:6px;font-size:var(--fs-sm);font-weight:var(--fw-bold);}
.fb-new i,.fb-dot{width:7px;height:7px;border-radius:50%;background:var(--gray-800);}
.fb-none{font-size:var(--fs-xs);color:var(--text-light);}
.fb-mine-more{display:inline-flex;align-items:center;gap:1px;font-size:var(--fs-sm);color:var(--text-mid);}
.fb-mine:active,.fb-compose:not(.is-off):active,.fb-row:active{opacity:.6;}
.fb-list{margin-top:-2px;}
.fb-row{position:relative;display:flex;align-items:center;gap:12px;width:100%;padding:13px 0;border:0;background:none;font:inherit;color:inherit;text-align:left;cursor:pointer;}
.fb-row+.fb-row::before{content:"";position:absolute;top:0;left:56px;right:0;height:1px;background:var(--border);pointer-events:none;}
.fb-row-body{flex:1;min-width:0;display:flex;flex-direction:column;gap:3px;}
.fb-name{display:flex;align-items:baseline;gap:6px;min-width:0;}
.fb-name b{font-size:var(--fs-md);font-weight:var(--fw-bold);letter-spacing:-.01em;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;}
.fb-name small{font-size:var(--fs-sm);color:var(--text-light);white-space:pre;}
.fb-name .is-soon{color:var(--text);font-weight:var(--fw-bold);}
.fb-text{font-size:var(--fs-md);line-height:1.4;color:var(--gray-600);word-break:keep-all;overflow-wrap:anywhere;display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden;}
/* 오른쪽 끝은 줄 가운데 높이에 알약 하나(대표 10/16 "가", 시안 chat-pill.html#pick), 남은 시간은 이름 줄 오른쪽 .fb-ago */
.fb-trail{flex:none;display:flex;align-items:center;padding-left:4px;}
.fb-pill{flex:none;display:inline-grid;place-items:center;min-width:60px;height:30px;padding:0 12px;box-sizing:border-box;border-radius:var(--radius-full);background:var(--gray-900);font-size:var(--fs-sm);font-weight:var(--fw-bold);color:var(--gray-0);}
.fb-pill.is-quiet{background:var(--gray-100);color:var(--text-light);}
.fb-row .fb-name .fb-ago{font-size:var(--fs-xs);}
.fb-skeleton{pointer-events:none;}.fb-skeleton .fb-av{width:44px;height:44px;}
.fb-skeleton i{display:block;height:12px;margin:5px 0;border-radius:var(--radius-2xs);background:var(--gray-100);}
.fb-skeleton i:first-child{width:40%;}
/* 시트 공통: 위 줄(취소, 제목, 버튼), 닫기 동그라미 */
.fb-nav{display:grid;grid-template-columns:1fr auto 1fr;align-items:center;min-height:40px;margin:-6px 0 6px;}
.fb-nav b{font-size:var(--fs-xl);font-weight:var(--fw-bold);}
.fb-nav-text{justify-self:start;padding:6px 0;border:0;background:none;font:inherit;font-size:var(--fs-md);color:var(--text);cursor:pointer;}
.fb-nav-btn{justify-self:end;height:32px;padding:0 14px;border:0;border-radius:var(--radius-full);background:var(--gray-800);color:var(--gray-0);font:inherit;font-size:var(--fs-sm);font-weight:var(--fw-bold);cursor:pointer;}
.fb-nav-btn:disabled{opacity:.4;}
.fb-x{justify-self:end;display:grid;place-items:center;width:30px;height:30px;border:0;border-radius:50%;background:var(--gray-100);color:var(--text-mid);cursor:pointer;}
.fb-x.is-plain{background:none;color:var(--text-light);}
/* 글쓰기 시트 */
.fb-write{display:flex;gap:12px;padding:6px 0 12px;border-bottom:1px solid var(--border);}
.fb-write-body{position:relative;flex:1;min-width:0;}
.fb-write-body b{font-size:var(--fs-md);font-weight:var(--fw-bold);}
.fb-write-input{display:block;width:100%;box-sizing:border-box;margin:2px 0 14px;padding:0;border:0;background:none;resize:none;font:inherit;font-size:17px;line-height:1.4;color:var(--text);}
.fb-write-input:focus{outline:none;}
.fb-count{position:absolute;right:0;bottom:-2px;font-size:var(--fs-xs);color:var(--text-light);}
.fb-group{padding:14px 0 2px;}
.fb-label{display:flex;justify-content:space-between;align-items:baseline;margin:0 0 8px;font-size:var(--fs-sm);font-weight:var(--fw-bold);color:var(--text-mid);}
.fb-label b{font-size:var(--fs-md);color:var(--text);}
.fb-seg{display:grid;grid-template-columns:1fr 1fr;padding:2px;border-radius:9px;background:var(--gray-100);}
.fb-seg button{height:32px;border:0;border-radius:7px;background:none;font:inherit;font-size:var(--fs-base);color:var(--text-mid);cursor:pointer;}
.fb-seg button.is-on{background:var(--bg1);color:var(--text);font-weight:var(--fw-bold);box-shadow:0 3px 8px rgba(0,0,0,.12),0 1px 1px rgba(0,0,0,.04);}
.fb-note{margin:7px 0 0;font-size:var(--fs-xs);line-height:1.45;color:var(--text-light);}
/* 올려 둘 시간(1~24시간)도 성격 패널 안의 시안 09 레일과 손잡이다(§user-controls.css .trait-panel). 눈금은 손잡이 중심이 오가는 칸(양쪽 17.5px 안쪽)에 1px로 새기고 6시간마다 길게 둔다 */
.fb-ruler-track{position:relative;height:26px;margin:0 0 16px;padding:0 3px;}
.fb-ticks{position:absolute;left:17px;right:17px;top:30px;display:flex;justify-content:space-between;align-items:flex-start;pointer-events:none;}
.fb-ticks i{flex:none;width:1px;height:3px;border-radius:.5px;background:rgb(23 24 26 / .2);}
.fb-ticks i.big{height:5px;background:rgb(23 24 26 / .42);}
.fb-range{position:relative;z-index:1;display:block;width:100%;height:44px;margin:-9px 0;background:transparent;-webkit-appearance:none;appearance:none;cursor:grab;touch-action:none;-webkit-tap-highlight-color:transparent;}
.fb-range::-webkit-slider-runnable-track{height:8px;border:0;border-radius:40px;background:linear-gradient(#b9bec1,#ededed,#afb5b9);box-shadow:inset 0 1px 3px #7e878c66,0 1px 0 rgba(255,255,255,.85);}
.fb-range::-moz-range-track{height:8px;border:0;border-radius:40px;background:linear-gradient(#b9bec1,#ededed,#afb5b9);box-shadow:inset 0 1px 3px #7e878c66,0 1px 0 rgba(255,255,255,.85);}
.fb-range::-webkit-slider-thumb{-webkit-appearance:none;appearance:none;width:27px;height:27px;margin-top:-10.5px;border-radius:50%;border:1px solid #9ba2a7;background:linear-gradient(180deg,rgba(255,255,255,.32),rgba(255,255,255,0) 48%,rgba(40,44,48,.05)),conic-gradient(from 0deg,#ddd,#aab1b4,#fefefe,#939da2,#efefef,#a3aaad,#ddd);box-shadow:inset 0 0 0 1px rgba(255,255,255,.42),0 1px 1px rgba(40,44,48,.16),0 2px 5px #66666640;}
.fb-range::-moz-range-thumb{width:27px;height:27px;border-radius:50%;border:1px solid #9ba2a7;background:linear-gradient(180deg,rgba(255,255,255,.32),rgba(255,255,255,0) 48%,rgba(40,44,48,.05)),conic-gradient(from 0deg,#ddd,#aab1b4,#fefefe,#939da2,#efefef,#a3aaad,#ddd);box-shadow:inset 0 0 0 1px rgba(255,255,255,.42),0 1px 1px rgba(40,44,48,.16),0 2px 5px #66666640;}
.fb-range:focus-visible{outline:none;}
.fb-range:focus-visible::-webkit-slider-thumb{outline:3px solid #9aaebc;outline-offset:2px;}
.fb-ruler-labels{display:flex;justify-content:space-between;margin:0 4px;font-size:var(--fs-2xs);font-weight:var(--fw-bold);color:rgb(23 24 26 / .5);}
.fb-switch-row{display:flex;align-items:center;justify-content:space-between;margin-top:12px;padding:10px 0 2px;border-top:1px solid var(--border);cursor:pointer;}
.fb-switch-row>span:first-child{display:flex;align-items:baseline;gap:8px;font-size:var(--fs-md);}
.fb-switch-row small{font-size:var(--fs-xs);color:var(--text-light);}
.fb-write-ori{margin-left:6px;font-size:var(--fs-sm);color:var(--text-light);}
.fb-dots{display:inline-flex;gap:3px;margin-right:8px;vertical-align:1px;}
.fb-dots i{width:6px;height:6px;border-radius:50%;background:var(--gray-300);}
.fb-dots i.on{background:var(--gray-800);}
.fb-sheet-foot{white-space:pre-wrap;}
.fb-sheet-foot{margin:16px -18px -20px;padding:12px 18px calc(16px + env(safe-area-inset-bottom));border-top:1px solid var(--border);background:var(--bg2);font-size:var(--fs-xs);line-height:1.5;color:var(--text-mid);text-align:center;}
/* 내 글 시트 */
.fb-mypost{padding:13px 14px;border-radius:var(--radius-sm);corner-shape:squircle;background:var(--bg2);}
.fb-mypost p{margin:7px 0 0;font-size:var(--fs-md);line-height:1.45;word-break:keep-all;overflow-wrap:anywhere;}
.fb-section{display:flex;justify-content:space-between;align-items:baseline;padding:18px 0 4px;font-size:var(--fs-sm);font-weight:var(--fw-bold);color:var(--text-mid);}
.fb-section small{font-size:var(--fs-xs);font-weight:var(--fw-regular);color:var(--text-light);}
.fb-person{position:relative;display:flex;align-items:center;gap:12px;width:100%;padding:8px 0;border:0;background:none;font:inherit;color:inherit;text-align:left;cursor:pointer;}
.fb-person-text{flex:1;min-width:0;display:flex;flex-direction:column;gap:1px;padding-right:14px;}
.fb-person-top{display:flex;justify-content:space-between;align-items:baseline;}
.fb-person-top b{font-size:var(--fs-md);font-weight:var(--fw-bold);}
.fb-person-top small{font-size:var(--fs-xs);color:var(--text-light);}
.fb-person-text>span:last-child{font-size:var(--fs-base);color:var(--text-mid);white-space:nowrap;overflow:hidden;text-overflow:ellipsis;}
.fb-person .fb-dot{position:absolute;right:0;top:50%;margin-top:6px;}
.fb-none-line{margin:4px 0;font-size:var(--fs-sm);color:var(--text-light);}
.fb-actions{display:flex;flex-direction:column;align-items:center;gap:6px;margin-top:20px;}
.fb-wide{width:100%;height:50px;border:0;border-radius:var(--radius-sm);corner-shape:squircle;background:var(--gray-100);font:inherit;font-size:var(--fs-md);font-weight:var(--fw-bold);color:var(--text);cursor:pointer;}
.fb-wide:disabled{font-size:var(--fs-sm);font-weight:var(--fw-regular);color:var(--text-light);cursor:default;}
.fb-text-btn{padding:8px 12px;border:0;background:none;font:inherit;font-size:var(--fs-sm);color:var(--text-light);cursor:pointer;}
/* 답장 칸 */
.fb-reply-head{display:flex;align-items:center;justify-content:space-between;margin:-6px 0 2px;}
.fb-reply-head b{font-size:var(--fs-sm);font-weight:var(--fw-bold);}
.fb-quote{margin:4px 0 10px;padding:2px 0 2px 10px;border-left:2px solid var(--gray-300);font-size:var(--fs-base);color:var(--text-mid);white-space:nowrap;overflow:hidden;text-overflow:ellipsis;}
.fb-input{display:flex;align-items:center;gap:8px;min-height:40px;padding:0 4px 0 14px;border:1px solid var(--border);border-radius:var(--radius-sm);corner-shape:squircle;background:var(--bg1);}
.fb-input textarea{flex:1;min-width:0;max-height:96px;padding:9px 0;border:0;background:none;resize:none;font:inherit;font-size:16px;line-height:1.4;color:var(--text);}
.fb-input textarea:focus{outline:none;}
.fb-send{display:grid;place-items:center;flex:none;width:32px;height:32px;border:0;border-radius:50%;background:var(--gray-800);color:var(--gray-0);cursor:pointer;}
.fb-send:disabled{opacity:.4;}
.fb-priv{display:flex;align-items:center;justify-content:center;gap:4px;margin:8px 0 0;font-size:var(--fs-xs);color:var(--text-light);text-align:center;}
/* 익명 글 답장 대화 화면(기다리는 중, 받은 답장). 채팅방과 같은 말풍선 */
.sheet-overlay.fb-thread-layer{padding:0;align-items:stretch;background:var(--bg1);}
.fb-thread{display:flex;flex-direction:column;width:100%;max-width:480px;height:100%;margin:0 auto;padding-top:env(safe-area-inset-top);background:var(--bg1);box-sizing:border-box;}
.fb-thread-head{display:flex;align-items:center;gap:10px;padding:8px 14px;border-bottom:1px solid var(--border);}
.fb-thread-head div{display:flex;flex-direction:column;min-width:0;}
.fb-thread-head b{font-size:var(--fs-lg);font-weight:var(--fw-bold);}
.fb-thread-head small{font-size:var(--fs-xs);color:var(--text-light);}
.fb-back{display:grid;place-items:center;width:40px;height:40px;margin-left:-8px;border:0;background:none;color:var(--text);cursor:pointer;}
.fb-thread-body{flex:1;overflow-y:auto;display:flex;flex-direction:column;gap:8px;padding:10px 14px;}
.fb-day{align-self:center;margin:4px 0;font-size:var(--fs-xs);color:var(--text-light);}
.fb-msg{display:flex;flex-direction:column;align-items:flex-start;max-width:80%;}
.fb-msg.is-mine{align-self:flex-end;align-items:flex-end;}
.fb-msg small{margin-top:3px;font-size:var(--fs-2xs);color:var(--text-light);}
.fb-bubble{padding:7px 12px;border:1px solid var(--border);border-radius:4px 16px 16px 16px;background:var(--gray-0);box-shadow:var(--shadow-sm);font-size:var(--fs-base);line-height:1.5;word-break:keep-all;overflow-wrap:anywhere;}
.fb-msg.is-mine .fb-bubble{border:0;border-radius:16px 4px 16px 16px;background:var(--gray-800);color:var(--gray-0);}
.fb-post-card{max-width:240px;padding:10px 13px 11px;border:1px solid var(--border);border-radius:4px 18px 18px 18px;background:var(--bg2);}
.fb-msg.is-mine .fb-post-card{border-radius:18px 4px 18px 18px;}
.fb-post-card span,.fb-post-msg span{display:inline-flex;align-items:center;gap:4px;font-size:var(--fs-2xs);font-weight:var(--fw-bold);color:var(--text-light);}
.fb-post-card p,.fb-post-msg p{margin:4px 0 0;font-size:var(--fs-md);font-weight:var(--fw-bold);line-height:1.4;word-break:keep-all;overflow-wrap:anywhere;}
.fb-thread-foot{padding:10px 12px calc(14px + env(safe-area-inset-bottom));}
.fb-wait{padding:6px 12px 10px;text-align:center;}
.fb-wait b{display:block;font-size:var(--fs-base);font-weight:var(--fw-bold);}
.fb-wait span{display:block;margin-top:5px;font-size:var(--fs-xs);line-height:1.55;color:var(--text-light);}
/* 채팅 목록 맨 위의 기다리는 답장(§screens/chat.js) */
.fb-pending-row .chat-room-card{width:100%;border:0;font:inherit;color:inherit;text-align:left;}
.fb-pending{font-weight:var(--fw-bold);color:var(--text);}
.fb-pending-row.is-incoming .chat-room-card{background:var(--bg2);}
.fb-stack{position:relative;flex:0 0 48px;width:48px;height:48px;}
.fb-stack .fb-av{position:absolute;box-shadow:0 0 0 2px var(--bg2);}
.fb-stack .fb-av:first-child{left:0;top:0;}.fb-stack .fb-av:nth-child(2){right:0;bottom:0;}
.fb-stack.is-one .fb-av{width:48px!important;height:48px!important;}
.fb-thread-head.is-plain{gap:6px;min-height:44px;}
.fb-thread-head.is-plain b{font-size:var(--fs-xl);}
.fb-replies{flex:1;overflow-y:auto;padding:12px 16px 24px;}
.fb-replies .fb-section{padding-top:22px;}
.fb-reply-row{position:relative;display:flex;align-items:center;gap:12px;padding:12px 0;cursor:pointer;}
.fb-reply-row+.fb-reply-row::before{content:"";position:absolute;top:0;left:60px;right:0;height:1px;background:var(--border);}
.fb-reply-row:active{opacity:.6;}
.fb-reply-body{flex:1;min-width:0;display:flex;flex-direction:column;gap:3px;}
.fb-name .fb-ago{margin-left:auto;padding-left:8px;}
.fb-reply-text{font-size:var(--fs-md);line-height:1.4;color:var(--gray-600);word-break:keep-all;overflow-wrap:anywhere;display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden;}
.fb-answer{flex:none;align-self:center;height:32px;padding:0 15px;border:0;border-radius:var(--radius-full);background:var(--gray-800);color:var(--gray-0);font:inherit;font-size:var(--fs-sm);font-weight:var(--fw-bold);cursor:pointer;}
.fb-answer:active{transform:scale(.95);}
.fb-replies-note{margin:14px 0 0;font-size:var(--fs-xs);line-height:1.5;color:var(--text-light);}
/* 민감 글(#341, 시안 sensitive-341.html?s=pick 2차): 글 자리를 연회색 판으로 덮고 그 위에 한 줄. 누르면 판이 걷히고 글이 흐림에서 또렷하게 */
.fb-cover{position:relative;display:block;margin-top:2px;border-radius:10px;corner-shape:squircle;overflow:hidden;}
.fb-cover-t{display:block;visibility:hidden;}
.fb-cover-on{position:absolute;inset:0;display:flex;align-items:center;gap:5px;padding:0 10px;background:var(--gray-100);font-size:var(--fs-sm);color:var(--text-light);}
.fb-cover-on svg{flex:none;color:var(--text-mid);}
.fb-cover-on b{font-weight:var(--fw-bold);color:var(--text-mid);}
.fb-cover-on span{margin-left:2px;}
.fb-text.is-reveal{animation:fbReveal 200ms ease-out both;}
@keyframes fbReveal{from{opacity:0;filter:blur(4px);}}
@media(prefers-reduced-motion:reduce){.fb-text.is-reveal{animation:none;}}
.fb-sens{margin-top:4px;}
/* ===== 그룹 탭 (§screens/party.js renderPartyList) ===== */
/* 둘러보기: 미팅 들어가는 줄과 분류별 가로 선반 */
@media(prefers-reduced-motion:reduce){.one-switch::before,.one-switch button,.one-filter-btn{transition:none;}}
/* 오늘의 추천 카드와 화살표를 홈 밖(1:1 탭)에서 쓸 때도 버튼 기본 모양을 지운다 */
.home-rec-card button{border:0;padding:0;font:inherit;cursor:pointer;}
.home-rec-card .heart{background:none;}

/* 메시지 탭: 전체, 1:1, 그룹 칩과 그룹 대화 줄(§screens/chat.js) */
.chat-filter-row{display:flex;gap:8px;margin:0 0 10px;}
.chat-group-card{display:flex;align-items:center;gap:12px;width:100%;border:0;background:none;text-align:left;font:inherit;color:var(--text);}
.chat-group-badge{width:48px;height:48px;flex:0 0 48px;display:flex;align-items:center;justify-content:center;border-radius:var(--radius-sm);corner-shape:squircle;background:var(--gray-900);color:var(--gray-0);font-size:var(--fs-lg);font-weight:var(--fw-bold);}
.chat-group-card .chat-room-name small{margin-left:5px;font-size:var(--fs-xs);color:var(--text-light);font-weight:var(--fw-regular);}
.chat-group-dot{width:8px;height:8px;flex:0 0 8px;border-radius:50%;background:var(--danger);}

/* ===== 알림 배지 통일(2026-10-04): 모든 안 읽음 표시는 --alert 하나. 배경색 테두리로 사진이나 아이콘과 떼어 놓는다 ===== */
.nav-orb .badge,.chat-room-bottom .badge{background:var(--alert)!important;color:#fff!important;}
.icon-btn .dot,.header-likes .dot,.party-unread-dot,.chat-group-dot{background:var(--alert)!important;}
.alert-dot{display:block;width:10px;height:10px;border-radius:50%;background:var(--alert);box-shadow:0 0 0 2px var(--bg1);}
.alert-badge{display:inline-flex;align-items:center;justify-content:center;min-width:20px;height:20px;padding:0 6px;box-sizing:border-box;border-radius:var(--radius-full);background:var(--alert);color:#fff;font-size:var(--fs-2xs);font-weight:var(--fw-bold);}
.nav-alert-dot{position:absolute;top:8px;right:calc(50% - 15px);}

/* 마이페이지 헤더 프로필 전환(§screens/mypage.js profileSwitcherHtml). 흰 패널을 띄우지 않고 헤더 줄 위에서 펼친다.
   겹친 동그라미를 누르면 얼굴이 겹친 자리에서 헤더 줄 위로 옆으로 퍼진다(오른쪽부터 40ms씩). 다 펼쳐도 왼쪽 워드마크와 겹치지 않는다(390px 기준 60px 여유).
   얼굴 칸(--k: 오른쪽부터 0, 지금 프로필이 0)은 펼친 자리가 기본이고 닫히면 겹친 자리로 당겨진다.
   지금 프로필은 테두리 대신 연한 회색 칩으로 감싼다(명도만으로 구분) */
.pf-morph{
  --pf-open-dur:300ms;--pf-close-dur:220ms;--pf-ease:cubic-bezier(0.34,1.25,0.64,1);--pf-close-ease:var(--ease-smooth-out);
  position:absolute;right:58px;top:calc(5px + env(safe-area-inset-top));z-index:60;
  width:calc(36px + (var(--stack) - 1) * 20px);height:44px;
}
.pf-morph[data-open="true"]{width:calc(var(--n) * 54px);}
.pf-morph-trigger{position:absolute;inset:0;z-index:3;border:0;background:none;padding:0;cursor:pointer;}
.pf-morph[data-open="true"] .pf-morph-trigger{pointer-events:none;}
.pf-item{
  position:absolute;top:0;right:0;width:52px;height:46px;display:flex;flex-direction:column;align-items:center;justify-content:flex-start;gap:2px;padding:2px 0 0;border:0;border-radius:var(--radius-sm);corner-shape:squircle;background:transparent;font:inherit;color:var(--text);
  transform-origin:top right;
  transform:translate(calc(var(--k) * -20px), 5px);
  transition:transform var(--pf-close-dur) var(--pf-close-ease),background-color 120ms ease;
}
.pf-morph[data-open="true"] .pf-item{
  transform:translate(calc(var(--k) * -54px), 0);
  transition:transform var(--pf-open-dur) var(--pf-ease) calc(var(--k) * 40ms),background-color 180ms ease calc(120ms + var(--k) * 40ms);
}
.pf-morph[data-open="true"] .pf-item.is-current{background:var(--gray-100);}
.pf-face{position:relative;width:30px;height:30px;flex:0 0 30px;display:flex;align-items:center;justify-content:center;border-radius:50%;box-shadow:0 0 0 2px var(--bg1);color:#fff;font-size:var(--fs-xs);font-weight:var(--fw-bold);transition:box-shadow 120ms ease;}
.pf-face img{width:100%;height:100%;border-radius:50%;object-fit:cover;}
.pf-morph[data-open="true"] .pf-face{box-shadow:none;}
.pf-face-add{background:transparent;color:var(--text-mid);border:1.5px dashed var(--gray-300);box-sizing:border-box;}
.pf-name,.pf-item-add,.pf-count{opacity:0;transition:opacity 120ms ease;}
.pf-name{max-width:48px;font-size:var(--fs-3xs);font-weight:var(--fw-bold);line-height:1.2;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;color:var(--text-mid);}
.pf-item.is-current .pf-name{color:var(--text);}
.pf-morph[data-open="true"] .pf-name,.pf-morph[data-open="true"] .pf-item-add,.pf-morph[data-open="true"] .pf-count{opacity:1;transition:opacity 180ms ease calc(80ms + var(--k) * 40ms);}
.pf-count{position:absolute;top:-5px;right:-9px;min-width:17px;height:17px;padding:0 4px;font-size:var(--fs-3xs);box-shadow:0 0 0 2px var(--bg1);}
.pf-item:active .pf-face{transform:scale(.94);}
.pf-morph-dot{position:absolute;top:4px;right:9px;z-index:4;transition:opacity 120ms ease;}
.pf-morph[data-open="true"] .pf-morph-dot{opacity:0;}
.pf-morph-backdrop{display:none;position:fixed;inset:0;z-index:59;}
.pf-morph[data-open="true"] + .pf-morph-backdrop{display:block;}
@media (prefers-reduced-motion: reduce){.pf-morph,.pf-item{transition:none !important;}}

/* 그룹 대표 이미지(§ui/components/group-cover.js). 그룹은 둥근 네모, 사람은 동그라미 */
/* 밝은 색(화이트, 스타라이트, 실버)도 바탕과 구분되게 아주 얇은 안쪽 선 */
.group-cover{display:inline-flex;flex:0 0 auto;overflow:hidden;border-radius:var(--radius-sm);corner-shape:squircle;box-shadow:inset 0 0 0 1px rgba(0,0,0,.08);}
.group-cover img{width:100%;height:100%;object-fit:cover;}
.chat-group-badge.group-cover{width:48px;height:48px;}
/* 만들기 화면의 고르기: 왼쪽 미리보기, 오른쪽 색과 사진 */
.cover-swatch{width:28px;height:28px;padding:0;border:0;border-radius:50%;box-shadow:inset 0 0 0 1px rgba(0,0,0,.1);cursor:pointer;transition:transform 120ms var(--ease-smooth-out),box-shadow 120ms ease;}
.cover-swatch.is-on{box-shadow:inset 0 0 0 1px rgba(0,0,0,.1),0 0 0 2px var(--bg1),0 0 0 4px var(--gray-900);}
.cover-swatch:active{transform:scale(.92);}
@media (prefers-reduced-motion: reduce){.cover-swatch{transition:none;}}

/* ===== 그룹 탭, 새 그룹, 그룹 상세, 접속 중 라운지 (2026-10-04, design/mono-tone-clean.md 화면 틀 규칙) ===== */
/* 분류 칩 한 줄: 고른 칩만 검정. 새 그룹 화면에서는 줄바꿈해서 쓴다 */
.group-chips{display:flex;gap:6px;margin:0 -18px 18px;padding:2px 18px;overflow-x:auto;scrollbar-width:none;}
.group-chips::-webkit-scrollbar{display:none;}
.group-chips--wrap{flex-wrap:wrap;overflow:visible;margin:0 0 4px;padding:0;}
.group-chip{flex:none;min-height:32px;padding:0 14px;border:0;border-radius:var(--radius-full);background:var(--bg2);color:var(--gray-600);font:inherit;font-size:var(--fs-md);font-weight:var(--fw-bold);transition:transform 120ms var(--ease-out);}
.group-chip.is-on{background:var(--gray-900);color:var(--gray-0);}
.group-chip:active{transform:scale(.95);}
.group-sec{display:flex;align-items:baseline;justify-content:space-between;gap:10px;margin:6px 2px 10px;}
.group-sec h2{margin:0;font-size:var(--fs-lg);font-weight:var(--fw-bold);}
.group-sec h2 small{margin-left:6px;font-size:var(--fs-md);font-weight:var(--fw-regular);color:var(--text-light);}
.group-sec-note,.group-sort-btn{font-size:var(--fs-sm);color:var(--text-mid);}
.group-sort-btn{min-height:44px;margin:-14px -6px -14px 0;padding:0 6px;border:0;background:none;font:inherit;font-size:var(--fs-sm);}
.group-return{display:flex;align-items:center;justify-content:space-between;width:100%;min-height:52px;margin:0 0 18px;padding:0 16px;border:0;border-radius:var(--radius);corner-shape:squircle;background:var(--gray-900);color:var(--gray-0);font:inherit;font-size:var(--fs-base);font-weight:var(--fw-bold);}
.group-return span:last-child{display:inline-flex;align-items:center;gap:2px;font-size:var(--fs-sm);opacity:.75;}
/* 모집 중인 미팅: 가로로 넘기는 카드. 다음 카드가 살짝 보여 넘길 수 있다는 게 보인다 */
.meet-strip{display:flex;gap:10px;margin:0 -18px 22px;padding:0 18px 2px;overflow-x:auto;scroll-snap-type:x mandatory;scrollbar-width:none;}
.meet-strip::-webkit-scrollbar{display:none;}
.meet-card{flex:0 0 236px;scroll-snap-align:start;display:flex;flex-direction:column;gap:8px;padding:14px;border-radius:var(--radius);corner-shape:squircle;background:var(--bg2);}
.meet-card.is-full{opacity:.5;}
.meet-card-top{display:flex;align-items:center;gap:10px;min-width:0;}
.meet-card-top b{font-size:var(--fs-lg);font-weight:var(--fw-bold);white-space:nowrap;overflow:hidden;text-overflow:ellipsis;}
.meet-card-cover{width:36px;height:36px;border-radius:var(--radius-xs);}
.meet-card-slots{font-size:var(--fs-sm);color:var(--text-mid);}
.meet-card-foot{display:flex;align-items:center;justify-content:space-between;gap:8px;font-size:var(--fs-sm);color:var(--text-mid);}
.meet-card-foot b{color:var(--gray-900);font-weight:var(--fw-bold);}
.meet-card-join{flex:none;min-height:34px;padding:0 14px;border:0;border-radius:var(--radius-full);background:var(--gray-900);color:var(--gray-0);font:inherit;font-size:var(--fs-sm);font-weight:var(--fw-bold);}
.meet-card-join:disabled{background:var(--gray-200);color:var(--text-light);}
/* 모집 중인 그룹: 한 줄 목록(대표 이미지, 이름, 분류와 인원과 기간) */
.grow-list{display:flex;flex-direction:column;margin:0 -6px 14px;}
.grow{display:flex;align-items:center;gap:14px;width:100%;padding:10px 6px;border:0;border-radius:var(--radius-sm);background:none;text-align:left;font:inherit;color:inherit;transition:transform 120ms var(--ease-out);}
.grow:active{transform:scale(.98);background:var(--bg2);}
.grow.is-full{opacity:.42;}
.grow-cover{width:52px;height:52px;}
.grow-text{display:flex;flex-direction:column;gap:3px;flex:1;min-width:0;}
.grow-title{font-size:var(--fs-lg);font-weight:var(--fw-bold);white-space:nowrap;overflow:hidden;text-overflow:ellipsis;}
.grow-meta{font-size:var(--fs-md);color:var(--text-mid);white-space:nowrap;overflow:hidden;text-overflow:ellipsis;}
.grow-tag{flex:none;padding:5px 9px;border-radius:var(--radius-full);background:var(--gray-100);color:var(--gray-900);font-size:var(--fs-sm);font-weight:var(--fw-bold);}
/* + 시트: 그룹과 미팅 중 고르기 */
.create-opt{display:flex;align-items:center;gap:14px;width:100%;margin:0 0 8px;padding:16px;border:0;border-radius:var(--radius);corner-shape:squircle;background:var(--bg2);text-align:left;font:inherit;color:inherit;transition:transform 120ms var(--ease-out);}
.create-opt:active{transform:scale(.98);}
.create-opt-ic{flex:none;width:44px;height:44px;display:grid;place-items:center;border-radius:var(--radius-sm);corner-shape:squircle;background:var(--gray-0);}
.create-opt b{display:block;font-size:var(--fs-xl);font-weight:var(--fw-bold);}
.create-opt small{display:block;margin-top:3px;font-size:var(--fs-md);color:var(--text-mid);}
/* 새 그룹, 새 미팅 맨 위: 대표 이미지와 이름 한 줄, 그 아래 색 */
.gid{margin:4px 0 6px;}
.gid-row{display:flex;align-items:center;gap:14px;}
.gid-cover{position:relative;flex:none;cursor:pointer;}
.gid-cover input{display:none;}
.gid-cover-img{width:76px;height:76px;border-radius:var(--radius-lg);}
.gid-empty{background:var(--bg2);box-shadow:inset 0 0 0 1.5px var(--gray-300);}
.gid-cam{position:absolute;right:-4px;bottom:-4px;width:28px;height:28px;display:grid;place-items:center;border-radius:50%;background:var(--gray-0);color:var(--gray-900);box-shadow:var(--shadow-sm);}
.gid-input{flex:1;min-width:0;display:flex;flex-direction:column;gap:4px;}
.party-form input.gid-name{width:100%;padding:10px 0;border:0;border-bottom:1.5px solid var(--border);border-radius:0;background:none;font-size:var(--fs-4xl);font-weight:var(--fw-bold);}
.party-form input.gid-name:focus{border-color:var(--gray-900);outline:none;}
.gid-fixed{font-size:var(--fs-4xl);font-weight:var(--fw-bold);}
.gid-hint{font-size:var(--fs-md);color:var(--text-mid);}
.gid-swatches{display:flex;flex-wrap:wrap;gap:10px;margin-top:16px;}
.form-label{display:block;margin:24px 0 10px;font-size:var(--fs-md);font-weight:var(--fw-bold);color:var(--text-mid);}
.form-label small{font-weight:var(--fw-regular);color:var(--text-light);}
.party-form textarea.form-field{width:100%;padding:14px 16px;border:0;border-radius:var(--radius-sm);corner-shape:squircle;background:var(--bg2);font-size:var(--fs-xl);}
.form-line{display:flex;align-items:center;justify-content:space-between;gap:10px;min-height:56px;border-bottom:1px solid var(--gray-100);font-size:var(--fs-xl);}
.form-step{display:inline-flex;align-items:center;gap:14px;}
.form-step b{min-width:44px;text-align:center;font-weight:var(--fw-bold);}
.form-step button{width:36px;height:36px;display:grid;place-items:center;padding:0;border:0;border-radius:50%;background:var(--bg2);color:var(--gray-900);}
.form-step button:disabled{color:var(--gray-300);}
.form-note{margin:10px 0 0;font-size:var(--fs-sm);line-height:1.5;color:var(--text-light);}
.form-error{margin:0 0 8px;text-align:center;font-size:var(--fs-sm);color:var(--text-mid);}
/* 만들기와 상세의 아래 고정 버튼. 스크롤해도 화면 아래에 붙어 있다 */
.modal-cta{position:sticky;bottom:calc(-96px - env(safe-area-inset-bottom));z-index:2;margin:20px -18px 0;padding:14px 18px calc(18px + env(safe-area-inset-bottom));background:linear-gradient(to top,var(--bg1) 72%,transparent);}
.modal-cta .btn{margin:0;}
.modal-cta .btn+.btn{margin-top:6px;}
/* 그룹 상세 */
.pd-hero{display:flex;align-items:center;gap:16px;margin:2px 0 4px;}
.pd-cover{width:72px;height:72px;border-radius:var(--radius-lg);}
.pd-title{margin:0;font-size:var(--fs-4xl);font-weight:var(--fw-bold);letter-spacing:-.01em;line-height:1.3;word-break:keep-all;}
.pd-meta{margin:4px 0 0;font-size:var(--fs-md);color:var(--text-mid);}
.pd-desc{margin:16px 0 0;font-size:var(--fs-xl);line-height:1.6;color:var(--gray-700);white-space:pre-wrap;word-break:keep-all;}
/* 인원, 기간 칸과 참여 조건 꼬리표(#86 31-B)를 한 회색 카드에 */
.pd-facts-card{margin:18px 0 0;border-radius:var(--radius);corner-shape:squircle;background:var(--bg2);}
.pd-facts{display:grid;grid-template-columns:1fr 1fr;}
.pd-facts div{padding:14px 0;text-align:center;}
.pd-facts b{display:block;font-size:var(--fs-2xl);font-weight:var(--fw-bold);}
.pd-facts span{font-size:var(--fs-sm);color:var(--text-mid);}
.pd-req{margin:0 14px;padding:12px 0 14px;border-top:1px solid var(--border);}
.pd-req small{display:block;margin-bottom:8px;font-size:var(--fs-xs);color:var(--text-mid);}
.pd-req-tags{display:flex;flex-wrap:wrap;gap:6px;}
.pd-req-tags span{padding:5px 10px;border-radius:var(--radius-full);background:var(--gray-0);font-size:var(--fs-sm);color:var(--text);}
.pd-sec{margin:26px 2px 8px;font-size:var(--fs-lg);font-weight:var(--fw-bold);}
.pd-sec small{margin-left:6px;font-weight:var(--fw-regular);color:var(--text-light);}
.pd-member{display:flex;align-items:center;gap:12px;padding:8px 2px;}
.pd-member .party-member-photo{width:40px;height:40px;}
.pd-member-name{flex:1;min-width:0;font-size:var(--fs-xl);font-weight:var(--fw-bold);}
.pd-member-name small{font-size:var(--fs-sm);font-weight:var(--fw-regular);color:var(--text-light);}
.pd-member-role{font-size:var(--fs-md);color:var(--text-mid);}
/* 접속 중 라운지: 머리와 "방금 들어온 사람" 줄은 고정, 그 아래 구름만 스크롤 */
.online-top{flex:none;padding:4px 18px 0;}
.online-top .subhead{margin-bottom:6px;}
.online-top .online-count{display:inline-flex;}
/* 새로 접속한 사람의 물결(ui/profile-cloud.js is-arrived) */
.cloud-profile.is-arrived::after{content:"";position:absolute;inset:-4px;border-radius:50%;border:2px solid var(--gray-900);pointer-events:none;animation:arrivalRipple 800ms var(--ease-out) 2;}
@keyframes arrivalRipple{from{opacity:.55;transform:scale(.96);}to{opacity:0;transform:scale(1.35);}}
@media(prefers-reduced-motion:reduce){

  .cloud-profile.is-arrived::after{animation:none;opacity:.35;transform:none;}
  .group-chip,.grow,.create-opt{transition:none;}
}

/* 하위 화면에서는 하단 탭을 숨긴다(§screens/app-shell.js renderBottomNav). 탭 첫 화면으로 돌아오면 다시 올라온다 */
.bottom-nav{transition:transform var(--duration-fast) var(--ease-drawer),opacity var(--duration-fast) var(--ease-smooth-out);}
.bottom-nav.nav-hidden{transform:translate(-50%,calc(100% + 24px + env(safe-area-inset-bottom)));opacity:0;pointer-events:none;}
.main:has(~ .bottom-nav.nav-hidden){padding-bottom:calc(28px + env(safe-area-inset-bottom));}
.main:has(~ .bottom-nav.nav-hidden) .modal-cta{bottom:calc(-28px - env(safe-area-inset-bottom));}
@media(prefers-reduced-motion:reduce){.bottom-nav{transition:opacity var(--duration-quick) var(--ease-smooth-out);}}
/* 접속 중 맨 아래: 구경에서 끝나지 않게 지인 글쓰기로 잇는 버튼 */
.online-cta{position:absolute;left:50%;bottom:calc(22px + env(safe-area-inset-bottom));z-index:3;transform:translateX(-50%);display:inline-flex;align-items:center;gap:8px;min-height:50px;padding:0 22px;border:0;border-radius:var(--radius-full);background:var(--gray-900);color:var(--gray-0);font:inherit;font-size:var(--fs-lg);font-weight:var(--fw-bold);box-shadow:var(--shadow-pop);white-space:nowrap;transition:transform 120ms var(--ease-out);}
.online-cta:active{transform:translateX(-50%) scale(.96);}
@media(prefers-reduced-motion:reduce){.online-cta{transition:none;}}

/* 화면별 뼈대(ui/components/state-view.js skeletonHtml). 실제 줄과 같은 크기와 여백, 같은 반짝임 */
.sk{display:block;height:14px;border-radius:var(--radius-full);background:linear-gradient(90deg,var(--gray-100) 25%,var(--gray-200) 37%,var(--gray-100) 63%);background-size:400% 100%;animation:skeletonShimmer 1.4s linear infinite;}
.sk-thin{height:11px;}.sk-tall{height:20px;}.sk-para{height:13px;margin:12px 0 0;}
.sk-w18{width:18px;flex:none;}.sk-w80px{width:80px;flex:none;}.sk-w28{width:28px;flex:none;}.sk-w40px{width:40px;flex:none;}
.sk-w40{width:40%;}.sk-w55{width:55%;}.sk-w70{width:70%;}.sk-w90{width:90%;}
.sk-circle{border-radius:50%;flex:none;}.sk-square{flex:none;border-radius:var(--radius-sm);}
.sk-28{width:28px;height:28px;}.sk-32{width:32px;height:32px;}.sk-36{width:36px;height:36px;}.sk-44{width:44px;height:44px;}.sk-48{width:48px;height:48px;}.sk-52{width:52px;height:52px;}.sk-72{width:72px;height:72px;border-radius:var(--radius-lg);}
.sk-lines{flex:1;min-width:0;display:flex;flex-direction:column;gap:8px;}
.sk-row{display:flex;align-items:center;gap:12px;}
.sk-list :is(.chat-room-card,.match-card){cursor:default;}
.sk-dot{height:8px;}.sk-filter{width:66px;height:30px;border-radius:var(--radius-xs);}
.sk-chip{width:68px;height:22px;border-radius:var(--radius-full);}
.sk-rec{height:174px;margin-top:10px;border-radius:var(--radius-xl);corner-shape:squircle;}
.sk-row--group{gap:14px;padding:10px 0;}
.sk-row--rank{padding:14px 0;border-bottom:1px solid var(--border);}
.sk-strip{display:flex;gap:10px;margin:0 -18px 22px;padding:0 18px;overflow:hidden;}
.sk-meet{flex:0 0 236px;display:flex;flex-direction:column;gap:10px;padding:16px 14px;border-radius:var(--radius);background:var(--bg2);}
.sk-meet .sk{background:var(--gray-100);animation:none;}
.sk-hero{display:flex;align-items:center;gap:16px;margin:2px 0 6px;}
.sk-box{height:72px;margin:18px 0 22px;border-radius:var(--radius);background:var(--bg2);}
.sk-bubble{display:flex;align-items:flex-end;gap:8px;margin:0 0 12px;}
.sk-bubble--me{justify-content:flex-end;}
.sk-pill{height:38px;border-radius:18px;}
.sk-b0{width:52%;}.sk-b1{width:38%;}.sk-b2{width:64%;}.sk-b3{width:44%;}
.chat-room-name .sk{display:inline-block;vertical-align:middle;}
.chat-loading{padding:12px 0 0;}
.sk-cloud{position:relative;height:380px;}
.sk-cloud .sk{position:absolute;transform:translate(-50%,-50%);}
@media(prefers-reduced-motion:reduce){.sk{animation:none;}}
/* 아래 고정 버튼이 있는 화면은 내용이 짧아도 버튼이 화면 맨 아래에 온다 */
.main:has(> .modal-cta){display:flex;flex-direction:column;}
.main:has(> .modal-cta) > .modal-cta{margin-top:auto;}
/* 신고 칸(§screens/mypage.js renderSupportWrite). 담아 둔 신고 대상을 고르는 카드 목록, 이전 신고 안내, 관리자 열람 안내.
   고른 카드는 색이 아니라 굵은 테두리와 채운 동그라미로 구분한다(design/mono-tone-clean.md 명도 대비 원칙) */
.blocked-actions{display:flex;gap:6px;flex-shrink:0;}

/* 새 단체 화면 묶음 카드(#86, 결정 30-B, 시안 party-polish-1 후): 회색 바탕 위 흰 둥근 카드, 줄 높이 48, 줄 사이 선은 글자 시작부터 */
.main:has(> .pf-page),.main:has(.party-form.pf-page){background:var(--gray-100);}
.pf-page textarea.form-field{background:var(--gray-0);}
.pf-card{background:var(--gray-0);border-radius:14px;corner-shape:squircle;overflow:hidden;}
.pf-card+.pf-card{margin-top:12px;}
.pf-row{position:relative;display:flex;align-items:center;justify-content:space-between;gap:10px;width:100%;min-height:48px;padding:0 14px;box-sizing:border-box;border:0;background:none;font:inherit;font-size:var(--fs-lg);color:var(--text);text-align:left;cursor:default;}
button.pf-row{cursor:pointer;}
.pf-row+.pf-row::before{content:"";position:absolute;top:0;left:14px;right:0;height:1px;background:var(--gray-100);}
.pf-row-col{flex-direction:column;align-items:stretch;gap:10px;padding:12px 14px;}
.pf-row-head{display:flex;justify-content:space-between;align-items:center;}
.pf-row-head b,.pf-value{font-weight:var(--fw-regular);color:var(--text-mid);}
.pf-value{display:inline-flex;align-items:center;gap:4px;min-width:0;max-width:60%;font-size:var(--fs-md);white-space:nowrap;overflow:hidden;text-overflow:ellipsis;}
.pf-seg{display:flex;padding:3px;border-radius:10px;background:var(--gray-100);}
.pf-seg-btn{flex:1;height:32px;border:0;border-radius:8px;background:none;font:inherit;font-size:var(--fs-md);color:var(--text-mid);cursor:pointer;}
.pf-seg-btn.is-on{background:var(--gray-0);color:var(--text);font-weight:var(--fw-bold);box-shadow:0 1px 3px rgba(0,0,0,.08);}
.party-form .pf-input{flex:1;min-width:0;padding:0;border:0;border-radius:0;background:none;font-size:var(--fs-lg);}
.party-form .pf-input:focus{outline:none;}
.pf-x{flex:none;display:grid;place-items:center;width:22px;height:22px;padding:0;border:0;border-radius:50%;background:var(--gray-100);color:var(--text-mid);cursor:pointer;}
.pf-add span{display:inline-flex;align-items:center;gap:6px;color:var(--text-mid);}
.pf-cond{padding:12px 16px 24px;}
/* 단체 상세 아래 버튼 위 한 줄과 "신청함" 꼬리표(#86 3.2) */
.pd-cta-note{display:flex;align-items:center;justify-content:center;gap:8px;margin:0 0 10px;font-size:var(--fs-sm);color:var(--text-mid);text-align:center;}
.pd-chip{padding:3px 9px;border-radius:var(--radius-full);background:var(--gray-100);font-size:var(--fs-xs);font-weight:var(--fw-bold);color:var(--text);}
.btn.btn-gray{background:var(--gray-100);color:var(--text);}
/* 신청 시트의 가입 질문과 답(#86 3.7, 시안 party-conditions-3): 질문은 작게, 답 칸은 회색 칸 */
.persona-qa{display:flex;flex-direction:column;gap:8px;width:100%;margin-top:10px;}
.persona-q{display:flex;flex-direction:column;gap:2px;padding:10px 14px;border-radius:12px;background:var(--gray-100);}
.persona-q small{font-size:var(--fs-xs);color:var(--text-mid);}
.persona-q input{width:100%;padding:0;border:0;background:none;font:inherit;font-size:var(--fs-lg);color:var(--text);}
.persona-q:focus-within{box-shadow:0 0 0 1.5px var(--gray-900);background:var(--gray-0);}
.persona-q input:focus{outline:none;}
.grow-tag.is-line{background:none;box-shadow:inset 0 0 0 1px var(--border);color:var(--text-mid);font-weight:var(--fw-regular);}
/* 방장 참여 신청 화면(#86 3.3, 시안 party-conditions-5 가) */
.pr-page{background:var(--bg1);}
.pr-head{display:flex;align-items:center;gap:6px;padding:calc(10px + env(safe-area-inset-top)) 10px 8px;}
.pr-head b{font-size:var(--fs-xl);}
.pr-list{display:flex;flex-direction:column;}
.pr-row{position:relative;display:flex;align-items:flex-start;gap:8px;padding:12px 16px;}
.pr-row+.pr-row::before{content:"";position:absolute;top:0;left:66px;right:0;height:1px;background:var(--gray-100);}
.pr-main{flex:1;min-width:0;display:flex;gap:12px;padding:0;border:0;background:none;font:inherit;color:inherit;text-align:left;cursor:pointer;}
.pr-face{flex:none;width:40px;height:40px;border-radius:50%;overflow:hidden;background:var(--gray-200);}
.pr-face img{width:100%;height:100%;object-fit:cover;}
.pr-mono{display:grid;place-items:center;color:var(--gray-0);font-weight:var(--fw-bold);}
.pr-text{display:flex;flex-direction:column;gap:2px;min-width:0;}
.pr-text b{display:flex;align-items:center;gap:6px;font-size:var(--fs-lg);}
.pr-text small{font-size:var(--fs-xs);color:var(--text-mid);}
.pr-q{margin-top:4px;font-size:var(--fs-2xs);color:var(--text-light);}
.pr-a{font-size:var(--fs-md);color:var(--text);overflow:hidden;text-overflow:ellipsis;white-space:nowrap;}
.pr-dup{padding:2px 7px;border-radius:var(--radius-full);background:var(--gray-900);color:var(--gray-0);font-size:var(--fs-2xs);font-weight:var(--fw-bold);}
.pr-pick{flex:none;display:grid;place-items:center;width:24px;height:24px;margin-top:8px;padding:0;border:1.5px solid var(--gray-300);border-radius:50%;background:none;color:transparent;cursor:pointer;}
.pr-pick.is-on{border-color:var(--gray-900);background:var(--gray-900);color:var(--gray-0);}
.pr-foot{position:sticky;bottom:0;padding:10px 16px calc(12px + env(safe-area-inset-bottom));background:linear-gradient(transparent,var(--bg1) 24%);}
.pr-why{margin:0 0 8px;text-align:center;font-size:var(--fs-sm);color:var(--text-mid);}
.pr-empty{padding:48px 16px;text-align:center;font-weight:var(--fw-bold);color:var(--text);}
.pr-sheet-top{display:flex;align-items:center;justify-content:space-between;margin-bottom:10px;}
.pr-sheet-top b{font-size:var(--fs-xl);}
.persona-q span{font-size:var(--fs-md);color:var(--text);white-space:pre-wrap;word-break:break-word;}
/* 정기 미팅 꼬리표(#257, 결정 85) */
.meet-official{flex:none;padding:2px 7px;border-radius:var(--radius-full);background:var(--gray-900);color:var(--gray-0);font-size:var(--fs-2xs);font-weight:var(--fw-bold);line-height:1.4;}
.meet-card.is-preview .meet-card-join{background:var(--gray-100);color:var(--text-mid);}
/* 정기 미팅 대화 AI 활용 동의 시트(#265, §actions/meeting.js openMeetingAiConsent) */
.consent-lines{margin:10px 0 8px;padding-left:18px;display:flex;flex-direction:column;gap:6px;font-size:var(--fs-md);line-height:1.5;color:var(--text-mid);}
.consent-actions{display:flex;gap:8px;margin-top:14px;}
.consent-actions .btn{flex:1;}
/* 잠긴 프로필 꼬리표(이슈 #305): 이름 아래 작은 글씨 */
.pf-lock{display:block;font-size:var(--fs-3xs);font-weight:var(--fw-bold);color:var(--text-light);}

/* #347 그룹 거르기와 대상 그룹(시안 claude/design-group-347 party-group-347.html MOCK_CSS 그대로) */
.grow.is-off{pointer-events:none;}
.grow.is-off>.group-cover,.grow.is-off .grow-title,.grow.is-off .grow-meta{opacity:.42;}
.grow-why{align-self:flex-start;margin-top:3px;padding:3px 8px;border-radius:var(--radius-full);background:var(--gray-100);color:var(--gray-700);font-size:var(--fs-xs);font-weight:var(--fw-bold);}
.gc-pick{display:inline-flex;align-items:center;gap:3px;padding:0 10px 0 14px;}
.gc-bar{flex:none;width:1px;height:18px;align-self:center;margin:0 2px;background:var(--gray-200);}
.gs-head{display:flex;align-items:baseline;justify-content:space-between;}
.gs-count{font-size:var(--fs-md);color:var(--text-mid);}
.gs-label{margin:6px 0 8px;font-size:var(--fs-sm);color:var(--text-mid);}
.chip:disabled{opacity:.35;}
/* 같이 하기(§actions/duo-games.js, duo-duel.js). 2026-10-07 사용자가 고른 C-2 시안: 게임 그림에서 뽑은 옅은 바탕(--game-bg, config의 bg),
   흰 카드, 검은 글자와 검은 주 버튼. 대기실은 위에 게임 그림(--art)을 옅게 깔고 왼쪽 정렬 제목. 방 화면은 위 줄(✕, 남은 시간 알약, 버튼),
   머리말과 큰 제목(hud), 판(스크롤), 아래 자리(채팅 말풍선, 주요 버튼이나 도구, 입력칸). 큰 제목은 게임 화면이라 800 굵기를 쓴다(시안 그대로).
   레퍼런스: 애플 게임 도전 만들기, NYT 게임, 애플 게임 도전 화면, Abode 게임, Freeform 도구막대, 텔레그램 투표 */
.duo,.duo-page,.duo-sheet.is-art{isolation:isolate;overflow:hidden;color:var(--text);background:var(--game-bg,#f4f1ea);}
/* 2026-10-07 V1(Clucky, Brilliant): 누를 곳과 고른 것만 게임 강조색(--accent, config의 accent), 보조는 그 색을 옅게(--accent-soft) */
.duo,.duo-page,.duo-sheet{--accent-ink:color-mix(in srgb,var(--accent,var(--gray-900)) 78%,#000);--accent-soft:color-mix(in srgb,var(--accent,var(--gray-900)) 12%,#fff);}
.duo{position:fixed;inset:0;z-index:900;display:flex;flex-direction:column;height:100dvh;padding:calc(env(safe-area-inset-top) + 6px) 0 env(safe-area-inset-bottom);opacity:0;transform:scale(.98);transition:opacity .25s var(--ease-smooth-out),transform .25s var(--ease-smooth-out);}
.duo.is-open{opacity:1;transform:none;}
/* 폰 비율 맞추기(§actions/duo-games.js fitHeight가 --duo-h에 화면 높이를 넣는다. 390x844가 기준).
   --lm은 대기실 제목 위 그림 칸 높이(844에서 183px, 짧은 폰은 그 절반 비율로만 줄여 갤럭시처럼 아래 버튼 줄이 있는 폰도 그림이 남는다, 긴 폰은 늘린다), --ak는 그 안 그림 배율(버튼과 제목 사이 빈 칸에 비례) */
.duo{--fh:var(--duo-h,844);--lmn:clamp(40,max(var(--fh) - 661,var(--fh) / 2 - 239),270);--lm:calc(var(--lmn) * 1px);--ak:clamp(.2,(var(--lmn) - 25) / 158,1.3);}
body:has(.duo) .toast-wrap{z-index:950;}
:is(.duo,.duo-page) .gp-btn{width:44px;height:44px;color:var(--gray-900);background:rgba(255,255,255,.72);}
.duo-bar{flex:none;display:flex;align-items:center;gap:8px;min-height:56px;padding:0 16px;}
.duo-timer{margin-left:auto;display:inline-flex;align-items:center;gap:6px;height:36px;padding:0 14px;border-radius:var(--radius-full);background:var(--accent-soft);color:var(--accent-ink);font-size:var(--fs-xl);font-weight:var(--fw-bold);font-variant-numeric:tabular-nums;transition:background .2s,color .2s;}
.duo-timer[hidden]{display:none;}
.duo-timer.is-low{background:#e5484d;color:#fff;}
.duo-bar-r{margin-left:auto;display:flex;gap:8px;}
.duo-timer:not([hidden]) + .duo-bar-r{margin-left:0;}
.duo-hud{flex:none;margin-top:24px;padding:4px 20px 14px;}
/* 2026-10-08 네 게임 게임·결과 화면 제목 높이 맞춤: 게임 화면 제목은 위에서 107px, 결과 화면 큰 제목은 231px.
   머리말이 없는 화면도 한 줄을 비워 제목이 위로 붙지 않는다 */
.duo-hud[hidden]{display:none;}
.duo-status{display:block;font-size:var(--fs-md);font-weight:var(--fw-bold);color:var(--text-mid);}
.duo-status:empty{display:none;}
/* 낙서 릴레이 쓰기·보고 쓰기: 안내 카드 없이 입력칸과 그림이 주인공. 위 한 줄(duo-cap)만 */
.duo-cap{flex:none;margin:0 4px;font-size:var(--fs-sm);font-weight:800;color:rgba(255,255,255,.9);}
.duo[data-stage="write"] .duo-body,.duo[data-stage="guess"] .duo-body{padding-top:12px;}
.duo[data-stage="write"] .duo-text{flex:1;min-height:200px;padding:22px;font-size:26px;}
.duo[data-stage="guess"] .duo-prev{width:100%;max-width:none;aspect-ratio:1;object-fit:contain;}
.duo[data-stage="guess"] .duo-text{margin-top:auto;}
/* 채팅 버튼(채팅칸이 없는 게임 화면)과 시트 */
.duo-chat-btn{position:relative;}
.duo-unread{position:absolute;top:6px;right:6px;width:9px;height:9px;border-radius:50%;background:#e5484d;box-shadow:0 0 0 2px #fff;}

/* 그림 맞히기 고르기: 직접 쓰는 칸이 먼저(크게), 예시 낱말은 그 아래 칩. 남는 높이 가운데에 */
.duo-pick{flex:1;display:flex;flex-direction:column;justify-content:center;gap:12px;min-height:0;}
.duo-own input{height:56px;font-size:var(--fs-xl);font-weight:var(--fw-bold);}
.duo-own .duo-send{width:56px;height:56px;}
.duo-own-or{margin:4px 4px 0;font-size:var(--fs-sm);color:var(--text-mid);}
[data-game="draw"] .duo-idea{height:44px;padding:0 16px;border:none;background:#fff;color:#2b2b2b;box-shadow:0 3px 0 var(--key);}
.duo-name{display:block;margin-top:2px;font-size:30px;font-weight:800;letter-spacing:-.035em;line-height:1.15;word-break:keep-all;overflow-wrap:anywhere;}
.duo-hud.is-long .duo-name{font-size:var(--fs-5xl);line-height:1.3;}
/* 정답 빈칸은 낱말마다 묶음(span), 묶음 사이는 띄어쓰기만큼 벌린다. 긴 속담은 묶음째 다음 줄로 */
.duo-blanks{display:inline-flex;flex-wrap:wrap;gap:8px 22px;padding:14px 0 8px;}
.duo-blanks span{display:inline-flex;gap:8px;}
.duo-blanks i{width:22px;height:4px;border-radius:2px;background:var(--gray-800);}
.duo-body{flex:1;min-height:0;overflow-y:auto;padding:0 16px 12px;display:flex;flex-direction:column;gap:12px;}
/* 아래 자리. 채팅이 아직 없어 칸이 비면 입력칸은 아래 끝에 */
.duo-dock{flex:none;display:flex;flex-direction:column;justify-content:flex-end;gap:8px;padding:0 16px 10px;}

.duo-act{display:flex;flex-direction:column;gap:8px;}
.duo-act:empty{display:none;}
.duo-log{max-height:clamp(96px,var(--fh) * 1px - 720px,240px);overflow-y:auto;display:flex;flex-direction:column;align-items:flex-start;gap:5px;padding:8px 0 4px;-webkit-mask-image:linear-gradient(transparent,#000 24px);mask-image:linear-gradient(transparent,#000 24px);scrollbar-width:none;}
.duo-log:empty,.duo-log[hidden]{display:none;}
.duo-msg{flex:none;margin:0;max-width:86%;padding:7px 12px;border-radius:14px;background:#fff;box-shadow:0 1px 2px rgba(0,0,0,.05);font-size:var(--fs-base);line-height:1.4;word-break:break-word;}
.duo-msg b{margin-right:6px;font-weight:var(--fw-bold);color:var(--text-mid);}
.duo-msg.is-ok{display:flex;align-items:center;gap:4px;background:#30a46c;color:#fff;font-weight:var(--fw-bold);}
.duo-msg.is-secret{opacity:.6;}
/* 거의 맞힌 답(쓴 사람에게만)과 넘기기 투표 같은 알림 줄 */
.duo-msg.is-near{background:#fce8a8;font-weight:var(--fw-bold);}
.duo-msg.is-note{padding:2px 4px;background:none;box-shadow:none;color:var(--text-mid);font-size:var(--fs-sm);}
button.duo-chip{border:none;color:inherit;}
/* 이야기가 주인공인 단계(스파이 찾기): 판은 줄이고 채팅을 크게 */
/* 채팅이 보이는 화면: 판은 내용만큼, 남는 자리는 전부 채팅이 채우고 넘치면 스크롤. 자리가 모자라면 판(그림판은 160px까지)이 먼저 줄고 채팅은 두 줄 높이를 남긴다 */
:where(.duo:has(.duo-dock > .duo-log:not([hidden]))) .duo-body{flex:0 1 auto;}
:where(.duo:has(.duo-dock > .duo-log:not([hidden]))) .duo-body .duo-stage{flex:0 1 auto;height:calc(100vw - 32px);}
:where(.duo:has(.duo-dock > .duo-log:not([hidden]))) .duo-dock{flex:1 1 0;}
:where(.duo) .duo-dock > .duo-log{flex:1 1 0;height:0;min-height:72px;max-height:none;}
.duo-log > :first-child{margin-top:auto;}
.duo.is-chatty .duo-body{flex:none;max-height:40%;}
.duo.is-chatty .duo-dock{flex:1;min-height:0;}
.duo-input{display:flex;gap:8px;}
.duo-input[hidden]{display:none;}
.duo-input input{flex:1;min-width:0;height:48px;padding:0 18px;border:none;border-radius:var(--radius-full);background:#fff;box-shadow:0 1px 2px rgba(0,0,0,.05);color:var(--text);font-size:16px;}
.duo-input input::placeholder{color:var(--text-light);}
.duo-send{flex:none;width:48px;height:48px;border:none;border-radius:50%;display:grid;place-items:center;background:var(--accent,var(--gray-900));color:#fff;transition:transform .15s var(--ease-smooth-out);}
.duo-send:active{transform:scale(.92);}
.duo-send:disabled{opacity:.4;}
/* 버튼(2026-10-07 크기 통일): 주·보조·기다림은 모든 게임에서 52px, 모서리 16px. 게임은 색·테두리·그림자 색만 바꾼다. 카드 20px, 작은 알약은 둥글게 */
.duo-cta{flex:none;display:flex;align-items:center;justify-content:center;gap:6px;width:100%;height:50px;padding:0 20px;border:none;border-radius:var(--radius-full);background:var(--accent,var(--gray-900));color:#fff;font-size:var(--fs-xl);font-weight:800;box-shadow:0 10px 20px -12px var(--accent,var(--gray-900));transition:transform .15s var(--ease-smooth-out),opacity .15s;}
.duo-cta:active{transform:scale(.97);}
.duo-cta:disabled{opacity:.3;box-shadow:none;}
.duo-cta em{font-style:normal;display:grid;place-items:center;min-width:24px;height:24px;padding:0 7px;box-sizing:border-box;border-radius:var(--radius-full);background:rgba(255,255,255,.2);font-size:var(--fs-md);font-variant-numeric:tabular-nums;}
.duo-pill{flex:none;display:flex;align-items:center;justify-content:center;gap:6px;height:50px;padding:0 22px;border:none;border-radius:var(--radius-full);background:var(--accent-soft);color:var(--accent-ink);font-size:var(--fs-xl);font-weight:var(--fw-bold);white-space:nowrap;transition:transform .15s var(--ease-smooth-out);}
.duo-pill:active{transform:scale(.97);}
.duo-pill:disabled{opacity:.45;}
.duo-pill-s{align-self:center;height:38px;padding:0 16px;font-size:var(--fs-base);}
.duo-btns{display:flex;gap:10px;}
.duo-btns .duo-cta{flex:1;}
.duo-wait{flex:1;margin:0;display:flex;align-items:center;justify-content:center;min-height:52px;padding:0 16px;border-radius:16px;background:rgba(0,0,0,.05);font-size:var(--fs-base);font-weight:var(--fw-bold);color:var(--text-mid);text-align:center;}
.duo-hint{margin:0;text-align:center;font-size:var(--fs-base);line-height:1.45;color:var(--text-mid);}
.duo-hint-l{padding:4px 12px 0;font-size:var(--fs-lg);}
/* 흰 카드와 기다림 카드 */
.duo-glass-card{flex:none;background:#fff;border-radius:20px;corner-shape:squircle;box-shadow:0 1px 2px rgba(0,0,0,.04);}
.duo-waitcard{flex:1 1 auto;max-height:360px;display:flex;flex-direction:column;align-items:center;justify-content:center;gap:10px;padding:28px 16px;text-align:center;}
.duo-waitcard p{margin:0;font-size:var(--fs-lg);color:var(--text-mid);}
.duo-waitcard .avatar{width:64px;height:64px;}
.duo-dots{display:flex;gap:5px;}
.duo-dots i{width:6px;height:6px;border-radius:50%;background:var(--gray-400);animation:duoDot 1.2s infinite ease-in-out;}
.duo-dots i:nth-child(2){animation-delay:.15s;}
.duo-dots i:nth-child(3){animation-delay:.3s;}
@keyframes duoDot{0%,80%,100%{opacity:.3;transform:none}40%{opacity:1;transform:translateY(-3px)}}
/* 머리(결과, 스파이 결과는 가운데 큰 얼굴, 대기실은 왼쪽 정렬): 머리말, 큰 한 줄, 할 일 한 줄, 칩 */
.duo-hero{flex:none;display:flex;flex-direction:column;align-items:center;text-align:center;padding:4px 4px 6px;}
.duo-hero.is-left{align-items:flex-start;text-align:left;margin-top:var(--lm);padding:0 4px 4px;}
.duo-art{display:block;width:112px;height:112px;border-radius:28px;corner-shape:squircle;background:#fff center/cover no-repeat;box-shadow:0 14px 30px -14px rgba(0,0,0,.35);}
.duo-eye{display:flex;align-items:center;gap:6px;margin:16px 0 0;font-size:var(--fs-md);font-weight:var(--fw-bold);color:var(--text-mid);}
.duo-hero.is-left .duo-eye{margin-top:0;}
.duo-eye img{width:20px;height:20px;border-radius:6px;object-fit:cover;}
.duo-big{margin:4px 0 0;font-size:30px;font-weight:800;letter-spacing:-.035em;line-height:1.18;word-break:keep-all;}
.duo-sub{margin:6px 0 0;font-size:var(--fs-lg);color:var(--text-mid);}
.duo-chips-row{display:flex;justify-content:center;flex-wrap:wrap;gap:6px;margin-top:14px;}
.duo-hero.is-left .duo-chips-row{justify-content:flex-start;}
.duo-glass{display:inline-flex;align-items:center;gap:4px;height:28px;padding:0 10px;border-radius:var(--radius-full);background:var(--accent-soft);color:var(--accent-ink);font-size:var(--fs-sm);font-weight:var(--fw-bold);white-space:nowrap;}
.duo-glass b{font-weight:800;}
.duo-face{position:relative;display:inline-block;flex:none;}
.duo-face-xl .avatar{width:clamp(64px,var(--fh) * .1137px,110px);height:clamp(64px,var(--fh) * .1137px,110px);box-shadow:0 0 0 4px #fff,0 16px 32px -14px rgba(0,0,0,.4);}
.duo-crown{position:absolute;top:-8px;right:-4px;display:grid;place-items:center;width:28px;height:28px;border-radius:50%;background:#ffd43b;color:#5c4400;box-shadow:0 0 0 3px #fff;}
/* 대기실: 참가자 카드와 초대 코드 줄 */
.duo-code{display:flex;align-items:center;gap:12px;min-height:56px;padding:0 8px 0 16px;}

.duo-mini{flex:none;display:flex;align-items:center;gap:5px;height:36px;padding:0 14px;border:none;border-radius:var(--radius-full);background:var(--accent-soft);color:var(--accent-ink);font-size:var(--fs-base);font-weight:var(--fw-bold);}
/* 사람 줄(판 아래): 흰 알약마다 얼굴, 이름, 점수. 맞힌 사람은 초록 */
/* 사람 줄: 얼굴 동그라미에 번호가 있어 이름은 나만. 옆으로 밀지 않고 넘치면 다음 줄(8명까지 두 줄) */
.duo-strip{flex:none;display:flex;flex-wrap:wrap;justify-content:center;gap:6px;padding:2px 0 3px;}
.duo-chip{flex:none;display:flex;align-items:center;gap:6px;height:44px;padding:0 11px 0 7px;border-radius:var(--radius-full);background:#fff;box-shadow:0 1px 2px rgba(0,0,0,.04);font-size:var(--fs-base);font-weight:var(--fw-bold);}
.duo-chip .avatar{width:30px;height:30px;}
.duo-chip-name{max-width:64px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;}
.duo-chip em{font-style:normal;color:var(--text-mid);font-variant-numeric:tabular-nums;}
.duo-chip.is-ok{background:#30a46c;color:#fff;}
.duo-chip.is-ok em{color:rgba(255,255,255,.8);}
.duo-chip.is-draw{box-shadow:inset 0 0 0 1.5px var(--accent,var(--gray-900));}
.duo-chip.is-off{opacity:.4;}
.duo-badge-ic{position:absolute;right:-4px;bottom:-3px;display:grid;place-items:center;width:16px;height:16px;border-radius:50%;background:var(--accent,var(--gray-900));color:#fff;}
/* 그림판 */
/* 그림판: 위 제목과 아래 사람 줄을 뺀 남은 높이와 폭 중 작은 쪽으로 정사각형(짧은 폰, 사람이 많아 줄이 두 줄일 때도 넘치지 않게) */
.duo-stage{position:relative;flex:1 1 0;min-height:160px;max-height:calc(100vw - 32px);container-type:size;display:flex;justify-content:center;}
.duo-canvas-slot{position:relative;width:min(100cqw,100cqh);height:min(100cqw,100cqh);}
.duo-canvas{display:block;width:100%;height:100%;border-radius:26px;background:#fff;touch-action:none;box-shadow:0 10px 30px -18px rgba(0,0,0,.35);}
.duo-canvas.is-edit{cursor:crosshair;}
.duo-replay{position:absolute;right:12px;bottom:12px;}
.duo-undo{position:absolute;z-index:1;left:10px;bottom:10px;}
.duo-options{display:flex;flex-direction:column;gap:10px;min-height:0;}
/* 낱말 카드는 남은 높이를 나눠 64~110px */
.duo-options{flex-grow:1;max-height:360px;}
/* 기다리기, 스파이 투표는 남는 높이 가운데에. 낙서 릴레이 그리기 판은 위아래 가운데 정사각형 */
.duo[data-stage="wait"] .duo-body,.duo[data-game="spy"] .duo-body:has(> .duo-poll){justify-content:center;}
.duo[data-stage="sketch"] .duo-stage{max-height:none;align-items:center;}
.duo-option{flex:1 1 64px;min-height:56px;max-height:110px;border:none;border-radius:20px;corner-shape:squircle;background:#fff;box-shadow:0 1px 2px rgba(0,0,0,.05);color:var(--text);font-size:var(--fs-4xl);font-weight:800;letter-spacing:-.02em;transition:transform .15s var(--ease-smooth-out),background .15s;}
.duo-option:active{transform:scale(.98);background:var(--accent-soft);}
/* 그리기 도구막대(Freeform처럼): 흰 알약 하나에 색 동그라미, 칸막이, 지우개, 굵기 점, 모두 지우기 */
.duo-toolbar{display:flex;align-items:center;justify-content:space-between;gap:2px;height:60px;padding:0 10px 0 14px;border-radius:var(--radius-full);background:#fff;box-shadow:0 8px 24px -16px rgba(0,0,0,.35);}
.duo-color{flex:none;width:26px;height:26px;padding:0;border:none;border-radius:50%;background:var(--c);box-shadow:inset 0 0 0 1px rgba(0,0,0,.1);transition:transform .15s var(--ease-smooth-out);}
.duo-color.is-on{transform:scale(1.08);box-shadow:0 0 0 2px #fff,0 0 0 4px var(--accent,var(--gray-900));}
.duo-tool-sep{flex:none;width:1px;height:24px;margin:0 2px;background:var(--gray-200);}
.duo-tool{flex:none;display:grid;place-items:center;width:38px;height:38px;padding:0;border:none;border-radius:50%;background:none;color:var(--text-mid);transition:background .15s;}
.duo-tool.is-on{background:var(--accent,var(--gray-900));color:#fff;}
.duo-dot{width:6px;height:6px;border-radius:50%;background:currentColor;transition:width .15s,height .15s;}
.duo-dot.is-thick{width:13px;height:13px;}
/* 낙서 릴레이 */
.duo-text{flex:none;width:100%;box-sizing:border-box;padding:16px;border:none;border-radius:20px;background:#fff;box-shadow:0 1px 2px rgba(0,0,0,.05);color:var(--text);font:inherit;font-size:var(--fs-3xl);font-weight:var(--fw-bold);line-height:1.4;resize:none;}
.duo-text::placeholder{color:var(--text-light);font-weight:var(--fw-regular);}
.duo-text:focus{outline:2px solid var(--accent,var(--gray-900));outline-offset:0;}
.duo-prev{display:block;flex:none;width:100%;max-width:min(100%,40dvh);margin:0 auto;aspect-ratio:1;border-radius:22px;background:#fff;box-shadow:0 1px 2px rgba(0,0,0,.05);}
.duo-album{list-style:none;margin:0;padding:14px;display:flex;flex-direction:column;gap:14px;}
.duo-album li{display:flex;align-items:flex-start;gap:10px;}
.duo-al-body{display:flex;flex-direction:column;align-items:flex-start;gap:4px;min-width:0;flex:1;}
.duo-album .avatar{width:34px;height:34px;}
.duo-album small{font-size:var(--fs-sm);font-weight:var(--fw-bold);color:var(--text-mid);}
.duo-album p{margin:0;max-width:100%;padding:10px 14px;border-radius:4px 18px 18px 18px;background:var(--bg2);font-size:var(--fs-lg);font-weight:var(--fw-bold);word-break:break-word;}
.duo-album img{width:100%;max-width:240px;box-sizing:border-box;border-radius:4px 18px 18px 18px;border:1px solid var(--gray-100);background:#fff;}
.duo-al-skip{justify-content:center;font-size:var(--fs-sm);color:var(--text-light);}
/* 스파이 찾기: 투표 줄(텔레그램 투표처럼 동그라미 체크), 두 단어, 표 막대 */
.duo-poll{display:flex;flex-direction:column;gap:8px;}
.duo-poll-row{display:flex;align-items:center;gap:12px;width:100%;min-height:62px;padding:0 14px;border:none;border-radius:20px;corner-shape:squircle;background:#fff;box-shadow:0 1px 2px rgba(0,0,0,.05);color:var(--text);font:inherit;font-size:var(--fs-xl);font-weight:var(--fw-bold);text-align:left;transition:box-shadow .15s;}
.duo-poll-row .avatar{width:40px;height:40px;}
.duo-poll-row span{flex:1;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;}
.duo-poll-row.is-on{background:var(--accent-soft);box-shadow:inset 0 0 0 2px var(--accent,var(--gray-900));}
.duo-radio{flex:none;display:grid;place-items:center;width:26px;height:26px;border-radius:50%;box-shadow:inset 0 0 0 2px var(--gray-300);color:#fff;}
.duo-poll-row.is-on .duo-radio{background:var(--accent,var(--gray-900));box-shadow:none;}
.duo-words{flex:none;display:flex;gap:8px;}
.duo-words span{flex:1;display:flex;flex-direction:column;gap:2px;padding:14px;border-radius:20px;corner-shape:squircle;background:#fff;box-shadow:0 1px 2px rgba(0,0,0,.05);text-align:center;}
.duo-words span.is-spy{background:var(--accent,var(--gray-900));color:#fff;}
.duo-words small{font-size:var(--fs-sm);font-weight:var(--fw-bold);opacity:.6;}
.duo-words b{font-size:var(--fs-4xl);font-weight:800;}
.duo-tally{list-style:none;margin:0;padding:14px;display:flex;flex-direction:column;gap:12px;}
.duo-tally li{display:grid;grid-template-columns:84px 1fr 40px;align-items:center;gap:10px;font-size:var(--fs-lg);}
.duo-tally span{overflow:hidden;text-overflow:ellipsis;white-space:nowrap;font-weight:var(--fw-bold);}
.duo-tally i{height:8px;border-radius:4px;background:linear-gradient(90deg,var(--gray-400) var(--p),var(--gray-100) var(--p));}
.duo-tally li.is-spy i{background:linear-gradient(90deg,var(--accent,var(--gray-900)) var(--p),var(--gray-100) var(--p));}
.duo-tally b{text-align:right;font-variant-numeric:tabular-nums;}
/* 주사위 요트: 흰 주사위(남긴 것은 노랑), 흰 점수표 */
.duo-dicecard{display:flex;justify-content:center;padding:16px 10px;}
/* 주사위 요트 점수판(§actions/duo-games.js yachtBoardHtml, 2026-10-09 사용자가 고른 B. 레퍼런스: Yahtzee with Buddies 위 점수 알약, Apple Games 친구 칩).
   위 줄은 사람마다 얼굴과 합계 알약(이름을 빼서 넷이어도 한 줄), 누르면 그 사람 칸을 본다(흰 알약). 그 아래 보너스 막대 한 줄, 칸 타일 2열(왼쪽 1~6, 오른쪽 나머지).
   타일은 광택 없는 반투명 판(예전 유리 광택이 촌스럽다는 의견), 받을 점수는 점선 칸, 가장 높은 칸은 노랑 */
.duo-yb-top{flex:none;display:flex;gap:6px;min-width:0;}
.duo-yb-p{flex:1 1 0;min-width:0;display:flex;align-items:center;justify-content:center;gap:6px;height:40px;padding:0 10px 0 5px;border:none;border-radius:var(--radius-full);background:rgba(0,0,0,.24);color:#fff;font:inherit;font-size:var(--fs-xl);font-weight:800;font-variant-numeric:tabular-nums;white-space:nowrap;}
.duo-yb-p > i{font-style:normal;font-size:var(--fs-sm);opacity:.8;overflow:hidden;text-overflow:ellipsis;}
.duo-yb-p.is-on{background:#fff;color:#1d4d2e;}
.duo-yb-av{position:relative;flex:none;display:grid;place-items:center;width:30px;height:30px;}
.duo-yb-av .avatar{width:30px;height:30px;font-size:var(--fs-md)!important;font-weight:800;}
.duo-yb-me{display:grid;place-items:center;width:30px;height:30px;border-radius:50%;background:#e8f5ec;color:#1d4d2e;font-size:var(--fs-md);font-weight:800;}
/* 차례인 사람 얼굴 둘레의 남은 시간 링: 차례 시간 동안 줄어든다(시간은 그릴 때 animation-delay로 맞춘다) */
.duo-yb-ring{position:absolute;inset:-4px;width:38px;height:38px;rotate:-90deg;overflow:visible;pointer-events:none;}
.duo-yb-ring circle{fill:none;stroke:#ffd43b;stroke-width:3;stroke-linecap:round;stroke-dasharray:100;animation:duoRing linear both;}
@keyframes duoRing{from{stroke-dashoffset:0;}to{stroke-dashoffset:100;}}
.duo-yb-bonus{flex:none;display:flex;align-items:center;gap:10px;height:34px;padding:0 12px;border-radius:12px;background:rgba(0,0,0,.2);font-size:var(--fs-sm);font-weight:var(--fw-bold);white-space:nowrap;font-variant-numeric:tabular-nums;}
.duo-yb-bonus b{color:#ffd43b;}
.duo-yb-bonus > i{flex:1;height:8px;border-radius:4px;background:rgba(255,255,255,.16);overflow:hidden;}
.duo-yb-bonus > i s{display:block;height:100%;border-radius:4px;background:#ffd43b;}
.duo-yb{flex:none;display:grid;grid-template-columns:1fr 1fr;grid-template-rows:repeat(6,auto);grid-auto-flow:column;gap:6px;}
.duo-yb-t{position:relative;display:flex;align-items:center;gap:8px;min-width:0;padding:0 8px 0 10px;border:none;border-radius:14px;background:rgba(255,255,255,.11);color:#fff;font:inherit;text-align:left;}
.duo-yb-t.is-done{background:rgba(0,0,0,.14);color:rgba(255,255,255,.6);}
.duo-yb-t.is-best{box-shadow:0 0 0 2px #ffd43b;}
button.duo-yb-t:active{transform:scale(.97);}
.duo-yb-die{flex:none;width:22px;height:22px;padding:3px;box-sizing:border-box;border-radius:5px;background:rgba(255,255,255,.92);box-shadow:0 1px 2px rgba(0,0,0,.25);}
.duo-yb-die .duo-pips i{width:4px;height:4px;}
.duo-yb-n{flex:1;min-width:0;}
.duo-yb-n b{display:block;font-size:var(--fs-md);font-weight:var(--fw-bold);white-space:nowrap;overflow:hidden;text-overflow:ellipsis;}
.duo-yb-n small{display:block;font-size:var(--fs-2xs);color:rgba(255,255,255,.62);white-space:nowrap;overflow:hidden;text-overflow:ellipsis;}
.duo-yb-t em{flex:none;display:grid;place-items:center;min-width:32px;height:28px;padding:0 4px;box-sizing:border-box;border-radius:8px;font-style:normal;font-size:var(--fs-xl);font-weight:800;font-variant-numeric:tabular-nums;}
button.duo-yb-t em{border:1.5px dashed rgba(255,255,255,.6);color:#fff;}
button.duo-yb-t em.is-zero{border-color:rgba(255,255,255,.2);color:rgba(255,255,255,.4);}
.duo-yb-t.is-best em{border:none;background:#ffd43b;color:#3a2a00;}
.duo-yb-t.is-done em{color:rgba(255,255,255,.78);}
/* 작은 폰(아이폰 SE 667px)도 스크롤 없이: 타일만 낮춘다 */
/* 칸 높이는 남은 높이를 여섯 줄로 나눠 40~80px */
.duo .duo-yb{flex:1 1 auto;max-height:510px;grid-template-rows:repeat(6,minmax(40px,1fr));}
.duo-dice{display:flex;justify-content:center;gap:8px;}
.duo-die{width:56px;height:56px;padding:8px;border:none;border-radius:14px;background:#fff;box-shadow:inset 0 0 0 1.5px var(--gray-200),0 3px 0 var(--gray-200);transition:transform .15s,background .15s;}
.duo-die:disabled{opacity:1;}
.duo-die.is-held{background:#ffd43b;box-shadow:inset 0 0 0 1.5px #e9bd1a,0 1px 0 #e9bd1a;transform:translateY(2px);}
/* 차례 첫 굴림 전: 앞사람 눈 대신 빈 주사위. 누를 수 없는 자리라는 게 보이게 테두리만 */
.duo .duo-die.is-blank{display:grid;place-items:center;background:rgba(255,255,255,.1);box-shadow:inset 0 0 0 2px rgba(255,255,255,.25);color:rgba(255,255,255,.5);font-size:var(--fs-3xl);font-weight:800;}
/* 굴릴 차례인데 아직 안 굴렸으면 굴리기 버튼이 은은하게 부른다 */
@keyframes duoCall{0%,100%{scale:1;}50%{scale:1.03;}}
.duo-cta.is-call{animation:duoCall 1.6s ease-in-out infinite;}
.duo-pips{display:grid;grid-template-columns:repeat(3,1fr);grid-template-rows:repeat(3,1fr);width:100%;height:100%;place-items:center;}
.duo-pips i{width:8px;height:8px;border-radius:50%;}
.duo-pips i.on{background:var(--gray-800);}
/* 굴림(§actions/duo-games.js throwDice): 흔들기 → 3D로 날아간 동안 칸은 비운다 */
@keyframes duoShake{0%,100%{rotate:0deg;translate:0 0;}20%{rotate:-9deg;translate:-2px -1px;}40%{rotate:8deg;translate:2px 1px;}60%{rotate:-6deg;translate:-1px 1px;}80%{rotate:5deg;translate:1px -1px;}}
.duo-dice.is-shake .duo-die:not(.is-held){animation:duoShake .26s ease-in-out;}
.duo-dice.is-fly .duo-die:not(.is-held){opacity:0;}
@keyframes duoRoll{0%{transform:rotate(0) scale(1)}30%{transform:rotate(-18deg) scale(.9)}60%{transform:rotate(14deg) scale(1.05)}100%{transform:none}}
/* 결과 순위 */
.duo-rank{list-style:none;margin:0;padding:4px 14px;}
.duo-rank li{display:flex;align-items:center;gap:12px;min-height:54px;font-weight:var(--fw-bold);}
.duo-rank li + li{border-top:1px solid var(--gray-100);}
.duo-rank li > b{width:20px;text-align:center;color:var(--text-mid);font-variant-numeric:tabular-nums;}
.duo-rank .avatar{width:36px;height:36px;}
.duo-rank li > span{flex:1;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;}
.duo-rank em{font-style:normal;font-variant-numeric:tabular-nums;}
/* 공개방 결과 화면의 하트(또 같이 하고 싶어요). 줄 끝에 두고 누르면 게임 강조색으로 채운다. 요트는 어두운 펠트 위라 왕관과 같은 노랑.
   보이는 하트는 22px, 누르는 자리는 44px이고 바깥 여백을 줄여 줄 높이와 점수 자리를 그대로 둔다(빈칸 .duo-like-gap과 같은 26px) */
.duo-like{flex:none;width:44px;height:44px;margin:-10px -12px -10px -6px;padding:0;border:none;border-radius:50%;background:none;display:grid;place-items:center;color:inherit;opacity:.45;}
.duo-like.is-on{color:var(--accent,var(--gray-900));opacity:1;}
[data-game="yacht"] .duo-like.is-on{color:#ffd43b;}
.duo-like-gap,.duo-rank li > span.duo-like-gap{flex:none;width:26px;}
.duo-tally.has-like li{grid-template-columns:70px 1fr 34px 26px;}
.duo-al-from .duo-like,.duo-others .duo-like{margin-left:auto;}
.duo-others .duo-glass-card:has(.duo-like){flex-basis:58%;}
.duo-like-tip{display:flex;align-items:center;justify-content:center;gap:5px;margin:0;padding:12px 14px 2px;font-size:var(--fs-sm);font-weight:var(--fw-bold);color:var(--text-mid);}
.duo-like-tip svg{color:var(--accent,var(--gray-900));}
[data-game="yacht"] .duo-like-tip svg{color:#ffd43b;}
.duo-others + .duo-like-tip{padding-top:6px;}
/* 서로 하트를 눌렀을 때 시트: 두 얼굴 사이에 하트 */
.duo-match{display:flex;flex-direction:column;align-items:center;gap:6px;text-align:center;}
.duo-match-pair{display:flex;align-items:center;margin:10px 0 8px;}
.duo-match-pair .avatar{width:72px;height:72px;font-size:22px;box-shadow:0 0 0 4px var(--bg1);}
.duo-match-heart{position:relative;z-index:1;display:grid;place-items:center;width:34px;height:34px;margin:0 -12px;border-radius:50%;background:var(--bg1);color:var(--accent,var(--gray-900));box-shadow:var(--shadow-sm);}
.duo-match-sub{margin:0 0 10px;font-size:var(--fs-base);color:var(--text-mid);}
.duo-match .duo-cta{width:100%;}
.duo-match-later{height:44px;padding:0 16px;border:none;background:none;font:inherit;font-weight:var(--fw-bold);color:var(--text-mid);}
.duo-invite-card .gdc-foot{margin-top:104px;}
/* 아래에서 올라오는 시트: 흰 면. 게임 시트는 그 게임의 옅은 바탕(is-art). 방 화면(900)보다 위 */
.duo-sheet-layer{position:fixed;inset:0;z-index:960;background:rgba(0,0,0,0);display:flex;align-items:flex-end;justify-content:center;transition:background .2s;}
.duo-sheet-layer.is-open{background:rgba(0,0,0,.35);}
.duo-sheet{position:relative;width:100%;max-width:480px;box-sizing:border-box;display:flex;flex-direction:column;gap:12px;background:var(--bg1);color:var(--text);border-radius:var(--radius-xl) var(--radius-xl) 0 0;padding:8px 16px calc(16px + env(safe-area-inset-bottom));transform:translateY(100%);transition:transform .28s var(--ease-smooth-out);}
.duo-sheet-layer.is-open .duo-sheet{transform:none;}
.duo-sheet .sheet-handle{margin-bottom:0;}
.duo-sheet-title{margin:2px 0 0;text-align:center;font-size:var(--fs-3xl);font-weight:var(--fw-bold);letter-spacing:-.02em;}
.duo-sheet-game{display:flex;flex-direction:column;align-items:center;text-align:center;padding:10px 0 6px;}
.duo-sheet-game .duo-art{width:88px;height:88px;border-radius:22px;}
.duo-sheet-game b{margin-top:14px;font-size:26px;font-weight:800;letter-spacing:-.03em;}
.duo-sheet-game small{margin-top:4px;font-size:var(--fs-base);color:var(--text-mid);}
/* 게임 방법은 시트 오른쪽 위 알약 */
.duo-sheet-game .duo-howto-link{position:absolute;top:16px;right:16px;margin:0;}
/* 게임 시트의 빠른 입장 조건(§actions/duo-games.js quickHtml, 애플 게임의 도전 만들기처럼): 아이콘, 작은 이름, 지금 값, ⌃⌄가 있는 줄 둘 */
.duo-quick{border-radius:18px;background:rgba(255,255,255,.72);}
.duo-quick-row{display:flex;align-items:center;gap:12px;width:100%;padding:10px 14px;border:0;background:none;color:var(--text);font:inherit;text-align:left;}
.duo-quick-row + .duo-quick-row{border-top:1px solid rgba(0,0,0,.06);}
.duo-quick-ic{flex:none;display:grid;place-items:center;width:34px;height:34px;border-radius:10px;background:var(--accent-soft);color:var(--accent-ink);}
.duo-quick-t{flex:1;display:flex;flex-direction:column;min-width:0;}
.duo-quick-t small{font-size:12px;color:var(--text-mid);}
.duo-quick-t b{font-size:var(--fs-lg);font-weight:var(--fw-bold);}
.duo-quick-ud{flex:none;display:flex;flex-direction:column;line-height:0;color:var(--text-light);}
/* 그 자리에 뜨는 작은 메뉴(빠른 입장 조건은 줄 위로 시트 바깥에, 함께한 사람은 줄 아래로) */
.duo-pop{position:absolute;z-index:3;right:8px;min-width:180px;max-height:320px;overflow-y:auto;padding:4px 0;border-radius:14px;background:rgba(252,252,252,.98);box-shadow:0 12px 32px -8px rgba(0,0,0,.35),0 0 0 .5px rgba(0,0,0,.08);transform-origin:top right;animation:modalScaleIn var(--modal-open-dur) var(--ease-smooth-out);}
.duo-pop.is-up{transform-origin:bottom right;}
.duo-pop button{display:flex;align-items:center;gap:8px;width:100%;min-height:44px;padding:0 14px;border:0;background:none;color:var(--gray-900);font:inherit;font-size:var(--fs-lg);text-align:left;}
.duo-pop button + button{border-top:.5px solid rgba(0,0,0,.08);}
.duo-pop button:active{background:rgba(0,0,0,.05);}
.duo-pop i{display:inline-flex;width:16px;color:var(--accent-ink,var(--gray-900));}
.duo-recent .duo-pop button{justify-content:space-between;}
.duo-pop .is-red{color:#e5484d;}
/* 함께한 사람 줄(Airchat의 뮤트한 계정처럼): 얼굴, 번호와 게임, 오른쪽 ⋯. 메뉴는 줄 아래에 뜬다 */
.duo-recent{position:relative;}
.duo-recent .duo-pop{top:calc(100% - 6px);}
.duo-recent .duo-pop.is-up{top:auto;bottom:calc(100% - 6px);}
.duo-recent-row{display:flex;align-items:center;gap:12px;width:100%;padding:8px 0;border:0;background:none;color:var(--text);font:inherit;text-align:left;}
.duo-recent-row .duo-sheet-text{flex:1;}
.duo-recent-row em{margin-left:6px;font-style:normal;font-size:var(--fs-sm);font-weight:var(--fw-regular);color:var(--gray-450);}
.duo-recent-more{flex:none;display:grid;place-items:center;width:36px;height:36px;color:var(--gray-500);}
/* 사람 메뉴 카드(§actions/duo-games.js openCard, 인스타그램 뮤트 카드처럼): 아래쪽 작은 카드와 떨어진 [취소] */
.duo-act-layer{align-items:flex-end;padding:0 14px calc(14px + env(safe-area-inset-bottom));box-sizing:border-box;}
.duo-act{width:100%;max-width:420px;display:flex;flex-direction:column;gap:8px;animation:modalScaleIn var(--modal-open-dur) var(--ease-smooth-out);}
.duo-act-box{border-radius:16px;background:rgba(250,250,250,.97);overflow:hidden;text-align:center;}
.duo-act-head{display:flex;flex-direction:column;align-items:center;gap:8px;padding:18px 16px 14px;}
.duo-act-head .avatar{width:56px;height:56px;font-size:20px;}
.duo-act-head b{font-size:var(--fs-lg);font-weight:var(--fw-bold);color:var(--gray-900);}
.duo-act-head small{font-size:var(--fs-sm);color:var(--gray-450);}
.duo-act-btn{display:block;width:100%;min-height:54px;padding:0 16px;border:0;border-top:.5px solid rgba(0,0,0,.1);background:none;color:var(--gray-900);font:inherit;font-size:var(--fs-xl);}
.duo-act-btn:active,.duo-act-cancel:active{background:rgba(0,0,0,.05);}
.duo-act-btn.is-red{color:#e5484d;}
.duo-act-cancel{min-height:54px;border:0;border-radius:16px;background:var(--gray-0);color:var(--gray-900);font:inherit;font-size:var(--fs-xl);font-weight:var(--fw-bold);}
@media(prefers-reduced-motion:reduce){.duo-pop,.duo-act{animation:none;}}
.duo-sheet-empty{margin:8px 0 16px;text-align:center;font-size:var(--fs-md);color:var(--text-mid);}
.duo-tiles{display:grid;grid-auto-flow:column;grid-auto-columns:minmax(0,1fr);gap:8px;}
.duo-tile{display:flex;flex-direction:row;align-items:center;justify-content:center;gap:6px;height:48px;padding:0 4px;border:none;border-radius:16px;corner-shape:squircle;background:var(--accent-soft);color:var(--accent-ink);font:inherit;font-size:var(--fs-base);font-weight:var(--fw-bold);transition:transform .15s var(--ease-smooth-out);}
.duo-tile:active{transform:scale(.96);}
.duo-sheet-text{display:flex;flex-direction:column;gap:2px;min-width:0;}
.duo-sheet-text b{font-size:var(--fs-lg);font-weight:var(--fw-bold);}
.duo-sheet-text small{font-size:var(--fs-sm);color:var(--text-mid);}
/* 방 코드 팝업(§actions/duo-games.js duoCodeSheet): 흰 카드에 네 게임 이름표와 기울어진 숫자 타일 넷(레고 빌더 파티 번호처럼).
   타일 위에 투명한 입력칸을 덮어 숫자 키패드와 붙여넣기를 받고, 지금 넣을 칸만 검게 */
.duo-code-layer{align-items:center;padding:24px;}
.duo-code-pop{position:relative;width:100%;max-width:327px;box-sizing:border-box;padding:26px 20px 16px;border-radius:var(--radius-xl);corner-shape:squircle;background:var(--gray-0);color:var(--gray-900);text-align:center;box-shadow:var(--shadow-pop);animation:modalScaleIn var(--modal-open-dur) var(--ease-smooth-out);}
@media(prefers-reduced-motion:reduce){.duo-code-pop{animation:none;}}
.duo-code-x{position:absolute;top:10px;right:10px;display:grid;place-items:center;width:36px;height:36px;padding:0;border:0;border-radius:50%;background:none;color:var(--gray-450);}
.duo-code-chips{display:flex;justify-content:center;gap:6px;margin:0;}
.duo-code-chips span{padding:5px 10px;border-radius:var(--radius-full);font-size:13px;font-weight:var(--fw-bold);color:#fff;}
.duo-code-h{margin:16px 0 0;font-size:var(--fs-4xl);font-weight:var(--fw-bold);letter-spacing:-.02em;}
.duo-code-sub{margin:6px 0 0;font-size:var(--fs-md);color:var(--gray-500);}
.duo-code-digits{position:relative;display:block;width:fit-content;margin:22px auto 0;}
.duo-code-slots{display:flex;gap:10px;}
.duo-code-slot{width:56px;height:68px;border-radius:16px;background:rgba(0,0,0,.06);font-size:40px;font-weight:800;line-height:68px;font-variant-numeric:tabular-nums;}
.duo-code-slot:nth-child(1){transform:rotate(-4deg);}
.duo-code-slot:nth-child(2){transform:rotate(3deg) translateY(4px);}
.duo-code-slot:nth-child(3){transform:rotate(-2deg);}
.duo-code-slot:nth-child(4){transform:rotate(4deg) translateY(3px);}
.duo-code-digits:focus-within .duo-code-slot.is-at{background:var(--gray-900);}
.duo-code-digits:focus-within .duo-code-slot.is-at::after{content:"";display:block;width:2px;height:34px;margin:17px auto 0;background:var(--gray-0);}
.duo-code-digits input{position:absolute;inset:0;width:100%;height:100%;margin:0;padding:0;border:0;opacity:0;font-size:16px;caret-color:transparent;}
.duo-code-paste{display:inline-flex;align-items:center;gap:5px;min-height:44px;margin-top:14px;padding:0 18px;border:0;border-radius:var(--radius-full);background:rgba(0,0,0,.06);color:var(--gray-900);font-size:var(--fs-sm);font-weight:var(--fw-bold);}
/* 티켓 팝업(§actions/chat-ticket.js). C안 입장권을 Days 코드 팝업처럼 밝게 흐린 바탕 위에 띄운다.
   절취선 양끝 홈은 mask로 실제로 파내서 뒤 바탕이 비친다. 아래 버튼은 A안(Instagram, TikTok 프로필 공유).
   번호 입력은 빈 입장권에 큰 숫자를 채운다: 빈 자리 밑줄(Luma), 넷씩 띄우기(LEGO Builder 파티 번호), 붙여넣기(UGLYCASH) */
.ticket-overlay{align-items:stretch;padding:0;background:rgba(233,233,235,.9);-webkit-backdrop-filter:blur(18px);backdrop-filter:blur(18px);}
.ticket-pop{--ticket-mono:'Courier Prime',ui-monospace,SFMono-Regular,Menlo,Consolas,monospace;display:flex;flex-direction:column;width:100%;padding:env(safe-area-inset-top,0px) 0 env(safe-area-inset-bottom,0px);overflow-y:auto;animation:modalScaleIn var(--modal-open-dur) var(--ease-smooth-out);}
.ticket-body{width:calc(100% - 48px);max-width:320px;margin:auto;padding-bottom:56px;}
.center-modal-overlay.closing .ticket-pop{animation:modalScaleOut var(--modal-close-dur) var(--ease-smooth-out) forwards;}
@media(prefers-reduced-motion:reduce){.ticket-pop,.center-modal-overlay.closing .ticket-pop{animation:none;}}
.ticket-bar{flex:none;display:grid;grid-template-columns:44px 1fr 44px;align-items:center;height:56px;padding:0 20px;}
.ticket-tabs{justify-self:center;display:flex;width:200px;padding:3px;border-radius:var(--radius-full);background:rgba(0,0,0,.06);}
.ticket-tabs button{flex:1;height:34px;border:0;border-radius:var(--radius-full);background:none;color:var(--gray-500);font-size:var(--fs-md);font-weight:var(--fw-bold);}
.ticket-tabs button.is-on{background:var(--gray-0);color:var(--gray-900);box-shadow:var(--shadow-sm);}
.ticket{position:relative;background:var(--gray-0);border-radius:var(--radius-xl);corner-shape:squircle;text-align:center;-webkit-mask:radial-gradient(circle 12px at 0 calc(100% - 52px),#0000 96%,#000) left/51% 100% no-repeat,radial-gradient(circle 12px at 100% calc(100% - 52px),#0000 96%,#000) right/51% 100% no-repeat;mask:radial-gradient(circle 12px at 0 calc(100% - 52px),#0000 96%,#000) left/51% 100% no-repeat,radial-gradient(circle 12px at 100% calc(100% - 52px),#0000 96%,#000) right/51% 100% no-repeat;}
.ticket-top{padding:30px 20px 24px;}
.ticket-logo{display:block;height:28px;width:auto;margin:0 auto;}
.ticket-kind{margin:10px 0 0;font-size:var(--fs-md);color:var(--gray-500);}
.ticket-code{display:block;min-height:40px;margin:20px auto 0;padding:0;border:0;background:none;font-size:30px;font-weight:var(--fw-bold);letter-spacing:.08em;line-height:40px;color:var(--gray-900);white-space:pre;}
.ticket-note{margin:10px 0 0;font-size:var(--fs-sm);color:var(--gray-450);}
.ticket-tear{position:absolute;left:18px;right:18px;bottom:52px;border-top:1.5px dashed var(--gray-300);}
.ticket-stub{display:flex;align-items:center;justify-content:space-between;height:52px;padding:0 22px;font-size:var(--fs-sm);color:var(--gray-450);}
.ticket-stub-r{display:flex;align-items:center;gap:12px;}
.ticket-ic{display:inline-flex;vertical-align:-2px;margin:0 1px;color:var(--gray-500);}
.ticket-left{font-family:var(--ticket-mono);font-variant-numeric:tabular-nums;}
.ticket-renew{position:relative;padding:0;border:0;background:none;color:var(--gray-900);font-size:var(--fs-sm);font-weight:var(--fw-bold);text-decoration:underline;text-underline-offset:3px;}
.ticket-paste{display:flex;align-items:center;gap:5px;min-height:44px;padding:0;border:0;background:none;font-size:var(--fs-sm);font-weight:var(--fw-bold);color:var(--gray-900);}
.ticket-digits{position:relative;display:block;width:fit-content;margin:20px auto 0;}
.ticket-slots{display:flex;gap:6px;}
.ticket-slot{width:22px;height:40px;border-bottom:2px solid var(--gray-200);font-size:30px;font-weight:var(--fw-bold);line-height:38px;color:var(--gray-900);}
.ticket-slot:nth-child(5){margin-left:12px;}
.ticket-slot.is-at{border-bottom-color:var(--gray-900);}
.ticket-input{position:absolute;inset:0;width:100%;height:100%;margin:0;padding:0;border:0;opacity:0;font-size:16px;caret-color:transparent;}
.ticket-face{display:flex;justify-content:center;margin-top:18px;}
.ticket-name{margin:10px 0 0;font-size:var(--fs-2xl);font-weight:var(--fw-bold);color:var(--gray-900);}
.ticket-acts{display:flex;gap:8px;margin-top:12px;}
.ticket-acts button{flex:1;display:flex;flex-direction:column;align-items:center;gap:6px;padding:13px 0 12px;border:0;border-radius:var(--radius-lg);corner-shape:squircle;background:var(--gray-0);color:var(--gray-900);font-size:var(--fs-md);font-weight:var(--fw-bold);transition:transform .1s ease-out;}
.ticket-acts button:active{transform:scale(.96);}
.ticket-acts button:disabled,.ticket-save:disabled{opacity:.4;}
.ticket-save{display:block;min-height:44px;margin:6px auto 0;padding:0 14px;border:0;background:none;color:var(--gray-500);font-size:var(--fs-md);}
.ticket-cta{margin-top:12px;}
/* 페이지 층: 방 만들기·설정(애플 게임 도전 만들기처럼 설정 줄), 공개방 목록. 바탕은 방 화면과 같은 옅은 게임 색 */
.duo-page{position:fixed;inset:0;z-index:910;display:flex;flex-direction:column;height:100dvh;padding:calc(env(safe-area-inset-top) + 6px) 0 env(safe-area-inset-bottom);opacity:0;transform:translateY(16px);transition:opacity .25s var(--ease-smooth-out),transform .25s var(--ease-smooth-out);}
.duo-page.is-open{opacity:1;transform:none;}
.duo-page-bar{display:grid;grid-template-columns:44px 1fr 44px;align-items:center;gap:8px;min-height:56px;padding:0 12px;}
.duo-page-bar b{text-align:center;font-size:var(--fs-2xl);font-weight:var(--fw-bold);}
.duo-page-body{flex:1;min-height:0;overflow-y:auto;padding:4px 16px 16px;display:flex;flex-direction:column;gap:16px;}
.duo-page-foot{flex:none;padding:10px 16px 12px;}
.duo-form-head{display:flex;flex-direction:column;align-items:center;text-align:center;gap:4px;padding:4px 0 6px;}
.duo-form-head .duo-art{width:96px;height:96px;margin-bottom:10px;border-radius:24px;}
.duo-form-head b{font-size:26px;font-weight:800;letter-spacing:-.03em;}
.duo-form-head small{font-size:var(--fs-base);color:var(--text-mid);}
.duo-vis-pick{display:flex;flex-direction:column;gap:8px;}
.duo-vis-h{margin:0 4px;font-size:var(--fs-md);font-weight:800;color:var(--text-mid);}
.duo-vis{display:flex;align-items:center;gap:12px;width:100%;padding:14px 16px;border:2px solid transparent;border-radius:20px;corner-shape:squircle;background:#fff;box-shadow:0 1px 2px rgba(0,0,0,.04);color:var(--text);font:inherit;text-align:left;}
.duo-vis > span{flex:1;min-width:0;display:flex;flex-direction:column;gap:3px;}
.duo-vis b{font-size:var(--fs-xl);font-weight:800;}
.duo-vis small{font-size:var(--fs-base);color:var(--text-mid);}
.duo-vis.is-on{border-color:var(--accent,var(--gray-900));}
.duo-vis:active{transform:scale(.98);}
/* 작은 폰(높이 700 아래): 게임 그림과 카드, 설정 줄을 줄여 [만들기]까지 스크롤 없이 */
@media (max-height:700px){
  .duo-form-head .duo-art{width:64px;height:64px;margin-bottom:6px;border-radius:18px;}
  .duo-form-head b{font-size:22px;}
  .duo-page-body{gap:12px;}
  .duo-vis{padding:10px 14px;}
  .duo-vis small{font-size:var(--fs-sm);}
  .duo-page .duo-row{min-height:52px;padding:8px 14px;}
}
.duo-group{background:#fff;border-radius:20px;corner-shape:squircle;overflow:hidden;box-shadow:0 1px 2px rgba(0,0,0,.04);}
.duo-row{position:relative;display:flex;align-items:center;gap:12px;min-height:60px;padding:12px 14px;box-sizing:border-box;}
.duo-row + .duo-row::before{content:"";position:absolute;top:0;right:0;left:58px;border-top:1px solid var(--gray-100);}
.duo-row-ic{flex:none;display:grid;place-items:center;width:32px;height:32px;border-radius:var(--radius-xs);corner-shape:squircle;background:var(--accent,var(--gray-900));color:#fff;}
.duo-row-text{display:flex;flex-direction:column;gap:2px;min-width:0;flex:1;}
.duo-row-text b{font-size:var(--fs-lg);font-weight:var(--fw-bold);}
.duo-row-text small{font-size:var(--fs-sm);color:var(--text-mid);}
.duo-stepper{flex:none;display:flex;align-items:center;gap:4px;background:var(--bg2);border-radius:999px;padding:3px;}
.duo-stepper button{width:32px;height:32px;border:none;border-radius:50%;background:#fff;color:var(--text);display:grid;place-items:center;box-shadow:0 1px 2px rgba(0,0,0,.08);}
.duo-stepper button:disabled{opacity:.35;}
.duo-stepper output{min-width:42px;text-align:center;font-weight:var(--fw-bold);font-variant-numeric:tabular-nums;}
.duo-seg{flex:none;display:flex;background:var(--bg2);border-radius:var(--radius-full);padding:3px;gap:2px;}
.duo-seg button{min-width:52px;height:32px;padding:0 10px;border:none;border-radius:var(--radius-full);background:none;color:var(--text-mid);font-weight:var(--fw-bold);font-size:var(--fs-base);white-space:nowrap;}
.duo-seg button.is-on{background:#fff;color:var(--accent-ink);box-shadow:0 1px 3px rgba(0,0,0,.12);}
.duo-chips{display:flex;gap:6px;overflow-x:auto;scrollbar-width:none;}
.duo-chip-btn{flex:none;height:36px;padding:0 14px;border-radius:999px;border:none;background:#fff;color:var(--text);font-weight:var(--fw-bold);font-size:var(--fs-md);box-shadow:0 1px 2px rgba(0,0,0,.05);}
.duo-chip-btn.is-on{background:var(--accent,var(--gray-900));color:#fff;}
.duo-chip-btn:disabled{opacity:.35;}
.duo-page .duo-wait{background:none;}
/* 입장료 꼬리표(이슈 #242, §actions/duo-games.js entryTag): 버튼 글 뒤에 옅게 "무료" 또는 "10C" */
.duo-cta-price{font-size:var(--fs-sm);font-weight:var(--fw-regular);opacity:.7;}
/* 게임별 겉모습(2026-10-07 사용자가 고른 시안). 화면 구조는 같고, applyTheme이 붙인 data-game으로 겉만 바꾼다. 글꼴은 앱 글꼴 그대로.
   그림 맞히기 = 스케치북(쿵야 캐치마인드): 줄 노트 바탕, 카드와 버튼은 자판처럼 아래 그림자, 1등 점수에 빨간 동그라미.
   주사위 요트 = 게임판(게임피전): 초록 펠트 테이블, 그 위에 주사위와 종이 점수표, 사람과 순위는 어두운 명패, 시작 버튼은 윤나는 초록 */
[data-game="draw"]{--key:#ddd5c0;background:#f8f4ea linear-gradient(#ebe3cf 1px,transparent 1px) 0 13px/100% 28px;}
[data-game="draw"] .gp-btn,.duo[data-game="draw"] .duo-timer{background:#fff;color:#2b2b2b;box-shadow:0 3px 0 var(--key);}
.duo[data-game="draw"] .duo-timer.is-low{background:#e5484d;color:#fff;box-shadow:0 3px 0 #b8363a;}
[data-game="draw"] :is(.duo-glass-card,.duo-poll-row,.duo-words span){box-shadow:0 3px 0 var(--key);}
[data-game="draw"] :is(.duo-chip,.duo-msg,.duo-input input){box-shadow:0 3px 0 var(--key);}
[data-game="draw"] :is(.duo-msg.is-ok,.duo-chip.is-ok){background:var(--accent);}
[data-game="draw"] :is(.duo-glass,.duo-mini){background:#fff;color:#5d5544;box-shadow:0 2px 0 var(--key);}
[data-game="draw"] .duo-rank li + li{border-top:1px dashed #e3dccb;}
[data-game="draw"] .duo-option{border-radius:16px;}
[data-game="draw"] :is(.duo-option,.duo-pill){background:#fff;color:#2b2b2b;box-shadow:0 3px 0 var(--key);transition:transform .1s,box-shadow .1s;}
[data-game="draw"] .duo-cta{box-shadow:0 3px 0 color-mix(in srgb,var(--accent) 70%,#000);transition:transform .1s,box-shadow .1s;}
[data-game="draw"] :is(.duo-option,.duo-pill,.duo-cta):active{transform:translateY(3px);box-shadow:0 2px 0 var(--key);}
[data-game="draw"] .duo-cta:active{box-shadow:0 2px 0 color-mix(in srgb,var(--accent) 70%,#000);}
[data-game="draw"] .duo-cta:disabled{box-shadow:none;transform:none;}
[data-game="draw"] .duo-blanks{gap:6px 18px;padding:10px 0 4px;}
[data-game="draw"] .duo-blanks span{gap:6px;}
[data-game="draw"] .duo-blanks i{display:grid;place-items:center;width:30px;height:34px;border-radius:9px;background:#fff;box-shadow:0 3px 0 var(--key);font-style:normal;font-size:var(--fs-3xl);font-weight:var(--fw-bold);line-height:1;color:var(--text);}
[data-game="draw"] .duo-canvas,[data-game="draw"] .duo-prev{border-radius:6px;box-shadow:0 2px 0 #e3dccb,0 12px 24px -10px rgba(80,60,20,.18);}
[data-game="draw"] .duo-toolbar{border-radius:18px;box-shadow:0 4px 0 var(--key);}
[data-game="draw"] .duo-rank li > b{font-size:22px;font-weight:800;color:#2b2b2b;}
[data-game="draw"] .duo-rank li:first-child em{padding:3px 10px;border:2.5px solid #e5484d;border-radius:50%;transform:rotate(-5deg);}
[data-game="yacht"]{--text:#fff;--text-mid:rgba(255,255,255,.75);--text-light:rgba(255,255,255,.55);color:#fff;background:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='160' height='160'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.9' numOctaves='2' stitchTiles='stitch'/%3E%3CfeColorMatrix values='0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 .16 0'/%3E%3C/filter%3E%3Crect width='100%' height='100%' filter='url(%23n)'/%3E%3C/svg%3E"),radial-gradient(120% 80% at 50% 30%,#2e8a52,#1f6b40 55%,#15502e);box-shadow:inset 0 0 90px rgba(0,0,0,.35);}
[data-game="yacht"] :is(.duo-group,.duo-vis,.duo-msg,.duo-input input,.duo-waitcard){--text:var(--gray-800);--text-mid:var(--gray-500);--text-light:var(--gray-450);color:var(--text);}
[data-game="yacht"] .gp-btn{background:rgba(255,255,255,.92);}
.duo[data-game="yacht"] .duo-timer:not(.is-low),[data-game="yacht"] :is(.duo-glass,.duo-mini){background:rgba(0,0,0,.25);color:#fff;}
[data-game="yacht"] .duo-dicecard{background:none;box-shadow:none;padding:10px 0;}
[data-game="yacht"] .duo-die{width:58px;height:58px;box-shadow:inset 0 -4px 0 #dcdcdc,0 9px 16px -5px rgba(0,0,0,.5);}
[data-game="yacht"] .duo-die.is-held{box-shadow:inset 0 -4px 0 #e0b614,0 0 0 3px rgba(255,212,59,.5),0 6px 12px -5px rgba(0,0,0,.45);}
[data-game="yacht"] :is(.duo-seats,.duo-code,.duo-glass-card:has(> .duo-rank)){background:rgba(0,0,0,.24);box-shadow:inset 0 0 0 1px rgba(255,255,255,.08);}
[data-game="yacht"] .duo-rank li + li{border-top-color:rgba(255,255,255,.12);}
[data-game="yacht"] .duo-seat.is-empty :is(.duo-seat-face,b){color:#c4f5d2;}
[data-game="yacht"] .duo-rank em{padding:1px 10px;border-radius:var(--radius-full);background:#174d2e;box-shadow:0 0 0 2px #e9f2ea,0 0 0 4px #174d2e;font-weight:800;}
[data-game="yacht"] .duo-cta{background:radial-gradient(120% 140% at 50% 0%,#86ec5c,#2fae3a 70%);box-shadow:inset 0 0 0 3px rgba(230,255,214,.75),0 10px 22px -10px rgba(0,0,0,.6);text-shadow:0 1px 1px rgba(0,0,0,.25);}
[data-game="yacht"] .duo-pill{background:rgba(255,255,255,.94);color:#1d4d2e;}
/* 단체 대결 방 만들기의 게임 알약은 늘 흰 바탕이라 테마의 흰 글씨 대신 [방 만들기] 알약과 같은 색 */
[data-game="yacht"] .duo-chip-btn:not(.is-on){color:#1d4d2e;}
[data-game="yacht"] .duo-wait{background:rgba(0,0,0,.24);color:rgba(255,255,255,.8);}
/* 스파이 찾기 = 기밀 서류(스파이폴): 어두운 책상 위 누런 서류철(::before)과 탭(::after), 빨간 숫자 시계.
   이야기 때 내 단어는 클립 꽂힌 쪽지에 "기밀" 도장, 투표는 핀 꽂은 용의자 사진, 공개는 사진에 "검거"(못 잡으면 "도주") 도장 */
[data-game="spy"]{--manila:#e8d6a8;--slip:#fffdf5;--stamp:#c8302c;--text:#2a2418;--text-mid:#5e4a24;--text-light:#806a40;color:var(--text);background:#3b3f47;}
.duo[data-game="spy"]::before,.duo.is-lobby[data-game="spy"]::before{content:"";position:absolute;z-index:-1;top:calc(env(safe-area-inset-top) + 88px);left:10px;right:10px;bottom:0;height:auto;border-radius:4px 14px 0 0;background:var(--manila);box-shadow:inset 0 2px 0 rgba(255,255,255,.35);-webkit-mask-image:none;mask-image:none;pointer-events:none;}
.duo[data-game="spy"]::after{content:"수사 파일";position:absolute;z-index:-1;top:calc(env(safe-area-inset-top) + 66px);left:10px;height:24px;padding:4px 14px 0;box-sizing:border-box;border-radius:10px 10px 0 0;background:var(--manila);font-size:var(--fs-sm);font-weight:800;color:var(--text-mid);pointer-events:none;}
/* 방 만들기·공개방 둘러보기(duo-page)에는 서류철이 없으니 바탕을 서류철 색으로(어두운 바탕에 진한 글자가 묻히지 않게) */
/* 서류철 탭이 나가기 버튼에 붙지 않게 게임 화면은 위 줄 아래를 8px 띄운다(대기실은 장면 아래에서 시작) */
.duo[data-game="spy"]:not(.is-lobby) .duo-bar{margin-bottom:8px;}
.duo-page[data-game="spy"]{background:var(--manila);}
[data-game="spy"] .gp-btn{background:rgba(255,255,255,.92);}
.duo[data-game="spy"] .duo-timer{background:#1a1a1a;box-shadow:inset 0 0 0 3px #555;color:#ff3b30;font-family:ui-monospace,Consolas,monospace;letter-spacing:.06em;text-shadow:0 0 8px rgba(255,59,48,.6);}
.duo[data-game="spy"] .duo-timer svg{display:none;}
[data-game="spy"] :is(.duo-glass-card,.duo-msg,.duo-input input,.duo-words span){background:var(--slip);box-shadow:0 1px 3px rgba(0,0,0,.16);}
[data-game="spy"] :is(.duo-msg,.duo-words span){border-radius:3px;}
[data-game="spy"] :is(.duo-glass,.duo-mini){background:rgba(0,0,0,.07);color:var(--text-mid);}
[data-game="spy"] .duo-pill{background:var(--slip);color:var(--text);}
[data-game="spy"] .duo-wait{background:rgba(0,0,0,.07);}
/* 이야기: 큰 제목(내 단어)이 클립 꽂힌 쪽지 */
.duo.is-chatty[data-game="spy"] .duo-hud{position:relative;margin:16px 24px 6px;padding:16px 16px 18px;background:var(--slip);box-shadow:0 2px 5px rgba(0,0,0,.18);transform:rotate(-1.5deg);}
.duo.is-chatty[data-game="spy"] .duo-hud::before{content:"";position:absolute;top:-12px;right:26px;width:12px;height:38px;border:3px solid #9a9a9a;border-radius:9px;}
.duo.is-chatty[data-game="spy"] .duo-hud::after{content:"기밀";position:absolute;right:14px;bottom:14px;padding:1px 10px;border:3px solid var(--stamp);border-radius:6px;color:var(--stamp);font-size:var(--fs-lg);font-weight:900;letter-spacing:.1em;opacity:.85;transform:rotate(-12deg);}
.duo.is-chatty[data-game="spy"] .duo-name{font-size:40px;font-weight:900;}
/* 투표: 핀 꽂은 용의자 사진 두 줄. 사진 칸(회색) 안에 얼굴, 아래 이름. 고르면 빨간 테두리 */
[data-game="spy"] .duo-poll{display:grid;grid-template-columns:1fr 1fr;gap:16px 12px;padding:6px 8px 0;}
[data-game="spy"] .duo-poll-row{position:relative;flex-direction:column;gap:6px;min-height:0;padding:22px 8px 9px;border-radius:2px;background:linear-gradient(#d9d4c7,#d9d4c7) 7px 7px/calc(100% - 14px) 82px no-repeat,#fff;box-shadow:0 2px 6px rgba(0,0,0,.22);text-align:center;}
[data-game="spy"] .duo-poll-row:nth-child(odd){transform:rotate(-1.5deg);}
[data-game="spy"] .duo-poll-row:nth-child(even){transform:rotate(1.5deg);}
[data-game="spy"] .duo-poll-row::before{content:"";position:absolute;top:-6px;left:50%;width:12px;height:12px;margin-left:-6px;border-radius:50%;background:var(--stamp);box-shadow:0 2px 2px rgba(0,0,0,.3);}
[data-game="spy"] .duo-poll-row .avatar{width:52px;height:52px;margin-bottom:12px;}
[data-game="spy"] .duo-poll-row span{flex:none;width:100%;font-size:var(--fs-lg);}
[data-game="spy"] .duo-poll-row.is-on{background:linear-gradient(#d9d4c7,#d9d4c7) 7px 7px/calc(100% - 14px) 82px no-repeat,#fff;box-shadow:0 0 0 3px var(--stamp),0 2px 6px rgba(0,0,0,.22);}
[data-game="spy"] .duo-radio{display:none;}
/* 차례 설명(2026-10-09 A 시안 "진술서 목록"): 순서대로 한 줄씩. 지금 쓰는 줄은 빨간 테두리와 줄어드는 시간 막대, 아직인 줄은 흐리게.
   판이 주인공이라 이야기 시간과 달리 판을 늘리고 채팅 칸(입력만 쓴다)은 아래로 */
.duo[data-game="spy"][data-stage="clue"] .duo-body{flex:1;max-height:none;}
.duo[data-game="spy"][data-stage="clue"] .duo-dock{flex:none;}
.duo-turns{margin:0;padding:6px 16px 4px;list-style:none;}
.duo-turn{position:relative;display:flex;align-items:center;gap:12px;min-height:58px;}
.duo-turn + .duo-turn{border-top:1.5px dashed rgba(94,74,36,.22);}
.duo-turn .avatar{width:36px;height:36px;font-size:14px!important;}
.duo-turn b{flex:none;min-width:42px;font-size:var(--fs-lg);font-weight:800;color:var(--text-mid);}
.duo-turn p{flex:1;min-width:0;margin:0;font-size:var(--fs-lg);color:var(--text-mid);word-break:break-word;}
.duo-turn.is-said p{font-weight:var(--fw-bold);color:var(--text);}
.duo-turn.is-wait{opacity:.45;}
.duo-turn.is-now{margin:0 -8px;padding:0 8px;border-radius:6px;background:#fff;box-shadow:inset 0 0 0 2.5px var(--stamp);}
.duo-turn.is-now + .duo-turn{border-top-color:transparent;}
.duo-turn-bar{position:absolute;left:10px;right:10px;bottom:6px;height:3px;border-radius:2px;background:rgba(200,48,44,.15);overflow:hidden;}
.duo-turn-bar i{display:block;height:100%;background:var(--stamp);transform-origin:0 50%;animation:duoDrain var(--d) linear var(--t) both;}
/* 이야기 시간 채팅의 설명 줄: 왼쪽 빨간 줄과 빨간 번호(자유 이야기와 구분) */
[data-game="spy"] .duo-msg.is-clue{background:#fff;box-shadow:inset 3px 0 0 var(--stamp),0 1px 3px rgba(0,0,0,.16);}
[data-game="spy"] .duo-msg.is-clue b{color:var(--stamp);}
/* 회의(2026-10-11 시안 나안): 진술서 목록 줄마다 [지목], 채팅에는 빨간 테두리 지목 카드. 설명은 목록에 있으니 채팅의 설명 줄은 숨긴다 */
.duo[data-game="spy"][data-stage="meet"] .duo-body{flex:none;max-height:44%;overflow-y:auto;}
.duo[data-game="spy"][data-stage="meet"] .duo-msg.is-clue{display:none;}
/* 8명이 작은 폰(360x640)에서도 채팅 자리가 남게 회의에서는 쪽지와 줄을 줄인다. 설명은 두 줄까지 */
.duo.is-chatty[data-game="spy"][data-stage="meet"] .duo-hud{margin:8px 24px 4px;padding:10px 14px 12px;}
.duo.is-chatty[data-game="spy"][data-stage="meet"] .duo-name{font-size:28px;}
.duo-turns.is-meet .duo-turn{min-height:44px;gap:10px;padding-top:4px;padding-bottom:4px;}
.duo-turns.is-meet .duo-turn .avatar{width:30px;height:30px;font-size:12px!important;}
.duo-turns.is-meet .duo-turn b{min-width:34px;font-size:var(--fs-base);}
.duo-turns.is-meet .duo-turn p{display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden;font-size:var(--fs-sm);font-weight:var(--fw-bold);color:var(--text);}
.duo-turn.is-hit{margin:0 -8px;padding:0 8px;border-radius:6px;background:#fff1ef;}
.duo-turn.is-out{opacity:.4;}
.duo-accuse{flex:none;height:32px;padding:0 12px;border:1.5px solid var(--stamp);border-radius:999px;background:#fff;color:var(--stamp);font-size:var(--fs-sm);font-weight:800;}
.duo-accuse.is-on{background:var(--stamp);color:#fff;}
.duo-meet-sum{margin:8px 0 0;text-align:center;font-size:var(--fs-sm);color:var(--text-mid);}
[data-game="spy"] .duo-msg.is-acc{align-self:stretch;max-width:none;background:#fff;box-shadow:inset 0 0 0 1.5px var(--stamp),0 1px 3px rgba(0,0,0,.16);}
.duo-msg.is-acc b{display:inline;margin:0;color:var(--stamp);font-size:var(--fs-sm);}
.duo-msg.is-acc{flex-wrap:wrap;}
.duo-msg.is-acc p{flex-basis:100%;margin:2px 0 0;color:var(--text);}
.duo-input.is-hot input{box-shadow:0 0 0 2px var(--stamp,#c8302c);}
.duo-input.is-hot input::placeholder{color:var(--stamp,#c8302c);font-weight:var(--fw-bold);}
/* 지목 이유 창: 그 사람이 쓴 설명, 자주 쓰는 이유 버튼(누르면 입력칸을 채운다), 직접 쓰는 칸. 이유가 있어야 [지목하기] */
.duo-acc{display:flex;flex-direction:column;gap:12px;}
.duo-acc-who{display:flex;align-items:center;gap:10px;font-size:var(--fs-lg);}
.duo-acc-who .avatar{width:36px;height:36px;font-size:14px!important;}
.duo-acc-said{margin:0;padding:8px 12px;border-radius:10px;background:var(--gray-100);font-size:var(--fs-base);}
.duo-acc-chips{display:flex;flex-wrap:wrap;gap:8px;}
.duo-acc-chips button{height:36px;padding:0 14px;border:1.5px solid var(--border);border-radius:999px;background:#fff;color:var(--text);font-size:var(--fs-base);}
.duo-acc-chips button.is-on{border-color:var(--stamp,#c8302c);background:#fff1ef;color:var(--stamp,#c8302c);font-weight:var(--fw-bold);}
.duo-acc-input{height:48px;padding:0 14px;border:1.5px solid var(--border);border-radius:12px;font-size:16px;}
.duo-acc .duo-cta{background:var(--stamp,#c8302c);}
.duo-acc .duo-cta:disabled{opacity:.4;}
/* 회의 시작 알림(어몽어스 "Discuss!"처럼 1.5초) */
.duo-splash{position:absolute;inset:0;z-index:30;display:flex;flex-direction:column;align-items:center;justify-content:center;gap:10px;background:rgba(30,31,38,.94);color:#fff;text-align:center;pointer-events:none;animation:duoSplash 1.6s ease both;}
.duo-splash small{font-size:var(--fs-base);opacity:.7;}
.duo-splash b{font-size:34px;font-weight:900;letter-spacing:-.02em;}
.duo-splash p{margin:8px 24px 0;font-size:var(--fs-base);opacity:.8;}
.duo-splash-faces{display:flex;gap:10px;margin-top:6px;}
.duo-splash-faces .avatar{width:44px;height:44px;}
@keyframes duoSplash{0%{opacity:0;transform:scale(1.04);}12%{opacity:1;transform:none;}82%{opacity:1;}100%{opacity:0;}}
@media (prefers-reduced-motion:reduce){.duo-splash{animation:none;}}
/* 공개: 스파이 얼굴이 사진, 그 위에 도장 */
[data-game="spy"] .duo-face-xl{padding:16px 22px 34px;background:linear-gradient(#d9d4c7,#d9d4c7) 8px 8px/calc(100% - 16px) calc(100% - 34px) no-repeat,#fff;box-shadow:0 3px 8px rgba(0,0,0,.25);transform:rotate(2deg);}
[data-game="spy"] .duo-face-xl .avatar{box-shadow:none;}
[data-game="spy"] .duo-hero .duo-face-xl::after{content:"도주";position:absolute;left:50%;top:44%;padding:0 12px;border:4px solid var(--stamp);border-radius:8px;background:rgba(255,255,255,.35);color:var(--stamp);font-size:26px;font-weight:900;white-space:nowrap;transform:translate(-50%,-50%) rotate(-14deg);}
[data-game="spy"] .duo-hero.is-caught .duo-face-xl::after{content:"검거";}
[data-game="spy"] .duo-words span.is-spy{background:var(--slip);color:var(--stamp);}
/* 낙서 릴레이 = 도톰한 스티커 게임 UI(2026-10-07 사용자가 고른 시안, 듀오링고·Abode 참고, 갈틱폰의 보라와 마스코트는 쓰지 않음).
   흰 점이 깔린 파란 바탕, 흰 카드와 버튼은 굵은 남색 테두리와 아래로 떨어지는 그림자, 주 버튼은 노랑, 3D 스티커는 Fluent Emoji(.duo-fe) */
.duo-fe{display:block;flex:none;width:24px;height:24px;pointer-events:none;}
[data-game="gartic"]{--ink:#16204d;--y:#ffd43b;--text:#fff;--text-mid:rgba(255,255,255,.85);--text-light:rgba(255,255,255,.6);color:#fff;
  background:radial-gradient(120% 50% at 50% -10%,#7a9bff,rgba(122,155,255,0) 60%),radial-gradient(rgba(255,255,255,.09) 1.6px,transparent 1.7px) 0 0/22px 22px,linear-gradient(#4a74ff,#2c50e0);}
[data-game="gartic"] :is(.duo-glass-card,.duo-group,.duo-vis,.duo-text,.duo-toolbar,.duo-album li,.duo-rx,.duo-msg,.duo-input input,.duo-pill,.duo-mini,.gp-btn,.duo-timer){--text:var(--ink);--text-mid:#5b6aa6;--text-light:#9aa3c7;color:var(--ink);}
[data-game="gartic"] :is(.duo-glass-card,.duo-group,.duo-text,.duo-toolbar,.duo-album li,.duo-rx){background:#fff;border:2.5px solid var(--ink);border-radius:20px;box-shadow:0 3px 0 var(--ink);}
[data-game="gartic"] :is(.duo-canvas,.duo-prev){border:2.5px solid var(--ink);border-radius:22px;box-shadow:0 5px 0 var(--ink);}
[data-game="gartic"] .avatar{box-shadow:0 0 0 2.5px var(--ink);}
[data-game="gartic"] :is(.gp-btn,.duo-timer){background:#fff;border:2.5px solid var(--ink);box-shadow:0 3px 0 var(--ink);}
.duo[data-game="gartic"] .duo-timer{padding:0 12px 0 8px;font-weight:800;}
.duo[data-game="gartic"] .duo-timer svg{display:none;}
.duo[data-game="gartic"] .duo-timer::before{content:"";width:22px;height:22px;background:url(../images/duo/hourglass.png) center/contain no-repeat;}
.duo[data-game="gartic"] .duo-timer.is-low{background:#ff5a5f;color:#fff;}
/* 버튼: 노랑 주 버튼, 흰 보조, 기다림은 반투명. 누르면 그림자만큼 내려간다 */
[data-game="gartic"] :is(.duo-cta,.duo-pill,.duo-wait){border:2.5px solid var(--ink);box-shadow:0 3px 0 var(--ink);font-weight:800;transition:transform .1s,box-shadow .1s;}
[data-game="gartic"] .duo-cta{background:var(--y);color:var(--ink);}
[data-game="gartic"] .duo-cta em{background:rgba(22,32,77,.12);}
[data-game="gartic"] .duo-pill{background:#fff;}
[data-game="gartic"] .duo-chip-btn:not(.is-on){color:var(--ink);}
[data-game="gartic"] .duo-wait{background:rgba(255,255,255,.16);border-color:rgba(255,255,255,.35);box-shadow:none;color:#fff;}
[data-game="gartic"] :is(.duo-cta,.duo-pill):active{transform:translateY(3px);box-shadow:0 2px 0 var(--ink);}
[data-game="gartic"] .duo-cta:disabled{opacity:.55;transform:none;box-shadow:0 3px 0 var(--ink);}
[data-game="gartic"] .duo-mini{background:#eaf0ff;border:2px solid var(--ink);}
[data-game="gartic"] .duo-glass{background:#fff;color:var(--ink);border:2px solid var(--ink);box-shadow:0 2px 0 var(--ink);}
[data-game="gartic"] .duo-big{font-weight:800;text-shadow:0 2px 0 rgba(22,32,77,.35);}
/* 채팅 */
[data-game="gartic"] .duo-msg{background:#fff;border:2.5px solid var(--ink);box-shadow:0 3px 0 var(--ink);border-radius:6px 16px 16px 16px;font-weight:600;}
[data-game="gartic"] .duo-input input{border:2.5px solid var(--ink);box-shadow:0 4px 0 var(--ink);border-radius:var(--radius-full);}
[data-game="gartic"] .duo-send{background:var(--y);color:var(--ink);border:2.5px solid var(--ink);box-shadow:0 4px 0 var(--ink);}
/* 위 줄: 진행 칸(단계)을 ✕ 옆에, 남은 시간은 오른쪽 */
.duo[data-game="gartic"]:is([data-stage="write"],[data-stage="sketch"],[data-stage="guess"],[data-stage="wait"]) .duo-bar-r{order:1;margin:0 auto 0 0;}
.duo[data-game="gartic"] .duo-timer{order:2;}
.duo-steps{display:flex;gap:5px;width:112px;}
.duo-steps i{flex:1;height:12px;border-radius:6px;background:rgba(255,255,255,.25);border:2px solid var(--ink);}
.duo-steps i.on{background:var(--y);}
/* 할 일 카드: 큰 제목(쓸 것, 그릴 문장)이 살짝 기운 흰 카드 */
.duo[data-game="gartic"]:is([data-stage="write"],[data-stage="sketch"],[data-stage="guess"]) .duo-hud{margin:18px 16px 14px;padding:12px 16px 14px;background:#fff;color:var(--ink);border:2.5px solid var(--ink);border-radius:22px;box-shadow:0 5px 0 var(--ink);transform:rotate(-1deg);}
.duo[data-game="gartic"]:is([data-stage="write"],[data-stage="sketch"],[data-stage="guess"]) .duo-status{color:#4f67d8;font-size:var(--fs-sm);}
.duo[data-game="gartic"]:is([data-stage="write"],[data-stage="sketch"],[data-stage="guess"]) .duo-name{font-size:24px;font-weight:800;line-height:1.28;}
[data-game="gartic"] .duo-text{padding:16px 18px;font-size:24px;font-weight:800;letter-spacing:-.03em;}
[data-game="gartic"] .duo-text:focus{outline:none;box-shadow:0 5px 0 var(--ink),0 0 0 4px rgba(255,212,59,.7);}
[data-game="gartic"] .duo-hint{color:rgba(255,255,255,.85);}
.duo-ideas{flex:none;display:flex;flex-wrap:wrap;gap:8px;}
.duo-idea{display:inline-flex;align-items:center;gap:6px;height:38px;padding:0 12px;border:2px solid rgba(255,255,255,.45);border-radius:var(--radius-full);background:rgba(255,255,255,.16);color:#fff;font:inherit;font-size:var(--fs-base);font-weight:700;}
.duo-idea .duo-fe{width:22px;height:22px;margin-left:-4px;}
/* 예시 낱말 난이도 별 */
.duo-lv{margin-left:-1px;font-size:var(--fs-2xs);letter-spacing:-1px;color:#f5a524;}
.duo-idea:active{background:rgba(255,255,255,.28);}
/* 그리기 도구막대 */
[data-game="gartic"] .duo-toolbar{height:58px;}
[data-game="gartic"] .duo-color{box-shadow:inset 0 0 0 2px var(--ink);}
[data-game="gartic"] .duo-color.is-on{box-shadow:inset 0 0 0 2px var(--ink),0 0 0 3px #fff,0 0 0 5px var(--ink);}
[data-game="gartic"] .duo-tool{color:var(--ink);}
[data-game="gartic"] .duo-tool.is-on{background:var(--ink);color:#fff;}
/* 기다림과 마지막 화면 머리: 큰 3D 스티커, 큰 한 줄, 작은 한 줄 */
.duo-relay-top{flex:none;display:flex;flex-direction:column;align-items:center;text-align:center;margin-top:8px;padding:8px 8px 0;}
/* 결과 위 여백도 폰 높이따라(844 기준에서 높이 차의 절반만큼, 짧으면 0). 긴 폰에서는 채팅 칸도 같이 커지므로 절반만 */
.duo-body > .duo-hero:not(.is-left):first-child{margin-top:clamp(0px,34px + (var(--fh) * 1px - 844px) * .5,80px);}
.duo[data-game="spy"] .duo-body > .duo-hero:not(.is-left):first-child{margin-top:clamp(0px,24px + (var(--fh) * 1px - 844px) * .5,70px);}
/* 짧은 폰에서는 순위 줄을 조금 낮게 */
.duo .duo-rank li{min-height:clamp(42px,var(--fh) * 1px - 790px,54px);}
[data-game="spy"] .duo-face-xl .avatar{width:56px;height:56px;}
.duo-relay-top .duo-fe{width:96px;height:96px;margin-bottom:6px;transform:rotate(-8deg);filter:drop-shadow(0 10px 10px rgba(0,0,0,.25));}
.duo-relay-top .duo-big{margin-top:4px;}
.duo-who{padding:4px 14px;}
.duo-who-row{display:flex;align-items:center;gap:12px;min-height:58px;}
.duo-who-row + .duo-who-row{border-top:2px solid #eef1f9;}
.duo-who-row .avatar{width:40px;height:40px;}
.duo-who-row b{flex:1;min-width:0;font-size:var(--fs-xl);font-weight:800;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;}
.duo-st{flex:none;display:inline-flex;align-items:center;gap:6px;height:30px;padding:0 10px;border:2px solid #c9d4f7;border-radius:10px;background:#eaf0ff;color:#3f5bd6;font-size:var(--fs-sm);font-weight:800;}
.duo-st .duo-dots i{width:4px;height:4px;background:#3f5bd6;}
.duo-st.is-done{background:#2fd18b;border-color:var(--ink);color:var(--ink);}
/* 대기실: 게임 이름 노란 스티커, 세 칸 자리판 */
[data-game="gartic"] .duo-eye{align-self:flex-start;padding:3px 10px 3px 6px;border:2.5px solid var(--ink);border-radius:12px;background:var(--y);box-shadow:0 3px 0 var(--ink);color:var(--ink);font-weight:800;transform:rotate(-3deg);}
[data-game="gartic"] .duo-eye .duo-fe{width:20px;height:20px;}
.duo-seats{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));row-gap:16px;padding:18px 8px 14px;}
.duo-seat{display:flex;flex-direction:column;align-items:center;gap:7px;min-width:0;padding:0;border:none;background:none;color:inherit;font:inherit;}
.duo-seat b{max-width:92%;font-size:var(--fs-md);font-weight:700;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;}
.duo-seat-face{position:relative;display:grid;place-items:center;width:60px;height:60px;border-radius:50%;background:var(--accent-soft);}
.duo-seat-face .avatar{width:60px;height:60px;font-size:var(--fs-3xl)!important;font-weight:800;line-height:1;}
.duo-seat-face .duo-fe{position:absolute;top:-16px;right:-10px;width:34px;height:34px;transform:rotate(18deg);}
.duo-seat.is-empty .duo-seat-face{box-sizing:border-box;border:2.5px dashed currentColor;background:none;color:var(--accent-ink);opacity:.75;}
.duo-seat.is-empty b{color:var(--accent-ink);}
[data-game="gartic"] .duo-seat-face{background:#eaf0ff;}
[data-game="gartic"] .duo-seat.is-empty .duo-seat-face{border-color:#9aa6cc;background:#f4f6fb;color:#5b72d6;opacity:1;}
[data-game="gartic"] .duo-seat.is-empty b{color:#5b72d6;}
/* 공개: 카드 사슬. 카드 사이는 화살표 동그라미, 마지막 글은 노란 카드와 "대반전" 스티커 */
[data-game="gartic"] .duo-album{flex:none;list-style:none;margin:0;padding:0 2px;display:flex;flex-direction:column;gap:28px;}
[data-game="gartic"] .duo-album li{position:relative;display:block;padding:12px 14px 14px;}
[data-game="gartic"] .duo-album li + li::before{content:"";position:absolute;left:50%;top:-29px;width:24px;height:24px;margin-left:-12px;box-sizing:border-box;border:2.5px solid var(--ink);border-radius:50%;background:#fff url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%2316204d' stroke-width='3.6' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M12 5v14M6 13l6 6 6-6'/%3E%3C/svg%3E") center/12px no-repeat;}
.duo-al-from{display:flex;align-items:center;gap:6px;margin-bottom:6px;font-size:var(--fs-sm);font-weight:700;color:#4f67d8;}
/* 방장만 보는 앨범 칸의 ⋯(가리기). 채팅 줄도 방장에게는 버튼이다 */
.duo-al-more{display:grid;place-items:center;width:28px;height:28px;margin:-4px -6px -4px auto;padding:0;border:0;border-radius:50%;background:none;color:var(--text-mid);}
button.duo-msg{border:0;font-family:inherit;font-weight:inherit;letter-spacing:inherit;color:inherit;text-align:left;cursor:pointer;}
.duo-al-from .avatar{width:26px;height:26px;font-size:10px;box-shadow:0 0 0 2px var(--ink);}
[data-game="gartic"] .duo-album p{margin:0;padding:0;max-width:none;background:none;border-radius:0;font-size:22px;font-weight:800;letter-spacing:-.03em;word-break:keep-all;overflow-wrap:anywhere;}
[data-game="gartic"] .duo-album li > img{display:block;width:100%;max-width:none;height:min(170px,21dvh);object-fit:contain;background:#fff;border:2px solid #e3e8f6;border-radius:14px;}
[data-game="gartic"] .duo-album li.is-final{background:var(--y);}
[data-game="gartic"] .duo-album li.is-final p{padding-right:56px;font-size:34px;}
[data-game="gartic"] .duo-album li.is-final .duo-al-from{color:#6b5200;}
.duo-album li.is-final > .duo-fe{position:absolute;right:14px;bottom:12px;width:50px;height:50px;transform:rotate(-12deg);filter:drop-shadow(0 6px 8px rgba(0,0,0,.25));}
.duo-boom{position:absolute;right:12px;top:-16px;padding:2px 9px;border:2.5px solid var(--ink);border-radius:10px;background:#ff5a5f;box-shadow:0 3px 0 var(--ink);color:#fff;font-size:var(--fs-sm);font-weight:800;transform:rotate(10deg);}
[data-game="gartic"] .duo-album li.duo-al-skip{padding:10px;background:rgba(255,255,255,.14);border:2px dashed rgba(255,255,255,.4);box-shadow:none;color:rgba(255,255,255,.75);text-align:center;font-size:var(--fs-sm);}
.duo-rx{flex:none;display:flex;justify-content:space-around;padding:4px;}
[data-game="gartic"] .duo-act{gap:12px;}
.duo-rx-b{display:inline-flex;align-items:center;gap:4px;height:50px;padding:0 10px 0 6px;border:2px solid transparent;border-radius:var(--radius-full);background:none;color:inherit;font:inherit;font-size:var(--fs-lg);font-weight:800;}
.duo-rx-b .duo-fe{width:36px;height:36px;transition:transform .15s var(--ease-smooth-out);}
.duo-rx-b:active .duo-fe{transform:scale(1.2);}
.duo-rx-b.is-on{border-color:var(--ink);background:#eaf0ff;}
/* 반응 줄 끝 [보내기]와 이야기 보내기 시트(미리보기는 위아래로 넘겨 보고, 아래에 Loóna처럼 동그란 버튼) */
.duo-rx-sep{flex:none;align-self:stretch;width:2px;margin:10px 0;border-radius:2px;background:#e3e8f6;}
.duo-rx-send{justify-content:center;width:50px;padding:0;}
.duo-share-pv{align-self:center;width:200px;height:min(300px,40dvh);overflow-y:auto;overscroll-behavior:contain;margin:4px 0 10px;border-radius:18px;box-shadow:0 0 0 2.5px #16204d,0 6px 0 #16204d;}
.duo-share-pv img{display:block;width:100%;}
.duo-share{display:flex;justify-content:center;gap:30px;padding:2px 0 8px;}
.duo-share-b{display:flex;flex-direction:column;align-items:center;gap:6px;padding:0;border:none;background:none;color:var(--text);font:inherit;font-size:var(--fs-sm);font-weight:var(--fw-bold);}
.duo-share-b span{display:grid;place-items:center;width:58px;height:58px;border-radius:50%;background:#16204d;color:#fff;transition:scale .25s cubic-bezier(.34,1.56,.64,1);}
.duo-share-b.is-out span{background:#4a74ff;}
.duo-share-b.is-save span{background:var(--gray-450);}
.duo-share-b:active span{scale:.95;transition-duration:.08s;}
/* 마지막 화면: 오늘의 대참사 카드(한 줄 사슬과 반응 수), 나머지 이야기 */
.duo-best{position:relative;margin-top:10px;padding:14px;}
.duo-medal{position:absolute;right:12px;top:-18px;display:flex;align-items:center;gap:4px;padding:4px 10px;border:2.5px solid var(--ink);border-radius:12px;background:var(--y);box-shadow:0 3px 0 var(--ink);font-size:var(--fs-sm);font-weight:800;transform:rotate(8deg);}
.duo-medal .duo-fe{width:20px;height:20px;}
.duo-mini-chain{display:flex;align-items:center;gap:6px;margin-top:10px;}
.duo-mini-chain > i{flex:none;color:#9aa3c7;font-style:normal;font-weight:900;}
.duo-mc{flex:1;min-width:0;height:86px;display:grid;place-items:center;padding:6px;box-sizing:border-box;border:2px solid #e3e8f6;border-radius:12px;overflow:hidden;text-align:center;font-size:var(--fs-md);font-weight:800;line-height:1.25;word-break:keep-all;}
.duo-mc img{max-width:100%;max-height:100%;}
.duo-mc.is-fin{border-color:var(--ink);background:var(--y);}
.duo-best-rx{display:flex;flex-wrap:wrap;gap:8px;margin-top:12px;}
.duo-best-rx span{display:inline-flex;align-items:center;gap:4px;height:34px;padding:0 10px 0 6px;border-radius:11px;background:#eaf0ff;font-weight:800;}
.duo-best-rx .duo-fe{width:24px;height:24px;}
.duo-others{flex:none;display:flex;gap:8px;overflow-x:auto;margin:0 -16px;padding:0 16px 4px;scrollbar-width:none;}
.duo[data-stage="end"] .duo-body{gap:6px;}
.duo-others::-webkit-scrollbar{display:none;}
.duo-others .duo-glass-card{flex:0 0 46%;min-width:0;display:flex;align-items:center;gap:8px;padding:10px;border-radius:18px;box-shadow:0 4px 0 var(--ink);}
.duo-others .avatar{width:32px;height:32px;font-size:11px;}
.duo-others span{min-width:0;}
.duo-others b{display:block;font-size:var(--fs-sm);font-weight:800;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;}
.duo-others small{font-size:var(--fs-xs);font-weight:700;color:#5b6aa6;}
/* 방 위 줄의 ?(게임 방법)는 맨 오른쪽, 대기실에서만 보인다. 게임 중에는 판과 채팅 자리를 비운다(2026-10-10) */
.duo-bar .duo-help{order:9;}
.duo:not(.is-lobby) .duo-help{display:none;}
/* 게임 방법(2026-10-10 A, 애플 뉴스 Quartiles 튜토리얼): 진한 게임 색 전체 화면, 한 장씩 옆으로 넘긴다(scroll-snap). 장면(hw-)은 흰 판 조각 */
.duo-howto-layer{position:fixed;inset:0;z-index:970;display:flex;flex-direction:column;align-items:center;box-sizing:border-box;padding:env(safe-area-inset-top) 0 calc(6px + env(safe-area-inset-bottom));background:var(--deep);color:#fff;opacity:0;transform:translateY(16px);transition:opacity .24s var(--ease-out),transform .24s var(--ease-out);}
.duo-howto-layer.is-open{opacity:1;transform:none;}
.duo-howto-x{position:absolute;top:calc(12px + env(safe-area-inset-top));right:16px;z-index:1;display:grid;place-items:center;width:36px;height:36px;padding:0;border:none;border-radius:50%;background:rgba(255,255,255,.16);color:#fff;}
.duo-howto-track{flex:1;display:flex;width:100%;max-width:480px;overflow-x:auto;overflow-y:hidden;scroll-snap-type:x mandatory;overscroll-behavior-x:contain;scrollbar-width:none;}
.duo-howto-track::-webkit-scrollbar{display:none;}
.duo-howto-page{flex:0 0 100%;display:flex;flex-direction:column;align-items:center;box-sizing:border-box;padding:68px 28px 0;text-align:center;scroll-snap-align:center;scroll-snap-stop:always;}
.duo-howto-page h2{margin:0;font-size:28px;font-weight:800;line-height:1.3;letter-spacing:-.03em;word-break:keep-all;text-wrap:balance;}
.duo-howto-page p{margin:10px 0 0;font-size:var(--fs-xl);font-weight:var(--fw-regular);line-height:1.45;opacity:.8;word-break:keep-all;text-wrap:balance;}
.duo-howto-dots{display:flex;gap:7px;margin:6px 0 18px;}
.duo-howto-dots i{width:7px;height:7px;border-radius:50%;background:rgba(255,255,255,.35);transition:background .2s;}
.duo-howto-dots i.is-on{background:#fff;}
.duo-howto-next{flex:none;width:calc(100% - 40px);max-width:440px;height:50px;border:none;border-radius:var(--radius-full);background:#fff;color:var(--deep);font:inherit;font-size:var(--fs-xl);font-weight:800;transition:transform .12s var(--ease-out);}
.duo-howto-next:active{transform:scale(.97);}
.duo-howto-skip{flex:none;height:48px;padding:0 20px;border:none;background:none;color:#fff;opacity:.8;font:inherit;font-size:var(--fs-lg);font-weight:var(--fw-bold);}
@media (prefers-reduced-motion:reduce){.duo-howto-layer{transform:none;}}
.hw-scene{flex:1;display:flex;flex-direction:column;align-items:center;justify-content:center;gap:16px;width:100%;padding:20px 0;}
.hw-col{display:flex;flex-direction:column;align-items:center;gap:10px;width:100%;max-width:300px;}
.hw-input{display:flex;align-items:center;justify-content:space-between;width:100%;height:52px;padding:0 16px;box-sizing:border-box;border-radius:var(--radius-full);background:#fff;color:var(--text-light);font-size:var(--fs-xl);}
.hw-input svg{color:var(--deep);}
.hw-chips{display:flex;flex-wrap:wrap;justify-content:center;gap:8px;}
.hw-chips span{padding:10px 14px;border-radius:var(--radius-full);background:rgba(255,255,255,.16);font-size:var(--fs-lg);font-weight:var(--fw-bold);}
.hw-chips .is-on{background:#fff;color:var(--deep);}
.hw-pad{display:grid;place-items:center;width:100%;max-width:250px;aspect-ratio:4/3;border-radius:22px;background:#fff;box-shadow:0 12px 24px -12px rgba(0,0,0,.45);}
.hw-pad.is-small{width:150px;border-radius:16px;}
.hw-whale{position:relative;display:inline-flex;padding-top:20%;}
.hw-whale svg:first-child{position:absolute;top:2%;left:30%;}
.hw-chat{display:flex;gap:8px;}
.hw-chat span{display:inline-flex;align-items:center;gap:4px;padding:9px 14px;border-radius:18px;background:rgba(255,255,255,.16);font-size:var(--fs-lg);font-weight:var(--fw-bold);}
.hw-chat .is-ok{background:#fff;color:var(--accent);}
.hw-row{display:flex;align-items:center;gap:10px;width:100%;min-height:56px;padding:0 16px;box-sizing:border-box;border-radius:16px;background:rgba(255,255,255,.14);font-size:var(--fs-xl);font-weight:var(--fw-bold);text-align:left;}
.hw-row > span:not(.hw-face){display:flex;flex-direction:column;}
.hw-row small{font-size:var(--fs-sm);font-weight:var(--fw-regular);opacity:.75;}
.hw-row > i{width:18px;font-style:normal;font-weight:800;}
.hw-row em{margin-left:auto;font-style:normal;font-size:var(--fs-3xl);font-weight:800;font-variant-numeric:tabular-nums;}
.hw-row.is-on{background:#fff;color:var(--deep);}
.hw-row.is-clue em{margin-left:0;font-size:var(--fs-xl);font-weight:var(--fw-bold);}
.hw-face{flex:none;display:grid;place-items:center;width:36px;height:36px;border-radius:50%;color:#1a1a1a;font-size:var(--fs-lg);font-weight:800;}
.hw-swap{display:flex;align-items:center;gap:18px;}
.hw-swap .hw-face{width:76px;height:76px;font-size:28px;}
.hw-big{display:grid;place-items:center;align-content:center;width:150px;height:150px;border-radius:50%;background:#fff;color:var(--deep);}
.hw-big b{font-size:64px;font-weight:800;line-height:1;}
.hw-big small{font-size:var(--fs-lg);font-weight:var(--fw-bold);}
.hw-card{display:flex;flex-direction:column;gap:2px;min-width:180px;padding:12px 18px;box-sizing:border-box;border-radius:18px;background:#fff;color:var(--text);text-align:left;box-shadow:0 12px 24px -12px rgba(0,0,0,.45);}
.hw-card small{font-size:var(--fs-sm);color:var(--text-mid);}
.hw-card b{font-size:var(--fs-3xl);font-weight:800;}
.hw-card.is-big{padding:20px 24px;transform:rotate(-3deg);}
.hw-card.is-big b{font-size:26px;}
.hw-card.is-guess{background:#ffd54f;}
.hw-album{position:relative;display:flex;flex-direction:column;align-items:center;gap:8px;}
.hw-album img{position:absolute;right:-34px;bottom:-10px;}
.hw-words{display:grid;grid-template-columns:repeat(2,120px);gap:12px;}
.hw-words span{display:flex;flex-direction:column;align-items:center;justify-content:center;height:84px;border-radius:18px;background:#fff;color:var(--text);}
.hw-words b{font-size:24px;font-weight:800;}
.hw-words small{font-size:var(--fs-sm);opacity:.85;}
.hw-words .is-spy{background:#c8302c;color:#fff;}
.hw-words.is-one{grid-template-columns:150px;}
.hw-words.is-one span{height:110px;}
.hw-win{display:inline-flex;align-items:center;gap:6px;padding:10px 16px;border-radius:var(--radius-full);background:#fff;color:var(--deep);font-size:var(--fs-xl);font-weight:800;}
.hw-vote{display:flex;gap:14px;}
.hw-vote > span{display:flex;flex-direction:column;align-items:center;gap:8px;opacity:.6;}
.hw-vote > .is-on{opacity:1;}
.hw-vote .hw-face{width:56px;height:56px;font-size:var(--fs-3xl);}
.hw-vote .is-on .hw-face{box-shadow:0 0 0 4px #fff;}
.hw-vote em{min-height:22px;font-style:normal;font-size:var(--fs-lg);font-weight:800;}
.hw-dice{display:flex;gap:8px;}
.hw-die{width:50px;height:50px;padding:7px;box-sizing:border-box;border-radius:13px;background:#fff;box-shadow:inset 0 -4px 0 #dcdcdc,0 9px 16px -5px rgba(0,0,0,.5);}
.hw-die.is-held{background:#ffd43b;box-shadow:inset 0 -4px 0 #e9bd1a,0 9px 16px -5px rgba(0,0,0,.5);transform:translateY(-12px);}
.hw-die .duo-pips i{width:7px;height:7px;}
.duo-howto-link{display:inline-flex;align-items:center;gap:4px;margin-top:10px;height:32px;padding:0 12px;border:none;border-radius:var(--radius-full);background:var(--accent-soft);color:var(--accent-ink);font:inherit;font-size:var(--fs-sm);font-weight:var(--fw-bold);}
/* 대기실 다듬기: 방 설정은 칩이 아니라 아이콘과 글자 한 줄(눌리지 않는 정보), 자리판 머리에 사람 수, 코드는 눌러 복사 */
.duo-meta{display:flex;flex-wrap:wrap;align-items:center;gap:4px 14px;margin:8px 0 0;font-size:var(--fs-md);font-weight:var(--fw-bold);color:var(--text-mid);}
.duo-meta span{display:inline-flex;align-items:center;gap:4px;}
.duo-meta.mf-pool{margin-top:4px;font-size:var(--fs-sm);font-weight:var(--fw-regular);}
.duo-seats-h{grid-column:1/-1;display:flex;align-items:center;justify-content:space-between;margin:-4px 8px 0;font-size:var(--fs-md);}
.duo-seats-h b{font-weight:var(--fw-bold);color:var(--text-mid);}
.duo-seats-h span{font-weight:800;font-variant-numeric:tabular-nums;}
.duo-code-b{flex:1;display:flex;align-items:center;gap:6px;min-width:0;padding:0;border:none;background:none;color:inherit;font:inherit;font-size:19px;font-weight:800;letter-spacing:.14em;font-variant-numeric:tabular-nums;text-align:left;}
.duo-code-b{flex-direction:column;align-items:flex-start;justify-content:center;gap:1px;}
.duo-code-b small{font-size:var(--fs-sm);font-weight:var(--fw-bold);letter-spacing:0;color:var(--text-mid);}
.duo-code-b b{white-space:nowrap;letter-spacing:.04em;}
/* 대기실 아래 줄: 초대 코드 | 시작하기(또는 기다림 안내) 두 칸. 채팅은 맨 아래 입력칸 바로 위에 붙는다 */
.duo-lobby-row{display:grid;grid-template-columns:auto minmax(0,1fr);gap:10px;}
.duo-lobby-row > *{min-height:60px;height:auto;margin:0;}
.duo-lobby-row .duo-code{gap:6px;padding:0 8px 0 16px;}
.duo-lobby-row .duo-wait{padding:0 10px;font-size:var(--fs-sm);line-height:1.35;}
/* 혼자 기다릴 때 안내(빠른 입장 30초 뒤, §duo-games.js waitHint): 방 설정 줄(.duo-row) 모양의 버튼, 머리 한 줄과 닫기 */
.duo-alone{padding:2px 0;}
.duo-alone-h{display:flex;align-items:center;justify-content:space-between;margin:0;padding:4px 4px 0 16px;font-size:var(--fs-lg);font-weight:var(--fw-bold);}
.duo-alone-x{display:grid;place-items:center;width:44px;height:44px;margin:-10px 0;border:none;background:none;color:var(--text-light);}
.duo-alone .duo-row{width:100%;min-height:44px;padding:4px 14px 4px 16px;border:none;background:none;color:var(--text);text-align:left;font:inherit;}
.duo-alone .duo-row + .duo-row::before{left:60px;}
.duo-alone .duo-row-text{gap:0;}
.duo-alone .duo-row-text b{font-size:var(--fs-base);}
.duo-code-ic{width:38px;height:38px;padding:0;justify-content:center;}
/* 대기실 위쪽 장면(§ui/components/duo-scenes.js): 화면 위 끝부터 320px, 아래만 바탕으로 흐려진다. 375px 칸을 가운데 둔다 */
.duo-scene{position:absolute;left:0;right:0;top:0;height:calc(env(safe-area-inset-top) + var(--lm) + 79px);padding-top:env(safe-area-inset-top);box-sizing:border-box;z-index:-1;overflow:hidden;pointer-events:none;-webkit-mask-image:linear-gradient(#000 92%,transparent);mask-image:linear-gradient(#000 92%,transparent);}
.duo-scene:empty{display:none;}
.duo-sc{position:relative;width:375px;height:100%;margin:0 auto;}
.duo-sc-at{position:absolute;display:block;}
.duo-sc-paper{position:absolute;left:28px;right:28px;top:62px;height:196px;border-radius:6px;background:#fff;box-shadow:0 10px 24px -12px rgba(0,0,0,.35);transform:rotate(-2deg);}
.duo-sc-colors{position:absolute;left:0;right:0;bottom:-34px;display:flex;justify-content:center;gap:8px;}
.duo-sc-colors i{width:22px;height:22px;border-radius:50%;box-shadow:0 0 0 3px #fff,0 3px 6px rgba(0,0,0,.2);}
.duo-sc-card{box-sizing:border-box;padding:12px 14px;border:2.5px solid #16204d;border-radius:20px;background:#fff;box-shadow:0 3px 0 #16204d;color:#16204d;}
.duo-sc-card small{display:block;font-size:12px;font-weight:700;color:#5b6aa6;}
.duo-sc-card b{display:block;margin-top:2px;font-size:19px;font-weight:800;}
.duo-sc-card.is-guess{background:#ffd43b;}
.duo-sc-card.is-guess small{color:#16204d;opacity:.7;}
.duo-sc-card.is-guess b{font-size:22px;font-weight:900;}
.duo-sc-pic{display:grid;place-items:center;padding:8px;}
.duo-sc-back{display:grid;place-items:center;width:76px;height:108px;border-radius:10px;background:#25274a;box-shadow:inset 0 0 0 3px #3a3d6b,0 10px 18px -8px rgba(0,0,0,.6);color:#5e63a8;font-size:34px;font-weight:900;}
.duo-sc-slip{display:flex;flex-direction:column;align-items:center;justify-content:center;gap:4px;width:100px;height:136px;border-radius:4px;background:#fffdf5;box-shadow:0 14px 24px -10px rgba(0,0,0,.6);color:#2a2418;}
.duo-sc-slip small{font-size:11px;font-weight:700;color:#7a6236;}
.duo-sc-slip b{font-size:30px;font-weight:900;}
.duo-sc-slip em{margin-top:6px;padding:0 8px;border:3px solid #c8302c;border-radius:6px;color:#c8302c;font-style:normal;font-size:14px;font-weight:900;transform:rotate(-8deg);}
.duo-sc .duo-die{width:64px;height:64px;}
/* 스파이 대기실: 서류철은 장면 아래에서 시작 */
.duo.is-lobby[data-game="spy"]::before{top:calc(env(safe-area-inset-top) + var(--lm) + 45px);}
.duo.is-lobby[data-game="spy"]::after{top:calc(env(safe-area-inset-top) + var(--lm) + 23px);}
/* 장면은 위 버튼 아래 14px부터 제목 위 14px까지(스파이는 서류철 탭 위 10px까지) 칸 가운데에 온다. --my는 375px 칸 안 그림의 위아래 가운데, --s는 배율 */
.duo-sc{--cy:64.5px;transform-origin:50% 0;transform:translateY(calc(var(--cy) + var(--lm) / 2 - var(--my) * var(--s) * var(--ak))) scale(calc(var(--s) * var(--ak)));}
.duo[data-game="draw"] .duo-sc{--my:185px;--s:.64;}
.duo[data-game="gartic"] .duo-sc{--my:173px;--s:.75;}
.duo[data-game="spy"] .duo-sc{--cy:45px;--my:146px;--s:.83;--ak:clamp(.2,(var(--lmn) - 64) / 119,1.3);}
/* 짧은 폰은 버튼과 제목 사이에 그림 들어갈 칸이 없어 장면을 숨긴다 */
.duo-sc{opacity:clamp(0,(var(--lmn) - 90) / 10,1);}
.duo[data-game="yacht"] .duo-sc{--my:142px;--s:1.05;}
/* 들어온 순서 번호: 얼굴 오른쪽 아래 작은 동그라미. 채팅 말풍선의 작은 얼굴에는 이름에 번호가 있어 뺀다 */
/* 낙서 릴레이 앨범 제목 앞 이야기 주인 얼굴 */
.duo-title-face{display:inline-block;vertical-align:-6px;margin-right:10px;line-height:0;}
.duo-title-face .avatar{width:34px;height:34px;}
.duo-face-no{position:relative;display:inline-block;flex:none;line-height:0;}
.duo-face-no > i{position:absolute;right:-3px;bottom:-3px;min-width:18px;height:18px;padding:0 4px;box-sizing:border-box;border-radius:9px;background:var(--gray-900);color:#fff;box-shadow:0 0 0 2px #fff;font-style:normal;font-size:11px;font-weight:800;line-height:18px;text-align:center;}
.duo-msg:not(.is-ok){display:flex;align-items:center;gap:6px;}
.duo-msg:not(.is-ok) b{margin-right:0;flex:none;}
.duo-msg-face{display:flex;flex:none;}
.duo-msg-face .avatar{width:22px;height:22px;padding:0!important;font-size:11px!important;font-weight:800;line-height:1;}
.duo-msg-face .duo-face-no > i{display:none;}
.duo-wait.is-need{background:none;border:2px dashed currentColor;box-shadow:none;}
/* 대기실 기다림 안내는 버튼처럼 보이지 않게 글자만 */
.duo.is-lobby .duo-wait:not(.is-need){background:none;border:none;box-shadow:none;}
.duo-seat.is-empty.is-ghost .duo-seat-face{opacity:.3;}
@media (prefers-reduced-motion: reduce){.duo,.duo-page{transition:opacity .2s;transform:none!important;}.duo-dice .duo-die,.duo-cta.is-call{animation:none;opacity:1;}.duo-dots i{animation:none;opacity:.6;}}
/* 미니게임 화면 묶음 머리: 제목과 한 줄 설명, 오른쪽 버튼(같이 하기의 [코드 입력]) */
.gh-group-head{display:flex;align-items:flex-end;justify-content:space-between;gap:12px;margin-bottom:12px;}
.gh-group-head p{margin-bottom:0;}
.duo-duel-streak{display:flex;flex-direction:column;align-items:center;gap:2px;padding:84px 0 16px;text-shadow:0 1px 3px rgba(0,0,0,.35);}
.duo-duel-streak b{font-size:34px;line-height:1;}
.duo-duel-streak span{font-size:var(--fs-sm);font-weight:var(--fw-bold);color:rgba(255,255,255,.85);}
.gdc-game small{margin-left:6px;font-weight:var(--fw-bold);color:rgba(255,255,255,.7);}
.duo-invite-card.is-over{filter:saturate(.15);opacity:.8;}
/* 게임 중 떠오르는 채팅(§actions/duo-games.js render, 2026-10-08 사용자가 고른 C. Instagram 라이브 댓글처럼).
   켠 채팅 버튼은 게임 강조색으로 차고, 최근 메시지 넷이 반투명 줄로 아래 자리 위에 뜬다. 줄은 터치가 통과한다 */
.duo .gp-btn[aria-pressed]{opacity:1;}
/* 소리 버튼: 끄면 빗금 아이콘에 흐린 글자색(버튼 바탕은 그대로) */
.duo .gp-btn.duo-audio.is-off{color:var(--gray-400);}
.duo .gp-btn.duo-chat-btn.is-on{background:var(--accent,var(--gray-900));color:#fff;border-color:var(--accent,var(--gray-900));}
/* 판 중 빠른 반응(2026-10-09 시안 C): 위 줄 스티커 버튼, 그 아래에서 펼쳐지는 흰 알약(버튼 쪽에서 열림),
   오른쪽 가장자리를 따라 떠오르는 스티커와 보낸 사람 얼굴. 움직임 줄이기에서는 제자리에서 나타났다 사라진다 */
.duo-rx-btn .duo-fe{width:28px;height:28px;}
.duo .gp-btn.duo-rx-btn[aria-expanded="true"]{background:#fff;box-shadow:0 0 0 2px var(--accent,var(--gray-900));}
.duo-rxp{position:absolute;top:calc(env(safe-area-inset-top) + 68px);right:16px;z-index:5;display:flex;gap:2px;padding:5px;border-radius:var(--radius-full);background:#fff;box-shadow:var(--shadow-pop);transform-origin:top right;opacity:0;visibility:hidden;transform:scale(.95);transition:opacity .16s var(--ease-out),transform .16s var(--ease-out),visibility 0s .16s;}
.duo-rxp.is-open{opacity:1;visibility:visible;transform:none;transition-delay:0s;}
.duo-rxp button{display:grid;place-items:center;width:48px;height:48px;padding:0;border:0;border-radius:50%;background:none;}
.duo-rxp .duo-fe{width:36px;height:36px;transition:transform .12s var(--ease-out);}
.duo-rxp button:active .duo-fe{transform:scale(.9);}
.duo-rxfly{position:absolute;right:12px;z-index:4;width:60px;height:0;pointer-events:none;}
/* 시작 확인(레디, B안): 게임 색 화면 가득, 가운데 남은 초 동그라미, 아래 큰 노란 버튼. 가끔 뜨는 큰 화면이라 0.22초 페이드와 살짝 커지기만 */
.duo-ready{position:absolute;inset:0;z-index:20;display:flex;flex-direction:column;align-items:center;padding:calc(env(safe-area-inset-top) + 96px) 16px calc(env(safe-area-inset-bottom) + 24px);background:var(--ready-bg,#1a1a1a);color:#fff;text-align:center;}
.duo-ready[hidden]{display:none;}
.duo-ready:not([hidden]){animation:duo-ready-in .22s var(--ease-out);}
@keyframes duo-ready-in{from{opacity:0;transform:scale(.97);}}
.duo-ready-x{position:absolute;top:calc(env(safe-area-inset-top) + 6px);left:16px;}
.duo-ready-game{margin:0;font-size:var(--fs-lg);opacity:.85;}
.duo-ready-h{margin:6px 0 0;font-size:34px;font-weight:800;letter-spacing:-.03em;}
.duo-ready-ring{position:relative;width:200px;height:200px;margin:40px 0 36px;}
.duo-ready-ring svg{width:100%;height:100%;transform:rotate(-90deg);}
.duo-ready-ring circle{fill:none;stroke:rgba(255,255,255,.18);stroke-width:14;}
.duo-ready-ring .is-left{stroke:#f5c518;stroke-linecap:round;stroke-dasharray:100;transition:stroke-dashoffset .25s linear;}
.duo-ready-n{position:absolute;inset:0;display:grid;place-items:center;font-size:72px;font-weight:800;font-variant-numeric:tabular-nums;}
.duo-ready-who{display:flex;flex-wrap:wrap;justify-content:center;gap:12px 18px;}
.duo-ready-p{display:flex;flex-direction:column;align-items:center;gap:6px;font-size:var(--fs-sm);opacity:.55;}
.duo-ready-p.is-ok{opacity:1;}
.duo-ready-ok{position:absolute;right:-4px;bottom:-2px;display:grid;place-items:center;width:24px;height:24px;border-radius:50%;background:#f5c518;color:#1a1a1a;box-shadow:0 0 0 3px var(--ready-bg,#1a1a1a);}
.duo-ready-go{display:flex;align-items:center;justify-content:center;gap:8px;width:100%;height:64px;margin-top:auto;border:none;border-radius:var(--radius-full);background:#f5c518;color:#1a1a1a;font-size:20px;font-weight:800;box-shadow:0 6px 0 #c99a00;transition:transform .12s var(--ease-out);}
.duo-ready-go:active{transform:scale(.97);}
.duo-ready-go:disabled{background:rgba(255,255,255,.2);color:#fff;box-shadow:none;}
@media (prefers-reduced-motion:reduce){.duo-ready:not([hidden]){animation-name:duo-ready-fade;}.duo-ready-ring .is-left{transition:none;}}
@keyframes duo-ready-fade{from{opacity:0;}}
.duo-rxf{position:absolute;right:var(--x,0);bottom:0;display:flex;flex-direction:column;align-items:center;animation:duo-rx-up 2s var(--ease-out) forwards;}
.duo-rxf .duo-fe{width:44px;height:44px;filter:drop-shadow(0 6px 8px rgba(0,0,0,.2));}
.duo-rxf .duo-msg-face{margin-top:-10px;border-radius:50%;box-shadow:0 0 0 2px #fff;}
@keyframes duo-rx-up{0%{opacity:0;transform:translateY(0) scale(.9);}10%{opacity:1;transform:translateY(-16px);}70%{opacity:1;}100%{opacity:0;transform:translateY(-180px);}}
@keyframes duo-rx-fade{0%,100%{opacity:0;}10%,70%{opacity:1;}}
/* 아래 .duo * 움직임 끄기보다 앞서서, 움직임 줄이기에서도 떠오르는 대신 제자리에서 흐려지게 둔다 */
@media (prefers-reduced-motion:reduce){.duo-rxp,.duo-rxp button:active .duo-fe{transform:none;}.duo .duo-rxf{animation:duo-rx-fade 2s linear forwards!important;}}
.duo-float{position:absolute;left:12px;right:12px;z-index:3;display:flex;flex-direction:column;gap:8px;pointer-events:none;}
.duo-float[hidden]{display:none;}
.duo-float-log{display:flex;flex-direction:column;align-items:flex-start;gap:6px;max-width:82%;}
.duo-float-log > :nth-last-child(n+5){display:none;}
.duo .duo-float .duo-msg{max-width:100%;padding:6px 12px 6px 6px;border:none;border-radius:18px;background:rgba(0,0,0,.5);box-shadow:none;color:#fff;-webkit-backdrop-filter:blur(8px);backdrop-filter:blur(8px);}
.duo .duo-float .duo-msg b{color:rgba(255,255,255,.75);}
.duo .duo-float .duo-msg.is-ok{background:rgba(48,164,108,.85);padding-left:12px;}
.duo-float-in{display:flex;gap:8px;pointer-events:auto;}
.duo-float-in input{flex:1;min-width:0;height:44px;padding:0 16px;border:1px solid rgba(255,255,255,.45);border-radius:22px;background:rgba(0,0,0,.4);color:#fff;font-size:16px;-webkit-backdrop-filter:blur(8px);backdrop-filter:blur(8px);}
.duo-float-in input::placeholder{color:rgba(255,255,255,.75);}
.duo-float-in .duo-send{width:44px;height:44px;}
/* 같이 하기 움직임(2026-10-08). 레퍼런스(노션 레퍼런스 움직임 효과): Animista slide-in-bottom과 bounce-in을 짧고 부드럽게 줄인 것,
   BeUI처럼 살짝 넘쳤다 돌아오는 쫀득한 스프링, Kawai Text Animation처럼 제목이 톡 올라오기, Design Spells처럼 고른 것만 작게 튀기.
   - 장면이 바뀌면(§actions/duo-games.js render의 is-entering, 0.9초) 제목이 톡, 판의 덩어리와 목록이 차례로 올라온다. 다시 그릴 때는 안 움직인다
   - 새로 들어온 사람, 새 메시지, 새로 맞힌 사람(is-new)만 튀거나 올라온다
   - 누르는 것은 눌리는 만큼 줄었다 스프링으로 돌아온다(scale 속성이라 기울인 카드도 그대로)
   - 대기실 그림은 천천히 둥실, 남은 시간 10초부터 알약이 두근 */
@property --p{syntax:"<percentage>";inherits:true;initial-value:0%;}
.duo,.duo-page{--spring:cubic-bezier(.34,1.56,.64,1);--out:var(--ease-smooth-out);}
@keyframes duoIn{from{opacity:0;transform:translateY(14px);}}
@keyframes duoPop{0%{opacity:0;scale:.6;}60%{opacity:1;scale:1.08;}100%{scale:1;}}
@keyframes duoJust{0%{scale:.92;}55%{scale:1.05;}100%{scale:1;}}
@keyframes duoTitle{from{opacity:0;transform:translateY(10px);scale:.96;}}
@keyframes duoMsg{from{opacity:0;transform:translateY(10px);scale:.92;}}
@keyframes duoFloat{to{translate:0 -6px;}}
@keyframes duoDrop{from{opacity:0;scale:.7;translate:0 -14px;}}
@keyframes duoBeat{50%{scale:1.07;}}
@keyframes duoBar{from{--p:0%;}}
@keyframes duoStamp{0%{opacity:0;scale:2.2;}70%{opacity:1;scale:.94;}100%{opacity:1;scale:1;}}
.duo.is-entering .duo-hud :is(.duo-name,.duo-blanks){animation:duoTitle .5s var(--spring) both;}
.duo.is-entering .duo-hud .duo-status{animation:duoIn .45s var(--out) .08s both;}
.duo.is-entering .duo-body > *,.duo.is-entering .duo-act > *{animation:duoIn .45s var(--out) both;animation-delay:calc(var(--i,0) * 60ms + 40ms);}
.duo.is-entering .duo-body > *:nth-child(2){--i:1;}.duo.is-entering .duo-body > *:nth-child(3){--i:2;}.duo.is-entering .duo-body > *:nth-child(4){--i:3;}.duo.is-entering .duo-body > *:nth-child(5){--i:4;}.duo.is-entering .duo-body > *:nth-child(6){--i:5;}
.duo.is-entering :is(.duo-option,.duo-poll-row,.duo-rank li,.duo-tally li,.duo-who-row,.duo-yb-t,.duo-seat,.duo-words span){animation:duoIn .4s var(--out) both;animation-delay:calc(var(--i,0) * 45ms + 120ms);}
.duo.is-entering :is(.duo-option,.duo-poll-row,.duo-rank li,.duo-tally li,.duo-who-row,.duo-yb-t,.duo-seat,.duo-words span):nth-child(2){--i:1;}.duo.is-entering :is(.duo-option,.duo-poll-row,.duo-rank li,.duo-tally li,.duo-who-row,.duo-yb-t,.duo-seat,.duo-words span):nth-child(3){--i:2;}.duo.is-entering :is(.duo-option,.duo-poll-row,.duo-rank li,.duo-tally li,.duo-who-row,.duo-yb-t,.duo-seat,.duo-words span):nth-child(4){--i:3;}.duo.is-entering :is(.duo-option,.duo-poll-row,.duo-rank li,.duo-tally li,.duo-who-row,.duo-yb-t,.duo-seat,.duo-words span):nth-child(5){--i:4;}.duo.is-entering :is(.duo-option,.duo-poll-row,.duo-rank li,.duo-tally li,.duo-who-row,.duo-yb-t,.duo-seat,.duo-words span):nth-child(6){--i:5;}.duo.is-entering :is(.duo-option,.duo-poll-row,.duo-rank li,.duo-tally li,.duo-who-row,.duo-yb-t,.duo-seat,.duo-words span):nth-child(7){--i:6;}.duo.is-entering :is(.duo-option,.duo-poll-row,.duo-rank li,.duo-tally li,.duo-who-row,.duo-yb-t,.duo-seat,.duo-words span):nth-child(8){--i:7;}.duo.is-entering :is(.duo-option,.duo-poll-row,.duo-rank li,.duo-tally li,.duo-who-row,.duo-yb-t,.duo-seat,.duo-words span):nth-child(9){--i:8;}.duo.is-entering :is(.duo-option,.duo-poll-row,.duo-rank li,.duo-tally li,.duo-who-row,.duo-yb-t,.duo-seat,.duo-words span):nth-child(10){--i:9;}.duo.is-entering :is(.duo-option,.duo-poll-row,.duo-rank li,.duo-tally li,.duo-who-row,.duo-yb-t,.duo-seat,.duo-words span):nth-child(11){--i:10;}.duo.is-entering :is(.duo-option,.duo-poll-row,.duo-rank li,.duo-tally li,.duo-who-row,.duo-yb-t,.duo-seat,.duo-words span):nth-child(12){--i:11;}
.duo.is-entering .duo-album li{animation:duoIn .5s var(--out) both;animation-delay:calc(var(--i,0) * 160ms + 120ms);}
.duo.is-entering .duo-album li:nth-child(2){--i:1;}.duo.is-entering .duo-album li:nth-child(3){--i:2;}.duo.is-entering .duo-album li:nth-child(4){--i:3;}.duo.is-entering .duo-album li:nth-child(5){--i:4;}.duo.is-entering .duo-album li:nth-child(6){--i:5;}.duo.is-entering .duo-album li:nth-child(7){--i:6;}.duo.is-entering .duo-album li:nth-child(8){--i:7;}
.duo.is-entering .duo-boom{animation:duoPop .5s var(--spring) both;animation-delay:calc(var(--i,0) * 160ms + 500ms);}
.duo.is-entering .duo-hero .duo-face-xl{animation:duoPop .6s var(--spring) .1s both;}
.duo.is-entering[data-game="spy"] .duo-hero .duo-face-xl::after{animation:duoStamp .45s var(--out) .55s both;}
.duo.is-entering .duo-tally i{animation:duoBar .9s var(--out) .35s both;}
.duo.is-entering .duo-turn{animation:duoIn .4s var(--out) both;animation-delay:calc(var(--i,0) * 45ms + 120ms);}
@keyframes duoDrain{to{transform:scaleX(0);}}
.duo-seat.is-new .duo-seat-face,.duo-chip.is-new{animation:duoPop .5s var(--spring) both;}
.duo-msg.is-new{animation:duoMsg .32s var(--out) both;transform-origin:0 100%;}
.duo-sc-at{animation:duoFloat 3.4s ease-in-out infinite alternate;}
.duo-sc-at:nth-child(even){animation-duration:4.1s;animation-direction:alternate-reverse;}
.duo.is-entering .duo-sc-at{animation:duoDrop .55s var(--spring) both,duoFloat 3.4s ease-in-out .55s infinite alternate;animation-delay:calc(var(--i,0) * 70ms),calc(var(--i,0) * 70ms + .55s);}
.duo.is-entering .duo-sc-at:nth-child(2){--i:1;}.duo.is-entering .duo-sc-at:nth-child(3){--i:2;}.duo.is-entering .duo-sc-at:nth-child(4){--i:3;}.duo.is-entering .duo-sc-at:nth-child(5){--i:4;}.duo.is-entering .duo-sc-at:nth-child(6){--i:5;}.duo.is-entering .duo-sc-at:nth-child(7){--i:6;}
.duo-timer.is-low{animation:duoBeat 1s ease-in-out infinite;}
.duo :is(.duo-cta,.duo-pill,.duo-option,.duo-poll-row,.duo-idea,.duo-code-b,.duo-seat,.duo-rx-b,.duo-yb-t),.duo-page :is(.duo-cta,.duo-seg button,.duo-stepper button,.duo-chip-btn){transition:scale .25s var(--spring),background-color .2s,border-color .2s,color .2s;}
.duo :is(.duo-cta,.duo-pill,.duo-option,.duo-poll-row,.duo-idea,.duo-code-b,.duo-seat,.duo-rx-b,.duo-yb-t):active:not(:disabled),.duo-page :is(.duo-cta,.duo-seg button,.duo-stepper button,.duo-chip-btn):active:not(:disabled){scale:.95;transition-duration:.08s;}
.duo-page .is-just:not(.duo-vis){animation:duoJust .35s var(--spring);}
/* 공개 범위 카드: 튀지 않고, 고른 카드에 테두리가 스며들고 아이콘이 게임 색으로 바뀐다 */
@keyframes duoVisOn{from{border-color:transparent;}}
.duo-vis{transition:background-color .2s;}
.duo-vis.is-on svg{color:var(--accent,var(--gray-900));}
.duo-vis.is-just{animation:duoVisOn .25s ease-out;}
.duo-vis.is-just svg{animation:duoIn .25s ease-out;}
.duo-vis:active{background:var(--gray-50,#f7f7f7);}
.duo .duo-chat-btn.is-on{animation:duoJust .35s var(--spring);}
.duo-page.is-entering .duo-page-body > *{animation:duoIn .45s var(--out) both;animation-delay:calc(var(--i,0) * 60ms + 60ms);}
.duo-page.is-entering .duo-page-body > *:nth-child(2){--i:1;}.duo-page.is-entering .duo-page-body > *:nth-child(3){--i:2;}.duo-page.is-entering .duo-page-body > *:nth-child(4){--i:3;}.duo-page.is-entering .duo-page-body > *:nth-child(5){--i:4;}.duo-page.is-entering .duo-page-body > *:nth-child(6){--i:5;}
.duo-page.is-entering .duo-page-foot{animation:duoIn .45s var(--out) .3s both;}
@media (prefers-reduced-motion: reduce){.duo *,.duo *::after,.duo-page *{animation:none!important;transition:none!important;}}
/* 주사위 굴림 3D 층(§actions/duo-games.js throwDice, §ui/dice3d.js). 판 칸 위에 투명한 캔버스, 다 멈추면 흐려진다 */
.duo-throw{position:absolute;z-index:6;pointer-events:none;}
.duo-dice3d{position:absolute;inset:0;width:100%;height:100%;transition:opacity .26s;}

/* 친구 초대 화면(§screens/mypage.js renderInvites). 남은 장수만 --primary-dark 굵은 숫자로 강조한다. */
.invite-summary{background:var(--gray-0);border-radius:var(--radius-lg);corner-shape:squircle;box-shadow:var(--shadow-sm);padding:20px 18px 18px;text-align:center;}
.invite-summary-label{font-size:var(--fs-sm);font-weight:var(--fw-bold);color:var(--text-light);}
.invite-summary-count{display:flex;align-items:baseline;justify-content:center;gap:6px;margin:6px 0 2px;font-size:var(--fs-xl);font-weight:var(--fw-bold);color:var(--primary-dark);}
.invite-summary-count strong{font-size:40px;line-height:1.1;letter-spacing:-.02em;}
.invite-summary-count span{font-size:var(--fs-md);color:var(--text-mid);}
.invite-summary-sub{font-size:var(--fs-sm);color:var(--text-mid);margin-bottom:16px;}
.invite-rules{margin:12px 4px 0;line-height:1.5;}
.invite-row{display:flex;align-items:center;gap:12px;padding:14px 16px;}
.invite-row+.invite-row{border-top:1px solid var(--border);}
.invite-row-main{flex:1;min-width:0;}
.invite-code{font-size:var(--fs-xl);font-weight:var(--fw-bold);letter-spacing:.14em;color:var(--primary-dark);font-variant-numeric:tabular-nums;}
.invite-row-detail{margin-top:2px;font-size:var(--fs-xs);color:var(--text-light);}
.invite-row.is-inactive .invite-code{color:var(--text-light);text-decoration:line-through;text-decoration-thickness:1px;}
.invite-state{flex-shrink:0;font-size:var(--fs-sm);font-weight:var(--fw-bold);color:var(--text-mid);}
.invite-copy{display:inline-flex;align-items:center;gap:4px;flex-shrink:0;}

/* 카페 인증 화면(§screens/auth.js renderCafeVerify). 가입 직후 온보딩 첫 화면과 설정의 "카페 인증"이 같은 화면을 쓴다 */
.cafe-verify-page{padding:44px 20px 32px;box-sizing:border-box;display:flex;flex-direction:column;}
.cafe-verify-title{margin:8px 0 6px;}
.cafe-verify-lead{margin:0 0 18px;}
.cafe-verify-steps{display:flex;flex-direction:column;gap:10px;margin:0 0 22px;padding:0 0 0 20px;font-size:var(--fs-md);line-height:1.5;color:var(--text);}
.cafe-verify-pick{display:flex;justify-content:center;width:100%;box-sizing:border-box;overflow:hidden;}
.cafe-verify-pick span{overflow:hidden;text-overflow:ellipsis;white-space:nowrap;}
.cafe-verify-pick.is-busy{opacity:.6;pointer-events:none;}
.cafe-verify-hint{margin:-4px 4px 16px;}
.cafe-verify-submit{margin-top:4px;}
.cafe-verify-next{margin-top:20px;}
.cafe-verify-state{align-self:flex-start;padding:3px 10px;border-radius:var(--radius-full);background:var(--gray-100);font-size:var(--fs-xs);font-weight:var(--fw-bold);color:var(--text-mid);}
.cafe-verify-rejected{display:flex;flex-direction:column;gap:4px;margin:0 0 18px;padding:14px 16px;border-radius:var(--radius-sm);corner-shape:squircle;background:var(--bg2);font-size:var(--fs-sm);color:var(--text-mid);line-height:1.5;}
.cafe-verify-rejected b{color:var(--text);font-weight:var(--fw-bold);}
.cafe-verify-load-error{display:flex;align-items:center;justify-content:space-between;gap:10px;font-size:var(--fs-sm);color:var(--text-mid);}
.cafe-verify-skip{width:100%;margin-top:10px;background:none;color:var(--text-mid);}
.cafe-verify-done{display:flex;flex-direction:column;gap:4px;padding:18px;}
.cafe-verify-done span{font-size:var(--fs-sm);color:var(--text-mid);}
.cafe-verify-note{margin:12px 4px 0;}
/* 내 초대 코드(§screens/mypage.js renderInvites). 멈춘 코드는 흐리게 줄을 긋는다 */
.invite-summary .invite-code{margin:6px 0 4px;font-size:var(--fs-5xl);}
.invite-code.is-stopped{color:var(--text-light);text-decoration:line-through;text-decoration-thickness:1px;}

/* 활동(§screens/notifications.js): 받은 좋아요 한 줄 목록. 인스타그램 활동처럼 사진 오른쪽 아래 작은 하트, 오른쪽 끝 버튼 */
.act-list{padding-bottom:24px;}
.act-sec{margin:18px 0 4px;font-size:var(--fs-md);font-weight:var(--fw-bold);color:var(--text-mid);}
.act-sec:first-child{margin-top:4px;}
.act-row{display:flex;align-items:center;gap:12px;padding:9px 0;cursor:pointer;-webkit-tap-highlight-color:transparent;}
.act-av{position:relative;flex:none;}
.act-av .avatar{width:46px;height:46px;}
.act-badge{position:absolute;right:-2px;bottom:-2px;width:18px;height:18px;border-radius:50%;background:var(--gray-800);border:2px solid var(--bg1);color:var(--gray-0);display:grid;place-items:center;}
.act-badge svg{display:block;}
.act-seat{display:grid;place-items:center;width:46px;height:46px;border-radius:50%;background:var(--gray-100);color:var(--text-mid);font-size:var(--fs-md);font-weight:var(--fw-bold);}
.act-btn:has(svg){display:inline-flex;align-items:center;gap:4px;}
.act-text{flex:1;min-width:0;font-size:var(--fs-base);line-height:1.4;color:var(--text);}
.act-text small{display:block;font-size:var(--fs-sm);color:var(--text-light);}
.act-btn{flex:none;height:32px;padding:0 14px;border:0;border-radius:var(--radius-full);background:var(--gray-800);color:var(--gray-0);font:inherit;font-size:var(--fs-md);font-weight:var(--fw-bold);cursor:pointer;transition:transform .12s var(--ease-smooth-out);}
.act-btn.is-ghost{background:var(--gray-100);color:var(--text);}
.act-btn:active{transform:scale(.95);}
@media(prefers-reduced-motion:reduce){.act-btn{transition:none;}}
/* 오픈 소스 라이선스 시트(§ui/licenses-sheet.js): 본문별 묶음, 눌러야 본문 */
.lic-sheet{max-height:86vh;overflow-y:auto;}
.lic-title{margin:16px 0 6px;font-size:var(--fs-md);color:var(--text-mid);}
.lic-group{border-bottom:1px solid var(--border);padding:10px 0;}
.lic-group summary{cursor:pointer;font-size:var(--fs-md);line-height:1.45;}
.lic-group summary small{margin-left:6px;color:var(--text-light);}
.lic-group pre{margin:8px 0 0;white-space:pre-wrap;word-break:break-word;font-size:var(--fs-2xs);line-height:1.5;color:var(--text-mid);font-family:inherit;}
/* 음성 통화(§ui/voice-call-ui.js, doc/VOICE-CALL-PLAN.md §7, 시안 design/call-mock2.html의 D와 F). #root 밖의 #voiceLayer에 그린다.
   전체 화면은 iOS 통화 화면처럼 왼쪽 위 작은 사진(76px)과 큰 이름, 아래 유리 버튼. 배경은 상대 프로필 사진을 흑백으로 흐리게(45px) 깔고
   어둡게 한 겹 누른다(밝은 사진에서도 글자와 버튼이 읽히게). 색은 무채색, 끊기와 거절은 --alert, 받기와 다시 걸기만 초록.
   모션은 전체 화면 진입(투명도와 0.97 배율), 배너와 작게 보기의 짧은 미끄러짐, 버튼 누름(0.95)뿐이다 */
#voiceLayer{--vc-ok:#34c759;--vc-sheet:#141416;}
.vc{position:fixed;inset:0;z-index:970;color:var(--gray-0);overflow:hidden;-webkit-user-select:none;user-select:none;}
.vc--enter{animation:vcIn var(--duration-fast) var(--ease-smooth-out);}
@keyframes vcIn{from{opacity:0;transform:scale(.97);}to{opacity:1;transform:none;}}
.vc-bg{position:absolute;inset:0;overflow:hidden;background:radial-gradient(130% 70% at 12% 0%,var(--gray-600) 0%,#242427 50%,#0e0e10 100%);}
.vc-bg img{position:absolute;left:-81px;top:-81px;width:calc(100% + 162px);height:calc(100% + 162px);max-width:none;object-fit:cover;filter:grayscale(1) contrast(1.08) blur(45px);}
.vc-bg.has-photo::after{content:"";position:absolute;inset:0;background:linear-gradient(180deg,rgba(0,0,0,.56) 0%,rgba(0,0,0,.42) 36%,rgba(0,0,0,.54) 60%,rgba(0,0,0,.74) 100%);}
.vc-head{position:absolute;left:24px;right:24px;top:calc(env(safe-area-inset-top) + 24px);display:flex;align-items:center;gap:14px;}
.vc-face{width:var(--vc-face,48px);height:var(--vc-face,48px);border-radius:50%;overflow:hidden;flex:none;display:grid;place-items:center;background:var(--gray-600);color:var(--gray-0);transition:box-shadow 120ms ease;}
.vc-face img{width:100%;height:100%;object-fit:cover;display:block;}
.vc-face em{font-style:normal;font-weight:var(--fw-bold);font-size:calc(var(--vc-face,48px) * .36);}
.vc-peer{display:inline-flex;border-radius:50%;}
.vc-peer.is-speaking .vc-face{box-shadow:0 0 0 2.5px rgba(0,0,0,.55),0 0 0 5px var(--gray-0);}
.vc-title{min-width:0;}
.vc-status{display:flex;align-items:center;gap:6px;font-size:var(--fs-xl);opacity:.78;font-variant-numeric:tabular-nums;white-space:pre;}
.vc-title b{display:block;font-size:36px;font-weight:var(--fw-regular);letter-spacing:-.035em;line-height:1.15;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;}
.vc-head.is-group .vc-title b{font-size:32px;}
.vc-wave{flex:none;}
/* 버튼: 유리 동그라미와 아래 이름. 켜진 토글(스피커, 마이크 꺼짐)은 흰색 */
.vc-btn{display:flex;flex-direction:column;align-items:center;gap:8px;padding:0;border:0;background:none;color:var(--gray-0);font:inherit;font-size:var(--fs-sm);cursor:pointer;-webkit-tap-highlight-color:transparent;}
.vc-btn-c{width:72px;height:72px;border-radius:50%;display:grid;place-items:center;background:rgba(255,255,255,.15);-webkit-backdrop-filter:blur(24px) saturate(180%);backdrop-filter:blur(24px) saturate(180%);box-shadow:inset 0 0 0 .6px rgba(255,255,255,.3),inset 0 1px 1px rgba(255,255,255,.18);transition:transform 120ms var(--ease-smooth-out),background-color 120ms ease;}
.vc-btn:active .vc-btn-c{transform:scale(.95);}
.vc-btn-l{opacity:.92;white-space:nowrap;}
.vc-btn.is-on .vc-btn-c{background:var(--gray-0);color:var(--gray-900);}
.vc-btn.is-end .vc-btn-c{background:var(--alert);box-shadow:none;}
.vc-btn.is-ok .vc-btn-c{background:var(--vc-ok);box-shadow:none;}
.vc-btn.is-sm .vc-btn-c{width:50px;height:50px;}
.vc-btn:disabled{opacity:.4;cursor:default;}
.vc-btn:disabled:active .vc-btn-c{transform:none;}
.vc-grid{position:absolute;left:0;right:0;bottom:calc(env(safe-area-inset-bottom) + 22px);display:grid;grid-template-columns:repeat(3,1fr);row-gap:22px;justify-items:center;padding:0 22px;}
.vc-grid.is-one{bottom:calc(env(safe-area-inset-bottom) + 62px);}
.vc-grid.is-four{grid-template-columns:repeat(4,1fr);padding:0 10px;}
.vc-grid.is-four .vc-btn-c{width:64px;height:64px;}
.vc-minor{position:absolute;left:0;right:0;bottom:calc(env(safe-area-inset-bottom) + 142px);display:flex;justify-content:space-between;padding:0 64px;}
.vc-big{position:absolute;left:0;right:0;bottom:calc(env(safe-area-inset-bottom) + 28px);display:flex;justify-content:space-between;padding:0 50px;}
.vc-big .vc-btn-c{width:78px;height:78px;}
.vc-unmute{position:absolute;left:50%;top:calc(env(safe-area-inset-top) + 124px);transform:translateX(-50%);display:inline-flex;align-items:center;gap:8px;padding:10px 16px;border:0;border-radius:var(--radius-full);background:var(--gray-0);color:var(--gray-900);font:inherit;font-size:var(--fs-md);font-weight:var(--fw-bold);white-space:nowrap;cursor:pointer;}
.vc-report{position:absolute;left:0;right:0;bottom:calc(env(safe-area-inset-bottom) + 10px);margin:0 auto;width:max-content;max-width:100%;min-height:44px;padding:0 16px;border:0;background:none;color:rgba(255,255,255,.7);font:inherit;font-size:var(--fs-base);cursor:pointer;}
.vc-report b{color:var(--gray-0);font-weight:var(--fw-bold);margin-left:4px;}
/* 대화 주제 카드(iOS 통화 맥락 카드 자리). 버튼 바로 위에 붙여 작은 화면에서도 이름과 겹치지 않게 아래에서 잰다 */
.vc-topic{position:absolute;left:18px;right:18px;bottom:calc(env(safe-area-inset-bottom) + 256px);padding:16px 18px 6px;border-radius:var(--radius-xl);corner-shape:squircle;background:rgba(255,255,255,.1);-webkit-backdrop-filter:blur(24px);backdrop-filter:blur(24px);box-shadow:inset 0 0 0 .6px rgba(255,255,255,.22);}
.vc-topic-h{display:flex;justify-content:space-between;font-size:var(--fs-md);opacity:.75;}
.vc-topic p{margin:8px 0 6px;font-size:var(--fs-3xl);font-weight:var(--fw-bold);line-height:1.38;letter-spacing:-.025em;word-break:keep-all;}
.vc-topic-f{display:flex;justify-content:space-between;align-items:center;font-size:var(--fs-md);}
.vc-topic-f button{display:inline-flex;align-items:center;gap:2px;min-height:44px;padding:0 0 0 12px;border:0;background:none;color:inherit;font:inherit;opacity:.9;cursor:pointer;}
.vc-dots i{display:inline-block;width:6px;height:6px;border-radius:50%;background:currentColor;opacity:.3;margin-right:5px;}
.vc-dots i.on{opacity:1;}
/* 단체 통화: 사진 격자 대신 목록. 누가 말하는 중이고 누가 마이크를 껐는지 글자로 */
.vc-list{position:absolute;left:14px;right:14px;top:calc(env(safe-area-inset-top) + 120px);max-height:calc(100% - env(safe-area-inset-top) - env(safe-area-inset-bottom) - 290px);overflow-y:auto;padding:4px 0;border-radius:var(--radius-xl);corner-shape:squircle;background:rgba(255,255,255,.08);}
.vc-list.is-empty{display:grid;place-items:center;min-height:80px;color:rgba(255,255,255,.6);}
.vc-row{position:relative;display:flex;align-items:center;gap:13px;width:100%;padding:11px 16px;border:0;background:none;color:inherit;font:inherit;text-align:left;}
button.vc-row{cursor:pointer;}
.vc-row+.vc-row::before{content:"";position:absolute;top:0;left:73px;right:0;height:.5px;background:rgba(255,255,255,.1);}
.vc-row-t{flex:1;min-width:0;}
.vc-row-t b{display:block;font-size:var(--fs-xl);font-weight:var(--fw-bold);overflow:hidden;text-overflow:ellipsis;white-space:nowrap;}
.vc-row-t small{display:flex;align-items:center;font-size:var(--fs-md);opacity:.55;margin-top:1px;}
.vc-say{display:none;align-items:center;gap:5px;}
.vc-row.is-speaking small{opacity:1;}
.vc-row.is-speaking .vc-say{display:inline-flex;}
.vc-row.is-speaking .vc-face{box-shadow:0 0 0 2px rgba(0,0,0,.55),0 0 0 4px var(--gray-0);}
/* 앱을 쓰는 중에 걸려 온 통화 배너. 누르면 전체 받기 화면 */
.vc-banner{position:fixed;left:10px;right:10px;top:calc(env(safe-area-inset-top) + 6px);z-index:976;max-width:460px;margin:0 auto;height:82px;display:flex;align-items:center;gap:10px;padding:0 14px 0 6px;border-radius:30px;background:var(--gray-800);color:var(--gray-0);box-shadow:var(--shadow-pop);animation:vcDrop var(--duration-fast) var(--ease-smooth-out);}
@keyframes vcDrop{from{opacity:0;transform:translateY(-12px);}to{opacity:1;transform:none;}}
.vc-banner-body{flex:1;min-width:0;height:100%;display:flex;align-items:center;gap:12px;padding:0 0 0 8px;border:0;background:none;color:inherit;font:inherit;text-align:left;cursor:pointer;}
.vc-banner-body span{min-width:0;}
.vc-banner-body b{display:block;font-size:var(--fs-2xl);font-weight:var(--fw-bold);overflow:hidden;text-overflow:ellipsis;white-space:nowrap;}
.vc-banner-body small{display:block;margin-top:2px;font-size:var(--fs-md);color:rgba(255,255,255,.65);}
.vc-round{width:46px;height:46px;flex:none;display:grid;place-items:center;border:0;border-radius:50%;color:var(--gray-0);cursor:pointer;transition:transform 120ms var(--ease-smooth-out);}
.vc-round:active{transform:scale(.95);}
.vc-round.is-end{background:var(--alert);}
.vc-round.is-ok{background:var(--vc-ok);}
.vc-round.is-glass{background:rgba(255,255,255,.14);}
.vc-round.is-on{background:var(--gray-0);color:var(--gray-900);}
/* 작게 보기(F): 통화한 대화방에서는 입력칸 위 시트, 그 밖에는 막대. 자리(bottom)는 화면 모듈이 입력칸이나 하단 탭에 맞춘다 */
.vc-mini{position:fixed;left:8px;right:8px;bottom:calc(env(safe-area-inset-bottom) + 12px);z-index:960;max-width:464px;margin:0 auto;color:var(--gray-0);background:var(--vc-sheet);animation:vcUp var(--duration-fast) var(--ease-smooth-out);}
@keyframes vcUp{from{opacity:0;transform:translateY(8px);}to{opacity:1;transform:none;}}
.vc-mini--sheet{padding:12px 16px 20px;border-radius:40px;box-shadow:0 -12px 40px rgba(0,0,0,.25);}
.vc-mini--bar{left:10px;right:10px;height:56px;display:flex;align-items:center;gap:10px;padding:0 8px;border-radius:28px;box-shadow:0 12px 30px -10px rgba(0,0,0,.45);}
.vc-mini--bar.is-top{top:calc(env(safe-area-inset-top) + 6px);bottom:auto;left:50%;right:auto;width:max-content;max-width:calc(100% - 120px);height:40px;gap:8px;padding:0 4px;border-radius:20px;transform:translateX(-50%);animation:none;}
.vc-mini--bar.is-top .vc-face{--vc-face:30px!important;}
.vc-mini--bar.is-top [data-voice="mic"]{display:none;}
.vc-mini--bar.is-top .vc-round{width:32px;height:32px;}
.vc-mini--bar.is-top .vc-bar-body b{font-size:var(--fs-md);}
.vc-mini--bar.is-top .vc-bar-body small{display:none;}
.vc-mini-top{display:grid;grid-template-columns:40px 1fr 40px;align-items:center;text-align:center;}
.vc-mini-top span{min-width:0;}
.vc-mini-top b{display:block;font-size:var(--fs-2xl);font-weight:var(--fw-bold);overflow:hidden;text-overflow:ellipsis;white-space:nowrap;}
.vc-mini-top small{font-size:var(--fs-md);color:rgba(255,255,255,.6);font-variant-numeric:tabular-nums;}
.vc-chip{width:38px;height:38px;display:grid;place-items:center;border:0;border-radius:50%;background:rgba(255,255,255,.1);color:inherit;cursor:pointer;}
.vc-mini-people{display:flex;justify-content:center;gap:16px;margin:18px 0 20px;}
.vc-mp{width:62px;display:flex;flex-direction:column;align-items:center;gap:8px;}
.vc-mp b{max-width:100%;font-size:var(--fs-md);font-weight:var(--fw-regular);opacity:.85;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;}
.vc-mp-face{position:relative;display:inline-flex;}
.vc-mp-wave{position:absolute;left:50%;bottom:-8px;height:18px;padding:0 6px;display:none;place-items:center;border-radius:9px;background:var(--gray-0);color:var(--gray-900);transform:translateX(-50%);}
.vc-mp-wave .vc-wave{width:12px;height:10px;}
.vc-mp.is-speaking .vc-face{box-shadow:0 0 0 2.5px var(--vc-sheet),0 0 0 5px var(--gray-0);}
.vc-mp.is-speaking .vc-mp-wave{display:grid;}
.vc-mini-btns{display:flex;justify-content:space-around;}
.vc-mini-btns .vc-btn-c{width:60px;height:60px;background:rgba(255,255,255,.12);-webkit-backdrop-filter:none;backdrop-filter:none;box-shadow:none;}
.vc-mini-btns .vc-btn.is-on .vc-btn-c{background:var(--gray-0);}
.vc-mini-btns .vc-btn.is-end .vc-btn-c{background:var(--alert);}
.vc-bar-body{flex:1;min-width:0;height:100%;display:flex;align-items:center;gap:10px;padding:0;border:0;background:none;color:inherit;font:inherit;text-align:left;cursor:pointer;}
.vc-bar-body span{min-width:0;}
.vc-bar-body b{display:block;font-size:var(--fs-lg);font-weight:var(--fw-bold);overflow:hidden;text-overflow:ellipsis;white-space:nowrap;}
.vc-bar-body small{display:flex;align-items:center;gap:5px;font-size:var(--fs-md);color:rgba(255,255,255,.7);font-variant-numeric:tabular-nums;}
.vc-mini--bar .vc-round{width:40px;height:40px;}
/* 앱의 시트나 팝업이 열리면 작게 보기는 잠깐 숨긴다(아래 버튼을 가리지 않게) */
body:has(.sheet-overlay) .vc-mini,body:has(.center-modal-overlay) .vc-mini{visibility:hidden;}
/* 통화 화면 위의 시트: 더보기, 같이 하기, 메시지로 거절, 방장 메뉴 */
.vc-dim{position:fixed;inset:0;z-index:972;background:rgba(0,0,0,.4);}
.vc-sheet-in{position:fixed;left:8px;right:8px;bottom:calc(env(safe-area-inset-bottom) + 8px);z-index:973;max-width:464px;margin:0 auto;padding:10px 20px 18px;border-radius:40px;color:var(--gray-0);background:rgba(32,32,36,.86);-webkit-backdrop-filter:blur(30px) saturate(180%);backdrop-filter:blur(30px) saturate(180%);box-shadow:inset 0 0 0 .6px rgba(255,255,255,.2);animation:vcUp var(--duration-fast) var(--ease-smooth-out);}
.vc-grab{display:block;width:38px;height:5px;margin:0 auto 14px;border-radius:3px;background:rgba(255,255,255,.3);}
.vc-sheet-in h4{margin:4px 0 12px;font-size:var(--fs-2xl);font-weight:var(--fw-bold);text-align:center;}
.vc-item{width:100%;height:52px;display:flex;align-items:center;gap:14px;padding:0 6px;border:0;background:none;color:inherit;font:inherit;font-size:var(--fs-xl);text-align:left;cursor:pointer;}
.vc-item.is-warn{color:#ff6b5e;}
.vc-quick{width:100%;height:54px;display:flex;align-items:center;margin-top:8px;padding:0 18px;border:0;border-radius:var(--radius-lg);corner-shape:squircle;background:rgba(255,255,255,.1);color:inherit;font:inherit;font-size:var(--fs-xl);text-align:left;cursor:pointer;}
.vc-quick.is-mute{color:rgba(255,255,255,.65);}
.vc-who{display:flex;align-items:center;gap:12px;margin-bottom:6px;padding:4px 4px 14px;border-bottom:.5px solid rgba(255,255,255,.14);}
.vc-who b{display:block;font-size:var(--fs-2xl);font-weight:var(--fw-bold);}
.vc-who small{font-size:var(--fs-md);color:rgba(255,255,255,.6);}
.vc-sheet-in .duel-tile{color:inherit;cursor:pointer;}
body.voice-open .toast-wrap{z-index:980;}
/* 작게 보기가 하단 탭 위에 붙어 있으면 목록 끝이 가리지 않게 그만큼 더 띄운다(대화방은 §chat-input-runtime.js가 --voice-dock을 더한다) */
body.voice-docked .main:not(.chatroom-main){padding-bottom:calc(96px + env(safe-area-inset-bottom) + var(--voice-dock,0px));}
/* 대화방의 통화 버튼과 단체 대화방의 "N명 통화 중" 줄 */
.chatroom-call-btn{color:var(--text);}
.party-voice-banner{display:flex;align-items:center;gap:10px;width:calc(100% - 32px);margin:0 16px 8px;padding:10px 14px;border:0;border-radius:var(--radius-lg);corner-shape:squircle;background:var(--gray-50);color:var(--text);font:inherit;font-size:var(--fs-md);text-align:left;cursor:pointer;}
.party-voice-banner-text{flex:1;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;}
.party-voice-banner-action{font-weight:var(--fw-bold);flex:0 0 auto;}
/* 단체방 유리 머리 바로 아래에 떠 있는 띠(메시지는 그 밑으로 지나간다) */
.chatroom-main .party-voice-banner{position:absolute;z-index:21;top:calc(env(safe-area-inset-top) + 62px);left:16px;right:16px;width:auto;margin:0;border-radius:var(--radius-full);}
/* 단체 통화 들어가기 전 시트(§actions/voice.js partyVoiceSheetHtml) */
.pvs-h{margin:2px 0 16px;text-align:center;}
.pvs-h b{display:block;font-size:var(--fs-2xl);font-weight:var(--fw-bold);}
.pvs-h small{display:block;margin-top:2px;font-size:var(--fs-md);color:var(--text-mid);}
.pvs-people{display:flex;justify-content:center;gap:18px;margin-bottom:20px;}
.pvs-p{width:72px;display:flex;flex-direction:column;align-items:center;gap:4px;}
.pvs-f{width:64px;height:64px;display:grid;place-items:center;overflow:hidden;border-radius:50%;background:var(--gray-200);}
.pvs-f img{width:100%;height:100%;object-fit:cover;display:block;}
.pvs-f em{font-style:normal;font-size:var(--fs-3xl);color:var(--gray-600);}
.pvs-p b{max-width:100%;font-size:var(--fs-base);font-weight:var(--fw-bold);overflow:hidden;text-overflow:ellipsis;white-space:nowrap;}
.pvs-p small{min-height:15px;font-size:var(--fs-sm);color:var(--text-light);}
.pvs-go{width:100%;margin-top:16px;}
@media (prefers-reduced-motion: reduce){.vc--enter,.vc-banner,.vc-mini,.vc-sheet-in{animation-name:vcFade;}.vc-btn:active .vc-btn-c,.vc-round:active{transform:none;}}
@keyframes vcFade{from{opacity:0;}to{opacity:1;}}
/* 채팅의 통화 기록 말풍선: 아이콘 동그라미, 종류, 통화 시간. 놓친 통화는 빨간 동그라미와 아래 다시 걸기 */
.chat-call-log{display:block;min-width:208px;padding:0;border:0;border-radius:20px;corner-shape:squircle;overflow:hidden;background:var(--gray-100);color:var(--text);font:inherit;text-align:left;cursor:pointer;}
.chat-call-log.is-mine{background:var(--gray-800);color:var(--gray-0);}
.ccl-top{display:flex;align-items:center;gap:11px;padding:10px 16px 10px 10px;}
.ccl-ic{width:38px;height:38px;flex:none;display:grid;place-items:center;border-radius:50%;background:var(--gray-0);color:var(--text);}
.chat-call-log.is-mine .ccl-ic{background:rgba(255,255,255,.16);color:var(--gray-0);}
.chat-call-log.is-missed .ccl-ic{background:var(--alert);color:var(--gray-0);}
.ccl-top b{display:block;font-size:var(--fs-lg);font-weight:var(--fw-bold);}
.ccl-top small{display:block;margin-top:1px;font-size:var(--fs-md);color:var(--text-mid);}
.chat-call-log.is-mine .ccl-top small{color:rgba(255,255,255,.65);}
.ccl-back{display:block;padding:11px 0;border-top:.5px solid rgba(0,0,0,.1);font-size:var(--fs-base);font-weight:var(--fw-bold);text-align:center;}
/* 채팅 목록의 부재중 통화: 빨간 글씨와 오른쪽 걸기 */
.chat-room-preview.is-missed{color:var(--alert);}
.chat-room-call{flex:none;height:28px;display:inline-flex;align-items:center;gap:4px;padding:0 11px;border:0;border-radius:var(--radius-full);background:rgba(118,118,128,.12);color:var(--text);font:inherit;font-size:var(--fs-md);font-weight:var(--fw-bold);cursor:pointer;}
/* ---------- 대화 정보(§screens/chat.js roomInfoHtml) ----------
   채팅방 위에 오른쪽에서 밀려 들어오는 화면(아이폰 화면 넘김). X 채팅 그룹 정보처럼 가운데 사진과 이름, 동그라미 버튼,
   흰 카드 묶음. 둘의 기록은 Box Box Club 맞대결 막대와 Turf 숫자 타일을 참고했다(design/chat-room-mock6.html) */
.room-info{position:fixed;top:0;bottom:0;left:0;right:0;max-width:480px;margin:0 auto;z-index:90;background:var(--bg2);transform:translateX(100%);transition:transform 320ms var(--ease-drawer);}
.room-info.is-open{transform:none;}
@media(prefers-reduced-motion:reduce){.room-info{transform:none;opacity:0;transition:opacity 200ms ease;}.room-info.is-open{opacity:1;}}
.room-info-back{position:absolute;top:calc(env(safe-area-inset-top) + 10px);left:14px;z-index:2;width:44px;height:44px;border-radius:50%;color:var(--text);}
.room-info-scroll{height:100%;overflow-y:auto;-webkit-overflow-scrolling:touch;overscroll-behavior:contain;padding:calc(env(safe-area-inset-top) + 56px) 16px calc(env(safe-area-inset-bottom) + 28px);box-sizing:border-box;}
.room-info-face{display:inline-flex;flex:none;}
.room-info-face .avatar.sm{width:var(--s);height:var(--s);font-size:calc(var(--s) * .22)!important;padding:0 2px!important;}
.room-info-top{display:flex;flex-direction:column;align-items:center;gap:2px;text-align:center;}
.room-info-top b{margin-top:10px;font-size:var(--fs-4xl);font-weight:var(--fw-bold);letter-spacing:-.02em;}
.room-info-top small{font-size:var(--fs-md);color:var(--text-light);}
.room-info-actions{display:flex;justify-content:center;gap:18px;margin:14px 0 16px;}
.room-info-actions button{display:flex;flex-direction:column;align-items:center;gap:6px;min-width:52px;padding:0;border:none;background:none;font:inherit;font-size:var(--fs-sm);color:var(--text);cursor:pointer;}
.room-info-actions i{width:52px;height:52px;border-radius:50%;background:var(--bg1);display:grid;place-items:center;box-shadow:var(--shadow-sm);transition:transform 120ms ease-out;}
.room-info-actions button:active i{transform:scale(.94);}
.room-info-actions button[aria-pressed="true"] i{background:var(--gray-800);color:var(--gray-0);}
.room-info-tiles{display:flex;gap:8px;margin-bottom:12px;}
.room-info-tiles div{flex:1;background:var(--bg1);border-radius:var(--radius-lg);corner-shape:squircle;padding:12px 0 10px;text-align:center;}
.room-info-tiles b{display:block;font-size:var(--fs-4xl);font-weight:var(--fw-bold);letter-spacing:-.02em;}
.room-info-tiles span{font-size:var(--fs-xs);font-weight:var(--fw-bold);color:var(--text-light);}
.room-info-card{display:block;width:100%;box-sizing:border-box;background:var(--bg1);border:none;border-radius:var(--radius);corner-shape:squircle;padding:16px;margin-bottom:12px;text-align:left;font:inherit;color:inherit;}
.room-info-card h3{font-size:var(--fs-md);font-weight:var(--fw-bold);color:var(--text-light);margin:0 0 12px;}
.room-info-empty{cursor:pointer;}
.room-info-empty h3{margin-bottom:6px;}
.room-info-empty span{font-size:var(--fs-md);color:var(--text-mid);}
.room-info-vs{display:flex;align-items:center;justify-content:space-between;margin-bottom:6px;}
.room-info-vs>span{display:flex;flex-direction:column;align-items:center;gap:6px;width:72px;font-size:var(--fs-sm);font-weight:var(--fw-bold);white-space:nowrap;overflow:hidden;text-overflow:ellipsis;}
.room-info-vs>b{display:flex;align-items:center;gap:12px;font-size:40px;font-weight:var(--fw-bold);letter-spacing:-.03em;}
.room-info-vs em{font-style:normal;font-size:var(--fs-3xl);color:var(--gray-300);}
.room-info-vs i{font-style:normal;color:var(--text-light);}
.room-info-bar{display:grid;grid-template-columns:22px 1fr 22px;align-items:center;column-gap:8px;margin-top:10px;font-size:var(--fs-md);font-weight:var(--fw-bold);}
.room-info-bar small{grid-column:1/4;text-align:center;font-size:var(--fs-xs);color:var(--text-light);margin-bottom:2px;}
.room-info-bar span:last-child{text-align:right;color:var(--text-light);}
.room-info-bar .track{height:6px;border-radius:3px;background:var(--gray-100);display:flex;overflow:hidden;}
.room-info-bar .track i{background:var(--gray-800);}
.room-info-bar .track s{margin-left:auto;background:var(--gray-400);}
.room-info-label{font-size:var(--fs-sm);font-weight:var(--fw-bold);color:var(--text-light);margin:4px 6px 8px;}
.room-info-ifs{display:flex;gap:8px;overflow-x:auto;scroll-snap-type:x mandatory;margin:0 -16px 12px;padding:0 16px;scrollbar-width:none;}
.room-info-ifs::-webkit-scrollbar{display:none;}
.room-info-if{flex:none;width:236px;scroll-snap-align:start;background:var(--bg1);border-radius:var(--radius);corner-shape:squircle;padding:14px;box-sizing:border-box;}
.room-info-if q{display:block;quotes:none;font-size:var(--fs-base);font-weight:var(--fw-bold);line-height:1.4;margin-bottom:10px;}
.room-info-a{display:flex;gap:6px;align-items:flex-start;margin-top:6px;font-size:var(--fs-md);}
.room-info-a>span:last-child{background:var(--bg2);border-radius:var(--radius-xs);corner-shape:squircle;padding:5px 9px;}
.room-info-photos{display:grid;grid-template-columns:repeat(4,1fr);gap:4px;margin-bottom:12px;}
.room-info-photos button{aspect-ratio:1;padding:0;border:none;border-radius:var(--radius-xs);corner-shape:squircle;overflow:hidden;background:var(--gray-100);cursor:pointer;}
.room-info-photos img{width:100%;height:100%;object-fit:cover;display:block;}
.room-info-group{background:var(--bg1);border-radius:var(--radius-lg);corner-shape:squircle;overflow:hidden;margin-bottom:12px;}
.room-info-row{position:relative;display:flex;align-items:center;gap:12px;width:100%;padding:12px 14px;border:none;background:none;font:inherit;font-size:var(--fs-lg);color:var(--text);text-align:left;cursor:pointer;}
.room-info-row+.room-info-row::before{content:"";position:absolute;top:0;left:48px;right:0;height:.5px;background:var(--border);}
.room-info-row>span{flex:1;}
.room-info-row em{font-style:normal;font-size:var(--fs-base);color:var(--text-light);}
.room-info-row>svg:last-child{color:var(--gray-400);}
.room-info-row.danger{color:var(--danger);}
.room-info-row:active{background:var(--bg2);}
/* 단체 대화 정보: 대화 상대 줄(사진 32px), 방장과 나 꼬리표, 더 보기 */
.room-info-cover{width:76px;height:76px;border-radius:var(--radius);}
.room-info-member{cursor:default;padding:9px 14px;}
.room-info-row>.room-info-face{flex:none;}
.room-info-member:active{background:none;}
.room-info-group .room-info-member~.room-info-row::before{left:58px;}
.room-info-row em.room-info-tag{padding:2px 8px;border-radius:var(--radius-full);background:var(--bg2);font-size:var(--fs-xs);font-weight:var(--fw-bold);color:var(--text-mid);}
.room-info-more span{font-size:var(--fs-md);color:var(--text-mid);}
/* 정보 화면의 사진이나 방 안 검색에서 데려간 말풍선을 잠깐 표시한다 */
.chat-msg-list [data-key].is-found{animation:msg-found 1.6s ease-out;}
@keyframes msg-found{0%,35%{background:var(--gray-100);border-radius:var(--radius-sm);}100%{background:transparent;}}

/* 단체마다 따로 쓰는 프로필(운영자가 고른 개선안, design/party-profile-mock.html) */
/* 멤버 프로필 시트(운영자 승인 시안 design/party-tags-mock.html 가 다듬기). iOS 26 연락처 카드처럼 화면을 거의 다 덮고,
   사진의 평균 색(--pm-t)으로 물든 배경, 큰 동그라미 사진, 유리 버튼과 유리 줄. 꼬리표(임관, 성향, 외부 연락 상대)는 이 시트에서만 */
.pm-overlay{align-items:flex-end;}
.sheet.pm-sheet{position:relative;overflow:hidden;display:flex;flex-direction:column;height:calc(100dvh - 12px - env(safe-area-inset-top,0px));max-height:none;padding:0 16px calc(22px + env(safe-area-inset-bottom));color:#fff;background:#2a2a2c;}
.pm-bg{position:absolute;inset:0;z-index:0;background:linear-gradient(180deg,var(--pm-t) 0%,color-mix(in srgb,var(--pm-t) 55%,#141414) 48%,color-mix(in srgb,var(--pm-t) 22%,#0c0c0c) 100%);}
.pm-sheet>*:not(.pm-bg){position:relative;z-index:1;}
.pm-bar{display:flex;justify-content:space-between;padding-top:14px;min-height:58px;}
.pm-glass{border:0;color:#fff;background:rgba(255,255,255,.18);-webkit-backdrop-filter:blur(14px) saturate(1.6);backdrop-filter:blur(14px) saturate(1.6);box-shadow:inset 0 0 0 .5px rgba(255,255,255,.45);}
.pm-round{width:44px;height:44px;border-radius:50%;display:grid;place-items:center;cursor:pointer;}
.pm-bar .pm-round:only-child{margin-right:auto;}
.pm-top{display:flex;flex-direction:column;align-items:center;margin-top:2px;text-align:center;}
.pm-photo{width:200px;height:200px;border-radius:50%;overflow:hidden;display:grid;place-items:center;background:linear-gradient(180deg,#8e8e93,#636366);box-shadow:0 0 0 .5px rgba(255,255,255,.35);}
.pm-photo img{display:block;width:100%;height:100%;object-fit:cover;}
.pm-mono{font-size:84px;font-weight:var(--fw-bold);color:rgba(255,255,255,.92);letter-spacing:-.02em;}
.pm-top b{margin-top:18px;font-size:28px;font-weight:var(--fw-bold);letter-spacing:-.02em;}
.pm-top small{margin-top:2px;font-size:var(--fs-md);color:rgba(255,255,255,.78);}
.pm-body{display:flex;flex-direction:column;align-items:center;margin-top:18px;}
.pm-cta{display:inline-flex;align-items:center;gap:8px;height:50px;padding:0 28px;border:0;border-radius:var(--radius-full);font:inherit;font-size:var(--fs-lg);font-weight:var(--fw-bold);color:#fff;background:rgba(255,255,255,.2);-webkit-backdrop-filter:blur(14px) saturate(1.6);backdrop-filter:blur(14px) saturate(1.6);box-shadow:inset 0 0 0 .5px rgba(255,255,255,.45);cursor:pointer;}
.pm-cta:disabled{opacity:.6;}
.pm-rows{align-self:stretch;display:flex;flex-direction:column;gap:8px;margin-top:22px;}
.pm-row{display:flex;align-items:center;gap:12px;width:100%;min-height:60px;padding:9px 16px;border:0;border-radius:var(--radius);corner-shape:squircle;background:rgba(255,255,255,.14);box-shadow:inset 0 0 0 .5px rgba(255,255,255,.22);font:inherit;color:#fff;text-align:left;}
.pm-row span{flex:1;display:flex;flex-direction:column;min-width:0;}
.pm-row small{font-size:var(--fs-sm);color:rgba(255,255,255,.72);}
.pm-row b{font-size:var(--fs-xl);font-weight:var(--fw-bold);overflow:hidden;text-overflow:ellipsis;white-space:nowrap;}
.pm-party{cursor:pointer;}
.pm-party .group-cover.pm-thumb{flex:0 0 38px;width:38px;height:38px;border-radius:11px;font-size:var(--fs-sm);}
.pm-chev,.pm-trail{display:flex;opacity:.75;}
.pm-foot{align-self:stretch;margin:10px 16px 0;font-size:var(--fs-xs);line-height:1.45;color:rgba(255,255,255,.62);}
.persona-ext{display:flex;align-items:center;justify-content:space-between;gap:12px;width:100%;margin-top:12px;padding:12px 14px;border:0;border-radius:var(--radius-sm);corner-shape:squircle;background:var(--bg2);text-align:left;font:inherit;color:var(--text);cursor:pointer;}
.persona-ext b{font-size:var(--fs-lg);font-weight:var(--fw-bold);}
/* 입력칸 안 내 얼굴과 "윈터로 보내기"(서브스택 답장 칸처럼). 단체방, 단체 1:1, 매칭 1:1 모두 같은 자리다. 단체에서는 얼굴을 누르면 이 단체에서 쓰는 프로필을 고친다 */
.chat-input-face{position:absolute;left:8px;top:8px;z-index:2;padding:0;border:0;background:none;border-radius:50%;cursor:pointer;}
.chat-input-face .avatar.sm{width:28px;height:28px;font-size:8px!important;padding:0 2px!important;}
.chat-input-wrap.has-face #partyInput{padding-left:44px;}
.chat-input-wrap.has-face #chatInput{padding-left:44px!important;} /* 1:1 입력칸은 글상자 스타일이 인라인이라 덮어쓴다 */
/* 이 단체에서 쓸 프로필 시트: 맨 위 어느 단체인지, 가운데 큰 사진, 한 줄 이름 칸, 안내 한 줄 */
.persona-for{display:flex;align-items:center;justify-content:center;gap:6px;margin:0 0 4px;font-size:var(--fs-sm);font-weight:var(--fw-bold);color:var(--text-mid);}
.persona-for .group-cover.persona-for-cover{width:18px;height:18px;flex:none;border-radius:6px;font-size:var(--fs-2xs);}
.persona-title{margin:0 0 16px;font-size:var(--fs-2xl);font-weight:var(--fw-bold);text-align:center;}
.persona-face{position:relative;display:flex;width:84px;margin:0 auto 16px;cursor:pointer;}
.persona-face input{position:absolute;inset:0;opacity:0;cursor:pointer;}
.persona-photo{display:block;width:84px;height:84px;border-radius:50%;overflow:hidden;background:var(--border);}
.persona-photo img{display:block;width:100%;height:100%;object-fit:cover;}
.persona-cam{position:absolute;right:-2px;bottom:-2px;display:grid;place-items:center;width:28px;height:28px;border-radius:50%;background:var(--gray-0);color:var(--text);box-shadow:0 1px 4px rgba(0,0,0,.25);pointer-events:none;}
.persona-field{display:flex;align-items:center;gap:8px;height:48px;padding:0 14px;border:1.5px solid var(--border);border-radius:var(--radius-sm);corner-shape:squircle;}
.persona-field:focus-within{border-color:var(--gray-900);}
.persona-field input{flex:1;min-width:0;width:0;border:0;outline:0;background:none;font:inherit;font-size:var(--fs-xl);font-weight:var(--fw-bold);color:var(--text);}
.persona-field span{font-size:var(--fs-xs);color:var(--text-light);}
.persona-hint{margin:12px 0 16px;font-size:var(--fs-md);color:var(--text-mid);text-align:center;}
/* 단체 멤버 시트(디스코드 멤버 시트처럼). 버튼 아래에 내가 어떤 이름으로 말하는지 */
.party-member-card{display:flex;flex-direction:column;align-items:center;gap:2px;margin:4px 0 20px;}
.party-member-card b{margin-top:10px;font-size:var(--fs-4xl);font-weight:var(--fw-bold);}
.party-member-card small{font-size:var(--fs-md);color:var(--text-light);}
.party-member-as{display:flex;align-items:center;justify-content:center;gap:6px;margin:12px 0 0;font-size:var(--fs-sm);color:var(--text-mid);}
.party-member-as .avatar.sm{width:20px;height:20px;font-size:0!important;}
/* 메시지 탭 단체 1:1 줄: 얼굴 모서리에 단체 대표 이미지(왓츠앱 커뮤니티 표지처럼). 단체 기간이 끝나면 표지만 흐려진다 */
.chat-face-badged{position:relative;display:inline-flex;flex:none;}
.chat-face-badged .group-cover.chat-face-badge{position:absolute;right:-3px;bottom:-3px;width:20px;height:20px;border-radius:6px;font-size:var(--fs-2xs);box-shadow:0 0 0 2.5px var(--bg1);}
.chat-face-badge.is-ended{opacity:.3;}
/* 단체 1:1 방 머리와 대화 정보: 어느 단체에서 만났는지 */
.chat-head-text small.chat-head-from .group-cover,.room-info-from .group-cover{width:14px;height:14px;flex:none;border-radius:4px;font-size:8px;}
.room-info-top small.room-info-from{display:flex;align-items:center;justify-content:center;gap:5px;}
.room-info-row em.party-link-want{display:inline-flex;align-items:center;gap:5px;font-weight:var(--fw-bold);color:var(--text);}
.room-info-row em.party-link-want .avatar.sm{width:20px;height:20px;font-size:0!important;}
/* 매칭 프로필로 이어 가기 팝업(인스타그램 계정 전환처럼 고른다) */
.center-modal.party-link-pop{max-width:310px;padding:22px 16px 16px;text-align:center;}
.party-link-pop h3{margin:0;font-size:var(--fs-2xl);font-weight:var(--fw-bold);}
.party-link-pop>p{margin:6px 0 12px;font-size:var(--fs-md);color:var(--text-mid);}
.party-link-pick{display:flex;flex-direction:column;margin:0 -4px 6px;text-align:left;}
.party-link-row{display:flex;align-items:center;gap:12px;width:100%;padding:10px 8px;border:0;background:none;font:inherit;color:var(--text);text-align:left;cursor:pointer;}
.party-link-row+.party-link-row{border-top:.5px solid var(--border);}
.party-link-row>span{flex:1;display:flex;flex-direction:column;}
.party-link-row b{font-size:var(--fs-lg);font-weight:var(--fw-bold);}
.party-link-row small{font-size:var(--fs-sm);color:var(--text-light);}
.party-link-row .avatar.sm{width:40px;height:40px;}
.party-link-pop p.party-link-note{margin:4px 0 14px;font-size:var(--fs-sm);color:var(--text-light);}
.party-link-btns{display:flex;gap:8px;}
.party-link-btns .btn{flex:1;}
.party-link-btns .btn-ghost{background:var(--gray-100);color:var(--text);}
/* 친목의 하위 분류 칩(사심 허용, 사심 지양). 친목 아래에 딸린 것이 보이게 왼쪽 선과 들여쓰기를 둔다 */
.group-chips--sub{margin:-10px -18px 18px 0;padding-left:12px;border-left:2px solid var(--gray-100)}
.group-chips--wrap.group-chips--sub{margin:8px 0 4px 14px}

/* 단체 안 비공개 대화(§functions/party-rooms.js). 원래 단체 대표 이미지 모서리에 자물쇠(왓츠앱 커뮤니티 안 그룹 표지처럼) */
.group-cover-room{position:relative;display:inline-flex;flex:none;}
.group-cover-lock{position:absolute;right:-3px;bottom:-3px;display:inline-flex;align-items:center;justify-content:center;width:18px;height:18px;border-radius:50%;background:var(--gray-900);color:var(--gray-0);box-shadow:0 0 0 2px var(--bg1);}
/* 초대 띠: 원래 단체 대화 머리 아래, 통화 띠와 같은 자리(통화 띠가 있으면 그 아래) */
.party-room-invite{position:absolute;z-index:21;top:calc(env(safe-area-inset-top) + 62px);left:16px;right:16px;display:flex;align-items:center;gap:10px;padding:8px 8px 8px 12px;border-radius:var(--radius-lg);corner-shape:squircle;}
.party-voice-banner~.party-room-invite{top:calc(env(safe-area-inset-top) + 114px);}
.party-room-invite-cover.group-cover{width:32px;height:32px;}
.party-room-invite-text{flex:1;min-width:0;display:flex;flex-direction:column;line-height:1.25;}
.party-room-invite-text b{font-size:var(--fs-md);font-weight:var(--fw-bold);white-space:nowrap;overflow:hidden;text-overflow:ellipsis;}
.party-room-invite-text small{font-size:var(--fs-xs);color:var(--text-mid);}
.party-room-invite .btn{flex:none;margin:0;height:32px;padding:0 12px;}
/* 원래 단체 대화 정보의 '비공개 대화' 줄 */
.room-info-room-cover.group-cover{width:32px;height:32px;}
.room-info-room>.group-cover-room{flex:none;}
.room-info-room small{font-size:var(--fs-sm);color:var(--text-light);}
.party-room-name{margin-bottom:10px;}
/* 사전 시트(§screens/dictionary.js): iOS 사전 찾아보기(Apple 북스)와 LookUp처럼 카드 없이 표제어 크게, 번호 칸을 둔 뜻, 표제어 사이 구분선. 검색칸은 iOS 검색 막대 */
.dict-top{display:flex;align-items:center;justify-content:space-between;margin-bottom:12px;}
.dict-top .title-md{margin:0;}
.dict-top .icon-btn{width:26px;height:26px;background:none;box-shadow:none;color:var(--text-mid);}
.dict-search{display:flex;align-items:center;gap:8px;height:40px;padding:0 12px;border-radius:var(--radius-sm);corner-shape:squircle;background:var(--bg2);color:var(--text-light);}
.dict-search input{flex:1;min-width:0;height:100%;border:0;background:none;outline:none;font:inherit;font-size:16px;color:var(--text);}
.dict-body{max-height:min(58dvh, calc(100dvh - 200px));overflow-y:auto;margin:6px -2px 0;padding:0 2px;}
.dict-entry{padding:18px 0;border-bottom:1px solid var(--border);}
.dict-entry:last-child{border-bottom:0;}
.dict-head{display:flex;align-items:baseline;gap:8px;}
.dict-head b{font-size:var(--fs-4xl);font-weight:var(--fw-bold);letter-spacing:-.01em;}
.dict-head sup{font-size:var(--fs-sm);margin-left:1px;}
.dict-pos{font-size:var(--fs-sm);color:var(--text-light);}
.dict-pron{margin-top:2px;font-size:var(--fs-md);color:var(--text-light);}
.dict-senses{list-style:none;margin:12px 0 0;padding:0;display:flex;flex-direction:column;gap:10px;}
.dict-senses li{display:flex;gap:10px;font-size:var(--fs-lg);line-height:1.55;color:var(--text);}
.dict-n{flex:none;width:18px;padding-top:1px;font-size:var(--fs-sm);font-weight:var(--fw-bold);color:var(--text-light);font-variant-numeric:tabular-nums;}
.dict-senses q{display:block;margin-top:4px;padding-left:10px;border-left:2px solid var(--border);font-size:var(--fs-md);color:var(--text-mid);quotes:none;}
.dict-foot{display:flex;justify-content:space-between;gap:12px;margin-top:12px;font-size:var(--fs-sm);color:var(--text-light);}
.dict-foot a{margin-left:auto;color:var(--text-mid);font-weight:var(--fw-bold);text-decoration:none;}
/* 사전 시트 바탕(운영자 2026-10-14 C): 회색 시트 위 흰 묶음, 첫 표제어는 위쪽에 입체 책(3dicons notebook, CC0)을 둔 그림 카드(Drops, CapWords 참고).
   검색칸에 쓰는 동안(키보드가 올라와 화면이 좁을 때)은 그림 칸을 접어 뜻이 밀리지 않게 한다 */
.dict-sheet{background:var(--gray-100);}
.dict-sheet .dict-search{background:var(--gray-0);}
.dict-sheet .dict-entry{margin-bottom:10px;padding:16px 18px 18px;border:0;border-radius:20px;corner-shape:squircle;background:var(--gray-0);}
.dict-art{height:132px;margin:-16px -18px 12px;background:url("../images/dict-book.webp") center 56%/104px no-repeat,radial-gradient(circle at 50% 56%,var(--gray-100) 0,var(--gray-0) 66px);transition:height .25s var(--ease-smooth-out),margin .25s var(--ease-smooth-out),opacity .2s;}
.dict-sheet:focus-within .dict-art{height:0;margin:0;opacity:0;}
.dict-entry.is-first .dict-head{justify-content:center;}
.dict-entry.is-first .dict-head b{font-size:30px;letter-spacing:-.02em;}
.dict-entry.is-first .dict-pron{text-align:center;}
.dict-entry.is-first .dict-senses{margin-top:14px;padding-top:14px;border-top:1px solid var(--border);}
@media(prefers-reduced-motion:reduce){.dict-art{transition:none;}}
.dict-search input::-webkit-search-cancel-button{filter:grayscale(1) opacity(.5);}

/* 모션 묶음 (2026-10-14, 노션 움직임 효과 레퍼런스. 시연판 design/motion-menu.html)
   1. 누름: 누르는 즉시 0.12초에 쫀득하게 줄고, 뗄 때 0.4초에 풀린다(BeUI, 모션 리퍼런스 Press). 큰 카드는 덜 줄인다 */
:is(.btn,.chip,.card,.home-mini,.home-rec-card,.mypage-card,.mypage-account-card,.notif-row){transition-property:opacity,transform,background-color,border-color,color;transition-duration:.15s,.4s,.32s,.32s,.22s;transition-timing-function:var(--ease-smooth-out),var(--ease-out),cubic-bezier(.4,0,.2,1),cubic-bezier(.4,0,.2,1),ease;}
:is(.btn,.chip):active:not(:disabled){transform:scale(.96);transition-duration:.12s;}
:is(.card,.home-mini,.home-rec-card,.mypage-card,.mypage-account-card,.notif-row):active{transform:scale(.97);transition-duration:.12s;}
/* 2. 숫자 굴리기(§ui/components/roll-number.js): 자리마다 위로 굴러 새 숫자가 된다. 오른쪽 자리부터 60ms씩 늦게 */
.roll{display:inline-flex;}
.roll-d{display:inline-block;height:1lh;overflow:hidden;vertical-align:bottom;}
.roll-d>span{display:flex;flex-direction:column;transform:translateY(calc(var(--to) * -1lh));animation:rollDigit .6s var(--ease-out) backwards;animation-delay:calc(var(--i) * 60ms - var(--past,0ms));}
.roll-d>span>span{height:1lh;}
@keyframes rollDigit{from{transform:translateY(calc(var(--from) * -1lh));}}
/* 3, 7. 좋아요 하트: 바뀔 때 흐림에서 또렷하게 녹아 들고(Morphicons), 채울 때는 톡 튀며 점 여섯 개가 퍼진다(모션 리퍼런스 Burst) */
.pp-like{position:relative;}
.pp-like.is-pop svg{animation:iconMorph .25s var(--ease-out);}
.pp-like.is-pop[aria-pressed="true"] svg{animation:likePop .35s var(--ease-bounce);}
.pp-like.is-pop[aria-pressed="true"]::after{content:"";position:absolute;left:50%;top:50%;width:4px;height:4px;margin:-2px;border-radius:50%;pointer-events:none;box-shadow:0 -17px currentColor,14.7px -8.5px currentColor,14.7px 8.5px currentColor,0 17px currentColor,-14.7px 8.5px currentColor,-14.7px -8.5px currentColor;animation:likeBurst .45s var(--ease-out) forwards;}
@keyframes iconMorph{from{opacity:0;transform:scale(.6);filter:blur(3px);}}
@keyframes likePop{0%{transform:scale(.6);}60%{transform:scale(1.18);}}
@keyframes likeBurst{from{opacity:1;transform:scale(.5);}to{opacity:0;transform:scale(1.35);}}
/* 4. 글자 떠오르기: 첫 화면 mono.는 왼쪽부터 쓸려 나타나고(Kawai Text Animation), 출석 완료 버튼 글자는 한 자씩 떠오른다 */
.auth-landing-mark{-webkit-mask-image:linear-gradient(90deg,#000 45%,transparent 55%);mask-image:linear-gradient(90deg,#000 45%,transparent 55%);-webkit-mask-size:300% 100%;mask-size:300% 100%;-webkit-mask-position:0 0;mask-position:0 0;animation:markReveal .9s var(--ease-out) .15s backwards;}
body:has(#appSplash:not(.is-hidden)) .auth-landing-mark{animation-play-state:paused;} /* 앱 시작 화면이 걷힌 뒤에 쓸려 나타난다 */
@keyframes markReveal{from{-webkit-mask-position:100% 0;mask-position:100% 0;opacity:0;transform:translate(-50%,calc(-50% + 6px));}}
.t-rise{display:inline-block;white-space:pre;animation:tRise .4s var(--ease-out) backwards;animation-delay:calc(var(--i) * 30ms);}
@keyframes tRise{from{opacity:0;transform:translateY(8px);filter:blur(4px);}}
/* 5. 목록 차례로 올라오기: 탭이나 화면을 옮겨 왔을 때만(.main.fade-in, slide) 앞 여덟 줄이 35ms씩 늦게 올라온다. 다시 그릴 때는 안 움직인다 */
.main:is(.fade-in,.slide-left,.slide-right) :is(.chat-room-row,.match-card,.notif-row){animation:listRise .3s var(--ease-out) backwards;}
.main:is(.fade-in,.slide-left,.slide-right) :is(.chat-room-row,.match-card,.notif-row):nth-child(2){animation-delay:35ms;}.main:is(.fade-in,.slide-left,.slide-right) :is(.chat-room-row,.match-card,.notif-row):nth-child(3){animation-delay:70ms;}.main:is(.fade-in,.slide-left,.slide-right) :is(.chat-room-row,.match-card,.notif-row):nth-child(4){animation-delay:105ms;}.main:is(.fade-in,.slide-left,.slide-right) :is(.chat-room-row,.match-card,.notif-row):nth-child(5){animation-delay:140ms;}.main:is(.fade-in,.slide-left,.slide-right) :is(.chat-room-row,.match-card,.notif-row):nth-child(6){animation-delay:175ms;}.main:is(.fade-in,.slide-left,.slide-right) :is(.chat-room-row,.match-card,.notif-row):nth-child(7){animation-delay:210ms;}.main:is(.fade-in,.slide-left,.slide-right) :is(.chat-room-row,.match-card,.notif-row):nth-child(8){animation-delay:245ms;}
.main:is(.fade-in,.slide-left,.slide-right) :is(.chat-room-row,.match-card,.notif-row):nth-child(n+9){animation-delay:280ms;}
@keyframes listRise{from{opacity:0;transform:translateY(8px);}}
@media(prefers-reduced-motion:reduce){
  :is(.btn,.chip,.card,.home-mini,.home-rec-card,.mypage-card,.mypage-account-card,.notif-row):active{transform:none;}
  .roll-d>span,.t-rise,.pp-like.is-pop svg,.main:is(.fade-in,.slide-left,.slide-right) :is(.chat-room-row,.match-card,.notif-row){animation:none;}
  .pp-like.is-pop[aria-pressed="true"]::after{display:none;}
  .auth-landing-mark{animation-name:markFade;}
}
@keyframes markFade{from{opacity:0;}}

/* 6. 아이콘 모션(§docs/animation.md 8절, Apple SF Symbols 지침, §ui/icon-motion.js). 뜻마다 움직임 종류와 시간이 정해져 있다.
   그림 전체를 움직여서 Lucide로 바꿔도(결정 68-가) 그대로 맞는다 */
svg[data-i].ic-go{transform-origin:50% 50%;animation:var(--ic-kf) var(--ic-dur,.4s) var(--ease-out);}
/* 일이 일어남(Bounce) */
svg[data-i="copy"]{--ic-kf:icCopy;--ic-dur:.35s;}
svg[data-i="share"]{--ic-kf:icRise;}
svg[data-i="camera"]{--ic-kf:icFlash;}
svg[data-i="ticket"]{--ic-kf:icTicket;}
svg[data-i="link"]{--ic-kf:icLink;}
svg[data-i="mic"],svg[data-i="micLine"],svg[data-i="music"]{--ic-kf:icHop;--ic-dur:.45s;}
/* 알림, 방향(Wiggle) */
svg[data-i="bell"]{--ic-kf:icBell;--ic-dur:.45s;}svg[data-i="bell"].ic-go{transform-origin:50% 10%;}
svg[data-i="chat"]{--ic-kf:icTilt;}
svg[data-i="phone"]{--ic-kf:icRing;--ic-dur:.45s;}
svg[data-i="search"]{--ic-kf:icLook;--ic-dur:.45s;}
svg[data-i="eraser"]{--ic-kf:icScrub;--ic-dur:.45s;}
/* 실물처럼 돎(Rotate) */
svg[data-i="gear"]{--ic-kf:icHalfTurn;--ic-dur:.45s;}
svg[data-i="undo"]{--ic-kf:icBackTurn;--ic-dur:.55s;}
svg[data-i="dice"]{--ic-kf:icDice;--ic-dur:.6s;}
svg[data-i="globe"]{--ic-kf:icTurn;--ic-dur:.6s;}
/* 끝남(Draw On) */
svg[data-i="check"]{--ic-kf:icDraw;--ic-dur:.35s;}
/* 그 밖: 잠금 고리, 눈 깜빡, 밤, 드문 축하(트로피, 왕관) */
svg[data-i="lock"]{--ic-kf:icLock;}
svg[data-i="eyeOff"]{--ic-kf:icBlink;--ic-dur:.3s;}
svg[data-i="moon"]{--ic-kf:icTilt;}
svg[data-i="trophy"]{--ic-kf:icCheer;--ic-dur:.6s;}
svg[data-i="crown"]{--ic-kf:icCrown;--ic-dur:.6s;}
/* 상태가 바뀜(Replace): 들어오는 아이콘이 작고 흐린 데서 커진다 */
svg.ic-in{animation:icIn .25s var(--ease-out);}
@keyframes icIn{from{opacity:0;transform:scale(.5);filter:blur(2px);}}
@keyframes icCopy{50%{transform:translate(2px,2px);}}
@keyframes icRise{40%{transform:translateY(-4px);}}
@keyframes icFlash{35%{transform:scale(1.15);}70%{transform:scale(.95);}}
@keyframes icTicket{40%{transform:translateX(3px) rotate(4deg);}}
@keyframes icLink{40%{transform:rotate(-8deg) scale(.94);}}
@keyframes icHop{30%{transform:translateY(-4px);}55%{transform:none;}75%{transform:translateY(-1.5px);}}
@keyframes icBell{20%{transform:rotate(-12deg);}45%{transform:rotate(10deg);}70%{transform:rotate(-6deg);}}
@keyframes icTilt{35%{transform:scale(1.06) rotate(-7deg);}70%{transform:scale(1.03) rotate(4deg);}}
@keyframes icRing{15%{transform:rotate(12deg);}35%{transform:rotate(-10deg);}55%{transform:rotate(7deg);}75%{transform:rotate(-3deg);}}
@keyframes icLook{30%{transform:translate(0,-3px);}65%{transform:translate(-3px,0);}}
@keyframes icScrub{25%{transform:translateX(-1.5px) rotate(-4deg);}50%{transform:translateX(1.5px) rotate(4deg);}75%{transform:translateX(-1.5px) rotate(-3deg);}}
@keyframes icHalfTurn{to{transform:rotate(180deg);}}
@keyframes icBackTurn{50%{transform:rotate(-180deg) scale(.92);}to{transform:rotate(-360deg);}}
@keyframes icDice{50%{transform:rotate(90deg) translateY(-3px) scale(.88);}to{transform:rotate(180deg);}}
@keyframes icTurn{to{transform:rotate(360deg);}}
@keyframes icDraw{from{clip-path:inset(0 100% 0 0);transform:scale(.85);}}
@keyframes icLock{45%{transform:rotate(-10deg) translateY(-2px);}}
@keyframes icBlink{45%{transform:scaleY(.15);}}
@keyframes icCheer{25%{transform:translateY(-4px) rotate(-10deg);}60%{transform:translateY(-4px) rotate(10deg);}}
@keyframes icCrown{30%{transform:translateY(-4px) rotate(-8deg);}60%{transform:translateY(1px) rotate(4deg);}}
@keyframes icFade{from{opacity:0;}}
@media(prefers-reduced-motion:reduce){svg[data-i].ic-go{animation:none;}svg.ic-in{animation-name:icFade;}}
/* 사진이 든 얼굴은 동그라미를 꽉 채운다. 글자 얼굴용 padding:0 2px!important(대화 말풍선 옆, 대화방 머리, 대화 정보, 입력칸 얼굴)가 사진 양옆을 2px씩 비워서,
   같은 우선순위로 맨 끝 파일 맨 끝에 둔다. 글자 얼굴의 여백은 그대로다 */
.avatar.avatar:has(>.avatar-photo){padding:0!important;overflow:hidden;}
