/* ============================================================
   JHR 업무 — Slack 스타일 사이드바 + Notion 스타일 콘텐츠
   ============================================================ */

@font-face {
  font-family: 'Noto Sans KR';
  font-weight: 400;
  font-display: swap;
  src: url('/fonts/NotoSansKR-Regular.woff') format('woff');
}
@font-face {
  font-family: 'Noto Sans KR';
  font-weight: 500;
  font-display: swap;
  src: url('/fonts/NotoSansKR-Medium.woff') format('woff');
}
@font-face {
  font-family: 'Noto Sans KR';
  font-weight: 700;
  font-display: swap;
  src: url('/fonts/NotoSansKR-Bold.woff') format('woff');
}

:root {
  /* Slack 사이드바 */
  --sb-bg: #3F0E40;
  --sb-hover: #350D36;
  --sb-active: #1164A3;
  --sb-text: #CFC3CF;
  --sb-bright: #FFFFFF;
  --sb-border: rgba(255,255,255,.13);
  --badge: #E01E5A;
  /* Notion 콘텐츠 */
  --ink: #37352F;
  --ink-2: #787774;
  --ink-3: #9B9A97;
  /* 인용 글자 — 회색(--ink-2)은 가늘고 흐려 본문과 섞여 안 읽혔다. 푸른 기가 도는 짙은 회색으로 구분하고 굵기를 준다 */
  --quote-ink: #3F4B5C;
  --bg: #FFFFFF;
  --bg-2: #F7F6F3;
  --hover: #F1F1EF;
  --border: #E9E9E7;
  --accent: #2383E2;
  --accent-soft: #E7F3F8;
  --green: #007A5A;
  --green-soft: #DFF3ED;
  --red: #D44C47;
  --red-soft: #FDEBEC;
  --amber: #CB912F;
  --amber-soft: #FBF3DB;
  --purple: #9065B0;
  --purple-soft: #F6F3F9;
  /* 다크 모드가 갈아 끼우는 색(맨 아래 [data-theme="dark"]) — 라이트 값은 원래 박혀 있던 값 그대로다.
     새 화면에 #fff 를 박지 말 것: 카드·입력칸·버튼·표는 --surface, 떠 있는 층(모달·팝업·목록)은 --elev */
  --surface: #FFFFFF;
  --elev: #FFFFFF;
  --border-strong: #B9B7B4;
  --msg-hover: #F8F8F6;
  --unread: #F3F9FD;
  --unread-hover: #EAF4FB;
  --mark: #FFF1A8;
  /* 옅은 바탕(-soft) 위 글자 — 칩·달력 일정·멘션 */
  --blue-ink: #1968A8;
  --green-ink: #0F7B6C;
  --red-ink: #C4554D;
  --amber-ink: #A8790B;
  --purple-ink: #7A549B;
  --pink-soft: #FDF0F6;
  --pink-ink: #B8457A;
  --orange-soft: #FAEBDD;
  /* 안내바 글자·테두리 */
  --amber-text: #8A6100;
  --amber-line: #F0DDA8;
  --red-text: #A3282A;
  --red-line: #F1CBCA;
  --pink-text: #9C3D6B;
  --pink-line: #F3D2E2;
  --pink-sub: #B77C9A;
  --radius: 8px;
  --shadow: 0 1px 2px rgba(15,15,15,.06), 0 4px 16px rgba(15,15,15,.08);
  --shadow-lg: 0 10px 40px rgba(15,15,15,.2);
}

* { margin: 0; padding: 0; box-sizing: border-box; }
/* 두 번 톡 쳐서 화면이 확대되지 않게 — 설치형 앱에서 페이지가 커지면 앱이 아니라 웹페이지처럼 보인다.
   manipulation 은 스크롤·두 손가락 확대는 그대로 두고 더블탭 확대만 끈다. html 에만 걸면 안 되는 이유: 웹킷은
   스크롤되는 상자(.main 등)에서 touch-action 을 새로 시작해 그 안의 누름에는 안 먹는다. 클래스로 지정한
   값(.lightbox 의 none, .sidebar 의 pan-y)은 * 보다 우선한다. 입력칸을 누를 때의 자동 확대는 뷰포트의 maximum-scale=1 이 막는다. */
* { touch-action: manipulation; }

html, body { height: 100%; }

body {
  font-family: 'Noto Sans KR', -apple-system, BlinkMacSystemFont, 'Apple SD Gothic Neo', 'Malgun Gothic', sans-serif;
  color: var(--ink);
  background: var(--bg);
  font-size: 14px;
  line-height: 1.6;
  -webkit-font-smoothing: antialiased;
}

a { color: var(--accent); text-decoration: none; }
a:hover { text-decoration: underline; }
button { font-family: inherit; }

/* ---------- 앱 레이아웃 ---------- */
.app { display: flex; height: 100vh; overflow: hidden; }
/* 화면 이동(사이드바는 두고 본문만 바꾼다, app.js '화면 이동') — 응답이 늦을 때만 본문을 살짝 흐린다.
   곧바로 흐리면 빠른 이동마다 깜빡여 더 거슬리므로 .15s 기다렸다 바꾼다 */
html.nav-busy .app > .main { opacity: .6; transition: opacity .15s ease .15s; }
html.nav-busy body { cursor: progress; }

.main {
  flex: 1;
  display: flex;
  flex-direction: column;
  min-width: 0;
  background: var(--bg);
}

.content {
  flex: 1;
  overflow-y: auto;
  padding: 28px 40px 60px;
}
/* 전 화면 풀와이드 — narrow 는 과거 폭 제한의 흔적으로 더 이상 제한하지 않음 */
.content.narrow { max-width: none; }
.content.full { padding: 0; display: flex; flex-direction: column; overflow: hidden; }

/* ---------- 사이드바 (Slack) ---------- */
.sidebar {
  width: 264px;
  min-width: 264px;
  background: var(--sb-bg);
  color: var(--sb-text);
  display: flex;
  flex-direction: column;
  transition: transform .2s ease;   /* 모바일 서랍의 여닫기(아래 반응형 블록) */
}

