/* 소비페이스 웹사이트 스타일 정본
   제약: CSP style-src 'self' + font-src 'self'(인라인 스타일 금지, 외부 CDN 금지),
   빌드 도구 없음, JS 없음, 외부 요청 0, 라이트·다크 대응.
   색 토큰은 앱의 BudgetTheme 자산 값을 그대로 옮긴다.

   이 파일은 두 종류의 페이지를 담는다.
   1. 랜딩(`/`) — 풀블리드 구획. body 패딩 없이 `.wrap`이 여백을 맡는다.
   2. 문서 페이지(`/support/`·`/privacy/`·`/terms/`·404) — 전부 `.page` 안에 있다.
   문서 페이지의 요소 선택자(h1·p·dt 같은 것)는 반드시 `.page` 스코프에 둔다.
   전역에 두면 랜딩의 `.ledger dt`나 `.plan-months` 같은 요소에 얹혀 여백이 어긋난다. */

/* 펴진고딕 — Pretendard의 곡선을 직선으로 펼친 파생 폰트(SIL OFL).
   직선적이고 중립적인 획이 이 페이지의 주제인 '계산'과 맞는다.
   3종만 자체 호스팅한다. 공식 배포 CSS는 jsDelivr를 참조하므로 쓰지 않는다 —
   방문자 IP가 제3자에게 전달되면 이 앱의 개인정보 주장이 깨진다.

   한글은 라틴보다 글자당 획이 많아 같은 굵기에서 훨씬 무겁게 읽힌다.
   그래서 400 / 500 / 700을 쓴다. 600 / 800 조합은 제목이 뭉친다. */
@font-face {
  font-family: "Pyeojin Gothic";
  src: url("/assets/fonts/PyeojinGothic-Regular.woff2") format("woff2");
  font-weight: 400;
  font-style: normal;
  font-display: swap;
}

@font-face {
  font-family: "Pyeojin Gothic";
  src: url("/assets/fonts/PyeojinGothic-Medium.woff2") format("woff2");
  font-weight: 500;
  font-style: normal;
  font-display: swap;
}

@font-face {
  font-family: "Pyeojin Gothic";
  src: url("/assets/fonts/PyeojinGothic-Bold.woff2") format("woff2");
  font-weight: 700;
  font-style: normal;
  font-display: swap;
}

:root {
  color-scheme: light dark;

  /* 앱 AccentLavender */
  --brand: #6c5ce7;
  /* 앱 AppInk / AppCanvas / AppSurface */
  --ink: #2b2440;
  --ink-muted: #5d5570;
  /* 문장으로 읽히는 옅은 텍스트용. --ink-faint는 본문 대비(4.5:1)에 못 미친다.
     캔버스 위 4.96:1, 서피스 위 5.36:1. 한 단계 더 옅은 인상은 유지한다. */
  --ink-note: #6f6685;
  /* 장식 전용. 도해 안의 자리표시자처럼 aria-label이 따로 읽어 주는 곳에만 쓴다.
     문단이나 라벨에 쓰지 않는다 — 캔버스 위 3.30:1로 본문 대비에 미달한다. */
  --ink-faint: #8b83a3;
  --canvas: #f7f5fb;
  --surface: #ffffff;
  --rule: #ded9ec;

  /* 영수증 종이와 그 위의 잉크. 종이는 히어로 배경 위에 올라가므로
     본문 배경 기준으로 맞춘 --ink-* 를 그대로 쓰면 다크에서 대비가 깨진다. */
  --paper: #ffffff;
  --paper-rule: #ded9ec;
  --paper-muted: #5d5570;
  --paper-faint: #8b83a3;
  --paper-shadow: 0 1.25rem 2.5rem rgb(20 14 40 / 26%);

  /* 히어로 배경 — 앱 heroGradient와 같은 팔레트에서 한 단계 어두운 톤을 쓴다.
     앱의 라이트 값(#7A6BEE→#5B4BD6)은 흰 텍스트와 4.99:1이어서 큰 제목은
     통과하지만 투명도를 준 부가 문구가 AA에 미달한다. 이 값은 6.36:1이다. */
  --hero-bg-start: #6a5bd8;
  --hero-bg-end: #4a3cb8;

  /* 앱이 이미 두 의무에 부여한 색 — 임의로 고르지 않는다.
     InstallmentApricot / CatTeal */
  --installment: #d97b33;
  --recurring: #2b9c96;

  /* 봉투 색 — 앱 자산 CatMint / CatSky / CatApricot.
     accent 채움 위 전경은 라이트 흰색, 다크 딥 잉크(앱 OnAccent). */
  --cat-food: #0e9f76;
  --cat-transit: #3e97d9;
  --cat-living: #d97b33;
  --on-accent: #ffffff;

  /* 앱 heroGradient — 앱 화면 카드 재현용 */
  --hero-start: #7a6bee;
  --hero-end: #5b4bd6;

  /* 앱 BudgetTheme.warning(시스템 red) */
  --status-warning: #ff3b30;

  /* 좁은 화면은 읽기 폭(46rem)에 맞춘 한 단. 데스크톱에서는 아래 미디어 쿼리로
     68rem까지 넓혀 제목과 도해를 나란히 세운다. */
  --shell: 46rem;
  --gutter: clamp(1.25rem, 3vw, 2rem);
  --gap-section: clamp(4.5rem, 11vw, 8rem);
  --gap-column: clamp(2.5rem, 5vw, 3.5rem);

  --font: "Pyeojin Gothic", -apple-system, BlinkMacSystemFont,
    "Apple SD Gothic Neo", "Segoe UI", "Malgun Gothic", system-ui, sans-serif;

  /* 기본 CSS 이징은 약하다. 강한 커브를 쓴다. */
  --ease-out: cubic-bezier(0.23, 1, 0.32, 1);
}

@media (prefers-color-scheme: dark) {
  :root {
    --brand: #a29bfe;
    --ink: #eae6f4;
    --ink-muted: #b3abc9;
    /* 캔버스 위 5.58:1, 서피스 위 5.00:1. 다크는 서피스가 더 밝아 그쪽이 하한이다. */
    --ink-note: #918aa8;
    --ink-faint: #7d7496;
    --canvas: #16131f;
    --surface: #211d2e;
    --rule: #322b45;

    /* 히어로 배경(#2E2550→#1B1533)보다 확실히 밝아야 종이가 위에 놓인 것으로
       읽힌다. 앱 AppSurface(#211D2E)를 그대로 쓰면 배경보다 어두워 파묻힌다.
       이 값 위에서 잉크는 9.47:1, 라벤더 합계는 4.81:1이다. */
    --paper: #3b3260;
    --paper-rule: #554a80;
    --paper-muted: #c0b8d6;
    --paper-faint: #a9a0c3;
    /* 어두운 배경에서는 보라 그림자가 보이지 않는다. 검정으로 바꾼다. */
    --paper-shadow: 0 1.5rem 3rem rgb(0 0 0 / 52%);

    /* 다크에서 밝은 라벤더 블록은 눈부시다. 깊은 보라로 낮춘다. */
    --hero-bg-start: #2e2550;
    --hero-bg-end: #1b1533;

    --installment: #f2a96a;
    --recurring: #63cfc9;

    --cat-food: #5bd9af;
    --cat-transit: #7cc0f0;
    --cat-living: #f2a96a;
    --on-accent: #2b2440;

    --hero-start: #6a5bd8;
    --hero-end: #4a3cb8;

    --status-warning: #ff453a;
  }
}

