/* 관리 앱 전용 스타일. 공개 사이트와 같은 공유 토큰(/shared/tokens.css)을 쓴다.
   색·폭·라운드는 항상 커스텀 속성을 참조한다 — 값을 직접 적지 않는다.
   관리 화면임을 한눈에 구분하도록 헤더 배경만 반전시키고 나머지 토큰은
   그대로 쓴다. */

.admin-header {
  background: var(--brand-deep);
  border-bottom: 1px solid var(--brand-deep);
  box-shadow: var(--shadow-sm);
}
.admin-header .wrap {
  display: flex;
  align-items: center;
  justify-content: space-between;
}
.admin-header .site-title {
  color: var(--on-brand);
}
/* 사이트명과 메뉴를 한 덩어리로 묶는다 — .admin-header .wrap 이
   space-between 이라, 묶지 않으면 자식이 셋이 되어 메뉴가 헤더 한가운데로
   떠 버린다(로고 옆에 붙어야 메뉴로 읽힌다). */
.admin-brand {
  display: flex;
  align-items: center;
  gap: var(--sp-5);
  min-width: 0;
}
.admin-nav {
  display: flex;
  align-items: center;
  gap: var(--sp-4);
}
.admin-nav a {
  color: var(--on-brand);
  text-decoration: none;
  font-size: var(--fs-sm);
  font-weight: 600;
  padding: var(--sp-2) 0;
  /* 현재 위치 밑줄과 같은 두께의 투명 선을 평소에도 깔아 둔다 —
     hover·선택 때 선이 새로 생기면 글자가 위아래로 흔들린다. */
  border-bottom: 2px solid transparent;
  opacity: 0.85;
}
.admin-nav a:hover,
.admin-nav a:focus-visible {
  opacity: 1;
  border-bottom-color: var(--on-brand);
}
.admin-nav a[aria-current="page"] {
  opacity: 1;
  border-bottom-color: var(--on-brand);
}
.admin-logout {
  margin: 0;
}
.admin-logout .btn {
  background: transparent;
  border-color: var(--on-brand);
  color: var(--on-brand);
}
.admin-logout .btn:hover {
  background: var(--on-brand);
  color: var(--brand-deep);
}

/* ── 로그인 화면 ─────────────────────────────────────────── */

/* ★UI 리뷰 2026-08-12(2차) — 카드가 화면 위쪽 40% 언저리에 뜨고 그 아래로
   빈 캔버스만 이어져 페이지가 아직 덜 채워진 것처럼 보였다. 로그인은
   본문이 카드 하나뿐인 유일한 화면이라 세로 가운데 정렬이 자연스럽다 —
   다른 화면의 <main class="wrap"> 은 전혀 건드리지 않고 이 페이지 안에서만
   flex 로 가운데로 당긴다. min-height 는 정확한 헤더·푸터 높이를 px로
   계산하지 않고 60vh 로 여유 있게 잡아, 화면 크기가 달라져도 카드가
   푸터에 붙거나 위로 치우치지 않게 한다. */
.login-page {
  max-width: 420px;
  min-height: 60vh;
  margin: var(--sp-6) auto;
  display: flex;
  flex-direction: column;
  justify-content: center;
}
.login-page h1 {
  text-align: center;
}
.login-card .field:last-of-type {
  margin-bottom: var(--sp-4);
}
.login-error {
  margin-bottom: var(--sp-4);
}
.login-card .btn-primary {
  width: 100%;
}

@media (max-width: 768px) {
  /* 좁은 화면에서는 60vh 가운데 정렬이 오히려 카드를 화면 아래로 밀어
     첫 화면에 폼이 안 보일 수 있다 — 위에서부터 자연스럽게 쌓이게 되돌린다. */
  .login-page {
    min-height: 0;
    display: block;
    margin: var(--sp-4) auto;
  }
}

/* ── 지원자 목록 ─────────────────────────────────────────── */

