@charset "UTF-8";
/* ============================================================================
 * v1 — 수채화 · 사료(史料)
 * 설계: ../DESIGN.v1.md  토큰: ../tokens.v1.css + ../tokens.base.css
 * ==========================================================================*/

/* ── reset ────────────────────────────────────────────────────────────────*/
*, *::before, *::after { box-sizing: border-box; }
html { -webkit-text-size-adjust: 100%; scroll-behavior: smooth; }
@media (prefers-reduced-motion: reduce) { html { scroll-behavior: auto; } }
body, h1, h2, h3, h4, p, figure, blockquote, dl, dd, ul, ol { margin: 0; padding: 0; }
ul, ol { list-style: none; }
img, svg { display: block; max-width: 100%; }
button, input, select, textarea { font: inherit; color: inherit; }
table { border-collapse: collapse; width: 100%; }

/* ── 한글 조판 — 완료조건 10 ──────────────────────────────────────────────*/
body, p, li, td, th, dd, dt, h1, h2, h3, h4, figcaption, label, button, a {
  word-break: keep-all;
  line-break: strict;
  overflow-wrap: break-word;
}

/* ── base ─────────────────────────────────────────────────────────────────*/
body {
  background: var(--v1-paper);
  color: var(--v1-ink);
  font-family: var(--v1-font-body);
  font-size: var(--v1-text-base);
  line-height: var(--v1-lead-base);
  letter-spacing: var(--v1-track-base);
  -webkit-font-smoothing: antialiased;
}

.wrap { width: min(100% - var(--v1-space-6), 1200px); margin-inline: auto; }
.wrap--narrow { width: min(100% - var(--v1-space-6), 900px); margin-inline: auto; }

:focus-visible {
  outline: 2px solid var(--v1-accent);
  outline-offset: 3px;
  border-radius: var(--v1-radius-sm);
}

.skip {
  position: absolute; left: var(--v1-space-4); top: var(--v1-space-4);
  background: var(--v1-ink); color: var(--v1-paper);
  padding: var(--v1-space-3) var(--v1-space-5);
  z-index: 200;
  transform: translateY(-200%);
  transition: transform var(--v1-dur-micro) var(--v1-ease-lift);
}
.skip:focus { transform: translateY(0); }

.sr-only {
  position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px;
  overflow: hidden; clip-path: inset(50%); white-space: nowrap;
}

/* ══ 4괘 파생 — 선(線)의 리듬 ═══════════════════════════════════════════════
 * 효(爻)의 반복·끊김을 괘선 패턴으로. v1 점유 (SIGNATURE-LEDGER.md)
 * 모션 없음 — 국가 상징을 가볍게 다루지 않는다. */
.rule {
  height: 1px; border: 0; margin: 0;
  background-image:
    linear-gradient(to right, var(--v1-ink) 0 44px, transparent 44px 52px,
                    var(--v1-ink) 52px 72px, transparent 72px 80px,
                    var(--v1-ink) 80px 124px, transparent 124px);
  background-repeat: no-repeat;
  background-size: 100% 1px;
  position: relative;
}
.rule::after {
  content: ""; position: absolute; inset: 0 0 0 140px;
  background: var(--v1-border);
  height: 1px;
}

/* ══ 타이포 ════════════════════════════════════════════════════════════════*/
.display {
  font-family: var(--v1-font-display);
  /* 명조는 볼드/레귤러 자폭비가 1.000 이다 — 굵게 해도 자폭이 늘지 않는다.
   * 800 은 획이 뭉쳐 판독만 떨어졌다. 위계는 크기로 만든다(§weight 운용). */
  font-weight: var(--v1-weight-display);
  font-size: var(--v1-text-3xl);
  line-height: var(--v1-lead-3xl);
  letter-spacing: var(--v1-track-3xl);
}
.h2 {
  font-family: var(--v1-font-display);
  font-weight: var(--v1-weight-display);
  font-size: var(--v1-text-2xl);
  line-height: var(--v1-lead-2xl);
  letter-spacing: var(--v1-track-2xl);
}
.h3 {
  font-family: var(--v1-font-display);
  font-weight: var(--v1-weight-display);
  font-size: var(--v1-text-xl);
  line-height: var(--v1-lead-xl);
  letter-spacing: var(--v1-track-xl);
}
.eyebrow {
  font-size: var(--v1-text-xs);
  letter-spacing: var(--v1-track-label);
  line-height: var(--v1-lead-tight);
  color: var(--v1-accent);
  font-weight: 600;
  text-transform: none;
}
.lede {
  font-size: var(--v1-text-lg); color: var(--v1-ink-2);
  line-height: var(--v1-lead-lg);
  letter-spacing: var(--v1-track-lg);
}
.muted { color: var(--v1-ink-3); }
.small { font-size: var(--v1-text-sm); letter-spacing: var(--v1-track-sm); }

/* 섹션 헤더 3요소 — 헤드라인 / 부제 / 우측 요소 (빵 계열에서 배운 패턴) */

/* ══ 섹션 여백 위계 — 3단계 (brief §6) ═════════════════════════════════════
 * 전 섹션 동일 padding 은 "어느 섹션도 다른 곳보다 중요하지 않다"는 뜻이다.
 * 공간 점유량 자체로 우선순위를 표현한다. 배정 근거: DESIGN.v1.md §6-4
 *
 * ⚠️ 재검토 (2026-07-30) — padding 값만 3단계로 두면 위계가 실제로는 사라진다.
 *    독자가 지각하는 것은 각 섹션의 padding 이 아니라 **섹션 사이의 간격**,
 *    즉 앞 섹션 padding-bottom + 뒤 섹션 padding-top 이다.
 *    실측 결과 그 값이 256 / 256 / 320 / 256 / 192 로 거의 균일했고,
 *    lead 두 개가 인접한 자리(320px)가 페이지에서 가장 큰 빈 구간이 되어
 *    "가장 중요한 섹션" 이 아니라 "가장 큰 공백" 을 만들고 있었다.
 *
 * → 해법: 위쪽 여백을 위계의 주 신호로 쓰고, 아래쪽은 절반으로 줄인다.
 *   섹션의 무게는 "그 앞에 얼마나 숨을 두는가" 로 표현된다.
 *   인접 lead 는 :has()/인접 선택자로 상쇄한다. */
.sec {
  padding-top: var(--v1-sec-base);
  padding-bottom: calc(var(--v1-sec-base) / 2);
}
.sec--lead {
  padding-top: var(--v1-sec-lead);
  padding-bottom: calc(var(--v1-sec-lead) / 2);
}
.sec--tight {
  padding-top: var(--v1-sec-tight);
  padding-bottom: calc(var(--v1-sec-tight) / 2);
}
/* 지면 색이 바뀌는 섹션 — 아래 여백도 살려야 배경 블록이 잘려 보이지 않는다 */
.sec--ground { background: var(--v1-surface); padding-bottom: var(--v1-sec-base); }
.sec--lead.sec--ground { padding-bottom: var(--v1-sec-lead); }

/* ── 절(subsection) 간격 — 한 섹션 안의 덩어리 나누기 ──────────────────────
 * 긴 안내 페이지는 h2 가 여럿 이어진다. 전부 같은 간격이면 **묶음이 안 보인다** —
 * 여섯 덩어리가 한 줄로 늘어서서 어디까지가 한 이야기인지 읽히지 않는다.
 * (실측: /apply/guide 의 제목 간격이 96·96·96·96·86 으로 사실상 균일했다)
 *
 * DESIGN §6-4 가 섹션 여백에 3단계를 준 것과 같은 원리를 절에도 적용한다.
 *   --sub      기본. 같은 묶음 안의 다음 절
 *   --sub-lead 묶음이 바뀌는 자리. 여기서 화제가 넘어간다
 * 제목마다 인라인 style 로 margin 을 박지 않는다. 그렇게 하면 다시 균일해진다. */
.sub      { margin-top: var(--v1-space-8); }   /* 64px */
.sub--lead{ margin-top: var(--v1-space-10); }  /* 120px — 묶음 경계 */

/* 묶음 경계에는 괘선을 얹어 눈으로도 끊기게 한다. 색 블록을 쓰지 않는다 */
.sub--lead::before {
  content: ""; display: block;
  width: var(--v1-space-6); height: 2px;
  background: var(--v1-accent);
  margin-bottom: var(--v1-space-5);
}
@media (max-width: 700px) {
  /* 모바일은 절대값을 줄이되 **비율은 유지**한다(§6-4 와 같은 규칙) */
  .sub      { margin-top: var(--v1-space-7); }   /* 48px */
  .sub--lead{ margin-top: var(--v1-space-9); }   /* 96px */
}

/* lead 가 연달아 오면 앞 섹션의 **아래** 여백을 줄인다.
 * 뒤 섹션의 위쪽 여백을 깎으면 강조 대상이 강조를 잃는다 —
 * course·apply 는 둘 다 lead 로 배정된 근거가 있으므로(DESIGN.v1.md §6-4)
 * 둘 다 위쪽 숨을 유지하고, 그 사이의 중복분만 앞쪽에서 덜어낸다. */
.sec--lead:has(+ .sec--lead) { padding-bottom: var(--v1-space-6); }
.sec--lead.sec--ground:has(+ .sec--lead) { padding-bottom: var(--v1-sec-base); }

/* 모바일에서는 위계 비율을 유지하되 절대값을 크게 줄인다.
 * 데스크탑 값을 그대로 쓰면 360px 화면에서 섹션 경계마다 빈 화면이 하나씩
 * 생긴다(실측: 연속 텍스트만 화면의 주 원인이 여백이었다).
 * 화면이 좁을수록 같은 px 이 차지하는 '화면 비율'이 커진다는 점을 반영한다. */
@media (max-width: 700px) {
  .sec        { padding-top: var(--v1-space-7); padding-bottom: var(--v1-space-5); }
  .sec--lead  { padding-top: var(--v1-space-8); padding-bottom: var(--v1-space-6); }
  .sec--tight { padding-top: var(--v1-space-6); padding-bottom: var(--v1-space-4); }
  .sec--lead:has(+ .sec--lead) { padding-bottom: var(--v1-space-5); }
  .sec--ground, .sec--lead.sec--ground { padding-bottom: var(--v1-space-7); }
}
.sec__head {
  display: grid;
  grid-template-columns: 1fr auto;
  gap: var(--v1-space-4) var(--v1-space-6);
  align-items: end;
  margin-bottom: var(--v1-space-7);
}
.sec__head .lede { grid-column: 1; max-width: 62ch; }
.sec__aside { grid-column: 2; grid-row: 1 / span 2; align-self: end; }
@media (max-width: 700px) {
  .sec__head { grid-template-columns: 1fr; }
  .sec__aside { grid-column: 1; grid-row: auto; }
}

/* ══ 버튼 — 호버가 색 단독이 아니다 (완료조건 9) ═════════════════════════*/
/* [hidden] 이 display 를 이기게 한다.
 * .btn 의 display:inline-flex 가 브라우저 기본 [hidden]{display:none} 보다
 * 구체성이 높아, hidden 을 걸어도 버튼이 그대로 보였다 —
 * 신청 완료 후 "접수 중…" 이 남아 있던 원인이다. */
[hidden] { display: none !important; }

.btn {
  display: inline-flex; align-items: center; gap: var(--v1-space-2);
  padding: var(--v1-space-3) var(--v1-space-6);
  font-weight: 600; font-size: var(--v1-text-sm);
  text-decoration: none;
  border: 1px solid var(--v1-ink);
  border-radius: var(--v1-radius-sm);
  background: var(--v1-ink); color: var(--v1-paper);
  transition:
    background-color var(--v1-dur-micro) var(--v1-ease-lift),
    transform var(--v1-dur-micro) var(--v1-ease-lift),
    box-shadow var(--v1-dur-micro) var(--v1-ease-lift),
    border-color var(--v1-dur-micro) var(--v1-ease-lift);
}
/* 색 + transform + 그림자 3축 동반 */
.btn:hover {
  background: var(--v1-accent);
  border-color: var(--v1-accent);
  transform: translateY(-1px);
  box-shadow: var(--v1-shadow-md);
}
.btn:active { transform: translateY(0); }

.btn--ghost {
  background: transparent; color: var(--v1-ink);
  border-color: var(--v1-border);
}
.btn--ghost:hover {
  background: transparent; color: var(--v1-accent);
  border-color: var(--v1-accent);
  transform: translateY(-1px);
  box-shadow: var(--v1-shadow-sm);
}

/* 텍스트 링크 — 밑줄이 좌→우로 그려짐 */
.link {
  color: var(--v1-ink); text-decoration: none;
  background-image: linear-gradient(var(--v1-accent), var(--v1-accent));
  background-repeat: no-repeat;
  background-position: 0 100%;
  background-size: 0% 1px;
  transition: background-size var(--v1-dur-short) var(--v1-ease-lift),
              color var(--v1-dur-micro) var(--v1-ease-lift);
}
.link:hover { color: var(--v1-accent); background-size: 100% 1px; }

/* ══ 네비 — 2단 구조 (brief §9-2) ══════════════════════════════════════════
 * 동작 규격은 세 버전 공통. v1의 표현: 괘선과 잉크 밑줄, 그림자 없는 평면 패널.
 * shell.js 가 내용을 주입하므로 높이를 미리 예약한다 (CLS 방지). */
.nav {
  position: sticky; top: 0; z-index: 100;
  background: var(--v1-white);
  border-bottom: 1px solid var(--v1-border-soft);
  min-height: var(--v1-nav-h);
}
@media (max-width: 900px) { .nav { min-height: var(--v1-nav-h-sm); } }
.nav__in {
  display: flex; align-items: center; justify-content: space-between;
  gap: var(--v1-space-5);
  padding-block: var(--v1-space-3);
  /* 폭은 넓게 잡아 CTA 를 화면 오른쪽 가까이 보내고,
   * 로고는 padding-left 로 본문 선(1200px)까지 밀어 넣는다.
   * 둘을 같은 폭에 묶으면 하나를 맞출 때 다른 하나가 어긋난다. */
  width: min(100% - var(--v1-space-6), 1560px);
  padding-inline-start: max(0px, (min(100vw - var(--v1-space-6), 1560px) - 1200px) / 2);
  margin-inline: auto;
}
/* 대분류가 줄바꿈되면 네비 높이가 흔들리고 밑줄이 두 줄로 끊긴다.
 * "참가신청 · 조회 · 수정" 처럼 긴 항목이 있어 명시적으로 막는다. */
.nav__top { white-space: nowrap; }
.nav__logo { display: flex; align-items: center; flex: 0 0 auto; }
/* 로고 잉크색 제어 — 단색 PNG를 mask로 착색 */
.logo-mark {
  /* span 이므로 display 를 명시하지 않으면 inline 이라 0×0 으로 접힌다.
   * 내비게이션은 별도 규칙으로 block 이 걸려 보였지만 푸터에서는 사라졌었다. */
  display: block;
  width: var(--v1-logo-w); height: var(--v1-logo-h);
  background-color: var(--logo-ink);
  -webkit-mask: url("/assets/logo.png") no-repeat center / contain;
  mask: url("/assets/logo.png") no-repeat center / contain;
}

/* 간격을 넓힌다 — 대분류가 4개뿐이라 붙어 있으면 하나로 읽힌다 */
.nav__list { display: flex; gap: var(--v1-space-8); align-items: center; }
.nav__item { position: static; }   /* 메가판은 네비 전체 기준으로 펼친다 */

.nav__top {
  position: relative;
  display: inline-block;
  background: none; border: 0; cursor: pointer;
  color: var(--v1-ink-2);
  /* 이전 text-sm(13px)은 대분류 치고 작았다. 한 단계 올린다 */
  font-size: var(--v1-text-base); font-weight: 500;
  text-decoration: none;
  padding: var(--v1-space-4) 0;
  transition: color var(--v1-dur-micro) var(--v1-ease-lift),
              transform var(--v1-dur-micro) var(--v1-ease-lift);
}
/* 하단 잉크 밑줄이 좌에서 자라남 */
.nav__top::after {
  content: ""; position: absolute; left: 0; bottom: var(--v1-space-2);
  height: 1px; width: 0; background: var(--v1-accent);
  transition: width var(--v1-dur-short) var(--v1-ease-lift);
}
.nav__top:hover, .nav__top.is-hot { color: var(--v1-ink); }
.nav__top:hover { transform: translateY(-1px); }
.nav__top:hover::after,
.nav__top.is-hot::after,
.nav__top[aria-expanded="true"]::after { width: 100%; }
/* 현재 그룹 표시 */
.nav__top[aria-current="true"] { color: var(--v1-ink); }
.nav__top[aria-current="true"]::after { width: 100%; background: var(--v1-ink); }

/* ── 통합 메가메뉴 ──────────────────────────────────────────────────────────
 * 대분류마다 따로 뜨던 드롭다운을 판 하나로 합쳤다. 4갈래가 한 번에 보인다.
 * 지면은 **흰색**이다 — 이전 --v1-paper 는 세피아라 누렇게 읽혔다. */
.mega {
  /* left·width 는 shell.js alignMega 가 메뉴 구간에 맞춰 잡는다.
   * 아래 값은 계산 전(또는 JS 꺼짐) 폴백이다. */
  position: absolute; left: 0; right: 0; top: 100%;
  z-index: 60;
  background: var(--v1-white);
  border-top: 1px solid var(--v1-border);
  border-bottom: 2px solid var(--v1-ink);
  box-shadow: var(--v1-shadow-md);
  opacity: 0; visibility: hidden;
  transform: translateY(-4px);
  transition: opacity var(--v1-dur-micro) var(--v1-ease-lift),
              transform var(--v1-dur-micro) var(--v1-ease-lift),
              visibility 0s linear var(--v1-dur-micro);
}
.mega[data-open="true"] {
  opacity: 1; visibility: visible; transform: none;
  transition-delay: 0s;
}
.mega__in {
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: var(--v1-space-7);
  padding-block: var(--v1-space-6) var(--v1-space-7);
}
/* 호버 중이 아닌 열은 한 단계 물러나 있는다. 지금 보는 갈래가 어디인지 알린다 */
.mega__col { opacity: 0.55; transition: opacity var(--v1-dur-micro) var(--v1-ease-lift); }
.mega__col.is-active { opacity: 1; }
.mega__h {
  display: block;
  font-family: var(--v1-font-display);
  font-size: var(--v1-text-base); color: var(--v1-ink);
  text-decoration: none;
  padding-bottom: var(--v1-space-3);
  border-bottom: 1px solid var(--v1-border);
  margin-bottom: var(--v1-space-3);
}
.mega__h:hover { color: var(--v1-accent); }
.mega__list { display: grid; gap: var(--v1-space-1); }
/* 대분류 글자 아래에 가운데로 모은다. 열 자체의 위치는 shell.js
 * alignMega 가 대분류 글자의 중심에 맞춘다. */
.mega__sub {
  display: block; padding: var(--v1-space-2) var(--v1-space-3);
  font-size: var(--v1-text-sm); color: var(--v1-ink-2);
  text-decoration: none;
  text-align: center;
  /* 왼쪽 테두리로 강조하던 것을 밑줄로 바꾼다 — 가운데 정렬에서는
   * 글자와 떨어진 왼쪽 끝에 선이 떠 무엇을 가리키는지 알기 어렵다. */
  transition: background-color var(--v1-dur-micro) var(--v1-ease-lift),
              color var(--v1-dur-micro) var(--v1-ease-lift);
}
.mega__sub:hover {
  background: var(--v1-surface); color: var(--v1-ink);
  text-decoration: underline;
  text-decoration-color: var(--v1-accent);
  text-underline-offset: 4px;
}
.mega__sub[aria-current="page"] { color: var(--v1-ink); font-weight: 600; }
.mega__sub[aria-current="page"]::before { content: "· "; color: var(--v1-accent); }

.nav__toggle { display: none; }

@media (max-width: 1024px) {
  .nav__links, .nav__cta .btn--ghost { display: none; }
  .nav__in { gap: var(--v1-space-3); }
  .nav__toggle {
    display: inline-flex; align-items: center; justify-content: center;
    width: var(--v1-tap-min); height: var(--v1-tap-min);
    background: transparent; border: 1px solid var(--v1-border);
    border-radius: var(--v1-radius-sm); cursor: pointer;
    transition: border-color var(--v1-dur-micro) var(--v1-ease-lift),
                transform var(--v1-dur-micro) var(--v1-ease-lift);
  }
  .nav__toggle:hover { border-color: var(--v1-accent); transform: translateY(-1px); }
}
@media (max-width: 420px) {
  .nav__cta .btn { display: none; }
}

/* ── 모바일 패널 — 아코디언 ─────────────────────────────────────────────── */
.mnav {
  display: none;
  border-top: 1px solid var(--v1-border);
  background: var(--v1-surface);
  max-height: calc(100dvh - 64px);
  overflow-y: auto;
}
.mnav[data-open="true"] { display: block; }
.mnav__group { border-bottom: 1px solid var(--v1-border-soft); }
.mnav__top {
  width: 100%; text-align: left;
  background: none; border: 0; cursor: pointer;
  padding: var(--v1-space-4) 0;
  font-family: var(--v1-font-display);
  font-size: var(--v1-text-lg); color: var(--v1-ink);
  display: flex; justify-content: space-between; align-items: center;
}
.mnav__top::after {
  content: ""; width: 8px; height: 8px;
  border-right: 1px solid var(--v1-ink-3); border-bottom: 1px solid var(--v1-ink-3);
  transform: rotate(45deg) translateY(-2px);
  transition: transform var(--v1-dur-short) var(--v1-ease-lift);
}
.mnav__top[aria-expanded="true"]::after { transform: rotate(-135deg) translateY(-2px); }
.mnav__sub { display: none; padding-bottom: var(--v1-space-3); }
.mnav__sub[data-open="true"] { display: block; }
.mnav__sub a {
  display: block; padding: var(--v1-space-3) 0 var(--v1-space-3) var(--v1-space-4);
  color: var(--v1-ink-2); text-decoration: none;
  border-left: 2px solid var(--v1-border);
  transition: border-left-color var(--v1-dur-micro) var(--v1-ease-lift),
              color var(--v1-dur-micro) var(--v1-ease-lift);
}
.mnav__sub a:hover { color: var(--v1-ink); border-left-color: var(--v1-accent); }
.mnav__sub a[aria-current="page"] { color: var(--v1-accent); font-weight: 600; border-left-color: var(--v1-accent); }

/* ══ 페이지 템플릿 (히어로 없는 하위 페이지) ══════════════════════════════ */
/* 세부 페이지 — 지면을 두 층으로 나눈다(2026-08-13).
 * 이전에는 머리부터 본문까지 전부 세피아 한 톤이라 섹션이 다 같은 무게로
 * 읽혔다. 머리만 세피아로 두고 본문은 화이트로 내려 층을 만든다. */
/* 세부 페이지 머리 — 히어로 이미지를 배경으로 깐다(2026-08-14 지시).
 * 누런 단색이라 페이지마다 첫인상이 같았다. 독립기념관 실경(hero-overview)을
 * 깔고 그 위에 제목을 얹는다. 홈 히어로(수채화 인물)와는 다른 이미지라
 * 홈과 세부가 구분된다.
 *
 * ⚠️ 이미지 위 텍스트는 대비가 무너지기 쉽다. 좌→우 그라디언트로
 *    텍스트가 앉는 좌측만 덮는다(홈 히어로와 같은 처리). */
.phead {
  position: relative;
  isolation: isolate;
  border-bottom: 1px solid var(--v1-border);
  background:
    linear-gradient(
      100deg,
      color-mix(in srgb, var(--v1-paper) 95%, transparent) 0%,
      color-mix(in srgb, var(--v1-paper) 90%, transparent) 34%,
      color-mix(in srgb, var(--v1-paper) 66%, transparent) 52%,
      color-mix(in srgb, var(--v1-paper) 34%, transparent) 68%,
      color-mix(in srgb, var(--v1-paper) 18%, transparent) 100%),
    image-set(
      url("/assets/hero-overview-1280.avif") type("image/avif"),
      url("/assets/hero-overview-1280.webp") type("image/webp"),
      url("/assets/hero-overview-1280.jpg")  type("image/jpeg"))
      center 62% / cover no-repeat,
    var(--v1-surface);
  padding-block: var(--v1-space-9) var(--v1-space-8);
}
/* 이야기 페이지는 어두운 지면이라 밝은 머리가 어울리지 않는다 */
.story-page .phead { background: color-mix(in srgb, var(--v1-paper) 5%, var(--v1-ground-deep)); }
/* 본문 지면 — 홈 하단과 같은 화이트 */
main > .sec, main > .sec--lead, main > .sec--tight { background: var(--v1-white); }
/* 교차 지면 — 섹션이 이어질 때 하나 걸러 지면을 바꿔 리듬을 만든다.
 * 전부 흰 지면이면 8개 섹션이 한 덩어리로 읽힌다. */
main > .sec--ground { background: var(--v1-paper); }
.crumb {
  display: flex; gap: var(--v1-space-2); align-items: center;
  font-size: var(--v1-text-xs); color: var(--v1-ink-3);
  margin-bottom: var(--v1-space-4);
}
.crumb a { color: var(--v1-ink-3); text-decoration: none; }
.crumb a:hover { color: var(--v1-accent); }
.crumb__sep { opacity: .5; }
/* 섹션 머리 — 제목 위에 얇은 잉크선을 둬서 섹션 시작점을 명확히 한다.
 * 여백만으로 구분하면 스크롤 중에 어디가 새 섹션인지 놓친다. */
main > .sec > .wrap > .h3,
main > .sec > .wrap > .h2 {
  position: relative;
  padding-top: var(--v1-space-5);
}
main > .sec > .wrap > .h3::before,
main > .sec > .wrap > .h2::before {
  content: ""; position: absolute; top: 0; left: 0;
  width: 40px; height: 2px; background: var(--v1-accent);
}

.phead__title {
  font-family: var(--v1-font-display);
  font-size: var(--v1-text-2xl);
  line-height: var(--v1-leading-tight);
  letter-spacing: var(--v1-tracking-tight);
}
.phead__lede { margin-top: var(--v1-space-3); max-width: 62ch; }