*,
*::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 {
  margin: 0;
  background: var(--canvas);
  color: var(--ink);
  font-family: var(--font);
  font-size: 1rem;
  font-weight: 400;
  line-height: 1.7;
  word-break: keep-all;
  overflow-wrap: anywhere;
}

/* 배경은 화면 폭 전체로 깔고, 내용만 이 컨테이너 안에 세운다. */
.wrap {
  max-width: var(--shell);
  margin: 0 auto;
  padding: 0 var(--gutter);
}

/* 두 문장의 리듬을 보존한다. 좁은 화면에서는 각 문장 안에서만 줄이 접힌다. */
.line {
  display: block;
}

/* ── 표지 ───────────────────────────────────────────────
   첫 화면은 이름 한 줄과 앱 화면만 남긴다. 라벤더 히어로가 곧바로 이어지므로
   여기서 색을 쓰면 두 블록이 서로를 깎는다. 검정으로 두고 화면만 빛나게 한다. */

.cover {
  position: relative;
  display: flex;
  flex-direction: column;
  align-items: center;
  /* 배경은 안전 영역이 아니라 기기 세로를 채운다. `100svh`는 iOS Safari의 하단
     도구모음이 펼쳐진 높이라, 도구모음이 반투명하게 덮는 아래 띠에 다음 구획인
     라벤더 히어로가 비쳐 첫 화면이 잘린 것처럼 보였다. `100lvh`는 도구모음을 감춘
     높이 = 기기 세로이므로 표지가 화면 끝까지 이어진다.
     도구모음이 펼쳐진 동안 아래 `100lvh − 100svh`가 그 뒤로 들어가는 것은 의도다 —
     그 자리에 놓이는 것은 아래로 흘러 나가는 앱 화면뿐이고, 글과 버튼은 그보다
     위에 선다. 데스크톱에서는 lvh = svh = vh라 이 줄이 아무것도 바꾸지 않는다. */
  min-height: 100lvh;
  overflow: hidden;
  padding-top: clamp(2rem, 6vh, 4rem);
  /* 위쪽 절반은 검정 그대로 두고 아래에서 라벤더가 올라와 히어로로 이어진다.
     예전에는 앱 heroGradient 계열에서 가장 어두운 #17122e에서 멈췄다. 표지가 기기
     세로를 채우게 되면서 이 경계가 화면 안으로 들어왔으므로 히어로 색까지 잇는다.
     마지막 정지점은 히어로 그라데이션(135deg)의 시작과 끝을 72:28로 섞은 값이다.
     135deg에서 임의 점의 진행률은 (x + y) / (폭 + 높이)이므로 히어로 위쪽 가장자리는
     왼쪽 끝이 진행률 0(시작색), 오른쪽 끝이 폭 / (폭 + 높이)다. 한 색으로 양쪽을 다
     맞출 수 없고, 좌우 오차가 같아지는 지점은 그 절반이라 데스크톱 0.34, 폰 0.21로
     화면마다 다르다. 0.28은 그 사이에 두어 어느 쪽에서도 한쪽으로 몰리지 않게 한
     값이고, 경계에 남는 차이는 채널당 10 안팎이다.
     앱 화면이 이 선에서 잘려 나가는 것은 의도한 자름이므로 이음매를 완전히 지우지는
     않는다. */
  background: linear-gradient(
    180deg,
    #08060d 0%,
    #08060d 42%,
    #100c1f 70%,
    #17122e 86%,
    color-mix(in srgb, var(--hero-bg-start) 72%, var(--hero-bg-end)) 100%
  );
  color: #ffffff;
  text-align: center;
}

/* 위아래 auto 여백으로 남는 공간 한가운데에 세운다. 스크롤 신호와 화면은
   아래에 붙으므로, 화면 비율이 달라져도 글의 위치가 크게 흔들리지 않는다. */
/* 장식 — 앱이 다루는 물건을 선으로만 그린다. 면을 칠하면 검정 위에서 덩어리가
   생겨 글과 다투므로 stroke만 쓴다.

   흰색 10%는 배경(#08060d) 위에서 rgb(33,31,37)로 그려진다. 25단계 차이라 보이긴
   하지만 여전히 주변광 수준이라, 그 밝기로 읽히게 하려면 세 가지가 함께 가야 한다.
   1) 크기를 뷰포트에 묶는다. rem으로 고정하면 넓은 화면에서 캔버스만 커지고 도형은
      그대로라 가장자리에 흩어진 점이 된다.
   2) 가운데를 비우지 않는다. 이 밝기로는 글을 가릴 수 없으므로 글 뒤로 지나가도 된다.
   3) 큰 화면에서는 선을 굵힌다. 1.5px는 이 밝기에서 사라진다. */
.cover-decor {
  position: absolute;
  inset: 0;
  pointer-events: none;
}

.decor {
  position: absolute;
  fill: none;
  stroke: rgb(255 255 255 / 10%);
  stroke-width: 1.5;
  stroke-linecap: round;
  stroke-linejoin: round;
  vector-effect: non-scaling-stroke;
}

.decor * {
  vector-effect: non-scaling-stroke;
}

/* 기준선은 실제 그래프처럼 점선으로 둔다. 앱의 권장 추세선과 같은 역할이다. */
.decor-chart-base {
  stroke-dasharray: 2 8;
}

.decor-card {
  width: clamp(11rem, 19vw, 22rem);
}

.decor-chart {
  width: clamp(14rem, 26vw, 30rem);
}

.decor-coin {
  width: clamp(3.25rem, 7vw, 8rem);
}

/* 표지를 한 바퀴 두르는 배치. 화면(가운데 아래)에 가려지는 것은 가려진 채로 둔다. */
.decor-card--a {
  top: 4%;
  left: -5%;
  rotate: -14deg;
}

.decor-coin--a {
  top: 8%;
  right: 7%;
  width: clamp(5rem, 11vw, 12rem);
}

.decor-chart--a {
  top: 20%;
  left: 6%;
}

.decor-coin--b {
  top: 34%;
  right: 17%;
}

.decor-card--b {
  top: 45%;
  right: -7%;
  rotate: 11deg;
}

.decor-coin--c {
  bottom: 15%;
  left: 8%;
  width: clamp(4rem, 9vw, 10rem);
}

.decor-chart--b {
  bottom: 7%;
  right: 6%;
  scale: -1 1;
}

/* 큰 화면일수록 선이 가늘게 보인다. 굵기로 보정한다. */
@media (min-width: 60rem) {
  .decor {
    stroke-width: 2.5;
  }
}