.applications-filter {
  /* 필터 축이 열대여섯 개로 늘어 한 줄에 다 못 넣는다 — 줄(.filter-row)
     단위로 쌓고, 각 줄 안에서만 가로로 배분한다. */
  display: flex;
  flex-direction: column;
  gap: var(--sp-3);
}
.filter-row {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-end;
  gap: var(--sp-3);
}
.applications-filter .field {
  /* 고정 px 폭 대신 flex-grow 로만 배분한다 — 토큰에 폭 값이 없어
     리터럴을 쓰지 않으려면 콘텐츠 크기 기반으로 늘어나게 두는 편이 낫다.
     ★min-width: 0 이 없으면 좁은 화면에서 flex 자식이 콘텐츠 최소 폭
     아래로 못 줄어 페이지가 가로로 밀린다. */
  margin-bottom: 0;
  flex: 1 1 auto;
  min-width: 0;
}
.applications-filter .field-grow { flex: 3 1 auto; }
/* 체크박스 칸은 라벨 길이만큼만 차지한다 — flex: 1 1 auto 를 그대로 물려받으면
   좁은 칸에 갇혀 "학점 미기재도 포함"이 세 줄로 접힌다(실측). 늘어나지도
   줄어들지도 않게 두고 줄바꿈을 막는다. */
.applications-filter .field-check {
  display: flex;
  align-items: center;
  flex: 0 0 auto;
  align-self: flex-end;
  padding-bottom: var(--sp-2);
}
.applications-filter .field-check label {
  display: flex;
  align-items: center;
  gap: var(--sp-2);
  margin: 0;
  white-space: nowrap;
}

/* 상세 필터는 <details> 로 접는다 — JS 없이 동작하고, CSP(default-src
   'self') 아래에서 인라인 스크립트를 못 쓰는 제약과도 맞는다. */
.filter-more {
  border-top: 1px solid var(--line);
  padding-top: var(--sp-3);
}
.filter-more > summary {
  cursor: pointer;
  font-weight: 600;
  color: var(--ink);
  display: flex;
  align-items: center;
  gap: var(--sp-2);
}
.filter-more > summary:focus-visible {
  outline: 2px solid var(--brand-mid);
  outline-offset: 2px;
}
.filter-more > .filter-row { margin-top: var(--sp-3); }

.filter-actions {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--sp-3);
}
/* 걸린 조건이 있는 목록을 전체라고 오해하지 않도록 항상 건수를 보여준다. */
.filter-count {
  margin: 0;
  margin-left: auto;
  color: var(--ink-2);
  font-size: var(--fs-sm);
}

/* 행 전체를 클릭 가능하게 한다 — 접수번호 셀의 링크는 JS 없는 환경을 위한 대비다.
   호버는 base.css 의 일반 표 줄무늬(--bg-soft)보다 뚜렷한 --brand-pale 로
   덮어써서, 가장 자주 쓰는 화면답게 "지금 어느 행 위에 있는지"가 바로
   보이게 한다(대비 11.78:1 — 위 애플리케이션 상태 배지와 같은 계열). */
.applications-row {
  cursor: pointer;
  transition: background var(--motion-fast);
}
.applications-row:hover td {
  background: var(--brand-pale);
}
.applications-row td a {
  color: inherit;
  text-decoration: none;
}
/* ★UI 리뷰 2026-08 지적사항 6(보통) — 위 규칙은 이 행의 모든 링크를
   평범한 글자처럼 보이게 한다. 접수번호 셀의 링크는 그래도 된다(행
   클릭과 정확히 같은 목적지라, 링크처럼 안 보여도 잃는 게 없다) —
   하지만 "인쇄" 링크는 다르다(새 탭으로 열리는, 행 클릭과는 다른
   동작이다, /static/admin.js 참고). 다른 셀과 구분이 안 되면 새 탭이
   열린다는 걸 미리 알 길이 없다. 이 링크만 셀렉터 특이성을 높여
   (.applications-row .row-print-link, 클래스 2개 vs 위 규칙의 클래스1+
   타입2 — 클래스 개수가 더 큰 쪽이 이긴다) 원래 링크 색·밑줄을 되살린다. */
.applications-row .row-print-link {
  color: var(--brand-deep);
  text-decoration: underline;
}

/* ── 선택 PDF 다운로드(2026-09) ── 표를 감싼 폼의 버튼 줄과 체크박스 열.
   체크박스 셀은 label 이 셀을 가득 채워(display:block + 패딩) 칸 어디를
   눌러도 체크가 바뀌고, 행 클릭(상세 이동)으로 새지 않는다(admin.js 는
   input·label 위 클릭을 행 이동에서 제외한다). */
