/* ──────────────────────────────────────────────────────────────────────────
 * hidden 속성은 항상 이긴다
 *
 * 이 파일의 컴포넌트 규칙 대부분이 `display:` 를 선언한다. 클래스 셀렉터와 `[hidden]` 은
 * 명시도가 같아서, 전역 규칙 없이는 **컴포넌트의 display 선언이 hidden 속성을 눌러버린다** —
 * JS 가 `el.hidden = true` 해도 요소가 그대로 보인다.
 *
 * 그래서 컴포넌트마다 `.foo[hidden]{display:none}` 가드를 손으로 달아 왔고, 빠뜨릴 때마다
 * 같은 버그가 났다(inline-reason-form 이 항상 펼쳐짐 / 썸네일 아이콘이 이미지 뒤에 남음).
 * 규칙을 시스템에 넣어 그 부류를 없앤다 — 새 컴포넌트는 가드를 기억할 필요가 없다.
 *
 * `!important` 는 명시도 경쟁을 끝내기 위한 것이다. hidden 은 "렌더하지 않는다" 는 뜻이고
 * 그걸 뒤집고 싶은 경우는 없다. 아래 개별 가드들은 이제 중복이지만 무해해 남겨 둔다.
 * ────────────────────────────────────────────────────────────────────────── */
[hidden] {
  display: none !important;
}

/* ── Toast (Sonner-inspired) ── */
.flash-container {
  position: fixed;
  z-index: 100;
  display: flex;
  gap: 0.5rem;
  pointer-events: none;
}

.flash-container-top-center {
  top: 1.5rem;
  left: 50%;
  transform: translateX(-50%);
  flex-direction: column;
}

.flash-toast {
  pointer-events: auto;
  min-width: 20rem;
  max-width: 28rem;
  padding: 0.875rem 1.25rem;
  border-radius: var(--radius-lg);
  font-size: 0.875rem;
  line-height: 1.4;
  display: flex;
  align-items: center;
  gap: 0.625rem;
  cursor: pointer;
}

/* Entrance animation */
.flash-container-top-center .flash-toast {
  animation: toastInDown 0.4s cubic-bezier(0.21, 1.02, 0.73, 1);
}

.flash-toast-notice {
  background-color: var(--text-primary);
  color: var(--text-inverse);
  box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
}

.flash-toast-alert {
  background-color: var(--destructive);
  color: #fff;
  box-shadow: 0 4px 12px rgba(239, 68, 68, 0.25);
}

.flash-toast-icon {
  flex-shrink: 0;
  width: 1.125rem;
  height: 1.125rem;
  opacity: 0.8;
}

.flash-toast-message {
  flex: 1;
  min-width: 0;
}

@media (max-width: 1023px) {
  .flash-container-top-center {
    top: 4rem;
    width: calc(100% - 2rem);
  }

  .app-main > .flash-container-top-center:has(.flash-toast) {
    position: relative;
    top: auto;
    left: auto;
    transform: none;
    width: auto;
    margin: 1rem 1rem 0;
  }

  .flash-container-top-center .flash-toast {
    box-sizing: border-box;
    width: 100%;
    min-width: 0;
    max-width: none;
  }
}

/* Dismiss animation */
.flash-container-top-center .flash-toast.hiding {
  opacity: 0;
  transform: scale(0.95) translateY(-0.5rem);
  transition: opacity 200ms ease, transform 200ms ease;
}

@keyframes toastInDown {
  from { opacity: 0; transform: scale(0.9) translateY(-1rem); }
  to   { opacity: 1; transform: scale(1) translateY(0); }
}

/* ── Dropdown Menu Transitions ── */
[data-dropdown-target="menu"] {
  transition: opacity var(--transition-fast), transform var(--transition-fast);
}

[data-dropdown-target="menu"]:not(.hidden) {
  animation: dropdownIn 0.15s ease-out;
}

@keyframes dropdownIn {
  from {
    opacity: 0;
    transform: scale(0.95) translateY(-0.25rem);
  }
  to {
    opacity: 1;
    transform: scale(1) translateY(0);
  }
}

/* ── Inline Review Actions ── */
/* ── 리뷰 액션 패널 — 승인/수정요청/반려 + 인라인 사유(textarea). 상세·액션센터 공용. ──
 * 사유 폼은 기본 hidden — 전역 [hidden] 규칙이 없어 display 선언이 hidden 속성을 눌러버리므로
 * .review-reason[hidden]{display:none}로 명시 가드(이전 .inline-reason-form이 항상 펼쳐지던 버그 해소). */
.review-actions { display: flex; flex-direction: column; gap: 0.625rem; }
.review-actions-bar { display: flex; flex-wrap: wrap; align-items: center; gap: 0.5rem; }
.review-actions-bar form { margin: 0; }
.review-reason {
  display: flex;
  flex-direction: column;
  gap: 0.5rem;
  padding: 0.75rem;
  background: var(--surface-1);
  border: 1px solid var(--border-subtle);
  border-radius: var(--radius-md);
}
.review-reason[hidden] { display: none; }
.review-reason form { display: flex; flex-direction: column; gap: 0.5rem; margin: 0; }
.review-reason-input { width: 100%; resize: vertical; min-height: 3.5rem; }
.review-reason-bar { display: flex; justify-content: flex-end; gap: 0.5rem; }

/* 사이드바 액션 — 풀폭 버튼 스택(button_to form 포함) */
.action-stack {
  display: flex;
  flex-direction: column;
  gap: 0.5rem;
}

.action-stack > form,
.action-stack > .btn {
  width: 100%;
}

.action-stack > form .btn,
.action-stack .btn {
  width: 100%;
  justify-content: center;
}


/* ── Comments thread (절제된 SaaS — Linear/Notion 기준) ── */
.comment {
  display: flex;
  flex-direction: column;     /* 헤더(아바타+이름/날짜) 위, 본문 아래 */
  gap: 0.25rem;
  padding: 0.5rem;
  margin: 0 -0.5rem;
  border-radius: var(--radius-md);
  transition: background-color 0.15s ease;
}

.comment:hover {
  background: var(--surface-hover);
}

/* ── 활동 이력 타임라인(COLLA-24) ── */
/* 시스템 액션만 보여주는 읽기 전용 영역. 입력창이 없는데 코멘트 목록과 같은 모양이면
   "여기 쓸 수 있나"로 읽혀서, 시간축이 있는 이력 형태로 구분한다.
   마크업은 코멘트 파셜 그대로 두고 표현만 바꾼다 — 브로드캐스트 append가 같은 모양으로
   들어와도 어긋나지 않는다(구조를 바꾸면 실시간 반영이 깨진다).
   한 항목 = 한 줄. 이력은 훑어 읽는 목록이라 이름·회사·시각을 3줄로 쌓으면 밀도가 무너진다. */
.activity-timeline {
  position: relative;
  padding-left: 1.125rem;   /* 점이 -1rem까지 나가므로 잘리지 않게 확보 */
}
/* 축은 컨테이너에 선 하나를 긋고 위아래를 깎는 대신 **항목마다 자기 구간을 그린다**
   (GitHub Primer TimelineItem과 같은 방식) — 항목이 추가·삭제돼도 매직넘버가 어긋나지 않는다.
   첫/마지막 항목에서만 구간을 반쪽으로 잘라 선이 밖으로 삐져나오지 않게 한다. */
.activity-timeline > .comment {
  position: relative;
  margin: 0;
  padding: 0.625rem 0.5rem;   /* 항목 간 여백 — 축은 padding 안쪽이라 선이 끊기지 않는다 */
  background: none;
  border-radius: 0;
}
.activity-timeline > .comment::after {
  content: "";
  position: absolute;
  top: 0;
  bottom: 0;
  left: -0.6875rem;   /* 선: -11 ~ -9px, 중심 -10px */
  width: 2px;
  background-color: var(--border-subtle);
}
.activity-timeline > .comment:first-child::after { top: 0.875rem; }
.activity-timeline > .comment:last-child::after { bottom: calc(100% - 0.875rem); }
/* 마커 — 배경색 테두리로 뒤의 선을 가린다(Primer와 같은 처리). 이벤트 색을 입혀
   훑을 때 종류가 색으로 먼저 읽히게 한다. 행 hover 배경을 두지 않는 이유는
   테두리 색이 배경과 어긋나 마커 주변에 헤일로가 생기기 때문이다(읽기 전용 목록이라 hover 불필요). */
.activity-timeline > .comment::before {
  content: "";
  position: absolute;
  z-index: 1;
  top: 0.75rem;
  left: -1rem;        /* 점: 총폭 12px(8+테두리 2×2) → -16 ~ -4px, 중심 -10px = 선 중심 */
  width: 0.5rem;
  height: 0.5rem;
  border-radius: var(--radius-full);
  border: 2px solid var(--surface-0);
  background-color: var(--text-tertiary);
  box-sizing: content-box;
}
.activity-timeline > .comment--event-requested::before,
.activity-timeline > .comment--event-resubmitted::before,
.activity-timeline > .comment--event-stage_changed::before { background-color: var(--status-info-dark); }
.activity-timeline > .comment--event-approved::before { background-color: var(--status-success-dark); }
.activity-timeline > .comment--event-conditionally_approved::before { background-color: var(--badge-purple-dark); }
.activity-timeline > .comment--event-rejected::before { background-color: var(--destructive-dark); }
.activity-timeline > .comment--event-revision_requested::before { background-color: var(--status-warning-dark); }

/* 한 항목을 3줄로 읽힌다 — 1줄: 액션 태그 + 시각 / 2줄: 사람·소속 / 3줄: 내용(있으면).
   사람은 DOM상 태그와 같은 .comment-author-row 안에 있어 그대로면 한 줄에 붙는다.
   author-row를 display:contents로 풀어 자식을 byline의 flex 아이템으로 승격시킨 뒤
   order로 순서를 잡고 사람만 flex-basis:100%로 줄을 통째로 쓰게 한다. */
.activity-timeline > .comment .comment-byline {
  display: flex;
  flex-direction: row;   /* 기본 .comment-byline은 column — 되돌리지 않으면 세로로 쌓인다 */
  flex-wrap: wrap;
  align-items: center;
  justify-content: flex-start;
  gap: 0.25rem 0.5rem;
}
.activity-timeline .comment-author-row { display: contents; }
/* 1줄: 액션 태그 → 유형 태그 → 시각. .comment .comment-time 기본 규칙(들여쓰기)과
   특이도가 같으면 순서에 의존하므로 한 단계 올린다. */
.activity-timeline > .comment .comment-time {
  order: 3;
  margin: 0;
  font-variant-numeric: tabular-nums;
  font-size: 0.6875rem;
  color: var(--text-muted);
}

.activity-timeline .comment-head { gap: 0.5rem; align-items: center; }
/* 아바타는 신원 힌트 정도로만 — 한 줄 높이를 넘기지 않게 줄인다. */
.activity-timeline .avatar { width: 1.125rem; height: 1.125rem; }
.activity-timeline .avatar-fallback { font-size: 0.5rem; }
/* 이름·회사를 세로 스택에서 한 줄로 — 회사는 가운뎃점으로 이어 붙인다. */
.activity-timeline .member-display-text { flex-direction: row; align-items: center; gap: 0.25rem; }
.activity-timeline .member-display-company::before { content: "·"; margin-right: 0.25rem; }
/* 행마다 반복되는 신원은 보조 정보다 — 액션 배지가 먼저 읽히도록 톤을 낮춘다. */
.activity-timeline .member-display-name,
.activity-timeline .member-display-company { font-size: 0.6875rem; color: var(--text-muted); }
.activity-timeline .comment-event-badge { order: 1; }
.activity-timeline .comment-approval-type-tag { order: 2; }
/* 2줄: 사람·소속 — 줄을 통째로 써서 태그·시각 아래로 내려온다. */
.activity-timeline .comment-author { order: 4; flex-basis: 100%; min-width: 0; }
/* 배지는 내부 줄바꿈 금지 — 좁은 폭에서 "단계/변경", "시/스/템"처럼 글자 단위로 쪼개졌다. */
.activity-timeline .comment-event-badge,
.activity-timeline .comment-approval-type-tag { white-space: nowrap; }

/* 좁은 화면 폴백 — 시각·액션·사람을 한 줄에 넣을 폭이 없다. 글자만 줄이는 게 아니라
   배치를 바꿔 시각을 윗줄로 올린다(고정폭 시각 열 + nowrap을 그대로 두면 배지가 쪼개진다). */
@media (max-width: 639px) {
  /* 한 줄을 통째로 쓰니 이름·회사를 줄임표로 자를 이유가 없다. */
  .activity-timeline .member-display-name { max-width: none; }
  .activity-timeline .comment-content { margin-left: 0; }
}

/* 사유·전이 내용은 헤더 아래 보조 줄로. 본문 기본 크기(0.875rem)를 그대로 쓰면
   행마다 본문이 헤더보다 커져 위계가 뒤집힌다 — 이력에선 액션이 먼저 읽혀야 한다.
   들여쓰기는 두지 않는다 — 임의 값으로 밀면 시각 열도 배지 열도 아닌 어중간한 위치가 된다. */
.activity-timeline .comment-content { margin-left: 0; padding-top: 0; }
.activity-timeline .comment-system-reason {
  font-size: 0.75rem;
  line-height: 1.5;
  color: var(--text-muted);
}

/* 시스템(이벤트) 코멘트 — 상태 전이 자동 기록. 옅은 중립 배경으로 사용자 코멘트와 구분,
   이벤트 종류는 헤더 배지 색으로 전달(좌측 바 없음 — 아래 규칙 참조). */
.comment--system {
  /* 옅은 중립 배경 + 위아래 여백·내부 패딩으로 사용자 코멘트와 구분(좌측 바 없음).
     이벤트 종류는 헤더의 이벤트 배지 색으로 전달(승인=초록·반려=빨강·수정=주황·신청/단계변경=파랑). */
  background: var(--surface-1);
  margin-block: 0.5rem;
  padding: 0.625rem 0.75rem;
}

.comment--system:hover {
  background: var(--surface-1);
}

.comment-head {
  display: flex;
  align-items: center;       /* 아바타가 이름/날짜 2줄 블록과 세로 중앙정렬 */
  gap: 0.625rem;
}

/* 이름(1줄) / 날짜(1줄) 세로 스택 — 이름이 길어도 날짜와 한 줄에 묶이지 않음 */
.comment-byline {
  display: flex;
  flex-direction: column;
  flex: 1;
  min-width: 0;              /* 긴 이름이 컬럼 폭 안에서 줄바꿈 */
}

.comment-author {
  font-size: 0.8125rem;
  font-weight: 600;
  line-height: 1.3;
  color: var(--text-primary);
}

.comment-time {
  font-size: 0.75rem;
  line-height: 1.3;
  color: var(--text-muted);
  white-space: nowrap;        /* 날짜·시각은 한 덩어리로 */
}

/* Slack식 정렬 — 아바타는 gutter를 차지하고, **이름과 본문이 같은 좌변**에 선다.
   gutter = 아바타(xs 1.5rem) + .member-display gap(0.375rem). 상수를 두 곳에 적으면 어긋나므로
   변수 하나로 두고 본문이 그걸 그대로 쓴다. 전엔 2.625rem(아바타 2rem 가정)이라 이름보다
   12px 더 밀려 있었다. */
.comment {
  --comment-gutter: calc(1.5rem + 0.375rem);
}
.comment-content {
  margin-left: var(--comment-gutter);
}

/* 수정·삭제 액션은 hover 시에만 노출(절제) */
.comment-actions {
  margin-left: auto;
  display: inline-flex;
  align-items: center;
  gap: 0.125rem;
}

.comment-actions form {
  display: inline-flex;
  margin: 0;
}

.comment-action {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  /* 터치 타깃 44px(WCAG 2.5.5) — 아이콘은 작게 유지, 클릭 영역만 확장 */
  min-width: 2.75rem;
  min-height: 2.75rem;
  color: var(--text-tertiary);
  background: transparent;
  border: 0;
  border-radius: var(--radius-sm);
  cursor: pointer;
  opacity: 0;
  transition: opacity 0.15s ease, color 0.15s ease, background-color 0.15s ease;
}

.comment:hover .comment-action,
.comment-action:focus-visible {
  opacity: 1;
}

.comment-action:hover {
  color: var(--text-primary);
  background: var(--surface-hover);
}

.comment-delete:hover {
  color: var(--destructive);
  background: var(--surface-hover);
}

/* ── 시스템(이벤트) 코멘트 — 일반 코멘트와 동일 레이아웃, 액션 배지로만 구분(#629) ── */
/* 별도 박스/아이콘 없이 "그 사람이 단 코멘트"처럼 보인다. 수정·삭제·리액션만 없음. */
/* 이름 + 액션 배지를 한 줄에(시각은 byline 아래 줄). */
.comment-author-row {
  display: inline-flex;
  align-items: center;
  gap: 0.375rem;
  flex-wrap: wrap;
}
.comment .comment-time { margin-top: 0.25rem; margin-left: 1.875rem; }

/* 사유 본문 — 여러 줄 보존(과거 한 줄 ellipsis 폐기). */
.comment-system-reason {
  font-size: 0.875rem;
  line-height: 1.7;
  color: var(--text-secondary);
  white-space: pre-wrap;
}

/* 사람이 남긴 말 — 자동 기록(단계 변경 등)과 섞이면 구분되지 않아 인용 형태로 세운다(COLLA-24). */
.comment-system-reason--message {
  padding-left: 0.5rem;
  border-left: 2px solid var(--border-default);
  /* 줄바꿈 보존은 텍스트를 담은 자식에게만 준다. 이 래퍼에 pre-wrap을 걸면 **마크업의 개행과
     들여쓰기가 문자 그대로 렌더**돼(태그 사이 12칸 공백), 본문이 오른쪽으로 밀리고 위아래로
     빈 줄이 생긴다. 인용 없는 분기가 flush left였던 건 그쪽이 한 줄로 쓰여 있었기 때문. */
  white-space: normal;
}
.comment-message-body {
  white-space: pre-wrap;
}
/* 리치 HTML 본문(COLLA-26)은 HTML이 이미 줄바꿈을 표현하므로 pre-wrap을 끈다 — 안 그러면
   ERB가 넣은 태그 사이 개행·들여쓰기가 그대로 빈 줄로 쌓인다. .comment-system-reason 조상으로
   스코프하면 그 조상 없이 이 클래스를 쓰는 곳(재제출 화면의 수정요청 사유 카드 등)에서 재발한다 —
   .trix-content 리치 본문이면 어디에 놓이든 적용해야 한다(#COLLA-59 머지 게이트 BLOCK). */
.comment-message-body.trix-content {
  white-space: normal;
}

/* 메시지 아래 한 줄 — "영어에서 자동 번역 · 원문 보기" / "번역 보기"(COLLA-233·COLLA-239).
   **번역 상태와 원문 상태가 같은 자리·같은 모양이어야 한다** — 한쪽은 본문 위에 안내가 있고
   다른 쪽은 아래에 링크만 있어서, 눌러서 오갈 때 글이 위아래로 밀렸다(사용자 지적). */
.comment-translation-meta {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  margin-top: 0.25rem;
}
.comment-translation-label {
  font-size: 0.75rem;
  color: var(--text-tertiary);
}
.comment-translation-error {
  font-size: 0.75rem;
  color: var(--destructive);
  margin: 0 0 0.25rem;
}
/* 트리거와 되돌리기는 평소 조용히 있는다 — 댓글마다 눈에 띄는 버튼이 서면 본문이 안 읽히고,
   되돌리는 링크가 옮긴 글보다 굵으면 화면에서 가장 큰 목소리가 "원문 보기"가 된다(실측).
   `.btn-link` 는 패딩이 0 이라 높이가 글자만 하다 — 손가락으로 누를 자리를 만든다. */
.comment-translation-trigger,
.comment-translation-toggle {
  font-size: 0.75rem;
  font-weight: 400;
  color: var(--text-tertiary);
  padding: 0.375rem 0;
}
.comment-translation-trigger:hover,
.comment-translation-toggle:hover {
  color: var(--text-secondary);
}

/* 이벤트/시스템 배지 — 액션색의 파스텔(라이트) 토큰. 승인 결정·단계 변경 구분(#459·#523·#629). */
.comment-event-badge {
  display: inline-flex;
  align-items: center;
  padding: 0.0625rem 0.4375rem;
  border-radius: var(--radius-full);
  font-size: 0.6875rem;
  font-weight: 600;
  line-height: 1.5;
}
/* 진행/이동 계열 — 신청·재제출·단계 변경(파랑 info).
   증지 교부 완료(issued)도 여기다 — 상태 배지의 `status_badge_variant("issued")` 가 info 이므로,
   다른 색을 주면 같은 사실이 활동과 상태에서 다른 색이 된다. */
.comment-event-badge--requested,
.comment-event-badge--resubmitted,
.comment-event-badge--issued,
.comment-event-badge--stage_changed { background: var(--status-info-light); color: var(--status-info-dark); }
.comment-event-badge--approved { background: var(--status-success-light); color: var(--status-success-dark); }
.comment-event-badge--conditionally_approved { background: var(--badge-purple-light); color: var(--badge-purple-dark); }
.comment-event-badge--rejected { background: var(--destructive-light); color: var(--destructive-dark); }
.comment-event-badge--revision_requested { background: var(--status-warning-light); color: var(--status-warning-dark); }
/* 다단계 결재의 중간 단계 승인(COLLA-141) — 승인 계열이지만 요청 전체 승인은 아니다.
   같은 색을 주면 타임라인에서 "승인" 과 구분되지 않아 이미 끝난 것으로 읽힌다. */
.comment-event-badge--step_approved { background: var(--surface-2); color: var(--status-success-dark); }
/* 레거시 시스템·라이프사이클 이벤트 — 중립 톤(안내). */
.comment-event-badge--system,
.comment-event-badge--updated,
.comment-event-badge--discontinued,
.comment-event-badge--reactivated,
.comment-event-badge--cancelled,
.comment-event-badge--reopened { background: var(--surface-2); color: var(--text-secondary); }

.comment-approval-type-tag {
  display: inline-flex;
  align-items: center;
  padding: 0.0625rem 0.4375rem;
  border-radius: var(--radius-full);
  background: var(--surface-2);
  color: var(--text-secondary);
  font-size: 0.6875rem;
  font-weight: 600;
  line-height: 1.5;
}