/* 좁은 화면에서는 도형이 서로 겹쳐 무늬가 된다. 네 개만 남긴다. */
@media (max-width: 47.99rem) {
  .decor-card--b,
  .decor-chart--b,
  .decor-coin--c {
    display: none;
  }

  .decor-chart--a {
    top: 7%;
    left: 3%;
  }

  .decor-card--a {
    top: 21%;
    left: -12%;
  }

  .decor-coin--b {
    top: 40%;
    right: 12%;
  }
}

.cover-copy {
  position: relative;
  margin-block: auto;
}

/* 이름이 디스플레이를 맡고 설명은 한 단계 내려간다. 아이콘은 두지 않는다 —
   워드마크가 이 크기면 아이콘은 같은 말을 두 번 하는 장식이 된다. */
.cover-mark {
  margin: 0 0 clamp(0.75rem, 2.4vh, 1.25rem);
  font-size: clamp(2.375rem, 8.6vw, 4.25rem);
  font-weight: 700;
  line-height: 1.16;
  letter-spacing: -0.045em;
}

/* 이름보다 얇게 둔다. 설명은 설명일 뿐이고, 목소리는 이름이 낸다. */
.cover-line {
  margin: 0;
  /* 이름과의 크기 비를 2.1~2.3 사이로 잡는다. 굵기로 이미 층이 갈리므로
     크기까지 크게 벌리면 설명이 각주처럼 읽힌다. */
  font-size: clamp(1.125rem, 3.7vw, 1.875rem);
  font-weight: 400;
  line-height: 1.45;
  letter-spacing: -0.022em;
  color: rgb(255 255 255 / 78%);
}

.store-cta--cover {
  justify-content: center;
  margin-top: clamp(1.75rem, 5vh, 2.75rem);
}

.cover-status {
  margin: 0.875rem 0 0;
  font-size: 0.875rem;
  color: rgb(255 255 255 / 62%);
}

/* 표지가 끝이 아니라는 신호. 화면 위로 올려 두면 스크린샷과 겹쳐 읽히지 않으므로
   복사 아래, 스크린샷 위 자리를 따로 준다. */
.cover-scroll {
  /* 장식과 같은 배치 레이어에 두고, DOM 순서로 위에 오게 한다. */
  position: relative;
  display: inline-flex;
  align-items: center;
  gap: 0.4375rem;
  margin: 0 0 clamp(1.25rem, 3.5vh, 2rem);
  padding: 0.5rem 0.25rem;
  font-size: 0.75rem;
  font-weight: 500;
  letter-spacing: -0.01em;
  color: rgb(255 255 255 / 62%);
  text-decoration: none;
}

.cover-scroll:hover,
.cover-scroll:focus-visible {
  color: rgb(255 255 255 / 92%);
}

.cover-scroll svg {
  width: 0.875rem;
  height: 0.875rem;
  fill: none;
  stroke: currentColor;
  stroke-width: 1.6;
  stroke-linecap: round;
  stroke-linejoin: round;
}

/* 화면은 아래로 잘려 나가면서 올라온다. 자산이 이미 잘려 있으므로 여기서는
   폭만 정한다. 높이는 자산 비율에서 따라온다 — 30rem을 넘으면 1.6:1이라 폭의
   62.5%, 폰 세로에서는 1.05:1이라 폭의 95%다. */
.cover-shot {
  position: relative;
  width: min(30rem, 84vw);
}

/* 세로가 짧은 창에서는 표지가 한 화면을 넘지 않도록 화면부터 줄인다.
   폭이 30rem 이하이면 84vw가 22rem보다 언제나 작아 이 규칙은 아무것도 하지
   않는다. 그 구간은 아래 폰 세로 규칙이 높이 기준으로 맡는다. */
@media (max-height: 44rem) {
  .cover-shot {
    width: min(22rem, 84vw);
  }
}

/* 폰 세로는 1.05:1 자산이라 같은 폭에서 세로를 훨씬 많이 쓴다. 창이 낮으면 화면
   하나가 표지의 글을 밀어내므로 높이로 폭을 되묶는다.
   걸리는 조건은 `창 높이 ÷ 창 폭 < 84 ÷ (56 × 1.0514) = 1.43`이다. 세로로 든 폰은
   모두 이 위에 있어(4인치 SE 1.65, 8 Plus 1.52, 15/16 1.90) 목업이 깎이지 않고,
   데스크톱에서 창을 작게 줄인 경우에만 걸린다.
   기준을 `lvh`로 두는 이유는 표지 높이가 `100lvh`이기 때문이다. 도구모음이 펼쳐진
   높이인 `svh`로 재면 기준이 어긋나 16:9 폰에서 목업이 5~13% 깎였다.
   위 `max-height: 44rem` 규칙보다 뒤에 있어 두 조건이 겹치면 이 값이 이긴다. */
@media (max-width: 30rem) {
  .cover-shot {
    width: min(84vw, calc(56lvh * 552 / 525));
  }
}

/* ── 히어로 ─────────────────────────────────────────────
   페이지가 라벤더 블록으로 열린다. 데스크톱에서는 제목이 폭을 다 쓰고,
   그 아래 왼쪽에 본문, 오른쪽 아래에 기울어진 영수증이 놓인다. */

.hero {
  position: relative;
  overflow: hidden;
  /* 워드마크는 표지가 가져갔다. 제목이 바로 서므로 위 여백을 더 준다. */
  padding: clamp(4rem, 11vw, 7rem) 0 clamp(3.75rem, 9vw, 6rem);
  background: linear-gradient(
    135deg,
    var(--hero-bg-start),
    var(--hero-bg-end)
  );
  color: #ffffff;
}

/* 데코 1 — 원장 괘선. 금액을 줄에 맞춰 적는 장부의 결을 배경에 남긴다.
   가로선 피치는 본문 행간(2.75rem)에, 세로선은 금액 칸 폭에 맞췄다.
   오른쪽 위의 넓은 광량은 영수증이 놓이는 자리를 들어 올린다. */
.hero-ruling {
  position: absolute;
  inset: 0;
  background-image: radial-gradient(
      58% 62% at 84% 14%,
      rgb(255 255 255 / 15%),
      transparent 72%
    ),
    repeating-linear-gradient(
      to bottom,
      rgb(255 255 255 / 6%) 0 1px,
      transparent 1px 2.75rem
    ),
    repeating-linear-gradient(
      to right,
      rgb(255 255 255 / 5%) 0 1px,
      transparent 1px 7.5rem
    );
  /* 아래로 갈수록 걷어내 추세 그래픽과 겹쳐 지저분해지지 않게 한다. */
  mask-image: linear-gradient(
    to bottom,
    rgb(0 0 0 / 100%) 0%,
    rgb(0 0 0 / 55%) 58%,
    transparent 100%
  );
}

/* 데코 2 — 앱의 소비 추세를 빌보드 크기로 키운 계단.
   비율을 버리고 폭에만 늘리므로 선 굵기는 non-scaling-stroke로 지킨다.
   높이를 고정해 좁고 긴 화면에서 세로 낙차가 기둥처럼 늘어나지 않게 한다. */
