/* ===========================================================================
   landing.css — 공개 랜딩 전용. `body.lp` 아래에서만 산다.

   ★ 2026-08-25 전면 재작성. 비주얼 정본은 templifica.com 이다.
     가져온 것: 니어블랙 캔버스 · 초대형 타이트 디스플레이 타입 · 헤드라인 인라인 칩 ·
     흰색 필 CTA · 카드 그리드 · 짧은 페이드업 모션.

   ★ **토큰을 자급자족한다.** 여기서 app.css 의 `--c-*`/`--fg` 를 쓰지 않는다.
     app.css 는 라이트("Ink on Paper") 표면이고 이 페이지는 다크다. 앞판은 그 위에
     지었기 때문에 면·글자 토큰을 통째로 물려받았는데, 다크로 뒤집으면 그 상속이 전부
     역방향이 된다. 그래서 아래 `--lp-*` 만 쓴다 — 이 파일 하나만 읽으면 색이 다 보인다.
     ⚠️ SPA(design.css)의 이름(`--fg2`·`--hairline`·`--s1`)도 금지다. 이 표면은
        design.css 를 링크하지 않아 `var()` 가 **조용히 빈 값**이 된다(에러도 안 난다).

   ★ 이미지는 반드시 **비율 박스**를 갖는다. width/height 속성만으로는 부족했다 —
     `justify-self:center` + `width:100%` 조합에서 로드 전 2px 로 붕괴했다가 340px 로
     점프한 실측 버그가 있었다. `aspect-ratio` 로 자리를 미리 잡는다.

   ★ 모션 게이트는 **역방향**이다. `html.lp-motion` 이 붙었을 때만 숨긴다. JS 가 못 돌면
     페이지는 그냥 다 보인다. 반대로 짜면 JS 한 줄이 죽을 때 백지가 되고, 그건 200 OK 라
     아무도 모른다.
   =========================================================================== */

body.lp {
  /* ── 면 ── */
  /* SEED Design **다크** 팔레트(design/24) — basement · gray-100 · gray-200 · gray-300 (dark) */
  --lp-bg: #000000;
  --lp-s1: #16171B;
  --lp-s2: #1D2025;
  --lp-s3: #2B2E35;
  /* ── 글자 3단 ── */
  --lp-fg: #F3F4F5;   /* fg.neutral (dark) */
  --lp-fg2: #DCDEE3;  /* fg.neutral-muted (dark) */
  --lp-fg3: #B0B3BA;  /* fg.neutral-subtle (dark) — 옛 #6B7280 은 면 위 3.6~4.1:1 이었다 */
  --lp-line: rgba(255, 255, 255, .10);
  --lp-line-2: rgba(255, 255, 255, .18);
  /* ── 액센트: 앱과 같은 브랜드색(코발트 #2E5BFF) — 랜딩에서 본 색이 앱에 들어와서도 "누를 것"이어야 한다.
     검정 면에서 파랑은 채움과 글자를 한 값으로 맡을 수 없다: #2E5BFF 는 흰 글자를 5.2:1 로 받쳐 주지만
     s2·s3 면 위 글자로는 3.5:1 아래다. 그래서 두 갈래로 나눈다(앱의 --c-brand / --c-brand_text 와 같은 구조).
     - --lp-acc      : 채움(버튼·태그·진행바). 위 글자는 흰색.
     - --lp-acc-text : 어두운 면 위 글자·테두리. bg 7.3 · s1 6.2 · s2 5.7 · s3 4.7 :1. */
  --lp-acc: #2E5BFF;
  --lp-acc-pressed: #1F46E0;
  --lp-acc-text: #7093FF;
  --lp-on-acc: #FFFFFF;
  --lp-on-fg: #1A1C20;
  --lp-r: 16px;
  --lp-r-lg: 24px;
  --lp-r-pill: 999px;
  /* 그림자 한 단. 어두운 면 위에서는 큰 부드러운 그림자가 실제로 깊이를 만든다
     (흰 종이 위에서 걷어낸 것과 상황이 다르다 — design/21 R1 의 근거는 '흰 종이 위의
     잉크 얼룩'이었다). 다만 값은 한 곳에서만 정한다. */
  --lp-shadow: 0 40px 90px -40px rgba(0, 0, 0, .9);
  --lp-display: 'Pretendard', -apple-system, 'Apple SD Gothic Neo', system-ui, sans-serif;
  --lp-body: 'Pretendard', -apple-system, 'Apple SD Gothic Neo', system-ui, sans-serif;
  --lp-pad: 20px;
  --lp-max: 1120px;

  /* app.css 의 앱 셸 레이아웃(중앙정렬 flex · 좌우 패딩 · 고정 글로우/그레인)을 무력화한다.
     공개면은 풀블리드로 흐른다. */
  display: block;
  align-items: initial;
  margin: 0;
  padding: 0;
  max-width: none;
  background: var(--lp-bg);
  color: var(--lp-fg);
  font-family: var(--lp-body);
  -webkit-font-smoothing: antialiased;
  overflow-x: hidden;
}
body.lp::before,
body.lp::after { content: none; }

/* app.css 가 `html` 에 건 `overscroll-behavior-y: contain` 을 되돌린다 — 같은 파일의
   앱 셸 레이아웃 무력화와 같은 성격의 훅이다(위 주석).

   왜 되돌리는가. 그 억제는 앱 셸의 **커스텀 PTR 과 안드로이드 네이티브 PTR 이 이중
   발화하는 것**을 막기 위한 것이고, 대가로 네이티브 당겨서 새로고침을 포기한다. 랜딩에는
   `.ptr` 인디케이터도 그 스크립트도 없다(`base_public.html` 은 `base.html` 의 형제라
   앱 셸의 본문 끝 스크립트를 물려받지 않는다) — 그래서 여기서 억제를 그대로 두면 얻는
   것 없이 **랜딩에서만 새로고침 손짓이 사라진다.** 순수 퇴행이라 명시적으로 끈다.
   ⚠️ 랜딩에 PTR 을 이식하게 되면 이 규칙을 지워야 한다. 남겨 두면 그때는 반대로
      네이티브와 커스텀이 겹친다. */
html { overscroll-behavior-y: auto; }

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

/* 스크린리더 전용. app.css 에 없어서 여기서 정의한다. */
.sr-only {
  position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px;
  overflow: hidden; clip-path: inset(50%); white-space: nowrap; border: 0;
}

/* ── 스크롤 진행바 ─────────────────────────────────────────────────────── */
.lp-progress {
  position: fixed; inset: 0 auto auto 0; height: 2px; width: 0;
  background: var(--lp-acc); z-index: 60; transition: width .1s linear;
}

