/* ═══════════════════════════════════════════════════════════════════════
   CHEMTROS HR — 공통 정렬 · 크기 · 반응형 규칙 (v7.9.4 · 담당자 승인 2026-09-29)

   «콘텐츠가 UI 를 밀어내는 화면» → «정해진 자리 안에 콘텐츠가 들어가는 화면»

   지키는 것
     · 색 · 글꼴 · 버튼 종류(ds-btn · secondary · ghost …) · 카드 모양은 **기존 그대로**.
       이 파일은 정렬 · 크기 · 간격 · 반응형만 정합니다.
     · 페이지마다 CSS 를 따로 만들지 않습니다. 화면은 아래 부품과 변수(--acts 등)만 씁니다.

   공통 반응형 기준 (시스템 전체 한 벌)
     Desktop        1280px 이상      전체 정보
     Narrow         1279px 이하      우선순위 낮은 열(p2) 접기 · 두 단 → 한 단
     Compact        1199px 이하      보조 열(p1) 추가로 접기 (1024px 태블릿 · 좌측 목록이 있는 화면 포함)
     Mobile          760px 이하      표 → 카드 (responsive.css ④)
     (1700 · 1440 은 «가끔 보는 열 · 참고 열» 을 접는 기존 단계 — responsive.css ①)

   단계 : ① 목록(이 파일 1장) → ② 입력폼(2장) → ③ 카드(3장) → ④ 모달(4장)
   ═══════════════════════════════════════════════════════════════════════ */

:root {
  /* 간격 · 높이 · 둥글기 — 이 값만 씁니다 (5 · 7 · 9 · 13px 같은 임의 값 금지) */
  --gap-xs: 4px;
  --gap-sm: 6px;
  --gap-md: 10px;
  --gap-lg: 16px;
  --gap-xl: 24px;
  --btn-h-sm: 30px;
  --btn-h-md: 34px;
  --radius-sm: 6px;
  --radius-md: 8px;
  --row-h: 48px;

  /* 처리 버튼 자리 폭 — 글자 길이가 아니라 **기능 자리**마다 고정 */
  --act-xs: 46px;     /* 상세 · 삭제 · 조회 · 검사 · 회수 */
  --act-sm: 56px;     /* 검토서 · 편집 · 고치기 · 보류 */
  --act-md: 66px;     /* 미리보기 · 채용검토 · AI 분석 · 되돌리기 · 내려받기 */
  --act-lg: 84px;     /* 면접평가표 · 채용확정서 · 대상자 수정 · 면접 진행 */
  --act-xl: 104px;    /* 채용검토서 A타입 · 기존 자료 가져오기 */
  --act-2xl: 124px;   /* 메일 발송 (내부 검토자) */
  /* (버튼 글자 12px 기준 · 글자가 자리를 넘치지 않는지는 시험이 잽니다 — test_v794_ui) */
  --label-w: 120px;   /* 입력폼 라벨 폭 */
}

/* ─────────────────────── 1. 목록 : 처리 버튼 자리 (ActionGrid) ───────────────────────
   쓰는 법
     <div class="act-grid" style="--acts: var(--act-xs) var(--act-lg) var(--act-sm)">
       {{ ui.act('상세', href) }}                     ← 쓸 수 있음
       {{ ui.act('면접평가표', state='off', why='서류판정이 «면접» 일 때 쓸 수 있습니다') }}
       {{ ui.act_none() }}                             ← 권한 없음 : 빈 자리 (글자 없음)
     </div>
   · 자리 수와 폭은 **목록마다 한 번** 정하고, 모든 행이 같은 값을 씁니다.
   · 버튼이 없어져도 자리는 남습니다 → 앞쪽 버튼 위치가 흔들리지 않습니다. */