.sb-head {
  padding: 14px 16px;
  border-bottom: 1px solid var(--sb-border);
  display: flex;
  align-items: center;
  justify-content: space-between;
}
.sb-title { color: var(--sb-bright); font-weight: 700; font-size: 17px; letter-spacing: -.2px; }
.sb-title small { display:block; font-size: 11px; font-weight: 400; color: var(--sb-text); }
/* 환경 칩('테스트') — 테스트 서버(mng-dev)에서만 붙는다. 실제 자료를 쓰는 주소라 어두운 사이드바에서도 로그인 화면에서도 눈에 띄어야 한다 */
.env-chip { display:inline-block; vertical-align:middle; padding:1px 7px; border-radius:4px; background:#f59e0b; color:#1f1300; font-size:11px; font-weight:700; letter-spacing:0; }

.sb-nav { flex: 1; overflow-y: auto; padding: 12px 8px; }
.sb-nav::-webkit-scrollbar { width: 8px; }
.sb-nav::-webkit-scrollbar-thumb { background: rgba(255,255,255,.2); border-radius: 4px; }

.sb-section {
  margin: 14px 8px 4px;
  font-size: 11px;
  text-transform: uppercase;
  letter-spacing: .6px;
  color: rgba(255,255,255,.5);
  font-weight: 700;
}

.sb-item {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 6px 10px;
  margin: 1px 0;
  border-radius: 6px;
  color: var(--sb-text);
  font-size: 14.5px;
  cursor: pointer;
  text-decoration: none !important;
  user-select: none;
}
.sb-item:hover { background: var(--sb-hover); color: var(--sb-bright); }
.sb-item.active { background: var(--sb-active); color: #fff; font-weight: 500; }
.sb-item .ico { width: 20px; display: flex; align-items: center; justify-content: center; }
.sb-item .ico .lni { width: 18px; height: 18px; }
.sb-item .grow { flex: 1; }

/* ── 라인 아이콘 (SVG 스프라이트 참조) ───────────────────── */
.lni {
  width: 1em; height: 1em; flex: none;
  fill: none; stroke: currentColor;
  stroke-width: 2; stroke-linecap: round; stroke-linejoin: round;
  vertical-align: -0.14em;
}
.topbar h1 .lni { width: 19px; height: 19px; }
.empty .big .lni { width: 42px; height: 42px; stroke-width: 1.6; }
.solo-card .logo .lni { width: 40px; height: 40px; stroke-width: 1.6; }
.doc-title .lni { width: 24px; height: 24px; }
.composer-tools .tool .lni { width: 18px; height: 18px; }
.sb-user .actions .lni { width: 16px; height: 16px; }

.sb-badge {
  background: var(--badge);
  color: #fff;
  border-radius: 10px;
  min-width: 18px;
  height: 18px;
  font-size: 11px;
  font-weight: 700;
  display: none;
  align-items: center;
  justify-content: center;
  padding: 0 6px;
}
.sb-badge.show { display: inline-flex; }
/* TF 항목의 D-day — 가장 가까운 일정 마감일까지. 일주일 안이면 색을 올려 훑을 때 걸리게 한다 */
.sb-dday {
  flex: none; font-size: 11px; font-weight: 700; letter-spacing: .2px;
  padding: 1px 7px; border-radius: 10px;
  background: rgba(255, 255, 255, .14); color: var(--sb-text);
}
.sb-dday.soon { background: var(--amber); color: #fff; }

.sb-user {
  border-top: 1px solid var(--sb-border);
  padding: 12px 14px;
  display: flex;
  align-items: center;
  gap: 10px;
}
.sb-user .info { flex: 1; min-width: 0; }
.sb-user .name { color: var(--sb-bright); font-weight: 500; font-size: 14px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.sb-user .role { font-size: 11.5px; color: var(--sb-text); }
.sb-user .actions { display: flex; gap: 4px; }
.sb-user .actions a {
  color: var(--sb-text); font-size: 15px; padding: 4px 6px; border-radius: 4px;
  text-decoration: none !important;
}
.sb-user .actions a:hover { background: var(--sb-hover); color: #fff; }
.sb-user .actions a.active { background: var(--sb-active); color: #fff; }

/* ---------- 탑바 ---------- */
.topbar {
  height: 56px;
  min-height: 56px;
  border-bottom: 1px solid var(--border);
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 0 24px;
  background: var(--bg);
}
/* 탑바는 절대 넘치지 않는다 — 좁은 화면에서 제목이 한 글자씩 세로로 접혀 본문 위를 덮던 자리다.
   (h1 이 flex 라 min-width 기본값이 auto 가 아니라 내용 폭이었고, 줄여도 안 줄어 세로로 흘렀다.
   드롭다운을 여는 요소는 탑바에 두지 말 것 — 여기서 잘린다. 검색되는 선택 상자는 .toolbar 에 있다.) */
.topbar { overflow: hidden; }
/* overflow: hidden — 버튼이 많은 탑바(휴대폰)에서 제목이 줄어들면 글자가 옆 버튼 위로 넘쳐 겹쳤다. 줄어든 만큼 잘라 낸다 */
.topbar h1 { font-size: 18px; font-weight: 700; letter-spacing: -.3px; display:flex; align-items:center; gap:8px;
             min-width: 0; white-space: nowrap; overflow: hidden; }
/* 제목 글자는 첫 span 이다(그 뒤의 상태 칩·버튼은 줄이지 않는다) */
.topbar h1 > span:first-of-type { min-width: 0; overflow: hidden; text-overflow: ellipsis; }
.topbar h1 > span ~ span, .topbar h1 .lni, .topbar h1 button { flex: none; }
.topbar .sub { color: var(--ink-3); font-size: 13px; font-weight: 400; white-space: nowrap; }
.topbar .spacer { flex: 1; }
.hamburger { display: none; background:none; border:none; font-size:20px; cursor:pointer; color: var(--ink); }

/* 탑바 전체 검색 (app.js mountTopSearch) — 모든 화면 탑바의 오른쪽 끝. 화면 버튼이 있으면 그 뒤, 없으면 margin-left:auto 로 끝에 붙는다.
   탑바가 좁아지면 제목과 함께 줄어든다(탑바는 넘치지 않는다) */
.top-search {
  display: flex; align-items: center; gap: 7px;
  margin-left: auto; flex: 0 1 260px; min-width: 150px; height: 34px; padding: 0 6px 0 10px;
  border: 1px solid var(--border); border-radius: 8px; background: var(--bg-2); color: var(--ink-3);
}
.top-search:focus-within { background: var(--surface); border-color: var(--accent); }
.top-search .lni { width: 15px; height: 15px; flex: none; }
.top-search input {
  flex: 1; min-width: 0; height: 100%; padding: 0;
  border: none; outline: none; background: none; font: inherit; font-size: 13.5px; color: var(--ink);
}
.top-search-open, .top-search-close {
  display: none; align-items: center; justify-content: center; flex: none;
  width: 32px; height: 32px; padding: 0; border: none; border-radius: 7px;
  background: none; color: var(--ink-2); cursor: pointer;
}
.top-search-open { margin-left: auto; }
.top-search-open:hover, .top-search-close:hover { background: var(--hover); color: var(--ink); }
.top-search-open .lni { width: 19px; height: 19px; }
.top-search-close { width: 26px; height: 26px; }
@media (max-width: 960px) {
  /* 좁은 탑바에 칸을 세워 두면 제목·화면 버튼이 밀려난다 — 돋보기만 두고, 누르면 탑바 전체가 검색칸이 된다 */
  .top-search { display: none; }
  /* 오른쪽 음수 여백 — 버튼의 빈 가장자리를 탑바 안쪽 여백에 걸쳐 돋보기가 다른 화면 버튼과 같은 선에 서고, 붐비는 탑바에서 6px 를 돌려받는다 */
  .top-search-open { display: inline-flex; margin-right: -6px; }
  .topbar.searching > * { display: none; }
  .topbar.searching > .top-search { display: flex; flex: 1; margin-left: 0; min-width: 0; }
  .topbar.searching .top-search-close { display: inline-flex; }
}
/* 탑바 버튼의 글자(.btn-lbl) — 휴대폰에서는 아이콘만 남긴다. 버튼이 많은 화면(사규 관리자)에서 글자가 전체 검색 버튼을 화면 밖으로 밀어냈다.
   아이콘만으로 뜻이 안 서므로 그 버튼에는 title 을 단다 */
@media (max-width: 600px) {
  .topbar .btn-lbl { display: none; }
}
/* 탑바 두 줄(휴대폰) — 화면 기능이 많아 한 줄에 안 들어가면(제목이 한두 글자로 눌리거나 체크박스·버튼 글자가 접히면)
   app.js(fitTopbar)가 .two-row 를 붙인다. 윗줄은 햄버거·뒤로·제목·안내(ⓘ)·전체 검색, 아랫줄은 화면 기능(.spacer 뒤의 것들)이다.
   들어가는 화면은 그대로 한 줄이다 — 넘치는지는 CSS 로 알 수 없어 한 줄로 그려 놓고 잰다(윗줄 목록은 app.js 의 TOPBAR_ROW1 과 같아야 한다).
   줄 나눔은 ::before(폭 100% 인 빈 칸)를 order 로 두 무리 사이에 끼워서 한다. 아랫줄은 PC 와 같은 오른쪽 정렬이고,
   검색칸(.input)은 아랫줄을 거의 다 쓴다(.spacer 보다 1000배 빨리 자란다) */
@media (max-width: 960px) {
  .topbar.two-row { flex-wrap: wrap; height: auto; align-content: flex-start; row-gap: 0; }
  .topbar.two-row::before { content: ''; order: 3; flex-basis: 100%; height: 0; }
  .topbar.two-row > * { order: 4; margin-bottom: 10px; }
  .topbar.two-row > :is(.hamburger, .back-btn, h1, .info-tip) { order: 1; margin-bottom: 0; }
  .topbar.two-row > :is(.top-search-open, .top-search) { order: 2; margin-bottom: 0; }
  .topbar.two-row > h1 { height: 56px; }
  .topbar.two-row > .input { flex-grow: 1000; }
  /* 전체 검색을 펼친 동안은 탑바 전체가 검색칸 한 줄이다 */
  .topbar.two-row.searching { flex-wrap: nowrap; height: 56px; }
  .topbar.two-row.searching::before { display: none; }
}

/* ---------- 아바타 ---------- */
.avatar {
  width: 36px; height: 36px;
  border-radius: 6px;
  display: inline-flex; align-items: center; justify-content: center;
  color: #fff; font-weight: 700; font-size: 15px;
  flex-shrink: 0;
}
.avatar.sm { width: 26px; height: 26px; font-size: 12px; border-radius: 5px; }
.avatar.lg { width: 44px; height: 44px; font-size: 18px; }

/* ---------- 버튼 ---------- */
.btn {
  display: inline-flex; align-items: center; justify-content: center; gap: 6px;
  border: 1px solid var(--border);
  background: var(--surface);
  color: var(--ink);
  border-radius: 6px;
  padding: 7px 14px;
  font-size: 13.5px;
  font-weight: 500;
  cursor: pointer;
  transition: background .1s;
  white-space: nowrap;
}
.btn:hover { background: var(--hover); }
.btn.primary { background: var(--green); border-color: var(--green); color: #fff; }
.btn.primary:hover { background: #148567; }
.btn.blue { background: var(--accent); border-color: var(--accent); color: #fff; }
.btn.blue:hover { background: #1b74ca; }
.btn.danger { color: var(--red); border-color: var(--red-line); background: var(--surface); }
.btn.danger:hover { background: var(--red-soft); }
.btn.ghost { border-color: transparent; background: transparent; color: var(--ink-2); }
.btn.ghost:hover { background: var(--hover); color: var(--ink); }
.btn.sm { padding: 4px 10px; font-size: 12.5px; }
.btn.xs { padding: 2px 8px; font-size: 12px; border-radius: 5px; }
.btn:disabled { opacity: .5; cursor: not-allowed; }

/* ---------- 입력 ---------- */
.input, .select, .textarea {
  border: 1px solid var(--border);
  border-radius: 6px;
  padding: 7px 10px;
  font-size: 14px;
  font-family: inherit;
  color: var(--ink);
  background: var(--surface);
  outline: none;
  transition: border-color .12s, box-shadow .12s;
}
.input:focus, .select:focus, .textarea:focus {
  border-color: var(--accent);
  box-shadow: 0 0 0 2px rgba(35,131,226,.18);
}
.textarea { resize: vertical; min-height: 90px; line-height: 1.55; }
.field { margin-bottom: 14px; }
.field label { display: block; font-size: 12.5px; font-weight: 500; color: var(--ink-2); margin-bottom: 5px; }
.field .input, .field .select, .field .textarea { width: 100%; }
.field .hint { font-size: 12px; color: var(--ink-3); margin-top: 4px; }
.row2 { display: grid; grid-template-columns: 1fr 1fr; gap: 12px; }

.checkbox { display: inline-flex; align-items: center; gap: 7px; cursor: pointer; font-size: 13.5px; }
.checkbox input { width: 15px; height: 15px; accent-color: var(--accent); }
/* 입력칸 묶음(.field) 안에 둔 체크박스 줄 — 위 '.field label'(칸 제목, display:block)이 선택자가 더 세서
   이 줄의 flex 까지 덮어쓰는 바람에 체크박스가 글자 가운데가 아니라 글자 기준선에 붙어 위로 떴다
   (로그인 '로그인 상태 유지', API 토큰 '사용함'). 줄 어디를 눌러도 체크되는 것은 block 이던 때와 같다. */
.field .checkbox { display: flex; }
/* display 를 정해 둔 요소는 그 값이 UA 의 [hidden] 을 이겨 hidden 속성으로 숨겨지지 않는다(.lightbox .lb-nav 와 같은 까닭).
   hidden 으로 숨기는 버튼·체크박스 줄·안내바는 여기서 다시 숨긴다 — 없던 때는 '새로 등록' 창에도 삭제 버튼이 떴다 */
.btn[hidden], .checkbox[hidden], .notice-bar[hidden] { display: none; }

/* ---------- 카드/패널 ---------- */
.card {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: 18px 20px;
}
.card h3 { font-size: 14px; font-weight: 700; margin-bottom: 12px; display:flex; align-items:center; gap:7px; }
.card h3 .more { margin-left: auto; font-size: 12.5px; font-weight: 400; }
.cards { display: grid; gap: 16px; }
.cards.c2 { grid-template-columns: 1fr 1fr; }
.cards.c3 { grid-template-columns: repeat(3, 1fr); }
.cards.c4 { grid-template-columns: repeat(4, 1fr); }
/* 격자 칸의 기본 최소 폭은 내용 폭이다 — 한 줄로 서는 긴 행이 있으면 칸이 화면보다 넓어져 좌우로 밀린다(.dash-col 참고) */
.cards > * { min-width: 0; }

.stat { text-align: left; }
.stat .num { font-size: 26px; font-weight: 700; letter-spacing: -.5px; }
.stat .lbl { font-size: 12.5px; color: var(--ink-2); }

/* ---------- 테이블 (Notion) ---------- */
.tbl-wrap { border: 1px solid var(--border); border-radius: var(--radius); overflow: auto; background: var(--surface); }
table.tbl { width: 100%; border-collapse: collapse; font-size: 13.5px; }
.tbl th {
  text-align: left;
  font-size: 12px;
  font-weight: 500;
  color: var(--ink-3);
  padding: 9px 14px;
  border-bottom: 1px solid var(--border);
  background: var(--bg-2);
  white-space: nowrap;
}
.tbl td { padding: 10px 14px; border-bottom: 1px solid var(--border); vertical-align: middle; }
.tbl tr:last-child td { border-bottom: none; }
.tbl tbody tr { cursor: default; }
.tbl tbody tr.clickable { cursor: pointer; }
.tbl tbody tr.clickable:hover { background: var(--bg-2); }
.tbl .right { text-align: right; }
.tbl .center { text-align: center; }
.tbl .nowrap { white-space: nowrap; }

/* 휴대폰 표 — 날짜·이름·버튼 칸(nowrap/center/right)이 제 폭을 지키고 남은 자리를 글 칸(클래스 없는 td)이 나눠 가지는데,
   칸이 많으면 글 칸이 한 글자 폭으로 눌려 제목이 세로로 한 글자씩 쌓였다(공지·관리웹 접속정보·프로젝트 채널 관리·연차 결재 사유…).
   글 칸에 최소 폭을 준다 — td 의 min-width 는 브라우저마다 달리 다뤄서(사파리) 폭을 가진 빈 블록(::before)으로 민다.
   표가 넓어지면 .tbl-wrap 이 좌우로 스크롤한다(원래 그렇게 본다). 클래스가 붙은 칸(근태 날짜 칸 등)·빈 줄(colspan)·체크박스만 든 칸은 두고 */
@media (max-width: 600px) {
  /* 한글은 글자 사이 어디서나 줄이 바뀌어 '헬스체크 테스/트' 처럼 끊겼다 — 좁은 칸에서는 낱말 단위로만 나눈다(주소 칸은 인라인 break-all 이 이긴다) */
  .tbl td:not([class]):not([colspan]) { word-break: keep-all; }
  .tbl td:not([class]):not([colspan]):not(:has(> input:only-child))::before {
    content: ''; display: block; width: 6em; height: 0;   /* 한 줄에 여섯 글자쯤 — 거의 들어가는 표(공휴일)는 좌우로 밀리지 않는다 */
  }
}
/* 고정 높이 안에서 스크롤하는 목록 — 머리글이 따라다니지 않으면 컬럼이 많을 때 어느 칸인지 알 수 없다.
   sticky 상태에서는 border-bottom 이 함께 스크롤되어 사라지므로 inset 그림자로 선을 그린다. */
.tbl-wrap.sticky-head thead th {
  position: sticky; top: 0; z-index: 1;
  box-shadow: inset 0 -1px 0 var(--border);
}
/* ---------- 칩/뱃지 ---------- */
.chip {
  display: inline-flex; align-items: center; gap: 4px;
  border-radius: 4px;
  padding: 2px 8px;
  font-size: 12px;
  font-weight: 500;
  white-space: nowrap;
}
.chip.gray { background: var(--hover); color: var(--ink-2); }
.chip.blue { background: var(--accent-soft); color: var(--blue-ink); }
.chip.green { background: var(--green-soft); color: var(--green-ink); }
.chip.red { background: var(--red-soft); color: var(--red-ink); }
.chip.amber { background: var(--amber-soft); color: var(--amber-ink); }
.chip.purple { background: var(--purple-soft); color: var(--purple-ink); }
.chip.pink { background: var(--pink-soft); color: var(--pink-ink); }
/* 상태 필터 알약 — 탭 아래 두 번째 줄이라 탭보다 작게(계층이 보이게) */
.seg { display: inline-flex; flex-wrap: wrap; gap: 4px; }
.seg-btn {
  border: 1px solid var(--border); background: var(--surface); color: var(--ink-2);
  border-radius: 999px; padding: 4px 11px; font-size: 12.5px; cursor: pointer; font-family: inherit;
}
.seg-btn:hover { background: var(--hover); }
.seg-btn.active { background: var(--accent); border-color: var(--accent); color: #fff; }
.seg-btn .cnt { margin-left: 4px; font-size: 11.5px; opacity: .75; }
/* 구분 드롭다운(프로젝트 / TF / 팀 채널) — 표 안에 들어가므로 낮게. 고르는 순간 옮기므로 버튼이 따로 없다 */
.select.kind-sel { height: 28px; padding-top: 2px; padding-bottom: 2px; font-size: 12.5px; width: auto; }

.count-badge {
  background: var(--badge); color: #fff; border-radius: 10px;
  font-size: 11px; font-weight: 700; padding: 1px 7px; display: inline-block;
}

.pin-flag { color: var(--amber); font-size: 13px; }

/* ---------- 목록 툴바 ---------- */
.toolbar { display: flex; flex-wrap: wrap; gap: 8px; align-items: center; margin-bottom: 16px; }
.toolbar .spacer { flex: 1; }
.toolbar .input, .toolbar .select { height: 34px; }

/* ---------- 페이지네이션 ---------- */
.pager { display: flex; gap: 4px; justify-content: center; margin-top: 18px; align-items: center; }
.pager button {
  min-width: 30px; height: 30px; border: 1px solid var(--border); border-radius: 6px;
  background: var(--surface); cursor: pointer; font-size: 13px; color: var(--ink-2);
}
.pager button:hover { background: var(--hover); }
.pager button.cur { background: var(--ink); color: var(--bg); border-color: var(--ink); font-weight: 700; }
.pager .meta { font-size: 12px; color: var(--ink-3); margin-left: 10px; }

/* ---------- 모달 ---------- */
.modal-overlay {
  display: none;
  position: fixed; inset: 0;
  background: rgba(15,15,15,.45);
  z-index: 100;
  align-items: flex-start;
  justify-content: center;
  padding: 60px 16px;
  overflow-y: auto;
}
.modal-overlay.open { display: flex; }
.modal {
  background: var(--elev);
  border-radius: 10px;
  box-shadow: var(--shadow-lg);
  width: 100%;
  max-width: 520px;
  animation: pop .14s ease;
}
.modal.wide { max-width: 720px; }
@keyframes pop { from { transform: translateY(8px); opacity: 0; } to { transform: none; opacity: 1; } }
.modal-head {
  padding: 16px 20px 0;
  display: flex; align-items: center; justify-content: space-between;
}
.modal-head h2 { font-size: 16px; font-weight: 700; }
.modal-head .x { background: none; border: none; font-size: 18px; cursor: pointer; color: var(--ink-3); padding: 4px 8px; border-radius: 6px; }
.modal-head .x:hover { background: var(--hover); }
.modal-body { padding: 16px 20px; }
.modal-foot { padding: 0 20px 18px; display: flex; justify-content: flex-end; gap: 8px; }

/* ---------- 토스트 ---------- */
#toast-wrap { position: fixed; bottom: 24px; left: 50%; transform: translateX(-50%); z-index: 460; display: flex; flex-direction: column; gap: 8px; align-items: center; }
.toast {
  background: #2B2B2B; color: #fff;
  border-radius: 8px;
  padding: 10px 18px;
  font-size: 13.5px;
  box-shadow: var(--shadow-lg);
  animation: rise .18s ease;
  max-width: 420px;
}
.toast.error { background: var(--red); }
.toast .toast-act { margin-left: 12px; padding: 2px 0; border: 0; background: none; color: #8FD3FF; font: inherit; font-weight: 700; cursor: pointer; white-space: nowrap; }
.toast.success { background: var(--green); }
@keyframes rise { from { transform: translateY(8px); opacity: 0; } to { transform: none; opacity: 1; } }

/* ---------- 내려받기 진행 (아이폰 공유 시트로 넘기기 전, app.js '아이폰: 내려받기는 공유 시트로') ---------- */
/* 라이트박스(400) 위에서도 눌러 받으므로 그보다 위에 둔다.
   자리는 탑바(56px) 바로 아래 — 화면 아래에 두었더니 채널 컴포저를 가려 받는 동안 글을 못 쓴다는 불편이 들어왔다 */
.share-panel {
  display: none; position: fixed; z-index: 450;
  left: 16px; right: 16px; top: 64px;
  max-width: 380px; margin: 0 auto;
  background: var(--elev); color: var(--ink);
  border: 1px solid var(--border); border-radius: 10px;
  box-shadow: var(--shadow-lg);
  padding: 12px 14px;
  animation: sp-drop .18s ease;
}
.share-panel.open { display: block; }
.share-panel .sp-row { display: flex; align-items: center; gap: 10px; min-width: 0; }
.share-panel .sp-title { flex: 1; min-width: 0; font-size: 13.5px; font-weight: 500; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.share-panel .sp-pct { font-size: 12.5px; color: var(--ink-2); font-variant-numeric: tabular-nums; }
.share-panel .sp-bar { position: relative; height: 6px; margin: 8px 0 10px; background: var(--hover); border-radius: 3px; overflow: hidden; }
.share-panel .sp-bar i { display: block; height: 100%; width: 0; background: var(--accent); border-radius: 3px; transition: width .15s linear; }
.share-panel .sp-bar.indet i { width: 35%; animation: sp-indet 1.1s ease-in-out infinite; }
.share-panel.ready .sp-bar i { background: var(--green); }
.share-panel .sp-sub { flex: 1; min-width: 0; font-size: 12.5px; color: var(--ink-2); font-variant-numeric: tabular-nums; }
.share-panel .sp-acts { display: flex; gap: 6px; flex-shrink: 0; }
.share-panel .sp-save { display: none; }
.share-panel.ready .sp-save { display: inline-flex; }
.share-panel .sp-save .lni { width: 14px; height: 14px; }
@keyframes sp-indet { from { transform: translateX(-100%); } to { transform: translateX(290%); } }
@keyframes sp-drop { from { transform: translateY(-8px); opacity: 0; } to { transform: none; opacity: 1; } }

/* ---------- 탭 ---------- */
.tabs { display: flex; gap: 2px; border-bottom: 1px solid var(--border); margin-bottom: 18px; }
.tab {
  padding: 8px 14px;
  font-size: 14px;
  color: var(--ink-2);
  cursor: pointer;
  border: none; background: none;
  border-bottom: 2px solid transparent;
  margin-bottom: -1px;
  font-weight: 500;
}
.tab:hover { color: var(--ink); }
.tab.active { color: var(--ink); border-bottom-color: var(--ink); font-weight: 700; }
.tab .cnt { font-size: 12px; color: var(--ink-3); margin-left: 4px; }
/* 휴대폰 — 탭이 많으면 줄어들며 글자가 두 줄로 접혔다('전체 내/역'·'연차 부/여', 개수는 아랫줄로). 접지 않고 한 줄로 두고
   좌우로 민다(문서관리 카테고리 탭과 같은 방식 — 스크롤 상자는 탭의 음수 margin 을 잘라 내므로 밑줄을 안쪽 그림자로 긋는다) */
@media (max-width: 960px) {
  .tabs { overflow-x: auto; overflow-y: hidden; scrollbar-width: none; border-bottom: none; box-shadow: inset 0 -1px 0 var(--border); }
  .tabs::-webkit-scrollbar { display: none; }
  .tabs .tab { flex-shrink: 0; white-space: nowrap; margin-bottom: 0; }
}

/* ---------- 빈 상태 ---------- */
.empty { text-align: center; padding: 48px 20px; color: var(--ink-3); }
.empty .big { font-size: 34px; margin-bottom: 10px; }

/* ---------- 로그인/차단 독립 페이지 ---------- */
.solo-page {
  min-height: 100vh;
  display: flex; align-items: center; justify-content: center;
  background: var(--bg-2);
  padding: 20px;
}
.solo-card {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: 12px;
  box-shadow: var(--shadow);
  width: 100%; max-width: 400px;
  padding: 36px 34px 30px;
}
.solo-card .logo { font-size: 30px; margin-bottom: 6px; }
.solo-card h1 { font-size: 21px; font-weight: 700; letter-spacing: -.4px; margin-bottom: 4px; }
.solo-card .desc { color: var(--ink-2); font-size: 13.5px; margin-bottom: 24px; }
.solo-card .btn { width: 100%; height: 42px; font-size: 14.5px; margin-top: 6px; }
.solo-card .msg { margin-top: 14px; font-size: 13px; color: var(--red); min-height: 18px; }
.solo-card .foot { margin-top: 20px; font-size: 12px; color: var(--ink-3); text-align: center; }

/* ---------- 프로젝트 채널(채팅) ---------- */
.channel { flex: 1; display: flex; min-height: 0; }
.channel-main { flex: 1; display: flex; flex-direction: column; min-width: 0; }
.channel-aside {
  width: 280px; min-width: 280px;
  border-left: 1px solid var(--border);
  overflow-y: auto;
  padding: 18px 16px;
  background: var(--bg-2);
}
.channel-aside h4 { font-size: 12px; color: var(--ink-3); text-transform: uppercase; letter-spacing: .5px; margin: 14px 0 8px; }
.channel-aside .member-row { display: flex; align-items: center; gap: 8px; padding: 5px 4px; border-radius: 6px; font-size: 13.5px; }
.channel-aside .member-row:hover { background: var(--hover); }
/* [ID] 복사 버튼 — 숫자를 보이지 않고 누르면 프로젝트·회원 ID 가 클립보드로 간다(외부 연동 설정용, API 토큰 발급 권한자 이상). 네모 안에 ID 라고만 써서 이름표와 헷갈리지 않게 */
.id-copy { display: inline-flex; align-items: center; height: 18px; padding: 0 5px; border: 1px solid var(--border); border-radius: 4px; background: var(--surface); color: var(--ink-3); font: 700 10.5px/1 ui-monospace, SFMono-Regular, Menlo, monospace; letter-spacing: .5px; cursor: pointer; vertical-align: middle; }
.id-copy:hover { border-color: var(--accent); color: var(--accent); background: var(--accent-soft); }
.topbar h1 .id-copy { margin-left: 4px; }

.pinned-strip {
  border-bottom: 1px solid var(--border);
  background: var(--amber-soft);
  padding: 8px 22px;
  font-size: 13px;
  max-height: 132px;
  overflow-y: auto;
}
.pinned-strip .pin-item { display: flex; gap: 8px; padding: 3px 0; align-items: baseline; cursor: pointer; }
.pinned-strip .pin-item:hover { text-decoration: underline; }


/* 대시보드 오늘 근무 현황 */
.work-line { display: flex; gap: 10px; padding: 5px 0; font-size: 13px; align-items: baseline; }
.work-line + .work-line { border-top: 1px solid var(--border); }
.work-lbl { flex: 0 0 62px; color: var(--ink-3); font-size: 12px; }
.work-body { flex: 1; display: flex; flex-wrap: wrap; gap: 4px 10px; }
.work-who { display: inline-flex; align-items: baseline; gap: 3px; }
.work-who b { font-weight: 500; color: var(--ink-3); font-size: 12px; }
.work-who.in { color: var(--green-ink); }
.work-who.done { color: var(--ink-2); }
.work-who.off { color: var(--purple); }
.work-who.yet { color: var(--ink-3); }
.work-line .muted { color: var(--ink-3); }
/* 출퇴근 막대 — 팀-출퇴근 채널 하단(컴포저 자리를 대신한다) */
.attend-bar {
  border-top: 1px solid var(--border);
  background: var(--bg-2);
  padding: 10px 22px;
  font-size: 13px;
}
.attend-bar .attend-act { display: flex; align-items: center; gap: 8px; }
.attend-bar .attend-act .btn { height: 30px; padding: 0 16px; }
.attend-bar .attend-list { display: flex; flex-wrap: wrap; gap: 6px 14px; margin-top: 8px; color: var(--ink-2); }
.attend-bar .attend-who { display: inline-flex; align-items: baseline; gap: 4px; }
.attend-bar .attend-who b { color: var(--ink); font-weight: 600; }
.attend-bar .attend-who .out { color: var(--ink-3); }
.attend-bar .muted { color: var(--ink-3); }
.timeline { flex: 1; overflow-y: auto; padding: 18px 0 8px; }
.load-older { text-align: center; padding: 6px 0 14px; }

.msg { display: flex; gap: 12px; padding: 7px 24px; position: relative; }
.msg:hover { background: var(--msg-hover); }
.msg .m-body { flex: 1; min-width: 0; }
/* 좁은 화면에서는 줄을 바꾼다 — 안 그러면 flex 가 칸을 눌러 이름과 '읽음 N' 이 두 줄로 꺾인다 */
.msg .m-head { display: flex; flex-wrap: wrap; align-items: baseline; gap: 0 8px; }
.msg .m-name { font-weight: 700; font-size: 14px; white-space: nowrap; }
.msg .m-dept { font-size: 11.5px; color: var(--ink-3); white-space: nowrap; }
.msg .m-time { font-size: 11.5px; color: var(--ink-3); white-space: nowrap; }
.msg .m-edited { font-size: 11px; color: var(--ink-3); white-space: nowrap; }
.msg .m-content { white-space: pre-wrap; word-break: break-word; font-size: 14px; margin-top: 1px; }
/* 게시글 본문(.m-content)과 댓글(.c-text) 모두 — 댓글은 .m-content 안이 아니라 선택자를 좁히면 댓글 멘션이 안 칠해진다 */
.m-content .mention, .c-text .mention { background: var(--accent-soft); color: var(--blue-ink); border-radius: 3px; padding: 0 3px; font-weight: 500; }
.msg .m-pin-mark { font-size: 11.5px; color: var(--amber); margin-bottom: 2px; }
/* 읽음 N — 글 머리줄의 시각 옆에 작게. 누르면 누가 언제 읽었는지 모달이 뜬다.
   머리줄 끝(margin-left:auto)에 두면 마우스를 올렸을 때 뜨는 고정·삭제 막대(.m-actions)가 그 위를 덮는다 */
.msg .m-reads {
  border: none; background: none; cursor: pointer; padding: 0 4px; white-space: nowrap;
  font-size: 11.5px; color: var(--ink-3); display: inline-flex; align-items: center; gap: 3px; border-radius: 4px;
}
.msg .m-reads .lni { width: 12px; height: 12px; }
.msg .m-reads:hover { background: var(--hover); color: var(--ink); }
.read-sec + .read-sec { margin-top: 14px; }
.read-sec h4 { font-size: 12.5px; color: var(--ink-2); margin: 0 0 6px; }
.read-sec .read-cnt { color: var(--ink-3); font-weight: 400; margin-left: 4px; }
.read-row { display: flex; align-items: center; gap: 10px; padding: 5px 0; }
.read-row .grow { flex: 1; min-width: 0; }
.read-row .read-name { font-weight: 600; font-size: 13.5px; }
.read-row .read-dept { font-size: 11.5px; color: var(--ink-3); margin-left: 6px; }
.read-row .read-time { font-size: 12px; color: var(--ink-3); white-space: nowrap; }
.read-none { font-size: 13px; color: var(--ink-3); padding: 4px 0; }

/* 확인(✓) 칩 — 관리자 이상이 남긴 체크 반응. 본문 아래에 작게 두고, 마우스를 올리면(data-tip) 누가 언제 확인했는지 뜬다.
   내가 확인한 글은 초록(.on). 관리자에게는 버튼이라 누르면 토글되고, 직원에게는 보기만 하는 칩이다 */
/* 헬스체크 장애 글의 상태 줄 — 상태 칩 · 누가 언제 · [작업 착수][완료] */
.msg .m-hc { display: flex; align-items: center; flex-wrap: wrap; gap: 6px; margin-top: 8px; font-size: 12px; color: var(--ink-2); }
.msg .m-hc .hc-meta:empty { display: none; }
.msg .m-hc .hc-btn {
  padding: 2px 9px; border-radius: 12px; font-size: 12px; font-family: inherit; cursor: pointer;
  border: 1px solid var(--border); background: var(--surface); color: var(--ink-2);
}
/* 업무협조를 알린 글 — 담당자에게만 뜨는 '내용확인'(자기 협조로 간다) */
.msg .m-coop { margin-top: 6px; }
.msg .m-hc .hc-btn:hover { border-color: var(--green); color: var(--green-ink); }
.msg .m-checks { margin-top: 6px; }
.msg .m-checks:empty { display: none; }
.msg .m-check {
  display: inline-flex; align-items: center; gap: 4px;
  padding: 1px 8px 1px 6px; border-radius: 12px; font-size: 12px; font-family: inherit;
  border: 1px solid var(--border); background: var(--surface); color: var(--ink-2); cursor: default;
}
.msg .m-check .lni { width: 13px; height: 13px; }
.msg .m-check.on { border-color: #9BD3C4; background: var(--green-soft); color: var(--green-ink); }
.msg button.m-check { cursor: pointer; }
.msg button.m-check:hover { border-color: var(--green); color: var(--green-ink); }

.msg .m-actions {
  display: none;
  position: absolute; top: -12px; right: 20px;
  background: var(--elev); border: 1px solid var(--border); border-radius: 8px;
  box-shadow: var(--shadow);
  padding: 2px;
}
.msg:hover .m-actions { display: flex; }
.m-actions button {
  border: none; background: none; cursor: pointer;
  font-size: 13px; padding: 5px 8px; border-radius: 6px; color: var(--ink-2);
}
.m-actions button:hover { background: var(--hover); color: var(--ink); }

/* 이미지와 파일칩이 같은 줄에 서면 칩이 이미지 높이만큼 늘어난다 — 위쪽에 맞춘다 */
.m-attach { display: flex; flex-wrap: wrap; align-items: flex-start; gap: 8px; margin-top: 8px; }
.file-chip {
  display: inline-flex; align-items: center; gap: 7px;
  border: 1px solid var(--border); border-radius: 8px;
  padding: 7px 11px; font-size: 12.5px; background: var(--surface);
  max-width: 260px;
}
.file-chip .fname { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.file-chip .fsize { color: var(--ink-3); font-size: 11px; }
.file-chip a, .file-chip button.del { text-decoration: none; }
.file-chip button.del { border:none; background:none; color: var(--ink-3); cursor:pointer; font-size: 12px; }
.file-chip button.del:hover { color: var(--red); }
.img-thumb { max-width: 240px; max-height: 170px; border-radius: 8px; border: 1px solid var(--border); cursor: zoom-in; display:block; }

/* 썸네일 오른쪽 위 내려받기 (App.imgThumb) */
.thumb-wrap { position: relative; display: inline-block; line-height: 0; }
.thumb-wrap .thumb-dl {
  position: absolute; top: 6px; right: 6px;
  width: 26px; height: 26px; border-radius: 6px;
  background: rgba(0,0,0,.55); color: #fff;
  display: flex; align-items: center; justify-content: center;
  opacity: 0; transition: opacity .12s, background .12s;
}
.thumb-wrap:hover .thumb-dl, .thumb-wrap .thumb-dl:focus-visible { opacity: 1; }
.thumb-wrap .thumb-dl:hover { background: rgba(0,0,0,.82); }
.thumb-wrap .thumb-dl .lni { width: 15px; height: 15px; }
/* 썸네일 삭제(✕) — 내려받기 왼쪽에 나란히. 지울 수 있는 사람에게만 그려진다(App.imgThumb 의 deletable) */
.thumb-wrap .thumb-del {
  position: absolute; top: 6px; right: 36px;
  width: 26px; height: 26px; border-radius: 6px; border: none; padding: 0;
  background: rgba(0,0,0,.55); color: #fff; font-size: 13px; line-height: 1; cursor: pointer;
  display: flex; align-items: center; justify-content: center;
  opacity: 0; transition: opacity .12s, background .12s;
}
.thumb-wrap:hover .thumb-del, .thumb-wrap .thumb-del:focus-visible { opacity: 1; }
.thumb-wrap .thumb-del:hover { background: rgba(212,76,71,.9); }
/* 터치 화면에는 호버가 없다 — 늘 보여 주지 않으면 닿을 방법이 없다 */
@media (hover: none) { .thumb-wrap .thumb-dl, .thumb-wrap .thumb-del { opacity: 1; } }

.dl-all { font-weight: 500; margin-left: 8px; vertical-align: middle; }
.m-attach .dl-all { margin-left: 0; }

/* 붙여넣기·끌어놓기로 고른 파일 (App.fileDrop) */
.drop-files { display: flex; flex-wrap: wrap; gap: 6px; margin-top: 8px; }
.drop-files:empty { display: none; }
.file-chip .pic { display: inline-flex; align-items: center; justify-content: center; width: 22px; height: 22px; flex: none; }
.file-chip .pic img { width: 22px; height: 22px; object-fit: cover; border-radius: 4px; display: block; }
/* 파일을 끌고 들어온 자리 — 어디에 놓으면 되는지 한눈에 보이게 */
.drop-hot { position: relative; }
.drop-hot::after {
  content: '여기에 놓으면 첨부됩니다';
  position: absolute; inset: 0; z-index: 30;
  display: flex; align-items: center; justify-content: center;
  background: rgba(35,131,226,.08);
  border: 2px dashed var(--accent); border-radius: inherit;
  color: var(--accent); font-size: 14px; font-weight: 700;
  pointer-events: none;
}

.m-comments { margin-top: 8px; }
.m-comments .toggle { font-size: 12.5px; color: var(--accent); cursor: pointer; background:none; border:none; padding:0; }
.comment-list { margin-top: 8px; border-left: 2px solid var(--border); padding-left: 12px; display: flex; flex-direction: column; gap: 8px; }
.comment-item { display: flex; gap: 8px; padding: 2px 4px; margin: 0 -4px; border-radius: 6px; transition: background .4s; }   /* 알림에서 온 댓글을 잠깐 칠한다 */
.comment-item .c-body { flex: 1; min-width: 0; }
.comment-item .c-head { display: flex; gap: 6px; align-items: baseline; }
.comment-item .c-name { font-weight: 500; font-size: 12.5px; }
.comment-item .c-time { font-size: 11px; color: var(--ink-3); }
.comment-item .c-text { font-size: 13px; white-space: pre-wrap; word-break: break-word; }
.comment-item .c-del { border:none; background:none; color: var(--ink-3); cursor:pointer; font-size:11px; }
.comment-item .c-del:hover { color: var(--red); }
/* 댓글 확인(✓) 버튼 — 관리자 이상에게만, 삭제 버튼과 같은 크기의 글자 버튼 */
.comment-item .c-check { border:none; background:none; color: var(--ink-3); cursor:pointer; font-size:11px; display:inline-flex; align-items:center; }
.comment-item .c-check .lni { width: 12px; height: 12px; }
.comment-item .c-check:hover { color: var(--green-ink); }
.comment-item .m-checks { margin-top: 4px; }
.comment-input { display: flex; gap: 6px; margin-top: 8px; }
.comment-input .input { flex: 1; height: 32px; font-size: 13px; }

/* 입력 컴포저 (Slack) */
.composer { padding: 10px 24px 18px; }
.composer-box {
  border: 1px solid var(--border-strong);
  border-radius: 10px;
  background: var(--surface);
  transition: border-color .12s, box-shadow .12s;
}
.composer-box:focus-within { border-color: var(--accent); box-shadow: 0 0 0 2px rgba(35,131,226,.15); }
.composer-box textarea {
  width: 100%; border: none; outline: none; resize: none;
  padding: 11px 13px 4px; font-size: 14px; font-family: inherit;
  max-height: 180px; line-height: 1.55; background: transparent;
}
.composer-tools { display: flex; align-items: center; gap: 6px; padding: 5px 8px 7px; }
.composer-tools .spacer { flex: 1; }
.composer-tools .tool {
  border: none; background: none; cursor: pointer; font-size: 15px;
  color: var(--ink-3); padding: 4px 7px; border-radius: 6px;
}
.composer-tools .tool:hover { background: var(--hover); color: var(--ink); }
.composer-tools .send {
  background: var(--green); color: #fff; border: none; border-radius: 6px;
  padding: 5px 14px; font-size: 13px; font-weight: 700; cursor: pointer;
}
.composer-tools .send:disabled { opacity: .4; cursor: default; }
.composer .pending-files { display: flex; flex-wrap: wrap; gap: 6px; padding: 0 10px 8px; }
/* 채널 컴포저 — 파일을 올리는 동안의 진행 막대, 글만 올라가고 파일이 남았을 때의 [그 글에 다시 올리기] 줄
   (display 를 정해 둔 요소라 hidden 을 다시 적는다) */
.up-box { display: flex; align-items: center; gap: 10px; padding: 2px 4px 6px; font-size: 12px; color: var(--ink-3); }
.up-box .bar { flex: 1; min-width: 60px; height: 5px; border-radius: 3px; background: var(--hover); overflow: hidden; }
.up-box .bar i { display: block; height: 100%; width: 0; background: var(--accent); transition: width .2s; }
.up-retry { display: flex; flex-wrap: wrap; align-items: center; gap: 6px 10px; margin: 0 2px 6px; padding: 8px 10px;
            border-radius: 8px; background: var(--red-soft); color: var(--red-ink); font-size: 12.5px; }
.up-retry .msg { flex: 1; min-width: 0; display: flex; flex-wrap: wrap; align-items: center; gap: 4px 6px; }
.up-retry .msg .lni { width: 14px; height: 14px; }
.up-retry .names { font-weight: 600; max-width: 100%; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.up-retry .why { color: var(--ink-2); }
.up-retry .acts { display: inline-flex; gap: 6px; margin-left: auto; }
.up-box[hidden], .up-retry[hidden] { display: none; }
/* 화면 위 안내 줄 — 지금 상태를 알리고 고칠 곳을 가리킨다 */
.notice-bar {
  display: flex; align-items: center; gap: 8px; flex-wrap: wrap;
  background: var(--amber-soft); color: var(--amber-text);
  border: 1px solid var(--amber-line); border-radius: 8px;
  padding: 10px 14px; font-size: 13px; margin-bottom: 14px;
}
.notice-bar a { color: var(--amber-text); font-weight: 700; }
.notice-bar .lni { width: 16px; height: 16px; flex: none; }
/* 빨간 쪽 — 사람 이름이 들어가는 자리라 눈에 띄어야 하지만 공지처럼 읽히면 안 된다 */
.notice-bar.danger { background: var(--red-soft); color: var(--red-text); border-color: var(--red-line); }
.notice-bar.danger a { color: var(--red-text); }
.notice-bar.danger .btn { margin-left: auto; }
/* 공유메모 마감 알림바 항목 — 제목(링크) 뒤에 '오늘·내일·D-2·N일 지남' 을 작게, 항목 사이는 점으로 */
.notice-bar .due-when { font-size: 12px; opacity: .85; }
.notice-bar .sep { opacity: .45; }
/* 생일반차 — 연차 잔여와 따로 가는 무상 반차라 카드 숫자에 섞지 않고 한 줄로 둔다. 다 쓴 해에는 가라앉힌다 */
.bday-bar {
  display: flex; align-items: center; gap: 8px; flex-wrap: wrap;
  background: var(--pink-soft); color: var(--pink-text); border: 1px solid var(--pink-line); border-radius: 8px;
  padding: 9px 14px; font-size: 13px; margin-bottom: 18px;
}
.bday-bar .lni { width: 16px; height: 16px; flex: none; }
.bday-bar .sub { color: var(--pink-sub); }
.bday-bar .btn { margin-left: auto; }
.bday-bar.used { background: var(--bg-2); color: var(--ink-2); border-color: var(--border); }
.bday-bar.used .sub { color: var(--ink-3); }
.archived-bar {
  background: var(--amber-soft); color: var(--amber-ink); text-align: center;
  padding: 10px; font-size: 13px; border-radius: 8px; margin: 0 24px 16px;
}

/* 멘션 드롭다운 */
.mention-pop {
  position: absolute;
  background: var(--elev); border: 1px solid var(--border); border-radius: 8px;
  box-shadow: var(--shadow-lg);
  max-height: 200px; overflow-y: auto;
  min-width: 220px;
  z-index: 200;
  display: none;
}
.mention-pop.open { display: block; }
.mention-pop .mi { display: flex; align-items: center; gap: 8px; padding: 7px 12px; cursor: pointer; font-size: 13.5px; }
/* 키보드로 고른 줄과 마우스가 얹힌 줄을 구분한다 — 같은 색이면 화살표로 옮기는 동안 두 줄이 골라진 것처럼 보인다 */
.mention-pop .mi:hover { background: var(--bg-2); }
.mention-pop .mi.sel { background: var(--accent-soft); box-shadow: inset 2px 0 0 var(--accent); }
.mention-pop .mi .dept { color: var(--ink-3); font-size: 11.5px; }

/* ---------- 멘션 강조(컴포저) ---------- */
/* textarea 안의 일부 글자만 칠할 수 없어, 같은 글꼴·여백의 div 를 뒤에 깔고 입력칸은 글자만 투명하게 한다.
   폭이 어긋나면 줄바꿈 위치가 달라져 강조가 밀리므로, 글꼴 값은 app.js 가 계산된 스타일에서 베껴 넣는다. */
.mention-host { position: relative; display: block; }
.mention-host > .mention-input {
  position: relative; z-index: 1;
  background: transparent; color: transparent; caret-color: var(--ink);
}
.mention-host > .mention-input::placeholder { color: var(--ink-3); }
.mention-host > .mention-input::selection { background: #B9DDF3; }
.mention-mirror {
  position: absolute; top: 0; left: 0; z-index: 0;
  box-sizing: border-box;            /* 폭·높이는 app.js 가 textarea 의 clientWidth/Height 로 넣는다 */
  overflow: hidden; pointer-events: none;
  white-space: pre-wrap; overflow-wrap: break-word;
  color: var(--ink);
}
/* 글자 폭을 바꾸는 값(padding·font-weight)은 쓰지 않는다 — 뒤따르는 글자가 밀려 어긋난다.
   여백처럼 보이는 것은 box-shadow 로 낸다(레이아웃에 영향이 없다). */
.mention-mirror mark {
  background: var(--accent-soft); color: var(--blue-ink);
  border-radius: 3px; box-shadow: 0 0 0 2px var(--accent-soft);
}

/* 채널 컴포저의 실시간 마크다운(App.mdLive) — 위와 같은 이유로 글자 폭을 바꾸는 꾸밈은 쓰지 않는다:
   굵게는 font-weight 대신 외곽선, 코드는 고정폭 글꼴 없이 바탕색만, 제목은 크기 대신 굵기·색. 기호(** ` >)는 지우지 않고 흐리게 둔다 */
.mention-mirror .lv-mk { color: var(--ink-3); }
.mention-mirror .lv-b, .mention-mirror .lv-h { -webkit-text-stroke: .45px currentColor; }
.mention-mirror .lv-i { font-style: italic; }
.mention-mirror .lv-s { text-decoration: line-through; }
.mention-mirror .lv-code, .mention-mirror .lv-pre { background: var(--bg-2); border-radius: 3px; box-shadow: 0 0 0 1px var(--border); color: var(--red-ink); }
.mention-mirror .lv-pre { color: var(--ink); }
.mention-mirror .lv-a { color: var(--accent); text-decoration: underline; }
.mention-mirror .lv-url { color: var(--ink-3); }
.mention-mirror .lv-qm { color: var(--accent); -webkit-text-stroke: .45px currentColor; }
.mention-mirror .lv-q { color: var(--quote-ink); }   /* 굵기는 폭을 바꿔 못 준다 — 색만 보이는 쪽과 맞춘다 */
.mention-mirror .lv-li { color: var(--accent); -webkit-text-stroke: .45px currentColor; }

/* ---------- 달력 ---------- */
/* flex-wrap — 한 줄에 다 안 들어가면(휴대폰 근태관리의 범례·안내) 넘치지 않고 아랫줄로 내려간다. 들어가는 화면은 그대로다 */
.cal-head { display: flex; flex-wrap: wrap; align-items: center; gap: 10px; margin-bottom: 12px; }
.cal-head h3 { font-size: 16px; font-weight: 700; min-width: 120px; text-align: center; }
.cal { border: 1px solid var(--border); border-radius: var(--radius); overflow: hidden; background: var(--surface); }
.cal-grid { display: grid; grid-template-columns: repeat(7, 1fr); }
.cal-dow { padding: 8px; text-align: center; font-size: 12px; color: var(--ink-3); background: var(--bg-2); border-bottom: 1px solid var(--border); font-weight: 500; }
.cal-cell {
  min-height: 96px; padding: 6px 7px;
  border-right: 1px solid var(--border); border-bottom: 1px solid var(--border);
  font-size: 12px;
  overflow: hidden;
}
.cal-cell:nth-child(7n) { border-right: none; }
.cal-cell.dim { background: var(--bg-2); color: var(--ink-3); }
/* 공휴일 — 빨간 날짜만으로는 일요일과 구분이 안 돼 칸 전체를 연분홍으로 깐다 */
.cal-cell.holiday { background: var(--red-soft); }
.cal-cell .d { font-size: 12px; font-weight: 500; margin-bottom: 3px; }
.cal-cell.today .d { color: #fff; background: var(--red); border-radius: 50%; width: 20px; height: 20px; display: inline-flex; align-items: center; justify-content: center; }
.cal-cell .sun { color: var(--red); }
.cal-cell .sat { color: var(--accent); }
/* 공휴일 이름은 날짜 옆 한 줄 — 공휴일에도 일정·연차 칩이 뜨므로 칩 모양으로 두면 일정과 섞인다 */
.cal-dh { display: flex; align-items: center; gap: 4px; min-width: 0; margin-bottom: 3px; }
.cal-dh .d { margin-bottom: 0; flex: none; }
.cal-hol { min-width: 0; font-size: 11px; font-weight: 500; color: var(--red); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.cal-ev {
  display: block;
  border-radius: 4px; padding: 1px 6px; margin-bottom: 2px;
  font-size: 11.5px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
  cursor: pointer;
}
.cal-ev.blue { background: var(--accent-soft); color: var(--blue-ink); }
.cal-ev.green { background: var(--green-soft); color: var(--green-ink); }
.cal-ev.amber { background: var(--amber-soft); color: var(--amber-ink); }
.cal-ev.red { background: var(--red-soft); color: var(--red-ink); }
.cal-ev.purple { background: var(--purple-soft); color: var(--purple-ink); }
.cal-ev.gray { background: var(--bg-2); color: var(--ink-2); }
.cal-ev.holiday { background: transparent; color: var(--red); font-weight: 500; cursor: default; }
.cal-ev.mine { font-weight: 700; }
/* 공휴일 칸은 바탕이 연분홍이라 같은 색 칩(일정 달력의 연차 등 .red)이 묻힌다 — 흰 바탕에 테두리로 띄운다 */
.cal-cell.holiday .cal-ev.red { background: var(--surface); box-shadow: inset 0 0 0 1px var(--red-line); }

/* 일정 상세 — 달력 칩은 말줄임이라 제목 전체를 여기서 읽는다(긴 제목도 끊지 않고 줄바꿈) */
.sch-view-title { font-size: 16px; font-weight: 700; line-height: 1.45; word-break: break-word; margin-bottom: 14px; }
.sch-view-meta { display: grid; grid-template-columns: 64px minmax(0, 1fr); gap: 9px 12px; margin: 0; font-size: 13px; align-items: center; }
.sch-view-meta dt { color: var(--ink-3); }
.sch-view-meta dd { margin: 0; min-width: 0; word-break: break-word; }

/* ---------- 대시보드 ---------- */
.dash-grid { display: grid; grid-template-columns: 2fr 1fr; gap: 16px; align-items: start; }
/* min-width: 0 — 격자 칸은 기본 최소 폭이 내용 폭이라 한 줄로 서는 긴 행(말줄임하는 제목도 글자 전체 폭으로 센다)이
   있으면 칸이 격자보다 넓어져, 휴대폰에서 오늘 근무 현황부터 아래가 통째로 화면 밖으로 밀려 좌우로 스크롤됐다 */
.dash-col { display: flex; flex-direction: column; gap: 16px; min-width: 0; }
.list-row { display: flex; align-items: center; gap: 10px; padding: 7px 4px; border-radius: 6px; font-size: 13.5px; }
.list-row:hover { background: var(--hover); }
.list-row .grow { flex: 1; min-width: 0; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.list-row .sub { color: var(--ink-3); font-size: 12px; white-space: nowrap; }
/* 일정 행(프로젝트 칩·제목·기간) — 프로젝트 이름이 길면 칩부터 말줄임해 제목 자리를 남긴다 */
.list-row.sched .chip { display: block; min-width: 0; max-width: 40%; overflow: hidden; text-overflow: ellipsis; }
@media (max-width: 600px) {
  /* 휴대폰은 셋이 한 줄에 서면 제목 자리가 남지 않는다 — 제목을 윗줄 전체로 올리고(줄바꿈 허용) 프로젝트·기간을 아랫줄에 둔다.
     아랫줄은 기간을 온전히 두고 남는 폭만큼만 칩을 말줄임한다(flex-wrap 은 줄어들기 전 폭으로 줄을 나눠 기간이 셋째 줄로 떨어진다) */
  .list-row.sched { display: grid; grid-template-columns: minmax(0, max-content) 1fr; gap: 4px 8px; }
  .list-row.sched .grow { grid-column: 1 / -1; white-space: normal; word-break: break-word; }
  .list-row.sched .chip { grid-row: 2; justify-self: start; max-width: 100%; }
  .list-row.sched .sub { grid-row: 2; }
}

/* ---------- 알림 ---------- */
.notif-row { display: flex; gap: 12px; padding: 13px 14px; border-bottom: 1px solid var(--border); cursor: pointer; align-items: flex-start; }
.notif-row:hover { background: var(--bg-2); }
.notif-row.unread { background: var(--unread); }
.notif-row.unread:hover { background: var(--unread-hover); }
.notif-row .n-dot { width: 8px; height: 8px; border-radius: 50%; background: var(--accent); margin-top: 7px; flex-shrink: 0; visibility: hidden; }
.notif-row.unread .n-dot { visibility: visible; }
.notif-row .n-body { flex: 1; min-width: 0; }
.notif-row .n-text { font-size: 13.5px; }
/* 본문 발췌(멘션·댓글) — 문구와 출처 사이, 한 줄로 자른다 */
.notif-row .n-excerpt { font-size: 12px; color: var(--ink-2); margin-top: 2px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.notif-row .n-meta { font-size: 12px; color: var(--ink-3); margin-top: 3px; display: flex; align-items: center; gap: 6px; flex-wrap: wrap; }
/* 어디서 온 알림인지 — 같은 문구가 채널마다 쌓이므로 이름이 제일 먼저 보여야 한다 */
.notif-row .n-place { font-size: 11px; padding: 1px 7px; }
.notif-row.deleted { opacity: .55; }

/* ---------- 상세(공지/업무일지) ---------- */
.doc { max-width: none; }
.doc-title { font-size: 26px; font-weight: 700; letter-spacing: -.5px; line-height: 1.3; margin-bottom: 8px; display:flex; gap:10px; align-items:center; }
.doc-meta { display: flex; gap: 14px; color: var(--ink-3); font-size: 13px; padding-bottom: 16px; border-bottom: 1px solid var(--border); margin-bottom: 20px; flex-wrap: wrap; align-items:center; }
.doc-content { font-size: 15px; white-space: pre-wrap; word-break: break-word; min-height: 120px; }
.doc-section { margin-top: 28px; }
.doc-section h4 { font-size: 13px; color: var(--ink-3); font-weight: 500; margin-bottom: 10px; text-transform: uppercase; letter-spacing: .4px; }
.slide-imgs { display: flex; gap: 10px; flex-wrap: wrap; }

/* 이미지 라이트박스 — 그림 클릭·휠·핀치·아래 −/+ 막대로 확대하고 끌어서 옮긴다(app.js lightbox).
   touch-action: none 은 손가락 제스처를 브라우저(스크롤·페이지 확대)에 뺏기지 않으려는 것이고,
   overflow: hidden 은 확대된 그림이 화면 밖으로 삐져나가 문서에 스크롤을 만들지 않게 한다 */
.lightbox { display:none; position: fixed; inset: 0; background: rgba(0,0,0,.85); z-index: 400; align-items: center; justify-content: center; cursor: zoom-out; overflow: hidden; touch-action: none; }
.lightbox.open { display: flex; }
.lightbox img { max-width: 92vw; max-height: 84vh; border-radius: 6px; cursor: zoom-in; transform-origin: center center; user-select: none; -webkit-user-drag: none; will-change: transform; }
.lightbox.zoomed img { cursor: grab; }
.lightbox.dragging img { cursor: grabbing; }
.lightbox .lb-close {
  position: absolute; top: 18px; left: 18px; cursor: pointer;
  width: 38px; height: 38px; border-radius: 50%; border: none;
  background: rgba(255,255,255,.18); color: #fff; display: flex; align-items: center; justify-content: center;
}
.lightbox .lb-close:hover { background: rgba(255,255,255,.32); }
.lightbox .lb-close .lni { width: 20px; height: 20px; }
.lightbox .lb-dl {
  position: absolute; top: 18px; right: 18px; cursor: pointer;
  display: inline-flex; align-items: center; gap: 6px;
  padding: 8px 14px; border-radius: 8px; text-decoration: none;
  background: rgba(255,255,255,.16); color: #fff; font-size: 13px; font-weight: 600;
}
.lightbox .lb-dl:hover { background: rgba(255,255,255,.3); }
.lightbox .lb-dl .lni { width: 16px; height: 16px; }
.lightbox .lb-count { position: absolute; top: 26px; left: 50%; transform: translateX(-50%); color: rgba(255,255,255,.85); font-size: 13px; letter-spacing: .5px; }
.lightbox .lb-nav {
  position: absolute; top: 50%; transform: translateY(-50%); cursor: pointer;
  width: 46px; height: 46px; border-radius: 50%; border: none;
  background: rgba(255,255,255,.18); color: #fff; display: flex; align-items: center; justify-content: center;
}
.lightbox .lb-nav[hidden] { display: none; }   /* display:flex 가 UA 의 [hidden] 을 이기므로 따로 적는다 */
.lightbox .lb-nav:hover { background: rgba(255,255,255,.32); }
.lightbox .lb-nav .lni { width: 24px; height: 24px; }
.lightbox .lb-prev { left: 18px; }
.lightbox .lb-next { right: 18px; }
/* 확대 막대 — 아래 가운데. 가운데 숫자를 누르면 맞춤(100%)으로 */
.lightbox .lb-zoom {
  position: absolute; bottom: 18px; left: 50%; transform: translateX(-50%);
  display: flex; align-items: center; gap: 2px; padding: 3px; border-radius: 999px;
  background: rgba(255,255,255,.16);
}
.lightbox .lb-zoom button {
  border: none; background: none; color: #fff; cursor: pointer;
  height: 32px; min-width: 32px; padding: 0 8px; border-radius: 999px;
  display: flex; align-items: center; justify-content: center; font-size: 12.5px; font-weight: 600; font-family: inherit;
}
.lightbox .lb-zoom button:hover { background: rgba(255,255,255,.22); }
.lightbox .lb-zoom .lni { width: 16px; height: 16px; }
.lightbox .lb-zoom .lb-zval { min-width: 56px; font-variant-numeric: tabular-nums; }
@media (max-width: 600px) {
  .lightbox .lb-nav { width: 38px; height: 38px; }
  .lightbox .lb-prev { left: 8px; }
  .lightbox .lb-next { right: 8px; }
  .lightbox .lb-close { top: 10px; left: 10px; }
  .lightbox .lb-dl { top: 10px; right: 10px; }
  .lightbox .lb-zoom { bottom: 12px; }
}

/* ---------- 로딩 ---------- */
.spinner { display: inline-block; width: 18px; height: 18px; border: 2px solid var(--border); border-top-color: var(--ink-2); border-radius: 50%; animation: spin .7s linear infinite; }
@keyframes spin { to { transform: rotate(360deg); } }
.loading-box { text-align: center; padding: 40px; color: var(--ink-3); }

/* 전체 검색 */
.search-bar { display: flex; gap: 8px; margin-bottom: 18px; max-width: 640px; }
.search-bar .input { flex: 1; height: 38px; font-size: 14px; }
.search-sec + .search-sec { margin-top: 26px; }
.search-sec h3 { font-size: 14px; font-weight: 700; display: flex; align-items: center; gap: 7px; margin: 0 0 8px; }
.search-sec .search-meta { font-size: 12px; font-weight: 400; color: var(--ink-3); margin-left: 4px; }
.search-row { display: block; padding: 10px 12px; border: 1px solid var(--border); border-radius: 8px; background: var(--surface);
  color: inherit; text-decoration: none; margin-bottom: 8px; }
.search-row:hover { background: var(--hover); }
.search-row-head { display: flex; flex-wrap: wrap; align-items: center; gap: 6px; font-size: 12.5px; margin-bottom: 4px; }
.search-row-head .search-author { color: var(--ink-2); }
.search-row-head .search-time { color: var(--ink-3); font-size: 11.5px; margin-left: auto; }
.search-snippet { font-size: 13.5px; color: var(--ink-2); word-break: break-word; }
.search-snippet mark, .search-row-head mark { background: var(--mark); color: inherit; padding: 0 1px; border-radius: 2px; }
.search-none { font-size: 13px; color: var(--ink-3); padding: 14px 2px; }
.search-sec .load-more { text-align: center; padding: 6px 0 2px; }

/* ---------- 안내 툴팁 (info 버튼 호버) ---------- */
.info-tip {
  position: relative; flex: none;
  display: inline-flex; align-items: center; justify-content: center;
  width: 22px; height: 22px; padding: 0;
  border: none; border-radius: 50%; background: none;
  color: var(--ink-3); cursor: help;
}
.info-tip:hover, .info-tip:focus-visible { background: var(--hover); color: var(--accent); outline: none; }
.info-tip .lni { width: 16px; height: 16px; }
/* 말풍선은 App 이 만드는 단일 요소(.tip-pop) — 화면 밖으로 나가지 않게 위치 보정 */
.tip-pop {
  position: fixed; z-index: 200;
  max-width: 320px; padding: 8px 11px;
  background: var(--ink); color: var(--bg);
  font-size: 12.5px; font-weight: 400; line-height: 1.65; text-align: left;
  white-space: pre-line;
  border-radius: 6px; box-shadow: var(--shadow-lg);
  opacity: 0; pointer-events: none; transform: translateY(-3px);
  transition: opacity .14s, transform .14s;
}
.tip-pop.show { opacity: 1; transform: none; }
.tip-pop::after {
  content: ''; position: absolute;
  bottom: 100%; left: var(--arrow-x, 16px); margin-left: -6px;
  border: 6px solid transparent; border-bottom-color: var(--ink);
}
.tip-pop.above::after { bottom: auto; top: 100%; border-bottom-color: transparent; border-top-color: var(--ink); }

/* ---------- 디자인 시안 뷰어 (/draft) ---------- */
.draft-stage { min-height: 100vh; background: var(--bg-2); padding-bottom: 76px; }
.draft-stage img { display: block; margin: 0 auto; max-width: 100%; }
.draft-menu-btn {
  position: fixed; top: 14px; left: 14px; z-index: 60;
  width: 42px; height: 42px; border: none; border-radius: 10px; cursor: pointer;
  background: var(--sb-bg); color: #fff; opacity: .92;
  display: flex; align-items: center; justify-content: center;
  box-shadow: var(--shadow-lg);
}
.draft-menu-btn:hover { opacity: 1; }
.draft-menu-btn .lni { width: 20px; height: 20px; }
.draft-scrim {
  position: fixed; inset: 0; z-index: 70; background: rgba(0,0,0,.45);
  opacity: 0; pointer-events: none; transition: opacity .2s;
}
.draft-scrim.open { opacity: 1; pointer-events: auto; }
.draft-drawer {
  position: fixed; top: 0; left: 0; bottom: 0; z-index: 80; width: 280px; max-width: 86vw;
  background: var(--sb-bg); color: var(--sb-text);
  display: flex; flex-direction: column;
  transform: translateX(-100%); transition: transform .22s ease;
}
.draft-drawer.open { transform: none; box-shadow: var(--shadow-lg); }
.draft-drawer .head { padding: 18px 14px 14px 18px; border-bottom: 1px solid var(--sb-border); display: flex; align-items: flex-start; gap: 8px; }
.draft-drawer .head .tt { color: var(--sb-bright); font-weight: 700; font-size: 16px; line-height: 1.35; word-break: break-all; }
.draft-drawer .head .ver { font-size: 11.5px; margin-top: 3px; }
.draft-drawer .head .x { background: none; border: none; color: var(--sb-text); cursor: pointer; padding: 5px; border-radius: 6px; display: flex; }
.draft-drawer .head .x:hover { background: var(--sb-hover); color: #fff; }
.draft-drawer .head .x .lni { width: 16px; height: 16px; }
.draft-pages { flex: 1; overflow-y: auto; padding: 10px 8px; }
.draft-page-item {
  display: block; width: 100%; text-align: left; border: none; background: none; cursor: pointer;
  color: var(--sb-text); font-family: inherit; font-size: 14px;
  padding: 9px 12px; border-radius: 6px; margin-bottom: 2px;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.draft-page-item:hover { background: var(--sb-hover); color: #fff; }
.draft-page-item.active { background: var(--sb-active); color: #fff; font-weight: 600; }
.draft-drawer .foot { padding: 12px; border-top: 1px solid var(--sb-border); display: flex; flex-direction: column; gap: 8px; }
.draft-drawer .foot .btn { width: 100%; }
.draft-drawer .foot .draft-fb-open { background: transparent; color: var(--sb-bright); border-color: var(--sb-border); }
.draft-drawer .foot .draft-fb-open:hover { background: var(--sb-hover); }
/* 오른쪽 아래 — 피드백 단추와 쪽 넘김(쪽 넘김은 이미지가 없으면 빠진다) */
.draft-dock { position: fixed; right: 16px; bottom: 16px; z-index: 60; display: flex; align-items: center; gap: 8px; }
.draft-fb-btn {
  display: inline-flex; align-items: center; gap: 7px; height: 44px; padding: 0 18px;
  border: none; border-radius: 999px; cursor: pointer; font-family: inherit; font-size: 14px; font-weight: 600;
  background: var(--sb-bg); color: #fff; box-shadow: var(--shadow-lg);
}
.draft-fb-btn:hover { filter: brightness(1.2); }
.draft-fb-btn .lni { width: 17px; height: 17px; }
.draft-pager {
  display: flex; align-items: center; gap: 2px; padding: 4px;
  background: var(--elev); border: 1px solid var(--border); border-radius: 999px; box-shadow: var(--shadow-lg);
}
.draft-pager button {
  width: 34px; height: 34px; border: none; background: none; border-radius: 50%; cursor: pointer;
  color: var(--ink-2); display: flex; align-items: center; justify-content: center;
}
.draft-pager button:hover { background: var(--hover); color: var(--ink); }
.draft-pager button:disabled { opacity: .3; cursor: default; background: none; }
.draft-pager .cnt { font-size: 12.5px; color: var(--ink-2); padding: 0 8px; min-width: 52px; text-align: center; }

/* 디자인 시안 관리(관리자) — 썸네일·접속 안내 */
.draft-thumbs { display: grid; grid-template-columns: repeat(auto-fill, minmax(122px, 1fr)); gap: 10px; margin-top: 12px; }
.draft-thumb { position: relative; border: 1px solid var(--border); border-radius: 8px; overflow: hidden; background: var(--bg-2); }
.draft-thumb img { width: 100%; height: 92px; object-fit: cover; object-position: top; display: block; cursor: zoom-in; }
.draft-thumb .nm { font-size: 11.5px; padding: 4px 7px; background: var(--surface); border-top: 1px solid var(--border); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.draft-thumb .dl {
  position: absolute; top: 4px; right: 30px; width: 22px; height: 22px; border-radius: 50%;
  background: rgba(0,0,0,.55); color: #fff; display: flex; align-items: center; justify-content: center;
}
.draft-thumb .dl:hover { background: rgba(0,0,0,.82); }
.draft-thumb .dl .lni { width: 13px; height: 13px; }
.draft-thumb .rm {
  position: absolute; top: 4px; right: 4px; width: 22px; height: 22px; border: none; border-radius: 50%;
  background: rgba(0,0,0,.55); color: #fff; cursor: pointer; display: flex; align-items: center; justify-content: center;
}
.draft-thumb .rm:hover { background: var(--red); }
.draft-thumb .rm .lni { width: 12px; height: 12px; }
.draft-access-box { background: var(--bg-2); border: 1px solid var(--border); border-radius: 8px; padding: 12px 14px; font-size: 13px; line-height: 1.9; }
.dd-access-acts { display: flex; gap: 6px; margin-bottom: 6px; }
/* 이미지를 보며 남긴 피드백 수 — 누르면 피드백을 그 이미지 것만 거른다 */
.draft-thumb .fbn {
  position: absolute; left: 5px; top: 5px; display: inline-flex; align-items: center; gap: 3px;
  height: 22px; padding: 0 7px; border: none; border-radius: 999px; cursor: pointer;
  font-family: inherit; font-size: 11.5px; font-weight: 600; background: rgba(0,0,0,.62); color: #fff;
}
.draft-thumb .fbn .lni { width: 12px; height: 12px; }
.draft-thumb .fbn:hover, .draft-thumb .fbn.on { background: var(--accent); }

/* 시안 관리 화면 — 왼쪽 시안(정보·접속 안내·이미지), 오른쪽 클라이언트 피드백. 등록 화면(solo)은 정보 칸 하나 */
.dd-layout { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); gap: 16px; align-items: start; }
.dd-layout.solo { grid-template-columns: minmax(0, 760px); }
.dd-col { display: flex; flex-direction: column; gap: 16px; min-width: 0; }
.dd-note { font-size: 12.5px; color: var(--ink-3); line-height: 1.6; }
.dd-acts { display: flex; align-items: center; gap: 8px; margin-top: 16px; }
.dd-acts .grow, .dd-fb-bar .grow { flex: 1; }
.dd-imgs h3 .btn { margin-left: 4px; }
.dd-fb-bar { display: flex; flex-wrap: wrap; align-items: center; gap: 6px; margin-bottom: 12px; }
.dd-fb-bar:empty { display: none; }
.dd-fb-img { display: inline-flex; align-items: center; gap: 4px; }
.dd-fb-img button { border: none; background: none; cursor: pointer; color: inherit; font-size: 11px; padding: 0 2px; }
/* 좁으면 한 줄로 — 칸을 풀어(display: contents) 카드를 한 줄에 세우고, 피드백을 이미지보다 위로 올린다 */
@media (max-width: 1100px) {
  .dd-layout { display: flex; flex-direction: column; align-items: stretch; }
  .dd-col { display: contents; }
  .dd-info { order: 0; } .dd-access { order: 1; } .dd-fb { order: 2; } .dd-imgs { order: 3; }
}

/* 시안 피드백 한 건 — 클라이언트 뷰어의 '보낸 피드백'과 시안 관리 화면이 같은 모양이다 */
.dfb-item { border: 1px solid var(--border); border-radius: 10px; padding: 12px 14px; background: var(--surface); }
.dfb-item + .dfb-item { margin-top: 10px; }
.dfb-item.new { border-left: 3px solid var(--amber); }
/* 채널 안내 글의 [피드백 보기] 로 들어온 그 피드백 — 잠깐 테를 둘렀다가 사라진다 */
.dfb-item.flash { animation: dfb-flash 2.4s ease-out; }
@keyframes dfb-flash { 0%, 40% { box-shadow: 0 0 0 3px rgba(35,131,226,.45); } 100% { box-shadow: none; } }
.dfb-head { display: flex; flex-wrap: wrap; align-items: center; gap: 6px 8px; font-size: 12.5px; color: var(--ink-3); margin-bottom: 8px; }
.dfb-who { color: var(--ink); font-weight: 600; font-size: 13px; }
.dfb-ver { font-size: 12px; }
.dfb-time { margin-left: auto; white-space: nowrap; }
button.dfb-page { border: none; cursor: zoom-in; font-family: inherit; }
button.dfb-page:hover { background: var(--accent-soft); color: var(--blue-ink); }
.dfb-body { font-size: 14px; }
.dfb-empty, .dfb-none { font-size: 13px; color: var(--ink-3); }
.dfb-none { padding: 18px 0; text-align: center; }
.dfb-att { margin-top: 8px; }
.dfb-foot { display: flex; flex-wrap: wrap; align-items: center; gap: 6px; margin-top: 10px; padding-top: 10px; border-top: 1px solid var(--border); font-size: 12.5px; color: var(--ink-3); }
.dfb-checked { display: inline-flex; align-items: center; gap: 4px; color: var(--green-ink); }
.dfb-checked .lni { width: 14px; height: 14px; }
/* 확인·삭제는 한 덩어리로 오른쪽에 — 좁으면 둘이 함께 다음 줄로 내려간다 */
.dfb-btns { display: inline-flex; gap: 6px; margin-left: auto; }
.dfb-tabs .dfb-tab-cnt { font-size: 12px; color: var(--ink-3); margin-left: 2px; }
#fbSent .dfb-item:first-child { margin-top: 2px; }

/* ---------- 마크다운 문서 (연동 가이드 · 사규 · 업무일지) ---------- */
/* white-space 는 normal 로 못박는다 — App.markdown 은 블록을 줄바꿈으로 이어 붙이는데, 평문용 pre-wrap 상자(.doc-content)
   안에 들어가면 그 줄바꿈이 블록마다 빈 줄 하나(약 26px)로 살아나 편집 화면보다 문단 사이가 세 배 넘게 벌어졌다(10px → 46px).
   문단 안 줄바꿈은 렌더러가 <br> 로 바꿔 두므로 pre-wrap 이 필요 없다. */
/* 띄어쓰기 없이 긴 주소·경로(자동 링크된 URL, 드라이브 경로·파일명)는 줄을 안 바꾸고 칸 밖으로 밀려 나가
   휴대폰에서 본문이 옆으로 밀렸다(업무협조 요청 글). 넘칠 때만 끊는 break-word 를 쓴다 —
   anywhere 는 표 칸의 최소 폭까지 줄여 글자 하나 폭 칸이 되고, break-word 면 표는 그대로 가로로 스크롤된다. */
.md-body { font-size: 14px; line-height: 1.85; color: var(--ink); max-width: 900px; white-space: normal; overflow-wrap: break-word; }
.md-body .md-h { font-weight: 700; line-height: 1.4; margin: 28px 0 10px; }
.md-body h1.md-h { font-size: 24px; margin-top: 0; }
.md-body h2.md-h { font-size: 19px; }   /* 밑줄을 두지 않는다 — H2 에만 있어 다른 제목과 달라 보였다 */
.md-body h3.md-h { font-size: 16px; }
.md-body h4.md-h { font-size: 14.5px; color: var(--ink-2); }
.md-body .md-p { margin: 10px 0; }
.md-body .md-list { margin: 8px 0 12px; padding-left: 22px; }
.md-body .md-list li { margin: 4px 0; }
.md-body .md-task { list-style: none; margin-left: -18px; }
.md-body .md-box { color: var(--ink-2); }
.md-body .md-hr { border: 0; border-top: 1px solid var(--border); margin: 24px 0; }
.md-body .md-quote { margin: 12px 0; padding: 10px 14px; background: var(--bg-2);
  border-left: 3px solid var(--accent); border-radius: 0 6px 6px 0; color: var(--quote-ink); font-weight: 500; }
.md-body code { background: var(--bg-2); border: 1px solid var(--border); border-radius: 4px;
  padding: 1px 5px; font-size: 12.5px; font-family: Consolas, 'Courier New', monospace; }
.md-body .md-code { background: #2B2B33; color: #E6E6E6; border-radius: 8px; padding: 14px 16px;
  overflow-x: auto; margin: 12px 0; position: relative; }
.md-body .md-code code { background: none; border: 0; padding: 0; color: inherit;
  font-size: 12.5px; line-height: 1.7; white-space: pre; }
.md-body .md-code[data-lang]::before { content: attr(data-lang); position: absolute; top: 6px; right: 10px;
  font-size: 11px; color: #8A8A99; letter-spacing: .5px; }
.md-body .md-table-wrap { overflow-x: auto; margin: 12px 0; }
.md-body .md-table { border-collapse: collapse; width: 100%; font-size: 13px; }
.md-body .md-table th, .md-body .md-table td { border: 1px solid var(--border); padding: 7px 10px; text-align: left; vertical-align: top; }
.md-body .md-table th { background: var(--bg-2); font-weight: 600; white-space: nowrap; }
.md-body a { color: var(--accent); }
.md-body del { color: var(--ink-3); }
/* 본문에 박힌 첨부 이미지 — 눌러서 원본을 띄운다(App.markdown 이 md-img 를 붙인다) */
.md-body .md-img { display: block; max-width: 100%; height: auto; margin: 10px 0; border: 1px solid var(--border);
  border-radius: 8px; cursor: zoom-in; background: var(--bg-2); }
/* 목록 항목에 딸린 줄(이미지·부연 설명) */
.md-body .md-sub { margin: 4px 0; }
.md-body .md-sub .md-img { margin: 6px 0; }
/* 채널 글·댓글의 마크다운(App.renderChat) — 대화라 문서보다 촘촘하게. 글자 크기는 원래 칸(.m-content 14px·.c-text 13px)이 이긴다 */
.md-body.md-chat { line-height: 1.6; max-width: none; }
.msg .m-content.md-chat, .comment-item .c-text.md-chat { white-space: normal; }
.md-chat > :first-child { margin-top: 0; }
.md-chat > :last-child { margin-bottom: 0; }
.md-chat .md-p { margin: 0 0 .7em; }
.md-chat .md-h { margin: 10px 0 4px; }
.md-chat h1.md-h { font-size: 18px; }
.md-chat h2.md-h { font-size: 16px; }
.md-chat h3.md-h, .md-chat h4.md-h { font-size: 15px; }
.md-chat .md-list { margin: 2px 0 .7em; }
.md-chat .md-list li { margin: 1px 0; }
.md-chat .md-quote { margin: 4px 0 .7em; padding: 4px 12px; }
.md-chat .md-code { margin: 6px 0 .7em; padding: 10px 12px; }
.md-chat .md-hr { margin: 10px 0; }
.md-chat .md-table-wrap { margin: 6px 0 .7em; }
.md-chat .md-img { margin: 6px 0; }


/* ---------- 사규 (버전 목록 + 문서) ---------- */
.rules-layout { display: grid; grid-template-columns: 272px minmax(0, 1fr); gap: 32px; align-items: start; }
.rules-aside { position: sticky; top: 0; }
.rules-aside h4 { font-size: 12px; color: var(--ink-3); font-weight: 500; text-transform: uppercase; letter-spacing: .4px; margin: 0 0 8px 6px; display:flex; align-items:center; gap:6px; }
.ver-list { display: flex; flex-direction: column; gap: 3px; }
.ver-item { display: block; padding: 9px 12px; border-radius: 8px; border: 1px solid transparent; cursor: pointer; color: inherit; text-decoration: none; }
.ver-item:hover { background: var(--hover); }
.ver-item.active { background: var(--accent-soft); border-color: #CFE4F7; }
.ver-item .v { font-weight: 700; font-size: 13.5px; display: flex; align-items: center; gap: 6px; }
.ver-item .d { font-size: 12.5px; color: var(--ink-2); margin-top: 2px; }
.ver-item .s { font-size: 12px; color: var(--ink-3); margin-top: 3px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.rule-banner { display: flex; align-items: center; gap: 8px; padding: 10px 14px; border-radius: 8px; font-size: 13px; margin-bottom: 18px; }
.rule-banner.amber { background: var(--amber-soft); color: var(--amber-text); }
.rule-banner.blue { background: var(--accent-soft); color: var(--blue-ink); }
.rule-banner .btn { margin-left: auto; }
.rule-summary { margin: -6px 0 22px; padding: 10px 14px; border-left: 3px solid var(--border); color: var(--ink-2); font-size: 13.5px; background: var(--bg-2); border-radius: 0 8px 8px 0; }

/* 마크다운 에디터 */
.md-editor { border: 1px solid var(--border); border-radius: var(--radius); background: var(--surface); display: flex; flex-direction: column; }
.md-editor .bar { display: flex; flex-wrap: wrap; gap: 2px; align-items: center; padding: 6px 8px; border-bottom: 1px solid var(--border); background: var(--bg-2); border-radius: var(--radius) var(--radius) 0 0; }
.md-editor .bar button { border: 0; background: transparent; padding: 5px 7px; border-radius: 6px; cursor: pointer; color: var(--ink-2); font-size: 12px; font-weight: 700; display: inline-flex; align-items: center; gap: 3px; font-family: inherit; }
.md-editor .bar button:hover { background: var(--hover); color: var(--ink); }
.md-editor .bar button[data-act="strike"] span { text-decoration: line-through; }
.md-editor .bar button .lni { width: 16px; height: 16px; }
.md-editor .bar .sep { width: 1px; height: 18px; background: var(--border); margin: 0 5px; }
.md-editor .bar .spacer { flex: 1; }
.md-editor .bar .mode { display: inline-flex; gap: 2px; background: var(--hover); border-radius: 7px; padding: 2px; }
.md-editor .bar .mode button.on { background: var(--surface); color: var(--ink); box-shadow: 0 1px 2px rgba(15,15,15,.12); }
.md-editor .panes { display: grid; grid-template-columns: 1fr 1fr; }
.md-editor .panes.edit { grid-template-columns: 1fr; }
.md-editor .panes.edit .md-preview { display: none; }
.md-editor .panes.view { grid-template-columns: 1fr; }
.md-editor .panes.view textarea { display: none; }
.md-editor textarea { border: 0; outline: 0; resize: none; padding: 18px 20px; width: 100%; height: 68vh; min-height: 460px; color: var(--ink); background: var(--surface);
  font: 13.5px/1.75 ui-monospace, SFMono-Regular, Menlo, Consolas, "Noto Sans KR", monospace; border-right: 1px solid var(--border); tab-size: 2; }
.md-editor .panes.edit textarea, .md-editor .panes.view textarea { border-right: 0; }
.md-editor .md-preview { padding: 18px 26px; overflow-y: auto; height: 68vh; min-height: 460px; }
.md-editor .md-preview .empty { padding: 60px 20px; }
/* 모달 안(업무일지 작성·수정)에서는 화면 높이를 다 쓰지 않는다 */
.modal .md-editor textarea, .modal .md-editor .md-preview { height: 42vh; min-height: 260px; }

/* 서식 편집기 — 보이는 화면이 곧 상세 화면이라 md-body 를 그대로 편집한다 */
.md-editor .bar button.on { background: var(--accent-soft); color: var(--accent); }
.md-editor .bar button:disabled { opacity: .35; cursor: default; }
.md-editor .bar .mode button span { font-size: 11.5px; }
.md-editor .rich-wrap { position: relative; }
.md-editor .rich-wrap textarea { border-right: 0; }
.md-editor .rich-body { padding: 18px 26px; height: 68vh; min-height: 460px; overflow-y: auto; outline: 0; }
/* 빈 글에도 문단이 하나 있으므로(입력 규칙이 줄을 찾아야 한다) 안내문은 겹쳐 띄운다 */
.md-editor .rich-body.is-empty::before { content: attr(data-placeholder); position: absolute; top: 18px; left: 26px;
  color: var(--ink-3); white-space: pre-line; pointer-events: none; }
.md-editor .rich-body .md-box { cursor: pointer; user-select: none; }
.md-editor .rich-body .md-code { white-space: pre-wrap; }
/* 서식을 지우는 백스페이스 — 한 번 누르면 대상(구분선·목록 항목·인용·제목·코드 블록)을 칠해서 보여 주고,
   한 번 더 누르면 지운다(richEditor 의 guardDelete). box-shadow 로 둘러 자리가 밀리지 않게 한다 */
.md-editor .rich-body .fmt-pick:not(.md-code) { background: var(--accent-soft); box-shadow: 0 0 0 3px var(--accent-soft); border-radius: 3px; }
/* 블록 경계 커서 — 표·코드 블록·구분선의 앞뒤(줄 밖)에 선 커서. 그 가장자리에 파란 줄을 그린다. Enter·글자를 치면 그 자리에 새 줄이 생긴다 */
.md-editor .rich-body .gap-before { box-shadow: 0 -4px 0 -1px var(--accent); }
.md-editor .rich-body .gap-after { box-shadow: 0 4px 0 -1px var(--accent); }
.md-editor .rich-body .md-hr.gap-before { box-shadow: 0 -5px 0 0 var(--accent); }
.md-editor .rich-body .md-hr.gap-after { box-shadow: 0 5px 0 0 var(--accent); }
.md-editor .rich-body .md-hr.fmt-pick { border-top-color: var(--accent);
  box-shadow: 0 -7px 0 0 var(--accent-soft), 0 6px 0 0 var(--accent-soft); border-radius: 2px; }
/* 코드 블록은 어두운 바탕이라 칠하면 글자가 안 보인다 — 테두리만 */
.md-editor .rich-body .md-code.fmt-pick { box-shadow: 0 0 0 3px var(--accent); }
.md-editor .rich-body .rich-uploading { color: var(--ink-3); font-size: 12.5px; background: var(--bg-2); border-radius: 4px; padding: 1px 6px; }
.modal .md-editor .rich-body { height: 42vh; min-height: 260px; }
/* 어디에 쓰고 있는지 — 입력칸·컴포저처럼 포커스가 들어오면 테두리를 올린다 */
.md-editor:focus-within { border-color: var(--accent); box-shadow: 0 0 0 2px var(--accent-soft); }
/* 커서가 놓인 빈 줄의 안내(노션처럼). float + height:0 이라 커서 자리를 밀지 않는다 */
.md-editor .rich-body .rich-cur::before { content: "'/' 를 눌러 블록 넣기"; color: var(--ink-3); float: left; height: 0; pointer-events: none; }
/* 편집 중의 그림은 눌러서 고른다(지우려고) — 확대는 두 번 누름 */
.md-editor .rich-body .md-img { cursor: pointer; }
.md-editor .rich-body .md-img.fmt-pick { outline: 3px solid var(--accent); outline-offset: 2px; box-shadow: none; }
@media (hover: none) { .md-editor .rich-body .md-box { display: inline-block; padding: 3px 6px; margin: -3px -2px -3px -6px; } }
/* 표 도구 — 커서가 표 안에 있을 때만 툴바에 나온다 */
.md-editor .bar .sep { flex: none; }
.md-editor .bar .tbl-tools { display: none; align-items: center; gap: 2px; margin-left: 6px; padding-left: 8px; border-left: 1px solid var(--border); }
.md-editor .bar .tbl-tools.on { display: inline-flex; }
.md-editor .bar .tbl-tools button { font-weight: 500; color: var(--accent); white-space: nowrap; }
.md-editor .bar .tbl-tools button.warn { color: var(--red); }
/* 편집기가 띄우는 작은 창 — '/' 명령, 링크 주소, 쓰는 법 (문서에 하나, richPopOpen) */
.rich-pop { display: none; position: fixed; z-index: 210; background: var(--elev); border: 1px solid var(--border);
  border-radius: 10px; box-shadow: var(--shadow-lg); font-size: 13.5px; color: var(--ink); }
.rich-pop.open { display: block; }
.rich-pop.slash { width: 264px; max-height: 300px; overflow-y: auto; padding: 5px; }
.rich-pop .rp-item { display: flex; align-items: center; gap: 10px; padding: 7px 10px; border-radius: 6px; cursor: pointer; }
.rich-pop .rp-item .lni { width: 16px; height: 16px; color: var(--ink-2); flex: none; }
.rich-pop .rp-item .t { flex: 1; }
.rich-pop .rp-item .k { color: var(--ink-3); font: 12px ui-monospace, SFMono-Regular, Menlo, Consolas, monospace; }
.rich-pop .rp-item:hover { background: var(--bg-2); }
.rich-pop .rp-item.sel { background: var(--accent-soft); box-shadow: inset 2px 0 0 var(--accent); }
.rich-pop .rp-none { padding: 10px 12px; color: var(--ink-3); }
.rich-pop.link { padding: 8px; }
.rich-pop .rp-link { display: flex; gap: 6px; align-items: center; }
.rich-pop .rp-link .input { width: 280px; max-width: 46vw; }
.rich-pop .rp-link .btn { flex: none; white-space: nowrap; }
.rich-pop.help { padding: 14px 16px; max-width: min(600px, calc(100vw - 16px)); max-height: 72vh; overflow-y: auto; }
.rich-pop .rp-help h4 { margin: 0 0 8px; font-size: 14px; }
.rich-pop .rp-help table { border-collapse: collapse; font-size: 13px; }
.rich-pop .rp-help th { text-align: left; font-weight: 600; white-space: nowrap; padding: 4px 14px 4px 0; vertical-align: top; color: var(--ink-2); }
.rich-pop .rp-help td { padding: 4px 0; line-height: 1.7; }
.rich-pop kbd { font: 12px ui-monospace, SFMono-Regular, Menlo, Consolas, monospace; background: var(--bg-2);
  border: 1px solid var(--border); border-radius: 4px; padding: 0 5px; }
/* 휴대폰 — 툴바를 여러 줄로 접지 않고 한 줄로 밀어 쓴다(버튼은 손가락 크기로) */
@media (max-width: 600px) {
  .md-editor .bar { flex-wrap: nowrap; overflow-x: auto; scrollbar-width: none; }
  .md-editor .bar::-webkit-scrollbar { display: none; }
  .md-editor .bar button { flex: none; min-width: 38px; min-height: 38px; justify-content: center; }
  .md-editor .bar .spacer { flex: 0 0 8px; }
  .md-editor .bar .mode { flex: none; }
  .rich-pop .rp-help th { white-space: normal; }
  .rich-pop .rp-link .input { width: 46vw; }
}

/* 버전 비교 */
.diff { border: 1px solid var(--border); border-radius: var(--radius); overflow: hidden; font: 13px/1.65 ui-monospace, SFMono-Regular, Menlo, Consolas, "Noto Sans KR", monospace; background: var(--surface); }
.diff-line { padding: 2px 12px 2px 8px; white-space: pre-wrap; word-break: break-word; display: flex; gap: 8px; }
.diff-line .sign { flex: none; width: 12px; color: var(--ink-3); user-select: none; text-align: center; }
.diff-line.eq { color: var(--ink-2); }
.diff-line.add { background: var(--green-soft); color: #0F5F4E; }
.diff-line.add .sign { color: var(--green); }
.diff-line.del { background: var(--red-soft); color: #A0403B; }
.diff-line.del .sign { color: var(--red); }
.diff-fold { padding: 5px 12px; background: var(--bg-2); color: var(--ink-3); cursor: pointer; font-size: 12px; text-align: center; border-top: 1px solid var(--border); border-bottom: 1px solid var(--border); font-family: "Noto Sans KR", sans-serif; }
.diff-fold:hover { color: var(--ink); background: var(--hover); }
.diff-legend { display: flex; gap: 14px; font-size: 12.5px; color: var(--ink-2); margin-bottom: 10px; align-items: center; }
.diff-legend .sw { display: inline-block; width: 12px; height: 12px; border-radius: 3px; vertical-align: -1px; margin-right: 4px; }

/* 모바일 서랍의 뒷막 — 서랍이 열려 있을 때만 화면을 덮고, 누르면 닫는다(app.js initDrawer 가 만든다). 960px 넘으면 없다 */
.sb-backdrop {
  display: none; position: fixed; inset: 0; z-index: 89;
  background: rgba(29, 28, 29, .45); opacity: 0; pointer-events: none; transition: opacity .2s ease;
}

/* ---------- 반응형 ---------- */
@media (max-width: 960px) {
  /* 서랍의 이동은 margin 이 아니라 transform 이다 — 손가락을 따라 끌다 놓으면 그 자리에서 이어서 닫혀야 하는데,
     인라인 transform 을 지우면서 .open 을 떼면 그 값에서 CSS 값으로 전환이 이어진다(margin 은 그렇게 못 잇는다).
     touch-action: pan-y 는 가로 끌기를 브라우저 제스처에 뺏기지 않게 한다(세로 스크롤은 그대로). */
  .sidebar { position: fixed; z-index: 90; height: 100vh; transform: translateX(-100%); touch-action: pan-y pinch-zoom; }
  .sidebar.open { transform: none; box-shadow: var(--shadow-lg); }
  .sb-backdrop { display: block; }
  .sb-backdrop.open { opacity: 1; pointer-events: auto; }
  .hamburger { display: block; }
  .content { padding: 20px 16px 40px; }
  /* 탑바 — 폭이 모자라니 여백·글자를 줄이고, 고정폭으로 박아 둔 검색칸은 남는 만큼만 쓰게 한다.
     인라인 style 로 박힌 width 를 이기려면 !important 가 필요하다(화면마다 값이 달라 JSP 로는 못 모은다). */
  .topbar { padding: 0 12px; gap: 8px; }
  .topbar h1 { font-size: 15.5px; }
  .topbar h1 .lni { width: 17px; height: 17px; }
  .topbar .sub { display: none; }
  .topbar .input, .topbar .select { width: auto !important; min-width: 0 !important; flex: 1 1 84px; }
  .topbar .btn { padding: 5px 9px; font-size: 12.5px; }
  .topbar .btn.sm { padding: 4px 8px; }
  .dash-grid, .cards.c2, .cards.c3, .cards.c4 { grid-template-columns: 1fr; }
  .row2 { grid-template-columns: 1fr; }
  .channel-aside { display: none; }
  /* minmax(0,1fr) — 1fr 은 내용 폭 아래로 안 줄어, 한 줄 말줄임인 버전 요약(.ver-item .s)이 칸을 글자 길이만큼 벌려 화면이 좌우로 밀렸다 */
  .rules-layout { grid-template-columns: minmax(0, 1fr); gap: 16px; }
  .rules-aside { position: static; }
  .md-editor .panes { grid-template-columns: 1fr; }
  .md-editor textarea { border-right: 0; border-bottom: 1px solid var(--border); height: 42vh; min-height: 260px; }
  .md-editor .md-preview, .md-editor .rich-body { height: 42vh; min-height: 260px; }
}

/* ============================================================
   관리웹 접속정보 — 값 표(아이디·비밀번호), 비밀번호는 가려서 보여준다
   ============================================================ */
.wa-kv { width: 100%; table-layout: fixed; }
.wa-kv th {
  width: 152px; text-align: left; font-weight: 500; color: var(--ink-2);
  background: var(--bg-2); white-space: nowrap; font-size: 12.5px;
}
.wa-kv td { font-size: 14px; word-break: break-all; }
.wa-kv .grp td {
  background: var(--bg-2); font-size: 11.5px; font-weight: 700; color: var(--ink-3);
  letter-spacing: .4px; text-transform: uppercase; padding: 6px 14px;
}
.wa-val { display: flex; align-items: center; gap: 6px; flex-wrap: wrap; }
.wa-val .v { font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace; font-size: 13.5px; }
.wa-val .v.masked { letter-spacing: 3px; color: var(--ink-3); user-select: none; }
.wa-ico {
  border: 1px solid var(--border); background: var(--surface); border-radius: 6px;
  padding: 3px 6px; cursor: pointer; color: var(--ink-3); line-height: 0;
}
.wa-ico:hover { background: var(--hover); color: var(--ink); }
.wa-ico .lni { width: 14px; height: 14px; }
.wa-tags { display: flex; gap: 5px; flex-wrap: wrap; }
.wa-etc { white-space: pre-wrap; word-break: break-word; font-size: 14px; }

/* ---------- 근태관리 (/admin/attendance) ---------- */
.att-sub { color: var(--ink-3); font-size: 11.5px; font-weight: 400; }

.att-legend { display: flex; flex-wrap: wrap; gap: 6px 12px; align-items: center; font-size: 12px; color: var(--ink-2); }
.att-legend span { display: inline-flex; align-items: center; gap: 4px; }
.att-k { width: 11px; height: 11px; border-radius: 3px; border: 1px solid var(--border); display: inline-block; }
.att-k.work { background: var(--green-soft); border-color: var(--green); }
.att-k.leave { background: var(--accent-soft); border-color: var(--accent); }
.att-k.absent { background: var(--red-soft); border-color: var(--red); }
.att-k.off { background: var(--bg-2); }

/* 화면을 채우는 목록 — 표 안에서만 스크롤하고 머리줄(.sticky-head)은 붙어 있는다.
   고정 px 로 잡으면 큰 화면에서도 그만큼만 쓰고 아래가 텅 빈 채 몇 줄만 보인다.
   모달 안의 고르는 목록은 여기 해당 없다 — 거기는 모달이 커지면 안 되므로 고정값이 맞다. */
.tbl-fill, .att-wrap { max-height: calc(100vh - 240px); }
table.att-grid { font-size: 12.5px; }
table.att-grid th, table.att-grid td { white-space: nowrap; }

/* 이름 칸은 가로로 밀어도 따라온다 — 날짜 31칸을 훑는 동안 누구 줄인지 놓치면 표를 못 읽는다 */
.att-grid .att-name { position: sticky; left: 0; z-index: 2; background: var(--surface); min-width: 132px; }
.att-grid thead .att-name { z-index: 3; background: var(--bg-2); }
.att-grid tbody tr:hover .att-name { background: var(--hover); }
.att-name a { color: var(--ink); text-decoration: none; font-weight: 600; }
.att-name a:hover { text-decoration: underline; }

.att-d { text-align: center; padding: 4px 2px !important; min-width: 34px; }
.att-d b { display: block; font-size: 12px; }
.att-d i { display: block; font-style: normal; font-size: 10px; font-weight: 400; color: var(--ink-3); }
.att-d.off { background: var(--bg-2); }
.att-d.off i { color: var(--red); }

.att-c { text-align: center; padding: 5px 2px !important; font-size: 11.5px; }
.att-c.work { background: var(--green-soft); color: var(--green); font-weight: 600; }
/* 자동 마감한 날은 근무시간이 실제 값이 아니라 색을 달리한다 */
.att-c.work.auto { background: var(--amber-soft); color: var(--amber); }
.att-c.leave { background: var(--accent-soft); color: var(--accent); font-weight: 600; }
.att-c.absent { background: var(--red-soft); color: var(--red); font-weight: 700; }
.att-c.off { background: var(--bg-2); }

.att-auto { font-size: 10.5px; color: var(--amber); border: 1px solid var(--amber); border-radius: 3px; padding: 0 3px; }
.att-warn { color: var(--red); font-weight: 600; }

.att-sum { display: flex; flex-wrap: wrap; gap: 16px; align-items: center; margin-bottom: 12px; font-size: 13px; color: var(--ink-2); }
.att-sum b { color: var(--ink); }
/* 반차를 쓰고 나온 날 — 출근 시각이 늦은 이유가 지각이 아니라는 표시 */
.att-c.work.half { box-shadow: inset 0 -2px 0 var(--accent); }

/* 상세 화면의 '목록으로' — 제목 아이콘에 링크만 걸어 두면 누를 수 있다는 걸 아무도 모른다.
   브라우저 뒤로가기 대신 목록으로 보내는 이유는 알림·공유 링크로 바로 들어온 경우에도
   갈 곳이 분명하기 때문이다(그때는 history 가 비어 있어 뒤로가기가 아무 일도 안 한다).
   옅은 테두리의 흰 네모였을 때는 흰 탑바에 묻혀 있는 줄도 몰라서, 파란 테두리·바탕에 굵은 화살표와
   '목록' 글자를 붙였다(휴대폰은 .btn-lbl 이 글자를 빼 아이콘만 남는다). */
.topbar .back-btn {
  display: inline-flex; align-items: center; justify-content: center; gap: 2px;
  height: 32px; padding: 0 12px 0 7px; flex-shrink: 0; white-space: nowrap;
  border: 1px solid var(--accent); border-radius: 8px;
  background: var(--accent-soft); color: var(--accent); text-decoration: none;
  font-size: 13.5px; font-weight: 600;
}
.topbar .back-btn:hover { background: var(--accent); color: #fff; }
.topbar .back-btn .lni { width: 18px; height: 18px; stroke-width: 2.6; }
@media (max-width: 600px) {
  .topbar .back-btn { width: 32px; padding: 0; }
}

/* ---------- 개인 메모 (/memos) ---------- */
.memo-new {
  max-width: 560px; margin: 0 auto 26px;
  border: 1px solid var(--border); border-radius: 10px;
  padding: 11px 16px; background: var(--surface); box-shadow: var(--shadow);
  color: var(--ink-3); cursor: text; user-select: none;
}
.memo-new:hover { box-shadow: 0 1px 2px rgba(15,15,15,.1), 0 4px 16px rgba(15,15,15,.12); }
.memo-new span { display: inline-flex; align-items: center; gap: 7px; }

.memo-sec { font-size: 11.5px; font-weight: 700; letter-spacing: .6px; color: var(--ink-3);
            text-transform: uppercase; margin: 0 4px 10px; }
.memo-sec ~ .memo-grid { margin-bottom: 26px; }

/* 카드가 저마다 높이가 달라 격자로 깔면 아래가 들쭉날쭉 빈다 — 단(column)으로 흘려 Keep 처럼 채운다.
   JS 없이 되는 대신 차례가 왼→오른쪽이 아니라 위→아래로 흐른다(Keep 도 그렇다). */
/* 250px 으로 잡으면 1000px 남짓한 화면에서 3단(단 폭 338px)이 되어 카드가 과하게 넓어진다 —
   220px 이면 같은 화면이 4단이 되고 실제 단 폭은 250px 안팎으로 떨어진다. */
.memo-grid { columns: 220px; column-gap: 14px; }
.memo-card {
  break-inside: avoid; -webkit-column-break-inside: avoid;
  margin: 0 0 14px;
  border: 1px solid var(--border); border-radius: 10px;
  padding: 13px 15px 8px; background: var(--surface);
  cursor: pointer; position: relative;
}
.memo-card:hover { box-shadow: var(--shadow); }
.memo-t { font-weight: 700; font-size: 14.5px; margin-bottom: 5px; word-break: break-word; }
/* 긴 메모가 화면을 다 먹지 않게 자르고, 잘렸다는 것이 보이도록 아래를 흐린다 */
.memo-c { max-height: 300px; overflow: hidden; font-size: 13.5px; word-break: break-word;
          -webkit-mask-image: linear-gradient(#000 82%, transparent); mask-image: linear-gradient(#000 82%, transparent); }
.memo-c img { max-width: 100%; border-radius: 6px; }
.memo-foot { display: flex; align-items: center; justify-content: space-between; margin-top: 6px; min-height: 24px; }
.memo-when { font-size: 11.5px; color: var(--ink-3); }
.memo-pin {
  border: none; background: none; cursor: pointer; padding: 3px; border-radius: 5px;
  color: var(--ink-3); opacity: 0; transition: opacity .1s;
}
.memo-card:hover .memo-pin, .memo-pin.on { opacity: 1; }
.memo-pin.on { color: var(--amber); }
.memo-pin:hover { background: var(--hover); color: var(--ink); }
/* 호버로만 보이는 버튼은 터치 화면에서 닿을 수 없다 */
@media (hover: none) { .memo-pin { opacity: 1; } }

/* 카드 색 — 이름은 MemoService.COLORS 가 정본이다(그 밖의 값은 서버가 버린다) */
.memo-card.red    { background: var(--red-soft);    border-color: var(--red-line); }
.memo-card.orange { background: var(--orange-soft);            border-color: #EED8C4; }
.memo-card.yellow { background: var(--amber-soft);  border-color: #EDE0BC; }
.memo-card.green  { background: var(--green-soft);  border-color: #C6E5DB; }
.memo-card.blue   { background: var(--accent-soft); border-color: #C9E2EE; }
.memo-card.purple { background: var(--purple-soft); border-color: #E3D9EC; }
.memo-card.gray   { background: var(--bg-2);        border-color: #E0DFDB; }

.memo-colors { display: flex; gap: 8px; flex-wrap: wrap; }
.memo-sw { width: 26px; height: 26px; border-radius: 50%; cursor: pointer; border: 1px solid var(--border); }
.memo-sw.on { outline: 2px solid var(--ink); outline-offset: 2px; }
.memo-sw.none   { background: var(--surface); }
.memo-sw.red    { background: var(--red-soft); }
.memo-sw.orange { background: var(--orange-soft); }
.memo-sw.yellow { background: var(--amber-soft); }
.memo-sw.green  { background: var(--green-soft); }
.memo-sw.blue   { background: var(--accent-soft); }
.memo-sw.purple { background: var(--purple-soft); }
.memo-sw.gray   { background: var(--bg-2); }
/* 모달 푸터에서 삭제 같은 버튼을 왼쪽에 떼어 둘 때 (.topbar .spacer 는 탑바 전용이다) */
.modal-foot .spacer { flex: 1; }

/* ---------- 검색되는 선택 상자 (App.searchSelect) ---------- */
/* 진짜 <select> 는 자리만 차지하지 않게 숨긴다 — 값은 그대로 그 안에 있다 */
.ss { position: relative; }
.ss > select { display: none; }
.ss-btn {
  width: 100%; display: flex; align-items: center; justify-content: space-between; gap: 8px;
  border: 1px solid var(--border); border-radius: 6px; background: var(--surface);
  padding: 7px 10px; font-size: 13.5px; color: var(--ink); cursor: pointer; text-align: left;
}
.ss-btn:hover { background: var(--hover); }
/* 잠근 칸 — 값은 보여 주되 누를 수 있어 보이지 않게(hover 보다 뒤에 둬야 이긴다) */
.ss-btn:disabled { background: var(--bg-2); color: var(--ink-2); cursor: default; }
.ss-btn:disabled .lni { display: none; }
.ss-btn span { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.ss-btn span.ph { color: var(--ink-3); }
.ss-btn .lni { width: 15px; height: 15px; color: var(--ink-3); flex: none; }

/* 목록은 칸보다 좁아지지 않되 적어도 240px — 좁은 거르기 칸에서도 프로젝트 이름이 읽혀야 한다(왼쪽에 붙어 오른쪽으로 넓어진다) */
.ss-pop {
  display: none; position: absolute; left: 0; right: 0; top: calc(100% + 4px); z-index: 150;
  min-width: min(240px, calc(100vw - 24px));
  background: var(--elev); border: 1px solid var(--border); border-radius: 8px; box-shadow: var(--shadow-lg);
  padding: 6px;
}
.ss-pop.open { display: block; }
/* 아래가 모자라면 위로 펼친다 — 모달 아래쪽 칸에서는 목록이 화면 밖으로 나간다 */
.ss-pop.up { top: auto; bottom: calc(100% + 4px); }
.ss-q { width: 100%; border: 1px solid var(--border); border-radius: 6px; padding: 6px 9px;
        font-size: 13.5px; font-family: inherit; outline: none; }
.ss-q:focus { border-color: var(--accent); }
.ss-list { max-height: 230px; overflow-y: auto; margin-top: 5px; }
.ss-group { font-size: 11px; font-weight: 700; letter-spacing: .5px; text-transform: uppercase;
            color: var(--ink-3); padding: 7px 9px 3px; }
.ss-opt { padding: 6px 9px; border-radius: 5px; font-size: 13.5px; cursor: pointer;
          overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.ss-opt:hover { background: var(--hover); }
.ss-opt.on { background: var(--accent-soft); }
.ss-opt.cur { font-weight: 700; }
.ss-none { padding: 12px 9px; color: var(--ink-3); font-size: 13px; text-align: center; }

/* ---------- 업무협조 진행 막대 ---------- */
/* 다음에 할 일(확인·처리·완료) 버튼을 진행 표시 옆에 둔다 —
   탑바 오른쪽 구석에 있으면 "지금 어디까지 왔나"를 보는 눈에 안 들어와 놓친다. */
.coop-flow {
  margin: 14px 0; background: var(--bg-2);
  display: flex; align-items: center; justify-content: space-between; gap: 14px; flex-wrap: wrap;
}
.coop-flow .flow { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; }
.coop-acts { display: flex; gap: 8px; flex-wrap: wrap; margin-left: auto; }
/* 기한 연장 요청이 답을 기다릴 때 — 진행 막대 아래 한 줄(관리자에게는 승인·반려, 요청한 사람에게는 취소) */
.coop-ext { flex-basis: 100%; border: 1px solid var(--amber-line); background: var(--amber-soft); color: var(--ink);
            border-radius: 8px; padding: 10px 12px; font-size: 13.5px; }
.coop-ext-head { display: flex; flex-wrap: wrap; align-items: center; gap: 4px 8px; }
.coop-ext-head .lni { width: 15px; height: 15px; color: var(--amber-ink); }
.coop-ext-dates { color: var(--amber-ink); }
.coop-ext-why { margin-top: 6px; white-space: pre-wrap; word-break: break-word; color: var(--ink-2); }
.coop-ext-acts { display: flex; gap: 6px; margin-top: 8px; }
.coop-ext-wait { margin-top: 6px; font-size: 12.5px; color: var(--ink-3); }
.ext-cur { font-size: 14px; font-weight: 600; }
.ext-date-row { display: flex; align-items: center; gap: 8px; margin-top: 8px; }
.ext-date-row .input { width: 170px; }

/* 업무협조 통계 — 기간·프로젝트 고르는 줄, 숫자 카드, 지금 상태 막대, 사람·프로젝트별 표, 기한 지난 미처리 표 */
.cst-bar { display: flex; flex-wrap: wrap; align-items: center; gap: 8px 12px; margin-bottom: 14px; }
.cst-dates { display: inline-flex; align-items: center; gap: 6px; }
.cst-dates .input { width: 150px; }
.cst-period { font-size: 12.5px; color: var(--ink-3); margin: 0 0 10px; }
#statsBox.cst-busy { opacity: .55; transition: opacity .15s; }
#statsBox > .card { margin-bottom: 14px; }
#statsBox .card h3 { flex-wrap: wrap; }
.cst-cards { display: grid; grid-template-columns: repeat(auto-fill, minmax(210px, 1fr)); gap: 12px; margin-bottom: 14px; }
.cst-card { min-width: 0; background: var(--surface); border: 1px solid var(--border); border-radius: var(--radius); padding: 14px 16px; }
.cst-card .t { font-size: 12.5px; font-weight: 600; color: var(--ink-3); }
.cst-card .v { font-size: 24px; font-weight: 700; line-height: 1.2; margin-top: 4px; }
.cst-card .s { font-size: 12px; line-height: 1.5; color: var(--ink-3); margin-top: 6px; }
.cst-rate.good { color: var(--green-ink); }
.cst-rate.bad, .cst-bad { color: var(--red-ink); }
.cst-dist { display: flex; height: 12px; border-radius: 6px; overflow: hidden; background: var(--hover); }
.cst-dist span { display: block; min-width: 3px; }
.cst-legend { display: flex; flex-wrap: wrap; gap: 4px 14px; margin-top: 8px; font-size: 12.5px; color: var(--ink-2); }
.cst-lg { display: inline-flex; align-items: center; gap: 5px; }
.cst-lg i { display: inline-block; width: 10px; height: 10px; border-radius: 3px; }
.cst-seg-amber { background: var(--amber); }
.cst-seg-blue { background: var(--accent); }
.cst-seg-purple { background: var(--purple); }
.cst-seg-red { background: var(--red); }
.cst-seg-green { background: var(--green); }
.card h3 .cst-group { margin-left: auto; font-weight: 400; }
.cst-tbl th.sortable { cursor: pointer; user-select: none; white-space: nowrap; }
.cst-tbl th.sortable:hover { color: var(--ink); }
.cst-none { padding: 14px 0; text-align: center; font-size: 13px; color: var(--ink-3); }
.cst-foot { margin: 4px 2px 20px; font-size: 12.5px; color: var(--ink-3); }
.cst-foot summary { cursor: pointer; font-weight: 600; color: var(--ink-2); }
.cst-foot ul { margin: 8px 0 0 18px; line-height: 1.7; }

/* 업무협조 상세 — 요청 본문을 채널 글과 같은 모양으로 두되 한 건뿐이라 카드로 감싼다 */
.coop-msg {
  border: 1px solid var(--border); border-radius: 10px; background: var(--surface);
  padding: 12px 14px; margin: 0 0 12px;
}
.coop-msg:hover { background: var(--surface); }
/* 채널 글은 평문이라 .m-content 가 pre-wrap 이지만 협조 본문은 마크다운을 렌더한 HTML 이다 —
   그대로 두면 태그 사이 들여쓰기까지 공백으로 살아나 줄이 벌어진다. */
.coop-msg .m-content { font-size: 14px; white-space: normal; }
/* 업무협조 타임라인 — 요청 글 아래로 단계(확인·진행·처리·재요청·완료)가 시간 순으로 쌓이고,
   단계마다 그때 남긴 글과 첨부가 그 자리에 붙는다. 왼쪽 칸은 단계 칩, 그 아래로 이어지는 선이 순서를 잇는다 */
.coop-tl { margin: 0 0 14px; }
.tl-item { position: relative; display: grid; grid-template-columns: 78px minmax(0, 1fr); gap: 0 14px; padding-bottom: 14px; }
.tl-item:last-child { padding-bottom: 0; }
.tl-item:not(:last-child)::before {
  content: ""; position: absolute; left: 38px; top: 26px; bottom: 0; width: 2px; background: var(--border);
}
/* 칩은 줄 맨 위에 — align-items 기본값(stretch)이면 칩이 줄 높이만큼 늘어난다 */
.tl-mark { display: flex; align-items: flex-start; justify-content: center; padding-top: 2px; }
.tl-body {
  min-width: 0; border: 1px solid var(--border); border-radius: 10px; background: var(--surface); padding: 10px 12px;
}
.tl-body .m-head { display: flex; flex-wrap: wrap; align-items: center; gap: 0 8px; }
.tl-body .m-name { font-weight: 700; font-size: 14px; white-space: nowrap; }
.tl-body .m-time { font-size: 11.5px; color: var(--ink-3); white-space: nowrap; }
/* 단계에 남긴 글은 평문이라 줄바꿈을 살린다(요청 본문만 마크다운이다) */
.tl-note { font-size: 14px; white-space: pre-wrap; word-break: break-word; margin-top: 4px; }
.tl-body .m-content { font-size: 14px; white-space: normal; margin-top: 4px; }
@media (max-width: 600px) {
  /* 휴대폰은 칸이 좁다 — 단계 칩을 윗줄로 올려 글에 폭을 다 준다 */
  .tl-item { grid-template-columns: minmax(0, 1fr); gap: 6px; }
  .tl-item:not(:last-child)::before { display: none; }
  .tl-mark { justify-content: flex-start; }
}
/* 목록의 제목 칸 — 다른 칸이 전부 nowrap 이라 좁은 화면에서는 남는 폭만 받아 91px 까지 눌리고,
   한글은 글자마다 줄이 바뀌어 한 줄이 260px 높이로 늘었다. 표는 이미 옆으로 스크롤되므로 제목만 읽을 폭을 지킨다 */
.tbl td.coop-title { min-width: 180px; }
/* 업무협조 요청 대상 — 여러 명을 체크로 고른다. 프로젝트 참여자면 몇 명, 전체면 수십 명이라 찾기 칸과 스크롤을 둔다 */
.coop-pick {
  display: grid; grid-template-columns: repeat(auto-fill, minmax(170px, 1fr)); gap: 2px;
  margin-top: 6px; padding: 4px; max-height: 204px; overflow-y: auto;
  border: 1px solid var(--border); border-radius: 6px;
}
.coop-pick .checkbox { margin: 0; padding: 5px 6px; border-radius: 6px; min-width: 0; color: var(--ink); font-size: 13px; font-weight: 400; }
.coop-pick .checkbox:hover { background: var(--hover); }
.coop-pick .checkbox.on { background: var(--accent-soft); }
.coop-pick .nm { min-width: 0; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.coop-pick .sub { color: var(--ink-3); font-size: 12px; }
.coop-pick .avatar.sm { width: 22px; height: 22px; font-size: 11px; flex: none; }
.coop-pick > .empty-note, .coop-pick > .loading-box { grid-column: 1 / -1; }
.coop-pick > .empty-note { padding: 10px; color: var(--ink-3); font-size: 13px; }
.coop-pick-count { margin-left: 4px; color: var(--accent); font-weight: 600; }
/* 협조 댓글 — 타임라인 아래 입력칸. 삭제는 그 댓글 머리줄 끝 */
.coop-cmt { margin: 0 0 16px; }
.coop-cmt .textarea { width: 100%; min-height: 64px; resize: vertical; }
.coop-cmt-foot { display: flex; align-items: center; justify-content: space-between; gap: 8px; margin-top: 6px; }
.coop-cmt-off { margin: 0 0 16px; }
.tl-body .c-del { border: none; background: none; color: var(--ink-3); cursor: pointer; font-size: 11px; margin-left: auto; }
.tl-body .c-del:hover { color: var(--red); }
.coop-up { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; margin-bottom: 22px; }
/* App.fileDrop 이 안내 문구를 파일 칸 바로 뒤에 끼워 넣어 업로드 버튼이 다음 줄로 밀린다 — 문구를 맨 뒤로 */
.coop-up .hint { order: 9; flex-basis: 100%; margin: 0; }

/* ---------- 입력칸 자동완성 (App.autocomplete) ---------- */
.ac { position: relative; display: inline-block; }
.ac-pop {
  display: none; position: absolute; left: 0; top: calc(100% + 4px); z-index: 150;
  min-width: 100%; max-width: 420px;
  background: var(--elev); border: 1px solid var(--border); border-radius: 8px;
  box-shadow: var(--shadow-lg); padding: 5px; max-height: 300px; overflow-y: auto;
}
.ac-pop.open { display: block; }
.ac-opt {
  display: flex; align-items: center; justify-content: space-between; gap: 10px;
  padding: 7px 9px; border-radius: 5px; font-size: 13.5px; cursor: pointer;
}
.ac-opt:hover, .ac-opt.on { background: var(--accent-soft); }
.ac-opt .nm { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.ac-opt .sub { font-size: 11.5px; color: var(--ink-3); flex: none; }

/* 근태 칸을 눌러 직접 고칠 수 있다는 표시 (관리자 화면) */
.att-c.can-edit { cursor: pointer; }
.att-c.can-edit:hover { outline: 2px solid var(--accent); outline-offset: -2px; }
/* 관리자가 지정한 값 — 본인이 찍은 값이 아니라는 표시(자동 마감과 같은 이유) */
.att-c.work.fixed { background: var(--purple-soft); color: var(--purple); }

/* 근태 지정 창 — 출퇴근과 휴가를 한 창에 두되 저장은 따로다.
   무엇이 한 덩어리이고 어느 버튼이 무엇을 저장하는지 테두리로 갈라 준다 */
.att-sec { border: 1px solid var(--border); border-radius: 10px; padding: 12px 14px; margin-bottom: 12px; }
.att-sec:last-child { margin-bottom: 0; }
.att-sec > h4 { margin: 0 0 10px; font-size: 13px; font-weight: 700; }
.att-sec > h4 .att-sub { font-weight: 400; margin-left: 6px; }
.att-sec .field:last-of-type { margin-bottom: 0; }
.att-sec-act { display: flex; justify-content: flex-end; margin-top: 10px; }
.att-leave-now { border: 1px solid var(--border); border-radius: 8px; background: var(--bg-2);
  padding: 10px 12px; margin-bottom: 12px; font-size: 13px; line-height: 1.8; }

/* ============================================================
   연락처 — 재직 직원의 전화·이메일 카드(부서별). 휴대폰에서 전화 버튼을 바로 누르는 화면이라 카드가 넉넉하다
   ============================================================ */
.contact-count { font-size: 13px; color: var(--ink-3); }
.contact-notice { background: var(--amber-soft); border: 1px solid var(--amber-line); color: var(--amber-text); border-radius: var(--radius); padding: 10px 14px; font-size: 13px; margin-bottom: 14px; }
.contact-dept { font-size: 12.5px; font-weight: 700; color: var(--ink-2); margin: 18px 0 8px; display: flex; gap: 6px; align-items: baseline; }
.contact-dept:first-child { margin-top: 0; }
.contact-dept .n { color: var(--ink-3); font-weight: 400; }
.contact-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(250px, 1fr)); gap: 10px; }
.contact-card { display: flex; gap: 12px; padding: 12px 14px; background: var(--surface); border: 1px solid var(--border); border-radius: var(--radius); }
.contact-card.me { background: var(--bg-2); }
.contact-card .c-body { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 3px; }
.contact-card .c-name { font-weight: 700; font-size: 14.5px; display: flex; align-items: center; gap: 6px; }
.contact-card .c-sub { font-size: 12px; color: var(--ink-3); }
.contact-card .c-line { display: inline-flex; align-items: center; gap: 5px; font-size: 13px; color: var(--ink-2); max-width: 100%; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.contact-card a.c-line:hover { color: var(--accent); text-decoration: none; }
.contact-card .c-line.none { color: var(--ink-3); }
.contact-card .c-line .lni { width: 14px; height: 14px; flex: none; }
.contact-card .c-acts { display: flex; gap: 6px; margin-top: 6px; flex-wrap: wrap; }
.contact-card .c-acts a.btn:hover, .topbar a.btn:hover { text-decoration: none; }

/* 메모 상태(작성/처리)·날짜 — 개인 메모·공유메모 공용(memos.js). 처리한 카드는 흐리게 */
.memo-card.done { opacity: .75; }
.memo-meta { display: flex; flex-wrap: wrap; align-items: center; gap: 4px 8px; margin-top: 6px; font-size: 11.5px; color: var(--ink-2); }
.memo-meta .chip { font-size: 10.5px; padding: 0 6px; }
.memo-date.over { color: var(--red); font-weight: 600; }
/* 공유메모 읽음 — 상대가 지금 내용을 봤는지(눈 아이콘, 마우스를 올리면 누가 언제). 새로 올라온 것은 '새 글' 칩 */
.memo-read { display: inline-flex; align-items: center; gap: 3px; font-size: 11px; color: var(--ink-3); cursor: default; }
.memo-read .lni { width: 12px; height: 12px; }
.memo-read.on { color: var(--green-ink); }
.memo-acts { display: inline-flex; align-items: center; gap: 2px; }
.memo-do {
  display: inline-flex; align-items: center; gap: 3px; cursor: pointer; font-family: inherit;
  border: 1px solid var(--border); background: var(--surface); border-radius: 6px; padding: 2px 8px; font-size: 11.5px; color: var(--ink-2);
}
.memo-do .lni { width: 12px; height: 12px; }
.memo-do:hover { background: var(--green); border-color: var(--green); color: #fff; }
.memo-do.undo:hover { background: var(--hover); border-color: var(--border); color: var(--ink); }

/* ============================================================
   경영관리 — 재직증명서 발급(자격증은 문서관리의 자격증 탭과 내 정보 관리의 자격증 — 둘 다 아래 bdoc 갤러리를 쓴다)
   ============================================================ */
.cert-log .sub { color: var(--ink-3); font-size: 12px; }
.card h3 .sub { color: var(--ink-3); font-size: 12.5px; font-weight: 400; }
/* 재직증명서 — 발급 버튼 줄, 미리보기(서버가 그린 A4 한 장) */
.cert-acts { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; }
/* 칸을 어디서 채웠는지(지난 발급 / 직원 정보) — 폼 맨 위 한 줄 */
.cert-source { display: flex; align-items: center; gap: 6px; margin-bottom: 12px; font-size: 13px; color: var(--ink-3); }
.cert-source .lni { width: 15px; height: 15px; flex: none; }
/* 지난 발급으로 채운 칸이 지금 직원 정보와 다를 때 — 칸 바로 아래(display 를 정하지 않아 hidden 이 그대로 먹는다) */
.cert-diff { margin-top: 5px; font-size: 12.5px; line-height: 1.6; color: var(--amber-ink); word-break: break-word; }
.cert-diff .btn { margin-left: 4px; vertical-align: middle; }
/* 발급 내역을 고르면 뜨는 줄 — 몇 건 골랐는지와 한꺼번에 받기·인쇄(display 를 정해 둔 요소라 hidden 을 다시 적는다) */
.cert-sel { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; margin-bottom: 10px; padding: 8px 10px;
            border-radius: 8px; background: var(--accent-soft); font-size: 13px; }
.cert-sel[hidden] { display: none; }
.cert-preview { background: var(--bg-2); border-radius: 8px; padding: 12px; text-align: center; }
.cert-preview img { max-width: 100%; height: auto; box-shadow: var(--shadow-lg); background: #fff; }

/* ============================================================
   경영관리 › 문서관리 — 카테고리 탭 + 갤러리(눌러서 크게 보기, 체크해서 한 번에 받기·인쇄)
   ============================================================ */
/* 카테고리 탭 — 늘면 옆으로 민다(줄바꿈하면 밑줄이 두 줄로 갈라진다). 밑줄은 테두리가 아니라 안쪽 그림자로 그린다 —
   overflow 를 주면 탭이 -1px 로 테두리에 겹쳐 두던 부분이 잘려 켜진 탭의 밑줄이 얇아진다 */
.bdoc-tabs { overflow-x: auto; overflow-y: hidden; scrollbar-width: none; border-bottom: none; box-shadow: inset 0 -1px 0 var(--border); margin-bottom: 12px; }
.bdoc-tabs::-webkit-scrollbar { display: none; }
.bdoc-tabs .tab { flex-shrink: 0; white-space: nowrap; margin-bottom: 0; }

/* 찾기·정렬 줄 — 고른 것이 있으면 같은 자리가 선택 동작으로 바뀐다(자리가 그대로라 갤러리가 밀리지 않는다).
   스크롤해도 위에 붙어 있어 아래쪽에서 고른 뒤에도 바로 누른다 */
.bdoc-bar {
  position: sticky; top: 0; z-index: 6;
  display: flex; flex-wrap: wrap; align-items: center; gap: 8px;
  margin: 0 -8px 12px; padding: 8px;
  background: var(--bg); border-radius: 8px;
}
.bdoc-bar.picking { background: var(--accent-soft); }
.bdoc-bar .bdoc-all { margin: 0; font-size: 13px; white-space: nowrap; }
.bdoc-normal, .bdoc-selacts { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; flex: 1; min-width: 0; }
.bdoc-normal[hidden], .bdoc-selacts[hidden] { display: none; }
.bdoc-normal .input { width: 200px; height: 34px; }
.bdoc-normal .select { height: 34px; }
.bdoc-count { margin-left: auto; color: var(--ink-3); font-size: 12.5px; }
.bdoc-selacts .btn.ghost { margin-left: auto; }

/* 올리는 중 — 파일마다 한 요청이라 몇 번째인지와 전체 진행을 보여 준다 */
.bdoc-up { margin-bottom: 12px; padding: 10px 12px; border: 1px solid var(--border); border-radius: 8px; background: var(--bg-2); }
.bdoc-up[hidden] { display: none; }
.bdoc-up-row { display: flex; gap: 10px; font-size: 13px; }
.bdoc-up-text { flex: 1; min-width: 0; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.bdoc-up-track { height: 5px; margin-top: 7px; background: var(--hover); border-radius: 3px; overflow: hidden; }
.bdoc-up-track i { display: block; height: 100%; width: 0; background: var(--accent); transition: width .2s; }

/* 갤러리 — 어디에 놓아도 올라가게 자리를 넉넉히 잡는다 */
.bdoc-zone { min-height: 240px; border-radius: 10px; }
.bdoc-zone.drop-hot::after { content: '여기에 놓으면 올라갑니다'; }
.bdoc-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(176px, 1fr)); gap: 14px; }
.bdoc-grid > .empty, .bdoc-grid > .loading-box { grid-column: 1 / -1; }
.bdoc-card {
  position: relative; min-width: 0;
  display: flex; flex-direction: column;
  background: var(--surface); border: 1px solid var(--border); border-radius: 10px; overflow: hidden;
  transition: box-shadow .12s, border-color .12s;
}
.bdoc-card:hover { box-shadow: var(--shadow); }
.bdoc-card.sel { border-color: var(--accent); box-shadow: 0 0 0 2px rgba(35,131,226,.3); }
.bdoc-card.new { animation: bdoc-new 2.4s ease-out; }
@keyframes bdoc-new { 0%, 40% { box-shadow: 0 0 0 3px rgba(0,122,90,.45); } 100% { box-shadow: none; } }
/* 고르기 칸 — 늘 보인다(휴대폰에는 마우스를 올려 꺼낼 방법이 없다) */
.bdoc-check {
  position: absolute; top: 7px; left: 7px; z-index: 2;
  display: flex; align-items: center; justify-content: center;
  width: 26px; height: 26px; border-radius: 6px; cursor: pointer;
  background: rgba(255,255,255,.92); box-shadow: 0 0 0 1px rgba(0,0,0,.08);
}
.bdoc-check input { width: 16px; height: 16px; margin: 0; cursor: pointer; }
/* 그림 칸 — 서류는 세로, 사진은 가로라 정사각에 잘리지 않게(contain) 앉힌다 */
.bdoc-thumb {
  position: relative; aspect-ratio: 1 / 1;
  display: flex; align-items: center; justify-content: center;
  background: var(--bg-2); cursor: zoom-in; overflow: hidden;
}
.bdoc-thumb.plain { cursor: pointer; }
.bdoc-thumb img { width: 100%; height: 100%; object-fit: contain; padding: 6px; display: block; }
.bdoc-badge { position: absolute; right: 6px; bottom: 6px; padding: 1px 6px; border-radius: 4px; background: rgba(196,85,77,.92); color: #fff; font-size: 10.5px; font-weight: 700; letter-spacing: .02em; }
/* 그림으로 못 보여 주는 형식 — 종류별 색의 확장자 */
.bdoc-file { display: flex; flex-direction: column; align-items: center; gap: 6px; color: var(--ink-3); }
.bdoc-file .lni { width: 44px; height: 44px; stroke-width: 1.4; }
.bdoc-file b { font-size: 12px; letter-spacing: .04em; }
.bdoc-file.pdf { color: var(--red-ink); }
.bdoc-file.hwp { color: #1E7BD6; }
.bdoc-file.word { color: #2B579A; }
.bdoc-file.excel { color: #217346; }
.bdoc-file.ppt { color: #C4532E; }
.bdoc-file.zip { color: #8A6D3B; }
.bdoc-body { padding: 8px 10px 2px; min-width: 0; cursor: pointer; }
.bdoc-name {
  font-size: 13px; font-weight: 600; line-height: 1.4; word-break: break-all;
  display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden;
}
.bdoc-meta { margin-top: 3px; font-size: 11.5px; color: var(--ink-3); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.bdoc-cat { color: var(--accent); }
.bdoc-cat.lic { color: var(--purple); }
/* 수정 창의 '누구의 자격증' — 고칠 수 없는 값이라 칸이 아니라 글자로 */
.bdoc-owner { font-size: 14px; font-weight: 600; padding: 4px 0; }
.bdoc-acts { display: flex; justify-content: flex-end; gap: 2px; margin-top: auto; padding: 2px 6px 6px; }
.bdoc-act {
  display: inline-flex; align-items: center; justify-content: center;
  width: 30px; height: 28px; border: none; border-radius: 6px; background: none;
  color: var(--ink-2); cursor: pointer;
}
.bdoc-act:hover { background: var(--hover); color: var(--ink); }
.bdoc-act .lni { width: 16px; height: 16px; }

/* 수정 창 */
.bdoc-edit-head { display: flex; gap: 12px; align-items: center; margin-bottom: 14px; padding: 10px; background: var(--bg-2); border-radius: 8px; }
.bdoc-edit-pic { width: 64px; height: 64px; flex: none; display: flex; align-items: center; justify-content: center; background: var(--surface); border-radius: 6px; overflow: hidden; }
.bdoc-edit-pic img { width: 100%; height: 100%; object-fit: contain; }
.bdoc-edit-pic .bdoc-file .lni { width: 28px; height: 28px; }
.bdoc-edit-pic .bdoc-file b { font-size: 10px; }
.bdoc-edit-info { min-width: 0; font-size: 13px; word-break: break-all; }
.bdoc-edit-info .sub { color: var(--ink-3); font-size: 12px; margin-top: 2px; }
.bdoc-name-row { display: flex; align-items: center; gap: 6px; }
.bdoc-name-row .input { flex: 1; min-width: 0; }
.bdoc-ext-lbl { color: var(--ink-2); font-size: 13.5px; white-space: nowrap; }

/* 카테고리 관리 창 — 칸마다 바로 저장 */
.bdoc-catlist { display: flex; flex-direction: column; gap: 6px; margin-bottom: 12px; }
.bdoc-catrow { display: flex; align-items: center; gap: 4px; }
.bdoc-catrow .input { flex: 1; min-width: 0; height: 34px; }
.bdoc-catcnt { min-width: 38px; text-align: right; color: var(--ink-3); font-size: 12px; margin-right: 4px; white-space: nowrap; }
.bdoc-catrow .btn .lni { width: 14px; height: 14px; }
.bdoc-catrow .lni.up { transform: rotate(180deg); }
.bdoc-catempty { padding: 10px 0; color: var(--ink-3); font-size: 13px; }
.bdoc-catadd { display: flex; gap: 6px; margin-bottom: 8px; }
.bdoc-catadd .input { flex: 1; min-width: 0; }

@media (max-width: 640px) {
  .bdoc-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 10px; }
  .bdoc-bar { margin: 0 -4px 10px; padding: 6px 4px; }
  .bdoc-normal .input { width: auto; flex: 1 1 120px; }
}

/* ============================================================
   내 정보 관리 › 설정 — 화면 모드(라이트 · 다크 · 시스템 설정)
   칸마다 그 모드의 작은 화면 그림을 그려 무엇이 바뀌는지 보여 준다. 그림 색은 토큰이 아니라 고정값이다 —
   지금 어느 모드로 보고 있든 '그 모드'를 보여 줘야 한다
   ============================================================ */
.theme-opts { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 12px; max-width: 540px; }
.theme-opt {
  display: flex; flex-direction: column; gap: 8px; min-width: 0; padding: 8px 8px 9px;
  border: 1px solid var(--border); border-radius: 10px; background: var(--surface);
  color: var(--ink); font: inherit; font-size: 13px; text-align: left; cursor: pointer;
}
.theme-opt:hover { border-color: var(--ink-3); }
.theme-opt.on { border-color: var(--accent); box-shadow: 0 0 0 1px var(--accent); }
.theme-opt .t-lbl { display: flex; align-items: center; gap: 6px; min-width: 0; padding: 0 2px; font-weight: 500; }
.theme-opt .t-lbl .lni { width: 15px; height: 15px; color: var(--ink-2); }
.theme-opt .t-lbl .t-ck { margin-left: auto; color: var(--accent); visibility: hidden; }
.theme-opt.on .t-lbl .t-ck { visibility: visible; }
.theme-pv { display: flex; height: 64px; border-radius: 6px; overflow: hidden; box-shadow: inset 0 0 0 1px rgba(128,128,128,.28); }
.theme-pv .pv-sb { width: 22%; flex: none; background: #3F0E40; }
.theme-pv .pv-main { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 5px; padding: 9px 8px; }
.theme-pv .pv-main i { display: block; height: 5px; border-radius: 3px; }
.theme-pv .pv-main i:nth-child(1) { width: 60%; height: 6px; }
.theme-pv .pv-main i:nth-child(2) { width: 88%; }
.theme-pv .pv-main i:nth-child(3) { width: 70%; }
.theme-pv .pv-main.light { background: #FFFFFF; }
.theme-pv .pv-main.light i { background: #E4E3E0; }
.theme-pv .pv-main.light i:nth-child(1) { background: #9B9A97; }
.theme-pv .pv-main.dark { background: #191919; }
.theme-pv .pv-main.dark i { background: #3A3A3A; }
.theme-pv .pv-main.dark i:nth-child(1) { background: #8A8986; }
@media (max-width: 600px) {
  .theme-opts { gap: 8px; }
  .theme-opt { padding: 6px 6px 8px; font-size: 12.5px; }
  .theme-pv { height: 52px; }
}

/* ============================================================
   다크 모드 — <html data-theme="dark">
   app.js 가 <head> 에서 기기별 설정(localStorage jhr.theme)을 읽어 본문이 그려지기 전에 정한다. '시스템 설정'도 거기서
   dark/light 로 풀어 넣으므로 CSS 는 이 한 벌만 둔다(@media prefers-color-scheme 로 같은 목록을 두 번 적지 않는다).
   app.js 를 싣지 않는 화면(차단 안내, 오류)과 외부 고객용 /draft(app.js 를 싣지만 <html data-theme-fixed>)는 늘 밝다.
   원칙은 토큰만 갈아 끼우는 것이다 — 새 화면을 토큰으로 쓰면 저절로 따라온다. 아래 선택자 덮어쓰기는 한 곳에서만
   쓰는 색이라 토큰으로 올리지 않은 것들이다. 주의: 여기 규칙은 원래 규칙보다 [data-theme] 만큼만 세서, 같은 세기의
   변형(.toast.error 같은)이 있으면 파일 뒤쪽인 이쪽이 이긴다 — 변형이 있는 요소는 덮어쓰지 말고 토큰으로 올린다
   ============================================================ */
:root[data-theme="dark"] {
  color-scheme: dark;              /* 스크롤바·날짜 고르기·select 목록 같은 브라우저 기본 조각도 어둡게 */
  --ink: #DCDCD9;
  --ink-2: #A3A29E;
  --ink-3: #7E7D79;
  --quote-ink: #C4CDD9;
  --bg: #191919;
  --bg-2: #232323;
  --surface: #1F1F1F;
  --elev: #262626;
  --hover: #2C2C2C;
  --border: #333333;
  --border-strong: #4A4A47;
  --accent: #3A8FE6;
  --accent-soft: #1B2E40;
  --green: #17876A;
  --green-soft: #173630;
  --red: #E0605A;
  --red-soft: #3C2323;
  --amber: #D29D3E;
  --amber-soft: #37301E;
  --purple: #A67ECA;
  --purple-soft: #2D2536;
  --msg-hover: #1E1E1E;
  --unread: #1A2633;
  --unread-hover: #1F2D3B;
  --mark: #5E4C12;
  --blue-ink: #7FB7EF;
  --green-ink: #5DC5A3;
  --red-ink: #F08C84;
  --amber-ink: #E2B45F;
  --purple-ink: #C5A2E5;
  --pink-soft: #3A2330;
  --pink-ink: #EE92BC;
  --orange-soft: #3A2A1C;
  --amber-text: #E2B45F;
  --amber-line: #52442A;
  --red-text: #F08C84;
  --red-line: #5A3131;
  --pink-text: #EE92BC;
  --pink-line: #5A3347;
  --pink-sub: #B98AA3;
  --shadow: 0 1px 2px rgba(0,0,0,.35), 0 4px 16px rgba(0,0,0,.35);
  --shadow-lg: 0 10px 40px rgba(0,0,0,.6);
}
[data-theme="dark"] .modal-overlay { background: rgba(0,0,0,.6); }
/* 휴대폰 서랍의 뒷막 — 밝은 화면용 옅은 막은 어두운 본문 위에서는 거의 안 보여 서랍이 떠 보이지 않는다 */
[data-theme="dark"] .sb-backdrop { background: rgba(0,0,0,.55); }
[data-theme="dark"] .btn.primary:hover { background: #1C9A78; }
[data-theme="dark"] .btn.blue:hover { background: #4C9BEA; }
/* 토스트 — 밝은 화면의 어두운 상자 그대로면 바탕과 구분이 안 된다. 오류·완료는 제 색을 지킨다(위 주의) */
[data-theme="dark"] .toast { background: #3A3A3A; box-shadow: 0 0 0 1px rgba(255,255,255,.07), var(--shadow-lg); }
[data-theme="dark"] .toast.error { background: var(--red); }
[data-theme="dark"] .toast.success { background: var(--green); }
[data-theme="dark"] .mention-host > .mention-input::selection { background: rgba(58,143,230,.45); }
[data-theme="dark"] .md-body .md-code { background: #111113; box-shadow: inset 0 0 0 1px var(--border); }
[data-theme="dark"] .ver-item.active { border-color: #2A4863; }
[data-theme="dark"] .msg .m-check.on { border-color: #2B5A4C; }
[data-theme="dark"] .diff-line.add { color: var(--green-ink); }
[data-theme="dark"] .diff-line.del { color: var(--red-ink); }
/* 메모 카드 테두리 — 바탕은 -soft 토큰을 따라 이미 바뀌어 있다 */
[data-theme="dark"] .memo-card.orange { border-color: #563F2B; }
[data-theme="dark"] .memo-card.yellow { border-color: #544A2C; }
[data-theme="dark"] .memo-card.green  { border-color: #28503F; }
[data-theme="dark"] .memo-card.blue   { border-color: #284A60; }
[data-theme="dark"] .memo-card.purple { border-color: #45384F; }
[data-theme="dark"] .memo-card.gray   { border-color: #3A3A3A; }
/* 문서관리 — 그림 위 고르기 칸, 파일 종류 색(어두운 바탕에서 읽히게 밝힌다. PDF 는 --red-ink 로 이미 따라온다) */
[data-theme="dark"] .bdoc-check { background: rgba(38,38,38,.92); box-shadow: 0 0 0 1px rgba(255,255,255,.12); }
[data-theme="dark"] .bdoc-file.hwp { color: #6CB0F2; }
[data-theme="dark"] .bdoc-file.word { color: #86A9E3; }
[data-theme="dark"] .bdoc-file.excel { color: #5CBF87; }
[data-theme="dark"] .bdoc-file.ppt { color: #EE9170; }
[data-theme="dark"] .bdoc-file.zip { color: #D2B27C; }