.select-actions {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--sp-3);
  margin: var(--sp-4) 0 var(--sp-3);
}
.select-hint {
  color: var(--ink-2);
  font-size: var(--fs-sm);
}
.table .select-cell {
  width: 1%;
  padding: 0;
  text-align: center;
  vertical-align: middle;
}
.table th.select-cell {
  padding: var(--sp-2) var(--sp-3);
}
.select-cell-label {
  display: block;
  padding: var(--sp-3);
  cursor: pointer;
}
.select-cell input[type="checkbox"] {
  width: 1rem;
  height: 1rem;
  margin: 0;
  cursor: pointer;
  accent-color: var(--brand-deep);
}

/* ── 지원서 상세 ─────────────────────────────────────────── */

/* ★UI 리뷰 2026-08-12(2차) — 접수번호·이름·이메일 같은 항목이 전부
   `<p><strong>라벨</strong> 값</p>` 로 나열돼 있어 라벨과 값이 굵기 하나
   차이로만 구분됐다 — 감사 실무자가 이 화면에서 하는 일은 라벨을 먼저
   훑고 값을 찾는 것인데, 문장처럼 붙어 있으면 매번 다시 읽어야 한다.
   공개 사이트 공고 상세(.job-meta-list)·이력서 인쇄본(.print-personal-list)
   이 이미 쓰는 "라벨=브랜드색 굵게 / 값=일반 톤" dt·dd 그리드를 그대로
   들여온다 — 화면 세 곳이 같은 언어를 쓰게 통일하는 것이지 새 패턴을
   만드는 게 아니다. */
.detail-list {
  display: grid;
  grid-template-columns: auto minmax(0, 1fr);
  gap: var(--sp-2) var(--sp-4);
  margin: 0;
}
/* dt/dd 쌍을 <div> 로 감싸 그리드 두 칸에 각각 배치한다 — display:contents
   로 감싸는 div 자체는 레이아웃에서 사라지고 안의 dt/dd 만 grid 를 탄다
   (.print-personal-list 와 같은 패턴). */
.detail-list > div {
  display: contents;
}
.detail-list dt {
  font-weight: 700;
  color: var(--brand-mid);
  white-space: nowrap;
}
.detail-list dd {
  margin: 0;
  overflow-wrap: break-word;
  font-variant-numeric: tabular-nums;
}

.applicant-photo {
  max-width: var(--w-photo-thumb);
  height: auto;
  border: 1px solid var(--line);
  border-radius: var(--radius-sig);
}

/* 자소서 답변은 지원자가 입력한 그대로다 — HTML로 만들지 않고
   줄바꿈만 CSS로 보존한다(|safe·nl2br 금지). */
.essay-answer {
  white-space: pre-wrap;
}

.btn-danger {
  background: var(--bg);
  border-color: var(--danger);
  color: var(--danger);
  font-weight: 700;
}
.btn-danger:hover {
  background: var(--danger-pale);
}

/* 파기 영역 — 되돌릴 수 없는 유일한 동작이라 시각적으로 분리한다. */
.application-purge {
  margin-top: var(--sp-6);
  border-color: var(--danger);
  background: var(--danger-pale);
}
.application-purge p {
  color: var(--danger);
}

/* AI 보조 고지 — 실제 AI 산출물이 있을 때만 붙는다. `.empty`(자리표시자·
   각주에 쓰는 흐린 회색)로 두면 경고가 아니라 화면 장식처럼 읽혀서, 고지를
   붙인 이유가 사라진다. */
.ai-caution {
  margin-bottom: var(--sp-4);
  padding: var(--sp-3);
  border-left: 3px solid var(--danger);
  background: var(--danger-pale);
  color: var(--ink);
  font-size: var(--fs-xs);
}

/* ── 공고 관리 ─────────────────────────────────────────── */

.jobs-header {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: var(--sp-3);
}
.jobs-header h1 {
  margin: 0;
}

.job-form textarea {
  font-family: inherit;
}

/* 자소서 문항 순서 변경 경고 — field-error(위험) 와 구분되는 주의 톤.
   --ink-2 는 본문 대비 기준(AA)을 충족하는 값이라 경고 문구에도 그대로 쓴다. */
.field-hint {
  color: var(--ink-2);
  font-size: var(--fs-sm);
  margin: 0 0 var(--sp-2);
}

