/* ─────────────────────────────────────────────────────────────────────────────
   42-v2-panes.css — 프로젝트 **기본 뷰**(web/v2/panes.ts, #1719 원준 2026-08-20).
   VS Code·Cursor 의 도킹 분할 문법: 칸(pane) = 탭 줄 + 본문, 칸 사이 경계는 끌어서 조정(.v2-split 재사용).
   토큰은 01-base.css 것만 쓴다. 채운 파랑은 화면당 하나(세션 보내기) — 나머지는 테두리·글자색으로 말한다.
   ───────────────────────────────────────────────────────────────────────────── */

/* ── 골격 ── */
.pn-wrap { --pn-head-h: 42px; flex: 1; min-height: 0; display: flex; flex-direction: column; background: var(--bg); }
/* #4443 — **머리 줄 높이는 한 값**(원준 2026-09-30: "상단 탭 부분 높이 … 터미널 세션의 상단 바 부분이랑 같게 맞춰라"). 곁칸 탭 줄과
   세션 머리줄(.sc-head)이 같은 --pn-head-h 를 읽어, 두 열의 아래선이 한 줄로 이어진다(종전 37px vs 42px 로 5px 어긋나 있었다). */
@media (min-width: 901px) { .pn-wrap .sc-head { height: var(--pn-head-h); min-height: 0; padding-top: 0; padding-bottom: 0; } }
/* 사이드바 열의 폭 = 적어 둔 폭(--pn-side-w)과 상한 가운데 작은 쪽(#3870). 상한 = 격자 폭 - 세션 최소 폭 360px - 손잡이 6px,
   하한 220px(web/lib/side-card-geom.ts sideCap 과 같은 식). 상한을 **그릴 때** 맞추므로 격자가 잠깐 좁아져도 적어 둔 폭은
   깎이지 않고, 격자가 다시 넓어지면 제 폭으로 돌아온다. */
/* --pn-side-w 의 340 은 곁칸 기본 폭 SIDE_DEF(web/lib/side-card-geom.ts)를 옮겨 적은 첫 페인트 값이다 — 스크립트가 곧 덮는다. 바꾸면 같이 바꾼다. */
.pn-body { --pn-side-w: 340px; --pn-side-fit: min(var(--pn-side-w), max(220px, calc(100% - 366px))); position: relative; flex: 1; min-height: 0; display: grid; grid-template-columns: minmax(0, 1fr) 6px var(--pn-side-fit); background: var(--line); }
.pn-body.no-side { grid-template-columns: minmax(0, 1fr) 0 0; }
/* 접힌 곁칸을 다시 펴는 손잡이 — 문패의 [칸] 버튼을 빼면서(원준 2026-08-20) 유일한 복구 통로.
   격자 칸을 안 차지하게 오른쪽 위에 띄운다(가운데 칸 탭 줄과 같은 높이 — 줄의 일부처럼 읽히게). */
.pn-side-reopen { position: absolute; top: 0; right: 0; z-index: 5; display: inline-flex; align-items: center; justify-content: center; width: 28px; height: calc(var(--pn-head-h, 42px) - 1px); border: 0; border-left: 1px solid var(--line); border-bottom: 1px solid var(--line); background: var(--bg); color: var(--muted-2); cursor: pointer; }
.pn-side-reopen:hover { color: var(--blue); background: var(--bg-punch); }
.pn-side-reopen svg { transform: rotate(180deg); }
/* ⚠ 격자 칸의 기본 min-height 는 auto 라 **내용이 칸을 밀어 늘린다** — 세션 화면처럼 자연 높이가 큰 것이
   들어오면 아래 칸(세션 서랍)이 화면 밖으로 나간다(실측 2026-08-20: 900px 뷰포트에서 칸이 2625px). 0 으로 못 박는다. */
.pn-body > * { min-height: 0; }
.pn-col { --pn-bottom-h: 240px; min-width: 0; min-height: 0; display: flex; flex-direction: column; background: var(--bg); }
.pn-col.no-bottom > .pn-pane[data-zone="bottom"] { display: none; }

.pn-pane { min-height: 0; min-width: 0; display: flex; flex-direction: column; background: var(--bg); }
.pn-pane[data-zone="main"] { flex: 1; }
.pn-pane[data-zone="bottom"] { height: var(--pn-bottom-h); flex: none; border-top: 1px solid var(--line); }
/* #4443 — overflow: clip: 곁칸 안의 것(독 · 이름표 · [더보기])은 곁칸 밖으로 넘치지 않는다. 자동으로 가리기의 독은 테두리 밖으로
   미끄러져 나가 숨는데, 곁칸이 안 자르면 그 상자가 탭 칸(.v2-tabpane, overflow:auto)의 넘침에 더해져 탭 칸 전체에 스크롤바가 섰다
   (리뷰 실측: 아래 +50px · 오른쪽 +50px). hidden 이 아니라 clip — 곁칸이 스크롤 상자가 되면 숨은 독에 초점이 들어갈 때 곁칸이 굴러간다.
   곁칸 밖에 떠야 하는 것(우클릭 메뉴 · 탭/독 끌기 조각 · 팝오버)은 body 에 붙어 여기에 안 걸린다. */
/* hidden 먼저 — clip 을 모르는 옛 사파리(15 이하)는 hidden 으로 자른다(가린 독의 넘침만은 막는다). */
.pn-pane[data-zone="side"] { position: relative; overflow: hidden; overflow: clip; border-left: 1px solid var(--line); }
/* #4443 곁칸 아래 독(3안)은 **내용 위에 떠 있다**(원준 10-02 «뒤에 그냥 뭐 없이 둥둥 떠있게»). 두께는 v2/pane-dock 이
   lib/pane-dock dockInset 으로 재서 --pn-dock-b 로 알린다(이음매 독 · 독 없음 = 0 — 아래 규칙이 모두 아무 일도 안 한다).
   종전엔 본문 전체를 그만큼 올려(padding-bottom) 독 뒤에 하얀 띠가 생기고 내용이 그 위에서 잘렸다. 이제 본문은 독 밑까지 흐르고 —
   · 목록(스크롤 상자)은 **끝에만** 그만큼 빈 자리를 둔다: 내용은 독 유리 뒤로 비치고, 마지막 줄도 독 위로 올려 볼 수 있다.
   · 맨 아래에 붙은 입력칸이 있는 앱(프로젝트 «태스크 추가» · 리브 입력창)은 앱 끝에 같은 빈 자리 — 그 칸은 늘 독 위에 선다.
   · 웹 · 붙은 앱 · 그린 HTML 처럼 우리가 못 미는 액자는 독이 그 위에 뜬다(독을 경계선으로 옮기면 비킨다). */
.pn-pane[data-zone="side"] > .pn-pane-body { padding: var(--pn-dock-t, 0px) var(--pn-dock-r, 0px) 0 var(--pn-dock-l, 0px); }
.pn-pane[data-zone="side"] :is(.pn-fbody, .pn-knlist, .pn-knr-scroll, .pn-tl .tl-scroll, .pn-prev, .pn-md, .pn-ed-pre, .pn-ed-pick2 .pn-flist, .pn-apps-grid, .fx-scroll)::after,
.pn-pane[data-zone="side"] :is(.pn-tk, .pn-liv)::after { content: ""; display: block; flex: none; grid-column: 1 / -1; height: var(--pn-dock-b, 0px); }
.pn-pane[data-zone="side"] .pn-ed-ta { padding-bottom: calc(12px + var(--pn-dock-b, 0px)); }
.pn-pane[hidden] { display: none; }
.pn-pane:focus { outline: none; }   /* 좁은 폭의 서랍으로 열릴 때 초점이 들어온다(tabindex -1) — 테두리는 안 그린다 */

/* ── 탭 줄 — 얇게, 그러나 무엇이 켜졌는지는 분명하게(활성 탭 위 파란 마디) ──
   ★ 줄은 두 조각이다: **미끄러지는 탭 띠(.pn-tabs)** + **못 박은 손잡이(.pn-tabtail — 모두 보기·＋·접기)**.
   종전엔 셋이 한 띠 안에 있어서, 탭이 칸 폭을 넘기는 순간 ＋·접기까지 같이 밀려 화면 밖으로 나갔다
   (원준 2026-08-20 신고 — 곁칸 기본 폭 339px 에 부품 9개면 띠가 884px, ＋는 x=1918 로 칸 밖이었다).
   손잡이를 띠 밖에 두면 탭이 몇 개든 제자리다. 가려진 탭은 [모두 보기]에서 켜거나 거기서 뺀다. */
.pn-tabbar { position: relative; flex: none; display: flex; align-items: stretch; height: var(--pn-head-h, 42px); background: var(--bg); border-bottom: 1px solid var(--line); }
.pn-tabbar[hidden] { display: none; }
.pn-tabbar.drop { background: var(--bg-punch); box-shadow: inset 0 -2px 0 var(--blue); }
/* #4443 탭 새 옷의 폭 예산 — 탭은 이전(아이콘 16 · 여백 9/12 · 간격 6 = 이름 + 43px)보다 먼저 접히지 않는다: 띠 안 여백 2+2 ·
   탭 사이 2 · 탭 = 6 + 칸 22 + 5 + 이름 + 7 = 이름 + 40px → 탭 n(≥2)개가 42n+2 ≤ 43n. 폭을 셈하는 쪽은 lib/pane-tabs stripRoom
   (안 여백·간격을 뺀다). 이 값을 바꾸면 pane-tabstrip-runtime 의 B1(예산) · B2(셈 = 실제) 가 잰다. */
.pn-tabs { flex: 1; min-width: 0; display: flex; align-items: center; gap: 2px; padding: 0 2px; overflow-x: auto; overscroll-behavior-x: contain; scrollbar-width: none; }
.pn-tabs::-webkit-scrollbar { display: none; }
.pn-tabtail { flex: none; display: flex; align-items: stretch; padding-right: 6px; background: inherit; }
/* ── 탭 한 장 (#3870 «곁칸 탭 관리», 원준 2026-09-30 — 사파리·크롬 문법) ──────────────────────────
   원준: "하나 닫고 하나씩 다 찾으러 다녀야 함 … 아이콘이 중앙이 맞는지도 살짝 헷갈림."
   · 폭은 JS 가 잰다(panes.ts fit · lib/pane-tabs planTabs): 들어가면 이름을 다 펴고, 모자라면 긴 이름부터 줄이고(말줄임),
     그래도 모자라면 켜진 탭만 이름을 남기고 아이콘으로 접는다(.compact). 여기서는 탭이 제 내용 폭(flex: none)으로 서고,
     JS 가 준 폭 안에서 이름이 말줄임으로 줄어드는 것만 정한다.
   · × 는 **아이콘 자리**에 겹쳐 선다 — 마우스를 올리면 아이콘이 × 로 바뀐다(사파리). 이름을 가리지 않고, 폭이 제각각이어도
     × 는 늘 탭의 왼쪽 끝이라 닫힌 탭 자리로 미끄러져 온 다음 탭의 × 가 커서 바로 밑에 온다.
   · 아이콘과 × 는 **같은 중심**이다: 아이콘 칸(16px)의 중심 = 왼쪽 여백 9 + 8 = 17px, × (20px)의 중심 = 7 + 10 = 17px.
     접힌 탭(34px = 9 + 16 + 9)도 같은 17px 이라 가운데다. 종전엔 접힌 탭 어깨에 번호(2·3·4)가 붙어 아이콘이 한쪽으로
     치우쳐 보였다 — 번호는 뺐다(뷰어는 이제 파일 종류 아이콘이고, 온전한 이름은 툴팁과 ⌄ 목록이 말한다). */
/* #4443 — 탭의 결은 1안 «곁칸 머리 독» 의 언어로(원준 2026-09-30: "탭이 있다는 디자인은 그대로 유지하되 색이나 언어는 1안 참고").
   · 앱마다 한 색(--ac, 셸이 탭마다 건다 — lib/pane-dock appColor): 아이콘은 흰 타일 위 앱 색 선(독 아이콘의 작은 판), 켜진 탭은 그 색으로
     옅게 물든 알약. 종전의 «회색 줄 + 켜진 탭 위 파란 마디» 대신 무엇이 켜졌는지를 **앱의 색**으로 말한다.
   · 기하는 그대로다(시험 pane-tabstrip-runtime G1–G4): 아이콘 칸 22px 을 왼쪽 여백 6px 에 두어 중심이 17px(× 의 중심과 같다),
     아이콘만 남은 탭은 6 + 22 + 6 = 34px(lib/pane-tabs TAB_METRICS.icon). */
.pn-tabwrap { position: relative; display: inline-flex; align-items: stretch; flex: none; min-width: 0; height: calc(var(--pn-head-h, 42px) - 13px); border-radius: 9px; transition: background-color .12s, box-shadow .12s; }
.pn-tabwrap:hover { background: color-mix(in srgb, var(--ac, var(--blue)) 7%, var(--bg)); }
.pn-tabwrap.on { background: color-mix(in srgb, var(--ac, var(--blue)) 12%, var(--bg)); box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--ac, var(--blue)) 26%, transparent); }
/* 이웃 사이의 가는 세로선 — 켜진 탭과 마우스를 올린 탭 양옆에서는 지운다(크롬). */
/* 이웃 사이의 가는 세로선은 뺐다 — 알약끼리는 틈(gap 2px)이 가른다. */
.pn-tab { display: flex; align-items: center; gap: 5px; width: 100%; min-width: 0; height: 100%; padding: 0 7px 0 6px; border: 0; border-radius: inherit; background: none; font: inherit; font-size: 12.5px; color: var(--muted-head); cursor: pointer; white-space: nowrap; }
.pn-tab:hover, .pn-tabwrap.on .pn-tab { color: var(--ink); }
.pn-tabwrap.on .pn-tab { font-weight: 700; }
.pn-tab:focus-visible { outline: 2px solid var(--blue); outline-offset: -3px; border-radius: 6px; }
.pn-tab-lead { flex: none; display: inline-flex; align-items: center; justify-content: center; width: 22px; height: 22px; border-radius: 7px; background: var(--surface); box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--ac, var(--muted-2)) 26%, var(--line)); color: var(--ac, var(--muted-2)); }
.pn-tab-lead .pn-i.sm { width: 14px; height: 14px; }
.pn-tab-t { min-width: 0; overflow: hidden; text-overflow: ellipsis; }
.pn-tab-x { position: absolute; left: 7px; top: 50%; margin-top: -10px; display: inline-flex; align-items: center; justify-content: center; width: 20px; height: 20px; padding: 0; border: 0; border-radius: 5px; background: none; color: var(--muted-2); cursor: pointer; opacity: 0; pointer-events: none; }
.pn-tab-x:hover { background: var(--line); color: var(--ink); }
.pn-tab-x .pn-i { stroke-width: 2; }
/* 마우스를 올렸거나 키보드 초점이 섰으면 아이콘 자리가 × 가 된다. */
.pn-tabwrap:hover .pn-tab-x, .pn-tab:focus-visible + .pn-tab-x { opacity: 1; pointer-events: auto; }
.pn-tabwrap:hover:has(.pn-tab-x) .pn-tab-lead, .pn-tabwrap:has(.pn-tab:focus-visible):has(.pn-tab-x) .pn-tab-lead { visibility: hidden; }
/* 마우스가 있는 화면에선 × 가 **늘 눌린다**(보이는 것은 올렸을 때뿐). 탭을 닫으면 다음 탭이 커서 밑으로 미끄러져 오는데,
   브라우저가 그 탭의 호버를 다시 잴 때까지 × 가 눌리지 않으면 연달아 누른 두 번째 클릭이 «닫기» 가 아니라 «켜기» 가 된다.
   (그 자리를 누르려면 어차피 마우스가 거기 있고, 그러면 × 가 보인다.) 손가락 화면은 아래 규칙대로 켜진 탭만. */