/* 하위 페이지 내 탭 (코스 3종, 대회안내 5개 등) */
.ptabs { display: flex; gap: 0; flex-wrap: wrap; margin-top: var(--v1-space-6); }
.ptabs a {
  padding: var(--v1-space-3) var(--v1-space-5);
  font-size: var(--v1-text-sm); text-decoration: none;
  color: var(--v1-ink-3);
  border-bottom: 2px solid var(--v1-border);
  transition: color var(--v1-dur-micro) var(--v1-ease-lift),
              border-bottom-color var(--v1-dur-micro) var(--v1-ease-lift);
}
.ptabs a:hover { color: var(--v1-ink); border-bottom-color: var(--v1-ink-3); }
.ptabs a[aria-current="page"] { color: var(--v1-ink); border-bottom-color: var(--v1-accent); font-weight: 600; }

/* ══ 히어로 ════════════════════════════════════════════════════════════════
 * 시그니처: 잉크 번짐 리빌 — mask-size를 --bleed 로 제어.
 * 스크롤/진입 모두 이 변수 하나만 갱신한다 (레이아웃 유발 없음). */
.hero { position: relative; overflow: clip; background: var(--v1-paper); }
.hero__media {
  position: relative;
  aspect-ratio: 1916 / 821;          /* CLS 0 — 종횡비 고정 */
  width: 100%;
}
/* ── 히어로 로테이션 ────────────────────────────────────────────────────────
 * 실사진 2~3장을 받으면 동작한다(data/event.json 의 hero.images).
 * 지금은 1장이라 .hero__slide 가 붙지 않고 아래 규칙도 적용되지 않는다.
 *
 * 위치를 겹쳐 두고 opacity 만 바꾼다 — 레이아웃을 건드리지 않으므로 CLS 0 이다.
 * 슬라이드가 하나뿐일 때 opacity:0 이 되면 히어로가 사라지므로,
 * :only-child 를 예외로 둔다(JS 가 실패해도 첫 장은 보인다). */
.hero__slide {
  position: absolute; inset: 0;
  opacity: 0;
  transition: opacity var(--v1-dur-epic) var(--v1-ease-ink);
}
/* 실사진 슬라이드 — 사진 전체를 고르게 어둡게 깐다(2026-08-19 지시).
 * 원본 사이트가 쓰는 방식이다. 한쪽만 눌러 그라디언트를 만들면 경계가 보이고,
 * 글자에 효과를 얹으면 테두리·번짐이 남는다. 사진 전체를 한 단계 내리는 것이
 * 가장 깨끗하다 — 흰 글자가 어디에 놓여도 읽힌다.
 * 수채화(첫 장)에는 붙지 않는다. 밝은 그림이라 어두운 잉크가 그대로 읽힌다. */
.hero__slide--photo::after {
  content: "";
  position: absolute; inset: 0;
  pointer-events: none;
  background: rgba(0, 0, 0, 0.42);
}
.hero__slide.is-on, .hero__slide:only-child { opacity: 1; }

/* ── 히어로 좌우 화살표 ─────────────────────────────────────────────────────
 * 원본 사이트도 같은 자리에 꺽새를 둔다. 사진 위에 얹히므로 어느 사진에서도
 * 보이도록 **지면색 원판 + 잉크 꺽새**로 만든다. 반투명 유리를 쓰지 않는다.
 * 크기는 44px — 손가락으로 누를 수 있는 최소 크기다. */
/* 배경 없는 반투명 꺽새. 원형 판을 두면 그림 위에 단추가 얹힌 것처럼
 * 보여 배너를 가린다. 꺽새만 남기고 판은 없앤다.
 * 다만 밝은 사진 위에서 흰 꺽새가 사라지므로 옅은 그늘을 깐다. */
.hero__arrow {
  position: absolute; top: 50%; transform: translateY(-50%);
  z-index: 2;
  width: 44px; height: 44px;
  display: grid; place-items: center;
  border: 0;
  border-radius: 50%;
  background: transparent;
  cursor: pointer;
  transition: background var(--v1-dur-short) var(--v1-ease-lift),
              border-color var(--v1-dur-short) var(--v1-ease-lift),
              transform var(--v1-dur-short) var(--v1-ease-lift);
}
.hero__arrow--prev { left: var(--v1-space-5); }
.hero__arrow--next { right: var(--v1-space-5); }
/* 꺽새는 글자가 아니라 도형이다 — 폰트가 없어도 같은 모양이 나오게 border 로 그린다 */
.hero__arrow span {
  width: 14px; height: 14px;
  border-top: 2px solid rgb(255 255 255 / 78%);
  border-right: 2px solid rgb(255 255 255 / 78%);
  /* 밝은 하늘 위에서도 보이게 얇은 그늘을 준다 — 판을 깔지 않는 대신이다 */
  filter: drop-shadow(0 1px 2px rgb(0 0 0 / 45%));
  transition: border-color var(--v1-dur-short) var(--v1-ease-lift);
}
.hero__arrow--prev span { transform: rotate(-135deg); margin-left: 3px; }
.hero__arrow--next span { transform: rotate(45deg);   margin-right: 3px; }
/* 호버 — 색만 바꾸지 않는다(완료조건 9). 살짝 커지고 꺽새가 또렷해진다 */
.hero__arrow:hover {
  transform: translateY(-50%) scale(1.12);
}
.hero__arrow:hover span { border-color: #fff; }
.hero__arrow:focus-visible {
  outline: 2px solid var(--v1-accent);
  outline-offset: 3px;
}

/* ── 점 표시 ────────────────────────────────────────────────────────────────
 * 화살표만 있으면 전체가 몇 장인지 모른다. 현재 위치를 함께 보여준다. */
.hero__dots {
  position: absolute; z-index: 2;
  left: 50%; transform: translateX(-50%);
  bottom: var(--v1-space-5);
  display: flex; gap: var(--v1-space-3);
}
.hero__dot {
  width: 10px; height: 10px; padding: 0;
  border: 1px solid var(--v1-ink);
  border-radius: 50%;
  background: transparent;
  cursor: pointer;
  transition: background var(--v1-dur-short) var(--v1-ease-lift),
              transform var(--v1-dur-short) var(--v1-ease-lift);
}
.hero__dot.is-on { background: var(--v1-ink); transform: scale(1.2); }
.hero__dot:focus-visible { outline: 2px solid var(--v1-accent); outline-offset: 3px; }

@media (max-width: 860px) {
  /* 모바일에서는 화살표를 지면 위가 아니라 사진 안쪽으로 더 붙인다 */
  .hero__arrow--prev { left: var(--v1-space-3); }
  .hero__arrow--next { right: var(--v1-space-3); }
}

.hero__img {
  width: 100%; height: 100%;
  object-fit: cover;
  object-position: 72% center;        /* 선두 인물이 잘리지 않게 */
}
/* 잉크 번짐 마스크 — 불규칙 경계를 radial 다중 겹침으로 정적 생성 */
.bleed {
  --bleed: 0;
  -webkit-mask-image:
    radial-gradient(58% 82% at 6% 10%,  var(--v1-mask-opaque) 38%, transparent 72%),
    radial-gradient(46% 66% at 30% 44%, var(--v1-mask-opaque) 34%, transparent 74%),
    radial-gradient(52% 74% at 58% 22%, var(--v1-mask-opaque) 30%, transparent 70%),
    radial-gradient(64% 88% at 82% 62%, var(--v1-mask-opaque) 32%, transparent 76%),
    radial-gradient(40% 58% at 46% 88%, var(--v1-mask-opaque) 28%, transparent 72%);
  mask-image:
    radial-gradient(58% 82% at 6% 10%,  var(--v1-mask-opaque) 38%, transparent 72%),
    radial-gradient(46% 66% at 30% 44%, var(--v1-mask-opaque) 34%, transparent 74%),
    radial-gradient(52% 74% at 58% 22%, var(--v1-mask-opaque) 30%, transparent 70%),
    radial-gradient(64% 88% at 82% 62%, var(--v1-mask-opaque) 32%, transparent 76%),
    radial-gradient(40% 58% at 46% 88%, var(--v1-mask-opaque) 28%, transparent 72%);
  -webkit-mask-repeat: no-repeat;
  mask-repeat: no-repeat;
  /* 각 겹의 크기를 --bleed 로 동시 확장 → 물감이 번지듯.
   * 시작을 0이 아니라 음수 오프셋으로 두면 초기에 더 작은 얼룩에서 퍼져나온다. */
  -webkit-mask-size: calc(var(--bleed) * 150%) calc(var(--bleed) * 170%);
  mask-size: calc(var(--bleed) * 150%) calc(var(--bleed) * 170%);
  -webkit-mask-position: 0% 0%, 22% 36%, 52% 14%, 78% 56%, 40% 84%;
  mask-position: 0% 0%, 22% 36%, 52% 14%, 78% 56%, 40% 84%;
}

/* 가독 스크림 — 텍스트가 앉는 좌측 띠만 밝게 깐다.
 * 근거(실측): 좌측 0~40% 구간은 평균 밝기 0.84 로 밝지만 겨레의탑·나무 그늘에서
 * 0.13 까지 떨어진다. 그 위에 잉크색 글자를 얹으면 최악 1.37:1 로 AA 에 한참 못 미친다
 * (eyebrow 1.37 · slogan 3.03 · meta 1.73 · scroll 4.19 — 5개 중 4개 실패).
 *
 * 전면에 반투명 판을 덮지 않는다. 그러면 수채화가 통째로 흐려진다.
 * 좌→우 그라디언트로 **텍스트 폭만큼만** 덮고 인물·태극기 쪽은 원본 그대로 둔다. */
.hero__panel {
  position: absolute; inset: 0;
  display: grid; align-content: center;
  pointer-events: none;
}
/* ⚠️ 좌측 덮개를 쓰지 않는다(2026-08-19 지시). 그림을 가리지 않는다.
 * 글자는 아래 .hero__stack 의 외곽선으로 읽히게 한다. */
.hero__panel::before { display: none; }
.hero__panel--unused::before {
  content: "";
  position: absolute; inset: 0;
  pointer-events: none;
  background: linear-gradient(
    100deg,
    color-mix(in srgb, var(--v1-paper) 94%, transparent) 0%,
    color-mix(in srgb, var(--v1-paper) 90%, transparent) 26%,
    color-mix(in srgb, var(--v1-paper) 62%, transparent) 42%,
    color-mix(in srgb, var(--v1-paper) 12%, transparent) 54%,
    transparent 64%
  );
}
/* 텍스트는 스크림 위에 온다 */
.hero__stack, .hero__scroll { position: relative; z-index: 1; }
.hero__stack {
  width: min(100% - var(--v1-space-6), 1200px);
  margin-inline: auto;
  max-width: 100%;
}
/* 좌측 정렬. 계단식 들여쓰기(0/52/104/148px)를 쓰지 않는다 —
 * "이미지 밝기 각도를 따라간다"는 의도였으나 화면에서는 정렬이 어긋난 것으로 읽힌다.
 * 한 축으로 맞추는 것이 히어로 문구의 기본이다. */
.hero__row { pointer-events: auto; margin-left: 0; }

.hero__title { max-width: 15ch; }
.hero__slogan {
  font-family: var(--v1-font-display);
  font-size: var(--v1-text-lg);
  color: var(--v1-accent);
  margin-top: var(--v1-space-4);
}
.hero__meta {
  margin-top: var(--v1-space-5);
  font-size: var(--v1-text-sm); color: var(--v1-ink-2);
  display: grid; gap: var(--v1-space-1);
}
/* 두 버튼의 폭·높이를 맞춘다. 폭이 제각각이면 정렬이 흐트러져 보인다. */
.hero__cta {
  margin-top: var(--v1-space-6);
  display: flex; gap: var(--v1-space-3); flex-wrap: wrap;
  align-items: stretch;
}
.hero__cta .btn { min-width: 148px; justify-content: center; }

/* 히어로 버튼은 배경 그림 위에 얹힌다. 수채화든 사진이든 뒤가 밝고
 * 무늬가 있어서, 투명 배경 + 얇은 선으로는 글자가 묻힌다.
 * 배경을 깔아 글자와 뒤 그림 사이 대비를 만든다 — 이게 유일하게
 * 배경을 가리지 않으면서 읽히는 방법이다. */
.hero__cta .btn--ghost {
  background: rgb(255 255 255 / 94%);
  border-color: rgb(255 255 255 / 94%);
  color: var(--v1-ink);
  font-weight: 700;
}
.hero__cta .btn--ghost:hover {
  background: #fff;
  border-color: #fff;
}
.hero__cta .btn:not(.btn--ghost) {
  background: rgb(26 22 20 / 96%);
  border-color: rgb(26 22 20 / 96%);
  font-weight: 700;
}

/* 스크롤 인디케이터 — 이미지 위가 아니라 좌측 여백 하단(밝은 영역)에 둔다.
 * 실측: 좌하단 광장은 암부가 섞여 있으므로 배경 칩을 깔아 대비를 보장한다. */
.hero__scroll {
  position: absolute; left: max(var(--v1-space-5), (100% - 1200px) / 2);
  bottom: var(--v1-space-5);
  display: inline-flex; align-items: center; gap: var(--v1-space-2);
  font-size: var(--v1-text-xs); color: var(--v1-ink-2);
  letter-spacing: var(--v1-tracking-wide);
  background: color-mix(in srgb, var(--v1-paper) 88%, transparent);
  padding: var(--v1-space-2) var(--v1-space-4);
  border: 1px solid var(--v1-border-soft);
}
.hero__scroll::after {
  content: ""; width: 1px; height: 14px;
  background: var(--v1-accent);
  animation: v1-drip 2.4s var(--v1-ease-ink) infinite;
  transform-origin: top;
}
@keyframes v1-drip {
  0%, 100% { transform: scaleY(0.35); opacity: .4; }
  45%      { transform: scaleY(1);    opacity: 1; }
}
@media (prefers-reduced-motion: reduce) {
  .hero__scroll::after { animation: none; transform: scaleY(1); }
}

/* 모바일 — 구조가 바뀐다: 이미지 위 / 텍스트 아래 */
@media (max-width: 860px) {
  .hero__media { aspect-ratio: 780 / 643; }
  .hero__panel {
    position: static; padding-block: var(--v1-space-7);
    background: var(--v1-paper);
  }
  .hero__row { margin-left: 0 !important; }
  .hero__title { max-width: none; }
  .hero__scroll { display: none; }
}

/* ── 진입 시퀀스 — stagger 140ms ────────────────────────────────────────── */
.enter { opacity: 0; }
.js-ready .enter {
  animation: v1-rise var(--v1-dur-long) var(--v1-ease-settle) both;
  animation-delay: var(--d, 0ms);
}
@keyframes v1-rise {
  from { opacity: 0; transform: translateY(10px); }
  to   { opacity: 1; transform: none; }
}
/* 로고는 잉크 농도 방식 */
.js-ready .enter--ink { animation-name: v1-ink; }
@keyframes v1-ink {
  from { opacity: 0; filter: blur(3px); }
  to   { opacity: 1; filter: none; }
}
/* JS 없을 때도 콘텐츠가 보여야 한다 */
.no-js .enter { opacity: 1; }

@media (prefers-reduced-motion: reduce) {
  .enter, .js-ready .enter { opacity: 1 !important; animation: none !important; transform: none !important; filter: none !important; }
  .bleed { -webkit-mask-image: none !important; mask-image: none !important; }
}

/* ══ D-DAY / 일정 ══════════════════════════════════════════════════════════*/
.dday { background: var(--v1-surface); border-block: 1px solid var(--v1-border); }
/* 컬럼을 auto 로 두면 폰트 swap 시 내용 폭이 변하며 레이아웃이 밀린다(CLS).
 * 비율 고정으로 폰트 교체가 컬럼 폭에 영향을 주지 못하게 한다. */
.dday__in {
  display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1.4fr);
  gap: var(--v1-space-7);
  align-items: center; padding-block: var(--v1-space-6);
}
.dday__count { display: flex; gap: var(--v1-space-4); align-items: baseline; }
.dday__num {
  font-family: var(--v1-font-display);
  font-size: var(--v1-text-3xl); line-height: 1;
  letter-spacing: var(--v1-tracking-display);
  color: var(--v1-accent);
  font-variant-numeric: tabular-nums;
}
.dday__unit { font-size: var(--v1-text-sm); color: var(--v1-ink-3); }
/* 웹폰트 swap 시 링크 폭이 변하면 flex-end 정렬이라 전체가 밀린다(CLS).
 * 균등 분할 그리드로 폭을 고정해 폰트 교체가 레이아웃을 움직이지 못하게 한다. */
.dday__quick {
  display: grid;
  grid-template-columns: repeat(5, minmax(0, 1fr));
  gap: var(--v1-space-3);
  justify-items: center;
}
.dday__quick a {
  text-decoration: none; color: var(--v1-ink-2); font-size: var(--v1-text-sm);
  display: grid; gap: var(--v1-space-1); justify-items: center;
  padding: var(--v1-space-2) var(--v1-space-3);
  border-bottom: 1px solid transparent;
  transition: color var(--v1-dur-micro) var(--v1-ease-lift),
              border-color var(--v1-dur-micro) var(--v1-ease-lift),
              transform var(--v1-dur-micro) var(--v1-ease-lift);
}
.dday__quick a:hover {
  color: var(--v1-ink); border-bottom-color: var(--v1-accent);
  transform: translateY(-2px);
}
/* 일정 미정 상태 — 숫자 자리를 비워두지 않고 상태로 조판한다 */
.dday__pending { display: grid; gap: var(--v1-space-1); }
.dday__pendingText {
  font-family: var(--v1-font-display);
  font-size: var(--v1-text-xl);
  line-height: var(--v1-leading-tight);
  letter-spacing: var(--v1-tracking-tight);
  color: var(--v1-ink-2);
}
@media (max-width: 860px) {
  .dday__in { grid-template-columns: 1fr; gap: var(--v1-space-5); }
  .dday__quick { justify-content: flex-start; gap: var(--v1-space-4); }
}

/* ══ 개요 — 행사장 실경을 앵커로 ═══════════════════════════════════════════
 * 이미지 좌측 0–50% 가 비어 있어(실측 휘도 0.89~0.95) 텍스트를 그 위에 얹는다.
 * 이미지 위에 텍스트를 얹는 건 히어로에서 이미 쓴 수법이지만, 여기서는
 * 대각선 배치가 아니라 좌측 정렬 단일 블록이라 리듬이 겹치지 않는다. */
.ovfig { position: relative; margin: 0 0 var(--v1-space-8); }
.ovfig img {
  width: 100%;
  aspect-ratio: 2244 / 701;      /* CLS 0 */
  object-fit: cover;
  /* R1 검수 결과: 모바일 크롭 시 70% 면 기념탑 상부가 잘린다 → 82% */
  object-position: 82% center;
}
.ovfig__panel {
  position: absolute; inset: 0;
  display: grid; align-content: center;
}
.ovfig__lede { max-width: 34ch; margin-top: var(--v1-space-4); }
.ovfig__more { margin-top: var(--v1-space-7); }

/* 좁은 화면에서는 이미지 위 텍스트를 포기한다 — 건축물이 좌측까지 밀려와
 * 대비를 보장할 수 없다. 이미지 아래로 내린다. */
@media (max-width: 860px) {
  .ovfig img { aspect-ratio: 16 / 10; }
  .ovfig__panel {
    position: static;
    padding-top: var(--v1-space-6);
  }
  .ovfig__lede { max-width: none; }
}

/* 고정 4열 — auto-fit 은 마지막 행에 고아 칸과 큰 빈 구멍을 만든다 */
/* 항목 수가 쓰는 곳마다 다르다(주최·주관 2개 ~ 코스 요약 6개).
 * 4열로 고정하면 2개짜리에서 오른쪽 600px 이 빈 채로 남는다(실측 대회요강).
 * auto-fit 으로 항목 수에 맞춘다 — 최대 4열은 max-width 로 유지한다. */
.facts {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(14rem, 100%), 1fr));
  gap: 0;
}
/* 항목이 적을 때 한 칸이 지나치게 넓어지지 않게 */
.facts:has(.facts__item:nth-child(-n+3):last-child) { max-width: 62ch; }
@media (max-width: 1000px) { .facts { grid-template-columns: repeat(2, 1fr); } }
/* 360px 에서도 2열을 유지한다.
 * 1열로 떨어뜨리면 11개 항목이 세로로 늘어서 모바일에서 "텍스트만인 화면"이
 * 연속 4개까지 생겼다(실측). 항목 하나가 짧은 라벨+값이라 2열이 읽힌다. */
@media (max-width: 560px) {
  .facts { grid-template-columns: repeat(2, 1fr); column-gap: var(--v1-space-4); }
  .facts__item { padding-right: 0; }
  .facts__v { font-size: var(--v1-text-base); }
}
.facts__item {
  padding: var(--v1-space-5) var(--v1-space-5) var(--v1-space-5) 0;
  border-top: 1px solid var(--v1-border-soft);
}
.facts__k { font-size: var(--v1-text-xs); color: var(--v1-ink-3); letter-spacing: var(--v1-tracking-wide); }
.facts__v { font-size: var(--v1-text-lg); font-family: var(--v1-font-display); margin-top: var(--v1-space-1); }
/* 이메일처럼 띄어쓰기 없는 긴 값이 옆 칸 위로 겹쳤다(처리방침 8절).
 * 그리드 칸은 기본 min-width:auto 라 내용만큼 넓어지려 하고, 못 넓어지면
 * 넘친다. 칸이 줄어들 수 있게 하고 값은 아무 데서나 줄바꿈되게 한다. */
.facts__item { min-width: 0; }
.facts__v { overflow-wrap: anywhere; }
/* 위 규칙은 .prose 안에서 .prose .facts__v(keep-all · overflow-wrap:normal)에
 * 진다 — 한국어 값이 단어 중간에서 꺾이지 않게 한 의도적 규칙이라 살려 둔다.
 * 처리방침 연락처만은 이메일이 한 덩어리라 그 규칙 아래서 옆 칸 위로
 * 글자가 그려졌다(박스는 안 넘치고 글자만 넘쳐 좌표 검사로는 안 잡혔다).
 * 이 블록에 한해서만 다시 꺾임을 허용한다. */
#privacyContact .facts__v { overflow-wrap: anywhere; }

/* ══ 코스 ══════════════════════════════════════════════════════════════════*/
.courses { display: grid; gap: var(--v1-space-6); grid-template-columns: repeat(3, 1fr); }
/* 모바일 — 카드를 세로로 쌓되 **압축**한다.
 * 카드 하나가 화면을 꽉 채우면 세 카드가 세 화면에 흩어져
 * 거리 비율을 비교할 수 없고(막대의 존재 이유가 사라진다),
 * 실측상 "텍스트만인 화면"이 연속 3개 생겼다.
 * → 거리·참가비·막대를 한 행에 모으고 상세 목록은 그 아래로 접는다. */
@media (max-width: 900px) {
  .courses { grid-template-columns: 1fr; gap: var(--v1-space-4); }
  .course {
    grid-template-columns: 1fr auto;
    align-items: baseline;
    gap: var(--v1-space-2) var(--v1-space-4);
    padding: var(--v1-space-5);
  }
  .course .eyebrow   { grid-column: 1; grid-row: 1; }
  .course__dist      { grid-column: 1; grid-row: 2; }
  .course__fee       { grid-column: 2; grid-row: 2; text-align: right; }
  .course .cbar      { grid-column: 1 / -1; grid-row: 3; }
  .course__list      { grid-column: 1 / -1; grid-row: 4; }
  /* 상세는 2열로 — 세로 길이를 절반으로 줄인다 */
  .course__list { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: var(--v1-space-2) var(--v1-space-4); }
}
@media (max-width: 460px) {
  .course__list { grid-template-columns: 1fr; }
}
.course {
  border: 1px solid var(--v1-border);
  background: var(--v1-paper);
  padding: var(--v1-space-6);
  display: grid; gap: var(--v1-space-4);
  transition: border-color var(--v1-dur-short) var(--v1-ease-lift),
              box-shadow var(--v1-dur-short) var(--v1-ease-lift),
              transform var(--v1-dur-short) var(--v1-ease-lift);
}
.course:hover {
  border-color: var(--v1-accent);
  box-shadow: var(--v1-shadow-md);
  transform: translateY(-2px);
}
.course__dist {
  font-family: var(--v1-font-display); font-size: var(--v1-text-2xl);
  letter-spacing: var(--v1-tracking-tight); line-height: 1;
}
.course__fee { font-size: var(--v1-text-lg); color: var(--v1-accent); font-weight: 600; }
.course__list { display: grid; gap: var(--v1-space-2); font-size: var(--v1-text-sm); color: var(--v1-ink-2); }
.course__list div { display: grid; grid-template-columns: 4.5em 1fr; gap: var(--v1-space-3); }
.course__list dt, .course__list .k { color: var(--v1-ink-3); }

/* ── 거리 비례 막대 — 장식이 아니라 데이터다 ───────────────────────────────
 * 막대 길이 = 실제 거리 / 최장 거리. 세 카드를 나란히 보면 1 : 2 : 4.22 가 보인다.
 * 트랙(회색 홈)을 깔고 그 안을 잉크가 채운다 — 전체 대비 얼마인지가 드러난다. */
.cbar {
  position: relative;
  height: var(--v1-track-h);
  display: flex; align-items: center; gap: var(--v1-space-3);
}
.cbar::before {
  content: ""; position: absolute; left: 0; right: 0; top: 50%;
  height: 1px; background: var(--v1-border-soft);
}
.cbar__ink {
  position: relative;
  /* 비율만큼의 폭을 차지하고, 그 안에서 좌→우로 자란다 */
  width: calc(var(--ratio, 1) * 100%);
  height: var(--v1-ink-bar);
  background: var(--v1-accent-raw);
  transform: scaleX(var(--draw, 0));
  transform-origin: left center;
  transition: transform var(--v1-dur-epic) var(--v1-ease-ink);
}
/* 붓이 떨어진 끝점 — 획의 끝이 뭉치는 느낌 */
.cbar__ink::after {
  content: ""; position: absolute; right: -1px;
  top: calc((var(--v1-ink-bar) - var(--v1-ink-nib)) / 2);
  width: 3px; height: var(--v1-ink-nib); background: var(--v1-accent);
}
.cbar__num {
  position: relative;
  font-size: var(--v1-text-xs); color: var(--v1-ink-3);
  font-variant-numeric: tabular-nums;
  flex: 0 0 auto;
}
@media (prefers-reduced-motion: reduce) {
  .cbar__ink { transform: scaleX(1); transition: none; }
}

/* ══ 표 — 참가비 / 시상 ════════════════════════════════════════════════════*/
.tbl-scroll { overflow-x: auto; -webkit-overflow-scrolling: touch; }
/* border-collapse 는 15줄 `table` 규칙이 이미 걸어 뒀다 — 여기서 다시 쓰지 않는다.
 * 셀마다 괘선을 그리므로 collapse 가 없으면 인접 셀 선이 두 겹으로 겹친다. */