.comment-body.trix-content {
  margin-top: 0.125rem;
  font-size: 0.875rem;
  line-height: 1.8;
  color: var(--text-secondary);
}

/* 옮긴 글이 본문 자리에 설 때(COLLA-239). 원문과 같은 크기·행간으로 둔다 — 무엇을 읽고 있는지는
   위의 한 줄("일본어에서 자동 번역 · 원문 보기")이 말하므로, 글자를 흐리게 하거나 인용 형태로
   들여 쓰면 기본으로 읽을 글이 곁가지처럼 보인다. 평문이라 줄바꿈은 직접 살린다. */
.comment-body--translated {
  margin-top: 0.125rem;
  font-size: 0.875rem;
  line-height: 1.8;
  color: var(--text-secondary);
  white-space: pre-wrap;
}

/* 리치텍스트 콘텐츠 제목 — H1/H2/H3 (read-view). 에디터 내부 스타일은 Lexxy 자체 CSS. */
.trix-content h1 {
  font-size: 1.5rem;
  font-weight: 700;
  line-height: 1.3;
  margin: 0.6rem 0 0.3rem;
  color: var(--text-primary);
}
.trix-content h2 {
  font-size: 1.25rem;
  font-weight: 700;
  line-height: 1.35;
  margin: 0.5rem 0 0.25rem;
  color: var(--text-primary);
}
.trix-content h3 {
  font-size: 1.0625rem;
  font-weight: 600;
  line-height: 1.4;
  margin: 0.4rem 0 0.2rem;
  color: var(--text-primary);
}

/* ── 이미지/첨부 (read-view) ── */
/* 첨부는 자기 줄을 차지(텍스트가 이미지 옆에 흐르지 않게) */
.trix-content action-text-attachment,
.trix-content .attachment--preview {
  display: block;
}

/* 이미지 프레이밍 — 둥근 모서리·경계·은은한 그림자·여백, 비율 유지하며 컨테이너 안에서 캡 */
.trix-content .attachment--preview img {
  display: block;
  max-width: min(440px, 100%);
  max-height: 460px;
  width: auto;
  height: auto;
  border-radius: var(--radius-md);
  border: 1px solid var(--border-subtle);
  box-shadow: var(--shadow-sm, 0 1px 3px rgb(0 0 0 / 6%));
  margin: 0.5rem 0;
}

.trix-content .attachment--preview {
  text-align: left;
}
/* 이미지 캡션(파일명·용량) 숨김 — 사용자가 단 캡션만. 파일 첨부(.attachment--file)는 영향 없음. */
.trix-content .attachment--preview .attachment__caption {
  display: none;
}

/* 영상 첨부(read-view) — 이미지 프레이밍과 동일 톤, 브라우저 기본 컨트롤로 원본 재생(COLLA-104) */
/* 폭을 미디어에 맞춘다 — block 이 본문 전체 폭이면 아래 캡션만 가운데로 떠서 어느 파일의
   설명인지 알 수 없다(actiontext 기본값이 text-align:center 다). 이미지는 캡션을 숨겨서
   드러나지 않았고 영상에서만 보였다. */
.trix-content .attachment--video {
  display: block;
  width: fit-content;
  text-align: left;
}
.trix-content .attachment--video video {
  display: block;
  max-width: min(440px, 100%);
  max-height: 460px;
  border-radius: var(--radius-md);
  border: 1px solid var(--border-subtle);
  margin: 0.5rem 0 0;
}

/* 파일명·용량은 보조 정보다 — 콘텐츠에 붙이고 본문보다 작게. 긴 파일명이 폭을 밀지 않게 끊는다.
   ⚠️ 폭 상한은 **figure 가 아니라 캡션에** 걸어야 한다. figure(.attachment)에 걸면
      actiontext.css 의 `.trix-content action-text-attachment .attachment{max-width:100% !important}`
      (Rails 생성 상용구 — 갤러리 33%/50% 를 무르는 용도)에 밀려 안 먹는다. 캡션은 그 셀렉터
      대상이 아니라 충돌하지 않는다.
      실측(1440, 2026-08-18): 캡션 440px·우변이 영상 우변과 일치·2줄 접힘. figure 박스 자체는
      642px 로 남는다 — Chrome 의 fit-content 는 max-content 산정에서 자식 max-width 로 클램프하지
      않고 캡션의 무절단 한 줄 폭을 쓴다. figure 는 배경·테두리가 없어 **보이는 것은 440 을 넘지
      않고** 레이아웃 밀림·가로 오버플로도 없으므로 그대로 둔다. */
.trix-content .attachment--video .attachment__caption {
  margin: 0.25rem 0 0.5rem;
  max-width: 440px;
  text-align: left;
  font-size: 0.8125rem;
  line-height: 1.4;
  color: var(--text-tertiary);
  overflow-wrap: anywhere;
}

.trix-content a {
  color: var(--cta);
  text-decoration: underline;
}

/* 줄간격 — 기본(1.5)이 좁아 1.8로(설명·코멘트 표시 등). */
.trix-content {
  line-height: 1.8;
}

/* 중첩 목록 — 레벨별 마커 구분 (read-view). */
.trix-content ul {
  list-style: disc;
}
.trix-content ul ul {
  list-style: circle;
}
.trix-content ul ul ul {
  list-style: square;
}
.trix-content ol {
  list-style: decimal;
}

/* 이미지 라이트박스 — 클릭 확대 오버레이(스크림) */
.lightbox-overlay {
  position: fixed;
  inset: 0;
  z-index: 100;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 2rem;
  background: rgb(0 0 0 / 80%);
  cursor: zoom-out;
  animation: lightbox-fade-in 0.18s ease;
}
.lightbox-img {
  max-width: 100%;
  max-height: 100%;
  border-radius: var(--radius-md);
  box-shadow: var(--shadow-lg, 0 10px 40px rgb(0 0 0 / 35%));
  cursor: default;
}
/* 닫기 버튼 — 우상단 고정 */
.lightbox-close {
  position: absolute;
  top: 1rem;
  right: 1rem;
  display: flex;
  align-items: center;
  justify-content: center;
  width: 2.25rem;
  height: 2.25rem;
  border-radius: var(--radius-full);
  background: rgb(255 255 255 / 15%);
  border: 1px solid rgb(255 255 255 / 25%);
  color: #fff;
  cursor: pointer;
  transition: background var(--transition-fast);
}
.lightbox-close:hover,
.lightbox-close:focus-visible {
  background: rgb(255 255 255 / 28%);
  outline: 2px solid rgb(255 255 255 / 60%);
  outline-offset: 2px;
}
/* 독립 썸네일 — data-lightbox-full-url 을 가진 이미지에 zoom 커서 */
[data-lightbox-full-url],
[data-controller~="lightbox"] .attachment--preview img {
  cursor: zoom-in;
}
@keyframes lightbox-fade-in {
  from { opacity: 0; }
  to   { opacity: 1; }
}
@media (prefers-reduced-motion: reduce) {
  .lightbox-overlay { animation: none; }
}

/* 링크 미리보기 카드(unfurl, P3) — 썸네일(좌) + 제목·설명·도메인 */
.link-previews {
  display: flex;
  flex-direction: column;
  gap: 0.5rem;
  margin-top: 0.5rem;
}
.link-preview-card {
  display: flex;
  gap: 0.75rem;
  max-width: 460px;
  border: 1px solid var(--border-default);
  border-radius: var(--radius-md);
  background: var(--surface-0);
  overflow: hidden;
  text-decoration: none;
  color: inherit;
  transition: border-color 0.15s ease, background 0.15s ease;
}
a.link-preview-card:hover {
  border-color: var(--primary);
  background: var(--surface-2);
}
.link-preview-thumb {
  flex: 0 0 96px;
  width: 96px;
  height: 96px;
  background: var(--surface-2);
}
.link-preview-thumb img {
  width: 100%;
  height: 100%;
  object-fit: cover;
}
.link-preview-text {
  display: flex;
  flex-direction: column;
  gap: 0.15rem;
  padding: 0.625rem 0.75rem;
  min-width: 0;
}
.link-preview-title {
  font-weight: 600;
  font-size: 0.875rem;
  color: var(--text-primary);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.link-preview-desc {
  font-size: 0.8125rem;
  color: var(--text-secondary);
  line-height: 1.4;
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
}
.link-preview-domain {
  font-size: 0.75rem;
  color: var(--text-muted);
  margin-top: 0.1rem;
}
/* 로딩 스켈레톤 */
.link-preview-skeleton .link-preview-thumb,
.link-preview-skeleton-line {
  background: var(--surface-2);
  animation: link-preview-pulse 1.2s ease-in-out infinite;
}
.link-preview-skeleton-line {
  height: 0.7rem;
  width: 70%;
  border-radius: var(--radius-sm);
}
.link-preview-skeleton-line.short {
  width: 40%;
}
@keyframes link-preview-pulse {
  50% {
    opacity: 0.5;
  }
}
@media (prefers-reduced-motion: reduce) {
  .link-preview-skeleton .link-preview-thumb,
  .link-preview-skeleton-line {
    animation: none;
  }
}

/* 본문 프레임 — turbo-frame 기본 inline 보정 */
.comment-body-frame {
  display: block;
}

/* 수정됨 표식 — 본문 끝 절제된 캡션. 좌측 마진 없이 본문에 바로 잇닿게. */
.comment-edited {
  font-size: 0.6875rem;
  color: var(--text-muted);
}

/* ── 코멘트 리액션 — 슬랙형 이모지 칩 + 추가 피커 ── */
/* turbo-frame은 기본 inline — 칩이 가로로 wrap되도록 flex 컨테이너로. */
.comment-reactions {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.25rem;
  margin-top: 0.375rem;
}

/* 칩 — 이모지 + 카운트. button_to가 감싸는 form은 inline-flex로(레이아웃 평탄화). */
.comment-reactions form {
  display: inline-flex;
  margin: 0;
}
.reaction-chip {
  display: inline-flex;
  align-items: center;
  gap: 0.25rem;
  /* 44px 터치 타깃 — 칩은 콤팩트하되 클릭 높이 확보 */
  min-height: 1.75rem;
  padding: 0.125rem 0.5rem;
  border: 1px solid var(--border-default);
  /* 라운드렉트(버튼 .btn과 동일 10px) — 완전 원형 대신 일관된 알약/사각 톤(#리액션 UI 통일). */
  border-radius: 10px;
  background: var(--surface-1);
  color: var(--text-secondary);
  font-size: 0.75rem;
  line-height: 1;
  cursor: pointer;
  transition: background var(--transition-fast), border-color var(--transition-fast);
}
.reaction-chip:hover {
  background: var(--surface-2);
  border-color: var(--text-tertiary);
}
.reaction-chip:focus-visible {
  outline: 2px solid var(--primary);
  outline-offset: 2px;
}
/* 내가 누른 이모지 — 강조(테두리·배경). */
.reaction-chip--mine {
  background: var(--surface-0);
  border-color: var(--primary);
  color: var(--text-primary);
  font-weight: 600;
}
.reaction-chip-emoji {
  font-size: 0.9375rem;
  line-height: 1;
}
/* 커스텀 이모지 칩 — 텍스트 이모지 높이(0.9375rem 폰트)에 맞춰 칩 높이 파손 방지. */
.reaction-chip-emoji .custom-emoji {
  height: 1em;
  vertical-align: -0.15em;
}
.reaction-chip-count {
  font-variant-numeric: tabular-nums;
}

/* 누가 눌렀는지(#601) — 칩과 팝오버를 함께 감싸 팝오버를 칩 기준으로 위치. */
.reaction-chip-wrap {
  position: relative;
  display: inline-flex;
}
/* 롱프레스 이름 팝오버 — 칩 위로 뜨는 작은 툴팁. 데스크톱은 title 호버가 대신하므로 터치 전용. */
.reaction-names-popover {
  position: absolute;
  bottom: calc(100% + 6px);
  left: 0;
  z-index: 40;
  width: max-content;
  max-width: min(16rem, calc(100vw - 2rem));
  padding: 0.375rem 0.5rem;
  background: var(--surface-0);
  border: 1px solid var(--border-default);
  border-radius: var(--radius-sm);
  box-shadow: var(--shadow-overlay);
  color: var(--text-secondary);
  font-size: 0.75rem;
  line-height: 1.3;
  white-space: normal;
}
.reaction-names-popover.hidden { display: none; }

/* 추가 — + 리액션 피커. 트리거는 SVG 아이콘(이모지를 컨트롤 아이콘으로 쓰지 않음). */
.reaction-add {
  position: relative;
  display: inline-flex;
}
.reaction-add-trigger {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 1.75rem;
  min-height: 1.75rem;
  padding: 0 0.25rem;
  border: 1px solid var(--border-default);
  /* 라운드렉트(칩·.btn과 동일 10px) — 완전 원형 제거(#리액션 UI 통일). */
  border-radius: 10px;
  background: transparent;
  color: var(--text-tertiary);
  cursor: pointer;
  transition: background var(--transition-fast), color var(--transition-fast), border-color var(--transition-fast);
}
.reaction-add-trigger:hover {
  background: var(--surface-hover);
  color: var(--text-secondary);
  border-color: var(--text-tertiary);
}
.reaction-add-trigger:focus-visible {
  outline: 2px solid var(--primary);
  outline-offset: 2px;
}
/* + 글리프는 face_smile 옆에 살짝 작게 */
.reaction-add-plus {
  margin-left: -0.0625rem;
}

/* 피커 패널 — 빠른 세트(가로 그리드). 트리거 아래로 열림(.hidden 토글). */
.reaction-picker-panel {
  position: absolute;
  top: calc(100% + 6px);
  left: 0;
  z-index: 40;
  display: flex;
  flex-wrap: wrap;
  gap: 0.125rem;
  width: max-content;
  max-width: min(18rem, calc(100vw - 2rem));
  /* 커스텀 이모지 다수 등록 시 패널이 과대해지지 않도록 스크롤로 전환. */
  max-height: 14rem;
  overflow-y: auto;
  padding: 0.375rem;
  background: var(--surface-0);
  border: 1px solid var(--border-default);
  border-radius: var(--radius-md);
  box-shadow: var(--shadow-overlay);
}
.reaction-picker-panel.hidden { display: none; }
.reaction-picker-panel form { display: inline-flex; margin: 0; }
.reaction-picker-cell {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 2.25rem;
  height: 2.25rem;
  padding: 0;
  border: 0;
  border-radius: var(--radius-sm);
  background: transparent;
  font-size: 1.25rem;
  line-height: 1;
  cursor: pointer;
  transition: background var(--transition-fast), transform var(--transition-fast);
}
.reaction-picker-cell:hover {
  background: var(--surface-hover);
  transform: scale(1.12);
}
.reaction-picker-cell:focus-visible {
  outline: 2px solid var(--primary);
  outline-offset: -1px;
}
/* 커스텀 이모지 셀 — 유니코드 텍스트(font-size)와 달리 이미지라 명시 크기 필요. */
.reaction-picker-cell .custom-emoji {
  height: 1.25rem;
}

/* 375 반응형 —
   (1) 패널: 트리거 위치가 칩 개수에 따라 가변이라(좌측 정렬 시 우측 오버플로) 4열로 좁혀(약 10rem)
       트리거가 우측에 있어도 뷰포트 안에. 8개 빠른 세트가 2행으로 wrap.
   (2) 터치 타깃 44px(WCAG 2.5.5) — 데스크톱은 콤팩트(28px) 유지, 모바일에서만 칩·트리거·셀 확대. */
@media (max-width: 28rem) {
  .reaction-picker-panel {
    width: 10rem;
    max-width: calc(100vw - 2rem);
    gap: 0.25rem;
  }
  /* 칩·트리거는 모바일에서도 PC와 같은 크기·형태를 쓴다 — 44px로 키우면 폭(약 50px)과 높이가
     비슷해져 정사각 덩어리로 보인다. 탭 타깃은 아래 패널 셀(2.75rem)이 담당한다. */
  .reaction-picker-cell {
    width: 2.75rem;
    height: 2.75rem;
  }
}

/* 리뷰 액션 스타일은 위 .review-actions 블록으로 일원화(.inline-actions 제거). */
/* 댓글이 하나라도 있으면 빈 상태 문구 숨김(append 후에도 정확 — turbo 불필요) */
#comments:has(.comment) + .comments-empty {
  display: none;
}

/* 코멘트 필터(#523) — 제목 + 우측 토글(전체/시스템만). */
.comments-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 0.75rem;
  flex-wrap: wrap;
}
.comments-filter {
  display: inline-flex;
  gap: 0.25rem;
  background: var(--surface-2);
  border-radius: var(--radius-full);
  padding: 0.125rem;
}
.comments-filter-btn {
  border: 0;
  background: transparent;
  color: var(--text-secondary);
  font-size: 0.8125rem;
  font-weight: 500;
  padding: 0.25rem 0.75rem;
  border-radius: var(--radius-full);
  transition: background-color 0.15s, color 0.15s;
  cursor: pointer;
}
.comments-filter-btn.is-active {
  background: var(--surface-1);
  color: var(--text-primary);
  box-shadow: 0 1px 2px rgba(0, 0, 0, 0.08);
}
/* "시스템만" — 사용자 코멘트 숨김(시스템 이벤트만). Turbo append에도 자동 적용(컨테이너 클래스 기반). */
#comments.comments--system-only .comment:not(.comment--system) {
  display: none;
}

/* "이전 코멘트 더보기"(#532) — 타임라인 상단 중앙 텍스트 버튼(비었으면 여백 없음).
   버튼과 첫 코멘트 아이템이 붙지 않도록 아래 여백 확보(#629). */
#comments-earlier:not(:empty) {
  display: flex;
  justify-content: center;
  margin-bottom: 1.25rem;
}
.comments-earlier-btn {
  background: transparent;
  border: 0;
  color: var(--text-secondary);
  font-size: 0.8125rem;
  font-weight: 500;
  padding: 0.25rem 0.75rem;
  border-radius: var(--radius-full);
  cursor: pointer;
}
.comments-earlier-btn:hover {
  background: var(--surface-2);
  color: var(--text-primary);
}

/* ── Comment composer — Trix를 단일 보더 카드로 결속(툴바 → 입력 → 푸터) ── */
.comment-composer {
  position: relative;
  border: 1px solid var(--border-default);
  border-radius: var(--radius-md);
  background: var(--surface-0);
  transition: border-color 0.15s ease, box-shadow 0.15s ease;
}

/* @멘션 하이라이트 (P3b-3) — 본문 내 @이름 강조 */
.comment-body .mention {
  font-weight: 600;
  color: var(--status-info);
  background: color-mix(in srgb, var(--status-info) 10%, transparent);
  border-radius: var(--radius-sm);
  padding: 0 0.1875rem;
}

/* ── 첨부 편집기 — 기존 첨부 카드(개별 × 제거) + 추가 dropzone. 상품·승인요청 공유 ── */
.attachment-editor { display: flex; flex-direction: column; gap: 0.75rem; }
.attachment-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(9rem, 1fr));
  gap: 0.6rem;
}
.attachment-item { position: relative; }
/* 단일 첨부(아바타·로고·파비콘) — 그리드 없이 혼자 선다.
   ×를 이미지 **위에 겹치지 않는다**: 미리보기가 2~3rem 이라 1.5rem 짜리 ×가 그림을 거의 다
   덮는다(그리드의 9rem 카드에서는 문제가 안 됐다). 옆에 나란히 두어 그림이 그대로 보이게 한다.
   `align-self`·`width` 는 감싼 .form-field 가 flex column 이어서 필요하다 — 없으면 stretch 로
   늘어나 ×가 컨테이너 오른쪽 끝까지 밀린다(실측). */
.attachment-item--inline {
  display: inline-flex;
  align-items: center;
  gap: 0.5rem;
  align-self: flex-start;
  width: fit-content;
}
.attachment-item--inline .attachment-remove-btn { position: static; }
/* "제거 예정"도 겹치지 않는다 — absolute 로 두면 작은 미리보기의 아래쪽을 덮는다. 옆에 세운다. */
.attachment-item--inline .attachment-removing-tag {
  position: static;
  border-radius: var(--radius-full);
  padding: 0.15rem 0.5rem;
}
.attachment-remove-btn {
  position: absolute; top: 0.35rem; right: 0.35rem;
  display: inline-flex; align-items: center; justify-content: center;
  width: 1.5rem; height: 1.5rem; border-radius: var(--radius-full);
  background: var(--surface-0); border: 1px solid var(--border-default);
  color: var(--text-secondary); box-shadow: var(--shadow-subtle);
  cursor: pointer; z-index: 1;
  transition: background 0.15s ease, color 0.15s ease, border-color 0.15s ease;
}
.attachment-remove-btn:hover { background: var(--destructive-light); border-color: var(--destructive-border); color: var(--destructive-dark); }
.attachment-remove-btn svg { width: 0.875rem; height: 0.875rem; }
/* 클릭 영역 전체를 덮는 숨은 체크박스(상태 보유) */
.attachment-remove-check { position: absolute; inset: 0; margin: 0; opacity: 0; cursor: pointer; }
/* 제거 예정 딤 — 미리보기가 무엇이든(파일 카드·아바타·이미지) 회색으로 죽는다. .file-preview
   하나만 잡던 시절에는 아바타·파비콘이 눌러도 그대로였다(단일 첨부를 같은 파셜로 옮기고 발견). */
.attachment-item.is-removing .file-preview,
.attachment-item.is-removing .avatar,
.attachment-item.is-removing .avatar-square,
.attachment-item.is-removing > img { opacity: 0.45; filter: grayscale(1); }
.attachment-item.is-removing .attachment-remove-btn { background: var(--destructive-dark); border-color: var(--destructive-dark); color: #fff; }
.attachment-removing-tag {
  display: none; position: absolute; left: 0; right: 0; bottom: 0;
  text-align: center; font-size: 0.6875rem; font-weight: 600; color: #fff;
  background: var(--destructive-dark); padding: 0.15rem;
  border-radius: 0 0 var(--radius-md) var(--radius-md);
}
.attachment-item.is-removing .attachment-removing-tag { display: block; }

/* 커스텀 이모지 — 본문 `:shortcode:` 치환 이미지. 텍스트 라인에 맞춰 인라인 표시.
   baseline 기준 -0.25em로 앉혀 텍스트와 수직 정렬(Slack/Notion식), 좌우 약간의 여백. */
.custom-emoji {
  display: inline-block;
  height: 1.25em;
  width: auto;
  vertical-align: -0.25em;
  margin: 0 0.05em;
}

/* 이모지 관리 목록의 미리보기 셀 이모지는 더 크게(가독) */
.table .custom-emoji {
  height: 1.75rem;
}

/* 포커스 링은 중립색 — 레드는 CTA/에러 전용 */
.comment-composer:focus-within {
  border-color: var(--primary);
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--primary) 8%, transparent);
}

