/* ============================================================
   components.css — 공통 컴포넌트
   확장 카드(아코디언) · 라이트박스 · 연도 드롭다운 · 탭 · 배너
   + 버튼 · 칩 필터 · 뱃지 · 데이터 표 · 정의형 목록

   사용자 화면과 관리자 화면이 **모두** 불러오는 파일이다.
   양쪽에서 쓰는 것만 여기 둔다 — 사용자 전용 레이아웃은 layout.css,
   관리자 전용은 admin.css.
   ============================================================ */

/* ── 버튼 ────────────────────────────────────────────────── */
.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--sp-2);
  min-height: var(--touch-min);
  padding: 0 var(--sp-5);
  font-size: var(--fs-md);
  font-weight: 700;
  text-decoration: none;
  border: 1px solid transparent;
  border-radius: var(--radius-pill);
  transition: background var(--dur) var(--ease), color var(--dur) var(--ease);
}
.btn .ico { width: 20px; height: 20px; }

.btn--primary { background: var(--navy); color: var(--white); }
.btn--primary:hover { background: var(--navy-d); color: var(--white); }

/* 골드는 배경으로만 — 그 위 텍스트는 --gold-ink (대비 확보) */
.btn--gold { background: var(--gold); color: var(--gold-ink); }
.btn--gold:hover { background: #D89400; color: var(--gold-ink); }

.btn--ghost { background: var(--white); color: var(--navy); border-color: var(--navy-15); }
.btn--ghost:hover { background: var(--navy-08); color: var(--navy-d); }

/* 되돌릴 수 없는 작업(휴지통 영구 제거) 전용. 관리자 화면에서만 쓴다.
   색만 다른 게 아니라 '이건 다르다'는 신호여야 하므로 테두리도 붉게 둔다.
   #B42318 위 흰 글씨 = 6.1:1 (KWCAG 통과) */
.btn--danger { background: #B42318; color: var(--white); border-color: #B42318; }
.btn--danger:hover { background: #8E1B12; color: var(--white); border-color: #8E1B12; }

.btn--block { width: 100%; }

/* 아이콘 버튼 (햄버거·검색·닫기) — 사용자 헤더와 관리자 상단바가 함께 쓴다.
   색은 상속받으므로 어두운 바 위에 얹으면 그대로 흰 아이콘이 된다. */
.icon-btn {
  min-width: var(--touch-min);
  min-height: var(--touch-min);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  padding: 0;
  background: none;
  border: 0;
  border-radius: var(--radius-sm);
  color: inherit;
}
.icon-btn .ico { width: 24px; height: 24px; }
.icon-btn:hover { background: rgba(255, 255, 255, .12); }

/* ── 셀렉트 ──────────────────────────────────────────────
   브라우저 기본 화살표는 **그리는 위치를 브라우저가 정한다.** padding-right 을
   아무리 줘도 테두리에 바짝 붙은 채라 답답해 보이고, 브라우저마다 모양도 다르다.
   appearance 를 끄고 직접 그려야 간격을 잡을 수 있다.

   사용자 화면과 관리자 화면이 모두 셀렉트를 쓰므로 여기(components.css)에 둔다.
   ⚠ 화살표는 background-image 다. 개별 규칙에서 `background:` 단축 속성으로
     흰 바탕을 칠하면 **이미지가 통째로 지워진다.** 반드시 `background-color:` 로 쓸 것.
   ------------------------------------------------------- */
:root {
  /* 네이비 셰브론 12x8, 선 두께 2 (.xcard__chevron 과 같은 무게) */
  --select-arrow: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='8' viewBox='0 0 12 8'%3E%3Cpath d='M1.5 1.75 6 6.25l4.5-4.5' fill='none' stroke='%23123470' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
  --select-arrow-space: 40px;   /* 화살표 자리 + 글자와의 간격 */
}
select {
  appearance: none;
  -webkit-appearance: none;
  background-image: var(--select-arrow);
  background-repeat: no-repeat;
  /* 오른쪽 테두리에서 16px 띄운다 */
  background-position: right var(--sp-4) center;
  background-size: 12px 8px;
  padding-right: var(--select-arrow-space);
}
/* 화살표를 못 그리는 환경(고대비 모드 등)에서 글자만 남지 않도록 기본 화살표를 되살린다 */
@media (forced-colors: active) {
  select { appearance: auto; -webkit-appearance: auto; }
}

/* ── 연도 선택 시트 (모바일 전용) ──────────────────────────
   좁은 화면에서 브라우저 기본 드롭다운이 누르기 불편하다는 지적에 따라,
   화면 아래에서 올라오는 목록으로 대신한다.

   ⚠ 네이티브 select 를 **없애지 않는다.** 화면이 넓거나 JS 가 없으면 그대로 쓴다.
     시트는 JS 가 조건을 확인했을 때만 만들어진다(app.js). 값도 여전히 select 가
     들고 있어 폼 제출 경로는 하나뿐이다.
   ------------------------------------------------------- */

/* 시트를 열 때 select 를 대신하는 단추 — 겉모습은 select 와 같게 맞춘다 */
.year-sheet__trigger {
  display: inline-flex;
  align-items: center;
  gap: var(--sp-2);
  min-height: var(--touch-min);
  padding: 0 var(--sp-4);
  font-size: var(--fs-md);
  font-weight: 700;
  color: var(--navy);
  background-color: var(--white);
  border: 1px solid var(--navy-15);
  border-radius: var(--radius-pill);
  cursor: pointer;
}
.year-sheet__trigger::after {
  content: '';
  width: 12px; height: 8px;
  background: var(--select-arrow) no-repeat center / 12px 8px;
}

.year-sheet {
  position: fixed;
  inset: 0;
  z-index: var(--z-lightbox);
  display: none;
}
.year-sheet.is-open { display: block; }
.year-sheet__backdrop {
  position: absolute;
  inset: 0;
  background: rgba(13, 38, 80, .55);
}
.year-sheet__panel {
  position: absolute;
  left: 0; right: 0; bottom: 0;
  background: var(--white);
  border-radius: var(--radius-lg) var(--radius-lg) 0 0;
  padding: var(--sp-3) var(--sp-4) calc(var(--sp-4) + env(safe-area-inset-bottom, 0px));
  /* 연도가 아주 많아져도 시트 안에서만 스크롤된다 */
  max-height: 70vh;
  overflow-y: auto;
  animation: sheet-up var(--dur) var(--ease);
}
@keyframes sheet-up { from { transform: translateY(100%); } to { transform: none; } }
@media (prefers-reduced-motion: reduce) { .year-sheet__panel { animation: none; } }

/* 손잡이 모양 — 아래에서 올라온 판이라는 것을 알린다 */
.year-sheet__grip {
  width: 40px; height: 4px;
  margin: 0 auto var(--sp-3);
  background: var(--line);
  border-radius: 2px;
}
.year-sheet__title {
  font-size: var(--fs-sm);
  font-weight: 700;
  color: var(--sub);
  padding: 0 var(--sp-2) var(--sp-2);
}
.year-sheet__opt {
  display: flex;
  align-items: center;
  justify-content: space-between;
  width: 100%;
  min-height: 56px;              /* 44px 기준보다 넉넉하게 — 누르기 쉬우라고 만든 화면이다 */
  padding: 0 var(--sp-4);
  font-size: var(--fs-lg);
  font-weight: 600;
  color: var(--ink);
  text-align: left;
  background: none;
  border: 0;
  border-radius: var(--radius-sm);
  cursor: pointer;
}
.year-sheet__opt:hover { background: var(--navy-08); }
.year-sheet__opt[aria-current="true"] { color: var(--navy); font-weight: 800; background: var(--navy-08); }
/* 고른 항목 표시 — 색만으로 구분하지 않는다 */
.year-sheet__opt[aria-current="true"]::after { content: '✓'; font-weight: 800; }
/* 올해 표시 — 셀렉트에서 굵게 보이던 것과 같은 뜻 */
.year-sheet__now {
  margin-left: var(--sp-2);
  font-size: var(--fs-xs);
  font-weight: 700;
  color: var(--navy);
  background: var(--navy-15);
  border-radius: var(--radius-badge);
  padding: 2px var(--sp-2);
}
.year-sheet__opt > span { display: inline-flex; align-items: center; }

/* ── 뱃지 ─────────────────────────────────────────────────
   시안 기준: 고정·카테고리 등 소형 뱃지는 radius 6px (pill 아님).
   D-day만 pill + 골드.
   ------------------------------------------------------- */
.badge {
  display: inline-flex;
  align-items: center;
  padding: 3px var(--sp-2);
  font-size: var(--fs-xs);
  font-weight: 800;
  line-height: 1.4;
  border-radius: var(--radius-badge);
  background: var(--navy-08);
  color: var(--navy);
}
.badge--live { background: var(--live); color: var(--white); }      /* 진행 중 */
.badge--pinned { background: var(--navy-08); color: var(--navy); }  /* 고정 공지 (시안 .pin) */

/* D-day — 시안 .dday: 골드 pill */
.badge--dday {
  border-radius: var(--radius-pill);
  background: var(--gold);
  color: var(--gold-ink);
  font-weight: 900;
  padding: 4px var(--sp-3);
  letter-spacing: .03em;
}

/* 카드 위 카테고리 뱃지 — 시안 .hl .cat
   ⚠ **바탕은 어두워야 한다.** 예전에는 흰색 16% 였는데, 그러면 밝은 그림 위에서
   흰 글씨가 흰 바탕에 놓인다 — 경연 포스터(베이지 바탕)를 넣자 뱃지가 통째로
   사라졌다. 자리표시 이미지가 남색 한 판이던 동안에는 드러나지 않았다.
   흰 테두리는 어두운 그림 위에서 뱃지의 경계를 잡아 준다. */
.badge--on-image {
  background: rgba(13, 38, 80, var(--shade));
  border: 1px solid rgba(255, 255, 255, .45);
  color: var(--white);
  backdrop-filter: blur(2px);
}

/* ── 카드 ────────────────────────────────────────────────── */
.card {
  background: var(--white);
  border: 1px solid var(--line);
  border-radius: var(--radius-card);
  overflow: hidden;
}

/* 2열 그리드 (전시·체험 목록 등) */
.grid { display: grid; gap: var(--sp-4); }
.grid--2 { grid-template-columns: repeat(2, 1fr); }
@media (min-width: 1024px) {
  .grid--2 { grid-template-columns: repeat(3, 1fr); gap: var(--sp-6); }
}

/* ── 확장 카드 (아코디언) — PROG 공통 템플릿 ──────────────
   <details class="xcard" id="{slug}">  ← 앵커 ID: URL 공유·일정 연결
   JS 없이도 펼침 동작. JS는 해시 진입 시 자동 열기·스크롤만 담당.
   ------------------------------------------------------- */
.xcard {
  background: var(--white);
  border: 1px solid var(--line);
  border-radius: var(--radius-card);
  overflow: hidden;
  scroll-margin-top: calc(var(--header-total) + var(--sp-4));  /* 앵커 이동 시 헤더에 가리지 않게 */
}
.xcard + .xcard { margin-top: var(--sp-4); }
.xcard[open] { box-shadow: var(--shadow-sm); }

/* 펼칠 것이 없는 카드 — 화살표도 없고 눌리지도 않는다.
   손 모양 커서가 남아 있으면 눌러도 되는 줄 알고 시도하게 된다. */
.xcard--flat .xcard__summary { cursor: default; }

/* 해시로 지목된 카드 강조 */
.xcard:target { border-color: var(--gold); box-shadow: 0 0 0 3px rgba(235, 162, 1, .3); }

.xcard__summary {
  display: flex;
  align-items: center;
  gap: var(--sp-4);
  min-height: var(--touch-min);
  padding: var(--sp-4);
  cursor: pointer;
  list-style: none;
}
.xcard__summary::-webkit-details-marker { display: none; }
.xcard__summary:hover { background: var(--navy-08); }

.xcard__thumb {
  width: 84px;
  height: 84px;
  flex: none;
  object-fit: cover;
  border-radius: var(--radius-sm);
  background: var(--navy-08);
}
.xcard__body { flex: 1; min-width: 0; }
.xcard__name { font-size: var(--fs-lg); font-weight: 700; color: var(--ink); }
.xcard__summary-text { margin-top: var(--sp-1); color: var(--sub); font-size: var(--fs-sm); }

/* 프로그램 태그 — 카드에서 어떤 필터에 걸리는지 보여 준다(표시 전용, 링크 아님).
   소형 뱃지 규칙에 맞춰 radius 6px. 골드는 배경으로만 쓰므로 여기서는 네이비 톤. */
.taglist {
  display: flex;
  flex-wrap: wrap;
  gap: var(--sp-1);
  margin-top: var(--sp-2);
  padding: 0;
  list-style: none;
}
.taglist__item {
  padding: 2px var(--sp-2);
  font-size: var(--fs-xs);
  font-weight: 700;
  line-height: 1.5;
  color: var(--navy);
  background: var(--navy-08);
  border-radius: 6px;
}

/* 펼침 화살표 */
.xcard__chevron {
  flex: none;
  width: 12px; height: 12px;
  border-right: 2px solid var(--sub);
  border-bottom: 2px solid var(--sub);
  transform: rotate(45deg) translate(-2px, -2px);
  transition: transform var(--dur) var(--ease);
}
.xcard[open] .xcard__chevron { transform: rotate(-135deg) translate(-2px, -2px); }

.xcard__detail { padding: 0 var(--sp-4) var(--sp-4); border-top: 1px solid var(--line); }

/* 확장 영역 항목 — 값이 있는 항목만 렌더링 (템플릿에서 조건부 출력) */
.deflist { margin-top: var(--sp-4); }
.deflist__row { display: flex; gap: var(--sp-3); padding: var(--sp-2) 0; border-bottom: 1px dashed var(--line); }
.deflist__row:last-child { border-bottom: 0; }
.deflist__key { flex: none; width: 76px; color: var(--sub); font-weight: 600; font-size: var(--fs-sm); }
.deflist__val { flex: 1; min-width: 0; }

/* 확장 영역 갤러리 — 이미지 등록 시에만 표시 */
.xcard__gallery {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: var(--sp-2);
  margin-top: var(--sp-4);
}
.xcard__gallery button {
  padding: 0;
  border: 0;
  background: none;
  border-radius: var(--radius-sm);
  overflow: hidden;
}
.xcard__gallery img { aspect-ratio: 4 / 3; object-fit: cover; width: 100%; }

/* 첨부 파일 */
.filelist a {
  display: inline-flex;
  align-items: center;
  gap: var(--sp-2);
  min-height: var(--touch-min);
  color: var(--navy);
}

/* ── 연도 선택 드롭다운 ────────────────────────────────────
   콘텐츠 영역 상단에만 배치 (행사안내·프로그램). GNB·헤더 금지.
   <form> 기반 서버 이동 — JS는 change 시 자동 제출만 담당.
   ------------------------------------------------------- */
/* 연도 선택은 **주된 기능이 아니다.** 지난 연도를 찾아보는 사람은 드물고,
   이 화면에서 가장 중요한 것은 올해 일정이다. 예전에는 네이비 카드로 감싸 놓아
   화면에서 가장 눈에 띄었다 — 카드를 벗기고 제목 옆에 붙는 작은 셀렉트로 낮춘다.
   (강조는 날짜 선택(.tabscroll)으로 옮겼다)

   ⚠ 위치는 여전히 '콘텐츠 영역 상단'이다. GNB·공통 헤더에는 두지 않는다(SPEC §3). */
.year-select {
  display: flex;
  align-items: center;
  gap: var(--sp-2);
  flex-wrap: wrap;
}
/* .year-select__label 은 더 이상 쓰지 않는다 — 셀렉트가 스스로 무엇인지 말해 주므로
   글자를 빼고 라벨은 sr-only 로만 남겼다(components.njk). */

/* 목록을 펼쳤을 때 올해만 굵게. 닫힌 셀렉트에 '· 현재' 를 붙이면 그만큼 길어지므로
   같은 정보를 자리 없이 전한다.
   ⚠ option 의 꾸밈은 브라우저마다 반영 정도가 다르다(특히 macOS Safari 는 대부분 무시한다).
     굵기가 안 보여도 목록의 맨 위가 올해라 못 고르는 일은 없다 — 있으면 좋은 표시로만 쓴다. */
.year-select__current { font-weight: 700; }
.year-select__field {
  min-height: var(--touch-min);
  /* ⚠ 16px 아래로 내리지 말 것. 프로젝트 규칙(본문 16px 이상)이기도 하고,
     iOS Safari 는 글자가 16px 미만인 폼 컨트롤을 누르면 **화면을 확대해 버린다.**
     강조를 낮추려고 15px 로 줄였다가 되돌렸다 — 표기가 '2026' 네 자리뿐이라
     16px 라도 충분히 짧다. */
  font-size: var(--fs-md);
  /* 오른쪽은 화살표 자리 (위 select 규칙 참고) */
  padding: 0 var(--select-arrow-space) 0 var(--sp-4);
  font-weight: 700;
  color: var(--navy);
  background-color: var(--white);
  border: 1px solid var(--navy-15);
  border-radius: var(--radius-pill);
}
/* JS 사용 가능 시 제출 버튼 숨김 (change 이벤트로 이동) */
.js .year-select__submit { display: none; }

/* ── 형제 화면 이동 (밑줄 탭) ──────────────────────────────
   같은 묶음의 다른 화면으로 옆으로 옮겨 다닌다. 제목 바로 아래.

   ⚠ 알약(칩)이 아니라 밑줄이다. 칩으로 하면 체험 화면의 태그 필터와 같은 모양이
     두 줄로 쌓여 **무엇이 화면 이동이고 무엇이 필터인지** 헷갈린다.
     일정의 날짜 탭(네이비 카드)과도 역할이 구별되어야 한다.
   ------------------------------------------------------- */
/* 형제 화면 탭의 옷 — 아래 구분선 하나뿐 (스크롤 장치는 .tabscroll 이 준다) */
.subnav-scroll { border-bottom: 1px solid var(--line); }
/* 띠를 화면 좌우 끝까지 넓힌다(full bleed) — 이동 단추가 브라우저 끝선에 붙어야
   탭 글자와 겹치는 구간이 줄고 스크롤할 공간도 넓어진다.
   대신 첫 항목 글자가 제목과 어긋나므로, 띠 안쪽 여백으로 그만큼 되돌린다
   (항목 자체의 좌우 여백 16px 을 뺀 값). */
.subnav-scroll { margin-inline: calc(var(--gutter) * -1); }
.subnav { padding-inline: calc(var(--gutter) - var(--sp-4)); }

/* 좌우 이동 단추 — 동그란 알약이 아니라 **가장자리에 붙는 네모 띠**다.
   테두리·그림자 없이, 안쪽은 투명해 탭이 비쳐 보이고 바깥으로 갈수록 배경색으로 덮인다.
   가려지는 글자가 자연스럽게 사라져 보이므로 '더 있다'는 신호가 단추 하나로 끝난다.

   ⚠ 그래서 .tabscroll 의 가장자리 그라데이션(::before/::after)은 여기서 끈다 —
     같은 자리에 두 겹이 되어 경계가 진해진다.
   ⚠ 화살표는 탭 글자 높이(약 16px)에 맞춘다. 띠는 줄 전체를 덮으므로
     세로 가운데(21px)에 두면 글자보다 아래로 처져 보인다. */
.subnav-scroll .tabscroll__btn {
  /* 높이는 스크롤 영역 전체. bottom:-1px 은 아래 구분선(1px)까지 덮어
     감싼 상자의 바깥 높이(44px)와 같게 맞추기 위함이다. */
  top: 0;
  bottom: -1px;
  height: auto;
  width: var(--touch-min);
  padding: 7px var(--sp-2) 0;  /* 화살표(18px) 중심을 탭 글자 중심에 맞춘다 */
  align-items: flex-start;
  border: 0;
  border-radius: 0;
  box-shadow: none;
  background: none;
}
/* 그라데이션은 **안쪽 20% 에서만** 일어난다.
   벽면부터 80% 지점까지는 배경색 그대로(불투명)이고, 남은 안쪽 끝에서만 급히 흐려진다.
   폭 전체에 걸쳐 서서히 흐려지면 어디까지가 단추이고 어디부터 글자인지 흐릿해 보인다.

   ⚠ 끝 색은 `transparent` 가 아니라 **같은 색의 알파 0** 으로 적는다 —
     transparent 는 rgba(0,0,0,0) 이라 사파리·구형 브라우저에서 중간이 회색으로 뜬다. */
.subnav-scroll .tabscroll__btn--prev {
  left: 0;
  justify-content: flex-start;
  background-image: linear-gradient(to right, var(--bg) 80%, rgba(244, 245, 247, 0) 100%);
}
.subnav-scroll .tabscroll__btn--next {
  right: 0;
  justify-content: flex-end;
  background-image: linear-gradient(to left, var(--bg) 80%, rgba(244, 245, 247, 0) 100%);
}
.subnav-scroll .tabscroll__btn:hover { background-color: transparent; }
.subnav {
  display: flex;
  /* ⚠ 항목 사이를 gap 으로 벌리면 **누를 자리는 글자 폭 그대로**다.
     '경연'·'공연' 같은 두 글자는 28px 밖에 안 돼 44px 기준에 못 미쳤다.
     간격을 각 항목의 좌우 여백으로 바꿔, 그 사이 공간까지 누를 수 있게 한다. */
  gap: 0;
  overflow-x: auto;
  overscroll-behavior-x: contain;
  scrollbar-width: none;
}
.subnav::-webkit-scrollbar { display: none; }
.subnav__item {
  flex: none;
  display: inline-flex;
  align-items: center;
  min-height: var(--touch-min);
  /* 밑줄이 글자 바로 밑에 오도록 아래를 조금 띄운다 */
  padding: 0 var(--sp-4) var(--sp-2);
  justify-content: center;
  color: var(--sub);
  font-size: var(--fs-md);
  font-weight: 600;
  text-decoration: none;
  white-space: nowrap;
  border-bottom: 3px solid transparent;
  /* 테두리 두께만큼 아래로 밀려 구분선과 겹치게 한다 */
  margin-bottom: -1px;
}
.subnav__item:hover { color: var(--navy); }
/* 현재 화면 — 색 하나에 기대지 않도록 굵기와 밑줄을 함께 바꾼다 */
.subnav__item[aria-current="page"] {
  color: var(--navy);
  font-weight: 800;
  border-bottom-color: var(--navy);
}

/* ── 탭 (일자 탭 등) ───────────────────────────────────────
   링크 기반 — 탭별 URL 공유 가능 (SPEC INFO-001).
   ------------------------------------------------------- */

/* 가로 스크롤이 있다는 것을 알리는 껍데기.
   좁은 화면에서 탭이 다 안 들어갈 때(375px 기준 108px 넘침) 잘린 자리가
   그냥 여백처럼 보여 **더 있다는 것을 알아채기 어려웠다.**
   가장자리 그라데이션으로 '이어짐'을 보이고, 좌우 버튼으로 밀 수 있게 한다.
   두 표시 모두 JS가 넘침을 확인해 클래스를 붙였을 때만 나타난다
   — 넓은 화면에서는 아예 안 보이고, JS가 없어도 손가락으로는 그대로 밀린다. */
/* 스크롤 장치 자체 — 겉모습은 붙이지 않는다.
   날짜 탭(네이비 카드)과 형제 화면 탭(밑줄)이 같은 장치를 쓰되 옷만 달리 입는다. */
.tabscroll {
  position: relative;
}

/* 일정 단계 묶음 — 사전 프로그램 / 본행사.
   2026년 포스터가 기간을 두 단계로 나눠 알리므로 일자 탭도 같은 모양으로 나눈다.
   나뉘지 않은 해에는 이 껍데기 자체가 나오지 않는다(탭 한 줄 그대로). */
/* 간격은 감싼 쪽의 gap 으로만 준다 — 묶음에 margin 을 주면 .page-sections 의
   gap 에 더해져 이 화면만 다른 리듬이 된다(.page-sections > * 가 margin 을 걷어내는 이유). */
.daygroups { display: grid; gap: var(--sp-4); }
.daygroup__label {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: var(--sp-2);
  margin: 0 0 var(--sp-2);
  font-weight: var(--fw-title);
  color: var(--navy);
}
/* 날짜 범위는 라벨보다 한 걸음 뒤로 — 무엇을 고르는 자리인지가 먼저다 */
.daygroup__period {
  font-weight: 500;
  font-size: var(--fs-sm);
  color: var(--sub);
}
/* 날짜 탭의 옷 — 이 화면에서 가장 자주 쓰는 것은 **날짜 고르기**다.
   예전에는 연도 선택이 네이비 카드를 두르고 있어 시선이 그쪽으로 먼저 갔다. */
.tabscroll--card {
  padding: var(--sp-3) var(--sp-3) var(--sp-2);
  background: var(--navy-08);
  border: 1px solid var(--navy-15);
  border-radius: var(--radius-card);
  /* 이동 단추가 카드 끝면까지 꽉 차는 네모라, 둥근 모서리에 맞춰 잘리도록 한다.
     단추마다 모서리 반경을 따로 주면 카드 반경이 바뀔 때 따로 놀게 된다. */
  overflow: hidden;
}

/* 가장자리 그라데이션은 **단추가 직접 그린다**(아래 변형별 규칙).
   예전에는 여기 ::before/::after 로 따로 그렸는데, ::after 는 자식들 **뒤에** 그려져
   오른쪽 이동 단추를 덮어 화살표를 연하게 만들었다(::before 는 앞이라 왼쪽은 멀쩡 —
   그래서 한쪽만 연한 증상이 났다). 두 겹으로 둘 이유도 없어 아예 없앤다. */

.tabscroll__btn {
  position: absolute;
  top: 0;                      /* 탭 항목(44px)과 눈높이를 맞춘다 */
  width: var(--touch-min);
  height: var(--touch-min);
  display: none;
  align-items: center;
  justify-content: center;
  padding: 0;
  color: var(--navy);
  background: var(--white);
  border: 1px solid var(--navy-15);
  border-radius: 50%;
  box-shadow: var(--shadow-sm);
  cursor: pointer;
}
.tabscroll__btn .ico { width: 18px; height: 18px; }
.tabscroll__btn:hover { background: var(--navy-08); }
.tabscroll__btn--prev { left: 0; }
.tabscroll__btn--next { right: 0; }

.tabscroll.can-prev .tabscroll__btn--prev,
.tabscroll.can-next .tabscroll__btn--next { display: inline-flex; }
/* 날짜 탭 이동 단추 — 형제 화면 탭과 같은 모양이다.
   카드 끝면에 붙는 네모 띠, 테두리·그림자 없음, 안쪽 20% 에서만 흐려진다.
   ⚠ 배경은 페이지색이 아니라 **카드색**(navy-08)이다. 페이지색을 쓰면 카드 위에서 떠 보인다. */
.tabscroll--card .tabscroll__btn {
  top: 0;
  bottom: 0;
  height: auto;
  width: var(--touch-min);
  /* 카드 위(12px)·아래(8px) 여백이 달라 그냥 가운데 두면 1px 위로 뜬다 — 그만큼 내린다 */
  padding: 2px var(--sp-2) 0;
  border: 0;
  border-radius: 0;
  box-shadow: none;
  background-color: transparent;
}
.tabscroll--card .tabscroll__btn--prev {
  left: 0;
  justify-content: flex-start;
  background-image: linear-gradient(to right, var(--navy-08) 80%, rgba(241, 244, 250, 0) 100%);
}
.tabscroll--card .tabscroll__btn--next {
  right: 0;
  justify-content: flex-end;
  background-image: linear-gradient(to left, var(--navy-08) 80%, rgba(241, 244, 250, 0) 100%);
}
.tabscroll--card .tabscroll__btn:hover { background-color: transparent; }

.tabs {
  display: flex;
  gap: var(--sp-2);
  overflow-x: auto;
  scrollbar-width: none;
  /* 세로 스크롤이 가로 스크롤에 끌려가지 않게 한다 */
  overscroll-behavior-x: contain;
  scroll-behavior: smooth;
  /* 키보드로 탭을 옮길 때 브라우저가 알아서 스크롤하는데, 그 도착 지점이
     버튼 밑에 깔리지 않게 한다. scroll-padding 은 배치를 바꾸지 않는다. */
  scroll-padding-inline: var(--touch-min);
  padding-bottom: 2px;
}
.tabs::-webkit-scrollbar { display: none; }
/* ⚠ 버튼이 보이는 쪽에 padding 을 주고 싶어지지만 그러면 안 된다.
   padding 은 scrollWidth 를 바꾸고, scrollWidth 가 바뀌면 can-next 판정이 뒤집혀
   **스크롤 끝에서 여백이 붙었다 떨어졌다 하며 화면이 튄다.**
   버튼에 가리는 탭은 가장자리에서 이미 그라데이션으로 흐려진 것이고,
   그 버튼을 누르면 바로 그쪽으로 밀리므로 닿지 못하는 탭은 생기지 않는다. */
@media (prefers-reduced-motion: reduce) { .tabs { scroll-behavior: auto; } }
.tabs__item {
  flex: none;
  min-height: var(--touch-min);
  display: inline-flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  padding: var(--sp-2) var(--sp-4);
  color: var(--sub);
  text-decoration: none;
  font-weight: 700;
  border-radius: var(--radius-sm);
  white-space: nowrap;
}
.tabs__item small { font-weight: 500; font-size: var(--fs-xs); }
/* 상자 자체가 navy-08 이라 같은 색으로는 호버가 보이지 않는다 — 한 단계 진하게 */
.tabs__item:hover { background: var(--navy-15); color: var(--navy); }
/* 선택 상태 — 색 + 배경 병행 (색 단독 의존 금지) */
.tabs__item[aria-current="page"] { background: var(--navy); color: var(--white); }
.tabs__item[aria-current="page"]:hover { background: var(--navy-d); color: var(--white); }

/* ── 칩 필터 (카테고리·태그) ─────────────────────────────── */
.chips { display: flex; flex-wrap: wrap; gap: var(--sp-2); margin-bottom: var(--sp-4); }
.chip {
  min-height: var(--touch-min);
  display: inline-flex;
  align-items: center;
  padding: 0 var(--sp-4);
  font-size: var(--fs-sm);
  font-weight: 600;
  color: var(--navy);
  background: var(--white);
  border: 1px solid var(--navy-15);
  border-radius: var(--radius-pill);
  text-decoration: none;
}
.chip:hover { background: var(--navy-08); color: var(--navy-d); }
.chip[aria-pressed="true"], .chip[aria-current="true"] {
  background: var(--navy);
  color: var(--white);
  border-color: var(--navy);
}

/* ── 배너 (행사 중 실시간 안내 · 지연 공지) ───────────────── */
.banner {
  display: flex;
  align-items: flex-start;
  gap: var(--sp-3);
  padding: var(--sp-4);
  margin-bottom: var(--sp-5);
  background: var(--gold);
  color: var(--gold-ink);
  border-radius: var(--radius-card);
}
.banner .ico { margin-top: 1px; }
.banner__body { flex: 1; }
.banner__title { font-weight: 700; }
.banner__text { margin-top: 2px; }
/* 골드 배경 위 링크 — 전역 a:hover가 네이비로 바꾸지 않도록 고정 */
.banner a, .banner a:hover { color: var(--gold-ink); font-weight: 700; }

.banner--info { background: var(--navy-08); color: var(--navy-d); }
.banner--info a { color: var(--navy); }

/* ── 라이트박스 (포스터·갤러리 크게보기) ──────────────────
   별도 서브 페이지 없이 화면 내 확대. 좌우 넘김·닫기.
   ------------------------------------------------------- */
.lightbox {
  position: fixed;
  inset: 0;
  z-index: var(--z-lightbox);
  display: none;
  align-items: center;
  justify-content: center;
  padding: var(--sp-4);
  background: rgba(13, 38, 80, .92);
}
.lightbox.is-open { display: flex; }

.lightbox__figure { margin: 0; max-width: 100%; max-height: 100%; text-align: center; }

/* 확대해서 보는 판.
   zoomview.js 는 이 상자를 기준으로 배율과 이동 한계를 계산한다 — 크기가
   내용에 따라 변하면 계산이 흔들리므로 **먼저 크기가 정해지는 상자**여야 한다.
   그래서 이미지의 max-width 로 크기를 잡던 방식에서 상자 쪽으로 옮겼다.

   .zoomview 를 함께 붙였으므로 배경·테두리 같은 배치도용 장식이 따라온다.
   라이트박스는 어두운 배경 위에 이미지만 떠야 하므로 여기서 걷어낸다. */
/* ⚠ 선택자를 .lightbox 로 한 단계 더 좁힌다.
   배치도용 .zoomview 규칙이 이 파일 **뒤쪽**에 있어, 같은 한 클래스끼리는 뒤가 이긴다.
   그대로 두면 배치도용 배경(navy-08)·테두리가 그대로 딸려와 어두운 라이트박스 한가운데
   밝은 회색 판이 뜬다(실제로 그렇게 보였다). 여기서는 어두운 배경 위에 이미지만 떠야 한다. */
.lightbox .lightbox__stage {
  width: min(100%, 1200px);
  height: calc(100vh - 160px);
  margin-inline: auto;
  background: none;
  border: 0;
  border-radius: 0;
}
.lightbox__img {
  border-radius: var(--radius-sm);
}
.lightbox__caption { margin-top: var(--sp-3); color: var(--white); font-size: var(--fs-sm); }
.lightbox__count { color: var(--navy-15); font-size: var(--fs-xs); margin-top: var(--sp-1); }

.lightbox__close,
.lightbox__nav {
  position: absolute;
  /* ⚠ 확대판(.lightbox__stage)보다 위에 있어야 한다.
     확대를 붙이면서 판이 화면 폭을 다 차지하게 됐는데, 그러면 이 단추들이
     그 아래 깔려 **눌리지 않는다**(실제로 그렇게 됐다 — 보이기는 하는데
     클릭이 판에 먹혀 아무 일도 일어나지 않았다). */
  z-index: 1;
  min-width: var(--touch-min);
  min-height: var(--touch-min);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  color: var(--white);
  /* ⚠ 흰 아이콘이므로 단추 배경은 **스스로 어두워야 한다.**
     예전에는 rgba(255,255,255,.14) 였다 — 어두운 배경 위에서만 보이는 값이다.
     확대판이 화면을 채우게 되면서 단추 뒤로 이미지가 지나가는데, 밝은 사진이 오면
     흰 바탕에 흰 아이콘이 되어 통째로 사라졌다. 실측 1.09:1 이었다(닫기 단추는
     어두운 자리에 있어 9.61:1 로 멀쩡했고, 그래서 좌우 단추만 안 보였다).

     네이비 .78 은 **흰색 위에 얹혀도** 흰 아이콘과 7.4:1 이 나온다
     (WCAG 1.4.11 조작 요소 기준 3:1 의 두 배 이상). 뒤가 무엇이든 보인다.
     바깥 테두리는 어두운 사진 위에서 단추의 윤곽을 잡아 준다. */
  background: rgba(13, 38, 80, .78);
  box-shadow: 0 0 0 1px rgba(255, 255, 255, .45);
  border: 0;
  border-radius: 50%;
}
.lightbox__close:hover,
.lightbox__nav:hover {
  background: rgba(13, 38, 80, .92);
  box-shadow: 0 0 0 1px rgba(255, 255, 255, .7);
}
.lightbox__close { top: var(--sp-4); right: var(--sp-4); }
.lightbox__close .ico, .lightbox__nav .ico { width: 24px; height: 24px; }
/* 좌우 단추는 **판(.lightbox__viewport)** 을 기준으로 잡는다.
   화면 전체를 기준으로 하면 아래 설명글·장수 표시 높이만큼 이미지 중심보다 내려간다. */
.lightbox__viewport { position: relative; }
.lightbox__nav--prev { left: var(--sp-3); top: 50%; transform: translateY(-50%); }
.lightbox__nav--next { right: var(--sp-3); top: 50%; transform: translateY(-50%); }
/* 단일 이미지일 때 좌우 버튼 숨김 (JS가 부여) */
.lightbox[data-single="true"] .lightbox__nav { display: none; }

/* 확대 가능 이미지 트리거 */
.zoomable { cursor: zoom-in; padding: 0; border: 0; background: none; display: block; width: 100%; }

/* ── 데이터 표 (주차 안내 등 — 이미지 금지, HTML 표) ─────── */
.data-table { width: 100%; border-collapse: collapse; background: var(--white); font-size: var(--fs-md); }
.data-table caption { text-align: left; padding: var(--sp-3) 0; color: var(--sub); font-size: var(--fs-sm); }
.data-table th, .data-table td { padding: var(--sp-3); border-bottom: 1px solid var(--line); text-align: left; }
.data-table thead th { background: var(--navy-08); color: var(--navy); font-weight: 700; white-space: nowrap; }
.data-table tbody tr:last-child td { border-bottom: 0; }

/* 모바일: 표를 카드형으로 전환 (헤더는 data-label로 표기) */
@media (max-width: 767px) {
  .data-table--stack thead { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); }
  .data-table--stack tbody tr {
    display: block;
    padding: var(--sp-2) 0;
    border-bottom: 1px solid var(--line);
  }
  /* 행 머리글(th[scope=row])도 카드형 전환 대상에 포함한다 */
  .data-table--stack tbody td,
  .data-table--stack tbody th {
    display: flex;
    justify-content: space-between;
    gap: var(--sp-4);
    padding: var(--sp-2) var(--sp-3);
    border: 0;
    text-align: left;
  }
  .data-table--stack tbody td::before,
  .data-table--stack tbody th::before {
    content: attr(data-label);
    flex: none;
    color: var(--sub);
    font-weight: 600;
  }
  /* 값 쪽은 오른쪽 정렬로 라벨과 시각적으로 분리 */
  .data-table--stack tbody .data-table__cell { text-align: right; }
}

/* ── 브레드크럼 — 시안 .crumb / .p-crumb ───────────────────
   서브 페이지가 없으므로 '대메뉴 · 현재 화면' 2단으로만 표기.
   ------------------------------------------------------- */
.breadcrumb {
  font-size: var(--fs-sm);
  color: var(--sub);
}
.breadcrumb ol { display: flex; flex-wrap: wrap; align-items: center; gap: var(--sp-2); }
/* 링크 자체를 44px 높이로 — 글자 크기는 유지한 채 터치 영역만 확보 */
.breadcrumb a,
.breadcrumb [aria-current="page"] {
  display: inline-flex;
  align-items: center;
  min-height: var(--touch-min);
}
.breadcrumb a { color: var(--sub); text-decoration: none; }
.breadcrumb a:hover { color: var(--navy); text-decoration: underline; }
.breadcrumb [aria-current="page"] { color: var(--navy); font-weight: 700; }
.breadcrumb li + li::before { content: '·'; margin-right: var(--sp-2); color: var(--line); }

/* PC에서 시안은 옅은 배경 띠 */
@media (min-width: 1024px) {
  .breadcrumb--bar {
    background: var(--bg-alt);
    border-bottom: 1px solid var(--line);
    margin-bottom: var(--sp-6);
  }
}

/* ── 섹션 헤더 (제목 + 더보기) — 시안 .sec-h ───────────────── */
.sec-head {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: var(--sp-4);
  margin-bottom: var(--sp-3);
}
.sec-head h2 {
  font-size: var(--fs-xl);
  font-weight: var(--fw-title);
  letter-spacing: -.02em;
  color: var(--ink);
}
.sec-head a {
  flex: none;
  font-size: var(--fs-sm);
  font-weight: 500;
  color: var(--sub);
  text-decoration: none;
  min-height: var(--touch-min);
  display: inline-flex;
  align-items: center;
  /* '더보기'는 글자 폭이 39px이라 44px에 못 미친다. 좌우 여백으로 누를 자리를 넓히되,
     음수 바깥여백으로 글자의 오른쪽 끝은 제목 줄에 그대로 맞춘다. */
  padding-inline: var(--sp-2);
  margin-right: calc(var(--sp-2) * -1);
}
.sec-head a:hover { color: var(--navy); text-decoration: underline; }

/* ── 행사 개요 표 — 시안 .ov (INTRO-001) ────────────────────
   dl 그리드. 라벨 열 고정폭, 옅은 배경.
   ------------------------------------------------------- */
.overview {
  border: 1px solid var(--line);
  border-radius: var(--radius-card);
  overflow: hidden;
  background: var(--white);
}
.overview dl { display: grid; grid-template-columns: 92px 1fr; }
.overview dt,
.overview dd { padding: var(--sp-3) var(--sp-4); border-top: 1px solid var(--line-2); }
.overview dt {
  font-size: var(--fs-sm);
  font-weight: 700;
  color: var(--navy);
  background: var(--bg-alt);
}
.overview dd { font-size: var(--fs-md); font-weight: 500; letter-spacing: -.01em; }
.overview dt:first-of-type, .overview dd:first-of-type { border-top: 0; }
@media (min-width: 1024px) {
  .overview dl { grid-template-columns: 128px 1fr; }
}

/* ── 바로가기 2×2 — 시안 .sc (MAIN-001) ──────────────────────
   minmax(0, 1fr): 1fr의 기본 최소값은 min-content라, 아이콘(44px)+긴 설명이 든 칸이
   화면보다 넓어져 가로 스크롤이 생긴다. 0까지 줄어들 수 있게 명시한다.
   ------------------------------------------------------- */
.shortcuts { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: var(--sp-3); }
@media (min-width: 1024px) {
  .shortcuts { grid-template-columns: repeat(4, minmax(0, 1fr)); gap: var(--sp-4); }
}
/* 칸이 좁아지면 설명 문구가 넘치지 않도록 */
.shortcuts b, .shortcuts__sub { overflow-wrap: break-word; }
.shortcuts a {
  display: flex;
  align-items: center;
  gap: var(--sp-3);
  min-height: var(--touch-min);
  padding: var(--sp-4) var(--sp-3);
  background: var(--white);
  border: 1px solid var(--line);
  border-radius: var(--radius-card);
  text-decoration: none;
  color: var(--ink);
  transition: border-color var(--dur), box-shadow var(--dur);
}
.shortcuts a:hover {
  border-color: var(--navy-15);
  box-shadow: 0 6px 16px -10px rgba(18, 52, 112, .3);
}
.shortcuts__icon {
  width: 44px; height: 44px;
  flex: none;
  display: grid;
  place-items: center;
  border-radius: var(--radius-tile);
  background: var(--navy-08);
  color: var(--navy);
}
.shortcuts__icon .ico { width: 21px; height: 21px; }

/* ⚠ 여기를 `.shortcuts span`으로 쓰면 아이콘 span까지 잡힌다.
   명시도가 .shortcuts__icon보다 높아 display:grid가 block으로 덮어써지고
   (아이콘이 사각형 위쪽에 붙는다) margin·색까지 함께 적용된다. 반드시 클래스로 한정할 것. */
.shortcuts__text { min-width: 0; }
.shortcuts b { display: block; font-size: var(--fs-md); font-weight: 700; letter-spacing: -.02em; }
.shortcuts__sub { display: block; font-size: var(--fs-xs); color: var(--sub); margin-top: 2px; }

/* ── 프로그램 하이라이트 가로 슬라이드 — 시안 .hl ────────────── */
.highlight {
  display: flex;
  gap: var(--sp-3);
  overflow-x: auto;
  padding-bottom: var(--sp-1);
  scrollbar-width: none;
  scroll-snap-type: x mandatory;
}
.highlight::-webkit-scrollbar { display: none; }
.highlight__card {
  position: relative;
  flex: 0 0 150px;
  aspect-ratio: 5 / 6;
  display: flex;
  flex-direction: column;
  justify-content: flex-end;
  border-radius: var(--radius-card);
  overflow: hidden;
  text-decoration: none;
  color: var(--white);
  scroll-snap-align: start;
  background: linear-gradient(160deg, var(--navy-l) 0%, var(--navy-d) 70%);
}
@media (min-width: 1024px) {
  .highlight { display: grid; grid-template-columns: repeat(3, 1fr); overflow: visible; }
  .highlight__card { flex: none; aspect-ratio: 4 / 5; }
}
/* 등록된 이미지는 배경으로 덮고, 텍스트 가독성을 위해 하단 그라데이션.
   ⚠ 층 순서를 **세 단계로 명시한다** — 그림 0 · 그늘 1 · 글자 2.
   예전에는 `> *` 가 이미지에도 z-index:1 을 걸어 **그림이 그늘 위로 올라왔다.**
   자리표시 이미지가 남색 한 판이던 때는 흰 글씨가 그냥 읽혀 드러나지 않다가,
   실제 포스터(밝은 베이지 바탕)를 넣자 카드 제목이 통째로 사라졌다. */
.highlight__card img {
  position: absolute;
  inset: 0;
  width: 100%; height: 100%;
  object-fit: cover;
  z-index: 0;
}
/* 글자 자리의 바탕 — 카드 전체가 아니라 **글자 블록에만** 깐다.
   카드 전체에 걸면 이름이 두세 줄이 될 때 윗줄이 옅은 구간에 걸린다.

   짙기는 히어로와 같은 --shade 다. 한 번에 뚝 떨어뜨리지 않고 히어로처럼
   여러 단계로 서서히 짙어지게 한다 — 한 단계로 끊으면 그림 위에 검은 띠를
   덧댄 것처럼 보인다. 글자는 padding-top 아래, 즉 다 짙어진 자리에서 시작한다. */
.highlight__cap {
  /* span 이라 그냥 두면 이름과 요약이 한 줄에 나란히 붙는다 (인라인) */
  display: flex;
  flex-direction: column;
  position: relative;
  z-index: 2;
  padding: 40px var(--sp-3) var(--sp-3);
  background: linear-gradient(180deg,
    rgba(13, 38, 80, 0)                             0px,
    rgba(13, 38, 80, calc(var(--shade) * .14))     10px,
    rgba(13, 38, 80, calc(var(--shade) * .40))     20px,
    rgba(13, 38, 80, calc(var(--shade) * .72))     30px,
    rgba(13, 38, 80, var(--shade))                 40px);
}
.highlight__card > *:not(img) { position: relative; z-index: 2; }
.highlight__card .badge { position: absolute; top: var(--sp-3); left: var(--sp-3); z-index: 2; }
/* ⚠ `.highlight__card span` 으로 쓰면 글자를 감싼 .highlight__cap(역시 span)까지 걸려
   묶음 전체가 흐려지고 글꼴이 작아진다. 요약 줄만 짚는다. */
.highlight__card b { font-size: var(--fs-md); font-weight: 800; line-height: 1.3; letter-spacing: -.02em; }
/* ⚠ opacity 를 더 내리지 말 것. 그늘이 --shade(.69) 로 옅어지면서 여유가 거의
   없어졌다 — .85 에서 4.50:1 로 기준에 걸렸다. 요약을 뒤로 물리는 일은 글자 크기가
   이미 하고 있으므로, 흐리기까지 겹칠 이유가 없다. */
.highlight__cap > span { font-size: var(--fs-xs); opacity: .94; margin-top: 3px; }

/* 전역 a:hover(color: navy-d)가 카드 위 흰 글씨를 덮어써 글자가 사라졌다.
   흰색을 유지하되 살짝 연해지게 해서 눌리는 느낌만 준다.
   카테고리 뱃지는 자체 색을 가지므로 또렷하게 남는다. */
.highlight__card { transition: color var(--dur) var(--ease); }
.highlight__card:hover,
.highlight__card:focus-visible { color: rgba(255, 255, 255, .78); }

/* ── 슬로건 블록 — 시안 .slogan (INTRO-001) ──────────────────
   Black Han Sans 허용 구간 (히어로 날짜와 함께 유이한 예외).
   ------------------------------------------------------- */
.slogan {
  background: var(--navy);
  border-radius: var(--radius-lg);
  padding: var(--sp-8) var(--sp-4);
  text-align: center;
  color: var(--white);
}
.slogan h3 {
  font-family: var(--font-display);
  font-weight: 400;
  font-size: var(--fs-2xl);
  letter-spacing: .03em;
}
.slogan h3 em { font-style: normal; color: var(--gold); }
.slogan p {
  font-size: var(--fs-xs);
  opacity: .7;
  margin-top: var(--sp-2);
  font-weight: 500;
  letter-spacing: .25em;
}

/* ── 본문 산문 (주제 설명문 등) — 시안 .theme ──────────────── */
.prose { font-size: var(--fs-md); line-height: 1.8; color: var(--ink-2); letter-spacing: -.01em; }
.prose b, .prose strong { color: var(--navy); }
.prose p + p { margin-top: var(--sp-4); }

/* ── 섹션 리듬 — 시안 .body { gap:24px } ──────────────────────
   그리드 트랙의 기본 최소값은 min-content다. 가로 스크롤 영역(하이라이트 카드 등)이
   자식으로 들어오면 트랙이 그 폭까지 벌어져 화면 전체에 가로 스크롤이 생긴다.
   시안의 `.body>*{min-width:0}`과 같은 처리를 넣어 트랙이 화면 폭을 넘지 않게 한다.
   ------------------------------------------------------- */
.page-sections { display: grid; grid-template-columns: minmax(0, 1fr); gap: var(--sp-8); }
/* ⚠ 간격은 gap 하나로만 정한다.
   자식이 자기 margin 을 들고 있으면 gap 에 **더해져** 화면마다 간격이 달라진다.
   실제로 32px 이어야 할 자리에 40·48·52·56·64px 이 섞여 있었다
   (.chips · .tabscroll · .archive · .search-group · .page-head 가 각자 여백을 갖고 있었다).
   컴포넌트가 다른 자리에서 쓰일 때를 위해 그쪽 규칙은 두고, 여기서만 걷어낸다.
   더 붙여야 하는 관계라면 **같은 자식 안으로 묶어야지** 여백을 줄이는 것으로 풀지 않는다
   (오시는 길의 주소↔지도, 배치도의 뷰어↔도움말이 그렇게 했다). */
.page-sections > * { min-width: 0; margin-top: 0; margin-bottom: 0; }

/* ── 히어로 (MAIN-001) — 시안 .hero / .p-hero ────────────────
   포스터·키비주얼 위에 실 텍스트 오버레이 (이미지에 텍스트를 굽지 않는다).
   ------------------------------------------------------- */
.hero {
  position: relative;
  background: var(--navy-d);
  margin-bottom: var(--sp-6);
}
.hero__img { width: 100%; height: auto; display: block; }

/* 글자 뒤 그늘 (.hero__scrim)
   ── 왜 히어로 전체가 아니라 글자 블록에 붙는가 ─────────────
   예전에는 히어로를 덮는 .hero__veil 에 **히어로 높이의 %** 로 곡선을 잡았다.
   그런데 히어로 이미지는 비율이 고정(1.22:1)이라 화면이 넓어지면 높이가 커지는데
   글자 높이는 거의 그대로다. 그래서 글자가 차지하는 비율이 폭마다 달라진다 —
   실측하면 글자 블록 시작점이 360px 에서 19.9%, 390px 26.0%, 430px 49.2%, 768px 71.5% 다.
   고정 %로는 어떤 폭에서는 쓸데없는 곳까지 어둡고(보기 싫다), 어떤 폭에서는
   글자가 그늘 밖에 놓인다(읽기 어렵다). 둘 다 실제로 일어났다.

   글자 블록에 붙이면 그 문제가 사라진다. 그늘이 늘 글자와 함께 움직이고,
   길이도 글자 높이를 따라간다. 폭마다 값을 다시 잴 이유도 없다.

   ── 부드러움 ──────────────────────────────────────────────
   위쪽 여백(padding-top) 안에서 서서히 짙어진다. 정거장을 촘촘히 둔 이유는
   두세 개만 두면 꺾이는 지점이 띠처럼 보이기 때문이다 — 앞선 시안이 32%→38% 에서
   0.05→0.76 으로 튀어 "극단적인 그라데이션" 으로 보인다는 지적을 받았다.

   ── 농도를 어떻게 정했나 ──────────────────────────────────
  "더 옅게" 요청을 두 번 받고, 그때마다 알파 전체에 배수를 걸어 가며 실제로 쟀다.
  기준선(4.5:1)이 무너지는 지점은 모바일 ×0.73 아래, 데스크톱 ×0.78 아래다.
  지금 값은 모바일 ×0.76(5.02:1) · 데스크톱 ×0.83(5.08:1) — 둘 다 5:1 을 겨우 넘긴다.
  **여기서 더 낮추면 여유가 0.3 아래로 떨어진다.** 그 상태에서 사무국이 더 밝은
  키비주얼로 바꾸면 곧바로 기준 미달이 되고, 그때는 그늘을 다시 맞춰야 한다.
  데스크톱을 덜 낮춘 이유는 글자가 가운데라 그늘이 이미지 한가운데를 지나가,
  같은 배수라도 대비가 먼저 무너지기 때문이다.

  ⚠ 대비는 scripts/check-browser.js 가 **실제로 그려진 화면을 찍어서** 잰다.
     글자를 감춘 히어로를 촬영해 각 글자 상자 안의 가장 밝은 배경 픽셀을 찾는 방식이라,
     그늘 모양이나 키비주얼이 바뀌어도 계산식을 고칠 필요가 없다. */
.hero__scrim {
  /* 그늘의 짙기는 **여기 한 곳에서만** 정한다.
     모바일(아래 그라데이션)과 데스크톱(흐린 타원)이 같은 값을 쓴다 —
     두 군데에 숫자를 따로 적어 두면 한쪽만 손댔을 때 조용히 어긋난다.
     실제로 데스크톱이 .85, 모바일이 .71 로 벌어져 "PC 가 더 진하다" 는 지적을 받았다.
     아래 정거장들은 이 값에 대한 **비율**이라, 이 한 줄을 바꾸면 양쪽이 함께 움직인다.

     ⚠ **이 값이 바닥이다.** 실측으로 확인한 한계다.
         .69 → 모바일 4.73 · 데스크톱 4.54  (기준 4.5 — 통과)
         .68 → 모바일 4.61 · 데스크톱 4.36  (미달)
         .65 → 모바일 4.17 · 데스크톱 4.04  (미달. 요청이 있었으나 쓸 수 없다)
       데스크톱 여유가 +0.04 뿐이다. 키비주얼을 조금이라도 밝은 것으로 바꾸면 곧바로
       미달이 되니, 그때는 이 값을 올리거나 아래 방법을 쓴다.

     ── 더 옅게 하려면 ──────────────────────────────────────
     발목을 잡는 것은 글자가 놓인 자리의 **밝은 키비주얼 조각**이다.
     히어로는 scripts/make-hero-collage.js 가 타일을 격자로 붙여 만든 콜라주이므로,
     글자 자리에 어두운 조각이 오도록 배치를 바꾸면 그늘을 훨씬 옅게 해도 기준을 지킨다.
     그늘 값만 만져서는 여기가 끝이다. */
  --hero-shade: var(--shade);

  padding-top: 96px;
  background: linear-gradient(180deg,
    rgba(13, 38, 80, 0)                                  0px,
    rgba(13, 38, 80, calc(var(--hero-shade) * .11))     22px,
    rgba(13, 38, 80, calc(var(--hero-shade) * .28))     40px,
    rgba(13, 38, 80, calc(var(--hero-shade) * .48))     56px,
    rgba(13, 38, 80, calc(var(--hero-shade) * .66))     72px,
    rgba(13, 38, 80, calc(var(--hero-shade) * .82))     88px,
    rgba(13, 38, 80, calc(var(--hero-shade) * .92))    104px,
    rgba(13, 38, 80, var(--hero-shade))                100%);
}

.hero__txt {
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0;
  color: var(--white);
}
/* 좌우 여백은 그늘 안쪽에 준다 — 그늘이 화면 폭을 꽉 채워야 글자 옆으로
   잘린 그늘 끝이 보이지 않는다. */
.hero__scrim { padding-inline: var(--gutter); padding-bottom: var(--sp-5); }

/* 행사명 — 실 텍스트. Black Han Sans는 날짜·슬로건 전용이므로 여기는 Pretendard 800.
   (CLAUDE.md 디자인 토큰: 섹션·페이지 제목·로고는 --fw-title) */
.hero__title {
  margin: var(--sp-2) 0 0;
  font-size: var(--fs-lg);
  font-weight: var(--fw-title);
  letter-spacing: -.02em;
  text-shadow: 0 1px 8px rgba(0, 0, 0, .35);
}
/* 슬로건 — 히어로 대형 텍스트라 디스플레이 서체를 쓴다 */
.hero__slogan {
  margin: var(--sp-1) 0 0;
  font-size: 22px;
  line-height: 1.25;
  letter-spacing: .01em;
  text-shadow: 0 1px 8px rgba(0, 0, 0, .35);
}
.hero__date {
  display: block;
  margin: var(--sp-2) 0 0;
  font-size: 26px;
  line-height: 1.2;
  letter-spacing: .02em;
  text-shadow: 0 1px 8px rgba(0, 0, 0, .3);
}
.hero__place { margin-top: var(--sp-1); font-size: var(--fs-md); font-weight: 500; opacity: .94; }

/* 사전 프로그램 / 본행사 — 기간 아래 한 줄.
   좁은 화면에서는 두 줄로 접힌다(가운데 정렬이라 접혀도 흐트러지지 않는다).
   opacity 를 더 낮추지 않는다 — 이미 그늘 위 흰 글씨라 여유가 크지 않다. */
.hero__phases {
  display: flex;
  flex-wrap: wrap;
  gap: var(--sp-1) var(--sp-4);
  margin-top: var(--sp-2);
  font-size: var(--fs-sm);
  font-weight: 500;
}
.hero__phases b { font-weight: 700; }

@media (min-width: 1024px) {
  /* 시안 PC: 400px 고정 높이 · 전체 베일 · 중앙 정렬 */
  .hero { height: 400px; overflow: hidden; }
  .hero__img { height: 100%; object-fit: cover; object-position: center 30%; }
  /* 데스크톱에서는 글자가 **가운데** 놓인다. 그늘도 위아래로 퍼져야 자연스럽다.
     예전에는 히어로 전체를 rgba(...,.65) 로 평평하게 덮었는데, 그러면 키비주얼이
     통째로 탁해진다. 글자 블록에만 두면 위아래 여백의 그림은 그대로 보인다. */
  .hero__txt {
    inset: 0;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    text-align: center;
    padding-inline: 0;
  }
  /* 데스크톱 그늘 — **흐린 타원 하나**.
     글자가 가운데 놓이므로 그늘도 그 자리에만 있으면 된다.

     ── 어떻게 여기까지 왔나 ──────────────────────────────────
     ① 화면 전체를 덮는 평면 → 키비주얼이 통째로 탁해진다.
     ② 글자 블록 너비의 사각형 → 좌우에 뚝 끊긴 세로 모서리가 생긴다.
     ③ 가로 마스크로 좌우를 흐림 → 부드러워졌지만 여전히 사각형으로 읽힌다.
        border-radius 를 줘도 소용이 없다. 가장자리는 이미 투명해서 깎을 것이 없고,
        각져 보이는 것은 **그늘이 짙은 안쪽 모양**이기 때문이다.
     ④ 흐린 타원 → 애초에 모서리가 없다. 지금 이것.

     inset 이 음수인 것은 글자 상자보다 조금 넓게 퍼뜨리기 위함이고,
     blur 가 실제 부드러움을 만든다.

     ── 농도를 모바일과 맞춘 방법 ────────────────────────────
     "PC 가 모바일보다 진해 보인다" 는 지적을 받고, 히어로 이미지를 감추고 흰 바탕에
     그늘만 찍어 **실제 알파**를 되돌려 쟀다. 모바일 0.66~0.71 대 데스크톱 0.84~0.85 —
     실제로 진했다.
     그냥 알파만 .68 로 낮추면 대비가 4.11:1 로 미달한다. 흐림이 크면 가장자리로 갈수록
     옅어져 글자 끝이 무방비가 되기 때문이다. 그래서 **알파를 낮추는 대신 흐림도 함께
     줄여** 글자 위 농도를 고르게 했다. 지금 값의 실측 농도는 0.65~0.72 로 모바일과
     같고 대비는 4.95:1 이다.

     ⚠ .hero__scrim 자체의 background 를 none 으로 지운다. 모바일 규칙이 이 요소에
       그라데이션을 깔아 두는데, 지우지 않으면 ::before 와 겹쳐 그려져 여기를
       아무리 고쳐도 화면이 거의 그대로다(실제로 그 상태로 한참 헤맸고,
       그동안 잰 대비 수치도 전부 부풀려져 있었다). */
  .hero__scrim {
    align-self: center;
    position: relative;
    padding: 88px 72px;
    background: none;
  }
  .hero__scrim > * { position: relative; z-index: 1; }   /* 글자는 그늘 위에 */
  .hero__scrim::before {
    content: '';
    position: absolute;
    /* ⚠ 이보다 좁히면 안 된다. shade .69 에서 -3% -5% / 26px 로 줄였더니
       데스크톱이 4.47:1 로 미달했다(기준 4.5). 그늘이 좁아지면 글자 끝이
       옅은 가장자리에 걸리기 때문이다 — 짙기를 낮춘 만큼 범위는 지켜야 한다. */
    inset: -4% -6%;
    z-index: 0;
    border-radius: 50%;
    background: rgba(13, 38, 80, var(--hero-shade));
    filter: blur(28px);
  }

  .hero__title { margin-top: var(--sp-4); font-size: var(--fs-xl); }
  .hero__slogan { font-size: 30px; margin-top: var(--sp-2); }
  .hero__date { font-size: 40px; letter-spacing: .04em; text-shadow: 0 2px 12px rgba(0, 0, 0, .35); }
  .hero__place { font-size: var(--fs-lg); margin-top: var(--sp-3); }
}

/* ── 공지 목록 (메인) — 시안 .nt ────────────────────────────── */
.notice-list li + li { border-top: 1px solid var(--line-2); }
.notice-list a {
  display: flex;
  align-items: center;
  gap: var(--sp-3);
  min-height: var(--touch-min);
  padding: var(--sp-3) var(--sp-4);
  text-decoration: none;
  color: var(--ink);
}
.notice-list a:hover { background: var(--navy-08); }
.notice-list__title {
  flex: 1;
  min-width: 0;
  font-weight: 500;
  letter-spacing: -.01em;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.notice-list time { flex: none; font-size: var(--fs-sm); color: var(--sub); }
/* 모바일은 3건까지 (SPEC MAIN-001: 최신 5건, 모바일 3건) */
@media (max-width: 767px) {
  .notice-list li:nth-child(n + 4) { display: none; }
}

/* ── 타임테이블 (INFO-001) ──────────────────────────────────
   Phase 3에서 일자 탭·카테고리 필터·'진행 중' 뱃지·앵커 연결이 얹힌다.
   ------------------------------------------------------- */
.timetable__row {
  display: flex;
  gap: var(--sp-4);
  padding: var(--sp-3) var(--sp-4);
}
.timetable__row + .timetable__row { border-top: 1px solid var(--line-2); }
.timetable__time {
  flex: none;
  /* 'HH:MM~HH:MM' 이 한 줄에 들어가는 폭.
     92px 이었을 때 실측 101px 가 필요해 **모든 행이 두 줄로 쪼개졌다**
     ("10:00~11:0" / "0"). 폭은 행마다 고정해야 본문 시작선이 나란히 선다. */
  width: 108px;
  /* 폰트가 대체글꼴로 떨어져 조금 넓어지더라도 줄을 바꾸지 않는다.
     넘치면 옆 간격(gap)으로 삐져나올 뿐, 숫자가 잘리지는 않는다. */
  white-space: nowrap;
  /* 제목과 같은 44px 띠 안에서 가운데를 맞춘다.
     이게 없으면 시간칸은 행 전체 높이(95px)로 늘어난 채 글자를 맨 위에 두고,
     제목은 44px 안에서 가운데 정렬이라 **글자가 8~9px 어긋나 보인다.**
     align-self 로 늘어남을 끊어야 44px 가 실제 높이가 된다. */
  align-self: flex-start;
  min-height: var(--touch-min);
  display: flex;
  align-items: center;
  font-weight: 700;
  color: var(--navy);
  font-variant-numeric: tabular-nums;
}
.timetable__end { color: var(--sub); font-weight: 500; }
.timetable__body { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 2px; }
/* 제목 칸의 높이를 44px로 못박는다.
   프로그램 카드로 이어지는 제목은 링크라 터치 영역 44px를 갖는데, 이어질 프로그램이
   없는 항목(개막식 등)은 평문이라 26px 였다. 그래서 같은 목록에서 행 높이가
   96px / 77px 로 들쭉날쭉했다. 바닥을 링크가 아니라 **칸**에 두면 양쪽이 같아진다. */
.timetable__title {
  font-weight: 500;
  display: flex;
  align-items: center;
  gap: var(--sp-2);
  flex-wrap: wrap;
  min-height: var(--touch-min);
}
/* 프로그램 카드 앵커로 이동하는 링크 — 터치 영역 44px 확보 */
.timetable__title a {
  display: inline-flex;
  align-items: center;
  min-height: var(--touch-min);
  color: var(--navy);
  text-decoration: none;
  font-weight: 700;
}
.timetable__title a:hover { text-decoration: underline; }
.timetable__place { font-size: var(--fs-sm); color: var(--sub); }

/* 진행 중 — 색 외에 좌측 바로도 구분 (색 단독 의존 금지) */
.timetable__row--live {
  background: var(--navy-08);
  box-shadow: inset 3px 0 0 var(--live);
}

/* ── 설화 본문 (INTRO-002) ──────────────────────────────────
   고령층·어린이가 함께 읽는 화면 — 글자와 행간을 본문 기준보다 키운다.
   ------------------------------------------------------- */
.story { font-size: var(--fs-lg); line-height: 1.9; }
.story p + p { margin-top: var(--sp-5); }
/* 위지윅으로 넣은 삽화는 문단 사이에서 폭을 채운다 */
.story img { width: 100%; border-radius: var(--radius-card); margin-block: var(--sp-5); }
.story figure { margin-block: var(--sp-5); }
.story figcaption {
  margin-top: var(--sp-2);
  font-size: var(--fs-sm);
  color: var(--sub);
  text-align: center;
}
@media (min-width: 1024px) {
  /* 긴 글은 한 줄이 너무 길면 읽기 어렵다 — 본문 폭을 제한 */
  .story { max-width: 68ch; }
}

.character { display: grid; gap: var(--sp-5); }
@media (min-width: 768px) {
  .character { grid-template-columns: 280px 1fr; align-items: start; }
  /* 이미지 칸(280px) + 본문 칸. 이미지는 선택 항목이므로 없을 때는 한 칸으로
     되돌린다 — 그러지 않으면 본문이 280px 안에서 잘린다(.archive__main 과 같은 결함). */
  .character--noimage { grid-template-columns: 1fr; }
}
.character__image .zoomable {
  border: 1px solid var(--line);
  border-radius: var(--radius-lg);
  overflow: hidden;
  background: var(--white);
}
.character__desc { font-size: var(--fs-md); line-height: var(--lh-base); }

/* ── 지난 축전 정보 (ARCH-001) ──────────────────────────────
   연도 블록이 자동으로 쌓인다.
   ------------------------------------------------------- */
.archive {
  padding: var(--sp-6);
  background: var(--white);
  border: 1px solid var(--line);
  border-radius: var(--radius-card);
}
/* 간격은 .page-sections 의 gap 이 준다 — 여기서 margin 을 더하면 56px 이 된다.
   `+` 결합자가 특정도(0,2,0)로 위 `.page-sections > *`(0,1,0)를 이기므로 여기서 지운다. */

.archive__title {
  display: flex;
  align-items: center;
  gap: var(--sp-3);
  flex-wrap: wrap;
  font-size: var(--fs-xl);
  font-weight: var(--fw-title);
  letter-spacing: -.02em;
  color: var(--navy);
  margin-bottom: var(--sp-4);
}
.archive__edition {
  font-size: var(--fs-sm);
  font-weight: 700;
  color: var(--navy);
  background: var(--navy-08);
  border-radius: var(--radius-badge);
  padding: 3px var(--sp-2);
}

.archive__main { display: grid; gap: var(--sp-5); }
@media (min-width: 768px) {
  .archive__main { grid-template-columns: 220px 1fr; align-items: start; }
  /* 포스터 칸(220px) + 내용 칸 구조라, 포스터가 없으면 내용이 첫 칸으로 밀려
     220px 안에서 잘린다. 포스터는 선택 항목이므로(지난 연도는 흔히 비어 있다)
     없을 때는 한 칸으로 되돌린다. 템플릿이 --noposter 를 붙인다. */
  .archive__main--noposter { grid-template-columns: 1fr; }
}
.archive__poster { margin: 0; }
.archive__poster .zoomable {
  border: 1px solid var(--line);
  border-radius: var(--radius-lg);
  overflow: hidden;
}
.archive__poster img { width: 100%; height: auto; }

.archive__gallery {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: var(--sp-2);
  margin-top: var(--sp-5);
}
@media (min-width: 1024px) {
  .archive__gallery { grid-template-columns: repeat(6, 1fr); }
}
.archive__gallery .zoomable { border-radius: var(--radius-sm); overflow: hidden; }
.archive__gallery img { aspect-ratio: 4 / 3; object-fit: cover; width: 100%; }

.archive__more { margin-top: var(--sp-3); }
.archive__more summary {
  display: inline-flex;
  align-items: center;
  min-height: var(--touch-min);
  padding: 0 var(--sp-4);
  color: var(--navy);
  font-weight: 700;
  font-size: var(--fs-sm);
  cursor: pointer;
  background: var(--navy-08);
  border-radius: var(--radius-pill);
  list-style: none;
}
.archive__more summary::-webkit-details-marker { display: none; }
.archive__more summary:hover { background: var(--navy-15); }
/* '사진 더보기' 는 다른 화면으로 가는 링크처럼 읽힌다 — 그 자리에서 펴진다는 것을
   화살표로 밝힌다. 사용자 화면 아코디언(.acc__summary)과 같은 모양이다. */
.archive__more summary::after {
  content: '';
  width: 8px; height: 8px;
  flex: none;
  margin-left: var(--sp-2);
  border-right: 2px solid currentColor;
  border-bottom: 2px solid currentColor;
  transform: rotate(45deg) translate(-2px, -2px);
  transition: transform var(--dur) var(--ease);
}
.archive__more[open] > summary::after { transform: rotate(-135deg) translate(-2px, -2px); }

.archive__nophoto { margin-top: var(--sp-4); font-size: var(--fs-sm); color: var(--sub); }

/* ── 통합 검색 결과 (ETC-002) ───────────────────────────────
   출처별 그룹 → 각 화면·카드 앵커로 연결.
   ------------------------------------------------------- */
/* 간격은 .page-sections 의 gap 이 준다 (위 .archive 주석과 같은 이유) */
.search-group__count {
  display: inline-flex;
  align-items: center;
  min-width: 24px;
  height: 24px;
  padding: 0 var(--sp-2);
  justify-content: center;
  font-size: var(--fs-sm);
  font-weight: 700;
  color: var(--navy);
  background: var(--navy-08);
  border-radius: var(--radius-pill);
  vertical-align: 2px;
}

.search-results__item + .search-results__item { border-top: 1px solid var(--line-2); }
.search-results__item a {
  display: flex;
  flex-direction: column;
  gap: var(--sp-1);
  min-height: var(--touch-min);
  padding: var(--sp-4);
  text-decoration: none;
  color: var(--ink);
}
.search-results__item a:hover { background: var(--navy-08); }
.search-results__title { font-weight: 700; letter-spacing: -.01em; }
.search-results__excerpt {
  font-size: var(--fs-sm);
  color: var(--sub);
  line-height: 1.6;
  /* 발췌문은 두 줄까지만 */
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
}
/* 일치 부분 강조 — 배경만으로 구분되지 않도록 굵기도 함께 준다 */
.search-results__excerpt mark {
  background: rgba(235, 162, 1, .28);
  color: inherit;
  font-weight: 700;
  border-radius: 3px;
  padding: 0 2px;
}

.search-tip { margin-top: var(--sp-2); }
.search-tip__links {
  display: flex;
  flex-wrap: wrap;
  gap: var(--sp-2);
  justify-content: center;
  margin-top: var(--sp-4);
}

/* ── 보도자료 (NOTI-004) ────────────────────────────────────
   링크형·파일형을 유형 뱃지로 구분한다. 상세 페이지 없음.
   ------------------------------------------------------- */
.press-list__item + .press-list__item { border-top: 1px solid var(--line-2); }
.press-list__item > a,
.press-list__body--plain {
  display: flex;
  align-items: center;
  gap: var(--sp-4);
  min-height: var(--touch-min);
  padding: var(--sp-4);
  text-decoration: none;
  color: var(--ink);
}
.press-list__item > a:hover { background: var(--navy-08); }
.press-list__body { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: var(--sp-1); }
.press-list__title { font-weight: 500; letter-spacing: -.01em; }
.press-list__meta { display: flex; flex-wrap: wrap; gap: var(--sp-3); font-size: var(--fs-sm); color: var(--sub); }
.press-list__type { flex: none; }
.press-list__type .badge { gap: var(--sp-1); }
.press-list__type .ico { width: 14px; height: 14px; }

/* ── 홍보영상 (NOTI-005) ────────────────────────────────────
   재생 전에는 섬네일만 — 유튜브 임베드는 클릭 시점에 삽입된다.
   ------------------------------------------------------- */
.video-list { display: grid; gap: var(--sp-8); }
@media (min-width: 768px) {
  .video-list { grid-template-columns: repeat(2, 1fr); gap: var(--sp-6); }
}
@media (min-width: 1024px) {
  .video-list { grid-template-columns: repeat(3, 1fr); }
}

/* 16:9 비율 고정 — 재생 전후로 높이가 바뀌지 않는다 */
.video__frame {
  position: relative;
  aspect-ratio: 16 / 9;
  overflow: hidden;
  border-radius: var(--radius-card);
  background: var(--navy-d);
}
.video__facade,
.video__iframe {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  border: 0;
}
.video__facade { padding: 0; background: none; cursor: pointer; }
/* hqdefault는 4:3이라 16:9 영역에 맞춰 잘라 넣는다 */
.video__facade img { width: 100%; height: 100%; object-fit: cover; }

/* 재생 삼각형 */
.video__play {
  position: absolute;
  top: 50%; left: 50%;
  transform: translate(-50%, -50%);
  width: 62px; height: 62px;
  border-radius: 50%;
  background: rgba(13, 38, 80, .82);
  border: 2px solid rgba(255, 255, 255, .9);
  transition: background var(--dur) var(--ease), transform var(--dur) var(--ease);
}
.video__play::after {
  content: '';
  position: absolute;
  top: 50%; left: 54%;
  transform: translate(-50%, -50%);
  border-style: solid;
  border-width: 11px 0 11px 18px;
  border-color: transparent transparent transparent var(--white);
}
.video__facade:hover .video__play { background: var(--gold); transform: translate(-50%, -50%) scale(1.06); }
.video__facade:hover .video__play::after { border-left-color: var(--gold-ink); }

.video__title { margin-top: var(--sp-3); font-size: var(--fs-lg); font-weight: 700; letter-spacing: -.02em; }
.video__meta {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--sp-3);
  margin-top: var(--sp-1);
  font-size: var(--fs-sm);
  color: var(--sub);
}
.video__meta a { min-height: var(--touch-min); display: inline-flex; align-items: center; color: var(--navy); }

/* ── FAQ 아코디언 (NOTI-003) ────────────────────────────────
   <details>/<summary> 기반 — JS 없이 펼쳐진다.
   ------------------------------------------------------- */
.faq-list { display: grid; gap: var(--sp-3); }

.faq {
  background: var(--white);
  border: 1px solid var(--line);
  border-radius: var(--radius-card);
  overflow: hidden;
  scroll-margin-top: calc(var(--header-total) + var(--sp-4));
}
.faq[open] { box-shadow: var(--shadow-sm); }
.faq:target { border-color: var(--gold); box-shadow: 0 0 0 3px rgba(235, 162, 1, .3); }

.faq__q {
  display: flex;
  align-items: flex-start;
  gap: var(--sp-3);
  min-height: var(--touch-min);
  padding: var(--sp-4);
  cursor: pointer;
  list-style: none;
  font-weight: 700;
}
.faq__q::-webkit-details-marker { display: none; }
.faq__q:hover { background: var(--navy-08); }

/* Q / A 표식 — 장식이므로 aria-hidden, 의미는 문답 구조가 전달 */
.faq__mark {
  flex: none;
  width: 26px; height: 26px;
  display: grid;
  place-items: center;
  border-radius: 50%;
  background: var(--navy);
  color: var(--white);
  font-size: var(--fs-sm);
  font-weight: 800;
  line-height: 1;
}
.faq__mark--a { background: var(--gold); color: var(--gold-ink); }

.faq__text { flex: 1; min-width: 0; letter-spacing: -.01em; }

.faq__chevron {
  flex: none;
  margin-top: 6px;
  width: 11px; height: 11px;
  border-right: 2px solid var(--sub);
  border-bottom: 2px solid var(--sub);
  transform: rotate(45deg) translate(-2px, -2px);
  transition: transform var(--dur) var(--ease);
}
.faq[open] .faq__chevron { transform: rotate(-135deg) translate(-2px, -2px); }

.faq__a {
  display: flex;
  align-items: flex-start;
  gap: var(--sp-3);
  padding: var(--sp-4);
  border-top: 1px solid var(--line-2);
  background: var(--bg-alt);
}
.faq__a .prose { flex: 1; min-width: 0; }

/* ── 공지 게시판 (NOTI-001) ─────────────────────────────────
   모바일은 2줄 카드(제목 / 날짜·조회수), 데스크톱은 한 줄로 붙인다.
   ------------------------------------------------------- */
.search-form--page { max-width: 480px; }

.result-summary {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--sp-3);
  color: var(--sub);
  font-size: var(--fs-sm);
}
.result-summary a { min-height: var(--touch-min); display: inline-flex; align-items: center; }

.notice-board__item + .notice-board__item { border-top: 1px solid var(--line-2); }
.notice-board__item a {
  display: flex;
  flex-direction: column;
  gap: var(--sp-1);
  min-height: var(--touch-min);
  padding: var(--sp-4);
  text-decoration: none;
  color: var(--ink);
}
.notice-board__item a:hover { background: var(--navy-08); }
/* 고정 공지 — 배경으로 구분 (SPEC: 상단 고정·배경 구분) */
.notice-board__item--pinned { background: var(--bg-alt); }
.notice-board__item--pinned a:hover { background: var(--navy-08); }

.notice-board__title {
  display: flex;
  align-items: center;
  gap: var(--sp-2);
  flex-wrap: wrap;
  font-weight: 500;
  letter-spacing: -.01em;
}
.notice-board__meta {
  display: flex;
  gap: var(--sp-3);
  font-size: var(--fs-sm);
  color: var(--sub);
}

@media (min-width: 1024px) {
  .notice-board__item a { flex-direction: row; align-items: center; justify-content: space-between; gap: var(--sp-4); }
  .notice-board__title { flex: 1; min-width: 0; }
  .notice-board__meta { flex: none; }
}

/* ── 페이지 이동 ────────────────────────────────────────── */
.pager {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: var(--sp-2);
  flex-wrap: wrap;
}
.pager__list { display: flex; gap: var(--sp-1); flex-wrap: wrap; justify-content: center; }
.pager__num,
.pager__arrow {
  min-width: var(--touch-min);
  min-height: var(--touch-min);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  padding: 0 var(--sp-2);
  color: var(--ink);
  text-decoration: none;
  border-radius: var(--radius-sm);
  font-weight: 600;
}
.pager__num:hover, .pager__arrow:hover { background: var(--navy-08); color: var(--navy); }
.pager__num[aria-current="page"] { background: var(--navy); color: var(--white); }
.pager__arrow .ico { width: 20px; height: 20px; }

/* ── 게시글 본문 (NOTI-002) ─────────────────────────────────
   위지윅 본문이 들어오므로 기본 태그 스타일을 여기서 보장한다.
   ------------------------------------------------------- */
/* 제목·작성일은 페이지 바탕에 그대로 두고, 본문은 흰 종이 위에 올린다.
   전에는 옅은 선 하나로만 나뉘어 있어 **어디부터 본문인지 눈에 잡히지 않았다.**
   선을 진하게 하는 대신 바탕을 달리하면 경계가 저절로 생긴다(선은 없앤다 —
   종이 가장자리와 겹쳐 두 줄로 보인다). */
.article__head { margin-bottom: var(--sp-5); }
.article__title {
  font-size: var(--fs-2xl);
  font-weight: var(--fw-title);
  letter-spacing: -.03em;
  display: flex;
  align-items: center;
  gap: var(--sp-2);
  flex-wrap: wrap;
}
.article__meta {
  display: flex;
  gap: var(--sp-4);
  margin-top: var(--sp-3);
  font-size: var(--fs-sm);
  color: var(--sub);
}
/* ⚠ 테두리를 두르지 않는다. 이 화면에서 테두리는 **누를 수 있는 것**(목록으로·
   이전·다음 글·첨부)의 표시다. 읽기만 하는 본문에까지 두르면 그 구분이 흐려진다.
   바탕색만으로 충분히 갈라진다. */
.article__sheet {
  background: var(--white);
  border-radius: var(--radius-card);
  padding: var(--sp-5) var(--sp-4);
}
@media (min-width: 768px) {
  .article__sheet { padding: var(--sp-6); }
}
/* 여백은 종이가 갖는다 — 본문이 또 여백을 들면 위아래가 두 겹이 된다 */
.article__body { padding-block: 0; }
.article__files { margin-top: var(--sp-6); padding-top: var(--sp-5); border-top: 1px solid var(--line); }

/* 위지윅으로 들어오는 기본 태그 */
.prose h2 { font-size: var(--fs-xl); font-weight: var(--fw-title); margin-top: var(--sp-6); margin-bottom: var(--sp-3); }
.prose h3 { font-size: var(--fs-lg); font-weight: 700; margin-top: var(--sp-5); margin-bottom: var(--sp-2); }
.prose ul, .prose ol { margin: var(--sp-3) 0; padding-left: 1.25em; }
.prose ul li { list-style: disc; }
.prose ol li { list-style: decimal; }
.prose li + li { margin-top: var(--sp-1); }
.prose a { color: var(--navy); }
.prose img { border-radius: var(--radius-sm); margin-block: var(--sp-3); }
/* 본문 표 — **표만 따로 가로로 민다.**
   경연 시상 규모처럼 열이 여섯 개인 표는 모바일 폭에 들어가지 않는다. 그대로 두면
   카드(.xcard)의 overflow:hidden 에 걸려 오른쪽 열이 **읽을 방법 없이 잘린다**
   (실제로 상금 칸이 통째로 사라졌다). 칸을 줄이면 '중·고등부'가 글자마다 끊긴다.
   width:max-content 로 표는 제 폭을 갖고, max-width 로 화면을 넘지 않으며,
   넘치는 만큼만 이 상자 안에서 밀린다. 손가락·트랙패드로 밀리고,
   키보드 이용자를 위해 app.js 가 넘칠 때만 tabindex 를 붙인다. */
.prose table {
  display: block;
  width: max-content;
  max-width: 100%;
  overflow-x: auto;
  border-collapse: collapse;
  margin-block: var(--sp-4);
}
.prose table:focus-visible { outline: 2px solid var(--navy); outline-offset: 2px; }
.prose th, .prose td { padding: var(--sp-2) var(--sp-3); border: 1px solid var(--line); text-align: left; }
/* 표 머리글은 줄바꿈하지 않는다 — '중·고등부'가 두 줄로 쪼개지면 열 이름으로 안 읽힌다 */
.prose th { white-space: nowrap; }
.prose blockquote {
  margin: var(--sp-4) 0;
  padding: var(--sp-3) var(--sp-4);
  border-left: 3px solid var(--navy-15);
  background: var(--bg-alt);
  color: var(--ink-2);
}

/* ── 이전·다음 글 ───────────────────────────────────────── */
/* minmax(0,…)과 항목의 min-width:0이 함께 필요하다.
   제목에 white-space:nowrap이 걸려 있어, 그대로 두면 트랙이 제목 전체 폭까지 벌어진다. */
.adjacent { display: grid; grid-template-columns: minmax(0, 1fr); gap: var(--sp-3); }
@media (min-width: 1024px) {
  .adjacent { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}
.adjacent__link {
  min-width: 0;
  display: flex;
  align-items: center;
  gap: var(--sp-3);
  min-height: var(--touch-min);
  padding: var(--sp-4);
  background: var(--white);
  border: 1px solid var(--line);
  border-radius: var(--radius-card);
  text-decoration: none;
  color: var(--ink);
}
.adjacent__link:hover { border-color: var(--navy-15); background: var(--navy-08); }
.adjacent__link .ico { flex: none; width: 20px; height: 20px; color: var(--sub); }
.adjacent__link span { min-width: 0; }
.adjacent__link small { display: block; font-size: var(--fs-xs); color: var(--sub); }
.adjacent__link strong {
  display: block;
  font-weight: 600;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
/* 다음(이전 글) 카드는 오른쪽 정렬 — 방향을 시각적으로 구분 */
.adjacent__link--next { justify-content: flex-end; text-align: right; }

/* ── 오시는 길 (INTRO-003) ──────────────────────────────────
   지도 앱 열기 · 주소 복사는 현장에서 가장 많이 쓰는 동작이라 크게 잡는다.
   ------------------------------------------------------- */
.applinks { display: flex; flex-wrap: wrap; gap: var(--sp-3); }
.applinks .btn { flex: 1 1 auto; min-width: 132px; }
/* 지도 바로 아래에 붙는다 — 제목 없이 이어지므로 지도와 한 묶음으로 읽히게 한다 */
.page-head .applinks { margin-top: var(--sp-3); }

/* .copyrow 는 '지도 앱으로 열기' 아래에 주소를 다시 적고 '주소 복사' 버튼을 두던 것이다.
   주소가 한 화면에 두 번 나와 복사 단추를 주소 옆(.addrline)으로 옮기면서 없앴다. */

/* 지도 임베드 — 관리자가 넣은 iframe이 화면 폭에 맞도록 */
.mapembed {
  position: relative;
  overflow: hidden;
  border: 1px solid var(--line);
  border-radius: var(--radius-card);
  background: var(--navy-08);
}
.mapembed iframe,
.mapembed > div { width: 100%; min-height: 320px; border: 0; display: block; }
@media (min-width: 1024px) {
  .mapembed iframe, .mapembed > div { min-height: 420px; }
}

/* 카카오맵 SDK가 그림을 채우기 전까지 상자가 무너지지 않게 높이를 잡아 둔다.
   높이가 0이면 SDK가 크기를 못 재 지도가 아예 안 그려진다. */
.mapembed__canvas { height: 320px; }
@media (min-width: 1024px) { .mapembed__canvas { height: 420px; } }

/* .mapembed__cap 은 지도를 '위치' 라는 별도 절에 두었을 때 주소를 다시 적어 주던 것이다.
   지도가 주소 바로 아래로 올라오면서 필요가 없어졌다(같은 주소를 두 번 적게 된다). */

/* 지도 범례 — 지도는 aria-hidden 이라 여기가 낭독기에 읽히는 설명이 된다 */
.maplegend {
  display: flex;
  flex-wrap: wrap;
  gap: var(--sp-2) var(--sp-4);
  margin-top: var(--sp-2);
  font-size: var(--fs-sm);
  color: var(--sub);
}
.maplegend__item { display: inline-flex; align-items: center; gap: var(--sp-2); }
.maplegend__pin {
  width: 18px; height: 18px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  border-radius: 50%;
  font-size: 11px;
  font-weight: 800;
}
.maplegend__pin--venue { background: #DB4040; }
.maplegend__pin--park { background: var(--gold); color: var(--gold-ink); }

/* ── 주소 한 줄 + 복사 단추 ────────────────────────────────
   주소를 아래에 다시 적고 '주소 복사' 버튼을 따로 두면 같은 주소가 두 번 나오고
   화면만 길어진다. 주소 옆에 바로 붙인다.
   ------------------------------------------------------- */
.addrline { display: flex; align-items: center; gap: var(--sp-1); flex-wrap: wrap; }
.addrline__copy {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  /* 아이콘은 20px 지만 누르는 자리는 44px 이어야 한다.
     글줄이 벌어지지 않도록 음수 여백으로 줄 높이 밖으로 넘긴다. */
  width: var(--touch-min);
  height: var(--touch-min);
  margin: calc((var(--touch-min) - 24px) / -2) 0;
  padding: 0;
  color: var(--navy);
  background: none;
  border: 0;
  border-radius: 50%;
  cursor: pointer;
}
.addrline__copy .ico { width: 20px; height: 20px; }
.addrline__copy:hover { background: var(--navy-15); }

/* ── 토스트 (복사 결과 등) ─────────────────────────────────
   화면 아래에서 잠깐 떴다 사라진다. 모바일 퀵바 위로 올려 가리지 않게 한다.
   ------------------------------------------------------- */
.toast {
  position: fixed;
  left: 50%;
  bottom: calc(var(--quickbar-h, 64px) + var(--sp-5) + env(safe-area-inset-bottom, 0px));
  transform: translateX(-50%);
  z-index: var(--z-lightbox);
  max-width: calc(100vw - var(--sp-8));
  padding: var(--sp-3) var(--sp-5);
  background: var(--navy-d);
  color: var(--white);
  font-size: var(--fs-sm);
  font-weight: 600;
  border-radius: var(--radius-pill);
  box-shadow: var(--shadow-sm);
  animation: toast-in var(--dur) var(--ease);
}
@keyframes toast-in { from { opacity: 0; transform: translate(-50%, 8px); } to { opacity: 1; transform: translateX(-50%); } }
@media (prefers-reduced-motion: reduce) { .toast { animation: none; } }
@media (min-width: 1024px) {
  /* 데스크톱에는 하단 퀵바가 없다 */
  .toast { bottom: var(--sp-8); }
}

/* 표 안의 부가 설명 (주차장 비고) */
.data-table__cell { display: block; }
.data-table__note {
  display: block;
  margin-top: 2px;
  font-size: var(--fs-sm);
  font-weight: 400;
  color: var(--sub);
}
/* 유의사항·면책 문구 */
.notice-text {
  margin-top: var(--sp-3);
  font-size: var(--fs-sm);
  color: var(--sub);
  line-height: 1.7;
}

/* ── 배치도 뷰어 (INFO-002) ─────────────────────────────────
   touch-action:none — 브라우저 기본 제스처를 끄고 핀치·팬을 직접 처리.
   ------------------------------------------------------- */
.zoomview {
  position: relative;
  overflow: hidden;
  height: min(70vh, 560px);
  background: var(--navy-08);
  border: 1px solid var(--line);
  border-radius: var(--radius-card);
  /* 확대 전에는 세로 스와이프를 페이지 스크롤로 넘긴다.
     확대하면 zoomview.js 가 none 으로 바꿔 뷰어가 가져간다. */
  touch-action: pan-y;
  user-select: none;
}
/* 화면이 낮으면(가로로 눕힌 폰 등) 70vh 도 화면을 거의 다 먹는다.
   아래에 무엇이 더 있다는 것이 보이도록 한 단계 낮춘다. */
@media (max-height: 640px) {
  .zoomview { height: min(56vh, 360px); }
}
.zoomview:active { cursor: grabbing; }
.zoomview__img {
  transform-origin: 0 0;
  will-change: transform;
  max-width: none;       /* base.css의 max-width:100%가 확대를 막지 않도록 */
  -webkit-user-drag: none;
}

.zoomview__controls {
  position: absolute;
  right: var(--sp-3);
  bottom: var(--sp-3);
  display: flex;
  align-items: center;
  gap: var(--sp-1);
  padding: var(--sp-1);
  background: rgba(255, 255, 255, .94);
  border: 1px solid var(--line);
  border-radius: var(--radius-pill);
  box-shadow: var(--shadow-sm);
}
.zoomview__controls .icon-btn { color: var(--navy); font-size: var(--fs-xl); line-height: 1; }
.zoomview__controls .icon-btn:hover { background: var(--navy-08); }
.zoomview__level {
  min-width: 52px;
  padding-inline: var(--sp-2);
  text-align: center;
  font-size: var(--fs-sm);
  font-weight: 700;
  color: var(--sub);
  font-variant-numeric: tabular-nums;
}
.zoomview__hint { margin-top: var(--sp-2); font-size: var(--fs-sm); color: var(--sub); }
/* 뷰어·도움말·저장 단추 한 덩어리 — 서로 딸린 것이므로 절 간격(32px)이 아니라 바짝 붙인다 */
.mapblock__save { margin-top: var(--sp-4); }

/* 범례 — 번호와 명칭이 1:1 대응하는 대체 콘텐츠 */
.legend ul { display: grid; gap: var(--sp-2); }
.legend li { padding-left: 0; }
.legend strong { color: var(--navy); }

/* ── 포스터 (INTRO-001) — 시안 .ph ──────────────────────────── */
.poster { margin: 0; }
.poster .zoomable {
  border: 1px solid var(--line);
  border-radius: var(--radius-lg);
  overflow: hidden;
  background: var(--white);
}
.poster img { width: 100%; height: auto; }
.poster__hint {
  margin-top: var(--sp-2);
  font-size: var(--fs-sm);
  color: var(--sub);
  text-align: center;
}
@media (min-width: 1024px) {
  /* 시안 PC: 포스터 400px 좌측 고정 + 우측 정보 — 화면 폭에 맞춰 중앙 제한 */
  .poster { max-width: 400px; }
}

/* ── 주최·주관 (INTRO-001) — 시안 .hosts ────────────────────── */
.hosts {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: var(--sp-2) var(--sp-5);
  padding-top: var(--sp-5);
  border-top: 1px solid var(--line);
  font-size: var(--fs-sm);
  color: var(--sub);
}
.hosts strong { color: var(--ink-2); font-weight: 700; }

/* ── 오류 화면 (404·500·정적 502) ──────────────────────────
   일반 페이지의 page-head 를 쓰면 짧은 제목 한 줄에 버튼 몇 개만 남아
   화면이 비어 보이고, 여느 사이트의 기본 오류 화면과 구별되지 않는다.
   축전의 색(네이비 바탕 · 골드 강조)을 그대로 써서 '이 사이트 안'임을 먼저 알린다.

   ⚠ 골드를 글자색으로 쓰는 예외 지점이다. 흰 배경 위에서는 2.2:1 이라 금지지만
     네이비(--navy) 위에서는 5.5:1 로 기준을 넘는다. **네이비 배경에서만** 쓸 것.
   ------------------------------------------------------- */
.errbox {
  background: var(--navy);
  color: var(--white);
  border-radius: var(--radius-lg);
  padding: var(--sp-10) var(--sp-5);
  text-align: center;
}
@media (min-width: 768px) {
  .errbox { padding: var(--sp-16) var(--sp-10); }
}

/* 상태 코드 — 읽어 주는 기기에는 의미가 없어 aria-hidden 으로 감춘다.
   Black Han Sans 는 히어로 전용이므로 여기서도 Pretendard 800 을 쓴다. */
.errbox__code {
  font-weight: var(--fw-title);
  font-size: 56px;
  line-height: 1;
  letter-spacing: -0.02em;
  color: var(--gold);
}
@media (min-width: 768px) { .errbox__code { font-size: 72px; } }

/* 코드와 제목 사이 골드 선 — 히어로의 강조 어법과 같은 자리 */
.errbox__rule {
  width: 48px;
  height: 3px;
  margin: var(--sp-5) auto;
  background: var(--gold);
  border-radius: 2px;
}

.errbox__title {
  font-size: var(--fs-xl);
  font-weight: var(--fw-title);
  line-height: 1.35;
}
.errbox__desc {
  margin-top: var(--sp-3);
  font-size: var(--fs-md);
  line-height: 1.7;
  opacity: .92;
}

/* 되돌아갈 길 — 인라인 style 로 두면 화면마다 값이 어긋난다 */
/* 네이비 판만 가운데로 두고, 그 아래는 다른 화면과 같이 왼쪽에 맞춘다.
   가운데·왼쪽이 번갈아 나오면 시선이 지그재그로 움직인다. */
.errpage__actions {
  display: flex;
  flex-wrap: wrap;
  gap: var(--sp-3);
}

/* 운영에서는 나오지 않는다 — 개발 중 스택 추적 */
.errpage__detail {
  overflow-x: auto;
  padding: var(--sp-4);
  background: var(--white);
  border: 1px solid var(--line);
  border-radius: var(--radius-card);
  font-size: var(--fs-sm);
  line-height: 1.6;
}

/* ── 빈 상태 ─────────────────────────────────────────────── */
.empty {
  padding: var(--sp-12) var(--sp-4);
  text-align: center;
  color: var(--sub);
  background: var(--white);
  border: 1px dashed var(--line);
  border-radius: var(--radius-card);
}

/* 준비 중 — 자료가 아직 오지 않은 자리.
   첫 줄은 무엇이 준비 중인지, 둘째 줄은 어떻게 되는지. 첫 줄을 본문 색으로 두어
   '빈 칸' 이 아니라 **안내**로 읽히게 한다(전부 흐린 회색이면 고장처럼 보인다). */
.empty--pending { display: grid; gap: var(--sp-2); }
.empty--pending b { color: var(--ink-2); font-weight: 700; font-size: var(--fs-md); }
.empty--pending span { font-size: var(--fs-sm); }

/* ── 홍보 팝업 (ADM-009) ───────────────────────────────────
   메인에 들어설 때 화면 가운데에 뜨는 안내창. JS 가 만들어 붙인다(popup.js).

   **화면 전체를 덮지 않는다.** 진입 직후 본문을 통째로 가리는 창은 모바일 검색에서
   불리하게 평가되고, 이 사이트는 검색 노출을 핵심 요구사항으로 잡고 있다.
   가운데 카드 + 어두운 배경이면 알릴 것은 알리면서 본문이 뒤에 남는다.  */
.popup {
  position: fixed;
  inset: 0;
  /* 라이트박스와 같은 층 — 헤더·퀵바·드로어보다 위에 있어야 가려지지 않는다 */
  z-index: var(--z-lightbox);
  display: grid;
  place-items: center;
  padding: var(--sp-4);
}
.popup__backdrop {
  position: absolute;
  inset: 0;
  background: rgba(13, 38, 80, .55);
}
.popup__panel {
  position: relative;
  width: min(480px, 100%);
  /* 팝업이 화면보다 길어지면 창이 아니라 **안쪽이** 스크롤된다.
     바깥이 스크롤되면 닫기 단추가 화면 밖으로 밀려 닫을 수 없다. */
  max-height: min(86vh, 720px);
  display: flex;
  flex-direction: column;
  background: var(--white);
  border-radius: var(--radius-lg);
  box-shadow: 0 18px 48px rgba(13, 38, 80, .28);
  overflow: hidden;
  animation: popup-in var(--dur) var(--ease);
}
@keyframes popup-in { from { opacity: 0; transform: translateY(12px); } to { opacity: 1; transform: none; } }
@media (prefers-reduced-motion: reduce) { .popup__panel { animation: none; } }

.popup__scroll {
  overflow-y: auto;
  padding: var(--sp-5) var(--sp-4);
  display: grid;
  gap: var(--sp-4);
}
/* 팝업이 여럿이면 한 상자 안에 쌓는다 — 창을 여러 개 띄우면 닫는 일만 늘어난다 */
.popup__item + .popup__item {
  padding-top: var(--sp-4);
  border-top: 1px solid var(--line-2);
}
.popup__item { display: grid; gap: var(--sp-3); }
.popup__title {
  font-size: var(--fs-xl);
  font-weight: var(--fw-title);
  color: var(--navy);
  line-height: 1.35;
}
.popup__img {
  width: 100%;
  height: auto;
  border-radius: var(--radius-sm);
}
.popup__body { font-size: var(--fs-md); }
.popup__link { justify-self: start; }

/* 단추 줄은 스크롤 밖에 고정 — 내용이 길어도 닫기가 늘 보인다 */
.popup__foot {
  display: flex;
  /* 두 단추가 한 줄에 못 들어가면 **줄을 바꿔 각자 한 줄씩** 쓴다.
     아래 nowrap 과 짝이다 — 글자를 접지 않기로 했으니 넘칠 자리를 줘야 한다. */
  flex-wrap: wrap;
  gap: var(--sp-2);
  padding: var(--sp-3) var(--sp-4) calc(var(--sp-3) + env(safe-area-inset-bottom, 0px));
  border-top: 1px solid var(--line);
  background: var(--bg-alt);
}
/* ⚠ '오늘 하루 보지 않기' 가 '오늘 하루 보지 / 않기' 로 접히지 않게 한다.
   base.css 의 overflow-wrap: break-word 가 전역이라 칸이 좁으면 그냥 접힌다.
   비율(2:1)로 나눠 봤지만 320px 대 화면에서는 그것으로도 모자랐다 —
   접지 않기로 못박고, 좁으면 줄을 바꾸게 두는 편이 확실하다.
   좌우 여백도 기본 단추(20px)보다 줄여 한 줄에 들어갈 여지를 넓힌다. */
.popup__foot .btn {
  min-height: var(--touch-min);
  padding-inline: var(--sp-3);
  white-space: nowrap;
  /* 늘어나되 줄어들지는 않는다 — 줄어들면 nowrap 글자가 단추 밖으로 삐져나온다 */
  flex: 1 0 auto;
}

/* ── 테스트 서버 안내 띠 (NOINDEX=1) ────────────────────────
   검수하는 사람이 '지금 어느 서버를 보고 있는지' 헷갈리지 않게 한다.
   운영에서는 아예 그려지지 않으므로 화면 높이에 영향을 주지 않는다.

   ⚠ 골드 배경 위 글자는 --gold-ink 를 쓴다(흰 배경 위 골드 글자는 대비 2.2:1). */
.stagingbar {
  padding: var(--sp-2) var(--gutter);
  background: var(--gold);
  color: var(--gold-ink);
  font-size: var(--fs-sm);
  text-align: center;
}
