/* Studio Oriens — 모노크롬 5단계. 색은 전부 토큰으로만 쓴다. */

/* ---------- 폰트 ---------- */
/* Pretendard (SIL OFL 1.1, © 2023 길형진) 셀프호스팅.
   이 사이트가 실제로 쓰는 335자만 남긴 서브셋이라 웨이트당 27KB 다 (원본 1.5MB).
   ⚠️ public/ 의 텍스트를 고치면 `python tools/subset-fonts.py` 를 다시 돌릴 것.
      서브셋에 없는 글자는 폴백 폰트로 튄다.
   ⚠️ Google Fonts CDN 을 쓰지 않는 이유는 성능이 아니라 법이다 —
      이용자 IP 가 Google 로 가면 개인정보처리방침의 국외이전 표에 항목이 하나 더 는다. */

@font-face {
  font-family: "Pretendard";
  src: url("/fonts/pretendard-400.woff2") format("woff2");
  font-weight: 400;
  font-style: normal;
  font-display: swap;
}

@font-face {
  font-family: "Pretendard";
  src: url("/fonts/pretendard-500.woff2") format("woff2");
  font-weight: 500;
  font-style: normal;
  font-display: swap;
}

@font-face {
  font-family: "Pretendard";
  src: url("/fonts/pretendard-700.woff2") format("woff2");
  font-weight: 700;
  font-style: normal;
  font-display: swap;
}

:root {
  --bg:    #F2F2F2;
  --fg:    #111111;
  --muted: #888888;
  --line:  #D9D9D9;
  --sub:   #333333;
  /* 게임 섹션 전용 액센트. 스튜디오 셸(헤더·푸터·법률)로 새어 나가지 않게 한다. */
  --gold:  #A8842C;

  /* 컨테이너를 본문 가독폭에 맞춘다. 이 값이 곧 구분선·표·그리드의 폭이라
     "텍스트는 좁은데 선만 길게 뻗는" 어긋남이 생기지 않는다. */
  --wrap: 44rem;
  --gap: clamp(2.75rem, 6vw, 4.5rem);
  /* 히어로 하단만 크게 연다. 모든 섹션이 같은 여백이면 페이지에 형태가 없다. */
  --gap-hero: clamp(4rem, 8vw, 6.5rem);

  /* 모션: 이징을 둘로 묶는 게 절제의 실행이다. 오버슈트 계열은 쓰지 않는다. */
  --ease-out: cubic-bezier(0.2, 0, 0, 1);
  --ease-std: cubic-bezier(0.4, 0, 0.2, 1);
  --dur-1: 140ms;
  --dur-2: 160ms;
  --dur-3: 420ms;
}

@media (prefers-color-scheme: dark) {
  :root {
    --bg:    #111111;
    --fg:    #F2F2F2;
    --muted: #888888;
    --line:  #333333;
    --sub:   #D9D9D9;
    --gold:  #D4B15E;
  }
}

*, *::before, *::after { box-sizing: border-box; }

html { -webkit-text-size-adjust: 100%; }

body {
  margin: 0;
  background: var(--bg);
  color: var(--fg);
  font-family: Pretendard, -apple-system, BlinkMacSystemFont, system-ui,
               "Segoe UI", "Apple SD Gothic Neo", "Malgun Gothic", sans-serif;
  font-size: clamp(1rem, 0.95rem + 0.25vw, 1.0625rem);
  line-height: 1.7;
  letter-spacing: -0.005em;
  -webkit-font-smoothing: antialiased;
}

/* ---------- 레이아웃 ---------- */

/* main.legal 이 빠지면 법률 페이지 본문이 화면 끝에 붙는다 — 반드시 함께 둘 것 */
.site-header,
main > section,
main.legal,
.site-footer {
  width: min(100% - 2.5rem, var(--wrap));
  margin-inline: auto;
}

main > section { padding-block: var(--gap); }

/* 히어로만 상단을 조이고 하단을 연다. 로고–아이브로–h1 이 한 덩어리가 된다. */
.hero { padding-block: clamp(2.25rem, 5vw, 3.25rem) var(--gap-hero); }

/* ---------- 지평선 룰 ---------- */
/* 구조선을 마크의 휜 지평선으로 교체한다. 브랜드 가이드가 "직선이 아닌 것"을
   마크의 성격으로 못 박았는데 페이지의 모든 선이 직선이면 그 주장이 죽는다.
   mask-size 의 y 를 14px 로 고정해 솟음 10px·두께 1px 가 폭과 무관하게 유지된다.
   표의 선은 직선 그대로 둔다 — 데이터 표의 선이 휘면 렌더링 버그로 읽힌다. */