/* ── 네비 ─────────────────────────────────────────────────────────────── */
.lp-nav {
  position: sticky; top: 0; z-index: 50;
  padding: 14px var(--lp-pad);
  background: rgba(8, 9, 10, .72);
  backdrop-filter: saturate(1.4) blur(14px);
  -webkit-backdrop-filter: saturate(1.4) blur(14px);
  border-bottom: 1px solid var(--lp-line);
}
.lp-nav-in { display: flex; align-items: center; justify-content: space-between; gap: 12px; }

.lp-logo {
  display: inline-flex; align-items: center; gap: 8px; min-height: 44px;
  color: var(--lp-fg); text-decoration: none;
  font-family: var(--lp-display); font-weight: 700; font-size: 1.06rem; letter-spacing: -.02em;
}
/* 브랜드 마크 — 다크 표면이라 **흰 잉크 마크**를 그대로 얹는다.
   ★ 여기 있던 **밝은 칩 우회를 제거했다.** 앞 로고는 검은 선화 일러스트 한 장뿐이라
     #08090A 위에서 실루엣이 잠겼고(26px 에서 형태가 안 읽혔다), 선화가 설 바탕을 주려고
     흰 칩을 덧댔었다. 이제 다크용 흰 마크가 따로 있으니 우회가 필요 없다 —
     자산이 맞으면 CSS 로 때울 일이 없다.
   ⚠️ 여기에 배경·패딩을 다시 넣지 마라. 넣으면 마크가 칩 안에 갇혀 작아 보인다. */
.lp-logo-img {
  width: var(--lg, 30px); height: auto;
  flex: 0 0 auto; display: block;
}

.lp-badge {
  font-family: var(--lp-body); font-size: .75rem; font-weight: 700; letter-spacing: .10em;
  padding: 3px 7px; border-radius: var(--lp-r-pill);
  border: 1px solid var(--lp-line-2); color: var(--lp-fg2);
}
/* ── 언어 전환 (2026-08-28, `/en` 네비) ──
   CTA 와 색으로 경쟁하지 않는다 — 주 버튼은 흰 필 하나여야 하고, 이건 **탈출구**다.
   ⚠️ 이 링크가 없으면 영문 페이지가 사이트의 막다른 길이 된다(뒤로가기 말고는 한국어로
      돌아올 길이 없다). 지우지 마라. */
.lp-nav-lang {
  margin-left: auto; margin-right: 10px; padding: 8px 12px;
  font-size: .8rem; font-weight: 500; color: var(--lp-fg2); text-decoration: none;
  white-space: nowrap;
}
.lp-nav-lang:hover { color: var(--lp-fg); }
/* ⚠️ `.lp-nav-lang` 이 `margin-left:auto` 로 밀어내므로 CTA 의 자동 여백을 되돌린다.
      한국어 페이지에는 이 링크가 없어 영향이 없다. */
.lp-nav-lang + .lp-nav-cta { margin-left: 0; }
.lp-nav-cta {
  display: inline-flex; align-items: center; min-height: 40px; padding: 0 16px; border-radius: var(--lp-r-pill);
  background: var(--lp-acc); color: var(--lp-on-acc);
  font-size: 1rem; font-weight: 700; text-decoration: none; white-space: nowrap;
}
.lp-nav-cta:active { background: var(--lp-acc-pressed); }

/* ── 공통 섹션 ────────────────────────────────────────────────────────── */
.lp-sec { padding: 68px var(--lp-pad); }
.lp-sec-in, .lp-hero-in, .lp-nav-in, .lp-foot-in {
  width: 100%; max-width: var(--lp-max); margin: 0 auto;
}

/* 킥커 — 대문자·자간을 걷었다(design/21 R2 · SEED). 한국어에 대문자는 없고 자간만 벌어진다. */
/* 본문 속 링크 — app.css 의 전역 `a` 색(잉크)이 검정 면으로 새어 1.2:1 이 됐다. */
body.lp p a, body.lp li a { color: var(--lp-fg); text-decoration: underline; text-underline-offset: 2px; }
.lp-kicker {
  margin: 0 0 14px; font-size: .8125rem; font-weight: 700;
  letter-spacing: 0; color: var(--lp-fg3);
}
/* ⚠️ vw 계수는 **가장 긴 줄**이 정한다. 지금 그 줄은 "전문적인 1:1 코칭을" 이고,
   12vw 였을 때 430px 화면에서 넘쳐 "코칭을" 만 다음 줄로 떨어졌다(고아 어절).
   각 줄이 `.h1-l` 로 이미 나뉘어 있어서 **줄바꿈이 아니라 넘침**으로 나타난다 —
   헤드라인 문구를 바꿀 때 가장 긴 줄이 길어지면 여기도 같이 내려야 한다. */
.lp-h1 {
  margin: 0 0 20px; font-family: var(--lp-display); font-weight: 700;
  font-size: clamp(2.1rem, 9.8vw, 5.4rem); line-height: .96; letter-spacing: -.045em;
}
.lp-h1 .h1-l { display: block; }
.lp-h2 {
  margin: 0 0 16px; font-family: var(--lp-display); font-weight: 700;
  font-size: clamp(1.75rem, 6.6vw, 2.9rem); line-height: 1.06; letter-spacing: -.035em;
}
.lp-h2.big { font-size: clamp(2.1rem, 9vw, 3.6rem); }
.lp-h3 {
  margin: 0 0 8px; font-family: var(--lp-display); font-weight: 700;
  font-size: 1.12rem; letter-spacing: -.02em; color: var(--lp-fg);
}
.lp-lede { margin: 0 0 24px; font-size: 1.02rem; line-height: 1.62; color: var(--lp-fg2); }
.lp-lede b { color: var(--lp-fg); font-weight: 500; }
.lp-body { margin: 0; font-size: .94rem; line-height: 1.66; color: var(--lp-fg2); }
.lp-body b { color: var(--lp-fg); font-weight: 500; }
.lp-body code {
  font-size: .86em; padding: 1px 5px; border-radius: 6px;
  background: var(--lp-s3); color: var(--lp-fg);
}
.lp-note { margin: 22px 0 0; font-size: .84rem; line-height: 1.6; color: var(--lp-fg3); }
.lp-note b { color: var(--lp-fg2); font-weight: 500; }
.lp-tag {
  display: inline-block; margin-left: 6px; padding: 2px 8px; border-radius: var(--lp-r-pill);
  background: var(--lp-acc); color: var(--lp-on-acc);  /* 코발트 위 흰 글자 5.2:1 (잉크는 3.3:1) */
  font-size: .75rem; font-weight: 700; letter-spacing: .06em; vertical-align: 1px;
}