.hero-curve {
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0;
  display: block;
  width: 100%;
  height: clamp(13rem, 32vw, 24rem);
}

.hero-curve-area {
  fill: rgb(255 255 255 / 7%);
  stroke: none;
}

.hero-curve-line {
  fill: none;
  stroke: rgb(255 255 255 / 20%);
  stroke-width: 1.5;
  stroke-linejoin: round;
}

/* 달의 경과에 맞춘 기준선. 계단이 이 선 아래로 내려가 있다. */
.hero-curve-guide {
  fill: none;
  stroke: rgb(255 255 255 / 22%);
  stroke-width: 1.5;
  stroke-linecap: round;
  stroke-dasharray: 2 7;
}

/* 데코가 글을 덮지 않도록 내용만 위로 올린다. */
.hero > .wrap {
  position: relative;
}

.hero h1 {
  margin: 0 0 1.125rem;
  font-size: clamp(1.875rem, 5.4vw, 3.75rem);
  font-weight: 700;
  line-height: 1.3;
  letter-spacing: -0.034em;
}

/* 배경이 흰 텍스트와 6.36:1이라 88%까지 내려도 5.33:1을 유지한다. */
.hero-lead {
  margin: 0;
  max-width: 34rem;
  font-size: clamp(1rem, 2.6vw, 1.3125rem);
  color: rgb(255 255 255 / 88%);
}

.store-cta {
  display: flex;
  align-items: center;
}

.app-store-button {
  appearance: none;
  display: inline-flex;
  margin: 0;
  padding: 0;
  border: 0;
  background: transparent;
  color: inherit;
  font: inherit;
  line-height: 0;
  cursor: pointer;
}

.app-store-badge {
  display: block;
  width: auto;
  height: 3rem;
}

/* 좁은 화면은 제목 → 본문 → 영수증 순으로 그대로 쌓는다. */
.receipt-slot {
  margin-top: clamp(2.25rem, 6vw, 3rem);
}

@media (min-width: 60rem) {
  :root {
    --shell: 68rem;
  }

  .hero-body {
    display: grid;
    grid-template-columns: minmax(0, 1fr) 22rem;
    grid-template-areas:
      "title title"
      "copy receipt";
    column-gap: var(--gap-column);
  }

  /* 제목은 두 단을 다 쓴다. 단 하나에 가두면 문장이 중간에서 접혀
     '거대한 제목'이 그냥 뭉친 덩어리가 된다. */
  .hero-body h1 {
    grid-area: title;
    margin-bottom: 1.75rem;
  }

  .hero-copy {
    grid-area: copy;
    align-self: start;
  }

  /* 영수증은 본문 오른쪽, 그 줄의 아래쪽 끝에 붙는다. */
  .receipt-slot {
    grid-area: receipt;
    align-self: end;
    margin-top: 0;
    /* 책상에 던져둔 계산서. 왼쪽 위가 들려 제목 쪽을 향한다.
       오른쪽 아래를 축으로 돌려야 회전분이 컨테이너 밖으로 밀려나지 않는다. */
    transform: rotate(-3.2deg);
    transform-origin: 100% 100%;
  }
}

/* ── 영수증 ─────────────────────────────────────────────
   계산서의 구조를 그대로 쓴다. 라벨은 왼쪽, 금액은 오른쪽 끝에 정렬해
   자릿수가 눈으로 비교되게 한다. 아래 가장자리는 찢어낸 톱니다. */

.receipt {
  position: relative;
  max-width: 25rem;
  padding: 1.25rem 1.25rem 1.5rem;
  background: var(--paper);
  color: var(--ink);
  /* 종이는 코너가 거의 없다. 위쪽만 살짝. */
  border-radius: 0.3125rem 0.3125rem 0 0;
  box-shadow: var(--paper-shadow);
}

/* 찢어낸 아래 가장자리. 종이와 같은 색의 반원을 이어 붙인다.
   mask 대신 background로 그린다 — 반원 사이가 그대로 비어 히어로 배경이 보인다. */
.receipt-tear {
  position: absolute;
  left: 0;
  right: 0;
  bottom: -0.5rem;
  height: 0.5rem;
  background-image: radial-gradient(
    circle at 50% 0,
    var(--paper) 0.34rem,
    transparent 0.35rem
  );
  background-size: 0.75rem 0.5rem;
  /* 중앙 기준으로 반복해 양끝이 대칭으로 잘리게 한다. 왼쪽 기준이면
     오른쪽 끝에서만 반원이 중간에 끊겨 어색해진다. */
  background-position: 50% 0;
  background-repeat: repeat-x;
}

.ledger {
  margin: 0;
  display: grid;
  gap: 0.5rem;
}

.ledger-row {
  display: grid;
  grid-template-columns: 1fr auto;
  align-items: baseline;
  gap: 0.875rem;
}

/* 점 표식이 있는 행만 들여쓰이면 라벨의 왼쪽 끝이 어긋난다. 모든 행에 같은
   들여쓰기를 주고 점은 그 자리에 얹어, 계산서의 좌우 정렬을 지킨다. */
.ledger-row dt {
  position: relative;
  display: flex;
  align-items: baseline;
  gap: 0.4375rem;
  padding-left: 0.875rem;
  font-size: 0.9375rem;
  font-weight: 500;
  line-height: 1.55;
  color: var(--paper-muted);
}

.ledger-row .count {
  font-size: 0.75rem;
  font-weight: 400;
  color: var(--paper-faint);
}

.amount {
  margin: 0;
  font-size: 1rem;
  font-weight: 500;
  font-variant-numeric: tabular-nums;
  letter-spacing: -0.01em;
  line-height: 1.55;
  color: var(--ink);
}

.sign {
  margin-right: 0.125rem;
  color: var(--paper-faint);
}

/* 두 의무는 앱에서 각자의 색을 가진다. 그 색을 표식으로 되살려
   랜딩과 앱 화면이 같은 것을 가리키게 한다. */
.ledger-row--recurring dt::before,
.ledger-row--installment dt::before {
  content: "";
  position: absolute;
  left: 0;
  top: 0.6em;
  width: 0.4375rem;
  height: 0.4375rem;
  border-radius: 50%;
}

.ledger-row--recurring dt::before {
  background: var(--recurring);
}

.ledger-row--installment dt::before {
  background: var(--installment);
}

/* 합계는 카피가 던진 질문의 답이다. 이 행만 크기와 색을 올린다. */
.ledger-row--total {
  margin-top: 0.375rem;
  padding-top: 0.9375rem;
  border-top: 1px dashed var(--paper-rule);
}

.ledger-row--total dt {
  font-weight: 700;
  color: var(--ink);
}

.ledger-row--total .amount {
  font-size: 1.625rem;
  font-weight: 700;
  letter-spacing: -0.03em;
  line-height: 1.2;
  color: var(--brand);
}