main > section + section,
.site-footer {
  border-top: 0;
  position: relative;
}

main > section + section::before,
.site-footer::before {
  content: "";
  position: absolute;
  inset-inline: 0;
  top: -13px;                          /* 끝점 잉크(viewBox y=13)가 원래 룰 자리에 앉는다 */
  height: 14px;
  background-color: var(--line);
  -webkit-mask: url(/assets/horizon.svg) no-repeat center / 100% 14px;
          mask: url(/assets/horizon.svg) no-repeat center / 100% 14px;
}

/* ---------- 해 캡 ---------- */
/* 마크 자체의 규칙이 "돔 밑선 = 지평선 정점"(둘 다 y 51.9, 실측 확인)이다.
   그 관계를 페이지 스케일로 재현한다. hero(선언)와 game(제품) 사이에서 해가 뜬다.
   ⚠ 페이지에 단 하나. --fg 로 칠하지 말 것. 40px 를 넘기지 말 것.
      셋 중 하나만 어겨도 헤더 로고와 경쟁하는 "두 번째 로고"가 된다. */

#seed-money::after {
  content: "";
  position: absolute;
  left: 33.33%;                        /* horizon.svg 의 정점 x = 36/108 */
  bottom: 100%;
  transform: translate(-50%, -10px);   /* -10px = 룰의 솟음 */
  width: 40px;
  aspect-ratio: 113 / 51.9;
  background-color: var(--muted);      /* 룰(--line)보다 한 단 진하게 = 초점 */
  -webkit-mask: url(/assets/sun.svg) no-repeat center / contain;
          mask: url(/assets/sun.svg) no-repeat center / contain;
  pointer-events: none;
}

/* ---------- 로고 ---------- */
/* mask 로 그려서 currentColor 를 따라가게 한다 → 다크모드 자동, 파일은 한 벌 */

.brand {
  display: block;
  width: clamp(120px, 14vw, 152px);
  aspect-ratio: 209.57 / 138.8;
  background-color: currentColor;
  -webkit-mask: url(/assets/logo.svg) no-repeat center / contain;
          mask: url(/assets/logo.svg) no-repeat center / contain;
}

.site-header { padding-block: clamp(2rem, 5vw, 3.5rem) 0; }

/* ---------- 타이포 ---------- */

h1, h2 {
  letter-spacing: -0.024em;
  font-weight: 700;
  margin: 0;
  text-wrap: balance;
}

/* 704px 컨테이너를 넘겨 2행이 되게 한다. 2행 디스플레이 타입은 그 자체로 형태가
   되고, 그게 이 페이지에 없던 초점이다. */
h1 {
  font-size: clamp(2.25rem, 1.1rem + 5.6vw, 3.75rem);
  line-height: 1.08;
  letter-spacing: -0.03em;
}

h2 {
  font-size: clamp(1.5rem, 1.05rem + 2.2vw, 2.125rem);
  line-height: 1.12;
}

/* 폭은 컨테이너가 정한다. 여기서 또 제한하면 요소마다 폭이 달라진다. */
p { margin: 0; }
p + p, h2 + p { margin-top: 1.25rem; }
h1 + p { margin-top: 1.875rem; }   /* h1 의 0.5em — 디스플레이 타입에는 20px 로 부족 */

.eyebrow, .section-label {
  margin: 0 0 0.625rem;             /* 라벨은 제목에 붙는다 (16 → 10px) */
  font-size: 0.75rem;
  font-weight: 500;
  text-transform: uppercase;
  color: var(--muted);
}

/* 워드마크 실측 자간(studio +0.328em)의 절반쯤까지 당겨 로고와 같은 목소리를 낸다.
   ⚠ 한글에는 절대 적용하지 말 것 — 글자가 흩어져 깨져 보인다. 그래서 셀렉터가 좁다. */
.eyebrow, .section-label, .specs dt { letter-spacing: 0.2em; }

.lede, .game-lede {
  font-size: clamp(1.125rem, 1rem + 0.55vw, 1.25rem);
  line-height: 1.5;                 /* 본문 1.7 과 분리 */
  color: var(--sub);
  max-width: 34rem;
  text-wrap: pretty;
}

/* 각주라 컨테이너 폭을 그대로 쓴다. 34rem 을 걸면 "kind." 한 단어만 넘어간다. */
.note {
  margin-top: 2rem;
  font-size: 0.875rem;
  color: var(--muted);
}