/* ── CTA ──────────────────────────────────────────────────────────────── */
.lp-cta { margin: 0 0 18px; }
.lp-btn {
  display: flex; align-items: center; justify-content: center;
  width: 100%; min-height: 56px; padding: 15px 22px; margin-bottom: 10px;
  border-radius: var(--lp-r-pill); font-size: 1rem; font-weight: 700;
  text-decoration: none; text-align: center;
  transition: transform .12s ease, opacity .12s ease;
}
.lp-btn:active { transform: scale(.985); }
.lp-btn-go { background: var(--lp-acc); color: var(--lp-on-acc); }
.lp-btn-go:active { background: var(--lp-acc-pressed); }
.lp-btn-kakao, .lp-btn-kakao:active { background: #FEE500; color: rgb(0 0 0 / .85); border-color: transparent; }
.lp-btn-alt { background: transparent; color: var(--lp-fg); border: 1px solid var(--lp-line-2); }
.lp-btn-dev {
  background: transparent; color: var(--lp-fg3);
  border: 1px dashed var(--lp-line-2); font-size: .84rem; min-height: 44px;
}
.lp-cta-sub { margin: 10px 0 0; font-size: .82rem; line-height: 1.55; color: var(--lp-fg3); }
.lp-hl { color: var(--lp-acc-text); font-weight: 700; }

/* ── 버튼 반짝임 ────────────────────────────────────────────────────────────
   대각선 하이라이트가 버튼을 훑고 지나간다. 5초에 한 번만 — 계속 돌면 배너 광고처럼
   보여서 오히려 안 눌린다(그리고 저사양 기기에서 계속 합성 레이어를 태운다).

   ⚠️ `overflow:hidden` 은 버튼 자신에 건다. 부모에 걸면 그림자·포커스 링까지 잘린다.
   ⚠️ 애니메이션 대상은 `transform` 하나뿐이다. `left`/`background-position` 을 움직이면
      매 프레임 레이아웃·페인트가 돌아 스크롤이 끊긴다.
   ⚠️ `::after` 를 쓴다 — `.lp-btn` 계열은 `::before` 를 쓰지 않지만, 나중에 아이콘을
      붙이는 사람이 `::before` 를 먼저 집을 확률이 높다. */
.lp-shine { position: relative; overflow: hidden; isolation: isolate; }
.lp-shine::after {
  content: '';
  position: absolute; top: -60%; bottom: -60%; left: -40%; width: 28%;
  /* 흰 필(주 CTA) 위에서는 흰 하이라이트가 안 보인다 → 밝기를 낮추는 쪽으로 훑는다.
     반대로 어두운 버튼에서는 밝게 훑어야 하므로 아래에서 뒤집는다. */
  background: linear-gradient(100deg, transparent, rgba(11, 12, 13, .16), transparent);
  transform: translateX(0) skewX(-18deg);
  animation: lp-shine 5s ease-in-out infinite;
  pointer-events: none;   /* 하이라이트가 클릭을 먹으면 버튼이 죽는다 */
  z-index: 1;
}
.lp-btn-alt.lp-shine::after,
.lp-nav-cta.lp-shine::after,
.lp-btn-dev.lp-shine::after {
  background: linear-gradient(100deg, transparent, rgba(255, 255, 255, .22), transparent);
}
/* nav CTA 는 흰 필이라 어두운 쪽으로 되돌린다(위 규칙보다 뒤에 와야 이긴다). */
.lp-nav-cta.lp-shine::after {
  background: linear-gradient(100deg, transparent, rgba(11, 12, 13, .18), transparent);
}
@keyframes lp-shine {
  0%          { transform: translateX(0) skewX(-18deg); }
  /* 훑는 구간은 앞의 18% 뿐이고 나머지는 쉰다 — 그래서 "가끔 반짝"으로 읽힌다. */
  18%, 100%   { transform: translateX(560%) skewX(-18deg); }
}

.lp-login {
  display: flex; align-items: center; flex-wrap: wrap; gap: 10px;
  margin-top: 16px; padding-top: 16px; border-top: 1px solid var(--lp-line);
}
.lp-login-k { font-size: .82rem; color: var(--lp-fg3); }
.lp-login-a {
  font-size: .84rem; font-weight: 500; color: var(--lp-fg);
  text-decoration: none; border-bottom: 1px solid var(--lp-line-2); padding-bottom: 1px;
}


/* ── 히어로 ───────────────────────────────────────────────────────────── */
.lp-hero {
  padding: 46px var(--lp-pad) 60px;
  /* 상단에 아주 옅은 글로우 — templifica 의 블러 이미지 자리를 대신한다.
     이미지를 깔지 않는 이유는 히어로 LCP 예산 때문이다. */
  background:
    radial-gradient(120% 62% at 78% -6%, rgba(200, 247, 81, .13), transparent 60%),
    radial-gradient(90% 46% at 8% 4%, rgba(120, 160, 255, .09), transparent 62%);
}

/* ── 인입 경로 고지 (폴드 위) ──
   "지금 무엇으로 넣는가" 를 스캔 가능한 칩으로 먼저 보여주고, 안 되는 것(자동 연동)을
   바로 아래 한 문단으로 붙인다. 칩을 액센트로 칠하지 않는다 — 이건 자랑이 아니라
   **사실 고지**라서, 주 CTA(흰 필)와 색으로 경쟁하면 안 된다. */
.lp-intake {
  display: flex; flex-wrap: wrap; gap: 6px;
  margin: 0 0 10px; padding: 0; list-style: none;
}
.lp-intake li {
  padding: 6px 12px; border-radius: var(--lp-r-pill);
  background: var(--lp-s2); border: 1px solid var(--lp-line);
  font-size: .78rem; font-weight: 500; color: var(--lp-fg);
}
.lp-intake-note {
  margin: 0 0 26px; font-size: .82rem; line-height: 1.62; color: var(--lp-fg3);
}
.lp-intake-note b { color: var(--lp-fg2); font-weight: 500; }

/* ── 해주는 일 (§2) ───────────────────────────────────────────────────────
   ★ 2026-08-27 신설. 여기 있던 `.lp-basis-list`/`.bs*`(§7 의 4문답 카드)를 **지웠다** —
     그 넷은 전부 유보였고(개인차·논쟁·심박 오차·8건), 지금은 `.lp-fold` 접힘 안에 있다.

   질문 넷 → 결과 넷. 앞판에는 "무엇을 얻는가" 를 말하는 자리가 **아예 없었다.** */

/* 질문 칩. `.lp-intake` 칩과 모양을 일부러 다르게 둔다 — 저건 "무엇을 넣을 수 있나"(사실
   목록)이고 이건 **러너가 머릿속에서 하는 말**이다. 그래서 둥근 필이 아니라 왼쪽에 액센트
   막대를 세운 줄로. 물음표는 붙이지 않는다(넷이 연달아 오면 심문처럼 읽힌다). */
.lp-asks {
  display: grid; gap: 7px; margin: 0 0 24px; padding: 0; list-style: none;
}
.lp-asks li {
  position: relative; padding: 7px 0 7px 15px;
  font-family: var(--lp-display); font-weight: 700;
  font-size: 1.02rem; letter-spacing: -.02em; color: var(--lp-fg);
}
.lp-asks li::before {
  content: ''; position: absolute; left: 0; top: .62em; bottom: .62em;
  width: 3px; border-radius: 2px; background: var(--lp-acc);
}
/* 질문 → 결과의 전환 문장. 이 한 줄이 섹션의 관절이라 아래 여백을 넉넉히 준다. */
.lp-what-turn { margin: 0 0 20px; }

.lp-outcomes {
  display: grid; gap: 8px; margin: 0 0 22px; padding: 0; list-style: none;
}
.oc {
  padding: 15px 16px; border-radius: var(--lp-r);
  background: var(--lp-s1); border: 1px solid var(--lp-line);
}
.oc-k {
  margin: 0 0 5px; font-size: .75rem; font-weight: 700;
  letter-spacing: .02em; color: var(--lp-acc-text);
}
.oc-t { margin: 0; font-size: .92rem; line-height: 1.58; color: var(--lp-fg2); }
.oc-t b { color: var(--lp-fg); font-weight: 500; }

/* 연동 없이 시작한다는 **강점 한 줄.** ⚠️ 부정형("자동 연동은 아직 없어요")으로 되돌리지
   마라 — 같은 사실인데 방향이 반대이고, 이 자리는 결과 넷을 읽은 직후다. 상세는 §4·FAQ. */
.lp-setupfree { margin: 0; font-size: .9rem; line-height: 1.6; color: var(--lp-fg2); }
.lp-setupfree b { color: var(--lp-fg); font-weight: 700; }

/* 사회적 증거 한 줄 — templifica 의 ★4.9/5 + 아바타 클러스터 자리.
   평점도 후기도 0건이라 별이 아니라 **문장**이 온다. 알약 형태로 감싸 CTA 아래에서
   버튼과 구분되게 한다(같은 필 모양이지만 채우지 않아 누를 것으로 오인되지 않는다). */
/* ⚠️ `inline-flex` 를 쓰면 안 된다. `<b>30명</b>의` 에서 `</b>` 뒤의 텍스트 노드가
   익명 flex item 이 되어 `gap` 이 조사 앞에 공백을 벌린다("30명 의 러너가").
   한 줄 문장이므로 그냥 텍스트로 흐르게 둔다. */
.lp-social {
  display: inline-block;
  margin: 0 0 12px; padding: 10px 16px;
  border-radius: var(--lp-r-pill); border: 1px solid var(--lp-line-2); background: var(--lp-s1);
  font-size: .84rem; line-height: 1.5; color: var(--lp-fg2);
}
.lp-social b {
  font-family: var(--lp-display); font-weight: 700; font-size: 1.02rem;
  letter-spacing: -.02em; color: var(--lp-acc-text);
}

/* ── 실사용 사례 (사회적 증거) ──
   머릿수 한 줄 아래에 "누가 어떻게 쓰고 있나" 를 둔다. 후기가 아니라 **관측**이므로
   따옴표·아바타를 쓰지 않는다 — 인용 꼴로 만들면 있지도 않은 증언처럼 읽힌다. */
.lp-cases {
  display: grid; gap: 8px; margin: 0 0 8px; padding: 0; list-style: none;
}
.lp-cases li {
  padding: 14px 16px; border-radius: var(--lp-r);
  background: var(--lp-s1); border: 1px solid var(--lp-line);
}
.cs-w {
  margin: 0 0 5px; font-size: .75rem; font-weight: 700;
  letter-spacing: .02em; color: var(--lp-fg3);
}
.cs-d { margin: 0; font-size: .9rem; line-height: 1.55; color: var(--lp-fg2); }
.cs-d b { color: var(--lp-acc-text); font-weight: 700; }
.lp-cases-cap { margin: 0 0 30px; font-size: .75rem; color: var(--lp-fg3); }

/* 앱 스크린샷. 2026-08-27 에 히어로 오른쪽 열에서 §2 "기록 넣기" 로 내려왔다(글래스가
   그 자리를 가져갔다). 히어로에 있을 때는 그리드 셀이 여백을 만들어 줬지만 이제 본문
   흐름 안이라 아래 여백을 스스로 가져야 한다. */
.lp-shot { margin: 0 0 26px; }
.lp-shot figcaption { margin: 0 0 12px; font-size: .8rem; line-height: 1.5; color: var(--lp-fg3); }

/* ── 히어로 글래스 마크 ───────────────────────────────────────────────────
   브랜드 마크를 WebGL 로 굴절시키는 블록. 스크립트는 `pages/landing-glass.js`.

   ★ **비율 박스가 필수다.** 캔버스는 이미지보다 첫 페인트가 더 늦다(SDF 굽기 + 셰이더
     컴파일이 앞에 있다). 자리를 미리 안 잡으면 로드 전 0px 로 붕괴했다가 점프하는데,
     그 결함은 이 페이지의 이미지에서 이미 실측된 적이 있다
     (`frontend/tests/jinja.landing.spec.mjs` 의 "모든 이미지가 로드 전에도 자리를 차지한다").

   ★ 게이트는 **역방향**이다. 포스터가 기본으로 보이고, 첫 프레임이 실제로 그려진 뒤에만
     `.live` 가 붙어 사라진다. JS 가 죽으면 정적 마크가 남는다 — 반대로 짜면 구멍이 남고
     그건 200 OK 라 아무도 모른다. `html.lp-motion` 게이트와 같은 판단이다. */
/* ★ 모바일 기본값이 **상단 배너**다. 단일 컬럼에서는 DOM 순서가 곧 화면 순서라
   이 블록이 히어로의 첫 자식이고, 그래서 폴드 최상단에 앉는다(2026-08-27 지시).
   ⚠️ 높이가 곧 예산이고, **예산의 기준은 prod 다.** 로컬 하니스(`seed_and_serve`)는
      `providers` 분기(OAuth 버튼 + dev 로그인)를 렌더하는데 prod 는
      `OMPB_WEB_INVITE_ONLY=1` 의 **`invite_only` 분기**다 — 대기신청 + 초대코드 + 2줄
      각주 + 로그인 줄로 **CTA 블록이 44px 더 높다**(실측: 로컬 끝 811 vs prod 끝 855).
      300px 로 뒀을 때 prod 에서 로그인 줄이 820~855 로 **11px 잘렸다**(로컬은 초록).
      그 줄은 "없애면 안 된다"고 위 `cta` 매크로가 못박은 기존 사용자의 문이다.
      그래서 264px 다 — prod 에서 로그인 줄 끝이 819 로 25px 여유가 생긴다.
      ⚠️ 키우려면 **로컬 초록을 믿지 말고 prod 를 재라.** 하니스와 prod 의 분기가 다르다.
   ⚠️ 마크 크기는 캔버스 **높이**에 묶인다(`landing-glass.js` 의 `targetHalf` 가 수직
      FOV 기준이다). 가로로 납작하게 만들면 폭만 늘고 마크는 그대로 작아진다 —
      그래서 상단 배너는 가로 띠가 아니라 **정사각**이다. */
.lp-glass {
  position: relative;
  margin: 0 auto 20px;
  width: 100%;
  max-width: 264px;
  aspect-ratio: 1 / 1;
}
.lp-glass-c,
.lp-glass-poster {
  position: absolute; inset: 0;
  display: block; width: 100%; height: 100%;
}
.lp-glass-c {
  /* 드래그로 돌릴 수 있다는 걸 커서로 알린다. 모바일에선 의미 없지만 해롭지도 않다. */
  cursor: grab;
  /* 캔버스 위에서 스크롤이 막히면 모바일에서 페이지가 갇힌다. 포인터 회전은
     pointermove 로 받으므로 브라우저 제스처를 뺏을 이유가 없다. */
  touch-action: pan-y;
}
.lp-glass-c:active { cursor: grabbing; }
.lp-glass-poster {
  object-fit: contain;
  /* 포스터는 마크 원본(160px)이라 3/4 박스 안에서 여백을 두고 앉는다. 캔버스가 그리는
     크기(size 60 = 프레임의 60%)와 눈으로 맞춘 값이다. */
  padding: 14%;
  opacity: 1;
  transition: opacity .45s ease;
}
/* 첫 프레임이 그려졌을 때만. 스크립트가 붙인다. */
.lp-glass.live .lp-glass-poster { opacity: 0; }
.lp-shot img {
  display: block; width: 100%; height: auto; aspect-ratio: 600 / 820;
  border-radius: var(--lp-r-lg); border: 1px solid var(--lp-line);
  background: var(--lp-s2);
  /* 이 페이지에서 그림자를 쓰는 유일한 곳 — 화면 목업만 떠 보이게 한다. */
  box-shadow: var(--lp-shadow);
}

/* ── 섹션 리듬 ────────────────────────────────────────────────────────────
   섹션 정체성 클래스에 **실제 규칙을 준다.** 규칙 없는 클래스를 마크업에 남기면 다음
   사람이 "이건 어디에 쓰이지"를 확인하느라 시간을 쓰고, 그 사이 죽은 훅이 쌓인다.
   니어블랙 한 톤으로 8스크린을 내려가면 어디까지 읽었는지 감각이 사라지므로, 면을
   한 단 올리거나(증거·요금) 헤어라인을 긋는다(FAQ). */
/* ⚠️ 2026-08-27 재배열. **이 표는 이웃 관계다** — 섹션 순서가 바뀌면 여기도 바뀐다.
   손으로 세지 않아도 된다: `test_no_two_adjacent_sections_share_a_surface` 가 이 CSS 에서
   배경을 읽어 이웃을 다시 센다.

      1 hero   그라디언트     6 basis  bg + border-top
      2 what   bg             7 usage  s1
      3 proof  s1             8 price  s1 + border-top
      4 how    bg             9 faq    bg + border-top
      5 open   s1            10 final  그라디언트

   ★ 배경이 같은 이웃은 **`border-top` 으로 끊는다.** 배경을 바꾸는 쪽으로 고치지 마라 —
     아래 "카드도 한 단 더" 규칙이 연쇄로 딸려 온다(s1 섹션의 카드는 s2 여야 한다). */
.lp-proof { background: var(--lp-s1); }
/* 요금은 사용 증거(s1) 바로 다음이라 헤어라인으로 끊는다. */
.lp-price { background: var(--lp-s1); border-top: 1px solid var(--lp-line); }
.lp-faq-sec { border-top: 1px solid var(--lp-line); }
/* 해주는 일 — 히어로 다음. 히어로가 그라디언트라 배경은 다르지만, 경계를 명시해 둔다. */
.lp-what { border-top: 1px solid var(--lp-line); }
.lp-basis { border-top: 1px solid var(--lp-line); }
.lp-open { background: var(--lp-s1); }
/* ★ 2026-08-27(2차). `.lp-intake-sec` 규칙을 **지웠다** — 그 섹션이 §작동 방식으로
   통합됐다(같은 다섯 항목을 두 번 말하고 있었다). 칩은 이제 `.lp-how`(바탕) 안에 있고,
   `.lp-intake li` 자체 규칙이 이미 s2 라 별도 승격이 필요 없다. */
/* 사용 증거 — 근거 공개(bg) 다음이라 면을 한 단 올려 끊는다. */
.lp-usage { background: var(--lp-s1); }
.lp-how { padding-top: 78px; }
/* ⚠️ 면을 올린 섹션 안에서는 카드도 **한 단 더** 올린다. 안 그러면 카드와 섹션이 같은
   `--lp-s1` 이 되어 카드가 사라진다(테두리만 남는다). 층이 없으면 카드가 아니다. */
/* ★ `.lp-usage` 두 줄은 2026-08-27 추가. 이 카드들은 이관 전에도 s1 섹션
     (`.lp-intake-sec`) 안에 있어서 **줄곧 테두리만 남아 있었다** — 위 규칙이 이미 경고하던
     것인데 이 둘만 빠져 있었다. 섹션을 새로 만들면서 함께 고친다.
     `test_cards_are_a_step_above_their_section` 이 앞으로 이 누락을 잡는다. */
.lp-proof .lp-quote,
.lp-proof .dc,
.lp-usage .lp-cases li,
.lp-usage .lp-social,
.lp-price .lp-step { background: var(--lp-s2); }
.lp-price .lp-step.on { background: var(--lp-s3); }

/* ── 증거(코치 리뷰 인용) ─────────────────────────────────────────────── */
.lp-quote {
  margin: 0 0 20px; padding: 22px 20px;
  border-radius: var(--lp-r-lg); background: var(--lp-s1); border: 1px solid var(--lp-line);
}
.q-row + .q-row { margin-top: 18px; padding-top: 18px; border-top: 1px solid var(--lp-line); }
.q-lb {
  margin: 0 0 7px; font-size: .75rem; font-weight: 700;
  letter-spacing: 0; color: var(--lp-acc-text);
}
.q-t { margin: 0; font-size: .96rem; line-height: 1.68; color: var(--lp-fg); }
/* ── 인용문 번역 줄 (2026-08-28, `/en`) ──
   ★ 원문(`.q-t`)보다 **약하게** 둔다. 두 줄이 같은 무게면 어느 쪽이 코치가 쓴 것인지
     알 수 없고, 그러면 "문장을 손대지 않았다" 는 주장이 흐려진다. 원문이 주인공이고
     번역은 읽기 보조다.
   ⚠️ 이 규칙을 지우면 번역이 원문과 같은 무게로 보인다 — 캡션이 하는 구분과 어긋난다. */
.q-tr {
  margin: 8px 0 0; padding-left: 11px; border-left: 2px solid var(--lp-line-2);
  font-size: .88rem; line-height: 1.62; color: var(--lp-fg2);
}
.q-cap {
  margin: 18px 0 0; padding-top: 14px; border-top: 1px solid var(--lp-line);
  font-size: .75rem; line-height: 1.55; color: var(--lp-fg3);
}

.lp-decode { display: grid; gap: 8px; margin: 0; padding: 0; list-style: none; }
.dc {
  padding: 14px 16px; border-radius: var(--lp-r);
  background: var(--lp-s1); border: 1px solid var(--lp-line);
}
.dc-k {
  margin: 0 0 5px; font-size: .75rem; font-weight: 700;
  letter-spacing: 0; color: var(--lp-fg3);
}
.dc-t { margin: 0; font-size: .88rem; line-height: 1.55; color: var(--lp-fg); }

/* ── 근거 화면(예측 근거) ──
   세로로 긴 한 장. 본문 폭을 다 쓰면 글자가 너무 커지므로 상한을 둔다. */
.lp-evshot { margin: 22px 0 0; }
.lp-evshot img {
  display: block; width: 100%; max-width: 420px; height: auto; aspect-ratio: 760 / 1013;
  border-radius: var(--lp-r-lg); border: 1px solid var(--lp-line); background: var(--lp-s2);
}
.lp-evshot figcaption {
  margin: 12px 0 0; max-width: 460px;
  font-size: .8rem; line-height: 1.55; color: var(--lp-fg3);
}
.lp-evshot figcaption b { color: var(--lp-fg2); font-weight: 500; }

/* ── 강제 vs 부탁 ──
   ⚠️ 두 칸의 **시각 무게를 다르게** 둔다. 같은 카드로 그리면 "둘 다 지킨다"로 읽히는데,
   이 섹션의 요지는 정확히 그 반대다. 강제 쪽만 액센트 테두리를 갖는다. */
.lp-enforce { display: grid; gap: 10px; margin: 24px 0 0; }
.ef { padding: 18px; border-radius: var(--lp-r); border: 1px solid var(--lp-line); }
.ef-hard { background: var(--lp-s2); border-color: var(--lp-acc-text); }
.ef-soft { background: transparent; }
.ef-k { margin: 0 0 10px; font-size: .75rem; font-weight: 700; letter-spacing: .02em; }
.ef-hard .ef-k { color: var(--lp-acc-text); }
.ef-soft .ef-k { color: var(--lp-fg3); }
.ef ul { margin: 0; padding: 0; list-style: none; display: grid; gap: 9px; }
.ef li {
  position: relative; padding-left: 18px;
  font-size: .88rem; line-height: 1.58; color: var(--lp-fg2);
}
.ef li b { color: var(--lp-fg); font-weight: 500; }
.ef li::before {
  content: ''; position: absolute; left: 0; top: .66em;
  width: 8px; height: 1px; background: var(--lp-fg3);
}
.lp-enforce-note { margin-top: 14px; }

/* ── 무엇이 열리나 갤러리 ── */
/* 2칸 대비와 갤러리 사이의 이음말. 2칸이 "무엇이 열리나" 를 말했으니 여기서는
   "그게 어떻게 만들어지나"(코드가 계산) 로 §7 을 예고한다. */
.lp-open-lede { margin: 26px 0 16px; }
.lp-gal { display: grid; gap: 14px; margin: 0; padding: 0; list-style: none; }
.lp-gal li {
  padding: 14px; border-radius: var(--lp-r-lg);
  background: var(--lp-s2); border: 1px solid var(--lp-line);
}
/* ⚠️ 자산마다 비율이 다르다(4:3 과 볼륨 차트의 와이드). 고정 `aspect-ratio` 를 걸면
   한쪽이 잘리므로 **속성 비율에 맡기고** 높이만 auto 로 둔다. 로드 전 붕괴는
   width/height 속성이 막는다(브라우저가 그 비율로 자리를 잡는다). */
.lp-gal img {
  display: block; width: 100%; height: auto;
  border-radius: var(--lp-r); border: 1px solid var(--lp-line); background: var(--lp-s2);
}
.g-t { margin: 12px 0 4px; font-size: .96rem; font-weight: 700; color: var(--lp-fg); }
.g-d { margin: 0; font-size: .86rem; line-height: 1.55; color: var(--lp-fg2); }
.g-d b { color: var(--lp-fg); font-weight: 500; }

/* ── 작동 방식 3단계 ──────────────────────────────────────────────────── */
.lp-steps-3 { margin: 0; padding: 0; list-style: none; display: grid; gap: 44px; }
.hw-n {
  margin: 0 0 10px; font-family: var(--lp-display); font-weight: 700;
  font-size: 2.4rem; line-height: 1; letter-spacing: -.02em; color: var(--lp-acc-text);
}
.hw-i { margin-top: 18px; }
/* ★ 세로 화면 3장을 원본 비율(600/820)로 세우면 좁은 화면에서 한 장이 530px 를 먹고,
   세 장이 페이지의 1/5 를 죽은 여백처럼 차지한다. 그래서 **위에서 4:3 으로 자른다** —
   앞판의 사고(의도 없이 잘려 탭 이름이 반쯤 보이던 것)와 다른 점은 이게 *규칙*이라는
   것이다. 셋 다 같은 비율·같은 기준점(top)이라 잘린 자리가 리듬으로 읽힌다.
   가로 여유가 생기는 데스크톱에서는 원본 비율로 되돌린다(아래 미디어쿼리). */
.hw-i img {
  display: block; width: 100%; height: auto; aspect-ratio: 4 / 3;
  object-fit: cover; object-position: top center;
  border-radius: var(--lp-r-lg); border: 1px solid var(--lp-line); background: var(--lp-s2);
}

/* ── 요금 사다리 ──────────────────────────────────────────────────────── */
/* 베타 전면 개방 고지 — 사다리보다 **먼저** 오는 현재 조건이다. 액센트 테두리로 층을
   분리한다: 같은 카드처럼 보이면 "무료 5회" 와 나란한 선택지로 읽힌다. */
.lp-beta {
  padding: 20px 18px; margin: 0 0 22px;
  border-radius: var(--lp-r-lg);
  border: 1px solid var(--lp-acc-text);
  background: rgba(200, 247, 81, .07);
}
.lp-beta-t { margin: 0 0 10px; font-size: .98rem; line-height: 1.62; color: var(--lp-fg2); }
.lp-beta-t b { color: var(--lp-fg); font-weight: 500; }
.lp-beta-s { margin: 0; font-size: .84rem; line-height: 1.6; color: var(--lp-fg3); }
.lp-beta-k { margin-top: 0; }
/* "현재 클로즈드 베타" — 아래 "정식 오픈 후 예정 요금" 킥커와 **짝**이다.
   두 시제를 나란히 보여야 "지금 무료" 와 "나중 요금" 이 서로를 취소하지 않는다. */
.lp-beta-k2 {
  margin: 0 0 8px; font-size: .75rem; font-weight: 700;
  letter-spacing: 0; color: var(--lp-acc-text);
}
/* ── 접힘 (§7 의 계산식·한계) ──────────────────────────────────────────────
   ★ `.lp-faq` 를 재사용하지 않는 이유: 거기엔 데스크톱 `max-width:800px` 가 걸려 있어
     본문(1120px)보다 좁아진다. 겉모습만 같게 10줄 복제하는 편이 싸다.
   ⚠️ 강한 주장을 이 안으로 넣지 마라 — "숫자는 코드가 계산한다"·강제/부탁 2칸은 **펼친
      채**여야 한다(`test_core_claims_are_outside_any_fold`). 이 레포는 접힌 UI 가 문자열
      테스트를 통과한 사고를 한 라운드에 세 번 겪었다. */
.lp-fold { margin: 24px 0 0; border-top: 1px solid var(--lp-line); }
.lp-fold details { border-bottom: 1px solid var(--lp-line); }
.lp-fold summary {
  cursor: pointer; list-style: none; padding: 16px 34px 16px 0; position: relative;
  font-size: .9rem; font-weight: 500; line-height: 1.5; color: var(--lp-fg2);
}
.lp-fold summary::-webkit-details-marker { display: none; }
.lp-fold summary::after {
  content: '+'; position: absolute; right: 4px; top: 13px;
  font-size: 1.3rem; font-weight: 400; color: var(--lp-fg3); transition: transform .18s ease;
}
.lp-fold details[open] summary { color: var(--lp-fg); }
.lp-fold details[open] summary::after { transform: rotate(45deg); }
.lp-fold details p {
  margin: 0 0 14px; font-size: .88rem; line-height: 1.72; color: var(--lp-fg2);
}
.lp-fold details p:last-child { padding-bottom: 6px; }
.lp-fold details p b { color: var(--lp-fg); font-weight: 500; }
/* 근거 링크(Gabbett). 밑줄을 남겨 링크임을 드러낸다 — 접힘 안에서 링크가 안 보이면 근거를
   단 의미가 없다. 이 규칙은 `.bs-a a` 에서 옮겨 왔다. */
.lp-fold details p a { color: var(--lp-fg); text-decoration: underline; text-underline-offset: 2px; }

.lp-steps { margin: 0; padding: 0; list-style: none; display: grid; gap: 10px; }
.lp-step {
  position: relative; padding: 20px 18px; border-radius: var(--lp-r-lg);
  background: var(--lp-s1); border: 1px solid var(--lp-line);
}
.lp-step.on { border-color: var(--lp-acc-text); background: var(--lp-s2); }
.s-k {
  margin: 0 0 4px; font-size: .75rem; font-weight: 700;
  letter-spacing: 0; color: var(--lp-fg3);
}
.lp-step.on .s-k { color: var(--lp-acc-text); }
.s-p {
  position: absolute; top: 18px; right: 18px; margin: 0;
  font-family: var(--lp-display); font-weight: 700; font-size: 1.28rem;
  letter-spacing: -.02em; color: var(--lp-fg); text-align: right;
}
.s-p span {
  display: block; font-family: var(--lp-body); font-size: .75rem;
  font-weight: 500; letter-spacing: 0; color: var(--lp-fg3);
}
.s-t {
  margin: 0 0 8px; padding-right: 96px;
  font-family: var(--lp-display); font-weight: 700; font-size: 1.08rem; letter-spacing: -.02em;
  color: var(--lp-fg);
}

/* ── FAQ ──────────────────────────────────────────────────────────────── */
.lp-faq { border-top: 1px solid var(--lp-line); }
.lp-faq details { border-bottom: 1px solid var(--lp-line); }
.lp-faq summary {
  cursor: pointer; list-style: none; padding: 18px 34px 18px 0; position: relative;
  font-size: .96rem; font-weight: 500; line-height: 1.5; color: var(--lp-fg);
}
.lp-faq summary::-webkit-details-marker { display: none; }
.lp-faq summary::after {
  content: '+'; position: absolute; right: 4px; top: 15px;
  font-size: 1.3rem; font-weight: 400; color: var(--lp-fg3); transition: transform .18s ease;
}
.lp-faq details[open] summary::after { transform: rotate(45deg); }
.lp-faq details p {
  margin: 0; padding: 0 0 20px; font-size: .9rem; line-height: 1.72; color: var(--lp-fg2);
}
.lp-faq-more { margin: 22px 0 0; font-size: .84rem; line-height: 1.6; color: var(--lp-fg3); }
.lp-faq-more a { color: var(--lp-fg); }
.lp-faq-more b { color: var(--lp-fg2); font-weight: 500; }

/* ── 마감 ─────────────────────────────────────────────────────────────── */
.lp-final {
  text-align: center;
  background: radial-gradient(100% 60% at 50% 0%, rgba(200, 247, 81, .10), transparent 62%);
}
/* ⚠️ 컨테이너를 가운데 두는 것만으로는 부족하다. 700px 이상에서 `.lp-cta` 는
   `display:flex` 가 되는데 `justify-content` 기본값이 flex-start 라, 가운데 놓인
   460px 상자 **안에서 버튼만 왼쪽으로 몰린다**(실측 −110px). 제목·리드·로그인 줄은
   text-align 으로 가운데였기 때문에 버튼만 어긋나 보였다. */
.lp-final .lp-cta {
  max-width: 460px; margin-inline: auto;
  justify-content: center;
}
.lp-final .lp-login { justify-content: center; }

/* ── 푸터 ─────────────────────────────────────────────────────────────── */
.lp-foot {
  padding: 40px var(--lp-pad) calc(40px + env(safe-area-inset-bottom, 0px));
  border-top: 1px solid var(--lp-line);
}
.lp-foot-nav { display: flex; flex-wrap: wrap; gap: 8px 18px; margin: 16px 0 14px; }
.lp-foot-nav a { font-size: .82rem; color: var(--lp-fg2); text-decoration: none;
                 display: inline-flex; align-items: center; justify-content: center; min-height: 44px; min-width: 44px; margin: -10px 0; }
.lp-foot-t { margin: 0; font-size: .75rem; color: var(--lp-fg3); }
/* `/en` 푸터의 한 줄 각주 — 요금·개인정보·약관이 한국어라는 사실. 링크를 지우는 대신
   사실을 적는다(법무 문서로 가는 길은 남아야 한다). */
.lp-foot-note { color: var(--lp-line-2); }

/* ── 모바일 스티키 ────────────────────────────────────────────────────── */
.lp-sticky {
  position: fixed; inset: auto 0 0 0; z-index: 55;
  padding: 10px var(--lp-pad) calc(10px + env(safe-area-inset-bottom, 0px));
  background: rgba(8, 9, 10, .88);
  backdrop-filter: saturate(1.4) blur(14px);
  -webkit-backdrop-filter: saturate(1.4) blur(14px);
  border-top: 1px solid var(--lp-line);
  /* ⚠️ 거리로만 밀어내면 안 된다. `translateY(102%)` 로만 숨긴 시트가 iOS Chrome 에서
     닫힌 채로 보인 사고가 있었다(브라우저 UI 띠 높이는 브라우저가 정한다).
     `visibility` 로 확실히 끈다. */
  transform: translateY(110%);
  visibility: hidden;
  transition: transform .22s ease, visibility 0s linear .22s;
}
.lp-sticky.on { transform: none; visibility: visible; transition-delay: 0s; }
.lp-sticky .lp-btn { margin-bottom: 0; }
body.lp-sticky-on { padding-bottom: 84px; }

/* ── 모션 (역게이트) ──────────────────────────────────────────────────── */
.lp-motion [data-rv] {
  opacity: 0; transform: translateY(14px);
  transition: opacity .5s ease, transform .5s ease;
}
.lp-motion [data-rv].in { opacity: 1; transform: none; }
.lp-motion [data-rv-s] > * {
  opacity: 0; transform: translateY(12px);
  transition: opacity .45s ease, transform .45s ease;
}
.lp-motion [data-rv-s].in > * { opacity: 1; transform: none; }
.lp-motion [data-rv-s].in > *:nth-child(2) { transition-delay: .07s; }
.lp-motion [data-rv-s].in > *:nth-child(3) { transition-delay: .14s; }
.lp-motion [data-rv-s].in > *:nth-child(4) { transition-delay: .21s; }

@media (prefers-reduced-motion: reduce) {
  .lp-motion [data-rv],
  .lp-motion [data-rv-s] > * { opacity: 1; transform: none; transition: none; }
  .lp-progress, .lp-sticky, .lp-btn { transition: none; }
  /* ⚠️ 반짝임은 **무한 반복**이라 여기서 반드시 꺼야 한다. 리빌은 한 번 돌고 끝나지만
     이건 계속 움직여서, 전정기관 문제가 있는 사용자에게는 페이지를 못 읽게 만든다.
     `animation: none` 만으로는 마지막 프레임이 남을 수 있어 요소 자체를 없앤다. */
  .lp-shine::after { animation: none; content: none; }
}

/* ── 태블릿 ───────────────────────────────────────────────────────────── */
@media (min-width: 700px) {
  body.lp { --lp-pad: 32px; }
  .lp-sec { padding: 92px var(--lp-pad); }
  .lp-hero { padding: 64px var(--lp-pad) 84px; }
  .lp-cta { display: flex; flex-wrap: wrap; gap: 10px; align-items: center; }
  .lp-btn { width: auto; min-width: 240px; margin-bottom: 0; }
  .lp-cta-sub, .lp-login { flex-basis: 100%; }
  .lp-login { border-top: 0; padding-top: 0; margin-top: 10px; }
  .lp-decode { grid-template-columns: repeat(3, 1fr); }
  /* 질문 넷·결과 넷 모두 2×2. **정확히 4개**라 고아 줄이 안 생긴다 — 항목을 3개나
     5개로 바꾸려면 이 두 줄을 함께 다시 보라. */
  .lp-asks { grid-template-columns: 1fr 1fr; column-gap: 22px; }
  .lp-outcomes { grid-template-columns: 1fr 1fr; }
  .lp-enforce { grid-template-columns: 1fr 1fr; }
  .lp-gal { grid-template-columns: 1fr 1fr; }
  .lp-steps { grid-template-columns: 1fr 1fr; }
  .lp-shot img, .hw-i img { max-width: 420px; margin-inline: auto; }
  /* 스티키는 모바일 전용 — 데스크톱에는 상단 네비 CTA 가 항상 보인다. */
  .lp-sticky { display: none; }
  body.lp-sticky-on { padding-bottom: 0; }
}

/* ── 데스크톱 ─────────────────────────────────────────────────────────── */
@media (min-width: 1000px) {
  .lp-hero-in {
    display: grid; grid-template-columns: 1.08fr .92fr; gap: 56px; align-items: start;
    /* ⚠️ `align-content` 가 없으면 자동 행이 **늘어난다.** 오른쪽 목업이 전체 행을
       span 하면서 컨테이너를 키우고, 남는 높이가 왼쪽 행들 사이에 균등 분배돼
       제목·리드·CTA 사이에 빈 칸이 생긴다(디자인이 아니라 그리드의 기본값이다).
       `start` 로 행을 위에 몰아 붙인다. */
    align-content: start;
    column-gap: 56px; row-gap: 0;
  }
  /* 히어로 글래스는 오른쪽 열에서 텍스트 전체 높이를 따라 선다. */
  /* span 은 왼쪽 열 자식 수와 맞춘다(킥커·H1·리드·CTA = 4). 모자라면 오브젝트가 짧은
     행에 갇혀 세로로 눌리고, 넘치면 빈 행이 생겨 아래 여백이 벌어진다.
     ⚠️ 히어로에 요소를 더하거나 빼면 이 숫자도 같이 고쳐라.
        `tests/test_web_landing.py::test_hero_grid_span_matches_left_column` 가 잠근다 —
        이 계약은 화면에서만 깨지고 테스트는 전부 초록이라 문자열로 못 잡는다. */
  /* 데스크톱에서는 상단 배너가 아니라 오른쪽 열의 기둥이다 — 모바일 배너용 상한·중앙정렬·
     아래 여백을 전부 되돌리고 세로 비율로 돌아간다. DOM 에서는 첫 자식이지만 아래 명시
     배치가 위치를 정하므로 순서는 무관하다. */
  .lp-hero .lp-glass {
    grid-column: 2; grid-row: 1 / span 4; align-self: center;
    max-width: none; margin: 0; aspect-ratio: 3 / 4;
  }
  .lp-hero .lp-kicker,
  .lp-hero .lp-h1,
  .lp-hero .lp-lede,
  .lp-hero .lp-cta { grid-column: 1; }

  .hw { display: grid; grid-template-columns: 1fr 1fr; gap: 44px; align-items: center; }
  .hw-i { margin-top: 0; }
  /* ⚠️ 예전엔 여기서 600/820(세로)으로 되돌렸다. 새 단계 자산은 **4:3 가로**라
     그대로 두면 화면이 세로로 늘어난다. 가로 여유가 있으니 자르지 않고 원본 비율. */
  .hw-i img { aspect-ratio: 4 / 3; object-fit: fill; }
  .hw.rev .hw-t { order: 2; }
  .lp-steps-3 { gap: 72px; }
  .lp-steps { grid-template-columns: repeat(4, 1fr); }
  .lp-faq { max-width: 800px; }
}