/* 에디터(lexxy-editor) 내부 스타일은 Lexxy 자체 CSS가 담당.
   단 컴포저 안에서는 lexxy 자체 테두리를 끈다 — .comment-composer가 이미 프레임(1px·radius 8)을 그리는데
   lexxy도 같은 색 1px·radius 10을 겹쳐 그려, 1px 간격의 두 겹 테두리가 모서리에서 서로 물려 보였다.

   ⚠️ 테두리는 끄되 **모서리는 부모를 따라야 한다.** 예전에 `border-radius: 0` 으로 뭉갰더니
      lexxy 의 흰 배경이 사각 모서리로 부모의 곡선 구간을 덮어, **상단 두 모서리에서만 프레임이
      사라져 보였다**(사용자 신고 2026-08-18). 하단은 푸터가 배경을 안 깔아 살아남았고, 그래서
      "곡선 부분만 테두리가 없다" 는 증상이 됐다. 부모는 clip 하지 않는다 — @멘션·서식 드롭다운이
      컴포저 밖으로 나가야 하므로 overflow:hidden 을 걸 수 없다.
      값은 부모 radius 에서 테두리 1px 을 뺀 **안쪽 반지름**이다. */
.comment-composer lexxy-editor {
  border: 0;
  border-radius: calc(var(--radius-md) - 1px) calc(var(--radius-md) - 1px) 0 0;
}

/* 푸터: 얇은 구분선 + 전송 버튼(브랜드 레드 CTA). 빈 회색 띠 인상을 피해 배경은 카드와 동일.
   심사 액션 통합(#637) 시 코멘트 등록(좌) + 결재 버튼 그룹(우), 좁으면 줄바꿈. */
.comment-composer-footer {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  flex-wrap: wrap;
  padding: 0.5rem 0.625rem;
  border-top: 1px solid var(--border-subtle);
}
/* 결재 버튼 그룹 — 코멘트 등록 버튼과 분리(우측), 자체적으로도 줄바꿈. */
.composer-review-actions {
  display: inline-flex;
  flex-wrap: wrap;
  gap: 0.5rem;
  margin-left: auto;
}
/* 증지 교부 수량 — 버튼 사이에 서는 좁은 입력. 기본 .input 은 폭 100%라 푸터를 한 줄 밀어낸다. */
.composer-review-actions .composer-inline-number {
  width: 6rem;
}

.notification-filters {
  display: inline-flex;
  align-items: center;
  gap: 0.25rem;
  padding: 0.25rem;
  border-radius: var(--radius-lg);
  background: var(--surface-1);
}
.notification-filter-btn {
  display: inline-flex;
  align-items: center;
  min-height: 2rem;
  padding: 0 0.75rem;
  border-radius: var(--radius-md);
  color: var(--text-secondary);
  font-size: 0.875rem;
  font-weight: 600;
  text-decoration: none;
}
.notification-filter-btn:hover {
  color: var(--text-primary);
  background: var(--surface-hover);
}
.notification-filter-btn.is-active {
  color: var(--text-primary);
  background: var(--surface-0);
  box-shadow: var(--shadow-sm);
}
/* 모바일(QA) — 코멘트 등록 버튼과 결재 버튼이 margin-left:auto로 좌우 반대편에 떨어져 보이던 문제.
   좁은 화면에선 결재 버튼을 전체폭 한 그룹으로 내려 묶는다(터치 타깃 확보·위치 분리 해소). */
@media (max-width: 40rem) {
  .composer-review-actions { margin-left: 0; width: 100%; }
  /* 위계는 빈도순이다 — 승인·수정 요청이 대부분이고 반려는 드물다. 전엔 `flex: 1 1 auto` + wrap이라
     마지막 버튼(반려)만 둘째 줄에 혼자 남아 100% 폭으로 늘어나 가장 커 보였다(정반대 위계).
     자주 쓰는 둘을 전역 폭으로 올리고, 조건부 승인·반려는 마지막 행에 반씩 나눠 작게 둔다.
     DOM 순서(승인·조건부·수정요청·반려)는 데스크톱 배치 기준이라 order로 재배열한다. */
  .composer-review-actions .review-action { flex: 1 1 calc(50% - 0.25rem); }
  .composer-review-actions .review-action--approve,
  .composer-review-actions .review-action--revision {
    flex-basis: 100%;
    min-height: 2.75rem; /* 터치 타깃(WCAG 2.5.5) — 자주 누르는 둘만 크게 */
    font-size: 0.9375rem;
  }
  .composer-review-actions .review-action--approve { order: 1; }
  .composer-review-actions .review-action--revision { order: 2; }
  .composer-review-actions .review-action--conditional { order: 3; }
  .composer-review-actions .review-action--reject { order: 4; }
  .notification-filters {
    width: 100%;
    overflow-x: auto;
  }
  .notification-filter-btn {
    flex: 0 0 auto;
  }
}

/* "/" 서식 커맨드 메뉴 항목 — 라벨(제목) + 힌트(설명) 2행(#612) */
.editor-slash-item {
  display: flex;
  flex-direction: column;
  gap: 0.0625rem;
}
.editor-slash-item__label {
  font-weight: 500;
  color: var(--text-primary);
}
.editor-slash-item__hint {
  font-size: 0.75rem;
  color: var(--text-tertiary);
}

/* "@" 멘션 드롭다운 항목 — 아바타 + 이름/회사 2행(#627) */
.editor-mention-item {
  display: flex;
  align-items: center;
  gap: 0.5rem;
}
.editor-mention-item__info {
  display: flex;
  flex-direction: column;
  gap: 0.0625rem;
}
.editor-mention-item__name {
  font-weight: 500;
  color: var(--text-primary);
}
.editor-mention-item__company {
  font-size: 0.75rem;
  color: var(--text-tertiary);
}
/* 사용자 그룹 항목 아이콘 — 아바타 자리에 그룹 표식(#679) */
.editor-mention-item__group-icon {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 1.5rem;
  height: 1.5rem;
  border-radius: var(--radius-full);
  background: var(--surface-2);
  color: var(--text-secondary);
}

/* ── Lexxy 에디터 — 앱 디자인 토큰에 매핑(테두리·색·포커스·폰트·라운드 통일) ── */
lexxy-editor {
  --lexxy-color-canvas: var(--surface-0);
  --lexxy-color-text: var(--text-primary);
  --lexxy-color-text-subtle: var(--text-secondary);
  --lexxy-color-ink: var(--text-primary);
  --lexxy-color-ink-medium: var(--text-secondary);
  --lexxy-color-ink-light: var(--text-tertiary);
  --lexxy-color-ink-lighter: var(--border-default);
  --lexxy-color-ink-lightest: var(--surface-1);
  --lexxy-color-link: var(--cta);
  --lexxy-color-accent-dark: var(--primary);
  --lexxy-color-accent-medium: var(--primary);
  --lexxy-color-accent-light: color-mix(in srgb, var(--primary) 14%, transparent);
  --lexxy-color-accent-lightest: color-mix(in srgb, var(--primary) 8%, transparent);
  --lexxy-color-selected: color-mix(in srgb, var(--primary) 12%, transparent);
  --lexxy-color-selected-hover: color-mix(in srgb, var(--primary) 18%, transparent);
  --lexxy-color-selected-dark: var(--primary); /* 선택 강조 — 기본 파랑 제거 */
  --lexxy-color-blue: var(--primary);
  --lexxy-color-code-bg: var(--surface-1);
  --lexxy-focus-ring-color: var(--primary);
  --lexxy-font-base: var(--font-body);
  --lexxy-radius: var(--radius-md);
  --lexxy-shadow: var(--shadow-md, 0 4px 12px rgb(0 0 0 / 10%));
}

/* 툴바 버튼 hover/active — 앱 표면색 */
lexxy-editor .lexxy-editor__toolbar-button:not(:disabled):hover {
  background: var(--surface-hover);
  color: var(--text-primary);
}

/* Placeholder 폭 고정(COLLA-27) — Lexxy 기본값은 offset 없는 position:absolute라 폭이
   배치 컨테이너의 "가용 폭"으로 shrink-to-fit된다. 그 값이 좁게 계산되는 환경(Windows
   전체화면 보고)에서는 글자가 한 자씩 세로로 쌓여 에디터 밖으로 흘러나온다.
   좌우를 에디터 패딩에 못박아 폭 계산에 의존하지 않게 한다(세로 위치는 그대로 static). */
lexxy-editor .lexxy-editor__content::before {
  inset-inline: var(--lexxy-editor-padding);
  inline-size: auto;
}

/* 미리보기 이미지 캡션 입력칸 숨김 — 캡션 미사용(파일 첨부 파일명은 유지). */
lexxy-editor .attachment--preview .attachment__caption {
  display: none;
}

/* 이미지 첨부 테두리 강조 제거 — hover·선택 시 뜨던 outline 박스가 어색(삭제 버튼이 조작 어포던스 담당). */
lexxy-editor .attachment:hover,
lexxy-editor .attachment.node--selected {
  outline: none;
}

/* ── 제품 보드: 뷰 전환 + 읽기전용 칸반/담당자별 ── */
.view-toolbar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 0.75rem;
  flex-wrap: wrap;
  margin-bottom: 1rem;
}
.view-switcher {
  display: inline-flex;
  gap: 0.25rem;
  padding: 0.25rem;
  background: var(--surface-1);
  border-radius: var(--radius-lg);
}
.mine-toggle {
  display: inline-flex;
  align-items: center;
  gap: 0.3125rem;
  padding: 0.3125rem 0.6875rem;
  font-size: 0.8125rem;
  font-weight: 500;
  color: var(--text-secondary);
  background: var(--surface-0);
  border: 1px solid var(--border-default);
  border-radius: var(--radius-md);
  text-decoration: none;
  transition: border-color 0.15s ease, color 0.15s ease, background 0.15s ease;
}
.mine-toggle:hover { color: var(--text-primary); border-color: var(--border-strong); }
.mine-toggle.is-active {
  color: var(--text-primary);
  font-weight: 600;
  background: var(--surface-2);
  border-color: var(--border-strong);
}
.view-switcher-item {
  padding: 0.3125rem 0.75rem;
  font-size: 0.8125rem;
  color: var(--text-secondary);
  border-radius: var(--radius-md);
  text-decoration: none;
}
.view-switcher-item:hover { color: var(--text-primary); }
.view-switcher-item.is-active {
  background: var(--surface-0);
  color: var(--text-primary);
  font-weight: 600;
  box-shadow: 0 1px 2px rgba(0, 0, 0, 0.06);
}

/* 칸반: 가로 스크롤 컬럼(Linear/Notion식) — 투명 컬럼 + 텍스트 우선 컴팩트 카드 */
.kanban {
  display: flex;
  gap: 0.875rem;
  overflow-x: auto;
  padding: 0.25rem 0 0.5rem;
  align-items: flex-start;
  /* 가로 스크롤 어포던스 — 컬럼이 많아 끝의 "단계 추가"까지 스크롤됨을 시각적으로 알림 */
  scrollbar-width: thin;
  scrollbar-color: var(--surface-2) transparent;
}
.kanban::-webkit-scrollbar { height: 0.5rem; }
.kanban::-webkit-scrollbar-thumb { background: var(--surface-2); border-radius: var(--radius-full); }
.kanban::-webkit-scrollbar-track { background: transparent; }
.kanban-column {
  flex: 0 0 17.5rem;
  width: 17.5rem;
  display: flex;
  flex-direction: column;
  /* 컬럼 영역을 카드(흰색)와 구분 — 옅은 배경 밴드 */
  background: var(--surface-1);
  border-radius: var(--radius-lg);
  padding: 0.5rem;
  align-self: flex-start;
}
.kanban-column-head {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  /* 게이트 배지(.kanban-column-gate)가 있는 컬럼만 키 커지는 문제(#450) — min-height로 게이트/비게이트 정렬 고정 */
  min-height: 2.25rem;
  box-sizing: border-box;
  padding: 0.25rem 0.25rem 0.5rem;
  position: sticky;
  top: 0;
  z-index: 2;
  background: var(--surface-1);
}
/* 좌: 점·이름·카운트 배지(이름 옆) / 우: 게이트·추가·메뉴 */
.kanban-column-title {
  display: flex;
  align-items: center;
  gap: 0.375rem;
  flex: 1;
  min-width: 0;
}
.kanban-column-actions {
  display: flex;
  align-items: center;
  gap: 0.125rem;
  flex-shrink: 0;
}
.kanban-column-add {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  /* 터치 타깃 44px(WCAG 2.5.5) — 아이콘은 작게, 탭 영역만 확장 */
  min-width: 2.75rem;
  min-height: 2.75rem;
  border-radius: var(--radius-sm);
  color: var(--text-tertiary);
  opacity: 0;
  transition: opacity 0.15s ease, background 0.15s ease, color 0.15s ease;
}
.kanban-column:hover .kanban-column-add,
.kanban-column-add:focus-visible { opacity: 1; }
.kanban-column-add:hover { background: var(--surface-2); color: var(--text-primary); }
.kanban-column-name {
  flex: 0 1 auto;
  min-width: 0;
  font-size: 0.8125rem;
  font-weight: 600;
  letter-spacing: 0.01em;
  color: var(--text-primary);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.kanban-column-count {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 1.25rem;
  height: 1.25rem;
  padding: 0 0.375rem;
  font-size: 0.6875rem;
  font-weight: 600;
  color: var(--text-secondary);
  background: var(--surface-2);
  border-radius: var(--radius-full);
}
/* 컬럼(단계) 관리 메뉴 트리거 — 상시 노출(발견성·접근성).
   아이콘은 작게, 탭 영역만 44px(WCAG 2.5.5)로 확장. */
.kanban-column-menu {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 2.75rem;
  min-height: 2.75rem;
  border-radius: var(--radius-sm);
  color: var(--text-muted);
  transition: background 0.15s ease, color 0.15s ease;
  cursor: pointer;
}
.kanban-column-menu:hover { background: var(--surface-2); color: var(--text-primary); }

/* 컬럼 추가 — 보드 끝 점선 컬럼 */
.kanban-add-column {
  flex: 0 0 17.5rem;
  width: 17.5rem;
  align-self: flex-start;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 0.375rem;
  min-height: 2.75rem;
  border: 1px dashed var(--border-strong);
  border-radius: var(--radius-lg);
  color: var(--text-muted);
  font-size: 0.8125rem;
  font-weight: 500;
  text-decoration: none;
  transition: border-color 0.15s ease, color 0.15s ease, background 0.15s ease;
}
.kanban-add-column:hover {
  color: var(--text-primary);
  background: var(--surface-1);
}
.kanban-column-gate {
  display: inline-flex;
  align-items: center;
  gap: 0.1875rem;
  font-size: 0.6875rem;
  font-weight: 600;
  color: var(--status-warning-dark);
  background: var(--status-warning-light);
  border-radius: var(--radius-full);
  padding: 0.0625rem 0.4375rem;
}
.kanban-column-body {
  display: flex;
  flex-direction: column;
  gap: 0.5rem;
  min-height: 1.5rem;
  border-radius: var(--radius-md);
  padding: 0.125rem;
  transition: background 0.15s ease, box-shadow 0.15s ease;
}
/* 드래그 중 모든 드롭존을 은은히 표시(컬럼 단위 어포던스) */
.kanban.is-dragging .kanban-column-body {
  background: var(--surface-1);
  box-shadow: inset 0 0 0 1px var(--border-subtle);
}
.kanban-dot {
  width: 0.5rem;
  height: 0.5rem;
  border-radius: var(--radius-full);
  background: var(--text-tertiary);
  flex-shrink: 0;
}
.kanban-dot--not_started { background: var(--text-tertiary); }
.kanban-dot--in_progress { background: var(--status-info); }
.kanban-dot--done { background: var(--status-success); }
.kanban-dot--on_hold { background: var(--status-warning); }

.kanban-card {
  display: flex;
  flex-direction: column;
  gap: 0.4375rem;
  align-items: flex-start;
  background: var(--surface-0);
  border: 1px solid var(--border-subtle);
  border-radius: var(--radius-lg);
  padding: 0.6875rem 0.75rem;
  text-decoration: none;
  cursor: pointer; /* 카드는 div — 클릭 시 상세로(card-open). 드래그 가능 측은 is-grabbable이 grab으로 덮음 */
  box-shadow: 0 1px 2px rgba(24, 24, 27, 0.04);
  transition: border-color 0.15s ease, box-shadow 0.15s ease, transform 0.15s ease;
}
.kanban-card:hover {
  border-color: var(--border-strong);
  box-shadow: 0 4px 12px rgba(24, 24, 27, 0.10);
  transform: translateY(-1px);
}
.kanban-card-name {
  font-size: 0.84375rem;
  font-weight: 550;
  color: var(--text-primary);
  line-height: 1.4;
}
.kanban-empty {
  font-size: 0.75rem;
  color: var(--text-muted);
  padding: 0.625rem 0.5rem;
  text-align: center;
  border: 1px dashed var(--border-default);
  border-radius: var(--radius-md);
}
/* "없음" 플레이스홀더는 항상 DOM에 있고, 컬럼에 카드가 들어오면 숨긴다(#437).
   서버 렌더·드래그·실시간 append/remove 모두 :has로 JS 없이 자동 토글. */
.kanban-column-body:has(.kanban-card) .kanban-empty { display: none; }

/* ── 담당자별 갤러리(B1, Notion 정렬) — 큰 커버 카드 그리드 ── */
.gallery-group { margin-bottom: 1.5rem; }
.gallery-group-head {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  padding: 0.375rem 0.125rem 0.75rem;
}
.gallery-group-name { font-size: 0.875rem; font-weight: 600; color: var(--text-primary); }
.gallery-group-count {
  font-size: 0.75rem;
  font-weight: 600;
  color: var(--text-muted);
}
.gallery-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(15rem, 1fr));
  gap: 0.875rem;
}
.gallery-card {
  display: flex;
  flex-direction: column;
  background: var(--surface-0);
  border: 1px solid var(--border-subtle);
  border-radius: var(--radius-lg);
  overflow: hidden;
  text-decoration: none;
  box-shadow: 0 1px 2px rgba(24, 24, 27, 0.04);
  transition: border-color 0.15s ease, box-shadow 0.15s ease, transform 0.15s ease;
}
.gallery-card:hover {
  border-color: var(--border-strong);
  box-shadow: 0 4px 12px rgba(24, 24, 27, 0.10);
  transform: translateY(-1px);
}
.gallery-cover {
  width: 100%;
  aspect-ratio: 3 / 2;
  object-fit: cover;
  background: var(--surface-2);
  display: block;
}
.gallery-cover-empty {
  display: flex;
  align-items: center;
  justify-content: center;
  color: var(--text-tertiary);
  background: var(--surface-1);
}
.gallery-card-body {
  display: flex;
  flex-direction: column;
  gap: 0.4375rem;
  padding: 0.75rem;
}
.gallery-card-name {
  font-size: 0.875rem;
  font-weight: 600;
  color: var(--text-primary);
  line-height: 1.4;
}

/* ── 공용 제품 칩(상태·담당자·브랜드) — 갤러리/보드 공용 ── */
.product-chip {
  display: inline-flex;
  align-items: center;
  gap: 0.25rem;
  font-size: 0.6875rem;
  font-weight: 600;
  line-height: 1.4;
  padding: 0.125rem 0.5rem;
  border-radius: var(--radius-full);
  background: var(--surface-2);
  color: var(--text-secondary);
  width: fit-content;
  max-width: 100%;
}
.product-chip-row { display: flex; flex-wrap: wrap; gap: 0.25rem; }
.product-chip-status { background: var(--surface-1); }
.product-chip-dot {
  width: 0.5rem;
  height: 0.5rem;
  border-radius: var(--radius-full);
  flex-shrink: 0;
}
.product-chip-person {
  padding: 0;
  white-space: normal;
  background: transparent;
}
.product-chip-person .member-chip-trigger { max-width: 100%; }
.member-display {
  display: inline-flex;
  align-items: center;
  gap: 0.375rem;
  width: fit-content;
  max-width: 100%;
  min-width: 0;
}
.member-chip-surface {
  display: inline-flex;
  max-width: 100%;
  padding: 0.25rem 0.625rem 0.25rem 0.25rem;
  border: 1px solid var(--border-subtle);
  border-radius: var(--radius-full);
  background: var(--surface-0);
}
.member-display-text {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 0.125rem;
  min-width: 0;
}
.member-display-name {
  max-width: 8.5rem;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  color: var(--text-primary);
  font-size: 0.6875rem;
  font-weight: 600;
  line-height: 1.2;
}
.member-display-company {
  max-width: 8.5rem;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  color: var(--text-muted);
  font-size: 0.625rem;
  font-weight: 500;
  line-height: 1.2;
}
.member-chip-trigger .member-chip-surface { max-width: 100%; }
/* 업체(브랜드) 칩 — 담당자(유저) 칩과 시각 구분(#450): 테두리 + 건물 아이콘. */
.product-chip-brand {
  background: transparent;
  color: var(--text-muted);
  border: 1px solid var(--border-default);
  font-weight: 500;
  white-space: nowrap;
}
.product-chip-brand svg { width: 0.75rem; height: 0.75rem; flex-shrink: 0; color: var(--text-muted); }
/* 기타승인 목록 제목 셀 — stretch-link 제목 옆 재제출 버튼(z-index는 .table-linkable 규칙이 처리).
   inline-flex는 셀 폭과 무관하게 콘텐츠 폭으로 자라 좁은 화면에서 버튼이 카드 밖으로 넘쳤다 —
   block flex + wrap으로 셀 폭에 맞추고, 넘치면 버튼이 다음 줄로 내려가게 한다. */