/* 시그니처 — 예산에서 의무가 하나씩 깎여 합계에 도달하는 순서를 시간으로 보여준다.
   흩어진 효과 대신 이 한 번의 시퀀스에만 모션을 쓴다. */
@keyframes ledger-in {
  from {
    opacity: 0;
    transform: translateY(0.5rem);
  }
  to {
    opacity: 1;
    transform: none;
  }
}

.ledger-row {
  animation: ledger-in 0.5s var(--ease-out) both;
}

.ledger-row:nth-child(1) {
  animation-delay: 0.06s;
}

.ledger-row:nth-child(2) {
  animation-delay: 0.18s;
}

.ledger-row:nth-child(3) {
  animation-delay: 0.3s;
}

/* 답이 도착하는 행이므로 한 박자 더 둔다. */
.ledger-row--total {
  animation-delay: 0.48s;
}

/* 축소 모션은 모션 0이 아니다. 이동만 걷어내고 페이드는 남긴다. */
@media (prefers-reduced-motion: reduce) {
  @keyframes ledger-in {
    from {
      opacity: 0;
    }
    to {
      opacity: 1;
    }
  }
}

/* ── 구획 공통 ────────────────────────────────────────
   두 배치를 번갈아 쓴다.
   split — 글 왼쪽, 도해 오른쪽(또는 flip으로 좌우 반전).
   stack — 글 위, 도해 아래 폭 전체. 카드가 여러 장일 때 이쪽이 맞다. */

.block {
  padding-top: var(--gap-section);
}

/* 데코 3 — 구획 경계는 절취선이다. 영수증을 한 칸씩 뜯어 읽는 것처럼
   구획이 넘어간다. 여백만으로 나누면 페이지가 그냥 비어 보인다. */
.block--perforated {
  position: relative;
}

.block--perforated::before {
  content: "";
  position: absolute;
  top: calc(var(--gap-section) / 2);
  left: 0;
  right: 0;
  height: 2px;
  background-image: radial-gradient(
    circle at 50% 50%,
    var(--rule) 1px,
    transparent 1.2px
  );
  background-size: 0.5rem 2px;
  background-position: 50% 50%;
  background-repeat: repeat-x;
}

.block h2 {
  margin: 0 0 0.875rem;
  font-size: clamp(1.375rem, 3.4vw, 2.375rem);
  font-weight: 700;
  line-height: 1.36;
  letter-spacing: -0.028em;
}

.block-lead {
  margin: 0;
  max-width: 34rem;
  font-size: clamp(0.9375rem, 2.4vw, 1.125rem);
  color: var(--ink-muted);
}

.block-note {
  margin: 1.375rem 0 0;
  max-width: 34rem;
  font-size: 0.875rem;
  line-height: 1.75;
  color: var(--ink-note);
}

/* 좁은 화면에서는 두 배치 모두 한 단으로 쌓인다. */
.block-figure {
  margin-top: 2rem;
}

@media (min-width: 60rem) {
  .block--split .wrap {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    column-gap: var(--gap-column);
    align-items: center;
  }

  .block--split .block-figure {
    margin-top: 0;
  }

  /* 리듬을 위해 한 구획만 좌우를 뒤집는다. 순서는 마크업 그대로 두고
     배치만 바꿔, 읽는 순서는 글 → 도해로 유지한다. */
  .block--flip .block-figure {
    grid-column: 1;
    grid-row: 1;
  }

  .block--stack .block-copy {
    max-width: 44rem;
  }

  .block--stack .block-figure {
    margin-top: 2.5rem;
  }
}

/* ── 앱 화면 카드 ───────────────────────────────────────
   그래프는 앱과 같이 카드 바닥에 풀블리드로 깔고 높이를 고정한다.
   비율을 유지하면 넓은 카드에서 점선이 카드를 대각선으로 가로지른다. */

.budget-card {
  position: relative;
  width: 100%;
  border-radius: 1.75rem;
  padding: 1.625rem 1.625rem 4.25rem;
  overflow: hidden;
  color: #ffffff;
}

.budget-card--warning {
  background: linear-gradient(135deg, var(--hero-start), var(--hero-end));
  box-shadow: 0 0.75rem 2rem rgb(108 92 231 / 32%);
}

.card-label {
  margin: 0;
  font-size: 0.9375rem;
  font-weight: 500;
  line-height: 1.5;
  color: rgb(255 255 255 / 80%);
}

.card-amount {
  margin: 0.125rem 0 0;
  font-size: clamp(1.5rem, 4.4vw, 2.125rem);
  font-weight: 700;
  letter-spacing: -0.022em;
  font-variant-numeric: tabular-nums;
  line-height: 1.2;
}

.card-badge {
  display: inline-flex;
  align-items: center;
  gap: 0.3125rem;
  margin: 1rem 0 0;
  padding: 0.375em 0.75em;
  border-radius: 999px;
  background: color-mix(in srgb, var(--status-warning) 88%, transparent);
  font-size: 0.8125rem;
  font-weight: 500;
  line-height: 1.35;
  white-space: nowrap;
}

.badge-icon {
  width: 1em;
  height: 1em;
  flex: none;
  fill: #ffffff;
}

/* 삼각형 안의 느낌표는 배지 배경색으로 뚫어 앱의 SF Symbol과 같은 인상을 만든다. */
.badge-icon-mark {
  fill: var(--status-warning);
}

.card-trend {
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0;
  display: block;
  width: 100%;
  height: 5.5rem;
  /* 텍스트와 겹치는 위쪽일수록 옅어지는 앱의 마스크를 그대로 옮긴다. */
  mask-image: linear-gradient(
    to bottom,
    rgb(0 0 0 / 20%) 0%,
    rgb(0 0 0 / 90%) 35%,
    rgb(0 0 0 / 100%) 100%
  );
}

/* 앱은 이 점선을 12%로 두지만, 앱에서는 배지가 상태를 이미 말해 준다.
   랜딩에서는 점선과 면의 어긋남 자체가 주장이므로 기준선을 읽을 수 있어야 한다. */
.trend-guide {
  fill: none;
  stroke: rgb(255 255 255 / 30%);
  stroke-width: 1;
  stroke-linecap: round;
  stroke-dasharray: 3 4.5;
}

.trend-area {
  fill: rgb(255 255 255 / 20%);
  stroke: none;
}

/* 오늘 점은 SVG 밖에 둔다. 그래프를 폭에만 늘리면 SVG 안의 원은 타원이 된다.
   위치는 그래프 좌표(x 216/360, 바닥에서 28%)를 그대로 옮긴 값이다. */
/* trend-area의 끝점(x 126/360, y 35.2/72)에 맞춘다. .card-trend가 5.5rem/72단위이므로
   바닥에서 (72 − 35.2) × 5.5 / 72 = 2.81rem이다. */
.trend-now {
  position: absolute;
  left: 35%;
  bottom: 2.81rem;
  width: 0.4375rem;
  height: 0.4375rem;
  border-radius: 50%;
  background: rgb(255 255 255 / 70%);
  transform: translate(-50%, 50%);
}