@media (hover: hover) and (pointer: fine) { .pn-tab-x { pointer-events: auto; } }   /* 터치 겸용 노트북은 hover:hover 를 말한다 — 첫 탭이 안 보이는 × 에 먹히지 않게 pointer:fine 까지 */
/* 손가락 화면(호버가 없다) — 켜진 탭은 × 를 늘 보인다(누르면 켜지고, 켜진 탭에서 × 로 닫는다). */
@media (hover: none) {
  .pn-tabwrap.on .pn-tab-x { opacity: 1; pointer-events: auto; }
  .pn-tabwrap.on:has(.pn-tab-x) .pn-tab-lead { visibility: hidden; }
}
.pn-tab-add, .pn-pane-hide, .pn-tab-more { flex: none; display: inline-flex; align-items: center; justify-content: center; width: 30px; height: 100%; border: 0; background: none; color: var(--muted-2); cursor: pointer; }
.pn-tab-add:hover, .pn-pane-hide:hover, .pn-tab-more:hover { color: var(--blue); background: var(--bg-punch); }
/* [모두 보기]는 **이름이 줄었거나 접혔거나 넘칠 때만** 나온다(다 펴져 있으면 군더더기다). 아래를 가리키는 꺾쇠 = '여기 더 있다'
   (브라우저·에디터 탭 줄의 공통 문법). ⚠ 이 줄들은 위 공용 버튼 규칙보다 **뒤**에 있어야 한다 —
   명시도가 같아 앞에 두면 display: inline-flex 가 이겨 늘 보인다(2026-08-20 실측). */
.pn-tab-more { display: none; }
.pn-tab-more svg { transform: rotate(90deg); }
.pn-tabbar.shrunk .pn-tab-more, .pn-tabbar.compact .pn-tab-more, .pn-tabbar.has-more .pn-tab-more { display: inline-flex; }
/* 손잡이 왼쪽 그늘 = 왼쪽에 가려진 탭이 더 있다는 신호 */
.pn-tabbar.has-more .pn-tabtail { box-shadow: -9px 0 9px -7px rgba(16, 24, 40, .22); }

/* ── 아이콘만 남은 탭 — 접힌 줄의 켜지지 않은 탭 · 고정한 탭 (34px, 아이콘이 한가운데) ─────────────
   접힌 탭의 이름은 툴팁(title)과 손잡이의 [모두 보기]가 말한다. 켜진 탭은 접혀도 이름을 지킨다
   (지금 보는 것이 무엇인지는 접혀도 남아야 한다). 고정한 탭은 켜져도 아이콘만(크롬). */
.pn-tabbar.compact .pn-tabwrap:not(.on) .pn-tab, .pn-tabwrap.pinned .pn-tab { gap: 0; padding: 0 6px; justify-content: center; }
.pn-tabbar.compact .pn-tabwrap:not(.on) .pn-tab-t, .pn-tabwrap.pinned .pn-tab-t { display: none; }
/* 아이콘만 남은 탭의 × — 아이콘 자리에 서면 탭 전체가 × 가 되어 **누르려다 닫는다**(34px 중 × 가 20px). 그래서 아이콘은 그대로
   두고 × 는 오른쪽 위 모서리의 작은 원으로 뜬다. 모두 같은 34px 라, 닫으면 다음 탭의 × 가 역시 커서 밑에 온다. */
.pn-tabbar.compact .pn-tabwrap:not(.on) .pn-tab-x { left: auto; right: 1px; top: 3px; margin-top: 0; width: 15px; height: 15px; border-radius: 50%; background: var(--muted-2); color: var(--bg); }
.pn-tabbar.compact .pn-tabwrap:not(.on) .pn-tab-x .pn-i { width: 9px; height: 9px; stroke-width: 2.4; }
.pn-tabbar.compact .pn-tabwrap:not(.on) .pn-tab-x:hover { background: var(--ink); color: var(--bg); }
.pn-tabbar.compact .pn-tabwrap:not(.on):hover .pn-tab-lead, .pn-tabbar.compact .pn-tabwrap:not(.on):has(.pn-tab:focus-visible) .pn-tab-lead { visibility: visible; }   /* 키보드로 옮겨 다닐 때도 아이콘이 남는다 */

/* ── 끌어 옮기기 (v2/pane-tabdrag) — 끄는 동안엔 × 대신 아이콘을 보인다(잡은 탭 밑에 늘 커서가 있어 × 가 떠 버린다). ── */
html.pn-tab-dragging, html.pn-tab-dragging * { cursor: grabbing !important; user-select: none; }
/* 끄는 동안 액자는 포인터를 못 받는다 — 세션 화면·웹·PDF 칸이 액자라, 그 위에서 놓으면 pointerup 이 액자 문서로 가 끌기가 안 끝났다
   (분할선 끌기 body.v2-splitting-x iframe 과 같은 방어). */
html.pn-tab-dragging iframe, html.pn-tab-dragging webview { pointer-events: none !important; }
html.pn-tab-dragging .pn-tab-x { opacity: 0 !important; pointer-events: none !important; }
html.pn-tab-dragging .pn-tab-lead { visibility: visible !important; }
html.pn-tab-dragging .pn-tabwrap:hover:not(.dragging) { background: none; }
.pn-tabwrap.lifted { opacity: .38; }
/* 줄 밖으로 끌어낸 탭 — 탭 모양 그대로 커서를 따라온다. */
.pn-tab-ghost { position: fixed; z-index: 1000; left: 0; top: 0; display: flex; max-width: 220px; height: calc(var(--pn-head-h, 42px) - 13px); border: 1px solid var(--line); border-radius: 9px; background: var(--surface); box-shadow: 0 10px 28px rgba(var(--shadow-ink), .20), 0 2px 6px rgba(var(--shadow-ink), .10); pointer-events: none; overflow: hidden; }
.pn-tab-ghost .pn-tab { color: var(--ink); font-weight: 700; }
/* 다른 칸 줄에 끼울 자리 */
.pn-tab-caret { position: absolute; top: 6px; bottom: 6px; width: 2px; border-radius: 1px; background: var(--blue); pointer-events: none; z-index: 3; }

/* 세션 탭 — 부품 탭과 한 줄에 서지만 결이 다르다: **상태점 + 이름**, 닫기(×)는 없다(세션은 '열어 둔 문서'가
   아니라 프로젝트에 속한 실체다). 이름이 길어도 탭 줄이 무너지지 않게 폭을 묶는다. */
.pn-stab { max-width: 190px; padding-right: 12px; }
.pn-stab .ell { min-width: 0; }
.pn-stab .v2-dot { flex: none; }
.pn-stab.new { color: var(--muted-head); }
.pn-stab.new:hover, .pn-tabwrap.on .pn-stab.new { color: var(--blue); }
.pn-pane[data-zone="side"] .pn-pane-hide svg { transform: rotate(0deg); }

.pn-pane-body { flex: 1; min-height: 0; position: relative; display: flex; flex-direction: column; }
.pn-pane-empty { margin: auto; padding: 24px; text-align: center; }
.pn-part { flex: 1; min-height: 0; display: flex; flex-direction: column; }
.pn-part[hidden] { display: none; }

/* ── 문패 ──
   ⭐ 문패는 **한 줄**이다(원준 2026-08-26: "너무 높이 많이 차지해"). 종전엔 눈썹줄이 제목 위에 한 줄을 더 먹어
   머리가 ~85px 였다. 눈썹에 있던 세션 수·할 일·지식은 각자의 칸이 이미 말하는 숫자라 문패에서 뺐고(panes.ts
   paintDoor), 남은 좌표(#id)·상태는 제목과 **같은 줄**에 선다.
   ⚠ 위 머리말이 말하던 캔버스 문패 `.stu-door` 는 지금 코드에 없다 — 맞출 짝이 사라졌으므로 그 제약도 없다. */
.pn-door { flex: none; display: flex; align-items: center; justify-content: space-between; gap: 16px; padding: 10px 24px; border-bottom: 1px solid var(--line); }
.pn-door-l { display: flex; align-items: baseline; gap: 10px; min-width: 0; }
/* (원준 2026-08-20) 알약 폐지 — 좌상단을 비워 둘 이유가 없다. */
.pn-eyebrow { display: flex; align-items: center; gap: 7px; font-size: 12.5px; color: var(--ink-sub); flex: none; }
.pn-eyebrow .sep { color: var(--muted-2); }
.pn-state.run { color: var(--blue); font-weight: 700; }
.pn-state.done { color: var(--mint-deep); font-weight: 700; }
.pn-state.todo { color: var(--muted); }
/* [세션 옮기기](#3778, 원준 2026-09-19) — 꼬리표(#번호 · 상태) 바로 뒤에 서는 작은 테두리 단추. 글자 크기는 꼬리표와 같다.
   테두리를 두는 이유: ghost(테두리 없음)면 회색 글자 사이에 흩어져 단추로 안 읽힌다 — 문패 단추가 한 번 밟은 신고
   (원준 2026-08-20 «거의 안 보인다»). 좁은 칸(≤600px)에서는 글자를 접고 아이콘만 남긴다(이름은 aria-label 이 말한다). */
.pn-move { display: inline-flex; align-items: center; gap: 5px; height: 24px; margin-left: 4px; padding: 0 9px;
  border: 1px solid var(--line-net); border-radius: 7px; background: var(--bg); color: var(--ink-sub);
  font: inherit; font-size: 12.5px; font-weight: 600; white-space: nowrap; cursor: pointer; }
.pn-move .pn-i { color: var(--muted-2); }
.pn-move:hover { border-color: var(--blue); color: var(--blue); background: var(--bg-tint); }
.pn-move:hover .pn-i { color: var(--blue); }
.pn-move:focus-visible { outline: 2px solid var(--blue); outline-offset: 1px; }
@media (max-width: 600px) { .pn-move { padding: 0 6px; } .pn-move-t { display: none; } }
/* [세션 복제](#4135, 원준 2026-09-27) — [세션 옮기기] 와 같은 단추(.pn-move)이고 그 앞에 선다. 둘 사이 간격만 좁힌다
   (.pn-move 의 왼쪽 여백 4px + 줄 간격 7px 가 두 번 들어가면 두 단추가 남남처럼 떨어진다). */
.pn-fork + .pn-move { margin-left: -1px; }
/* 문패가 좁으면(창이 좁거나 곁칸을 넓혔을 때) 세션 단추 둘의 글자를 접어 **제목에 자리를 돌려준다**. 폭은 창이 아니라 문패를
   잰다(@container) — 곁칸을 넓히면 창은 그대로인데 문패만 좁아진다. 단추가 하나 늘면서 1024px 창(문패 626px)에서 제목이
   한 글자 폭으로 눌렸다(스테이지 실측). 접은 뒤의 이름은 aria-label·title 이 말한다(≤600px 창의 기존 규칙과 같은 모양). */
.pn-door { container-type: inline-size; container-name: pndoor; }
@container pndoor (max-width: 820px) { .pn-move { padding: 0 6px; } .pn-move .pn-move-t { display: none; } }
/* 확인 창 — anchoredPopover 는 자리만 잡는다(배경·테두리·그림자는 패널이 갖는다, 45-v2-side-swap.css .sw-pop 과 같은 규약). */
.fk-pop { width: 340px; padding: 16px 16px 14px; background: var(--bg); border: 1px solid var(--line); border-radius: 12px;
  box-shadow: 0 12px 32px rgba(var(--shadow-ink), .16);
  /* 한글은 낱말 단위로 줄을 바꾼다 — 글자 단위면 «만듭니/다.» 처럼 끝 글자 하나가 다음 줄로 떨어진다(스테이지 실측). */
  word-break: keep-all; overflow-wrap: anywhere; }
