/* 터미널 글꼴 Lodelai Demo Mono: D2Coding(Copyright (c) 2015 NAVER Corporation) 서브셋, SIL Open Font License 1.1 — https://openfontlicense.org */
/* packages/ui/src/tokens.css */
/* 생성 파일 — 직접 고치지 말 것. 원천: packages/ui/tokens, 빌드: bun run tokens */

:host,
[data-theme="light"] {
  --color-bg: #fcfcfc; /** 창 바탕. 목록·대화·카드 모두 같은 바탕이다(채운 카드 없음). */
  --color-bg-hover: #f3f3f3; /** 목록 행 호버·선택, 입력창 바탕. */
  --color-bg-side: #f3f3f3; /** 사이드바·축소판 면(머리 줄 아래 선부터 — 맨 위 신호등 줄은 창 전체 폭이라 bg). m1-spec §2 B1, 루오님 10-24. 묶음 43: 글래스 틀(레일·사이드바·머리 줄·상태창 한 장)은 이 색 60% 반투명(78% → 60%, 라이트·어두운 바탕 ink-secondary 4.58 하한). */
  --color-bg-side-list: #f8f8f8; /** 사이드바 칸 안 스크롤 목록 면(10-25). '나' 행·칸 제목 띠는 bg-side 그대로 — 면이 칸 제목과 목록을 가른다. 호버·선택은 bg-side-hover·bg-selected. */
  --color-bg-selected: #d9d9d9; /** 사이드바 선택 행(지금 본문에 열린 동료·세션), 축소판 아이콘 행도. 호버해도 그대로. 주황은 선택에 쓰지 않는다. */
  --color-bg-side-hover: #e7e7e7; /** 사이드바 안 행 호버. */
  --color-bg-frame: #ececec; /** 바깥 틀 불투명 면(묶음 43 §43.6) — 비활성 창·투명도 줄이기 때 레일·사이드바·머리 줄·상태창 한 장의 면. 안쪽 칸 bg 와 다크 1.13:1 · 라이트 1.15:1(bg-side 는 1.06·1.08 로 거의 안 갈림, 디자인검수 v417 🟡2). 글래스 때는 이 면 대신 bg-side 60% 반투명. */
  --color-bg-frame-hover: #e2e2e2; /** 불투명 틀(bg-frame — 비활성 창·투명도 줄이기) 위 사이드바·레일 행 호버(묶음 43 §43.6). 틀과 다크 1.14 · 라이트 1.10, bg-selected 와 1.11 · 1.09. 글래스 판 호버는 bg-side-hover 그대로. */
  --color-bg-card: #f6f6f6; /** 코드·diff 블록 바탕만. 다른 데 면을 채우지 않는다. */
  --color-bg-mine: #efefef; /** 내 쪽 면 — 대화의 내 말풍선(#341)과 내 에이전트 블록(interaction-rules 37-1a, 쪽 + 면 두 단서). 카드(bg-card) 위에선 bg-mine-card. 다른 데 면을 채우지 않는다. */
  --color-bg-mine-card: rgba(0, 0, 0, 0.05); /** 줄기·카드 안 내 쪽 블록 면(규칙 37-1a) — 반투명이라 바로 뒤 바탕이 무엇이든(창 bg · 카드 bg-card · 나에게 온 accent-soft · 새 답 success-soft) 대비 1.11~1.15:1 = 창 바탕 위 내 말풍선(bg-mine)과 같은 값. 불투명 회색은 색 면(accent-soft·success-soft) 위에서 1.00~1.06 으로 사라짐(41 v409 검수 · 프론트 실측). 대화의 내 말풍선은 bg-mine. 다른 데 면을 채우지 않는다. */
  --color-ink: #0f0f0f; /** 본문·이름·제목. 주버튼 채움색(글자는 on-ink). */
  --color-ink-secondary: #555555; /** 메타·세션명·보조 글자. 여덟 면 모두(선택 행 포함) 4.5:1 이상 — 다크 bg 8.2·선택 5.7, 라이트 bg 7.3·선택 5.3(#432 루오님 10-28 안 A). */
  --color-ink-tertiary: #686868; /** 단축키·시각·자리표시 글·비활성. bg 위 5.4:1(다크·라이트) — 선택 행(bg-selected) 위에서는 못 넘으니 선택 행 안 흐린 글자는 ink-secondary 로 바꾼다(컴포넌트 규칙). #432 루오님 10-28 안 A(옛 다크 #6a6a6a·라이트 #9c9c9c 는 2.7~3.6). */
  --color-on-ink: #fcfcfc; /** ink 채움(주버튼) 위 글자. */
  --color-line: #e8e8e8; /** 헤어라인: 구분선, 카드 테두리, 입력창 테두리. */
  --color-line-strong: #cfcfcf; /** 강조 테두리: 보조 버튼, 포커스 안 둔 선택 행. */
  --color-shadow-drawer: rgba(0, 0, 0, 0.18); /** 떠 있는 레일 서랍 그림자 색(§49, 루오님 11-01 (다)) — box-shadow 8px 0 20px -8px 로 오른쪽 변·둥근 모서리에만(퍼짐 -8 이라 위아래로 안 샘). 선 테두리 대신. 다른 데 쓰지 않는다. */
  --color-line-drawer-edge: rgba(0, 0, 0, 0); /** 레일 서랍 오른쪽 변 1px 하이라인(§49) — 다크에서 그림자만으로는 대화 칸(bg)과 안 갈려서. 라이트는 없음(투명). 오른쪽 변만, 위·아래·왼쪽 선 없음. */
  --color-accent: #ff6a00; /** 강조 하나. 포커스 링, 로고 점, 미읽 수. 글자·버튼 채움에 쓰지 않는다. */
  --color-accent-text: #9a3d00; /** 강조 글자: 미읽 수, '처리 중', 작업 요청 라벨. bg 위 4.5:1 이상. */
  --color-accent-soft: rgba(255, 106, 0, 0.12); /** 강조 배지 바탕(accent-text 글자와 짝). 대화 창 나에게 온 카드 바탕(accent 테두리와 짝, #592 루오님 10-29) — 그 밖 면 채움 없음. */
  --color-danger-text: #b3261e; /** 거부·거절 글자, 폴더 밖 표시, 오류 아이콘(state-error). 채운 빨강 면은 세션 끄기 버튼 호버(danger-quiet 반전)뿐 — 사용량 95% 막대 채움은 danger-fill. */
  --color-success: #166e2f; /** 녹 = 켜짐·정상(규칙 21): 처리 중·새 답·쉼 아이콘, 연결됨·접속 점. 프로젝트 패널 깃 상태 글자(새 파일·추적 안 함)와 +n 에도(§28.9, 루오님 10-26). 면 채움 없음(예외: 대화 창 확인 전 새 답 카드 면은 success-soft, #592 B+A) — 예외 사용량 막대 80% 미만 채움(80% warn-fill·95% danger-fill, 루오님 10-28). 여덟 면 모두 4.5:1 이상(#432 루오님 10-28 — 라이트 값 진하게). */
  --color-success-soft: rgba(22, 110, 47, 0.08); /** 대화 창 줄기 카드 '답이 왔는데 확인 전' 면(success 테두리와 짝, #592 루오님 10-29 B+A — 뜻은 규칙 21 state-unseen). 그 밖 면 채움 없음. accent-soft(나에게 온 카드)와 같은 꼴. */
  --color-warn: #9a4707; /** 노 = 주의 — 글자·아이콘·점: 서버 주의 아이콘·설정 상태 점, 깃 상태 글자(고침·이름 바꿈, §28.9). bg 위 4.5:1. 막대 채움엔 쓰지 않는다(warn-fill). 라이트는 옛 올리브 #8a6100 이 탁한 갈색으로 보여 앰버로(루오님 10-27). 여덟 면 모두 4.5:1 이상(#432 루오님 10-28 — 라이트 값 진하게). */
  --color-agent-claude: #d97757; /** Claude 에이전트 색(공식 색) — 상태가 아니라 '어느 에이전트'. ① 마크: 메시지 행 세션 아바타·사이드바·넘기기 대상·상태창 사용량, 늘 이 색(꺼진 세션 행 전체가 흐릴 때만 ink-tertiary). 막대에는 쓰지 않는다 — 사용량 막대 80% 미만은 success(루오님 10-28, 에이전트 몫은 마크가 말함). 글자에도 쓰지 않는다. 에이전트 종류 마크 = 그 브랜드 원래 색(이후 Codex 등도 각자 브랜드 색) — 대화 창 카드 머리 마크도 이 색, 12 크기(루오님 10-27·10-29). */
  --color-agent-tile: #ffffff; /** 에이전트 마크(agent-claude) 뒤 타일 — 라이트에서만 흰 타일 + line 테두리로 마크 대비 3.1:1(옅은 면 #f3f3f3 위 2.8 → 타일 위 3.1). 다크는 투명(바탕 위 이미 4.3~6.2). 공식 색은 그대로, #432 루오님 10-28. */
  --color-org-tile-1: #4f5fa8; /** 조직 사진이 없을 때 첫 글자 타일 바탕 1(남색) — 키(조직 id) 문자 코드 합 % 6 으로 고름(#554 루오님 10-28). 흰 글자 4.99:1 이상, 바탕 위 3.2:1 이상. 타일에만 — 글자·상태·버튼엔 쓰지 않는다. 사람 아바타는 person-tile-1..6(#592). */
  --color-org-tile-2: #2f7a72; /** 조직 사진이 없을 때 첫 글자 타일 바탕 2(청록) — 키(조직 id) 문자 코드 합 % 6 으로 고름(#554 루오님 10-28). 흰 글자 4.99:1 이상, 바탕 위 3.2:1 이상. 타일에만 — 글자·상태·버튼엔 쓰지 않는다. 사람 아바타는 person-tile-1..6(#592). */
  --color-org-tile-3: #3f7d3a; /** 조직 사진이 없을 때 첫 글자 타일 바탕 3(초록) — 키(조직 id) 문자 코드 합 % 6 으로 고름(#554 루오님 10-28). 흰 글자 4.99:1 이상, 바탕 위 3.2:1 이상. 타일에만 — 글자·상태·버튼엔 쓰지 않는다. 사람 아바타는 person-tile-1..6(#592). */
  --color-org-tile-4: #9a5b13; /** 조직 사진이 없을 때 첫 글자 타일 바탕 4(황토) — 키(조직 id) 문자 코드 합 % 6 으로 고름(#554 루오님 10-28). 흰 글자 4.99:1 이상, 바탕 위 3.2:1 이상. 타일에만 — 글자·상태·버튼엔 쓰지 않는다. 사람 아바타는 person-tile-1..6(#592). */
  --color-org-tile-5: #a8466a; /** 조직 사진이 없을 때 첫 글자 타일 바탕 5(장미) — 키(조직 id) 문자 코드 합 % 6 으로 고름(#554 루오님 10-28). 흰 글자 4.99:1 이상, 바탕 위 3.2:1 이상. 타일에만 — 글자·상태·버튼엔 쓰지 않는다. 사람 아바타는 person-tile-1..6(#592). */
  --color-org-tile-6: #7650a6; /** 조직 사진이 없을 때 첫 글자 타일 바탕 6(보라) — 키(조직 id) 문자 코드 합 % 6 으로 고름(#554 루오님 10-28). 흰 글자 4.99:1 이상, 바탕 위 3.2:1 이상. 타일에만 — 글자·상태·버튼엔 쓰지 않는다. 사람 아바타는 person-tile-1..6(#592). */
  --color-person-1: #4a599e; /** 사람 이름 글자 색 1(남색) — 대화 창 사람 이름·그룹 카드 머리 '(이름)의' 만(#592 루오님 10-29 모노톤 의견). 계정 id 문자 코드 합 % 6 으로 고름 — 사이드바·대화 창·그룹 목록 어디서나 같은 사람 = 같은 색. 카드 바탕 위 다크 6.6:1·라이트 6.1:1. 에이전트 이름·상태·버튼·면엔 쓰지 않는다. 짝 = person-tile-1. */
  --color-person-2: #2b6480; /** 사람 이름 글자 색 2(하늘) — 대화 창 사람 이름·그룹 카드 머리 '(이름)의' 만(#592 루오님 10-29 모노톤 의견). 계정 id 문자 코드 합 % 6 으로 고름 — 사이드바·대화 창·그룹 목록 어디서나 같은 사람 = 같은 색. 카드 바탕 위 다크 6.5:1·라이트 6.0:1. 에이전트 이름·상태·버튼·면엔 쓰지 않는다. 짝 = person-tile-2. */
  --color-person-3: #27665f; /** 사람 이름 글자 색 3(청록) — 대화 창 사람 이름·그룹 카드 머리 '(이름)의' 만(#592 루오님 10-29 모노톤 의견). 계정 id 문자 코드 합 % 6 으로 고름 — 사이드바·대화 창·그룹 목록 어디서나 같은 사람 = 같은 색. 카드 바탕 위 다크 6.6:1·라이트 6.2:1. 에이전트 이름·상태·버튼·면엔 쓰지 않는다. 짝 = person-tile-3. */
  --color-person-4: #704c9d; /** 사람 이름 글자 색 4(보라) — 대화 창 사람 이름·그룹 카드 머리 '(이름)의' 만(#592 루오님 10-29 모노톤 의견). 계정 id 문자 코드 합 % 6 으로 고름 — 사이드바·대화 창·그룹 목록 어디서나 같은 사람 = 같은 색. 카드 바탕 위 다크 6.6:1·라이트 6.1:1. 에이전트 이름·상태·버튼·면엔 쓰지 않는다. 짝 = person-tile-4. */
  --color-person-5: #983f60; /** 사람 이름 글자 색 5(장미) — 대화 창 사람 이름·그룹 카드 머리 '(이름)의' 만(#592 루오님 10-29 모노톤 의견). 계정 id 문자 코드 합 % 6 으로 고름 — 사이드바·대화 창·그룹 목록 어디서나 같은 사람 = 같은 색. 카드 바탕 위 다크 6.6:1·라이트 6.0:1. 에이전트 이름·상태·버튼·면엔 쓰지 않는다. 짝 = person-tile-5. */
  --color-person-6: #8f3d8f; /** 사람 이름 글자 색 6(자홍) — 대화 창 사람 이름·그룹 카드 머리 '(이름)의' 만(#592 루오님 10-29 모노톤 의견). 계정 id 문자 코드 합 % 6 으로 고름 — 사이드바·대화 창·그룹 목록 어디서나 같은 사람 = 같은 색. 카드 바탕 위 다크 6.6:1·라이트 6.0:1. 에이전트 이름·상태·버튼·면엔 쓰지 않는다. 짝 = person-tile-6. */
  --color-person-tile-1: #4f5fa8; /** 사람 아바타(사진 없을 때) 첫 글자 원 바탕 1(남색) — 흰 글자 5.0:1 이상. 이름 글자 person-1 와 같은 사람·같은 번호(#592 루오님 10-29). */
  --color-person-tile-2: #327697; /** 사람 아바타(사진 없을 때) 첫 글자 원 바탕 2(하늘) — 흰 글자 5.0:1 이상. 이름 글자 person-2 와 같은 사람·같은 번호(#592 루오님 10-29). */
  --color-person-tile-3: #2f7a72; /** 사람 아바타(사진 없을 때) 첫 글자 원 바탕 3(청록) — 흰 글자 5.0:1 이상. 이름 글자 person-3 와 같은 사람·같은 번호(#592 루오님 10-29). */
  --color-person-tile-4: #7650a6; /** 사람 아바타(사진 없을 때) 첫 글자 원 바탕 4(보라) — 흰 글자 5.0:1 이상. 이름 글자 person-4 와 같은 사람·같은 번호(#592 루오님 10-29). */
  --color-person-tile-5: #a8466a; /** 사람 아바타(사진 없을 때) 첫 글자 원 바탕 5(장미) — 흰 글자 5.0:1 이상. 이름 글자 person-5 와 같은 사람·같은 번호(#592 루오님 10-29). */
  --color-person-tile-6: #a848a8; /** 사람 아바타(사진 없을 때) 첫 글자 원 바탕 6(자홍) — 흰 글자 5.0:1 이상. 이름 글자 person-6 와 같은 사람·같은 번호(#592 루오님 10-29). */
  --color-warn-fill: #ff9500; /** 막대 채움 전용 — 사용량 80% 이상·서버 주의 막대(macOS systemOrange). 글자·아이콘엔 쓰지 않는다(라이트 바탕 위 2.1:1 — 길이와 % 글자가 값을 말한다). 루오님 10-27. */
  --color-danger-fill: #ff3b30; /** 막대 채움 전용 — 사용량 95% 이상(macOS systemRed). 글자·아이콘은 danger-text. 루오님 10-27. */
  --color-danger-quiet: #dc5d55; /** 세션 끄기(power) 위험 아이콘 버튼 — 평소 아이콘 색이자, 호버·포커스·누름·열림 때는 같은 색이 칩 면이 되고 아이콘이 on-danger(흰)로 바뀐다(반전, 루오님 10-28). bg 위 라이트 3.57:1·다크 5.6:1, 흰 아이콘 대비 라이트 3.66:1·다크 3.47:1(아이콘 3:1). 글자엔 쓰지 않는다(danger-text). #543. */
  --color-danger-surface: #dc5d55; /** danger-quiet 별칭(루오님 10-28 — 호버는 반전: 면 = 평소 아이콘 색). 옛 #c42b20 은 평소 빨강과 달라 쓰지 않음. 새로 쓰지 말고 danger-quiet 를 쓴다. #543. */
  --color-on-danger: #ffffff; /** 위험 아이콘 버튼 호버 면(danger-quiet) 위 아이콘 — 라이트 3.66:1·다크 3.47:1. #543. */
  --color-diff-add-bg: rgba(26, 127, 55, 0.14); /** patch 더한 줄 바탕(success 14%). 프로젝트 패널 깃 탭(§28.9)·대화 diff 펜스(§52.1). 줄 앞 + 는 success 글자. */
  --color-diff-del-bg: rgba(179, 38, 30, 0.14); /** patch 뺀 줄 바탕(danger-text 14%). 줄 앞 − 는 danger-text 글자. */
  --color-syntax-keyword: #7a3fc0; /** 코드 보기 구문 색 — 키워드(보라). 프로젝트 패널 파일 보기(§28.9)·대화 코드 블록(§52.1, 아는 언어만). 상태색과 겹치지 않는 색. */
  --color-syntax-string: #1f5f9e; /** 구문 색 — 글자열(파랑). */
  --color-syntax-number: #0d6b63; /** 구문 색 — 숫자(청록). 여덟 면 모두 4.5:1 이상(#432 루오님 10-28 — 라이트 값 진하게). */
  --color-syntax-comment: #5f5f5f; /** 구문 색 — 주석(회색, 바탕 위 4.5:1). 나머지 코드는 ink. 여덟 면 모두 4.5:1 이상(#432 루오님 10-28 — 라이트 값 진하게). */
  --color-code-fg: #5f5f5f; /** diff 의 바뀌지 않은 줄. 바뀐 줄은 ink. 여덟 면 모두 4.5:1 이상(#432 루오님 10-28 — 라이트 값 진하게). */
  --space-1: 4px; /** 아이콘과 글자. */
  --space-2: 8px; /** 행 안 요소 사이, 버튼 사이. */
  --space-3: 12px; /** 카드 안쪽 가로, 행 좌우 패딩. */
  --space-4: 16px; /** 섹션 패딩, 대화 영역 좌우. */
  --space-5: 20px; /** 창 안쪽 여백. */
  --space-6: 28px; /** 온보딩 단계 사이. */
  --radius-radius: 10px; /** 카드, 입력창, 주버튼, 아트보드 모서리. */
  --radius-sm: 6px; /** 목록 행 선택, 배지, 작은 버튼, 코드 블록. */
  --size-row: 36px; /** 목록 행 높이(Raycast 밀도). */
  --size-control: 30px; /** 데스크톱 버튼·입력 높이. */
  --size-control-touch: 44px; /** 온보딩·터치 폭의 버튼 높이. */
  --size-avatar: 20px; /** 이름 앞 이니셜 원. */
  --size-sidebar: 240px; /** 왼쪽 목록 폭(레일 64 오른쪽 — 묶음 39 m1-spec §41.2). */
  --size-popover: 360px; /** 메뉴바 팝오버 폭. */
  --size-popover-wide: 440px; /** 글이 긴 팝오버 폭 — 바뀐 점(m1-spec §47.2, release.md 항목 길이가 두 줄 안). */
  --size-thread: 760px; /** 대화 열 최대 폭. */
  --size-conv-x: 20px; /** 대화 칸·입력칸 좌우 여백 — 대화 열 오른쪽 끝선(interaction-rules 37-11). 오른쪽에 붙는 것(카드·내 블록·줄 끝 동작·입력칸)이 모두 이 끝선. */
  --size-read: 680px; /** 읽기 폭 — 받은 글 글자 줄(문단·인용·코드)만 여기서 줄을 바꾼다. 카드·행 상자는 자르지 않는다(37-11). */
  --size-scrollbar: 8px; /** 스크롤 막대 칸 — 대화 칸은 이 칸을 conv-x 여백 안에 늘 잡아 끝선이 입력칸과 같다(37-11). */
  --size-badge: 20px; /** 배지 높이(미읽 수·작업 요청 라벨). */
  --size-avatar-text: 10px; /** 아바타 안 이니셜·>_ 글자 크기. */
  --size-gap-tight: 6px; /** 좁은 간격: 버튼 안 글자와 단축키, 카드 footer 버튼 사이, 메시지와 인라인 카드 사이. */
  --size-gap-inner: 10px; /** 안쪽 간격: 행 안 아이콘-제목, 행 좌우 패딩, 메시지 아바타-본문 열, 카드 본문·코드·입력창 세로 패딩, 토글 트랙-라벨. */
  --size-pane-gap: 8px; /** 안쪽 칸(대화·작업·가운데 좁은 열)과 바깥 틀 사이 간격 — 오른쪽·아래·나란히 두 칸 사이 홈(묶음 43). = space-2. 칸 모서리는 radius 10. */
  --size-icon-sm: 12px; /** 하단 상태창 아이콘(연결·상태 수·경고·Claude 마크·새로고침, 묶음 43). 누름 상자는 줄이지 않는다(24×20 · 20×20). */
  --motion-duration-instant: 150ms; /** 포인터 아래 피드백(호버·눌림). DD 값. */
  --motion-duration-fast: 200ms; /** 실제로 바뀐 상태(색·크기, 카드 접힘). */
  --motion-duration-base: 320ms; /** 중간 전환(팝오버 자라남 상한). */
  --motion-duration-slow: 640ms; /** 등장(rise). 저빈도에만, 70ms 스태거. */
  --motion-easing-out: cubic-bezier(0.16, 1, 0.3, 1); /** 등장 */
  --motion-easing-base: cubic-bezier(0.32, 0.72, 0, 1); /** 이동·확산 */
  --motion-easing-state: cubic-bezier(0.23, 0.88, 0.26, 0.92); /** 상태 변화 */
  --font-family-body: 'Pretendard Variable', Pretendard, -apple-system, BlinkMacSystemFont, 'Apple SD Gothic Neo', 'Noto Sans KR', sans-serif;
  --font-family-mono: 'JetBrains Mono', 'SF Mono', Menlo, 'Pretendard Variable', monospace;
  --font-family-keys: -apple-system, BlinkMacSystemFont, 'SF Pro Text', sans-serif; /** 단축키 기호(⌘⌫ ⇧⌘F) — 맥 메뉴와 같은 시스템 글꼴. 모노(JetBrains Mono)는 ⌘·⌫ 그림이 칸을 꽉 채워 서로 붙는다(루오님 10-30). 크기·굵기·줄높이는 text-kbd 그대로, .ld-kbd 에서만. */
  --font-size-title: 18px;
  --font-size-ui: 14px;
  --font-size-body: 13px;
  --font-size-body-chat: 14px;
  --font-size-small: 12px;
  --font-size-meta: 12px;
  --font-size-kbd: 11px;
  --font-size-code: 12px;
  --font-weight-title: 500;
  --font-weight-ui: 500;
  --font-weight-body: 400;
  --font-weight-body-chat: 400;
  --font-weight-small: 400;
  --font-weight-meta: 400;
  --font-weight-kbd: 400;
  --font-weight-code: 400;
  --font-line-height-title: 1.4;
  --font-line-height-ui: 1.5;
  --font-line-height-body: 1.5;
  --font-line-height-body-chat: 1.55;
  --font-line-height-small: 1.5;
  --font-line-height-meta: 1.5;
  --font-line-height-kbd: 1.4;
  --font-line-height-code: 1.6;
  --text-title: var(--font-weight-title) var(--font-size-title)/var(--font-line-height-title) var(--font-family-body); /** 온보딩 제목, 대화 상대 이름(E2 급 큰 헤더). */
  --text-ui: var(--font-weight-ui) var(--font-size-ui)/var(--font-line-height-ui) var(--font-family-body); /** 헤더 이름, 버튼, 44px 컨트롤 라벨. */
  --text-body: var(--font-weight-body) var(--font-size-body)/var(--font-line-height-body) var(--font-family-body); /** 메시지 본문, 설정 설명, 목록 행 제목. */
  --text-body-chat: var(--font-weight-body-chat) var(--font-size-body-chat)/var(--font-line-height-body-chat) var(--font-family-body); /** 대화 창 읽을 글 — 사람 말·카드 질문·답 첫 줄·펼친 본문(#592 루오님 10-29: 읽을 글이 가장 진하고 크게). 메타는 small(ink-secondary). */
  --text-small: var(--font-weight-small) var(--font-size-small)/var(--font-line-height-small) var(--font-family-body); /** 상태 줄, 카드 머리 줄, 보조 설명. ink-secondary 로. */
  --text-meta: var(--font-weight-meta) var(--font-size-meta)/var(--font-line-height-meta) var(--font-family-mono); /** 세션명, 작성 주체 표기('web 세션이 작성'), 섹션 눈썹, 경로. */
  --text-kbd: var(--font-weight-kbd) var(--font-size-kbd)/var(--font-line-height-kbd) var(--font-family-mono); /** 단축키 표시(⌘↵ ⌘⌫ ⌘K), 시각. ink-tertiary 또는 ink-secondary. */
  --text-code: var(--font-weight-code) var(--font-size-code)/var(--font-line-height-code) var(--font-family-mono); /** 명령·diff 블록. */
}

[data-theme="dark"] {
  --color-bg: #0d0d0d; /** 창 바탕. 목록·대화·카드 모두 같은 바탕이다(채운 카드 없음). */
  --color-bg-hover: #161616; /** 목록 행 호버·선택, 입력창 바탕. */
  --color-bg-side: #141414; /** 사이드바·축소판 면(머리 줄 아래 선부터 — 맨 위 신호등 줄은 창 전체 폭이라 bg). m1-spec §2 B1, 루오님 10-24. 묶음 43: 글래스 틀(레일·사이드바·머리 줄·상태창 한 장)은 이 색 60% 반투명(78% → 60%, 라이트·어두운 바탕 ink-secondary 4.58 하한). */
  --color-bg-side-list: #0f0f0f; /** 사이드바 칸 안 스크롤 목록 면(10-25). '나' 행·칸 제목 띠는 bg-side 그대로 — 면이 칸 제목과 목록을 가른다. 호버·선택은 bg-side-hover·bg-selected. */
  --color-bg-selected: #2e2e2e; /** 사이드바 선택 행(지금 본문에 열린 동료·세션), 축소판 아이콘 행도. 호버해도 그대로. 주황은 선택에 쓰지 않는다. */
  --color-bg-side-hover: #202020; /** 사이드바 안 행 호버. */
  --color-bg-frame: #1b1b1b; /** 바깥 틀 불투명 면(묶음 43 §43.6) — 비활성 창·투명도 줄이기 때 레일·사이드바·머리 줄·상태창 한 장의 면. 안쪽 칸 bg 와 다크 1.13:1 · 라이트 1.15:1(bg-side 는 1.06·1.08 로 거의 안 갈림, 디자인검수 v417 🟡2). 글래스 때는 이 면 대신 bg-side 60% 반투명. */
  --color-bg-frame-hover: #262626; /** 불투명 틀(bg-frame — 비활성 창·투명도 줄이기) 위 사이드바·레일 행 호버(묶음 43 §43.6). 틀과 다크 1.14 · 라이트 1.10, bg-selected 와 1.11 · 1.09. 글래스 판 호버는 bg-side-hover 그대로. */
  --color-bg-card: #141414; /** 코드·diff 블록 바탕만. 다른 데 면을 채우지 않는다. */
  --color-bg-mine: #1c1c1c; /** 내 쪽 면 — 대화의 내 말풍선(#341)과 내 에이전트 블록(interaction-rules 37-1a, 쪽 + 면 두 단서). 카드(bg-card) 위에선 bg-mine-card. 다른 데 면을 채우지 않는다. */
  --color-bg-mine-card: rgba(255, 255, 255, 0.05); /** 줄기·카드 안 내 쪽 블록 면(규칙 37-1a) — 반투명이라 바로 뒤 바탕이 무엇이든(창 bg · 카드 bg-card · 나에게 온 accent-soft · 새 답 success-soft) 대비 1.11~1.15:1 = 창 바탕 위 내 말풍선(bg-mine)과 같은 값. 불투명 회색은 색 면(accent-soft·success-soft) 위에서 1.00~1.06 으로 사라짐(41 v409 검수 · 프론트 실측). 대화의 내 말풍선은 bg-mine. 다른 데 면을 채우지 않는다. */
  --color-ink: #f2f2f2; /** 본문·이름·제목. 주버튼 채움색(글자는 on-ink). */
  --color-ink-secondary: #a8a8a8; /** 메타·세션명·보조 글자. 여덟 면 모두(선택 행 포함) 4.5:1 이상 — 다크 bg 8.2·선택 5.7, 라이트 bg 7.3·선택 5.3(#432 루오님 10-28 안 A). */
  --color-ink-tertiary: #878787; /** 단축키·시각·자리표시 글·비활성. bg 위 5.4:1(다크·라이트) — 선택 행(bg-selected) 위에서는 못 넘으니 선택 행 안 흐린 글자는 ink-secondary 로 바꾼다(컴포넌트 규칙). #432 루오님 10-28 안 A(옛 다크 #6a6a6a·라이트 #9c9c9c 는 2.7~3.6). */
  --color-on-ink: #0d0d0d; /** ink 채움(주버튼) 위 글자. */
  --color-line: #222222; /** 헤어라인: 구분선, 카드 테두리, 입력창 테두리. */
  --color-line-strong: #3a3a3a; /** 강조 테두리: 보조 버튼, 포커스 안 둔 선택 행. */
  --color-shadow-drawer: rgba(0, 0, 0, 0.6); /** 떠 있는 레일 서랍 그림자 색(§49, 루오님 11-01 (다)) — box-shadow 8px 0 20px -8px 로 오른쪽 변·둥근 모서리에만(퍼짐 -8 이라 위아래로 안 샘). 선 테두리 대신. 다른 데 쓰지 않는다. */
  --color-line-drawer-edge: rgba(255, 255, 255, 0.08); /** 레일 서랍 오른쪽 변 1px 하이라인(§49) — 다크에서 그림자만으로는 대화 칸(bg)과 안 갈려서. 라이트는 없음(투명). 오른쪽 변만, 위·아래·왼쪽 선 없음. */
  --color-accent-text: #ff8533; /** 강조 글자: 미읽 수, '처리 중', 작업 요청 라벨. bg 위 4.5:1 이상. */
  --color-danger-text: #ff6961; /** 거부·거절 글자, 폴더 밖 표시, 오류 아이콘(state-error). 채운 빨강 면은 세션 끄기 버튼 호버(danger-quiet 반전)뿐 — 사용량 95% 막대 채움은 danger-fill. */
  --color-success: #3fb950; /** 녹 = 켜짐·정상(규칙 21): 처리 중·새 답·쉼 아이콘, 연결됨·접속 점. 프로젝트 패널 깃 상태 글자(새 파일·추적 안 함)와 +n 에도(§28.9, 루오님 10-26). 면 채움 없음(예외: 대화 창 확인 전 새 답 카드 면은 success-soft, #592 B+A) — 예외 사용량 막대 80% 미만 채움(80% warn-fill·95% danger-fill, 루오님 10-28). 여덟 면 모두 4.5:1 이상(#432 루오님 10-28 — 라이트 값 진하게). */
  --color-success-soft: rgba(63, 185, 80, 0.1); /** 대화 창 줄기 카드 '답이 왔는데 확인 전' 면(success 테두리와 짝, #592 루오님 10-29 B+A — 뜻은 규칙 21 state-unseen). 그 밖 면 채움 없음. accent-soft(나에게 온 카드)와 같은 꼴. */
  --color-warn: #e3b341; /** 노 = 주의 — 글자·아이콘·점: 서버 주의 아이콘·설정 상태 점, 깃 상태 글자(고침·이름 바꿈, §28.9). bg 위 4.5:1. 막대 채움엔 쓰지 않는다(warn-fill). 라이트는 옛 올리브 #8a6100 이 탁한 갈색으로 보여 앰버로(루오님 10-27). 여덟 면 모두 4.5:1 이상(#432 루오님 10-28 — 라이트 값 진하게). */
  --color-agent-tile: rgba(0, 0, 0, 0); /** 에이전트 마크(agent-claude) 뒤 타일 — 라이트에서만 흰 타일 + line 테두리로 마크 대비 3.1:1(옅은 면 #f3f3f3 위 2.8 → 타일 위 3.1). 다크는 투명(바탕 위 이미 4.3~6.2). 공식 색은 그대로, #432 루오님 10-28. */
  --color-person-1: #8d98ce; /** 사람 이름 글자 색 1(남색) — 대화 창 사람 이름·그룹 카드 머리 '(이름)의' 만(#592 루오님 10-29 모노톤 의견). 계정 id 문자 코드 합 % 6 으로 고름 — 사이드바·대화 창·그룹 목록 어디서나 같은 사람 = 같은 색. 카드 바탕 위 다크 6.6:1·라이트 6.1:1. 에이전트 이름·상태·버튼·면엔 쓰지 않는다. 짝 = person-tile-1. */
  --color-person-2: #47a3d1; /** 사람 이름 글자 색 2(하늘) — 대화 창 사람 이름·그룹 카드 머리 '(이름)의' 만(#592 루오님 10-29 모노톤 의견). 계정 id 문자 코드 합 % 6 으로 고름 — 사이드바·대화 창·그룹 목록 어디서나 같은 사람 = 같은 색. 카드 바탕 위 다크 6.5:1·라이트 6.0:1. 에이전트 이름·상태·버튼·면엔 쓰지 않는다. 짝 = person-tile-2. */
  --color-person-3: #3bab9f; /** 사람 이름 글자 색 3(청록) — 대화 창 사람 이름·그룹 카드 머리 '(이름)의' 만(#592 루오님 10-29 모노톤 의견). 계정 id 문자 코드 합 % 6 으로 고름 — 사이드바·대화 창·그룹 목록 어디서나 같은 사람 = 같은 색. 카드 바탕 위 다크 6.6:1·라이트 6.2:1. 에이전트 이름·상태·버튼·면엔 쓰지 않는다. 짝 = person-tile-3. */
  --color-person-4: #aa8fcd; /** 사람 이름 글자 색 4(보라) — 대화 창 사람 이름·그룹 카드 머리 '(이름)의' 만(#592 루오님 10-29 모노톤 의견). 계정 id 문자 코드 합 % 6 으로 고름 — 사이드바·대화 창·그룹 목록 어디서나 같은 사람 = 같은 색. 카드 바탕 위 다크 6.6:1·라이트 6.1:1. 에이전트 이름·상태·버튼·면엔 쓰지 않는다. 짝 = person-tile-4. */
  --color-person-5: #d184a0; /** 사람 이름 글자 색 5(장미) — 대화 창 사람 이름·그룹 카드 머리 '(이름)의' 만(#592 루오님 10-29 모노톤 의견). 계정 id 문자 코드 합 % 6 으로 고름 — 사이드바·대화 창·그룹 목록 어디서나 같은 사람 = 같은 색. 카드 바탕 위 다크 6.6:1·라이트 6.0:1. 에이전트 이름·상태·버튼·면엔 쓰지 않는다. 짝 = person-tile-5. */
  --color-person-6: #d37bd3; /** 사람 이름 글자 색 6(자홍) — 대화 창 사람 이름·그룹 카드 머리 '(이름)의' 만(#592 루오님 10-29 모노톤 의견). 계정 id 문자 코드 합 % 6 으로 고름 — 사이드바·대화 창·그룹 목록 어디서나 같은 사람 = 같은 색. 카드 바탕 위 다크 6.6:1·라이트 6.0:1. 에이전트 이름·상태·버튼·면엔 쓰지 않는다. 짝 = person-tile-6. */
  --color-warn-fill: #ff9f0a; /** 막대 채움 전용 — 사용량 80% 이상·서버 주의 막대(macOS systemOrange). 글자·아이콘엔 쓰지 않는다(라이트 바탕 위 2.1:1 — 길이와 % 글자가 값을 말한다). 루오님 10-27. */
  --color-danger-fill: #ff453a; /** 막대 채움 전용 — 사용량 95% 이상(macOS systemRed). 글자·아이콘은 danger-text. 루오님 10-27. */
  --color-danger-quiet: #d9675f; /** 세션 끄기(power) 위험 아이콘 버튼 — 평소 아이콘 색이자, 호버·포커스·누름·열림 때는 같은 색이 칩 면이 되고 아이콘이 on-danger(흰)로 바뀐다(반전, 루오님 10-28). bg 위 라이트 3.57:1·다크 5.6:1, 흰 아이콘 대비 라이트 3.66:1·다크 3.47:1(아이콘 3:1). 글자엔 쓰지 않는다(danger-text). #543. */
  --color-danger-surface: #d9675f; /** danger-quiet 별칭(루오님 10-28 — 호버는 반전: 면 = 평소 아이콘 색). 옛 #c42b20 은 평소 빨강과 달라 쓰지 않음. 새로 쓰지 말고 danger-quiet 를 쓴다. #543. */
  --color-diff-add-bg: rgba(63, 185, 80, 0.14); /** patch 더한 줄 바탕(success 14%). 프로젝트 패널 깃 탭(§28.9)·대화 diff 펜스(§52.1). 줄 앞 + 는 success 글자. */
  --color-diff-del-bg: rgba(255, 105, 97, 0.14); /** patch 뺀 줄 바탕(danger-text 14%). 줄 앞 − 는 danger-text 글자. */
  --color-syntax-keyword: #c8a2f0; /** 코드 보기 구문 색 — 키워드(보라). 프로젝트 패널 파일 보기(§28.9)·대화 코드 블록(§52.1, 아는 언어만). 상태색과 겹치지 않는 색. */
  --color-syntax-string: #9cc9f5; /** 구문 색 — 글자열(파랑). */
  --color-syntax-number: #6ad0c7; /** 구문 색 — 숫자(청록). 여덟 면 모두 4.5:1 이상(#432 루오님 10-28 — 라이트 값 진하게). */
  --color-syntax-comment: #969696; /** 구문 색 — 주석(회색, 바탕 위 4.5:1). 나머지 코드는 ink. 여덟 면 모두 4.5:1 이상(#432 루오님 10-28 — 라이트 값 진하게). */
  --color-code-fg: #a1a1aa; /** diff 의 바뀌지 않은 줄. 바뀐 줄은 ink. 여덟 면 모두 4.5:1 이상(#432 루오님 10-28 — 라이트 값 진하게). */
}
@media (prefers-color-scheme: dark) {
  :host:not([data-theme="light"]) {
    --color-bg: #0d0d0d; /** 창 바탕. 목록·대화·카드 모두 같은 바탕이다(채운 카드 없음). */
    --color-bg-hover: #161616; /** 목록 행 호버·선택, 입력창 바탕. */
    --color-bg-side: #141414; /** 사이드바·축소판 면(머리 줄 아래 선부터 — 맨 위 신호등 줄은 창 전체 폭이라 bg). m1-spec §2 B1, 루오님 10-24. 묶음 43: 글래스 틀(레일·사이드바·머리 줄·상태창 한 장)은 이 색 60% 반투명(78% → 60%, 라이트·어두운 바탕 ink-secondary 4.58 하한). */
    --color-bg-side-list: #0f0f0f; /** 사이드바 칸 안 스크롤 목록 면(10-25). '나' 행·칸 제목 띠는 bg-side 그대로 — 면이 칸 제목과 목록을 가른다. 호버·선택은 bg-side-hover·bg-selected. */
    --color-bg-selected: #2e2e2e; /** 사이드바 선택 행(지금 본문에 열린 동료·세션), 축소판 아이콘 행도. 호버해도 그대로. 주황은 선택에 쓰지 않는다. */
    --color-bg-side-hover: #202020; /** 사이드바 안 행 호버. */
    --color-bg-frame: #1b1b1b; /** 바깥 틀 불투명 면(묶음 43 §43.6) — 비활성 창·투명도 줄이기 때 레일·사이드바·머리 줄·상태창 한 장의 면. 안쪽 칸 bg 와 다크 1.13:1 · 라이트 1.15:1(bg-side 는 1.06·1.08 로 거의 안 갈림, 디자인검수 v417 🟡2). 글래스 때는 이 면 대신 bg-side 60% 반투명. */
    --color-bg-frame-hover: #262626; /** 불투명 틀(bg-frame — 비활성 창·투명도 줄이기) 위 사이드바·레일 행 호버(묶음 43 §43.6). 틀과 다크 1.14 · 라이트 1.10, bg-selected 와 1.11 · 1.09. 글래스 판 호버는 bg-side-hover 그대로. */
    --color-bg-card: #141414; /** 코드·diff 블록 바탕만. 다른 데 면을 채우지 않는다. */
    --color-bg-mine: #1c1c1c; /** 내 쪽 면 — 대화의 내 말풍선(#341)과 내 에이전트 블록(interaction-rules 37-1a, 쪽 + 면 두 단서). 카드(bg-card) 위에선 bg-mine-card. 다른 데 면을 채우지 않는다. */
    --color-bg-mine-card: rgba(255, 255, 255, 0.05); /** 줄기·카드 안 내 쪽 블록 면(규칙 37-1a) — 반투명이라 바로 뒤 바탕이 무엇이든(창 bg · 카드 bg-card · 나에게 온 accent-soft · 새 답 success-soft) 대비 1.11~1.15:1 = 창 바탕 위 내 말풍선(bg-mine)과 같은 값. 불투명 회색은 색 면(accent-soft·success-soft) 위에서 1.00~1.06 으로 사라짐(41 v409 검수 · 프론트 실측). 대화의 내 말풍선은 bg-mine. 다른 데 면을 채우지 않는다. */
    --color-ink: #f2f2f2; /** 본문·이름·제목. 주버튼 채움색(글자는 on-ink). */
    --color-ink-secondary: #a8a8a8; /** 메타·세션명·보조 글자. 여덟 면 모두(선택 행 포함) 4.5:1 이상 — 다크 bg 8.2·선택 5.7, 라이트 bg 7.3·선택 5.3(#432 루오님 10-28 안 A). */
    --color-ink-tertiary: #878787; /** 단축키·시각·자리표시 글·비활성. bg 위 5.4:1(다크·라이트) — 선택 행(bg-selected) 위에서는 못 넘으니 선택 행 안 흐린 글자는 ink-secondary 로 바꾼다(컴포넌트 규칙). #432 루오님 10-28 안 A(옛 다크 #6a6a6a·라이트 #9c9c9c 는 2.7~3.6). */
    --color-on-ink: #0d0d0d; /** ink 채움(주버튼) 위 글자. */
    --color-line: #222222; /** 헤어라인: 구분선, 카드 테두리, 입력창 테두리. */
    --color-line-strong: #3a3a3a; /** 강조 테두리: 보조 버튼, 포커스 안 둔 선택 행. */
    --color-shadow-drawer: rgba(0, 0, 0, 0.6); /** 떠 있는 레일 서랍 그림자 색(§49, 루오님 11-01 (다)) — box-shadow 8px 0 20px -8px 로 오른쪽 변·둥근 모서리에만(퍼짐 -8 이라 위아래로 안 샘). 선 테두리 대신. 다른 데 쓰지 않는다. */
    --color-line-drawer-edge: rgba(255, 255, 255, 0.08); /** 레일 서랍 오른쪽 변 1px 하이라인(§49) — 다크에서 그림자만으로는 대화 칸(bg)과 안 갈려서. 라이트는 없음(투명). 오른쪽 변만, 위·아래·왼쪽 선 없음. */
    --color-accent-text: #ff8533; /** 강조 글자: 미읽 수, '처리 중', 작업 요청 라벨. bg 위 4.5:1 이상. */
    --color-danger-text: #ff6961; /** 거부·거절 글자, 폴더 밖 표시, 오류 아이콘(state-error). 채운 빨강 면은 세션 끄기 버튼 호버(danger-quiet 반전)뿐 — 사용량 95% 막대 채움은 danger-fill. */
    --color-success: #3fb950; /** 녹 = 켜짐·정상(규칙 21): 처리 중·새 답·쉼 아이콘, 연결됨·접속 점. 프로젝트 패널 깃 상태 글자(새 파일·추적 안 함)와 +n 에도(§28.9, 루오님 10-26). 면 채움 없음(예외: 대화 창 확인 전 새 답 카드 면은 success-soft, #592 B+A) — 예외 사용량 막대 80% 미만 채움(80% warn-fill·95% danger-fill, 루오님 10-28). 여덟 면 모두 4.5:1 이상(#432 루오님 10-28 — 라이트 값 진하게). */
    --color-success-soft: rgba(63, 185, 80, 0.1); /** 대화 창 줄기 카드 '답이 왔는데 확인 전' 면(success 테두리와 짝, #592 루오님 10-29 B+A — 뜻은 규칙 21 state-unseen). 그 밖 면 채움 없음. accent-soft(나에게 온 카드)와 같은 꼴. */
    --color-warn: #e3b341; /** 노 = 주의 — 글자·아이콘·점: 서버 주의 아이콘·설정 상태 점, 깃 상태 글자(고침·이름 바꿈, §28.9). bg 위 4.5:1. 막대 채움엔 쓰지 않는다(warn-fill). 라이트는 옛 올리브 #8a6100 이 탁한 갈색으로 보여 앰버로(루오님 10-27). 여덟 면 모두 4.5:1 이상(#432 루오님 10-28 — 라이트 값 진하게). */
    --color-agent-tile: rgba(0, 0, 0, 0); /** 에이전트 마크(agent-claude) 뒤 타일 — 라이트에서만 흰 타일 + line 테두리로 마크 대비 3.1:1(옅은 면 #f3f3f3 위 2.8 → 타일 위 3.1). 다크는 투명(바탕 위 이미 4.3~6.2). 공식 색은 그대로, #432 루오님 10-28. */
    --color-person-1: #8d98ce; /** 사람 이름 글자 색 1(남색) — 대화 창 사람 이름·그룹 카드 머리 '(이름)의' 만(#592 루오님 10-29 모노톤 의견). 계정 id 문자 코드 합 % 6 으로 고름 — 사이드바·대화 창·그룹 목록 어디서나 같은 사람 = 같은 색. 카드 바탕 위 다크 6.6:1·라이트 6.1:1. 에이전트 이름·상태·버튼·면엔 쓰지 않는다. 짝 = person-tile-1. */
    --color-person-2: #47a3d1; /** 사람 이름 글자 색 2(하늘) — 대화 창 사람 이름·그룹 카드 머리 '(이름)의' 만(#592 루오님 10-29 모노톤 의견). 계정 id 문자 코드 합 % 6 으로 고름 — 사이드바·대화 창·그룹 목록 어디서나 같은 사람 = 같은 색. 카드 바탕 위 다크 6.5:1·라이트 6.0:1. 에이전트 이름·상태·버튼·면엔 쓰지 않는다. 짝 = person-tile-2. */
    --color-person-3: #3bab9f; /** 사람 이름 글자 색 3(청록) — 대화 창 사람 이름·그룹 카드 머리 '(이름)의' 만(#592 루오님 10-29 모노톤 의견). 계정 id 문자 코드 합 % 6 으로 고름 — 사이드바·대화 창·그룹 목록 어디서나 같은 사람 = 같은 색. 카드 바탕 위 다크 6.6:1·라이트 6.2:1. 에이전트 이름·상태·버튼·면엔 쓰지 않는다. 짝 = person-tile-3. */
    --color-person-4: #aa8fcd; /** 사람 이름 글자 색 4(보라) — 대화 창 사람 이름·그룹 카드 머리 '(이름)의' 만(#592 루오님 10-29 모노톤 의견). 계정 id 문자 코드 합 % 6 으로 고름 — 사이드바·대화 창·그룹 목록 어디서나 같은 사람 = 같은 색. 카드 바탕 위 다크 6.6:1·라이트 6.1:1. 에이전트 이름·상태·버튼·면엔 쓰지 않는다. 짝 = person-tile-4. */
    --color-person-5: #d184a0; /** 사람 이름 글자 색 5(장미) — 대화 창 사람 이름·그룹 카드 머리 '(이름)의' 만(#592 루오님 10-29 모노톤 의견). 계정 id 문자 코드 합 % 6 으로 고름 — 사이드바·대화 창·그룹 목록 어디서나 같은 사람 = 같은 색. 카드 바탕 위 다크 6.6:1·라이트 6.0:1. 에이전트 이름·상태·버튼·면엔 쓰지 않는다. 짝 = person-tile-5. */
    --color-person-6: #d37bd3; /** 사람 이름 글자 색 6(자홍) — 대화 창 사람 이름·그룹 카드 머리 '(이름)의' 만(#592 루오님 10-29 모노톤 의견). 계정 id 문자 코드 합 % 6 으로 고름 — 사이드바·대화 창·그룹 목록 어디서나 같은 사람 = 같은 색. 카드 바탕 위 다크 6.6:1·라이트 6.0:1. 에이전트 이름·상태·버튼·면엔 쓰지 않는다. 짝 = person-tile-6. */
    --color-warn-fill: #ff9f0a; /** 막대 채움 전용 — 사용량 80% 이상·서버 주의 막대(macOS systemOrange). 글자·아이콘엔 쓰지 않는다(라이트 바탕 위 2.1:1 — 길이와 % 글자가 값을 말한다). 루오님 10-27. */
    --color-danger-fill: #ff453a; /** 막대 채움 전용 — 사용량 95% 이상(macOS systemRed). 글자·아이콘은 danger-text. 루오님 10-27. */
    --color-danger-quiet: #d9675f; /** 세션 끄기(power) 위험 아이콘 버튼 — 평소 아이콘 색이자, 호버·포커스·누름·열림 때는 같은 색이 칩 면이 되고 아이콘이 on-danger(흰)로 바뀐다(반전, 루오님 10-28). bg 위 라이트 3.57:1·다크 5.6:1, 흰 아이콘 대비 라이트 3.66:1·다크 3.47:1(아이콘 3:1). 글자엔 쓰지 않는다(danger-text). #543. */
    --color-danger-surface: #d9675f; /** danger-quiet 별칭(루오님 10-28 — 호버는 반전: 면 = 평소 아이콘 색). 옛 #c42b20 은 평소 빨강과 달라 쓰지 않음. 새로 쓰지 말고 danger-quiet 를 쓴다. #543. */
    --color-diff-add-bg: rgba(63, 185, 80, 0.14); /** patch 더한 줄 바탕(success 14%). 프로젝트 패널 깃 탭(§28.9)·대화 diff 펜스(§52.1). 줄 앞 + 는 success 글자. */
    --color-diff-del-bg: rgba(255, 105, 97, 0.14); /** patch 뺀 줄 바탕(danger-text 14%). 줄 앞 − 는 danger-text 글자. */
    --color-syntax-keyword: #c8a2f0; /** 코드 보기 구문 색 — 키워드(보라). 프로젝트 패널 파일 보기(§28.9)·대화 코드 블록(§52.1, 아는 언어만). 상태색과 겹치지 않는 색. */
    --color-syntax-string: #9cc9f5; /** 구문 색 — 글자열(파랑). */
    --color-syntax-number: #6ad0c7; /** 구문 색 — 숫자(청록). 여덟 면 모두 4.5:1 이상(#432 루오님 10-28 — 라이트 값 진하게). */
    --color-syntax-comment: #969696; /** 구문 색 — 주석(회색, 바탕 위 4.5:1). 나머지 코드는 ink. 여덟 면 모두 4.5:1 이상(#432 루오님 10-28 — 라이트 값 진하게). */
    --color-code-fg: #a1a1aa; /** diff 의 바뀌지 않은 줄. 바뀐 줄은 ink. 여덟 면 모두 4.5:1 이상(#432 루오님 10-28 — 라이트 값 진하게). */
  }
}

:host {
  color-scheme: light dark;
}
[data-theme="light"] {
  color-scheme: light;
}
[data-theme="dark"] {
  color-scheme: dark;
}

/* packages/ui/src/components.css */
/* @lodelai/ui 컴포넌트 스타일. 클래스 접두 ld-. 색·간격·모션은 tokens.css 의 의미 토큰만.
   원천: 디자인 시스템 Artifact components/bundle.css (docs/ux/README.md). 변수명만 tokens.css 이름으로 바꿨다.
   고빈도 전환(버튼·카드·행)에 이동·크기 transition 없음 — docs/ux/interaction-rules.md 1. */

.ld {
  font: var(--text-body);
  color: var(--color-ink);
}
/* 한국어만 어절 단위 줄바꿈(디자인 시스템 v17). */
.ld:lang(ko),
.ld :lang(ko) {
  word-break: keep-all;
}
.ld-row {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  flex-wrap: wrap;
}
.ld-col {
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
}

/* Button */
.ld-btn {
  font-family: var(--font-family-body);
  font-size: var(--font-size-small);
  font-weight: 500;
  height: var(--size-control);
  padding: 0 var(--space-3);
  border-radius: var(--radius-sm);
  border: 1px solid var(--color-line-strong);
  background: transparent;
  color: var(--color-ink);
  cursor: pointer;
  white-space: nowrap;
  display: inline-flex;
  align-items: center;
  gap: var(--size-gap-tight);
  transition:
    opacity var(--motion-duration-instant),
    background-color var(--motion-duration-instant);
}
.ld-btn:active {
  transform: scale(0.97);
}
.ld-btn:focus-visible {
  outline: 2px solid var(--color-accent);
  outline-offset: 3px;
}
.ld-btn:disabled {
  opacity: 0.4;
  cursor: default;
}
.ld-btn-primary {
  background: var(--color-ink);
  border-color: var(--color-ink);
  color: var(--color-on-ink);
}
.ld-btn-ghost {
  border-color: transparent;
  color: var(--color-ink-secondary);
}
.ld-btn-danger {
  border-color: transparent;
  color: var(--color-danger-text);
}
.ld-btn-lg {
  height: var(--size-control-touch);
  font-size: var(--font-size-ui);
  padding: 0 18px;
  border-radius: var(--radius-radius);
}
@media (hover: hover) {
  /* 비활성은 호버해도 모양이 바뀌지 않는다(화면확인 5차 N4 — 비활성 `다시 열기` 가 호버에 활성처럼 바뀌었다). */
  .ld-btn:hover:not(:disabled) {
    background: var(--color-bg-hover);
  }
  .ld-btn-primary:hover:not(:disabled) {
    background: var(--color-ink);
    opacity: 0.85;
  }
}

/* Kbd */
.ld-kbd {
  font: var(--text-kbd);
  /* 기호는 시스템 글꼴 + 자간(루오님 10-30 — 모노의 ⌘·⌫ 가 칸을 꽉 채워 겹쳐 보임). 끝 자간은 되돌려 버튼 여백을 그대로. */
  font-family: var(--font-family-keys);
  letter-spacing: 0.06em;
  margin-inline-end: -0.06em;
  color: var(--color-ink-tertiary);
  white-space: nowrap;
}
.ld-btn .ld-kbd {
  opacity: 0.7;
  color: inherit;
}

/* Badge */
.ld-badge {
  display: inline-flex;
  align-items: center;
  height: var(--size-badge);
  padding: 0 7px;
  border-radius: var(--radius-sm);
  font-family: var(--font-family-body);
  font-size: var(--font-size-small);
  font-weight: 500;
  font-variant-numeric: tabular-nums;
  background: var(--color-accent-soft);
  color: var(--color-accent-text);
  white-space: nowrap;
}
.ld-badge-quiet {
  background: transparent;
  color: var(--color-ink-secondary);
  font-weight: 400;
  padding: 0;
}
.ld-badge-mono {
  /* 폐기(#226) — 상태는 배지가 아니라 Row meta 글자. 넘기면 quiet 와 같게. */
  background: transparent;
  color: var(--color-ink-secondary);
  font-weight: 400;
  padding: 0;
}

/* Avatar */
.ld-avatar {
  width: var(--size-avatar);
  height: var(--size-avatar);
  border-radius: 999px;
  background: var(--color-line);
  color: var(--color-ink-secondary);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  font-family: var(--font-family-body);
  font-size: var(--size-avatar-text);
  font-weight: 500;
  flex: none;
}
.ld-avatar-photo {
  position: relative;
  overflow: hidden;
}
/* 사진 위 안쪽 1px line 테두리(묶음 27 §34.2) — 밝은 사진이 바탕에 녹지 않게, 라이트·다크 모두. 사진 위에 겹쳐 그린다. */
.ld-avatar-photo::after {
  content: "";
  position: absolute;
  inset: 0;
  border-radius: inherit;
  box-shadow: inset 0 0 0 1px var(--color-line);
  pointer-events: none;
}
.ld-avatar-photo img {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
}
.ld-avatar-group {
  border-radius: var(--radius-sm);
  background: var(--color-bg-card);
  color: var(--color-ink-secondary);
}
/* 세션 아바타(DS v56): 에이전트 마크만 — 바탕·테두리 없음, ink-secondary. */
.ld-avatar-agent {
  /* 라이트에서만 흰 타일 + line 테두리 — 옅은 면 위 마크 대비 3.1:1(#432 DS v120). 다크 타일은 투명. */
  background: var(--color-agent-tile, transparent);
  color: var(--color-agent-claude);
}
[data-theme="light"] .ld-avatar-agent {
  box-shadow: inset 0 0 0 1px var(--color-line);
}
@media (prefers-color-scheme: light) {
  :host:not([data-theme="dark"]) .ld-avatar-agent {
    box-shadow: inset 0 0 0 1px var(--color-line);
  }
}
/* 에이전트 마크는 상태가 아니라 '어느 에이전트' — 늘 agent-claude(m1-spec §20.9, 루오님 10-27). 선택·호버여도 그대로.
   흐리는 것은 꺼진 행 전체가 흐릴 때뿐(앱 쪽 규칙). 세션 머리 Segment 의 에이전트 칸은 다른 탭 칸과 같은 색(규칙 28). */
.ld-icon[data-icon="agent-claude"] {
  color: var(--color-agent-claude);
}
.ld-seg .ld-icon[data-icon="agent-claude"] {
  color: inherit;
}
/* DS v126(#555·#554): 크기 있는 Avatar · 조직 타일. 조직 = 둥근 네모(사람 원과 가름), 첫 글자 흰색 500, 색 org-tile-1..6
   (흰 글자 4.99:1 이상, 바탕 위 3.2:1 이상 — 다크·라이트 같은 값). 사진이면 같은 모양으로 자름. */
.ld-avatar-sized {
  flex: none;
  font-weight: 500;
}
.ld-avatar-org {
  border-radius: 22%;
  color: #fff;
  background: var(--color-org-tile-1);
}
.ld-avatar-org[data-tile="2"] {
  background: var(--color-org-tile-2);
}
.ld-avatar-org[data-tile="3"] {
  background: var(--color-org-tile-3);
}
.ld-avatar-org[data-tile="4"] {
  background: var(--color-org-tile-4);
}
.ld-avatar-org[data-tile="5"] {
  background: var(--color-org-tile-5);
}
.ld-avatar-org[data-tile="6"] {
  background: var(--color-org-tile-6);
}
/* AvatarButton: 사진 자체가 버튼. 호버·키보드 포커스·메뉴 열림·올리는 중에 검은 45% 겹침 + camera(흰). 포커스 링 accent 2px 바깥 2px.
   애니메이션 없음. 평소엔 오른쪽 아래 camera 배지(v127) — 겹침이 보일 땐 숨김(카메라 둘 금지). */
.ld-avbtn {
  all: unset;
  position: relative;
  display: inline-flex;
  flex: none;
  border-radius: 999px;
  cursor: pointer;
  box-sizing: border-box;
}
.ld-avbtn-org {
  border-radius: 22%;
}
.ld-avbtn .ld-avatar {
  width: 100% !important;
  height: 100% !important;
}
.ld-avbtn-ov {
  position: absolute;
  inset: 0;
  border-radius: inherit;
  background: rgba(0, 0, 0, 0.45);
  color: #fff;
  display: none;
  align-items: center;
  justify-content: center;
  pointer-events: none;
}
.ld-avbtn:focus-visible {
  outline: 2px solid var(--color-accent);
  outline-offset: 2px;
}
.ld-avbtn[data-busy="true"] {
  cursor: default;
}
.ld-avbtn-badge {
  position: absolute;
  right: -2px;
  bottom: -2px;
  width: max(16px, 40%);
  height: max(16px, 40%);
  box-sizing: border-box;
  border-radius: 999px;
  background: var(--color-bg);
  border: 1px solid var(--color-line-strong);
  color: var(--color-ink-secondary);
  display: flex;
  align-items: center;
  justify-content: center;
  pointer-events: none;
}
@media (hover: hover) {
  .ld-avbtn:hover .ld-avbtn-ov {
    display: flex;
  }
  .ld-avbtn:hover .ld-avatar {
    color: transparent;
  }
  .ld-avbtn:hover .ld-avbtn-badge {
    display: none;
  }
}
.ld-avbtn:focus-visible .ld-avbtn-ov,
.ld-avbtn[aria-expanded="true"] .ld-avbtn-ov,
.ld-avbtn[data-busy="true"] .ld-avbtn-ov {
  display: flex;
}
/* 겹침이 보일 때 이니셜·타일 글자는 숨김(카메라와 겹쳐 읽히지 않게) — 사진은 그대로 비침. */
.ld-avbtn:focus-visible .ld-avatar,
.ld-avbtn[aria-expanded="true"] .ld-avatar,
.ld-avbtn[data-busy="true"] .ld-avatar {
  color: transparent;
}
.ld-avbtn:focus-visible .ld-avbtn-badge,
.ld-avbtn[aria-expanded="true"] .ld-avbtn-badge,
.ld-avbtn[data-busy="true"] .ld-avbtn-badge {
  display: none;
}
/* 둥근 네모 테두리 상자 — 축소판 프로젝트 칸(app.css .app-project-cell)이 쓴다. */
.ld-avatar-session {
  border-radius: var(--radius-sm);
  background: transparent;
  border: 1px solid var(--color-line-strong);
  font-family: var(--font-family-mono);
}

/* Row */
.ld-rowitem {
  display: flex;
  align-items: center;
  gap: var(--size-gap-inner);
  width: 100%;
  box-sizing: border-box;
  height: var(--size-row);
  padding: 0 var(--size-gap-inner);
  border: 0;
  border-radius: var(--radius-sm);
  background: transparent;
  font-family: var(--font-family-body);
  font-size: var(--font-size-body);
  color: var(--color-ink);
  text-align: start;
  cursor: default;
  text-decoration: none;
}
.ld-rowitem:focus-visible {
  outline: 2px solid var(--color-accent);
  outline-offset: -2px;
}
.ld-rowitem-sel {
  background: var(--color-bg-hover);
}
.ld-rowitem-dim {
  color: var(--color-ink-tertiary);
}
/* 선택 면(bg-selected) 위에서는 ink-tertiary 가 4.5:1 을 못 넘는다 — 선택 행 안 흐린 글자는 ink-secondary(#432 DS v120 안 A). */
.ld-rowitem-sel .ld-rowitem-r,
.ld-rowitem-sel.ld-rowitem-dim,
.ld-rowitem-sel .ld-rowitem-dim,
.ld-rowitem-sel .ld-kbd,
.ld-rail-i[aria-current="true"] .ld-rowitem-r,
.ld-seg-i[aria-checked="true"] .ld-kbd,
.ld-seg-i[aria-pressed="true"] .ld-kbd {
  color: var(--color-ink-secondary);
}
@media (hover: hover) {
  .ld-rowitem:hover {
    background: var(--color-bg-hover);
  }
}
.ld-rowitem-radio {
  gap: var(--space-2);
}
.ld-radio {
  flex: none;
  width: 14px;
  height: 14px;
  box-sizing: border-box;
  border: 1px solid var(--color-line-strong);
  border-radius: 999px;
  display: flex;
  align-items: center;
  justify-content: center;
}
/* DS v54(디자인감사 12 — 주황은 '나를 부름' 하나): 고른 라디오는 ink 채움, Radio 컴포넌트와 같은 무게. */
.ld-rowitem-radio[aria-checked="true"] .ld-radio {
  background: var(--color-ink);
  border-color: var(--color-ink);
}
.ld-rowitem-radio[aria-checked="true"] .ld-radio::after {
  content: "";
  width: 6px;
  height: 6px;
  border-radius: 999px;
  background: var(--color-bg);
}
.ld-rowitem-t {
  /* 이름이 주인공 — 자리가 모자라면 메타가 먼저 줄어든다(메타 flex-shrink 가 더 크다). */
  flex: 1 1 auto;
  min-width: 0;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.ld-rowitem-m {
  font-family: var(--font-family-mono);
  font-size: var(--font-size-meta);
}
.ld-rowitem-r {
  /* 줄어드는 몫은 기준 폭 × 이 값에 비례 — 크게 둬서 메타가 0 이 될 때까지 이름은 거의 그대로. */
  flex: 0 1000 auto;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  font-size: var(--font-size-small);
  color: var(--color-ink-tertiary);
  font-variant-numeric: tabular-nums;
}

/* MessageRow */
.ld-msg {
  display: grid;
  grid-template-columns: var(--size-avatar) 1fr;
  column-gap: var(--size-gap-inner);
  font-family: var(--font-family-body);
  font-size: var(--font-size-body);
  line-height: var(--font-line-height-body);
  color: var(--color-ink);
}
.ld-msg-body {
  min-width: 0;
}
/* 이어진 줄(DS v113 continued): 같은 사람이 잇달아 보낸 묶음의 둘째 줄부터 — 아바타 열은 같은 폭으로 비우고 이름 줄 없음. 앞 줄과의 간격은 목록 몫. */
.ld-msg-cont > span:first-child {
  width: var(--size-avatar);
}
.ld-msg-hd {
  display: flex;
  gap: var(--space-2);
  align-items: baseline;
  flex-wrap: wrap;
}
.ld-msg-hd b {
  font-weight: 500;
}
/* 작성 주체 텍스트는 어떤 폭에서도 줄이지 않는다(규칙 14): 말줄임·overflow hidden 금지. */
/* 이름 줄(묶음 3 N9 디자이너): 본문 글꼴 ink-secondary, 세션 이름(slug)만 모노 — 한글을 모노로 쓰면 폭이 벌어진다(DS v35). */
.ld-msg-by {
  font-family: var(--font-family-body);
  font-size: var(--font-size-small);
  color: var(--color-ink-secondary);
}
.ld-msg-by .app-mono,
.ld-msg-by .ld-mono {
  font-family: var(--font-family-mono);
  font-size: var(--font-size-meta);
}
.ld-msg-t {
  font-family: var(--font-family-body);
  font-size: var(--font-size-kbd);
  color: var(--color-ink-tertiary);
  font-variant-numeric: tabular-nums;
}
/* 오른쪽 쪽(규칙 37): 아바타 열을 오른쪽으로, 머리는 거울(오른쪽 끝부터 이름 · 시각 · tail · by). 본문 글은 왼쪽 정렬 그대로. */
.ld-msg[data-side="right"] {
  grid-template-columns: 1fr var(--size-avatar);
}
.ld-msg[data-side="right"]:not(.ld-msg-cont) > :first-child,
.ld-msg-cont[data-side="right"] > span[aria-hidden="true"] {
  grid-column: 2;
  grid-row: 1;
}
.ld-msg[data-side="right"] > .ld-msg-body {
  grid-column: 1;
  grid-row: 1;
  /* 본문 칸 680 상한(.ld-msg > div)이 1fr 열 왼쪽에 붙어 머리 끝과 아바타 사이가 비던 것(41 재관문 6) — 아바타 쪽으로 붙인다. */
  justify-self: end;
}
.ld-msg[data-side="right"] .ld-msg-hd {
  flex-direction: row-reverse;
}
.ld-msg[data-side="right"] .ld-msg-hd > span:first-child {
  order: 1;
}
.ld-msg[data-side="right"] .ld-msg-t {
  order: 2;
}
.ld-msg[data-side="right"] .ld-msg-tail {
  order: 3;
}
.ld-msg[data-side="right"] .ld-msg-by {
  order: 4;
}
.ld-msg-tail {
  display: inline-flex;
  align-items: center;
  color: var(--color-ink-secondary);
}
.ld-msg-ft {
  font-size: var(--font-size-small);
  color: var(--color-ink-secondary);
  margin-top: var(--space-1);
}

/* InlineCard */
.ld-card {
  margin-top: var(--size-gap-tight);
  border: 1px solid var(--color-line);
  border-radius: var(--radius-radius);
  overflow: hidden;
  font-family: var(--font-family-body);
  font-size: var(--font-size-body);
  color: var(--color-ink);
}
.ld-card-hd {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  min-height: 32px;
  padding: 0 var(--space-3);
  border-bottom: 1px solid var(--color-line);
  font-size: var(--font-size-small);
  color: var(--color-ink-secondary);
}
.ld-card-k {
  /* 종류 라벨은 강조색이 아니다(#226, focus.md 강조 예산). */
  font-family: var(--font-family-body);
  font-weight: 500;
  color: var(--color-ink);
}
.ld-card-hd b {
  color: var(--color-ink);
  font-weight: 500;
}
/* 경로는 잘라 숨기지 않는다(규칙 7): 길면 줄바꿈. */
.ld-card-target {
  font-family: var(--font-family-mono);
  min-width: 0;
  overflow-wrap: anywhere;
}
.ld-card-scope {
  white-space: nowrap;
}
.ld-card-scope-out {
  color: var(--color-danger-text);
}
.ld-card-sp {
  flex: 1;
}
.ld-card-bd {
  padding: var(--size-gap-inner) var(--space-3);
}
.ld-card-lead {
  padding: var(--size-gap-inner) var(--space-3) 0;
  font-size: 12px;
  color: var(--color-ink-tertiary);
}
.ld-card-extra {
  padding: 0 var(--space-3) var(--size-gap-inner);
}
.ld-card-ft {
  display: flex;
  align-items: flex-start;
  gap: var(--size-gap-tight);
  padding: var(--space-2) var(--space-3) var(--size-gap-inner);
}
/* 버튼 묶음만 꺾인다 — 오른쪽 끝 secondary 는 늘 첫 줄 끝(배치 대조 2 🟡1). */
.ld-card-acts {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--size-gap-tight);
  min-width: 0;
}
.ld-card-ft > .ld-card-n,
.ld-card-ft > :last-child {
  flex-shrink: 0;
}
.ld-card-n {
  font-size: var(--font-size-small);
  color: var(--color-ink-tertiary);
}
.ld-card-ft-line {
  border-top: 1px solid var(--color-line);
}
/* diff 전문: 스크롤이지 말줄임이 아니다(규칙 7). 바뀐 줄만 ink. */
.ld-pre {
  margin: 0;
  padding: var(--size-gap-inner) var(--space-3);
  background: var(--color-bg-card);
  font-family: var(--font-family-mono);
  font-size: var(--font-size-code);
  line-height: var(--font-line-height-code);
  color: var(--color-code-fg);
  white-space: pre;
  overflow: auto;
}
.ld-pre-add,
.ld-pre-del {
  color: var(--color-ink);
}
/* 줄바꿈 켬(규칙 32 E): 줄마다 한 블록, 이어진 줄은 원래 줄 들여쓰기(--ld-ind)에 맞춘다(hanging indent). */
.ld-pre[data-wrap] {
  white-space: pre-wrap;
  overflow-wrap: anywhere;
  tab-size: 4;
}
.ld-pre-ln {
  display: block;
  padding-inline-start: var(--ld-ind, 0);
  text-indent: calc(-1 * var(--ld-ind, 0ch));
}
/* 드러낸 숨은 문자 표식 ⟦U+XXXX⟧ — 줄 색과 무관하게 위험 색. */
.ld-pre-hidden {
  color: var(--color-danger-text);
}
/* 회신 원문(글) — 줄바꿈하고 ink 로 읽는다. 민감 구간(AC-RV-4)은 색만으로 가르지 않게 밑줄도, 바탕은 칠하지 않는다. */
.ld-pre-text {
  color: var(--color-ink);
  white-space: pre-wrap;
  overflow-wrap: anywhere;
}
.ld-pre-sensitive {
  color: var(--color-danger-text);
  text-decoration: underline 1px;
  text-underline-offset: 2px;
}
.ld-ta {
  display: block;
  width: 100%;
  box-sizing: border-box;
  font: inherit;
  padding: var(--size-gap-inner) var(--space-3);
  border: 0;
  background: transparent;
  color: var(--color-ink);
  resize: none;
  line-height: var(--font-line-height-body);
}
.ld-ta:focus-visible {
  outline: 2px solid var(--color-accent);
  outline-offset: -2px;
  border-radius: var(--radius-radius);
}

/* Toggle */
.ld-toggle {
  display: flex;
  align-items: flex-start;
  gap: var(--size-gap-inner);
  cursor: pointer;
  font-family: var(--font-family-body);
  position: relative;
}
.ld-toggle input {
  position: absolute;
  opacity: 0;
  width: 0;
  height: 0;
}
.ld-toggle-track {
  width: 28px;
  height: 16px;
  border-radius: 999px;
  background: var(--color-line-strong);
  position: relative;
  flex: none;
  margin-top: 2px;
  transition: background-color var(--motion-duration-fast);
}
.ld-toggle-track::after {
  content: "";
  position: absolute;
  top: 2px;
  inset-inline-start: 2px;
  width: 12px;
  height: 12px;
  border-radius: 999px;
  background: var(--color-bg);
  transition: inset-inline-start var(--motion-duration-fast) var(--motion-easing-state);
}
.ld-toggle input:checked + .ld-toggle-track {
  background: var(--color-ink);
}
.ld-toggle input:checked + .ld-toggle-track::after {
  inset-inline-start: 14px;
}
.ld-toggle input:focus-visible + .ld-toggle-track,
.ld-toggle-track[data-state~="focus"] {
  outline: 2px solid var(--color-accent);
  outline-offset: 3px;
}
.ld-toggle-bare {
  align-items: center;
}
.ld-toggle-bare .ld-toggle-track {
  margin-top: 0;
}
.ld-toggle input:is(:disabled, [aria-disabled="true"]) + .ld-toggle-track {
  opacity: 0.4;
}
.ld-toggle:has(input:is(:disabled, [aria-disabled="true"])) {
  cursor: default;
}
.ld-toggle-l {
  display: block;
  font-size: var(--font-size-body);
  color: var(--color-ink);
}
.ld-toggle-d {
  display: block;
  font-size: var(--font-size-small);
  color: var(--color-ink-secondary);
}

/* Note */
.ld-note {
  display: flex;
  gap: var(--space-2);
  align-items: baseline;
  padding: var(--space-2) 0;
  border-top: 1px solid var(--color-line);
  border-bottom: 1px solid var(--color-line);
  font-family: var(--font-family-body);
  font-size: var(--font-size-small);
  color: var(--color-ink-secondary);
}
.ld-note b {
  color: var(--color-ink);
  font-weight: 500;
}
.ld-note-ic {
  flex: none;
  display: inline-flex;
  align-self: center;
  color: var(--color-danger-text);
}
/* 좁은 열: 제목 위·본문 아래 */
.ld-note-stack {
  flex-direction: column;
  align-items: stretch;
  gap: var(--space-1);
}

/* 섹션 눈썹(목록 머리) */
.ld-eyebrow {
  font: var(--text-kbd);
  letter-spacing: 0.02em;
  color: var(--color-ink-secondary);
  padding: var(--size-gap-inner) 14px 4px;
}
/* 한글 눈썹은 본문 글꼴 — 모노 폭 공백이 `내  세션` 처럼 벌어져 보인다(디자인 점검 #341-1, DS v35). 크기·색은 그대로. */
:lang(ko) .ld-eyebrow {
  font-family: var(--font-family-body);
  letter-spacing: 0;
}
/* 눈썹 줄 + 오른쪽 만드는 동작(v28): 줄 높이는 그대로 — 버튼이 위아래로 space-1 씩 겹친다. */
.ld-eyebrow-act {
  display: flex;
  align-items: center;
  gap: var(--space-2);
}
.ld-eyebrow-act > .sp {
  flex: 1;
}
.ld-eyebrow-act .ld-tip {
  margin-block: calc(var(--space-1) * -1);
}
/* 같은 이름 구분(#355): 이름 뒤 · 아이디 — 흐리게, 줄지 않음. 감싼 쪽이 이름을 줄인다(ld-person). */
.ld-pid {
  flex: none;
  white-space: nowrap;
  color: var(--color-ink-tertiary);
  font-weight: 400;
}
.ld-pid-id {
  font-family: var(--font-family-mono);
  font-size: var(--font-size-small);
}
.ld-person {
  display: inline-flex;
  align-items: baseline;
  max-width: 100%;
  min-width: 0;
  vertical-align: bottom;
}
.ld-person-n {
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
/* 목록 섹션 빈 상태 — 흐린 한 줄, 버튼 없음(v28). */
.ld-list-empty {
  padding: var(--space-1) var(--size-gap-inner);
  font-family: var(--font-family-body);
  font-size: var(--font-size-small);
  color: var(--color-ink-tertiary);
}
/* 아이콘 버튼(v28): 20px 상자, 누르는 영역 28px, 테두리·채움 없음, 상시 표시. */
.ld-ibtn {
  position: relative;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  flex: none;
  width: var(--size-badge);
  height: var(--size-badge);
  padding: 0;
  border: 0;
  border-radius: var(--radius-sm);
  background: transparent;
  color: var(--color-ink-secondary);
  cursor: pointer;
}
.ld-ibtn::before {
  content: "";
  position: absolute;
  inset: calc(var(--space-1) * -1);
}
.ld-ibtn[aria-pressed="true"],
.ld-ibtn[data-state~="hover"] {
  color: var(--color-ink);
}
.ld-ibtn[data-state~="hover"],
.ld-ibtn[aria-pressed="true"] {
  /* 눌림은 배경까지(디자이너 10-24 — 세션 정보를 보는 동안 info 가 눌린 모양, 메인·옆 칸·떼어진 창 같음). */
  background: var(--color-bg-hover);
}
/* 채움(관리자 shield — interaction-rules 19): 상태는 배경이 아니라 채운 모양으로. 호버 배경은 그대로. */
.ld-ibtn[data-filled] {
  background: transparent;
}
.ld-ibtn[data-filled] svg path {
  fill: currentColor;
}
@media (hover: hover) {
  .ld-ibtn:hover {
    color: var(--color-ink);
    background: var(--color-bg-hover);
  }
}
.ld-ibtn:focus-visible,
.ld-ibtn[data-state~="focus"] {
  outline: 2px solid var(--color-accent);
  outline-offset: 2px;
  color: var(--color-ink);
}
/* tone=danger(DS v123, #543 루오님 10-28): 평소 아이콘 danger-quiet, 호버·포커스·누름(열림 포함)은 같은 색 면 반전 + on-danger.
   전환 없음(규칙 1). 비활성은 quiet 그대로 흐림(아래 :disabled). */
.ld-ibtn[data-tone="danger"] {
  color: var(--color-danger-quiet);
}
.ld-ibtn[data-tone="danger"]:not(:disabled, [aria-disabled="true"]):is(
    :hover,
    :focus-visible,
    :active,
    [aria-expanded="true"],
    [data-state~="hover"]
  ) {
  color: var(--color-on-danger);
  background: var(--color-danger-quiet);
}
.ld-ibtn:disabled,
.ld-ibtn[aria-disabled="true"] {
  opacity: 0.4;
  cursor: default;
  background: transparent;
}

@media (prefers-reduced-motion: reduce) {
  .ld-btn,
  .ld-toggle-track,
  .ld-toggle-track::after {
    transition: none;
  }
  .ld-btn:active {
    transform: none;
  }
}

/* ── 설정(focus.md 9.2, 디자인 시스템 v22) ── */

/* 강제 상태 훅(data-state): 상태 카탈로그 전용. 제품 코드는 넘기지 않는다. */
.ld-rowitem:focus-visible,
.ld-rowitem[data-state~="focus"] {
  outline: 2px solid var(--color-accent);
  outline-offset: -2px;
}
.ld-rowitem[data-state~="hover"] {
  background: var(--color-bg-hover);
}

/* Icon */
.ld-icon {
  display: inline-flex;
  flex: none;
  color: inherit;
}
.ld-icon svg {
  display: block;
}

/* SettingGroup · SettingRow */
.ld-set-group {
  display: flex;
  flex-direction: column;
}
.ld-set-group + .ld-set-group {
  margin-top: calc(var(--space-5) * 2);
}
/* 그룹 앞 40 은 앞 그룹의 **보이는 끝**(끝 행 마지막 글자 아래 끝, 각주가 있으면 각주 글자 끝)에서 다음 제목 상자 위 끝까지
   (interaction-rules 20a 439c930a). 끝 행 상자 안에서 글자 아래 남는 자리(tail)만큼 앞 그룹 아래를 당긴다.
   tail 은 행 꼴마다 실측(헤드리스 10-25): 한 줄 행(최소 44, 가운데) 14.25 · 설명 있는 행 8 · 각주 2. */
.ld-set-group:has(+ .ld-set-group) {
  margin-bottom: -14.25px;
}
.ld-set-group:has(> .ld-set-row:last-child .ld-set-d):has(+ .ld-set-group) {
  margin-bottom: -8px;
}
.ld-set-group:has(> .ld-set-foot:last-child):has(+ .ld-set-group) {
  margin-bottom: -2px;
}
/* 섹션 제목(interaction-rules 20a, DS v43 — 루오님 10-25 안 2): 본문 글꼴 600 12 ink + 앞 막대 2×12 ink(주황 아님 — 강조 예산),
   제목→첫 행 8, 제목 아래 선 없음. */
.ld-set-group > .ld-eyebrow {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  font: 600 12px / 1.4 var(--font-family-body);
  letter-spacing: 0;
  color: var(--color-ink);
  padding: 0 0 var(--space-2);
}
/* 막대는 바깥으로(20a e0dd6a77, 루오님 10-25): 제목 **글자**가 행 라벨과 같은 시작선, 막대 2 + 간격 8 은 그 왼쪽 여백에. */
.ld-set-group > .ld-eyebrow {
  margin-inline-start: calc((2px + var(--space-2)) * -1);
}
.ld-set-group > .ld-eyebrow::before {
  content: "";
  flex: none;
  width: 2px;
  height: 12px;
  background: currentColor;
}
.ld-set-foot {
  font-size: var(--font-size-small);
  color: var(--color-ink-secondary);
  padding-top: var(--space-2);
}
.ld-set-row {
  display: flex;
  align-items: center;
  gap: var(--space-4);
  min-height: var(--size-control-touch);
  padding: var(--size-gap-tight) 0;
  box-sizing: border-box;
  font-family: var(--font-family-body);
  font-size: var(--font-size-body);
  color: var(--color-ink);
  text-decoration: none;
}
/* 선은 행 사이에만 — 섹션 첫 행 위·마지막 행 아래 없음(20a). */
.ld-set-row + .ld-set-row {
  border-top: 1px solid var(--color-line);
}
.ld-set-l {
  flex: 1;
  min-width: 0;
}
.ld-set-lb {
  font-size: var(--font-size-body);
  color: var(--color-ink);
}
.ld-set-d {
  font-size: var(--font-size-small);
  color: var(--color-ink-secondary);
  margin-top: 1px;
}
/* 값이 길면(세션 이름 = 대화 제목 80자 등) 라벨을 밀어 겹치지 않게 — 값 칸은 행의 60% 까지, 넘치면 값만 말줄임(버튼은 그대로). */
.ld-set-c {
  flex: 0 1 auto;
  min-width: 0;
  max-width: 60%;
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
}
.ld-set-c > * {
  flex: none;
}
.ld-set-c > .ld-set-v {
  flex: 0 1 auto;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
}
.ld-set-v {
  font-size: var(--font-size-body);
  color: var(--color-ink-secondary);
  white-space: nowrap;
  font-variant-numeric: tabular-nums;
}
.ld-set-v-quiet {
  color: var(--color-ink-tertiary);
}
.ld-set-v-danger {
  color: var(--color-danger-text);
}
.ld-set-v-mono {
  font-family: var(--font-family-mono);
  font-size: var(--font-size-meta);
}
.ld-set-row-dim .ld-set-lb,
.ld-set-row-dim .ld-set-d {
  color: var(--color-ink-tertiary);
}
/* 누르는 행(결함 7 — 디자이너): 행 자체는 다른 행과 같은 100% 폭이라 구분선·글자 끝이 같다. 호버·포커스 면만 ::before 로
   좌우 gap-inner 만큼 넓게 그린다(구분선을 넓히지 않고). */
a.ld-set-row,
button.ld-set-row {
  cursor: pointer;
  background: transparent;
  /* 단추 기본 테두리를 다 지운다 — 행 사이 선은 `.ld-set-row + .ld-set-row` 위 선이 그린다(20a 뒤 끝 행 아래에 단추 기본 2px 이 드러났음, 화면확인 8차). */
  border: 0;
  text-align: start;
  width: 100%;
  border-radius: 0;
  position: relative;
  isolation: isolate;
}
a.ld-set-row::before,
button.ld-set-row::before {
  content: "";
  position: absolute;
  inset-block: 0;
  inset-inline: calc(var(--size-gap-inner) * -1);
  z-index: -1;
  pointer-events: none;
  border-radius: var(--radius-sm);
}
a.ld-set-row:focus-visible,
button.ld-set-row:focus-visible {
  outline: none;
}
a.ld-set-row:focus-visible::before,
button.ld-set-row:focus-visible::before,
a.ld-set-row[data-state~="focus"]::before,
button.ld-set-row[data-state~="focus"]::before {
  outline: 2px solid var(--color-accent);
  outline-offset: -2px;
}
a.ld-set-row[data-state~="hover"]::before,
button.ld-set-row[data-state~="hover"]::before {
  background: var(--color-bg-hover);
}
@media (hover: hover) {
  a.ld-set-row:hover::before,
  button.ld-set-row:hover::before {
    background: var(--color-bg-hover);
  }
}
.ld-set-row-dis {
  cursor: default;
  pointer-events: none;
}
.ld-set-row-dis .ld-set-lb,
.ld-set-row-dis .ld-set-v {
  color: var(--color-ink-tertiary);
}

/* ValuePopup — 메뉴 애니메이션 없음(규칙 1) */
.ld-pop {
  position: relative;
  display: inline-flex;
}
.ld-pop-t {
  display: inline-flex;
  align-items: center;
  gap: var(--size-gap-tight);
  height: var(--size-control);
  padding: 0 var(--space-2);
  border: 0;
  border-radius: var(--radius-sm);
  background: transparent;
  font-family: var(--font-family-body);
  font-size: var(--font-size-body);
  color: var(--color-ink-secondary);
  cursor: pointer;
  white-space: nowrap;
}
.ld-pop-t .ld-icon {
  color: var(--color-ink-tertiary);
}
.ld-pop-t:focus-visible,
.ld-pop-t[data-state~="focus"] {
  outline: 2px solid var(--color-accent);
  outline-offset: 3px;
}
.ld-pop-t[aria-expanded="true"],
.ld-pop-t[data-state~="hover"] {
  background: var(--color-bg-hover);
  color: var(--color-ink);
}
@media (hover: hover) {
  .ld-pop-t:hover {
    background: var(--color-bg-hover);
    color: var(--color-ink);
  }
}
.ld-pop-t:disabled,
.ld-pop-t[aria-disabled="true"] {
  opacity: 0.4;
  cursor: default;
  background: transparent;
}
.ld-menu {
  position: absolute;
  top: calc(100% + var(--space-1));
  inset-inline-end: 0;
  z-index: 20;
  min-width: 100%;
  box-sizing: border-box;
  padding: var(--space-1);
  background: var(--color-bg);
  border: 1px solid var(--color-line-strong);
  border-radius: var(--radius-radius);
  transform-origin: top right;
  margin: 0;
  list-style: none;
  /* 긴 항목(이름 · 이메일)은 팝오버 폭에서 라벨을 줄인다 — meta 는 끝까지(#357). */
  max-width: var(--size-popover);
}
.ld-menu-h {
  padding: var(--space-1) var(--space-2) 0 calc(var(--space-2) + 16px + var(--space-2));
  font-size: var(--font-size-small);
  color: var(--color-ink-secondary);
  white-space: nowrap;
}
.ld-menu-sep {
  height: 1px;
  background: var(--color-line);
  margin: var(--space-1) 0;
}
.ld-menu-i {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  height: var(--size-control);
  padding-block: 0;
  padding-inline: var(--space-2) var(--size-gap-inner);
  border-radius: var(--radius-sm);
  font-family: var(--font-family-body);
  font-size: var(--font-size-body);
  color: var(--color-ink);
  white-space: nowrap;
  cursor: pointer;
}
.ld-opt {
  display: inline-flex;
  min-width: 0;
  max-width: 100%;
}
.ld-opt-l {
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
}
.ld-opt-m {
  flex: none;
  display: inline-flex;
  align-items: center;
  color: var(--color-ink-secondary);
}
.ld-opt-m > .ld-icon {
  margin-right: 2px;
}
.ld-opt-h {
  flex-shrink: 1000;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  color: var(--color-ink-tertiary);
}
.ld-menu-ck {
  width: 16px;
  display: inline-flex;
  color: var(--color-ink);
}
.ld-menu-i[data-active="true"],
.ld-menu-i[data-state~="hover"] {
  background: var(--color-bg-hover);
}
@media (hover: hover) {
  .ld-menu-i:hover {
    background: var(--color-bg-hover);
  }
}
.ld-menu-i[aria-disabled="true"] {
  color: var(--color-ink-tertiary);
  cursor: default;
  background: transparent;
}

/* Segment */
.ld-seg {
  display: inline-flex;
  height: var(--size-control);
  border: 1px solid var(--color-line-strong);
  border-radius: var(--radius-sm);
  box-sizing: border-box;
  overflow: hidden;
}
.ld-seg-i {
  border: 0;
  background: transparent;
  padding: 0 var(--space-3);
  font-family: var(--font-family-body);
  font-size: var(--font-size-small);
  font-weight: 500;
  color: var(--color-ink-secondary);
  cursor: pointer;
  white-space: nowrap;
}
.ld-seg-i + .ld-seg-i {
  border-inline-start: 1px solid var(--color-line);
}
/* 아이콘 칸(묶음 6 세션 머리 `에이전트 | 셸 | 정보`, 보드 StateIcons iseg): 폭 34, 아이콘 ink-secondary, 눌린 칸 ink.
   툴팁 감싸개(ld-tip)가 칸 사이에 끼므로 경계선은 감싸개 기준으로. */
.ld-seg > .ld-tip {
  display: inline-flex;
}
.ld-seg > .ld-tip + .ld-tip > .ld-seg-i {
  border-inline-start: 1px solid var(--color-line);
}
.ld-seg-i.ld-seg-icon {
  width: 34px;
  padding: 0;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  color: var(--color-ink-secondary);
}
.ld-seg-i.ld-seg-icon[aria-checked="true"] {
  color: var(--color-ink);
}
/* 눌린 칸은 사이드바 선택과 같은 뜻이라 같은 색(디자이너 10-24 — 라이트에서 bg-hover 는 옆 칸과 거의 같았다). */
.ld-seg-i[aria-checked="true"] {
  background: var(--color-bg-selected);
  color: var(--color-ink);
}
.ld-seg-i:focus-visible,
.ld-seg-i[data-state~="focus"] {
  outline: 2px solid var(--color-accent);
  outline-offset: -2px;
  border-radius: var(--radius-sm);
}
@media (hover: hover) {
  .ld-seg-i:hover {
    color: var(--color-ink);
  }
}
.ld-seg-i[data-state~="hover"] {
  color: var(--color-ink);
}
.ld-seg-i:disabled,
.ld-seg-i[aria-disabled="true"] {
  opacity: 0.4;
  cursor: default;
}

/* SettingsNav */
.ld-snav {
  display: flex;
  flex-direction: column;
  padding: var(--space-2) var(--size-gap-tight);
}
.ld-snav-hd {
  height: var(--size-row);
  display: flex;
  align-items: center;
  gap: var(--size-gap-inner);
  padding: 0 var(--size-gap-inner);
  font-size: var(--font-size-body);
  font-weight: 500;
  color: var(--color-ink);
}
.ld-snav-sp {
  flex: 1;
}
.ld-snav .ld-rowitem .ld-icon {
  color: var(--color-ink-secondary);
}
.ld-snav .ld-rowitem-sel .ld-icon {
  color: var(--color-ink);
}
.ld-snav button.ld-rowitem {
  border: 0;
  background: transparent;
  width: 100%;
  text-align: start;
  font: inherit;
  color: var(--color-ink);
}
.ld-snav button.ld-rowitem.ld-rowitem-sel {
  background: var(--color-bg-hover);
}

/* 강제 상태 훅(버튼·입력, v24) — 상태 카탈로그 전용 */
.ld-btn[data-state~="hover"] {
  background: var(--color-bg-hover);
}
.ld-btn-primary[data-state~="hover"] {
  background: var(--color-ink);
  opacity: 0.85;
}
.ld-btn[data-state~="active"] {
  transform: scale(0.97);
}
.ld-btn[data-state~="focus"] {
  outline: 2px solid var(--color-accent);
  outline-offset: 3px;
}
.ld-ta[data-state~="focus"] {
  outline: 2px solid var(--color-accent);
  outline-offset: -2px;
  border-radius: var(--radius-radius);
}

/* TextField */
.ld-field {
  display: flex;
  flex-direction: column;
  gap: var(--space-1);
  font-family: var(--font-family-body);
}
.ld-field-l {
  font-size: var(--font-size-small);
  color: var(--color-ink-secondary);
}
.ld-field-i {
  font: inherit;
  font-size: var(--font-size-body);
  height: var(--size-control);
  box-sizing: border-box;
  padding: 0 var(--size-gap-inner);
  border: 1px solid var(--color-line-strong);
  border-radius: var(--radius-sm);
  background: transparent;
  color: var(--color-ink);
  min-width: 0;
}
.ld-field-lg .ld-field-i {
  height: var(--size-control-touch);
  padding: 0 var(--space-3);
  border-radius: var(--radius-radius);
}
.ld-field-i::placeholder {
  color: var(--color-ink-tertiary);
}
.ld-field-i:focus-visible,
.ld-field-i[data-state~="focus"] {
  outline: 2px solid var(--color-accent);
  outline-offset: -1px;
}
.ld-field-i:disabled {
  opacity: 0.4;
}
.ld-field-err .ld-field-i {
  border-color: var(--color-danger-text);
}
.ld-field-h {
  font-size: var(--font-size-small);
  color: var(--color-ink-secondary);
}
.ld-field-err .ld-field-h {
  color: var(--color-danger-text);
}

/* Tooltip — 애니메이션 없음 */
.ld-tip {
  position: relative;
  display: inline-flex;
}
/* 비활성 단추는 포인터 이벤트를 받지 않아(WebKit) 감싼 툴팁이 안 뜬다 — 비활성 이유 툴팁은 감싸개가 받게 한다(화면확인 6차 N4). */
.ld-tip > :disabled {
  pointer-events: none;
}
.ld-tip-b {
  position: absolute;
  bottom: calc(100% + var(--size-gap-tight));
  left: 50%;
  transform: translateX(-50%);
  z-index: 30;
  padding: var(--space-1) var(--space-2);
  background: var(--color-bg);
  border: 1px solid var(--color-line-strong);
  border-radius: var(--radius-sm);
  font-family: var(--font-family-body);
  font-size: var(--font-size-small);
  line-height: 1.4;
  color: var(--color-ink);
  white-space: nowrap;
  pointer-events: none;
}
/* 맨 위 레이어(interaction-rules 18): 툴팁·값 팝업 메뉴·확인 팝오버를 문서 끝 portal 에 fixed 로 — 자리는 useFloating 이 style 로 준다.
   위 .ld-tip-b 의 bottom·left·transform 은 서버 렌더(카탈로그 정적 마크업)용 기본 자리다. */
.ld-menu.ld-float {
  min-width: 0;
}
.ld-float {
  position: fixed;
  z-index: 1000;
  bottom: auto;
  right: auto;
  inset-inline-end: auto;
  transform: none;
  margin: 0;
}
/* 긴 글 툴팁(잘린 행의 전문): 폭 안에서 줄바꿈. */
.ld-tip-b.ld-tip-wrap {
  white-space: normal;
  max-width: 360px;
  overflow-wrap: anywhere;
}
/* 행을 감싼 툴팁은 행 폭 그대로(목록 한 줄). */
.ld-tip:has(> .ld-rowitem) {
  display: flex;
  width: 100%;
}
.ld-tip-b .ld-kbd {
  margin-inline-start: var(--size-gap-tight);
}

/* 내 메시지(DS v33, #341): 오른쪽 정렬 말풍선 — bg-mine, 최대 80%, 아바타·이름 없음. 상태 · 시각은 말풍선 아래 오른쪽 한 줄. */
.ld-msg-mine {
  display: flex;
  flex-direction: column;
  align-items: flex-end;
  gap: var(--space-1);
}
.ld-msg-mine .ld-msg-b {
  max-width: 70%;
  box-sizing: border-box;
  padding: var(--space-2) var(--space-3);
  background: var(--color-bg-mine);
  border-radius: var(--radius-radius);
  color: var(--color-ink);
  overflow-wrap: anywhere;
}
.ld-msg-mine .ld-msg-b > .ld-card {
  margin-top: 0;
  background: var(--color-bg);
}
.ld-msg-mine .ld-msg-ft {
  margin-top: 0;
  display: flex;
  gap: var(--space-2);
  align-items: baseline;
}

/* 알림(DS v40 Toast, #341 — 떠 있는 안내 대체): 오른쪽 영역 머리 바로 아래 가운데, 내용 폭(최대 520)·한 줄·높이 42.
   아래 2px 선이 남은 시간(6초) — 호버·포커스면 멈춤. 같은 것은 하나만, 최대 셋. */
.ld-toasts {
  position: absolute;
  top: calc(44px + var(--space-2));
  left: 0;
  right: 0;
  z-index: 40;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--space-2);
  pointer-events: none;
}
.ld-toast {
  pointer-events: auto;
  position: relative;
  display: flex;
  align-items: center;
  gap: var(--size-gap-inner);
  max-width: min(520px, calc(100% - var(--space-5) * 2));
  box-sizing: border-box;
  padding: var(--size-gap-tight) var(--size-gap-tight) var(--size-gap-tight) var(--space-3);
  background: var(--color-bg);
  border: 1px solid var(--color-line-strong);
  border-radius: var(--radius-radius);
  font-family: var(--font-family-body);
  font-size: var(--font-size-body);
  line-height: 1.4;
  overflow: hidden;
  min-height: calc(var(--size-control) + var(--size-gap-tight) * 2 + 2px);
}
.ld-toast-i {
  flex: none;
  display: inline-flex;
  color: var(--color-ink-secondary);
}
.ld-toast-danger .ld-toast-i {
  color: var(--color-danger-text);
}
.ld-toast-t {
  flex: none;
  font-weight: 500;
  color: var(--color-ink);
  white-space: nowrap;
}
.ld-toast-d {
  flex: 0 1 auto;
  min-width: 0;
  font-size: var(--font-size-small);
  color: var(--color-ink-secondary);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.ld-toast-a {
  flex: none;
  display: inline-flex;
  align-items: center;
  gap: var(--space-1);
  margin-inline-start: var(--space-1);
}
.ld-toast-time {
  position: absolute;
  left: 0;
  bottom: 0;
  height: 2px;
  width: 100%;
  background: var(--color-line-strong);
  transform-origin: left;
  animation: ld-toast-time 6s linear forwards;
}
.ld-toast:hover .ld-toast-time,
.ld-toast:focus-within .ld-toast-time {
  animation-play-state: paused;
}
@keyframes ld-toast-time {
  to {
    transform: scaleX(0);
  }
}
@media (prefers-reduced-motion: reduce) {
  .ld-toast-time {
    animation: none;
  }
}
/* 안내 줄 구조(DS v37): [제목·본문] 글 덩어리가 남은 폭, 동작은 오른쪽 위에 줄지 않게. 제목은 한 줄, 본문은 제목 뒤에 이어 쓰다 꺾인다. */
.ld-note-txt {
  flex: 1;
  min-width: 0;
}
/* 제목은 보통 줄바꿈(DS — 디자이너 10-25, 디자인검수 648): 한 줄 고정이면 긴 제목(en)이 오른쪽 동작 버튼 위로 넘쳤다.
   단어 중간에서 꺾지 않고(ko 어절·en 단어), 아주 긴 한 단어만 넘치지 않게 끊는다. 말줄임 없음(위험 안내의 글을 잃지 않게). */
.ld-note-txt > b {
  word-break: keep-all;
  overflow-wrap: anywhere;
}
.ld-note-stack .ld-note-txt {
  display: flex;
  flex-direction: column;
  gap: var(--space-1);
}
.ld-note-act {
  flex: none;
  /* 버튼 하나면 Note 세로 가운데(루오님 10-24 — 첫 줄 맞춤 margin 은 지움). */
  align-self: center;
  display: inline-flex;
  align-items: center;
  gap: var(--size-gap-tight);
}
/* 버튼 하나: 글과 버튼을 같은 세로 가운데에(위아래 여백 같게 — 글이 위로 붙지 않게, m1-spec §4·디자이너 10-24). */
.ld-note:has(> .ld-note-act):not(.ld-note-below):not(.ld-note-stack) {
  align-items: center;
}
/* 버튼 둘 이상: 글은 위 한 줄(전체 폭), 버튼은 아래 줄 — 글이 버튼에 밀려 줄바꿈되지 않게(m1-spec §4 꺼진 세션 규칙). */
.ld-note-below {
  flex-wrap: wrap;
  row-gap: var(--space-2);
}
.ld-note-below .ld-note-txt {
  flex-basis: 100%;
}
.ld-note-below .ld-note-act {
  align-self: flex-start;
}
/* 대화 폭(DS v38, 루오님 10-24 · 37-11): 행 상자는 끝선까지 — 읽기 폭(--size-read)은 받은 글 글자 줄(문단·인용·코드)에만.
   카드는 자르지 않는다. 내 말풍선 70%(좁은 영역 85%). */
.ld-msg:not(.ld-msg-mine) > div {
  min-width: 0;
}
@container (max-width: 560px) {
  .ld-msg-mine .ld-msg-b {
    max-width: 85%;
  }
}

/* 사이드바 축소판·경계 드래그·세션 상태 기호(DS v39, #341 루오님 요구). */
.ld-rail {
  width: 56px;
  flex: none;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--space-1);
  padding: var(--space-2) 0;
  box-sizing: border-box;
}
.ld-rail-sep {
  width: 24px;
  height: 1px;
  background: var(--color-line);
  margin: var(--space-1) 0;
}
.ld-rail-i {
  position: relative;
  width: 32px;
  height: 32px;
  display: flex;
  align-items: center;
  justify-content: center;
  border: 0;
  border-radius: var(--radius-sm);
  background: transparent;
  color: var(--color-ink-secondary);
  cursor: pointer;
  padding: 0;
}
.ld-rail-i[aria-current="true"] {
  background: var(--color-bg-hover);
  color: var(--color-ink);
}
@media (hover: hover) {
  .ld-rail-i:hover {
    background: var(--color-bg-hover);
  }
}
.ld-rail-i:focus-visible {
  outline: 2px solid var(--color-accent);
  outline-offset: -2px;
}
.ld-rail-dim {
  color: var(--color-ink-tertiary);
}
.ld-rail-dot {
  position: absolute;
  top: 4px;
  right: 4px;
  width: 6px;
  height: 6px;
  border-radius: 3px;
  background: var(--color-accent);
}
.ld-rail-live {
  position: absolute;
  bottom: 2px;
  left: 50%;
  width: 4px;
  height: 4px;
  margin-left: -2px;
  border-radius: 2px;
  background: var(--color-ink-tertiary);
}
.ld-state {
  display: inline-flex;
  flex: none;
  color: var(--color-ink-secondary);
}
.ld-state-need {
  color: var(--color-accent);
}
.ld-state-off {
  color: var(--color-ink-tertiary);
}
@keyframes ld-spin {
  to {
    transform: rotate(360deg);
  }
}
.ld-state-working svg {
  animation: ld-spin 1s linear infinite;
}
/* 상태 아이콘(DS v50, interaction-rules 21): 처리 중만 돈다 — 전환이 아니라 '지금 돌고 있음'. 그 밖의 상태 아이콘은 움직이지 않는다. */
.ld-icon[data-icon="state-working"] svg {
  animation: ld-spin 1.2s linear infinite;
}
@media (prefers-reduced-motion: reduce) {
  .ld-state-working svg,
  .ld-icon[data-icon="state-working"] svg {
    animation: none;
  }
}
.ld-resize {
  position: absolute;
  /* 맨 위 줄(44 + 선)은 끌기 띠가 지나지 않는다 — 신호등 둘레에 선이 생기지 않게(interaction-rules 17). */
  top: 45px;
  bottom: 0;
  width: 6px;
  margin-left: -3px;
  cursor: col-resize;
  z-index: 5;
}
.ld-resize::after {
  content: "";
  position: absolute;
  top: 0;
  bottom: 0;
  left: 2px;
  width: 1px;
  background: transparent;
}
.ld-resize:hover::after,
.ld-resize:focus-visible::after,
.ld-resize[data-state~="drag"]::after {
  background: var(--color-line-strong);
}
.ld-resize:focus-visible {
  outline: none;
}

/* 설정 정보 구조(DS v41, #355): 행 오른쪽 끝 맞춤 — 값과 ghost 버튼 글자가 같은 선. 빨간 눈썹 = 되돌리기 어려운 것. */
.ld-set-c > .ld-btn-ghost:last-child,
.ld-set-c > .ld-confirm-anchor:last-child > .ld-btn-ghost,
.ld-set-c > .app-confirm-anchor:last-child > .ld-btn-ghost {
  margin-inline-end: calc(var(--space-3) * -1);
}
.ld-set-c > .ld-pop:last-child > .ld-pop-t {
  margin-inline-end: calc(var(--space-2) * -1);
}
/* 링크 행 쉐브론 — 그림의 오른쪽 빈자리만큼 당겨 선 끝을 값·버튼 글자와 같은 선에(결함 8). 24 격자 선 끝 15.75(경로 15 + 선 굵기 반).
   16px 은 Icon 기본 크기 — 아이콘 크기 토큰이 아직 없어 숫자로 둔다. 크기가 바뀌면 이 16px 도 같이. */
.ld-set-c > .ld-icon:last-child {
  margin-inline-end: calc(16px * -8.25 / 24);
}
.ld-set-lb .ld-pid {
  font-family: var(--font-family-mono);
  font-size: var(--font-size-small);
  color: var(--color-ink-tertiary);
  margin-inline-start: var(--space-1);
}
.ld-set-group > .ld-eyebrow.ld-eyebrow-danger {
  color: var(--color-danger-text);
}

/* Checkbox · Radio (DS v54 — 손그림 상자·✓ 글자 금지). 16 상자, 켜짐은 ink 채움 + check 12(강조색 아님). */
.ld-check {
  position: relative;
  display: inline-flex;
  align-items: flex-start;
  gap: var(--space-2);
  font-size: 13px;
  color: var(--color-ink);
  cursor: pointer;
}
.ld-check input {
  position: absolute;
  opacity: 0;
  width: 1px;
  height: 1px;
  margin: 0;
}
.ld-check-box,
.ld-radio-box {
  width: 16px;
  height: 16px;
  box-sizing: border-box;
  border: 1px solid var(--color-line-strong);
  border-radius: 4px;
  background: var(--color-bg);
  flex: none;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  color: var(--color-bg);
  margin-top: 1px;
}
.ld-check-bare .ld-check-box,
.ld-check-bare .ld-radio-box {
  margin-top: 0;
}
.ld-check-box .ld-icon {
  visibility: hidden;
}
.ld-check input:checked + .ld-check-box {
  background: var(--color-ink);
  border-color: var(--color-ink);
}
.ld-check input:checked + .ld-check-box .ld-icon {
  visibility: visible;
}
.ld-radio-box {
  border-radius: 999px;
}
.ld-check input:checked + .ld-radio-box {
  border: 5px solid var(--color-ink);
}
.ld-check input:focus-visible + span,
.ld-check input[data-state~="focus"] + span {
  outline: 2px solid var(--color-accent);
  outline-offset: 2px;
}
.ld-check-dis {
  cursor: default;
}
.ld-check-dis .ld-check-box,
.ld-check-dis .ld-radio-box,
.ld-check-dis .ld-check-l {
  opacity: 0.4;
}
.ld-check-l {
  display: flex;
  flex-direction: column;
  gap: 2px;
}
.ld-check-d {
  font-size: 12px;
  color: var(--color-ink-secondary);
}

/* Segment fill(칸 균등 — 팝오버 폭에 두 칸, 묶음 20·14) · multiple(요일 다중, 묶음 12) — DS v54 */
.ld-seg.ld-seg-fill {
  display: flex;
  width: 100%;
}
.ld-seg.ld-seg-fill > .ld-seg-i,
.ld-seg.ld-seg-fill > .ld-tip {
  flex: 1 1 0;
  min-width: min-content;
}
.ld-seg.ld-seg-fill > .ld-tip > .ld-seg-i {
  width: 100%;
}
.ld-seg-i[aria-pressed="true"] {
  background: var(--color-bg-selected);
  color: var(--color-ink);
}
.ld-seg-multi:not(.ld-seg-fill) {
  align-self: flex-start;
}

/* 화면 틀은 선택되지 않는다(interaction-rules 31, 루오님 10-27 — 드래그하면 웹페이지처럼 파랗게 칠해짐). 기본은 none,
   읽을 내용(메시지 본문·카드 본문·마크다운·코드·diff·Note 본문)과 입력칸만 연다. 틀 안의 값은 우클릭 `복사`(data-copy). */
body {
  -webkit-user-select: none;
  user-select: none;
}
input,
textarea,
[contenteditable=""],
[contenteditable="true"],
.ld-msg-b,
.ld-msg-body > :not(.ld-msg-hd):not(.ld-msg-ft),
.ld-card-bd,
.ld-note-b,
pre,
code {
  -webkit-user-select: text;
  user-select: text;
}
/* 내용 칸 안에 놓인 틀(버튼·카드 머리·발)은 다시 닫는다 — user-select 는 부모를 따르므로 요소에 직접 둔다. */
button,
[role="button"],
.ld-card-hd,
.ld-card-ft,
.ld-msg-ft {
  -webkit-user-select: none;
  user-select: none;
}

/* ScrollArea(디자인 시스템 v67, interaction-rules 32): 잘린 쪽 가장자리 페이드 24 — 칸 바탕(--ld-fade-bg) → 투명. 페이드는 스크롤
   요소 안의 sticky 자식이라 공간을 먹지 않고(음수 margin, flex gap 만큼 더) 오버레이 스크롤바를 덮지 않는다. 누르기를 막지 않고,
   나타남·사라짐은 즉시(transition 없음). 위에 붙은 머리([data-stuck])가 있거나 다음 머리가 곧 붙으면([data-stuck-near]) 위 페이드는 생략(머리가 덮는다). */
/* 칸마다 제 값에서 시작한다 — 사용자 변수는 물려받아, 0 이라 style 을 비운 안쪽 칸(대화 안 승인 명령 칸)이 바깥 대화 칸의
   gap 12 를 물려받아 위 페이드가 첫 줄을 12 끌어올렸다(화면확인 b34 hold 카드 명령 줄 잘림). 0 이 아니면 style 이 덮는다. */
.ld-scroll {
  --ld-scroll-gap: 0px;
  --ld-scroll-pt: 0px;
  --ld-scroll-pb: 0px;
  --ld-scroll-pl: 0px;
  --ld-scroll-pr: 0px;
}
.ld-scroll-f {
  position: sticky;
  z-index: 2;
  display: block;
  flex: none;
  align-self: stretch;
  list-style: none;
  pointer-events: none;
  visibility: hidden;
}
.ld-scroll-ft,
.ld-scroll-fb {
  left: 0;
  height: 24px;
}
.ld-scroll-ft {
  top: calc(-1 * var(--ld-scroll-pt, 0px));
  margin-bottom: calc(-24px - var(--ld-scroll-gap, 0px));
  background: linear-gradient(to bottom, var(--ld-fade-bg, var(--color-bg)), transparent);
}
.ld-scroll-fb {
  bottom: calc(-1 * var(--ld-scroll-pb, 0px));
  margin-top: calc(-24px - var(--ld-scroll-gap, 0px));
  background: linear-gradient(to top, var(--ld-fade-bg, var(--color-bg)), transparent);
}
.ld-scroll[data-fade-top] > .ld-scroll-ft,
.ld-scroll[data-fade-bottom] > .ld-scroll-fb,
.ld-scroll[data-fade-top] > .ld-scroll-x > .ld-scroll-ft,
.ld-scroll[data-fade-bottom] > .ld-scroll-x > .ld-scroll-fb {
  visibility: visible;
}
.ld-scroll:has([data-stuck], [data-stuck-near]) > .ld-scroll-ft {
  visibility: hidden;
}
/* 가로: 내용을 max-content(보이는 폭 이상) 한 겹으로 감싸 좌우 페이드를 그 줄 안에 sticky 로 세운다(높이는 내용 전체).
   위·아래 페이드도 그 겹 안 — 폭이 내용 전체라 가로로 밀어도 보인다. 겹 안에는 gap 이 없다. */
.ld-scroll-x {
  --ld-scroll-gap: 0px;
  display: block;
  width: max-content;
  min-width: 100%;
}
.ld-scroll-row {
  display: flex;
}
.ld-scroll-xin {
  display: block;
  flex: 1 0 auto;
}
.ld-scroll-fl,
.ld-scroll-fr {
  width: 24px;
}
.ld-scroll-fl {
  left: calc(-1 * var(--ld-scroll-pl, 0px));
  margin-right: -24px;
  background: linear-gradient(to right, var(--ld-fade-bg, var(--color-bg)), transparent);
}
.ld-scroll-fr {
  right: calc(-1 * var(--ld-scroll-pr, 0px));
  margin-left: -24px;
  background: linear-gradient(to left, var(--ld-fade-bg, var(--color-bg)), transparent);
}
/* 좌우 페이드는 sticky 띠 대신 내용 겹의 마스크(관문 13 ❌⑤ — WebKit 은 가로 sticky 띠가 서지 않아 칼처럼 잘림, Blink 만 됐음).
   마스크는 내용과 함께 밀리므로 보이는 창의 자리(--ld-sl = scrollLeft − 왼쪽 여백, --ld-vw = 보이는 폭)를 mark 가 넣는다.
   잘린 쪽 24px 이 투명 → 그 칸 바탕이 비친다(색 띠와 같은 효과, 테두리·스크롤바는 그대로). */
/* 칸마다 0 에서 시작 — 바깥 칸의 값이 안쪽 칸으로 물려 내려가지 않게(§52.6: 안쪽 상자가 스크롤 0 인데 왼쪽이 흐렸다). */
.ld-scroll {
  --ld-fl: 0px;
  --ld-fr: 0px;
}
.ld-scroll[data-fade-left] {
  --ld-fl: 24px;
}
.ld-scroll[data-fade-right] {
  --ld-fr: 24px;
}
.ld-scroll[data-fade-left] > .ld-scroll-x,
.ld-scroll[data-fade-right] > .ld-scroll-x {
  --ld-hmask: linear-gradient(
    to right,
    transparent var(--ld-sl, 0px),
    #000 calc(var(--ld-sl, 0px) + var(--ld-fl, 0px)),
    #000 calc(var(--ld-sl, 0px) + var(--ld-vw, 100%) - var(--ld-fr, 0px)),
    transparent calc(var(--ld-sl, 0px) + var(--ld-vw, 100%))
  );
  -webkit-mask-image: var(--ld-hmask);
  mask-image: var(--ld-hmask);
}
/* 세로 마스크 겹(ScrollArea mask, §44.3): 레이아웃은 블록 한 겹 그대로 — 마스크는 글래스 틀 위에서만 앱 CSS 가 건다. */
.ld-scroll-y {
  display: block;
  flex: none;
  min-width: 0;
}
/* 늘 보이는 얇은 스크롤바(ScrollArea bar — 대화·파일/diff·사이드바, 규칙 32): 넘칠 때만, 끌기·트랙 누르기 됨. */
.ld-scroll-bar::-webkit-scrollbar {
  width: 8px;
  height: 8px;
  background: transparent;
}
.ld-scroll-bar::-webkit-scrollbar-track,
.ld-scroll-bar::-webkit-scrollbar-corner {
  background: transparent;
}
.ld-scroll-bar::-webkit-scrollbar-thumb {
  background: var(--color-line-strong);
  border-radius: 4px;
}
.ld-scroll-bar::-webkit-scrollbar-thumb:hover,
.ld-scroll-bar::-webkit-scrollbar-thumb:active {
  background: var(--color-ink-tertiary);
}
/* #592 사람 색(루오님 10-29): 사람 첫 글자 원 = person-tile-n 바탕 + 흰 글자, 사람이 쓴 줄 이름 = person-n(계정 주소 문자 코드 합 % 6).
   에이전트·그룹·조직은 해당 없음. 사진이면 사진 그대로. */
.ld-avatar[data-person] {
  color: #fff;
  background: var(--color-person-tile-1);
}
.ld-avatar[data-person="2"] {
  background: var(--color-person-tile-2);
}
.ld-avatar[data-person="3"] {
  background: var(--color-person-tile-3);
}
.ld-avatar[data-person="4"] {
  background: var(--color-person-tile-4);
}
.ld-avatar[data-person="5"] {
  background: var(--color-person-tile-5);
}
.ld-avatar[data-person="6"] {
  background: var(--color-person-tile-6);
}
.ld-avatar-photo[data-person] {
  background: none;
}
.ld-msg[data-person] > .ld-msg-body > .ld-msg-hd b {
  color: var(--color-person-1);
}
.ld-msg[data-person="2"] > .ld-msg-body > .ld-msg-hd b {
  color: var(--color-person-2);
}
.ld-msg[data-person="3"] > .ld-msg-body > .ld-msg-hd b {
  color: var(--color-person-3);
}
.ld-msg[data-person="4"] > .ld-msg-body > .ld-msg-hd b {
  color: var(--color-person-4);
}
.ld-msg[data-person="5"] > .ld-msg-body > .ld-msg-hd b {
  color: var(--color-person-5);
}
.ld-msg[data-person="6"] > .ld-msg-body > .ld-msg-hd b {
  color: var(--color-person-6);
}

/* apps/desktop/src/app.css */
/* 메인 창 레이아웃. 색·간격·글꼴은 tokens.css 의 의미 토큰만. 컴포넌트 스타일은 @lodelai/ui/components.css. */
html,
body,
#root {
  height: 100%;
  margin: 0;
  /* 앱 껍데기는 스크롤·고무줄 튕김이 없다(루오님 10-24 — 스크롤하니 앱 전체가 밀려 내 이름 줄이 신호등 밑으로). 스크롤은 안쪽 칸만. */
  overflow: hidden;
  overscroll-behavior: none;
}
body {
  background: var(--color-bg);
  color: var(--color-ink);
  font: var(--text-body);
}

.app {
  display: flex;
  height: 100%;
}
.app-sidebar {
  flex: none;
  position: relative;
  overflow: hidden;
  width: var(--size-sidebar);
  /* 세로 경계선은 맨 위 줄(신호등·머리 높이 44 + 아래 선 1) 아래부터 — 축소판(52)은 신호등 묶음(약 12~68)보다 좁아
     선이 가운데 단추를 가르던 것(루오님 10-24 "공사 중 같다", interaction-rules 17). 맨 위 줄은 창 전체 폭 한 줄. */
  border-inline-end: 0;
  display: flex;
  flex-direction: column;
  min-height: 0;
}
/* 맥 신호등 버튼 자리(titleBarStyle Overlay, tauri.conf trafficLightPosition). 창 드래그 영역이다 —
   위 44px 줄(이 줄과 각 화면의 .app-header)에 data-tauri-drag-region="deep": 안의 버튼은 Tauri 가 알아서 뺀다. */
/* 머리 줄 높이 하나(신호등 줄·본문 머리·패널 머리) — 글래스 안쪽 칸 위 가장자리·끌기 띠 시작도 이 값(§43.2). 작업 칸 화면 면은
   xterm 테마도 읽는 --term-bg(떼어진 창 bg-card, 메인 창 글래스는 칸 bg — 아래 글래스 블록). */
:host {
  --app-head-h: 44px;
  --term-bg: var(--color-bg-card);
}
.app-titlebar {
  height: var(--app-head-h);
  flex: none;
}
/* 사이드바 쪽 맨 위 줄도 본문 머리(.app-header 44 + 아래 선)와 같은 높이에 아래 선 — 펼침·축소판 모두 한 가로줄로 이어진다. */
.app-sidebar > .app-titlebar {
  border-bottom: 1px solid var(--color-line);
}
.app-sidebar::after {
  content: "";
  position: absolute;
  top: 45px;
  bottom: 0;
  inset-inline-end: 0;
  width: 1px;
  background: var(--color-line);
  pointer-events: none;
}
/* 여닫기 버튼(interaction-rules 17): 신호등(x 14, 오른쪽 끝 약 73, 세로 가운데 약 20) 바로 오른쪽·같은 높이에 창 기준으로 고정.
   펼침·축소판·겹쳐 펼친 사이드바 어디서나 같은 자리 — 겹친 사이드바(31) 위. */
.app-fold {
  position: absolute;
  top: calc(20px - var(--size-badge) / 2);
  left: 80px;
  z-index: 40;
  display: flex;
}
/* 사이드바를 접어 레일(64)만일 때 메인 머리 줄 제목은 여닫기 버튼 오른쪽에서 시작한다(B1 — 신호등·버튼을 덮지 않게, 묶음 39 §41.1).
   80 + 버튼 + space-5 - 64(레일 폭). 버튼과 글자 사이는 펼침 머리 줄 왼쪽 여백(space-5)과 같게(디자이너 10-24 — space-3 은 붙어 보임).
   겹쳐 펼친 사이드바는 메인 위에 덮이므로 상관없다. 버튼 옆에 닿는 맨 왼쪽 머리만 — 나란히 보기 오른쪽 칸 머리는 아니다(39 관문 ❌ —
   오른쪽 칸까지 56 을 비워 버튼이 밀려 넘쳤다). */
.app-main-rail .app-header:not(.app-split-right .app-header) {
  padding-inline-start: calc(80px + var(--size-badge) + var(--space-5) - 64px);
}
/* 메인 맨 위 안내(꺼진 에이전트 기다림·업데이트 등 .app-notes)도 같은 시작선 — 신호등 옆 여닫기 버튼에 글이 겹치지 않게(39 관문 ❌). */
.app-main-rail > .app-notes {
  padding-inline-start: calc(80px + var(--size-badge) + var(--space-5) - 64px);
}
/* 기기 되찾기 안내(#577)도 축소판이면 신호등·여닫기 버튼 자리를 비운다(관문 🟡-5) — 머리 줄과 같은 시작선. */
.app-main-rail > .app-recovery-top {
  padding-inline-start: calc(80px + var(--size-badge) + var(--space-5) - 64px - var(--space-5));
}
.app-recovery-top:empty {
  display: none;
}
.app-search {
  /* 한 줄 행(상자 아님). */
  margin-bottom: var(--space-2);
}
.app-eyebrow-group {
  /* 묶음 사이는 선이 아니라 여백(focus.md §4). */
  padding-top: calc(var(--space-3) * 2);
}
.app-list {
  padding: 0 var(--size-gap-tight);
}
.app-sidebar-foot {
  padding: var(--space-1) var(--size-gap-tight) var(--space-2);
}
.app-spacer {
  flex: 1;
}

.app-main {
  /* 알림(ld-toasts)의 자리. */
  position: relative;
  flex: 1;
  min-width: 0;
  display: flex;
  flex-direction: column;
  min-height: 0;
}
.app-header {
  height: var(--app-head-h);
  flex: none;
  display: flex;
  align-items: center;
  padding: 0 var(--space-5);
  gap: var(--size-gap-inner);
  border-bottom: 1px solid var(--color-line);
}
.app-thread {
  flex: 1;
  /* 창이 낮으면 줄어드는 것은 대화 칸만(규칙 35) — 머리 줄·Note 띠·입력칸·상태 막대는 flex: none. */
  min-height: 0;
  /* 세로 막대 칸은 늘(37-11) — WebKit 은 scrollbar-gutter: stable 을 따르지 않아 넘침이 없으면 칸이 사라져 끝선이 8 밀렸다(실측
     1168). 막대 바탕은 투명(.ld-scroll-bar)이라 칸만 잡힌다. */
  overflow-x: hidden;
  overflow-y: scroll;
  /* 맨 아래 여백 12 — 마지막 footer 가 입력칸·띠에 붙어 가려 보이지 않게(9869d43f). 끝선(37-11): 스크롤 막대 칸을 늘 잡고 그 칸을
     conv-x 여백 안에 둬 내용 끝 = 영역 끝 − conv-x = 입력칸 끝(막대가 생겨도 안 움직임). */
  padding: var(--space-4) calc(var(--size-conv-x) - var(--size-scrollbar)) var(--space-3) var(--size-conv-x);
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
  /* 대화는 영역 전체 폭(루오님 10-24, DS v38) — 줄 길이는 메시지 쪽(680px·말풍선 70%)이 잡는다. 좁은 영역은 @container. */
  container-type: inline-size;
  box-sizing: border-box;
  width: 100%;
}
.app-panel {
  flex: 1;
  overflow: auto;
  /* 위·아래 여백은 섹션 간격 하나(interaction-rules 20) — 띠가 있든 없든 첫 블록 윗변이 같은 y, 런처 스크롤 끝 마지막 선 ↔ 바닥 줄 선도 24(화면확인 4차). */
  padding: calc(var(--space-3) * 2) var(--space-5);
  /* 세션 정보 본문은 560 열, 넓으면 가운데(#341 디자이너 — 루오님 폭 지적). 머리 줄은 모든 화면 전체 폭(#361 결함 3). */
  max-width: calc(560px + var(--space-5) * 2);
  margin-inline: auto;
  width: 100%;
  box-sizing: border-box;
  display: flex;
  flex-direction: column;
}
.app-notes {
  padding: 0 var(--space-5);
}
/* 머리 바로 아래 Note(꺼진 세션·개발 채널 등)는 윗선을 빼고 머리 아래 선 하나만(디자이너 — 두 줄로 보임). */
header + .app-notes > .ld-note:first-child {
  border-top: 0;
}

.app-msg-text {
  white-space: pre-wrap;
  /* 공백 없는 긴 URL·경로·해시가 말풍선을 밀지 않게(#446 '긴 한 줄'). */
  overflow-wrap: anywhere;
}
/* 긴 글 접기(#446, ui/Fold): 접힌 본문은 끝 24px 를 흐리고(글자가 이어진다는 표시), 아래 왼쪽 글자 버튼. 애니메이션 없음. */
.app-longtext-closed {
  overflow: hidden;
  -webkit-mask-image: linear-gradient(to bottom, #000 calc(100% - 24px), transparent);
  mask-image: linear-gradient(to bottom, #000 calc(100% - 24px), transparent);
}
.app-text-btn.app-longtext-btn {
  display: block;
  margin-top: var(--space-1);
  padding: 0;
  height: auto;
  font-size: 12px;
  color: var(--color-ink-secondary);
}
.app-text-btn.app-longtext-btn:hover {
  color: var(--color-ink);
}
/* 대화 안 첨부(묶음 15 §23.2, ui/Attachments): 첨부마다 한 행(격자 없음). 파일 행 높이 40·bg-card, 이미지는 축소본 그대로. */
.app-attach-list {
  display: flex;
  flex-direction: column;
  gap: var(--space-1);
  margin-top: var(--space-2);
}
.app-attach-row {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  height: 40px;
  min-width: 0;
  padding: 0 var(--space-1) 0 var(--space-3);
  border-radius: var(--radius-radius);
  background: var(--color-bg-card);
  color: var(--color-ink);
}
.app-attach-row > .ld-icon {
  flex: none;
  color: var(--color-ink-secondary);
}
.app-attach-name {
  display: flex;
  min-width: 0;
  flex: 0 1 auto;
}
.app-attach-fit {
  display: grid;
  min-width: 0;
}
.app-attach-fit > * {
  grid-area: 1 / 1;
}
/* 캔버스로 잰 폭과 그려진 폭의 반올림 차로 다 들어가는 이름이 잘리지 않게 4px 여유. */
.app-attach-sizer {
  visibility: hidden;
  height: 0;
  overflow: hidden;
  white-space: nowrap;
  padding-right: 4px;
}
.app-attach-fit .app-path-mid {
  text-align: start;
}
.app-attach-meta {
  flex: none;
  font-size: 12px;
  color: var(--color-ink-tertiary);
  white-space: nowrap;
}
.app-attach-actions {
  display: flex;
  align-items: center;
  gap: var(--space-1);
  margin-left: auto;
  flex: none;
}
.app-composer-note {
  margin-bottom: var(--space-2);
}
/* 손상(F9) 글자는 다른 행 Finder 아이콘과 같은 오른쪽 안쪽 여백(아이콘 버튼 안 여백 = (버튼 - 16) / 2). */
.app-attach-broken {
  padding-right: calc((var(--size-badge) - 16px) / 2);
}
.app-attach-image {
  position: relative;
  display: block;
  align-self: flex-start;
  flex: none;
  box-sizing: border-box;
  padding: 0;
  border: 1px solid var(--color-line);
  border-radius: 8px;
  background: none;
  overflow: hidden;
  cursor: default;
}
.app-attach-image img {
  display: block;
  max-width: 320px;
  max-height: 240px;
  width: auto;
  height: auto;
}
/* 묶음 37 #612 — 보낸 쪽 올리는 중: 축소본 흐리게 + 오른쪽 아래 state-working(동그란 어두운 바탕 22). */
.app-attach-image[data-up] img {
  opacity: 0.55;
}
.app-attach-up-at {
  position: absolute;
  right: 6px;
  bottom: 6px;
  display: flex;
}
.app-attach-up {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 22px;
  height: 22px;
  border-radius: 11px;
  background: rgba(0, 0, 0, 0.55);
  color: #fff;
}
/* 받는 중·실패 상자 — 받으면 같은 자리에 그림(규칙 33). */
.app-attach-box {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 4px;
  background: var(--color-bg-card);
  color: var(--color-ink-secondary);
  font-size: 12px;
}
.app-attach-broken-ic {
  display: inline-flex;
  color: var(--color-danger-text);
}
/* 여러 장(§23.2): 2열 격자 — 칸 156(줄기 카드 116), 간격 4, 모서리 6, 1024 축소본을 가운데 기준으로 채워 자름. */
.app-attach-grid {
  display: grid;
  grid-template-columns: repeat(2, max-content);
  gap: 4px;
  align-self: flex-start;
}
.app-attach-grid > .app-attach-image,
.app-attach-grid > .ld-tip > .app-attach-image {
  border-radius: 6px;
}
.app-attach-image[data-cell] img {
  width: 100%;
  height: 100%;
  max-width: none;
  max-height: none;
  object-fit: cover;
  object-position: center;
}
.app-attach-more {
  position: absolute;
  inset: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  background: rgba(0, 0, 0, 0.5);
  color: #fff;
  font-size: 20px;
  font-weight: 600;
}
.app-attach-one {
  display: flex;
  align-self: flex-start;
}
/* 보낸 쪽은 오른쪽 정렬(말풍선 아래). */
.ld-msg-mine .app-attach-list {
  align-items: flex-end;
}
.ld-msg-mine .app-attach-grid,
.ld-msg-mine .app-attach-one {
  align-self: flex-end;
}
/* 크게 보기(§23.2a) — 창 안 덮개, 애니메이션 없음. */
.app-viewer {
  position: fixed;
  inset: 0;
  z-index: 60;
  background: rgba(0, 0, 0, 0.82);
  color: #fff;
}
/* 위 줄은 신호등 줄(44)과 같은 높이, 이름은 신호등 뒤에서 — 떼어진 창 머리 줄과 같은 시작선(§23.2a, 37 관문 🟡②). */
.app-viewer-bar {
  position: absolute;
  inset: 0 0 auto;
  height: 44px;
  display: flex;
  align-items: center;
  gap: var(--space-2);
  padding: 0 12px 0 calc(74px + var(--space-3));
  font-size: 13px;
  --color-ink: #fff;
  --color-ink-secondary: rgba(255, 255, 255, 0.8);
}
.app-viewer-name {
  font-weight: 600;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.app-viewer-count {
  flex: none;
  color: rgba(255, 255, 255, 0.65);
  font-variant-numeric: tabular-nums;
}
.app-viewer-pic {
  position: absolute;
  inset: 44px 80px 0;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 24px 0;
}
.app-viewer-pic img {
  display: block;
  max-width: 100%;
  max-height: 100%;
  border-radius: 4px;
}
.app-viewer-nav-at {
  position: absolute;
  top: 50%;
  margin-top: -20px;
  display: flex;
}
.app-viewer-nav-at[data-side="prev"] {
  left: 24px;
}
.app-viewer-nav-at[data-side="next"] {
  right: 24px;
}
.app-viewer-nav {
  width: 40px;
  height: 40px;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 0;
  border: none;
  border-radius: 20px;
  background: rgba(255, 255, 255, 0.12);
  color: #fff;
}
.app-viewer-nav:disabled {
  opacity: 0.3;
}
.app-viewer-nav:focus-visible {
  outline: 2px solid var(--color-accent);
  outline-offset: 2px;
}
/* 줄기 카드 안(§23.2b) — 한 단계 작게(240×180). */
.app-attach-list[data-size="card"] .app-attach-one .app-attach-image img {
  max-width: 240px;
  max-height: 180px;
}
/* 답 쪽(오른쪽 줄)은 그림도 오른쪽 정렬(§23.2b — 그 글과 같은 쪽). */
.app-stem-side[data-side="right"] .app-attach-grid,
.app-stem-side[data-side="right"] .app-attach-one {
  align-self: flex-end;
}
/* 검토 카드 긴 글·보낼 파일(묶음 15 §23.4). 원문 그대로 — 렌더링하지 않는다. */
.app-review-full {
  max-height: 480px;
  overflow: auto;
}
.app-review-files {
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
  padding-top: var(--space-2);
}
.app-review-files-hd {
  font-size: 12px;
  color: var(--color-ink-secondary);
}
.app-review-file {
  display: flex;
  flex-direction: column;
  gap: var(--space-1);
  min-width: 0;
}
.app-review-file-l1 {
  display: flex;
  align-items: baseline;
  gap: var(--space-2);
  min-width: 0;
}
.app-review-file-name {
  flex: none;
  max-width: 60%;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.app-review-file-path {
  flex: 1 1 auto;
  min-width: 0;
  font-family: var(--font-family-mono);
  font-size: 12px;
  color: var(--color-ink-tertiary);
}
.app-review-file-path .app-path-mid {
  text-align: start;
}
.app-review-file-hash {
  font-family: var(--font-family-mono);
  font-size: 12px;
  color: var(--color-ink-tertiary);
}
.app-review-file-img {
  display: block;
  max-width: 240px;
  max-height: 240px;
  border: 1px solid var(--color-line);
  border-radius: var(--radius-radius);
}
.app-review-file-text {
  max-height: 320px;
  overflow: auto;
  font-size: 12px;
}
.app-review-file-more {
  color: var(--color-ink-tertiary);
}
/* 1 MiB 뒤 민감 발췌(#631 §41.14 끝) — 줄 번호는 pre 밖 위(앱 글), 발췌 pre 는 높이 120 뒤 안쪽 스크롤. */
.app-review-excerpt-at {
  margin-top: var(--space-1);
  font: var(--text-body);
  font-size: 12px;
  color: var(--color-ink-tertiary);
}
.app-review-excerpt-text {
  max-height: 120px;
  overflow: auto;
  font-size: 12px;
}
.app-review-file-below {
  margin-top: var(--space-1);
  font: var(--text-body);
  font-size: 12px;
  color: var(--color-ink-tertiary);
}
.app-review-file-below-why {
  color: var(--color-ink-secondary);
}
/* 그 줄 끝 `Finder 에서 보기` — {이유} · {할 일} 꼴의 할 일, ink-secondary 글자 버튼(호버 밑줄). */
.app-review-file-below .app-text-btn {
  height: auto;
  line-height: inherit;
  padding: 0;
  border: 0;
}
@media (hover: hover) {
  .app-review-file-below .app-text-btn:hover:enabled {
    text-decoration: underline;
  }
}
/* 입력칸 첨부(묶음 15 §23.1, ui/AttachChips): 칩 줄은 입력칸 위 — 가로로 넘치면 줄바꿈, 3줄 뒤 안쪽 스크롤. */
.app-attach-chips {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-1);
  margin: 0;
  padding: var(--space-2) var(--space-3) 0;
  list-style: none;
  max-height: calc(3 * 32px + 2 * var(--space-1) + var(--space-2));
  overflow-y: auto;
}
/* 줄바꿈 칩 줄 — ScrollArea 페이드(규칙 32)가 제 줄을 갖게(공간 0). */
.app-attach-chips > .ld-scroll-f {
  width: 100%;
}
.app-attach-chip {
  display: flex;
  align-items: center;
  gap: var(--space-1);
  height: 32px;
  max-width: 100%;
  padding: 0 0 0 var(--space-2);
  border-radius: var(--radius-radius);
  background: var(--color-bg-card);
  font-size: 12px;
}
.app-attach-chip > .ld-icon {
  flex: none;
  color: var(--color-ink-secondary);
}
.app-attach-chip-thumb {
  flex: none;
  width: 24px;
  height: 24px;
  object-fit: cover;
  border-radius: var(--radius-sm);
}
.app-attach-chip .app-attach-fit {
  max-width: 200px;
}
.app-attach-chip-size {
  flex: none;
  color: var(--color-ink-tertiary);
}
/* 긴 글 알림(§23.3) — #445 줄 자리, 막힘이 아니라 흐린 글자. */
.app-composer-long {
  margin-block-start: calc(6px - var(--size-gap-inner));
  padding: 0 var(--space-3);
  font-size: 12px;
  color: var(--color-ink-tertiary);
}
/* 끌어놓기 면(§23.1): 대화 영역 전체 bg-hover + 가운데 흐린 한 줄. 애니메이션 없음, 포인터는 받지 않는다. */
.app-drop {
  position: fixed;
  z-index: 50;
  display: flex;
  align-items: center;
  justify-content: center;
  /* 대화가 비쳐 화면이 바뀐 것처럼 보이지 않게 0.85(디자이너 a2348f11). */
  background: color-mix(in srgb, var(--color-bg-hover) 85%, transparent);
  color: var(--color-ink-tertiary);
  pointer-events: none;
}
.app-injection {
  /* 카드 본문 패딩을 덮어 전문 블록이 카드 폭을 채운다. */
  margin: calc(-1 * var(--size-gap-inner)) calc(-1 * var(--space-3));
}
.app-injection-eyebrow {
  font: var(--text-meta);
  color: var(--color-ink-secondary);
  padding: var(--space-1) var(--space-3);
}
.app-text-btn {
  font: inherit;
  height: 22px;
  padding: 0 var(--space-2);
  border: 1px solid transparent;
  border-radius: var(--radius-sm);
  background: transparent;
  color: var(--color-ink-secondary);
  cursor: pointer;
}
@media (hover: hover) {
  .app-text-btn:hover:enabled {
    color: var(--color-ink);
  }
}
/* 고른 상태(질문/작업 요청 같은 묶음 안의 하나). */
.app-text-btn[aria-pressed="true"] {
  border-color: var(--color-line-strong);
  color: var(--color-ink);
}
.app-text-btn:disabled {
  color: var(--color-ink-tertiary);
  cursor: default;
}
.app-text-btn:focus-visible {
  outline: 2px solid var(--color-accent);
  outline-offset: 2px;
}
/* footer `{이유} · {할 일}` 의 글자 버튼: 패딩 0 이라 `·` 양쪽 간격이 같다. 누르는 면은 ::before 로 바깥에. */
.app-text-btn.app-footer-btn {
  position: relative;
  height: auto;
  padding: 0;
}
.app-text-btn.app-footer-btn::before {
  content: "";
  position: absolute;
  inset: -3px calc(-1 * var(--space-1));
}

.app-composer {
  flex: none;
  /* 아래 20(규칙 35, 동료 실사용 — 받는 쪽 줄이 창 끝에 반쯤 잘림). 상태 막대가 있든 없든 같다. 좌우 = 대화 칸 끝선(37-11). */
  padding: var(--space-2) var(--size-conv-x) var(--space-5);
  box-sizing: border-box;
  width: 100%;
}
.app-composer-box {
  border: 1px solid var(--color-line-strong);
  border-radius: var(--radius-radius);
  overflow: hidden;
  /* 묶음 39 §41.5: 안쪽 면 한 단계 올림. */
  background: var(--color-bg-card);
}
/* 에이전트에게(§48.5): 쉴 때 테두리 1 · 프로바이더 색 60% + line-strong(두 테마 같은 식 — 늘 가장 센 색이라 경고처럼 읽혔다),
   포커스 = 2 · 프로바이더 색 100% — 바깥 여백 −1 로 글 자리 그대로(이중 링·바깥 빛·면 칠 없음). */
.app-composer-box[data-agent="claude"] {
  border: 1px solid color-mix(in srgb, var(--color-agent-claude) 60%, var(--color-line-strong));
}
.app-composer-box[data-agent="claude"]:focus-within {
  border: 2px solid var(--color-agent-claude);
  margin: -1px;
}
/* 사람에게: 포커스 링은 글 칸이 아니라 상자 전체(아래 줄·/ 칩까지 — 39 관문 🟡⑤ 위 절반만 두르던 것). 테두리 1 → 2 accent, 안쪽 여백을
   1 줄여 글 자리 그대로. */
.app-composer-box:not([data-agent]):has(.ld-ta:focus-visible) {
  border: 2px solid var(--color-accent);
  margin: -1px;
}
.app-composer-box .ld-ta:focus-visible {
  outline: none;
}
.app-composer-in {
  display: flex;
  align-items: flex-start;
}
.app-composer-in .app-md > textarea {
  flex: 1;
  min-width: 0;
}
.app-composer-mark {
  display: inline-flex;
  flex: none;
  padding: calc(var(--size-gap-inner) + 2px) 0 0 var(--space-3);
  color: var(--color-agent-claude);
}
.app-composer-mark + .app-md > textarea {
  padding-left: var(--space-2);
}
/* 보내기 = 채운 네모 28 — 보낼 것이 없으면 흐린 꼴(bg-hover · ink-tertiary), 자리 그대로. */
.app-send {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  flex: none;
  width: 28px;
  height: 28px;
  padding: 0;
  border: 0;
  border-radius: 8px;
  background: var(--color-ink);
  color: var(--color-bg);
}
.app-send[data-agent="claude"] {
  background: var(--color-agent-claude);
  color: #fff;
}
.app-send[data-off] {
  background: var(--color-bg-hover);
  color: var(--color-ink-tertiary);
}
.app-send:focus-visible {
  outline: 2px solid var(--color-accent);
  outline-offset: 2px;
}
/* 입력칸 아래 안쪽 여백은 스크롤 영역이라 셋째 줄이 반쯤 비쳐 보인다 — 같은 높이를 바깥 여백으로 둬 글이 줄 단위로 끊기게(#445 디자이너). */
.app-composer-in .app-md > textarea {
  padding-block-end: 0;
  margin-block-end: var(--size-gap-inner);
}
.app-composer-bar {
  display: flex;
  align-items: center;
  gap: var(--size-gap-inner);
  height: var(--size-row);
  padding-block: 0;
  padding-inline: var(--space-3) var(--space-2);
  border-top: 1px solid var(--color-line);
  font-size: var(--font-size-small);
  color: var(--color-ink-secondary);
}
/* 카드 이름 줄의 세션 라벨 꼴 `{제목} · {폴더}`(디자이너 10-24): 제목만 말줄임, 폴더는 흐린 meta 로 남는다. */
.app-session-label {
  display: inline-flex;
  max-width: 100%;
  min-width: 0;
  vertical-align: bottom;
  white-space: nowrap;
}
.app-session-label-t {
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
}
.app-session-label-f {
  flex: none;
  font-weight: 400;
  color: var(--color-ink-secondary);
}
/* 받는 쪽 이름(세션 라벨 꼴 `{제목} · {폴더}`): 바는 한 줄 — 넘치면 제목만 줄이고 폴더는 남긴다. */
.app-composer-bar > * {
  flex-shrink: 0;
  white-space: nowrap;
}
/* 본문 상한을 넘은 동안 입력칸 아래 한 줄(#445): danger-text 12, 아이콘·애니메이션 없음. */
.app-composer-over {
  /* 보드 Main L1: 6 12 0 — 입력칸 글 끝에서 6. 입력칸 바깥 아래 여백(size-gap-inner)을 겹쳐 뺀다. */
  margin-block-start: calc(6px - var(--size-gap-inner));
  padding: 0 var(--space-3);
  font-size: 12px;
  color: var(--color-ink-secondary);
}
/* 받는 쪽 버튼(묶음 27 §2 A 안): 맥 팝업 버튼 꼴 — 테두리 없음, 호버 bg-hover. 아이콘·chevron 자리는 고정, 이름(세션 제목)만 줄인다.
   툴팁 감싸개(.ld-tip)째 줄어야 한다. */
.app-composer-bar > .ld-tip:has(> .app-to-btn),
.app-composer-bar > .app-to-btn {
  flex-shrink: 1;
  min-width: 0;
  /* 호버 면 안쪽 여백만큼 왼쪽으로 — 아이콘이 입력칸 글 시작과 맞게. 버튼 자신에 두면 감싸개가 그만큼 작게 재여 제목이 잘린다. */
  margin-inline-start: calc(var(--space-1) * -1);
}
.app-to-btn {
  display: inline-flex;
  align-items: center;
  gap: var(--space-1);
  max-width: 100%;
  min-width: 0;
  height: 22px;
  padding: 0 var(--space-1);
  border: 0;
  border-radius: var(--radius-sm);
  background: transparent;
  font: inherit;
  color: inherit;
  cursor: pointer;
}
@media (hover: hover) {
  .app-to-btn:not([data-none]):hover {
    background: var(--color-bg-hover);
  }
}
.app-to-btn[data-none] {
  cursor: default;
}
.app-to-btn > .app-composer-to {
  /* 한 줄(시안 A5, 27 g3 🟡①): 제목만 말줄임, 프로젝트·#n·chevron 은 남는다 — 안의 flex 조각이 줄을 꺾지 않게 이 자리도 flex. */
  display: flex;
  align-items: baseline;
  min-width: 0;
  overflow: hidden;
  white-space: nowrap;
}
.app-to-btn > .app-composer-to > * {
  flex: none;
}
.app-to-btn > .app-composer-to > .app-composer-split {
  flex: 0 1 auto;
}
.app-to-ic,
.app-to-chev {
  display: inline-flex;
  flex: none;
  color: var(--color-ink-secondary);
}
.app-to-chev {
  color: var(--color-ink-tertiary);
}
/* 고를 것이 하나(세션 0개): chevron 만 더 흐리게 — 자리·꼴은 그대로(규칙 17). */
.app-to-btn[data-none] > .app-to-chev {
  opacity: 0.4;
}
/* 받는 쪽 목록: 버튼 바로 위(폭 300, 애니메이션 없음). 8줄 높이 뒤 스크롤. */
.app-to-list {
  width: 300px;
  box-sizing: border-box;
  padding: var(--space-1);
  background: var(--color-bg);
  border: 1px solid var(--color-line-strong);
  border-radius: var(--radius-radius);
  z-index: 30;
}
.app-to-find {
  display: flex;
  align-items: center;
  gap: var(--size-gap-inner);
  height: var(--size-control);
  margin-block-end: var(--space-1);
  box-shadow: inset 0 -1px 0 var(--color-line);
}
.app-to-find:focus-within {
  box-shadow: inset 0 -1px 0 var(--color-line-strong);
}
.app-to-scroll {
  max-height: calc(var(--size-control) * 8);
  overflow: auto;
}
.app-to-scroll > [role="listbox"]:focus {
  outline: none;
}
.app-to-row > .app-to-name {
  flex: 1;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
}
.app-to-head {
  padding-inline-start: var(--space-2);
}
.app-composer-split {
  display: flex;
  min-width: 0;
}
.app-composer-title {
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
}
.app-composer-split > .app-name-no-n {
  flex: none;
}
.app-kind {
  display: inline-flex;
  gap: var(--space-1);
}

.app-ui {
  font: var(--text-ui);
}
.app-mono {
  font-family: var(--font-family-mono);
  font-size: var(--font-size-meta);
}
.app-ink {
  color: var(--color-ink);
}
.app-secondary {
  color: var(--color-ink-secondary);
}
.app-small {
  font-size: var(--font-size-small);
}
.app-note-gap {
  /* 섹션 사이(interaction-rules 20). */
  margin-top: calc(var(--space-3) * 2);
}
/* 세션 정보(옆 칸·떼어진 창 같음): 섹션 사이는 무엇이 위에 오든 24, 맨 위 띠 묶음 안은 8(interaction-rules 20).
   DS 의 그룹+그룹 24 는 gap 과 겹치니 여기서 0. 띠가 하나도 없으면 묶음이 gap 한 칸을 먹지 않게 숨긴다. */
.app-session-info {
  gap: calc(var(--space-3) * 2);
}
.app-session-info .app-note-gap {
  margin-top: 0;
}
/* 제목 있는 그룹 앞은 40(20a) — gap 24 에 16 을 더한다. 맨 위 첫 그룹·띠 다음은 24 그대로. */
.app-session-info > .ld-set-group + .ld-set-group {
  margin-top: calc(var(--space-5) * 2 - var(--space-3) * 2);
}
.app-note-stack {
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
}
.app-note-stack:empty {
  display: none;
}

/* 가입 ①b 스팸함 메타 한 줄(#586 D): mail-search 12 + ink-secondary 12, 누르는 동작 없음. */
.acc-spam {
  display: inline-flex;
  align-items: center;
  gap: var(--space-1);
  font-size: 12px;
  color: var(--color-ink-secondary);
}
.app-visually-hidden {
  position: absolute;
  left: -9999px;
}

/* 한국어는 어절 단위 줄바꿈, 다른 언어는 기본(<html lang> 은 LocaleProvider 가 맞춘다). */
:lang(ko) {
  word-break: keep-all;
}

/* 앱 안 터미널(#62). 화면 + 첫 실행 안내(오른쪽에 붙음, flows §9). 좁으면 안내가 아래로 꺾인다. */
.app-term {
  flex: 1;
  min-height: 0;
  display: flex;
  flex-wrap: wrap;
  overflow: hidden;
}
/* 셸 칸을 보는 동안 에이전트 터미널은 숨겨 둔다(xterm 은 살아 있음 — 돌아오면 그대로, 묶음 6 §4b). */
.app-term[hidden] {
  display: none;
}
/* 셸 칸(보드 ShellTab): 맨 위 흐린 한 줄 `{폴더} · {셸 이름}` + 오른쪽 ghost `셸 닫기`, 끝나면 아래 흐린 한 줄 + `새 셸`. */
.app-shell-where {
  flex: none;
  display: flex;
  align-items: center;
  gap: 4px;
  min-height: 30px;
  padding: 4px 8px 0 16px;
  font-size: 12px;
  color: var(--color-ink-tertiary);
}
.app-shell-path {
  font-family: var(--font-family-mono);
  color: var(--color-ink-secondary);
}
.app-shell-ended {
  flex: none;
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 6px 16px 12px;
  font-size: 12px;
  color: var(--color-ink-tertiary);
}
.app-term-screen {
  /* #590: 승인 카드 겹침(.app-approvals-over)의 기준. */
  position: relative;
  flex: 999 1 400px;
  min-width: 0;
  min-height: 0;
  display: flex;
  /* 칸이 줄어드는 프레임(셸 끝남 줄이 붙을 때)에 xterm 화면이 다음 fit 전까지 밖으로 넘쳐 아래 줄을 덮지 않게. */
  overflow: hidden;
  padding: var(--space-3) var(--space-4);
  background: var(--term-bg);
  box-sizing: border-box;
}
/* #594 살려 둔 에이전트 칸: 지금 것만 제자리(감싸개는 상자를 만들지 않음 — #589 flex 크기 그대로), 나머지는 숨김. */
.app-term-keep {
  display: none;
}
.app-term-keep[data-active] {
  display: contents;
}
/* #590 승인 카드 겹침(보드 v308 S): 터미널·셸을 밀지 않는다 — 칸 오른쪽 위(위 8 · 오른쪽 12, 폭 380, 좁으면 칸 폭 − 24).
   덮는 것은 위쪽 지난 출력뿐: 높이 상한 = 칸의 절반, 넘으면 카드 안 스크롤(맨 아래 입력칸·수락창은 가리지 않음).
   DS floating Note 겉(bg + line-strong + radius), 그림자·전환 없음(고빈도). 찾기 막대가 열려 있으면 그 아래(T6). */
.app-approvals-over {
  position: absolute;
  top: var(--space-2);
  right: var(--space-3);
  z-index: 4;
  width: min(380px, calc(100% - 24px));
  max-height: 50%;
  box-sizing: border-box;
  overflow: auto;
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
  padding: var(--space-1) var(--space-3) var(--space-2);
  background: var(--color-bg);
  border: 1px solid var(--color-line-strong);
  border-radius: var(--radius-radius);
}
.app-approvals-over[data-below-find] {
  top: 54px;
}
/* 셸 칸 + 겹침 카드의 기준(셸 칸은 TerminalView 밖 부품이라 한 겹 감싼다). */
.app-term-area {
  position: relative;
  flex: 1;
  min-height: 0;
  display: flex;
  flex-direction: column;
}
.app-term-host {
  flex: 1;
  min-width: 0;
  min-height: 0;
  /* #589: .app-term 은 줄바꿈(wrap) flex 라 줄 높이가 내용으로 정해진다 — xterm 이 흐름 안에 있으면 창을 줄여도 화면이
     줄지 않고(ResizeObserver 도 안 불림) 입력칸이 창 밖으로 숨는다. xterm 을 흐름 밖에 두어 칸 크기는 바깥이 정하게. */
  position: relative;
}
.app-term-host > .xterm {
  position: absolute;
  inset: 0;
}
.app-term-guide {
  flex: 1 1 260px;
  max-width: 300px;
  border-inline-start: 1px solid var(--color-line);
  padding: var(--space-2) var(--size-gap-tight);
  display: flex;
  flex-direction: column;
}
.app-term-guide-note,
.app-term-guide-hint {
  padding: var(--size-gap-inner) var(--size-gap-inner) 0;
}
.app-term-guide-actions {
  display: flex;
  flex-wrap: wrap;
  justify-content: flex-end;
  gap: var(--space-2);
  padding: var(--size-gap-inner);
}

/* 세션 머리(규칙 19): 폭이 모자라면 이름은 지키고 캐시 → 상태 순으로 준다(줄어드는 몫 캐시 ≫ 상태 ≫ 이름). */
/* 좁은 창(떼어진 창 최소 480)에서도 오른쪽 Segment·아이콘·`세션 끄기` 는 줄지 않고 잘리지 않는다 — 줄어드는 것은 이름 하나(말줄임,
   화면확인 21 🟡). 캐시·상태 meta 는 그 앞에서 빠진다(§4). */
.app-header > :not(.app-head-name):not(.app-spacer) {
  flex-shrink: 0;
}
.app-head-name {
  flex: 0 1 auto;
  /* 이름 최소 96(#623 §39.4 ②) — 그보다 좁아지면 아이콘을 ⋯ 로 접는다(useHeadFold). */
  min-width: 96px;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.app-header > .app-head-name.app-mono {
  flex: 0 1 auto;
}
/* 이름 + 같은 이름 번호 #n(명세 43379189): 말줄임은 이름만, #n 은 제 폭으로 남는다(가르는 표시라 잘리면 뜻이 없다). */
.app-name-no {
  display: flex;
  min-width: 0;
  max-width: 100%;
}
.app-name-no-t {
  flex: 0 1 auto;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.app-name-no-n {
  flex: none;
  white-space: pre;
}
.app-head-state {
  min-width: 0;
  overflow: hidden;
  white-space: nowrap;
  text-overflow: ellipsis;
}
.app-head-state {
  flex: 0 100 auto;
}
/* 캐시는 아이콘 하나(규칙 21) — 줄지 않고 ink-tertiary. */
.app-head-cache {
  flex: none;
  display: inline-flex;
  align-items: center;
  color: var(--color-ink-tertiary);
}
/* 동료 요청도 오토로 처리(#383) — 상태 줄 맨 끝 zap, 상태 아이콘(규칙 21)이라 상자·호버 없음. */
.app-head-auto {
  flex: none;
  display: inline-flex;
  align-items: center;
  color: var(--color-ink-secondary);
}
/* 헤더는 44px 한 줄 — 이름·상태줄은 꺾지 않는다. */
.app-header > .app-mono,
.app-header > .ld-badge {
  flex: none;
  white-space: nowrap;
}

.app-header-meta {
  font-size: var(--font-size-small);
  color: var(--color-ink-tertiary);
  white-space: nowrap;
}
/* 이름 · 아이디 뒤에 이어지는 ` · 팀 · 이메일`(#355): 머리 줄 gap 을 빼 `·` 사이가 모두 같게(디자이너 10-25). */
.app-header-cont {
  margin-inline-start: calc(var(--size-gap-inner) * -1);
}

.app-tertiary {
  color: var(--color-ink-tertiary);
}
/* 헤더 이름은 13/500(focus.md §4 크기 3단계). */
.app-header .app-ui {
  font-size: var(--font-size-body);
  font-weight: 500;
}
.app-danger {
  color: var(--color-ink-secondary);
}
.app-waiting {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  flex-wrap: wrap;
}
/* 접힘 줄의 '폴더 밖'(#593 용어집): 안전 경고라 접혀도 늘 보임 — danger-text 600. */
.app-outside {
  color: var(--color-danger-text);
  font-weight: 600;
}
/* 붙잡은 카드가 판정 없이 걷힌 줄(#593): 아이콘 12 + 두 낱말(흐림), 줄 끝 × — 카드가 있던 자리. */
.app-hold-closed {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-2);
}
.app-hold-closed .app-tertiary {
  display: inline-flex;
  align-items: center;
  gap: var(--space-1);
}

/* 직접 답하기 맥락 줄(디자인 시스템 v29): 입력창 상자 안 위쪽, 36, 아래 헤어라인. */
.app-composer-ctx {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  height: var(--size-row);
  padding-inline: var(--space-3) var(--space-1);
  border-bottom: 1px solid var(--color-line);
  font-size: var(--font-size-small);
}
.app-composer-ctx-l {
  flex: none;
  color: var(--color-ink-secondary);
  white-space: nowrap;
}
.app-composer-ctx-q {
  flex: 1;
  min-width: 0;
  color: var(--color-ink-tertiary);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

/* lodelai MCP 등록 실패(#60): 명령은 말줄임 없이 한 줄 가로 스크롤(모노 12, 선택 가능). */
.app-mcp-cmd {
  display: flex;
  flex-direction: column;
  gap: var(--space-1);
  padding-top: var(--space-2);
}
.app-mcp-cmd > p {
  margin: 0;
}
/* 펼친 `자세히` 안 명령 한 줄 + 복사(용어집 584a67b5). */
.app-mcp-cmd-row {
  display: flex;
  align-items: center;
  gap: var(--space-2);
}
.app-mcp-code {
  flex: 1;
  min-width: 0;
  overflow-x: auto;
  white-space: pre;
  font-family: var(--font-family-mono);
  font-size: var(--font-size-small);
  user-select: text;
}
/* 런처(#340, 보드 "런처 — 새 세션" 왼쪽). */
/* 런처 칸 제목(`작업 폴더`·`이 폴더에서`): SettingGroup 제목과 같은 꼴(20a — 600 12 ink, 막대 2×12 는 왼쪽 여백, 제목→첫 행 8).
   DS 정본엔 없는 앱 쪽 클래스라 여기 둔다(디자이너 10-25). */
.app-sec-title {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  margin-inline-start: calc((2px + var(--space-2)) * -1);
  font: 600 12px / 1.4 var(--font-family-body);
  letter-spacing: 0;
  color: var(--color-ink);
  padding: 0 0 var(--space-2);
}
.app-sec-title::before {
  content: "";
  flex: none;
  width: 2px;
  height: 12px;
  background: currentColor;
}
/* 칸 제목이 있는 칸이 이어지면 앞은 40(20a) — gap 24 + 16, 앞 칸의 보이는 끝에서(439c930a). 선 없는 행으로 끝나는 칸은
   .app-row-end:last-child 가 행 안 여백을 이미 줄였고, 남는 글자 아래 2.25 만 더 당긴다(실측). */
.app-launcher-sec + .app-launcher-sec {
  margin-top: calc(var(--space-5) * 2 - var(--space-3) * 2);
}
.app-launcher-sec:has(> .app-row-end:last-child):has(+ .app-launcher-sec) {
  margin-bottom: -2.25px;
}
/* 섹션 사이 24(interaction-rules 20) — 띠·폴더·이 폴더에서·에이전트·동작. 섹션 안(목록 아래 상태 띠)은 8. */
.app-launcher {
  max-width: 460px;
  gap: calc(var(--space-3) * 2);
}
.app-launcher > .app-note-gap {
  margin-top: 0;
}
.app-launcher-sec .app-note-gap {
  margin-top: var(--space-2);
}
/* 선 없는 행으로 끝나는 섹션(interaction-rules 20 3c30fd7 — 간격은 보이는 끝에서 잰다): 행 상자 안 아래 여백((행 높이 − 글줄)/2)만큼
   다음 섹션 간격을 줄여 글자 끝 → 다음 눈썹·선이 다른 화면의 선 → 눈썹과 같게. 섹션의 마지막 자식일 때만(뒤에 띠가 오면 그대로). */
.app-row-end:last-child {
  font-size: var(--font-size-body);
  margin-bottom: calc((var(--size-row) - 1lh) / -2);
}
/* 런처 바닥 동작 줄(목록만 스크롤): 위에 선 하나, 글자 열은 본문(460)과 같은 폭·가운데. */
.app-launcher-foot {
  flex: none;
  border-top: 1px solid var(--color-line);
}
.app-launcher-actions {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  max-width: 460px;
  margin-inline: auto;
  padding: var(--space-3) var(--space-5);
  box-sizing: border-box;
}
/* 여는 중이 길 때(#566): 동작 줄 왼쪽 흐린 한 줄 + ghost — 취소·주버튼 자리는 그대로. 줄은 줄어들고 넘치면 두 줄까지. */
.app-launcher-slow {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  min-width: 0;
  flex: 1 1 auto;
  font: var(--text-small);
}
.app-launcher-slow > .app-tertiary {
  min-width: 0;
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
}
/* 바뀌는 글자 중 가장 긴 것의 폭(규칙 17): 같은 칸에 겹친 보이지 않는 버튼들이 칸 폭을 잡고, 진짜 버튼은 칸을 채운다. */
.app-btn-sizer {
  display: inline-grid;
}
.app-btn-sizer > * {
  grid-area: 1 / 1;
  display: flex;
}
.app-btn-sizer .ld-btn {
  flex: 1;
  justify-content: center;
}
.app-btn-sizer-ghost {
  visibility: hidden;
}
/* 앱 크롬(사이드바·창 머리)의 글자는 드래그로 선택되지 않는다(#340) — 대화 본문·명령 등 내용은 그대로 선택된다. */
.app-sidebar,
.app-header {
  -webkit-user-select: none;
  user-select: none;
}
.app-me-name {
  font-weight: 500;
}
/* 첫 사용 빈 상태(#341): 대화 자리 위쪽 1/3 에 제목·본문·다음 행동 하나. */
/* 빈 메인 화면 안내: 가로는 가운데, 세로는 위에서 18vh(대화 첫 화면 .app-thread-first 와 같은 자리, #361 N13).
   .app-thread 가 세로 flex 라 justify 는 세로·align 은 가로다. */
.app-first {
  display: flex;
  justify-content: flex-start;
  align-items: center;
  padding-top: 18vh;
}
.app-first-box {
  max-width: 360px;
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: var(--space-2);
}
.app-first-body {
  margin: 0;
}
/* 글 묶음(제목·본문 8) ↔ 동작은 섹션 사이 24(interaction-rules 20). */
.app-first-box > .ld-btn {
  margin-top: calc(var(--space-3) * 2 - var(--space-2));
}
.app-thread-first {
  margin: 18vh auto 0;
}
.app-device-body {
  margin: 0 0 var(--space-2);
}
/* 처음 대화라 모두 신뢰한 기기(#313 디자이너 ②): 상자 없이 흐린 기록 줄 + 지문 한 줄씩. */
.app-first-contact {
  display: flex;
  flex-direction: column;
  gap: var(--space-1);
}
/* 사이드바 목록 칸: 신호등 줄·'나' 행은 고정, 그 아래만 스크롤. 안쪽 칸은 끝에서 바깥으로 튕김을 넘기지 않는다. */
/* 동료 칸 · 내 세션 칸(m1-spec §2, 루오님 10-24): '나' 행 아래 두 칸이 각자 스크롤. 동료 칸 높이는 SidebarPanes 가 정한다. */
.app-side-panes {
  flex: 1;
  min-height: 0;
  display: flex;
  flex-direction: column;
}
.app-side-pane {
  flex: none;
  min-height: 0;
  overflow: hidden;
  display: flex;
  flex-direction: column;
}
.app-side-scroll {
  --ld-fade-bg: var(--color-bg-side-list);
  flex: 1;
  min-height: 0;
  overflow: auto;
  display: flex;
  flex-direction: column;
}
/* 동료 칸 눈썹 뒤 흐린 사람 수(규칙 32): 이름 바로 뒤, tabular. */
.app-eyebrow-n {
  flex: none;
  margin-inline-start: var(--space-1);
  color: var(--color-ink-tertiary);
  font-variant-numeric: tabular-nums;
}
.app-side-pane-grow {
  flex: 1;
}
/* 경계: 2px line(칸 사이, 10-25) + 위아래 3px 씩 잡는 자리, row-resize, 호버·끄는 중 line-strong.
   포커스는 DS 다른 포커스처럼 accent 링 2px — 잡는 자리 전체(8, 사이드바 폭)에 안쪽으로 그려 칸 overflow 에 안 잘린다(명세 6ffbff95). */

/* 가려진 쪽 띠(묶음 26 §2): 칸 끝에 붙는 띠 — bg-side, 가려진 쪽 경계에 1px line, 높이 28(행보다 낮게). 띠는 스크롤 칸 밖이라 뜨면 스크롤 영역이 띠 높이만큼 줄어 행을 덮지 않는다. */
.app-offscreen {
  flex: none;
  display: flex;
  align-items: center;
  gap: var(--space-2);
  width: 100%;
  height: 28px;
  padding: 0 calc(var(--size-gap-tight) + var(--size-gap-inner));
  border: 0;
  background: var(--color-bg-side);
  color: var(--color-accent-text);
  font: inherit;
  font-size: var(--font-size-small);
  text-align: start;
  cursor: default;
}
.app-offscreen-up {
  border-bottom: 1px solid var(--color-line);
}
.app-offscreen-down {
  border-top: 1px solid var(--color-line);
}
.app-offscreen-up .app-offscreen-ic {
  transform: rotate(180deg);
}
.app-offscreen-ic {
  display: inline-flex;
  width: var(--size-avatar);
  justify-content: center;
  /* 화살표는 방향만 — ink-secondary(묶음 26 §2). */
  color: var(--color-ink-secondary);
}
/* 내 세션 칸: 상태창 세션 요약(.app-statusbar-n)과 같은 꼴 — 아이콘 + 수, 상태색. */
.app-offscreen-n {
  display: inline-flex;
  align-items: center;
  gap: 2px;
  font-variant-numeric: tabular-nums;
}
.app-offscreen-n[data-kind="error"] {
  color: var(--color-danger-text);
}
.app-offscreen-n[data-kind="waiting"] {
  color: var(--color-accent);
}
.app-offscreen-n[data-kind="unseen"] {
  color: var(--color-success);
}
/* 동료 칸: `안 읽은 대화 {n}` — 사람 배지와 같은 '처리할 것' 색. */
.app-offscreen-peers {
  color: var(--color-accent-text);
}
.app-side-scroll,
.acc-screen,
.app-thread,
.app-panel {
  overscroll-behavior: contain;
}

/* 터미널 전용 글꼴(#361 결함 2 — 디자이너): D2Coding(NAVER, SIL OFL 1.1, 원본 그대로 — 예약 글꼴 이름이 있어 서브셋하지 않는다).
   라틴 0.5em·한글 1em 이 정확히 2:1 이라 한글이 두 칸에 꼭 맞는다. 이름은 깔려 있는 D2Coding 과 겹치지 않게 따로. */


/* 터미널 기호 폴백(#380 묶음 6 — 루오님 실사용: 셸 탭의 p10k·oh-my-zsh 프롬프트): Nerd Fonts v3.2.1 Symbols Nerd Font Mono
   (기호 전용, MIT — 글리프 출처별 라이선스는 fonts/NerdFontsSymbols-glyphs.txt). 누구나 설치 없이 Powerline·아이콘 글리프가
   보이게 앱에 넣는다(Ghostty·WezTerm 방식). 글자 글꼴이 아니라 TERM_FONT 목록 끝(generic 앞)의 폴백. 굵게도 같은 파일.
   xterm DOM 렌더러는 글리프를 칸에 맞춰 줄이지 않아 powerline 구분자만 칸(0.5em)에 늘여 맞춘 판(scripts/lodelai-symbols-font.py). */

/* 대화 스크롤(맥 앱 기본기 S1·S3): 첫 안 읽음 위 헤어라인 + 글, 위를 읽는 중 새 메시지 알약(입력창 위 가운데, 스크롤 영역 바닥에 붙음). */
.app-unread-line {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  /* 위 16 · 아래 12(§41.6 — 뒤 글에 속해 아래가 가깝다). 대화 칸 gap 12 위에 더한 값. */
  margin-top: calc(var(--space-4) - var(--space-3));
  font-size: var(--font-size-small);
  color: var(--color-ink-secondary);
}
.app-unread-line::after {
  content: "";
  flex: 1;
  height: 1px;
  background: var(--color-line);
}
/* `최신 메시지로`(규칙 32 D): 대화 칸 안 오른쪽, 입력칸 테두리 위 8px — 높이 0 sticky 줄에 아래로 붙여 공간을 먹지 않는다(gap 도
   되돌림). sticky 는 칸 padding 안쪽에 서므로 bottom 은 8 - padding-bottom. 페이드(z 2) 위. 면은 창 바탕 그대로(글 위에서 읽히게). */
.app-latest {
  position: sticky;
  bottom: calc(8px - var(--space-3));
  z-index: 3;
  flex: none;
  align-self: flex-end;
  display: flex;
  align-items: flex-end;
  height: 0;
  margin-top: calc(-1 * var(--space-3));
}
/* 묶음 39 §41.6: 안 읽음이 있으면 알약 — 무채(bg 면 · line-strong 테두리). */
.app-latest-pill {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  height: 28px;
  padding: 0 10px 0 8px;
  border: 1px solid var(--color-line-strong);
  border-radius: 14px;
  background: var(--color-bg);
  color: var(--color-ink);
  font-size: 12px;
  font-weight: 500;
  font-variant-numeric: tabular-nums;
}
.app-latest-pill:hover {
  background: var(--color-bg-hover);
}
.app-latest-pill:focus-visible {
  outline: 2px solid var(--color-accent);
  outline-offset: 2px;
}
/* 날짜 경계(§41.6) — 가운데 알약, 무채, 위에 붙지 않음. */
.app-day-line {
  display: flex;
  justify-content: center;
  /* 안 읽음 줄과 같은 여백(위 16 · 아래 12, §41.6) — 대화 칸 gap 12 위에 더한 값. */
  margin-top: calc(var(--space-4) - var(--space-3));
}
/* 날짜 알약 바로 뒤 안 읽음 줄은 그 사이만 8(16+12 가 쌓이지 않게). */
.app-day-line + .app-unread-line {
  margin-top: calc(var(--space-2) - var(--space-3));
}
.app-day-line > span {
  padding: 2px 10px;
  border: 1px solid var(--color-line-strong);
  border-radius: 10px;
  background: var(--color-bg);
  color: var(--color-ink-secondary);
  font-size: 12px;
  font-weight: 500;
}
.app-latest-box {
  display: inline-flex;
  align-items: center;
  border-radius: var(--radius-sm);
  background: var(--color-bg);
}
/* 사이드바 자리(mac-basics): 폭은 SidebarFrame 이 정한다(펼침 200~400 · 축소판 56). 경계 띠는 .app 안에서 절대 위치. */
.app {
  position: relative;
}
.app-side {
  flex: none;
  display: flex;
  min-height: 0;
}
.app-side > .app-sidebar {
  width: 100%;
}
/* 축소판 = 펼친 목록에서 글자만 뺀 것(명세 §2, 루오님 10-24): 행·눈썹·빈 줄 높이는 그대로, 글자 칸만 숨긴다.
   폭 52 = (목록 패딩 6 + 행 패딩 10 + 아바타 20/2) × 2 — 아이콘 열 가운데가 펼침과 같다. */

/* 칸 제목 띠: 펼침과 같은 높이 40·면, + 만 가운데(구분선 없음 — 면이 가른다, 10-25). */

/* 마크·아바타 위 점(안 읽음·처리할 것 accent, 일하는 중 흐린 점). */

/* 좁은 창에서 펼친 사이드바: 본문 위에 겹쳐 뜬다. 바깥(scrim)을 누르면 닫힘 — 색은 칠하지 않는다. */
.app-side-scrim {
  position: absolute;
  inset: 0;
  /* 레일은 덮지 않는다(묶음 39 §41.2 — 덮개는 레일 오른쪽에 열리고 레일 메뉴는 그대로 눌린다). */
  left: 64px;
  z-index: 30;
}
.app-side-over {
  position: absolute;
  top: 0;
  bottom: 0;
  left: 0;
  z-index: 31;
  display: flex;
  background: var(--color-bg);
}
.app-side-over > .app-sidebar {
  width: 100%;
}
/* 레일 서랍(§49, 루오님 11-01 기본안·(다)): 접힌 채 대메뉴 호버로 엿보는 사이드바. 레일 오른쪽 x 64 에 틈 0, 제목줄 44 아래부터 안쪽
   칸 아래 끝(상태창 24 + 칸 홈 8 위)까지, 폭은 사용자 사이드바 폭(style). 아래 칸 위에 겹친다 — 배치·스크롤·포커스 그대로.
   면은 펼친 사이드바의 불투명 판(bg-frame, 글래스 단에서도 — 뒤가 대화 글이라), 안쪽 사이드바의 틀 변수도 그 판으로. 오른쪽 두 모서리
   10, 선 테두리 없이 오른쪽 변·모서리에만 그림자(퍼짐 −8, 왼쪽·위·아래는 clip-path 로 자름), 다크만 오른쪽 변 1px 하이라인(라이트는 투명 토큰).
   가림막 없음 · 움직임 없음. */
.app-side-drawer {
  position: absolute;
  left: 64px;
  top: var(--app-head-h);
  bottom: calc(24px + var(--size-pane-gap));
  z-index: 31;
  display: flex;
  overflow: hidden;
  border-radius: 0 var(--radius-radius) var(--radius-radius) 0;
  --glass-bg: var(--color-bg-frame);
  --glass-side: var(--color-bg-frame);
  --glass-side-list: var(--color-bg-frame);
  background: var(--color-bg-frame);
  box-shadow:
    8px 0 20px -8px var(--color-shadow-drawer),
    inset -1px 0 0 var(--color-line-drawer-edge);
  /* 그림자는 오른쪽으로만 — 흐림 반경(10)이 왼쪽 레일 끝 4~5pt 를 1~2 어둡게 했다(49 서랍 관문 🟡). 왼쪽·위·아래는 서랍 변에서 자른다. */
  clip-path: inset(0 -32px 0 0);
}
.app-side-drawer > .app-sidebar {
  width: 100%;
}
/* 서랍은 제목줄 아래에서 시작 — 사이드바 맨 위 제목줄 띠(44)는 서랍에 없다. */
.app-side-drawer > .app-sidebar > .app-titlebar {
  display: none;
}
/* 서랍이 열린 동안 레일|목록 세로선 없음 — 레일과 서랍이 한 장(루오님 11-01). 펼친 사이드바 세로선(§44.10)은 그대로. */
.app-rail:has(+ .app-side-drawer)::after {
  content: none;
}
/* 글래스 창: 서랍은 제 면을 깔지 않고(사이드바와 같은 글래스 변수·투명) 그 자리의 안쪽 칸 열을 가려 레일과 같은 창 재질이 보이게
   한다(디자이너 49 판정, 루오님 '레일과 한 장'). CSS 흐림으로는 바탕화면 재질을 다시 만들 수 없어(뒤 대화 칸만 흐림) 색을 맞추면
   단·바탕화면마다 어긋난다. 칸 열(.app-main — 칸 면 ::before·대화·터미널 포함)에서 서랍 사각형(오른쪽 두 모서리 10)만큼 mask 로
   뺀다: 전체 − (몸통 ∪ 오른쪽 띠 ∪ 모서리 원 둘). 배치·크기 그대로(이동 0·xterm 크기 0), 닫히면 뗌. 폭은 SidebarFrame 이 .app-body 에
   --ld-drawer-w 로. 불투명 단·비활성·투명도 줄이기는 body 가 bg-frame 이라 저절로 같은 면. mask 를 못 쓰면 위 불투명 bg-frame 그대로. */
@supports (mask-composite: subtract) or (-webkit-mask-composite: source-out) {
  [data-glass] .app-side-drawer {
    --glass-bg: inherit;
    --glass-side: inherit;
    --glass-side-list: inherit;
    background: transparent;
  }
  [data-glass] .app-body:has(> .app-side-drawer) > .app-main {
    --r: var(--radius-radius);
    --w: var(--ld-drawer-w, 240px);
    --top: var(--app-head-h);
    --bot: var(--size-pane-gap);
    --cut: linear-gradient(#000 0 0);
    -webkit-mask-image:
      var(--cut), var(--cut), var(--cut),
      radial-gradient(circle at 0 100%, #000 calc(var(--r) - 0.5px), transparent var(--r)),
      radial-gradient(circle at 0 0, #000 calc(var(--r) - 0.5px), transparent var(--r));
    mask-image:
      var(--cut), var(--cut), var(--cut),
      radial-gradient(circle at 0 100%, #000 calc(var(--r) - 0.5px), transparent var(--r)),
      radial-gradient(circle at 0 0, #000 calc(var(--r) - 0.5px), transparent var(--r));
    -webkit-mask-size:
      100% 100%,
      calc(var(--w) - var(--r)) calc(100% - var(--top) - var(--bot)),
      var(--r) calc(100% - var(--top) - var(--bot) - 2 * var(--r)),
      var(--r) var(--r),
      var(--r) var(--r);
    mask-size:
      100% 100%,
      calc(var(--w) - var(--r)) calc(100% - var(--top) - var(--bot)),
      var(--r) calc(100% - var(--top) - var(--bot) - 2 * var(--r)),
      var(--r) var(--r),
      var(--r) var(--r);
    -webkit-mask-position:
      0 0,
      left 0 top var(--top),
      left calc(var(--w) - var(--r)) top calc(var(--top) + var(--r)),
      left calc(var(--w) - var(--r)) top var(--top),
      left calc(var(--w) - var(--r)) bottom var(--bot);
    mask-position:
      0 0,
      left 0 top var(--top),
      left calc(var(--w) - var(--r)) top calc(var(--top) + var(--r)),
      left calc(var(--w) - var(--r)) top var(--top),
      left calc(var(--w) - var(--r)) bottom var(--bot);
    -webkit-mask-repeat: no-repeat;
    mask-repeat: no-repeat;
    /* 맨 위 전체에서 아래 넷을 합친 것을 뺀다. */
    -webkit-mask-composite: source-out, source-over, source-over, source-over, source-over;
    mask-composite: subtract, add, add, add, add;
  }
  /* 사이드바 폭 띠(접힌 채 x 64 알약)는 서랍 밑으로 비친다 — 서랍이 열린 동안 숨김. */
  [data-glass] .app-body:has(> .app-side-drawer) > .ld-resize {
    visibility: hidden;
  }
}
/* 서랍을 연 아이콘엔 호버 면만(고른 메뉴 bg-selected 는 그대로, §49.3). */
.app-rail-btn[data-peek]:not([data-on]) {
  background: var(--color-bg-hover);
}

/* 사이드바 프로젝트·팀 묶기(묶음 3 디자이너 ⑧, 묶음 6 B1·T1): 머리 행은 Row 모양(36, 같은 포커스 링), 아이콘 15 · 이름 secondary,
   접혔을 때만 오른쪽 `{n}` + 처리할 것 점. 전환 애니메이션 없음. */
/* 칸 제목(눈썹)은 스크롤 밖에 고정, 폴더 머리는 sticky — 다음 머리가 밀어낸다. 붙어 있을 때만 아래 1px line(m1-spec §2). */
/* 칸 제목 띠(m1-spec §2 a2388fec, 루오님 10-25): 높이 40, bg-side, 본문 글꼴 600 12 ink(영어도 모노 아님), 아래 선 없음.
   그 아래 스크롤 목록은 한 단계 다른 면 bg-side-list — 면이 칸 제목과 목록을 가른다. 사이드바엔 20a 막대 없음. */
.app-side-pane > .ld-eyebrow {
  flex: none;
  box-sizing: border-box;
  height: 40px;
  padding-block: 0;
  font: 600 12px / 1.4 var(--font-family-body);
  letter-spacing: 0;
  color: var(--color-ink);
  background: var(--color-bg-side);
}
.app-side-scroll {
  padding-block: var(--space-1);
  background: var(--color-bg-side-list);
}
/* 폴더 머리 글자는 12 400 ink-secondary — 세션 이름(13 ink)보다 한 단계 낮게. */
.app-project-head .ld-rowitem-t {
  font-size: 12px;
  font-weight: 400;
  color: var(--color-ink-secondary);
}
.app-project-sticky {
  position: sticky;
  /* 스크롤 칸 맨 위(찾기 칸 바로 아래)에 틈 0(#679 디자이너): sticky 는 칸 padding 안쪽에 서므로 칸 위 여백(--ld-scroll-pt, ScrollArea
     가 잼)만큼 바깥으로 — 위 페이드와 같은 값. 동료 팀 머리·내 에이전트 폴더 머리 같은 규칙. */
  top: calc(-1 * var(--ld-scroll-pt, 0px));
  z-index: 1;
  background: var(--color-bg-side-list);
}
.app-project-sticky[data-stuck] {
  box-shadow: inset 0 -1px 0 var(--color-line);
}
.app-project-head {
  color: var(--color-ink-secondary);
  cursor: default;
}
/* 우클릭 `꺼진 세션 숨기기…` 확인이 열린 동안 그 머리 행은 호버 꼴(묶음 8 f907ac8a — 사이드바 안 호버는 bg-side-hover). */
.app-project-asking .app-project-head.ld-rowitem {
  background: var(--color-bg-side-hover);
}
/* 폴더·팀 머리(묶음 6 B1·T1, m1-spec §2): 아이콘 15 가운데 x 18, 이름 x 30(행 왼쪽 끝 x 6 기준 4.5 + 15 + 4.5). */
.app-project-head.ld-rowitem {
  gap: 4.5px;
  padding-inline-start: 4.5px;
}
.app-project-folder {
  display: inline-flex;
  flex: none;
  width: 15px;
  height: 15px;
  color: var(--color-ink-secondary);
}
.app-project-folder svg {
  width: 15px;
  height: 15px;
}
/* 고정 표시(감사 D1): 이름 바로 뒤 pin 12 ink-tertiary — 고정한 머리는 이름 칸이 늘지 않고, 남는 폭은 pin 뒤가 먹는다(접힌 {n} 은 오른쪽 끝).
   축소판은 이름과 같이 뺀다. */
.app-project-head[data-pinned] .ld-rowitem-t,
.app-project-head:has(.app-project-shared) .ld-rowitem-t {
  flex: 0 1 auto;
}
.app-project-pin {
  display: inline-flex;
  color: var(--color-ink-tertiary);
}
/* pin 을 감싼 툴팁 자리가 남는 폭을 먹는다. */
.app-project-head > .ld-tip:has(> .app-project-pin) {
  display: inline-flex;
  flex: none;
  margin-inline-end: auto;
}

/* 공개 표시 users(묶음 36 P1)도 이름 바로 뒤 — 감싼 툴팁 자리가 남는 폭을 먹는다. pin·users 둘 다면 뒤의 users 만(검수 🟡). */
.app-project-head > .ld-tip:has(> .app-project-shared) {
  display: inline-flex;
  flex: none;
  margin-inline-end: auto;
}
.app-project-head > .ld-tip:has(> .app-project-pin):has(~ .ld-tip > .app-project-shared) {
  margin-inline-end: 0;
}
/* 머리 호버 more(감사 D1): 행 오른쪽 끝에 겹쳐 두고 호버·포커스 때만 보인다 — 그동안 접힌 {n}·점은 가린다(자리 하나). */
.app-project-act {
  position: absolute;
  inset-block: 0;
  inset-inline-end: var(--space-1);
  display: flex;
  align-items: center;
  visibility: hidden;
}
.app-project-sticky:hover .app-project-act,
.app-project-act:focus-within {
  visibility: visible;
}
.app-project-sticky:hover .app-project-head .ld-rowitem-r,
.app-project-sticky:focus-within .app-project-head .ld-rowitem-r {
  visibility: hidden;
}
/* 축소판에서만: 이름 자리(x 30)에 흐린 `…` — 이름이 줄어 있다는 표시. */
/* 공개 표시 P1(묶음 36): 보이는 프로젝트 머리 이름 뒤 users 12 + 고른 사람 수, 누름 자리 최소 20(팝오버). */
.app-project-shared {
  display: inline-flex;
  flex: none;
  align-items: center;
  justify-content: center;
  gap: 2px;
  min-width: 20px;
  min-height: 20px;
  margin-inline-start: var(--space-1);
  border-radius: var(--radius-sm);
  color: var(--color-ink-tertiary);
  cursor: default;
}
.app-project-shared:hover {
  background: var(--color-bg-hover);
}
.app-project-shared-n {
  font-size: var(--font-size-small);
  font-variant-numeric: tabular-nums;
}
.app-project-more {
  display: none;
  font-size: 12px;
  color: var(--color-ink-tertiary);
}

/* 묶음 사이 가로선: 두 번째 폴더·팀 머리부터 위에 1px line(좌우 10 안쪽, 위아래 6). */
.app-project + .app-project {
  margin-top: 0;
  padding-top: 13px;
  position: relative;
}
.app-project + .app-project::before {
  content: "";
  position: absolute;
  top: 6px;
  left: 10px;
  right: 10px;
  height: 1px;
  background: var(--color-line);
}
.app-project-dot {
  display: inline-block;
  width: 6px;
  height: 6px;
  border-radius: 999px;
  background: var(--color-accent);
  margin-inline-start: var(--space-1);
  vertical-align: middle;
}
.app-accent {
  color: var(--color-accent-text);
}

/* 세션 줄 에이전트 마크(공식 로고 단색 16, 꺼진 행 색 — 켜진 세션은 아래 공식 색). 32 아바타 자리와 같은 폭에 가운데 — 동료 행 이름과 글자 시작선을 맞춘다. */
.app-agent {
  display: inline-flex;
  flex: none;
  align-items: center;
  justify-content: center;
  width: var(--size-avatar);
  color: var(--color-ink-secondary);
}
/* 마크 색은 토큰 agent-claude(@lodelai/ui, m1-spec §20.9). 꺼진 행은 마크도 글자처럼 흐리게(ld-rowitem-dim 은 글자색만 바꾼다).
   호버여도 그대로, 선택되면 아래 B1 규칙대로 secondary. */
.ld-rowitem-dim .app-agent {
  color: var(--color-ink-tertiary);
}
.ld-rowitem-dim .app-agent > .ld-icon[data-icon="agent-claude"] {
  color: inherit;
}
/* 축소판 프로젝트 칸: 둥근 네모 테두리 상자(ld-avatar-session), 글자는 본문 글꼴 첫 글자. */
.app-project-cell {
  font-family: var(--font-family-body);
}

/* 나란히 보기(§7): 대화 | 세션. 칸마다 세로 flex(머리·본문·입력창), 경계는 사이드바와 같은 6px 띠(ld-resize) — 메인 창(글래스)은 8 홈 + 손잡이(§43.4, 아래 글래스 블록). */
.app-split {
  position: relative;
  flex: 1;
  min-height: 0;
  display: flex;
}
.app-split-left,
.app-split-right {
  min-width: 0;
  min-height: 0;
  display: flex;
  flex-direction: column;
}
.app-split-left {
  flex: none;
}
/* 규칙 35: 대화 칸 옆 띠·입력칸 자리는 줄지 않는다(창 480 에서도 입력칸 전체가 보이게). */
.app-split-left > :not(.app-thread) {
  flex: none;
}
.app-split-right {
  flex: 1;
  border-inline-start: 1px solid var(--color-line);
}
/* 옆(세션) 칸 = 세션 화면 | 프로젝트 패널(#518 — 패널은 세션 칸에 딸린다). 세션 화면이 남는 폭을 쓴다. */
.app-split-session {
  flex: 1;
  min-height: 0;
  display: flex;
}
.app-split-session-main {
  flex: 1;
  min-width: 0;
  min-height: 0;
  display: flex;
  flex-direction: column;
}
.app-split-handle {
  position: relative;
  flex: none;
  width: 6px;
  margin-inline: -3px;
  z-index: 1;
}
/* 떼어진 세션 창(7b): 사이드바가 없으니 머리 줄이 신호등(x 14 + 버튼 셋, 오른쪽 끝 약 74) 뒤에서 시작한다. */
.app-session-window .app-header {
  padding-inline-start: calc(74px + var(--space-3));
}

/* 사이드바 면과 선택(m1-spec §2 B1, 루오님 10-24): side 면은 머리 줄 아래 선부터(맨 위 신호등 줄은 창 전체 폭이라 bg),
   선택 행 = bg-selected(호버해도 그대로), 호버 = bg-side-hover. 주황은 선택에 쓰지 않는다. 축소판도 같다.
   side 면 위에서 bg-hover(#161616/#f3f3f3)는 묻히므로 사이드바 안 버튼·아이콘 버튼 호버도 bg-side-hover 로. */
.app-sidebar {
  background: var(--color-bg-side);
}
.app-sidebar > .app-titlebar {
  background: var(--color-bg);
}
.app-side-over {
  background: var(--color-bg-side);
}
.app-sidebar .ld-rowitem-sel,
.app-sidebar .ld-rowitem-sel[data-state~="hover"] {
  background: var(--color-bg-selected);
}
.app-sidebar .ld-rowitem[data-state~="hover"]:not(.ld-rowitem-sel),
.app-sidebar .ld-ibtn[data-state~="hover"],
.app-sidebar .ld-ibtn[aria-pressed="true"] {
  background: var(--color-bg-side-hover);
}
@media (hover: hover) {
  .app-sidebar .ld-rowitem:hover:not(.ld-rowitem-sel),
  .app-sidebar .ld-ibtn:hover,
  .app-sidebar .ld-btn:not(.ld-btn-primary):not(:disabled):hover {
    background: var(--color-bg-side-hover);
  }
  .app-sidebar .ld-rowitem-sel:hover {
    background: var(--color-bg-selected);
  }
}
/* 꺼진 세션이 선택되면 이름·마크를 tertiary → secondary 로(지금 열린 창이 흐려 보이지 않게). */
.app-sidebar .ld-rowitem-sel.ld-rowitem-dim,
.app-sidebar .ld-rowitem-sel.ld-rowitem-dim .app-agent {
  color: var(--color-ink-secondary);
}

/* 넘기기 팝오버 다른 맥 내 에이전트(묶음 28 §36.1): 제목 뒤 흐린 꼬리 = 그 맥 이름. */
.app-forward-device {
  margin-left: var(--space-2);
}
/* 기기 꼬리는 다 보이고 제목이 줄어든다(#490 관문 🟡 — 꼬리가 잘리면 어느 맥인지 모름). */
.app-forward-name-dev {
  display: flex;
  align-items: baseline;
}
/* 줄이는 순서(#569 ①): 제목 9자째부터(…) → 앞 8자에 닿으면 기기 꼬리(…). 앞 8자는 줄지 않는다. */
/* pre: 앞 8자와 나머지 사이 띄어쓰기가 칸 경계에서 사라지지 않게. */
.app-forward-title-head {
  flex: none;
  white-space: pre;
}
.app-forward-title-rest {
  flex: 0 1000 auto;
  /* … 자리 — 나머지가 다 줄어도 잘렸다는 표시는 남는다(기기 꼬리도 같음). */
  min-width: 1.5em;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: pre;
}
.app-forward-name-dev > .app-forward-device {
  flex: 0 1 auto;
  min-width: 1.5em;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
/* 내 에이전트끼리 행(묶음 28 §36.2): message-square 15 ink-secondary. */
.app-own-relay-mark {
  display: inline-flex;
  color: var(--color-ink-secondary);
}
/* 옛 서버 동료·조직에 없는 사람 행은 고른 상태에서도 글자를 흐리게(c89621de) — 선택 면 위 대비 4.5:1 을 지키려 ink-secondary(#432 DS v120).
   선택 행 안의 다른 흐린 글자(시각·meta·단축키)도 같은 규칙. */
.app-sidebar .app-past-peer .ld-rowitem-sel.ld-rowitem-dim,
.app-sidebar .ld-rowitem-sel .app-tertiary {
  color: var(--color-ink-secondary);
}

/* 세션 이름 인라인 편집(설정 표시 이름 .set-name-* 와 같은 꼴). */
.app-name-edit {
  display: flex;
  align-items: flex-end;
  gap: var(--space-2);
  padding: var(--space-2) 0;
  border-bottom: 1px solid var(--color-line);
}
.app-name-field {
  flex: 1;
  min-width: 0;
}
.app-name-actions {
  display: flex;
  gap: var(--space-2);
  flex: none;
}
/* 사이드바 행: 대화 제목(최대 80자)이 길어도 상태(승인·질문·꺼짐)는 줄지 않게 — 상태는 제 폭(최대 행의 60%), 제목이 말줄임(세션 이름 m1-spec §2). */
.app-sidebar .ld-rowitem-r {
  flex: 0 0 auto;
  max-width: 60%;
}

/* 세션 목록 거르기(m1-spec §2 묶음 4). 찾기 줄: `내 세션` 눈썹 아래 스크롤 밖 한 줄(32). 마크 열에 search(세션 마크와 같은 x —
   목록·행 안쪽 여백을 그대로 더한다), 테두리 없는 입력(12), 오른쪽 끝 칩. 포커스면 아래 1px line-strong, 아니면 line. */
.app-side-search {
  flex: none;
  display: flex;
  align-items: center;
  gap: var(--size-gap-inner);
  height: 32px;
  padding-inline: calc(var(--size-gap-tight) + var(--size-gap-inner));
  box-shadow: inset 0 -1px 0 var(--color-line);
  background: var(--color-bg-side);
}
.app-side-search[data-focus] {
  box-shadow: inset 0 -1px 0 var(--color-line-strong);
}
.app-side-search-icon {
  display: inline-flex;
  flex: none;
  justify-content: center;
  width: var(--size-avatar);
  color: var(--color-ink-tertiary);
}
.app-side-search-input {
  flex: 1 1 auto;
  min-width: 0;
  height: 100%;
  padding: 0;
  border: 0;
  outline: none;
  background: transparent;
  font-family: var(--font-family-body);
  font-size: 12px;
  color: var(--color-ink);
}
.app-side-search-input::placeholder {
  color: var(--color-ink-tertiary);
}
.app-side-search-input::-webkit-search-cancel-button {
  display: none;
}
/* 칩 `기다림 {n}`: 줄지 않는다(사이드바 최소 폭에서도 입력이 줄어든다). */
/* 기다림 칩(규칙 19 점검 2차 A2): state-waiting + {n}. 색은 눌렸을 때만 accent. */
.app-chip {
  flex: none;
  display: inline-flex;
  align-items: center;
  gap: 4px;
  height: 22px;
  padding: 0 var(--space-2);
  border: 0;
  border-radius: 999px;
  background: transparent;
  font-family: var(--font-family-body);
  font-size: 12px;
  color: var(--color-ink-secondary);
  font-variant-numeric: tabular-nums;
  cursor: default;
}
.app-chip:hover:not(:disabled) {
  background: var(--color-bg-side-hover);
}
.app-chip[aria-pressed="true"] {
  background: var(--color-bg-selected);
  color: var(--color-accent-text);
}
.app-chip:disabled {
  color: var(--color-ink-tertiary);
}

.app-chip:focus-visible {
  outline: 2px solid var(--color-accent);
  outline-offset: 1px;
}
/* 축소판: 같은 x 의 search 아이콘만(칩은 숨음), 기다림이 켜져 있으면 아이콘 위 accent 점. */

/* `꺼진 세션 {n}개` 묶음 제목 줄(m1-spec §2 e9f4ab54): 행이 아니다 — 높이 24, 아이콘 없음, 시작선 = 세션 이름
   (행 여백 12 + 마크 16 + 간격 12), 글자 바로 뒤 ▸/▾(간격 4), 그 뒤 줄 끝까지 1px 선. 호버는 배경 없이 글자·화살표만. */
.app-off-head {
  display: flex;
  align-items: center;
  gap: 4px;
  width: 100%;
  height: 24px;
  box-sizing: border-box;
  /* 시작선 = 세션 행 아이콘 열: 행 왼쪽 여백만 — 마크 왼쪽 끝과 같은 x 16(m1-spec §2, 2bb7232d). */
  padding: 0 var(--size-gap-inner);
  border: 0;
  border-radius: var(--radius-sm);
  background: transparent;
  font-family: var(--font-family-body);
  font-size: 12px;
  color: var(--color-ink-tertiary);
  cursor: default;
}
.app-off-head:hover {
  color: var(--color-ink-secondary);
}
.app-off-head:focus-visible {
  outline: 2px solid var(--color-accent);
  outline-offset: -2px;
}
.app-off-n {
  flex: none;
  white-space: nowrap;
}
.app-off-count {
  display: none;
  font-size: 11px;
  font-variant-numeric: tabular-nums;
}
.app-off-chev {
  display: inline-flex;
  flex: none;
}
.app-off-line {
  flex: 1;
  min-width: 0;
  height: 1px;
  margin-inline-start: 4px;
  background: var(--color-line);
}
/* 툴팁 감싸개(축소판)째 줄 전체 폭 — 누르는 범위·선이 줄 끝까지. */
.app-off-group > .ld-tip {
  display: flex;
}
/* 펼치면 제목 줄과 흐린 행들을 옅은 묶음 면 하나가 감싼다(bg-side, 목록 면 bg-side-list 와 한 단계 다름). 접으면 면 없음. */
.app-off-group-open {
  margin-bottom: 2px;
  border-radius: var(--radius-sm);
  background: var(--color-bg-side);
}
/* 축소판 = 글자만 뺀 것: `{n}




.app-filter-empty {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: var(--space-1);
}
/* ghost 글자 시작선 = 윗줄 글자 시작선 — 버튼 안쪽 여백만큼 바깥으로(호버 면만 밖으로 나온다, 디자이너). */
.app-filter-empty .ld-btn {
  margin-inline-start: calc(var(--space-3) * -1);
}
/* 런처 지난 대화 찾기 칸(묶음 4 §6): 사이드바 찾기 줄과 같은 꼴, 런처 면 위라 배경 없이 행 안쪽 여백에 맞춘다. */
.app-launcher-search {
  background: transparent;
  padding-inline: var(--size-gap-inner);
}
/* 읽기만 대화(묶음 4 §3)에서 숨겨 둔 입력창 — 초안을 지우지 않으려고 그대로 둔다. */
.app-composer-slot[hidden] {
  display: none;
}
.app-composer-slot {
  flex: none;
}
/* 그룹을 끈 서버의 그룹 대화(#535): 입력칸 자리·높이 그대로 흐린 한 줄(ink-tertiary), Note 없음. 입력칸은 숨겨 포커스도 안 간다. */
.app-composer-slot[data-off] {
  position: relative;
}
.app-composer-slot[data-off] > :not(.app-composer-off) {
  visibility: hidden;
}
.app-composer-off {
  position: absolute;
  inset: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  padding-inline: var(--space-5);
  color: var(--color-ink-tertiary);
  text-align: center;
}
/* 동료 칸 눈썹(묶음 5, m1-spec §2): 서버 relay 면 조직 이름 — 좁으면 이름이 먼저 줄고(툴팁 전체), 필터·`+` 는 줄지 않는다. */
/* 사이드바 조직 머리의 조직 사진(#554): 이름 앞 20 — 위 '나' 행과 같은 선(아바타 16·이름 46, 배치 대조 4 🟡2).
   눈썹 왼쪽 여백 14 + 2, 눈썹 간격 8 + 2. */
.app-eyebrow-org {
  display: inline-flex;
  margin-inline: 2px;
}
.app-eyebrow-name {
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.ld-eyebrow-act > .sp {
  min-width: 0;
}
/* 팀 필터 `모든 팀 ▾`: 눈썹 줄 안의 흐린 글자 트리거(값 팝업 그대로, 크기만 눈썹에 맞춤). */
.app-team-filter {
  flex: none;
}
.app-team-filter .ld-pop-t {
  height: auto;
  padding: var(--space-1) var(--space-1);
  margin-block: calc(var(--space-1) * -1);
  font: inherit;
  font-weight: 400;
  color: var(--color-ink-tertiary);
}
.app-team-filter .ld-pop-t:hover {
  background: var(--color-bg-side-hover);
}
.app-team-filter .ld-menu {
  min-width: max-content;
}
/* 다른 팀에 읽을 것 줄(눈썹 바로 아래, 스크롤 밖) — 누르면 모든 팀. */
.app-team-more {
  all: unset;
  display: flex;
  align-items: center;
  gap: var(--space-1);
  margin: 2px 6px 4px;
  padding: 4px 10px;
  font-size: var(--font-size-small);
  color: var(--color-ink-secondary);
  border-radius: var(--radius-sm);
  cursor: pointer;
}
.app-team-more:hover {
  background: var(--color-bg-hover);
}
.app-team-more:focus-visible {
  outline: 2px solid var(--color-accent);
  outline-offset: -2px;
}
/* 조직 목록 — 내 동료 고르기(묶음 5, m1-spec §2): 동료 칸 `+` 에 붙는 팝오버. 폭 320·높이 최대 480, 애니메이션 없음.
   찾기 줄은 사이드바 찾기 줄 꼴, 팀 머리는 폴더 머리 글자 꼴(접기 없음), 행 오른쪽 한 자리 IconButton(plus ↔ check). */
.app-orgpick {
  width: 320px;
  max-height: 480px;
  display: flex;
  flex-direction: column;
  background: var(--color-bg);
  border: 1px solid var(--color-line-strong);
  border-radius: var(--radius-radius);
  overflow: hidden;
}
.app-orgpick-list {
  flex: 1 1 auto;
  min-height: 0;
  overflow-y: auto;
  padding: var(--space-1) var(--size-gap-tight);
}
.app-orgpick-head {
  height: var(--size-row);
  display: flex;
  align-items: center;
  padding-inline: var(--size-gap-inner);
  font-size: 12px;
  color: var(--color-ink-secondary);
}
.app-orgpick-row {
  padding-inline-end: var(--space-1);
}
.app-orgpick-row[data-active] {
  background: var(--color-bg-hover);
}
.app-orgpick-open {
  flex: 1 1 auto;
  min-width: 0;
  display: flex;
  align-items: center;
  gap: var(--size-gap-inner);
  height: 100%;
  padding: 0;
  border: 0;
  background: transparent;
  font: inherit;
  color: inherit;
  text-align: start;
}
.app-orgpick-alone {
  display: flex;
  align-items: center;
  justify-content: space-between;
}

/* 하단 상태창(묶음 6, m1-spec §12b · 보드 StatusBar): 창 전체 폭 한 줄 24, 위 1px line, bg, 12 ink-tertiary, 애니메이션 없음
   (처리 중 아이콘의 돎만 — 규칙 21). 사이드바·본문은 그 위 .app-body 안. */
.app-with-bar {
  flex-direction: column;
}
.app-body {
  flex: 1;
  min-height: 0;
  display: flex;
}
.app-statusbar {
  flex: none;
  box-sizing: border-box;
  height: 24px;
  display: flex;
  align-items: center;
  /* 왼쪽 아이콘 가운데 = 사이드바 아이콘 열 가운데 x 26(세션 마크·아바타와 같은 열, 축소판도 — 규칙 17): 14 + 24/2. 오른쪽 ↻ 가운데도
     창 끝 − 26(16 + 20/2, §43.5 대칭). */
  padding: 0 16px 0 14px;
  border-top: 1px solid var(--color-line);
  background: var(--color-bg);
  font-size: 12px;
  line-height: 1;
  color: var(--color-ink-tertiary);
  font-variant-numeric: tabular-nums;
}
/* 상태창 아이콘은 12(§43.5 --size-icon-sm) — 연결·상태 수·경고·Claude 마크·↻ 모두. 누름 상자는 그대로(24 × 20 · 20 × 20). */
.app-statusbar .ld-icon svg {
  width: var(--size-icon-sm);
  height: var(--size-icon-sm);
}
.app-statusbar-l,
.app-statusbar-r {
  flex: 1;
  min-width: 0;
  display: flex;
  align-items: center;
}
.app-statusbar-r {
  justify-content: flex-end;
}
.app-statusbar-c {
  flex: none;
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 0 12px;
  white-space: nowrap;
}
.app-statusbar-n {
  display: inline-flex;
  align-items: center;
  gap: 4px;
}
/* 상태 아이콘 색(규칙 21, 10-26): 기다림 accent · 오류 danger · 켜져 있음(처리 중·새 답·쉼) success — 수도 같은 색(아이콘과 한 덩어리). */
.app-statusbar-n[data-kind="waiting"] {
  color: var(--color-accent);
}
.app-statusbar-n[data-kind="error"] {
  color: var(--color-danger-text);
}
.app-statusbar-n[data-kind="working"],
.app-statusbar-n[data-kind="unseen"],
.app-statusbar-n[data-kind="idle"] {
  color: var(--color-success);
}
.app-statusbar-btn {
  all: unset;
  box-sizing: border-box;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 24px;
  height: 20px;
  padding: 0;
  border-radius: var(--radius-sm);
  cursor: pointer;
  color: var(--color-ink-tertiary);
}
.app-statusbar-btn:hover {
  background: var(--color-bg-hover);
  color: var(--color-ink-secondary);
}
.app-statusbar-btn:focus-visible {
  outline: 2px solid var(--color-accent);
  outline-offset: -2px;
}
/* 연결(§12b, 10-26 색 뜻): 이 맥 laptop success · 다시 연결 중 회색 돎 · 서버 주의 warn · 문제 danger. accent 는 '나를 부름' 전용. */
.app-statusbar-btn[data-conn="local"] {
  color: var(--color-success);
}
.app-statusbar-btn[data-conn="reconnecting"] {
  color: var(--color-ink-secondary);
}
.app-statusbar-btn[data-level="warn"] {
  color: var(--color-warn);
}
.app-statusbar-btn[data-level="bad"] {
  color: var(--color-danger-text);
}
/* 방해 금지 켜짐(§21.3): bell-off ink-secondary — 연결 아이콘보다 한 단계 진하게, 지금 알림이 꺼져 있음을 알린다. */
.app-statusbar-btn[data-dnd] {
  color: var(--color-ink-secondary);
}
/* 알림 꺼짐(#579): bell warn — 시스템이 막아 배너를 못 받는 문제라 회색 아님. */
.app-statusbar-btn[data-notify-off] {
  color: var(--color-warn);
}
/* 앱·서버 판 불일치(§29.9): 막힘 = state-error danger. */
.app-statusbar-btn[data-conn="mismatch"],
.app-statusbar-btn[data-conn="cut"] {
  color: var(--color-danger-text);
}
/* 업데이트 하루 넘게 확인 못 함(§18.6 stale): state-error — 빨강은 아이콘만(규칙 25). 확인하는 동안은 회색 돎. */
.app-statusbar-btn[data-stale] {
  color: var(--color-danger-text);
}
.app-statusbar-dot {
  /* 연결됨 = 녹색 점(§20.9) — 옆 글자는 무채색 그대로. */
  color: var(--color-success);
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: currentColor;
}
.app-statusbar-usage {
  all: unset;
  box-sizing: border-box;
  display: inline-flex;
  align-items: center;
  gap: 6px;
  height: 20px;
  padding: 0 6px;
  border-radius: var(--radius-sm);
  white-space: nowrap;
  font-variant-numeric: tabular-nums;
  cursor: pointer;
}
.app-statusbar-usage:hover,
.app-statusbar-usage[aria-expanded="true"] {
  background: var(--color-bg-hover);
  color: var(--color-ink-secondary);
}
.app-statusbar-usage:focus-visible {
  outline: 2px solid var(--color-accent);
  outline-offset: -2px;
}
/* Claude 마크는 상태가 아니라 '어느 에이전트' — @lodelai/ui 의 agent-claude 그대로(§20.9). */
.app-statusbar-usage > .ld-icon:not([data-icon="agent-claude"]) {
  color: var(--color-ink-secondary);
}
.app-usage-bar {
  display: inline-flex;
  align-items: center;
  gap: 4px;
}
/* 막대 감싸개도 flex — 인라인이면 4px 막대가 글자 기준선에 앉아 아래로 치우친다(루오님 10-27, 세로 가운데). */
.app-usage-meter-box {
  display: inline-flex;
  align-items: center;
}
/* 상태창 오른쪽 묶음 간격(§43.5): ✳ —6— 막대 —6— 글자 —4— ↻ 상자. 막대 뒤만 6(% 와 남은 시간 사이는 4 그대로), 누름 상자 오른쪽
   여백 4 — ↻ 상자 가운데가 창 끝 − 26 에 오게. */
.app-statusbar-usage {
  padding-inline-end: 4px;
}
.app-statusbar .app-usage-meter-box {
  margin-inline-end: 2px;
}
/* 좁은 창: 가운데 먼저 숨김(§12b). */
@media (max-width: 560px) {
  .app-statusbar-c {
    display: none;
  }
}
/* 더 좁으면 사용량은 % 만(막대·남은 시간·덧붙임 숨김). */
@media (max-width: 360px) {
  .app-usage-wide,
  .app-usage-meter-box {
    display: none;
  }
}

/* 세션 상태 아이콘(interaction-rules 21, 보드 StateIcons .si): 16, 상자·호버 없음. 색은 상태마다 하나 — 처리 중 ink-secondary ·
   나를 기다림 accent(앱에서 accent 상태는 이것 하나) · 오류 danger · 쉼·꺼짐 ink-tertiary. 기다림 2 이상이면 오른쪽 수(12 tabular). */
.app-state {
  display: inline-flex;
  align-items: center;
  flex: none;
  min-width: 16px;
  min-height: 16px;
  gap: 2px;
}
.app-state[data-tone="live"],
.app-state-badge[data-tone="live"] {
  color: var(--color-success);
}
.app-state[data-tone="wait"],
.app-state-badge[data-tone="wait"] {
  color: var(--color-accent);
}
.app-state[data-tone="err"],
.app-state-badge[data-tone="err"] {
  color: var(--color-danger-text);
}
.app-state[data-tone="quiet"],
.app-state-badge[data-tone="quiet"] {
  color: var(--color-ink-tertiary);
}
.app-state-n {
  font-size: 12px;
  font-variant-numeric: tabular-nums;
}
/* 축소판 배지: 에이전트 마크 오른쪽 아래 10, 바탕색 2px 테두리(보드 rbadge). */
.app-state-badge {
  position: absolute;
  right: -6px;
  bottom: -5px;
  width: 12px;
  height: 12px;
  border-radius: 7px;
  display: flex;
  align-items: center;
  justify-content: center;
  background: var(--color-bg-side-list);
  box-shadow: 0 0 0 2px var(--color-bg-side-list);
}

/* 터미널 링크 툴팁(⌘+클릭 열기, #380): 앵커는 링크 칸 자리에 fixed, 포인터는 xterm 이 받는다. URL 은 ink 로 자르지 않고, 열기 안내는 흐리게. */
.app-term-link-anchor {
  position: fixed;
  pointer-events: none;
}
.app-term-link-anchor > .ld-tip,
.app-term-link-box {
  display: block;
  width: 100%;
  height: 100%;
}
.app-term-link-tip {
  display: flex;
  flex-direction: column;
  gap: 2px;
  overflow-wrap: anywhere;
}
.app-term-link-how {
  color: var(--color-ink-tertiary);
}

/* 흐린 메타 자리의 상태 아이콘(규칙 19 점검 2차 — 관리자 shield 채움·요청 받는 세션 마크 + 수): 12, ink-tertiary, 상자 없음. */
.app-meta-icon {
  display: inline-flex;
  flex: none;
  align-items: center;
  gap: 3px;
  margin-inline-start: var(--space-1);
  color: var(--color-ink-tertiary);
  font-size: 12px;
  font-variant-numeric: tabular-nums;
}
/* ` · ` 뒤에 오는 상태 아이콘은 앞 여백 없이 — 간격은 ` · ` 하나(§22.7 내가 확인하고 보냄 · {상태}). */
.app-ft-sep + .ld-tip > .app-meta-icon,
.app-ft-sep + .app-meta-icon {
  margin-inline-start: 0;
}
.app-meta-icon[data-tone="danger"] {
  color: var(--color-danger-text);
}
.app-meta-icon[data-filled] svg {
  fill: currentColor;
}

/* 경로 가운데 말줄임(규칙 7): 마지막 `/이름` 은 줄지 않고, 앞부분만 … 로. */
.app-path-mid {
  display: block;
  width: 100%;
  overflow: hidden;
  white-space: nowrap;
  text-align: end;
}
/* 경로 meta 가 있는 행(런처 폴더): 이름이 먼저 자리를 갖고(행 폭의 최대 60% — 사이드바 meta 규칙과 같은 비율), 경로는 남은 폭을
   다 쓰며 가운데를 줄인다. 이름이 60% 보다 짧으면 경로가 나머지를 다 쓴다(디자이너 10-25). */
.ld-rowitem:has(.app-path-mid) .ld-rowitem-t {
  flex: 0 0 auto;
  max-width: 60%;
}
.ld-rowitem:has(.app-path-mid) .ld-rowitem-r {
  flex: 1 1 0;
}

/* 승인 대기 한 줄(M1, m1-spec §2): 요청 카드 아래 흐린 글 + ghost `터미널 열기`. 애니메이션 없음. */
/* 받은 쪽 실패 한 줄(§31.3) — 글 + 줄 끝 rotate-cw `세션에 다시 넣기`. */
.app-reinject {
  display: flex;
  align-items: center;
  gap: var(--space-2);
}
.app-terminal-wait {
  display: flex;
  align-items: center;
  gap: 12px;
  margin-top: 8px;
  font-size: 13px;
  color: var(--color-ink-tertiary);
}
/* 세션 정보 `바뀐 파일`(묶음 10 A1): 상태 글자(모노)·경로(가운데 말줄임)·+a −d(모노 12, 색으로 좋고 나쁨을 말하지 않음). */
.app-diff-row {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  width: 100%;
  min-height: var(--size-row);
  padding: 0;
  border: 0;
  background: transparent;
  color: var(--color-ink);
  font: inherit;
  text-align: start;
}
button.app-diff-row:hover {
  background: var(--color-bg-hover);
}
.app-diff-st {
  flex: none;
  width: 12px;
  font-family: var(--font-family-mono);
  font-size: 12px;
  color: var(--color-ink-secondary);
}
.app-diff-path {
  flex: 1;
  min-width: 0;
}
/* 경로는 왼쪽부터(런처 meta 의 끝 정렬과 다르다). */
.app-diff-path .app-path-mid {
  text-align: start;
  font-family: var(--font-family-mono);
  font-size: var(--font-size-code);
}
.app-diff-n {
  flex: none;
  font-family: var(--font-family-mono);
  font-size: 12px;
}
.app-diff-patch {
  /* 페이드는 칸 바탕(bg-card)에서 — 기본 bg(흰)면 좌우 페이드가 거의 안 보였다(관문 13 ❌⑤, 규칙 32 b). */
  --ld-fade-bg: var(--color-bg-card);
  margin: 0 0 var(--space-2);
  padding: var(--space-2) var(--space-3);
  max-height: 320px;
  overflow: auto;
  white-space: pre;
  font: var(--text-code);
  background: var(--color-bg-card);
  border: 1px solid var(--color-line);
  border-radius: var(--radius-radius);
}
.app-diff-line {
  padding-block: var(--space-1);
  font-size: 12px;
}

/* 세션 머리 브랜치(묶음 12 §20.3): 흐린 모노 12, 최대 160 말줄임. 상태보다 먼저 준다(상태 0 100, 브랜치 0 1000). */
.app-head-branch {
  flex: 0 1000 auto;
  min-width: 0;
  max-width: 160px;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  font-size: 12px;
  color: var(--color-ink-tertiary);
}
.ld-tip:has(> .app-head-branch) {
  flex: 0 1000 auto;
  min-width: 0;
}
.app-head-branch[data-narrow] {
  visibility: hidden;
}

/* 행 아래 한 줄(거절·실패) — 메인 창용(설정 창의 set-row-note 와 같은 꼴). 다음 누름에 걷힌다. */
.app-row-note {
  margin-top: calc(-1 * var(--space-1));
  padding-bottom: var(--space-2);
  font-size: 12px;
}
/* 행 아래 실패·거절 줄(감사 D4): state-error 12 + ink-secondary 글자 [+ 다시 시도 IconButton]. */
.app-row-err {
  display: flex;
  align-items: center;
  gap: var(--size-gap-tight);
  color: var(--color-ink-secondary);
}
/* 오류 아이콘은 어디서나 빨강(규칙 21 표), 글자는 ink-secondary 그대로. */
.app-row-err > .ld-icon {
  color: var(--color-danger-text);
}
/* 행 오른쪽 동작 + 누른 프레임 state-working(왼쪽) — 동작 자리 고정. */
.app-row-act {
  display: inline-flex;
  align-items: center;
  gap: var(--size-gap-tight);
}
/* 링크 행 전체에 툴팁(지시문 경로) — 툴팁 감싸개가 행 폭을 그대로 갖게. */
.app-row-tip > .ld-tip {
  display: block;
}

/* 정해진 시각(묶음 12 §20.7): 그룹 설명 한 줄, 행 오른쪽 Toggle + pencil, 인라인 편집(시각·요일 한 줄, 지시, 바닥 버튼). */
.app-schedule-desc {
  padding-bottom: var(--space-2);
  font-size: 12px;
}
.app-schedule-acts {
  display: flex;
  align-items: center;
  gap: var(--size-gap-tight);
}
.app-schedule-edit {
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
  padding: var(--space-2) 0;
  border-bottom: 1px solid var(--color-line);
}
.app-schedule-line {
  display: flex;
  align-items: center;
  gap: var(--space-3);
}
/* 행 라벨 한 줄 말줄임(전문은 툴팁, 감사 D6) — 툴팁 감싸개도 줄어야 한다. */
.app-schedule-label {
  display: block;
  overflow: hidden;
  white-space: nowrap;
  text-overflow: ellipsis;
}
.ld-set-lb > .ld-tip:has(> .app-schedule-label) {
  display: block;
  min-width: 0;
}
/* 다음 예정 글자 + 지난 결과 아이콘. */
.app-schedule-meta {
  display: inline-flex;
  align-items: center;
  gap: var(--size-gap-tight);
}
/* 그룹 제목 오른쪽 동작(감사 D6 `일정 추가` plus) — 눈썹 줄을 가로로 펴 오른쪽 끝에. */
.ld-eyebrow:has(> .app-eyebrow-act) {
  display: flex;
  align-items: center;
}
.app-eyebrow-act {
  margin-inline-start: auto;
}
.app-schedule-prompt {
  width: 100%;
  padding: var(--space-2);
  border: 1px solid var(--color-line-strong);
  border-radius: var(--radius-sm);
}
.app-schedule-foot {
  display: flex;
  align-items: center;
  gap: var(--space-2);
}

/* 접히지 않은 꺼진 행의 `요청 {n}` 꼬리 — 다시 열어야 전달되니 처리할 것(accent-text, m1-spec c799d71a). */
.app-pending-tail {
  font-size: 12px;
  color: var(--color-accent-text);
}
/* 메시지 호버 줄(묶음 14 §22.1): 말풍선 위쪽 바깥 오른쪽 끝, 높이 28, bg 면 + line-strong 1px, radius-sm, 애니메이션 없음.
   포인터가 있거나 키보드 포커스가 메시지 안에 오면 보인다 — 숨긴 동안에도 Tab 으로 닿게 opacity 로(마우스만의 길 없음). */
.app-item {
  position: relative;
}
/* 대화 줄 호버·키보드 포커스(묶음 39 §41.7): 맨 위 줄만, 대화 칸 전체 폭(좌우 여백까지)이 bg-hover — 그 프레임에, 전환 없음.
   이어진 줄은 그 줄만. 키보드 포커스는 같은 면 + 줄 안쪽 accent 2 링(면 차이만으론 어디 있는지 안 보인다). */
.app-item[data-row] {
  /* 좌우 여백까지 넓힘 — 오른쪽은 막대 칸 앞까지(대화 칸 오른쪽 padding = conv-x − scrollbar, 37-11). */
  margin-inline: calc(-1 * var(--size-conv-x)) calc(var(--size-scrollbar) - var(--size-conv-x));
  padding-inline: var(--size-conv-x) calc(var(--size-conv-x) - var(--size-scrollbar));
  outline: none;
}
.app-item[data-row]:hover,
.app-item[data-row]:focus-visible {
  background: var(--color-bg-hover);
}
.app-item[data-row]:focus-visible {
  box-shadow: inset 0 0 0 2px var(--color-accent);
}
/* 묶음의 이어진 줄(§34.2): 앞 줄과 4 — 목록 gap(12)에서 뺀다. */
.app-item-cont {
  margin-top: calc(var(--space-1) - var(--space-3));
}
.app-msg-acts {
  position: absolute;
  top: -14px;
  /* 받은 것: 그 행 상자의 끝선(37-11 — 행 상자는 끝선까지 감). 내 말풍선·고정 칸 있는 행은 MessageActionBar 가 style 로. */
  right: 0;
  z-index: 2;
  display: inline-flex;
  align-items: center;
  height: 28px;
  padding: 0 2px;
  background: var(--color-bg);
  border: 1px solid var(--color-line-strong);
  border-radius: var(--radius-sm);
  opacity: 0;
  pointer-events: none;
}
.app-item-acts:hover > .app-msg-acts,
.app-item-acts:focus-within > .app-msg-acts {
  opacity: 1;
  pointer-events: auto;
}
/* 맨 위 줄은 좌우 여백까지 넓어졌다(§41.7) — 받은 것의 바 자리는 그 여백 안쪽 = 대화 열 끝선(37-11). */
.app-item[data-row] > .app-msg-acts:not([style]) {
  right: calc(var(--size-conv-x) - var(--size-scrollbar));
}
/* 거둔 메시지·요청(§22.2) — 말풍선 자리 흐린 한 줄. 거두지 못한 이유 한 줄도 같은 크기. */
.app-withdrawn {
  padding-block: var(--space-1);
  font-size: 13px;
}
.app-withdrawn-mine {
  text-align: right;
}
.app-withdraw-note {
  margin-top: calc(-1 * var(--space-1));
  padding-bottom: var(--space-1);
  font-size: 12px;
  text-align: right;
}
/* 고치기(§22.3) — 말풍선 자리 인라인 편집. 행 아래 한 줄은 메인 창용 app-row-note. */
.app-edit-bubble {
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
  min-width: 320px;
}
.app-edit-ta {
  width: 100%;
  padding: var(--space-2);
  border: 1px solid var(--color-line-strong);
  border-radius: var(--radius-sm);
}
.app-edit-foot {
  display: flex;
  justify-content: flex-end;
  gap: var(--space-2);
}
.app-row-note {
  margin-top: calc(-1 * var(--space-1));
  padding-bottom: var(--space-2);
  font-size: 12px;
}
/* 인용(§22.4): 말풍선 안 맨 위 한 줄 12 ink-tertiary, 면·세로 막대 없음. 누르면 원문에 1초 bg-hover. */
.app-quote {
  display: flex;
  align-items: center;
  gap: var(--size-gap-tight);
  max-width: 100%;
  margin-bottom: var(--space-1);
  padding: 0;
  border: 0;
  background: none;
  font: inherit;
  font-size: 12px;
  text-align: left;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
button.app-quote {
  cursor: pointer;
}
.app-quote-l {
  display: inline-flex;
  align-items: center;
  gap: var(--size-gap-tight);
}
.app-item-flash {
  background: var(--color-bg-hover);
}
/* 동료 접속 표시(§22.6·§20.9): 아바타 오른쪽 아래 점 8 — success 채움(녹 = 켜짐) + 바탕색 2px 테두리. */
.app-presence {
  position: relative;
  display: inline-flex;
}
.app-online-dot {
  position: absolute;
  right: -2px;
  bottom: -2px;
  width: 8px;
  height: 8px;
  box-sizing: content-box;
  border-radius: 999px;
  /* 동료 접속 점은 success(m1-spec §20.9 — §22.6 의 ink-secondary 를 바꿈, 루오님 10-26). */
  background: var(--color-success);
  border: 2px solid var(--color-bg-side-list);
}

/* 넘기기(묶음 14 §22.7): 호버 줄에 붙은 팝오버(폭 360) — 찾기 → 고르면 덧붙일 말·등급·흐린 미리보기·취소·넘기기. 애니메이션 없음. */
.app-forward {
  z-index: 10;
  width: 360px;
  /* 창 안에 다 들어가게 — 낮은 창이면 목록이 줄고 그 안에서 스크롤된다(화면확인 25 11차 🟡: `내 세션` 이 창 아래로 잘림). */
  max-height: calc(100vh - 16px);
  box-sizing: border-box;
  padding: var(--space-3);
  background: var(--color-bg);
  border: 1px solid var(--color-line-strong);
  border-radius: var(--radius-radius);
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
}
.app-forward-list {
  display: flex;
  flex-direction: column;
  flex: 0 1 auto;
  min-height: 0;
  max-height: 240px;
  overflow-y: auto;
}
.app-forward-row {
  text-align: start;
  padding: var(--space-1) var(--space-2);
  border: 0;
  border-radius: var(--radius-sm);
  background: transparent;
  color: var(--color-ink);
  font: inherit;
  cursor: pointer;
}
.app-forward-row:hover,
.app-forward-row:focus-visible {
  background: var(--color-bg-hover);
  outline: none;
}
/* 받을 수 없는 대상(25 10차): 자리 그대로 흐리게(마크·이름 ink-tertiary — 마크는 currentColor), 누를 수 없음 — 호버 면 없음, 툴팁이 까닭.
   툴팁 감싸개(ld-tip)가 목록 칸을 다 쓰게. */
.app-forward-list > .ld-tip {
  display: flex;
}
.app-forward-list > .ld-tip > .app-forward-off {
  flex: 1;
  min-width: 0;
}
.app-forward-off,
.app-forward-off:hover {
  color: var(--color-ink-tertiary);
  background: transparent;
  cursor: default;
}
/* 대상 행(§22.10): 세션이면 마크 · 상태 · 이름(줄임) · 흐린 받는 요청 값. */
.app-forward-row {
  display: flex;
  align-items: center;
  gap: var(--size-gap-tight);
  min-width: 0;
  white-space: nowrap;
}
.app-forward-name {
  flex: 1 1 auto;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
}
.app-forward-head {
  padding: var(--space-2) var(--space-2) var(--space-1);
  font: var(--text-small);
}
.app-forward-sub {
  padding-inline-start: var(--space-5);
  color: var(--color-ink-secondary);
}
.app-forward-desc {
  margin: 0;
  font: var(--text-small);
}
.app-forward-note {
  width: 100%;
  resize: none;
}
.app-forward-preview {
  margin-bottom: 0;
}
.app-forward-foot {
  display: flex;
  justify-content: flex-end;
  gap: var(--space-2);
}
/* 세션 요청 범위(묶음 20 §27): 행 값 트리거(값 팝업 꼴, 한 줄 말줄임) · 팝오버(넘기기와 같은 틀). */
.app-audience-t {
  max-width: 260px;
}
.app-audience-v {
  min-width: 0;
  overflow: hidden;
  white-space: nowrap;
  text-overflow: ellipsis;
}
.app-forward-foot {
  align-items: center;
}
.app-audience {
  gap: calc(var(--space-3) * 2);
}
.app-aud-block {
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
}
.app-aud-teams {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-1) var(--space-2);
}
.app-aud-label {
  width: 100%;
  font: var(--text-small);
}
.app-aud-team {
  gap: var(--space-1);
}
.app-aud-list {
  display: flex;
  flex-direction: column;
  max-height: 280px;
  overflow-y: auto;
}
/* 툴팁을 단 행(빠진 사람·256 상한)도 목록 폭 그대로. */
.app-aud-list > .ld-tip {
  display: flex;
}
.app-aud-list > .ld-tip > .app-aud-row {
  flex: 1;
}
/* 사람 행: DS Checkbox 가 행 전체를 감싼다 — 높이 row 36. */
.app-aud-row {
  display: flex;
  align-items: center;
  min-height: var(--size-row);
  padding: 0 var(--space-2);
  border-radius: var(--radius-sm);
  min-width: 0;
}
.app-aud-row:hover {
  background: var(--color-bg-hover);
}
.app-aud-row > .ld-check {
  flex: 1;
  min-width: 0;
  align-items: center;
}
.app-aud-row .ld-check-l {
  min-width: 0;
}
.app-aud-who {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  min-width: 0;
}
/* 조직에서 빠진 사람(감사 M4): 글자 없이 행 전체(상자 포함) 흐림 — 체크를 풀 수만 있다. 툴팁은 그 행 오른쪽 같은 줄. */
.app-aud-row.app-aud-gone {
  position: relative;
}
.app-aud-gone > .ld-check {
  opacity: 0.4;
}
.app-aud-gone-tip {
  position: absolute;
  top: 50%;
  right: var(--space-2);
  transform: translateY(-50%);
  padding: var(--space-1) var(--space-2);
  background: var(--color-bg);
  border: 1px solid var(--color-line-strong);
  border-radius: var(--radius-sm);
  font-size: var(--font-size-small);
  color: var(--color-ink);
  white-space: nowrap;
  pointer-events: none;
  visibility: hidden;
}
.app-aud-gone:hover > .app-aud-gone-tip,
.app-aud-gone:focus-within > .app-aud-gone-tip {
  visibility: visible;
}
.app-aud-name {
  min-width: 0;
  overflow: hidden;
  white-space: nowrap;
  text-overflow: ellipsis;
}
.app-aud-id {
  flex: none;
  font: var(--text-small);
}
.app-aud-count {
  font: var(--text-small);
}
/* 받은 요청 카드 — 보낸 사람이 지금 그 세션 요청 범위 밖(§27.3): by 줄 아래 흐린 한 줄 12. */
/* 요청 범위 밖(묶음 38 §40.2): by 줄 끝 shield-alert 12 + 짧은 글(warn), 문장은 툴팁. */
.app-out-aud {
  display: inline-flex;
  align-items: center;
  gap: 2px;
  margin-inline-start: var(--space-1);
  font-size: 12px;
  color: var(--color-warn);
  vertical-align: middle;
}
/* 그룹 대화(묶음 16 §24.3): 대화 줄은 가운데 흐린 한 줄(시각은 툴팁), 머리 그룹 아바타 뒤 이름. */
.app-group-lines {
  display: flex;
  flex-direction: column;
  gap: var(--space-1);
}
.app-group-line {
  text-align: center;
  font-size: var(--font-size-small);
  color: var(--color-ink-tertiary);
}
/* 내 초대가 멈춘 오류 줄(묶음 22 §12-26 ⑤, 규칙 25): state-error 12 + ink-secondary, 빨강은 아이콘만. */
.app-group-line-failed {
  display: flex;
  gap: var(--space-1);
  align-items: center;
  justify-content: center;
  color: var(--color-ink-secondary);
}
.app-group-line-failed [data-icon="state-error"] {
  color: var(--color-danger-text);
}
/* 처리하지 못한 그룹 변경(묶음 22 §29.8): 주의(막힘 아님) — shield-alert 만 warn, 글자는 ink-secondary. */
.app-mls-alert {
  display: flex;
  gap: var(--space-1);
  align-items: center;
  justify-content: center;
  color: var(--color-ink-secondary);
}
.app-mls-alert [data-icon="shield-alert"] {
  color: var(--color-warn);
}
.app-header > .ld-avatar-group {
  margin-inline-end: var(--space-2);
}
/* 읽음 n/m 팝오버: 읽은 사람 ink, 아직인 사람 흐림, 시각 없음 — 이름만 한 줄씩. */
.app-group-read {
  position: absolute;
  z-index: 20;
  margin: 0;
  padding: var(--space-1) 0;
  list-style: none;
  min-width: 120px;
  max-width: var(--size-popover);
  background: var(--color-bg);
  border: 1px solid var(--color-line-strong);
  border-radius: var(--radius-radius);
  font-size: var(--font-size-small);
  color: var(--color-ink);
}
.app-group-read > li {
  padding: 2px var(--space-3);
  overflow: hidden;
  white-space: nowrap;
  text-overflow: ellipsis;
}
/* 그룹 만들기·멤버 추가 폼(묶음 16 §24.2): 조직 목록 패널 안에서 바뀜 — 이름 칸 · 찾기 · 목록 · 아래 줄(흐린 수 · 취소 · 주버튼). */
.app-grouppick {
  display: flex;
  flex-direction: column;
  min-height: 0;
  flex: 1 1 auto;
}
.app-grouppick-name {
  padding: var(--space-3) var(--space-3) 0;
}
.app-grouppick-team {
  width: 100%;
  border: 0;
  background: none;
  font: inherit;
  font-size: 12px;
  text-align: start;
  cursor: pointer;
}
.app-grouppick-team:hover {
  color: var(--color-ink);
}
.app-grouppick-foot {
  flex: none;
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-2);
  padding: var(--space-2) var(--space-3);
  border-top: 1px solid var(--color-line);
}
/* 취소·주버튼 한 덩어리 — 늘 오른쪽 끝, 좁으면 수 글 아래 줄로(잘리지 않게, 42 관문). */
.app-grouppick-acts {
  margin-inline-start: auto;
  display: flex;
  align-items: center;
  gap: var(--space-2);
}
.app-grouppick-count {
  font-size: var(--font-size-small);
  color: var(--color-ink-tertiary);
  white-space: nowrap;
}
.app-orgpick-new {
  width: 100%;
  border: 0;
  border-bottom: 1px solid var(--color-line);
  background: none;
  font: inherit;
  color: var(--color-ink);
  text-align: start;
  cursor: pointer;
}
/* 그룹 정보(묶음 16 §24.6): 멤버 행 = 아바타 · 이름 · 흐린 meta · (관리자면) more. 맨 아래 멤버 추가, 확인 안 된 변경 한 줄. */
.app-group-member {
  gap: var(--space-2);
}
.app-group-member-name {
  font-size: var(--font-size-body);
  color: var(--color-ink);
}
.app-group-name {
  display: inline-flex;
  align-items: center;
  gap: var(--space-1);
}
.app-group-add {
  padding: var(--space-2) 0;
}
.app-group-unapplied {
  padding: var(--space-1) 0;
  font-size: var(--font-size-small);
}
/* 그룹 정보를 보는 동안 대화는 숨겨 둔다(스크롤 자리 그대로). */
.app-thread[hidden] {
  display: none;
}
.app-group-add-pick {
  width: auto;
  max-height: 360px;
  margin: var(--space-2) 0;
}

/* 터미널 찾기 막대(묶음 12 §20.11): 터미널 오른쪽 위에 겹침, 애니메이션 없음. 맞은 곳 칠하기는 xterm 데코레이션(TermFind). */
.app-term-screen {
  position: relative;
}
.app-term-find {
  position: absolute;
  top: var(--space-2);
  right: var(--space-3);
  z-index: 5;
  display: flex;
  align-items: center;
  gap: var(--space-1);
  padding: var(--space-1);
  background: var(--color-bg);
  border: 1px solid var(--color-line-strong);
  border-radius: var(--radius-radius);
}
.app-term-find-input {
  /* 고정 폭 대신 최소 폭 + flex(규칙 16, 디자인감사 71103617). */
  flex: 1 1 auto;
  width: auto;
  min-width: 160px;
  height: 24px;
  padding: 0 var(--space-2);
  border: 0;
  outline: none;
  background: transparent;
  color: var(--color-ink);
  font: inherit;
  font-size: var(--font-size-body);
}
.app-term-find-count {
  min-width: 56px;
  text-align: right;
  font-size: var(--font-size-small);
  color: var(--color-ink-tertiary);
  font-variant-numeric: tabular-nums;
}
/* 프로젝트 패널(묶음 21 m1-spec §28): 창 오른쪽, 폭은 App(320 · 280~60%). 머리 44 는 세션 머리와 같은 줄. 애니메이션 없음. */
.app-proj {
  position: relative;
  flex: none;
  min-width: 0;
  display: flex;
  flex-direction: column;
  border-inline-start: 1px solid var(--color-line);
  background: var(--color-bg);
}
.app-proj-edge {
  position: absolute;
  inset-block: 0;
  inset-inline-start: -3px;
  width: 6px;
  cursor: col-resize;
  z-index: 2;
}
.app-proj-head {
  height: var(--app-head-h);
  flex: none;
  display: flex;
  align-items: center;
  padding: 0 var(--space-3);
  border-bottom: 1px solid var(--color-line);
}
/* 탭: 아이콘 Segment 를 머리 줄 폭 꽉 채움(§28.2·감사 ①). */
.app-proj-head .ld-seg {
  display: flex;
  width: 100%;
}
.app-proj-head .ld-seg .ld-tip,
.app-proj-head .ld-seg-i {
  flex: 1;
}
.app-proj-head .ld-seg-i {
  width: 100%;
  gap: var(--space-1);
}
.app-proj-tabn {
  font-size: 12px;
  color: var(--color-ink-tertiary);
  font-variant-numeric: tabular-nums;
}
.app-proj-body {
  flex: 1;
  min-height: 0;
  display: flex;
  flex-direction: column;
}
/* 이름 찾기 줄(§28.3 — 사이드바 찾기 줄과 같은 꼴, 높이 32). */
.app-proj-find {
  flex: none;
  height: 32px;
  margin: 0 var(--space-3) var(--space-1);
}
.app-proj-tree {
  flex: 1;
  min-height: 0;
  overflow: auto;
  padding-bottom: var(--space-3);
  outline: none;
}
.app-proj-list {
  margin: 0;
  padding: 0;
  list-style: none;
}
/* 트리 행 28, 깊이마다 12(인라인 style). 파일 종류 아이콘 없음 — 글자로(장식 금지). */
.app-proj-row {
  height: 28px;
  display: flex;
  align-items: center;
  gap: var(--space-1);
  padding-inline-end: var(--space-3);
  font-size: 13px;
  white-space: nowrap;
  cursor: default;
}
.app-proj-row:hover {
  background: var(--color-bg-hover);
}
.app-proj-tree:focus-visible .app-proj-row[data-active] {
  background: var(--color-bg-selected);
}
.app-proj-chev {
  flex: none;
  width: 12px;
  display: inline-flex;
  color: var(--color-ink-tertiary);
}
.app-proj-chev[data-open] svg {
  transform: rotate(90deg);
}
.app-proj-name {
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
}
.app-proj-found .app-proj-name b {
  font-weight: 600;
}
.app-proj-dir {
  min-width: 0;
  flex: 1;
  overflow: hidden;
  text-overflow: ellipsis;
  direction: rtl;
  text-align: start;
  font-size: 12px;
}
.app-proj-lock {
  display: inline-flex;
  color: var(--color-ink-tertiary);
}
/* 깃 상태색(§28.9 — 규칙 21 색의 뜻, 파일·깃 정보 색 예외): 이름 글자색 + 끝 글자(모노 12, 같은 색). 무시 = ink-tertiary. */
.app-proj-row[data-tone="success"] .app-proj-name,
.app-proj-row[data-tone="success"] .app-proj-mark {
  color: var(--color-success);
}
.app-proj-row[data-tone="warn"] .app-proj-name,
.app-proj-row[data-tone="warn"] .app-proj-mark {
  color: var(--color-warn);
}
.app-proj-row[data-tone="danger"] .app-proj-name,
.app-proj-row[data-tone="danger"] .app-proj-mark {
  color: var(--color-danger-text);
}
.app-proj-row[data-ignored] .app-proj-name,
.app-proj-row[data-out] .app-proj-name {
  color: var(--color-ink-tertiary);
}
/* 링크 행은 툴팁이 감싼다 — 감싸개(inline-flex)를 줄 폭으로 펴 hover 바탕이 다른 행처럼 줄 전체(디자인검수 🟡③). */
.ld-tip:has(> .app-proj-row) {
  display: flex;
}
.ld-tip > .app-proj-row {
  flex: 1;
  min-width: 0;
}
.app-proj-mark {
  flex: none;
  font: var(--text-code);
  font-size: 12px;
}
.app-proj-line {
  margin: 0;
  padding: var(--space-2) var(--space-3);
  font-size: 12px;
}
/* 찾기 결과 행은 버튼(누르면 보기) — 행 꼴 그대로. */
button.app-proj-found {
  width: 100%;
  border: 0;
  background: none;
  color: inherit;
  font: inherit;
  text-align: start;
  padding-inline-start: var(--space-3);
}
/* 파일 보기(§28.4): 트리 자리가 보기로. 머리 36 은 모든 상태에서 같은 자리. */
.app-proj-view {
  flex: 1;
  min-height: 0;
  display: flex;
  flex-direction: column;
}
.app-proj-viewhead {
  height: 36px;
  flex: none;
  display: flex;
  align-items: center;
  gap: var(--space-1);
  padding: 0 var(--space-2);
  border-bottom: 1px solid var(--color-line);
}
.app-proj-viewname {
  flex: 1;
  min-width: 0;
  font-size: 13px;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.app-proj-viewname-out {
  display: flex;
  font-family: var(--font-family-mono);
  color: var(--color-ink-tertiary);
}
/* 머리 이름 자리는 왼쪽부터(파일 이름과 같은 자리) — 행 값 자리용 오른쪽 맞춤을 덮는다. */
.app-proj-viewname-out .app-path-mid {
  text-align: start;
}
.app-proj-viewbody {
  flex: 1;
  min-height: 0;
  overflow: auto;
  outline: none;
}
/* 글·코드: 모노 12, 왼쪽 흐린 줄 번호, 가로 스크롤(줄바꿈 없음). 구문 색 넷(§28.9), 나머지 ink. */
.app-proj-code {
  margin: 0;
  padding: var(--space-2) 0;
  font: var(--text-code);
  font-size: 12px;
  color: var(--color-ink);
  width: max-content;
  min-width: 100%;
}
.app-proj-line-code {
  display: flex;
  white-space: pre;
}
.app-proj-ln {
  flex: none;
  width: 40px;
  padding-inline-end: var(--space-3);
  text-align: end;
  color: var(--color-ink-tertiary);
  user-select: none;
  font-variant-numeric: tabular-nums;
}
.app-proj-line-code code {
  font: inherit;
  padding-inline-end: var(--space-3);
}
/* 줄바꿈 켬(규칙 32 E, 기본): 보이는 폭 안에서 접고, 이어진 줄은 원래 줄 들여쓰기(--ld-ind, ch)에 맞춘다. 줄 번호 열은 첫 화면 줄에만. */
.app-proj-code,
.app-git-patch-body {
  tab-size: 4;
}
.app-proj-code[data-wrap] {
  width: auto;
}
.app-proj-code[data-wrap] .app-proj-line-code {
  white-space: pre-wrap;
}
.app-proj-code[data-wrap] .app-proj-line-code code {
  flex: 1;
  min-width: 0;
  overflow-wrap: anywhere;
  padding-inline-start: var(--ld-ind, 0);
  text-indent: calc(-1 * var(--ld-ind, 0ch));
}
[data-syn="keyword"] {
  color: var(--color-syntax-keyword);
}
[data-syn="string"] {
  color: var(--color-syntax-string);
}
[data-syn="number"] {
  color: var(--color-syntax-number);
}
[data-syn="comment"] {
  color: var(--color-syntax-comment);
}
.app-proj-md {
  padding: var(--space-3);
  font-size: 13px;
}
.app-proj-md .app-md-img {
  max-width: 100%;
}
.app-proj-note {
  margin: 0;
  padding: var(--space-2) var(--space-3) 0;
}
.app-proj-trunc {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  padding: var(--space-2) var(--space-3);
}
/* 가운데 한 묶음(quicklook·binary·secret·못 읽음). */
.app-proj-center {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--space-1);
  padding: calc(var(--space-6) * 2) var(--space-4);
  text-align: center;
}
.app-proj-center p {
  margin: 0 0 var(--space-2);
}
.app-proj-center-name {
  font-size: 13px;
  word-break: break-all;
}
.app-proj-img {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--space-2);
  padding: var(--space-3);
}
.app-proj-img img {
  max-width: 100%;
  height: auto;
}
/* 파일 탭은 깃 탭을 보는 동안 숨기기만(감시·보던 파일 유지). */
.app-proj-pane {
  flex: 1;
  min-height: 0;
  display: flex;
  flex-direction: column;
}
.app-proj-pane[hidden] {
  display: none;
}
/* 깃 탭(§28.5): 브랜치 줄 36 · 그룹 `바뀐 파일`·`최근 커밋`. 조작 버튼 없음. */
.app-proj-git {
  padding-inline: var(--space-3);
}
.app-git-branch {
  height: 36px;
  display: flex;
  align-items: center;
  gap: var(--space-2);
}
.app-git-branch-ic {
  display: inline-flex;
}
.app-git-branch-name {
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  font: var(--text-code);
  font-size: 12px;
}
.app-git-ab {
  font-variant-numeric: tabular-nums;
}
/* 그룹은 설정 그룹 20a 꼴 — 깃 탭 안 간격은 토큰만: 섹션 사이 24, 제목 → 첫 행 8(디자인감사 b2ce89a3). */
.app-proj-git .ld-set-group.app-git-group {
  margin-top: calc(var(--space-5) + var(--space-1));
  margin-bottom: 0;
}
.app-git-n {
  font-weight: 400;
}
.app-git-row,
.app-git-commit {
  min-height: 28px;
}
/* 상태색(§28.9): 상태 글자·경로 = 상태색, +n success · −n danger-text. */
.app-git-row[data-tone="success"] .app-diff-st,
.app-git-row[data-tone="success"] .app-diff-path {
  color: var(--color-success);
}
.app-git-row[data-tone="warn"] .app-diff-st,
.app-git-row[data-tone="warn"] .app-diff-path {
  color: var(--color-warn);
}
.app-git-row[data-tone="danger"] .app-diff-st,
.app-git-row[data-tone="danger"] .app-diff-path {
  color: var(--color-danger-text);
}
.app-git-add {
  color: var(--color-success);
}
.app-git-del {
  color: var(--color-danger-text);
}
.app-git-patch-head {
  display: flex;
  justify-content: flex-end;
}
/* patch 줄: 더한 줄 바탕 diff-add-bg·뺀 줄 diff-del-bg, 줄 앞 +/− 는 같은 색(글자 본문은 ink). */
/* diff 내용은 읽을 글이라 고를 수 있다(규칙 31). */
.app-git-patch-body {
  -webkit-user-select: text;
  user-select: text;
  padding-inline: 0;
}
.app-git-patch-body .app-diff-ln {
  display: flex;
  padding-inline: var(--space-3);
  color: var(--color-ink);
}
.app-git-patch-body .app-diff-mk {
  flex: none;
  width: 1ch;
}
.app-git-patch-body [data-line="hunk"] .app-diff-mk {
  display: none;
}
.app-git-patch-body [data-line="add"] {
  background: var(--color-diff-add-bg);
}
.app-git-patch-body [data-line="del"] {
  background: var(--color-diff-del-bg);
}
.app-git-patch-body [data-line="add"] .app-diff-mk {
  color: var(--color-success);
}
.app-git-patch-body [data-line="del"] .app-diff-mk {
  color: var(--color-danger-text);
}
.app-git-patch-body [data-line="hunk"] {
  color: var(--color-ink-tertiary);
}
/* 줄바꿈 켬(규칙 32 E, 기본): +/− 열은 첫 화면 줄에만, 이어진 줄은 원래 줄 들여쓰기(--ld-ind)에 맞춘다. */
.app-git-patch-body[data-wrap] {
  white-space: pre-wrap;
}
.app-git-patch-body[data-wrap] .app-diff-tx {
  flex: 1;
  min-width: 0;
  overflow-wrap: anywhere;
  padding-inline-start: var(--ld-ind, 0);
  text-indent: calc(-1 * var(--ld-ind, 0ch));
}
.app-git-short {
  flex: none;
  font: var(--text-code);
  font-size: 12px;
}
.app-git-subject {
  flex: 1;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.app-git-commit-files {
  padding-inline-start: var(--space-3);
}
/* 깃 탭 안 흐린 줄은 행 글자와 같은 시작선(탭 바깥 여백이 이미 있음). */
.app-proj-git .app-proj-line {
  padding-inline: 0;
}
/* 대화 속 경로(§28.6): 내 로컬 세션에 묶인 글에서만 — 흐린 점선 밑줄, 툴팁 프로젝트 패널에서 열기. */
.app-path-link {
  cursor: pointer;
  text-decoration: underline dotted var(--color-ink-tertiary);
  text-underline-offset: 3px;
}
.app-path-link:hover,
.app-path-link:focus-visible {
  text-decoration-color: var(--color-ink-secondary);
}
/* 머리 eye 를 뺀 자리(quicklook·binary) — 이름 줄 폭이 다른 보기와 같게. */
.app-proj-eye-slot {
  flex: none;
  width: var(--size-control);
}
.app-proj-loading {
  display: inline-flex;
  color: var(--color-ink-tertiary);
}

/* 깃 탭 비밀 파일 diff(묶음 21): 파일 보기 비밀 카드와 같은 한 줄 + `내용 보기`. */
.app-git-secret {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: var(--space-2);
  padding-bottom: var(--space-2);
}
.app-group-info-btn .ld-ibtn[aria-pressed="true"] {
  background: var(--color-bg-selected);
}

/* 멈춤 콜아웃(묶음 22 §29.2): 입력칸 바로 위, 카드 꼴 Note. 아이콘(묻기·내 기기)은 머리 줄 오른쪽, 결정 글자 버튼은 아래 줄. */
/* 입력칸(.app-composer)과 같은 왼쪽·오른쪽 끝(디자이너 cap22 🟡②). */
.app-stall {
  padding: var(--space-2) var(--space-5) 0;
}
.app-stall .ld-note > * {
  min-width: 0;
}
/* 결정 버튼 줄(아래) — 받아들이기·다시 받기 왼쪽, 그룹 나가기 오른쪽 끝. */
.app-stall-row {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  margin-top: var(--space-2);
}
/* 지문은 늘 보인다 — §9 기기 줄과 같은 모노 크기 하나(acc-fp, 디자이너 cap22 🟡②). */
.app-stall-fp {
  line-height: 1.2;
}
/* 콜아웃은 판처럼 테두리·안쪽 여백이 있는 Note(디자이너 cap22 🟡① — 기본 Note 는 위아래 줄만). */
.app-stall .ld-note {
  border: 1px solid var(--color-line);
  border-radius: var(--radius-radius);
  padding: var(--space-3);
}
.app-stall-body {
  margin: 0;
}
.app-stall-devices {
  list-style: none;
  margin: var(--space-2) 0 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: var(--space-1);
}
.app-stall-devices li {
  display: flex;
  gap: var(--space-2);
  align-items: baseline;
}
.app-stall-acts {
  display: inline-flex;
  gap: var(--space-2);
  align-items: center;
}
/* 누른 프레임: 버튼 자리에 state-working 회색·돎(폭은 버튼 하나 — 규칙 17). */
.app-stall-busy {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 88px;
  height: 28px;
  color: var(--color-ink-tertiary);
}
/* 다시 받기 실패(규칙 25): state-error 12 + ink-secondary 한 줄. */
.app-stall-failed {
  display: flex;
  gap: var(--space-1);
  align-items: center;
  margin: 0 0 var(--space-1);
  color: var(--color-ink-secondary);
}
.app-stall-failed [data-icon="state-error"] {
  color: var(--color-danger-text);
}
.app-stall-pick {
  display: flex;
  flex-direction: column;
  gap: var(--space-1);
}
.app-stall-pick-row {
  display: flex;
  gap: var(--space-2);
  align-items: center;
}

/* 규칙 밖 그룹 변경(묶음 22 §29.3): 줄 앞 shield-alert 12 warning-text, 줄 끝 되돌리기. */
.app-rule-line {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: var(--space-1);
}
.app-rule-mark {
  display: inline-flex;
  color: var(--color-warn);
}

/* ③ 멈춘 대화 행(묶음 22 — 처리할 것 아님): meta 자리 state-error 12, 빨강은 아이콘만(규칙 21). */
.app-paused-mark .app-meta-icon {
  color: var(--color-danger-text);
}
/* 기기가 모두 바뀜 기록 줄은 툴팁(지문)이 감싼다 — 감싸개를 줄 폭으로 펴 가운데(규칙 28). */
.ld-tip:has(> .app-mls-line) {
  display: flex;
  justify-content: center;
}
/* 묶음 24 §31.4: 앱이 멈춘 카드의 이름 줄 끝 이유 — 나를 기다림이라 accent-text. */
.app-hold-reason {
  color: var(--color-accent-text);
}

/* 런처 처음 묻기 행(묶음 23 §30.1): 프로젝트 목록 바로 아래, 설명 두 줄은 늘 같은 줄 수(끔이면 빈 줄). */
.app-launcher-vis {
  display: flex;
  flex-direction: column;
  gap: var(--space-1);
  padding: var(--space-2) var(--size-gap-inner) 0;
}
.app-launcher-vis-d {
  margin: 0;
  font-size: 12px;
}

/* 동료 쪽 프로젝트 줄(묶음 23 §30.5): 대화 머리 바로 아래, 스크롤 밖, 높이 32 + 아래 1px. 칩은 ghost(작게), 살아 있는 세션 0 이면 흐림. */
.app-peer-projects {
  display: flex;
  align-items: center;
  gap: var(--space-1);
  height: 32px;
  flex: none;
  padding: 0 var(--space-3);
  border-bottom: 1px solid var(--color-line);
  overflow: hidden;
}
.app-peer-proj {
  height: 24px;
  padding: 0 var(--space-2);
  font-size: 12px;
  gap: var(--space-1);
  white-space: nowrap;
}
.app-peer-proj {
  max-width: 160px;
}
.app-peer-proj-t {
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
}
.app-peer-proj-live {
  display: inline-flex;
  align-items: center;
  gap: 3px;
  margin-inline-start: 2px;
  font-variant-numeric: tabular-nums;
  color: var(--color-ink-secondary);
}
/* 켜짐 점 6(§48.6 — 사이드바 에이전트 '켜짐'과 같은 success 점): 숫자가 이름 번호로 읽히지 않게 수 앞에 둔다. */
.app-peer-proj-live::before {
  content: "";
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: var(--color-success);
}
.app-peer-proj[data-empty] {
  color: var(--color-ink-tertiary);
}
.app-peer-pop {
  width: 280px;
  gap: var(--space-1);
  padding: var(--space-2);
}
.app-peer-pop-head {
  font-size: 12px;
  padding: var(--space-1) var(--space-2) 0;
}
.app-peer-pop-row {
  width: 100%;
}

/* 규칙 25(UX점검 3-A): 실패 줄은 한 꼴 — state-error 12(빨강은 아이콘만) + ink-secondary 글자. */
.acc-field-error,
.app-review-file-below-why,
.app-composer-over,
.app-composer-race,
.app-danger,
.set-mine-error,
.set-shortcut-error,
.set-update-failed,
.set-avatar-failed,
.app-recovery-error {
  color: var(--color-ink-secondary);
}
.acc-field-error > [data-icon="state-error"],
.app-review-file-below-why > [data-icon="state-error"],
.app-composer-over > [data-icon="state-error"],
.app-composer-race > [data-icon="state-error"],
.app-danger > [data-icon="state-error"],
.set-mine-error > [data-icon="state-error"],
.set-shortcut-error > [data-icon="state-error"],
.set-update-failed > [data-icon="state-error"],
.set-avatar-failed > [data-icon="state-error"],
.app-recovery-error > [data-icon="state-error"] {
  color: var(--color-danger-text);
  margin-inline-end: var(--space-1);
  vertical-align: -1px;
}

/* 진행 중(규칙 26): 누른 컨트롤 옆 state-working 12, 흐림. 컨트롤 글자는 그대로. */
.app-busy-mark {
  display: inline-flex;
  align-items: center;
  margin-inline-start: var(--space-1);
  color: var(--color-ink-tertiary);
}
/* 행 오른쪽 컨트롤 + 진행 중 표시(규칙 26) — 표시는 컨트롤 왼쪽, 컨트롤 자리는 그대로. */
.app-row-acts {
  display: inline-flex;
  align-items: center;
  gap: var(--space-1);
}

/* `동료에게 보이기` 행(26 관문 🟡 10): 좁은 폭(창 1180 + 프로젝트 패널)에선 값 옆에 이어 열기·설정 버튼이 붙어
   말줄임이면 `받을 수 없어` 가 잘린다 — 값만 줄바꿈해 다 보이게(버튼 자리는 그대로). */
.app-vis-row .ld-set-c > .ld-set-v {
  white-space: normal;
  text-align: end;
}

/* 이 기기를 내 계정에 더한 뒤 메인 창 맨 위 Note(누름 점검 10-27) — 기기 되찾기 Note(#577 A)도 같은 자리. */
.app-added-note {
  padding: var(--space-2) var(--space-5) 0;
}
/* #577 보드 Bundle32: 확인 번호는 본문 뒤 mono 12 흐림, 실패는 본문 아래 한 줄(규칙 25). */
.app-recovery-meta {
  font-family: var(--font-family-mono);
  font-size: 12px;
  color: var(--color-ink-tertiary);
  margin-inline-start: var(--space-1);
}
/* 조각 사이에서만 꺾인다(디자인검수 보드 v306) — '오늘 14:02 추가' 같은 조각 안은 한 줄. */
.app-recovery-piece {
  white-space: nowrap;
}
.app-confirm-body .app-recovery-meta {
  margin-inline-start: 0;
}
.app-recovery-error {
  display: block;
  font-size: 12px;
}
/* 막기 카드(B1): 메인 창 맨 위, 제목·본문·요청 기기 줄·버튼 줄이 세로로. × 없음, 애니메이션 없음. */
.app-recovery-card {
  flex-direction: column;
  align-items: stretch;
  gap: var(--space-2);
  margin: var(--space-2) var(--space-5) 0;
}
.app-recovery-card > .app-recovery-meta {
  margin-inline-start: 0;
}
.app-recovery-body {
  color: var(--color-ink-secondary);
}
.app-recovery-actions {
  display: flex;
  gap: var(--space-2);
}
/* 동료 기기 바꾸기 걸림 줄(D1): shield-alert 12 만 warn. */
.app-peer-recovery > [data-icon] {
  margin-inline-end: var(--space-1);
  vertical-align: -1px;
}
.app-peer-recovery > [data-icon="shield-alert"] {
  color: var(--color-warn);
}
.app-peer-recovery > [data-icon="shield-check"] {
  color: var(--color-success);
}
/* 내 기기 목록의 끊은 옛 기기(A8): 흐린 행. */
.set-mine-gone {
  opacity: 0.55;
}
/* 막은 뒤(B4): 카드 자리에 흐린 한 줄(이번 실행만). */
.app-recovery-line {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: var(--space-2);
  padding: var(--space-2) var(--space-5) 0;
  font-size: 12px;
  color: var(--color-ink-tertiary);
}

/* E4 footer 의 고쳐서 보내기 pencil(UX점검 12): 상태 글자 바로 뒤 한 칸 띄움, 줄 높이 안에서 세로 가운데. */
.app-footer-edit {
  display: inline-flex;
  vertical-align: middle;
  margin-inline-start: var(--space-1);
}

/* 대화 찾기 ⌘F(묶음 13 §21.1): 터미널 막대와 한 꼴 — 대화 칸 오른쪽 위 겹침. 맞은 곳 bg-selected, 지금 것 ink 1px 테두리. */
.app-conv-find {
  position: relative;
  height: 0;
  z-index: 6;
}
.app-conv-find > .app-term-find {
  top: var(--space-2);
  right: var(--space-5);
}
.app-conv-find-cur {
  position: fixed;
  z-index: 5;
  border: 1px solid var(--color-ink);
  border-radius: 2px;
  pointer-events: none;
}
::highlight(lodelai-find) {
  background-color: var(--color-bg-selected);
}
/* 모든 대화에서 찾기 ⌘⇧F(묶음 13 §21.1): 머리 줄 = 찾기 칸 + x, 아래 흐린 범위 한 줄, 결과 행 = 아바타 · 이름 · 시각 / snippet. */
.app-search-headbox {
  position: absolute;
  left: 0;
  right: 0;
  top: 0;
  bottom: 0;
  display: flex;
  align-items: center;
  /* 결과 행 면과 같은 선: 본문 열(560) 안 목록 여백 space-3 만큼 들임. */
  max-width: calc(560px - var(--space-3) * 2);
  margin-inline: auto;
  padding-inline: calc(var(--space-5) + var(--space-3));
  box-sizing: content-box;
  pointer-events: none;
}
.app-search-head {
  flex: 1;
  min-width: 0;
  margin: 0;
  pointer-events: auto;
}
.app-header:has(> .app-search-headbox) {
  position: relative;
}
.app-search {
  display: flex;
  flex-direction: column;
  min-height: 0;
  flex: 1;
}
.app-search-scope {
  padding: var(--space-2) var(--space-5) var(--space-1);
  font-size: var(--font-size-small);
}
.app-search-list {
  flex: 1;
  min-height: 0;
  overflow-y: auto;
  padding: 0 var(--space-3) var(--space-3);
}
.app-search-row {
  display: flex;
  align-items: flex-start;
  gap: var(--space-2);
  width: 100%;
  padding: var(--space-2);
  border: 0;
  border-radius: var(--radius-radius);
  background: none;
  color: var(--color-ink);
  font: inherit;
  text-align: start;
  cursor: pointer;
}
.app-search-row[data-active] {
  background: var(--color-bg-hover);
}
.app-search-main {
  flex: 1;
  min-width: 0;
  display: flex;
  flex-direction: column;
  gap: 2px;
}
.app-search-top {
  display: flex;
  align-items: baseline;
  gap: var(--space-2);
}
.app-search-name {
  font-weight: 600;
}
.app-search-top > time {
  font-size: var(--font-size-small);
}
.app-search-snip {
  color: var(--color-ink-secondary);
  overflow: hidden;
  white-space: nowrap;
  text-overflow: ellipsis;
}
.app-search-snip b {
  color: var(--color-ink);
  font-weight: 600;
}
.app-search-more {
  /* 끝 줄(보이면 다음 50개) — 불러오는 동안 회색 처리 중 아이콘이 돈다. 자리는 늘 같다. */
  display: flex;
  justify-content: center;
  min-height: 32px;
  padding: var(--space-2);
  color: var(--color-ink-tertiary);
}
/* 음소거한 대화의 안 읽은 chat(묶음 13 §21.3): 배지 자리에 흐린 숫자 — 면 없음. */
/* 음소거 표시(§21.3 안 B): 끝 칸 바로 왼쪽 4px bell-off 12 ink-tertiary. 끝 칸 오른쪽 맞춤은 음소거 안 한 행과 같다. */
.app-meta-muted {
  display: inline-flex;
  align-items: center;
  justify-content: flex-end;
  gap: var(--space-1);
}
.app-mute-icon {
  display: inline-flex;
  color: var(--color-ink-tertiary);
}
.app-quiet-count {
  min-width: 18px;
  text-align: center;
  font-size: 12px;
  color: var(--color-ink-tertiary);
  font-variant-numeric: tabular-nums;
}

/* 그룹 안 다른 멤버 요청 줄(§24.4): 화살표 · 마크 · {주인} · {세션}, 한 줄 가운데 맞춤. */
.app-observer {
  display: inline-flex;
  align-items: center;
  gap: var(--space-1);
}
/* 세션 끄는 중(묶음 13 power): 아이콘 자리 그대로 state-working(규칙 26) — IconButton 과 같은 28 상자. */
.app-end-working {
  display: inline-flex;
  width: 28px;
  height: 28px;
  align-items: center;
  justify-content: center;
  color: var(--color-ink-tertiary);
}
/* 설정 행 오른쪽 아이콘 + 토글(§31.9 승인 기다림 — 집중 모드에선 오지 않음일 때 시스템 설정 열기). */
.app-set-pair {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
}

/* `lodelai 에서 이어 열기`(묶음 26 §33.2): 처리 중이면 aria-disabled — disabled 와 같은 흐림이지만 툴팁은 뜬다. */
.app-soft-disabled[aria-disabled="true"] {
  opacity: 0.4;
  cursor: default;
}
/* 행 아래 한 줄(진행 state-working·실패 state-error 12) — 행 안에 넣지 않는다(값이 밀려 자리가 움직임, 규칙 26). */
.app-resume-line[data-busy],
.app-resume-line[data-busy] > .ld-icon {
  color: var(--color-ink-tertiary);
}

/* 업데이트가 필요해요 Note 의 받는 중 표시(§29.9): IconButton 과 같은 자리·크기, 회색 돎. */
.app-note-working {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: var(--size-badge);
  height: var(--size-badge);
  color: var(--color-ink-tertiary);
}

/* 이유(hint)가 붙는 값 메뉴는 360 보다 넓게 — 런처 계정 프로필 `· In use by lodelai Dev` 가 잘렸다(27 g4 🟡). 창 밖으로는 안 나감. */
.ld-menu.ld-float:has(.ld-opt-h) {
  max-width: min(560px, calc(100vw - 2 * var(--space-4)));
}
/* 세션 끄기 버튼 감싸개(#543): 머리 줄 flex 항목이 되면 블록이라 안의 inline-flex 가 기준선 줄 상자에 놓여 위로 1.75px 뜬다. */
.app-end-wrap {
  display: inline-flex;
}
/* GitHub 별 안내(#540 시안 v4): 사이드바 맨 아래, 목록과 같은 흐름(덮어 그리지 않음 — 위 칸이 그만큼 줄어 스크롤). 움직임 없음(규칙 1). */
.app-star-card {
  flex: none;
  margin: var(--space-2);
  padding: var(--space-3);
  background: var(--color-bg);
  border: 1px solid var(--color-line-strong);
  border-radius: var(--radius-radius);
  display: flex;
  flex-direction: column;
  gap: var(--space-1);
}
.app-star-title {
  font-weight: 500;
}
.app-star-body {
  font: var(--text-small);
  color: var(--color-ink-secondary);
}
.app-star-actions {
  margin-top: var(--space-2);
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2);
}

/* #592 줄기 카드(보드 Bundle33 D1~D8 · 마감 88622186b E4·B+A·색 위계). 박스: need 주황 면 · fresh 녹 면 · dim 흐림 · 그 밖 보통.
   색 전환은 들어온 소식으로 바뀔 때만 motion.fast 200 · easing.state(펼침·내 누름은 즉시 — data-open·data-instant), 움직임 줄이기면 즉시. */
.app-stem {
  display: flex;
  flex-direction: column;
  gap: 4px;
  padding: 10px var(--space-3);
  border: 1px solid var(--color-line);
  border-radius: var(--radius-radius);
  font: var(--text-body-chat);
  min-width: 0;
  transition:
    background-color var(--motion-duration-fast) var(--motion-easing-state),
    border-color var(--motion-duration-fast) var(--motion-easing-state);
}
.app-stem[data-open],
.app-stem[data-instant] {
  transition: none;
}
@media (prefers-reduced-motion: reduce) {
  .app-stem {
    transition: none;
  }
}
.app-stem[data-tone="need"] {
  border-color: var(--color-accent);
  background: var(--color-accent-soft);
}
/* 확인 전 새 답(B+A) — success 테두리 + success-soft 면(824b4db4b). */
.app-stem[data-tone="fresh"] {
  border-color: var(--color-success);
  background: var(--color-success-soft);
}
.app-stem[data-tone="dim"] .app-stem-who,
.app-stem[data-tone="dim"] .app-stem-text {
  color: var(--color-ink-secondary);
}
.app-stem-hd {
  display: flex;
  align-items: center;
  gap: 6px;
  min-width: 0;
  font-size: var(--font-size-small);
  color: var(--color-ink-secondary);
  white-space: nowrap;
}
.app-stem-dir {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  min-width: 0;
  overflow: hidden;
}
.app-stem-who {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  min-width: 0;
  color: var(--color-ink);
  font-weight: 600;
  font-size: var(--font-size-body);
  overflow: hidden;
  text-overflow: ellipsis;
}
.app-stem-ar {
  flex: none;
  color: var(--color-ink-secondary);
}
/* 에이전트 주인 표시 D1(루오님 10-30, m1-spec §31.2): 주인 아바타 16 오른쪽 아래(−4, −3)에 마크 10 배지 — 뒷면 = 카드 면색,
   이름과 사이 4+2. 좁으면 두 쪽이 쪽마다 50% 로 같은 비율로 줄고 이름만 말줄임(동료 쪽이 먼저 잘리지 않음). */
.app-stem {
  --app-stem-face: var(--color-bg);
}
.app-stem[data-tone="need"] {
  --app-stem-face: var(--color-accent-soft);
}
.app-stem[data-tone="fresh"] {
  --app-stem-face: var(--color-success-soft);
}
.app-owner-who {
  gap: 6px;
  min-width: 0;
}
/* 쪽 = 툴팁 감싸개(.ld-tip) 또는 사람 이름. 넘칠 때만 두 쪽이 제 길이에 비례해 같은 비율로 준다(flex-shrink — 자리가 남으면
   안 줄음). % max-width 는 내용 폭으로 정해지는 머리 칸 기준이라 자리가 남아도 긴 쪽을 반으로 잘랐다(화면확인 D1 ❌). */
.app-stem-dir > .ld-tip,
.app-stem-dir > .app-stem-who {
  display: inline-flex;
  flex: 0 1 auto;
  min-width: 0;
}
/* 에이전트 쪽은 아바타 16 + 배지 삐짐 4 아래로 줄지 않는다 — 이름만 다 줄고 아바타·배지는 남음(검수 🟡). */
.app-stem-dir > .ld-tip,
.app-blocked > .ld-tip {
  min-width: 20px;
}
.app-stem-dir > .ld-tip > .app-owner-who {
  max-width: 100%;
}
.app-owner {
  position: relative;
  display: inline-flex;
  flex: none;
}
/* 배지 고리(판 v360): 라이트에만 1px line — 다크는 바탕 위 마크 대비가 이미 넉넉하다(agent-tile 과 같은 기준). */
:host {
  --app-owner-ring: var(--color-line);
}
[data-theme="dark"] {
  --app-owner-ring: transparent;
}
@media (prefers-color-scheme: dark) {
  :host:not([data-theme="light"]) {
    --app-owner-ring: transparent;
  }
}
/* 메시지 행 아바타 자리의 D1(회신 검토·보낸 기록 머리 끝, MessageRow avatar): grid 항목이라 늘이면 행 높이만큼 길어져 배지가 카드
   아래 모서리로 떨어졌다(41 마지막 재확인 🟡) — 아바타 크기로 위에 붙인다. */
.app-owner-row {
  align-self: start;
  justify-self: start;
}
.ld-msg[data-side="right"] > .app-owner-row {
  justify-self: end;
}
.app-owner-mk {
  position: absolute;
  right: -4px;
  bottom: -3px;
  display: inline-flex;
  /* 마크 8 + 1 = 10 상자(판 v360 — 16 아바타 이니셜을 덜 덮게). */
  padding: 1px;
  border-radius: 3px;
  box-shadow: 0 0 0 1px var(--app-owner-ring);
  /* 카드 면색 — 녹·주황 박스면 그 면을 bg 위에 덮은 색(옅은 면이 비쳐 아바타가 보이지 않게). 카드 밖(D10 막힘 줄)은 bg. */
  background:
    linear-gradient(var(--app-stem-face, var(--color-bg)), var(--app-stem-face, var(--color-bg))), var(--color-bg);
}
.app-owner-t {
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.app-stem-mk {
  display: inline-flex;
  flex: none;
  padding: 1px;
  border-radius: 4px;
  background: var(--color-agent-tile);
}
.app-stem-sp {
  flex: 1;
}
.app-stem-tm {
  flex: none;
  color: var(--color-ink-secondary);
}
/* 머리가 길면 이름 쪽(.app-stem-dir)만 말줄임 — 시각·연필·› 는 자리 그대로(§E4, › 는 오른쪽 위 끝 고정). */
.app-stem-hd-end {
  display: inline-flex;
  flex: none;
  align-items: center;
  gap: 6px;
}
.app-stem-status {
  display: inline-flex;
  align-items: center;
  gap: 3px;
  font-weight: 600;
}
.app-stem-status[data-tone="ok"] {
  color: var(--color-success);
}
.app-stem-status[data-tone="need"] {
  color: var(--color-accent-text);
}
.app-stem-status[data-tone="fail"] {
  color: var(--color-danger-text);
}
/* 처리 중 아이콘은 녹(규칙 21 — 사이드바 에이전트 처리 중과 같은 색), 머리 글자 색과 따로(§48.4). */
.app-stem-working {
  display: inline-flex;
  color: var(--color-success);
}
.app-stem-status[data-tone="wait"],
.app-stem-status[data-tone="off"],
.app-stem-status[data-tone="done"] {
  color: var(--color-ink-secondary);
  font-weight: 500;
}
/* 상대가 답하는 중(보낸 쪽 consumed) — 3px 점 셋 차례로, 1.2초(메신저 입력 중 꼴). 움직임 줄이기면 멈춘 점. */
.app-stem-dots {
  display: inline-flex;
  align-items: center;
  gap: 2px;
  height: 12px;
  padding: 0 1px;
}
.app-stem-dots > i {
  width: 3px;
  height: 3px;
  border-radius: 50%;
  background: currentColor;
  animation: app-stem-blink 1.2s infinite;
}
.app-stem-dots > i:nth-child(2) {
  animation-delay: 0.2s;
}
.app-stem-dots > i:nth-child(3) {
  animation-delay: 0.4s;
}
@keyframes app-stem-blink {
  0%,
  80%,
  100% {
    opacity: 0.25;
  }
  40% {
    opacity: 1;
  }
}
@media (prefers-reduced-motion: reduce) {
  .app-stem-dots > i {
    animation: none;
    opacity: 0.6;
  }
}
/* 동료 입력 중(묶음 36 §38) — 같은 점 셋. 머리(T2)·사이드바 행 이름 바로 뒤, 늘 flex:none(이름만 줄어든다). 글자 없음, 뜻은 툴팁·aria. */
.app-typing {
  display: inline-flex;
  flex: none;
  align-items: center;
  gap: 4px;
  color: var(--color-ink-secondary);
  font-size: 12px;
  font-weight: 500;
}
.app-typing-stack {
  display: inline-flex;
}
/* 그룹 머리 아바타 14 둘 — 겹침 −4, 바깥 고리 1.5 bg. */
.app-typing-stack > * + * {
  margin-left: -4px;
  border-radius: 50%;
  box-shadow: 0 0 0 1.5px var(--color-bg);
}
.app-typing-title {
  display: flex;
  align-items: center;
  min-width: 0;
}
.app-typing-title > .app-typing {
  margin-left: 6px;
}
.app-typing-name {
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
}
.app-stem-body {
  display: flex;
  flex-direction: column;
  gap: 10px;
  min-width: 0;
}
/* E4 좌우: 질문 쪽 왼쪽 + 왼쪽 선, 답 쪽 오른쪽 + 오른쪽 선 — 선 색 = 그 쪽 사람 색(person-1..6). */
.app-stem-side {
  min-width: 0;
  max-width: 86%;
  --app-lc: var(--color-person-1);
}
.app-stem-side[data-side="left"] {
  align-self: flex-start;
  padding-left: 10px;
  border-left: 2px solid var(--app-lc);
}
.app-stem-side[data-side="right"] {
  align-self: flex-end;
  /* 대화 열 바로 밑(flex 아님)에서도 오른쪽 끝에. */
  margin-left: auto;
}
/* 내 쪽 블록(규칙 37-1a·1b, 디자이너 c1c02259a): 오른쪽 끝에 붙는 내용 폭(최대 86%) — 머리(아바타·이름·시각)는 블록 위 오른쪽 끝,
   본문은 bg-mine 면(내 말풍선과 같은 면·모서리·여백) 안 왼쪽 정렬, 세로선 없음. 면이 테두리를 보여 줘 짧은 답도 한 꼴(b33 ❌ 풀림 —
   옛 86% 고정 폭은 걷음). */
.app-stem-side[data-side="right"],
.app-stem-side[data-side="right"] .app-stem-line {
  display: flex;
  flex-direction: column;
  align-items: flex-end;
}
.app-stem-side[data-side="right"] .app-stem-face {
  box-sizing: border-box;
  max-width: 100%;
  min-width: 0;
  padding: var(--space-2) var(--space-3);
  background: var(--color-bg-mine);
  border-radius: var(--radius-radius);
  overflow-wrap: anywhere;
}
/* 줄기·칩 밑 카드 안 면은 bg-mine-card(반투명 — 투명·accent-soft·success-soft 어느 바탕 위든 대비 1.11~1.15, 디자이너 9119af3c7).
   대화 열 바로 위(칩 아래 답 스레드)는 bg-mine 그대로. */
.app-stem .app-stem-side[data-side="right"] .app-stem-face {
  background: var(--color-bg-mine-card);
}
/* 안 읽은 오른쪽 블록 = 점(아바타 바깥) + 면 오른쪽 끝 accent 2px. */
.app-stem-side[data-side="right"]:has(> .app-item[data-fresh]) .app-stem-face {
  box-shadow: inset -2px 0 0 var(--color-accent);
}
/* 요청 카드가 든 블록은 내용 폭이 정해지지 않아(overflow-wrap:anywhere) 86% 로 — 왼쪽 :has(.ld-card) 와 같은 까닭. */
.app-stem-side[data-side="right"]:has(.ld-card) {
  width: 86%;
}
/* 질문 쪽은 내용 폭(짧은 질문은 짧게)이지만, 요청 카드가 들면 답 쪽과 같은 86% — 본문 overflow-wrap:anywhere 로 min-content 가 0 이라
   폭을 정하지 않은 사슬(stem-side → ld-msg grid → 카드)이 글자 한 자 폭까지 줄던 것(웹개발 제보 10-30, 그룹 '결제 개편'). */
.app-stem-side[data-side="left"]:has(.ld-card) {
  width: 86%;
}
.app-stem-side[data-color="2"] {
  --app-lc: var(--color-person-2);
}
.app-stem-side[data-color="3"] {
  --app-lc: var(--color-person-3);
}
.app-stem-side[data-color="4"] {
  --app-lc: var(--color-person-4);
}
.app-stem-side[data-color="5"] {
  --app-lc: var(--color-person-5);
}
.app-stem-side[data-color="6"] {
  --app-lc: var(--color-person-6);
}
.app-stem-who[data-color="1"] {
  color: var(--color-person-1);
}
.app-stem-who[data-color="2"] {
  color: var(--color-person-2);
}
.app-stem-who[data-color="3"] {
  color: var(--color-person-3);
}
.app-stem-who[data-color="4"] {
  color: var(--color-person-4);
}
.app-stem-who[data-color="5"] {
  color: var(--color-person-5);
}
.app-stem-who[data-color="6"] {
  color: var(--color-person-6);
}
.app-stem-ft {
  font-size: 12px;
}
.app-stem-text {
  display: flex;
  gap: 5px;
  min-width: 0;
  color: var(--color-ink);
}
.app-stem-text[data-dim] {
  color: var(--color-ink-tertiary);
}
.app-stem-clip {
  min-width: 0;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.app-stem-meta {
  flex: none;
  color: var(--color-ink-secondary);
  font-size: var(--font-size-small);
}
.app-stem-between {
  all: unset;
  align-self: center;
  padding: 0 6px;
  font-family: var(--font-family-mono);
  font-size: var(--font-size-small);
  letter-spacing: 1px;
  color: var(--color-ink-secondary);
  cursor: pointer;
  border-radius: var(--radius-sm);
}
.app-stem-between:focus-visible {
  outline: 2px solid var(--color-accent);
}
.app-stem-rs {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  font-size: var(--font-size-small);
  color: var(--color-ink);
}
/* 내가 먼저 답해 보내지 않은 에이전트 답(#602 a3): 답 아래 접힌 한 줄 — 흐린 꼬리, 펼치면 전문. */
/* 내가 답하기 경합 한 줄(#602 a4): 입력 상자 위, state-error — 늘 보임(보내거나 비우면 걷힘). */
/* 받은 사람 말 끝 넘기기 버튼(#602 b1): 글 오른쪽 아래, 자리 고정. */
/* 읽기 폭(--size-read, 37-11)은 받은 글 글자 줄만 — 행 상자·카드는 끝선까지. */
.ld-msg:not(.ld-msg-mine) .ld-msg-body > .app-md,
.ld-msg:not(.ld-msg-mine) .ld-msg-body > .app-msg-text,
.ld-msg:not(.ld-msg-mine) .ld-msg-body > .app-quote,
.ld-msg:not(.ld-msg-mine) .app-fwd-wrap > :first-child {
  max-width: var(--size-read);
}
.app-fwd-wrap {
  display: flex;
  align-items: flex-end;
  /* 글은 읽기 폭에서 줄을 바꾸고 → 는 끝선(37-11). */
  justify-content: space-between;
  gap: var(--space-1);
}
.app-fwd-wrap > :first-child {
  flex: 1;
  min-width: 0;
}
.app-composer-race {
  display: flex;
  align-items: center;
  gap: var(--space-1);
  font-size: 12px;
  padding: 0 var(--space-3) var(--space-1);
}
.app-withheld-hd {
  display: flex;
  align-items: center;
  gap: var(--space-1);
  font-size: var(--font-size-small);
}
.app-withheld-hd > b {
  font-weight: 500;
}
/* 보류 줄은 붙은 답의 쪽을 따른다(규칙 37-6). 오른쪽 블록이면 이름 · 보내지 않음을 오른쪽으로 모으고, 복사·› 는 줄 끝 고정 그대로. */
.app-stem-side[data-side="right"] .app-withheld-hd {
  justify-content: flex-end;
}
.app-stem-side[data-side="right"] .app-withheld-hd > .app-stem-sp {
  display: none;
}
.app-withheld-b {
  white-space: pre-wrap;
  color: var(--color-ink-secondary);
  padding-inline-start: 16px;
}

/* #592 D2 맨 위 줄: 나에게 온 것(accent)·답 기다림. 누른 줄기는 1초 app-item-flash. */
.app-attention {
  display: flex;
  align-items: center;
  gap: var(--space-4);
  padding: 2px var(--space-4);
  border-bottom: 1px solid var(--color-line);
  font-size: var(--font-size-small);
  color: var(--color-ink-secondary);
}
.app-attention-a {
  display: inline-flex;
  align-items: center;
  gap: 4px;
}
.app-attention-a[data-me] {
  color: var(--color-accent-text);
  font-weight: 500;
}

/* #592 D6 펼친 카드에 온 새 답: 그 행 왼쪽 accent 선 + 이름 줄 앞 점(읽으면 사라짐). 화면 밖이면 맨 아래 한 줄. */
.app-stem-body .app-item[data-fresh] {
  border-left: 2px solid var(--color-accent);
  padding-left: var(--space-2);
}
.app-stem-body .app-item[data-fresh] .ld-msg-hd::before {
  content: "";
  flex: none;
  width: 6px;
  height: 6px;
  margin-right: 6px;
  align-self: center;
  border-radius: 3px;
  background: var(--color-accent);
}
.app-fresh-ptr {
  display: flex;
  align-items: center;
  gap: 6px;
  align-self: center;
  margin: var(--space-2) auto;
  padding: 4px 10px;
  border: 1px solid var(--color-line-strong);
  border-radius: var(--radius-radius);
  font: inherit;
  font-size: var(--font-size-small);
  color: var(--color-ink);
  background: var(--color-bg);
  cursor: pointer;
}

/* #592 D10 보내기 전에 막힌 기록 줄: 흐린 한 줄, 끝의 state-error 아이콘만 danger(규칙 25)·이유 툴팁, 버튼 없음. 쪽은 D1 꼴. */
.app-blocked {
  display: flex;
  align-items: center;
  gap: 6px;
  font-size: var(--font-size-small);
  color: var(--color-ink-secondary);
}
.app-blocked-ic {
  display: inline-flex;
  flex: none;
  color: var(--color-danger-text);
}
/* 쪽(D1)은 카드 머리와 같은 꼴 — 이름만 말줄임. */
.app-blocked .app-owner-who {
  font-weight: 500;
  color: var(--color-ink-secondary);
}
/* 시각은 상태(이유 아이콘) 바로 뒤 — 줄 오른쪽 끝으로 떼어 놓지 않는다(규칙 37-2·3). */
.app-blocked-t {
  color: var(--color-ink-tertiary);
}

.app-blocked-w {
  color: var(--color-danger-text);
  font-weight: 600;
}
/* E4 펼침 줄 꼴(#592 33g): 말풍선·작성 줄 없이 `마크 · 이름 · 시각` 한 줄 + 글 — 접힘과 같은 줄·글자. */
.app-stem-line {
  display: flex;
  flex-direction: column;
  gap: 2px;
  min-width: 0;
  font: var(--text-body-chat);
  color: var(--color-ink);
}
.app-stem-nm {
  display: flex;
  align-items: center;
  gap: 6px;
  font-size: 12px;
  color: var(--color-ink-secondary);
}
.app-stem-nm > b {
  color: var(--color-ink);
  font-weight: 600;
  font-size: 13px;
}
/* 쓴 사람 줄 거울(규칙 37-2): 오른쪽 블록은 이름 줄을 뒤집어 오른쪽 끝부터 (점 칸 ·) 아바타 · 이름 · 시각, 본문은 블록 안 왼쪽 정렬
   그대로. 접힌 답 줄·펼친 안쪽 행 모두 .app-stem-nm. DOM(읽는 차례 이름 → 시각)은 그대로 두고 row-reverse 로만. 좁으면 이름만 말줄임. */
.app-stem-side[data-side="right"] .app-stem-nm {
  flex-direction: row-reverse;
}
.app-stem-side[data-side="right"] .app-owner-who {
  flex-direction: row-reverse;
}
.app-stem-nm > b {
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.app-stem-nm-t {
  flex: none;
}
/* 안 읽은 점(D6, 37-5): 그 쪽 끝 아바타 바깥 고정 칸 — 늘 자리를 잡고 새 답일 때만 칠한다(점이 생기고 걷혀도 자리 그대로). */
.app-stem-dot {
  flex: none;
  width: 6px;
  height: 6px;
  border-radius: 3px;
}
/* 오른쪽 블록은 점 칸을 끝선 밖(오른쪽 여백)으로 내민다 — 아바타 끝 = 면 끝 = 끝선(37-11 예외, 디자이너 41 마지막 확인). 점 6 + 간격 6. */
.app-stem-side[data-side="right"] .app-stem-nm:has(> .app-stem-dot) {
  margin-inline-end: -12px;
}
.app-item[data-fresh] .app-stem-dot {
  background: var(--color-accent);
}
/* 새 답 accent 는 그 쪽 선 자리(답 쪽은 오른쪽)를 덮는다 — 안쪽 행 왼쪽에 따로 긋지 않는다. */
.app-stem-side:has(> .app-item[data-fresh]) {
  --app-lc: var(--color-accent);
}
.app-stem-side > .app-item[data-fresh] {
  border-left: 0;
  padding-left: 0;
}
/* E4 펼침(#592): 안쪽 행은 좌우 줄 안에서 본문 글자 body-chat, 첫 질문은 이름 줄·아바타 없이(접힘과 같은 윗부분). */
.app-stem-body > .app-stem-side > .app-item .app-msg-text {
  font: var(--text-body-chat);
}
.app-stem-side[data-first] > .app-item .ld-msg > .ld-avatar,
.app-stem-side[data-first] > .app-item .ld-msg-hd {
  display: none;
}
/* 도착 빛남(#592): 0.5s 고리(box-shadow) → 1s 가라앉음, 한 번. 녹(fresh)·주황(need)에 맞춘 색. 움직임 줄이기면 없음(색만). */
.app-stem[data-glow] {
  --app-glow: var(--color-success);
  animation: app-stem-glow 1.5s var(--motion-easing-state) 1;
}
.app-stem[data-glow][data-tone="need"] {
  --app-glow: var(--color-accent);
}
@keyframes app-stem-glow {
  0% {
    box-shadow: 0 0 0 3px color-mix(in srgb, var(--app-glow) 35%, transparent);
  }
  33% {
    box-shadow: 0 0 0 2px color-mix(in srgb, var(--app-glow) 18%, transparent);
  }
  100% {
    box-shadow: 0 0 0 0 transparent;
  }
}
@media (prefers-reduced-motion: reduce) {
  .app-stem[data-glow] {
    animation: none;
  }
}
/* 사람이 누른 펼침에 새로 보이는 글은 같은 200ms 에 opacity 0 → 1(StemCard 가 data-moving 을 그 동안만). */
.app-stem[data-moving="open"] > .app-stem-body > :not(:first-child) {
  animation: app-stem-fade var(--motion-duration-fast) var(--motion-easing-state);
}
@keyframes app-stem-fade {
  from {
    opacity: 0;
  }
  to {
    opacity: 1;
  }
}

/* #592 사이드바: 확인 전 새 답(녹 카드)이 남은 사람 행은 끝 시각만 굵게(배지 수는 그대로). */
.app-row-time-new {
  color: var(--color-ink);
  font-weight: 600;
}

/* 넣기 기다림(#619 ③) 카드 아래 버튼 줄 — 에이전트 열기(primary) · 지금 넣기(secondary). 전환 애니메이션 없음(고빈도 카드). */
.app-stem-foot {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  margin-top: var(--space-1);
}

/* #614 보이는 폴더 안에서 공개되지 못한 에이전트 줄(묶음 36, m1-spec §30.3 끝): 줄 끝 상태 아이콘 바로 앞 같은 자리. 행이 버튼이라
   안에 버튼을 둘 수 없어, 행 meta 에는 같은 폭 빈칸(.app-hidden-slot)만 두고 표시는 행 감싸개 위에 겹쳐 그린다. */
.app-srow-hidden {
  position: relative;
}
.app-hidden-slot {
  display: inline-block;
  flex: none;
  width: 20px;
}
.app-hidden-mark {
  position: absolute;
  top: 50%;
  /* 행 오른쪽 안쪽 여백 + 상태 아이콘 상자(16) 바로 앞. */
  right: calc(var(--size-gap-inner) + 16px);
  transform: translateY(-50%);
  display: inline-flex;
}
.app-hidden-ic {
  all: unset;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  /* 누름 자리 최소 20(명세). */
  width: 20px;
  height: 20px;
  border-radius: var(--radius-sm);
  color: var(--color-ink-tertiary);
  cursor: default;
}
button.app-hidden-ic:hover {
  background: var(--color-bg-hover);
}
.app-hidden-ic:focus-visible {
  outline: 2px solid var(--color-accent);
  outline-offset: -2px;
}
.app-hidden-mark[data-tone="secondary"] .app-hidden-ic {
  color: var(--color-ink-secondary);
}
.app-hidden-mark[data-tone="danger"] .app-hidden-ic {
  color: var(--color-danger-text);
}
/* 2단 줄(묶음 39 §41.4)엔 오른쪽 meta 칸이 없다 — 빈칸을 두면 위 줄 시각이 밀리고, 줄 가운데에 겹치면 시각·미리보기를 가린다(42 재검
   탐침: 시각 209~258 위에 표시 252~272). 표시는 아래 줄(미리보기) 끝, 미리보기는 그만큼 비운다. */
.ld-rowitem:has(.app-row2) .app-hidden-slot {
  display: none;
}
.app-srow-hidden:has(.app-row2) .app-row2-pv {
  padding-inline-end: 22px;
}
.app-srow-hidden:has(.app-row2) > .app-hidden-mark {
  /* 표시 상자 20(#614 eye-off·clock 버튼과 실패 표시 같은 칸, 아이콘 12 가운데): 아이콘 오른쪽 끝 = 위 줄 시각 끝, 세로 = 아래 줄
     가운데(탐침 1180 창, 디자이너 자리 확인). */
  top: auto;
  bottom: 8px;
  transform: none;
  right: 16px;
}
/* 줄 아래 팝오버 — 폭 250, 애니메이션 없음(규칙 1). */
.app-hidden-pop {
  width: 250px;
  box-sizing: border-box;
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
  padding: var(--space-3);
  /* 확인 팝오버(.app-confirm)와 같은 면. */
  border: 1px solid var(--color-line-strong);
  border-radius: var(--radius-radius);
  background: var(--color-bg);
}
.app-hidden-pop-title,
.app-hidden-pop-err {
  display: flex;
  align-items: center;
  gap: 6px;
  font-size: var(--font-size-small);
  color: var(--color-ink-secondary);
}
.app-hidden-pop-err > .ld-icon {
  color: var(--color-danger-text);
}
.app-hidden-pop-cmd {
  display: flex;
  align-items: center;
  gap: 6px;
}
.app-hidden-pop-cmd > code {
  flex: 1;
  font: var(--text-meta);
  color: var(--color-ink);
}
/* 확인 방식 바꾸기 실패(묶음 38 §40.4): 값 칸 뒤 state-error 12 + 짧은 글(ink-secondary, 규칙 25). */
.app-mode-failed {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  font-size: 12px;
  color: var(--color-ink-secondary);
}
.app-mode-failed > .ld-icon {
  color: var(--color-danger-text);
}
/* 확인 방식 예약 clock·바꾸는 중 state-working(§40.4): 값 칸 뒤 아이콘 하나, 툴팁으로 읽는다. */
.app-mode-mark {
  display: inline-flex;
  align-items: center;
  color: var(--color-ink-secondary);
}
/* 목록 줄 2단(묶음 39 §41.4): 줄 높이 52 고정 · 아바타 28 · 위 이름 13 · 시각 11 · 아래 미리보기 12(한 줄 말줄임). */
.ld-rowitem:has(.app-row2) {
  height: 52px;
  gap: 10px;
}
.app-row2 {
  display: flex;
  flex-direction: column;
  gap: 1px;
  min-width: 0;
}
.app-row2-l1,
.app-row2-l2 {
  display: flex;
  align-items: center;
  gap: 6px;
  min-width: 0;
}
.app-row2-nm {
  flex: 1;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  font-size: 13px;
}
.app-row2[data-un] .app-row2-nm {
  font-weight: 700;
}
.app-row2-tm,
.app-row2-l1 .app-row-time-new {
  flex: none;
  font-size: 11px;
  color: var(--color-ink-tertiary);
  font-variant-numeric: tabular-nums;
}
.app-row2-l1 .app-row-time-new {
  color: var(--color-ink);
}
.app-row2-pv {
  flex: 1;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  font-size: 12px;
  color: var(--color-ink-secondary);
}
.app-row2[data-un] .app-row2-pv {
  color: var(--color-ink);
}
.app-row2-pv[data-dim] {
  color: var(--color-ink-tertiary);
}
.app-row2-draft {
  display: inline-flex;
  flex: none;
  align-items: center;
  gap: 3px;
  font-size: 12px;
  color: var(--color-accent-text);
}
.app-row2-l2 > .ld-tip,
.app-row2-l2 > .ld-badge,
.app-row2-l2 > .app-paused-mark,
.app-row2-l2 > .app-quiet-count {
  flex: none;
}
.app-row2-acc {
  color: var(--color-accent-text);
}
.app-row2-l2 > .ld-state {
  flex: none;
}
/* 입력칸 서식(묶음 39 §41.9) — 원문 그대로 + 뒤 거울 층이 꼴을 그림. 입력칸 글자는 투명(커서·고름은 입력칸 것).
   글자 폭이 바뀌는 꼴은 쓰지 않는다(커서가 어긋남): 굵게 = 획 덧칠, 기울임 = 기울인 꼴(글꼴이 만든 것), 코드 = 면. */
.app-md {
  position: relative;
  flex: 1;
  min-width: 0;
}
.app-md > textarea {
  position: relative;
  color: transparent;
  caret-color: var(--color-ink);
}
.app-md > textarea::placeholder {
  color: var(--color-ink-tertiary);
}
.app-md > textarea::selection {
  color: transparent;
  background: color-mix(in srgb, var(--color-accent) 30%, transparent);
}
.app-md-mirror {
  position: absolute;
  inset: 0;
  overflow: hidden;
  white-space: pre-wrap;
  overflow-wrap: break-word;
  word-break: normal;
  pointer-events: none;
  color: var(--color-ink);
}
.app-composer-mark + .app-md > .app-md-mirror {
  padding-left: var(--space-2);
}
.app-md-mirror [data-md="mk"] {
  color: var(--color-ink-tertiary);
}
.app-md-mirror [data-md="b"] {
  -webkit-text-stroke: 0.04em currentColor;
}
.app-md-mirror [data-md="i"] {
  font-style: oblique 10deg;
}
.app-md-mirror [data-md="s"] {
  text-decoration: line-through;
}
.app-md-mirror [data-md="code"],
.app-md-mirror [data-md="block"] {
  background: var(--color-bg-hover);
  border-radius: 3px;
}
.app-md-mirror [data-md="link"] {
  color: var(--color-accent-text);
  text-decoration: underline;
}
.app-md-mirror [data-md="quote"] {
  color: var(--color-ink-secondary);
}
/* 고른 @이름(§41.10) — bg-selected 면. 글자 폭을 바꾸지 않게 padding 대신 바깥 그림자로 넓힌다(입력칸 글자와 겹침). */
.app-md-mirror [data-mention] {
  background: var(--color-bg-selected);
  border-radius: 3px;
  box-shadow: 0 0 0 2px var(--color-bg-selected);
}
.app-fmt-bar {
  display: flex;
  align-items: center;
  gap: 2px;
  padding: 4px 6px 0;
}
/* 입력칸 코드 상자(§52.4, 디자이너 cbdb81e5c): 여는 줄~닫는 줄 한 덩이에 bg-card 면·1px line·radius 6. 글꼴·글자 자리는 입력칸 그대로
   (커서는 textarea 것) — 선은 그림자로, 면은 좌우로만 바깥 여백을 당겨 넓힌다(글자는 안 움직임). 펜스 두 줄은 흐린 글자(mk). */
.app-md-mirror [data-md="box"] {
  display: block;
  margin-inline: -6px;
  padding-inline: 6px;
  border-radius: 6px;
  background: var(--color-bg-card);
  box-shadow: inset 0 0 0 1px var(--color-line);
}
.app-md-mirror [data-md="box"] [data-md="block"] {
  background: none;
}
/* 상자 머리 오른쪽 위 언어 단추(받은 상자는 왼쪽 — 입력칸은 왼쪽 위에 흐린 여는 펜스 줄이 있다). */
.app-composer-box-lang {
  position: absolute;
  right: var(--space-3);
  z-index: 1;
}
/* / 명령(묶음 39 §41.11): 입력칸 위 목록(폭 340, 넘치면 안에서 스크롤, 애니메이션 없음) · 명령 칩(22 · 모서리 6 · bg-selected). */
.app-composer {
  position: relative;
}
.app-slash {
  position: absolute;
  left: var(--space-5);
  bottom: calc(100% - var(--space-2));
  z-index: 20;
  width: 340px;
  max-height: 320px;
  overflow-y: auto;
  box-sizing: border-box;
  padding: 4px;
  border: 1px solid var(--color-line-strong);
  border-radius: var(--radius-radius);
  background: var(--color-bg);
  box-shadow: 0 6px 24px rgba(0, 0, 0, 0.25);
}
.app-slash-head {
  padding: 6px 8px 2px;
  font-size: 11px;
  color: var(--color-ink-tertiary);
}
.app-slash-row {
  display: flex;
  align-items: center;
  gap: 8px;
  width: 100%;
  height: 32px;
  padding: 0 8px;
  border: 0;
  border-radius: var(--radius-sm);
  background: transparent;
  color: var(--color-ink);
  font: inherit;
  font-size: 13px;
  text-align: start;
}
.app-slash-row[data-sel] {
  background: var(--color-bg-selected);
}
.app-slash-row[data-dim] {
  opacity: 0.4;
}
.app-slash-name {
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.app-slash-name > b {
  font-weight: 700;
}
.app-slash-hint {
  flex: none;
  font-size: 12px;
  color: var(--color-ink-tertiary);
}
.app-slash-chip-at {
  display: inline-flex;
  flex: none;
  padding: calc(var(--size-gap-inner) - 1px) 0 0 var(--space-3);
}
.app-slash-chip {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  height: 22px;
  padding: 0 8px;
  border-radius: 6px;
  background: var(--color-bg-selected);
  color: var(--color-ink-secondary);
  font-size: 12px;
  white-space: nowrap;
}
.app-slash-chip > b {
  color: var(--color-ink);
  font-weight: 600;
}
.app-slash-chip-peek {
  max-width: 180px;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  color: var(--color-ink-tertiary);
}
.app-slash-chip[data-error] > .ld-icon {
  color: var(--color-danger-text);
}
.app-slash-chip-at + .app-md > textarea,
.app-slash-chip-at + .app-md > .app-md-mirror {
  padding-left: var(--space-2);
}
.app-slash > .ld-tip {
  display: flex;
}
/* @ 목록(§41.10) — / 목록과 같은 꼴, 폭 300 · 사람 → 가는 줄 → 에이전트(마크 16 · 흐린 주인 이름). */
.app-mention {
  width: 300px;
}
.app-mention-name {
  display: inline-flex;
  min-width: 0;
}
.app-mention-no {
  flex: none;
  white-space: pre;
}
.app-mention-sep {
  height: 1px;
  margin: 4px 6px;
  background: var(--color-line);
}
/* 받는 쪽 @조각(§41.10, 루오님 10-31): 입력칸 조각과 같은 면 — 남을 부름(내 글 포함) bg-selected + ink 500(굵게 서식 600 과 다르게),
   나를 부름만 accent-soft + accent-text. 줄바꿈되면 면도 나뉜다. */
.app-mention-tok {
  padding: 0 2px;
  border-radius: 4px;
  background: var(--color-bg-selected);
  color: var(--color-ink);
  font-weight: 500;
  -webkit-box-decoration-break: clone;
  box-decoration-break: clone;
}
.app-mention-tok[data-me] {
  background: var(--color-accent-soft);
  color: var(--color-accent-text);
}
.app-mention-mark {
  display: inline-flex;
  flex: none;
  color: var(--color-agent-claude);
}
/* 레일 64(묶음 39 §41.1): 맨 위 44 는 신호등 줄(사이드바·본문 머리와 한 가로줄 — 아래 선), 그 아래 조직 타일 32 · 가는 줄 ·
   대메뉴 40 둘. 고른 메뉴 bg-selected, 호버 bg-hover — 그 프레임에, 전환 없음. 사이드바를 접어도 이 칸은 그대로. */
.app-rail {
  flex: none;
  width: 64px;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 6px;
  position: relative;
  background: var(--color-bg-side-list);
}
/* 레일|사이드바 세로선은 제목줄 띠(44 + 아래 선) 아래부터(§41.2) — 띠는 창 폭 한 줄이라 선이 없다. 레일 64 가 신호등 폭보다 좁아
   맨 위부터 그으면 초록 버튼을 가로질렀다(41 관문 뒤 루오님). 사이드바 ::after 와 같은 꼴. */
.app-rail::after {
  content: "";
  position: absolute;
  top: 45px;
  bottom: 0;
  inset-inline-end: 0;
  width: 1px;
  background: var(--color-line);
  pointer-events: none;
}
.app-rail > .app-titlebar {
  align-self: stretch;
  border-bottom: 1px solid var(--color-line);
}
.app-rail-org {
  height: 36px;
  padding-top: 6px;
  display: flex;
  align-items: flex-start;
}
.app-rail-tile {
  position: relative;
  display: inline-flex;
  padding: 0;
  border: 0;
  background: none;
  color: inherit;
  cursor: pointer;
  outline: none;
  isolation: isolate;
}
/* 조직 타일 누름 면(§44.9): 자리를 차지하지 않는 둘레 2 — 36×36, 모서리 10(타일 8 과 동심). 호버 = 틀 위 겹 5%, 누름 10%(레일 안
   bg-hover·bg-selected 는 그 겹, §44.7). 포커스 링은 그대로. */
.app-rail-tile::before {
  content: "";
  position: absolute;
  inset: -2px;
  z-index: -1;
  border-radius: 10px;
  pointer-events: none;
}
.app-rail-tile:hover::before {
  background: var(--color-bg-hover);
}
.app-rail-tile:active::before {
  background: var(--color-bg-selected);
}
.app-rail-tile:focus-visible {
  box-shadow: 0 0 0 2px var(--color-accent);
  border-radius: 8px;
}
/* 조직 마크(§41.1): 오른쪽 아래 building — 면은 바탕색 테두리 1.5, 글리프 ink(사람 아바타의 접속 점 자리, 조직엔 접속 상태가 없음). */
.app-rail-tile-mark {
  position: absolute;
  right: -3px;
  bottom: -3px;
  width: 14px;
  height: 14px;
  box-sizing: border-box;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  border-radius: 4px;
  background: var(--color-bg);
  border: 1.5px solid var(--color-bg-side-list);
  color: var(--color-ink);
}
.app-rail-sep {
  width: 28px;
  height: 1px;
  margin: 2px 0 4px;
  background: var(--color-line);
}
.app-rail-btn {
  position: relative;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 40px;
  height: 40px;
  padding: 0;
  border: 0;
  border-radius: var(--radius-sm);
  background: transparent;
  color: var(--color-ink-secondary);
  cursor: pointer;
}
.app-rail-btn:hover {
  background: var(--color-bg-hover);
}
.app-rail-btn[data-on] {
  background: var(--color-bg-selected);
  color: var(--color-ink);
}
.app-rail-btn:focus-visible {
  outline: 2px solid var(--color-accent);
  outline-offset: -2px;
}
/* 레일 배지: 대화 = 행 배지의 합(무채), 내 에이전트 = 승인 기다림(accent). */
.app-rail-n {
  position: absolute;
  top: 1px;
  right: 1px;
  min-width: 16px;
  height: 16px;
  padding: 0 4px;
  box-sizing: border-box;
  border-radius: 8px;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 10px;
  font-weight: 700;
  background: var(--color-ink-secondary);
  color: var(--color-bg);
}
.app-rail-n[data-tone="accent"] {
  background: var(--color-accent);
  color: #fff;
}
/* 상단바 오른쪽 끝 내 프로필(§41.1): 아바타 24 + 접속 점, 끌기 자리 안의 누름 자리. 열린 동안 bg-selected. */
.app-profile {
  display: inline-flex;
  -webkit-app-region: no-drag;
}
.app-profile-btn {
  position: relative;
  display: inline-flex;
  padding: 2px;
  border: 0;
  border-radius: 8px;
  background: transparent;
  cursor: pointer;
}
.app-profile-btn:hover {
  background: var(--color-bg-hover);
}
.app-profile-btn[data-open] {
  background: var(--color-bg-selected);
}
.app-profile-btn:focus-visible {
  outline: 2px solid var(--color-accent);
  outline-offset: 0;
}
/* 새 기기 배지(#339, Shell 빈자리 판정): 아바타 오른쪽 위. */
.app-profile-n {
  position: absolute;
  top: -4px;
  right: -6px;
  display: inline-flex;
  pointer-events: none;
}
.app-pmenu {
  width: 260px;
  max-width: none;
}
.app-pmenu-head {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: var(--space-2) var(--space-2) 10px;
}
.app-pmenu-who {
  display: flex;
  flex-direction: column;
  min-width: 0;
}
.app-pmenu-name {
  font-weight: 700;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.app-pmenu-id {
  font-size: 11px;
  color: var(--color-ink-secondary);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
button.app-pmenu-i {
  width: 100%;
  border: 0;
  background: transparent;
  text-align: start;
}
button.app-pmenu-i:focus-visible {
  outline: none;
  background: var(--color-bg-hover);
}
.app-pmenu-ic {
  display: inline-flex;
  width: 16px;
  justify-content: center;
  color: var(--color-ink-secondary);
}
.app-pmenu-l {
  flex: 1;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
}
.app-pmenu-end {
  display: inline-flex;
  color: var(--color-ink);
}
.app-pmenu-kbd {
  font-family: var(--font-family-mono);
  font-size: 11px;
  color: var(--color-ink-secondary);
}
.app-pmenu-h {
  padding-inline-start: var(--space-2);
}
/* 글래스(묶음 39 §41.3 → 묶음 43 §43, 메인 창만 — main.tsx 가 html[data-glass]): 창 바탕은 macOS 사이드바 재질(NSVisualEffectView,
   tauri.conf windowEffects). 바깥 틀(레일·사이드바·머리 줄·하단 상태창·오른쪽 패널)은 선 없는 **한 장** — body 한 곳에 bg-side
   60%(--glass-mix) 한 겹, 조각들은 투명(조각마다 깔면 겹쳐 60% 가 아니다). 안쪽 칸(대화·작업·가운데 좁은 열)은 불투명 bg · 모서리 10 —
   칸을 품은 열(.app-main · 나란히 두 열)의 ::before 한 장이 그리고, 틀과 오른쪽·아래·나란히 사이 간격은 pane-gap 8(§43.2). 위는 머리
   줄(44) 바로 아래, 왼쪽은 사이드바에 붙음. 비치는 면 위 글자 바닥은 ink-secondary(ink-tertiary 안 씀 — 면 위 4.5:1). */
/* color-mix 가 없는 웹뷰(아주 이른 macOS 13)는 글래스 전체를 걸지 않는다 — 토큰이 무효가 되면 면이 투명해져 글이 안 보이는
   조용한 실패가 된다(총괄 10-30). 그때 body 가 지금처럼 불투명이라 창 재질은 가려진다. */
@supports (color: color-mix(in srgb, red, blue)) {
  :host {
    /* 틀 면 불투명도(§43.1): 라이트·어두운 바탕에서 사이드바 ink-secondary 4.58(56% 는 4.39 미달). */
    --glass-mix: 60%;
    --glass-bg: color-mix(in srgb, var(--color-bg) var(--glass-mix), transparent);
    --glass-side: color-mix(in srgb, var(--color-bg-side) var(--glass-mix), transparent);
    --glass-side-list: color-mix(in srgb, var(--color-bg-side-list) var(--glass-mix), transparent);
    /* 틀 위 선택·호버 면은 틀을 따라 비치는 겹(§44.7) — 불투명 bg-selected 는 밝은 바탕 자리에서 틀과 1.01~1.03 으로 사라졌다. 하한
       선택 ↔ 틀 1.2. 세 단·비활성·투명도 줄이기 모두 같은 겹. */
    --glass-sel: rgb(0 0 0 / 10%);
    --glass-hov: rgb(0 0 0 / 5%);
    /* 투명 단(§44.3): 라이트 재질은 바탕을 흰 55% 로 덮어 덜 비쳐 15%(다크 25% 와 같은 만큼), 틀 위 보조 글자·색 글자는 한 값으로 덮고
       창 틀 안쪽에 정지한 가장자리 빛. */
    --glass-clear-mix: 15%;
    --glass-clear-ink: #2e2e2e;
    --glass-clear-edge:
      inset 0 1px 0 rgb(255 255 255 / 95%), inset 0 0 0 1px rgb(0 0 0 / 8%), inset 0 -1px 2px rgb(0 0 0 / 8%);
  }
  [data-theme="dark"] {
    --glass-sel: rgb(255 255 255 / 10%);
    --glass-hov: rgb(255 255 255 / 5%);
    --glass-clear-mix: 25%;
    --glass-clear-ink: #c8c8c8;
    --glass-clear-edge:
      inset 0 1px 0 rgb(255 255 255 / 45%), inset 0 0 0 1px rgb(255 255 255 / 18%), inset 0 -1px 2px rgb(0 0 0 / 30%);
  }
  @media (prefers-color-scheme: dark) {
    :host:not([data-theme="light"]) {
      --glass-sel: rgb(255 255 255 / 10%);
      --glass-hov: rgb(255 255 255 / 5%);
      --glass-clear-mix: 25%;
      --glass-clear-ink: #c8c8c8;
      --glass-clear-edge:
        inset 0 1px 0 rgb(255 255 255 / 45%), inset 0 0 0 1px rgb(255 255 255 / 18%), inset 0 -1px 2px rgb(0 0 0 / 30%);
    }
  }
  [data-glass] body {
    background: var(--glass-side);
  }
  /* 불투명 판(§43.6) — 비활성 창(main.tsx 가 html[data-inactive])과 macOS '투명도 줄이기'(WebKit 은 prefers-reduced-transparency 를
     주지 않아 플랫폼 신호 → html[data-opaque], 43 탐침). 틀 =
     bg-frame(칸 bg 와 1.13·1.15), 칸 = bg. 배치·모서리·간격 그대로, 그 프레임에 바뀜(전환 없음). 창 투명도 불투명 단(§44.1)도 같은
     판. 단 규칙은 모두 :not([data-opaque], [data-inactive]) 로 걸어 이 판이 파일 순서와 상관없이 이긴다(§44.3 선택자 고정). */
  [data-glass][data-inactive],
  [data-glass][data-opaque],
  [data-glass][data-glass-level="solid"]:not([data-opaque], [data-inactive]) {
    --glass-bg: var(--color-bg-frame);
    --glass-side: var(--color-bg-frame);
    --glass-side-list: var(--color-bg-frame);
  }
  /* 투명 단(§44.3) — 대비 높이기(prefers-contrast: more, WKWebView 가 줌 — 44 탐침)면 기본 단으로 그린다(§44.4). */
  @media not all and (prefers-contrast: more) {
    [data-glass][data-glass-level="clear"]:not([data-opaque], [data-inactive]) {
      --glass-mix: var(--glass-clear-mix);
    }
    /* 틀 위 보조 글자·레일과 상태창 아이콘을 한 값으로(렌더 최저 다크 4.76 · 라이트 4.84) — 칸 안 글자는 그대로. 상태창 색 글자·
       색 아이콘(경고 수·주의·연결 점·기다림 수)도 이 값, 뜻은 모양이 맡는다(규칙 21). */
    [data-glass][data-glass-level="clear"]:not([data-opaque], [data-inactive])
      :is(.app-rail, .app-sidebar, .app-statusbar, .app-header, .app-proj) {
      --color-ink-secondary: var(--glass-clear-ink);
      --color-ink-tertiary: var(--glass-clear-ink);
    }
    [data-glass][data-glass-level="clear"]:not([data-opaque], [data-inactive]) .app-statusbar {
      --color-danger-text: var(--glass-clear-ink);
      --color-warn: var(--glass-clear-ink);
      --color-success: var(--glass-clear-ink);
      --color-accent: var(--glass-clear-ink);
    }
    /* 가장자리 빛: 창 틀 안쪽에만(칸 bg 에는 없음), 정지 — 포인터·창 이동을 따르지 않는다. */
    [data-glass][data-glass-level="clear"]:not([data-opaque], [data-inactive]) .app-with-bar {
      box-shadow: var(--glass-clear-edge);
    }
  }
  [data-glass] #root > :not(.app-with-bar) {
    background: var(--color-bg);
  }
  [data-glass] .app-rail,
  [data-glass] .app-sidebar,
  [data-glass] .app-statusbar,
  [data-glass] .app-proj,
  [data-glass] .app-header {
    --color-bg: var(--glass-bg);
    --color-bg-side: var(--glass-side);
    --color-bg-side-list: var(--glass-side-list);
    --color-ink-tertiary: var(--color-ink-secondary);
  }
  /* 레일·사이드바의 선택·호버 면 = 틀 위 겹(§44.7) — 목록 고른 줄·레일 눌린 버튼·호버. 칸 안 선택 면은 그대로. */
  [data-glass] .app-rail,
  [data-glass] .app-sidebar {
    --color-bg-selected: var(--glass-sel);
    --color-bg-side-hover: var(--glass-hov);
    --color-bg-hover: var(--glass-hov);
  }
  /* 틀 조각은 제 면을 깔지 않는다(body 한 겹) — 사이드바 안 머리·찾기·목록·신호등 줄도 비운다. 폴더 머리(.app-project-sticky)는
     붙어서 목록 위에 뜰 때만 한 겹(밑 행을 가려야 해서). */
  [data-glass] .app-rail,
  [data-glass] .app-sidebar,
  [data-glass] .app-statusbar,
  [data-glass] .app-proj,
  [data-glass] .app-header,
  [data-glass] .app-sidebar > .app-titlebar,
  [data-glass] .app-side-pane > .ld-eyebrow,
  [data-glass] .app-side-search,
  [data-glass] .app-side-scroll,
  [data-glass] .app-project-sticky {
    background: transparent;
  }
  [data-glass] .app-project-sticky[data-stuck] {
    background: var(--glass-side-list);
  }
  /* 붙은 머리 아래로 지나가는 줄 글자가 비치지 않게(#665, 디자이너 10-31 §44.3): 투명·기본 단은 면 없이(transparent) 흐림 20 하나 —
     면을 한 겹 더 깔면 글래스 위 두 겹 알파라 틀보다 어두운 띠가 된다(46 관문 ❌, 다크 기본 26 ↔ 틀 42). backdrop-filter 는 창 뒤
     바탕화면이 아니라 아래 웹 줄만 흐린다(blur 20 → 글자 무늬 5%). 불투명 단·비활성·투명도 줄이기는 bg-frame 불투명, 흐림 없음. */
  @supports ((backdrop-filter: blur(1px)) or (-webkit-backdrop-filter: blur(1px))) {
    [data-glass]:not([data-opaque], [data-inactive]):not([data-glass-level="solid"]) .app-project-sticky[data-stuck] {
      background: transparent;
      -webkit-backdrop-filter: blur(20px);
      backdrop-filter: blur(20px);
    }
  }
  /* 틀 위 스크롤 페이드(§44.3, #665 후속): 글래스 단에선 덮는 그러데이션 면 대신 내용 마스크 — 면은 body 글래스 위 한 겹 더라
     어두운 띠가 된다. 마스크는 내용 겹(ScrollArea mask → .ld-scroll-y)에만 — 오버레이 스크롤바는 마스크 밖. 보이는 창(--ld-st·
     --ld-vh) 안 잘린 쪽 24px 만 투명 → 불투명. 켜고 끄는 조건은 그대로(data-fade-top·bottom, 붙은·곧 붙을 머리가 있으면 위 없음 —
     머리를 지우지 않게). 불투명 단·비활성·투명도 줄이기와 칸 안은 면 그러데이션 그대로. */
  [data-glass]:not([data-opaque], [data-inactive]):not([data-glass-level="solid"])
    :is(.app-rail, .app-sidebar, .app-statusbar, .app-proj, .app-header)
    .ld-scroll {
    --ld-mt: 0px;
    --ld-mb: 0px;
  }
  [data-glass]:not([data-opaque], [data-inactive]):not([data-glass-level="solid"])
    :is(.app-rail, .app-sidebar, .app-statusbar, .app-proj, .app-header)
    .ld-scroll[data-fade-top]:not(:has([data-stuck], [data-stuck-near])) {
    --ld-mt: 24px;
  }
  [data-glass]:not([data-opaque], [data-inactive]):not([data-glass-level="solid"])
    :is(.app-rail, .app-sidebar, .app-statusbar, .app-proj, .app-header)
    .ld-scroll[data-fade-bottom] {
    --ld-mb: 24px;
  }
  [data-glass]:not([data-opaque], [data-inactive]):not([data-glass-level="solid"])
    :is(.app-rail, .app-sidebar, .app-statusbar, .app-proj, .app-header)
    .ld-scroll
    > .ld-scroll-y {
    --ld-vmask: linear-gradient(
      to bottom,
      transparent var(--ld-st, 0px),
      #000 calc(var(--ld-st, 0px) + var(--ld-mt)),
      #000 calc(var(--ld-st, 0px) + var(--ld-vh, 100%) - var(--ld-mb)),
      transparent calc(var(--ld-st, 0px) + var(--ld-vh, 100%))
    );
    -webkit-mask-image: var(--ld-vmask);
    mask-image: var(--ld-vmask);
  }
  [data-glass]:not([data-opaque], [data-inactive]):not([data-glass-level="solid"])
    :is(.app-rail, .app-sidebar, .app-statusbar, .app-proj, .app-header)
    .ld-scroll:has(> .ld-scroll-y)
    > :is(.ld-scroll-ft, .ld-scroll-fb) {
    background: none;
  }
  /* 붙는 머리가 있는 목록(사이드바 폴더·팀 묶음)은 글래스 단에서 페이드를 끈다(47 관문 ❌, 디자이너 ③): 마스크를 건 겹은
     backdrop root 가 되어 그 안 붙은 머리의 흐림(#665)이 아래 줄을 못 보고 줄 글자가 또렷하게 겹쳤다. 머리 흐림이 먼저.
     머리 없는 목록(파일·찾기·git 트리, 묶음 없는 동료)은 위 마스크 그대로. */
  [data-glass]:not([data-opaque], [data-inactive]):not([data-glass-level="solid"])
    :is(.app-rail, .app-sidebar, .app-statusbar, .app-proj, .app-header)
    .ld-scroll:has(.app-project-sticky)
    > .ld-scroll-y {
    -webkit-mask-image: none;
    mask-image: none;
  }
  /* 흐림을 못 쓰면 조용히 비치지 않게 불투명 판(bg-frame). */
  @supports not ((backdrop-filter: blur(1px)) or (-webkit-backdrop-filter: blur(1px))) {
    [data-glass] .app-project-sticky[data-stuck] {
      background: var(--color-bg-frame);
    }
  }
  /* 틀을 가르던 선을 모두 뺀다(§43.1) — 영역은 면 차이(반투명 틀 ↔ 불투명 칸)와 간격으로 갈린다. 머리 줄은 선 없이 44. */
  [data-glass] .app-sidebar > .app-titlebar,
  [data-glass] .app-rail > .app-titlebar,
  [data-glass] .app-header,
  [data-glass] .app-proj-head {
    border-bottom: 0;
  }
  [data-glass] .app-sidebar::after,
  [data-glass] .app-rail::after {
    content: none;
  }
  /* 레일 | 목록 가르기(#654 B5, 루오님 확정): 창 위아래를 가르는 선이 아니라 짧은 세로선 하나 — 레일 오른쪽 끝 안쪽 1px(목록 글자를
     밀지 않게), 위·아래는 칸(머리 줄 아래 ~ 칸 아래)에서 8 씩 안쪽(1180×800 창 y 52~760). 색은 틀 위 겹(선택 겹과 같은 10%), 세 단·
     비활성·투명도 줄이기 모두 같은 값. 사이드바를 접으면(.app-side 없음) 없다. */
  [data-glass] .app-rail:has(+ .app-side)::after {
    content: "";
    top: calc(var(--app-head-h) + var(--size-pane-gap));
    bottom: calc(var(--size-pane-gap) * 2);
    background: var(--glass-sel);
  }
  [data-glass] .app-statusbar {
    border-top: 0;
  }
  /* 사이드바·프로젝트 패널 찾기 줄 아래 선, 붙은 폴더 머리 아래 선도 틀 안 선이라 뺀다(§43 시안). 찾기 줄의 포커스 밑줄
     (line-strong)은 입력 포커스 표시라 남긴다. */
  [data-glass] .app-side-search:not([data-focus]),
  [data-glass] .app-project-sticky[data-stuck] {
    box-shadow: none;
  }
  [data-glass] .app-proj,
  [data-glass] .app-split-right {
    border-inline-start: 0;
  }
  [data-glass] .ld-resize {
    top: var(--app-head-h);
  }
  /* 가운데 좁은 열 칸(.app-panel — 새 에이전트·정보·그룹 정보)은 칸 전체 폭으로 깔고 글 열은 padding 으로 가운데(39 관문 🟡).
     글 열 폭은 그대로(560 · 새 에이전트 420). */
  [data-glass] .app-panel {
    max-width: none;
    margin-inline: 0;
    padding-inline: max(var(--space-5), calc((100% - 560px) / 2));
  }
  [data-glass] .app-launcher {
    padding-inline: max(var(--space-5), calc((100% - 420px) / 2));
  }
  /* 안쪽 칸(§43.2): 칸을 품은 열은 모두 투명, 칸 면은 열의 ::before 한 장(불투명 bg · 네 모서리 10, 테두리·그림자 없음). 머리 줄은
     칸 밖 틀 위. 오른쪽 끝 열(메인 · 나란히 오른쪽)은 padding 으로 칸 폭을 8 줄이고 머리 줄은 음수 margin 으로 창 끝까지 — 머리 단추
     자리는 그대로(§43.7). 끝선은 칸 안쪽 끝 − conv-x(1180 창 1152, §43.3). 나란히면 메인 대신 두 열이 칸을 그린다. */
  [data-glass] .app-main,
  [data-glass] .app-split,
  [data-glass] .app-split-left,
  [data-glass] .app-split-right,
  [data-glass] .app-split-session,
  [data-glass] .app-split-session-main,
  [data-glass] .app-term-keep {
    background: transparent;
  }
  [data-glass] .app-with-bar .app-main {
    isolation: isolate;
    padding-block-end: var(--size-pane-gap);
    padding-inline-end: var(--size-pane-gap);
  }
  [data-glass] .app-with-bar .app-main > .app-header,
  [data-glass] .app-split-session-main > .app-header {
    margin-inline-end: calc(-1 * var(--size-pane-gap));
  }
  [data-glass] .app-split {
    margin-inline-end: calc(-1 * var(--size-pane-gap));
  }
  [data-glass] .app-split-left,
  [data-glass] .app-split-session-main {
    position: relative;
    isolation: isolate;
  }
  [data-glass] .app-split-session-main {
    padding-inline-end: var(--size-pane-gap);
  }
  [data-glass] .app-with-bar .app-main:not(:has(> .app-split))::before,
  [data-glass] .app-split-left::before,
  [data-glass] .app-split-session-main::before {
    content: "";
    position: absolute;
    inset: var(--app-head-h) var(--size-pane-gap) var(--size-pane-gap) 0;
    z-index: -1;
    border-radius: var(--radius-radius);
    background: var(--color-bg);
    pointer-events: none;
  }
  [data-glass] .app-split-left::before {
    inset-inline-end: 0;
  }
  /* 작업 칸(터미널·셸)은 칸 전체를 채우는 bg-card 화면이라 칸 모서리를 덮는다 — 같은 10 으로 둥글린다(이미 overflow: hidden). */
  [data-glass] .app-term {
    border-radius: var(--radius-radius);
  }
  /* 작업 칸 면 = 칸 bg(§43.2) — bg-card 면 틀 bg-frame 과 1.05:1 로 안 갈린다(디자이너 43 🟡). xterm 테마도 이 값을 읽는다. */
  [data-glass] {
    --term-bg: var(--color-bg);
  }
  [data-glass] .app-split-left::before,
  [data-glass] .app-split-session-main::before {
    inset-block-end: 0;
  }
  /* 나란히 홈(§43.4): 두 칸 사이 8 이 끌기 영역 전체(col-resize). 손잡이(§44.8)는 얇은 알약 2 × 20 · 모서리 1 · ink-tertiary 70% 가
     세로 가운데 늘 보이고, 호버·끌기·키보드 포커스 때 2 × 32 · ink-secondary. 전환·툴팁 없음. 목록 | 대화 경계(사이드바 폭 띠)도 같은
     알약 — 끌기 영역 8. */
  [data-glass] .app-split-handle {
    top: 0;
    width: var(--size-pane-gap);
    margin: var(--app-head-h) 0 0;
  }
  /* 목록 폭 띠는 경계 오른쪽(칸 안 왼쪽 여백 8 — 칸 글자는 20 안쪽)에만 둔다. 가운데에 두면 왼쪽 4 가 사이드바 스크롤 막대를 덮어
     막대를 잡을 수 없다(기술설계 93841e3ad 🟡). 알약은 경계 x 가운데 그대로(아래 left −1). */
  [data-glass] .app-body > .ld-resize {
    width: var(--size-pane-gap);
    margin-left: 0;
  }
  [data-glass] .ld-resize::after,
  [data-glass] .ld-resize:hover::after,
  [data-glass] .ld-resize:focus-visible::after,
  [data-glass] .ld-resize[data-state~="drag"]::after {
    top: 50%;
    bottom: auto;
    left: calc(50% - 1px);
    width: 2px;
    height: 20px;
    margin-top: -10px;
    border-radius: 1px;
    background: color-mix(in srgb, var(--color-ink-tertiary) 70%, transparent);
  }
  [data-glass] .ld-resize:hover::after,
  [data-glass] .ld-resize:focus-visible::after,
  [data-glass] .ld-resize[data-state~="drag"]::after {
    height: 32px;
    margin-top: -16px;
    background: var(--color-ink-secondary);
  }
  [data-glass] .app-body > .ld-resize::after,
  [data-glass] .app-body > .ld-resize:hover::after,
  [data-glass] .app-body > .ld-resize:focus-visible::after,
  [data-glass] .app-body > .ld-resize[data-state~="drag"]::after {
    left: -1px;
  }
}
/* 이모지 반응(묶음 39 §41.8 · #626). 칩: 높이 22 · 모서리 6 · bg-card · 이모지 + 수, 테두리 없음 — 내가 누른 칩만 테두리 1 ink-tertiary
   (색 없음). 받은 글은 본문 열(아바타·간격 뒤)에, 내 말풍선은 오른쪽 끝에. 누른 그 프레임에 바뀜, 전환 없음. */
.app-reacts {
  display: flex;
  flex-wrap: wrap;
  gap: 4px;
  margin-top: 4px;
  padding-inline-start: calc(var(--size-avatar) + var(--size-gap-inner));
}
.app-item:has(.ld-msg-mine) > .app-reacts {
  justify-content: flex-end;
  padding-inline-start: 0;
}
.app-react {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  height: 22px;
  padding: 0 7px;
  box-sizing: border-box;
  border: 1px solid transparent;
  border-radius: 6px;
  background: var(--color-bg-card);
  color: var(--color-ink);
  font-size: 12px;
  cursor: pointer;
}
.app-react[data-mine] {
  border-color: var(--color-ink-tertiary);
}
.app-react:hover {
  background: var(--color-bg-hover);
}
.app-react:focus-visible {
  outline: 2px solid var(--color-accent);
  outline-offset: 1px;
}
.app-react-e {
  font-size: 13px;
  line-height: 1;
}
.app-react-n {
  font-variant-numeric: tabular-nums;
  color: var(--color-ink-secondary);
}
.app-react > .ld-icon {
  color: var(--color-danger-text);
}
/* 끊긴 동안 누른 반응의 clock 은 실패가 아니라 대기 — 붉게 말고 ink-tertiary(39 재관문 🟡, 명세 b163f17ce). */
.app-react[data-held] > .ld-icon {
  color: var(--color-ink-tertiary);
}
/* 호버 줄 앞쪽 빠른 다섯 + plus — 줄 버튼과 같은 24 칸, 내가 켠 것 bg-selected, 다 쓰면 흐림. */
.app-react-quick {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 24px;
  height: 24px;
  padding: 0;
  border: 0;
  border-radius: var(--radius-sm);
  background: transparent;
  color: var(--color-ink-secondary);
  font-size: 14px;
  line-height: 1;
  cursor: pointer;
}
.app-react-quick:hover {
  background: var(--color-bg-hover);
}
.app-react-quick[data-on] {
  background: var(--color-bg-selected);
}
.app-react-quick[aria-disabled="true"] {
  opacity: 0.4;
  cursor: default;
}
.app-react-quick:focus-visible {
  outline: 2px solid var(--color-accent);
  outline-offset: -2px;
}
.app-react-sep {
  width: 1px;
  height: 16px;
  margin: 0 3px;
  background: var(--color-line);
}
/* 칸막이 뒤에 동작이 없으면(반응만 되는 글) 칸막이도 없다. */
.app-react-sep:last-child {
  display: none;
}
/* 이모지 고르기 창이 글자를 넣을 자리(#626) — 보이지 않고 누를 수 없음, 포커스만 받는다. */
.app-react-pick {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  border: 0;
  opacity: 0;
  pointer-events: none;
}
/* 에이전트 정보 모델·대화 압축(#629 §41.13) — 실패 자리는 state-error(danger-text), 작업 중 아이콘은 고른 값 앞. */
.app-agent-cmd {
  display: inline-flex;
  align-items: center;
  gap: 4px;
}
.app-agent-cmd[data-error] [data-icon="state-error"] {
  color: var(--color-danger-text);
}
/* 상단바 오른쪽 끝 내 프로필 자리(묶음 39 §41.1): 맨 위 44 줄 오른쪽, 창 오른쪽 끝 머리(본문·오른쪽 패널·나란히의 오른쪽 칸)는 그만큼 비운다. */
.app-profile-slot {
  position: absolute;
  top: 8px;
  right: 12px;
  z-index: 40;
}
.app-body > :last-child .app-header:not(.app-split-left .app-header) {
  padding-inline-end: calc(var(--space-5) + 36px);
}
/* 나란히 보기에서 패널이 세션 칸 오른쪽에 붙으면 창 끝은 패널 머리 — 에이전트 머리는 프로필 자리를 비우지 않는다(39 관문 ❌). */
.app-body .app-split-session:has(> .app-proj) .app-split-session-main .app-header {
  padding-inline-end: var(--space-5);
}
.app-body > :last-child .app-proj-head {
  padding-inline-end: calc(var(--space-3) + 36px);
}
/* 상단바 아바타의 접속 점 테두리는 상단바 면(bg) 색 — 사이드바 목록 면이 아니다. */
.app-profile .app-online-dot {
  border-color: var(--color-bg);
}
/* @로 부른 에이전트 칩 줄(§41.10 · #627): (a) 밑, 높이 22 · bg-card · 마크 12 · 이름 · 상태 11 — 낱말 없음, 누름 없음. */
.app-agent-chips {
  display: flex;
  flex-wrap: wrap;
  gap: 4px;
  margin-top: 4px;
  padding-inline-start: calc(var(--size-avatar) + var(--size-gap-inner));
}
.app-agent-chips[data-mine] {
  justify-content: flex-end;
  padding-inline-start: 0;
}
.app-agent-chip {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  height: 22px;
  max-width: 220px;
  padding: 0 7px;
  box-sizing: border-box;
  border-radius: 6px;
  background: var(--color-bg-card);
  color: var(--color-ink);
  font-size: var(--font-size-small);
}
.app-agent-chip-name {
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
/* 상태 칸은 늘 11 폭. */
.app-agent-chip-st {
  display: inline-flex;
  flex: none;
  width: 11px;
  color: var(--color-ink-secondary);
}
/* 기다림은 돌지 않는 clock — ink-tertiary(디자이너 10-31). */
.app-agent-chip-st[data-tone="wait"] {
  color: var(--color-ink-tertiary);
}
.app-agent-chip-st[data-tone="ok"] {
  color: var(--color-success);
}
.app-agent-chip-st[data-tone="need"] {
  color: var(--color-accent-text);
}
.app-agent-chip-st[data-tone="fail"] {
  color: var(--color-danger-text);
}
/* 칩 아래 답 스레드(§41.10 · 규칙 37): 답 행마다 쓴 사람 쪽 블록. */
.app-mention-thread {
  display: flex;
  flex-direction: column;
  gap: 4px;
}
/* 쪽·폭·선 자리는 줄기 블록(.app-stem-side)과 같고 선 색만 line-strong — 여러 주인의 에이전트가 섞여 사람 색이 맞지 않는다.
   안 읽은 답은 .app-stem-side:has(fresh) 가 그 쪽 선을 accent 로 덮는다. */
.app-mention-side {
  --app-lc: var(--color-line-strong);
}
/* 회신 검토 카드 by 줄 끝 받는 곳(§41.10 4층): users 12 + 그룹 이름 — 길면 이름만 말줄임(전체는 툴팁). */
.app-review-group {
  display: inline-flex;
  align-items: center;
  gap: 3px;
  max-width: 160px;
  vertical-align: bottom;
}
.app-review-group > .ld-icon {
  flex: none;
}
.app-review-group-name {
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
/* 이름 없는 그룹 제목(#647 §42.3): 좁으면 이름만 말줄임, ` +N` 은 늘 보임. */
.app-group-title {
  display: inline-flex;
  min-width: 0;
  max-width: 100%;
  vertical-align: bottom;
}
.app-group-title-names {
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.app-group-title-more {
  flex: none;
  white-space: pre;
}
/* 이름 줄 설정 버튼(규칙 37-10, 디자이너 53ef18735): 시각 바로 뒤 인라인, 아이콘 12 · 누름 칸 20, 이름 줄 가운데. 칩 밑 카드의 줄
   오른쪽 끝 배치는 취소 — 줄 오른쪽 끝은 호버 바 자리. */
.ld-msg-tail {
  gap: var(--space-1);
}
.ld-msg-hd > .ld-msg-tail:has(.app-scope-set),
.ld-msg-by:has(.app-scope-set) {
  align-self: center;
}
.app-scope-set {
  display: inline-flex;
  vertical-align: middle;
}
.app-scope-set .ld-ibtn {
  width: 20px;
  height: 20px;
}
.app-scope-set .ld-ibtn .ld-icon,
.app-scope-set .ld-ibtn svg {
  width: 12px;
  height: 12px;
}
/* 보내기 전 회신 검토(디자이너 c1c02259a): 오른쪽 블록 + bg-mine 면, 고칠 칸 때문에 폭만 86% 고정. 면은 본문 칸(머리 줄 밖). */
.app-review-side {
  width: 86%;
}
/* 면은 bg-mine-card(반투명 — 바탕을 가르지 않음, 디자이너 9119af3c7): 대화 열 말풍선·칩 아래 답 스레드만 bg-mine. */
/* 폭이 정해진 블록(86%)이라 행·본문 칸은 그 폭을 다 쓴다 — 오른쪽 블록의 flex-end(내용 폭)·MessageRow side='right' 의
   justify-self:end 대신. */
.app-review-side > .ld-msg {
  align-self: stretch;
}
.app-review-side .ld-msg[data-side="right"] > .ld-msg-body {
  justify-self: stretch;
}
.app-review-side .ld-msg-body > [data-card-keys] {
  /* 면 끝 = 머리 D1 끝(그 블록 끝선, 37-11) — 본문 칸은 아바타 열 앞에서 끝나므로 면만 그 열 아래까지 뻗는다(41 마지막 확인 🟡). */
  margin-inline-end: calc(-1 * (var(--size-avatar) + var(--size-gap-inner)));
  padding: var(--space-2) var(--space-3);
  background: var(--color-bg-mine-card);
  border-radius: var(--radius-radius);
}

/* #644 B §42.1 — 계정 프로필 값 뒤 열쇠(내 설정이라 경고색 아님). */
.app-auth-env {
  display: inline-flex;
  margin-inline-start: var(--space-1);
  vertical-align: -1px;
  color: var(--color-ink-secondary);
}

/* 다시 열기 실패(#644 C 42 관문) — `다시 열기` 앞 state-error, 이유는 툴팁. 사이드바 꺼진 줄에선 #614 표시 자리(20 칸, 여백 없음). */
.app-reopen-failed {
  display: inline-flex;
  align-items: center;
  margin-inline-end: var(--space-2);
  color: var(--color-danger-text);
}
.app-hidden-mark .app-reopen-failed {
  justify-content: center;
  width: 20px;
  height: 20px;
  margin: 0;
}

/* apps/desktop/src/account.css */
/* 계정·기기 연결(U12, flows 2b). 메인 창(가입·연결 대기)과 설정 창(기기 추가)이 같이 쓴다. 컴포넌트 모양은 @lodelai/ui. */

/* 지문: 두 화면에서 같은 모양이어야 사람이 대조한다 — 줄이거나 말줄임하지 않는다(모노 18/500, 글자 사이 넓게). */
.acc-fp {
  font-family: var(--font-family-mono);
  font-size: var(--font-size-title);
  font-weight: 500;
  letter-spacing: 0.08em;
  line-height: 1.4;
  overflow-wrap: anywhere;
}
.acc-title {
  font: var(--text-title);
  margin: 0;
}
.acc-desc {
  margin: 0;
  color: var(--color-ink-secondary);
}
.acc-eyebrow {
  padding: 0;
}

/* 가입·연결 대기: 메인 창 전체를 대신한다(온보딩 창이 아직 없다). 가운데 한 줄기, 폭 360. */
/* 창 드래그 영역(맥 overlay 타이틀바). 계정 화면 위쪽 여백 위에 겹친다 — 그 자리엔 조작할 것이 없다. */
.acc-drag {
  position: fixed;
  inset: 0 0 auto;
  height: 44px;
  z-index: 1;
}
/* 가입·연결 화면 맨 위 Note(업데이트 받을 수 없음·업데이트 필요): 신호등 줄 아래에서 시작, 가로는 가입 칸(.acc-col 360)과 같은 폭으로
   가운데(26 2차 ❌② — 제목이 신호등에 가림, 디자이너 1612bbe1 ⑤). */
.acc-drag + .app-main > .app-notes {
  box-sizing: border-box;
  width: 100%;
  max-width: calc(360px + var(--space-5) * 2);
  margin-inline: auto;
}
.acc-drag + .app-main > .app-notes:first-child {
  padding-top: 44px;
}
/* Note 가 있을 때만 그 아래~가입 칸 위 여백 56 → 12(디자이너 0599392a, 26 화면확인 new2 🟡 — Note 만큼 칸이 내려가 기본 창
   1180×720 에서 `계속` 이 아래 흐림에 걸림). 위 여백(56)이 신호등 줄 + Note 보다 작아 Note 를 여백에 겹칠 수 없다(실측). */
.acc-drag + .app-main > .app-notes ~ .acc-screen {
  padding-top: var(--space-3);
}
.acc-screen {
  height: 100%;
  overflow: auto;
  display: flex;
  justify-content: center;
  align-items: flex-start;
  padding: calc(var(--space-6) * 2) var(--space-5) var(--space-5);
  box-sizing: border-box;
  /* 가로 줄(가운데 열 하나)이라 ScrollArea 페이드(규칙 32)가 제 줄을 갖게 줄바꿈 — 페이드는 공간 0. */
  flex-wrap: wrap;
  align-content: flex-start;
}
.acc-screen > .ld-scroll-f {
  width: 100%;
}
.acc-col {
  width: 100%;
  max-width: 360px;
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
}
.acc-gap {
  height: var(--space-2);
}
/* 기기 연결 코드 한 줄(공개 정보) — 말줄임 + 툴팁 전문. */
.acc-code {
  font: var(--text-meta);
  color: var(--color-ink-secondary);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.acc-row {
  display: flex;
  align-items: center;
  gap: var(--space-2);
}
.acc-spacer {
  flex: 1;
}
.acc-quiet {
  font: var(--text-small);
  color: var(--color-ink-tertiary);
}
/* 문단 꼴 흐린 한 줄(가입 §25 — 다른 조직은 다른 이메일·코드가 없으면). */
.acc-line {
  margin: 0;
}
/* `코드가 없으면` 은 위 주버튼과 간격 16(§25.1) — 열 gap 12 에 4 를 더한다. */
.acc-nocode {
  margin-top: var(--space-1);
}

/* 설정 › 조직 › 기기 추가 — 탭 본문을 바꿔 그린다. */
.acc-crumb {
  font: var(--text-small);
  color: var(--color-ink-secondary);
  display: flex;
  align-items: center;
  gap: var(--space-2);
  margin-bottom: var(--space-3);
}
.acc-col-wide {
  max-width: 560px;
}
.acc-stack {
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
}
.acc-plain {
  margin: 0;
}
.acc-mono {
  font-family: var(--font-family-mono);
}
/* 호스트·주소는 하이픈에서 끊지 않는다(22g 🟡 'lodelai-/other.test') — 긴 줄은 값 사이에서 바뀐다. */
.acc-host {
  white-space: nowrap;
}

/* 온보딩 단계 표시(보드 "온보딩"): 흐린 숫자 한 줄. */
.acc-step {
  font-size: var(--font-size-small);
  color: var(--color-ink-tertiary);
  font-variant-numeric: tabular-nums;
}
/* 온보딩 ②·③ 아래 버튼 줄: ghost 건너뛰기 왼쪽, 주버튼 오른쪽. */
.acc-actions {
  margin-top: var(--space-2);
}

/* 가입 ① 서버 주소·조직 만들기 코드 칸은 모노(m1-spec §1·§8 묶음 4). TextField 에 모노 옵션이 없어 감싸개로. */
.acc-mono-field input {
  font-family: var(--font-family-mono);
}
/* ①c `다른 코드 넣기` — 칸 시작선에 맞춘 흐린 글자 버튼(묶음 6 — 코드 칸 하나, 누르면 칸을 비우고 초대로). */
.acc-link {
  align-self: flex-start;
  padding: 0;
  border: 0;
  background: none;
  font: inherit;
  font-size: var(--font-size-small);
  color: var(--color-ink-secondary);
  text-decoration: underline;
  text-underline-offset: 2px;
  cursor: default;
}
.acc-link:hover {
  color: var(--color-ink);
}
.acc-link:focus-visible {
  outline: 2px solid var(--color-accent);
  outline-offset: 2px;
  border-radius: var(--radius-sm);
}
/* 가입 ① 로고(m1-spec §1·§8): 맨 위 왼쪽, 워드마크 높이 24. 아래 `1 / 3` 까지 24 = 열 gap 12 + 12(디자이너 10-25). */
.acc-logo {
  display: flex;
  margin-bottom: var(--space-3);
}
/* 서버 relay 가입 ①a~c(묶음 5, m1-spec §1). 동의 체크박스 줄 — 글자 + 오른쪽 글자 링크 `처리방침`. DS 에 체크박스가 없어 맥 기본 모양. */
.acc-agree {
  display: flex;
  align-items: center;
  gap: var(--space-2);
}
.acc-check {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  font: var(--text-small);
  color: var(--color-ink);
}
.acc-check input {
  margin: 0;
  accent-color: var(--color-ink);
}
.acc-inline-link {
  align-self: center;
  text-decoration: underline;
  /* 영어 `Privacy policy` 가 두 줄로 꺾였다(29 관문 🟡) — 링크는 한 덩어리. */
  white-space: nowrap;
}
.acc-field-error {
  margin: 0;
  font: var(--text-small);
  color: var(--color-ink-secondary);
}
/* 서버 판·이름 어긋남 한 줄(#533·#534): 글 + 줄 끝 `업데이트 확인`(앱이 낮을 때만). */
.acc-server-blocked {
  display: flex;
  align-items: center;
  gap: var(--space-1);
}
.acc-server-blocked > .ld-btn {
  margin-inline-start: auto;
}
/* 초대 확인 뒤 `{조직}에 들어가요` · `초대한 사람: …` */
.acc-join {
  display: flex;
  flex-direction: column;
  gap: var(--space-1);
}
.acc-join-org {
  font-weight: 500;
}
/* 초대 가입 조직 확인(#554): 제목 앞 조직 사진 32. */
.acc-join-head {
  display: flex;
  align-items: center;
  gap: var(--space-3);
}
.acc-label {
  font: var(--text-small);
  color: var(--color-ink-secondary);
}
/* 세로 간격(interaction-rules 20·20a, 디자이너 10-25) — acc-col 의 gap 12 위에 더한다.
   ① 칸(라벨 + 입력 + hint) 사이 24: 8 이면 앞 칸 hint 가 다음 칸 라벨에 붙어 읽힌다. 칸은 감싸개 안에 있기도 하다. */
.acc-col > :is(.ld-field, :has(> .ld-field)) + :is(.ld-field, :has(> .ld-field)) {
  margin-top: calc(var(--space-3) * 2 - var(--space-3));
}
/* ②③ 소개 끝 → 목록(제목 없는 그룹) 윗선 24. */
.acc-col > .acc-desc + .ld-set-group {
  margin-top: calc(var(--space-3) * 2 - var(--space-3));
}
/* ③ 제목 있는 그룹 앞 40(20a, 보이는 끝에서) — 그룹끼리의 40 에 열 gap 12 가 더해지지 않게. */
.acc-col > .ld-set-group + .ld-set-group {
  margin-top: calc(var(--space-5) * 2 - var(--space-3));
}
/* 가입 ① 주버튼(①a~c 같은 꼴, 디자이너 10-25 m1-spec §1): 칸 폭 가득 + 글자 가운데. 비활성 툴팁 감싸개(ld-tip)가 있어도 같은 폭. */
.acc-col > .ld-tip {
  display: flex;
}
.acc-col > .ld-tip > .ld-btn {
  flex: 1;
}
.acc-col > .ld-btn,
.acc-col > .ld-tip > .ld-btn {
  justify-content: center;
}

/* 온보딩 ③ 의 `이 기기에서 찾은 것` 소제목(설정 창 꼴과 같게) — 위 묶음과 섹션 간격 24(디자이너 10-26 J9b). */
.acc-col .set-subtitle {
  padding: 24px 0 4px;
  font-size: 12px;
  color: var(--color-ink-tertiary);
}
/* 가입 화면 간격(디자인감사 10-26 — 토큰만): 묶음 안 8, 블록 사이 24(acc-gap 16 + 열 gap 8). */
.acc-col.acc-signup {
  gap: var(--space-2);
}
.acc-signup .acc-gap {
  height: var(--space-4);
}
.acc-signup .acc-logo {
  margin-bottom: var(--space-4);
}
.acc-wide {
  width: 100%;
}
/* 누른 프레임의 버튼 안 진행(회색·돎) — 글자 왼쪽 8px, 흐름 밖이라 글자·버튼이 움직이지 않는다(규칙 17). */
.acc-btn-label {
  position: relative;
}
.acc-btn-working {
  position: absolute;
  top: 50%;
  right: calc(100% + var(--space-2));
  display: inline-flex;
  color: var(--color-ink-tertiary);
  transform: translateY(-50%);
}
/* 서버 주소 칸 바로 아래 왼쪽 보조 글자 버튼 `이 기기에서 새로 시작`(UX점검 9 — 안내 문장 대신, 가입 ①·설정 › 서버). */
.acc-start-local {
  display: flex;
  margin-top: var(--space-1);
}
/* 글자 왼쪽 = 칸 왼쪽(디자이너 cap17u 🟡) — 가로 여백 0, 누를 자리는 세로 높이 그대로. */
.acc-start-local > .ld-btn {
  padding-inline: 0;
}
/* 칸이 비면 이미 이 기기 — 누를 일 없는 버튼은 흐리게 두지 않고 숨김, 자리는 남겨 아래가 움직이지 않게(규칙 17, 디자이너 10-27). */
.acc-start-local[data-empty] {
  visibility: hidden;
}

/* apps/desktop/src/confirm.css */
/* 되돌릴 수 없는 동작의 확인(ConfirmButton, #181 세션 끝내기에서 생김). 메인 창·설정 창(계정 빼기·프로필 빼기)이 같이 쓴다.
   누른 버튼 옆(아래·오른쪽 정렬) 팝오버 — 가운데 모달 없음(규칙 4), 애니메이션 없음(규칙 1). */
.app-confirm-anchor {
  position: relative;
  display: inline-flex;
}
.app-confirm {
  position: absolute;
  top: calc(100% + var(--space-1));
  inset-inline-end: 0;
  z-index: 10;
  min-width: 240px;
  max-width: 320px;
  padding: var(--space-3);
  background: var(--color-bg);
  border: 1px solid var(--color-line-strong);
  border-radius: var(--radius-radius);
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
}
.app-confirm-title {
  font-weight: 500;
}
.app-confirm-body {
  margin: 0;
  font: var(--text-small);
  color: var(--color-ink-secondary);
}
.app-confirm-actions {
  display: flex;
  justify-content: flex-end;
  gap: var(--space-2);
}
/* 위험 쪽 동작이 상시 보일 때(프로필 빼기, #340 디자이너): 평소엔 보조 글자, 호버·열림만 danger(강조 예산 danger 1). */
.app-confirm-quiet .ld-btn-ghost:hover,
.app-confirm-quiet .ld-btn-ghost[aria-expanded="true"] {
  color: var(--color-danger-text);
}
/* 앵커 없는 확인(묶음 10 D1 ⌘Q·업데이트 재시작): 창 머리 아래 가운데 폭 360, 뒤는 막고(투명) 바깥 클릭으로 닫히지 않는다. */
.app-sheet-scrim {
  position: fixed;
  inset: 0;
  z-index: 100;
}
.app-confirm.app-sheet {
  position: fixed;
  top: 52px;
  left: 50%;
  inset-inline-end: auto;
  transform: translateX(-50%);
  width: 360px;
  max-width: 360px;
  box-sizing: border-box;
}

/* 확정 버튼의 누른 프레임(§26.4a K8·K9·K10): 글자 그대로 + state-working 회색·돎을 글자 오른쪽 8px 흐름 밖에 — 글자·버튼 폭이 그대로(규칙 17).
   왼쪽에 두면 `취소` 쪽 진행처럼 읽힌다(디자이너 10-26). */
.app-btn-label {
  position: relative;
}
.app-btn-working {
  position: absolute;
  top: 50%;
  left: calc(100% + var(--space-2));
  display: inline-flex;
  color: var(--color-ink-tertiary);
  transform: translateY(-50%);
}

/* 단축키 모아 보기 ⌘/(묶음 13 §21.8): 같은 자리, 최대 폭 480, 넘치면 안쪽 스크롤. 행 = 이름 왼쪽 · Kbd 오른쪽. */
.app-confirm.app-sheet.app-shortcuts {
  /* 고정 폭 대신 내용 폭, 최대 480(규칙 16, 디자인감사 71103617). */
  width: max-content;
  max-width: min(480px, calc(100vw - 2 * var(--space-4)));
  /* 최대 높이 = 위 자리(52)부터 하단 상태창(24) 위 16 까지 — 상태창을 덮지 않는다(관문 13 🟡⑥, 648/720 이 닿았음). */
  max-height: calc(100vh - 52px - 24px - var(--space-4));
  gap: var(--space-3);
}
.app-shortcuts-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
}
.app-shortcuts-body {
  overflow-y: auto;
  /* 넘치면 제목 줄은 고정, 이 영역만 줄어 안쪽 스크롤(오버레이 + 페이드, 규칙 32). */
  min-height: 0;
  flex: 1 1 auto;
  display: flex;
  flex-direction: column;
  /* 제목 막대가 왼쪽 여백(2 + 8)으로 나간다 — 스크롤 상자가 자르지 않게 안쪽 여백. */
  padding-inline-start: calc(2px + var(--space-2));
  margin-inline-start: calc((2px + var(--space-2)) * -1);
}
/* 그룹 앞 40 은 보이는 끝에서(20a): 이 행은 위아래 4 여백뿐이라 설정 행 보정(-14.25) 대신 -4. */
.app-shortcuts .ld-set-group:has(+ .ld-set-group) {
  margin-bottom: calc(var(--space-1) * -1);
}
.app-shortcuts-row {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: var(--space-3);
  padding-block: var(--space-1);
}

/* apps/desktop/src/markdown.css */
/* 대화 메시지 본문 마크다운(ui/Markdown.tsx, m1-spec 2c0ed97). 글자 크기는 본문 그대로 — 제목도 굵게만. */
.app-md {
  white-space: normal;
  overflow-wrap: anywhere;
}
.app-md > :first-child {
  margin-top: 0;
}
.app-md > :last-child {
  margin-bottom: 0;
}
.app-md p,
.app-md ul,
.app-md ol,
.app-md blockquote,
.app-md hr,
.app-md .app-md-pre,
.app-md .app-md-table {
  margin: var(--space-2) 0;
}
.app-md ul,
.app-md ol {
  padding-inline-start: 1.5em;
}
.app-md .app-md-h {
  margin: var(--space-2) 0;
  font-size: inherit;
  line-height: inherit;
  font-weight: 600;
}
.app-md blockquote {
  padding-inline-start: var(--space-3);
  border-inline-start: 2px solid var(--color-line-strong);
  color: var(--color-ink-secondary);
}
.app-md hr {
  border: 0;
  border-top: 1px solid var(--color-line);
}
.app-md-code {
  font-family: var(--font-family-mono);
  font-size: var(--font-size-code);
  background: var(--color-bg-hover);
  border-radius: var(--radius-sm);
  padding: 0 0.25em;
}
/* 링크: 밑줄 글자. 누르면 기본 브라우저(앱 안에서 열지 않음). */
.app-md-link {
  color: inherit;
  text-decoration: underline;
  text-underline-offset: 2px;
  cursor: pointer;
}
.app-md-tip-url {
  font-weight: 600;
  overflow-wrap: anywhere;
}
/* 코드 블록: 모노 상자, 줄이지 않고 가로 스크롤, 오른쪽 위 복사. */
.app-md-pre {
  background: var(--color-bg-card);
  border: 1px solid var(--color-line);
  border-radius: var(--radius-radius);
}
/* 줄마다 블록(diff 줄 바탕이 가로 스크롤해도 블록 폭 끝까지, §52.3) — code 는 가장 긴 줄 폭까지 늘고 줄은 그 폭을 채운다. */
.app-md-pre pre code {
  display: inline-block;
  /* 줄 상자 바닥 글자 아래 자리(descender)가 생기지 않게. */
  vertical-align: top;
  box-sizing: border-box;
  min-width: 100%;
  padding-bottom: var(--space-3);
}
.app-md-pre .app-md-line {
  display: block;
  padding-inline: var(--space-3);
}
.app-md-pre [data-diff="add"] {
  background: var(--color-diff-add-bg);
  color: var(--color-ink);
}
.app-md-pre [data-diff="del"] {
  background: var(--color-diff-del-bg);
  color: var(--color-ink);
}
.app-md-pre [data-diff-mark="add"] {
  color: var(--color-success);
}
.app-md-pre [data-diff-mark="del"] {
  color: var(--color-danger-text);
}
/* 접힌 상자(§52.5, 디자이너 50 판정 ①): 앞 12줄 + 아래 끝 페이드(긴 글 접기와 같은 mask), 그 아래 본문 접기(#446)와 같은 꼴 —
   왼쪽 정렬(코드 글 왼쪽 끝 = 줄 안쪽 여백에 맞춤), chevron 없음. `접기` 도 같은 자리. */
.app-text-btn.app-longtext-btn.app-md-pre-fold {
  margin: 0 0 0 var(--space-3);
  padding-bottom: var(--space-2);
}
/* 머리 언어 단추(§52.1): 흐린 모노 12 글자, 누를 수 있음 = 호버 면 + chevron 10. */
.app-code-lang {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  height: 22px;
  margin-inline-start: calc(-1 * var(--space-1));
  padding: 0 var(--space-1);
  border: 0;
  border-radius: var(--radius-sm);
  background: none;
  font-family: var(--font-family-mono);
  font-size: 12px;
  color: var(--color-ink-tertiary);
  cursor: pointer;
}
.app-code-lang:hover,
.app-code-lang[aria-expanded="true"] {
  background: var(--color-bg-hover);
}
.app-code-lang-auto {
  white-space: pre;
}
.app-to-list.app-code-lang-list {
  width: 220px;
}
.app-md-raw {
  white-space: pre-wrap;
}
.app-md-pre-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: var(--space-1) var(--space-1) 0 var(--space-3);
}
/* 여백은 안쪽 code 에 — ScrollArea(규칙 32)가 padding 보정 style 을 두지 않게(마크다운에는 style 속성이 없어야 한다, 주입 검사). */
.app-md-pre pre {
  --ld-fade-bg: var(--color-bg-card);
  margin: 0;
  overflow-x: auto;
  white-space: pre;
  font-family: var(--font-family-mono);
  font-size: var(--font-size-code);
  line-height: var(--font-line-height-code);
  color: var(--color-code-fg);
  /* 블록 안 세로 스크롤 없음 — 긴 상자는 접는다(§52.5, §8 의 24줄 줄을 갈음). */
}
/* 표: 헤어라인, 넓으면 표만 가로 스크롤. */
.app-md-table {
  overflow-x: auto;
}
.app-md table {
  border-collapse: collapse;
}
.app-md th,
.app-md td {
  border: 1px solid var(--color-line);
  padding: var(--space-1) var(--space-2);
  text-align: start;
  vertical-align: top;
}
.app-md th {
  font-weight: 600;
}
.app-md .app-md-center {
  text-align: center;
}
.app-md .app-md-right {
  text-align: end;
}
/* 불러오지 않은 이미지 자리: 흐린 한 줄(아이콘 + 이미지 · 호스트). 누르면 확인 팝오버. */
.app-md-image-line {
  display: inline-flex;
  align-items: center;
  gap: var(--space-1);
  max-width: 100%;
  padding: 0;
  border: 0;
  background: none;
  font: inherit;
  color: var(--color-ink-tertiary);
  cursor: pointer;
  text-align: start;
}
.app-md-image-line:hover:not(:disabled) {
  color: var(--color-ink-secondary);
}
.app-md-image-line:focus-visible {
  outline: 2px solid var(--color-accent);
  outline-offset: 2px;
  border-radius: var(--radius-sm);
}
.app-md-image-url {
  overflow-wrap: anywhere;
  white-space: normal;
}
/* 불러온 이미지: 본문 열 폭까지, 높이 최대 320, 비율 유지. */
.app-md-img {
  display: block;
  max-width: 100%;
  max-height: 320px;
  object-fit: contain;
}

/* apps/desktop/src/usage.css */
/* 에이전트 사용량(묶음 6 §12b) — 메인 창 상태창·팝오버와 설정 › 에이전트 프로필 행이 같이 쓴다. */
/* 사용량 막대(§37.5, 루오님 10-28): 40×4. 3단 — 80% 미만 success(녹, 정상) · 80% warn-fill · 95% danger-fill, 빈 트랙은 line.
   브랜드색 agent-claude 는 앞의 마크에만(§20.9). 색은 덧붙인 신호 — 값은 길이와 늘 붙은 % 글자가 말한다(규칙 21). */
.app-usage-meter {
  flex: none;
  display: inline-block;
  width: 40px;
  height: 4px;
  border-radius: 2px;
  background: var(--color-line);
  overflow: hidden;
  color: var(--color-success);
}
.app-usage-meter > i {
  display: block;
  height: 100%;
  background: currentColor;
}
/* 80% 이상 warn-fill(앰버)·95% 이상 danger-fill(빨강) — 막대 채움 전용 토큰(루오님 10-27 '탁한 갈색 싫어', DS v70). */
.app-usage-meter[data-level="hi"] > i {
  background: var(--color-warn-fill);
}
.app-usage-meter[data-level="max"] > i {
  background: var(--color-danger-fill);
}
/* % 글자는 늘 ink-secondary — 경고여도 색을 주지 않는다, 색은 막대만(루오님 10-27). */
.app-usage-pct {
  color: var(--color-ink-secondary);
}
.app-usage-ago {
  color: var(--color-ink-tertiary);
}
/* 15분 넘은 값은 막대·% 를 옅게(#547) — 지금 값이 아님을 글자(· n분 전)와 함께 말한다. */
.app-statusbar-usage[data-stale] .app-usage-meter-box,
.app-statusbar-usage[data-stale] .app-usage-pct {
  opacity: 0.5;
}
/* 불러오기 실패 ⚠(#547) — 마지막 값 옆, 까닭은 툴팁. warn 은 글자색 토큰(막대 채움 warn-fill 과 따로). */
.app-usage-warn {
  display: inline-flex;
  color: var(--color-warn);
}
/* 사용량 팝오버 — 상태창 오른쪽에 붙어 위로, 폭 360, bg + line-strong, 그림자·애니메이션 없음. */
.app-usage-pop {
  width: 360px;
  box-sizing: border-box;
  background: var(--color-bg);
  border: 1px solid var(--color-line-strong);
  border-radius: var(--radius-radius);
  padding: 6px 0;
  font-size: 13px;
  color: var(--color-ink);
}
.app-usage-pop-h {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 6px 14px 4px;
  font-weight: 600;
}
.app-usage-pop-q {
  margin-left: auto;
  font-weight: 400;
  font-size: 12px;
  color: var(--color-ink-tertiary);
}
.app-usage-row {
  display: flex;
  align-items: flex-start;
  gap: 8px;
  padding: 8px 14px;
}
.app-usage-row + .app-usage-row {
  border-top: 1px solid var(--color-line);
}
.app-usage-row-b {
  flex: 1;
  min-width: 0;
}
.app-usage-row-n {
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.app-usage-row[data-off] .app-usage-row-n {
  color: var(--color-ink-tertiary);
}
.app-usage-row-why {
  margin-top: 2px;
  font-size: 12px;
  color: var(--color-ink-secondary);
}
.app-usage-line {
  display: flex;
  align-items: center;
  gap: 8px;
  margin-top: 4px;
  font-size: 12px;
  color: var(--color-ink-secondary);
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}
/* 이름 칸 폭은 목록의 가장 긴 이름(64~112, UsageKeys 가 잼) — 줄마다 막대 시작이 같은 x, 112 넘는 이름만 말줄임 + 툴팁. */
.app-usage-keys {
  display: contents;
}
.app-usage-k {
  flex: none;
  width: var(--usage-k, 64px);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  /* 읽어야 하는 라벨이라 tertiary(2.7:1) 금지 — secondary(10-27). */
  color: var(--color-ink-secondary);
}
/* 이름 칸 64(보드 36 + 28)만큼 막대를 줄여 한 줄 폭은 보드와 같게 — `1시간 12분 뒤 초기화` 가 360 안에 든다. */
.app-usage-line .app-usage-meter {
  width: 92px;
}
/* % 칸 36 오른쪽 맞춤(tabular) — 47%·100% 가 섞여도 남은 시간의 시작 x 가 같다(디자이너 10-25). */
.app-usage-line .app-usage-pct {
  flex: none;
  width: 36px;
  text-align: right;
}
.app-usage-t {
  color: var(--color-ink-tertiary);
}
.app-usage-manage {
  all: unset;
  box-sizing: border-box;
  display: flex;
  align-items: center;
  width: 100%;
  height: 30px;
  padding: 0 14px;
  margin-top: 4px;
  border-top: 1px solid var(--color-line);
  color: var(--color-ink-secondary);
  cursor: pointer;
}
.app-usage-manage:hover {
  background: var(--color-bg-hover);
  color: var(--color-ink);
}
.app-usage-manage:focus-visible {
  outline: 2px solid var(--color-accent);
  outline-offset: -2px;
}
.app-usage-sp {
  flex: 1;
}

/* 세션 정보 `사용량`(묶음 11 §19.1): 막대 80 + `{p}%` 36(오른쪽 맞춤) + `압축`. 색은 ink 하나 — 넘쳐도 바꾸지 않는다(규칙 22). */
.app-ctx {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
}
.app-usage-meter.app-ctx-meter {
  width: 80px;
  color: var(--color-ink);
}
.app-ctx-pct {
  width: 36px;
  text-align: right;
  font-variant-numeric: tabular-nums;
}
/* 행 아래 한 줄(거절·실패) — 메인 창용(설정 창의 set-row-note 와 같은 꼴). 다음 누름에 걷힌다. */
.app-row-note {
  margin-top: calc(-1 * var(--space-1));
  padding-bottom: var(--space-2);
  font-size: 12px;
}
/* 압축 안내(§19.1 330cf4bc): 컨텍스트 행 아래 흐린 12 한 줄 + 오른쪽 `터미널 열기` — 글자 끝을 다른 행 값의 오른쪽 선에. */
.app-compact-hint {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-2);
}
.app-compact-hint code {
  font-family: var(--font-family-mono);
  font-size: var(--font-size-meta);
}
.app-compact-hint > .ld-btn-ghost {
  margin-inline-end: calc(var(--space-3) * -1);
}
/* 안내 줄은 컨텍스트 행의 일부 — 다음 행과의 사이 선은 행 사이 선과 같게(디자이너 10-26, 같은 그룹 행은 같은 꼴). */
.app-compact-hint + .ld-set-row {
  border-top: 1px solid var(--color-line);
}

/* bundled */
.xterm{cursor:text;position:relative;user-select:none;-ms-user-select:none;-webkit-user-select:none}.xterm.focus,.xterm:focus{outline:none}.xterm .xterm-helpers{position:absolute;z-index:5;top:0}.xterm .xterm-helper-textarea{position:absolute;opacity:0;z-index:-5;white-space:nowrap;overflow:hidden;resize:none;border:0;width:0;height:0;margin:0;padding:0;top:0;left:-9999em}.xterm .composition-view{color:#fff;display:none;position:absolute;white-space:nowrap;z-index:1;background:#000}.xterm .composition-view.active{display:block}.xterm .xterm-viewport{overflow-y:scroll;cursor:default;position:absolute;background-color:#000;inset:0}.xterm .xterm-screen{position:relative}.xterm .xterm-screen canvas{position:absolute;top:0;left:0}.xterm-char-measure-element{display:inline-block;visibility:hidden;position:absolute;line-height:normal;top:0;left:-9999em}.xterm.enable-mouse-events{cursor:default}.xterm.xterm-cursor-pointer,.xterm .xterm-cursor-pointer{cursor:pointer}.xterm.column-select.focus{cursor:crosshair}.xterm .xterm-accessibility:not(.debug),.xterm .xterm-message{position:absolute;z-index:10;color:#0000;pointer-events:none;inset:0}.xterm .xterm-accessibility-tree:not(.debug) *::selection{color:#0000}.xterm .xterm-accessibility-tree{user-select:text;white-space:pre;font-family:monospace}.xterm .xterm-accessibility-tree>div{transform-origin:left;width:-moz-fit-content;width:fit-content}.xterm .live-region{position:absolute;overflow:hidden;width:1px;height:1px;left:-9999px}.xterm-dim{opacity:1!important}.xterm-underline-1{text-decoration:underline}.xterm-underline-2{text-decoration:double underline}.xterm-underline-3{text-decoration:wavy underline}.xterm-underline-4{text-decoration:dotted underline}.xterm-underline-5{text-decoration:dashed underline}.xterm-overline{text-decoration:overline}.xterm-overline.xterm-underline-1{text-decoration:overline underline}.xterm-overline.xterm-underline-2{text-decoration:overline double underline}.xterm-overline.xterm-underline-3{text-decoration:overline wavy underline}.xterm-overline.xterm-underline-4{text-decoration:overline dotted underline}.xterm-overline.xterm-underline-5{text-decoration:overline dashed underline}.xterm-strikethrough{text-decoration:line-through}.xterm-screen .xterm-decoration-container .xterm-decoration{z-index:6;position:absolute}.xterm-screen .xterm-decoration-container .xterm-decoration.xterm-decoration-top-layer{z-index:7}.xterm-decoration-overview-ruler{z-index:8;position:absolute;pointer-events:none;top:0;right:0}.xterm-decoration-top{z-index:2;position:relative}.xterm .xterm-scrollable-element>.scrollbar{cursor:default}.xterm .xterm-scrollable-element>.scrollbar>.scra{cursor:pointer;font-size:11px!important}.xterm .xterm-scrollable-element>.visible{opacity:1;z-index:11;background:0 0;transition:opacity .1s linear}.xterm .xterm-scrollable-element>.invisible{opacity:0;pointer-events:none}.xterm .xterm-scrollable-element>.invisible.fade{transition:opacity .8s linear}.xterm .xterm-scrollable-element>.shadow{position:absolute;display:none}.xterm .xterm-scrollable-element>.shadow.top{display:block;box-shadow:var(--vscode-scrollbar-shadow,#000)0 6px 6px -6px inset;width:100%;height:3px;top:0;left:3px}.xterm .xterm-scrollable-element>.shadow.left{display:block;box-shadow:var(--vscode-scrollbar-shadow,#000)6px 0 6px -6px inset;width:3px;height:100%;top:3px;left:0}.xterm .xterm-scrollable-element>.shadow.top-left-corner{display:block;width:3px;height:3px;top:0;left:0}.xterm .xterm-scrollable-element>.shadow.top.left{box-shadow:var(--vscode-scrollbar-shadow,#000)6px 0 6px -6px inset}

/* 사이트 모드: 에이전트 마크는 공식 색 아님 */
:host{--color-agent-claude:var(--color-ink-secondary)}