/* ── 봉투 카드 ──────────────────────────────────────────
   앱의 봉투 카드를 옮긴다. 아이콘 자리에는 봉투 컬러 점을 쓴다 —
   SF Symbols는 Apple 플랫폼 앱 UI 밖에서 쓸 수 없다. */

.envelope-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(11rem, 1fr));
  gap: 0.875rem;
}

.envelope-card {
  padding: 1.25rem 1.25rem 1.375rem;
  border-radius: 1.375rem;
  background: var(--surface);
  border: 1px solid var(--rule);
}

.envelope-name {
  display: flex;
  align-items: center;
  gap: 0.4375rem;
  margin: 0;
  font-size: 0.9375rem;
  font-weight: 500;
  color: var(--ink-muted);
}

.envelope-dot {
  width: 0.5rem;
  height: 0.5rem;
  flex: none;
  border-radius: 50%;
}

.envelope-amount {
  display: flex;
  align-items: baseline;
  gap: 0.375rem;
  margin: 0.375rem 0 0.875rem;
  font-size: clamp(1.125rem, 3.4vw, 1.5rem);
  font-weight: 700;
  letter-spacing: -0.024em;
  font-variant-numeric: tabular-nums;
}

.envelope-unit {
  font-size: 0.8125rem;
  font-weight: 500;
  letter-spacing: 0;
  color: var(--ink-note);
}

.envelope-bar {
  height: 0.375rem;
  border-radius: 999px;
  background: color-mix(in srgb, var(--ink) 9%, transparent);
  overflow: hidden;
}

.envelope-bar-fill {
  display: block;
  height: 100%;
  border-radius: 999px;
}

.envelope-card--food .envelope-dot,
.envelope-card--food .envelope-bar-fill {
  background: var(--cat-food);
}

.envelope-card--transit .envelope-dot,
.envelope-card--transit .envelope-bar-fill {
  background: var(--cat-transit);
}

.envelope-card--living .envelope-dot,
.envelope-card--living .envelope-bar-fill {
  background: var(--cat-living);
}

/* 사용률. index.html의 남은 금액·aria-label과 같은 값이어야 한다.
   배정액 900,000 / 300,000 / 600,000에 대해 남은 금액이 정확히 떨어진다. */
.envelope-card--food .envelope-bar-fill {
  width: 43.8%;
}

.envelope-card--transit .envelope-bar-fill {
  width: 47.2%;
}

.envelope-card--living .envelope-bar-fill {
  width: 66.8%;
}

/* ── 예산 점유 도해 ─────────────────────────────────────
   한 번 등록한 할부·정기지출이 앞으로의 달마다 자동으로 깔리는 모습을 그린다.
   금액은 범례가 맡고 띠는 시간만 맡는다. 칸마다 숫자를 반복하면 읽히지 않는다.
   막대 높이는 두 금액의 비(20만 : 9.5만)를 그대로 쓴다. */

.plan {
  padding: 1.375rem 1.375rem 1.5rem;
  border-radius: 1.375rem;
  background: var(--surface);
  border: 1px solid var(--rule);
}

.plan-legend {
  display: flex;
  flex-wrap: wrap;
  gap: 0.375rem 1.125rem;
  margin: 0 0 1.25rem;
  padding: 0;
  list-style: none;
  font-size: 0.8125rem;
  color: var(--ink-muted);
}

.plan-legend-item {
  display: flex;
  align-items: baseline;
  gap: 0.4375rem;
}

/* 두 의무의 색은 히어로 영수증의 표식과 같다. 같은 것을 가리킨다. */
.plan-legend-item::before {
  content: "";
  flex: none;
  width: 0.4375rem;
  height: 0.4375rem;
  border-radius: 50%;
  transform: translateY(-0.1em);
}

.plan-legend-item--installment::before {
  background: var(--installment);
}

.plan-legend-item--recurring::before {
  background: var(--recurring);
}

.plan-months {
  display: grid;
  grid-template-columns: repeat(6, minmax(0, 1fr));
  gap: 0.3125rem;
  margin: 0;
  padding: 0;
  list-style: none;
}

.plan-month {
  display: grid;
  gap: 0.25rem;
}

.plan-month-name {
  font-size: 0.75rem;
  font-weight: 500;
  font-variant-numeric: tabular-nums;
  color: var(--ink-note);
}

/* 히어로 영수증이 말한 '이번 달'과 이 띠의 첫 칸이 같은 달이다. */
.plan-month--now .plan-month-name {
  font-weight: 700;
  color: var(--ink);
}

.plan-bar {
  border-radius: 0.3125rem;
}

.plan-bar--installment {
  height: 2.75rem;
  background: var(--installment);
}

.plan-bar--recurring {
  height: 1.3125rem;
  background: var(--recurring);
}

/* 앱이 미래를 끝까지 그리지 않는 것과 같다. 남은 달은 옅게만 남긴다. */
.plan-bar--faded {
  opacity: 0.3;
}

.plan-foot {
  margin: 1.125rem 0 0;
  font-size: 0.8125rem;
  line-height: 1.7;
  color: var(--ink-note);
}

/* ── 스크린샷 ───────────────────────────────────────────
   다른 구획의 도해는 앱의 값과 계산으로 다시 그린 재현이지만, 스크린샷 구획과
   구획 5의 컴포저만은 앱 화면을 그대로 캡처한 것이다. 캡처 절차는 `web/README.md`.

   기기 틀은 이미지가 아니라 CSS로 그린다. 실제 iPhone 사진을 쓰면 Apple 하드웨어
   이미지 사용 규칙을 따로 확인해야 하고, 화면 폭마다 다른 해상도를 준비해야 한다.
   치수는 전부 백분율이라 어떤 폭에서도 기기 비율을 유지한다. */