/* ── 이력서 인쇄 화면(v2-5 §C) ───────────────────────────── */

.print-toolbar {
  display: flex;
  flex-wrap: wrap;
  justify-content: flex-end;
  align-items: center;
  gap: var(--sp-3);
  margin-bottom: var(--sp-4);
}
/* 안내 한 줄은 버튼과 같은 줄에 쑤셔 넣지 않는다 — 좁은 화면에서 버튼을
   밀어내 두 줄로 깨진다. 항상 아래 줄을 통째로 차지하게 둔다. */
.print-toolbar-hint {
  flex-basis: 100%;
  min-width: 0;
  margin: 0;
  text-align: right;
  color: var(--ink-2);
  font-size: var(--fs-xs);
}
/* ★UI 리뷰 2026-08 지적사항 7(사소) — 우측정렬은 넓은 화면에서는
   버튼과 나란히 있는 인상을 주지만, 좁은 화면에서 문구가 3~4줄로
   줄바꿈되면 매 줄의 시작점이 오른쪽에 맞춰져 읽는 시작 위치가 줄마다
   달라진다(왼쪽부터 읽는 한국어 문장에서 불편하다). 이 폭에서는 왼쪽
   정렬로 바꾼다 — 이 규칙이 뒤(소스 순서)에 있어 같은 특이성이면 이긴다. */
@media (max-width: 768px) {
  .print-toolbar-hint {
    text-align: left;
  }
}

/* 목록 페이지 이동 — 표 바로 아래 가운데. */
.pager {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: center;
  gap: var(--sp-3);
  margin-top: var(--sp-4);
}
.pager-status {
  color: var(--ink-2);
  font-size: var(--fs-xs);
}

/* 상세·공고 화면의 이동 버튼 줄 — 제목 바로 아래 한 줄. */
.detail-actions {
  display: flex;
  flex-wrap: wrap;
  gap: var(--sp-2);
  margin: 0 0 var(--sp-4);
}

.print-header {
  display: flex;
  gap: var(--sp-4);
  align-items: flex-start;
  margin-bottom: var(--sp-5);
}
/* 폭은 관리 화면이 이미 쓰는 썸네일 토큰(--w-photo-thumb)을 그대로
   재사용한다 — 사진 전용 새 리터럴 폭을 추가하지 않기 위해서다.
   aspect-ratio 로 3:4 비율의 높이를 따라오게 한다(applicant-photo 는
   세로형 원본을 그대로 보여주는 반면, 이 슬롯은 이력서 사진칸처럼
   고정 비율이어야 한다는 점이 다르다). */
.print-photo {
  width: var(--w-photo-thumb);
  aspect-ratio: 3 / 4;
  object-fit: cover;
  border: 1px solid var(--line);
  border-radius: var(--radius-sig);
  flex: none;
}
.print-photo-empty {
  display: flex;
  align-items: center;
  justify-content: center;
  background: var(--bg-soft);
  color: var(--ink-2);
  font-size: var(--fs-sm);
  text-align: center;
}
/* ★UI 리뷰 2026-08 지적사항 1(치명) — .print-header 는 flex 컨테이너이고
   .print-photo 는 flex: none 으로 폭이 고정돼 있다. .print-personal 은
   그 옆의 나머지 flex 자식인데 min-width 를 안 줬다 — flex 자식의 기본
   min-width 는 auto(=콘텐츠 최소 폭 아래로 못 줄어듦)라서, 사진 폭
   (--w-photo-thumb, 고정) + 긴 이메일·주소가 좁은 화면(390px)의 가용
   폭을 넘으면 줄어들지 못하고 페이지 전체가 가로로 밀린다
   (.applications-filter .field 의 같은 이유·같은 고정 패턴 참고, 위쪽
   57번째 줄 부근). */
.print-personal {
  min-width: 0;
}
.print-name {
  margin: 0 0 var(--sp-3);
}
.print-personal-list {
  display: grid;
  /* ★같은 지적사항 — grid 의 1fr 트랙도 flex 와 같은 함정이 있다:
     기본 min-width 가 auto 라 트랙 안 콘텐츠(긴 이메일 등)보다 작게
     줄어들지 못한다. minmax(0, 1fr) 로 명시적으로 풀어야 한다. */
  grid-template-columns: auto minmax(0, 1fr);
  gap: var(--sp-2) var(--sp-3);
  margin: 0;
}
/* dt/dd 쌍을 <div> 로 감싸 grid 두 칸에 각각 배치한다 — display:contents
   로 감싸는 div 자체는 레이아웃에서 사라지고 안의 dt/dd 만 grid 를 탄다. */