.fk-h b { font-size: 14px; color: var(--ink); }
.fk-name { margin: 2px 0 0; font-size: 12.5px; color: var(--ink-sub); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.fk-sub { margin: 10px 0 0; font-size: 13px; line-height: 1.55; color: var(--ink); }
.fk-list { margin: 8px 0 0; padding: 8px 10px; list-style: none; display: flex; flex-direction: column; gap: 6px;
  border-radius: 9px; background: var(--bg-tint); }
.fk-list li { display: flex; align-items: flex-start; gap: 7px; font-size: 12.5px; line-height: 1.5; color: var(--ink-sub); }
.fk-list li .pn-i { flex: none; margin-top: 3px; color: var(--blue); }
.fk-note { margin: 10px 0 0; font-size: 12.5px; line-height: 1.5; color: var(--ink-sub); }
.fk-note.bad { color: var(--danger); }
.fk-note[hidden] { display: none; }
.fk-act { margin-top: 12px; display: flex; justify-content: flex-end; gap: 8px; }
.fk-go { gap: 6px; }
.fk-go .pn-i { color: currentColor; }
.fk-go[disabled], .fk-act .btn[disabled] { opacity: .6; cursor: default; }
@media (max-width: 600px) { .fk-pop { width: min(340px, calc(100vw - 24px)); } }
.pn-title { margin: 0; min-width: 0; font-size: 25px; font-weight: 800; letter-spacing: -.022em; line-height: 1.22; }
/* 제목이 다시 왼쪽 끝이다(원준 2026-09-03, 순서 = 이름 › 번호 › 상태) — 링크 판의 좌측 패딩 8px 만큼
   당겨 **글자**가 문패 왼쪽에 딱 맞게 선다(패딩까지 맞추면 글자가 8px 안쪽으로 들어가 보인다). */
.pn-door-l .pn-title-btn { margin-left: -8px; }
/* 이름이 길면 이름이 줄고, 꼬리표(#번호 · 상태)는 끝까지 남는다 — 좌표를 잃으면 어느 프로젝트인지 못 읽는다. */
.pn-door-l .pn-title { flex: 0 1 auto; }
/* 제목 = **프로젝트 전체 화면으로 가는 링크**(원준 2026-08-26). 종전엔 눌러서 이름을 고치는 자리였다 —
   이름 편집은 사이드바 줄 더블클릭으로 갔고, 여기는 링크의 문법을 그대로 쓴다(커서 pointer, 밑줄 대신 은은한 판). */
.pn-title-btn { display: inline-flex; align-items: center; gap: 8px; max-width: 100%; padding: 2px 8px;
  border: 0; border-radius: 9px; background: none; font: inherit; color: inherit; text-align: left;
  text-decoration: none; cursor: pointer; }
/* ⚠ `overflow: hidden` 은 **패딩 상자**에서 자른다 — 25px·800 굵기에 letter-spacing -.022em 까지 겹치면
   마지막 글자의 잉크가 제 advance 폭을 넘어서(한글 받침 ㅇ·ㄱ·ㅅ 에서 특히) 그 경계에 그대로 썰린다.
   실측(원준님 2026-09-09): 「자잘한 UI 수정」의 '정' · 「프로젝트 자동 이름짓기」의 '기' · 「Lively Gateway 정합성」의 '성'
   — 이름 끝이 한글인 프로젝트는 사실상 전부 걸린다(말줄임이 필요없는 짧은 이름에서도 난다).
   그래서 **자르는 자리를 잉크 밖으로** 패딩만큼 밀고, 같은 크기의 음수 마진으로 배치는 종전 그대로 둔다
   (알약 폭·아이콘 간격이 안 변한다). 말줄임은 그대로 산다 — 패딩 상자가 넓어질 뿐 내용 폭은 그대로다. */
.pn-title-btn .pn-title-t { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; min-width: 0;
  padding: .08em .12em; margin: -.08em -.12em; }
/* 프로젝트 아이콘 — 이 굵은 글자가 세션 이름이 아니라 **프로젝트 이름**임을 말한다. 글자보다 조용하게. */
.pn-title-ic { width: 20px; height: 20px; flex: none; fill: none; stroke: var(--muted-2); stroke-width: var(--ic-stroke);
  stroke-linecap: round; stroke-linejoin: round; }
.pn-title-btn:hover { background: var(--bg-punch); box-shadow: inset 0 0 0 1px var(--line-net); }
.pn-title-btn:hover .pn-title-ic { stroke: var(--blue); }
.pn-title-btn:hover .pn-title-t { color: var(--blue); }
.pn-title-btn:focus-visible { outline: 2px solid var(--blue); outline-offset: 1px; }
/* 이름 고치기 = **연필**(원준 2026-09-03). 제목 클릭은 이동으로 남기고 편집은 이 단추가 쥔다 —
   생김새·손짓 모두 세션 이름의 연필과 같다(36-chat.css .sc-title-penbtn). 손을 올렸을 때만 나타난다. */
.pn-title-penbtn { display: inline-flex; align-items: center; justify-content: center; width: 26px; height: 26px; margin-left: 2px;
  vertical-align: middle; border: 0; background: none; padding: 0; border-radius: 6px; cursor: pointer;
  opacity: 0; transition: opacity .12s ease; flex: none; }
.pn-title:hover .pn-title-penbtn, .pn-title-penbtn:focus-visible { opacity: 1; }
.pn-title-penbtn:hover { background: var(--bg-tint); }
.pn-title-penbtn:hover .pn-title-pen { stroke: var(--blue); }
.pn-title-pen { width: 16px; height: 16px; flex: none; fill: none; stroke: var(--muted); stroke-width: var(--ic-stroke);
  stroke-linecap: round; stroke-linejoin: round; }
.pn-title-in { font: inherit; width: min(46ch, 46vw); margin-left: -8px; padding: 2px 8px;
  border: 1px solid var(--blue); border-radius: 9px; background: var(--bg); color: var(--ink); }
.pn-title-in:focus { outline: none; box-shadow: 0 0 0 3px color-mix(in srgb, var(--blue-fill) 18%, transparent); }
.pn-title-in:disabled { opacity: .6; }
.pn-door-r { display: flex; align-items: center; gap: 8px; flex: none; }
/* 얼굴 줄(#2116) — **[공유] 바로 왼쪽에 상주**한다(구글 문서와 같은 자리). 겹쳐 세워 자리를 아끼되
   첫 얼굴은 왼쪽으로 새지 않게 여백을 되돌린다. 최대 3명, 넘으면 마지막 칸이 `+N` 이 된다(panes.ts FACE_MAX). */
.pn-faces { display: inline-flex; align-items: center; margin-right: 4px; }
/* ⚠ 얼굴은 **글자 한 자를 가운데 세우는 상자**다 — width·height·radius 만 주면 이니셜이 좌상단 베이스라인에
   그대로 얹힌다(원준 2026-08-26 "'윤' 글자가 가운데정렬이 안되자나"). 다른 얼굴 클래스(v2-ss-face·v2-wscard-face)가
   쓰는 것과 같은 처방을 쓴다: inline-grid + place-items:center + 글자 크기·굵기·색까지 여기서 못 박는다. */
.pn-face { width: 26px; height: 26px; border-radius: 50%; border: 2px solid var(--bg); margin-left: -6px;
  box-sizing: border-box; display: inline-grid; place-items: center; overflow: hidden; flex: none;
  font-size: 11px; font-weight: 700; line-height: 1; color: var(--on-fill); }
.pn-face > img { width: 100%; height: 100%; object-fit: cover; display: block; }
.pn-faces > .pn-face:first-child { margin-left: 0; }
.pn-face-more { background: var(--bg-tint); color: var(--muted); letter-spacing: -.02em; }

/* ── 아이콘·잔글씨 ── */
.pn-i { width: 16px; height: 16px; fill: none; stroke: currentColor; stroke-width: var(--ic-stroke); stroke-linecap: round; stroke-linejoin: round; flex: none; }
.pn-i.sm { width: 13px; height: 13px; }
.pn-i.xs { width: 11px; height: 11px; }
.pn-i.big { width: 26px; height: 26px; stroke-width: 1.5; color: var(--muted-3); }
.pn-fine { font-size: 11.5px; color: var(--muted); }
.pn-empty { margin: auto; max-width: 320px; padding: 28px 20px; text-align: center; display: flex; flex-direction: column; align-items: center; gap: 7px; }
.pn-empty b { font-size: 13.5px; }
.pn-empty p { margin: 0; line-height: 1.55; }
.pn-head { flex: none; display: flex; align-items: center; gap: 8px; padding: 9px 12px 7px; }
.pn-head.end { justify-content: flex-end; border-top: 1px solid var(--line-row); }
.ell { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.ell2 { display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden; }
.ell1 { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; min-width: 0; }

/* ── 팝오버(칸 고르기·보기 메뉴) ──
   ⚠ anchoredPopover 는 **위치만** 잡는다(.dash-pop = position:fixed·z-index). 배경·테두리·그림자는 패널이
   직접 가져야 한다 — 안 주면 글자가 본문 위에 투명하게 겹쳐 읽을 수 없다(원준 신고 2026-08-20). */
.pn-pop { min-width: 264px; max-width: 320px; max-height: 70vh; overflow-y: auto; padding: 8px;
  background: var(--bg); border: 1px solid var(--line); border-radius: 12px;
  box-shadow: 0 12px 32px rgba(var(--shadow-ink), .16); scrollbar-width: thin; }
.pn-pop-h { margin: 2px 6px 8px; font-size: 12px; color: var(--ink-sub); }
.pn-pop-list { display: flex; flex-direction: column; gap: 1px; }
.pn-pop-row { display: flex; align-items: flex-start; gap: 9px; padding: 8px 9px; border: 0; border-radius: 8px; background: none; font: inherit; text-align: left; color: var(--ink); cursor: pointer; }
.pn-pop-row:hover { background: var(--bg-punch); }
.pn-pop-row .n { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.pn-pop-row .n b { font-size: 12.5px; }
.pn-pop-row svg { margin-top: 2px; color: var(--muted-head); }
/* [모두 보기]의 한 줄 = **고르기(행) + 빼기(×)**. 띠에서 손이 안 닿는 탭도 여기선 늘 닿는다. */
.pn-pop-line { display: flex; align-items: stretch; gap: 2px; border-radius: 8px; }
.pn-pop-line.on { background: var(--bg-tint); }
.pn-pop-line > .pn-pop-row { flex: 1; min-width: 0; }
.pn-pop-line.on > .pn-pop-row b { color: var(--blue); }
.pn-pop-x { flex: none; width: 28px; border: 0; border-radius: 8px; background: none; color: var(--muted-3); cursor: pointer; }
.pn-pop-x:hover { background: var(--bg-punch); color: var(--coral-text); }
.pn-pop-foot { margin-top: 6px; padding-top: 7px; border-top: 1px solid var(--line-row); display: flex; justify-content: flex-end; gap: 14px; }
.pn-check { width: 15px; height: 15px; margin-top: 1px; border: 1.5px solid var(--muted-3-line); border-radius: 4px; flex: none; }
.pn-check.on { border-color: var(--blue); background: var(--blue-fill); position: relative; }
.pn-check.on::after { content: ''; position: absolute; left: 4px; top: 1px; width: 4px; height: 8px; border: solid #fff; border-width: 0 2px 2px 0; transform: rotate(42deg); }

/* ══ 세션 — 위: 고른 세션 하나의 대화판 · 아래: 세션 서랍(타일) ═══════════════
   (원준 2026-08-20 "한 열에 여러 개가 동시에 보여서 정신이 하나도 없음")
   서랍 타일은 곁칸 자료 카드(.pn-fcard)와 **같은 문법**이다 — 아이콘 면 + 이름 + 잔글씨. 두 서랍이
   같은 모양이라 '여기 담겨 있는 것들'이라는 뜻이 한 번에 읽힌다. */
.pn-sessions { overflow: hidden; }
.pn-stage { flex: 1; min-height: 0; display: flex; flex-direction: column; overflow: hidden; }
.pn-stage > * { min-height: 0; }
.pn-stage-h { flex: none; display: flex; align-items: center; gap: 8px; padding: 12px 20px 10px; border-bottom: 1px solid var(--line-row); }
.pn-stage-h[hidden] { display: none; }
.pn-sname { font-size: 14px; font-weight: 700; min-width: 0; max-width: 42%; }
.pn-smeta { display: inline-flex; align-items: center; gap: 5px; font-size: 11.5px; color: var(--muted); flex: none; }
.pn-smeta .sep { color: var(--muted-3); }
.pn-swork { font-size: 11.5px; color: var(--ink-sub); min-width: 0; flex: 1; padding-left: 4px; }
.pn-sopen { font-size: 11.5px; color: var(--blue); text-decoration: none; flex: none; margin-left: auto; }
.pn-sopen:hover { text-decoration: underline; }

.pn-conv { flex: 1; min-height: 0; overflow: auto; padding: 14px 20px 10px; display: flex; flex-direction: column; gap: 14px; }
.pn-conv-none { margin: 0; }
.pn-msg { display: flex; gap: 10px; align-items: flex-start; font-size: 13px; line-height: 1.62; }
.pn-msg .who { flex: none; width: 22px; font-size: 10.5px; font-weight: 700; color: var(--muted); padding-top: 3px; }
.pn-msg.me .who { color: var(--ink-sub); }
.pn-msg .tx { min-width: 0; flex: 1; word-break: break-word; color: var(--ink); }
.pn-msg.me .tx { white-space: pre-wrap; font-weight: 600; }
.pn-msg.ai .tx { color: var(--ink-sub); }
.pn-msg.pend .tx { opacity: .6; }
.pn-msg .tx.pn-md { padding: 0; overflow: visible; font-size: 13px; }
.pn-keys { flex: none; display: flex; align-items: center; gap: 6px; padding: 0 20px 8px; }
.pn-keys[hidden] { display: none; }
.pn-wait-k { font-size: 11.5px; font-weight: 700; color: #9A6B12; margin-right: 2px; }
/* 새 세션 자리 — 홈 입력창과 **같은 카드**를 이 칸 가운데에 놓는다(원준 2026-08-20 "홈이랑 비슷한 느낌으로").
   카드 자체(.v2-launch*)는 40-v2.css 의 홈 것을 그대로 쓴다 — 여기서 정하는 건 '칸 안에 어떻게 놓이나'뿐이라
   홈 컴포저가 바뀌면 이 자리도 같이 바뀐다(같은 자리에서 같은 일을 하는 두 화면이 갈라지지 않게). */
.pn-newpane { flex: 1; min-height: 0; overflow: auto; display: flex; padding: 24px 22px 30px; }
.pn-launch { margin: auto; width: 100%; max-width: 820px; }   /* 홈과 같은 폭 — 아래 네 칸이 한 줄에 들어간다(40-v2.css .v2-home-launch 주석) */
.pn-launch .v2-h1 { margin: 0; font-size: 26px; font-weight: 750; letter-spacing: -.6px; line-height: 1.3; }
.pn-launch .v2-home-sub { font-size: 26px; }
.pn-launch .v2-launch { margin-top: 20px; }

.pn-sfoot { flex: none; padding: 4px 18px 14px; }
.pn-new { display: flex; align-items: flex-end; gap: 8px; padding: 9px 9px 9px 13px; border: 1px solid var(--line-net); border-radius: 12px; background: var(--bg); box-shadow: 0 1px 2px rgba(var(--shadow-ink), .05); }
.pn-new:focus-within { border-color: var(--blue); box-shadow: 0 0 0 3px rgba(45,107,240,.10); }
.pn-new-in { flex: 1; min-width: 0; border: 0; background: none; font: inherit; font-size: 13.5px; line-height: 1.5; resize: none; max-height: 180px; color: var(--ink); }
.pn-new-in:focus { outline: none; }
.pn-new-send { flex: none; width: 30px; height: 30px; border: 0; border-radius: 9px; background: var(--blue-fill); color: var(--on-fill); display: flex; align-items: center; justify-content: center; cursor: pointer; }
.pn-new-send:hover { background: var(--blue-fill-deep); }
.pn-new-send:disabled { background: var(--muted-3-line); cursor: default; }
/* 새 세션 창에 붙여넣은 첨부 — 보낼 것이 무엇인지 보내기 전에 보인다. */
.pn-att { display: flex; flex-wrap: wrap; gap: 5px; padding: 0 2px 7px; }
.pn-att[hidden] { display: none; }
.pn-att-c { display: inline-flex; align-items: center; gap: 4px; max-width: 190px; padding: 3px 5px 3px 7px;
  border: 1px solid var(--line-net); border-radius: 999px; background: var(--bg); font-size: 11px; color: var(--muted-head); }
.pn-att-c svg { flex: none; color: var(--muted-2); }
.pn-att-c .n { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.pn-att-x { flex: none; width: 15px; height: 15px; border: 0; border-radius: 50%; background: none; color: var(--muted-2); font-size: 9px; line-height: 1; cursor: pointer; }
.pn-att-x:hover { background: var(--bg-punch); color: var(--ink); }
.pn-newpane.drop-active { outline: 2px dashed var(--blue); outline-offset: -6px; }

/* ══ 자료 — 맥 파인더 문법(폴더·보기·정렬·다중선택) ═════════════════════════ */
.pn-files { overflow: hidden; outline: none; }
.pn-files.drop-active { outline: 2px dashed var(--blue); outline-offset: -6px; background: var(--bg-tint); }

/* 맨 위 안내 — 이 칸의 계약을 한 줄로. 조용하되 읽히게(본문보다 작고, 배경으로 구분). */
.pn-fnote { flex: none; display: flex; align-items: flex-start; gap: 7px; margin: 8px 12px 2px; padding: 8px 9px 9px 10px;
  border: 1px solid #DCE7FA; border-radius: 9px; background: var(--bg-sel); }
.pn-fnote[hidden] { display: none; }
.pn-fnote svg { flex: none; margin-top: 1px; color: var(--blue); }
.pn-fnote p { margin: 0; flex: 1; font-size: 11.5px; line-height: 1.5; color: var(--muted-head); }
.pn-fnote-x { flex: none; width: 18px; height: 18px; border: 0; border-radius: 5px; background: none; color: var(--muted-2); font-size: 11px; line-height: 1; cursor: pointer; }
.pn-fnote-x:hover { background: var(--bg-tint-2); color: var(--ink); }

.pn-fhead { flex: none; padding: 8px 12px 6px; display: flex; flex-direction: column; gap: 6px; }
.pn-frow1 { display: flex; align-items: center; gap: 8px; min-width: 0; }
.pn-fcrumbs { flex: 1; min-width: 0; display: flex; align-items: center; gap: 2px; overflow: hidden; }
.pn-fcrumb { flex: none; max-width: 140px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
  border: 0; border-radius: 6px; background: none; padding: 2px 5px; font: inherit; font-size: 12px; color: var(--muted-head); cursor: pointer; }
.pn-fcrumb:hover { background: var(--bg-punch); color: var(--ink); }
.pn-fcrumb.on { font-weight: 700; color: var(--ink); }
.pn-fcrumb.drop-in { background: var(--blue-fill); color: var(--on-fill); }
.pn-fcsep { flex: none; font-size: 11px; color: var(--muted-3); }
.pn-frow1 .pn-fine { flex: none; }
.pn-frow1 .pn-fine.sel { color: var(--blue); font-weight: 700; }

.pn-files:focus-visible .pn-fbody { box-shadow: inset 0 0 0 2px rgba(45,107,240,.28); border-radius: 9px; }   /* 키보드로 들어왔을 때만 — 이 칸이 키를 받는다 */

/* 도구줄은 **한 줄**(#3870) — 좁아지면 JS(fitTools)가 덜 중요한 것부터 .pn-fold 로 접고 [⋯] 에 모은다. 넘치는지 재려면
   줄이 넘쳐야 한다(nowrap + overflow). 글자는 한 크기(13px)·높이는 한 높이(28px) — 찾기칸만 크게 보이던 것(#3870 신고)을 맞춘다. */
.pn-ftools { display: flex; align-items: center; gap: 4px; flex-wrap: nowrap; overflow: hidden; min-width: 0; }
.pn-ftools > .pn-fold { display: none !important; }
.pn-fsp { flex: 1 1 0; min-width: 0; }
.pn-ftools .btn-text { flex: none; height: 28px; padding: 0 7px; border-radius: 7px; font-size: 13px; white-space: nowrap; }
.pn-ftools .btn-text:hover { background: var(--bg-punch); color: var(--ink); }
/* [＋ 올리기 ⌄] 분할 단추 — 한 덩이로 읽히고(사이 틈 0), 누르는 자리는 둘(큰 쪽 = 파일 창 곧바로 · ⌄ = 파일/폴더). 올리면 사이에 가는 선. */
.pn-upgrp { flex: none; display: inline-flex; align-items: center; border-radius: 7px; }
.pn-upgrp > .pn-up-main { border-radius: 7px 0 0 7px; padding-right: 5px; }
.pn-upgrp > .pn-up-car { width: 22px; padding: 0; border-radius: 0 7px 7px 0; display: inline-flex; align-items: center; justify-content: center; color: var(--muted-2);
  box-shadow: inset 1px 0 0 transparent; }
.pn-upgrp > .pn-up-car[hidden] { display: none; }
.pn-upgrp > .pn-up-main:has(+ .pn-up-car[hidden]) { border-radius: 7px; padding-right: 7px; }   /* 폴더 입력을 못 받치는 브라우저 — 한 단추 */
.pn-upgrp:hover > .pn-up-car { box-shadow: inset 1px 0 0 var(--line-net); }
.pn-upgrp > .pn-up-car[aria-expanded="true"], .pn-upgrp[aria-expanded="true"] > .pn-up-car { background: var(--bg-punch); color: var(--ink); }
.pn-fbtn { flex: none; height: 28px; min-width: 28px; padding: 0 6px; display: inline-flex; align-items: center; justify-content: center; gap: 4px;
  border: 1px solid var(--line-net); border-radius: 7px; background: var(--bg); font: inherit; font-size: 13px; color: var(--muted-head); cursor: pointer; white-space: nowrap; }
.pn-fbtn[hidden] { display: none; }
.pn-fbtn:hover, .pn-fbtn[aria-expanded="true"] { border-color: var(--blue); color: var(--ink); }
.pn-fbtn.wide { padding: 0 7px 0 9px; }
.pn-fbtn .pn-i.xs { color: var(--muted-2); }
.pn-fsize { flex: none; width: 62px; accent-color: var(--blue); }
.pn-fsize[hidden] { display: none; }

.pn-fbody { flex: 1; min-height: 0; overflow: auto; position: relative; padding: 2px 12px 16px; --pn-fsz: 110px; container-type: inline-size; }
.pn-fgrid { display: grid; grid-template-columns: repeat(auto-fill, minmax(var(--pn-fsz), 1fr)); gap: 10px; align-content: start; }
.pn-fcard { display: flex; flex-direction: column; align-items: center; gap: 5px; padding: 8px 5px 9px; border: 1px solid transparent; border-radius: 10px; background: none; font: inherit; color: var(--ink); cursor: default; user-select: none; }
.pn-fcard:hover { border-color: var(--line-net); background: var(--bg-tint); }
.pn-fcard.on { border-color: var(--blue); background: var(--bg-tint-2); }
.pn-fcard.drop-in { border-color: var(--blue); background: var(--bg-punch); box-shadow: inset 0 0 0 1px var(--blue); }
/* 잘라낸 것(⌘X) — 붙이면 옮겨진다는 표시로 흐리게(탐색기와 같다). */
.pn-fcard.cut > .pn-fic, .pn-frow2.cut > .pn-fic, .pn-fcard.cut > .pn-fname, .pn-frow2.cut > .pn-fname1 { opacity: .5; }
.pn-fic { width: 100%; aspect-ratio: 1 / .82; border: 1px solid var(--line); border-radius: 8px; background: var(--gray-bg); display: flex; align-items: center; justify-content: center; overflow: hidden; color: var(--muted-2); }
.pn-fic img { width: 100%; height: 100%; object-fit: cover; }
.pn-fic video { width: 100%; height: 100%; object-fit: cover; }
/* 폴더는 채운 그림이라 카드 테두리·바탕이 필요 없다 — 그림 자체가 덩어리다. */
.pn-fic.dir { border-style: none; background: none; }
.pn-folder { width: 76%; height: auto; filter: drop-shadow(0 1px 1.5px rgba(21,35,59,.10)) drop-shadow(0 3px 6px rgba(21,35,59,.10)); }
.pn-folder.sm { width: 20px; height: 20px; filter: none; }
.pn-fic.dir.sm { width: 20px; height: 20px; }
.pn-fcard.on .pn-folder, .pn-frow2.on .pn-folder { filter: drop-shadow(0 2px 4px rgba(45,107,240,.35)); }
.pn-fic.sm { width: 20px; height: 20px; flex: none; aspect-ratio: auto; border-radius: 5px; }
.pn-fic.sm svg { width: 13px; height: 13px; }
.pn-fname { font-size: 11.5px; font-weight: 600; line-height: 1.35; text-align: center; word-break: break-all; }
.pn-fmeta { display: inline-flex; gap: 4px; font-size: 10.5px; color: var(--muted); }
.pn-fmeta .sep { color: var(--muted-3); }

/* 목록 보기 — 파인더의 '목록'. 좁은 칸에선 종류 열이 먼저 접힌다. */
.pn-flist { display: flex; flex-direction: column; gap: 1px; }
.pn-frow2 { display: flex; align-items: center; gap: 8px; padding: 5px 7px; border: 1px solid transparent; border-radius: 7px; font-size: 12.5px; cursor: default; user-select: none; }
/* 손가락 입구 [⋯](#4088 후속) — 우클릭 메뉴와 같은 것. hover 없는 기기에서만 보인다(50-mobile.css). 카드는 오른쪽 위, 줄은 맨 끝. */
.pn-fcard, .pn-frow2 { position: relative; touch-action: manipulation; }
.pn-fmore { display: none; position: absolute; top: 2px; right: 2px; width: 32px; height: 32px; padding: 0; border: 0; border-radius: 8px;
  background: var(--bg); color: var(--muted); font: inherit; font-size: 16px; line-height: 1; cursor: pointer; align-items: center; justify-content: center; }
.pn-frow2 .pn-fmore { position: static; margin-left: auto; flex: none; }
.pn-fmore:active { background: var(--bg-punch); color: var(--ink); }
/* 세션 파일 칸(#4088 후속) — 우패널 탐색기(.v2-files)를 곁칸에 세운다. 머리줄은 타임라인 칸과 같은 트림. */
.pn-sessfiles .v2-aside-h { padding: 9px 12px 8px; }
.pn-frow2:hover { background: var(--bg-punch); }
.pn-frow2.on { border-color: var(--blue); background: var(--bg-tint-2); }
.pn-frow2.drop-in { border-color: var(--blue); background: var(--bg-punch); }
.pn-fname1 { flex: 1; min-width: 0; font-weight: 600; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.pn-fcol { flex: none; font-size: 11px; color: var(--muted); font-weight: 400; }
.pn-fcol.k { width: 40px; } .pn-fcol.s { width: 54px; text-align: right; } .pn-fcol.d { width: 58px; text-align: right; }
/* 제자리 이름 고치기 — 이름이 있던 자리를 그대로 입력칸이 받는다(자리가 안 흔들린다). */
.pn-frename { min-width: 0; width: 100%; border: 1px solid var(--blue); border-radius: 5px; padding: 1px 4px;
  background: var(--bg); font: inherit; font-size: 11.5px; font-weight: 600; color: var(--ink); text-align: center; }
.pn-frow2 .pn-frename { flex: 1; text-align: left; font-size: 12.5px; }
.pn-frename:focus { outline: none; box-shadow: 0 0 0 3px rgba(45,107,240,.14); }
.pn-fcard.editing, .pn-frow2.editing { border-color: var(--blue); background: var(--bg-tint); }
@container (max-width: 300px) { .pn-fcol.k { display: none; } }

/* 끌어 만든 사각형 — 파인더의 선택 상자. */
.pn-fmarq { position: absolute; z-index: 3; border: 1px solid var(--blue); background: rgba(45,107,240,.12); border-radius: 2px; pointer-events: none; }
.pn-fmarq[hidden] { display: none; }

/* 우클릭 메뉴 — 화면 어디서든 그 자리에. */
.pn-ctx { position: fixed; z-index: 90; min-width: 156px; padding: 4px; display: flex; flex-direction: column;
  border: 1px solid var(--line-net); border-radius: 10px; background: var(--bg); box-shadow: 0 10px 30px rgba(var(--shadow-ink), .18); }
.pn-ctx-i { text-align: left; border: 0; border-radius: 6px; background: none; padding: 6px 9px; font: inherit; font-size: 12.5px; color: var(--ink); cursor: pointer; }
.pn-ctx-i:hover { background: var(--bg-punch); }
.pn-ctx-i:disabled { color: var(--muted-3); cursor: default; background: none; }
.pn-ctx-i.danger { color: var(--danger); }
.pn-ctx-i.danger:hover { background: var(--danger-bg); }
.pn-ctx-sep { height: 1px; margin: 4px 6px; background: var(--line-row); }

/* ══ 지식 · 할 일 · 개요 · 타임라인 ══════════════════════════════════════════ */
.pn-knlist { flex: 1; min-height: 0; overflow: auto; padding: 0 10px 14px; display: flex; flex-direction: column; gap: 1px; }
.pn-knrow { display: flex; align-items: center; gap: 8px; padding: 8px 9px; border: 0; border-radius: 8px; width: 100%; text-align: left; background: none; font: inherit; font-size: 12.5px; text-decoration: none; color: var(--ink); cursor: pointer; }
.pn-knrow:hover { background: var(--bg-punch); }
.pn-knrow svg { color: var(--muted-2); }
.pn-knrow .n { min-width: 0; flex: 1; }
.pn-knrel { flex: none; font-size: 10.5px; padding: 1px 6px; border-radius: 999px; background: var(--gray-bg); color: var(--muted-head); }
.pn-knrel.prod { background: var(--ok-bg); color: var(--mint-deep); }

/* 끝냄 체크 — 프로젝트 상세(proj-settings)의 할 일 줄이 쓴다. 곁칸 태스크 부품은 아래 .pn-tk 가 그린다. */
.pn-tcheck { flex: none; width: 16px; height: 16px; margin-top: 1px; border: 1.5px solid var(--muted-3-line); border-radius: 5px; background: none; cursor: pointer; position: relative; }
.pn-tcheck:hover { border-color: var(--blue); }
.pn-tcheck.on { border-color: var(--mint-deep); background: var(--mint-deep); }
.pn-tcheck.on::after { content: ''; position: absolute; left: 4.5px; top: 1px; width: 4px; height: 8px; border: solid #fff; border-width: 0 2px 2px 0; transform: rotate(42deg); }

/* ══ 태스크(#4084) — 보는 세션이 속한 프로젝트의 태스크 ═══════════════════════════════════
   문법은 하나다: 줄을 누르면 그 줄의 속이 그 자리에서 펴지고, 쓰면 저절로 저장된다(본문·규칙 접이도, 태스크 줄도).
   채운 파랑은 화면에 하나 — «이 세션의 태스크» 카드의 [끝냈다고 표시]. 상태는 색 면이 아니라 점·글자로 말한다. */
.pn-tk { overflow: hidden; }
.pn-tk .grow { flex: 1; }
.pn-tk-head { flex: none; display: flex; flex-direction: column; gap: 7px; padding: 11px 12px 9px; }
.pn-tk-head-row { display: flex; align-items: center; gap: 6px; color: var(--muted-head); }
.pn-tk-name { flex: 1; min-width: 0; padding: 0; border: 0; background: none; font: inherit; font-size: 13.5px; font-weight: 800; letter-spacing: -.01em; color: var(--ink); text-align: left; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; cursor: pointer; }
.pn-tk-name:hover { color: var(--blue); }
.pn-tk-count { flex: none; }
.pn-tk-bar { height: 3px; border-radius: 999px; background: var(--gray-bg); overflow: hidden; }
.pn-tk-bar-fill { height: 100%; width: 0; background: var(--mint-deep); transition: width .25s ease; }

.pn-tk-folds { flex: none; border-bottom: 1px solid var(--line-row); padding-bottom: 2px; }
.pn-tk-fold { display: flex; align-items: center; gap: 7px; width: 100%; height: 30px; padding: 0 12px; border: 0; background: none; font: inherit; text-align: left; color: var(--ink); cursor: pointer; }
.pn-tk-fold:hover { background: var(--bg-punch); }
.pn-tk-fold-l { flex: none; font-size: 11.5px; font-weight: 700; color: var(--muted-head); }
.pn-tk-fold-ex { flex: 1; font-size: 11.5px; color: var(--muted); }
.pn-tk-chev { color: var(--muted-3); transition: transform .15s ease; }
.pn-tk-foldwrap.open .pn-tk-chev, .pn-tk-gh.open .pn-tk-chev, .pn-tk-card.open .pn-tk-chev { transform: rotate(90deg); }
.pn-tk-editor { margin: 2px 12px 8px; border: 1px solid var(--line-net); border-radius: 8px; background: var(--surface); display: flex; flex-direction: column; overflow: hidden; }
.pn-tk-editor:focus-within { border-color: var(--blue); box-shadow: 0 0 0 3px rgba(45,107,240,.10); }
.pn-tk-ta { display: block; width: 100%; box-sizing: border-box; margin: 0; padding: 8px 10px; border: 1px solid var(--line-net); border-radius: 8px; background: var(--surface); font: inherit; font-size: 12px; line-height: 1.6; color: var(--ink); resize: vertical; min-height: 64px; }
.pn-tk-ta:focus { outline: none; border-color: var(--blue); box-shadow: 0 0 0 3px rgba(45,107,240,.10); }
.pn-tk-editor .pn-tk-ta.big { height: 236px; min-height: 120px; max-height: 60vh; border: 0; border-radius: 0; background: none; }
.pn-tk-editor .pn-tk-ta.big:focus { box-shadow: none; }
.pn-tk-ta:disabled { color: var(--muted); }
/* 발치는 좁으면 두 줄로 흐른다 — 충돌 안내(긴 문장) + 단추 둘이 한 줄에 눌려 글자가 세로로 꺾이지 않게. */
.pn-tk-editor-foot { display: flex; flex-wrap: wrap; align-items: center; gap: 2px 8px; min-height: 30px; padding: 3px 8px 3px 10px; border-top: 1px solid var(--line-row); }
.pn-tk-editor-foot .pn-fine { white-space: nowrap; }
.pn-tk-editor-acts { display: inline-flex; align-items: center; gap: 4px; margin-left: auto; }
.pn-tk-link { padding: 2px 4px; font-size: 11.5px; color: var(--blue); display: inline-flex; align-items: center; gap: 4px; white-space: nowrap; }
.pn-tk-link:disabled { color: var(--muted-3); cursor: default; }

.pn-tk-list { flex: 1; min-height: 0; overflow: auto; padding: 0 0 8px; display: flex; flex-direction: column; }
.pn-tk-card { flex: none; margin: 10px 10px 4px; padding: 11px 12px; border: 1px solid var(--line-note); border-radius: 10px; background: var(--bg-tint); display: flex; flex-direction: column; gap: 7px; }
.pn-tk-card-h { display: flex; align-items: center; gap: 6px; font-size: 11.5px; font-weight: 700; color: var(--muted-head); }
.pn-tk-card-st { display: inline-flex; align-items: center; gap: 5px; font-weight: 600; color: var(--ink-sub); }
.pn-tk-card-n { display: flex; align-items: flex-start; gap: 6px; width: 100%; padding: 0; border: 0; background: none; font: inherit; font-size: 14px; font-weight: 700; line-height: 1.35; color: var(--ink); text-align: left; cursor: pointer; }
.pn-tk-card-n > span { flex: 1; min-width: 0; overflow-wrap: anywhere; }
.pn-tk-card-n .pn-tk-chev { margin-top: 5px; }
.pn-tk-card-n:hover { color: var(--blue); }
.pn-tk-card-m { display: flex; align-items: center; gap: 7px; font-size: 11.5px; color: var(--muted); }
.pn-tk-card-m .sep { color: var(--muted-3-line); }
.pn-tk-card-a { display: flex; align-items: center; gap: 10px; margin-top: 2px; }
.pn-tk-card-a .pn-fine { line-height: 1.4; }
.pn-tk-card .pn-tk-detail { padding: 2px 0 0; }

.pn-tk-gh { flex: none; display: flex; align-items: center; gap: 6px; width: 100%; padding: 10px 12px 4px; border: 0; background: none; font: inherit; font-size: 11.5px; font-weight: 700; color: var(--muted-head); text-align: left; }
.pn-tk-gh.fold { cursor: pointer; }
.pn-tk-gh .n { color: var(--muted-3); font-weight: 600; }
.pn-tk-row { flex: none; display: flex; align-items: center; gap: 9px; padding: 0 12px; min-height: 32px; }
.pn-tk-row:hover, .pn-tk-row.open { background: var(--bg-punch); }
.pn-tk-row.done .pn-tk-rname, .pn-tk-row.done .pn-tk-sub-n { color: var(--muted); text-decoration: line-through; }
.pn-tk-rname { flex: 1; min-width: 0; display: flex; align-items: center; height: 32px; padding: 0; border: 0; background: none; font: inherit; font-size: 12.5px; color: var(--ink); text-align: left; cursor: pointer; }
.pn-tk-row.open .pn-tk-rname { font-weight: 600; }
.pn-tk-row.sub { padding: 0; min-height: 28px; }
.pn-tk-row.sub:hover { background: none; }
.pn-tk-sub-n { flex: 1; font-size: 12.5px; }
/* 상태 글리프 — 할 일(점선 고리) · 진행 중(반 채움) · 완료(민트 채움 + 체크). 누르면 끝냄을 뒤집는다. */
.pn-tk-st { flex: none; position: relative; width: 15px; height: 15px; padding: 0; border: 1.6px dashed var(--muted-3-line); border-radius: 50%; background: none; box-sizing: border-box; cursor: pointer; }
.pn-tk-st:hover { border-color: var(--blue); }
.pn-tk-st:focus-visible { outline: 2px solid var(--blue); outline-offset: 2px; }
.pn-tk-st.doing { border: 1.6px solid var(--blue); background: linear-gradient(90deg, var(--blue) 50%, transparent 50%); }
.pn-tk-st.done { border: 1.6px solid var(--mint-deep); background: var(--mint-deep); }
.pn-tk-st.done::after { content: ''; position: absolute; left: 3.6px; top: .8px; width: 3.4px; height: 7px; border: solid var(--on-fill); border-width: 0 2px 2px 0; transform: rotate(42deg); }
.pn-tk-st.static { width: 13px; height: 13px; cursor: default; pointer-events: none; }
.pn-tk-st.static.done::after { left: 2.8px; top: .2px; height: 6px; }
/* 줄 끝 칩 — 맡은 세션(.on, 상태 점 포함)이면 그 세션으로, 없으면 [세션 열기]. 이름이 먼저라 칩은 절반을 넘지 않는다. */
.pn-tk-chip { flex: none; max-width: 45%; display: inline-flex; align-items: center; gap: 5px; padding: 1px 8px 1px 7px; border: 1px solid var(--muted-3-line); border-radius: 999px; background: none; font: inherit; font-size: 11px; line-height: 16px; color: var(--muted-head); white-space: nowrap; cursor: pointer; }
.pn-tk-chip:hover:not(:disabled) { border-color: var(--blue); color: var(--blue); }
.pn-tk-chip:focus-visible { outline: 2px solid var(--blue); outline-offset: 1px; }
.pn-tk-chip:disabled { cursor: default; }
.pn-tk-chip.on { border-color: transparent; background: var(--ok-bg); color: var(--mint-deep); }
.pn-tk-chip.on.past { background: var(--gray-bg); color: var(--muted-head); }
.pn-tk-chip.on:hover { border-color: currentColor; color: var(--mint-deep); }
.pn-tk-chip.on.past:hover { color: var(--blue); }

.pn-tk-detail { flex: none; display: flex; flex-direction: column; gap: 8px; padding: 4px 12px 12px 36px; background: var(--bg-punch); }
.pn-tk-card .pn-tk-detail { background: none; }
.pn-tk-ta-foot { min-height: 0; margin-top: -4px; }
.pn-tk-ta-foot .pn-set-chip:empty { display: none; }
.pn-tk-seg { display: flex; gap: 2px; padding: 2px; border-radius: 8px; background: var(--gray-bg); }
.pn-tk-card .pn-tk-seg, .pn-tk-row.open + .pn-tk-detail .pn-tk-seg { background: var(--bg); box-shadow: inset 0 0 0 1px var(--line-row); }
.pn-tk-seg-b { flex: 1; height: 24px; padding: 0; border: 0; border-radius: 6px; background: none; font: inherit; font-size: 11.5px; color: var(--muted-head); cursor: pointer; }
.pn-tk-seg-b:hover { color: var(--blue); }
.pn-tk-seg-b.on { background: var(--bg-punch); color: var(--blue); font-weight: 700; cursor: default; }
.pn-tk-sec { display: flex; flex-direction: column; }
.pn-tk-sec-h { display: flex; align-items: center; gap: 6px; padding: 2px 0; font-size: 11.5px; font-weight: 700; color: var(--muted-head); }
.pn-tk-sec-h .n { color: var(--muted-3); font-weight: 600; }
.pn-tk-srow { display: flex; align-items: center; gap: 8px; min-height: 28px; font-size: 12.5px; }
.pn-tk-srow .nm { flex: 1; }
.pn-tk-srow .pn-fine { flex: none; }
.pn-tk-link.add { align-self: flex-start; padding-left: 0; }
.pn-tk-detail-foot { display: flex; align-items: center; gap: 8px; }

.pn-tk-add { flex: none; display: flex; align-items: center; gap: 8px; margin: 6px 10px 10px; padding: 0 10px; height: 34px; border: 1px dashed var(--muted-3-line); border-radius: 8px; color: var(--muted-2); cursor: text; }
.pn-tk-add:focus-within { border-style: solid; border-color: var(--blue); color: var(--blue); }
/* 전역 input[type="text"](0,1,1) 가 테두리·바탕·안여백을 입힌다 — 점선 상자 안에 상자가 하나 더 서지 않게 (0,2,0) 으로 벗긴다. */
.pn-tk-add .pn-tk-add-in { flex: 1; min-width: 0; width: auto; height: auto; padding: 0; border: 0; border-radius: 0; outline: 0; box-shadow: none; background: none; font: inherit; font-size: 12.5px; color: var(--ink); }
}

.pn-ov { overflow: hidden; }
.pn-md { flex: 1; min-height: 0; overflow: auto; padding: 14px 18px 18px; font-size: 13.5px; line-height: 1.7; color: var(--ink); }
.pn-md h1, .pn-md h2, .pn-md h3 { margin: 18px 0 7px; line-height: 1.3; }
.pn-md h1 { font-size: 18px; } .pn-md h2 { font-size: 15.5px; } .pn-md h3 { font-size: 14px; }
.pn-md p, .pn-md ul, .pn-md ol { margin: 0 0 10px; }
.pn-md code { font-size: 12px; background: var(--gray-bg); padding: 1px 4px; border-radius: 4px; }
/* 코드·표는 제 안에서 가로로 흐른다 — 칸(또는 창)을 밀어 본문 글줄이 잘리지 않게. */
.pn-md pre { margin: 0 0 10px; padding: 10px 12px; border-radius: 8px; background: var(--gray-bg); overflow-x: auto; }
.pn-md pre code { background: none; padding: 0; }
.pn-md table { display: block; max-width: 100%; overflow-x: auto; border-collapse: collapse; }
/* 타임라인 칸 = 그 세션의 발자취 위젯(web/timeline.ts) 통째. 위젯이 [머리 바 + 자기 스크롤]을 이미 갖고 있으니
   여기서는 높이만 내주고 스크롤은 겹치지 않게 둔다 — 겉과 속이 둘 다 스크롤하면 휠이 어디로 갈지 사람이 못 읽는다. */
.pn-tl { display: flex; flex-direction: column; min-height: 0; overflow: hidden; }
.pn-tlhost { display: flex; flex-direction: column; flex: 1; min-height: 0; }
.pn-tl .v2-aside-h { padding: 9px 12px 8px; }          /* 곁칸은 좁다 — 머리 바 좌우 여백을 칸 폭에 맞춘다 */
.pn-tl .tl-scroll { padding: 10px 12px 18px; }
.pn-tl .tl-scope { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; max-width: 46%; }  /* 세션 이름이 길면 줄인다 */
.pn-liv { overflow: hidden; }

/* ══ 프로젝트 설정 창 ═══════════════════════════════════════════════════════ */
.pn-modal-back { position: fixed; inset: 0; z-index: 60; background: rgba(var(--shadow-ink), .34); }
/* 오른쪽 시트는 창 맨 윗줄까지 올라가 닫기 X 가 윈도우 창 단추(닫기) 밑에 깔렸다 — 안쪽 위를 비운다(40-v2.css .v2-studio 설명 · #4480) */
.pn-modal { position: fixed; z-index: 61; top: 0; right: 0; bottom: 0; padding-top: var(--v2-desk-tb, 0px); width: min(520px, 94vw); display: flex; flex-direction: column;
  background: var(--bg); box-shadow: -18px 0 48px rgba(var(--shadow-ink), .20); }
.pn-modal-h { flex: none; display: flex; align-items: center; gap: 10px; padding: 16px 18px 13px; border-bottom: 1px solid var(--line); }
.pn-modal-h h2 { margin: 0; font-size: 16px; font-weight: 800; flex: 1; }
.pn-modal-x { width: 28px; height: 28px; border: 0; border-radius: 8px; background: none; color: var(--muted); display: flex; align-items: center; justify-content: center; cursor: pointer; }
.pn-modal-x:hover { background: var(--bg-punch); color: var(--ink); }
.pn-modal-b { flex: 1; min-height: 0; overflow: auto; padding: 4px 18px 18px; }
.pn-modal-f { flex: none; display: flex; align-items: center; justify-content: space-between; gap: 10px; padding: 12px 18px; border-top: 1px solid var(--line); }
.pn-set-sec { padding: 16px 0 4px; border-bottom: 1px solid var(--line-row); }
.pn-set-sec:last-child { border-bottom: 0; }
.pn-set-sec h3 { margin: 0 0 3px; font-size: 13px; font-weight: 700; }
.pn-set-sec > .pn-fine { margin: 0 0 9px; line-height: 1.5; }
.pn-set-name, .pn-set-tin { width: 100%; height: 34px; padding: 0 11px; border: 1px solid var(--line-net); border-radius: 9px; background: var(--bg); font: inherit; font-size: 13px; color: var(--ink); }
.pn-set-name:focus, .pn-set-tin:focus, .pn-set-desc:focus { outline: none; border-color: var(--blue); box-shadow: 0 0 0 3px rgba(45,107,240,.10); }
.pn-set-desc { width: 100%; padding: 10px 12px; border: 1px solid var(--line-net); border-radius: 10px; background: var(--bg); font: inherit; font-size: 13px; line-height: 1.6; color: var(--ink); resize: vertical; }
.pn-set-foot { display: flex; justify-content: flex-end; align-items: center; min-height: 16px; padding: 6px 0 2px; }
/* 본문 자동저장 상태 — 버튼을 없앤 자리에 선다. 아무 일 없을 땐 빈 글씨라 조용히 사라진다. */
.pn-set-chip { font-size: 11.5px; color: var(--muted-2); transition: opacity .2s; }
.pn-set-chip.warn { color: var(--coral); }
.pn-set-chip:empty { opacity: 0; }
.pn-set-states { display: inline-flex; gap: 6px; }
.pn-set-state { height: 30px; padding: 0 13px; border: 1px solid var(--line-net); border-radius: 9px; background: var(--bg); font: inherit; font-size: 12.5px; color: var(--ink-sub); cursor: pointer; }
.pn-set-state:hover { border-color: var(--blue); color: var(--blue); }
.pn-set-state.on { border-color: var(--blue); background: var(--bg-punch); color: var(--blue); font-weight: 700; }
.pn-set-tasks { margin-top: 9px; display: flex; flex-direction: column; gap: 1px; }
.pn-set-trow { display: flex; align-items: flex-start; gap: 9px; padding: 7px 6px; border-radius: 8px; font-size: 12.5px; }
.pn-set-trow:hover { background: var(--bg-punch); }
.pn-set-trow .n { flex: 1; min-width: 0; }
.pn-set-trow.done .n { color: var(--muted); text-decoration: line-through; }
.pn-set-trow a { text-decoration: none; }
.pn-set-trow a:hover { text-decoration: underline; }

/* ── 좁은 화면(≤900px) — 곁칸은 접고 한 칸만 본다(모바일 크롬은 v2/mobile.ts 가 따로 쥔다) ── */
@media (max-width: 900px) {
  .pn-body { grid-template-columns: minmax(0, 1fr) 0 0; }
  .pn-pane[data-zone="side"], .pn-body > .v2-split-x, .pn-side-reopen { display: none; }
  .pn-door { padding: 8px 14px; }
  .pn-title { font-size: 19px; }
}

/* ── 보관한 세션(#1719 원준 2026-08-20) — 닫아 둔 세션을 되살리는 자리 ── */
.pn-alist { display: flex; flex-direction: column; padding: 2px 6px 10px; }
.pn-arow { display: flex; align-items: center; gap: 8px; padding: 7px 8px; border-radius: 8px; font-size: 13px; color: var(--ink); }
.pn-arow:hover { background: var(--bg-tint); }
.pn-arow.busy { opacity: .6; }
.pn-arow .n { flex: 1; min-width: 0; color: var(--ink); text-decoration: none; }
.pn-arow .n:hover { color: var(--blue); }
.pn-arow .w { flex: none; font-size: 11.5px; }
.pn-arow .btn-text { flex: none; }
.pn-arow-x { flex: none; display: inline-flex; align-items: center; justify-content: center; width: 22px; height: 22px;
  border: 0; background: none; padding: 0; border-radius: 6px; color: var(--muted-2); cursor: pointer; opacity: 0; }
.pn-arow:hover .pn-arow-x, .pn-arow-x:focus-visible { opacity: 1; }
.pn-arow-x:hover { background: var(--bg-punch); color: var(--danger); }
/* 세션 탭 — 끌어 옮기기(크롬 문법) · 두 번 눌러 이름 고치기 */
.pn-tabwrap { position: relative; }
.pn-tabs.dnd .pn-tabwrap { transition: transform .16s cubic-bezier(.2,.7,.3,1); }
.pn-tabs.dnd .pn-tabwrap.dragging { transition: none; z-index: 5; }
.pn-tabs.dnd .pn-tabwrap.dragging .pn-tab { background: var(--bg); box-shadow: 0 6px 16px rgba(16, 24, 40, .16); cursor: grabbing; }
.pn-stab-in { width: 160px; max-width: 44vw; min-width: 90px; height: 20px; border: 1px solid var(--blue); border-radius: 5px;
  padding: 0 5px; font: inherit; font-size: 12.5px; background: var(--bg); color: var(--ink); }
.pn-stab-in:focus { outline: none; box-shadow: 0 0 0 3px rgba(45, 107, 240, .12); }

/* ── 자료 미리보기 — 아이콘 대신 내용이 보이게(원준 2026-08-20) ────────────────
   작은 종이 한 장(폭 300px)을 만들어 카드 폭에 맞춰 줄인다(JS 가 scale 을 준다). 글자·표·시안이
   뭉개지지 않고 비율 그대로 작아진다 — 브라우저가 11px 글자를 그린 뒤 축소하는 것이라 선이 살아 있다. */
.pn-fic.has-pv { background: var(--surface); position: relative; }
/* 새로 받아 그린 미리보기만 살짝 떠오른다 — 페이지 보관함에서 곧바로 선 것은 처음부터 그 자리에 있다(깜빡이지 않게). */
.pn-fic.pv-in > * { animation: pn-pv-in 160ms ease-out; }
@keyframes pn-pv-in { from { opacity: 0; } to { opacity: 1; } }
@media (prefers-reduced-motion: reduce) { .pn-fic.pv-in > * { animation: none; } }
/* 미리보기 한 장 — 논리 크기는 JS 가 내용에 맞춰 준다(글 300 · 시안 1180). 여기서는 자리와 규율만. */
.pn-fpaper { position: absolute; inset: 0; width: 300px; height: 246px; transform-origin: top left; overflow: hidden; background: var(--surface); pointer-events: none; }
.pn-fpaper > .pn-fframe { width: 100%; height: 100%; }
/* PDF 첫 장 그림(#762) — 종이 폭에 맞춰 눕고, 종이보다 길면 아래가 잘린다(카드 = 첫 장의 윗부분). */
.pn-fpaper > .pn-fpdf { display: block; width: 100%; height: auto; }
.pn-fframe { width: 300px; height: 246px; border: 0; background: var(--surface); }
.pn-fpre { margin: 0; padding: 10px 11px; width: 300px; height: 246px; overflow: hidden; white-space: pre-wrap; word-break: break-all;
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace; font-size: 9.5px; line-height: 1.5; color: var(--ink-sub); }
.pn-fic video { width: 100%; height: 100%; object-fit: cover; background: #000; }
/* 사무문서 썸네일(#3778) — 표는 종이 위에 작은 격자로, 글은 위 .pn-fpre 를 그대로 쓴다. */
.pn-fsheet { width: 300px; border-collapse: collapse; table-layout: fixed; font-size: 8.5px; line-height: 1.45; color: var(--ink-sub); }
.pn-fsheet th, .pn-fsheet td { border: 1px solid var(--line); padding: 2px 4px; text-align: left;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.pn-fsheet th { background: var(--bg-tint); font-weight: 700; }
.pn-fic.office > img { width: 100%; height: 100%; object-fit: cover; object-position: top center; }
.pn-fic.text, .pn-fic.pdf, .pn-fic.page, .pn-fic.video { position: relative; }
.pn-fic.office { position: relative; }

/* ── 웹 · 파일 편집(원준 2026-08-20) ─────────────────────────────────────────── */
.pn-web, .pn-ed { display: flex; flex-direction: column; min-height: 0; }
/* 뷰어에 파일을 끌어다 놓는 중 — 자료 칸과 같은 신호로(같은 일이 일어나므로). */
.pn-ed.drop-active { outline: 2px dashed var(--blue); outline-offset: -6px; background: var(--bg-tint); }
.pn-web-bar, .pn-ed-bar { flex: none; display: flex; align-items: center; gap: 6px; padding: 8px 10px; border-bottom: 1px solid var(--line); }
.pn-web-in { flex: 1; min-width: 0; height: 28px; padding: 0 9px; border: 1px solid var(--line-net); border-radius: 8px; font: inherit; font-size: 12.5px; background: var(--bg); color: var(--ink); }
.pn-web-in:focus { outline: none; border-color: var(--blue); box-shadow: 0 0 0 3px rgba(45,107,240,.10); }
.pn-web-btn { display: inline-flex; align-items: center; justify-content: center; gap: 5px; height: 28px; padding: 0 9px; border: 1px solid var(--line-net); border-radius: 8px; background: var(--bg); font: inherit; font-size: 12px; color: var(--ink-sub); cursor: pointer; text-decoration: none; flex: none; }
.pn-web-btn:hover { color: var(--blue); border-color: var(--blue); }
/* ── 주소줄 왼쪽 묶음 = [뒤로][앞으로][다시] (원준 2026-08-21) ──────────────────
   브라우저와 같은 순서·같은 자리에 둔다 — 여기서 배우지 않아도 아는 배치가 제일 빠르다.
   셋은 아이콘만이라 정사각으로 붙이고(묶음), 주소칸이 남은 폭을 다 쓴다. */
.pn-web-navs { flex: none; display: inline-flex; align-items: center; gap: 3px; }
.pn-web-btn.ic { width: 28px; padding: 0; }
.pn-web-btn.back svg { transform: rotate(180deg); }
/* 갈 데가 없으면 끈다 — 눌러도 아무 일 없는 단추를 켜 둔 채로 두지 않는다. */
.pn-web-btn:disabled { color: var(--muted-3); border-color: var(--line-row); cursor: default; }
.pn-web-btn:disabled:hover { color: var(--muted-3); border-color: var(--line-row); }
/* ── 무대(stage) — 프레임을 넓게 잡고 줄여 그리는 자리 (원준 2026-08-21 '폭 맞춤') ────────────
   프레임의 **논리 폭**을 1/배율 로 키우고 그만큼 축소하면, 사이트는 넓은 화면인 줄 알고 데스크톱 배치를
   펴고 그게 칸 안에 통째로 들어온다(가로가 안 잘린다). 무대는 넘치는 부분을 잘라 담는 그릇이다. */
.pn-webstage { flex: 1; min-height: 0; min-width: 0; position: relative; overflow: hidden; background: var(--surface); }
/* ⚠ width·height 를 **여기서 반드시** 준다. 프레임(iframe·webview)은 '대체 요소'라 크기를 안 주면
   CSS 기본값 300×150px 로 앉는다 — 자리를 잡아 주던 flex 는 position:absolute 가 되는 순간 손을 뗀다.
   브라우저 경로는 배율 때문에 인라인 style 로 늘 크기를 주지만, **앱 경로(<webview>)는 진짜 줌을 쓰므로
   인라인 style 을 지운다** — 그때 이 규칙이 없으면 칸이 아무리 커도 페이지는 150px 만 그려진다
   (원준 2026-08-23 신고 "로드가 계속 이 정도까지만 돼": 아티팩트 머리글 44px + 본문 106px = 정확히 150px). */
.pn-webstage > .pn-webframe { position: absolute; top: 0; left: 0; width: 100%; height: 100%; transform-origin: top left; }
.pn-webframe { flex: 1; min-height: 0; min-width: 0; width: 100%; border: 0; background: var(--surface); }
/* ── 배율 알약 — 웹 칸·뷰어가 **같은 자리에 같은 모양**으로 (#762, 원준 2026-09-04) ─────────
   종전엔 주소줄에 28px 짜리 [−][배율][+] 셋이 [뒤로][앞으로][다시]와 똑같은 생김새로 끼어 있어
   '배율'로 읽히지 않았고("확대 축소하는 버튼이랑 위치랑 안 느껴져"), 뷰어에는 아예 없었다.
   무대 오른쪽 아래는 지도·PDF 뷰어가 쓰는 자리라 찾지 않아도 눈에 걸린다. 셋을 테두리 하나로 묶어
   옆 단추들과 다른 **한 덩어리**로 만든다. */
.pn-zoom { position: absolute; right: 12px; bottom: 12px; z-index: 3; display: inline-flex; align-items: center;
  padding: 3px; border: 1px solid var(--line-net); border-radius: 999px; background: var(--surface);
  box-shadow: 0 8px 30px rgba(var(--shadow-ink), .12); }
/* ⚠ .pn-zoom 의 display 가 UA 의 [hidden] 규칙을 이기므로 숨김을 여기서 다시 적는다. */
.pn-zoom[hidden] { display: none; }
.pn-zoom-b { width: 27px; height: 26px; display: grid; place-items: center; border: 0; border-radius: 999px;
  background: none; font: inherit; font-size: 15px; font-weight: 700; line-height: 1; color: var(--ink-sub); cursor: pointer; }
.pn-zoom-b:hover { background: var(--bg-punch); color: var(--blue); }
.pn-zoom-b:disabled { color: var(--muted-3); background: none; cursor: default; }
.pn-zoom-lbl { min-width: 62px; height: 26px; padding: 0 4px; border: 0; border-radius: 999px; background: none;
  font: inherit; font-size: 11.5px; font-weight: 700; color: var(--ink); font-variant-numeric: tabular-nums; cursor: pointer; }
.pn-zoom-lbl:hover { background: var(--bg-punch); }
/* 맞춤일 때만 파랗다 — '지금 칸을 따라가는 중'이라는 뜻이고, 사람이 배율을 정하면 잉크로 돌아온다. */
.pn-zoom.is-fit .pn-zoom-lbl { color: var(--blue); }
/* 데스크톱 앱(#1829)에서는 이 칸이 <webview> 다 — 교체 요소라 내재 크기로 버티므로 flex 자식임을 명시한다. */
webview.pn-webframe { display: flex; }
.pn-web-note { flex: none; padding: 6px 10px 8px; border-top: 1px solid var(--line); }
/* ⚠ position: relative — 배율 알약이 이 칸의 오른쪽 아래에 선다(무대 안에 두면 내용과 함께 굴러간다). */
.pn-ed-body { flex: 1; min-height: 0; display: flex; overflow: hidden; position: relative; }
/* ── 뷰어 무대 — 펴 놓은 것이 서는 자리 (#762) ─────────────────────────────────
   배율은 **이 폭**을 자로 쓴다. 그림·글은 넘치면 여기서 구르고, 프레임(PDF·시안)은 논리 폭을 키워
   줄여 그리므로 구를 것이 없다(.frame). 목록 화면은 제가 세로로 흐르는 판이라 그릇이 된다(.list). */
.pn-ed-stage { flex: 1; min-width: 0; min-height: 0; overflow: auto; background: var(--surface); }
.pn-ed-stage > * { transform-origin: top left; }
.pn-ed-stage.list { overflow: hidden; display: flex; flex-direction: column; }
/* 프레임은 웹 칸의 무대와 같은 규칙 — 자리를 절대좌표로 잡아야 '대체 요소' 기본 300×150 으로 앉지 않는다. */
.pn-ed-stage.frame { overflow: hidden; position: relative; }
.pn-ed-stage.frame > * { position: absolute; top: 0; left: 0; width: 100%; height: 100%; }
/* 글은 무대가 대신 구른다 — 제가 또 구르면 스크롤이 두 겹이 된다. */
.pn-ed-stage > .pn-ed-pre, .pn-ed-stage > .pn-md { flex: none; overflow: visible; }
.pn-ed-name { flex: 1; min-width: 0; font-size: 12.5px; }
.pn-ed-pv { width: 100%; height: 100%; border: 0; background: var(--surface); }
/* 그림·영상 — 크기는 **가로만** 정한다(세로는 따라온다). 종전 object-fit: contain 은 칸의 세로에 걸려
   가로를 넓혀도 그대로였다(원준 2026-09-04 신고). 칸보다 좁으면 가운데에 선다. */
.pn-ed-img { display: block; margin: 0 auto; max-width: none; background: var(--gray-bg); }
.pn-ed-pre { flex: 1; min-height: 0; overflow: auto; margin: 0; padding: 12px 14px; font-family: ui-monospace, SFMono-Regular, Menlo, monospace; font-size: 12px; line-height: 1.6; color: var(--ink); white-space: pre-wrap; word-break: break-word; }
/* ── 고치기 (#762, 원준 2026-09-05) — 보는 화면이 그대로 고치는 화면이 된다 ────────────
   무대를 통째로 쓰는 글칸 하나. 배율 알약은 이때 숨는다(글은 칸 폭에 맞춰 흐르므로 배율이 뜻이 없다).
   글씨는 보기(.pn-ed-pre)와 **같은 고정폭·같은 줄간** — 고치기 전후로 글의 생김새가 바뀌면 안 된다. */
.pn-ed-stage.edit { overflow: hidden; display: flex; }
/* ── 뷰어가 공용 렌더러에 맡긴 형식(사무문서·한글·압축·소리·모르는 바이트) (#3778) ────────────────
   무대가 스스로 구르므로 여기서는 여백과 표 폭만 정한다. 실제 그림은 fp-* (32-file-share.css)가 그린다. */
.pn-fp { padding: 14px 16px; box-sizing: border-box; }
.pn-fp-tools { display: flex; flex-wrap: wrap; gap: 6px; margin-bottom: 10px; }
.pn-fp .fp-table { font-size: 11.5px; }
.pn-fp .fp-table th, .pn-fp .fp-table td { max-width: 200px; padding: 4px 7px; }
.pn-fp .fp-code { max-height: none; font-size: 11.5px; }
.pn-fp .fp-doc { font-size: 13px; }
.pn-fp .fp-msg { padding: 24px 12px; }
.pn-fp .fp-audio { width: 100%; }
.pn-ed-ta { flex: 1; min-width: 0; min-height: 0; width: 100%; margin: 0; padding: 12px 14px; border: 0; resize: none;
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace; font-size: 12px; line-height: 1.6;
  background: var(--surface); color: var(--ink); overflow: auto; tab-size: 2; }
.pn-ed-ta:focus { outline: none; }
/* 저장 = 이 막대에서 유일한 '하는' 단추다 — 나머지(돌아가기)와 무게가 같으면 어느 것이 결론인지 안 보인다. */
.pn-web-btn.pri { border-color: var(--blue); background: var(--blue); color: #fff; font-weight: 600; }
.pn-web-btn.pri:hover { border-color: var(--blue); background: var(--blue-deep); color: #fff; }
/* 저장 안 한 글이 있다 — 점 하나로만 말한다(경고창이 아니라 상태 표시다). */
.pn-ed-bar .pn-fine.warn { color: var(--danger); font-weight: 600; }

/* 뷰어의 '무엇을 열까' 화면 — 드롭다운을 대신하는 목록(검색 + 종류·크기·시각) */
.pn-ed-pick2 { flex: 1; min-width: 0; display: flex; flex-direction: column; }
.pn-ed-find { flex: none; margin: 9px 12px 7px; height: 30px; padding: 0 10px; border: 1px solid var(--line-net); border-radius: 9px; font: inherit; font-size: 12.5px; background: var(--bg); color: var(--ink); }
.pn-ed-find:focus { outline: none; border-color: var(--blue); box-shadow: 0 0 0 3px rgba(45,107,240,.10); }
.pn-ed-pick2 .pn-flist { flex: 1; min-height: 0; overflow: auto; padding: 0 8px 12px; }
.pn-ed-pick2 .pn-frow2 { width: 100%; border: 1px solid transparent; background: none; font: inherit; text-align: left; cursor: pointer; }
.pn-ed-pick2 .pn-frow2:hover { border-color: var(--line-net); background: var(--bg-tint); }

/* ── 앱 부품(#1780 panes 정합) — 설치된 앱을 곁칸에서 목록·열기 ── */
.pn-apps { display: flex; flex-direction: column; overflow: hidden; }
.pn-apps-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(120px, 1fr)); gap: 10px; padding: 12px; overflow-y: auto; }
.pn-app { display: flex; flex-direction: column; align-items: center; gap: 6px; padding: 14px 8px; background: var(--bg); border: 1px solid var(--line); border-radius: 12px; cursor: pointer; text-align: center; font: inherit; color: var(--ink); }
.pn-app:hover { border-color: var(--blue); }
.pn-app b { font-size: 12.5px; font-weight: 700; }
.pn-app-ic { width: 40px; height: 40px; border-radius: 11px; background: var(--bg-tint); border: 1px solid var(--line); display: grid; place-items: center; color: var(--blue); }
.pn-app-ic .pn-i { width: 20px; height: 20px; }
.pn-apps-bar { flex: none; display: flex; align-items: center; gap: 10px; padding: 8px 12px; border-bottom: 1px solid var(--line); background: var(--gray-bg-2); }
.pn-apps-cur { font-size: 12.5px; }
.pn-apps .v2-appui-frame { flex: 1; width: 100%; border: 0; background: var(--surface); }

/* ── 붙은 앱 탭(#4225) — 지금 세션에 붙은 앱 화면이 곁칸의 탭 하나로 선다. 여럿 붙었으면 안에 작은 탭 줄 ── */
.pn-sessapp { display: flex; flex-direction: column; overflow: hidden; }
.pn-sessapp-tabs { flex: none; display: flex; gap: 4px; padding: 6px 8px; border-bottom: 1px solid var(--line); background: var(--gray-bg-2); overflow-x: auto; scrollbar-width: none; }
.pn-sessapp-tabs[hidden] { display: none; }
.pn-sessapp-tab { display: inline-flex; align-items: center; gap: 6px; max-width: 200px; padding: 4px 10px; border: 1px solid transparent;
  border-radius: 8px; background: none; font: inherit; font-size: 12.5px; color: var(--muted-head); cursor: pointer; white-space: nowrap; }
.pn-sessapp-tab span { overflow: hidden; text-overflow: ellipsis; }
.pn-sessapp-tab .pn-i { width: 14px; height: 14px; flex: none; color: var(--blue); }
.pn-sessapp-tab:hover { background: var(--bg-tint); }
.pn-sessapp-tab.on { background: var(--bg); border-color: var(--line); color: var(--ink); font-weight: 700; }
.pn-sessapp-body { flex: 1; min-height: 0; display: flex; flex-direction: column; overflow: auto; }
.pn-sessapp-body > .v2-appui-frame { flex: 1; width: 100%; border: 0; background: var(--surface); }
.pn-sessapp-wait { padding: 16px; }
.pn-sessapp-info { padding: 16px; display: flex; flex-direction: column; gap: 8px; }
.pn-sessapp-tbl { display: flex; flex-direction: column; gap: 2px; padding: 8px 10px; border: 1px solid var(--line); border-radius: 8px; }

/* ── 붙은 앱 탭 머리줄 · ⋯ 메뉴 · 방금 고침 띠(#4600 — 각자 AI 에게 시켜 고쳐 쓰는 앱) ──
   머리줄은 앱이 하나여도 선다: «이 앱은 고칠 수 있다» 를 알려 주는 자리가 이것뿐이다. 띠는 app_save·app_revert 뒤 60초. */
.pn-sessapp-head { flex: none; display: flex; align-items: center; gap: 7px; height: 32px; padding: 0 6px 0 10px; border-bottom: 1px solid var(--line); background: var(--gray-bg-2); font-size: 12.5px; color: var(--ink); }
.pn-sessapp-head[hidden] { display: none; }
.pn-sessapp-head .pn-i { color: var(--blue); }
.pn-sessapp-head .pn-sp { flex: 1; min-width: 0; }
.pn-sessapp-title { font-weight: 700; min-width: 0; }
.pn-sessapp-ver { flex: none; font-size: 10.5px; font-weight: 800; color: var(--muted-head); background: var(--bg); border: 1px solid var(--line); border-radius: 999px; padding: 0 6px; line-height: 16px; }
.pn-sessapp-more { flex: none; width: 24px; height: 24px; display: grid; place-items: center; border: 0; border-radius: 6px; background: none; color: var(--muted-head); cursor: pointer; }
.pn-sessapp-more:hover { background: var(--bg-tint); color: var(--ink); }
.pn-sessapp-more .pn-i { color: inherit; }
.pn-sessapp-band { flex: none; display: flex; align-items: center; gap: 8px; padding: 5px 6px 5px 10px; border-bottom: 1px solid var(--line-note); background: var(--bg-note); color: var(--blue-deep); font-size: 11.5px; font-weight: 700; }
.pn-sessapp-band[hidden] { display: none; }
.pn-sessapp-band-t { flex: 1; min-width: 0; }
.pn-sessapp-band-b { flex: none; font: inherit; font-size: 11.5px; font-weight: 700; color: var(--blue-deep); background: var(--bg); border: 1px solid var(--line-note); border-radius: 6px; padding: 2px 8px; cursor: pointer; }
.pn-sessapp-band-b:hover { background: var(--bg-sel); }
.pn-sessapp-band-x { flex: none; width: 22px; height: 22px; display: grid; place-items: center; border: 0; border-radius: 6px; background: none; color: var(--muted-head); cursor: pointer; }
.pn-sessapp-band-x:hover { background: var(--bg-tint); }

/* ── 앱 고치기 설정 창(#4225) — 누가 이 앱을 고칠 수 있나(기본 전원 · 지정한 사람만) ── */
.pn-editpol { width: min(460px, 94vw); }
.pn-editpol .pn-modal-b { display: flex; flex-direction: column; gap: 10px; }
.pn-editpol-opt { display: flex; align-items: flex-start; gap: 10px; padding: 10px 12px; border: 1px solid var(--line); border-radius: 10px; cursor: pointer; }
.pn-editpol-opt:has(input:checked) { border-color: var(--blue); background: var(--bg-sel); }
.pn-editpol-opt > span { display: flex; flex-direction: column; gap: 2px; }
.pn-editpol-opt input { margin-top: 3px; }
.pn-editpol-list { display: flex; flex-direction: column; gap: 2px; max-height: 260px; overflow: auto; padding: 4px 2px; border-top: 1px solid var(--line-row); }
.pn-editpol-list[hidden] { display: none; }
.pn-editpol-person { display: flex; align-items: center; gap: 8px; padding: 6px 8px; border-radius: 8px; cursor: pointer; font-size: 13px; }
.pn-editpol-person:hover { background: var(--bg-tint); }
.pn-editpol-person .pn-fine { margin-left: auto; font-size: 11px; }

/* ══ 지식 읽기 — 그 칸 안에서 (#4443 원준 10-05 «오른쪽에서 칸 튀어나오듯이 … 하지말고 그냥 곁칸에서 마크다운 이쁘게») ══
   목록과 읽기는 한 칸의 두 화면이다(.pn-kn.reading). 본문은 위키와 같은 렌더러 · 같은 모양(md-rendered)을 사이드바 폭으로 줄인다. */
.pn-kn.reading > .pn-fnote, .pn-kn.reading > .pn-knlist { display: none; }
.pn-kn:not(.reading) > .pn-knr { display: none; }
.pn-knr { flex: 1; min-height: 0; display: flex; flex-direction: column; }
.pn-knr-bar { flex: none; display: flex; align-items: center; justify-content: space-between; gap: 8px; padding: 6px 8px 6px 6px; border-bottom: 1px solid var(--line); }
.pn-knr-back { display: inline-flex; align-items: center; gap: 2px; height: 28px; padding: 0 10px 0 4px; border: 0; border-radius: 8px; background: none; font: inherit; font-size: 12.5px; font-weight: 700; color: var(--muted-head); cursor: pointer; }
.pn-knr-back:hover { background: var(--bg-punch); color: var(--ink); }
.pn-knr-open { display: inline-flex; align-items: center; gap: 5px; height: 28px; padding: 0 9px; border-radius: 8px; font-size: 12px; font-weight: 600; color: var(--muted); text-decoration: none; white-space: nowrap; }
.pn-knr-open:hover { background: var(--bg-punch); color: var(--ink); }
.pn-knr-scroll { flex: 1; min-height: 0; overflow: auto; padding: 16px 18px 18px; }
.pn-knr-head { margin-bottom: 14px; }
.pn-knr-t { margin: 0; font-size: 18px; font-weight: 800; line-height: 1.35; color: var(--ink); text-wrap: balance; overflow-wrap: anywhere; }
.pn-knr-full { margin: 6px 0 0; font-size: 12px; line-height: 1.55; color: var(--muted-head); overflow-wrap: anywhere; display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: 3; overflow: hidden; cursor: pointer; border-radius: 4px; }
.pn-knr-full.open { display: block; -webkit-line-clamp: unset; }
.pn-knr-full:focus-visible, .pn-knr-back:focus-visible, .pn-knr-open:focus-visible { outline: 2px solid var(--blue); outline-offset: 1px; }
.pn-knr-meta { display: flex; flex-wrap: wrap; align-items: center; gap: 6px; margin-top: 10px; }
.pn-knr-tag { font-size: 10.5px; padding: 1px 7px; border-radius: 999px; background: var(--gray-bg); color: var(--muted-head); }
.pn-knr-sum { margin: 0 0 16px; padding: 10px 12px; border-left: 3px solid var(--blue); border-radius: 0 8px 8px 0; background: var(--bg-sel); font-size: 13px; line-height: 1.6; color: var(--ink); overflow-wrap: anywhere; }
.pn-knr-md.md-rendered { font-size: 13.5px; line-height: 1.72; }
.pn-knr-md .md-h { margin: 22px 0 8px; }
.pn-knr-md .md-h1 { font-size: 17px; }
.pn-knr-md .md-h2 { font-size: 15.5px; padding-bottom: 5px; border-bottom: 1px solid var(--line); }
.pn-knr-md .md-h3 { font-size: 14px; }
.pn-knr-md :is(.md-h4, .md-h5, .md-h6) { font-size: 13.5px; }
.pn-knr-md .md-p { margin: 0 0 11px; }
.pn-knr-md .md-list { margin-bottom: 11px; padding-left: 20px; }
.pn-knr-md .md-pre { padding: 10px 12px; border-radius: 8px; }
.pn-knr-md .md-pre code { font-size: 12px; }
.pn-knr-md .md-table { max-width: 100%; font-size: 12.5px; }
.pn-knr-md .md-table :is(th, td) { padding: 5px 8px; }
.pn-knr-md img { max-width: 100%; height: auto; border-radius: 6px; }
.pn-knr-foot { display: flex; align-items: center; justify-content: space-between; gap: 10px; margin-top: 22px; padding-top: 12px; border-top: 1px solid var(--line); }
.pn-knr-name { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-family: ui-monospace, SFMono-Regular, Menlo, monospace; font-size: 11px; color: var(--muted-2); }
.pn-knr-foot .btn-text { flex: none; display: inline-flex; align-items: center; gap: 4px; font-size: 12px; }
.pn-knr-wait { margin: 6px 0; }
.pn-knr-err { display: flex; flex-direction: column; align-items: flex-start; gap: 10px; padding: 6px 0; font-size: 13px; color: var(--muted-head); }
.pn-knr-err p { margin: 0; }

/* ══ 문패 버튼 — 크기·글자는 그대로 두고 '무게'만 준다 (#1819 원준) ═══════════ */
/*  ghost 둘이 나란히 있으면 어느 것이 주된 동작인지 색이 말해 주지 않는다. 주된 동작만 칠한다. */
/* (문패 구분선은 #3778 로 죽었다 — 얼굴·공유가 세션 머리줄로 내려가면서 가를 것이 없어졌다.) */
.pn-door-btn { gap: 6px; }
.pn-door-btn svg { width: 15px; height: 15px; }
.pn-door-r .btn-primary.pn-door-btn { box-shadow: 0 1px 2px rgba(45,107,240,.30), 0 2px 8px rgba(45,107,240,.16); }
.pn-door-r .btn-primary.pn-door-btn:hover { box-shadow: 0 1px 2px rgba(45,107,240,.34), 0 4px 12px rgba(45,107,240,.22); }
.pn-door-r .btn-ghost.pn-door-btn { border-color: var(--line-net); color: var(--ink); font-weight: 600; }
.pn-door-r .btn-ghost.pn-door-btn svg { color: var(--muted-2); }
.pn-door-r .btn-ghost.pn-door-btn:hover { border-color: var(--blue); color: var(--blue); background: var(--bg-tint); }
.pn-door-r .btn-ghost.pn-door-btn:hover svg { color: var(--blue); }

/* ── 미리보기 칸 (previewPart) ─────────────────────────────────────────────
   띄워 둔 화면 목록. 누르면 웹 칸이 그 주소를 문다 — 이 칸은 '무엇을 띄울지 고르는' 자리다. */
.pn-prev{display:flex;flex-direction:column;min-height:0;overflow:auto}
.pn-prev-list{display:flex;flex-direction:column;gap:2px;padding:6px}
.pn-prev-msg{padding:14px 10px;font-size:12.5px;color:var(--muted-2)}
.pn-prev-row{display:flex;align-items:center;gap:8px;width:100%;text-align:left;
  background:none;border:1px solid transparent;border-radius:8px;padding:7px 8px;cursor:pointer;font:inherit;color:inherit}
.pn-prev-row:hover{background:var(--bg-punch);border-color:var(--line)}
.pn-prev-row:focus-visible{outline:2px solid var(--blue);outline-offset:1px}
.pn-prev-row.is-on{background:var(--bg-punch);border-color:var(--blue)}
.pn-prev-dot{width:7px;height:7px;border-radius:50%;flex:0 0 7px;background:var(--muted-3-line)}
.pn-prev-dot--on{background:#0e9f87}
.pn-prev-dot--busy{background:#a9660c}
.pn-prev-dot--bad{background:#b3261e}
.pn-prev-b{flex:1;min-width:0;display:flex;flex-direction:column;gap:1px}
.pn-prev-t{font-size:12.5px;font-weight:600;line-height:1.4;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.pn-prev-m{font-size:11px;color:var(--muted-2);line-height:1.45;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.pn-prev-go{flex:0 0 auto;opacity:0;transition:opacity .12s}
.pn-prev-row:hover .pn-prev-go,.pn-prev-row.is-on .pn-prev-go{opacity:.6}

/* ── 세션 공유(#2116) — 문패 [공유]가 여는 팝오버 ────────────────────────────────
   구글 문서의 [공유]와 같은 자리·같은 뜻이다: 맨 위가 '지금 보고 있는 사람', 그 아래가 '함께 볼 사람'.
   위치만 .dash-pop(position:fixed)이 잡아 주므로 카드 모양은 여기서 그린다. */
.pn-share { width: 292px; max-width: calc(100vw - 16px); background: var(--bg); border: 1px solid var(--line-net);
  border-radius: 12px; box-shadow: 0 10px 32px rgba(20,35,59,.18); overflow: hidden; }
.pn-share-head { display: flex; align-items: baseline; gap: 8px; padding: 11px 13px 9px; border-bottom: 1px solid var(--line); }
.pn-share-head b { font-size: 13.5px; }
.pn-share-sub { min-width: 0; font-size: 11.5px; color: var(--muted-2); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.pn-share-body { padding: 11px 13px 12px; display: flex; flex-direction: column; gap: 11px; }
.pn-share-block { display: flex; flex-direction: column; gap: 7px; }
.pn-share-sec { font-size: 11px; font-weight: 700; letter-spacing: .01em; color: var(--muted); }
.pn-share-fine { margin: 0; font-size: 11.5px; line-height: 1.5; color: var(--muted-2); }
.pn-share-people { display: flex; flex-direction: column; gap: 5px; }
.pn-share-person { display: flex; align-items: center; gap: 7px; font-size: 12.5px; color: var(--ink); }
/* 팝오버 안의 얼굴도 같은 처방 — 위 .pn-face 와 크기만 다르다. */
.pn-share-face { width: 22px; height: 22px; border-radius: 50%; flex: none; box-sizing: border-box;
  display: inline-grid; place-items: center; overflow: hidden;
  font-size: 10px; font-weight: 700; line-height: 1; color: var(--on-fill); }
.pn-share-face > img { width: 100%; height: 100%; object-fit: cover; display: block; }
/* 고른 사람 = 칩. 없을 때는 '비공개'라는 사실 한 줄이 그 자리를 대신한다(빈 칸을 보여 주지 않는다). */
.pn-share-chips { display: flex; flex-wrap: wrap; gap: 5px; }
.pn-share-chip { display: inline-flex; align-items: center; gap: 5px; padding: 3px 5px 3px 3px; border-radius: 999px;
  background: var(--bg-tint); font-size: 12px; }
.pn-share-x { border: none; background: none; padding: 0 2px; cursor: pointer; color: var(--muted); font-size: 13px; line-height: 1; }
.pn-share-x:hover { color: var(--ink); }
.pn-share-in { width: 100%; padding: 6px 9px; border: 1px solid var(--line-net); border-radius: 8px;
  font-family: inherit; font-size: 12.5px; background: var(--bg); color: var(--ink); }
.pn-share-in:focus { outline: none; border-color: var(--blue); box-shadow: 0 0 0 3px rgba(45,107,240,.10); }
.pn-share-list { display: flex; flex-direction: column; max-height: 176px; overflow-y: auto; scrollbar-width: thin; }
.pn-share-row { display: flex; align-items: center; gap: 7px; width: 100%; padding: 5px 6px; border: none; background: none;
  border-radius: 8px; cursor: pointer; font-family: inherit; font-size: 12.5px; color: inherit; text-align: left; }
.pn-share-row:hover { background: var(--bg-tint); }
/* Enter 가 고를 한 줄(#3778, 2026-09-10) — 무엇이 담길지 **누르기 전에** 보이게. 키 표식(↵)이 그 약속을 말한다. */
.pn-share-row.on { background: var(--bg-tint-2); box-shadow: inset 0 0 0 1px var(--line-note); }
.pn-share-kbd { margin-left: auto; flex: none; font-size: 10.5px; font-weight: 700; color: var(--blue);
  background: var(--bg); border: 1px solid var(--line-net); border-radius: 4px; padding: 0 5px; line-height: 16px; }
.pn-share-act { display: flex; justify-content: flex-end; gap: 6px; }
/* #3870 — 빈 찾기칸에서 ↵ = 저장. 그때 ↵ 표식은 목록 줄이 아니라 저장 단추에 붙는다(한 번에 한 자리). */
.pn-share-save { display: inline-flex; align-items: center; gap: 6px; }
.pn-share-kbd--btn { margin-left: 0; color: inherit; background: transparent; border-color: currentColor; opacity: .85; }
.pn-share-hint { color: var(--muted); }
/* 초대받은 사람의 나가기 — 되돌리기가 내 손에 없는 동작이라 붉은 글자(채운 단추까지는 아니다 · 확인 창이 한 번 더 묻는다). */
.pn-share-leave { color: var(--danger); }
.pn-share-leave:hover { color: var(--danger-deep); background: var(--danger-bg); }

/* ── 타임라인 찾기 칸 (#762) ─────────────────────────────────────────────────
   머리 바의 [최신순][자세히] 과 같은 급이라 높이·반경을 맞춘다(28 · 8). 좁은 칸에서는 이 칸이 먼저 줄고
   단추는 안 줄어든다 — 단추는 글자 폭이 정해져 있지만 찾기 칸은 줄어도 쓸 수 있다. */
.tl-find { flex: 1 1 90px; min-width: 60px; height: 26px; padding: 0 9px; border: 1px solid var(--line-net); border-radius: 8px;
  background: var(--bg); font: inherit; font-size: 12px; color: var(--ink); }
.tl-find::placeholder { color: var(--muted-2); }
.tl-find:focus-visible { outline: 2px solid var(--blue); outline-offset: -1px; }

/* ── 자료 칸 찾기 (#762) — 툴바의 다른 단추와 같은 높이(28)·글자(13). 좁아지면 이 칸이 먼저 줄고(96 까지), 그다음 도구가 접힌다.
   ⚠ `input.` 을 붙여야 먹는다 — 03-components 의 `input[type="search"]`(14px·반경 9)가 클래스 하나보다 특이도가 높다
   (#3870 신고: 찾기 글자만 14px 로 옆 [새 폴더] 13px 보다 컸다). */
input.pn-ffind { flex: 0 1 200px; min-width: 96px; height: 28px; padding: 0 9px; border: 1px solid var(--line-net); border-radius: 7px;
  background: var(--bg); font: inherit; font-size: 13px; line-height: normal; color: var(--ink); box-shadow: none; }
.pn-ffind::placeholder { color: var(--muted-2); }
.pn-ffind:focus-visible { outline: 2px solid var(--blue); outline-offset: -1px; }

/* ── 뷰어 목록의 미리보기 (#762) ────────────────────────────────────────────
   자료 칸과 같은 기계를 쓰되 **행**이라 작다(44×36). 아이콘만 있을 땐 종전 자리 그대로. */
.pn-fic.pv { width: 44px; height: 36px; flex: none; aspect-ratio: auto; border-radius: 6px; overflow: hidden; position: relative; }
.pn-fic.pv .pn-i { width: 15px; height: 15px; }
.pn-frow2.pv { align-items: center; gap: 10px; }

/* ── 곁칸 «태스크» 3차(#4135, 2026-09-26) — 허브 태스크 위젯·프로젝트 탭과 같은 결: 줄 36 · 이름 13.5 · 묶음 머리 13/800 · 상태 원 16 실선 ·
   «＋ 세션 열기» 칩은 줄마다 늘 서지 않고 올릴 때만(맡은 세션 칩 .on 은 상태를 나르므로 늘). ── */
.pn-tk-head { padding: 12px 14px 10px; gap: 8px; }
.pn-tk-name { font-size: 14px; }
.pn-tk-count { font-size: 12.5px; }
.pn-tk-fold { height: 34px; padding: 0 14px; gap: 8px; }
.pn-tk-fold-l { font-size: 12.5px; }
.pn-tk-fold-ex { font-size: 12.5px; }
.pn-tk-card { margin: 10px 12px 4px; padding: 12px 14px; border-radius: 12px; gap: 8px; }
.pn-tk-card-h { font-size: 12px; }
.pn-tk-card-n { font-size: 14.5px; }
.pn-tk-card-m, .pn-tk-card-a .pn-fine { font-size: 12.5px; }
.pn-tk-gh { padding: 14px 14px 4px; font-size: 13px; font-weight: 800; letter-spacing: -.1px; color: var(--ink); }
.pn-tk-gh .n { font-size: 12.5px; font-weight: 600; color: var(--muted-2); }
.pn-tk-row { min-height: 36px; padding: 0 14px; gap: 10px; }
.pn-tk-row + .pn-tk-row { border-top: 1px solid var(--line-row); }
.pn-tk-row:hover, .pn-tk-row.open { background: var(--bg-tint); }
.pn-tk-row:hover + .pn-tk-row, .pn-tk-row.open + .pn-tk-row { border-top-color: transparent; }
.pn-tk-rname { height: 36px; font-size: 13.5px; }
.pn-tk-sub-n { font-size: 13px; }
.pn-tk-row.sub { min-height: 32px; }
.pn-tk-st { width: 16px; height: 16px; border-style: solid; }
.pn-tk-st.doing { border-style: solid; }
.pn-tk-st.done::after { left: 4px; top: 1.2px; width: 3.6px; height: 7.5px; }
.pn-tk-st.static { width: 14px; height: 14px; }
.pn-tk-chip { font-size: 11.5px; line-height: 18px; padding: 1px 9px 1px 8px; }
.pn-tk-chip:not(.on) { display: none; }
.pn-tk-row:hover .pn-tk-chip, .pn-tk-row.open .pn-tk-chip, .pn-tk-row:focus-within .pn-tk-chip { display: inline-flex; }
@media (hover: none) { .pn-tk-chip { display: inline-flex; } }
.pn-tk-detail { padding: 6px 14px 14px 40px; }
.pn-tk-add { margin: 10px 12px 12px; height: 36px; padding: 0 12px; border-radius: 10px; }
.pn-tk-add .pn-tk-add-in { font-size: 13px; }