.phone {
  position: relative;
  /* 베젤. 백분율 패딩은 자기 폭을 기준으로 하므로 틀이 함께 줄고 늘어난다. */
  padding: 1.35%;
  /* 바깥 반지름 = 화면 반지름 + 베젤. 화면 반지름 13.5%는 iPhone 17 Pro의
     실제 곡률(약 55pt / 화면 폭 402pt)이다. */
  border-radius: 14.5% / 6.8%;
  background: linear-gradient(150deg, #cfcada 0%, #8d879e 42%, #b9b4c8 100%);
  box-shadow:
    0 0 0 1px rgb(20 14 40 / 10%),
    0 1rem 2.25rem rgb(20 14 40 / 18%);
}

/* 섬의 백분율 좌표가 베젤이 아니라 화면을 기준으로 잡히도록 한 겹 더 감싼다.
   이 상자가 없으면 패딩을 조금만 바꿔도 섬이 화면 안에서 밀린다. */
.phone-screen {
  position: relative;
  display: block;
}

/* `picture`는 기본이 인라인이다. 그대로 두면 블록인 `img`가 인라인 상자 안에 들어가
   행 높이만큼의 여백이 화면 아래에 붙는다. */
.phone picture {
  display: block;
}

.phone img {
  display: block;
  width: 100%;
  height: auto;
  /* 가로·세로 반지름을 따로 줘 세로로 긴 화면에서도 원형 모서리로 보이게 한다.
     세로 값은 캡처 비율(552 × 1200)에서 나온다 — 13.5% × 552 ≈ 6.2% × 1200. */
  border-radius: 13.5% / 6.2%;
  background: var(--canvas);
}

/* Dynamic Island. 시뮬레이터 캡처는 이 자리를 그릴 때도 있고 비울 때도 있어,
   찍힌 것을 완전히 덮도록 실측보다 아주 조금 크게 잡는다.
   iPhone 17 Pro 캡처(1206×2622) 실측: 좌 34.2%·폭 31%·상단 1.75%·높이 3.85%. */
.phone-island {
  position: absolute;
  top: 1.6%;
  left: 50%;
  translate: -50% 0;
  width: 31.5%;
  aspect-ratio: 3.55;
  border-radius: 999px;
  background: #000;
}

@media (prefers-color-scheme: dark) {
  .phone {
    background: linear-gradient(150deg, #4b455c 0%, #2a2537 45%, #403a50 100%);
    box-shadow:
      0 0 0 1px rgb(0 0 0 / 45%),
      0 1rem 2.25rem rgb(0 0 0 / 45%);
  }
}

/* 좁은 화면에서는 가로 스크롤 스트립으로, 60rem부터는 네 장을 한 줄에 세운다.
   4장을 좁은 폭에 욱여넣으면 한 장이 90px 남짓이 되어 아무것도 읽히지 않는다. */
.shots {
  display: grid;
  grid-auto-flow: column;
  grid-auto-columns: min(62vw, 15rem);
  gap: clamp(0.875rem, 3vw, 1.5rem);
  margin: 0;
  padding: 0 var(--gutter) 0.5rem;
  list-style: none;
  overflow-x: auto;
  overscroll-behavior-x: contain;
  scroll-snap-type: x proximity;
  scroll-padding-left: var(--gutter);
  /* `.wrap`의 좌우 여백을 되돌려 스트립이 화면 끝까지 스크롤되게 한다. */
  margin-inline: calc(var(--gutter) * -1);
}

.shot {
  scroll-snap-align: start;
}

.shot figure {
  margin: 0;
}

.shot figcaption {
  margin-top: 1rem;
  font-size: 0.8125rem;
  line-height: 1.6;
  color: var(--ink-note);
}

.shot-name {
  display: block;
  margin-bottom: 0.125rem;
  font-size: 0.9375rem;
  font-weight: 500;
  color: var(--ink);
}

@media (min-width: 60rem) {
  .shots {
    grid-auto-columns: minmax(0, 1fr);
    gap: 1.5rem;
    margin-inline: 0;
    padding: 0;
    overflow-x: visible;
  }
}

/* 표지는 언제나 검정 위이므로 배색과 무관하게 어두운 틀을 쓴다. */
.phone--dark {
  background: linear-gradient(150deg, #565064 0%, #26222f 45%, #454051 100%);
  box-shadow:
    0 0 0 1px rgb(0 0 0 / 55%),
    0 -0.5rem 3rem rgb(124 108 231 / 22%);
}

/* 표지의 화면은 위쪽만 남는다. 세로 반지름은 잘라낸 비율(800 × 500)에서 나온다 —
   13.5% × 800 ≈ 21.6% × 500. */
.phone--top {
  padding-bottom: 0;
  border-radius: 14.5% 14.5% 0 0 / 23.3% 23.3% 0 0;
}

.phone--top img {
  border-radius: 13.5% 13.5% 0 0 / 21.6% 21.6% 0 0;
}

/* 잘라낸 자산에서는 섬의 세로 위치가 원본 비율과 달라진다. */
.phone--top .phone-island {
  top: 5.9%;
}

/* 폰 세로 화면은 552 × 525로 더 길게 잘라낸 자산을 쓴다(index.html의 `picture`).
   표지가 `100lvh`를 채우면서 화면 자리도 도구모음 높이만큼 길어졌고, 1.6:1 자산은
   그만큼 짧아 보인다.

   경계는 폰 세로 폭의 상한인 30rem이다. 이 자산은 552px짜리 `overview.png`를 잘라
   만들어 `cover.png`(원본 1206px에서 줄인 800px)보다 해상도가 낮다. 폰의 표시 폭
   (84vw, 최대 403px)에서는 그 차이가 묻히지만, 창이 더 넓어지면 표시 폭이 자라고
   결국 `min(30rem, …)`에 걸려 480px에서 멈추므로(뷰포트 약 571px부터) 작은
   태블릿에서 눈에 띄게 흐려진다. 그 위는 원래 자산을 쓴다 — 하단 도구모음으로
   세로를 빼앗기는 것은 폰 브라우저 쪽 사정이다.

   비율이 달라지므로 세로 값을 다시 구한다.
     이미지  13.5% × 552 ≈ 14.2% × 525
     틀      14.5% × 567 ≈ 15.4% × 533   (폭·높이 모두 위 베젤을 포함한 값)
     섬      원본 캡처의 섬 위 20px ÷ 525 = 3.8%. 위를 조금 더 덮도록 3.65%로 둔다.
   `aspect-ratio`를 함께 두는 이유는 `img` 속성의 800 × 500이 이 자산의 비율이
   아니어서다. 로드 전에 1.6:1로 자리를 잡으면 표지의 LCP 이미지가 로드되는 순간
   세로로 밀린다. */
@media (max-width: 30rem) {
  .phone--top {
    border-radius: 14.5% 14.5% 0 0 / 15.4% 15.4% 0 0;
  }

  .phone--top img {
    aspect-ratio: 552 / 525;
    border-radius: 13.5% 13.5% 0 0 / 14.2% 14.2% 0 0;
  }

  .phone--top .phone-island {
    top: 3.65%;
  }
}

/* 구획 5의 컴포저는 화면 아래쪽만 잘라 쓴다. 입력 바 하나를 말하는데 화면을
   통째로 보이면 정작 봐야 할 곳이 작아진다. 기기 아래쪽만 남은 틀이므로
   위 모서리는 각지고 위 베젤도 없다. 세로 반지름은 잘라낸 비율(660 × 482)에서
   나온다 — 13.5% × 660 ≈ 18.5% × 482. */
.phone--bottom {
  max-width: 24rem;
  margin-inline: auto;
  padding-top: 0;
  border-radius: 0 0 14.5% 14.5% / 0 0 19.8% 19.8%;
}

.phone--bottom img {
  border-radius: 0 0 13.5% 13.5% / 0 0 18.5% 18.5%;
}

/* ── 개인정보 두 줄 ─────────────────────────────────────
   구획 하나를 쓸 만큼 방문자의 관심사가 아니다. 푸터 앞에 옅은 띠로만 둔다. */

.privacy-line {
  margin-top: var(--gap-section);
  padding: clamp(1.875rem, 5vw, 2.75rem) 0;
  background: color-mix(in srgb, var(--brand) 7%, transparent);
}

.privacy-claim {
  margin: 0;
  max-width: 40rem;
  font-size: clamp(1rem, 2.4vw, 1.1875rem);
  font-weight: 500;
  color: var(--ink);
}

.privacy-detail {
  margin: 0.5rem 0 0;
  max-width: 40rem;
  font-size: 0.9375rem;
  color: var(--ink-muted);
}

/* ── 푸터 ───────────────────────────────────────────── */

/* 띠가 이미 경계를 만든다. 선을 한 번 더 그으면 두 줄이 된다. */
.privacy-line + .site-footer {
  margin-top: 0;
  border-top: 0;
}

.site-footer {
  margin-top: var(--gap-section);
  padding: 1.75rem 0 3.5rem;
  border-top: 1px solid var(--rule);
  font-size: 0.875rem;
  color: var(--ink-muted);
}

.platforms {
  margin: 0 0 1.25rem;
}

.store-cta--footer {
  margin: 0 0 1.25rem;
}

.store-cta--footer .app-store-badge {
  height: 2.5rem;
}

.site-footer ul {
  display: flex;
  flex-wrap: wrap;
  gap: 0.5rem 1.125rem;
  margin: 0;
  padding: 0;
  list-style: none;
}

.site-footer a {
  color: var(--brand);
  text-decoration-thickness: 1px;
  text-underline-offset: 0.2em;
  transition: opacity 150ms var(--ease-out);
}

/* 터치 기기는 탭을 hover로 잡는다. 포인터가 있는 환경에만 적용한다. */
@media (hover: hover) and (pointer: fine) {
  .site-footer a:hover {
    opacity: 0.7;
  }
}

.copyright {
  margin: 1.25rem 0 0;
  color: var(--ink-note);
}

.apple-trademark {
  margin: 0.5rem 0 0;
  max-width: 48rem;
  font-size: 0.75rem;
  color: var(--ink-faint);
}

/* ── 출시 예정 안내 ─────────────────────────────────── */

.launch-dialog {
  width: min(22rem, calc(100% - 2rem));
  padding: 1.5rem;
  border: 0;
  border-radius: 1rem;
  background: var(--paper);
  color: var(--ink);
  box-shadow: 0 1.5rem 4rem rgb(24 19 46 / 28%);
  text-align: center;
}

.launch-dialog::backdrop {
  background: rgb(18 14 34 / 48%);
  backdrop-filter: blur(4px);
}

.launch-dialog h2 {
  margin: 0;
  font-size: 1.375rem;
  line-height: 1.35;
}

.launch-dialog p {
  margin: 0.625rem 0 1.25rem;
  color: var(--ink-muted);
}

.launch-dialog form {
  margin: 0;
}

.launch-dialog button {
  min-width: 6rem;
  padding: 0.6875rem 1.25rem;
  border: 0;
  border-radius: 999px;
  background: var(--brand);
  color: #ffffff;
  font: inherit;
  font-weight: 500;
  cursor: pointer;
}

/* ── 문서 페이지 ────────────────────────────────────────
   지원·개인정보처리방침·이용약관·404. 모두 `.page` 안에 있으므로 이 스코프를
   벗어나지 않는다. 랜딩은 같은 요소를 다른 여백으로 쓴다. */

.page {
  max-width: 46rem;
  margin: 0 auto;
  padding: 1.5rem var(--gutter) 0;
}

.page a {
  color: var(--brand);
  text-decoration-thickness: 1px;
  text-underline-offset: 0.2em;
}

.page .site-header {
  display: flex;
  flex-wrap: wrap;
  gap: 0.75rem 1.25rem;
  align-items: center;
  justify-content: space-between;
  padding-bottom: 1.5rem;
  border-bottom: 1px solid var(--rule);
}

.wordmark {
  display: inline-flex;
  align-items: center;
  gap: 0.5rem;
  font-size: 1.0625rem;
  font-weight: 500;
  color: var(--ink);
  text-decoration: none;
}

.wordmark img {
  width: 1.5rem;
  height: 1.5rem;
}

.site-nav {
  display: flex;
  gap: 1rem;
  font-size: 0.9375rem;
}

.page h1 {
  margin: 2.5rem 0 0.75rem;
  font-size: clamp(1.875rem, 6vw, 2.5rem);
  font-weight: 700;
  line-height: 1.28;
  letter-spacing: -0.028em;
}

.page h2 {
  margin: 2.75rem 0 0.5rem;
  font-size: 1.3125rem;
  font-weight: 700;
  letter-spacing: -0.018em;
}

.page h3 {
  margin: 1.75rem 0 0.375rem;
  font-size: 1rem;
  font-weight: 700;
  letter-spacing: -0.01em;
}

.page p,
.page ul,
.page ol,
.page dl {
  margin: 0.75rem 0;
}

.page ul,
.page ol {
  padding-left: 1.25rem;
}

.page li {
  margin: 0.25rem 0;
}

.page dt {
  margin-top: 1.25rem;
  font-weight: 500;
}

.page dd {
  margin: 0.25rem 0 0;
  color: var(--ink-muted);
}

.page .policy-table {
  width: 100%;
  margin: 1rem 0;
  border-collapse: collapse;
  font-size: 0.9375rem;
  overflow-wrap: anywhere;
}

.page .policy-table caption {
  margin-bottom: 0.5rem;
  text-align: left;
  font-weight: 500;
}

.page .policy-table th,
.page .policy-table td {
  padding: 0.75rem 0;
  border-bottom: 1px solid var(--rule);
  text-align: left;
  vertical-align: top;
}

.page .policy-table th {
  width: 5.5em;
  padding-right: 1rem;
  font-weight: 500;
}

.lead {
  font-size: 1.125rem;
  color: var(--ink-muted);
}

.meta {
  font-size: 0.875rem;
  color: var(--ink-muted);
}

.note {
  padding: 1rem 1.25rem;
  background: var(--surface);
  border: 1px solid var(--rule);
  border-radius: 0.875rem;
}

.note p:first-child {
  margin-top: 0;
}

.note p:last-child {
  margin-bottom: 0;
}

/* 문서 페이지의 푸터는 `.page` 안에 있어 랜딩의 풀블리드 푸터와 다르다. */
.page .site-footer {
  margin-top: 3.5rem;
  padding: 1.5rem 0 max(1.5rem, env(safe-area-inset-bottom));
  border-top: 1px solid var(--rule);
}

.page .site-footer ul {
  margin: 0;
  padding-left: 0;
}

.page .site-footer li {
  margin: 0;
}

.page .copyright {
  margin: 1.25rem 0 0;
  max-width: 100%;
  line-height: 1.55;
}

:focus-visible {
  outline: 2px solid var(--brand);
  outline-offset: 3px;
}

/* 어두운 블록 위에서는 브랜드 보라 링이 배경에 잠긴다. 표지(#08060d)에서는
   특히 심해 흰색으로 바꾼다. */
.cover :focus-visible,
.hero :focus-visible {
  outline-color: #ffffff;
}