.print-personal-list div {
  display: contents;
}
.print-personal-list dt {
  font-weight: 700;
  color: var(--brand-mid);
}
.print-personal-list dd {
  margin: 0;
  /* ★UI 리뷰 2026-08 지적사항 1 — 위 minmax(0, 1fr) 로 트랙 자체는
     줄어들 수 있게 됐지만, 그 안의 텍스트(긴 이메일·주소 등 공백 없는
     한 토큰)는 여전히 안 쪼개진다 — 트랙 폭을 넘는 순간 그 칸만 넘친다.
     여기서 실제로 줄바꿈을 허용해야 넘침이 완전히 사라진다. */
  overflow-wrap: break-word;
}

.print-section {
  margin-bottom: var(--sp-5);
  /* ★UI 리뷰 2026-08 지적사항 2(치명) — 인쇄본은 .card 를 쓰지 않는다
     (packages/core/static/base.css 의 .card 주석 참고) — 포트폴리오
     URL 을 전문 텍스트로 그대로 보여주는 섹션(application_print.html)이
     바로 이 클래스라, 여기도 같은 방어가 필요하다. */
  overflow-wrap: break-word;
}
/* 자소서·경력기술서·기타 경험사항처럼 지원자가 직접 쓴 긴 글은
   HTML로 만들지 않고 줄바꿈만 CSS로 보존한다(|safe·nl2br 금지 — 다른
   서술 항목과 같은 원칙, application_detail.html 의 essay-answer 참고). */
.print-longtext {
  white-space: pre-wrap;
}
.print-essay + .print-essay {
  margin-top: var(--sp-4);
}
/* 인쇄본·PDF 의 AI 고지 — 흑백 출력에서도 남아야 하므로 배경색이 아니라
   테두리와 굵기로 구분한다(컬러 배경은 프린터·PDF 뷰어에 따라 사라진다). */
.print-ai-caution {
  margin-bottom: var(--sp-3);
  padding: var(--sp-2) var(--sp-3);
  border: 1px solid var(--ink-2);
  font-size: var(--fs-xs);
  font-weight: 700;
}

/* 좁은 화면에서는 사이트명 + 메뉴 두 개를 한 줄에 담을 수 없다 —
   가로로 밀려 로그아웃 버튼이 잘리는 대신 줄을 바꾼다. min-height 는
   base.css 가 60px 로 잡아 두었을 뿐 고정 높이가 아니라, 줄이 늘어나면
   헤더가 자연스럽게 같이 늘어난다. */
@media (max-width: 768px) {
  .admin-header .wrap {
    flex-wrap: wrap;
    gap: var(--sp-2) var(--sp-4);
    padding-top: var(--sp-3);
    padding-bottom: var(--sp-3);
  }
  .admin-brand {
    flex-wrap: wrap;
    gap: var(--sp-2) var(--sp-4);
  }
}

@media print {
  /* 인쇄에는 네비·버튼·푸터가 필요 없다 — 관리 화면임을 알리는
     헤더도 인쇄물에 남을 이유가 없다. */
  .site-header,
  .site-footer,
  .no-print {
    display: none !important;
  }
  .wrap {
    max-width: none;
    padding: 0;
  }
  body {
    margin: 0;
  }
  /* A4·여백은 디자인 토큰이 아니라 물리적인 종이 규격이다 — .hp-field 의
     "화면 밖" 좌표와 같은 이유로 리터럴을 그대로 쓴다. */
  @page {
    size: A4;
    margin: 16mm 14mm;
  }
  /* 섹션이 페이지 중간에서 잘리지 않게 한다. */
  .print-header,
  .print-section {
    break-inside: avoid;
  }
  /* 서술 블록(경력기술서·기타 경험사항·자기소개서)만 예외적으로 다음
     장으로 자연스럽게 흘러가도록 허용한다(스펙 §4-C) — 같은 클래스
     조합(.print-section.print-section-flow)에서는 뒤에 정의된 이 규칙이
     이긴다. */
  .print-section-flow {
    break-inside: auto;
  }
}