.tbl { font-size: var(--v1-text-sm); min-width: 480px; }
.tbl caption { text-align: left; color: var(--v1-ink-3); font-size: var(--v1-text-xs); padding-bottom: var(--v1-space-3); }
/* 아래선만 있으면 값이 어느 열에 속하는지 눈으로 이어지지 않는다 —
 * 행은 보이는데 열이 안 보여서 목록처럼 읽혔다. 세로선까지 넣어 격자를 만든다.
 * 바깥 테두리는 .tbl 이 아니라 셀에 준다. 가로 스크롤(.tbl-scroll) 안에서
 * 표가 잘릴 때 바깥선만 남아 떠 있는 것을 막는다. */
.tbl th, .tbl td {
  padding: var(--v1-space-3) var(--v1-space-4);
  text-align: left;
  border: 1px solid var(--v1-border-soft);
}
/* 머리행 아래는 본문과 갈라지는 자리라 굵게 — 격자 안에서도 머리는 머리다 */
.tbl thead th { border-bottom: 1px solid var(--v1-ink); font-weight: 600; color: var(--v1-ink); }
.tbl tbody tr:hover { background: var(--v1-surface); }
.tbl td:first-child, .tbl th:first-child { color: var(--v1-ink-3); }
/* 행 머리(종목명)는 본문 색으로 — 스캔의 기준점이다 */
.tbl tbody th[scope="row"] { color: var(--v1-ink); font-weight: 600; }

/* 금액 열 — 자릿수가 세로로 맞아야 비교가 된다 */
.tbl__num { text-align: right; font-variant-numeric: tabular-nums; }
.tbl__num--alt { color: var(--v1-accent); font-weight: 600; }
.tbl__sub {
  display: block; font-weight: 400;
  font-size: var(--v1-text-xs); color: var(--v1-ink-3);
  letter-spacing: var(--v1-tracking-normal);
}
.tbl--fee { min-width: 620px; }

/* 표 아래 안내 — 괘선 표식 붙은 목록 */
.notes { margin-top: var(--v1-space-4); display: grid; gap: var(--v1-space-2); }
.notes__i {
  position: relative;
  padding-left: var(--v1-space-5);
  font-size: var(--v1-text-sm); color: var(--v1-ink-2);
}
.notes__i::before {
  content: ""; position: absolute; left: 0; top: 0.7em;
  width: 12px; height: 1px; background: var(--v1-accent-raw);
}

/* ── 신청 순서 — 진행 다이어그램 ──────────────────────────────────────────
 * 번호 목록이 아니다. 단계가 한 방향으로 이어지는 것이 형태로 보여야 한다. */
.steps {
  margin-top: var(--v1-space-5);
  display: grid; grid-template-columns: repeat(6, minmax(0, 1fr));
  gap: 0;
}
.steps__i {
  position: relative;
  padding: var(--v1-space-5) var(--v1-space-4) var(--v1-space-4) 0;
  border-top: 1px solid var(--v1-border);
}
/* 진행선 — 단계 사이를 잇는다. 마지막 단계는 잇지 않는다(끝점) */
.steps__i:not(:last-child)::after {
  content: ""; position: absolute; top: -1px; left: 0; right: 0;
  height: 1px; background: var(--v1-border);
}
.steps__i::before {
  content: ""; position: absolute; top: -3px; left: 0;
  width: 5px; height: 5px; background: var(--v1-accent-raw);
}
.steps__n {
  display: block;
  font-family: var(--v1-font-display);
  font-size: var(--v1-text-lg); color: var(--v1-accent);
  font-variant-numeric: tabular-nums;
  line-height: 1;
}
.steps__t {
  display: block; margin-top: var(--v1-space-2);
  font-size: var(--v1-text-sm); color: var(--v1-ink-2);
}
@media (max-width: 900px) { .steps { grid-template-columns: repeat(3, minmax(0, 1fr)); } }
@media (max-width: 520px) { .steps { grid-template-columns: repeat(2, minmax(0, 1fr)); } }

/* ══ 기념품 실사진 ═════════════════════════════════════════════════════════
 * 두 제품의 종횡비가 다르다(0.82 / 0.96). 높이를 억지로 맞추면 왜곡되므로
 * 고정 비율 프레임을 두고 그 안에서 contain 으로 담는다.
 * 제품 사진은 원색 그대로 — 세피아 보정하지 않는다. 실제 상품이기 때문이다.
 * 대신 지면(surface)과 얇은 괘선 프레임으로 v1 조판 안에 앉힌다. */
/* 기념품은 시상 표의 보조 정보다 — 사진이 표보다 커지면 위계가 뒤집힌다.
 * 열 폭을 고정해 두 사진이 섹션의 절반을 넘지 않게 한다. */
.souv {
  margin-top: var(--v1-space-5);
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 220px)) minmax(0, 1fr);
  gap: var(--v1-space-6);
  align-items: start;
}
/* 프레임 비율이 같으므로(5:6) 두 캡션은 자동으로 같은 높이에서 시작한다.
 * 별도의 행 공유 장치가 필요 없다 — height:100% 를 주면 오히려 늘어난다. */
.souv__item { margin: 0; }
/* 프레임에 비율을 주고 이미지는 그 안을 채운다.
 * ⚠️ img 에 aspect-ratio 를 걸면 width/height 속성(640×780)과 경합해
 *    높이가 의도한 값으로 잡히지 않는다. 비율은 컨테이너가 갖는다.
 * 비율 5:6(0.833)은 두 제품(0.82 / 0.96)의 낮은 쪽에 맞춘 값 —
 * contain 이므로 어느 쪽도 잘리거나 늘어나지 않는다. */
