/* ============================================================
   styles.css — 2026 HI-CON 전 페이지. 사이트의 유일한 스타일시트.
   index · guide · sponsor · community · privacy 가 모두 이 파일을 쓴다.
   (카드 + JetBrains Mono + AC/PENDING 칩을 쓰던 이전 styles.css는 폐기)

   원칙
   1. 변하는 색은 풍선에서만 나온다. 그 외에는 잉크 · 종이 · 회색뿐.
      고정값 색 예외가 셋이고, 전부 이름이 있다. 이름 없는 색은 없다.
      (가) 초안 표시(.todo) — 공개 전에 눈에 걸려야 하는 자리.
      (나) 진행 표시(--mark, .track의 "지금") — 시간 위의 현재 위치.
      (다) 강조색(--accent-from → --accent-to) — 후원 제안서 덱 아래 띠에서
           가져온 초록 → 노랑. 쓰는 모양이 둘뿐이고 자리가 정해져 있다.
           · 띠(100% 농도, --band-h) — 묶음의 머리를 표시한다. .notes · .rank.
             한 묶음에 하나까지다.
           · 옅은 면(12% / 10%) — 여럿 중 하나를 고른다. .rank 첫 칸(먼저인 것),
             .paths 가리킨 칸(지금 이것). 둘 다 오른쪽 끝이 투명으로 풀린다.
           다른 자리나 다른 모양으로 쓰려면 이 줄을 먼저 고친다.
           .paths만 쉴 때 보이지 않고 가리킬 때만 나타난다 — 색이 상태를 말하는
           유일한 자리이므로, 거기서도 색이 혼자 지지 않게 글자가 오른쪽으로
           밀리는 움직임을 함께 둔다.
      (마) 로고 — 푸터의 HI-ARC · LinearSolve 마크. 이건 우리가 고른 색이 아니라
           남의 브랜드다. 무채색으로 바꾸거나 색을 빼지 않는다 — 남의 마크를
           다시 칠하는 것은 표기 규칙의 문제가 아니라 예의의 문제다.
           그래서 위 넷과 달리 값이 이 파일에 없다. 파일 안에 없는 유일한 색이다.
      (라) 티어 색(--tier-plat · --tier-gold, 그리고 실버 자리의 --faint) —
           덱이 티어 이름에 쓰는 색. 쓰는 곳은 .tiers 요약표의 티어 이름 한 줄뿐이다.
           색이 등급을 혼자 지지 않는다 — 같은 칸에 PLATINUM/GOLD/SILVER와
           플래티넘/골드/실버가 글자로 있고, 옆 칸에 300/100/50만 원이 있다.
           색을 지워도 티어를 읽는 데 줄어드는 것이 없다.
      셋 다 사이트 어디서나 같은 값이다. 섹션마다 달라지는 색은 풍선의 몫이고,
      띠를 그 섹션 풍선 색에 맞추고 싶어지는 날이 오는데 하지 않는다 —
      달라지는 순간 독자는 색 체계가 둘이라고 읽는다.
      그리고 색이 혼자 뜻을 지는 자리는 없다. 자리 · 차례 · 잉크 굵기 · 한국어가
      먼저 말하고 색은 그 위에 얹힐 뿐이다. 판단 기준은 하나다 —
      색을 통째로 지워도(인쇄 · 강제 색상 · 색각 이상) 읽을 것이 하나도 줄지 않아야 한다.
   2. 상자를 쓰지 않는다. 위계는 괘선 · 여백 · 활자 크기로 만든다.
      다만 괘선에는 예산이 있다. 긋는 자리는 둘뿐이다 — 섹션의 경계(.blk · .blk-rule · .sub),
      그리고 같은 모양이 되풀이되는 행 사이(.rows · .notices · .log · .tiers · .qa · .paths).
      목록 항목 사이는 긋지 않고, 이미 제 변을 그리는 것 위에 또 긋지 않는다.
      선이 모자라서가 아니라 너무 많아서 생긴 예외가 하나 있다 — 강조 띠(--band-h).
      띠는 반드시 있던 괘선을 걷어낸 자리에만 놓는다. 띠를 들이는 묶음에서는
      칸마다 긋던 괘선을 함께 지운다. 장식의 순증은 없다, 교환만 있다.
      띠는 상자가 아니다. 한 변뿐이고 테두리가 없으며 안을 감싸지 않는다.
      띠에 딸린 옅은 면(.rank의 첫 칸)도 오른쪽 끝이 투명으로 풀려 끝이 없다.
      (.notes는 2026-09-21에 괘선을 버리고 띠로 옮겨 이 예산에서 빠졌다.)
   3. 판정 어휘(AC/PENDING)를 쓰지 않는다 — 아는 사람만 아는 말이다.
      확정되지 않은 것은 "미정"이라고 한국어로 쓴다.
   ============================================================ */

:root {
  /* 종이와 잉크 — 무채색 4단.
     글자 세 단은 모두 종이 대비 4.5:1을 넘긴다(각각 17.2 / 6.4 / 4.5).
     연한 회색이 예뻐 보여도 라벨과 날짜는 읽으라고 있는 글이다. */
  --paper: #fbfbf7;
  --ink: #14181f;    /* 본문 */
  --dim: #565d68;    /* 보조 설명 */
  --faint: #6d747f;  /* 라벨 · 날짜 */
  --rule: #e3e3da;       /* 괘선 — 글자가 아니므로 대비 기준 밖 */
  --rule-strong: #c8c9bd;

  /* 풍선 — 섹션마다 바뀌는 색. ICPC 풍선 팔레트.
     a→f 순서가 곧 무지개 순서다(빨 주 노 초 파 보). 각 페이지는 위에서
     아래로 a부터 차례로 쓰므로, 스크롤하면 줄에 매달린 풍선이 무지개로 넘어간다.
     섹션이 여섯 개보다 적은 페이지는 앞쪽만 쓴다 — 앞이 잘려도 순서는 무지개다.
     그래서 이 목록의 순서를 건드리면 전 페이지의 색이 함께 움직인다. */
  --bal-a: #dd5140;  /* 빨 */
  --bal-b: #e5781f;  /* 주 */
  --bal-c: #d19a00;  /* 노 */
  --bal-d: #0e9752;  /* 초 */
  --bal-e: #2e7bd4;  /* 파 */
  --bal-f: #8757e8;  /* 보 */

  /* 진행 표시(.track의 "지금") — 팔레트에서 노랑을 가져오되 순서에 묶이지 않는다.
     --bal-d를 직접 쓰던 때는 무지개 순서로 바꾸자마자 초록으로 딸려 바뀌었다.
     그런데 var(--bal-c)로 적어 둔 것은 같은 실수의 다른 철자였다 —
     이름이 바뀌면 똑같이 딸려 간다. 값으로 못박는다.
     (지금 --bal-c와 값이 같으므로 화면은 한 픽셀도 바뀌지 않는다.) */
  --mark: #d19a00;

  /* 강조 띠 — 후원 제안서 덱 아래 각주 띠에서 가져온 두 색. 왼쪽 초록 → 오른쪽 노랑.
     덱이 정본이다(_deckcheck/track-*.html, 일곱 장 전부 같은 한 줄).
     값을 고칠 일이 생기면 덱을 먼저 고친다.

     리터럴로 적는 이유가 둘이다.
     하나 — 덱과 사이트는 --bal-* 이름은 같은데 가리키는 색이 다르다.
     덱의 --bal-c는 초록이고 여기 --bal-c는 노랑이다. 이름으로 옮겨 적으면
     덱 띠가 좌우로 뒤집힌 채 들어온다.
     둘 — 위 무지개 목록은 순서가 곧 뜻이라 언제든 다시 섞일 수 있다.
     이름에 묶으면 그때 강조색이 통째로 딸려 움직인다. --mark가 겪은 일이다. */
  --accent-from: #0e9752;   /* 초록 — 덱 띠의 왼쪽 끝 */
  --accent-to:   #d19a00;   /* 노랑 — 덱 띠의 오른쪽 끝 */

  /* 띠 두께. 이 파일에서 가장 굵은 변이 .track의 3px이고 그 정확히 두 배다.
     1px 괘선 옆에서 "굵은 선"이 아니라 다른 종류의 물건으로 읽히는 최소치이면서,
     색 면적이 풍선을 넘지 않는 선이다. 여기 하나만 고치면 .notes와 .rank가 함께 온다.
     10px을 넘기면 지면에서 색 면적이 풍선을 앞질러 체계가 뒤집힌다. */
  --band-h: 6px;

  /* 옅은 면 — 위 두 색을 종이에 12% / 10%로 깐 것. 띠와 같은 색, 농도만 다르다.
     합성 결과는 #dfefe3 / #f7f1de 이고, 그 위에서
     --ink는 14.9:1 ~ 15.8:1, --dim은 5.57:1 ~ 5.88:1 로 둘 다 4.5:1을 넘긴다.
     --faint만 3.95:1 ~ 4.10:1 로 모자라므로 이 면 위에는 절대 올리지 않는다.
     14%가 상한이다(--dim이 5.43:1까지 내려온다). 색을 고치면 여기도 다시 섞는다. */
  --accent-wash-from: rgba(14, 151, 82, 0.12);
  --accent-wash-mid:  rgba(209, 154, 0, 0.10);

  /* 티어 색 — 덱이 티어 이름에 쓰는 두 색(플래티넘 teal · 골드 노랑)을 가져왔다.
     색상과 채도는 덱 그대로고 명도만 내렸다. 덱 값을 그대로 쓰면 이 종이 위에서
     teal 3.61:1 · 노랑 2.43:1 로 둘 다 본문 기준 4.5:1에 못 미친다 —
     .tiers .tn 은 12.5px 굵은 글씨라 "큰 글씨" 예외에도 들지 않는다.
     덱은 슬라이드라 통과하지 않아도 되지만 이건 읽는 지면이다.
     내용은 덱을 따르되 표기 규칙은 각자의 것을 쓴다는 원칙이 여기에도 적용된다.
     실버는 원래 쓰던 --faint(4.54:1)를 그대로 둔다. 셋이 나란히 4.5~4.6:1이라
     대비가 티어 순서를 암시하지 않는다 — 층계는 금액과 차례가 말한다. */
  --tier-plat: #0b8076;   /* 덱 #0d9488 에서 명도만 32% -> 27%. 4.64:1 */
  --tier-gold: #936c00;   /* 덱 #d19a00 에서 명도만 41% -> 29%. 4.62:1 */

  --latin: "Barlow", "Helvetica Neue", Arial, sans-serif;
  --sans: "Pretendard Variable", Pretendard, -apple-system, BlinkMacSystemFont, system-ui, sans-serif;

  /* 활자 8단 — 그 사이는 없다.
     --t-lead는 2026-09-21에 냈다. --t-h2(30.7px)와 --t-display(86.4px) 사이가
     2.8배로 벌어져 있었고, 홈 표제부의 한 문장이 갈 자리가 그 틈이었다.
     워드마크만큼 클 수는 없지만 섹션 제목과 같아서도 안 되는 유일한 활자다 —
     쓰는 곳도 .hero-slogan 하나뿐이다. 새 칸을 내는 대신 기존 칸을 빌려 쓰면
     "메인의 한 문장"과 "섹션 제목"이 같은 말이 된다.

     최대값 2.3rem은 --t-h2의 최대값(1.92rem)의 1.2배다. 기울기도 3vw의 1.2배인
     3.6vw로 맞췄다 — 둘이 같은 비율로 자라므로 어느 폭에서나 1.17~1.20배다.
     처음엔 2.6rem으로 뒀는데, --t-h2가 1024px에서 최대값에 닿아 멈추는 동안
     이것만 계속 자라 1200px부터 1.35배로 벌어졌다. 좁은 화면은 멀쩡하고
     넓은 화면에서만 튀는 이유가 그것이었다. 최대값을 고칠 일이 생기면
     --t-h2의 최대값에 1.2를 곱한 값에서 출발할 것. */
  --t-display: clamp(3.4rem, 9.5vw, 5.4rem);
  --t-lead: clamp(1.75rem, 3.6vw, 2.3rem);
  --t-h2: clamp(1.5rem, 3vw, 1.92rem);
  --t-h3: 1.14rem;
  --t-body: 1rem;
  --t-sm: 0.9rem;
  --t-label: 0.78rem;
  --t-micro: 0.68rem;

  /* 왼쪽 풍선 줄 레일.
     풍선 크기는 --bal-w/--bal-h만 바꾸면 매듭 위치·줄 시작점이 따라온다.
     SVG viewBox 26×36 비율 유지, 매듭 꼭짓점은 높이의 정확히 0.8 지점(28.8/36). */
  --rail: 92px;
  --string-x: 30px;
  /* 폭은 홀수로 둔다. 풍선 중심이 1px 선의 중심(x.5)과 맞아야 하는데,
     짝수 폭이면 요소 자체를 0.5px 밀어야 해서 모든 모서리가 상시 반픽셀로 흐려진다.
     홀수 폭이면 요소는 정수 픽셀에 놓이고 중심만 .5로 떨어진다. */
  --bal-w: 37px;
  --bal-h: 50px;
  --bal-top: 58px;        /* 섹션 풍선 */
  --bal-top-hero: 74px;   /* 표제부 풍선 */

  --maxw: 1040px;
  /* 산문 단. 자료 단(= .doc 안쪽 전체 폭)보다 좁다 — 아래 "두 폭" 참고. */
  --measure: 620px;
}