.act-grid {
  display: inline-grid;
  grid-auto-flow: column;
  grid-template-columns: var(--acts, auto);
  column-gap: var(--gap-sm);
  align-items: center;
  justify-content: end;
  vertical-align: middle;
  max-width: none;
}
.act-grid > .act, .act-grid > form > .act {
  width: 100%; min-width: 0; height: var(--btn-h-sm);
  padding: 0 4px; box-sizing: border-box;
  display: inline-flex; align-items: center; justify-content: center;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
  font-size: 12px; border-radius: var(--radius-md);
}
.act-grid > form { display: block; margin: 0; min-width: 0; }
/* 기능은 있지만 지금은 못 씀 : 보이되 흐리게 · 누르면 까닭(title) */
.act-grid .act.is-off,
.act.is-off { opacity: .42; cursor: not-allowed; }
.act.is-off:focus-visible { outline: 2px solid var(--royal, #2F5FA8); outline-offset: 1px; }
/* 권한 없음 : 자리만 (글자 · 테두리 없음 — 기능의 존재를 드러내지 않음) */
.act-grid > .act-none { display: block; width: 100%; height: var(--btn-h-sm); visibility: hidden; }

/* 선택(체크) 열 : 체크상자 크기만 — 예전 .row-check { width:34px } 가 여백까지 더해 53px 을 차지했습니다 */
.ds-table td > input[type=checkbox], .ds-table th > input[type=checkbox] { width: auto; margin: 0; vertical-align: middle; }

/* 긴 글 한 줄 + … (마우스를 올리면 title 로 전체) */
.cell-ellipsis { display: block; min-width: 0; max-width: 100%; overflow: hidden;
  text-overflow: ellipsis; white-space: nowrap; }

/* 목록 행 높이 : 버튼이 두 줄로 내려가지 않으므로 행 높이가 같게 유지됩니다 */
.ds-table td .act-grid { white-space: nowrap; }

/* 1440px 미만 : 버튼 사이 간격만 줄입니다 (버튼 자리 폭은 그대로) */
@media (max-width: 1439px) {
  .act-grid { column-gap: var(--gap-xs); }
}

/* 좁은 화면 : 처리 버튼 영역은 **한 줄 유지** — 목록 전체가 표 안에서 가로로 밀립니다 */
@media (max-width: 760px) {
  table[data-stack] td .act-grid { justify-content: start; }
  /* v7.9.6 담당자 지시 «오른쪽 끝 버튼이 잘려 보이지 않는다» — 카드 모양에서는 버튼을 **줄바꿈**합니다.
     (자리 고정은 여러 행을 나란히 볼 때의 규칙이라, 한 장씩 보는 카드에는 필요 없습니다) */
  table[data-stack] tbody td .act-grid {
    display: flex; flex-wrap: wrap; gap: 6px; flex: 1 1 auto; min-width: 0; white-space: normal;
  }
  table[data-stack] tbody td .act-grid > .act,
  table[data-stack] tbody td .act-grid > form > .act { width: auto; padding: 0 10px; overflow: visible; }
  table[data-stack] tbody td .act-grid > .act-none { display: none; }
}

/* 휴대폰(760px 이하) 머리띠 : 오른쪽 묶음(버전 · 주소 · 이름 · 로그아웃)이 화면 밖(476px)으로 밀려
   **로그아웃 버튼이 보이지 않던** 문제 (v7.9.4 측정). 줄을 바꿔 화면 안에 둡니다 · 사내 주소는 줄여 보입니다. */
@media (max-width: 760px) {
  .ds-header { flex-wrap: wrap; row-gap: var(--gap-sm); }
  .ds-header .ds-hd-right { flex-wrap: wrap; row-gap: var(--gap-xs); min-width: 0; max-width: 100%; }
  .ds-header .ds-hd-right .ds-badge { max-width: 100%; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
}

/* ─────────────────────── 2. 입력폼 ───────────────────────
   · 라벨 : 입력칸 위 · 12px · 굵게 (bridge.css .ds-label) — 한 줄 최소 높이 확보로 옆 칸과 입력칸 시작선이 맞습니다.
   · 필수 표시 : 라벨 안 <em class="req">필수</em> (글자로 표시 · 색만으로 알리지 않음)
   · 도움말 · 오류 : 입력칸 **아래** 한 곳 (.ds-help / .field-err)
   · 버튼줄 : 폼 맨 아래 · 왼쪽 정렬 · 간격 --gap-md
   · 두 단 입력 화면(처우산정 등)은 Narrow(1279px 이하)에서 한 단 — 화면 폭이 아니라 칸 폭으로 나뉘는 부품은 @container */
.ds-label em.req, .ds-form-field > label em.req { font-style: normal; font-size: 10.5px; font-weight: 700; }
.ds-form-field > .ds-help, .ds-form-field > .field-err { margin: 0; }
.field-err { font-size: 11.5px; line-height: 1.5; color: var(--st1, #B42318); }
.ds-btn-row { display: flex; flex-wrap: wrap; align-items: center; gap: var(--gap-md); }
/* 한글 낱말 단위 줄바꿈 (입력폼 · 카드의 설명 글) */
.ds-form, .ds-card, .ds-help { word-break: keep-all; overflow-wrap: break-word; }

/* ─────────────────────── 3. 카드 ───────────────────────
   같은 무리의 카드는 **같은 높이** : 제목 줄 · 본문 시작선 · 바닥 버튼 위치가 카드마다 같아야 합니다.
   · 설명 글은 정해진 줄 수만 보이고 나머지는 … (마우스를 올리면 title 로 전체) → 글 길이가 카드 높이를 바꾸지 않습니다.
   · 줄 수만큼 자리를 늘 확보(min-height) → 짧은 글의 카드도 같은 높이. */
.ui-clamp2, .ui-clamp3 { display: -webkit-box; -webkit-box-orient: vertical; overflow: hidden; }
.ui-clamp2 { -webkit-line-clamp: 2; line-clamp: 2; min-height: calc(2 * 1.5em); line-height: 1.5; }
.ui-clamp3 { -webkit-line-clamp: 3; line-clamp: 3; min-height: calc(3 * 1.5em); line-height: 1.5; }
/* 카드 안 바닥 버튼줄 : 카드 맨 아래에 붙습니다 (본문 길이와 상관없이 같은 위치) */
.ui-card-stack { display: flex; flex-direction: column; }
.ui-card-stack > .ui-card-foot { margin-top: auto; padding-top: var(--gap-md); display: flex; gap: var(--gap-sm); flex-wrap: wrap; }

/* ─────────────────────── 4. 모달 ───────────────────────
   · 제목줄 : 제목 왼쪽 · 닫기(×) 오른쪽 한 줄 · 본문이 길어 스크롤해도 **제목줄은 위에 남습니다**
   · 본문 : 모달 상자 안에서만 스크롤 (화면 높이 88% 까지 — bridge.css)
   · 버튼줄 : 모달 맨 아래 · 왼쪽 정렬 · 순서는 시스템 전체 한 가지 «실행(확인) → 취소»
             (지금 모든 모달이 이 순서입니다 — 바꾸지 않고 규칙으로 고정 · test_v794_ui 가 검사)
             본문이 길어도 맨 아래 버튼줄은 **아래에 붙어 보입니다**
   · 좁은 화면(760px 이하) : 바깥 여백 12px · 상자 안 여백 18px · 폭은 화면 폭 - 24px */
.modal-box .modal-header {
  display: flex; align-items: center; justify-content: space-between; gap: var(--gap-md);
  position: sticky; top: -24px; z-index: 2; background: #fff;
  margin: -24px -24px 12px; padding: 18px 24px 10px;
}
.modal-box .modal-header h2 { margin: 0; font-size: 17px; min-width: 0; }
.modal-box .modal-close { flex: none; width: 32px; height: 32px; line-height: 1; border-radius: var(--radius-md); }
.modal-box > .ds-btn-row:last-child,
.modal-box > form:last-child > .ds-btn-row:last-child,
.modal-box .modal-foot {   /* 부품(partial) 안에 있어 «마지막 줄» 로 못 찾는 버튼줄은 modal-foot 로 표시 */
  position: sticky; bottom: -24px; z-index: 2; background: #fff;
  margin-bottom: -24px; padding: var(--gap-md) 0 18px;
}
@media (max-width: 760px) {
  .modal-overlay { padding: 12px; }
  .modal-box { padding: 18px; max-width: calc(100vw - 24px) !important; }
  .modal-box .modal-header { top: -18px; margin: -18px -18px 10px; padding: 14px 18px 8px; }
  .modal-box > .ds-btn-row:last-child,
  .modal-box > form:last-child > .ds-btn-row:last-child,
  .modal-box .modal-foot { bottom: -18px; margin-bottom: -18px; padding-bottom: 14px; }
}