.other-approval-title-cell {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 0.5rem;
  min-width: 0;
}
/* layer 밖 display 규칙이 Tailwind .hidden을 이긴다 — 지금은 JS로 토글되지 않지만 재발 방지 가드. */
.other-approval-title-cell.hidden {
  display: none;
}
/* 상태 칩 색 — semantic token 단일 출처(하드코딩 hex·중복 정의 제거, #일관성감사 B). */
.product-chip-pending { background: var(--status-info-light); color: var(--status-info-dark); }
.product-chip-pending svg { width: 0.6875rem; height: 0.6875rem; flex-shrink: 0; }
/* 다음 게이트 블로커(Phase C 2c) — 전진에 필요한 미충족 승인 유형 */
.product-chip-blocker { background: var(--destructive-light); color: var(--destructive-dark); }
.product-chip-blocker svg { width: 0.75rem; height: 0.75rem; flex-shrink: 0; }
.product-chip-setup { background: var(--status-warning-light); color: var(--status-warning-dark); }
.product-chip-setup svg { width: 0.75rem; height: 0.75rem; flex-shrink: 0; }
/* 게이트 충족(완료) 승인 유형 — 카드에서 "어떤 승인이 끝났는지"를 상태로(#521 R2 개편, 썸네일 대체) */
.product-chip-done { background: var(--status-success-light); color: var(--status-success-dark); }
.product-chip-done svg { width: 0.75rem; height: 0.75rem; flex-shrink: 0; }
/* 칸반 카드 썸네일·관리 코드(#450) */
.kanban-card-thumb {
  width: 100%;
  aspect-ratio: 2 / 1;
  object-fit: cover;
  border-radius: var(--radius-md);
  background: var(--surface-2);
  display: block;
}
.kanban-card-code { padding: 0; }

/* 보유 IP 목록의 대표 이미지 — 캐릭터를 알아보는 것이 목적이라 정사각으로 잘라 세운다. */
/* 상세의 대표 이미지 — 목록 썸네일(2.5rem)과 달리 읽으라고 두는 그림이라 카드 폭 안에서 크게. */
.ip-property-cover {
  max-width: 20rem;
  width: 100%;
  height: auto;
  border-radius: var(--radius-md);
  background: var(--surface-2);
  display: block;
}
.ip-property-thumb {
  width: 2.5rem;
  height: 2.5rem;
  object-fit: cover;
  border-radius: var(--radius-md);
  background: var(--surface-2);
  display: block;
}

/* 전체 표(table) 뷰 */
.product-table-name { font-weight: 550; color: var(--text-primary); text-decoration: none; }
.product-table-name:hover { color: var(--primary); }
.product-table-assignees { display: inline-flex; flex-wrap: wrap; gap: 0.25rem; }

/* 좁은 화면에서 셀이 한 줄을 유지해 표가 컨테이너보다 넓어지고, 감싼 .overflow-x-auto가 가로 스크롤되도록 */
.product-full-table .table-cell { white-space: nowrap; }

/* SortableJS 드래그 상태 */
.kanban-card.is-grabbable { cursor: grab; }
.kanban-card.is-grabbable:active { cursor: grabbing; }
.kanban-card-drag {
  box-shadow: 0 10px 24px rgba(24, 24, 27, 0.18);
  transform: rotate(1.5deg);
  cursor: grabbing;
}
.kanban-card-ghost {
  opacity: 0.4;
  border-style: dashed;
  box-shadow: none;
}
.kanban-card-ghost * { visibility: hidden; }

/* ── 다중 선택(Ui::MultiSelect) ── */
/* native select는 값의 단일 출처로만 남기고 화면에서 감춘다. display:none이면 일부 브라우저가
   폼 전송에서 빼므로 시각적으로만 숨긴다. */
.multi-select-source {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
}
.multi-select-control {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.375rem;
  padding: 0.375rem 0.5rem;
  background-color: var(--surface-0);
  border: 1px solid var(--border-subtle);
  border-radius: var(--radius-md);
}
.multi-select-chips {
  display: flex;
  flex-wrap: wrap;
  gap: 0.25rem;
}
.multi-select-chip {
  display: inline-flex;
  align-items: center;
  gap: 0.25rem;
  padding: 0.125rem 0.25rem 0.125rem 0.5rem;
  font-size: 0.8125rem;
  color: var(--text-primary);
  background-color: var(--surface-1);
  border: 1px solid var(--border-subtle);
  border-radius: var(--radius-full);
}
.multi-select-chip-remove {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 1.125rem;
  height: 1.125rem;
  font-size: 0.875rem;
  line-height: 1;
  color: var(--text-muted);
  background: none;
  border: none;
  border-radius: var(--radius-full);
  transition: all var(--transition-fast);
}
.multi-select-chip-remove:hover { color: var(--text-primary); background-color: var(--surface-2); }
.multi-select-chip-remove:focus-visible { outline: none; box-shadow: var(--shadow-focus-ring); }

/* 순서가 값인 칩(결재선) — 앞의 차례 번호와 위/아래 이동. 이동 버튼은 제거 버튼과 같은 크기·톤이라
   칩 안에서 세 아이콘이 한 줄로 정렬된다. 끝 칩의 이동 버튼은 눌러도 갈 곳이 없어 흐리게 둔다. */
.multi-select-chip-order {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 1.125rem;
  height: 1.125rem;
  font-size: 0.6875rem;
  font-weight: 600;
  font-variant-numeric: tabular-nums;
  color: var(--text-secondary);
  background-color: var(--surface-2);
  border-radius: var(--radius-full);
}
.multi-select-chip-move {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 1.125rem;
  height: 1.125rem;
  font-size: 0.75rem;
  line-height: 1;
  color: var(--text-muted);
  background: none;
  border: none;
  border-radius: var(--radius-full);
  transition: all var(--transition-fast);
}
.multi-select-chip-move:hover:not(:disabled) { color: var(--text-primary); background-color: var(--surface-2); }
.multi-select-chip-move:disabled { opacity: 0.35; cursor: default; }
.multi-select-chip-move:focus-visible { outline: none; box-shadow: var(--shadow-focus-ring); }
/* 이동·제거 버튼은 18px, 인접 간격 4px(중심간 22px)라 WCAG 2.5.8(AA) 간격 예외의 24px에 못 미친다.
   알고 유지한다 — 간격을 8px로 벌려 보니(2026-08-12) 375px 카드에서 담당자 이름이 단어 중간에서
   접혔다. 이 셀이 카드 그리드에서 ~202px만 받는 것이 진짜 원인이라, 간격은 폭 문제의 하위 문제다.
   폭을 먼저 주기 전에는 간격만 손대지 말 것. */
.multi-select-placeholder { margin: 0; }
.multi-select-placeholder[hidden] { display: none; }
.multi-select-picker { position: relative; margin-left: auto; }
.multi-select-toggle {
  padding: 0.125rem 0.5rem;
  font-size: 0.8125rem;
  color: var(--text-muted);
  background: none;
  border: 1px dashed var(--border-default);
  border-radius: var(--radius-full);
  transition: all var(--transition-fast);
}
.multi-select-toggle:hover { color: var(--text-primary); border-color: var(--text-muted); }
.multi-select-toggle:focus-visible { outline: none; box-shadow: var(--shadow-focus-ring); }
.multi-select-menu {
  position: absolute;
  right: 0;
  z-index: var(--z-anchored-menu);
  display: flex;
  flex-direction: column;
  gap: 0.125rem;
  min-width: 12rem;
  max-height: 14rem;
  margin-top: 0.25rem;
  padding: 0.375rem;
  overflow-y: auto;
  background-color: var(--surface-0);
  border: 1px solid var(--border-default);
  border-radius: var(--radius-md);
  box-shadow: var(--shadow-md);
}
/* Tailwind .hidden과 달리 hidden 속성은 위 display:flex에 눌린다 — 명시 가드. */
.multi-select-menu[hidden] { display: none; }
.multi-select-option {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  padding: 0.25rem 0.375rem;
  font-size: 0.8125rem;
  border-radius: var(--radius-sm);
}
.multi-select-option:hover { background-color: var(--surface-1); }

/* 표 아래 "행 추가" 버튼 — 표와 붙지 않게 간격만 준다. */
.table-add-row { padding-top: 0.75rem; }

/* 승인 방식 섹션 머리말 — 제목과 설명을 붙여 한 덩어리로 읽히게. */
.approval-section-header { display: flex; flex-direction: column; gap: 0.125rem; }


/* ── 행 순서 드래그(row-sort) ── */
/* 순서를 숫자로 받지 않고 끌어다 놓는다. 손잡이만 잡히게 해 입력칸 조작이 드래그로 오인되지 않게. */
.row-sort-handle {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  cursor: grab;
  color: var(--text-muted);
  padding: 0.25rem;
  border-radius: var(--radius-sm);
}
.row-sort-handle:hover { color: var(--text-default); background-color: var(--surface-1); }
.row-sort-handle:active { cursor: grabbing; }
/* 끌고 있는 자리 표시 — 어디에 놓이는지 보이게. */
.row-sort-ghost { opacity: 0.4; }
.row-sort-ghost > * { visibility: hidden; }

/* ── 삭제 예정 행(row-removal) ── */
/* 저장 전까지는 되돌릴 수 있는 상태 — 색이 유일한 신호가 되지 않도록 버튼 문구도 함께 바뀐다. */
.is-pending-removal .input,
.is-pending-removal .select,
.is-pending-removal .multi-select-control {
  opacity: 0.45;
  text-decoration: line-through;
}
/* 되돌리는 버튼까지 흐려지면 취소 경로가 안 보인다 — 삭제 취소는 또렷하게 남긴다. */
.is-pending-removal .btn { opacity: 1; }

/* ── 워크플로우(단계) 편집 (P0b) ── */
/* 템플릿 이름·기본 여부 — 표 위의 한 줄. 이름 칸이 페이지 폭을 다 먹으면 아래 표의 좁은
   입력들과 어긋나 "여기가 본문"으로 읽히고, 기본 여부 배지는 폭을 채워 옵션처럼 보인다. */
.template-identity {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-end;
  gap: 0.75rem;
}
.template-identity > .form-field {
  flex: 0 1 20rem;
  min-width: 12rem;
  margin-bottom: 0;
}
/* 배지·체크박스는 이름 칸 옆에 붙는다 — 폭을 차지하지 않는다. */
.template-identity > .badge,
.template-identity > .form-check {
  flex: 0 0 auto;
  margin-bottom: 0.5rem;
}

.stage-edit-row {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-end;
  gap: 0.5rem;
  padding: 0.5rem 0;
  border-bottom: 1px solid var(--border-subtle);
}
/* 페이지 단위 저장 폼의 행 입력도 기존 행별 폼과 동일한 폭·정렬을 사용한다. */
.stage-edit-row > .input,
.stage-edit-row > .select { margin: 0; }
.stage-edit-row > .input:first-of-type { flex: 1 1 12rem; }
.stage-edit-row > .stage-name-field { flex: 1 1 12rem; min-width: 12rem; }
.stage-edit-row > .select[multiple] { flex: 1 1 14rem; min-height: 2.5rem; }
.stage-edit-row > .approver-select { flex: 1 1 18rem; height: 3rem; min-height: 3rem; max-height: 3rem; overflow-y: auto; }
.stage-edit-row > .stage-position { flex: 0 0 4.5rem; }
.stage-edit-row > input[type="color"] { flex: 0 0 3rem; padding: 0.15rem; }
/* 단계 편집기 열 머리글(a11y·가독) — 행 입력과 같은 flex 폭 규칙으로 정렬, 행이 줄바꿈되는 좁은 화면에선 숨김. */
.stage-edit-column-labels {
  display: flex;
  gap: 0.5rem;
  padding: 0.5rem 0 0;
  color: var(--text-muted);
  font-size: 0.75rem;
  font-weight: 600;
}
.stage-edit-column-labels > .stage-col-name { flex: 1 1 12rem; }
.stage-edit-column-labels > .stage-col-color { flex: 0 0 3rem; }
.stage-edit-column-labels > .stage-col-position { flex: 0 0 4.5rem; }
.stage-edit-column-labels > .stage-col-forward { flex: 1 1 14rem; }
@media (max-width: 900px) {
  .stage-edit-column-labels { display: none; }
}
.approval-type-edit-row {
  display: grid;
  grid-template-columns: minmax(16rem, 1fr) 14rem 3rem 4.5rem auto minmax(14rem, 20rem);
  align-items: center;
  gap: 0.625rem;
}
.approval-type-column-labels {
  display: grid;
  grid-template-columns: minmax(16rem, 1fr) 14rem 3rem 4.5rem auto minmax(14rem, 20rem);
  gap: 0.625rem;
  color: var(--text-muted);
  font-size: 0.75rem;
  font-weight: 600;
  padding: 0 0.25rem;
}
.approval-type-edit-row > .stage-name-field { min-width: 0; width: 100%; }
.approval-type-edit-row > .select { width: 100%; min-width: 0; }
.approval-type-edit-row > .approver-select { width: 100%; max-width: 20rem; height: 2.75rem; min-height: 2.75rem; }
.table .approver-select { width: 18rem; max-width: 18rem; height: 2.5rem; min-height: 2.5rem; }
@media (max-width: 900px) {
  .table .approver-select { width: 100%; max-width: none; }
}

/* 담당자 일괄 적용 바 — 선택한 담당자를 모든 승인유형 행에 한 번에 추가. */
.bulk-approver-bar {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.75rem;
  padding: 0.75rem 1rem;
  border: 1px solid var(--border-subtle);
  border-radius: var(--radius-md);
  background: var(--surface-1);
}
.bulk-approver-bar .select { width: auto; min-width: 12rem; }
.bulk-approver-status { color: var(--text-secondary); }
.bulk-approver-applied { animation: bulk-approver-flash 0.9s ease; }
@keyframes bulk-approver-flash {
  from { background: var(--status-info-light); }
  to { background: transparent; }
}
@media (max-width: 900px) {
  .approval-type-column-labels { grid-template-columns: minmax(12rem, 1fr) 12rem 3rem 4rem auto; }
  .approval-type-column-labels span:last-child { grid-column: 1 / -1; }
  .approval-type-edit-row { grid-template-columns: minmax(12rem, 1fr) 12rem 3rem 4rem auto; }
  .approval-type-edit-row > .approver-select { grid-column: 1 / -1; max-width: none; }
}
@media (max-width: 560px) {
  .approval-type-column-labels { display: none; }
  .approval-type-edit-row { grid-template-columns: 1fr 1fr; }
  .approval-type-edit-row > .stage-name-field { grid-column: 1 / -1; }
  .approval-type-edit-row > .approver-select { grid-column: 1 / -1; }
}
/* 보관(soft delete)된 단계 — 비활성 회색 행 + "보관됨" 배지(삭제됨을 명확히). */
.stage-archived-section { margin-top: 0.75rem; }
.stage-archived-section > .caption-text { display: block; margin-bottom: 0.375rem; color: var(--text-secondary); font-weight: 600; }
.stage-archived-row { align-items: center; opacity: 0.6; }
.stage-archived-name { font-weight: 600; color: var(--text-secondary); text-decoration: line-through; }
/* 단계 1건 = 한 줄 인라인(이름·분류·색상·승인토글·저장). 좁으면 wrap. */
.stage-edit-form {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.625rem;
  flex: 1 1 auto;
}
/* 이름 입력만 늘어나고 나머지는 내용폭 — 한 줄을 꽉 채움 */
.stage-edit-form .form-field:first-child { flex: 1 1 12rem; margin: 0; }
.stage-edit-form .form-field { margin: 0; }
.stage-save-btn { margin-left: auto; }

/* 단계별 요구 승인 유형(Phase C 2c) — 게이트형 유형 체크박스 칩 그룹 */
.stage-required-types, .stage-transition-targets { border: 0; padding: 0; margin: 0; display: flex; flex-wrap: wrap; align-items: center; gap: 0.375rem; flex: 1 1 100%; }
.stage-required-types legend, .stage-transition-targets legend { width: 100%; margin-bottom: 0.25rem; padding: 0; }
.stage-required-type-option {
  display: inline-flex; align-items: center; gap: 0.25rem;
  padding: 0.125rem 0.5rem; border: 1px solid var(--border-default);
  border-radius: var(--radius-full, 999px); font-size: 0.75rem; color: var(--text-secondary); cursor: pointer;
}
.stage-required-type-input:checked + span { font-weight: 600; color: var(--text-primary); }
.stage-row-actions {
  display: flex;
  align-items: center;
  gap: 0.25rem;
}

/* 단계 컬러 — 현재 색 트리거(드롭다운으로 팔레트 열기) */
.stage-color-trigger {
  display: inline-flex;
  align-items: center;
  gap: 0.25rem;
  padding: 0.25rem 0.375rem;
  border: 1px solid var(--border-default);
  border-radius: var(--radius-md);
  background: var(--surface-0);
  color: var(--text-muted);
  cursor: pointer;
}
.stage-color-trigger:hover { background: var(--surface-1); }
.stage-color-current {
  width: 1.25rem;
  height: 1.25rem;
  border-radius: var(--radius-full);
  background: var(--swatch);
  box-shadow: 0 0 0 1px var(--border-subtle);
}
/* 프리셋 팔레트 — 드롭다운 메뉴 안 그리드 */
.stage-color-picker .dropdown-menu .stage-swatches {
  display: grid;
  grid-template-columns: repeat(6, 1.5rem);
  gap: 0.375rem;
  padding: 0.25rem;
}
.stage-swatch {
  width: 1.5rem;
  height: 1.5rem;
  border-radius: var(--radius-full);
  background: var(--swatch);
  border: 2px solid transparent;
  box-shadow: 0 0 0 1px var(--border-subtle);
  cursor: pointer;
  padding: 0;
  transition: transform 0.1s ease, box-shadow 0.1s ease;
}
.stage-swatch:hover { transform: scale(1.12); }
.stage-swatch.is-selected {
  border-color: var(--surface-0);
  box-shadow: 0 0 0 2px var(--text-primary);
}
.stage-swatch:focus-visible {
  outline: 2px solid var(--primary);
  outline-offset: 2px;
}
/* 입력 하나 + 제출 버튼짜리 인라인 추가 폼. 필드 margin을 죽이고 간격은 gap이 전담한다 —
   margin만 0으로 두면 버튼이 입력에 붙어 버린다. */
.stage-add-form {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 0.75rem;
}
.stage-add-form .form-field { margin: 0; width: 100%; }
/* 목록 하단 "단계 추가" 트리거 버튼 — 마지막 단계 행과 간격을 둔다. */
.stage-add-action {
  margin-top: 0.75rem;
}
/* 터치 타깃 44px(WCAG 2.5.5) */
.stage-add-trigger {
  min-height: 2.75rem;
}

/* ── 진행 단계 — Notion식 명시 상태 칩(#419) ──
 * 현재 단계를 "상태 프로퍼티" 칩으로 보여주고, 클릭하면 이동 가능한 단계 목록을 연다.
 * 칩 자체가 상태 표시이므로 카테고리(진행중 등)는 칩 안 보조 라벨로 demote —
 * 단계의 진행상태로 오인되던 배지를 제거(#419-3). dropdown_controller(.dropdown-menu) 재사용. */
.status-select-trigger {
  display: inline-flex;
  align-items: center;
  gap: 0.5rem;
  align-self: flex-start;
  max-width: 100%;
  padding: 0.375rem 0.625rem;
  border: 1px solid var(--border-default);
  border-radius: var(--radius-full);
  background: var(--surface-0);
  color: var(--text-primary);
  font-size: 0.875rem;
  font-weight: 500;
  line-height: 1.25rem;
  cursor: pointer;
  transition: background-color var(--transition-fast), border-color var(--transition-fast);
}
.status-select-trigger:hover {
  background: var(--surface-hover);
  border-color: var(--surface-2);
}
.status-select-trigger:focus-visible {
  outline: 2px solid var(--primary);
  outline-offset: 2px;
}
/* 변경 불가(권한 없음·승인 대기·옵션 없음) — 클릭 어포던스 없이 정적 표시 */
.status-select-trigger-static {
  cursor: default;
}
.status-select-trigger-static:hover {
  background: var(--surface-0);
  border-color: var(--border-default);
}
/* 단계 컬러 점 — 칩·메뉴 옵션·타임라인이 공유하는 시각 코드 */
.status-select-dot {
  width: 0.625rem;
  height: 0.625rem;
  border-radius: var(--radius-full);
  flex-shrink: 0;
  box-shadow: 0 0 0 1px rgba(0, 0, 0, 0.06);
}
.status-select-name {
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
/* 칩 셰브론은 끝에 붙이고 옅게 */
.status-select-trigger svg {
  color: var(--text-tertiary);
  flex-shrink: 0;
}
/* 메뉴 헤더 — "단계 이동" 안내 라벨(메뉴 첫 줄) */
.status-select-menu-label {
  padding: 0.25rem 0.625rem 0.375rem;
  font-size: 0.6875rem;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  color: var(--text-muted);
}

/* 단계 변경 이력 타임라인 CSS는 코멘트 시스템 메시지 통합(#523)으로 제거 — 이력은 코멘트 카드로 렌더. */
.inline-form { display: inline-block; }

/* ── Emoji Picker (상품 이모지 — Notion 스타일) ──────────────────────────
   트리거(현재 이모지/중립 SVG) + 패널(검색·카테고리·그리드·직접입력).
   디자인 토큰 사용, 터치 타깃 44px, 라이트 모드 B2B 대비. */
.emoji-picker {
  position: relative;
  display: block;
}
.emoji-picker-control {
  display: inline-flex;
  align-items: center;
  gap: 0.375rem;
}
/* 트리거 — 현재 선택 이모지(또는 빈 상태 SVG)를 보여주는 버튼 */
.emoji-picker-trigger {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 2.75rem;
  height: 2.75rem;
  padding: 0;
  border: 1px solid var(--border-default);
  border-radius: var(--radius-md);
  background: var(--surface-0);
  color: var(--text-tertiary);
  transition: background var(--transition-fast), border-color var(--transition-fast);
  cursor: pointer;
}
.emoji-picker-trigger:hover {
  background: var(--surface-hover);
  border-color: var(--border-default);
}
.emoji-picker-trigger:focus-visible {
  outline: 2px solid var(--primary);
  outline-offset: 2px;
}
.emoji-picker-trigger-glyph {
  font-size: 1.5rem;
  line-height: 1;
}
.emoji-picker-trigger-placeholder {
  display: inline-flex;
  color: var(--text-tertiary);
}
/* 언레이어 컴포넌트 클래스가 Tailwind .hidden(display:none)을 캐스케이드로 눌러
   항상 보이던 버그 회피 — 토글 대상에 명시적 .hidden 가드(.dropdown-menu와 동일 패턴). */
.emoji-picker-trigger-glyph.hidden,
.emoji-picker-trigger-placeholder.hidden,
.emoji-picker-clear.hidden,
.emoji-picker-quick.hidden,
.emoji-picker-empty.hidden { display: none; }
/* 비우기 — 선택된 이모지가 있을 때만 노출되는 아이콘 버튼 */
.emoji-picker-clear {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 2.75rem;
  min-height: 2.75rem;
  padding: 0;
  border: 0;
  border-radius: var(--radius-md);
  background: transparent;
  color: var(--text-muted);
  transition: background var(--transition-fast), color var(--transition-fast);
  cursor: pointer;
}
.emoji-picker-clear:hover {
  background: var(--surface-hover);
  color: var(--text-primary);
}
.emoji-picker-clear:focus-visible {
  outline: 2px solid var(--primary);
  outline-offset: 2px;
}

/* 패널 — 트리거 아래로 열리는 드롭다운(카드형). display는 .hidden 토글로 제어. */
.emoji-picker-panel {
  position: absolute;
  top: calc(100% + 6px);
  left: 0;
  z-index: 40;
  display: flex;
  flex-direction: column;
  width: 22rem;
  max-width: calc(100vw - 2rem);
  background: var(--surface-0);
  border: 1px solid var(--border-default);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-overlay);
  padding: 0.75rem;
  gap: 0.625rem;
}
.emoji-picker-panel.hidden { display: none; }