* { margin: 0; padding: 0; box-sizing: border-box; }

html {
  scroll-behavior: smooth;
  scroll-padding-top: 96px;
  -webkit-text-size-adjust: 100%;
}

body {
  background: var(--paper);
  color: var(--ink);
  font-family: var(--sans);
  font-size: var(--t-body);
  line-height: 1.75;
  -webkit-font-smoothing: antialiased;
  letter-spacing: -0.005em;
  word-break: keep-all;   /* 한글은 단어 단위로 끊는다 */
}

.lt { font-family: var(--latin); font-feature-settings: "tnum" 1; }
h1, h2, h3 { line-height: 1.4; font-weight: 800; letter-spacing: -0.028em; }
a { color: inherit; text-decoration: none; }
ul, ol { list-style: none; }
strong { font-weight: 700; }

:focus-visible {
  outline: 2px solid var(--ink);
  outline-offset: 3px;
  border-radius: 2px;
}

.container { max-width: var(--maxw); margin: 0 auto; padding: 0 28px; }

/* 본문으로 건너뛰기 — 탭 순서 맨 앞에 있다가 초점을 받을 때만 나타난다.
   네비 링크 서너 개를 매 페이지 다시 지나지 않게 하는 유일한 장치다. */
.skip {
  position: absolute; left: -9999px; top: 0; z-index: 20;
  background: var(--ink); color: var(--paper);
  padding: 12px 18px; font-size: var(--t-sm); font-weight: 700;
}
.skip:focus { left: 12px; top: 12px; }
/* 건너뛰기의 목적지. <main>은 원래 초점을 받지 못해서, 이게 없으면 어떤
   브라우저는 스크롤만 하고 초점은 건너뛰기 링크에 남는다 — 다음 Tab이
   다시 네비로 돌아가 링크가 한 일이 없어진다. 테두리는 본문 전체를
   감싸 버리므로 지운다(초점은 이미 눈에 보이는 스크롤로 드러난다). */
main[tabindex="-1"]:focus { outline: none; }

/* ============================================================
   상단 — 네비. 배경도 그림자도 없다. 괘선 한 줄로 끝낸다.
   ============================================================ */
.nav {
  position: sticky; top: 0; z-index: 40;
  background: var(--paper);
  border-bottom: 1px solid var(--rule);
}
.nav-inner {
  max-width: var(--maxw); margin: 0 auto; padding: 0 28px;
  height: 64px; display: flex; align-items: center; justify-content: space-between; gap: 20px;
}
.wordmark {
  font-family: var(--latin); font-weight: 700; font-size: var(--t-sm);
  letter-spacing: 0.02em; white-space: nowrap;
}
.wordmark .x { color: var(--bal-a); }
.nav-links { display: flex; align-items: center; gap: 26px; }
.nav-links > a {
  font-size: var(--t-sm); color: var(--dim);
  padding: 4px 0; border-bottom: 1px solid transparent;
  transition: color 0.15s, border-color 0.15s;
}
.nav-links > a:hover { color: var(--ink); border-bottom-color: var(--ink); }