/* ---------- 광선 틱 ---------- */
/* 마크의 가장 낮은 광선(23.2°)을 라벨 마커로. 길이:획 = 26.1:4.76 = 5.48:1 유지.
   background 가 currentColor 라 .game .section-label 의 골드를 자동으로 타고,
   셸로 골드가 새어나갈 경로가 CSS 상 존재하지 않는다. */

.eyebrow::before,
.section-label::before {
  content: "";
  display: inline-block;
  width: 8.22px;
  height: 1.5px;
  margin-right: 0.75em;
  vertical-align: 0.32em;
  background: currentColor;
  transform: rotate(-23.2deg);
}

/* ---------- 게임 섹션 ---------- */

.game .section-label { color: var(--gold); }

/* 스펙을 페이지의 유일한 '촘촘한 구간'으로 만든다. 미니멀에서 여백이 의도로 읽히려면
   어딘가에 밀도가 있어야 한다. 상단만 직선으로 두는 이유: 섹션 상단에 이미 곡선+해가
   있어 40px 아래 또 곡선이 오면 초점이 분산된다. */
.specs {
  display: block;
  margin: clamp(2.5rem, 5vw, 3.25rem) 0 0;
  padding-top: 0;
  border-top: 1px solid var(--line);
}

.specs > div {
  display: grid;
  grid-template-columns: minmax(6.5rem, 9rem) 1fr;
  gap: 0 1.5rem;
  align-items: baseline;
  margin: 0;
  padding-block: 0.85rem;
  border-bottom: 1px solid var(--line);
}

.specs > div:last-child { border-bottom: 0; }

.specs dt {
  font-size: 0.6875rem;
  font-weight: 500;
  text-transform: uppercase;
  color: var(--muted);
}

.specs dd {
  margin: 0;
  line-height: 1.45;                /* 1.7 은 한 줄 데이터에 과하다 */
  color: var(--fg);
}

@media (max-width: 30rem) {
  .specs > div { grid-template-columns: 1fr; gap: 0.15rem; padding-block: 0.75rem; }
}

/* ---------- 링크 ---------- */

a { color: inherit; }

/* 링이 7px 밖에서 조여 앉아 시선을 도착점으로 끈다.
   색·굵기는 첫 프레임부터 완전하다 — 접근성 장치를 늦게 보이게 하면 안 된다.
   transition 이 아니라 animation 인 이유: 포커스가 A→B 로 점프할 때 매번 재생된다. */
@keyframes focus-settle {
  from { outline-offset: 7px; }
}

a:focus-visible {
  outline: 2px solid var(--fg);
  outline-offset: 3px;
  border-radius: 2px;
  animation: focus-settle var(--dur-1) var(--ease-out);
}

@media (hover: hover) {
  .mail, .site-footer a, .brand, .legal .back {
    transition: color var(--dur-1) var(--ease-std),
                text-decoration-color var(--dur-1) var(--ease-std),
                opacity var(--dur-2) var(--ease-std);
  }
}

/* 누름은 즉시, 복귀만 이징한다. 누름에 duration 을 주면 지연으로 느껴진다. */
.mail:active, .site-footer a:active, .brand:active, .legal .back:active {
  opacity: 0.55;
  transition-duration: 0ms;
}

.mail {
  display: inline-block;
  margin-top: 0.35rem;
  font-size: clamp(1.25rem, 0.85rem + 1.8vw, 1.75rem);
  line-height: 1.15;
  text-decoration-thickness: 1px;
  text-underline-offset: 0.22em;
  text-decoration-color: var(--muted);
}

/* 유일한 CTA 가 호버에 물러나면 어포던스가 거꾸로다. 또렷해지는 방향으로. */
.mail:hover {
  color: var(--fg);
  text-decoration-color: var(--fg);
}

/* ---------- 푸터 ---------- */

.site-footer {
  display: flex;
  flex-wrap: wrap;
  gap: 0.75rem 2rem;
  justify-content: space-between;
  align-items: baseline;
  padding-block: 2.5rem 3.5rem;
  font-size: 0.875rem;
  color: var(--muted);
}

.site-footer a { text-decoration-color: var(--line); }
.site-footer a:hover { color: var(--fg); text-decoration-color: var(--fg); }

/* ---------- 법률 문서 ---------- */

/* 홈 h1(60px) 과 격차를 둬 "여긴 선언, 저긴 문서"라는 위계를 만든다 */
.legal { padding-block: var(--gap); }
.legal h1 { font-size: clamp(1.625rem, 1.25rem + 1.7vw, 2.25rem); line-height: 1.2; }