.emoji-picker-search .search-input { width: 100%; }

/* 카테고리 바로가기 — 각 카테고리 대표 이모지로 점프(이모지 피커 관용 패턴) */
/* 자주 쓰는(빠른선택) 줄 — 그리드와 동일한 .emoji-picker-cell을 써 '클릭=적용'임이 분명하게 보이고,
   그리드와 구분되도록 아래 경계선. (이전 카테고리 점프 nav의 "이동 전용인데 선택처럼 보임" 혼동 제거) */
.emoji-picker-quick {
  padding-bottom: 0.5rem;
  margin-bottom: 0.25rem;
  border-bottom: 1px solid var(--border-subtle);
}

/* 그리드 — 스크롤 영역. 카테고리 섹션별 제목 + 이모지 셀. */
.emoji-picker-grid {
  overflow-y: auto;
  max-height: 14rem;
  /* abs 자식(없음) 대비 + 내부 스크롤 격리 */
  position: relative;
}
.emoji-picker-section + .emoji-picker-section { margin-top: 0.5rem; }
.emoji-picker-section-title {
  position: sticky;
  top: 0;
  z-index: 1;
  margin: 0 0 0.25rem;
  padding: 0.125rem 0.25rem;
  font-size: 0.6875rem;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  color: var(--text-muted);
  background: var(--surface-0);
}
.emoji-picker-section-grid {
  display: grid;
  grid-template-columns: repeat(8, 1fr);
  gap: 0.125rem;
}
.emoji-picker-cell {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  aspect-ratio: 1 / 1;
  width: 100%;
  padding: 0;
  border: 0;
  border-radius: var(--radius-sm);
  background: transparent;
  font-size: 1.25rem;
  line-height: 1;
  cursor: pointer;
  transition: background var(--transition-fast), transform var(--transition-fast);
}
.emoji-picker-cell:hover {
  background: var(--surface-hover);
  transform: scale(1.12);
}
.emoji-picker-cell:focus-visible {
  outline: 2px solid var(--primary);
  outline-offset: -1px;
}
.emoji-picker-empty {
  padding: 1.25rem 0.5rem;
  text-align: center;
  font-size: 0.8125rem;
  color: var(--text-muted);
}

/* 직접 입력 — 임의 이모지/문자를 붙여넣어 사용(string 컬럼이므로 커스텀 = 임의 문자). */
.emoji-picker-custom {
  display: flex;
  flex-direction: column;
  gap: 0.375rem;
  padding-top: 0.625rem;
  border-top: 1px solid var(--border-subtle);
}
.emoji-picker-custom-label {
  font-size: 0.75rem;
  font-weight: 500;
  color: var(--text-secondary);
}
.emoji-picker-custom-row {
  display: flex;
  align-items: center;
  gap: 0.375rem;
}
.emoji-picker-custom-input {
  flex: 1 1 auto;
  width: auto;
}

/* 좁은 화면(375) — 패널을 트리거 폭에 가두지 않고 화면 폭에 맞춤 */
@media (max-width: 28rem) {
  .emoji-picker-panel { width: calc(100vw - 2rem); }
  .emoji-picker-section-grid { grid-template-columns: repeat(7, 1fr); }
}

/* ── 상품 상세 — 노션 문서형(제목 → 속성 목록 → 본문 → 섹션) ──
 * 카드 박스 없이 한 문서처럼. 속성은 key(라벨)→value 행. 토큰만 사용. */
.product-doc { max-width: 56rem; }
.product-doc-head {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 1rem;
  margin: 0.25rem 0 1.25rem;
}
.product-doc-title {
  display: flex;
  align-items: center;
  gap: 0.625rem;
  min-width: 0;
  margin: 0;
  font-size: 1.75rem;
  font-weight: 700;
  line-height: 1.2;
  color: var(--text-primary);
}
.product-doc-emoji { font-size: 1.75rem; line-height: 1; flex-shrink: 0; }
.product-doc-name { min-width: 0; word-break: break-word; }
.product-doc-actions { display: flex; gap: 0.5rem; flex-shrink: 0; }
.product-doc-menu-button { color: var(--text-primary); border-color: var(--border-default); }

/* 속성 목록 — 각 행: 라벨(고정폭, 약하게) + 값 */
.product-props { display: flex; flex-direction: column; gap: 0.0625rem; margin: 0; }
.product-prop {
  display: flex;
  align-items: flex-start;
  gap: 0.75rem;
  min-height: 2.25rem;
  padding: 0.1875rem 0;
}
/* 라벨은 값보다 확실히 작고 옅게 — 13/14px + 색만으로는 위계가 서지 않아 라벨과 값이
   한 덩어리로 읽혔다. 라벨 12px, 값 15px·중간 굵기로 벌린다. */
.product-prop-label {
  flex: 0 0 8rem;
  padding-top: 0.4375rem;
  font-size: 0.75rem;
  font-weight: 500;
  color: var(--text-muted);
}
.product-prop-value {
  flex: 1 1 auto;
  min-width: 0;
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.375rem;
  padding-top: 0.1875rem;
  font-size: 0.9375rem;
  font-weight: 500;
  color: var(--text-primary);
}
.product-prop-value-block { flex-direction: column; align-items: flex-start; gap: 0.5rem; }
.product-prop-empty { color: var(--text-muted); }
.product-prop-link {
  color: var(--text-primary);
  text-decoration: none;
  border-bottom: 1px solid currentColor;
}
.product-prop-link:hover { color: var(--primary); border-color: var(--primary); }
.product-prop-link:focus-visible {
  outline: 2px solid var(--primary);
  outline-offset: 2px;
}
/* 담당자 칩의 × 제거 버튼 — 칩 안에 들어가는 미니 버튼(button_to 폼은 inline-form으로 흐름 유지) */
.product-chip-remove {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  margin-left: 0.0625rem;
  padding: 0;
  border: 0;
  background: transparent;
  color: var(--text-tertiary);
  line-height: 0;
  cursor: pointer;
}
.product-chip-remove:hover { color: var(--text-secondary); }
/* 슬롯 세팅 패널(#589) — 단계별 슬롯 목록 */
/* 카드화(COLLA-41) — 위 정보 카드와 리듬을 맞추기 위해 다음 .product-doc-section과 같은 상단 여백 */
.slot-setup-section { margin-top: 2rem; }
.slot-setup-list { display: flex; flex-direction: column; gap: 0.5rem; margin-bottom: 0.75rem; }
.slot-setup-stage { display: flex; flex-direction: column; gap: 0.25rem; }
.slot-setup-stage-name { font-weight: 500; color: var(--text-secondary); }
.slot-setup-chips { display: flex; flex-wrap: wrap; gap: 0.25rem; }
/* 단계별 승인 설정 모달 — 단계 리스트 + 승인 유형 체크박스 격자 */
.slot-editor { display: flex; flex-direction: column; gap: 0.75rem; margin-top: 0.75rem; }
.slot-editor-stage { display: flex; flex-direction: column; gap: 0.375rem; padding-bottom: 0.75rem; border-bottom: 1px solid var(--border-subtle); }
.slot-editor-stage-name { font-weight: 600; color: var(--text-primary); }
.slot-editor-types { display: flex; flex-wrap: wrap; gap: 0.5rem 1rem; }
.slot-editor-check { display: inline-flex; align-items: center; gap: 0.375rem; cursor: pointer; color: var(--text-secondary); }
.slot-editor-check input[disabled] { cursor: not-allowed; }
.slot-editor-check:has(input[disabled]) { color: var(--text-tertiary); cursor: not-allowed; }
.slot-editor-actions { display: flex; justify-content: flex-end; margin-top: 0.25rem; }
/* 역할별 담당자 그룹(영업/기획/생산/미지정) — 그룹마다 한 줄, 라벨 + 칩 */
.product-prop-assignees { flex-direction: column; align-items: flex-start; gap: 0.5rem; }
.assignee-role-group { display: flex; flex-wrap: wrap; align-items: center; gap: 0.375rem; }
.assignee-role-label {
  flex: 0 0 auto;
  min-width: 2.75rem;
  font-size: 0.75rem;
  font-weight: 600;
  color: var(--text-tertiary);
}

/* 인라인 담당자 추가(셀렉트 + 버튼) */
.product-prop-add { display: flex; align-items: center; gap: 0.375rem; }
.product-prop-add .form-field { margin: 0; }

.product-doc-divider { border: 0; border-top: 1px solid var(--border-subtle); margin: 1.25rem 0; }
.product-doc-body { margin-bottom: 0.25rem; }
/* 옮긴 글이 설명 자리에 설 때(COLLA-240). 원문(리치텍스트)과 같은 자리·같은 크기로 둔다 —
   무엇을 읽고 있는지는 아래 한 줄이 말한다. 평문이라 줄바꿈은 직접 살린다. */
.product-doc-body--translated { white-space: pre-wrap; }
/* 섹션 구분 강화 — 각 섹션을 상단 디바이더 + 넉넉한 간격으로 명확히 분리, 타이틀도 강조.
   좌우 패딩은 카드 내용 좌변(카드 보더 1px + .card-content 패딩)과 같은 값 — 같은 화면에서
   카드 섹션과 구분선 섹션의 내용 시작점이 달라 블록마다 들쭉날쭉했다(COLLA-44).
   디바이더는 패딩 밖(보더 박스)이라 카드 폭과 같은 전폭으로 남는다. */
.product-doc-section {
  margin-top: 2rem;
  padding: 1.75rem calc(1.5rem + 1px) 0;
  border-top: 1px solid var(--border-default);
}
/* 내용이 카드 그 자체인 섹션(활동 이력)은 카드가 자기 패딩을 갖는다 — 여기에 또 패딩을 주면
   카드 보더만 안쪽으로 밀려 위 카드들과 좌변이 어긋난다. 글자 좌변은 어차피 같아진다. */
.product-doc-section:has(> .card) { padding-left: 0; padding-right: 0; }
.product-doc-section > .section-title,
.product-doc-section > .section-head-row > .section-title { font-size: 1.0625rem; font-weight: 700; }

/* 좁은 화면(<=640) — 라벨/값 세로 스택, 액션 줄바꿈 */
@media (max-width: 40rem) {
  .product-doc-head {
    display: grid;
    grid-template-columns: minmax(0, 1fr) 44px;
    align-items: center;
    gap: 0.75rem;
  }
  .product-doc-actions { grid-column: 2; align-self: center; }
  .product-doc-menu-button { width: 44px; height: 44px; padding: 0; }
  /* 좁은 화면의 .card-content 패딩(1rem)에 맞춰 좌변을 다시 정렬 */
  .product-doc-section { padding-left: calc(1rem + 1px); padding-right: calc(1rem + 1px); }
  /* 세로 스택에선 짝(라벨-값)을 붙이고 행 사이를 벌려야 짝이 읽힌다 — 둘 다 1px 간격이면
     어느 값이 위 라벨의 것인지 아래 라벨의 것인지 알 수 없다. */
  .product-props { gap: 0.75rem; }
  .product-prop { flex-direction: column; gap: 0.125rem; min-height: 0; padding: 0; }
  .product-prop-label { flex-basis: auto; padding-top: 0; }
  .product-prop-value { padding-top: 0; }
}

/* 관리 코드 태그 — 목록·상세에서 사용자 입력 식별자를 모노스페이스 배지로 */
/* 관리 코드 — 배경 없는 모노스페이스 라벨(#450, 시각 잡음 제거) */
.product-code-tag,
.item-code-tag {
  display: inline-flex;
  align-items: center;
  color: var(--text-secondary);
  font-size: 0.75rem;
  font-family: ui-monospace, "SF Mono", Menlo, monospace;
  white-space: nowrap;
}

/* 코드 + 클립보드 복사 버튼 — code_tag_with_copy 단일 출처. 표·카드·상세 공용 */
/* 이벤트가 열다섯 개라 한 줄씩 쌓으면 폼이 화면을 넘긴다. 이름만 있고 규칙이 없었다. */
.webhook-events-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(14rem, 1fr));
  gap: 0.5rem;
}

/* 회사별 묶음 사이 간격 — 자식(head·name)은 스타일이 있는데 묶는 쪽만 없었다. */
.member-add-company + .member-add-company {
  margin-top: 0.75rem;
}

.code-tag {
  display: inline-flex;
  align-items: center;
  gap: 0.25rem;
}

.code-copy-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  padding: 0.1875rem;
  border: 0;
  background: transparent;
  border-radius: var(--radius-sm);
  color: var(--text-tertiary);
  cursor: pointer;
  transition: color 150ms ease, background-color 150ms ease;
  /* 모바일 table-linkable 카드의 stretch-link 오버레이(z-index:1) 위로 올려 탭 가능하게 */
  position: relative;
  z-index: 2;
}
.code-copy-btn:hover {
  color: var(--text-secondary);
  background: var(--surface-hover);
}
.code-copy-btn:focus-visible {
  outline: 2px solid var(--focus-ring, var(--text-tertiary));
  outline-offset: 1px;
}

/* 복사 성공 피드백 — 클립보드 아이콘 → 체크(성공색). 레이아웃 이동 없음 */
.code-copy-icon-done { display: none; }
.code-tag.is-copied .code-copy-icon-default { display: none; }
.code-tag.is-copied .code-copy-icon-done { display: inline-flex; }
.code-tag.is-copied .code-copy-btn { color: var(--status-success-dark); }

@media (prefers-reduced-motion: reduce) {
  .code-copy-btn { transition: none; }
}

/* 관리 코드 실시간 중복 체크 피드백(#449) — slug-feedback와 동일 상태 색 규약(ok/error/pending) */
.code-feedback {
  min-height: 1.25rem;
  margin-top: 0.375rem;
  font-size: 0.8125rem;
  color: var(--text-secondary);
}
.code-feedback[data-status="ok"] { color: var(--status-success-dark); }
.code-feedback[data-status="error"] { color: var(--destructive); }
.code-feedback[data-status="pending"] { color: var(--text-muted); }

/* 카테고리 다중(태그) 선택 — 폼의 체크박스 그룹(#449). 칩처럼 가로 흐름, 다중 선택. */
.category-tag-group {
  display: flex;
  flex-wrap: wrap;
  gap: 0.375rem;
  margin: 0;
  padding: 0;
  border: 0;
}
/* fieldset legend는 flex 흐름에서 한 줄을 차지(라벨처럼 태그 위에 표시) */
.category-tag-legend {
  width: 100%;
  margin-bottom: 0.5rem;
  padding: 0;
}
.category-tag-option {
  display: inline-flex;
  align-items: center;
  gap: 0.375rem;
  padding: 0.25rem 0.625rem;
  border: 1px solid var(--border-default);
  border-radius: var(--radius-full, 999px);
  font-size: 0.8125rem;
  color: var(--text-secondary);
  cursor: pointer;
  transition: background-color var(--transition-fast), border-color var(--transition-fast), color var(--transition-fast);
}
.category-tag-option:hover { background: var(--surface-hover); }
.category-tag-input { accent-color: var(--primary); cursor: pointer; }
/* 선택된 태그 — 라벨을 감싼 option에 강조(체크박스 :checked 형제 선택자) */
.category-tag-input:checked + .category-tag-label { color: var(--text-primary); font-weight: 600; }
.category-tag-input:focus-visible { outline: 2px solid var(--primary); outline-offset: 1px; }

/* 카테고리 다중 표시(상세) — 선택된 태그를 칩으로 나열 */
.product-category-tags {
  display: inline-flex;
  flex-wrap: wrap;
  gap: 0.375rem;
}
.product-category-tag {
  display: inline-flex;
  align-items: center;
  padding: 0.0625rem 0.5rem;
  border-radius: var(--radius-full, 999px);
  background: var(--surface-2);
  color: var(--text-secondary);
  font-size: 0.75rem;
}
/* 목록 상품명 셀 — 썸네일(있을 때) + 이름. 썸네일 없으면 이름만(정렬 유지) */
.product-name-cell {
  display: inline-flex;
  align-items: center;
  gap: 0.5rem;
  min-width: 0;
}
.product-name-text {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 0.125rem;
  min-width: 0;
}
.product-thumb {
  width: 2.25rem;
  height: 2.25rem;
  border-radius: var(--radius-sm);
  object-fit: cover;
  background: var(--surface-2);
  flex-shrink: 0;
}

/* 승인 목록 대상 — 첨부 썸네일과 관리 코드를 제목의 보조 정보로 묶는다. */
.approval-request-subject-cell {
  display: inline-flex;
  align-items: center;
  gap: 0.5rem;
  min-width: 0;
}
.approval-request-subject-thumb {
  width: 2.25rem;
  height: 2.25rem;
  border-radius: var(--radius-sm);
  object-fit: cover;
  background: var(--surface-2);
  flex-shrink: 0;
}
.approval-request-subject-cell > .attachment-preview {
  width: 2.25rem;
  height: 2.25rem;
  flex-shrink: 0;
  border-radius: var(--radius-sm);
}
.approval-request-subject-text {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 0.125rem;
  min-width: 0;
}

/* 태블릿에서는 표 구조를 유지하되 칩·이름이 한 글자씩 깨지지 않도록 가로 스크롤을 허용한다. */
@media (min-width: 640px) and (max-width: 1023px) {
  .product-list-table .table { min-width: 64rem; }
  .approval-request-list-table .table { min-width: 62rem; }
}

@media (max-width: 639px) {
  /* 터치 타깃 44px(WCAG 2.5.5). 높이만 늘리면 짧은 라벨은 가로가 그대로라
     "목록"·"칸반"이 46x44로 거의 정사각이 되고, 라벨 길이마다 폭이 46/46/69px로 들쭉날쭉해진다. */
  .filter-trigger,
  .view-switcher-item,
  .mine-toggle { min-height: 2.75rem; }

  /* 뷰 전환은 모바일에서 세그먼트 컨트롤로 — 폭을 꽉 채우고 균등 분할한다.
     라벨 길이와 무관하게 같은 폭이 되고, 44px 높이가 정사각으로 보이지 않는다. */
  .view-toolbar { align-items: stretch; }
  .view-switcher {
    display: flex;
    width: 100%;
  }
  .view-switcher-item {
    flex: 1 1 0;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    padding-inline: 0.5rem;
    text-align: center;
  }
  /* "내 담당만"은 전환 축이 아니라 필터라 세그먼트에 섞지 않는다 — 아래 줄에서 폭을 채운다. */
  .mine-toggle {
    justify-content: center;
    width: 100%;
  }
}

/* ── 개요 현황 대시보드 — 위젯 그리드(계약·기획·상품·승인·증지·일정) ── */
.dash-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(20rem, 1fr));
  gap: 1rem;
  margin-top: 1rem;
}
.dash-widget {
  display: flex;
  flex-direction: column;
  background: var(--surface-0);
  border: 1px solid var(--border-subtle);
  border-radius: var(--radius-lg);
  padding: 1rem 1.125rem;
  box-shadow: 0 1px 2px rgba(24, 24, 27, 0.04);
}
.dash-widget-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 0.5rem;
  margin-bottom: 0.625rem;
}
.dash-widget-title {
  display: flex;
  align-items: center;
  gap: 0.4375rem;
  margin: 0;
  font-size: 0.9375rem;
  font-weight: 600;
  color: var(--text-primary);
}
.dash-widget-count {
  font-size: 0.75rem;
  font-weight: 600;
  color: var(--text-muted);
  background: var(--surface-2);
  border-radius: var(--radius-full);
  padding: 0.0625rem 0.4375rem;
}
.dash-widget-more {
  font-size: 0.75rem;
  color: var(--text-muted);
  text-decoration: none;
  white-space: nowrap;
}
.dash-widget-more:hover { color: var(--primary); }
.dash-rows { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; }
.dash-row {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  padding: 0.4375rem 0;
  border-top: 1px solid var(--border-subtle);
}
.dash-row:first-child { border-top: 0; }
.dash-row-label {
  flex: 1;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  font-size: 0.8125rem;
  color: var(--text-primary);
  text-decoration: none;
}
a.dash-row-label:hover { color: var(--primary); }
.dash-row-trailing {
  font-size: 0.75rem;
  color: var(--text-muted);
  white-space: nowrap;
  font-variant-numeric: tabular-nums;
}
.dash-widget-empty {
  font-size: 0.8125rem;
  color: var(--text-muted);
  padding: 0.5rem 0;
}