/* 좁은 화면 메뉴 */
.navmenu { display: none; position: relative; }
.navmenu > summary {
  list-style: none; cursor: pointer; display: grid; place-items: center;
  width: 34px; height: 34px; border: 1px solid var(--rule-strong);
}
.navmenu > summary::-webkit-details-marker { display: none; }
.navmenu-bars { display: block; width: 15px; height: 1px; background: var(--ink); position: relative; }
.navmenu-bars::before, .navmenu-bars::after {
  content: ""; position: absolute; left: 0; width: 15px; height: 1px; background: var(--ink);
}
.navmenu-bars::before { top: -5px; }
.navmenu-bars::after { top: 5px; }
.navmenu-panel {
  position: absolute; right: 0; top: calc(100% + 10px); width: 232px;
  background: var(--paper); border: 1px solid var(--rule-strong); padding: 6px 0;
}
.navmenu-panel a { display: block; padding: 11px 18px; font-size: var(--t-sm); }
.navmenu-panel a:hover { background: #f2f2ea; }

/* ============================================================
   풍선 줄 — 페이지 왼쪽을 관통하는 한 가닥.
   이 선이 섹션 구분선이자 목차다. 각 섹션의 풍선이 여기에 매달린다.
   ============================================================ */
.doc { position: relative; padding-left: var(--rail); }
/* 줄은 맨 위 풍선의 매듭에서 시작한다. 풍선 위로 줄이 지나가면 매달린 게 아니다.
   끝점은 매듭 삼각형의 위쪽 꼭짓점(SVG y=28.8)에 정확히 맞춘다 —
   --string-top = 히어로 풍선 top(82px) + 28.8px. 그 아래 구간은 삼각형이 덮어
   선이 매듭 밑변에서 흘러나오는 것처럼 보인다. */
.doc::before {
  content: ""; position: absolute; left: var(--string-x); bottom: 0;
  /* --string-shift: 맨 위 풍선이 시차로 움직인 만큼. balloon.js가 넣는다. */
  top: calc(var(--bal-top-hero) + var(--bal-h) * 0.8 + var(--string-shift, 0px));
  width: 1px; background: var(--rule-strong);
}

/* 기본은 한 폭이다. 왼쪽은 레일, 오른쪽은 단이 끝나는 곳 하나.
   본문·표·목록·괘선이 모두 같은 오른쪽 끝을 공유한다 — 정돈된 문서의 조건이다.
   폭을 둘로 가르는 것도, 갈래표를 여백으로 빼는 것도 넓은 화면에서만 한다.
   맨 아래 "넓은 화면" 블록 하나에 모여 있다. */

.blk { position: relative; padding: 76px 0; }
.blk + .blk { border-top: 1px solid var(--rule); }

/* 풍선 — 줄에 매달려 종이 위에 떠 있다.
   블록이 기준이므로 레일 폭만큼 왼쪽으로 빼야 줄 위에 앉는다.

   스크롤 시차는 balloon.js가 translateY로 넣는다(회전 없음).
   레이어로 승격해 한 번만 래스터화하고 이동은 GPU에 맡긴다 —
   이게 없으면 매 프레임 다시 래스터화되어 윤곽선이 지글거린다. */
.balloon {
  position: absolute;
  /* (폭 − 1) / 2 → 정수. 홀수 폭이라 중심이 저절로 선 중심(x.5)에 온다. */
  left: calc(var(--string-x) - var(--rail) - (var(--bal-w) - 1px) / 2);
  top: var(--bal-top);
  width: var(--bal-w); height: var(--bal-h);
  will-change: transform;
  backface-visibility: hidden;
}
.balloon .body { fill: var(--b, var(--faint)); }
.balloon .knot { fill: var(--b, var(--faint)); }
.balloon .gloss { fill: rgba(255, 255, 255, 0.5); }

/* ============================================================
   표제부 — 문제지 표지
   ============================================================ */
/* 사진 패널이 위를 맡았으므로 표제부는 그 아래에서 시작한다.
   위 여백을 줄여 출처 줄이 사진에 붙어 읽히게 한다. */
.hero { padding: 40px 0 62px; position: relative; }
.hero .balloon { top: var(--bal-top-hero); }

.hero-year {
  font-family: var(--latin); font-size: var(--t-label); font-weight: 500;
  letter-spacing: 0.24em; color: var(--dim); margin-bottom: 10px;
}
.hero-name {
  font-family: var(--latin); font-size: var(--t-display); font-weight: 700;
  letter-spacing: -0.03em; line-height: 0.94; margin-bottom: 26px;
}
.hero-name .x { color: var(--bal-a); }

/* 이 지면의 본문(本文). 사진 패널의 워드마크가 이름을 말하고 이 줄이 무엇인지를 말한다.
   활자 단은 --t-lead — 이 한 줄을 위해 낸 칸이고 쓰는 곳도 여기뿐이다.
   섹션 제목(--t-h2)보다 크고 워드마크(--t-display)보다 작다. 명색이 메인이다.
   전에는 clamp(1.15rem, 2.4vw, 1.42rem)이라는 제 값을 따로 갖고 있었는데,
   --t-h3(1.14)와 --t-h2(1.5) 사이라 활자 단을 어기면서 정작 작았다.
   굵기·자간·행간은 지웠다 — h1, h2, h3 공통 규칙(800 / -0.028em / 1.4)이
   이미 같은 말을 한다.

   2026-09-21까지 이 규칙은 한 글자에도 닿지 않았다. 마크업이
   <p class="hero-slogan"><h2>…</h2></p> 였는데 블록인 <h2>가 <p>를 자동으로
   닫아 버려서, 실제 DOM은 빈 <p>와 그 뒤의 맨 <h2>였다. 크기는 브라우저 기본값
   24px이었고 max-width가 닿지 않아 한 줄로 892px을 가로질렀다.
   <h2>에 클래스를 직접 걸어 고쳤다. */
.hero-slogan {
  font-size: var(--t-lead);
  margin-bottom: 20px;
  /* max-width를 두지 않는다. 줄바꿈은 아래 <br>이 정하고, 바깥 끝은 단이 잡는다.
     폭으로 쉼표 줄바꿈을 만들 수는 없다 — 첫 줄이 "…넘어, 함께"(282px)보다
     좁아야 하는데 둘째 줄에는 "함께 만드는 대학생 프로그래밍 대회"(410px)가
     들어가야 한다. 두 수는 글자 크기를 바꿔도 같은 비율로 움직이므로
     어떤 폭에서도 동시에 만족되지 않는다. 그래서 마크업에서 끊는다. */
}
.hero-sub { color: var(--dim); max-width: 46ch; margin-bottom: 34px; }
.hero-note { font-size: var(--t-sm); color: var(--faint); margin-top: 24px; }

/* ── 표제부 사진 패널 ─────────────────────────────────────────
   지난 대회의 기록 사진이 뒤로 흐르고 그 위에 이름이 선다.
   이 사이트에서 유일하게 사진이 놓이는 자리다.

   사진은 배경이므로 전환은 겹쳐 사라지는 방식만 쓴다. 미끄러지는 전환은
   시선이 사진을 따라가게 만들어 그 위의 워드마크를 읽지 못하게 한다.
   자바스크립트가 없으면 첫 장에서 멈춘다 — 조작 단추는 gallery.js가 켠다. */
.stage {
  position: relative;
  /* 단 바깥에 놓여 화면 폭을 그대로 쓴다. 높이는 화면에 맞춰 눕히되,
     큰 모니터에서 표제부가 화면을 통째로 삼키지 않도록 상한을 둔다.
     사진 원본은 16:9라 이보다 납작한 창에서는 위아래가 잘린다 —
     풍선이 대개 사진 위쪽에 있어 자르는 기준점을 조금 위로 올려 둔다(.stage-frame img). */
  height: min(58vh, 560px);
  min-height: 300px;
  overflow: hidden;
  background: #e7e6dd;   /* 사진이 아직 안 뜬 동안의 바탕 */
  /* 층을 이 패널 안에 가둔다 — 바깥의 z-index 와 겨루지 않게. */
  isolation: isolate;
  --swap: 0.9s;
  --swap-ease: cubic-bezier(0.4, 0, 0.2, 1);   /* 속도가 0에서 시작해 0으로 끝난다 */
  --hit-out: 9px;   /* 멈춤 단추 누름 영역의 좌우 돌출. 넘김 표시와의 틈이 여기서 나온다 */
}

/* 사진은 화면 끝까지 가되 글자는 단에 맞춘다.
   .container와 같은 폭·같은 여백이라 워드마크의 왼쪽이 본문 왼쪽과 한 줄에 선다. */
.stage-inner {
  position: relative; z-index: 6;
  max-width: var(--maxw); height: 100%;
  margin: 0 auto;
}
/* 층: 지나간 장 0 · 바닥 1 · 물러나는 장 2 · 지금 장 3 · 그늘 5 · 글자 6

   .is-base 가 요점이다. 두 장을 동시에 반투명하게 만들면 전환 한가운데서
   덮임이 1이 아니라 0.75까지 내려앉고, 그 틈으로 .stage 의 바탕(#e7e6dd)이
   25%까지 비쳐 사진이 잠깐 뿌옇게 뜬다. 다 떠오른 장을 바닥에 불투명하게
   깔아 두면 덮임이 언제나 1이다. .is-fading 은 전환 도중에 다른 칸을 눌렀을 때
   반쯤 떠오른 장이 튀지 않고 마저 빠지도록 하는 자리다. */
.stage-frame          { position: absolute; inset: 0; z-index: 0; opacity: 0;
                        transition: opacity var(--swap) var(--swap-ease); }
.stage-frame.is-base  { z-index: 1; opacity: 1; transition: none; }
.stage-frame.is-fading{ z-index: 2; }
.stage-frame.is-on    { z-index: 3; opacity: 1; }
.stage-frame img {
  width: 100%; height: 100%; display: block;
  object-fit: cover; object-position: center 42%;
}

/* 사진 위에 글자를 얹는 유일한 칠. 아래쪽만 가라앉혀 워드마크의 바탕을 만든다 —
   사진 전체를 덮으면 사진을 실은 이유가 없어진다.

   정지점을 %가 아니라 px로 잡은 것이 요점이다. 이 칠이 받쳐야 하는 것은 사진이
   아니라 그 위에 얹힌 글자 덩어리이고, 덩어리 높이는 사진이 커지든 작아지든 비슷하다.
   %로 잡으면 4:3으로 눕는 좁은 화면(약 281px)에서 같은 글자가 사진의 절반 높이에
   걸려서, 글자를 읽히게 하려면 사진 절반을 덮어야 했다. px로 잡으니 아래 170px만
   가라앉고 그 위는 두 화면 모두 사진 그대로다.

   값은 눈대중이 아니다. 다섯 장에서 글자가 놓이는 자리의 가장 밝은 화소를 뽑아
   이 그라디언트와 글자 알파를 실제로 합성해 구했다. 필요했던 칠은 출처 줄 0.64,
   '2026' 0.59였고 — 이전 %판에서는 좁은 화면의 '2026' 자리가 0.33밖에 되지 않아
   화소의 61.8%가 4.5:1에 못 미쳤다. 출처 표기는 사진 사용 허가의 조건이므로
   읽히지 않으면 표기한 것이 아니다. */
.stage::after {
  content: ""; position: absolute; inset: 0; z-index: 5; pointer-events: none;
  background: linear-gradient(
    to top,
    rgba(16, 19, 25, 0.84) 0,
    rgba(16, 19, 25, 0.62) 170px,
    rgba(16, 19, 25, 0) 290px
  );
}
/* 워드마크의 왼쪽은 레일 너머 본문이 시작하는 자리다. 바로 아래의 출처 줄과
   슬로건이 같은 x에서 시작하므로, 사진 위에서 아래까지 왼쪽 끝이 한 줄로 선다.
   (절대 위치는 부모의 패딩을 타지 않으므로 여백을 left에 직접 더한다.) */
.stage-mark { position: absolute; left: calc(28px + var(--rail)); bottom: 26px; }
.stage-mark .hero-year { color: rgba(251, 251, 247, 0.86); margin-bottom: 8px; }
/* 상자를 같은 x에 두어도 글자는 어긋난다. Barlow Bold의 'H'는 제 상자보다
   0.058em 안쪽에서 시작하는데 '2026'의 '2'는 베어링이 0이라, 큰 쪽만 들여쓴 것처럼 보인다.
   그만큼 당겨 두 줄의 잉크 왼쪽 끝을 맞춘다. em이라 활자가 커지고 작아져도 따라온다. */
.stage-mark .hero-name { color: var(--paper); margin-bottom: 0; margin-left: -0.058em; }

/* 사진 설명과 조작. 워드마크는 왼쪽 아래를 쓰므로 이쪽은 오른쪽에 붙는다.

   :not([hidden])로 거는 것이 중요하다. 그냥 `display:flex`로 쓰면 저자
   스타일시트가 UA의 `[hidden]{display:none}`을 출처 우선순위로 이겨서,
   HTML에 적어 둔 hidden이 아무것도 숨기지 못한다 — 자바스크립트가 없을 때
   눌러도 반응 없는 단추 여덟 개가 본문보다 앞선 탭 순서에 그대로 남았다. */
/* 출처와 조작이 한 줄에 선다. 사진마다 붙던 설명(.stage-cap)은 없앴고 그 자리를 출처가 받는다.
   묶음(.stage-bar)은 늘 있고 그 안의 조작만 gallery.js가 켠다 —
   출처는 사용 허가의 조건이라 스크립트가 꺼져도 남아야 하기 때문이다.
   넘김 표시는 사진 밖(.stage-nav)으로 내려가 이 줄에는 둘만 남는다.
   375px에서도 219px이라 한 줄에 들어가지만, 활자 설정이 커지는 경우를 대비해
   wrap은 남겨 둔다. */
/* 글자와 아이콘은 상자가 아니라 **베이스라인**으로 맞춘다.
   align-items:center 로 두었더니 상자 중심은 정확히 맞는데도 어긋나 보였다.
   한글은 글자 바닥이 베이스라인에 딱 서는데, 줄상자는 그 아래로 내려가는
   영문 디센더 몫(0.24em)까지 안고 있어서 중심이 서로 다른 것을 가리킨다.
   실측으로 아이콘 잉크 바닥이 글자 바닥보다 1.07px 흘러내려 있었다. */
.stage-bar {
  position: absolute; right: 28px; bottom: 26px;
  display: flex; flex-wrap: wrap; justify-content: flex-end;
  align-items: baseline; gap: 8px 18px;
}
/* 블록으로 두어 진짜 줄상자를 갖게 한다 — flex 였다면 베이스라인이 없어
   바깥의 align-items:baseline 이 바닥 모서리로 떨어졌을 것이다.
   활자 설정은 출처와 같게 맞춘다. */
.stage-ui:not([hidden]) { display: block; }
.stage-ui { font-size: var(--t-label); line-height: 1.75; }

/* 자동 넘김 멈춤 단추. 재생(세모)과 일시정지(막대 둘)를 한 SVG에 넣고 하나만 보인다.
   유니코드 ▶ ‖ 대신 SVG인 이유: ▶는 환경에 따라 이모지로 그려지고 크기도 제각각이다. */
.stage-play {
  position: relative; display: inline-block;
  border: 0; background: none; padding: 0; cursor: pointer; line-height: 1;
  color: rgba(251, 251, 247, 0.74); transition: color 0.15s;
  /* font:inherit 이 없으면 UA가 단추에 제 글꼴(13.3px Arial)을 먹여서
     아래 svg 의 0.8em 이 글자의 0.8em 과 다른 값이 된다. 실측 10.66px 대 9.98px. */
  font: inherit;
}
.stage-play:hover { color: var(--paper); }
/* 높이를 한글 글자 높이(0.8em)와 같게 두고, vertical-align:baseline 으로
   아이콘 바닥을 글자 바닥과 같은 선에 세운다. 잉크가 viewBox를 꽉 채우도록
   그려 두었으므로(index.html) 상자 높이가 곧 잉크 높이다.
   px 대신 em이라 활자가 커지고 작아져도 따라온다. */
.stage-play svg {
  display: inline; vertical-align: baseline;
  width: 0.6em; height: 0.8em; fill: currentColor;
}
.stage-play .i-play { display: none; }
.stage-play.is-paused .i-pause { display: none; }
.stage-play.is-paused .i-play { display: block; }
/* 아이콘이 7.5×10px이라 보이는 대로 두면 누를 수가 없다. 영역만 24px로 키운다. */
.stage-play::after {
  content: ""; position: absolute; inset: -7px calc(-1 * var(--hit-out));
}

/* ── 넘김 표시 — 출처 줄의 세 번째 항목 ──────────────────────
   사진 아래 종이가 아니라 사진 위에 얹힌다. 그래서 색이 뒤집힌다 —
   먹이 아니라 종이색을 알파로 쓴다.

   자리를 새로 고르지 않았다. 출처 글자와 멈춤 단추가 이미 서 있는 기준선을
   오른쪽으로 이었을 뿐이다. 새 선을 긋는 것이 아니라 있는 선을 늘리는 것이라
   지면에 부품이 하나도 늘지 않는다.

   기준선을 맞추는 장치가 font-size:0 · line-height:0 이다. 그러면 줄상자
   높이가 안에 든 1px 인라인 블록만으로 정해지고, 빈 인라인 블록의 기준선은
   제 아래 마진 모서리다 — 괘선의 아랫변이 곧 기준선이 되어 출처 글자와 같은
   선에 선다. 글꼴의 어센트·디센트에 기대지 않으므로 활자가 바뀌어도 어긋나지 않는다.
   (멈춤 단추도 같은 방법으로 맞춰 두었다. 6-11절 참고.)

   display 는 :not([hidden]) 안에만 둔다 — 저자 스타일시트의 display 는
   UA 의 [hidden]{display:none} 을 출처 우선순위로 이긴다. */
.stage-nav:not([hidden]) { display: block; }
.stage-nav {
  --seg: 22px; --gap: 6px;
  --pitch: calc(var(--seg) + var(--gap));   /* 한 걸음 28px */
  --i: 0;                                   /* 지금 장. gallery.js 가 적는다 */
  /* 인라인 블록이라 태그 사이 공백 하나가 그대로 간격이 된다. 둘 다로 막는다. */
  font-size: 0; line-height: 0; white-space: nowrap;
}
/* 굵기를 정하는 선언은 여기 하나뿐이다. 어느 상태에서도 1px 이고,
   달라지는 것은 알파와 잉크의 x 좌표뿐이다 — 굵어지는 칸이 없으니
   윗변이 계단처럼 튈 자리도 없다. */
.stage-nav > *,
.stage-nav button,
.stage-nav .stage-now {
  display: inline-block; vertical-align: baseline;
  width: var(--seg); height: 1px;
}
.stage-nav button {
  position: relative;
  font: inherit;   /* UA 가 단추에 제 글꼴을 먹이면 위 기준선 장치가 흔들린다 */
  margin: 0 0 0 var(--gap); padding: 0; border: 0;
  background: rgba(251, 251, 247, 0.46);
  cursor: pointer;
  transition: background 0.2s var(--swap-ease);
}
.stage-nav button:first-of-type { margin-left: 0; }
.stage-nav button:hover { background: rgba(251, 251, 247, 0.74); }
/* --i 가 어떤 이유로 죽어도 맞는 칸은 켜진다. 굵기는 건드리지 않고 알파만 쓴다.
   전환을 0초로 두되 0.9s 늦춰, 미끄러진 잉크가 도착하는 순간에 바닥이 밝아진다. */
.stage-nav button.is-on {
  background: rgba(251, 251, 247, 0.92);
  transition: background 0s linear var(--swap);
}
/* 1px 선이라 보이는 대로 두면 누를 수가 없다. 영역만 키운다 — 28×27px.
   좌우로 사이의 절반(3px)씩 나와 옆 칸과 정확히 맞닿고 겹치지 않는다.
   오른쪽 끝 칸이 3px, 멈춤 단추가 --hit-out(9px) 나오므로
   둘 사이 틈 = 열 간격 18 − 3 − 9 = 6px 로 확정된다. */
.stage-nav button::after {
  content: ""; position: absolute; inset: -13px calc(var(--gap) / -2);
}
/* 사진 위이므로 초점 표시도 종이색이어야 보인다 */
.stage-nav button:focus-visible {
  outline: 2px solid var(--paper); outline-offset: 5px; border-radius: 0;
}
/* 지금 칸을 가리키는 잉크. 다섯 칸 위를 미끄러진다.
   음수 마진으로 첫 칸에 겹쳐 두어 줄의 폭을 늘리지 않고,
   바뀌는 것이 transform 하나뿐이라 줄상자를 건드리지 않는다. */
.stage-now {
  margin-right: calc(-1 * var(--seg));
  position: relative; z-index: 1; pointer-events: none;
  background: rgba(251, 251, 247, 0.92);
  transform: translateX(calc(var(--i) * var(--pitch)));
  transition: transform var(--swap) var(--swap-ease);
}
/* 되감기(5→1)와 건너뛰기는 미끄러지지 않고 즉시 자리를 잡는다 —
   112px 을 0.9초에 거꾸로 훑는 것은 이 지면에서 가장 큰 움직임이 된다. */
.stage-nav.is-jump .stage-now { transition: none; }

.stage-ui :focus-visible { outline: 2px solid var(--paper); outline-offset: 3px; }

/* 출처 한 줄. 위 .stage-bar 안에서 조작 줄과 나란히 선다. */
.stage-credit {
  font-size: var(--t-label); font-weight: 500;
  color: rgba(251, 251, 247, 0.86);
}

/* 행동은 하나뿐 — 나머지는 전부 글 안의 링크로 */
.act {
  display: inline-block; padding: 13px 26px;
  background: var(--ink); color: var(--paper);
  font-size: var(--t-sm); font-weight: 700; letter-spacing: -0.01em;
  transition: background 0.15s;
}
.act:hover { background: #000; }

.link {
  color: var(--ink); font-weight: 600;
  border-bottom: 1px solid var(--rule-strong);
  transition: border-color 0.15s;
}
.link:hover { border-bottom-color: var(--ink); }
.link .arw { color: var(--faint); }

/* ============================================================
   섹션 머리 — 제목, 그다음 도입문, 그다음 괘선
   ============================================================ */
/* 갈래표(A · 대회 소개 …)는 두지 않는다. 섹션이 넷뿐이라 색인이 필요 없고,
   제목 위에 얹으면 섹션마다 같은 3단 스택이 반복돼 그 자체가 단조로움이 됐다.
   순서는 풍선 색이, 갈래는 제목이 이미 말한다. */
.blk h2 { font-size: var(--t-h2); margin-bottom: 18px; max-width: 24ch; }
/* 도입문에만 단 너비를 건다. `.blk > p`로 걸면 라벨·주석까지 잘린다. */
.blk > p.lede { color: var(--dim); }
.blk-rule { height: 1px; background: var(--rule); margin: 30px 0; }

/* 한글 소제목 — 영문 서체의 자간을 주면 글자가 흩어진다. Pretendard로 조용하게. */
.sub {
  font-size: var(--t-label); font-weight: 700; color: var(--faint);
  margin: 52px 0 18px; padding-bottom: 10px; border-bottom: 1px solid var(--rule);
}
/* 아래 요소가 이미 제 변을 그리는 경우 — .track의 3px 윗변, .notes의 강조 띠,
   .rank의 세로 띠 — 괘선을 뺀다. `.paths`에서 겪은 것과 같은 문제다.
   띠 위에서는 더 나쁘다. 6px 색 면 18px 위의 1px 회색 선은 부스러기로 보이고,
   세로 띠 위에 가로 괘선을 얹으면 뚜껑이 된다. */
.sub--bare { border-bottom: 0; padding-bottom: 0; }
/* 묶음 안에서 쓰는 소제목. .sub의 52px는 섹션 사이 간격이라 한 칸 안에서는 너무 벌어진다. */
.sub--tight { margin: 24px 0 10px; }

/* ============================================================
   자료 — 라벨 + 값. 상자 없이 괘선만.
   ============================================================ */
.rows > div {
  display: flex; gap: 28px; align-items: baseline;
  padding: 13px 0; border-bottom: 1px solid var(--rule);
}
.rows dt { flex: 0 0 74px; font-size: var(--t-label); color: var(--faint); }
.rows dd { font-size: var(--t-sm); }
.rows dd .muted { color: var(--dim); }

/* 주최 — 두 단, 카드가 아니라 두 개의 글 */
.orgs { display: grid; grid-template-columns: 1fr 1fr; gap: 44px; }
.org-name { font-family: var(--latin); font-size: var(--t-h3); font-weight: 700; letter-spacing: -0.02em; }
.org-role { font-size: var(--t-label); color: var(--faint); margin: 5px 0 12px; }
.org p { font-size: var(--t-sm); color: var(--dim); }

.foot-note { font-size: var(--t-sm); color: var(--faint); margin-top: 30px; }
/* 각주가 둘 이어질 때. 30px은 본문과 각주를 떼어 놓는 간격이라,
   각주끼리 그만큼 벌리면 서로 다른 이야기로 읽힌다. 한 문단 사이만큼만 둔다. */
.foot-note + .foot-note { margin-top: 14px; }
.foot-note a { border-bottom: 1px solid var(--rule-strong); }
.foot-note a:hover { border-bottom-color: var(--ink); color: var(--ink); }

/* ============================================================
   공지 — 날짜와 한 줄
   ============================================================ */
.notices > li {
  display: flex; gap: 26px; align-items: baseline;
  padding: 14px 0; border-bottom: 1px solid var(--rule);
}
.notices time {
  flex: 0 0 78px; font-family: var(--latin); font-size: var(--t-micro); font-feature-settings: "tnum" 1;
  color: var(--faint); font-variant-numeric: tabular-nums;
}
.notices p { font-size: var(--t-sm); }

/* 준비 순서 — 이 페이지에서 유일하게 흐르는 요소.
   나머지(자료 · 공지 · 표 · 파트너)가 전부 괘선으로 끊긴 행 목록이라
   같은 형태로 그리면 그중 하나로 묻힌다.
   순서는 화살표가, 현재 위치는 잉크 굵기가 말한다.
   번호는 뺐다 — 순서는 읽는 방향이 이미 말해주고,
   영문 숫자는 연도 · 날짜와 겹쳐 보인다. */
/* 여섯 칸으로 나눈 진행 막대. 각 칸의 윗변이 곧 그 단계의 구간이다.
   칸 폭이 같으니 왼쪽에서 오른쪽으로 나아가는 축이 생기고,
   색이 있는 칸이 지금 어디인지 말한다. 줄바꿈이 없으므로 선이 끊기지 않는다.
   라벨은 한 칸(약 108px)에 한 줄로 들어가도록 짧게 쓴다. */
.track {
  display: grid; grid-template-columns: repeat(6, 1fr); gap: 0 10px;
}
.track li {
  padding-top: 13px;
  border-top: 3px solid var(--rule);
  font-size: var(--t-label); line-height: 1.5; color: var(--faint);
}
.track li.done { border-top-color: var(--ink); color: var(--dim); }
.track li.now  { border-top-color: var(--mark); color: var(--ink); font-weight: 700; }
.track .mark {
  display: block; margin-top: 5px;
  font-size: var(--t-micro); font-weight: 700; color: var(--mark);
}

/* ============================================================
   지난 대회 — 연도와 문제지, 두 칸.

   칸이 넷이던 때는 min-width 520px을 깔고 .tablewrap이 가로로 스크롤됐다.
   좁은 화면에 스크롤을 만들면서까지 보여줄 내용이 아니었다
   (대회명은 세 줄이 같은 값, 참가 인원은 어림수). 그래서 둘로 줄였고,
   min-width도 없앴다. .tablewrap은 칸이 다시 늘 때를 위한 안전망으로만 남긴다.

   괘선은 단을 다 채워 오른쪽 끝을 나머지와 공유한다. 대신 글만 가운데로 모은다.

   두 칸을 반씩 나누고 왼쪽 칸은 오른쪽 정렬, 오른쪽 칸은 왼쪽 정렬 —
   두 칸이 가운데선에서 만나므로 괘선이 890px이어도 글은 붙어 있다.
   양쪽을 다 가운데 정렬하면 두 칸의 글이 220px씩 벌어져 한 줄로 읽히지 않는다.
   ============================================================ */
.tablewrap { overflow-x: auto; }
.log { width: 100%; border-collapse: collapse; }
/* 세 칸이다. 연도 · 기록(당시 공지·기사) · 문제지.
   한동안 "연도 / 문제지" 두 칸이었고 가운데선을 사이에 두고 마주 보게 놓았는데,
   기록 링크가 붙으면서 마주 볼 상대가 셋이 되었다. 셋부터는 마주 보기가 성립하지
   않으므로 왼쪽 정렬로 되돌리고, 연도 칸만 좁게 고정해 눈이 걸릴 자리를 만든다. */
.log th, .log td { text-align: left; padding-right: 28px; }
.log tr > :last-child { padding-right: 0; }
.log .yr, .log th:first-child { width: 92px; }
.log th {
  padding-bottom: 11px; font-size: var(--t-label); font-weight: 500;
  color: var(--faint); border-bottom: 1px solid var(--rule-strong);
}
.log td { padding: 17px 0; border-bottom: 1px solid var(--rule); font-size: var(--t-sm); }
.log .yr { font-family: var(--latin); font-feature-settings: "tnum" 1; font-size: var(--t-h3); font-weight: 700; letter-spacing: -0.02em; }
.log .mt { color: var(--faint); font-size: var(--t-label); }
/* 주소가 없는 칸은 config.js가 "준비 중"(.mt)으로 바꿔 놓는다.
   문제지 PDF가 붙으면 그 칸도 링크가 된다. .link + .arw 는 이미 있다. */

/* ============================================================
   파트너 — 카드가 아니라 두 줄
   ============================================================ */

.paths > a {
  display: block; position: relative;
  /* 옅은 면을 글자 뒤에 깔기 위한 것. ::after에 z-index: -1을 주면 이 상자가
     쌓임 맥락을 만들지 않는 한 조상의 배경 뒤까지 빠져나가 안 보인다.
     isolation이 여기서 맥락을 닫으므로 면은 이 칸 안에, 글자 바로 뒤에 머문다. */
  isolation: isolate;
  /* 왼쪽 12px은 면이 깔릴 자리다. 쉴 때도 비워 둔다 —
     글자와 면의 왼쪽 끝이 같은 x에 있으면, 손을 떼고 글자가 돌아오는 동안
     글자가 면의 모서리에 맞닿는 프레임이 생긴다. 그 12px이 그걸 막는다.
     어긋나는 것은 글자뿐이다. 상자의 왼쪽 끝은 그대로라 아랫변 괘선도, 면도
     h2 · .blk-rule · .rows · .tiers와 같은 x에 선다 — 지면의 왼쪽 끝은 흔들리지 않고
     그 안에서 글자만 들여 쓴다. 이것이 문서가 아니라 누르는 칸이라 치르는 값이다. */
  padding: 24px 0 24px 12px; border-bottom: 1px solid var(--rule);
  transition: padding-left 0.18s;
}
/* 위쪽 테두리를 두지 않는다 — 도입문 아래 .blk-rule이 이미 목록의 윗변이다.
   둘 다 있으면 30px 간격으로 괘선이 두 줄 겹친다.
   .rows / .notices / .log 도 전부 "아래 테두리만" 규칙을 따른다. */
/* 가리키면 12 -> 24. 움직이는 폭(12px)은 그대로고 출발점만 옮겼다.
   초점에도 같이 건다 — 색이 혼자 뜻을 지지 않게 움직임을 함께 둔다는 것이
   원칙 1 (다)에 적어 둔 조건이고, 키보드에서도 그 조건은 같다. */
.paths > a:hover,
.paths > a:focus-visible { padding-left: 24px; }

/* 가리키면 칸 전체에 옅은 면이 왼쪽에서 오른쪽으로 깔린다.
   .rank 첫 칸에 깔린 것과 같은 면이다 — 같은 두 색, 같은 농도, 같은 사그라듦.
   거기서는 "이것이 먼저"를 말하고 여기서는 "지금 이 칸"을 말한다.
   6px 띠는 쓰지 않는다. 띠는 묶음의 머리를 표시하는 물건이지 한 칸을 고르는
   물건이 아니고, 이 자리에서는 고르는 일만 필요하다.

   오른쪽 끝이 투명으로 풀리는 것을 그대로 가져왔다. 끝이 없으므로 상자가 아니다 —
   칸 전체를 칠하면서도 원칙 2를 지키는 것이 이 사그라듦 하나다.
   네 변을 다 채운 불투명한 면을 깔면 그 순간 이 목록은 카드가 된다.

   아랫변 1px 괘선은 그대로 둔다. 쉴 때의 행 구분이고, 면은 그 위를 지나갈 뿐이다.

   width나 transform: scaleX 가 아니라 clip-path로 연다.
   scaleX는 그라데이션을 통째로 눌러 담아 매 프레임 초록→노랑 전체가 보인다 —
   좁았다 넓어지는 다른 면처럼 보이지 면이 왼쪽에서 번지는 것으로 보이지 않는다.
   clip-path는 다 그려 둔 면을 왼쪽부터 드러내므로, 중간 프레임에서 보이는 것이
   늘 "그 면의 왼쪽 부분"이다. 같은 그라데이션이 왼쪽에서 오른쪽으로 나타난다.

   0.28s는 글자가 밀리는 0.18s보다 길다. 글자가 먼저 자리를 잡고 면이 뒤따라
   끝까지 가는 편이, 둘이 동시에 멈추는 것보다 방향이 또렷하다.
   손을 떼면 같은 길을 되짚어 왼쪽으로 접힌다. */
.paths > a::after {
  content: ""; position: absolute; inset: 0; z-index: -1;
  background-image: linear-gradient(
    90deg,
    var(--accent-wash-from) 0,
    var(--accent-wash-mid) 62%,
    rgba(209, 154, 0, 0) 100%
  );
  clip-path: inset(0 100% 0 0);
  transition: clip-path 0.28s ease-out;
}
/* 키보드로 옮겨 다닐 때도 같은 면이 깔린다. 초점 테두리만으로도 자리는 알 수 있지만,
   마우스로 얻는 신호를 키보드에서 빼 둘 이유가 없다. */
.paths > a:hover::after,
.paths > a:focus-visible::after { clip-path: inset(0 0 0 0); }
/* 화살표만 잉크를 올린다. --faint는 이 면 위에서 3.95:1이라 토큰 주석이
   "면 위에 절대 올리지 않는다"고 못박아 둔 색이다. 면이 깔리는 순간
   그 조건이 깨지므로 함께 올린다 — 가리킨 칸의 화살표가 진해지는 것은
   덤이 아니라 그 규칙을 지키다 나온 결과다. */
.path-top .arw { transition: color 0.18s; }
.paths > a:hover .arw,
.paths > a:focus-visible .arw { color: var(--ink); }
.path-top { display: flex; align-items: baseline; gap: 12px; }
.path-top b { font-size: var(--t-h3); font-weight: 800; letter-spacing: -0.02em; }
.path-top .arw { margin-left: auto; color: var(--faint); }
.paths p { font-size: var(--t-sm); color: var(--dim); margin-top: 7px; }

/* 확정 파트너가 생기면 이 격자를 쓴다. 그 전에는 빈 자리를 보이지 않는다. */
.logos { display: grid; grid-template-columns: repeat(auto-fill, minmax(150px, 1fr)); gap: 1px; background: var(--rule); border: 1px solid var(--rule); margin-bottom: 34px; }
.logos li { display: grid; place-items: center; height: 92px; background: var(--paper); }
.logos img { max-height: 34px; width: auto; }

/* ============================================================
   푸터
   ============================================================ */
/* 문서가 끝나고 판권이 시작된다. 괘선은 페이지를 가로지르되,
   글은 본문과 같은 왼쪽 끝에서 시작해 한 줄기를 유지한다. */
footer { border-top: 1px solid var(--rule-strong); padding: 46px 0 40px; }
footer .container { padding-left: calc(28px + var(--rail)); }
.foot-grid { display: grid; grid-template-columns: 1.7fr 1fr 1fr; gap: 36px; }
/* 판권의 두 제목. 문서 제목 층계에서 H2 다음에 곧바로 H4가 오는 것을 막으려고
   태그는 h2로 두고 크기만 여기서 되돌린다 — 푸터는 contentinfo 안이라
   본문 H2와 섞이지 않는다. */
.foot-h { font-size: var(--t-label); font-weight: 700; color: var(--faint); margin-bottom: 12px; letter-spacing: 0; }
.foot-grid p, .foot-grid li { font-size: var(--t-sm); color: var(--dim); }
.foot-grid li { padding: 3px 0; }
.foot-grid a:hover { color: var(--ink); }
.foot-mark { font-family: var(--latin); font-weight: 700; font-size: var(--t-sm); color: var(--ink); margin-bottom: 12px; }

/* 주최 두 곳의 공식 홈페이지. 화살표는 <a>에만 붙는다 —
   config.js가 주소 없는 항목을 <span>으로 바꾸므로, 링크가 아닌 것은
   화살표도 밑줄도 없이 이름만 남아 저절로 구분된다. */
.foot-orgs { display: flex; flex-wrap: wrap; gap: 8px 22px; margin-top: 6px; }
/* 로고 · 이름 · 화살표가 한 줄에 선다. 밑줄은 이름에만 건다 —
   링크 전체에 걸면 로고 밑에도 선이 그어져 그림에 밑줄을 친 꼴이 되고,
   화살표까지 딸려 들어간다. 밑줄은 "여기가 글자 링크다"라는 표시다. */
.foot-orgs a { display: inline-flex; align-items: center; gap: 7px; transition: color 0.15s; }
.foot-orgs a > span { border-bottom: 1px solid var(--rule-strong); transition: border-color 0.15s; }
.foot-orgs a::after { content: "↗"; color: var(--faint); }
.foot-orgs a:hover { color: var(--ink); }
.foot-orgs a:hover > span { border-bottom-color: var(--ink); }
/* 높이만 고정하고 너비는 그림이 정한다 — 하이아크 마크는 세로로 조금 길다.
   flex: none 이 없으면 좁은 화면에서 이름이 길어질 때 로고부터 찌그러진다. */
.foot-logo { height: 18px; width: auto; flex: none; }

/* 판권 맨 아래 한 줄. 대회가 아니라 저지를 가리키는 표기이므로 가장 조용하게. */
.foot-powered {
  margin-top: 20px;
  font-family: var(--latin); font-size: var(--t-micro); letter-spacing: 0.04em;
  color: var(--faint);
}
.foot-powered a { border-bottom: 1px solid var(--rule); }
.foot-powered a:hover { color: var(--ink); border-bottom-color: var(--ink); }
.foot-legal {
  margin-top: 40px; padding-top: 22px; border-top: 1px solid var(--rule);
  display: flex; justify-content: space-between; gap: 20px; flex-wrap: wrap;
}
.foot-legal p { font-size: var(--t-micro); color: var(--faint); max-width: 68ch; line-height: 1.8; }

/* ============================================================
   하위 페이지 — 종목 · 참가 안내 / 후원 / 커뮤니티 / 방침

   메인과 같은 뼈대(레일 · 풍선 줄 · .blk)를 그대로 쓴다.
   여기 있는 건 메인에 없던 형태뿐이다: 페이지 머리, 목록, 문답, 단추.
   상자는 여전히 쓰지 않는다 — 카드처럼 보이는 건 괘선 한 줄이나 색 띠 하나로 대신한다.
   둘 다 한 변뿐이고 안을 감싸지 않는다.
   ============================================================ */

/* 페이지 머리 — 표제부의 축소판. 워드마크 대신 문장이 제목이므로 활자를 낮춘다.
   풍선은 표제부와 같은 자리에 둔다. 줄의 시작점이 --bal-top-hero에 걸려 있어서다. */
.phead { position: relative; padding: 84px 0 58px; }
.phead .balloon { top: var(--bal-top-hero); }
.phead-kicker {
  font-family: var(--latin); font-size: var(--t-label); font-weight: 500;
  letter-spacing: 0.2em; color: var(--dim); margin-bottom: 14px;
}
.phead h1 {
  font-size: clamp(1.72rem, 3.5vw, 2.4rem); letter-spacing: -0.032em;
  margin-bottom: 18px; max-width: 19ch;
}
.phead > p { color: var(--dim); max-width: var(--measure); }

/* 행동 — 메인은 단추가 하나뿐이지만 하위 페이지는 둘씩 놓인다.
   테두리 1px만큼 안쪽 여백을 줄여 두 단추의 바깥 높이를 같게 맞춘다. */
.acts { display: flex; flex-wrap: wrap; gap: 12px; align-items: center; margin-top: 32px; }
.act--ghost {
  background: none; color: var(--ink);
  border: 1px solid var(--rule-strong); padding: 12px 25px;
}
.act--ghost:hover { background: none; border-color: var(--ink); }

/* 목록 — 글머리는 점이 아니라 짧은 괘선. 이 페이지의 다른 선들과 같은 말이다. */
.list > li {
  position: relative; padding-left: 16px;
  font-size: var(--t-sm); color: var(--dim); margin-bottom: 8px;
}
.list > li::before {
  content: ""; position: absolute; left: 0; top: 0.72em;
  width: 6px; height: 1px; background: var(--rule-strong);
}
.list > li strong { color: var(--ink); }
/* 하지 않는 것들. 같은 괘선을 쓰면 하는 일과 구분이 안 되므로 표시를 바꾼다. */
.list--no > li::before {
  content: "×"; top: 0; width: auto; height: auto;
  background: none; color: var(--faint); font-size: 0.92em; line-height: 1.75;
}
/* 아직 정해지지 않은 것. 확정된 항목과 같은 무게로 두면 다 정해진 것처럼 읽힌다. */
.list--pend > li { color: var(--faint); }
/* 항목이 짧고 많을 때만 두 단. 세로로 읽는 순서는 단 안에서 유지된다. */
.list--two { column-count: 2; column-gap: 44px; }
.list--two > li { break-inside: avoid; }

/* 갈래 묶음 — 카드가 아니라 띠 아래 놓인 글 묶음.
   칸마다 1px 괘선을 긋던 것을 걷어내고, 묶음 전체에 강조 띠 하나를 놓는다.
   세 칸이면 가로줄 셋이던 것이 띠 하나가 된다 — 장식은 줄고 색만 들어왔다.
   원칙 2의 교환 규칙이 요구하는 것이 이것이다.

   칸들은 차례가 아니라 갈래다(대회 환경 · 부하 테스트 · 예비소집).
   칸마다 제 윗변을 긋던 때는 나란한 셋을 각각 한 구간처럼 보이게 만들어
   없는 순서를 암시했다 — .track의 말투를 순서 없는 것에 빌려 쓴 것이었다.
   끊기지 않은 띠 하나가 하는 말은 하나뿐이다: "이 셋은 한 묶음이다."
   차례가 있는 것은 아래 .rank가 맡는다. 같은 두 색을 세로로 세워 쓴다.

   띠는 묶음 자신의 배경으로 그린다(테두리로는 그라데이션을 못 넣는다).
   background-origin 기본값이 padding-box이고 테두리가 없으므로 띠의 윗변이 곧
   요소의 윗변이다 — .rows · .tiers · .log와 같은 왼쪽 끝, 같은 오른쪽 끝에 선다.
   묶음에 하나뿐이라 칸 수(--n)가 4든 3든 2든 1이든 모양이 바뀌지 않는다.
   덕분에 좁은 화면에서 윗변을 칸에서 묶음으로 옮겨 담던 장치가 통째로 없어졌다.
   칸 구분은 40px 열 간격과 제목 굵기가 한다 — 표에서 머리글 괘선 하나가
   모든 열을 통솔하는 것과 같다.

   칸 수는 --n으로 바꾼다. 영문 키커는 두지 않는다 — 제목이 이미 갈래다. */
.notes {
  display: grid; gap: 32px 40px;
  grid-template-columns: repeat(var(--n, 3), minmax(0, 1fr));
  /* 띠 + 옛 괘선 아래 공백 15px. 눈에 보이는 간격을 그대로 물려받는다. */
  padding-top: calc(var(--band-h) + 15px);
  background-image: linear-gradient(90deg, var(--accent-from), var(--accent-to));
  background-repeat: no-repeat;
  background-size: 100% var(--band-h);
  background-position: 0 0;
}
.notes h3 { font-size: var(--t-h3); margin-bottom: 8px; }
.notes p { font-size: var(--t-sm); color: var(--dim); }
/* 칸 수는 클래스로 건다. 인라인 style="--n:4"는 어떤 @media도 이기므로,
   375px에서 50px짜리 네 칸이 그대로 남아 "대학 · 지역"이 단어마다 꺾인다.
   아래 @media의 --n 재정의보다 반드시 앞에 둔다 — 특정도가 같아 차례가 결정한다. */
.notes--4 { --n: 4; }
/* 도입문 바로 아래 올 때. 그 자리에 있던 .blk-rule을 걷어냈지만(윗변은 .notes가
   스스로 긋는다) 선이 차지하던 간격까지 걷어낼 이유는 없다. 30 + 1 + 30 을 그대로 준다. */
.blk > p.lede + .notes { margin-top: 61px; }

/* 두 갈래 대비 — 하는 일 / 하지 않는 일처럼 나란히 놓고 읽는 것 */
.pair { display: grid; grid-template-columns: 1fr 1fr; gap: 44px; }
.pair h3 { font-size: var(--t-h3); margin-bottom: 14px; }

/* 차례 묶음 — 후원 안내 "후원금 배정 순서" 한 곳에서만 쓴다.
   .notes 바로 아래 둔 것은 둘이 같은 어휘라서다. 덱의 같은 두 색을,
   .notes는 가로로 눕혀 "한 묶음"을, 여기는 세로로 세워 "차례"를 말한다.

   가로 3칸 격자를 버린 것이 이 요청의 실제 해답이다. 나란한 세 칸은 그 자체가
   "셋이 같다"는 말이라, 그 안에 무엇을 칠하든 순위가 서지 않는다.
   축을 세로로 돌리는 것이 먼저고 색은 그다음이다.

   .track을 쓰지 않는다. 셋 다 이유가 된다.
   하나. .track은 시간이고 done/now가 딸려 온다. 배정 순서에는 끝난 칸도 지금 칸도 없다.
         그 모양을 빌리면 "1번은 끝났고 2번이 진행 중"으로 읽힌다 — 하지 않은 말이다.
   둘.  .track은 repeat(6, 1fr)이 박혀 있고 --n이 없다. 인스턴스가 index 하나뿐인
         부품을 새 호출자 하나 때문에 일반화할 값이 없다.
   셋.  .track의 강조는 3px 괘선이다. 선으로 하는 강조가 물렸다는 것이 이 작업의 출발점이었다.
   빌려 온 건 하나뿐이다 — 왼쪽 세로 변이 순서를 뜻한다는 어휘(.track이 좁은 화면에서
   쓰던 것). 여기서는 모든 폭에서 상시로 쓴다.

   띠는 칸마다 끊지 않고 묶음 전체를 하나로 관통한다. 막대 길이나 굵기로 순위를
   그리지 않는다 — 바로 위가 금액 표인 지면에서 길이가 다른 조각 셋은 "얼마씩"으로
   읽힌다. 배분 비율은 원고 어디에도 없다. 끊기지 않은 막대 하나에는 잴 것이 없다.

   순서를 말하는 것은 넷이고 색은 그중 하나도 혼자 지지 않는다 —
   세로로 내려가는 자리, 01/02/03, 숫자의 잉크 3단, 그리고 띠가 위(초록 L=0.23)에서
   아래(노랑 L=0.37)로 밝아지는 것. 마지막 것은 색이 아니라 명도라 흑백에서도 남는다.
   번호는 counter로 만든다 — 본문에 적어 넣으면 목록 차례와 어긋날 자리가 생긴다. */
.rank { position: relative; counter-reset: rank; }
.rank::before {
  content: ""; position: absolute; left: 0; top: 0; bottom: 0;
  width: var(--band-h);
  background-image: linear-gradient(180deg, var(--accent-from), var(--accent-to));
  /* 첫 칸의 옅은 면과 겹친다. .rank > li가 position:relative라 그냥 두면
     나중에 칠해지는 칸 배경이 띠를 덮어 그 구간만 흐려진다. 띠를 위로 올린다. */
  z-index: 1;
}
.rank > li {
  position: relative;
  padding: 15px 0 19px 70px;   /* 70 = 띠 6 + 틈 16 + 숫자단 44 + 틈 4 */
}
.rank > li::before {
  content: counter(rank, decimal-leading-zero);
  counter-increment: rank;
  position: absolute; left: 22px; top: 14px;
  font-family: var(--latin); font-size: 1.28rem; font-weight: 700;
  line-height: 1.4; letter-spacing: 0.01em;
  font-feature-settings: "tnum" 1; font-variant-numeric: tabular-nums;
  color: var(--faint);
}
/* 숫자만 잉크가 내려간다. 본문은 내리지 않는다 —
   배정 3순위라고 읽을 가치가 3순위인 것은 아니다. 셋 다 배정되는 항목이다. */
.rank > li:nth-child(1)::before { color: var(--ink); }
.rank > li:nth-child(2)::before { color: var(--dim); }
/* 첫 칸에만 옅은 면. 먼저인 것이 둘이면 "먼저"가 아니다.
   오른쪽으로 투명하게 풀어 끝을 없앤다 — 끝이 없으므로 상자가 아니다.
   왼쪽 위 모서리에서 이 면의 초록과 세로 띠의 초록이 맞닿는다. 같은 색, 농도만 다르다. */
.rank > li:first-child {
  background-image: linear-gradient(
    90deg,
    var(--accent-wash-from) 0,
    var(--accent-wash-mid) 62%,
    rgba(209, 154, 0, 0) 100%
  );
}
.rank h3 { font-size: var(--t-h3); margin-bottom: 6px; }
.rank p { font-size: var(--t-sm); color: var(--dim); }

/* ============================================================
   후원 구성 — 후원 제안서 덱(T2~T5)의 지면을 그대로 옮긴 것.
   금액·티어·혜택 문구를 고칠 일이 생기면 덱을 먼저 고친다. 덱이 정본이다.

   덱은 티어 이름에 색을 쓴다(플래티넘 teal · 골드 노랑). 2026-09-21에 가져왔다.
   그 전까지는 "옮기지 않는다"고 적혀 있었는데, 실버만 --faint 라서 셋 중 하나만
   금속색을 입은 꼴이 되어 있었다. 색을 빼서 맞추는 길도 있었지만 덱이 이미
   색으로 티어를 부르고 있으므로, 덱 쪽으로 맞추는 편이 두 매체가 같은 말을 한다.

   명도만 이 지면에 맞게 내렸다 — 근거는 :root 의 --tier-* 주석에.
   색이 등급을 혼자 지지는 않는다. 티어 이름이 영문·한글로 두 번 적혀 있고
   금액이 옆 칸에 있다. 원칙 1의 시험("색을 지워도 읽을 것이 줄지 않는다")은
   지운 화면을 상상할 것도 없이 통과한다.

   한글 이름(.ko)은 잉크 그대로 둔다. 이 칸에서 가장 큰 활자라 색을 입히면
   표가 아니라 딱지처럼 보이고, 1.14rem/800 이라 "큰 글씨" 경계(18.66px)에도
   간발로 못 미쳐 같은 4.5:1을 다시 요구받는다. 색은 티어 이름 한 줄이면 족하다.
   ============================================================ */
.t-plat { color: var(--tier-plat); }
.t-gold { color: var(--tier-gold); }
.t-silver { color: var(--faint); }

/* 한눈에 보는 표 — 덱 T2 */
.tiers { width: 100%; border-collapse: collapse; }
.tiers th {
  text-align: left; font-size: var(--t-label); font-weight: 600; color: var(--faint);
  padding: 0 0 10px; border-bottom: 1px solid var(--rule-strong);
}
.tiers td { padding: 16px 0; border-bottom: 1px solid var(--rule); vertical-align: baseline; }
.tiers .tn {
  font-family: var(--latin); font-size: var(--t-label); font-weight: 700;
  letter-spacing: 0.12em; line-height: 1.45; padding-right: 26px;
}
.tiers .tn .ko {
  display: block; margin-top: 5px; color: var(--ink);
  font-family: var(--sans); font-size: var(--t-h3); font-weight: 800; letter-spacing: -0.02em;
}
.tiers .amt { font-size: var(--t-h3); font-weight: 700; white-space: nowrap; padding-right: 26px; }
.tiers .amt .num { font-family: var(--latin); font-feature-settings: "tnum" 1; }
.tiers .desc { font-size: var(--t-sm); color: var(--dim); line-height: 1.6; }
.tiers .desc strong { color: var(--ink); }

/* 제안서 내려받기 — 요약표를 읽은 사람의 다음 질문이 "그래서 뭘 받나"이고,
   그 답이 이 줄이다. 각주(--faint, 0.9rem)로 두었더니 회색 각주 넷 중 셋째로
   묻혀서 본문 크기로 꺼냈다. 단추로 만들지는 않는다 — 이 지면의 행동은
   `후원 신청` 하나뿐이고(위 "행동은 하나뿐"), 제안서는 읽을거리지 행동이 아니다. */
.deck { margin: 26px 0; font-size: var(--t-sm); }
.deck .arw { color: var(--faint); }
/* 형식·장수·용량. 링크를 누르기 전에 무엇이 열리는지 알려 준다 — 가로형 슬라이드라
   휴대폰에서 작게 열린다는 사실을 링크가 스스로 말하게 둔다. */
.deck-meta { margin-left: 10px; font-size: var(--t-label); color: var(--faint); white-space: nowrap; }

/* 티어별 상세(.tier-list · .tier)는 2026-09-16에 지웠다. 특전 26줄이 덱과
   바이트 단위로 같아 제안서 PDF로 넘겼고, 마크업이 사라지면서 규칙도 함께 죽었다.
   되살릴 일이 생기면 그 커밋을 보면 된다 — 여기에 주석으로 남겨 두지 않는다.
   위 .tiers(요약표)는 계속 쓰인다. 둘을 헷갈리지 말 것. */

/* 문답 — 물음만 보이다가 열린다. 답은 산문이므로 단을 좁힌다. */
.qa > details { border-bottom: 1px solid var(--rule); }
.qa summary {
  list-style: none; cursor: pointer;
  display: flex; gap: 13px; align-items: baseline;
  padding: 16px 0; font-size: var(--t-sm); font-weight: 600;
}
.qa summary::-webkit-details-marker { display: none; }
.qa summary::before {
  content: "Q"; flex: none;
  font-family: var(--latin); font-size: var(--t-label); font-weight: 700;
  letter-spacing: 0.06em; color: var(--faint);
}
/* 여닫이 표시. 회전이나 삼각형 대신 부호 하나 — 선만 쓰는 페이지에 맞춘다. */
.qa summary::after { content: "+"; margin-left: auto; color: var(--faint); font-weight: 400; }
.qa details[open] summary::after { content: "−"; }
.qa .a {
  padding: 0 0 20px 26px; font-size: var(--t-sm); color: var(--dim);
  max-width: var(--measure);
}

/* 라벨이 긴 자료 목록. .rows의 74px 칸에 "대회 · 결과 공유"가 들어가지 않는다. */
.rows--wide dt { flex: 0 0 132px; }

/* 방침 · 유의사항 — 이 사이트에서 유일하게 긴 산문이 이어지는 곳.
   (.doc는 이미 페이지 전체 감싸개라 이름을 나눈다) */
.legal h3 { font-size: var(--t-h3); margin: 40px 0 11px; }
.legal > h3:first-child { margin-top: 0; }
.legal p { font-size: var(--t-sm); color: var(--dim); margin-bottom: 13px; max-width: var(--measure); }
.legal p strong { color: var(--ink); }
.legal .list { margin-bottom: 18px; }
/* 초안 표시 — 공개 전에 반드시 채워야 하는 자리.
   눈에 걸리지 않으면 그대로 게시되기 때문에 색을 쓴다.
   파일 머리 원칙 1이 열거한 색 예외 셋 중 (가). 나머지는 --mark 와 --accent-*.
   한동안 "여기만 무채색 규칙에서 벗어난다"라고 적혀 있었는데, 그때도 이미
   --mark가 노랑을 쓰고 있었다. 틀린 주석은 없느니만 못하다. */
.todo { background: #f6edc4; padding: 1px 6px; color: var(--ink); font-weight: 600; }

/* 지금 보고 있는 페이지 */
.nav-links > a[aria-current] { color: var(--ink); border-bottom-color: var(--rule-strong); }

/* ============================================================
   반응형 — 레일은 좁혀도 없애지 않는다. 줄이 이 페이지의 뼈대다.
   ============================================================ */

/* ── 넓은 화면 · 두 폭 ────────────────────────────────────────
   괘선을 가진 것(구분선 · 자료 · 공지 · 표 · 파트너)은 단을 꽉 채워
   오른쪽 끝을 서로 공유하고 — 그 끝은 네비와 푸터의 오른쪽 끝과도 같은 자리다 —
   괘선 없는 산문만 --measure로 좁힌다. 읽는 글과 훑는 자료가 구분되고
   섹션마다 들고 나는 리듬이 생긴다. 정렬은 그대로 왼쪽이다 —
   왼쪽 끝이 흔들리면 풍선 줄도 라벨 열도 기준을 잃는다.

   901px 아래로는 한 폭으로 되돌린다. 그 밑에서는 두 폭의 차가 수십 px까지
   줄어 리듬이 아니라 어긋난 괘선으로 보인다. 경계에서 약 120px, 1040px 위로는
   272px가 벌어진다. 폭 대비는 남는 자리가 있을 때만 쓸 수 있는 장치다.
   이 블록이 통째로 빠져도 페이지는 한 폭으로 멀쩡히 선다. */
@media (min-width: 901px) {
  .blk > p.lede,
  .foot-note,
  .hero-note { max-width: var(--measure); }
}

@media (max-width: 900px) {
  .orgs { grid-template-columns: 1fr; gap: 32px; }
  .foot-grid { grid-template-columns: 1fr 1fr; }
  /* 세 칸이 각각 210px 밑으로 내려가면 제목이 두 줄로 꺾인다. 두 칸까지만. */
  .notes { --n: 2; }
}
@media (max-width: 720px) {
  /* 크기만 줄이면 매듭 위치와 줄 시작점은 계산으로 따라온다 */
  :root { --rail: 58px; --string-x: 20px; --bal-w: 29px; --bal-h: 40px; }
  .blk { padding: 60px 0; }
  .hero { padding: 68px 0 62px; }
  /* 좁은 화면에서는 쉼표 줄바꿈을 걷는다. 둘째 줄에 필요한 폭이 단보다 넓어
     그대로 두면 거기서 또 접혀 석 줄이 되고, 대회 이름이 다시 가운데서 잘린다.
     balance에 맡기면 두 줄로 고르게 나누고 이름을 한 줄에 붙여 둔다. */
  .hero-slogan br { display: none; }
  .hero-slogan { text-wrap: balance; }
  .phead { padding: 68px 0 50px; }
  /* 예전에는 여기서 윗변을 칸마다에서 묶음 전체로 옮겨야 했다 — 한 칸으로 접히면
     칸마다의 1px 괘선이 제각기 제 폭의 가로줄 셋이 됐기 때문이다.
     이제 띠는 처음부터 묶음의 것이라 접혀도 옮길 것이 없다. 칸 수와 간격만 바꾼다.
     (그 논리는 선에만 해당한다. 면 셋이 쌓인 것은 떠도는 가로줄 셋으로 읽히지 않는다.) */
  .notes { --n: 1; gap: 34px; }
  /* 차례 묶음은 어느 폭에서나 세로라 접을 것이 없다. 숫자단만 좁힌다. */
  .rank > li { padding: 13px 0 17px 56px; }   /* 56 = 6 + 14 + 32 + 4 */
  .rank > li::before { left: 20px; top: 12px; font-size: 1.12rem; }
  .pair { grid-template-columns: 1fr; gap: 32px; }
  /* 세 칸을 375px에 밀어 넣으면 "PLATINUM · TITLE PARTNER"가 세 줄로 꺾이고
     핵심 구성 칸은 두 단어마다 끊긴다. 가로 스크롤도 답이 아니다 — 표 하나 때문에
     읽는 방향이 바뀐다. 한 행을 한 덩이로 세워 위에서 아래로 읽게 한다.
     머리글은 각 칸이 이미 스스로를 설명하므로 통째로 걷어낸다(아래 .tiers thead). */
  .tiers, .tiers tbody, .tiers tr, .tiers td { display: block; width: auto; }
  .tiers tr { padding: 18px 0; border-bottom: 1px solid var(--rule); }
  /* 윗변은 두지 않는다 — 도입문 아래 .blk-rule이 이미 이 표의 윗변이다.
     둘 다 있으면 31px 간격으로 괘선이 두 줄 겹친다. 넓은 화면에는 없고
     좁은 화면에서만 나타나던 선이었다. .rows / .notices / .log 와 같이
     "아래 테두리만" 규칙을 따른다. */
  .tiers td { border: 0; padding: 0; }
  .tiers .tn { padding-right: 0; }
  .tiers .amt { margin: 9px 0 7px; padding-right: 0; }
  /* 세로 화면에서는 눕힌 사진이 띠처럼 보인다. 조금 세워 인물이 보이게 한다. */
  .stage { height: auto; aspect-ratio: 4 / 3; min-height: 0; }
  /* 아래 한 줄(출처와 멈춤 단추)만큼 워드마크를 올려 자리를 비운다. */
  .stage-mark { left: calc(20px + var(--rail)); bottom: 52px; }
  /* 넘김 표시가 사진 밖으로 내려가면서 이 줄에는 출처와 멈춤 단추만 남았다.
     좁은 화면에서도 둘은 한 줄에 들어가므로 세로로 쌓지 않는다. */
  .stage-bar { right: 20px; bottom: 16px; gap: 8px 14px; }
  /* 좁은 화면에서는 머리글을 접근성 트리에서도 걷어낸다. 화면 밖으로만 밀면
     칸마다 "티어 금액 기준 핵심 구성"이 먼저 읽혀 순서가 어지러워진다. */
  .tiers thead { display: none; }
  .list--two { column-count: 1; }
  .rows--wide dt { flex: none; }
  .container { padding: 0 20px; }
  footer .container { padding-left: calc(20px + var(--rail)); }
  .rows > div, .notices > li { flex-direction: column; gap: 4px; }
  .rows dt, .notices time { flex: none; }
  /* 좁은 화면에서는 같은 막대를 세로로 세운다.
     여섯 칸을 2~3열 격자로 접으면 읽는 순서가 꺾여 선형성이 깨진다. */
  .track { grid-template-columns: 1fr; gap: 0; }
  .track li {
    padding: 9px 0 9px 15px;
    border-top: 0; border-left: 3px solid var(--rule);
  }
  .track li.done { border-left-color: var(--ink); }
  .track li.now  { border-left-color: var(--mark); }
  .track .mark { display: inline; margin: 0 0 0 9px; }
}
/* ── 넘김 표시가 들어오면서 좁아진 자리 ─────────────────────
   표시가 출처 줄에 합류하면 그 줄이 왼쪽으로 134px + 18px 더 자란다.
   721~860px 구간에서 그 줄이 워드마크와 가로로 부딪히므로, 워드마크를 올려
   세로로 갈라 놓는 분기점을 720 → 860px 로 앞당긴다.
   (위 720px 블록 뒤에 와야 한다. 같은 속성을 다시 적는 자리라 차례가 결정한다.) */
@media (max-width: 860px) {
  .stage-mark { bottom: 52px; }
  .stage-bar  { bottom: 16px; }
}
@media (max-width: 720px) {
  .stage-nav { --seg: 18px; }    /* 걸음 24px → 누름 영역 24×27px, 여전히 24px 이상 */
  .stage-bar { gap: 8px 16px; }  /* 멈춤 단추와의 틈 16 − 3 − 9 = 4px */
}
/* 367px 은 눈대중이 아니다. 한 줄에 필요한 폭은
   출처 194.1 + 열간격 16 + 막대 114 + 열간격 16 + 단추 7.5 = 347.6px 이고,
   오른쪽 여백 20px 을 더하면 창 폭 368px 에서 넘친다. 375px 은 7.4px 남기고
   아직 들어가므로 — 흔한 휴대폰 폭이다 — 분기를 그 아래로 내렸다.
   그보다 좁으면 어차피 접히니, 어정쩡하게 접히게 두지 말고 출처를 제 줄로 내린다.

   여유가 7.4px 뿐이라 Pretendard 가 안 떠서 대체 글꼴로 그려지면 375px 에서도
   접힐 수 있다. 그때는 이 분기가 걸리지 않아 워드마크와 겹친다 —
   출처 문구를 손보거나 열간격을 줄이게 되면 이 값을 다시 재야 한다. */
@media (max-width: 367px) {
  .stage-credit { flex-basis: 100%; text-align: right; }
  .stage-mark { bottom: 86px; }   /* 두 줄이 된 만큼 워드마크를 올려 겹침을 없앤다 */
}

@media (max-width: 560px) {
  .nav-links > a { display: none; }
  .navmenu { display: block; }
  .foot-grid { grid-template-columns: 1fr; gap: 26px; }
}

@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  /* balloon.js가 시차를 아예 걸지 않는다. 레이어도 필요 없으니 정수 픽셀에 또렷하게 놓는다. */
  .balloon { transform: none; will-change: auto; }
  .paths > a, .act, .link, .nav-links > a { transition: none; }
  /* 움직임만 없앤다. 되돌리는 자리는 0이 아니라 쉴 때의 12px이다 —
     0으로 되돌리면 면이 깔릴 자리가 사라져 글자가 면에 맞닿는다. */
  .paths > a:hover,
  .paths > a:focus-visible { padding-left: 12px; }
  /* 띠는 남긴다 — 가리키는 곳을 알려 주는 표시이지 장식이 아니다.
     없애는 것은 쓸려 나가는 움직임뿐이고, 띠는 그 자리에서 곧바로 켜진다. */
  .paths > a::after { transition: none; }
  /* 사진은 gallery.js가 자동으로 넘기지 않는다. 사람이 눌러 넘길 때만 바뀌고,
     그때도 겹쳐 사라지지 않고 곧바로 바뀐다.
     세 선택자를 함께 적는다 — @media 는 특정도를 올려 주지 않으므로
     .stage-frame 하나만 적으면 .is-on/.is-fading(한 단 높다)이 이긴다. */
  .stage-frame, .stage-frame.is-on, .stage-frame.is-fading { transition: none; }
  /* 잉크도 미끄러지지 않고 곧바로 자리를 옮긴다. 이 표시에는 저 혼자 도는
     애니메이션이 없어서, 장이 안 넘어가면 움직임도 전부 선다. */
  .stage-now, .stage-nav button { transition: none; }
}

/* ============================================================
   인쇄 · 강제 색상 — 띠와 면은 background로 그린다. 둘 다 제 방식으로 사라진다.

   인쇄: 브라우저 기본값이 배경을 버리므로, 색을 칠하는 세 군데만 집어서 살린다.
   *에 걸지는 않는다 — 종이색(#fbfbf7)까지 찍히면 흰 종이에 아이보리 판을
   한 장 까는 꼴이 된다. 덱은 슬라이드라 *에 걸어도 되지만 이건 문서다.
   드라이버가 무시해도 뜻은 남는다 — .rank는 01/02/03과 자리와 잉크 3단이,
   .notes는 제목과 열이 이미 말하고 있다.

   강제 색상(윈도 고대비): UA가 배경 이미지를 무조건 지운다. exact로도 못 살린다.
   그대로 두면 .notes가 장식을 통째로 잃어 지금(1px 괘선)보다 나빠지므로,
   여기서만 띠를 원래의 괘선으로 되돌린다. background-color는 배경 이미지와 달리
   시스템 색으로 남으므로 세로 띠는 막대 모양을 유지한다.
   ============================================================ */
@media print {
  .notes,
  .rank::before,
  .rank > li:first-child {
    -webkit-print-color-adjust: exact;
    print-color-adjust: exact;
  }
  .notes, .rank > li { break-inside: avoid; }
}
@media (forced-colors: active) {
  .notes {
    padding-top: 15px;
    background-image: none;
    border-top: 1px solid CanvasText;
  }
  .rank::before { background-image: none; background-color: CanvasText; }
  .rank > li:first-child { background-image: none; }
  /* 칸 전체를 덮는 면이라 시스템 색으로 채우면 그 위의 글자가 묻힌다.
     (Highlight 를 쓰려면 글자도 HighlightText 로 함께 뒤집어야 하는데,
      가리킨 칸 하나 때문에 글자색 체계를 통째로 두 벌 만들 값이 없다.)
     여기서는 면을 그리지 않는다. 초점 테두리와 밀리는 글자가 이미 자리를 말한다. */
  .paths > a::after { background-image: none; }
}