.legal h2 {
  margin-top: 2.75rem;
  font-size: clamp(1.0625rem, 0.98rem + 0.45vw, 1.25rem);
  line-height: 1.4;
  letter-spacing: -0.015em;
}

.legal h1 + p, .legal h2 + p { margin-top: 1.25rem; }
.legal ul { padding-left: 1.2rem; margin: 1.25rem 0 0; }
.legal li + li { margin-top: 0.4rem; }

.legal .updated {
  margin-top: 0.75rem;
  font-size: 0.875rem;
  color: var(--muted);
}

/* 표: 좁은 화면에서 페이지가 아니라 표 자체가 가로 스크롤되게 한다 */
.table-wrap {
  overflow-x: auto;
  margin-top: 1.25rem;
  border: 1px solid var(--line);
  border-radius: 4px;
}

table {
  border-collapse: collapse;
  width: 100%;
  min-width: 30rem;
  font-size: 0.875rem;
  line-height: 1.6;
}

th, td {
  padding: 0.65rem 0.85rem;
  text-align: left;
  vertical-align: top;
  border-bottom: 1px solid var(--line);
}

/* 표의 좌측 열은 전부 짧은 라벨이라 줄바꿈을 막는다 ("문의 응/대" 처럼 끊기는 것 방지).
   넘치면 .table-wrap 이 가로 스크롤로 받는다. */
tbody th[scope="row"] {
  font-weight: 500;
  color: var(--muted);
}

tbody th[scope="row"],
tbody td:first-child { white-space: nowrap; }

/* ⚠ 한글 헤더다 — 와이드 트래킹을 주면 글자가 흩어진다. 0.08em 을 넘기지 말 것. */
thead th {
  font-size: 0.75rem;
  letter-spacing: 0.08em;
  color: var(--muted);
  white-space: nowrap;
}

tbody tr:last-child td,
tbody tr:last-child th { border-bottom: 0; }

.table-wrap + p, .legal ul + p { margin-top: 1.25rem; }

.legal .back {
  display: inline-block;
  margin-top: 3.5rem;
  font-size: 0.875rem;
  color: var(--muted);
}

.legal .back:hover { color: var(--fg); }

/* ---------- 등장 ---------- */
/* 스크롤 트리거가 아니라 로드 1회. 관찰자도 JS 도 필요 없다.
   ⚠ 반드시 이 패턴이어야 한다: 기본 상태가 곧 최종 상태이고 키프레임의 from 에서만
      벗어난다. opacity:0 을 기본값에 두면 아래 reduced-motion 차단이 걸리는 순간
      콘텐츠가 영영 안 보인다. 여기서는 애니메이션이 죽어도 완성된 페이지가 남는다.
   헤더는 제외한다 — 로고는 페이지 전환에서 고정되는 요소라 등장도 하지 않는 게 일관된다. */

@keyframes rise-in {
  from { opacity: 0; transform: translateY(4px); }
}

main > section,
main.legal {
  animation: rise-in var(--dur-3) var(--ease-out) both;
}

.hero      { animation-delay: 0ms; }
.game      { animation-delay: 60ms; }
.contact   { animation-delay: 120ms; }
main.legal { animation-delay: 0ms; }   /* 문서는 조각내지 않고 한 덩어리로 */

/* ---------- 페이지 전환 ---------- */
/* 지금 가장 거친 순간이 여기다. 다크모드에서 흰 페인트 플래시가 눈을 찌른다.
   셸(로고·푸터)은 두 페이지가 동일하므로 붙잡아 두면 "문서 두 장"이 "한 사이트"가 된다.
   미지원 브라우저는 오늘과 똑같이 동작한다 — 다운사이드가 구조적으로 0이다. */

@view-transition { navigation: auto; }

.brand       { view-transition-name: brand; }
.site-footer { view-transition-name: shell-footer; }

::view-transition-old(root),
::view-transition-new(root) {
  animation-duration: 220ms;
  animation-timing-function: var(--ease-std);
}

::view-transition-group(brand) {
  animation-duration: 260ms;
  animation-timing-function: var(--ease-out);
}

@media (prefers-reduced-motion: reduce) {
  * { animation: none !important; transition: none !important; }

  /* ⚠ 위의 * 는 의사요소에 매칭되지 않는다 — View Transition 은 따로 꺼야 한다 */
  @view-transition { navigation: none; }

  ::view-transition-old(root),
  ::view-transition-new(root),
  ::view-transition-group(brand),
  ::view-transition-group(shell-footer) { animation: none !important; }
}