/* ── 워크스페이스 홈 — 내 프로젝트 "한눈에" 카드(파이프라인 카운트 + 대기 강조) ── */
.pstatus-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(18rem, 1fr));
  gap: 0.875rem;
}
.pstatus-card {
  display: flex;
  flex-direction: column;
  gap: 0.75rem;
  padding: 1rem 1.125rem;
  background: var(--surface-0);
  border: 1px solid var(--border-subtle);
  border-radius: var(--radius-lg);
  box-shadow: 0 1px 2px rgba(24, 24, 27, 0.04);
  text-decoration: none;
  transition: border-color 0.15s ease, box-shadow 0.15s ease, transform 0.15s ease;
}
.pstatus-card:hover {
  border-color: var(--border-strong);
  box-shadow: 0 4px 12px rgba(24, 24, 27, 0.10);
  transform: translateY(-1px);
}
.pstatus-head {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 0.5rem;
}
.pstatus-name {
  font-size: 0.9375rem;
  font-weight: 600;
  color: var(--text-primary);
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.pstatus-badges { display: inline-flex; align-items: center; gap: 0.25rem; flex-shrink: 0; }
/* 파이프라인 카운트 — 라벨(작게) 위, 숫자(크게) 아래. 0은 흐리게(상황 대비). */
.pstatus-metrics {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: 0.5rem;
}
.pstatus-metric {
  display: flex;
  flex-direction: column;
  gap: 0.125rem;
  align-items: flex-start;
}
.pstatus-metric-label {
  font-size: 0.6875rem;
  color: var(--text-muted);
  white-space: nowrap;
}
.pstatus-metric-value {
  font-size: 1.125rem;
  font-weight: 600;
  color: var(--text-primary);
  font-variant-numeric: tabular-nums;
  line-height: 1.1;
}
.pstatus-metric-value.is-zero { color: var(--text-tertiary); font-weight: 500; }
/* 승인 대기 — 주황 강조 칩(설명 없이 "막혀있음"이 보이게). */
.pstatus-pending {
  display: inline-flex;
  align-items: center;
  gap: 0.3125rem;
  align-self: flex-start;
  padding: 0.1875rem 0.5rem;
  border-radius: var(--radius-full);
  background: var(--status-warning-soft, #fef3c7);
  color: var(--status-warning-strong, #92400e);
  font-size: 0.75rem;
  font-weight: 600;
}
.pstatus-pending svg { width: 0.8125rem; height: 0.8125rem; }

/* ── 목록 정렬 헤더 — 클릭 가능한 표 헤더 + 활성 방향 화살표 ── */
.sort-header {
  display: inline-flex;
  align-items: center;
  gap: 0.25rem;
  color: inherit;
  text-decoration: none;
  cursor: pointer;
  white-space: nowrap;
}
.sort-header:hover { color: var(--text-primary); }
.sort-header.is-active { color: var(--text-primary); font-weight: 600; }
.sort-header .sort-arrow { font-size: 0.75rem; color: var(--text-muted); }

/* 상품 목록 단계 셀(#442) — 단계 칩 + 현재 스텝 승인 상태 배지를 줄바꿈 허용해 나란히. */
.product-stage-cell { display: inline-flex; flex-wrap: wrap; align-items: center; gap: 0.375rem; }

/* 신청·승인 원장(G1 Phase B) — 제품 상세의 유형별 승인 리스트 */
.approval-ledger-list { list-style: none; margin: 0.5rem 0 0; padding: 0; display: flex; flex-direction: column; gap: 0.5rem; }
.approval-ledger-item { border: 1px solid var(--border-subtle); border-radius: var(--radius-md); padding: 0.625rem 0.75rem; }
/* 항목 머리 — 유형·상태·날짜·상세링크 한 줄. 아래로 인라인 처리(심사/취소/재제출) 폼이 붙는다. */
.approval-ledger-head { display: flex; align-items: center; gap: 0.625rem; flex-wrap: wrap; }
.approval-ledger-type { font-weight: 600; font-size: 0.8125rem; }
.approval-ledger-date { margin-left: auto; }

/* 승인 섹션(#488) — 섹션 머리(제목 + 신청 버튼) 한 줄, 통과 필요 행 강조. */
.section-head-row { display: flex; align-items: center; justify-content: space-between; gap: 0.75rem; flex-wrap: wrap; }
.approval-row-needed { background: color-mix(in srgb, var(--badge-purple) 7%, transparent); }

/* 단계 승인 카드 그리드 — 단계별 묶음 + 썸네일 카드(Task 2) */
.approval-card-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(11rem, 1fr));
  gap: 0.75rem;
}
.approval-card {
  display: flex;
  flex-direction: column;
  border: 1px solid var(--border-default);
  border-radius: var(--radius-md);
  background: var(--surface-1);
  overflow: hidden;
}
.approval-card-needed { border-color: var(--badge-warning, var(--accent-amber)); }
.approval-card-cover {
  display: flex;
  align-items: center;
  justify-content: center;
  aspect-ratio: 3 / 2;
  background: var(--surface-2);
}
.approval-card-cover-img { width: 100%; height: 100%; object-fit: cover; }
.approval-card-cover-empty { color: var(--text-tertiary); }
.approval-card-body {
  display: flex;
  flex-direction: column;
  gap: 0.375rem;
  padding: 0.625rem;
}
.approval-card-type { font-size: 0.8125rem; font-weight: 600; color: var(--text-primary); display: flex; align-items: center; gap: 0.375rem; flex-wrap: wrap; }
.approval-card-status { display: flex; align-items: center; gap: 0.375rem; flex-wrap: wrap; }
.approval-card-meta { display: flex; align-items: center; gap: 0.25rem; }
.approval-card-actions { display: flex; align-items: center; gap: 0.375rem; flex-wrap: wrap; margin-top: 0.125rem; }

/* ── 승인 항목(유형)별 그룹(#637b) — 항목이 단위, 그 아래 필요 승인 카드 여럿 + ＋ 추가 ── */
.appr-item-list { display: flex; flex-direction: column; gap: 0.85rem; }
.appr-item {
  border: 1px solid var(--border-default);
  /* 승인유형 색은 좌측 세로 바로 — 단계 색은 점(dot)이라 같은 화면에서 형태가 겹치지 않게 한다.
     색 미지정이면 기본 테두리색으로 떨어져 카드 형태(두께)는 항상 같다. */
  border-left: 3px solid var(--appr-item-color, var(--border-default));
  border-radius: var(--radius-lg);
  background: var(--surface-0);
  overflow: hidden;
}
.appr-item-head {
  display: flex;
  align-items: center;
  gap: 0.6rem;
  flex-wrap: wrap;
  padding: 0.75rem 1rem;
  border-bottom: 1px solid var(--border-subtle);
  background: var(--surface-1);
}
.appr-item-title {
  display: inline-flex;
  align-items: center;
  gap: 0.4rem;
  font-weight: 650;
  font-size: 0.9375rem;
  letter-spacing: -0.01em;
  color: var(--text-primary);
}
.appr-item-summary {
  margin-left: auto;
  font-size: 0.75rem;
  color: var(--text-muted);
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}
.appr-status-none {
  display: inline-flex; align-items: center;
  font-size: 0.6875rem; font-weight: 600; line-height: 1.5;
  padding: 0.1rem 0.5rem; border-radius: var(--radius-full);
  background: var(--surface-2); color: var(--text-muted);
}

/* 승인 슬롯 — 썸네일 리스트뷰(이번 단계·완료된 승인 공통). 단계 표시.
   하단 padding은 상단 .appr-item-head와 동일 수준(0.75rem)으로 — ＋ 추가 버튼 아래 여백이
   카드 상단보다 좁아 보이던 문제(#COLLA-45). */
.appr-item-rows { display: flex; flex-direction: column; padding: 0.25rem 0.5rem 0.75rem; }
.appr-slot-row {
  display: grid;
  grid-template-columns: 48px 1fr auto;
  align-items: center;
  gap: 0.85rem;
  padding: 0.6rem 0;
}
.appr-slot-row + .appr-slot-row { border-top: 1px solid var(--border-subtle); }
.appr-slot-row-thumb {
  width: 48px; height: 48px;
  border-radius: var(--radius-md);
  background: var(--surface-1);
  border: 1px solid var(--border-subtle);
  display: flex; align-items: center; justify-content: center;
  color: var(--text-tertiary); overflow: hidden;
}
.appr-slot-row-thumb-img { width: 100%; height: 100%; object-fit: cover; }
.appr-slot-row-main { min-width: 0; display: flex; flex-direction: column; gap: 0.2rem; }
.appr-slot-row-line { display: flex; align-items: center; gap: 0.5rem; flex-wrap: wrap; }
.appr-slot-row-stage {
  font-size: 0.75rem; font-weight: 600; color: var(--text-secondary);
  background: var(--surface-2); border-radius: var(--radius-sm); padding: 0.05rem 0.4rem;
}
.approval-list-item-meta-stack { display: flex; flex-direction: column; gap: 0.2rem; color: var(--text-muted); padding-top: 0.125rem; }
.approval-list-item-meta { display: inline-flex; align-items: center; gap: 0.25rem; color: var(--text-muted); flex-wrap: wrap; }
.approval-list-item-meta-label {
  display: inline-flex;
  align-items: center;
  justify-content: flex-start;
  min-width: 2.4rem;
  padding-right: 0.35rem;
  font-weight: 600;
  color: var(--text-secondary);
}
.approval-list-item-meta-content { display: inline-flex; align-items: center; gap: 0.25rem; flex-wrap: wrap; }
.approval-list-item-meta-fallback { color: var(--text-secondary); }
@media (max-width: 520px) {
  .appr-item {
    padding: 0.75rem;
    border-radius: var(--radius-md);
  }
  .appr-item-head {
    align-items: flex-start;
    gap: 0.45rem;
    margin-bottom: 0.625rem;
  }
  .appr-item-summary {
    width: 100%;
    margin-left: 0;
  }
  .appr-slot-row {
    grid-template-columns: 44px minmax(0, 1fr);
    align-items: flex-start;
    gap: 0.75rem;
    padding: 0.75rem 0;
  }
  .appr-slot-row-thumb {
    width: 44px;
    height: 44px;
    margin-top: 0.125rem;
  }
  .appr-slot-row-main { gap: 0.35rem; }
  .appr-slot-row-line {
    align-items: flex-start;
    gap: 0.375rem;
  }
  .appr-slot-row-stage {
    max-width: 100%;
    line-height: 1.35;
  }
  .approval-list-item-meta-stack {
    gap: 0.35rem;
    padding-top: 0;
  }
  .approval-list-item-meta {
    display: grid;
    grid-template-columns: 2.75rem minmax(0, 1fr);
    align-items: start;
    column-gap: 0.35rem;
    row-gap: 0.125rem;
  }
  .approval-list-item-meta-label {
    min-width: 0;
    padding-right: 0;
    line-height: 1.45;
  }
  .approval-list-item-meta-content {
    min-width: 0;
    align-items: flex-start;
    gap: 0.25rem 0.375rem;
  }
  .approval-list-item-meta-content .member-chip,
  .approval-list-item-meta-content .member-chip-trigger,
  .approval-list-item-meta-content .member-display {
    max-width: 100%;
    min-width: 0;
  }
  .appr-slot-row-action {
    grid-column: 2;
    justify-self: start;
    display: flex;
    flex-wrap: wrap;
    gap: 0.375rem;
    padding-top: 0.125rem;
  }
  .appr-slot-row-detail-link {
    min-height: 2rem;
    display: inline-flex;
    align-items: center;
  }
  .approval-received-details .approval-received-grid {
    padding: 0.25rem 0.75rem;
  }
  .appr-item-history {
    padding: 0.7rem 0;
  }
  .appr-item-history .appr-slot-row {
    padding: 0.55rem 0;
  }
}

/* ＋ 필요 승인 추가 — 리스트 하단 점선 행(IP 제공사). 위압적이지 않게 중립 톤. */
.appr-add-row-form { margin: 0; }
.appr-add-row {
  width: 100%;
  display: inline-flex; align-items: center; gap: 0.4rem;
  border: 1px dashed var(--border-default);
  border-radius: var(--radius-md);
  background: transparent;
  color: var(--text-muted);
  font-family: inherit; font-size: 0.8125rem; font-weight: 600;
  padding: 0.55rem 0.75rem;
  margin-top: 0.5rem;
  cursor: pointer;
  transition: border-color var(--transition-fast), background var(--transition-fast), color var(--transition-fast);
}
.appr-add-row:hover { border-color: var(--text-tertiary); background: var(--surface-hover); color: var(--text-secondary); }
.appr-add-row-plus { font-size: 1rem; line-height: 1; font-weight: 700; }

/* 승인 진행 요약 한 줄 배 — §4.1 상단 배치 */
/* 승인 마감 안내 — 완료 문구 + 다음 단계 선택(라벨·드롭다운·이동 버튼 한 줄) */
.stage-advance { display: flex; flex-direction: column; gap: 0.625rem; }
.stage-advance-actions { display: flex; flex-wrap: wrap; align-items: center; gap: 0.5rem; }
/* select(.select 0.5rem padding)와 버튼(.btn-sm 0.375rem)의 기본 높이가 5px 달라 같은 줄에서
   어긋난다 — 실측 39 vs 34. 한 줄에 나란히 서는 컨트롤이므로 높이를 함께 고정한다. */
.stage-advance-actions .select,
.stage-advance-actions .btn { min-height: 2.5rem; }
@media (max-width: 520px) {
  /* 모바일 최소 터치 타깃 44px — select만 39px로 남으면 같은 줄 버튼(44)과도 어긋난다. */
  .stage-advance-actions .select,
  .stage-advance-actions .btn { min-height: 2.75rem; }
}

/* 완료된 승인 접힘 블록(details/summary) — 이력 기본 접기 */
.approval-received-details { border: none; }
.approval-received-details .approval-received-grid {
  margin-top: 0.75rem;
  gap: 0;
  border: 1px solid var(--border-default);
  border-radius: var(--radius-lg);
  background: var(--surface-0);
  padding: 0.2rem 1rem;
}
.approval-received-summary {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  cursor: pointer;
  list-style: none;
  margin-bottom: 0;
}
.approval-received-summary::-webkit-details-marker { display: none; }
.approval-received-summary .section-title { margin-bottom: 0; }
.approval-received-caret { color: var(--text-tertiary); flex-shrink: 0; transition: transform var(--transition-fast); }
.approval-received-details[open] .approval-received-caret { transform: rotate(90deg); }
.approval-received-count {
  font-size: 0.75rem;
  color: var(--text-secondary);
  background: var(--surface-1);
  border-radius: 999px;
  padding: 0.0625rem 0.5rem;
}

.appr-item-history {
  border: 0;
  border-radius: 0;
  background: transparent;
  box-shadow: none;
  padding: 0.8rem 0;
}
.appr-item-history + .appr-item-history { border-top: 1px solid var(--border-subtle); }
.appr-item-history .appr-item-head { margin-bottom: 0.35rem; }
.approval-list-item-history { padding-block: 0.25rem; }
.approval-list-item-history .approval-list-item-thumbnail { width: 36px; height: 36px; border-radius: var(--radius-sm); }
.approval-list-item-history .approval-list-item-main { gap: 0.12rem; }
.appr-slot-row-detail-link { font-size: 0.8125rem; white-space: nowrap; }

/* 승인 목록 공통 행 — 제목 링크가 행 전체를 덮고 실제 액션·첨부 미리보기는 그 위에 둔다. */
.approval-list-item {
  position: relative;
  display: grid;
  grid-template-columns: 48px minmax(9rem, 0.75fr) minmax(16rem, 1.25fr) auto;
  align-items: center;
  gap: 0.85rem;
  min-height: 68px;
  padding: 0.6rem;
  border-radius: var(--radius-md);
}
.approval-list-item + .approval-list-item { border-top: 1px solid var(--border-subtle); }
.approval-list-item:has(.approval-list-item-link):hover { background: var(--surface-1); }
.approval-list-item-thumbnail {
  width: 48px;
  height: 48px;
  border: 1px solid var(--border-subtle);
  border-radius: var(--radius-md);
  background: var(--surface-1);
  color: var(--text-tertiary);
  display: flex;
  align-items: center;
  justify-content: center;
  overflow: hidden;
}
.approval-list-item-thumbnail img { width: 100%; height: 100%; object-fit: cover; }
.approval-list-item-thumbnail [data-lightbox-full-url] { position: relative; z-index: 2; cursor: pointer; }
.approval-list-item-main { min-width: 0; display: flex; flex-direction: column; gap: 0.35rem; }
.approval-list-item-heading { display: flex; align-items: center; gap: 0.45rem; flex-wrap: wrap; }
.approval-list-item-link,
.approval-list-item-title {
  color: var(--text-primary);
  font-size: 0.875rem;
  font-weight: 650;
  letter-spacing: -0.01em;
}
.approval-list-item-link::after {
  content: "";
  position: absolute;
  inset: 0;
  z-index: 1;
  border-radius: var(--radius-md);
}
.approval-list-item-link:focus-visible { outline: none; }
.approval-list-item-link:focus-visible::after { box-shadow: var(--shadow-focus-ring); }
.approval-list-item-context {
  color: var(--text-muted);
  font-size: 0.75rem;
  font-weight: 600;
}
.approval-list-item-metadata { min-width: 0; }
.approval-list-item-meta-stack { gap: 0.35rem; padding-top: 0; }
.approval-list-item-meta-content .member-display-company { display: block; }
.approval-list-item-meta-time { color: var(--text-tertiary); font-variant-numeric: tabular-nums; white-space: nowrap; }
.approval-list-item-actions {
  position: relative;
  z-index: 2;
  display: flex;
  align-items: center;
  gap: 0.375rem;
}

/* 삭제(x) — 다른 액션과 섞이지 않게 카드 코너에 독립 배치(#COLLA-45). PC 리스트는 우측 정렬(수직 중앙),
   모바일 카드는 우상단으로 이동(아래 모바일 미디어쿼리). 부모(.approval-list-item)가 위치 기준. */
.appr-item-rows .approval-list-item-remove {
  position: absolute;
  z-index: 2;
  top: 50%;
  right: 0.6rem;
  transform: translateY(-50%);
}
.appr-item-rows .approval-list-item:has(.approval-list-item-remove) .approval-list-item-actions {
  padding-right: 2.75rem; /* 코너 삭제 버튼과 겹치지 않게 여유(드묾: 사유 캡션 + 삭제 동시 노출) */
}
.approval-list {
  display: flex;
  flex-direction: column;
  padding: 0.25rem 0.5rem;
  border: 1px solid var(--border-default);
  border-radius: var(--radius-lg);
  background: var(--surface-0);
}
/* 승인 요청 확인면 — 무엇을 제출하는지 보여주는 산출물 파일 목록(줄 간격만 필요) */
.submit-confirm-artifacts { display: flex; flex-direction: column; gap: 0.25rem; }

@media (min-width: 521px) and (max-width: 900px) {
  .approval-list-item { grid-template-columns: 48px minmax(0, 1fr) auto; }
  .approval-list-item-metadata { grid-column: 2; }
  .approval-list-item-actions { grid-column: 3; grid-row: 1 / span 2; }
}

@media (max-width: 520px) {
  .appr-item {
    border: 0;
    border-radius: 0;
    background: transparent;
    padding: 0;
    overflow: visible;
  }
  /* 모바일은 카드 크롬이 없어 바를 붙일 테두리가 없다. 바 + 그 오른쪽 여백만큼(11px) 음수 margin으로
     당겨 바를 본문 여백 쪽에 두고, 콘텐츠 좌변은 다른 섹션 제목과 정확히 맞춘다(COLLA-44 — 실측 29px).
     margin은 padding만이 아니라 border 두께까지 상쇄해야 한다(안 하면 콘텐츠가 3px 밀린다). */
  .appr-item {
    border-left: 3px solid var(--appr-item-color, var(--border-default));
    padding-left: 0.5rem;
    margin-left: calc(-0.5rem - 3px);
  }
  .appr-item-head {
    padding: 0;
    margin-bottom: 0.5rem;
    border-bottom: 0;
    background: transparent;
  }
  .appr-item-rows,
  .approval-list {
    gap: 0.625rem;
    padding: 0;
    border: 0;
    background: transparent;
  }
  .approval-list-item {
    grid-template-columns: 44px minmax(0, 1fr);
    align-items: start;
    gap: 0.75rem;
    min-height: 68px;
    padding: 0.875rem;
    border: 1px solid var(--border-default);
    border-radius: var(--radius-lg);
    background: var(--surface-0);
  }
  .approval-list-item + .approval-list-item { border-top: 1px solid var(--border-default); }
  .approval-list-item-thumbnail { width: 44px; height: 44px; }
  .approval-list-item-main { display: flex; }
  .approval-list-item-heading { grid-column: 2; align-items: flex-start; gap: 0.375rem; }
  .approval-list-item-metadata { grid-column: 1 / -1; }
  .approval-list-item-meta-content { align-items: flex-start; }
  .approval-list-item-meta-time { flex-basis: 100%; padding-top: 0.125rem; }
  .approval-list-item-actions { grid-column: 1 / -1; width: 100%; flex-wrap: wrap; }
  .approval-list-item-actions .btn { width: 100%; min-height: 44px; justify-content: center; }
  /* 모바일 카드 — 삭제(x)는 코너로 이탈, 나머지 액션 행과 안 겹치게 헤딩에 여유(#COLLA-45). */
  .appr-item-rows .approval-list-item-remove { top: 0.75rem; right: 0.75rem; transform: none; }
  .appr-item-rows .approval-list-item:has(.approval-list-item-remove) .approval-list-item-heading { padding-right: 2.5rem; }
  .approval-received-details .approval-received-grid {
    gap: 0.625rem;
    padding: 0;
    border: 0;
    background: transparent;
  }
  .appr-item-history { padding: 0; border-top: 0; border-left: 0; margin-left: 0; }
  .appr-item-history + .appr-item-history { border-top: 0; }
  .approval-list-item-history { padding: 0.875rem; }
  .approval-list-item-history .approval-list-item-thumbnail { width: 44px; height: 44px; }
}

/* 차수 배지(P3) — 헤더 상태 옆 "N차 검수" 표시(재제출 시 검수 혼동 방지) */
.approval-round-badge {
  display: inline-flex;
  align-items: center;
  margin-right: 0.375rem;
  padding: 0.0625rem 0.5rem;
  border-radius: var(--radius-full);
  background: var(--surface-2);
  color: var(--text-secondary);
  font-size: 0.75rem;
  font-weight: 600;
}

/* 재제출 폼 위 "요청받은 수정 항목"(P2) — 살짝 강조된 안내 박스 */
.resubmit-todo {
  padding: 0.5rem 0.75rem;
  border-radius: var(--radius-sm);
  background: #fffbeb;
  border: 1px solid #fde68a;
}
.resubmit-todo .label-text { color: #92400e; margin-bottom: 0.25rem; }

/* 제출 이력(라운드 비교, P1) — 라운드별 구분선 카드 */
.submission-round + .submission-round {
  margin-top: 0.75rem;
  padding-top: 0.75rem;
  border-top: 1px solid var(--border-subtle, var(--border-default));
}
.submission-round-head {
  display: flex;
  align-items: baseline;
  flex-wrap: wrap;
  gap: 0.5rem;
  margin-bottom: 0.375rem;
}
.submission-round-badge {
  flex: 0 0 auto;
  padding: 0.0625rem 0.5rem;
  border-radius: var(--radius-full);
  background: var(--surface-2);
  color: var(--text-secondary);
  font-size: 0.75rem;
  font-weight: 600;
}
.submission-round-author { font-size: 0.8125rem; font-weight: 600; color: var(--text-primary); }
.submission-round-time { font-size: 0.75rem; color: var(--text-tertiary); }
.submission-round-desc { margin: 0.25rem 0 0.5rem; }
/* 차수 파일 미리보기(COLLA-115) — 이력은 훑는 자리라 타일을 작게 **고정**한다. 1fr 로 늘리면
   열 폭에 따라 타일이 커져 표의 다른 열을 눌렀다(기본 9rem 타일이 그랬다).
   줄이는 것은 **썸네일 높이**다 — 파일명은 그대로 읽혀야 한다(파일을 여는 경로다). */
.submission-files {
  display: grid;
  grid-template-columns: repeat(auto-fill, 5.5rem);
  gap: 0.5rem;
  max-width: 18rem;
}

.submission-files .file-preview-media {
  height: 3.25rem;
}

.submission-files .file-preview-name {
  font-size: 0.6875rem;
}

/* 조건부 승인 체크사항(#509) — 클리어 가능한 체크리스트 */
.condition-list { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 0.5rem; }
.condition-item {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 0.75rem;
  padding: 0.5rem 0.75rem;
  border: 1px solid var(--border-subtle, var(--border-default));
  border-radius: var(--radius-md);
}
/* 슬랙형 멤버 칩 + 프로필 팝오버 */
.member-chip { position: relative; display: inline-flex; }
.member-chip-trigger {
  display: inline-flex;
  align-items: center;
  gap: 0.375rem;
  background: none;
  border: 0;
  padding: 0;
  font: inherit;
  color: inherit;
  border-radius: var(--radius-sm);
  cursor: pointer;
}
.member-chip-trigger:hover .member-chip-name,
.member-chip-trigger:hover .member-display-name { text-decoration: underline; }
.member-profile-popover {
  z-index: 50;
  width: 17rem;
  max-width: calc(100vw - 2rem);
  background: var(--surface-0);
  border: 1px solid var(--border-default);
  border-radius: var(--radius-lg);
  padding: 1.25rem;
}
.member-profile-skeleton {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 0.5rem;
}
.member-profile-skeleton-avatar,
.member-profile-skeleton-line,
.member-profile-skeleton-badge {
  background: var(--surface-2);
  animation: member-profile-skeleton-pulse 1.2s ease-in-out infinite;
}
.member-profile-skeleton-avatar {
  width: 4rem;
  height: 4rem;
  border-radius: var(--radius-full);
}
.member-profile-skeleton-line {
  width: 100%;
  height: 0.75rem;
  border-radius: var(--radius-full);
}
.member-profile-skeleton-line-name {
  width: 7rem;
  margin-top: 0.25rem;
}
.member-profile-skeleton-line-company { width: 5.5rem; }
.member-profile-skeleton-badge {
  width: 4rem;
  height: 1.625rem;
  border-radius: var(--radius-md);
}
.member-profile-skeleton-fields {
  width: 100%;
  margin-top: 0.5rem;
  display: flex;
  flex-direction: column;
  gap: 0.5rem;
}
@keyframes member-profile-skeleton-pulse {
  0%, 100% { opacity: 0.55; }
  50% { opacity: 1; }
}
@media (prefers-reduced-motion: reduce) {
  .member-profile-skeleton-avatar,
  .member-profile-skeleton-line,
  .member-profile-skeleton-badge {
    animation: none;
  }
}
.member-profile { display: flex; flex-direction: column; align-items: center; gap: 0.5rem; text-align: center; }
.member-profile-name { font-weight: 600; font-size: 0.875rem; line-height: 1.25; color: var(--text-primary); }
.member-profile-company { font-size: 0.8125rem; line-height: 1.3; color: var(--text-tertiary); }
.member-profile-badges { display: flex; flex-wrap: wrap; justify-content: center; gap: 0.375rem; }
.member-profile-fields { width: 100%; margin: 0.5rem 0 0; display: flex; flex-direction: column; gap: 0.5rem; }
.member-profile-field { display: flex; flex-direction: column; gap: 0.125rem; text-align: left; }
.member-profile-field dt { font-size: 0.75rem; color: var(--text-secondary); margin: 0; }
.member-profile-field dd { font-size: 0.875rem; color: var(--text-primary); margin: 0; }

/* 기획 목록 — 멤버 칩은 row-click 오버레이 위에서 동작해야 한다. */
.project-concepts-table .member-chip-trigger {
  position: relative;
  z-index: 2;
}
@container (max-width: 62rem) {
  .project-concepts-table td.project-concept-code-cell:first-child:not([data-label]) {
    margin-bottom: 0.125rem;
    font-size: 0.75rem;
    font-weight: 500;
    color: var(--text-muted);
  }
  .project-concepts-table td.project-concept-code-cell:first-child:not([data-label]) a {
    color: var(--text-muted);
  }
  .project-concepts-table td.project-concept-name-cell[data-label]:not(:empty) {
    display: block;
    margin-bottom: 0.375rem;
    font-size: 0.9375rem;
    font-weight: 600;
    line-height: 1.35;
  }
  .project-concepts-table td.project-concept-name-cell[data-label]:not(:empty)::before {
    display: none;
  }
}

/* 클리어 완료 — 흐림(opacity) 대신 완료 톤(읽히게). 초록 체크 + '클리어됨' 배지로 명확히. */
.condition-item.is-resolved { background: var(--surface-1); }
.condition-item.is-resolved .text-pre-wrap { color: var(--text-secondary); }
.condition-check-done { color: var(--accent-green); }
.condition-body { display: flex; align-items: center; gap: 0.5rem; font-size: 0.875rem; }

/* 결재선(#508) — 유형별 순차 결재자 편집 */
.approval-type-approvers {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.375rem;
  margin: 0.25rem 0 0.75rem;
  padding-left: 0.5rem;
}
.approval-type-approver-add { display: inline-flex; align-items: center; gap: 0.375rem; }

/* 검수 차수(#511) — 진행률 + admin 인라인 설정 */
.approval-rounds { display: inline-block; margin-left: 0.375rem; color: var(--text-tertiary); }
.approval-rounds-set { display: inline-flex; align-items: center; gap: 0.375rem; margin-top: 0.25rem; }
.approval-rounds-input { width: 3.5rem; }

/* 콜라보 스코프 필터 칩(#498) — 할일/알림이 특정 프로젝트로 필터 중임을 표시 */
.filter-active-chip {
  display: flex;
  align-items: center;
  gap: 0.625rem;
  margin-bottom: 0.75rem;
  padding: 0.5rem 0.75rem;
  border-radius: var(--radius-md);
  background: var(--surface-2);
  font-size: 0.8125rem;
  color: var(--text-secondary);
}

/* 멤버 추가(#491) — 업체별 검색 추가 */
.member-add { display: flex; flex-direction: column; gap: 0.875rem; }
.member-add-company-head { display: flex; align-items: center; gap: 0.5rem; margin-bottom: 0.375rem; }
.member-add-company-name { font-size: 0.875rem; font-weight: 600; color: var(--text-primary); }
.member-add-form { display: flex; align-items: flex-start; gap: 0.5rem; }
.member-add-invite { margin: 0.25rem 0 0; font-size: 0.8125rem; }

/* 검색 가능한 셀렉트 */
.searchable-select { position: relative; flex: 1 1 auto; min-width: 0; }
.searchable-select-options {
  position: absolute;
  z-index: 40;
  top: 100%;
  left: 0;
  right: 0;
  max-height: 14rem;
  overflow-y: auto;
  margin: 0.25rem 0 0;
  padding: 0.25rem;
  list-style: none;
  background: var(--surface-0);
  border: 1px solid var(--border-default);
  border-radius: var(--radius-md);
  box-shadow: 0 8px 24px rgba(0, 0, 0, 0.12);
}
.searchable-select-option {
  display: block;
  width: 100%;
  text-align: left;
  padding: 0.375rem 0.5rem;
  border: 0;
  border-radius: var(--radius-sm);
  background: transparent;
  font-size: 0.875rem;
  color: var(--text-primary);
}
.searchable-select-option:hover { background: var(--surface-hover); }

/* 공지 메인 진입 팝업 — 모달 본문 아래 "전체 보기" 링크. */
.announcement-popup-footer {
  margin-top: 1rem;
  padding-top: 0.75rem;
  border-top: 1px solid var(--border-subtle);
  text-align: right;
}

/* 증지 섹션(#488 ㉢) — 상품 상세의 총 교부수량 요약 stat. 이력 표는 Ui::Table 재사용. */
.label-issuance-stat { display: flex; align-items: baseline; gap: 0.5rem; margin: 0.5rem 0 0.75rem; }
.label-issuance-stat-label { font-size: 0.8125rem; color: var(--text-tertiary); }
.label-issuance-stat-value { font-size: 1.125rem; font-weight: 600; color: var(--text-primary); }

/* 프로젝트 셸 컨텍스트 전환기 */
.project-switcher,
.project-switcher-static {
  width: 100%;
  min-width: 0;
}

.project-switcher-trigger,
.project-switcher-static {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  min-height: 2.75rem;
  padding: 0.5rem;
  border: 0;
  border-radius: var(--radius-md);
  background: transparent;
  color: var(--text-primary);
  text-align: left;
}

.project-switcher-trigger {
  width: 100%;
  cursor: pointer;
  transition: background-color var(--transition-fast);
}

.project-switcher-trigger:hover {
  background: var(--surface-hover);
}

.project-switcher-trigger:focus-visible {
  outline: 2px solid var(--primary);
  outline-offset: -2px;
}

.project-switcher-current {
  min-width: 0;
  overflow: hidden;
  font-size: 0.875rem;
  font-weight: 600;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.project-switcher-chevron {
  flex: 0 0 auto;
  margin-left: auto;
  color: var(--text-tertiary);
}

.project-switcher-menu.dropdown-menu {
  width: 18rem;
  max-width: calc(100vw - 2rem);
  gap: 0.5rem;
  padding: 0.5rem;
}

.project-switcher-search {
  position: relative;
}

.project-switcher-search-icon {
  position: absolute;
  top: 50%;
  left: 0.75rem;
  color: var(--text-tertiary);
  pointer-events: none;
  transform: translateY(-50%);
}

.project-switcher-search-input {
  min-height: 2.75rem;
  padding-left: 2rem;
}

.project-switcher-options {
  display: flex;
  max-height: 15rem;
  overflow-y: auto;
  flex-direction: column;
  gap: 0.25rem;
}

.project-switcher-option[hidden],
.project-switcher-empty[hidden] {
  display: none;
}

.project-switcher-option {
  min-height: 2.75rem;
  padding: 0.5rem 0.75rem;
}

.project-switcher-option:focus-visible {
  outline: 2px solid var(--primary);
  outline-offset: -2px;
}

.project-switcher-option[aria-current="page"] {
  background: var(--surface-active);
  color: var(--text-primary);
  font-weight: 600;
}

.project-switcher-option-name {
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.project-switcher-option-code {
  flex: 0 0 auto;
  padding: 0.25rem 0.5rem;
  border-radius: var(--radius-sm);
  background: var(--surface-2);
  color: var(--text-muted);
  font-size: 0.75rem;
  font-weight: 500;
}

.project-switcher-check {
  flex: 0 0 auto;
  margin-left: auto;
  color: var(--primary);
}

.project-switcher-empty {
  margin: 0;
  padding: 1rem 0.5rem;
  color: var(--text-muted);
  font-size: 0.75rem;
  text-align: center;
}

/* breadcrumb variant — 스위처를 breadcrumb 마지막 crumb 자리에(사이드바 overflow 클리핑 회피).
   트리거 시각은 .ui-breadcrumb-current와 일치, 드롭다운은 트리거 기준 절대배치 */
.project-switcher--breadcrumb {
  position: relative;
  display: inline-flex;
  width: auto;
}

.project-switcher--breadcrumb .project-switcher-trigger {
  width: auto;
  min-height: 0;
  padding: 0.125rem 0.25rem;
  /* crumb 텍스트 좌측 정렬을 유지하면서 히트 영역만 확보 */
  margin: -0.125rem -0.25rem;
  gap: 0.25rem;
}

.project-switcher-static.project-switcher--breadcrumb {
  min-height: 0;
  padding: 0;
}

.project-switcher--breadcrumb .project-switcher-current {
  /* .ui-breadcrumb의 crumb 폰트 크기 상속 */
  font-size: inherit;
}

.project-switcher--breadcrumb .project-switcher-chevron {
  margin-left: 0;
}
.attachment-preview {
  display: grid;
  width: 100%;
  height: 100%;
  overflow: hidden;
  color: var(--text-tertiary);
  /* 이미지 뒤에 브랜드 노랑/강한 회색을 깔지 않고 콘텐츠를 우선한다. */
  background-color: var(--surface-0);
  border-radius: inherit;
}

.attachment-preview-fallback,
.attachment-preview > img {
  grid-area: 1 / 1;
  width: 100%;
  height: 100%;
}

.attachment-preview-fallback {
  display: flex;
  align-items: center;
  justify-content: center;
}

/* 전역 [hidden] 규칙이 없어 위 display 선언이 hidden 속성을 눌러버린다 — 명시 가드.
   이게 없으면 썸네일 URL 이 있을 때도 아이콘이 계속 렌더돼, 투명 PNG 뒤로 비친다. */
.attachment-preview-fallback[hidden] { display: none; }

/* 썸네일 존재가 확정되기 전 덮는 레이어. 확정되면 JS 가 이 요소를 제거하므로
   [hidden] 가드가 필요 없다. 셰이머는 .skeleton 이 준다. */
.attachment-preview-skeleton {
  grid-area: 1 / 1;
  width: 100%;
  height: 100%;
  border-radius: inherit;
}

.attachment-preview > img {
  object-fit: cover;
}

.attachment-preview-pdf > img {
  object-fit: contain;
  background-color: var(--surface-0);
}

.attachment-preview-trigger {
  all: unset;
  display: block;
  width: 100%;
  height: 100%;
  box-sizing: border-box;
  border-radius: inherit;
  cursor: pointer;
}

.attachment-preview-trigger:focus-visible {
  box-shadow: var(--shadow-focus-ring);
}

/* ── 선택 속성(노션식) — 고르거나 그 자리에서 만든다 ────────────────────────
   칩에 색을 입히지 않는다: 색면은 상태·승인 배지가 독점한다(design-rule). */
.select-property { position: relative; }
.select-property-control {
  display: flex;
  align-items: center;
  gap: 0.375rem;
  flex-wrap: wrap;
  min-height: 2.5rem;
  padding: 0.3rem 0.625rem;
  border: 1px solid var(--border-default);
  border-radius: var(--radius-md);
  background: var(--surface-0);
}
.select-property-control:focus-within { box-shadow: var(--shadow-focus-ring); border-color: var(--border-strong); }
.select-property-input {
  flex: 1 1 6rem;
  min-width: 6rem;
  border: 0;
  outline: none;
  background: transparent;
  font-size: 0.875rem;
  color: var(--text-primary);
}
.select-property-chip {
  display: inline-flex;
  align-items: center;
  gap: 0.25rem;
  padding: 0.1rem 0.5rem;
  border-radius: var(--radius-sm);
  background: var(--surface-2);
  color: var(--text-primary);
  font-size: 0.8125rem;
  line-height: 1.5;
}
.select-property-chip--menu { background: var(--surface-2); }
.select-property-chip-remove {
  border: 0; background: transparent; padding: 0; cursor: pointer;
  color: var(--text-tertiary); font-size: 0.9rem; line-height: 1;
}
.select-property-chip-remove:hover { color: var(--text-primary); }
.select-property-menu {
  position: absolute;
  z-index: 40;
  top: 100%;
  left: 0;
  right: 0;
  margin-top: 0.25rem;
  padding: 0.375rem;
  max-height: 16rem;
  overflow-y: auto;
  border: 1px solid var(--border-default);
  border-radius: var(--radius-md);
  background: var(--surface-0);
  box-shadow: var(--shadow-overlay);
}
.select-property-hint { padding: 0.25rem 0.375rem; }
.select-property-options { list-style: none; margin: 0; padding: 0; }
/* 손잡이 — 고르는 버튼 — ⋮ 한 줄. 편집기는 그 아래로 펼쳐진다(줄바꿈). */
.select-property-row { display: flex; align-items: center; flex-wrap: wrap; }
.select-property-option {
  flex: 1; min-width: 0; text-align: left;
  padding: 0.3rem 0.375rem; border: 0; border-radius: var(--radius-sm);
  background: transparent; cursor: pointer;
}
.select-property-option:hover { background: var(--surface-hover); }
/* 손잡이·⋮ 는 흐리게 늘 있다가 그 행을 가리키면 진해진다. 호버에서만 나타나게 하면
   터치 기기에서는 영영 나타나지 않는다 — 이 앱은 375px 에서도 쓴다. */
.select-property-handle,
.select-property-edit { color: var(--text-muted); }
.select-property-row:hover .select-property-handle,
.select-property-row:hover .select-property-edit,
.select-property-row:focus-within .select-property-handle,
.select-property-row:focus-within .select-property-edit { color: var(--text-secondary); }
/* 손잡이 칸은 손잡이가 없는 행에도 같은 폭으로 있다 — 이름이 한 선에서 시작해야 한 목록이다. */
.select-property-handle,
.select-property-handle-slot { flex: none; width: 1.25rem; }
.select-property-handle { padding: 0.125rem; border-radius: var(--radius-sm); }
.select-property-edit {
  padding: 0.25rem; border: 0; border-radius: var(--radius-sm);
  background: transparent; color: var(--text-tertiary); cursor: pointer;
}
.select-property-edit:hover { background: var(--surface-hover); color: var(--text-primary); }
.select-property-create {
  display: block; width: 100%; text-align: left;
  padding: 0.375rem; margin-top: 0.25rem; border: 0; border-radius: var(--radius-sm);
  background: transparent; cursor: pointer;
  font-size: 0.875rem; color: var(--text-primary);
  border-top: 1px solid var(--border-subtle);
}
.select-property-create:hover { background: var(--surface-hover); }
.select-property-empty { padding: 0.375rem; }

/* ── Ui::ProgressBar ────────────────────────────────────────────────────────
 * 수량 진행 막대. 업로드 전용이던 `.dropzone-progress-*` 와 같은 형태·토큰을 쓰되,
 * 도메인 화면이 쓸 수 있게 컴포넌트로 뺐다(증지 교부가 첫 사용처, COLLA-217).
 * 채움 색은 진행=primary / 완료=success 둘뿐이다 — 그라데이션 없음, semantic token만. */
.progress-bar { display: flex; flex-direction: column; gap: 0.25rem; min-width: 8rem; }
/* 표 셀 안의 작은 막대는 폭을 조인다 — 셀을 꽉 채우면 숫자 밑줄로 읽힌다. */
.progress-bar--sm { max-width: 10rem; }
.progress-bar-label { font-size: 0.8125rem; font-weight: 500; color: var(--text-primary); }
.progress-bar-track {
  overflow: hidden;
  border-radius: var(--radius-full);
  background-color: var(--surface-2);
}
.progress-bar-track--sm { height: 0.25rem; }
.progress-bar-track--md { height: 0.375rem; }
.progress-bar-fill {
  height: 100%;
  border-radius: inherit;
  background-color: var(--primary);
  transition: width var(--transition-fast);
}
.progress-bar-fill--complete { background-color: var(--status-success); }
.progress-bar-caption { font-size: 0.75rem; color: var(--text-muted); }

/* 렌더된 Markdown 본문 — 간격·색은 typography 플러그인이 정한다(app/assets/tailwind/application.css).
   여기서는 그 플러그인이 다루지 않는 것만 손본다. */
/* 목차를 눌러 뛰면 소제목이 상단 헤더에 가린다 — 그만큼 미리 띄운다. */
.manual-body :is(h2, h3) {
  scroll-margin-top: 5rem;
}
.manual-body table {
  /* 좁은 화면에서 표가 자기 안에서 스크롤한다 — 본문이 가로로 밀리지 않게. */
  display: block;
  overflow-x: auto;
  max-width: 100%;
}
.manual-body code {
  /* 화면 이름을 감싸는 자리로도 쓰인다 — 코드 글꼴을 쓰면 개발자 문서처럼 읽힌다. */
  font-family: inherit;
  background: var(--surface-2);
  border: 1px solid var(--border-subtle);
  border-radius: var(--radius-sm);
  padding: 0.05rem 0.3rem;
}
.manual-body code::before,
.manual-body code::after { content: none; }
.manual-body pre code {
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
  border: 0;
  background: none;
  padding: 0;
}

/* 화면 → 사용법 문서 링크(COLLA-234) — 제목 옆에 작게. 눌러야 알 수 있는 자리가 아니라
   "여기 설명이 있다"를 알리는 자리라 제목의 무게를 가져가지 않게 둔다. */
.page-title-row {
  display: flex;
  align-items: baseline;
  flex-wrap: wrap;
  gap: 0.625rem;
}
.page-help-link {
  display: inline-flex;
  align-items: center;
  gap: 0.25rem;
  font-size: 0.8125rem;
  color: var(--text-muted);
  text-decoration: none;
  transition: color var(--transition-fast);
}
.page-help-link:hover {
  color: var(--text-primary);
  text-decoration: underline;
}

/* 소제목 앵커(COLLA-234) — 소제목마다 그 자리를 가리키는 주소를 만든다. 평소에는 보이지 않고
   소제목에 마우스를 올리거나 키보드 포커스가 닿을 때 나타난다. */
.manual-body .manual-heading {
  position: relative;
}
.manual-anchor {
  position: absolute;
  left: -1.125rem;
  top: 0;
  width: 1.125rem;
  color: var(--text-tertiary);
  text-decoration: none;
  opacity: 0;
  transition: opacity var(--transition-fast);
}
.manual-heading:hover .manual-anchor,
.manual-anchor:focus-visible { opacity: 1; }
.manual-anchor:hover { color: var(--text-secondary); }
/* 왼쪽 여백이 없는 좁은 화면에서는 제목 뒤에 붙인다. */
@media (max-width: 60rem) {
  .manual-anchor {
    position: static;
    margin-left: 0.375rem;
    width: auto;
  }
}

/* 사용법 문서의 화면 이미지 — 소개 페이지의 액자와 같은 모양이다(COLLA-234). */
.manual-shot {
  margin: 1.25rem 0;
  border: 1px solid var(--border-default);
  border-radius: var(--radius-md);
  overflow: hidden;
  background: var(--surface-0, #fff);
  box-shadow: var(--shadow-card);
}
.manual-shot img {
  display: block;
  width: 100%;
  height: auto;
  margin: 0;
}
@media (max-width: 48rem) {
  .manual-shot {
    overflow-x: auto;
    max-width: 100%;
  }
  .manual-shot img {
    /* 2배로 찍었으니 34rem 로 그려도 선명하다 — 칸 폭에 맞추면 글자를 못 읽는다. */
    width: 34rem;
    max-width: none;
  }
}

/* 사용 안내 골격(COLLA-234) — 사이드바 + 본문. 도움말 센터의 통용 구조다. */
.manual-shell {
  display: grid;
  grid-template-columns: 17rem 1fr;
  gap: 2.5rem;
  max-width: 68rem;
  margin: 0 auto;
  padding: 1.5rem 1rem 4rem;
  align-items: start;
}
.manual-sidebar {
  position: sticky;
  top: 1.5rem;
  display: flex;
  flex-direction: column;
  gap: 1rem;
}
.manual-search {
  position: relative;
}
.manual-search-input {
  width: 100%;
  padding-right: 3rem;
}
.manual-search-hint {
  position: absolute;
  right: 0.6rem;
  top: 50%;
  transform: translateY(-50%);
  font-size: 0.6875rem;
  color: var(--text-tertiary);
  background: var(--surface-2);
  border: 1px solid var(--border-subtle);
  border-radius: var(--radius-sm);
  padding: 0.1rem 0.3rem;
  pointer-events: none;
}
.manual-search-results {
  display: flex;
  flex-direction: column;
  gap: 0.25rem;
}
.manual-search-results.hidden,
.manual-search-results[hidden] { display: none !important; }
.manual-nav[hidden] { display: none !important; }
.manual-search-hit {
  display: block;
  padding: 0.5rem 0.625rem;
  border-radius: var(--radius-sm);
  text-decoration: none;
  border: 1px solid transparent;
}
.manual-search-hit.is-active,
.manual-search-hit:hover {
  background: var(--surface-2);
  border-color: var(--border-default);
}
.manual-search-hit-name {
  display: block;
  font-size: 0.875rem;
  font-weight: 600;
  color: var(--text-primary);
}
.manual-search-hit-context {
  display: block;
  font-size: 0.75rem;
  color: var(--text-tertiary);
  line-height: 1.5;
  margin-top: 0.125rem;
}
.manual-search-empty {
  font-size: 0.8125rem;
  color: var(--text-tertiary);
  margin: 0.5rem 0.25rem;
}
.manual-nav {
  display: flex;
  flex-direction: column;
  gap: 1.25rem;
}
.manual-nav-group + .manual-nav-group {
  margin-top: 0;
}
.manual-nav-group-title {
  display: flex;
  align-items: center;
  gap: 0.375rem;
  font-size: 0.75rem;
  font-weight: 700;
  color: var(--text-tertiary);
  letter-spacing: 0.02em;
  margin-bottom: 0.375rem;
}
.manual-nav-count {
  font-weight: 500;
  color: var(--text-tertiary);
  background: var(--surface-2);
  border-radius: 999px;
  padding: 0 0.375rem;
}
.manual-nav-list {
  list-style: none;
  margin: 0;
  padding: 0;
}
.manual-nav-link {
  display: block;
  padding: 0.3125rem 0.5rem;
  margin-left: -0.5rem;
  border-radius: var(--radius-sm);
  font-size: 0.875rem;
  color: var(--text-secondary);
  text-decoration: none;
  line-height: 1.5;
}
.manual-nav-link:hover {
  background: var(--surface-2);
  color: var(--text-primary);
}
.manual-nav-link.is-current {
  background: var(--surface-2);
  color: var(--text-primary);
  font-weight: 600;
}
.manual-main {
  min-width: 0;
}
.manual-page-head {
  margin-bottom: 2rem;
}
.manual-h1 {
  font-size: 1.75rem;
  font-weight: 700;
  color: var(--text-primary);
  margin: 0 0 0.5rem;
}
.manual-lead {
  color: var(--text-secondary);
  margin: 0;
}
.manual-group {
  margin-bottom: 2.5rem;
}
.manual-group-title {
  font-size: 1.0625rem;
  font-weight: 700;
  margin: 0 0 0.25rem;
}
.manual-group-desc {
  font-size: 0.875rem;
  color: var(--text-secondary);
  margin: 0 0 0.75rem;
}
.manual-cards {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  gap: 0.5rem;
}
.manual-card {
  display: block;
  padding: 0.875rem 1rem;
  border: 1px solid var(--border-default);
  border-radius: var(--radius-md);
  background: var(--surface-0, #fff);
  text-decoration: none;
}
.manual-card:hover {
  border-color: var(--primary);
  background: var(--surface-2);
}
.manual-card-name {
  display: block;
  font-weight: 600;
  color: var(--text-primary);
  margin-bottom: 0.1875rem;
}
.manual-card-summary {
  display: block;
  font-size: 0.8125rem;
  color: var(--text-secondary);
  line-height: 1.6;
}
.manual-crumbs {
  display: flex;
  align-items: center;
  gap: 0.375rem;
  font-size: 0.8125rem;
  color: var(--text-tertiary);
  margin-bottom: 1.25rem;
}
.manual-crumb-link {
  color: var(--text-secondary);
  text-decoration: none;
}
.manual-crumb-link:hover { text-decoration: underline; }
.manual-crumb-sep { color: var(--text-tertiary); }
.manual-crumb-current { color: var(--text-tertiary); }
.manual-pager {
  display: flex;
  gap: 0.75rem;
  margin-top: 3rem;
  padding-top: 1.5rem;
  border-top: 1px solid var(--border-subtle);
}
.manual-pager-link {
  flex: 1;
  padding: 0.75rem 1rem;
  border: 1px solid var(--border-default);
  border-radius: var(--radius-md);
  text-decoration: none;
}
.manual-pager-link:hover { background: var(--surface-2); }
.manual-pager-next { text-align: right; }
.manual-pager-dir {
  display: block;
  font-size: 0.75rem;
  color: var(--text-tertiary);
}
.manual-pager-name {
  display: block;
  font-size: 0.875rem;
  font-weight: 600;
  color: var(--text-primary);
}

/* 목차를 여는 버튼과 드로어 머리글 — 넓은 화면에는 없다(목차가 늘 보인다). */
.manual-nav-toggle,
.manual-sidebar-head { display: none; }

/* 좁은 화면 — 목차가 본문 위에 쌓이는 대신 왼쪽 드로어로 열린다.
   쌓았을 때는 문서를 열면 첫 화면이 통째로 목차였고 본문이 그 아래로 밀렸다. */
@media (max-width: 60rem) {
  .manual-shell {
    grid-template-columns: 1fr;
    gap: 1rem;
  }
  .manual-nav-toggle {
    display: inline-flex;
    align-items: center;
    gap: 0.375rem;
    /* 그리드 칸을 다 채우면 버튼이 배너처럼 보인다 — 글자만큼만 차지한다. */
    justify-self: start;
    align-self: start;
    padding: 0.4375rem 0.75rem;
    border: 1px solid var(--border-default);
    border-radius: var(--radius-md);
    background: var(--surface-0, #fff);
    font-size: 0.8125rem;
    color: var(--text-secondary);
    cursor: pointer;
  }
  .manual-nav-toggle:hover { background: var(--surface-2); }
  .manual-sidebar {
    position: fixed;
    inset: 0 auto 0 0;
    /* 상단 헤더가 50 이다 — 드로어는 그 위, 배경(mobile-drawer-overlay)은 그 사이. */
    z-index: 51;
    width: min(20rem, 86vw);
    padding: 1rem;
    gap: 0.875rem;
    background: var(--surface-0, #fff);
    border-right: 1px solid var(--border-default);
    overflow-y: auto;
    transform: translateX(-100%);
    visibility: hidden;
    transition: transform 200ms ease, visibility 200ms ease;
  }
  .manual-sidebar.mobile-drawer-open {
    transform: translateX(0);
    visibility: visible;
    box-shadow: var(--shadow-overlay);
  }
  .manual-sidebar-head {
    display: flex;
    align-items: center;
    justify-content: space-between;
    padding-bottom: 0.75rem;
    border-bottom: 1px solid var(--border-subtle);
  }
  .manual-sidebar-title {
    font-size: 0.875rem;
    font-weight: 700;
    color: var(--text-tertiary);
  }
  .manual-sidebar-close {
    display: inline-flex;
    padding: 0.375rem;
    border-radius: var(--radius-sm);
    color: var(--text-secondary);
    cursor: pointer;
  }
  .manual-sidebar-close:hover { background: var(--surface-2); }
  /* 좁은 화면에서 ⌘K 는 안내가 아니라 장식이다. */
  .manual-search-hint { display: none; }
  .manual-search-input { padding-right: 0.75rem; }
}

/* 우측 목차(COLLA-234) — 문서의 모양을 한눈에 보여 주고 지금 읽는 절을 표시한다.
   좁은 화면에서는 사라진다: 본문 폭을 빼앗으면 읽기가 더 나빠진다. */
.manual-with-toc {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: 2rem;
}
.manual-toc { display: none; }
@media (min-width: 78rem) {
  .manual-with-toc { grid-template-columns: minmax(0, 1fr) 12rem; }
  .manual-toc {
    display: block;
    position: sticky;
    top: 1.5rem;
    align-self: start;
    max-height: calc(100vh - 3rem);
    overflow-y: auto;
  }
}
.manual-toc-title {
  font-size: 0.75rem;
  font-weight: 700;
  color: var(--text-tertiary);
  margin-bottom: 0.5rem;
}
.manual-toc-list {
  list-style: none;
  margin: 0;
  padding: 0;
  border-left: 1px solid var(--border-subtle);
}
.manual-toc-link {
  display: block;
  padding: 0.25rem 0 0.25rem 0.75rem;
  margin-left: -1px;
  border-left: 2px solid transparent;
  font-size: 0.8125rem;
  line-height: 1.5;
  color: var(--text-tertiary);
  text-decoration: none;
}
.manual-toc-link:hover { color: var(--text-secondary); }
.manual-toc-link.is-current {
  color: var(--text-primary);
  border-left-color: var(--primary);
  font-weight: 600;
}

/* 서비스 소개(COLLA-234) — 유형별 한 장. 마크다운이 아니라 뷰라서 히어로·대조표·순서를
   쓸 수 있다. 구성은 B2B 제품 소개의 통용 순서다(히어로 → 대조 → 순서 → 언어 → 시작하기). */
.guide {
  max-width: 60rem;
  margin: 0 auto;
  padding: 3rem 1.5rem 4.5rem;
}
.guide-hero { text-align: center; }
.guide-eyebrow {
  display: inline-block;
  padding: 0.1875rem 0.625rem;
  border-radius: var(--radius-full);
  background: var(--surface-2);
  font-size: 0.75rem;
  font-weight: 700;
  letter-spacing: 0.02em;
  color: var(--text-secondary);
  margin-bottom: 1rem;
}
.guide-title {
  font-size: 2.5rem;
  font-weight: 700;
  color: var(--text-primary);
  letter-spacing: -0.02em;
  margin: 0 0 1rem;
  line-height: 1.15;
}
.guide-lead {
  font-size: 1.0625rem;
  color: var(--text-secondary);
  line-height: 1.75;
  margin: 0 auto 1.75rem;
  max-width: 36rem;
}
.guide-hero-actions {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  align-items: center;
  gap: 1.25rem;
}
.guide-hero-link,
.guide-cta-link {
  font-size: 0.875rem;
  color: var(--text-secondary);
  text-decoration: underline;
  text-underline-offset: 3px;
  transition: color var(--transition-fast);
}
.guide-hero-link:hover,
.guide-cta-link:hover { color: var(--text-primary); }

/* 요약 — 카드 세 장이 아니라 실선으로 나눈 한 줄 띠다. 카드가 이어지면 히어로 아래가
   곧바로 격자가 되어 무엇이 중요한지 흐려진다. */
.guide-facts {
  list-style: none;
  margin: 2.5rem 0 0;
  padding: 1.25rem 0 0;
  border-top: 1px solid var(--border-subtle);
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  text-align: left;
}
.guide-fact { padding: 0 1.25rem; }
.guide-fact + .guide-fact { border-left: 1px solid var(--border-subtle); }
.guide-fact-label {
  display: block;
  font-size: 0.9375rem;
  font-weight: 700;
  color: var(--text-primary);
  margin-bottom: 0.25rem;
}
.guide-fact-desc {
  display: block;
  font-size: 0.8125rem;
  color: var(--text-muted);
  line-height: 1.6;
}

.guide-section { margin-top: 4rem; }
.guide-section-title {
  font-size: 1.5rem;
  font-weight: 700;
  color: var(--text-primary);
  letter-spacing: -0.01em;
  margin: 0 0 1.25rem;
}

/* 지금과 대조 — 왼쪽은 겪는 일(회색), 오른쪽은 그 자리를 대신하는 것(흰 바탕 + 체크).
   불편만 늘어놓으면 무엇이 나아지는지 읽는 사람이 짐작해야 한다. */
.guide-shift {
  border: 1px solid var(--border-default);
  border-radius: var(--radius-lg);
  overflow: hidden;
  background: var(--surface-0, #fff);
}
.guide-shift-head {
  display: grid;
  grid-template-columns: 1fr 1fr;
  background: var(--surface-1);
  border-bottom: 1px solid var(--border-default);
}
.guide-shift-head-before,
.guide-shift-head-after {
  padding: 0.625rem 1.25rem;
  font-size: 0.75rem;
  font-weight: 700;
  letter-spacing: 0.04em;
}
.guide-shift-head-before { color: var(--text-muted); }
.guide-shift-head-after {
  color: var(--text-primary);
  border-left: 1px solid var(--border-default);
}
.guide-shift-row {
  display: grid;
  grid-template-columns: 1fr 1fr;
}
.guide-shift-row + .guide-shift-row { border-top: 1px solid var(--border-subtle); }
.guide-shift-before,
.guide-shift-after {
  margin: 0;
  padding: 1rem 1.25rem;
  font-size: 0.9375rem;
  line-height: 1.65;
}
.guide-shift-before {
  background: var(--surface-1);
  color: var(--text-muted);
}
.guide-shift-after {
  display: flex;
  align-items: flex-start;
  gap: 0.5rem;
  border-left: 1px solid var(--border-default);
  color: var(--text-primary);
}
.guide-shift-check {
  flex-shrink: 0;
  margin-top: 0.1875rem;
  color: var(--status-success-dark);
}

/* 실제로 하는 일 — 번호가 세로선에 꿰여 순서로 읽힌다. */
.guide-steps {
  position: relative;
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  /* **`minmax(0, 1fr)` 이 필요하다.** 그리드 항목의 기본 최소 폭은 내용 크기라, 안에 든 화면
     이미지가 칸을 늘려 목록이 화면 밖으로 삐져나갔다(실측: 항목 594px, 화면 375px). */
  grid-template-columns: minmax(0, 1fr);
  gap: 1.75rem;
}
.guide-steps::before {
  content: "";
  position: absolute;
  left: 0.9375rem;
  top: 1.75rem;
  bottom: 1.75rem;
  width: 1px;
  background: var(--border-default);
}
.guide-step {
  position: relative;
  display: flex;
  gap: 1.125rem;
  min-width: 0;
}
.guide-step-num {
  position: relative;
  z-index: 1;
  display: flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
  width: 1.875rem;
  height: 1.875rem;
  border-radius: var(--radius-full);
  background: var(--primary);
  color: var(--text-inverse);
  font-size: 0.8125rem;
  font-weight: 700;
}
.guide-step-body {
  min-width: 0;
  max-width: 46rem;
  padding-bottom: 0.25rem;
}
.guide-step-title {
  font-size: 1.0625rem;
  font-weight: 700;
  color: var(--text-primary);
  margin: 0.1875rem 0 0.5rem;
}
.guide-step-desc {
  color: var(--text-secondary);
  line-height: 1.75;
  margin: 0;
}
/* 단계별 화면 이미지 — 2배로 찍어 폭을 줄여 넣는다. 테두리로 화면임을 알린다. */
.guide-shot {
  margin: 0.875rem 0 0;
  border: 1px solid var(--border-default);
  border-radius: var(--radius-md);
  overflow: hidden;
  background: var(--surface-0, #fff);
  box-shadow: var(--shadow-card);
}
.guide-shot img {
  display: block;
  width: 100%;
  height: auto;
}
.guide-step-link {
  display: inline-flex;
  align-items: center;
  gap: 0.25rem;
  margin-top: 0.75rem;
  padding: 0.375rem 0.75rem;
  border: 1px solid var(--border-default);
  border-radius: var(--radius-full);
  background: var(--surface-0, #fff);
  font-size: 0.8125rem;
  color: var(--text-secondary);
  text-decoration: none;
  transition: border-color var(--transition-fast), background-color var(--transition-fast), color var(--transition-fast);
}
.guide-step-link:hover {
  border-color: var(--border-strong);
  background: var(--surface-hover);
  color: var(--text-primary);
}

/* 여러 언어 — 말로만 두지 않고 지원 언어를 칩으로 보여 준다. */
.guide-lang {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  gap: 2rem;
  align-items: center;
  padding: 1.75rem;
  border: 1px solid var(--border-default);
  border-radius: var(--radius-lg);
  background: var(--surface-0, #fff);
}
.guide-lang-text { min-width: 0; }
.guide-lang .guide-section-title {
  font-size: 1.25rem;
  margin-bottom: 0.5rem;
}
.guide-lang-desc {
  color: var(--text-secondary);
  line-height: 1.75;
  margin: 0;
  max-width: 34rem;
}
.guide-lang-chips {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-wrap: wrap;
  gap: 0.5rem;
  max-width: 12rem;
}
.guide-lang-chip {
  display: inline-flex;
  align-items: center;
  gap: 0.375rem;
  padding: 0.375rem 0.75rem;
  border: 1px solid var(--border-default);
  border-radius: var(--radius-full);
  background: var(--surface-1);
  font-size: 0.8125rem;
  color: var(--text-secondary);
}

.guide-cta {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  gap: 2rem;
  align-items: center;
  margin-top: 4rem;
  padding: 2rem;
  border: 1px solid var(--border-default);
  border-radius: var(--radius-lg);
  background: var(--surface-1);
}
.guide-cta-text { min-width: 0; }
.guide-cta-title {
  font-size: 1.375rem;
  font-weight: 700;
  color: var(--text-primary);
  margin: 0 0 0.5rem;
}
.guide-cta-lead {
  color: var(--text-secondary);
  line-height: 1.75;
  margin: 0;
  max-width: 34rem;
}
.guide-cta-actions {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 0.75rem;
}

@media (max-width: 56rem) {
  .guide-lang,
  .guide-cta {
    grid-template-columns: minmax(0, 1fr);
    gap: 1.25rem;
  }
  .guide-lang-chips { max-width: none; }
  .guide-cta-actions { align-items: flex-start; }
}

/* 좁은 화면 — 대조표는 두 칸을 나란히 둘 수 없다. 위에 지금, 아래에 대신하는 것을 쌓고
   묶음 제목은 접는다(체크 표시가 어느 쪽인지 말해 준다). */
@media (max-width: 48rem) {
  .guide { padding: 2rem 1rem 3rem; }
  .guide-title { font-size: 1.875rem; }
  .guide-facts {
    grid-template-columns: minmax(0, 1fr);
    gap: 1rem;
  }
  .guide-fact { padding: 0; }
  .guide-fact + .guide-fact {
    border-left: 0;
    border-top: 1px solid var(--border-subtle);
    padding-top: 1rem;
  }
  .guide-section-title { font-size: 1.25rem; }
  .guide-shift-head { display: none; }
  .guide-shift-row { grid-template-columns: minmax(0, 1fr); }
  /* 두 칸 사이의 선은 지운다 — 회색(지금)과 흰 바탕(대신하는 것)의 톤 차이가 이미 나누고,
     선까지 있으면 쌍의 경계와 칸의 경계가 같은 굵기라 무엇이 한 쌍인지 흐려진다. */
  .guide-shift-after { border-left: 0; }
  /* 화면 이미지는 폭에 맞춰 줄이면 글자가 안 읽힌다 — 액자 안에서 옆으로 밀어 본다
     (본문은 절대 가로로 밀리지 않는다). */
  .guide-shot {
    overflow-x: auto;
    /* 액자가 칸을 넘지 못하게 못 박는다 — 이걸 빼면 이미지 폭이 단계 칸을 늘려서
       본문 문단이 화면 밖으로 잘렸다(실측: 문단 폭 546px, 화면 375px). */
    width: 100%;
    max-width: 100%;
  }
  .guide-shot img {
    /* 2배로 찍었으니 34rem 로 그려도 선명하다. `auto` 로 두면 원본 폭(2100px 대)이 그대로 서서
       글자가 거대해진다(실측). */
    width: 34rem;
    max-width: none;
  }
  .guide-shift-row + .guide-shift-row { border-top-color: var(--border-strong); }
}
}