.souv__item picture {
  display: block;
  aspect-ratio: 5 / 6;                    /* 프레임 비율 고정 → CLS 0 */
  background: var(--v1-neutral-ground);   /* 제품 사진의 흰 배경과 이어진다 */
  border: 1px solid var(--v1-border);
  padding: var(--v1-space-4);
}
.souv__item img {
  width: 100%; height: 100%;
  object-fit: contain;                     /* 제품을 자르거나 늘리지 않는다 */
}
.souv__item figcaption {
  display: grid; gap: var(--v1-space-1);
  padding-top: var(--v1-space-3);
  border-top: 1px solid var(--v1-border-soft);
  margin-top: var(--v1-space-3);
}
.souv__who { font-size: var(--v1-text-xs); color: var(--v1-ink-3); letter-spacing: var(--v1-tracking-wide); }
.souv__what { font-family: var(--v1-font-display); font-size: var(--v1-text-lg); }
.souv__note { align-self: end; padding-bottom: var(--v1-space-3); }
@media (max-width: 900px) {
  .souv { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .souv__note { grid-column: 1 / -1; align-self: start; }
}
@media (max-width: 520px) {
  .souv { grid-template-columns: 1fr; }
}

/* ══ 공지 — 행(row) 조판. 메인 홈에는 없고 /community/notice 에서 쓴다 ══════*/
.notices { border-top: 1px solid var(--v1-ink); }
.notice {
  display: grid; grid-template-columns: 9em 1fr auto;
  gap: var(--v1-space-4);
  align-items: baseline;
  padding: var(--v1-space-5) 0;
  border-bottom: 1px solid var(--v1-border-soft);
  border-left: 2px solid transparent;   /* 호버 시 잉크 표식이 생긴다 */
  text-decoration: none; color: inherit;
  /* transform 으로 들여쓴다 — padding 전이는 레이아웃을 유발한다 */
  transition: background-color var(--v1-dur-micro) var(--v1-ease-lift),
              border-left-color var(--v1-dur-short) var(--v1-ease-lift),
              transform var(--v1-dur-short) var(--v1-ease-lift);
}
/* 색 + 좌측 잉크 보더 + 들여쓰기 3축 (완료조건 9) */
.notice:hover {
  background: var(--v1-surface);
  border-left-color: var(--v1-accent);
  transform: translateX(var(--v1-space-2));
}
.notice:hover .notice__t { color: var(--v1-accent); }
/* 색 외 동반 변화: + 기호가 회전하며 우측으로 이동 (완료조건 9) */
.notice:hover .notice__m { transform: translateX(4px) rotate(90deg); color: var(--v1-accent); }
.notice__d { font-size: var(--v1-text-sm); color: var(--v1-ink-3); font-variant-numeric: tabular-nums; }
.notice__t { font-weight: 600; transition: color var(--v1-dur-micro) var(--v1-ease-lift); }
.notice__m {
  color: var(--v1-ink-3);
  display: inline-block;
  transition: transform var(--v1-dur-short) var(--v1-ease-lift),
              color var(--v1-dur-micro) var(--v1-ease-lift);
}
@media (max-width: 700px) {
  .notice { grid-template-columns: 1fr auto; }
  .notice__d { grid-column: 1 / -1; }
}

/* ══ 후원사 — 괘선 표(表) 그리드. 원색 유지 ════════════════════════════════
 * 세피아 팔레트와 충돌하므로 섹션을 중립 지면으로 분리한다. */
/* 홈 하단(코스·신청·후원사)은 화이트 지면이다(2026-08-13 지시).
 * 히어로의 수채화만 세피아로 두고 그 아래로는 흰 지면으로 내린다 —
 * 세피아가 화면 전체를 덮으면 누렇게 읽힌다. */
#apply { background: var(--v1-white); }

.sponsors {
  background: var(--v1-neutral-ground);      /* 중립 지면 — 팔레트에서 의도적으로 분리 */
  /* 위 검정 2px 선을 뺐다(2026-08-14) — 바로 위 4괘 구분선이 이미 경계다. */
  padding-block: var(--v1-space-8);
}
.sponsors__grid {
  display: grid; grid-template-columns: repeat(6, 1fr);
  border-left: 1px solid var(--v1-border);
}
.sponsors__cell {
  border-right: 1px solid var(--v1-border);
  display: grid; place-items: center;
  padding: var(--v1-space-5) var(--v1-space-4);
  min-height: 96px;
}
/* 광학 정렬 — 높이 일괄 고정 금지. 기준 높이 × 개별 보정 계수(--k).
 * width:auto 만 두면 잉크 크기 속성과 충돌해 0으로 접힌다 → height 를 명시한다. */
.sponsors__cell img {
  width: auto;
  height: calc(var(--v1-sponsor-h) * var(--k, 1));
  max-width: 100%;
  object-fit: contain;
}
@media (max-width: 1000px) { .sponsors__grid { grid-template-columns: repeat(3, 1fr); } }
@media (max-width: 560px)  { .sponsors__grid { grid-template-columns: repeat(2, 1fr); } }

/* ══ 푸터 ══════════════════════════════════════════════════════════════════
 * 2026-08-14 재작업 — 네 덩이가 세로로 쌓여 두꺼웠다(536px → 394px).
 * 로고·갈래·문의를 한 줄로 펼치고 주최 정보도 한 줄로 흘린다.
 * 태그라인은 뺐다 — 푸터에서 대회 소개문을 읽는 사람은 없다.
 *
 * 글자는 paper(#FBF6E9) 기준. 이전 sunken 은 세피아라 어두운 지면에서 탁했다.
 * 배경 독립 — --foot-ink / --foot-bg 로만 그린다(.foot--onpaper 가 뒤집는다). */
.foot {
  --foot-bg:  var(--v1-ink);
  --foot-ink: var(--v1-paper);
  background: var(--foot-bg);
  color: var(--foot-ink);
  padding-block: var(--v1-space-7);
  min-height: var(--v1-foot-h);
}
/* ⚠️ 브레이크포인트를 .foot__top 이 1열로 접히는 지점(860px)과 맞춘다.
 * 760px 로 두었더니 761~860 구간에서 실제 621px 인데 394px 만 예약해
 * CLS 가 최대 0.31 까지 튀었다(실측). 예약 지점과 접히는 지점은 같아야 한다. */
@media (max-width: 860px) { .foot { min-height: var(--v1-foot-h-sm); } }
.foot--onpaper {
  --foot-bg:  var(--v1-paper);
  --foot-ink: var(--v1-ink);
}
.foot a { color: var(--foot-ink); }
.foot .logo-mark { background-color: var(--logo-ink-inverse); }
.foot--onpaper .logo-mark { background-color: var(--logo-ink); }

/* ── 위 — 로고 · 갈래 · 문의 한 줄 ────────────────────────────────────── */
.foot__top {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  gap: var(--v1-space-7) var(--v1-space-8);
  align-items: start;
}
/* 로고와 갈래를 좌측에 세로로 묶는다 — 갈래가 가로로 길어졌기 때문이다 */
.foot__id { grid-column: 1; }
.foot__nav { grid-column: 1; }
.foot__ask { grid-column: 2; grid-row: 1 / span 2; }
.foot__h {
  font-size: var(--v1-text-xs);
  letter-spacing: var(--v1-tracking-wide);
  color: color-mix(in srgb, var(--foot-ink) 58%, transparent);
  margin-bottom: var(--v1-space-2);
}

/* 갈래 링크 — 가로 일자 배치(2026-08-14 지시).
 * 세로로 쌓으면 괘 네 개가 한눈에 안 들어온다. 가로로 놓아야
 * 건☰ 리☲ 감☵ 곤☷ 가 나란히 보이면서 태극기의 네 괘임이 읽힌다. */
.foot__nav {
  display: flex; flex-wrap: wrap;
  gap: var(--v1-space-2) var(--v1-space-7);
  align-items: center;
}
.foot__gate {
  display: inline-flex; align-items: center; gap: var(--v1-space-3);
  min-height: var(--v1-tap-min);
  font-size: var(--v1-text-sm);
  text-decoration: none;
  color: color-mix(in srgb, var(--foot-ink) 82%, transparent);
  transition: color var(--v1-dur-micro) var(--v1-ease-lift),
              gap var(--v1-dur-short) var(--v1-ease-lift);
}
.foot__gate:hover { color: var(--foot-ink); gap: var(--v1-space-4); }
.foot__gatelabel { border-bottom: 1px solid transparent; }
.foot__gate:hover .foot__gatelabel { border-bottom-color: var(--foot-ink); }

/* 괘선 표식 — 갈래마다 다른 괘(건☰ 리☲ 감☵ 곤☷).
 * 색은 --foot-ink 를 통해서만 쓴다: 밝은/어두운 배경 양쪽에서 성립해야 한다. */
.gate__mark {
  display: grid; gap: 2px;
  width: var(--v1-yao-w); flex: 0 0 var(--v1-yao-w);
}
.gate__yao { display: flex; gap: 2px; height: 2px; }
.gate__yao i {
  flex: 1;
  background: color-mix(in srgb, var(--foot-ink) 45%, transparent);
  transition: background-color var(--v1-dur-short) var(--v1-ease-lift);
}
.gate__yao--split i { flex: 0 0 calc(50% - 1px); }
.foot__gate:hover .gate__yao i { background: var(--foot-ink); }

/* 문의 — 우측 정렬 */
.foot__ask { display: grid; gap: 2px; justify-items: end; text-align: right; }
.foot__big {
  font-family: var(--v1-font-display);
  font-size: var(--v1-text-base);
  line-height: 1.5;
  text-decoration: none;
  width: max-content; max-width: 100%;
  word-break: break-all;
  border-bottom: 1px solid transparent;
  transition: border-color var(--v1-dur-micro) var(--v1-ease-lift);
}
.foot__big:hover { border-bottom-color: var(--foot-ink); }
.foot__sub {
  margin-top: var(--v1-space-2);
  font-size: var(--v1-text-xs);
  color: color-mix(in srgb, var(--foot-ink) 70%, transparent);
}
.foot__sub .muted { color: color-mix(in srgb, var(--foot-ink) 48%, transparent); }
.foot__dot { padding-inline: var(--v1-space-2); opacity: 0.4; }

/* ── 아래 — 주최·주관·주소 한 줄 ─────────────────────────────────────── */
.foot__org {
  margin-top: var(--v1-space-6);
  padding-top: var(--v1-space-4);
  border-top: 1px solid color-mix(in srgb, var(--foot-ink) 16%, transparent);
  font-size: var(--v1-text-xs);
  line-height: 1.9;
  color: color-mix(in srgb, var(--foot-ink) 78%, transparent);
}
.foot__k { color: color-mix(in srgb, var(--foot-ink) 48%, transparent); }

.foot__bottom {
  margin-top: var(--v1-space-3);
  font-size: var(--v1-text-xs);
  color: color-mix(in srgb, var(--foot-ink) 48%, transparent);
}
/* 처리방침 링크 — 법적 고지라 흐리게 두지 않는다.
 * 호버 단서가 색 하나면 안 되므로(조건 9) 밑줄 두께가 함께 변한다. */
.foot__priv {
  margin-left: var(--v1-space-4);
  color: color-mix(in srgb, var(--foot-ink) 78%, transparent);
  text-decoration: underline;
  text-underline-offset: 3px;
  text-decoration-thickness: 1px;
  transition: color var(--v1-dur-micro) var(--v1-ease-lift),
              text-decoration-thickness var(--v1-dur-micro) var(--v1-ease-lift);
}
.foot__priv:hover { color: var(--foot-ink); text-decoration-thickness: 2px; }

/* ── 모바일 터치 타깃 ──────────────────────────────────────────────────────
 * 손가락으로 누르는 링크는 44px 이상이어야 한다(WCAG 2.5.5 / 애플 HIG).
 * 브레드크럼·본문 인라인 링크·푸터 처리방침이 15~22px 이라 옆 링크를
 * 잘못 누른다. 글자 크기는 그대로 두고 위아래 여백만 늘려 높이를 만든다 —
 * 글자를 키우면 조판이 흔들린다.
 *
 * 인라인 링크(.link)는 문단 안에 있어 padding 을 주면 줄간격이 벌어진다.
 * 대신 ::after 로 보이지 않는 판정 영역만 덧댄다. */
@media (max-width: 860px) and (pointer: coarse) {
  .crumb { gap: var(--v1-space-3); }
  .crumb a { display: inline-flex; align-items: center; min-height: 44px; }

  .foot__priv { display: inline-flex; align-items: center; min-height: 44px; }

  .prose .link, main p .link, .lede .link, .notes__i .link {
    position: relative;
  }
  .prose .link::after, main p .link::after, .lede .link::after, .notes__i .link::after {
    content: '';
    position: absolute;
    left: 0; right: 0;
    top: 50%; transform: translateY(-50%);
    height: 44px;
  }
}

@media (max-width: 860px) {
  .foot__top { grid-template-columns: 1fr; gap: var(--v1-space-6); }
  .foot__ask { justify-items: start; text-align: left; }
}

/* ══ 모바일 고정 CTA 바 — 신청+접수확인 페어링 유지 ═══════════════════════
 * 상단 CTA를 접는 좁은 화면(≤420px)에서만 나타난다. */
.mcta { display: none; }
@media (max-width: 420px) {
  .mcta {
    display: grid; grid-template-columns: 1fr 1fr; gap: var(--v1-space-3);
    position: fixed; left: 0; right: 0; bottom: 0; z-index: 120;
    padding: var(--v1-space-3) var(--v1-space-4);
    padding-bottom: calc(var(--v1-space-3) + env(safe-area-inset-bottom, 0px));
    background: var(--v1-paper);
    border-top: 1px solid var(--v1-border);
  }
  .mcta .btn { justify-content: center; }
  /* 고정 바에 콘텐츠가 가리지 않게 */
  body { padding-bottom: 76px; }

  /* 히어로 안의 같은 버튼 2개를 숨긴다.
   * 주석에 "상단 CTA를 접는 좁은 화면" 이라고 적혀 있었는데 정작 접는 규칙이
   * 없어서, 고정 바가 히어로 버튼 위에 겹쳐 보였다(실측 390px).
   * 같은 동작을 하는 버튼이 한 화면에 두 벌 있을 이유가 없다. */
  .hero__cta { display: none; }
}

/* ══ 대분류 진입점 — 괘선 구획, 화살표 글리프 없이 잉크 표식으로 ══════════ */
/* ── 괘선 표식 — 홈 진입점에서 푸터 갈래 링크로 이동 ────────────────────────
 * 도형 자체는 그대로 둔다. 크기만 푸터 밀도에 맞춰 줄인다(34→22px).
 * 색은 --foot-ink 를 통해서만 쓴다 — 밝은/어두운 배경 양쪽에서 성립해야 한다. */
.gate__mark {
  display: grid; gap: 2px;
  width: var(--v1-yao-w); flex: 0 0 var(--v1-yao-w);
}
.gate__yao { display: flex; gap: 2px; height: 2px; }
.gate__yao i {
  flex: 1;
  background: color-mix(in srgb, var(--foot-ink) 45%, transparent);
  transition: background-color var(--v1-dur-short) var(--v1-ease-lift);
}
.gate__yao--split i { flex: 0 0 calc(50% - 1px); }

/* R2 초상 — 출처 표기가 이미지 근처에서 확인되어야 한다 */
.story__portrait picture { display: block; }
.story__credit strong { color: var(--v1-ink-2); font-weight: 600; }

/* ══════════════════════════════════════════════════════════════════════════
 * 대회 이야기 페이지 (/story)
 * 획 사양: docs/STROKE-SPEC.md · 스크립트: v1/story.js
 * A안 기준 — 여백과 획으로 구성한다. 절마다 레이아웃 골격이 다르다.
 * ════════════════════════════════════════════════════════════════════════*/

/* ── 페이지 머리 ─────────────────────────────────────────────────────────── */
.shead {
  border-bottom: 1px solid var(--v1-border);
  background: var(--v1-surface);
  padding-block: var(--v1-space-9) var(--v1-space-8);
}
.shead__in {
  display: grid; grid-template-columns: 1fr 340px;
  gap: var(--v1-space-8);
  align-items: center;
}
/* 제목이 두 줄로 조판되는데, 폰트 swap 시 폴백(sans)과 명조의 글자폭이 달라
 * 줄 수가 2 → 3 → 2 로 바뀌며 컬럼 높이가 흔들린다(실측 CLS 0.0096).
 * 줄 수를 고정하지 않고 **최소 높이를 예약**해 swap 이 레이아웃을 밀지 못하게 한다.
 * 2줄 × leading-display 기준. */
.shead__title {
  font-family: var(--v1-font-display);
  font-size: var(--v1-text-3xl);
  line-height: var(--v1-leading-display);
  letter-spacing: var(--v1-tracking-display);
  max-width: 18ch;
  min-height: calc(var(--v1-text-3xl) * var(--v1-leading-display) * 2);
}
.shead__lede { margin-top: var(--v1-space-5); max-width: 46ch; }
.shead__portrait { margin: 0; }
.shead__portrait img { width: 100%; height: auto; border: 1px solid var(--v1-border); }
@media (max-width: 899px) {
  .shead__in { grid-template-columns: 1fr; }
  .shead__portrait { max-width: 260px; }
}

/* ── 본문 승인 대기 안내 ─────────────────────────────────────────────────── */
/* ⚠️ 높이를 예약한다. 이 배너는 글꼴이 늦게 오면 줄 수가 바뀌어 아래 전체를
 * 밀었다 되돌린다 — /privacy 에서 CLS 0.0473 으로 잡혔다(실측).
 * 값은 뷰포트별 실측치다. **문구를 고치면 이 값도 다시 재야 한다.** */
.pending {
  background: var(--v1-sunken);
  border-bottom: 1px solid var(--v1-border);
  padding-block: var(--v1-space-5);
  font-size: var(--v1-text-sm); color: var(--v1-ink-2);
  min-height: 76px;
}
@media (max-width: 1200px) { .pending { min-height: 104px; } }
@media (max-width: 560px)  { .pending { min-height: 126px; } }
@media (max-width: 420px)  { .pending { min-height: 150px; } }
/* 안내 배너 바로 뒤 섹션은 위 여백을 줄인다.
 * .sec 의 padding-top 96px 은 "앞에 콘텐츠가 있다"를 전제한 값이라,
 * 배너(자체 상하 24px) 다음에 그대로 오면 빈 띠가 120px 넘게 생긴다(실측 winners). */
.pending + .sec { padding-top: var(--v1-space-7); }

.pending code {
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
  font-size: 0.92em; background: var(--v1-paper);
  padding: 0 var(--v1-space-1); border: 1px solid var(--v1-border-soft);
}

/* ── 절 공통 ─────────────────────────────────────────────────────────────── */
/* ══ 대회 이야기 — 어두운 지면 ═════════════════════════════════════════════
 * 이 페이지만 어둡다(2026-08-01 사용자 지시). 다른 페이지는 밝은 지면 그대로다.
 * 색은 --v1-ground-deep — ink 를 같은 색상·채도에서 명도만 내린 값이다.
 * 새 색을 들여온 것이 아니라 같은 먹을 더 짙게 쓴 것이다.
 *
 * 대비 실측(지면 #12100C 위): paper 17.61:1 · surface 15.74 · sunken 14.21 ·
 * border 10.72 — 전부 AAA. accent(2.80)는 미달이라 쓰지 않고 accent-raw(4.30)를 쓴다. */
.story-page {
  background: var(--v1-ground-deep);
  color: var(--v1-sunken);
}
/* 헤더·푸터 반전 — 페이지가 어두운데 머리와 발만 밝으면 띠처럼 떠 보인다 */
.story-page .nav {
  background: var(--v1-ground-deep);
  border-bottom-color: color-mix(in srgb, var(--v1-sunken) 20%, transparent);
}
.story-page .nav a,
.story-page .nav__top { color: var(--v1-sunken); }
.story-page .nav .logo-mark { background-color: var(--logo-ink-inverse); }
/* 푸터는 이미 어두운 지면을 기본으로 갖고 있다(--foot-bg = ink).
 * 이 페이지에서는 본문보다 살짝 밝게 둬서 경계가 보이게 한다. */
.story-page .foot { --foot-bg: var(--v1-ink); }
/* 타이포 컨트롤 패널은 지면이 --v1-ink 라 어두운 페이지에서 배경과 거의 같아진다
 * (ink #1F1B15 vs ground-deep #12100C). 이 페이지에서만 테두리로 경계를 준다. */
.story-page .fontbadge {
  border: 1px solid color-mix(in srgb, var(--v1-sunken) 30%, transparent);
}

.story-page .shead {
  /* .shead 자체가 surface(밝은 지면)를 배경으로 갖고 있어서 페이지만 어둡게
   * 해서는 머리 부분이 밝은 띠로 남는다(실측). 지면을 함께 뒤집는다. */
  background: color-mix(in srgb, var(--v1-paper) 5%, var(--v1-ground-deep));
  border-bottom-color: color-mix(in srgb, var(--v1-sunken) 20%, transparent);
}
.story-page .shead__title { color: var(--v1-paper); }
.story-page .shead__lede { color: var(--v1-sunken); }
.story-page .crumb a { color: var(--v1-border); }
.story-page .crumb__sep { color: var(--v1-ink-3); }
.story-page .shead__portrait img { border-color: color-mix(in srgb, var(--v1-sunken) 26%, transparent); }
.story-page .story__credit { color: var(--v1-border); }
.story-page .story__credit strong { color: var(--v1-paper); }
/* 출처 절 — ⚠️ 지면을 먼저 뒤집는다.
 * `main > .sec` 가 흰 지면을 깔기 때문에(§ 본문 지면 규칙), 그 위에 이 페이지의
 * 밝은 글자색이 그대로 얹혀 크림 위 크림이 됐다.
 * 실측: 제목 1.08 · 목록 1.34 · 설명 1.77 — 사실상 보이지 않는 상태였다.
 * 색을 조정하지 않고 **지면을 페이지와 같은 어두운 층위로** 되돌린다. */
.story-page main > .sec { background: var(--v1-ground-deep); }
.story-page #sources { border-top: 1px solid color-mix(in srgb, var(--v1-sunken) 14%, transparent); }
.story-page .notes__i { color: var(--v1-sunken); border-color: color-mix(in srgb, var(--v1-sunken) 18%, transparent); }
.story-page .notes__i strong { color: var(--v1-paper); }
.story-page .muted { color: var(--v1-border); }
.story-page .h3, .story-page .h2 { color: var(--v1-paper); }
.story-page .eyebrow { color: var(--v1-accent-ondark); }  /* accent 2.80 · accent-raw 4.04 둘 다 미달 */

.story-page .link { color: var(--v1-paper); }

.sc {
  /* 밝은 획 — 어두운 지면 위의 먹. 지면 대비 15.74:1 */
  --stroke-ink: var(--v1-stroke-light);
  position: relative;
  overflow: clip;
  isolation: isolate;
  padding-block: var(--v1-sec-lead);
}
.sc__stroke {
  position: absolute;
  pointer-events: none;
  z-index: 0;
}
.sc__stroke svg { width: 100%; height: 100%; display: block; }
/* 어두운 지면 위에서는 획이 지면에 먹힌다. 밝은 지면에서 쓰던 .88 로는
 * 대비가 깎여 흐릿해진다 → 거의 불투명하게 둔다(지면 대비 15.74:1 유지). */
.sc__stroke g { opacity: .96; }
.sc__brush {
  stroke-dasharray: var(--len, 2600);
  stroke-dashoffset: calc(var(--len, 2600) * (1 - var(--draw, 0)));
}
.sc__in { position: relative; z-index: 1; }

/* 본문 진입 — 획이 지나간 뒤 나타난다 */
.sc__seq { opacity: 0; }
.no-js .sc__seq { opacity: 1; }
.sc.is-drawn .sc__seq {
  animation: sc-emerge 560ms var(--v1-ease-settle) both;
  animation-delay: calc(var(--seq, 0) * 120ms + 200ms);
}
.sc.is-erasing .sc__seq {
  animation: sc-emerge 300ms var(--v1-ease-exit) reverse both;
  animation-delay: calc((3 - var(--seq, 0)) * 60ms);
}
@keyframes sc-emerge {
  from { opacity: 0; transform: translateY(12px); }
  to   { opacity: 1; transform: none; }
}

.sc .h2 { margin-top: var(--v1-space-3); }

/* 본문 — 서술문이다. 목록이 아니라 문단으로 읽혀야 한다.
 *
 * 측정(measure)을 ch 로 주지 않는다. ch 는 '0' 글자 너비 기준이라 한글에서는
 * 실제 글자 수와 어긋나고, 폰트가 바뀌면(?body= 비교 중) 측정도 함께 흔들린다.
 * 실측: 42ch → 436px, 한 줄 22자. 리드 문장이 4어절에서 꺾였다.
 * → 한글 본문 한 줄 30자 안팎이 되는 절대값으로 고정한다. */
.sc__body {
  margin-top: var(--v1-space-6);
  max-width: 34rem;
  display: grid;
  gap: var(--v1-space-5);
  font-size: var(--v1-text-base);
  line-height: 1.85;          /* DESIGN §5 — 한글 본문은 넉넉하게 */
  color: var(--v1-sunken);    /* 어두운 지면 위 14.21:1 */
  text-wrap: pretty;          /* 마지막 줄에 한 어절만 남는 것을 막는다 */
}

/* 첫 문단 — 절의 사실을 여는 문장이다. 크기로 한 단계만 올린다.
 * 색이나 굵기를 함께 바꾸지 않는다. 세 축을 동시에 바꾸면 인용문처럼 읽힌다.
 *
 * ⚠️ max-width 를 ch 로 다시 주지 않는다. ch 는 **자기 폰트 크기 기준**이라
 *    큰 글자에서는 같은 42ch 가 훨씬 좁아진다(실측: 리드가 4어절에서 꺾였다).
 *    측정은 부모(.sc__body)가 본문 크기 기준으로 한 번만 정한다. */
.sc__lead {
  font-size: var(--v1-text-lg);
  line-height: 1.72;
  color: var(--v1-paper);     /* 17.61:1 */
}

/* 나이 — 절 4에 한 번만 나온다. 강조하지 않되 문단 끝에 남게 한다.
 * 굵게 하거나 색을 넣으면 감상이 되고, 그냥 두면 묻힌다.
 * margin 을 주면 HTML 개행 공백과 겹쳐 두 칸으로 보인다(실측) → 여백을 주지 않는다.
 * 문장이 짧아 그 자체로 남는다. 줄 중간에서 끊기지만 않게 한다. */
.sc__age { white-space: nowrap; }

/* 각주 — 본문 흐름 밖의 보조 정보. 괘선 하나로 층위를 낮춘다 */
.sc__note {
  margin-top: calc(var(--v1-space-2) * -1);
  padding-top: var(--v1-space-4);
  border-top: 1px solid color-mix(in srgb, var(--v1-sunken) 16%, transparent);
  font-size: var(--v1-text-xs);
  line-height: 1.7;
  color: var(--v1-border);    /* 10.72:1 */
  max-width: 38ch;
}

/* 이 대회에 대하여 — 역사 서술에서 대회 사실로 넘어가는 자리.
 * 앞 절들과 같은 조판이면 서술의 연장으로 읽힌다.
 *
 * ⚠️ 좌측 컬러 스트라이프를 쓰지 않는다 — DESIGN §6-6 이 `.facts__pending` 에서
 *    이미 뺀 형태다(avoid-ai-design K4). 같은 실수를 여기서 반복하지 않는다.
 * → 상하 괘선과 지면 층위 차이로만 구분한다. */
.sc__about {
  margin-top: var(--v1-space-8);
  max-width: 46ch;
  padding-block: var(--v1-space-5);
  border-block: 1px solid color-mix(in srgb, var(--v1-sunken) 20%, transparent);
  font-size: var(--v1-text-base);
  line-height: 1.8;
  color: var(--v1-sunken);
  text-wrap: pretty;
}
.sc__aboutH {
  font-family: var(--v1-font-display);
  font-size: var(--v1-text-lg);
  color: var(--v1-paper);
  margin-bottom: var(--v1-space-3);
}

/* ── 절별 레이아웃 — 다섯 절이 같은 블록의 반복이면 안 된다 ────────────────
 * 획의 방향·캔버스에 맞춰 본문의 자리를 다르게 둔다. */

/* 절 1 — 1919. 획이 수평으로 상단을 지나간다. 본문은 그 아래 왼쪽. */
.sc[data-sc="1919"] { background: var(--v1-ground-deep); }
.sc[data-sc="1919"] .sc__stroke { top: -6%; height: 52%; left: -22vw; right: -22vw; }
.sc[data-sc="1919"] .sc__in { padding-top: clamp(var(--v1-space-8), 16vw, 200px); }

/* 절 2 — 아우내. 획이 우상에서 좌하로 관통. 본문은 우측 하단으로 피한다. */
/* 절마다 지면을 미세하게 달리해 층이 나뉘는 것이 보이게 한다 */
.sc[data-sc="aunae"] { background: color-mix(in srgb, var(--v1-paper) 4%, var(--v1-ground-deep)); }
.sc[data-sc="aunae"] .sc__stroke { inset: -8% -24vw auto; height: 66%; }
.sc[data-sc="aunae"] .sc__in {
  padding-top: clamp(var(--v1-space-8), 20vw, 250px);
  display: grid; justify-content: end;
}
/* 이 절만 본문이 우측에 앉는다. 획이 좌측을 지나가므로 폭을 조금 더 준다 */
.sc[data-sc="aunae"] .sc__body { max-width: 37rem; }

/* 절 3 — 재판과 옥중. 유일한 수직 획. 좌측에 세로로 세우고 본문은 우측. */
.sc[data-sc="trial"] { background: var(--v1-ground-deep); }
.sc[data-sc="trial"] .sc__stroke {
  top: -8%; bottom: -8%; left: 0; width: min(30vw, 340px); right: auto;
}
.sc[data-sc="trial"] .sc__in {
  display: grid; grid-template-columns: min(30vw, 340px) 1fr;
}
.sc[data-sc="trial"] .sc__in > * { grid-column: 2; }

/* 절 4 — 순국. 가장 굵고 무거운 획. 지면을 어둡게 반전해 무게를 준다. */
/* 페이지 전체가 어두워졌으므로(2026-08-01) 이 절은 "반전"이 아니라
 * **가장 깊은 지면**이다. 다른 절보다 더 내려가 무게를 만든다. */
.sc[data-sc="death"] {
  background: var(--v1-ground-abyss);
  color: var(--v1-sunken);
}
/* ⚠️ 이 절의 획은 한때 화면 하나를 통째로 덮었다(실측: 캔버스 911px ·
 * 굵은 구간이 화면에서 247px — 절 5 의 2.5배). 그 크기가 되면 붓이 아니라
 * 색 블록으로 읽히고, 실제로 eyebrow "1920년 9월 28일" 을 가렸다.
 * → 캔버스를 낮추고(72%→56%) 본문 시작을 끌어올려 획과 글이 한 화면에 같이 온다.
 * 굵기 자체는 STROKE-SPEC 의 값(최대 132)으로 되돌렸다 — 코드가 사양을 넘어 168 이었다. */
.sc[data-sc="death"] .sc__stroke { inset: -4% -24vw auto; height: 56%; }
.sc[data-sc="death"] .sc__in { padding-top: clamp(var(--v1-space-9), 21vw, 300px); }
/* 이 절만 지면이 한 단계 더 어둡다(abyss). 각주 괘선이 그대로면 묻힌다 */
.sc[data-sc="death"] .sc__note {
  border-top-color: color-mix(in srgb, var(--v1-sunken) 22%, transparent);
}

/* 절 5 — 오늘. 획이 아래에서 위로 올라간다. 본문은 상단에 둔다. */
.sc[data-sc="today"] { background: color-mix(in srgb, var(--v1-paper) 6%, var(--v1-ground-deep)); }
.sc[data-sc="today"] .sc__stroke { bottom: -6%; top: auto; height: 58%; left: -22vw; right: -22vw; }
.sc[data-sc="today"] .sc__in { padding-bottom: clamp(var(--v1-space-8), 16vw, 200px); }

/* 모바일 — 획의 관통 범위를 넓히고 본문 여백을 줄인다 */
@media (max-width: 700px) {
  .sc { padding-block: var(--v1-space-8); }
  /* 좌우로 -30vw 넓히면 같은 각도의 사선이 그만큼 더 아래로 내려와 본문을 덮는다.
   * 폭을 넓히는 대신 **획 상자 높이를 줄여** 사선이 상단에 머물게 한다. */
  .sc__stroke { left: -22vw !important; right: -22vw !important; }
  .sc[data-sc="1919"] .sc__stroke { height: 30%; }
  .sc[data-sc="aunae"] .sc__stroke { height: 34%; }
  .sc[data-sc="death"] .sc__stroke { height: 38%; }
  .sc[data-sc="today"] .sc__stroke { height: 32%; }
  .sc[data-sc="trial"] .sc__stroke { left: -12vw !important; right: auto !important; width: 52vw; }
  .sc[data-sc="trial"] .sc__in { grid-template-columns: 1fr; }
  .sc[data-sc="trial"] .sc__in > * { grid-column: 1; }
  .sc[data-sc="trial"] .sc__in { padding-top: clamp(var(--v1-space-7), 30vw, 180px); }
  /* 획이 두꺼워졌으므로(2026-08-01) 상한 200px 로는 제목이 획에 얹힌다(실측).
   * 절마다 획 굵기가 다르므로 여백도 따로 잡는다 — 순국 절이 가장 두껍다. */
  .sc[data-sc="1919"] .sc__in { padding-top: clamp(var(--v1-space-8), 52vw, 300px); }
  .sc[data-sc="aunae"] .sc__in { padding-top: clamp(var(--v1-space-8), 56vw, 330px); }
  .sc[data-sc="death"] .sc__in { padding-top: clamp(var(--v1-space-9), 68vw, 400px); }
  .sc[data-sc="today"] .sc__in { padding-bottom: clamp(var(--v1-space-8), 46vw, 280px); }
  .sc__body { max-width: none !important; }
  .sc[data-sc="aunae"] .sc__in { justify-content: stretch; }
}

@media (prefers-reduced-motion: reduce) {
  .sc__brush { stroke-dashoffset: 0 !important; }
  .sc__seq { opacity: 1 !important; animation: none !important; transform: none !important; }
}

/* ══════════════════════════════════════════════════════════════════════════
 * 하위 페이지 컴포넌트 (대회안내 / 코스 / 참가신청 / 커뮤니티 / 대회사진)
 * ════════════════════════════════════════════════════════════════════════*/

/* ── 진입 연출 — 하위 페이지는 절제한다 ───────────────────────────────────
 * 히어로가 없는 페이지에서 요소마다 큰 모션을 주면 산만해진다.
 * 짧게, 블록 단위로 한 번만. */
.reveal { opacity: 0; transform: translateY(10px); }
.no-js .reveal { opacity: 1; transform: none; }
.reveal.is-in {
  opacity: 1; transform: none;
  transition: opacity var(--v1-dur-short) var(--v1-ease-settle) calc(var(--i, 0) * 60ms),
              transform var(--v1-dur-short) var(--v1-ease-settle) calc(var(--i, 0) * 60ms);
}
@media (prefers-reduced-motion: reduce) {
  .reveal { opacity: 1 !important; transform: none !important; transition: none !important; }
}

/* ── 페이지 상단 이미지 띠 ────────────────────────────────────────────────── */
.pband { margin: 0; position: relative; }
.pband img {
  width: 100%; aspect-ratio: 2244 / 701;
  object-fit: cover; object-position: 82% center;
}
.pband figcaption {
  position: absolute; right: 0; bottom: 0;
  font-size: var(--v1-text-xs); color: var(--v1-ink-2);
  background: color-mix(in srgb, var(--v1-paper) 90%, transparent);
  padding: var(--v1-space-2) var(--v1-space-4);
  border-left: 1px solid var(--v1-border-soft);
  border-top: 1px solid var(--v1-border-soft);
}
@media (max-width: 700px) { .pband img { aspect-ratio: 16 / 10; } }

/* ── 키-값 표 (대회개요·주차요금) ─────────────────────────────────────────
 * 열이 두 개뿐인 표. 행 머리를 고정폭으로 둬 값이 세로로 정렬된다. */
.tbl--key { min-width: 0; }
.tbl--key th[scope="row"] {
  width: 8.5em; color: var(--v1-ink-3); font-weight: 500;
  vertical-align: top; background: var(--v1-surface);
}
.tbl--key td { color: var(--v1-ink); }
@media (max-width: 520px) {
  .tbl--key th[scope="row"] { width: 6.5em; font-size: var(--v1-text-xs); }
}
.tbl__none { color: var(--v1-ink-3); }

/* ── 강조 패널 (단체 보조금 등) ────────────────────────────────────────────
 * 좌측 컬러 스트라이프를 쓰지 않는다(K4 금지). 지면과 괘선으로 구분한다. */
.panel {
  background: var(--v1-surface);
  border-block: 1px solid var(--v1-border);
  padding: var(--v1-space-6);
  /* 폰트 swap 시 내부 텍스트 높이가 변해 뒤 콘텐츠를 민다 */
  min-height: var(--v1-panel-h);
}
@media (max-width: 620px) { .panel { min-height: var(--v1-panel-h-sm); } }

/* JS 로 채우는 한 줄 리드문 — 비어 있다가 채워지며 아래를 민다.
 * .panel 이 657→692 로 밀린 원인이 이것이었다(실측). */
#noticeCount { min-height: var(--v1-lede-h); }
@media (max-width: 620px) { #noticeCount { min-height: var(--v1-lede-h-sm); } }
.panel .facts__v { margin-top: var(--v1-space-2); color: var(--v1-accent); }
.panel .notes { margin-top: var(--v1-space-5); }

/* ── 유의사항 — 번호 체계 타이포 조판 (§9-3 앵커) ──────────────────────────
 * 이미지가 없는 페이지의 해법을 조판으로 찾는다.
 * 큰 번호를 좌측에 세워 본문과 다른 층위를 만든다. */
/* JS 로 9개 항목을 주입하므로 최소 높이를 예약한다 — 없으면 푸터가 밀려 CLS 가 튄다
 * (실측 CLS 0.1424: 푸터가 y=639 에서 아래로 밀렸다).
 * 값은 추정이 아니라 실측이다 — 데스크탑/태블릿 2346·2359px, 360px 2909px.
 * 콘텐츠가 늘면 예약분을 넘어 자연스럽게 커진다(min-height 이므로 잘리지 않는다). */
.cauts { display: grid; gap: var(--v1-space-8); min-height: 2350px; }
@media (max-width: 620px) { .cauts { min-height: 2910px; } }
.caut { display: grid; gap: var(--v1-space-4); }
.caut__h {
  display: grid; grid-template-columns: 3.2em 1fr;
  gap: var(--v1-space-4); align-items: baseline;
  padding-bottom: var(--v1-space-3);
  border-bottom: 1px solid var(--v1-border);
}
/* 번호를 앵커로 쓰려면 실제로 보여야 한다.
 * --v1-border 는 지면 위 1.64:1 로 거의 안 보였다(붓 획 taupe 와 같은 문제).
 * 번호 칩 — 지면을 반전해 숫자가 도형처럼 읽히게 한다. */
.caut__n {
  font-family: var(--v1-font-display);
  font-size: var(--v1-text-xl); line-height: 1;
  color: var(--v1-paper);
  background: var(--v1-accent);
  letter-spacing: var(--v1-tracking-normal);
  font-variant-numeric: tabular-nums;
  display: grid; place-items: center;
  width: 2.2em; height: 2.2em;
  align-self: start;
}
.caut__t {
  font-family: var(--v1-font-display);
  font-size: var(--v1-text-lg);
  line-height: var(--v1-leading-tight);
  color: var(--v1-ink);
}
.caut__body {
  display: grid; gap: var(--v1-space-3);
  padding-left: calc(3.2em + var(--v1-space-4));
}
.caut__p { color: var(--v1-ink-2); }
.caut__note {
  font-size: var(--v1-text-sm); color: var(--v1-ink-3);
  padding-top: var(--v1-space-2);
}
@media (max-width: 620px) {
  .caut__h { grid-template-columns: 2.4em 1fr; gap: var(--v1-space-3); }
  .caut__body { padding-left: 0; }
}

/* ── 오시는 길 — 개략도 배경 ───────────────────────────────────────────────
 * ⚠️ 실제 지도가 아니다. 추상 워시이며 도로·라벨·기호가 없다. */
/* 배경 워시는 텍스트를 앉히는 지면이다 — 워시 자체가 주인공이 아니다.
 * 21:9 로 두면 1440px 에서 617px 이 되어 대부분이 빈 얼룩이 된다.
 * 텍스트 블록 높이에 맞춰 컨테이너를 정하고 이미지는 그 안을 채운다. */
.locmap {
  position: relative;
  border-bottom: 1px solid var(--v1-border);
  min-height: 340px;
  display: grid;
  overflow: clip;
}
.locmap picture { position: absolute; inset: 0; }
.locmap img {
  width: 100%; height: 100%;
  object-fit: cover; object-position: center 45%;
}
.locmap__in {
  position: relative;             /* 이미지 위 */
  display: grid; align-content: center;
  padding-block: var(--v1-space-8);
}
.locmap__name {
  font-family: var(--v1-font-display);
  font-size: var(--v1-text-2xl);
  line-height: var(--v1-leading-tight);
  letter-spacing: var(--v1-tracking-tight);
  margin-top: var(--v1-space-3);
}
.locmap__addr { margin-top: var(--v1-space-3); color: var(--v1-ink-2); }
.locmap__note {
  margin-top: var(--v1-space-5);
  font-size: var(--v1-text-xs); color: var(--v1-ink-3);
  max-width: 34ch;
}
@media (max-width: 780px) {
  .locmap { min-height: 300px; }
  .locmap__in { padding-block: var(--v1-space-7); }
}

/* ── 교통편 — 여정(旅程) 조판 ──────────────────────────────────────────────
 * 표가 아니라 "어디에서 어디로"가 보이는 형태로 둔다.
 * 선(線)이 출발지와 도착지를 잇는다 — 목록이 아니라 경로로 읽힌다. */
.trips { display: grid; gap: 0; border-top: 1px solid var(--v1-ink); }
.trip {
  display: grid;
  /* "고속전철·KTX" 가 한 줄에 들어가야 한다 — 7em 이면 두 줄로 접혔다 */
  grid-template-columns: 9.5em minmax(0, 1fr) 5.5em;
  gap: var(--v1-space-3) var(--v1-space-5);
  align-items: center;
  padding: var(--v1-space-5) 0;
  border-bottom: 1px solid var(--v1-border-soft);
}
.trip__mode { font-family: var(--v1-font-display); font-size: var(--v1-text-lg); }
.trip__path { display: flex; align-items: center; gap: var(--v1-space-3); min-width: 0; }
.trip__from, .trip__to { font-size: var(--v1-text-sm); color: var(--v1-ink-2); white-space: nowrap; }
.trip__to { color: var(--v1-ink-3); }
/* 잇는 선 — 끝에 잉크 점을 둬 방향을 만든다 */
.trip__line {
  flex: 1 1 auto; min-width: var(--v1-space-6);
  height: 1px; background: var(--v1-border);
  position: relative;
}
.trip__line::after {
  content: ""; position: absolute; right: 0; top: -2px;
  width: 5px; height: 5px; background: var(--v1-accent-raw);
}
.trip__time {
  text-align: right; font-size: var(--v1-text-sm);
  color: var(--v1-accent); font-weight: 600;
  font-variant-numeric: tabular-nums;
}
.trip__detail {
  grid-column: 2 / -1;
  font-size: var(--v1-text-xs); color: var(--v1-ink-3);
}
@media (max-width: 640px) {
  .trip { grid-template-columns: 1fr auto; }
  .trip__mode { grid-column: 1; }
  .trip__time { grid-column: 2; }
  .trip__path { grid-column: 1 / -1; }
  .trip__detail { grid-column: 1 / -1; }
}

/* ── 행사장 배치도 ─────────────────────────────────────────────────────────*/
.plan { margin: 0; }
.plan img { width: 100%; height: auto; border: 1px solid var(--v1-border); }
.plan figcaption {
  margin-top: var(--v1-space-3);
  font-size: var(--v1-text-xs); color: var(--v1-ink-3);
}

/* ── 동호회 목록 — 번호 조판 ───────────────────────────────────────────────*/
.teams {
  display: grid; grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 0; border-top: 1px solid var(--v1-border);
}
.team {
  display: grid; grid-template-columns: 2.4em 1fr;
  gap: var(--v1-space-3);
  align-items: baseline;
  padding: var(--v1-space-4) var(--v1-space-5) var(--v1-space-4) 0;
  border-bottom: 1px solid var(--v1-border-soft);
}
/* 번호를 괘선 표식으로 — 유의사항의 번호 칩과 같은 계열이지만
 * 여기는 17개 항목이라 칩으로 하면 시끄럽다. 잉크 눈금으로 처리한다.
 * 눈금 길이가 번호에 따라 늘어나 목록 전체가 하나의 자(尺)처럼 읽힌다. */
.team__n {
  position: relative;
  font-size: var(--v1-text-xs); color: var(--v1-ink-3);
  font-variant-numeric: tabular-nums; letter-spacing: var(--v1-tracking-wide);
  padding-bottom: var(--v1-space-3);
}
.team__n::after {
  content: ""; position: absolute; left: 0; bottom: 0;
  width: 100%; height: 2px;
  background: var(--v1-accent-raw);
}
/* 짝수 항목의 눈금을 짧게 — 반복이 리듬을 만든다 */
.team:nth-child(even) .team__n::after { width: 55%; background: var(--v1-border); }
.team__name { font-size: var(--v1-text-base); }
@media (max-width: 860px) { .teams { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
/* 1열로 떨어뜨리지 않는다 — 17개 항목이 세로로 늘어서면 모바일에서 화면
 * 3개가 연속으로 텍스트만이 된다(실측). 2열이면 눈금 표식이 좌우로 반복되며
 * 무늬로 읽히고 목록 길이도 절반이 된다. 단체명이 길지 않아 2열에 들어간다. */
@media (max-width: 520px) {
  .team { grid-template-columns: 2.1em 1fr; padding-right: var(--v1-space-3); }
  .team__name { font-size: var(--v1-text-sm); }
}

/* 시상 페이지의 기념품은 메인보다 넓게 둔다 — 여기가 주 콘텐츠다 */
.souv--wide { grid-template-columns: repeat(2, minmax(0, 300px)); }
@media (max-width: 700px) { .souv--wide { grid-template-columns: 1fr; } }

/* ── JS 주입 블록의 높이 예약 — CLS 방지 ──────────────────────────────────
 * event.json 을 fetch 한 뒤 표·목록을 채우므로, 예약이 없으면 뒤 콘텐츠와
 * 푸터가 밀려 내려간다(실측: awards 0.0285, caution 0.1424).
 * 행 수가 데이터로 고정된 표는 행수 × 행높이로 예약한다.
 * min-height 이므로 콘텐츠가 늘면 자연히 커지고 잘리지 않는다. */
/* ⚠️ tbody 에 min-height 는 듣지 않는다(display:table-row-group).
 *    표를 감싼 스크롤 래퍼에 예약해야 한다. 행 수는 데이터로 고정돼 있다. */
.tbl-scroll[data-rows] { min-height: calc(var(--rows) * var(--v1-row-h) + var(--v1-row-h)); }
#organizers { min-height: calc(2 * var(--v1-row-h)); }
#groupEntry { min-height: 228px; }
@media (max-width: 620px) {
  .tbl-scroll[data-rows] { min-height: calc(var(--rows) * var(--v1-row-h-sm) + var(--v1-row-h-sm)); }
  #groupEntry { min-height: 300px; }
}

/* ══ 코스안내 — 경유지 다이어그램 ══════════════════════════════════════════
 * ⚠️ 지도가 아니다. 순서(위상)만 나타낸다. 지리적 정확성을 주장하지 않는다.
 *    근거: docs/IA.md §코스 지도 — 원본에 지도 이미지·좌표가 없다. A안 승인. */

/* 코스 요약 섹션 — texture-course 지면 (§9-4 요청 자산) */
.ctex {
  position: relative;
  background-image: url("/assets/texture-course-1000.jpg");
  background-size: cover;
  background-position: center;
  border-bottom: 1px solid var(--v1-border);
}
@media (min-width: 1001px) {
  .ctex { background-image: url("/assets/texture-course-1600.jpg"); }
}
.ctex .facts__item { border-top-color: var(--v1-border); }

.cpath-wrap {
  display: grid; grid-template-columns: minmax(0, 1fr) 320px;
  gap: var(--v1-space-8);
  align-items: start;
}
@media (max-width: 900px) { .cpath-wrap { grid-template-columns: 1fr; } }
/* 위성 코스 이미지 — 가운데 정렬, 옆 설명 상자 없음 */
.cpath-wrap--center { grid-template-columns: 1fr; justify-items: center; }
.cmap-sat { margin: 0; width: 100%; max-width: 570px; }   /* 2배 해상도(1140px) 이미지를 570px 로 — 망막 화면에서 또렷하다 */
.cmap-sat img { display: block; width: 100%; height: auto; border-radius: var(--v1-radius-notch, 12px); border: 1px solid var(--v1-border); }

/* 노선도 — 실제 SVG. 사행(蛇行)으로 접어 한 화면에 담는다.
 * 한 구간 길이(150)를 세 코스가 공유하므로 경유지가 많을수록 선이 길어진다:
 * 하프 12구간 4행 / 10km 9구간 3행 / 5km 5구간 2행.
 * 세 페이지를 나란히 보면 길이 차이가 그대로 보인다.
 *
 * 지도가 아니다 — 좌표는 순서에서 계산한 값이고 실제 위치가 아니다. */
.croute {
  /* JS 로 그리기 전에도 자리를 차지한다. viewBox 종횡비를 그대로 예약하므로
   * 렌더 뒤에도 높이가 바뀌지 않는다(CLS 0). */
  aspect-ratio: var(--ar, 666 / 516);
  background: var(--v1-paper);
  border: 1px solid var(--v1-border);
}
.croute__svg { display: block; width: 100%; height: 100%; }
/* 좁은 화면은 행당 2지점으로 접는다(page.js). viewBox 가 달라지므로
 * 예약 종횡비도 함께 바꾼다 — 안 바꾸면 렌더 직후 높이가 튄다. */
@media (max-width: 720px) { .croute { aspect-ratio: var(--ar-sm, 366 / 912); } }

.croute__line {
  fill: none;
  stroke: var(--v1-ink-3);
  stroke-width: 3;
  stroke-linecap: round;
  stroke-linejoin: round;
}
/* 반환 갈고리 — 회전 방향이 아니라 "되돌아온다"는 표시다 */
.croute__turn {
  fill: none;
  stroke: var(--v1-accent);
  stroke-width: 2.5;
  stroke-linecap: round;
  stroke-linejoin: round;
}
.croute__node {
  fill: var(--v1-paper);
  stroke: var(--v1-ink-3);
  stroke-width: 3;
}
.croute__node.is-start, .croute__node.is-end {
  fill: var(--v1-ink);
  stroke: var(--v1-ink);
}
.croute__node.is-turn {
  fill: var(--v1-accent);
  stroke: var(--v1-accent);
}
.croute__num {
  fill: var(--v1-ink-3);
  font-size: 11px;
  font-variant-numeric: tabular-nums;
  text-anchor: middle;
}
.is-start ~ .croute__num { fill: var(--v1-paper); }
.croute__label {
  fill: var(--v1-ink-2);
  font-size: 13px;
  text-anchor: middle;
}
.croute__kind {
  fill: var(--v1-ink-3);
  font-size: 11px;
  letter-spacing: 0.08em;
  text-anchor: middle;
}

/* 요약 팩트 6개 — 2행 × 실측 높이 */
#courseSummary { min-height: 237px; }
#applySteps { min-height: 100px; }
@media (max-width: 620px) { #courseSummary { min-height: 333px; } }

/* 도표 설명 — 지리적 정확성을 주장하지 않는다는 것을 도표 옆에 둔다.
 * 각주로 작게 두면 읽히지 않는다. 도표와 같은 층위에 놓는다. */
.cpath__note {
  background: var(--v1-sunken);
  border: 1px solid var(--v1-border);
  padding: var(--v1-space-5);
  display: grid; gap: var(--v1-space-3);
  font-size: var(--v1-text-sm); color: var(--v1-ink-2);
  position: sticky; top: calc(var(--v1-nav-h) + var(--v1-space-5));
}
.cpath__noteH {
  font-family: var(--v1-font-display);
  font-size: var(--v1-text-base); color: var(--v1-ink);
  padding-bottom: var(--v1-space-3);
  border-bottom: 1px solid var(--v1-border);
}
.cpath__note strong { color: var(--v1-ink); }
@media (max-width: 900px) { .cpath__note { position: static; } }

/* ── 세 종목 거리 비교 — 메인의 막대를 링크로 재사용 ────────────────────── */
.ccmps { display: grid; gap: 0; border-top: 1px solid var(--v1-ink); }
.ccmp {
  display: grid; grid-template-columns: 7em minmax(0, 1fr) 7em;
  gap: var(--v1-space-5);
  align-items: center;
  padding: var(--v1-space-5) 0;
  border-bottom: 1px solid var(--v1-border-soft);
  border-left: 2px solid transparent;
  text-decoration: none; color: inherit;
  transition: background-color var(--v1-dur-micro) var(--v1-ease-lift),
              border-left-color var(--v1-dur-short) var(--v1-ease-lift),
              transform var(--v1-dur-short) var(--v1-ease-lift);
}
.ccmp:hover {
  background: var(--v1-surface);
  border-left-color: var(--v1-accent);
  transform: translateX(var(--v1-space-2));
}
.ccmp--current { background: var(--v1-surface); border-left-color: var(--v1-ink); }
.ccmp__label { font-family: var(--v1-font-display); font-size: var(--v1-text-lg); }
.ccmp__dist {
  text-align: right; font-size: var(--v1-text-sm);
  color: var(--v1-ink-3); font-variant-numeric: tabular-nums;
}
@media (max-width: 620px) {
  .ccmp { grid-template-columns: 1fr auto; gap: var(--v1-space-2) var(--v1-space-4); }
  .ccmp .cbar { grid-column: 1 / -1; }
}

/* ══ 참가신청 폼 ═══════════════════════════════════════════════════════════
 * ⚠️ 실제 접수 기능이 아니다(시안). 그러나 검증·aria·포커스는 실제 수준이다.
 * 폼의 완성도는 동작하는 척이 아니라 접근성에서 나온다. */

.form { display: grid; gap: var(--v1-space-7); }
/* 좁은 폼. 안쪽 격자가 이미 34rem 로 가운데 정렬되므로
 * 이 상자도 가운데로 보내야 제목과 시작선이 맞는다. */
.form--narrow { max-width: 720px; margin-inline: auto; }
/* 입력칸은 한 줄에 하나다.
 * 2열로 두면 시선이 좌우로 오가고, 라벨과 칸의 짝이 한눈에 안 잡힌다.
 * 폼은 위에서 아래로 한 줄씩 채우는 것이 읽기 쉽다. */
.form__grid {
  display: grid; grid-template-columns: minmax(0, 1fr);
  gap: var(--v1-space-5);
  /* 1열이라 폭이 좁다. 왼쪽에 붙여 두면 넓은 화면에서 한쪽으로 쏠린다.
   * width 를 같이 주지 않으면 그리드가 내용 폭(200px 남짓)까지만 늘어나
   * 가운데 정렬해도 제목과 시작선이 어긋난다. */
  width: 100%;
  max-width: 34rem;
  margin-inline: auto;
}
/* --two 는 예전 이름이다. 지금은 1열과 같다 —
 * 마크업을 일일이 고치는 대신 여기서 맞춘다. */
.form__grid--two { grid-template-columns: minmax(0, 1fr); }

.field { display: grid; gap: var(--v1-space-2); align-content: start; }
.field__label {
  font-size: var(--v1-text-sm); font-weight: 600; color: var(--v1-ink);
}
/* 필수 표시 — 색만으로 구분하지 않는다(색각 이상 대응). 별표가 실제 문자로 있다. */
.field__label span { color: var(--v1-accent); margin-left: 2px; }

.field__in {
  width: 100%;
  padding: var(--v1-space-3) var(--v1-space-4);
  background: var(--v1-paper);
  border: 1px solid var(--v1-border);
  border-radius: var(--v1-radius-sm);
  color: var(--v1-ink);
  min-height: var(--v1-tap-min);        /* 터치 타깃 하한 */
  transition: border-color var(--v1-dur-micro) var(--v1-ease-lift),
              background-color var(--v1-dur-micro) var(--v1-ease-lift),
              box-shadow var(--v1-dur-micro) var(--v1-ease-lift);
}
.field__in:hover { border-color: var(--v1-ink-3); }
/* 포커스는 outline 만으로 두지 않는다 — 지면도 바뀌어 "지금 여기"가 분명해진다 */
.field__in:focus-visible {
  outline: 2px solid var(--v1-accent);
  outline-offset: 2px;
  background: var(--v1-neutral-ground);
  border-color: var(--v1-accent);
}
select.field__in { cursor: pointer; }

.field__hint { font-size: var(--v1-text-xs); color: var(--v1-ink-3); line-height: 1.6; }

/* 오류 — 색 단독으로 알리지 않는다. 좌측 잉크 막대 + 텍스트를 동반한다. */
.field__err:empty { display: none; }
.field__err {
  font-size: var(--v1-text-sm); color: var(--v1-accent); font-weight: 600;
  padding-left: var(--v1-space-4);
  position: relative;
}
.field__err::before {
  content: ""; position: absolute; left: 0; top: 0.45em;
  width: 8px; height: 2px; background: var(--v1-accent);
}
.field--bad .field__in { border-color: var(--v1-accent); border-width: 2px; }

/* 체크박스 — 기본 컨트롤을 키우고 라벨과 나란히 */
.field--check { gap: var(--v1-space-3); }
.check { display: grid; grid-template-columns: auto minmax(0, 1fr); gap: var(--v1-space-3); align-items: start; }
.check input[type="checkbox"] {
  width: var(--v1-check); height: var(--v1-check);
  margin: 0;
  accent-color: var(--v1-accent);
  cursor: pointer;
}
.check input[type="checkbox"]:focus-visible { outline: 2px solid var(--v1-accent); outline-offset: 3px; }
.check .field__label { font-weight: 500; cursor: pointer; }

/* 제출 실패 요약 — 오류가 여러 개일 때 하나씩 찾아다니게 하지 않는다.
 * ⚠️ display 를 지정하면 hidden 속성이 무력화된다 —
 *    빈 상자가 폼 위에 항상 떠 있게 된다(실제로 그렇게 렌더됐다).
 *    [hidden] 에 display:none 을 명시해 되돌린다. */
.form__summary {
  background: var(--v1-sunken);
  border: 2px solid var(--v1-accent);
  padding: var(--v1-space-5);
  display: grid; gap: var(--v1-space-3);
}
.form__summary[hidden], .form__done[hidden] { display: none; }
.form__summary:focus-visible { outline: 2px solid var(--v1-ink); outline-offset: 2px; }
.form__summaryH {
  font-family: var(--v1-font-display);
  font-size: var(--v1-text-lg); color: var(--v1-ink);
}
.form__summaryList { display: grid; gap: var(--v1-space-2); }
.form__summaryList a {
  color: var(--v1-accent); font-size: var(--v1-text-sm); font-weight: 600;
  text-decoration: underline; text-underline-offset: 3px;
  display: inline-block; padding-block: var(--v1-space-1);
}
.form__summaryList a:hover { color: var(--v1-ink); }

.form__act { display: flex; gap: var(--v1-space-3); flex-wrap: wrap; }

/* 제출 성공 — 실제로는 접수되지 않는다는 사실을 명확히 */
.form__done {
  background: var(--v1-surface);
  border-block: 2px solid var(--v1-ink);
  padding: var(--v1-space-5);
  display: grid; gap: var(--v1-space-2);
}
.form__done:focus-visible { outline: 2px solid var(--v1-accent); outline-offset: 2px; }
.form__doneH { font-family: var(--v1-font-display); font-size: var(--v1-text-lg); }

/* ── 신청 진입점 카드 — 원본의 메뉴 선택 구조 ────────────────────────────── */
.amenus {
  display: grid; grid-template-columns: repeat(3, minmax(0, 1fr));
  border-left: 1px solid var(--v1-border);
  /* JS 로 주입되므로 높이를 예약한다(실측 데스크탑 177px — 개수와 무관하게 1행).
   * 없으면 뒤 폼이 밀려 CLS 0.013 이 발생한다. */
  min-height: var(--v1-amenu-h);
}
.amenu {
  border-right: 1px solid var(--v1-border);
  border-top: 2px solid var(--v1-ink);
  padding: var(--v1-space-5);
  display: grid; gap: var(--v1-space-2); align-content: start;
}
.amenu__label { font-family: var(--v1-font-display); font-size: var(--v1-text-lg); }
.amenu__desc { font-size: var(--v1-text-sm); color: var(--v1-ink-2); }
.amenu__note {
  font-size: var(--v1-text-xs); color: var(--v1-ink-3);
  padding-top: var(--v1-space-2);
  border-top: 1px solid var(--v1-border-soft);
  margin-top: var(--v1-space-2);
}
@media (max-width: 780px) {
  .amenus { grid-template-columns: 1fr; border-left: 0; }
  .amenu { border-right: 0; }
  /* 모바일은 세로로 쌓이므로 개수에 비례한다 — 실측 카드당 약 144px */
  .amenus[data-menu] { min-height: calc(var(--n, 2) * var(--v1-amenu-h-sm)); }
}

/* ── 신청 절차 진행 표시 ───────────────────────────────────────────────────
 * 장식이 아니라 정보다 — 신청은 6단계이고 이 화면이 그중 어디인지 알려준다.
 * 완료/현재/예정을 색이 아니라 도형과 굵기로도 구분한다. */
.prog {
  background: var(--v1-surface);
  border-bottom: 1px solid var(--v1-border);
  padding-block: var(--v1-space-6);
}
.prog__list {
  width: min(100% - var(--v1-space-6), 1200px);
  margin-inline: auto;
  display: grid; grid-template-columns: repeat(6, minmax(0, 1fr));
  gap: 0;
}
.prog__i {
  position: relative;
  display: grid; gap: var(--v1-space-3);
  padding-top: var(--v1-space-5);
  padding-right: var(--v1-space-4);
}
/* 단계를 잇는 선 — 마지막 단계는 잇지 않는다 */
.prog__i:not(:last-child)::after {
  content: ""; position: absolute;
  top: var(--v1-space-5); left: 0; right: 0;
  height: 2px; background: var(--v1-border);
}
.prog__n {
  position: relative; z-index: 1;
  width: var(--v1-check); height: var(--v1-check);
  display: grid; place-items: center;
  margin-top: calc(var(--v1-space-5) * -1 - var(--v1-check) / 2 + 1px);
  font-size: var(--v1-text-xs);
  font-variant-numeric: tabular-nums;
  background: var(--v1-paper);
  border: 2px solid var(--v1-border);
  color: var(--v1-ink-3);
}
.prog__t { font-size: var(--v1-text-xs); color: var(--v1-ink-3); line-height: 1.5; }
/* 현재 단계 — 채운 도형 + 굵은 글자. 색 단독이 아니다. */
.prog__i--current .prog__n {
  background: var(--v1-accent); border-color: var(--v1-accent);
  color: var(--v1-paper); font-weight: 700;
}
.prog__i--current .prog__t { color: var(--v1-ink); font-weight: 700; }
@media (max-width: 780px) {
  .prog__list { grid-template-columns: repeat(3, minmax(0, 1fr)); row-gap: var(--v1-space-5); }
  /* 3열로 접히면 3번째와 4번째 사이의 선은 이어지지 않아야 한다 */
  .prog__i:nth-child(3n)::after { display: none; }
}

/* ── 폼 옆 참가비 요약 ─────────────────────────────────────────────────────
 * 신청자가 폼을 채우면서 확인해야 하는 정보다. 장식이 아니다. */
.form--aside { grid-template-columns: minmax(0, 1fr) 300px; align-items: start; }
.form--aside .form__summary,
.form--aside .field--check,
.form--aside .form__act,
.form--aside .form__done { grid-column: 1 / -1; }
.form--aside .form__grid { grid-column: 1; }
.fside {
  grid-column: 2; grid-row: span 3;
  background: var(--v1-surface);
  border: 1px solid var(--v1-border);
  border-top: 2px solid var(--v1-ink);
  padding: var(--v1-space-5);
  display: grid; gap: var(--v1-space-4);
  position: sticky; top: calc(var(--v1-nav-h) + var(--v1-space-5));
}
.fside__h {
  font-family: var(--v1-font-display);
  font-size: var(--v1-text-base); color: var(--v1-ink);
  padding-bottom: var(--v1-space-3);
  border-bottom: 1px solid var(--v1-border);
}
.fside__note { font-size: var(--v1-text-xs); color: var(--v1-ink-3); line-height: 1.6; }
/* 요약 안의 막대는 좁으므로 라벨·금액을 위아래로 둔다 */
.ccmps--mini { border-top: 0; }
.ccmps--mini .ccmp {
  grid-template-columns: 1fr auto;
  gap: var(--v1-space-2) var(--v1-space-3);
  padding: var(--v1-space-3) 0;
  border-left: 0;
}
.ccmps--mini .ccmp:hover { background: none; transform: none; }
.ccmps--mini .ccmp__label { font-size: var(--v1-text-base); }
.ccmps--mini .cbar { grid-column: 1 / -1; height: var(--v1-space-5); }
.ccmps--mini .ccmp__dist { font-size: var(--v1-text-sm); color: var(--v1-accent); font-weight: 600; }

@media (max-width: 1000px) {
  .form--aside { grid-template-columns: 1fr; }
  .fside { grid-column: 1; grid-row: auto; position: static; }
}

/* ══ 커뮤니티 · 대회사진 ═══════════════════════════════════════════════════ */

/* ── 목록 행 (공지·문의) ──────────────────────────────────────────────────
 * 메인의 .notice 와 다른 조판이다 — 여기는 번호·상태가 있는 게시판 목록이다. */
/* ══ 부스안내 — 배치도 범례 ═══════════════════════════════════════════════
 * 배치도 이미지에 표시된 시설을 목록으로 다시 짚는다. 이미지 하나만 두면
 * 모바일에서 축소돼 글씨가 읽히지 않고, 아래 동호회 목록까지 화면 2개가
 * 연속으로 텍스트만이 된다(실측).
 * 위치 설명은 넣지 않는다 — 이미지에서 좌표를 읽어 옮기면 추정이 섞인다. */
.fac {
  margin-top: var(--v1-space-5);
  display: grid; grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: var(--v1-space-4) var(--v1-space-6);
}
.fac__i {
  display: grid; grid-template-columns: auto minmax(0, 1fr);
  gap: var(--v1-space-3); align-items: center;
  padding-block: var(--v1-space-3);
  border-top: 1px solid var(--v1-border);
}
/* 표식 — 배치도 위의 구획을 뜻하는 사각. 아이콘을 쓰지 않는다(v1은 도형 언어다) */
.fac__mark {
  width: var(--v1-fac-mark); height: var(--v1-fac-mark);
  border: 2px solid var(--v1-accent);
  background: color-mix(in srgb, var(--v1-accent) 14%, transparent);
}
.fac__t { font-size: var(--v1-text-sm); line-height: 1.5; }
@media (max-width: 780px) { .fac { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
@media (max-width: 460px) { .fac { grid-template-columns: 1fr; gap: 0; } }

/* ══ 1:1문의 — 처리 흐름 / 문의 전 확인 ════════════════════════════════════
 * 조건 13·14 앵커. 폼과 목록만 있으면 화면 전체가 텍스트다(실측 앵커 0개).
 * ⚠️ 처리 소요일을 숫자로 쓰지 않는다 — 원본에 근거가 없다. */
.qflow__steps {
  margin-top: var(--v1-space-5);
  display: grid; grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: var(--v1-space-5);
  counter-reset: qflow;
}
.qflow__i {
  position: relative;
  display: grid; align-content: start; gap: var(--v1-space-2);
  padding-top: var(--v1-space-5);
  border-top: 2px solid var(--v1-ink);
}
/* 단계 사이를 잇는 선 — 네 칸이 따로 노는 카드로 읽히지 않게 한다 */
.qflow__i:not(:last-child)::after {
  content: ""; position: absolute;
  top: -2px; right: calc(var(--v1-space-5) * -1);
  width: var(--v1-space-5); height: 2px;
  background: var(--v1-border);
}
.qflow__n {
  font-family: var(--v1-font-display);
  font-size: var(--v1-text-xl);
  color: var(--v1-accent);
  line-height: 1;
}
.qflow__t { font-size: var(--v1-text-base); font-weight: 600; }
.qflow__d { font-size: var(--v1-text-sm); color: var(--v1-ink-3); line-height: 1.6; }
@media (max-width: 780px) {
  .qflow__steps { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  /* 2열로 접히면 2·4번 오른쪽의 이음선이 허공을 가리킨다 */
  .qflow__i:nth-child(2n)::after { display: none; }
}
@media (max-width: 460px) {
  .qflow__steps { grid-template-columns: 1fr; gap: var(--v1-space-4); }
  .qflow__i::after { display: none; }
}

/* 문의 전 확인 — 답을 여기 다시 쓰지 않고 FAQ 원문으로 보낸다 */
.qpre {
  background: var(--v1-sunken);
  border: 1px solid var(--v1-border);
  padding: var(--v1-space-6);
}
.qpre__head { display: grid; gap: var(--v1-space-2); }
.qpre__list {
  margin: var(--v1-space-5) 0;
  display: grid; gap: 0;
  border-top: 1px solid var(--v1-border);
}
.qpre__i { border-bottom: 1px solid var(--v1-border); }
.qpre__link {
  display: grid; grid-template-columns: auto minmax(0, 1fr);
  gap: var(--v1-space-4); align-items: start;
  padding: var(--v1-space-4) 0;
  min-height: var(--v1-tap-min);
  text-decoration: none; color: var(--v1-ink);
  transition: color var(--v1-dur-micro) var(--v1-ease-lift),
              padding-left var(--v1-dur-short) var(--v1-ease-lift);
}
/* 호버 단서가 색 하나면 안 된다(조건 9) — 들여쓰기가 함께 움직인다 */
.qpre__link:hover { color: var(--v1-accent); padding-left: var(--v1-space-3); }
.qpre__mark {
  font-family: var(--v1-font-display);
  font-size: var(--v1-text-base);
  color: var(--v1-paper); background: var(--v1-ink);
  width: 1.9em; height: 1.9em;
  display: grid; place-items: center;
}
.qpre__link:hover .qpre__mark { background: var(--v1-accent); }
.qpre__q { font-size: var(--v1-text-base); line-height: 1.6; }

.nrows { border-top: 1px solid var(--v1-ink); }
.nrow {
  /* 마지막 칸(등록일)은 "2026. 08. 17" 이 한 줄로 들어갈 만큼 준다 */
  display: grid; grid-template-columns: 4em minmax(0, 1fr) 4.4em 8.5em;
  gap: var(--v1-space-4);
  align-items: baseline;
  padding: var(--v1-space-4) 0;
  border-bottom: 1px solid var(--v1-border-soft);
}
.nrow--qna { grid-template-columns: 4em minmax(0, 1fr) 6em 8.5em 5.5em; }
/* ── 접수 기간이 아닐 때 ──────────────────────────────────────────────────
 * 작은 글씨로 알리고 버튼만 끄면, 아래 유의사항·동의 전문을 다 내려 본 뒤에야
 * 신청이 안 된다는 걸 안다. 화면을 비우고 크게 알린다. */
.closed {
  margin: var(--v1-space-9) auto;
  padding: var(--v1-space-9) var(--v1-space-6);
  max-width: 34rem;
  text-align: center;
  border: 1px solid var(--v1-border);
  border-radius: var(--v1-radius-sm);
  background: var(--v1-surface);
}
.closed__h {
  margin: 0;
  font-family: var(--v1-font-display);
  font-size: var(--v1-text-xl);
  font-weight: var(--v1-weight-display-bold);
  line-height: var(--v1-leading-tight);
  color: var(--v1-ink);
}
.closed__p {
  margin: var(--v1-space-4) 0 0;
  font-size: var(--v1-text-base);
  color: var(--v1-ink-2);
  line-height: var(--v1-leading-body);
}
.closed__act {
  margin-top: var(--v1-space-7);
  display: flex; gap: var(--v1-space-3);
  justify-content: center; flex-wrap: wrap;
}

/* 비었을 때 안내 한 줄 — 그리드를 풀지 않으면 어절이 칸마다 쪼개진다 */
.nrow--empty {
  grid-template-columns: 1fr;
  padding: var(--v1-space-7) 0;
  text-align: center;
  color: var(--v1-ink-3);
  font-size: var(--v1-text-sm);
}
/* 연도 구분 머리 — 지난 대회임이 목록에서 드러난다 */
.nrow--year {
  grid-template-columns: 1fr;
  padding-top: var(--v1-space-7);
  border-bottom: 2px solid var(--v1-ink);
}
.nrow--year:first-child { padding-top: var(--v1-space-4); }
.nrow__year {
  font-family: var(--v1-font-display);
  font-size: var(--v1-text-lg); color: var(--v1-ink);
}
.nrow__n {
  font-size: var(--v1-text-xs); color: var(--v1-ink-3);
  font-variant-numeric: tabular-nums; letter-spacing: var(--v1-tracking-wide);
}
.nrow__t { color: var(--v1-ink); }
.nrow__who { font-size: var(--v1-text-sm); color: var(--v1-ink-3); }
.nrow__d {
  font-size: var(--v1-text-sm); color: var(--v1-ink-3);
  font-variant-numeric: tabular-nums; text-align: right;
  /* "2026. 08. 17" 이 7em 칸에서 두 줄로 접혔다. 날짜는 한 줄이어야
   * 위아래 행의 숫자가 같은 자리에 놓여 훑어 읽힌다. */
  white-space: nowrap;
}
/* 상태 뱃지 — 색 단독이 아니다. 보더 유무와 굵기로도 구분된다. */
.badge {
  font-size: var(--v1-text-xs);
  padding: 2px var(--v1-space-3);
  border: 1px solid var(--v1-accent);
  color: var(--v1-accent);
  text-align: center;
  white-space: nowrap;
}
.badge--done {
  border-color: var(--v1-border); color: var(--v1-ink-3);
  border-style: dashed;
}
@media (max-width: 780px) {
  .nrow, .nrow--qna { grid-template-columns: 3.2em minmax(0, 1fr) auto; }
  .nrow--qna .nrow__who { grid-column: 2; font-size: var(--v1-text-xs); }
  .nrow--qna .nrow__d { grid-column: 3; }
  .nrow--qna .badge { grid-column: 3; justify-self: end; margin-top: var(--v1-space-1); }
}

/* ── 공지 상세 ────────────────────────────────────────────────────────────
 * 목록과 같은 지면 폭을 쓴다. 상세만 좁히면 목록에서 넘어올 때 글이 흔들린다.
 * 높이는 제한하지 않는다 — .abox 처럼 스크롤을 안에 가두면 긴 공지에서
 * 페이지 스크롤과 상자 스크롤이 겹쳐 읽기가 어렵다. */
.post {
  border-top: 1px solid var(--v1-ink);
  border-bottom: 1px solid var(--v1-border-soft);
  padding: var(--v1-space-6) 0 var(--v1-space-7);
}
.post__t {
  font-family: var(--v1-font-display);
  font-size: var(--v1-text-xl); line-height: 1.4; color: var(--v1-ink);
}
/* 등록일·조회수 — 제목 아래 한 줄. 담당자가 아니라 참가자에게 보이는 값이다 */
.post__meta {
  margin-top: var(--v1-space-2);
  font-size: var(--v1-text-sm); color: var(--v1-ink-3);
  font-variant-numeric: tabular-nums;
}
.post__dot { margin: 0 var(--v1-space-2); }
.post__b {
  margin-top: var(--v1-space-6);
  line-height: 1.9; color: var(--v1-ink-2);
}
.post__b > p + p { margin-top: var(--v1-space-4); }
.post__load, .post__err { color: var(--v1-ink-3); }

/* 본문 이미지 — 원본 비율 그대로 둔다. 공지에 붙는 건 안내문·코스도면이라
 * 격자에 맞춰 잘라내면 글씨가 잘려 못 읽는다(대회사진과 다른 점이다). */
.post__fig { margin: var(--v1-space-6) 0 0; }
.post__img {
  display: block;
  max-width: 100%; height: auto;
  background: var(--v1-surface);
}
.post__cap {
  margin-top: var(--v1-space-2);
  font-size: var(--v1-text-sm); color: var(--v1-ink-3);
}
.post__back { margin-top: var(--v1-space-6); }

/* ── 자주묻는질문 — details/summary 아코디언 ──────────────────────────────
 * 브라우저 기본 동작을 쓴다. 키보드·스크린리더 지원이 함께 온다. */
.faqs { display: grid; gap: 0; border-top: 1px solid var(--v1-ink); }
.faq { border-bottom: 1px solid var(--v1-border-soft); }
.faq__q {
  display: grid; grid-template-columns: 2.2em minmax(0, 1fr) auto;
  gap: var(--v1-space-4);
  align-items: start;
  padding: var(--v1-space-5) 0;
  cursor: pointer;
  list-style: none;                 /* 기본 삼각형 제거 */
}
.faq__q::-webkit-details-marker { display: none; }
.faq__q:focus-visible { outline: 2px solid var(--v1-accent); outline-offset: 2px; }
/* Q/A 표식 — 조판 자체가 §9-3 앵커다 */
/* Q/A 표식 — lg(22.4px)는 질문 글씨보다 커서 배지가 먼저 읽혔다.
 * 표식은 질문을 찾는 이정표지 내용이 아니다. 본문 크기로 내린다. */
.faq__mark {
  font-family: var(--v1-font-display);
  font-size: var(--v1-text-base); line-height: 1;
  color: var(--v1-accent);
  width: 1.6em; height: 1.6em;
  display: grid; place-items: center;
  border: 1px solid var(--v1-accent);
}
.faq__mark--a { color: var(--v1-ink-3); border-color: var(--v1-border); }
/* 질문 글씨 — lg(22.4px)는 답변(17.4px)과 5px 이나 차이가 나 질문만 크게
 * 튀었다. 아코디언 제목은 소제목 위계면 충분하다. 사이트 소제목 크기로 맞춘다. */
.faq__qt {
  font-family: var(--v1-font-display);
  font-size: var(--v1-text-base);
  line-height: var(--v1-leading-tight);
}
/* 여닫음 표식 — 색이 아니라 회전으로 상태를 보인다 */
.faq__q::after {
  content: ""; width: 10px; height: 10px;
  border-right: 1px solid var(--v1-ink-3); border-bottom: 1px solid var(--v1-ink-3);
  transform: rotate(45deg); margin-top: 0.5em;
  transition: transform var(--v1-dur-short) var(--v1-ease-lift);
}
.faq[open] .faq__q::after { transform: rotate(-135deg); }
.faq__a {
  display: grid; grid-template-columns: 2.2em minmax(0, 1fr);
  gap: var(--v1-space-4);
  padding-bottom: var(--v1-space-6);
}
.faq__at { display: grid; gap: var(--v1-space-3); color: var(--v1-ink-2); }
@media (max-width: 620px) {
  .faq__q { grid-template-columns: 1.8em minmax(0, 1fr) auto; gap: var(--v1-space-3); }
  .faq__a { grid-template-columns: 1.8em minmax(0, 1fr); gap: var(--v1-space-3); }
}

/* 여러 줄 입력 */
.field__in--area { min-height: 8em; resize: vertical; line-height: var(--v1-leading-body); }

/* 수상자 표의 2단 머리 */
.tbl__sub2 { font-size: var(--v1-text-xs); font-weight: 500; color: var(--v1-ink-3); }

/* ── JS 주입 목록의 높이 예약 — CLS 방지 ──────────────────────────────────
 * 목록이 서버에서 늦게 오므로 자리를 미리 잡아 둔다. 안 그러면 푸터가
 * 위로 붙었다가 목록이 오면서 아래로 밀린다.
 *
 * 이전 값(공지 2640px)은 **지난 대회 공지 36건을 함께 그리던 때**의 실측이다.
 * 그 목록을 걷어냈는데(2026-08-20) 예약만 남아 3건짜리 화면 아래에
 * 2400px 넘는 빈 공간이 생겼다. 몇 건이 올지 모르는 값이므로
 * 한두 행 분량만 잡고 나머지는 콘텐츠가 정하게 둔다. */
#noticeList,
#faqList,
#qnaList { min-height: 180px; }

/* ── 공지 목록의 월(月) 눈금 — §9-3 앵커 ──────────────────────────────────
 * 장식이 아니라 데이터다. 12개월 눈금 중 해당 월이 채워진다.
 * "이 공지가 언제 것인가"가 목록에서 형태로 읽히고,
 * 지난 대회 공지라는 사실이 연도 머리와 눈금 위치로 이중으로 드러난다. */
.mscale { display: flex; gap: 2px; align-items: flex-end; height: var(--v1-space-4); }
.mscale i {
  width: 3px; height: 40%;
  background: var(--v1-border-soft);
}
.mscale i.is-on {
  height: 100%;
  background: var(--v1-accent);
}

/* JS 주입 — 조회 안내 1줄 + 폼 옆 요약 패널. 실측 기준 예약 */
#recordNotice { min-height: 28px; }
.fside { min-height: 580px; }
@media (max-width: 620px) { #recordNotice { min-height: 52px; } }

/* ══ 숫자 조판 — tabular-nums 일괄 적용 ════════════════════════════════════
 * 참가비·거리·시간·순위가 자릿수 맞게 정렬되어야 한다.
 * 비례폭 숫자는 표에서 열이 흔들려 비교가 안 된다.
 * 개별 요소에 흩어져 있던 지정을 여기서 한 번에 정리한다. */
.tbl, .tbl th, .tbl td,
.team__n, .caut__n, .nrow__n, .nrow__d,
.steps__n, .prog__n, .cbar__num, .ccmp__dist,
.trip__time, .dday__num, .course__dist, .course__fee,
time {
  font-variant-numeric: tabular-nums;
}
/* 표의 금액·수치 열은 우측 정렬까지 함께 — 자릿수가 세로로 맞는다 */
.tbl__num { text-align: right; }

/* ── 타이포 비교 페이지 전용 (확정 후 v1/type.html 과 함께 삭제) ─────────── */
.tspec { display: grid; gap: var(--v1-space-7); margin-top: var(--v1-space-6); }
.tspec__row {
  display: grid; grid-template-columns: 15em minmax(0, 1fr);
  gap: var(--v1-space-5);
  align-items: start;
  padding-top: var(--v1-space-4);
  border-top: 1px solid var(--v1-border-soft);
}
.tspec__k {
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
  font-size: var(--v1-text-xs); color: var(--v1-ink-3);
  line-height: var(--v1-lead-tight);
}
@media (max-width: 780px) { .tspec__row { grid-template-columns: 1fr; gap: var(--v1-space-2); } }

/* ══ 처리방침 등 긴 산문 페이지 ════════════════════════════════════════════
 * 조항이 이어지는 문서다. 읽는 사람이 한 줄을 놓치지 않게 폭을 제한하고
 * 조항 사이 간격을 문단 사이보다 크게 벌린다. */
.prose { max-width: 72ch; }
/* 보호책임자 표는 JS 로 채운다 — 예약이 없으면 그만큼 아래가 밀린다.
 * 실측(2026-08-13): 1440px 276 · 900px 269 · 390px 601 · 360px 600.
 * 데스크탑에서는 렌더가 빨라 안 보였지만 CLS 0.0526 의 원인이었다. */
#privacyContact { min-height: 276px; }
@media (max-width: 760px) { #privacyContact { min-height: 601px; } }
/* 보호책임자 표는 4칸이라 좁다. 전화번호가 "042-/255-/7917" 로 세 줄이 됐다(실측).
 * 하이픈에서 줄이 바뀌지 않게 막는다. */
.prose .facts__v { word-break: keep-all; overflow-wrap: normal; }
.prose .facts { grid-template-columns: repeat(auto-fit, minmax(11rem, 1fr)); }
.prose p { margin-top: var(--v1-space-4); line-height: 1.9; }
.prose .notes { margin-top: var(--v1-space-4); }
.prose .h3 { padding-top: var(--v1-space-5); border-top: 1px solid var(--v1-border-soft); }
.prose .h3:first-child { padding-top: 0; border-top: 0; }

/* 강조 상자 — "주민등록번호를 수집하지 않는다" 처럼 오해를 미리 막는 문장에 쓴다.
 * 색 스트라이프를 쓰지 않는다. 지면과 괘선으로만 층위를 만든다(v1 규칙). */
.callout {
  background: var(--v1-sunken);
  border-block: 1px solid var(--v1-border);
  padding: var(--v1-space-5);
}
.callout__h {
  font-family: var(--v1-font-display);
  font-size: var(--v1-text-lg);
  color: var(--v1-ink);
  margin-bottom: var(--v1-space-2);
}
.callout p { margin-top: 0; }

/* 미확정 문구 자리 — 확정 전이라는 걸 숨기지 않는다.
 * 회색으로 흐리게 두면 "채워진 내용"으로 오인된다. 점선 테두리로 빈칸임을 보인다. */
.pending-inline {
  margin-top: var(--v1-space-4);
  padding: var(--v1-space-3) var(--v1-space-4);
  border: 1px dashed var(--v1-accent);
  color: var(--v1-accent);
  font-size: var(--v1-text-sm);
}

/* 처리방침 — 수집·이용 목적 번호 칩 (조건 13·14 앵커) */
.purp {
  margin-top: var(--v1-space-5);
  display: grid; grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: var(--v1-space-4) var(--v1-space-6);
}
.purp__i {
  display: grid; grid-template-columns: auto minmax(0, 1fr);
  gap: var(--v1-space-4); align-items: center;
  padding-block: var(--v1-space-3);
  border-top: 1px solid var(--v1-border);
}
.purp__n {
  font-family: var(--v1-font-display);
  font-size: var(--v1-text-base);
  width: 2em; height: 2em;
  display: grid; place-items: center;
  background: var(--v1-ink); color: var(--v1-paper);
}
.purp__t { font-size: var(--v1-text-sm); line-height: 1.6; }
@media (max-width: 620px) { .purp { grid-template-columns: 1fr; gap: 0; } }

/* ══ 고정 헤더 아래로 앵커가 숨는 문제 ═════════════════════════════════════
 * 헤더가 sticky 라 #해시로 이동하거나 스크롤할 때 제목이 헤더 뒤로 들어간다
 * (실측: /apply/winners 에서 "종합 수상자"·"시상 유의사항" 이 가려졌다).
 * 링크로 찾아온 사람이 제목을 못 보고 본문 중간부터 읽게 된다.
 *
 * scroll-margin-top 으로 착지점을 헤더 높이만큼 내린다.
 * html 의 scroll-padding-top 도 함께 둔다 — 키보드 Tab 이동에도 적용된다. */
html { scroll-padding-top: calc(var(--v1-nav-h) + var(--v1-space-4)); }
main :is(h1, h2, h3, section, [id]) { scroll-margin-top: calc(var(--v1-nav-h) + var(--v1-space-4)); }
@media (max-width: 700px) {
  html { scroll-padding-top: calc(var(--v1-nav-h-sm) + var(--v1-space-3)); }
  main :is(h1, h2, h3, section, [id]) { scroll-margin-top: calc(var(--v1-nav-h-sm) + var(--v1-space-3)); }
}

/* ══ 코스 카드 (홈) ════════════════════════════════════════════════════════
 * draft-05 조판을 v1 토큰으로 옮긴 것(2026-08-13 지시).
 *
 * 핵심은 **노치(notch)** 다. 카드 좌상단을 mask 로 실제로 파내고 그 자리에
 * 라벨을 놓는다. 사진 위에 글자를 얹는 게 아니라 페이지 지면 위에 그대로
 * 앉으므로 배경이 어떤 사진이든 대비가 무너지지 않는다.
 * 라운드 이음새는 radial-gradient 로 안쪽 곡선을 만들어 파낸 자리가
 * 칼로 자른 듯 각지지 않게 한다. */
.csec { background: var(--v1-white); padding-block: var(--v1-sec-lead); }
.csec__head {
  display: flex; align-items: flex-end; justify-content: space-between;
  gap: var(--v1-space-6); margin-bottom: var(--v1-space-8);
}
.csec__head .lede { margin-top: var(--v1-space-3); max-width: 52ch; }
.csec__all {
  flex: 0 0 auto; white-space: nowrap;
  font-size: var(--v1-text-sm); font-weight: 600;
  color: var(--v1-ink-2); text-decoration: none;
  padding-bottom: var(--v1-space-1);
  border-bottom: 2px solid var(--v1-accent);
  transition: color var(--v1-dur-micro) var(--v1-ease-lift),
              padding-bottom var(--v1-dur-micro) var(--v1-ease-lift);
}
.csec__all:hover { color: var(--v1-accent); padding-bottom: var(--v1-space-2); }

/* 같은 폭 세로 카드 3장 (384×560).
 * 세 코스 모두 남북으로 길다. 예전처럼 10km·5km 를 가로 카드 두 장(588×268)으로 쌓으면
 * 호버 코스도가 높이 200px 로 줄어 읽히지 않았다(실측). 세로로 세우면 코스가 카드를 채운다. */
/* 2026-10-27 하프코스 제외 — 카드가 2장이 됐다 */
.cgrid { display: grid; grid-template-columns: repeat(2, 1fr); gap: var(--v1-space-5); }

.ccard { position: relative; text-decoration: none; color: inherit; display: block; }
.ccard__label {
  position: absolute; top: 0; left: var(--v1-space-5); z-index: 3;
  width: var(--nw); height: var(--nh);
  padding-top: 2px;
}
.ccard__lt {
  font-family: var(--v1-font-display);
  font-size: var(--v1-text-xl); color: var(--v1-ink);
  letter-spacing: var(--v1-track-xl); line-height: 1.25;
}
.ccard__ls { font-size: var(--v1-text-sm); color: var(--v1-ink-3); margin-top: 2px; }

.ccard__frame {
  position: relative; overflow: hidden; height: 100%;
  border-radius: var(--v1-radius-notch);
  background: var(--v1-sunken);
  transition: transform var(--v1-dur-short) var(--v1-ease-lift);
  /* 좌상단을 파낸다 — nw × nh 만큼 */
  --r: var(--v1-radius-notch);
  -webkit-mask:
    linear-gradient(#000 0 0) 0 calc(var(--nh) + var(--r)) / 100% calc(100% - var(--nh) - var(--r)) no-repeat,
    linear-gradient(#000 0 0) var(--r) var(--nh) / calc(100% - var(--r)) var(--r) no-repeat,
    radial-gradient(circle var(--r) at 100% 100%, #000 98%, transparent 100%) 0 var(--nh) / var(--r) var(--r) no-repeat,
    linear-gradient(#000 0 0) calc(var(--nw) + var(--r)) 0 / calc(100% - var(--nw) - var(--r)) var(--nh) no-repeat,
    linear-gradient(#000 0 0) var(--nw) var(--r) / var(--r) calc(var(--nh) - var(--r)) no-repeat,
    radial-gradient(circle var(--r) at 100% 100%, #000 98%, transparent 100%) var(--nw) 0 / var(--r) var(--r) no-repeat,
    radial-gradient(circle var(--r) at 0 0, transparent 98%, #000 100%) calc(var(--nw) - var(--r)) calc(var(--nh) - var(--r)) / var(--r) var(--r) no-repeat;
  mask:
    linear-gradient(#000 0 0) 0 calc(var(--nh) + var(--r)) / 100% calc(100% - var(--nh) - var(--r)) no-repeat,
    linear-gradient(#000 0 0) var(--r) var(--nh) / calc(100% - var(--r)) var(--r) no-repeat,
    radial-gradient(circle var(--r) at 100% 100%, #000 98%, transparent 100%) 0 var(--nh) / var(--r) var(--r) no-repeat,
    linear-gradient(#000 0 0) calc(var(--nw) + var(--r)) 0 / calc(100% - var(--nw) - var(--r)) var(--nh) no-repeat,
    linear-gradient(#000 0 0) var(--nw) var(--r) / var(--r) calc(var(--nh) - var(--r)) no-repeat,
    radial-gradient(circle var(--r) at 100% 100%, #000 98%, transparent 100%) var(--nw) 0 / var(--r) var(--r) no-repeat,
    radial-gradient(circle var(--r) at 0 0, transparent 98%, #000 100%) calc(var(--nw) - var(--r)) calc(var(--nh) - var(--r)) / var(--r) var(--r) no-repeat;
}
.ccard { --nw: var(--v1-notch-w); --nh: var(--v1-notch-h); }
/* 호버 코스도가 이 비율로 렌더돼 있다 — 바꾸면 docs/course-proposals/satellite 의 card 판도 다시 만든다 */
/* 2장이 되며 카드 폭이 384 → 588 로 넓어졌다. 높이는 전과 같은 560 을 지킨다 */
.ccard .ccard__frame { height: auto; aspect-ratio: 588 / 560; }

/* 배경 — 실제 대회 사진(2026-08-13 사용자 지시로 draft-05 이미지 사용).
 * image-set 으로 AVIF → WebP → JPEG 순으로 고른다. 카드 종횡비에 맞춰
 * 미리 크롭해 뒀으므로 cover 가 잘라내는 양이 적다. */
.ccard__bg {
  position: absolute; inset: 0;
  background: var(--v1-sunken) center / cover no-repeat;
  transition: transform var(--v1-dur-short) var(--v1-ease-lift);
}
/* 10km·5km 세로 카드 — 같은 결승 사진에서 각 코스 시계가 노치 오른쪽에 오게 잘랐다.
 * 10km 카드에는 5km 시계가, 5km 카드에는 10km 시계가 들어가지 않는다. */
.ccard--10k .ccard__bg {
  background-image: image-set(
    url("/images/course-10k-tall.avif") type("image/avif"),
    url("/images/course-10k-tall.webp") type("image/webp"),
    url("/images/course-10k-tall.jpg")  type("image/jpeg"));
}
.ccard--5k .ccard__bg {
  background-image: image-set(
    url("/images/course-5k-tall.avif") type("image/avif"),
    url("/images/course-5k-tall.webp") type("image/webp"),
    url("/images/course-5k-tall.jpg")  type("image/jpeg"));
}
.ccard__frame::after {
  content: ""; position: absolute; inset: 0; z-index: 1;
  background: linear-gradient(180deg,
    color-mix(in srgb, var(--v1-ink) 8%, transparent) 0%,
    transparent 42%,
    color-mix(in srgb, var(--v1-ink) 52%, transparent) 100%);
}
.ccard:hover .ccard__frame { transform: translateY(-4px); }
.ccard:hover .ccard__bg { transform: scale(1.05); }

/* 호버 — 어두운 덮개 위에 코스만 뜬다(지도 없음). 코스 페이지와 같은 경로·지점·라벨이다.
 * 카드 크기 그대로 렌더한 투명 PNG 라 늘거나 잘리지 않는다. 좌상단 노치와 우하단 화살표
 * 자리에는 코스·라벨을 두지 않았다(docs/course-proposals/satellite — basemap.py card). */
.ccard__route {
  position: absolute; inset: 0; z-index: 2;
  background: color-mix(in srgb, var(--v1-ink) 94%, transparent);
  opacity: 0; pointer-events: none;
  transition: opacity var(--v1-dur-short) var(--v1-ease-lift);
}
.ccard:hover .ccard__route, .ccard:focus-visible .ccard__route { opacity: 1; }
.ccard__route img { display: block; width: 100%; height: 100%; object-fit: contain; }   /* 넓어진 카드에서 세로 코스가 잘리지 않게 */

.ccard__foot {
  position: absolute; left: 0; right: 0; bottom: 0; z-index: 3;
  padding: var(--v1-space-6);
  display: flex; justify-content: flex-end;
}
.ccard__arrow {
  width: var(--v1-arrow); height: var(--v1-arrow);
  border-radius: 50%;
  background: var(--v1-ink);
  display: grid; place-items: center;
  transition: background-color var(--v1-dur-micro) var(--v1-ease-lift),
              transform var(--v1-dur-short) var(--v1-ease-lift);
}
.ccard:hover .ccard__arrow { background: var(--v1-accent); transform: translateX(4px); }
.ccard__arrow svg {
  width: 40%; height: 40%;
  stroke: var(--v1-paper); stroke-width: 2.4; fill: none;
  stroke-linecap: round; stroke-linejoin: round;
}

/* 1100px 아래는 세 카드를 가로로 쌓는다. 세로 카드가 너무 좁아지면(340px 아래)
 * 고정 크기인 노치·화살표가 카드의 큰 몫을 차지해 코스도와 겹친다.
 * 가로로 납작한 카드에는 세로 코스도가 맞지 않아 호버 코스도는 띄우지 않는다 —
 * 코스 페이지에 같은 지도가 있다. */
@media (max-width: 1099px) {
  .cgrid { grid-template-columns: 1fr; }
  .ccard .ccard__frame { aspect-ratio: auto; min-height: var(--v1-ccard-h-sm); }
  .ccard__route { display: none; }
  .ccard--10k .ccard__bg {
    background-image: image-set(
      url("/images/course-10k.avif") type("image/avif"),
      url("/images/course-10k.webp") type("image/webp"),
      url("/images/course-10k.jpg")  type("image/jpeg"));
  }
  .ccard--5k .ccard__bg {
    background-image: image-set(
      url("/images/course-5k.avif") type("image/avif"),
      url("/images/course-5k.webp") type("image/webp"),
      url("/images/course-5k.jpg")  type("image/jpeg"));
  }
}
@media (max-width: 620px) {
  .csec__head { flex-direction: column; align-items: flex-start; }
  .ccard { --nw: var(--v1-notch-w-sm); }
}
/* 터치 기기는 호버가 없다 — 코스맵을 항상 옅게 겹쳐 두지 않고 아예 숨긴다.
 * 상세 페이지에 같은 노선도가 있으므로 정보 손실이 아니다. */
@media (hover: none) {
  .ccard__route { display: none; }
}

/* ══ 헤리티지 밴드 (홈 — 대회 이야기 진입) ═════════════════════════════════
 * draft-05 조판(2026-08-13 지시). 이전 티저는 누런 지면에 초상 한 장이라
 * 무게가 없었다. 배경 사진을 화면 폭으로 깔고 그 위에 문구만 올린다.
 * 초상은 /story 로 옮겼다 — 이야기의 본문이 있는 자리다. */
.heritage { position: relative; overflow: hidden; background: var(--v1-ground-deep); }
.heritage__bg {
  position: absolute; inset: 0;
  background: url("/images/heritage-wide.jpg") center / cover;
  opacity: .5;
}
/* 좌우를 어둡게 눌러 가운데 문구의 대비를 만든다. */
.heritage::after {
  content: ""; position: absolute; inset: 0;
  background: linear-gradient(90deg,
    color-mix(in srgb, var(--v1-ground-deep) 78%, transparent),
    color-mix(in srgb, var(--v1-ground-deep) 42%, transparent) 50%,
    color-mix(in srgb, var(--v1-ground-deep) 78%, transparent));
}
.heritage__in {
  position: relative; z-index: 1;
  max-width: 1100px; margin-inline: auto;
  padding: var(--v1-sec-lead) var(--v1-space-6);
  text-align: center;
}
.heritage__yr {
  font-size: var(--v1-text-sm); font-weight: 700;
  letter-spacing: 0.32em; color: var(--v1-accent-ondark);
}
.heritage__h {
  margin-top: var(--v1-space-4);
  font-family: var(--v1-font-display);
  font-size: var(--v1-text-2xl);
  letter-spacing: var(--v1-track-2xl);
  line-height: 1.55; color: var(--v1-paper);
}
.heritage__p {
  margin-top: var(--v1-space-4);
  color: color-mix(in srgb, var(--v1-paper) 80%, transparent);
}
.heritage__btn {
  display: inline-block; margin-top: var(--v1-space-7);
  background: var(--v1-paper); color: var(--v1-ink);
  text-decoration: none; font-weight: 600;
  padding: var(--v1-space-4) var(--v1-space-8);
  border-radius: var(--v1-radius-sm);
  border: 1px solid transparent;
  transition: background-color var(--v1-dur-micro) var(--v1-ease-lift),
              transform var(--v1-dur-micro) var(--v1-ease-lift);
}
.heritage__btn:hover { background: var(--v1-surface); transform: translateY(-2px); }
@media (max-width: 700px) {
  .heritage__in { padding-block: var(--v1-sec-base); }
  .heritage__h { font-size: var(--v1-text-xl); }
}

/* ══ 4괘 섹션 구분선 ═══════════════════════════════════════════════════════
 * 건☰ 리☲ 감☵ 곤☷ — 태극기의 네 괘.
 * 국가 상징이므로 회전·튕김 같은 가벼운 모션을 주지 않는다. */
/* 지면은 화이트, 괘는 잉크색(2026-08-14 지시).
 * 이전에는 body 의 세피아가 비쳐 누런 띠로 보였다. */
.gwae-band { background: var(--v1-white); }
.gwae {
  display: flex; align-items: center; justify-content: center;
  gap: var(--v1-space-6);
  /* 위아래를 같게 둔다. 구분선은 두 섹션의 경계이지 앞 섹션의 꼬리가 아니다. */
  padding-block: var(--v1-space-8);
}
.gwae__line { height: 1px; flex: 1; max-width: 220px;
  background: linear-gradient(90deg, transparent, color-mix(in srgb, var(--v1-ink) 28%, transparent)); }
.gwae__line:last-child { background: linear-gradient(90deg, color-mix(in srgb, var(--v1-ink) 28%, transparent), transparent); }
.gwae__bar rect { fill: var(--v1-ink); }

/* ══ 홈 본문 — 제목 크기 축소 (2026-08-13 지시) ═══════════════════════════
 * 히어로와 푸터 사이 제목이 48px 이라 본문(17px) 대비 2.8배였다.
 * 히어로 대회명(60px)과도 크기가 붙어 위계가 흐려진다.
 * 세부 페이지의 h1(phead__title)은 그대로 두고 **홈 본문만** 줄인다 —
 * 토큰을 직접 낮추면 세부 페이지 제목까지 같이 작아진다.
 *
 * 실측 변화: 섹션 제목 48→34px · 소제목 32→25px · 리드문 22.4→19px
 *            헤리티지 문구 48→32px · 카드 라벨 32→25px */
.csec, #apply, .heritage {
  --v1-text-2xl: clamp(1.5rem, 1.25rem + 0.9vw, 2.125rem);
  --v1-text-xl:  clamp(1.25rem, 1.1rem + 0.5vw, 1.5625rem);
  --v1-text-lg:  clamp(1.05rem, 1rem + 0.28vw, 1.1875rem);
}
/* 헤리티지 문구는 배경 사진 위에 얹히므로 한 단계 더 낮춘다 —
 * 큰 글씨가 사진을 덮으면 배경이 안 보인다. */
.heritage__h { font-size: clamp(1.375rem, 1.15rem + 0.85vw, 2rem); }

/* ══ 세부 페이지 다듬기 (2026-08-14) ═══════════════════════════════════════
 * 히어로 이미지를 머리에 넣은 뒤 본문이 상대적으로 밋밋해 보였다.
 * 요소마다 지면을 주지 않고 **괘선과 여백**으로만 층을 만든다. */

/* 표 — 흰 지면 위에서 경계가 약했다. 머리행에 지면을 줘서 열을 잡는다. */
main .tbl thead th {
  background: var(--v1-surface);
  border-bottom: 2px solid var(--v1-ink);
}
main .tbl tbody tr:hover { background: color-mix(in srgb, var(--v1-surface) 55%, transparent); }
main .tbl caption {
  text-align: left;
  padding-bottom: var(--v1-space-3);
  color: var(--v1-ink-3);
  font-size: var(--v1-text-sm);
}

/* 제품·자산 사진 — 흰 지면에 흰 배경 사진이라 액자가 사라졌다.
 * 프레임 지면을 한 단계 내려 사진이 얹혀 있음을 보이게 한다. */
.souv__item picture {
  background: var(--v1-surface);
  border-color: var(--v1-border);
}

/* 안내 목록(.notes) — 글머리 선이 본문과 같은 잉크라 묻혔다.
 * 액센트로 바꾸고 들여쓰기를 줘서 목록임이 먼저 읽히게 한다. */
main .notes__i::before { background: var(--v1-accent); }

/* 패널 — 단체 참가 안내처럼 묶어 보여주는 상자.
 * 좌측에 잉크 기둥을 세워 "여기부터 다른 층위"를 표시한다(색 스트라이프 아님). */
main .panel {
  border-left: 3px solid var(--v1-ink);
  padding-left: var(--v1-space-6);
}

/* 페이지 안 탭 — 현재 항목이 눈에 덜 띄었다. 밑줄을 굵게. */
.ptabs a[aria-current="page"] {
  border-bottom-width: 3px;
  font-weight: 700;
}

/* JS 렌더 블록 높이 예약 — 신청 페이지 사이드(2026-08-14 실측).
 * 예약이 없어 렌더 후 본문이 밀렸다(/apply/solo CLS 0.0257/0.0498).
 * courseCompare 1440=372 360=364 · fsideH 1440=45 360=48 */
#courseCompare { min-height: 372px; }
#fsideH { min-height: 45px; }
@media (max-width: 860px) {
  #courseCompare { min-height: 364px; }
  #fsideH { min-height: 48px; }
}

/* ══ 대회 개요 ═════════════════════════════════════════════════════════════
 * 히어로 바로 아래. 좌측 표 + 우측 세로 사진.
 * 표는 <table> 이 아니라 <dl> 이다 — 행/열 교차가 없는 '항목: 값' 목록이므로
 * 정의목록이 의미에 맞고, 모바일에서 한 줄씩 접기도 쉽다. */
/* 지면은 흰색이다. 사진을 빼고 표만 중앙에 둔다(2026-08-19 지시) */
.ovw { padding-block: var(--v1-sec-lead) var(--v1-sec-base); background: var(--v1-white); }
.ovw__in { max-width: 46rem; }
.ovw__list { margin-top: var(--v1-space-6); }
/* 행 — 얇은 괘선으로만 나눈다. 배경 줄무늬를 쓰지 않는다(표가 아니다) */
.ovw__row {
  display: grid;
  grid-template-columns: 7.5rem minmax(0, 1fr);
  gap: var(--v1-space-5);
  padding-block: var(--v1-space-4);
  border-bottom: 1px solid var(--v1-border-soft);
}
.ovw__row:first-child { border-top: 1px solid var(--v1-ink); }
.ovw__k {
  font-family: var(--v1-font-display);
  font-size: var(--v1-text-base);
  color: var(--v1-ink);
}
.ovw__v {
  font-size: var(--v1-text-base);
  color: var(--v1-ink-2);
  line-height: 1.6;
}
/* 미확정 값 — 지어내지 않고 상태를 그대로 보여준다. 색만으로 구분하지 않는다 */
.ovw__v--pending { color: var(--v1-ink-3); font-style: italic; }
.ovw__note { margin-top: var(--v1-space-5); }

.ovw__fig { margin: 0; }
.ovw__fig img {
  width: 100%; height: auto; display: block;
  border: 1px solid var(--v1-border);
}

@media (max-width: 900px) {
  .ovw__row { grid-template-columns: 6rem minmax(0, 1fr); gap: var(--v1-space-4); }
}

/* ══ 개인신청 — 단계형 흐름 ════════════════════════════════════════════════
 * 0 선택 → 1 동의 → 2 본인확인 → 3 상세 → 4 완료 */

/* ── 0 선택 — 두 갈래 ───────────────────────────────────────────────────── */
.apick { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: var(--v1-space-5); }
.apick__b {
  display: block; text-align: left; text-decoration: none;
  padding: var(--v1-space-6);
  background: var(--v1-white);
  border: 1px solid var(--v1-border);
  border-top: 2px solid var(--v1-ink);
  cursor: pointer;
  transition: border-color var(--v1-dur-micro) var(--v1-ease-lift),
              box-shadow var(--v1-dur-micro) var(--v1-ease-lift),
              transform var(--v1-dur-micro) var(--v1-ease-lift);
}
/* 호버 — 색만 바꾸지 않는다(완료조건 9) */
.apick__b:hover {
  border-color: var(--v1-accent);
  box-shadow: var(--v1-shadow-md);
  transform: translateY(-2px);
}
.apick__b:focus-visible { outline: 2px solid var(--v1-accent); outline-offset: 3px; }
.apick__t {
  display: block;
  font-family: var(--v1-font-display);
  font-size: var(--v1-text-lg); color: var(--v1-ink);
}
.apick__d {
  display: block; margin-top: var(--v1-space-2);
  font-size: var(--v1-text-sm); color: var(--v1-ink-3); line-height: 1.6;
}

/* ── 1 동의 — 읽을 상자 ─────────────────────────────────────────────────── */
/* 읽을 상자 — 지면은 **흰색**이다. 누런 판을 만들지 않는다(2026-08-19).
 * 전문이 길어 스크롤이 생기므로 높이를 넉넉히 준다. */
.abox {
  margin-top: var(--v1-space-4);
  padding: var(--v1-space-5) var(--v1-space-6);
  background: var(--v1-white);
  border: 1px solid var(--v1-border);
  font-size: var(--v1-text-sm); color: var(--v1-ink-2); line-height: 1.8;
  max-height: 26rem; overflow-y: auto;
}
.abox__h {
  font-weight: 700; color: var(--v1-ink);
  margin-top: var(--v1-space-5);
}
.abox__h:first-child { margin-top: 0; }
.abox__list { margin-top: var(--v1-space-2); padding-left: var(--v1-space-4); }
.abox__list li {
  position: relative; padding-left: var(--v1-space-4);
  margin-top: var(--v1-space-2);
}
.abox__list li::before {
  content: ""; position: absolute; left: 0; top: 0.72em;
  width: 6px; height: 1px; background: var(--v1-accent);
}

/* ── 라디오 — 성별·내외국인. 서로 배타적인 항목은 라디오로(CLAUDE.md) ──── */
.field--radio { border: 0; padding: 0; margin: 0; }
.radios { display: flex; gap: var(--v1-space-6); margin-top: var(--v1-space-3); }
.radio { display: inline-flex; align-items: center; gap: var(--v1-space-2); cursor: pointer; }
.radio input { width: 18px; height: 18px; accent-color: var(--v1-accent); }
.radio span { font-size: var(--v1-text-base); color: var(--v1-ink-2); }

/* 주소처럼 긴 항목은 두 칸을 쓴다 */
/* 1열이므로 별도 처리가 필요 없다. 마크업 호환을 위해 남긴다. */
.field--wide { grid-column: 1 / -1; }

/* ── 4 완료 — 접수 내용 요약 ───────────────────────────────────────────── */
.adone {
  padding: var(--v1-space-5);
  background: var(--v1-surface);
  border-top: 2px solid var(--v1-ink);
  border-bottom: 1px solid var(--v1-border);
  margin-top: var(--v1-space-5);
}
.adone__h {
  font-family: var(--v1-font-display);
  font-size: var(--v1-text-lg); color: var(--v1-ink);
}
.adone__p { margin-top: var(--v1-space-2); font-size: var(--v1-text-sm); color: var(--v1-ink-2); }

/* 요약 목록 — 개요와 같은 조판을 쓴다. 사이트 안에서 같은 것은 같게 보여야 한다 */
.asum { margin-top: var(--v1-space-4); }
.asum__row {
  display: grid; grid-template-columns: 8rem minmax(0, 1fr);
  gap: var(--v1-space-5);
  padding-block: var(--v1-space-3);
  border-bottom: 1px solid var(--v1-border-soft);
}
.asum__row:first-child { border-top: 1px solid var(--v1-ink); }
/* 확인 화면의 세부 항목 — 본문과 같은 크기(17.4px)로 그려 표가 아니라
 * 본문처럼 커 보였다. 한 단계 낮춰 읽는 덩어리와 구분한다. */
.asum__k { font-size: var(--v1-text-sm); color: var(--v1-ink-3); }
.asum__v { font-size: var(--v1-text-sm); color: var(--v1-ink); }

/* ── 접수 완료 팝업 ──────────────────────────────────────────────────────
 * 결과가 화면 아래쪽에 그려져 스크롤 위치에 따라 안 보인다.
 * 계좌·금액을 한 번 더 보여주고 확인을 누르면 조회 화면으로 보낸다. */
.dlg__back {
  position: fixed; inset: 0; z-index: 1000;
  display: flex; align-items: center; justify-content: center;
  padding: var(--v1-space-5);
  background: rgb(0 0 0 / 45%);
}
.dlg {
  width: min(100%, 30rem);
  max-height: 90vh; overflow-y: auto;
  padding: var(--v1-space-7) var(--v1-space-6);
  background: var(--v1-white);
  border-radius: var(--v1-radius-sm);
}
.dlg__h {
  font-family: var(--v1-font-display);
  font-size: var(--v1-text-lg);
  font-weight: var(--v1-weight-display-bold);
  color: var(--v1-ink);
}
.dlg__sum { margin-top: var(--v1-space-5); }
.dlg__p {
  margin-top: var(--v1-space-5);
  font-size: var(--v1-text-sm); color: var(--v1-ink-3);
  line-height: var(--v1-leading-relaxed);
}
.dlg__act { margin-top: var(--v1-space-6); display: flex; justify-content: flex-end; }

/* ── 접수 개시 팝업 (홈 · js/apply-open.js · 2026-10-27) ─────────────────
 * <dialog> 를 쓴다 — 포커스 가두기·Esc 닫기가 브라우저 기본으로 온다.
 * 접수 전에는 신청 버튼이 잠겨 있고, 시각이 되면 그 자리에서 열린다. */
.apop {
  position: fixed; inset: 0; margin: auto;
  width: min(calc(100% - 2 * var(--v1-space-4)), 30rem);
  height: fit-content;
  border: 0; color: var(--v1-ink);
  padding: var(--v1-space-7) var(--v1-space-6) var(--v1-space-5);
}
.apop::backdrop { background: rgb(0 0 0 / 45%); }
.apop__x {
  position: absolute; top: var(--v1-space-2); right: var(--v1-space-2);
  width: 44px; height: 44px;
  border: 0; background: none; cursor: pointer;
  font-size: 1.6rem; line-height: 1; color: var(--v1-ink-3);
}
.apop__x:hover { color: var(--v1-ink); }
.apop__eye { margin: 0; }
.apop__h { margin: var(--v1-space-2) 0 0; font-size: var(--v1-text-xl); line-height: var(--v1-leading-tight); }
.apop__dl { margin: var(--v1-space-5) 0 0; border-top: 1px solid var(--v1-border-soft); }
.apop__row {
  display: grid; grid-template-columns: 5.5rem minmax(0, 1fr); gap: var(--v1-space-3);
  padding: var(--v1-space-3) 0;
  border-bottom: 1px solid var(--v1-border-soft);
  font-size: var(--v1-text-sm); line-height: var(--v1-lead-tight);
}
.apop__row dt { color: var(--v1-ink-3); }
.apop__row dd { margin: 0; color: var(--v1-ink); font-weight: 600; white-space: pre-line; }
.apop__cd {
  margin: var(--v1-space-5) 0 0;
  font-size: var(--v1-text-sm); color: var(--v1-ink-2);
  font-variant-numeric: tabular-nums;
}
.apop__cd.is-wait {
  padding: var(--v1-space-3) var(--v1-space-4);
  background: var(--v1-sunken);
  text-align: center; font-weight: 600; color: var(--v1-accent);
}
.apop__act { margin-top: var(--v1-space-5); display: grid; grid-template-columns: 1fr 1fr; gap: var(--v1-space-3); }
.apop__btn { justify-content: center; min-height: 48px; }
.apop__btn.is-locked,
.apop__btn.is-locked:hover {
  background: var(--v1-sunken); border-color: var(--v1-border); color: var(--v1-ink-3);
  cursor: not-allowed; transform: none; box-shadow: none;
}
.apop__foot { margin-top: var(--v1-space-4); display: flex; justify-content: space-between; }
.apop__link {
  min-height: 44px; padding: 0 var(--v1-space-1);
  border: 0; background: none; cursor: pointer;
  font-size: var(--v1-text-xs); color: var(--v1-ink-3);
}
.apop__link:hover { color: var(--v1-ink); text-decoration: underline; }

@media (max-width: 700px) {
  .apick { grid-template-columns: minmax(0, 1fr); }
  .asum__row { grid-template-columns: 6.5rem minmax(0, 1fr); gap: var(--v1-space-4); }
  .radios { gap: var(--v1-space-5); }
}

/* ══ 2026-08-19 지시 반영 ═══════════════════════════════════════════════════ */

/* 히어로 글자 — 덮개를 뺐으므로 글자 쪽에서 읽히게 한다.
 * 획 둘레 8방향 1px 지면색 외곽선. 넓게 번지는 후광은 쓰지 않는다. */
/* ⚠️ 히어로 글자에 외곽선·흰 상자를 쓰지 않는다(2026-08-19 지시).
 * 가독성 때문에 넣었던 것이지만 사진 위에서 테두리와 상자가 그대로 드러났다.
 * → 장치를 얹는 대신 **글자색 자체를 지면에 맞춘다.**
 *   수채화(밝은 그림) = 어두운 잉크 / 실사진(어두운 그림) = 흰 글자.
 *   .hero 에 .is-photo 가 붙는지로 갈린다(app.js 가 슬라이드 전환 때 토글). */

/* 실사진 슬라이드 — 글자를 전부 흰색으로 */
.hero.is-photo .hero__stack .eyebrow,
.hero.is-photo .hero__title,
.hero.is-photo .hero__slogan,
.hero.is-photo .hero__meta,
.hero.is-photo .hero__meta .muted {
  color: var(--v1-on-image);
}
/* 슬라이드 전환 중 — 글자·버튼 색을 이미지 교차(.hero__slide)와 같은 시간·곡선으로.
 * app.js 가 전환 동안만 .is-fading 을 붙인다(평소에는 호버가 느려지지 않게). */
.hero.is-fading .hero__stack .eyebrow,
.hero.is-fading .hero__title,
.hero.is-fading .hero__slogan,
.hero.is-fading .hero__meta,
.hero.is-fading .hero__meta .muted,
.hero.is-fading .hero__cta .btn {
  transition:
    color var(--v1-dur-epic) var(--v1-ease-ink),
    background-color var(--v1-dur-epic) var(--v1-ease-ink),
    border-color var(--v1-dur-epic) var(--v1-ease-ink);
}
/* ⚠️ 글자에 어떤 효과도 얹지 않는다(2026-08-19 지시).
 * 외곽선 → 테두리로 보였고, 뒤에 깐 그늘 → 사진을 가로지르는 띠로 보였고,
 * 글자에 준 그림자 → 글자 주변에 번짐이 남았다. 셋 다 뺐다.
 * 흰 글자만으로 간다. 색 대비 하나로 읽히게 두는 것이 이 사진에서 가장 깨끗하다. */
.hero.is-photo .hero__stack,
.hero.is-photo .hero__meta { text-shadow: none; }
/* 사진·수채화 배경 양쪽에서 읽혀야 한다.
 *
 * 투명 배경 + 얇은 흰 선으로 뒀더니, 밝은 하늘에서는 선이 사라지고
 * 사람이 많은 사진에서는 글자가 배경에 묻혔다. 배경을 깔아 글자와
 * 배경 사이 대비를 만든다 — 배경 그림이 무엇이든 읽히는 유일한 방법이다. */
.hero.is-photo .hero__cta .btn--ghost {
  color: var(--v1-ink);
  border-color: rgb(255 255 255 / 92%);
  background: rgb(255 255 255 / 92%);
  font-weight: 700;
}
.hero.is-photo .hero__cta .btn--ghost:hover {
  border-color: #fff;
  background: #fff;
}
/* 기본 버튼도 사진 위에서는 더 진하게 — 반투명이면 뒤 그림이 비쳐 글자를 흩뜨린다 */
.hero.is-photo .hero__cta .btn:not(.btn--ghost) {
  background: rgb(26 22 20 / 96%);
  border-color: rgb(26 22 20 / 96%);
  font-weight: 700;
}

/* 히어로 문구를 굵게. 배경 그림 위에 얹히는 글자라 평소 굵기로는 흩어져 보인다. */
.hero__slogan { font-weight: var(--v1-weight-display-bold); }
.hero__meta { font-weight: 600; }
.hero__meta .muted { font-weight: 600; }

/* 섹션 제목을 굵게 — '대회 개요' '코스 안내' 처럼 갈래를 여는 제목이다.
 * 명조체는 굵기를 올려도 획이 가늘어 보이므로 한 단계 더 준다. */
.ovw h2, .csec h2, .sponsors h2, .sec > .wrap > .sec__head h2 { font-weight: 700; }
.ovw__k { font-weight: 700; }

/* ── 네비 — 세부 메뉴 줄을 대분류와 같은 열에 맞춘다 ──────────────────────
 * 원본 사이트처럼 메가판의 각 열이 자기 대분류 **바로 아래**에 오게 한다.
 * 이전에는 판 전체를 4등분해서 열과 대분류의 x 위치가 어긋났다. */
/* 대분류 4개뿐이라 조금 키워도 줄이 넘치지 않는다.
 * 굵기는 500 → 600 — 700 은 로고와 다투고 메뉴가 제목처럼 읽힌다. */
.nav__top { font-size: var(--v1-text-base); font-weight: 600; }
/* 메뉴는 화면 정중앙 절대배치라 폭이 늘면 좌우로 함께 자란다.
 * 1025~1100px 에서 120px 간격을 쓰면 오른쪽 CTA 를 파고든다.
 * 넓은 화면에서만 최대 간격을 준다. */
.nav__list { gap: var(--v1-space-6); }
@media (min-width: 1120px) { .nav__list { gap: var(--v1-space-8); } }
@media (min-width: 1200px) { .nav__list { gap: var(--v1-space-9); } }
@media (min-width: 1400px) { .nav__list { gap: var(--v1-space-10); } }
.mega__in {
  /* 열 위치는 shell.js alignMega 가 대분류 x 좌표에 맞춰 잡는다.
   * 여기서는 흐름만 정하고 간격을 0 으로 둔다 — gap 이 있으면 계산이 어긋난다.
   *
   * 판 자체가 메뉴 구간만 덮으므로(alignMega) .wrap 의 좌우 여백·최대폭을
   * 여기서 푼다. 그대로 두면 판 안에서 한 번 더 들여써 열이 어긋난다. */
  max-width: none;
  margin-inline: 0;
  padding-inline: 0;
  display: flex;
  gap: 0;
  justify-content: flex-start;
  padding-block: var(--v1-space-6) var(--v1-space-7);
}
/* 열 안의 항목을 가운데로 모은다. 열 폭은 가장 긴 항목에 맞춰 늘어나고,
 * 그 열의 중심을 shell.js alignMega 가 대분류 글자 중심에 맞춘다.
 *
 * min-width 를 두지 않는다. 6rem 을 걸면 '하프코스'(가장 긴 항목이 96px
 * 미만)처럼 짧은 열이 실제 글자보다 넓어지고, 1100px 안팎에서 그 여분이
 * 앞 열과 부딪쳐 중심을 못 맞춘다. 폭은 글자가 정하게 둔다. */
.mega__col { flex: 0 0 auto; text-align: center; }
/* 제목 줄은 대분류가 이미 말하고 있다 — 판 안에서 반복하지 않는다 */
.mega__h { display: none; }
.mega__sub { padding-inline: 0; }
.mega__sub:hover {
  background: none;
  text-decoration: underline;
  text-decoration-color: var(--v1-accent);
  text-underline-offset: 3px;
}

/* CTA 를 더 우측으로 */
.nav__in { gap: var(--v1-space-6); }
.nav__links { margin-right: auto; margin-left: var(--v1-space-8); }

/* 단계 제목 크기는 아래 '제목 크기' 절에서 정한다(.astep .h2) */

/* 본인확인처럼 항목이 적은 폼은 한 열로 좁게 — 두 열로 벌리면 허전하다 */
.form__grid--narrow { grid-template-columns: minmax(0, 1fr); max-width: 26rem; }

/* ── 단체 구성원 표 ────────────────────────────────────────────────────────
 * 한 줄이 구성원 한 명이다. "+ 구성원 추가"로 입력 줄이 하나씩 붙고,
 * 저장하면 그 줄이 목록 줄로 바뀐다. 표를 쓰지 않은 이유는
 * 입력 줄과 저장된 줄이 같은 자리에서 오가야 하기 때문이다. */
.mtable { display: grid; gap: var(--v1-space-2); }
/* 세 가지 줄이 같은 자리에 오간다 — 머리글 · 저장된 줄 · 입력 줄.
 * 폭을 1fr 로 똑같이 나누면 '남/여' 한 글자 칸과 휴대폰 칸이 같은 폭이 되어
 * 휴대폰이 잘린다(010-2705-2367 이 '010-270-52' 로 보였다).
 * 항목마다 필요한 만큼 준다. 머리글과 저장 줄의 칸 수·폭을 같게 맞춰야
 * 제목과 값이 세로로 이어진다. */
.mrow {
  display: grid;
  /* 번호 · 이름 · 생년월일 · 성별 · 휴대폰 · 종목 · 참가비 · 입금 · 버튼2 */
  /* 마지막 두 칸은 폭을 고정한다. auto 로 두면 머리글(빈 칸 0px)과
   * 저장 줄(버튼 48px)의 폭이 달라져, 그 차이가 앞쪽 fr 칸으로 번져
   * 제목과 값이 최대 97px 까지 어긋났다. */
  grid-template-columns:
    2.5rem minmax(0, 1.1fr) minmax(0, 1.1fr) 3rem minmax(8.5rem, 1.4fr)
    minmax(0, 1fr) minmax(0, 1fr) minmax(0, 1fr) 3.6rem 3.6rem;
  gap: var(--v1-space-2);
  align-items: center;
  padding: var(--v1-space-2) 0;
  border-bottom: 1px solid var(--v1-border);
}
/* 입력 줄은 번호 칸이 없고, 받는 항목도 다르다 —
 * 이름 · 생년월일 · 성별 · 국적 · 휴대폰 · 종목 · 사이즈 + 버튼2 */
.mrow:not(.mrow--saved):not(.mrow--head) {
  grid-template-columns:
    minmax(0, 1.1fr) minmax(7rem, 1.1fr) 4.5rem 5.5rem minmax(9.5rem, 1.3fr)
    minmax(0, 1fr) minmax(0, 1fr) auto auto;
}
.mrow--head {
  border-bottom: 2px solid var(--v1-ink);
  font-size: var(--v1-text-xs);
  color: var(--v1-ink-3);
  font-weight: 600;
}
.mrow__c { min-width: 0; font-size: var(--v1-text-sm); }
.mrow__n { font-size: var(--v1-text-sm); color: var(--v1-ink-3); }
.mrow__b { padding-inline: var(--v1-space-3); font-size: var(--v1-text-xs); }
.mrow__err { grid-column: 1 / -1; margin: 0; }

@media (max-width: 900px) {
  /* 좁은 화면에서는 가로로 늘어놓을 수 없다. 한 명당 한 덩어리로 쌓는다. */
  .mrow, .mrow:not(.mrow--saved):not(.mrow--head) {
    grid-template-columns: 1fr 1fr;
    padding: var(--v1-space-3) 0;
  }
  .mrow--head { display: none; }
}

/* ── 동의 블록 ─────────────────────────────────────────────────────────────
 * 참고 사이트(seoulhalfrun.kr) 구성: 제목 → 흰 스크롤 상자(전문) →
 * 그 아래 체크박스 한 줄 → 맨 끝에 "모두 동의합니다".
 *
 * 전문을 접지 않고 그대로 보여준다. 무엇에 동의하는지 열어 보지 않아도
 * 알 수 있어야 한다. 상자는 고정 높이로 두고 안에서만 스크롤한다 —
 * 페이지가 동의문으로 끝없이 길어지면 아래 입력칸을 못 찾는다. */
.agree { margin-top: var(--v1-space-7); }
.agree__h {
  font-size: var(--v1-text-base);
  font-weight: 700;
  margin-bottom: var(--v1-space-3);
}
.agree__body {
  /* 폭이 넓어져 같은 높이에 더 많은 줄이 들어간다. 상자도 조금 키운다 —
   * 다섯 줄만 보이면 무슨 내용인지 가늠이 안 되고 스크롤만 길어진다. */
  height: 24rem;
  overflow-y: auto;
  background: var(--v1-white);
  border: 1px solid var(--v1-border);
  padding: var(--v1-space-5) var(--v1-space-6);
  font-size: var(--v1-text-sm);
  line-height: 1.75;
  color: var(--v1-ink-2);
}
.agree__body:focus-visible { outline: 2px solid var(--v1-accent); outline-offset: 2px; }
.agree__body p { margin: 0 0 var(--v1-space-2); }
.agree__body p:last-child { margin-bottom: 0; }

.agree__check {
  display: flex;
  align-items: center;
  gap: var(--v1-space-2);
  margin-top: var(--v1-space-3);
  font-size: var(--v1-text-sm);
}
.agree__check input { flex: 0 0 auto; width: 1.05rem; height: 1.05rem; }
.agree__check label { cursor: pointer; }
.agree__check strong { color: var(--v1-accent); font-weight: 700; }

/* 맨 끝 — 나머지와 구분되게 위에 선을 긋는다 */
.agree__all {
  display: flex;
  align-items: center;
  gap: var(--v1-space-2);
  margin-top: var(--v1-space-7);
  padding-top: var(--v1-space-5);
  border-top: 1px solid var(--v1-border);
  font-size: var(--v1-text-base);
  font-weight: 700;
}
.agree__all input { flex: 0 0 auto; width: 1.15rem; height: 1.15rem; }
.agree__all label { cursor: pointer; }

@media (max-width: 700px) {
  .agree__body { height: 15rem; padding: var(--v1-space-4); }
}


/* ══ 화면 정리 (2026-08-19) ═══════════════════════════════════════════════ */

/* 1) 네비 — 메뉴를 가운데로.
 * 로고와 CTA 를 양끝에 두고 메뉴가 정확히 화면 중앙에 오게 한다.
 * 이전에는 로고 바로 옆에 붙어 왼쪽으로 쏠려 있었다. */
.nav__links {
  position: absolute;
  left: 50%;
  transform: translateX(-50%);
  margin: 0;
}
.nav__in { position: relative; }

/* 9) 입력칸을 흰색으로. --v1-paper 는 세피아라 누렇게 읽힌다.
 * 참고 사이트처럼 흰 바탕 + 옅은 테두리로 둔다. */
.field__in,
select.field__in,
textarea.field__in {
  background: var(--v1-white);
}


/* 입력만 하는 단계(2·3)에는 읽을 글이 없다. 제목만 62rem 이면 폼(34rem)과
 * 시작선이 어긋나 제목이 왼쪽으로 삐져나온다.
 * 동의 상자가 없는 단계에서는 제목·안내도 폼 폭에 맞춘다.
 *
 * 다만 요약표(.asum)가 있는 완료 단계는 표가 62rem 이므로 제외한다 —
 * 제목만 좁히면 표 안쪽으로 들어가 가운데 뜬 것처럼 보인다.
 *
 * 구성원 표(.mtable)가 있는 단체신청 3단계도 같은 이유로 제외한다.
 * 표는 지면 전폭(62rem)인데 「구성원 추가」 제목만 34rem 으로 좁혀
 * 가운데 정렬되니, 표는 왼쪽 끝에서 시작하고 제목은 화면 한가운데
 * 떠 있어 둘이 한 묶음으로 읽히지 않았다. 제목·안내를 표와 같은 왼쪽
 * 선에 세운다. */
.astep:not(:has(.agree)):not(:has(.asum)):not(:has(.mtable)) > h2,
.astep:not(:has(.agree)):not(:has(.asum)):not(:has(.mtable)) > .lede,
.astep:not(:has(.agree)):not(:has(.asum)):not(:has(.mtable)) > .small,
.astep:not(:has(.agree)):not(:has(.asum)):not(:has(.mtable)) > .h3 {
  max-width: 34rem;
}

/* 8) 폼 버튼을 가운데로. 왼쪽 정렬이면 긴 폼에서 시선이 끊긴다.
 * 입력칸이 1열(34rem)이 되면서 버튼만 화면 기준 중앙에 있으면 폼과 어긋난다.
 * 폼과 같은 폭을 잡고 그 안에서 가운데로 둔다. */
.form__act {
  display: flex;
  justify-content: center;
  gap: var(--v1-space-3);
  flex-wrap: wrap;
  width: 100%;
  max-width: 34rem;
  margin-inline: auto;
}

/* 단계형 신청 화면은 한 단(段)으로 세운다. 다만 폭은 두 갈래다.
 *
 *   읽는 글(동의 전문·유의사항·요약)  넓게 — 62rem
 *   입력하는 칸(폼·버튼)              좁게 — 34rem
 *
 * 긴 글을 입력칸 폭에 맞추면 줄이 잘게 끊겨 읽기 힘들다. 반대로 입력칸을
 * 글 폭에 맞추면 이름 한 칸이 화면을 가로지른다. 참고 사이트도 동의문은
 * 넓게, 입력칸은 좁게 쓴다.
 *
 * 두 갈래가 같은 왼쪽 선에서 시작하지는 않지만, 각자 가운데 정렬이라
 * 중심선이 같아 한 덩어리로 읽힌다. */
.astep > h2,
.astep > .lede,
.astep > .adone,
.astep > #consentList,
.astep > .agree,
.astep > .abox,
.astep > .asum,
.astep > .h3,
.astep > .small,
.astep > #applyResult,
.astep > .mtable,
/* 구성원 관리 묶음. 안에 표(.mtable)가 들어 있어 직계 자식이 아니므로
 * 위 .astep > .mtable 규칙이 닿지 않았다 — 표만 지면 전폭(1200px)으로
 * 퍼져 제목(62rem)보다 왼쪽에서 시작했다. 묶음째로 폭을 맞춘다. */
.astep > #teamPanel,
.astep > .field__err {
  max-width: 62rem;
  margin-inline: auto;
}

/* 조회 결과 화면(cstep 11)만 지면 폭을 잡는다. 다른 단계는 폼(720px)이
 * 스스로 가운데를 잡으므로 건드리지 않는다.
 *
 * 표(.asum)를 wrap 전폭으로 두면 「접수번호」와 값 사이가 화면 하나
 * 거리로 벌어져 어느 값이 어느 항목인지 눈으로 이어지지 않는다.
 * 신청 화면의 확인 단계(.astep)와 같은 62rem 으로 맞춘다 —
 * 사이트 안에서 같은 것은 같게 보여야 한다.
 *
 * 높이는 제한하지 않는다. 상자에 가두면(.abox 처럼) 여러 건을 조회했을 때
 * 페이지 스크롤과 상자 스크롤이 겹쳐 아래 내역을 못 찾는다. */
.cstep[data-cstep="11"] > h2,
.cstep[data-cstep="11"] > .lede,
.cstep[data-cstep="11"] > #checkResult,
.cstep[data-cstep="211"] > h2,
.cstep[data-cstep="211"] > .lede,
.cstep[data-cstep="211"] > #editResult {
  max-width: 62rem;
  margin-inline: auto;
}

/* 수정 화면의 카드는 .abox 의 높이 제한을 쓰지 않는다.
 * .abox 는 동의 전문처럼 '읽는' 상자라 26rem 에서 잘리는데, 여기서는
 * 저장 버튼이 그 안에 갇혀 화면에 안 보인다. */
#editResult .abox {
  max-height: none;
  overflow-y: visible;
}
/* 카드 안에서는 가운데로 몰지 않는다. .form__grid 는 넓은 화면에서
 * 한쪽 쏠림을 막으려 margin-inline:auto 로 가운데 정렬하는데, 이미 폭이
 * 정해진 카드 안에서는 그 여백이 제목과 칸의 시작선을 어긋나게 만든다.
 * 폼을 1열로 두는 것은 사이트 전체 규칙이라 그대로 둔다. */
#editResult .form__grid {
  margin-inline: 0;
}

/* 제목을 굵게. 원래는 "명조는 굵게 해도 자폭이 안 늘어 위계를 크기로 만든다"
 * 는 판단이었는데, 그 뒤 제목 크기를 두 단계 낮추면서 크기만으로는 위계가
 * 서지 않게 됐다. 작아진 만큼 굵기로 받쳐 준다. */
.display,
.h2,
.h3,
.phead__title,
.astep > h2,
.cstep > h2,
.agree__h {
  font-weight: var(--v1-weight-display-bold);
}

/* 2) 제목 크기 — 화면에서 과하게 크던 것들을 낮춘다.
 * 명조체는 같은 크기라도 획이 굵어 더 커 보인다.
 * 폼 화면의 제목은 내용을 읽는 데 방해가 되지 않을 만큼만 있으면 된다. */
/* lg(최대 22.4px)는 본문 17.4px 과 차이가 작아 제목으로 안 읽혔다.
 * xl 로 한 단계 올린다. */
.astep .h2,
.cstep .h2 { font-size: var(--v1-text-xl); }
.phead__title { font-size: var(--v1-text-xl); }
.sec .h3 { font-size: var(--v1-text-base); }
.agree__h { font-size: var(--v1-text-sm); }
/* 폼 위 안내 문장도 한 단계 낮춘다 */
.astep .lede { font-size: var(--v1-text-sm); }


/* 주소 찾기 — 우편번호 칸 + 버튼을 한 줄에, 아래로 주소·상세주소 */
.addr__find { display: flex; gap: var(--v1-space-2); }
.addr__find .field__in { flex: 0 0 10rem; }
/* 우편번호 칸과 찾기 버튼을 한 줄에 둔다. 이 규칙이 admin.css 에만 있어
 * 공개 화면에서는 버튼이 칸 아래로 떨어져 있었다. */
.addr__row { display: flex; gap: var(--v1-space-2); align-items: center; }
.addr__row .field__in { flex: 1 1 auto; min-width: 0; }
.addr__btn { flex: 0 0 auto; white-space: nowrap; }
.addr__line { margin-top: var(--v1-space-2); }
/* 읽기 전용 칸은 눌러도 커서가 안 뜬다 — 찾기로만 채운다는 뜻이 보여야 한다 */
.field__in[readonly] { background: var(--v1-sunken, #f6f6f4); cursor: default; }

/* 입력칸 글씨 크기 — 기본이 과했다 */
.field__in, select.field__in, textarea.field__in { font-size: var(--v1-text-sm); }
/* placeholder 는 회색이어야 한다. 검정이면 이미 입력된 값처럼 보인다.
 * 앞서 정의된 규칙을 덮어야 하므로 선택자를 더 구체적으로 쓴다. */
input.field__in::placeholder,
textarea.field__in::placeholder { color: var(--v1-ink-3); opacity: 0.75; }

/* 동의 항목은 서버에서 온다. 도착 전 빈 화면을 두면 "왜 아무것도 없지" 가 된다. */
.agree__wait { color: var(--v1-ink-3); font-size: var(--v1-text-sm); padding: var(--v1-space-5) 0; }

/* 참가 부문 — 네모 표시 + 라벨이 옆에 오는 형태.
 * 버튼 전체를 칠하면 무엇이 선택인지보다 색이 먼저 읽힌다.
 * 라디오라서 하나만 켜진다(체크박스로 두면 둘 다 켜져 모순이 생긴다). */
.picks { display: flex; flex-wrap: wrap; gap: var(--v1-space-6); align-items: center; }
.pick {
  display: inline-flex; align-items: center; gap: var(--v1-space-2);
  cursor: pointer;
}
.pick input { position: absolute; opacity: 0; width: 0; height: 0; }

/* 네모 표시 — 켜지면 검게 차고 흰 체크가 뜬다 */
.pick .pick__box {
  flex: 0 0 auto;
  width: 1.5rem; height: 1.5rem;
  border: 1px solid var(--v1-border);
  border-radius: var(--v1-radius-sm);
  background: var(--v1-white);
  display: grid; place-items: center;
  transition: background-color var(--v1-dur-micro) var(--v1-ease-lift),
              border-color var(--v1-dur-micro) var(--v1-ease-lift);
}
.pick .pick__box::after {
  content: "";
  width: 0.55rem; height: 0.3rem;
  border-left: 2px solid var(--v1-white);
  border-bottom: 2px solid var(--v1-white);
  transform: rotate(-45deg) translateY(-1px);
  opacity: 0;
  transition: opacity var(--v1-dur-micro) var(--v1-ease-lift);
}
.pick input:checked + .pick__box {
  background: var(--v1-ink);
  border-color: var(--v1-ink);
}
.pick input:checked + .pick__box::after { opacity: 1; }
.pick input:hover + .pick__box { border-color: var(--v1-ink-3); }
.pick input:focus-visible + .pick__box { outline: 2px solid var(--v1-accent); outline-offset: 2px; }

.pick .pick__t { font-size: var(--v1-text-sm); font-weight: 600; }

/* 완료 화면 — 소제목이 가운데로 떠서 아래 표와 어긋나 보였다.
 * 표(.asum)는 62rem 폭이므로 그 위 제목도 같은 폭·같은 선에서 시작해야
 * 한 묶음으로 읽힌다. 제목만 좁혀 두면 표 안쪽으로 들어가 붕 뜬다. */
.astep > .h3.sub {
  max-width: 62rem;
  margin-inline: auto;
  text-align: left;
  margin-top: var(--v1-space-8);
  margin-bottom: var(--v1-space-2);
}
.astep > .adone { text-align: left; }

/* 마지막 버튼 줄은 위 내용과 떨어뜨린다. 붙어 있으면 표의 일부처럼 보인다. */
.form__act--done {
  margin-top: var(--v1-space-9);
  padding-top: var(--v1-space-6);
  border-top: 1px solid var(--v1-border);
  padding-bottom: var(--v1-space-7);
}

/* ── 대회사진 갤러리 ─────────────────────────────────────────────────────
 * 담당자가 올리는 사진은 비율이 제각각이다. 격자를 맞추려고 잘라 보여주되
 * 원본은 그대로 두므로 나중에 라이트박스를 붙여도 손해가 없다. */
/* 원본 대회사진 화면처럼 3열이다. auto-fill + 260px 로 두니 1440px 에서
 * 4열이 되어 사진이 작아졌다 — 현장 사진은 인물이 작게 찍혀 크게 봐야 한다.
 * 좁은 화면에서는 2열 → 1열로 줄인다. */
.gal {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: var(--v1-space-6) var(--v1-space-5);
}
@media (max-width: 900px) { .gal { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
@media (max-width: 560px) { .gal { grid-template-columns: minmax(0, 1fr); } }

.gal__i { margin: 0; }

.gal__img {
  display: block;
  width: 100%;
  aspect-ratio: 3 / 2;
  object-fit: cover;
  border-radius: var(--v1-radius-sm);
  background: var(--v1-surface);
}

/* 격자 사진은 버튼이다 — 눌러서 크게 본다.
 * 버튼 기본 모양(테두리·배경·안쪽 여백)을 지운다. */
.gal__b {
  display: block; width: 100%;
  padding: 0; border: 0; background: none; cursor: zoom-in;
  border-radius: var(--v1-radius-sm); overflow: hidden;
}
.gal__b:focus-visible { outline: 2px solid var(--v1-accent); outline-offset: 3px; }
.gal__b img { transition: transform var(--v1-dur-short) var(--v1-ease-lift); }
.gal__b:hover img { transform: scale(1.03); }

/* ── 사진 크게 보기 ────────────────────────────────────────────────────── */
/* 스티키 네비(z-index 100)보다 위에 와야 한다. 아래로 두면 사진 위로
 * 네비가 떠서 어두워진 화면에 메뉴만 밝게 남는다. */
.lb {
  position: fixed; inset: 0; z-index: 2000;
  display: flex; align-items: center; justify-content: center;
  gap: var(--v1-space-3);
  padding: var(--v1-space-5);
  background: rgb(0 0 0 / 88%);
}
.lb__in {
  /* 세로로 쌓되 사진이 남는 높이를 다 쓰게 한다. 설명이 사진과 겹치지
   * 않도록 둘 다 흐름 안에 두는 것이 요점이다(absolute 를 쓰지 않는다). */
  display: flex; flex-direction: column; align-items: center;
  gap: var(--v1-space-4);
  min-width: 0;
  max-width: min(100%, 1100px);
  max-height: 100%;
}
.lb__img {
  /* 원본 비율 그대로. 격자에서는 3:2 로 잘라 보여 준다.
   * min-height:0 이 없으면 flex 안에서 사진이 안 줄어들어 설명을 밀어낸다. */
  min-height: 0;
  max-width: 100%; max-height: 78vh;
  width: auto; height: auto;
  object-fit: contain;
  border-radius: var(--v1-radius-sm);
  background: rgb(255 255 255 / 6%);
}
.lb__cap {
  margin: 0; text-align: center;
  color: rgb(255 255 255 / 88%);
  font-size: var(--v1-text-sm);
  line-height: var(--v1-leading-body);
}
.lb__x {
  position: absolute; top: var(--v1-space-4); right: var(--v1-space-4);
  width: 2.75rem; height: 2.75rem;
  display: grid; place-items: center;
  border: 0; border-radius: 50%;
  background: rgb(255 255 255 / 12%);
  color: #fff; font-size: 1.1rem; cursor: pointer;
}
.lb__nav {
  flex: 0 0 auto;
  width: 2.75rem; height: 2.75rem;
  display: grid; place-items: center;
  border: 0; border-radius: 50%;
  background: rgb(255 255 255 / 12%);
  color: #fff; font-size: 1.75rem; line-height: 1; cursor: pointer;
}
.lb__x:hover, .lb__nav:hover { background: rgb(255 255 255 / 22%); }
.lb__x:focus-visible, .lb__nav:focus-visible { outline: 2px solid #fff; outline-offset: 2px; }
.lb__nav[hidden] { display: none; }

@media (max-width: 620px) {
  /* 좁은 화면에서는 화살표가 사진을 가린다 — 아래로 내린다 */
  .lb { flex-wrap: wrap; padding: var(--v1-space-4); }
  .lb__in { order: -1; width: 100%; }
  .lb__img { max-height: 68vh; }
}

.gal__cap {
  margin-top: var(--v1-space-3);
  font-size: var(--v1-text-sm);
  color: var(--v1-ink-2);
  line-height: 1.6;
  text-align: center;   /* 사진 아래 가운데 — 원본과 같다 */
}


/* ══ 조판 통일 (2026-08-21) ════════════════════════════════════════════════
 * 실측 결과 같은 위계의 제목이 페이지마다 다른 크기로 나왔다.
 *
 *   홈  「대회 개요」 48px  vs 「코스 안내」 33px   — 나란히 놓인 두 섹션이다
 *   /course/half 「지나는 자리」 48px  vs  /about/overview 「대회 개요」 17.4px
 *   /community/notice 「공지사항」 48px  vs  /apply/guide 소제목 17.4px
 *
 * 원인은 두 가지였다.
 *  (1) 2026-08-13 에 홈 제목을 줄이면서 `.csec, #apply, .heritage` 안에서만
 *      토큰(--v1-text-2xl 등)을 재정의했다. 같은 홈에 있는 `.ovw` 가 빠져
 *      한 화면 안에서 48 / 33 두 크기가 공존했다.
 *  (2) 세부 페이지는 마크업이 `<h2 class="h3">` 형태라 실제 위계(섹션 제목)와
 *      클래스(.h3)가 어긋나 있었다. 그래서 섹션 제목이 본문(17.4px)과 같아졌다.
 *
 * 해법: 크기를 새로 만들지 않는다. tokens.v1.css 의 기존 단계에만 맞춘다.
 *   페이지 제목(h1)      --v1-text-2xl   32px   (.phead__title — 기존 유지)
 *   섹션 제목            --v1-text-xl    25px
 *   소제목               --v1-text-lg    19px
 *   본문 · 리드문        --v1-text-base  17.4px
 *
 * ⚠️ .astep / .cstep(폼 단계)과 .phead__title 은 최근에 따로 맞춘 값이라
 *    건드리지 않는다. 위 표에서 이미 서로 어긋나지 않는다. */

/* 홈 — .ovw 를 축소 대상에 넣어 「대회 개요」와 「코스 안내」를 같게 만든다.
 * 2936줄의 `.csec, #apply, .heritage` 와 같은 값을 쓴다. */
.ovw {
  --v1-text-2xl: clamp(1.5rem, 1.25rem + 0.9vw, 2.125rem);
  --v1-text-xl:  clamp(1.25rem, 1.1rem + 0.5vw, 1.5625rem);
  --v1-text-lg:  clamp(1.05rem, 1rem + 0.28vw, 1.1875rem);
}

/* 세부 페이지의 섹션 제목 — 마크업이 `<h2 class="h3">` 여도 섹션 제목이면
 * 섹션 제목 크기로 보여야 한다. 클래스가 아니라 **자리**로 크기를 정한다.
 * (main > .sec > .wrap 의 직계 제목 = 그 섹션의 머리)
 *
 * lg(22.4px)를 쓴다. xl 이 아니다 —
 * .phead__title 이 3466줄에서 xl 로 고정돼 있어(1440px 에서 32px) 섹션 제목에
 * xl 을 주면 페이지 제목과 **정확히 같은 크기**가 된다. 실측으로 확인했다:
 * /about/overview 에서 「대회요강」(h1)과 「대회개요」(섹션)가 둘 다 32px 이 됐다.
 * 페이지 제목보다 한 단계 아래여야 페이지 안에서 위아래가 읽힌다.
 *   h1 32px  >  섹션 제목 22.4px  >  본문 17.4px */
main > .sec > .wrap > .h2,
main > .sec > .wrap > .h3,
main > .sec > .wrap > .sec__head .h2,
main > .sec > .wrap > .sec__head .h3 {
  font-size: var(--v1-text-lg);
}

/* 섹션 안쪽 소제목은 본문 크기 + 굵기로만 세운다. 섹션 제목(lg) 아래로 한 단계
 * 더 내려갈 자리가 스케일에 없다 — base 와 lg 사이가 비어 있어서, 크기를 더
 * 쪼개는 대신 굵기로 가른다. */
main > .sec > .wrap .prose > .h3,
main > .sec > .wrap > .panel > .h3 {
  font-size: var(--v1-text-base);
}

/* 리드문 — .lede 는 22.4px(lg 최대) 인데 세부 페이지 본문이 17.4px 이라
 * 리드문만 혼자 떠 보였다. 페이지 머리(.phead__lede)는 제목을 받쳐야 하므로
 * lg 를 유지하고, 본문 중간에 끼는 리드문만 본문 크기로 내린다. */
main > .sec > .wrap > .lede,
main > .sec > .wrap > .sec__head > .lede {
  font-size: var(--v1-text-base);
  line-height: var(--v1-lead-base);
}

/* 정렬 — 섹션 제목·본문은 전부 왼쪽이다.
 * .heritage__h 만 가운데였는데(사진 위 문구) 그건 배경 이미지 위 카피라
 * 의도된 것이므로 둔다. 그 외 가운데 정렬이 섞여 들어오지 않게 못을 박는다. */
main > .sec > .wrap > .h2,
main > .sec > .wrap > .h3,
main > .sec > .wrap > .lede,
main > .sec > .wrap > p {
  text-align: left;
}


/* ══ 코스 세부 페이지 — 지면 흰색 (2026-08-21 지시) ═══════════════════════
 * /course/half · /course/10k · /course/5k 의 「지나는 자리」 절이
 * .sec--ground 라 세피아(--v1-paper #FBF6E9)로 깔렸다. 코스 지도·경유지
 * 사진이 얹히는 자리인데 누런 지면이 사진의 흰 여백과 부딪혀 얼룩져 보였다.
 *
 * .sec--ground 자체는 건드리지 않는다 — 다른 페이지에서 지면을 바꾸는
 * 용도로 쓰이고 있고, 여기서 토큰을 고치면 그쪽까지 흰색이 된다.
 * 코스 페이지에만 있는 .ctex 를 기준으로 이 페이지들만 집어낸다. */
main:has(> .ctex) > .sec--ground { background: var(--v1-white); }
