/* ===== v50-11 폰트 교체: 영문 TWK Lausanne / 한글 ABC Favorit Hangul (자체 호스팅 woff2) =====
   ⟳ 롤백: 이 @font-face 블록 + :root의 새 --font-body 줄을 주석 → 옛 --font-body 줄 활성 → index.html:27 Pretendard <link> 주석 해제. (원본 백업: zz.old/prefont/) */
@font-face{font-family:'TWK Lausanne';font-style:normal;font-weight:400;font-display:swap;src:url('../fonts/TWK%20Lausanne%20Family/TWKLausanne-400.woff2') format('woff2')}
@font-face{font-family:'TWK Lausanne';font-style:normal;font-weight:500;font-display:swap;src:url('../fonts/TWK%20Lausanne%20Family/TWKLausanne-500.woff2') format('woff2')}
@font-face{font-family:'TWK Lausanne';font-style:normal;font-weight:600;font-display:swap;src:url('../fonts/TWK%20Lausanne%20Family/TWKLausanne-600.woff2') format('woff2')}
@font-face{font-family:'TWK Lausanne';font-style:normal;font-weight:650;font-display:swap;src:url('../fonts/TWK%20Lausanne%20Family/TWKLausanne-650.woff2') format('woff2')}
@font-face{font-family:'TWK Lausanne';font-style:normal;font-weight:700;font-display:swap;src:url('../fonts/TWK%20Lausanne%20Family/TWKLausanne-700.woff2') format('woff2')}
@font-face{font-family:'TWK Lausanne';font-style:normal;font-weight:750;font-display:swap;src:url('../fonts/TWK%20Lausanne%20Family/TWKLausanne-750.woff2') format('woff2')}
@font-face{font-family:'TWK Lausanne';font-style:italic;font-weight:500;font-display:swap;src:url('../fonts/TWK%20Lausanne%20Family/TWKLausanne-500Italic.woff2') format('woff2')}
@font-face{font-family:'ABC Favorit Hangul';font-style:normal;font-weight:400;font-display:swap;src:url('../fonts/ABC%20Favorit%20Hangul/ABCFavoritHangul-Regular.woff2') format('woff2')}
@font-face{font-family:'ABC Favorit Hangul';font-style:normal;font-weight:500;font-display:swap;src:url('../fonts/ABC%20Favorit%20Hangul/ABCFavoritHangul-Medium.woff2') format('woff2')}
@font-face{font-family:'ABC Favorit Hangul';font-style:normal;font-weight:700;font-display:swap;src:url('../fonts/ABC%20Favorit%20Hangul/ABCFavoritHangul-Bold.woff2') format('woff2')}
:root{
  --ink:#161614;
  --ink-soft:#4c4b47;
  --paper:#EDEBE6;
  --paper-deep:#E2DFD8;
  --line:rgba(22,22,20,.16);
  --green:#2C5C40;
  --cream:#F3EADB;
  --white:#FBFAF7;
  /* --font-body:'Pretendard Variable',Pretendard,-apple-system,sans-serif;   ← v50-11 롤백용 옛 값(활성화 시 아래 줄 주석) */
  --font-body:'TWK Lausanne','ABC Favorit Hangul',-apple-system,sans-serif;   /* v50-11: 라틴=Lausanne, 한글=Favorit Hangul */
  --pad:clamp(20px,4.5vw,64px);
}
*{margin:0;padding:0;box-sizing:border-box}
/* v49: 시스템 스크롤바 제거 — 커스텀 동그라미(scrollbar.js)로 대체. 스크롤바가 0폭이라
   모달 overflow:hidden 잠금 시 콘텐츠가 밀리는(오른쪽 점프) 버그도 함께 사라짐. */
html{scrollbar-width:none;-ms-overflow-style:none;overflow-x:clip}   /* v50-19: 뷰포트 레벨 가로 스크롤 완전차단. body clip만으론 애니(케이스 스트립·팝업 파티클) 잔여가 새 맨아래서 가로 스크롤됐음. clip은 hidden과 달리 스크롤 컨테이너를 안 만들어 ScrollTrigger 윈도우 스크롤러·핀에 무영향(스모크 stick.top==0·필름 통과 확인). 세로 스크롤 정상. [원복: overflow-x:clip 제거] */
body{overflow-x:clip}   /* v50-13: 모바일 가로 스크롤 차단(캡슐 캔버스·오브젝트 아이콘이 뷰포트 밖 넘침). html이 아니라 body에 걸어 ScrollTrigger 핀 스크롤러(html/window)는 안 건드림 */
html::-webkit-scrollbar,body::-webkit-scrollbar{width:0;height:0;display:none}
body{
  font-family:var(--font-body);
  background:transparent;
  color:var(--ink);
  line-height:1.6;
  letter-spacing:-0.012em;
  /* v50-19: 중복 overflow-x:hidden 제거 — 위 line30 body{overflow-x:clip}(v50-13)를 덮어써 실제론 hidden으로 동작(=스크롤 컨테이너 생성 → 맨 아래서 잔여 가로 스크롤). clip은 순수 클립이라 가로 스크롤 원천 차단. [원복: overflow-x:hidden 복원] */
}
::selection{background:var(--ink);color:var(--paper)}
/* v50-89: `height:auto` 추가 — **v50-78 회귀 수정**.
   v50-78에서 모든 <img>에 `width`/`height` 속성을 넣었는데(콜라이더 레이스 방지·CLS 제거용),
   이 전역 규칙이 `max-width`만 있고 height를 안 정해 **속성값 height가 그대로 살아남았다**.
   → width는 max-width/부모에 맞춰 줄었는데 height는 원본 픽셀 그대로 = **세로로 길쭉하게 왜곡**.
   실측 왜곡: `joy_mark` 40.1%(2.09→1.251) · `brand_shake_01/02`·`custom_shake_01` 각 20.2%(0.562→0.448).
   `aspect-ratio`가 속성에서 생기지만 **width·height가 둘 다 확정되면 무시**되므로 이걸론 못 막는다.
   `max-width:100%` + `height:auto`가 반응형 이미지의 표준 짝이고, width/height 속성을 쓰는 순간 필수가 된다.
   ⚠height를 **명시**하는 규칙들(`.jst img`·`.step .ph img`·`.case-strip img`의 `height:100%`)은
   선택자 특이도가 높아 그대로 이긴다 — 크롭 레이아웃은 영향 없음(실측 확인). */
img{display:block;max-width:100%;height:auto}
a{color:inherit;text-decoration:none}
button{font:inherit;cursor:pointer;border:none;background:none}

.bg-layer{position:fixed;inset:0;z-index:-1;background:#EDEBE6}
/* ---------- nav ---------- */
.nav{
  position:fixed;inset:0 0 auto 0;z-index:100;
  display:flex;align-items:center;justify-content:space-between;
  padding:18px var(--pad);
  transition:color .35s;
}
.nav-logo{width:64px;color:var(--navc,#161614)}
.nav{--navc:#161614}
.nav.nav-light{--navc:#FBFAF7}
.nav-logo svg{display:block;width:100%;height:auto}
.nav-actions{display:flex;gap:10px;align-items:center}
.btn{
  display:inline-flex;align-items:center;gap:8px;
  padding:10px 20px;border-radius:0;   /* v49: 알약형 → 각진 네모(문의 모달·본사 문법 통일, 사용자) */
  font-size:14px;font-weight:600;letter-spacing:-0.01em;
  transition:transform .2s,background .2s,color .2s,border-color .2s;
}
.btn:active{transform:scale(.97)}
.btn-ghost{border:1px solid var(--navc);color:var(--navc);transition:color .35s,border-color .35s}
.btn-ghost:hover{opacity:.75}
.btn-solid{background:var(--navc);color:var(--navb,#FBFAF7);transition:background .35s,color .35s}
.nav.nav-light{--navb:#161614}
.btn-solid:hover{opacity:.85}
@media(max-width:640px){ .btn{padding:9px 16px;font-size:13px} }   /* v50-13: .btn-ghost(브로슈어) 숨김 해제 — 모바일에도 노출(사용자 요청) */

/* ===== v50-46: 터치 탭 영역 확장 (반응형 점검에서 유일하게 나온 실질 이슈) =====
   실측(전 기기 공통): 전화 84x17 / 이메일 165x17 / 푸터 링크 61x15 / 헤더 버튼 79x39
   → iOS 44px·Android 48px 권장 미달. 폰에서 정확히 17px를 찍어야 눌리는 상태였다.
   방식: **글자·버튼 크기는 건드리지 않고** 투명 ::after로 히트 영역만 확대 → 레이아웃·디자인 변화 0.
   ⚠::after가 링크 '안'에 있으므로 클릭은 그대로 링크로 간다. 대상 4종 모두 ::after 미사용 확인함.
   터치 기기에만 적용(마우스는 정밀 포인팅이라 불필요 + 데스크톱 히트영역 확대는 오히려 오클릭). */
@media(pointer:coarse){
  .contact-info a, .footer a{ position:relative }   /* display는 건드리지 않음 — inline-block로 바꾸면 베이스라인·줄바꿈이 미세하게 달라짐 */
  /* v50-89: 탭 영역 확대(사용자). 44 → **60px**, 좌우 -12 → **-14px**.
     실측 제약 — 폰에서 같은 줄 인접 링크 간격이 **28px**뿐이라 좌우는 각 14px가 **겹치지 않는 최대**다
     (14+14=28 = 딱 맞닿음). 더 늘리면 인접 링크와 탭 영역이 겹쳐 **엉뚱한 링크가 눌린다** — 작은 타깃보다 나쁘다.
     세로는 다른 줄과 76px 떨어져 있어 60px면 여유 16px. 44(최소 권장)에서 36% 확대.
     ⚠좌우를 더 키우려면 CSS가 아니라 **항목 전체(<b>값</b>+라벨)를 링크로 감싸야** 한다 — 구조 변경. */
  .contact-info a::after, .footer a::after{
    content:''; position:absolute; left:-14px; right:-14px;
    top:50%; height:60px; transform:translateY(-50%);
  }
  .btn{ position:relative }
  .btn::after{ content:''; position:absolute; inset:-4px -2px }   /* 39 → 47px */
}

/* ---------- section chrome ---------- */
.sec-head{
  display:flex;justify-content:space-between;align-items:baseline;
  padding-top:22px;
  font-size:13px;font-weight:600;letter-spacing:.02em;
}
.sec-head .idx{font-style:italic;font-weight:500;color:var(--ink-soft)}
.sec{padding:0 var(--pad)}
.sec-inner{max-width:1280px;margin:0 auto;position:relative}
h2.headline{
  font-size:clamp(28px,4.2vw,54px);
  font-weight:650;line-height:1.24;letter-spacing:-0.035em;
  margin:clamp(28px,4vw,52px) 0 clamp(36px,5vw,72px);
  white-space:pre-line;
}
h2.headline em{font-style:normal;font-weight:750}

/* ---------- hero ---------- */
.hero{
  position:relative;height:100svh;min-height:560px;
  display:flex;align-items:center;justify-content:center;
  overflow:visible;
}
.fall-canvas{position:fixed;top:0;left:0;width:100vw;height:100svh;z-index:5;pointer-events:none}
.hero-logo{
  position:relative;z-index:1;
  width:min(72vw,76svh);color:var(--ink); /* v49: 900px 캡 제거 — 뷰포트 비례(와이드=높이 기준, 좁으면 폭 기준). 공R=로고폭 파생이라 함께 비례 */
}
.hero-logo .shake{animation:heroIn 1.2s cubic-bezier(.2,.8,.2,1) both .15s}
/* 패럴럭스(--py)·눌림(--press)·기울기(--rot) 를 변수로 분리 합성 — 트윈 충돌 방지 */
[data-para], .hero-logo, .step .ph, .joy{
  transform:translateY(calc(var(--py,0px) + var(--press,0px))) rotate(var(--rot,0deg)) !important;
}
.hero-logo svg{width:100%;height:auto;display:block}
@keyframes heroIn{from{opacity:0;transform:translateY(24px)}to{opacity:1;transform:none}}
.hero-meta{
  position:absolute;z-index:3;left:var(--pad);right:var(--pad);
  display:flex;justify-content:space-between;
  font-size:13px;font-weight:600;color:var(--ink-soft);
  pointer-events:none;
}
.hero-meta.top{top:76px}
.hero-meta.bottom{bottom:26px;align-items:flex-end}
.luck-counter{font-variant-numeric:tabular-nums;letter-spacing:.04em}
.luck-counter b{color:var(--ink)}
.scroll-cue{display:flex;flex-direction:column;align-items:center;gap:6px;font-size:12px;letter-spacing:.1em}
.scroll-cue::after{content:"";width:1px;height:34px;background:var(--ink-soft);animation:cue 1.8s ease-in-out infinite}
@keyframes cue{0%,100%{transform:scaleY(.4);transform-origin:top}50%{transform:scaleY(1)}}

/* ---------- 빈 공간 장애물 (회사 아이콘 = 충돌체) ---------- */
.gapzone{position:relative;height:84svh;max-width:1280px;margin:0 auto;pointer-events:none}
/* v50-24: 컨택트 바로 위 gapzone(웃는얼굴 아이콘~컨택트 사이 빈공간)만 모바일서 반으로(84→42svh) — 사용자: 그 빈 공간이 너무 큼. 다른 gapzone은 불변. [원복: 이 줄 삭제] */
@media(max-width:640px){ .gz-contact{height:42svh} }
.obstacle{position:absolute;pointer-events:none}
.obstacle svg{display:block;width:100%;height:auto}
/* v50-16: 모바일 장식 아이콘(.obstacle) ~70% 축소 — 폰서 인라인 clamp 최소 220px가 화면폭 56%로 과대. 폭만 축소(svg width:100%라 비례 축소·transform 물리(--press/--rot) 무관·콜라이더는 rect 기반이라 자동 추종). !important로 인라인 width 오버라이드. [원복: 이 줄 삭제] */
@media(max-width:640px){ .obstacle{width:clamp(154px,22.4vw,336px)!important} }
/* ---------- JOY : 컨트롤러 카드 ---------- */
.joy-wrap{position:relative;z-index:4} /* 볼 캔버스(5) 아래 — 볼·접촉그림자가 카드 위에 그려지도록 */
.joy{position:relative;margin:clamp(240px,calc(6vw + 200px),290px) auto 0;
  visibility:hidden; /* JS 초기화 전 첫 페인트 노출 방지 */
  --jscol:#A5DB61;
  width:min(100%,1040px);aspect-ratio:2.1/1;
  border-radius:clamp(16px,2.4vw,30px);
  background:url(../img/joy_bg.webp) center/cover no-repeat;
  overflow:hidden;user-select:none;-webkit-user-select:none;touch-action:pan-y;
  box-shadow:0 26px 64px rgba(20,20,16,.12), 0 5px 16px rgba(20,20,16,.06);
  will-change:transform}
.joy-inner{position:absolute;inset:0}
.joy-btn{position:absolute;top:50%;transform:translateY(-50%);
  width:47%;aspect-ratio:1;pointer-events:none}
.joy-dpad{left:1.5%}
.joy-grab{right:4.5%}
/* 히트존: 에셋 투명 여백 제외, 버튼 형상 부근만 반응 */
.jhit{position:absolute;left:50%;top:50%;transform:translate(-50%,-50%);
  width:64%;height:64%;border-radius:50%;pointer-events:auto;cursor:pointer;touch-action:none}
.joy-grab .jhit{width:58%;height:46%}
.jst{position:absolute;inset:0;opacity:0;pointer-events:none}
.joy-btn[data-s="def"] .jst[data-s="def"],.joy-btn[data-s="up"] .jst[data-s="up"],
.joy-btn[data-s="down"] .jst[data-s="down"],.joy-btn[data-s="left"] .jst[data-s="left"],
.joy-btn[data-s="right"] .jst[data-s="right"],.joy-btn[data-s="press"] .jst[data-s="press"]{opacity:1}
.jst img,.jst .jm{position:absolute;inset:0;width:100%;height:100%;display:block;-webkit-user-drag:none}
.jst .jm{background:var(--jscol);
  -webkit-mask-size:100% 100%;mask-size:100% 100%;
  -webkit-mask-repeat:no-repeat;mask-repeat:no-repeat;
  -webkit-mask-position:center;mask-position:center}
.jst .j-sh{mix-blend-mode:multiply}
.jst .j-lt{mix-blend-mode:screen}
.joy-mark{position:absolute;right:4.5%;bottom:6.5%;width:16%;pointer-events:none}
.joy-part{position:absolute;left:0;top:0;width:100%;height:100%;pointer-events:none;overflow:visible;z-index:7}
@media(max-width:640px){
  .joy{width:100%}
}
/* ---------- statement ---------- */
.statement{padding-top:clamp(60px,7vw,110px);padding-bottom:clamp(80px,10vw,170px);position:relative}
/* v49: 전용 대형 h2(76px·들여쓰기) 폐기 → 다른 섹션과 동일한 h2.headline 문법으로 통일(사용자 요청).
   밸류 = feat-grid 문법 통일 — 오버라이드는 §feature sections 뒤(캐스케이드) */
.float{position:absolute;z-index:1}
.float .shake{border-radius:3px;box-shadow:0 24px 60px rgba(22,22,20,.18);overflow:hidden}
.float img{display:block;width:100%}
.shake{will-change:transform}
.float.f1{right:2%;top:0;width:clamp(120px,15vw,225px)}
.float.f2{right:22%;bottom:-4%;width:clamp(90px,11vw,165px)}
@media(max-width:860px){
  .value-list{max-width:none}
  .float.f1{width:100px;right:0;top:2%}
  .float.f2{display:none}
}

/* ---------- film : fullscreen -> wall screen + floor reflection ---------- */
.film{position:relative;z-index:6;height:260svh;background:#0B0B0A} /* v36: 여정 27% 단축 */
.film-stick{position:sticky;top:0;height:100svh;overflow:hidden}
/* 하단 경계 봉인 (v35): 룸 스케일 애니메이션과 무관하게 스틱 하단을 섹션 배경색(#0B0B0A)으로
   완전 불투명하게 마감 — 아래 검은 배경과의 단차 라인 제거. 알파는 하단에 몰아 반사 손실 최소화.
   z-index 2: 룸(0)·영상(film-center, 0) 위, 캡션(3) 아래. */
.film-stick::after{
  content:"";position:absolute;left:0;right:0;bottom:0;height:14svh;z-index:2;pointer-events:none;
  opacity:var(--sealA, 0); /* v36: 진행 90~100%에서 타임라인이 0->1 (REDUCED는 JS에서 1 고정) */
  background:linear-gradient(to bottom,
    rgba(11,11,10,0) 0%, rgba(11,11,10,.5) 60%, rgba(11,11,10,1) 100%);
}
.film-room{
  position:absolute;inset:0;opacity:0;
  transform-origin:50% 60%;will-change:transform,opacity;
  background:url('../img/film_room_bg.webp') center/cover no-repeat;
}
.film-room::after{
  content:"";position:absolute;inset:0;
  background:
    linear-gradient(to bottom, rgba(11,11,10,0) 80%, rgba(11,11,10,.5) 93%, rgba(11,11,10,.94) 100%),
    radial-gradient(100% 80% at 50% 44%, rgba(0,0,0,0) 52%, rgba(0,0,0,.28) 100%),
    linear-gradient(rgba(0,0,0,.18), rgba(0,0,0,0) 30%);
}
.film-center{position:absolute;inset:0;display:flex;align-items:center;justify-content:center}
.film-scale{
  position:relative;
  width:min(47vw,780px);aspect-ratio:16/9;
  will-change:transform; /* 합성 레이어 고정 */
}
.film-screen{
  position:absolute;inset:0;overflow:hidden;
  background:#101010;
}
.film-bezel{
  /* v37: 폭 70% 축소(-2.49/-1.4 -> -1.74/-0.98) + 유광 프레임 — 상단 광원 그라디언트와
     안쪽 모서리 하이라이트로 빛 반사 느낌 */
  position:absolute;inset:-1.74% -0.98%;border-radius:4px;opacity:0;
  background:linear-gradient(145deg,#2a2a2a 0%,#0a0a0a 28%,#050505 62%,#161616 100%);
  z-index:-1;
  box-shadow:0 34px 80px rgba(0,0,0,.6), 0 4px 16px rgba(0,0,0,.5),
             inset 0 1px 0 rgba(255,255,255,.06), inset 0 -1px 0 rgba(255,255,255,.03);
}
.film-brandbar{
  position:absolute;left:0;right:0;top:-13%;opacity:0;
  text-align:center;color:rgba(255,255,255,.42);
  font-size:clamp(9px,0.9vw,13px);letter-spacing:.42em;font-weight:700;
}
/* FILM PLACEHOLDER — 영상 교체 시 .film-ph 를 <video>로 (반사쪽도 동일하게) */
.film-ph{
  position:absolute;inset:0;display:flex;flex-direction:column;
  align-items:center;justify-content:center;gap:18px;color:#e8e8e2;
  background:#131312;
}
.film-ph .ph-poster{
  position:absolute;inset:0;width:100%;height:100%;object-fit:cover;
  opacity:.5;filter:saturate(.8) brightness(.85);
}
.film-ph .ring,.film-ph span{position:relative;z-index:1;text-shadow:0 1px 14px rgba(0,0,0,.6)}
.film-ph .ring{
  width:clamp(44px,5vw,74px);height:clamp(44px,5vw,74px);
  border:1px solid rgba(255,255,255,.55);border-radius:50%;
  display:flex;align-items:center;justify-content:center;flex:none;
}
.film-ph .ring::after{content:"";border-style:solid;border-width:9px 0 9px 15px;border-color:transparent transparent transparent #e8e8e2;margin-left:4px}
.film-ph span{font-size:clamp(9px,0.85vw,12px);letter-spacing:.18em;font-weight:600;white-space:nowrap}
.film-reflect{
  /* 좌우 12% 블리드: 블러가 요소 경계에서 잘리지 않도록 스크린보다 넓게 */
  position:absolute;top:calc(100% + var(--rgap, 12px));left:-12%;right:-12%;height:92%;
  opacity:0;overflow:hidden;pointer-events:none;
  filter:blur(9px) brightness(.92) saturate(1); /* v36: 반사 강화 */
  -webkit-mask-image:linear-gradient(to bottom, transparent, rgba(0,0,0,.78) 5%, rgba(0,0,0,.28) 44%, transparent 76%),
                     linear-gradient(to right, transparent, #000 13%, #000 87%, transparent);
  -webkit-mask-composite:source-in;
          mask-image:linear-gradient(to bottom, transparent, rgba(0,0,0,.78) 5%, rgba(0,0,0,.28) 44%, transparent 76%),
                     linear-gradient(to right, transparent, #000 13%, #000 87%, transparent);
          mask-composite:intersect;
}
.film-reflect canvas{position:absolute;inset:0;width:100%;height:100%;display:block}
.film-reflect .film-ph{transform:scaleY(-1);top:auto;bottom:0;height:128%}
.film-vid{position:absolute;inset:0;width:100%;height:100%;object-fit:cover;
  /* v43 검정 플래시 완화: 스케일/리사이즈 중 하드웨어 디코드 영상의 레이어 재래스터 순단 시
     .film-screen 배경(#101010)이 비치는 문제 — 영상 자체 합성 레이어 고정으로 재할당 빈도 축소 */
  transform:translateZ(0);backface-visibility:hidden;will-change:transform}
.film-caption{
  position:absolute;left:0;right:0;bottom:5.5%;z-index:3;
  text-align:center;color:var(--paper);opacity:0;transform:translateY(24px);
  padding:0 var(--pad);text-shadow:0 2px 24px rgba(0,0,0,.5);
}
/* v50-70: FILM 섹션 번호 (2). 다른 섹션의 `.sec-head .idx`(:94)와 같은 문법 —
   italic / weight 500 / 13px / letter-spacing .02em. 색은 어두운 배경 위라 `.inv .sec-head .idx`(:532)와 동일한
   rgba(251,250,247,.55)를 씀. 캡션이 text-align:center이므로 자동으로 가운데 정렬되고,
   부모의 opacity 페이드를 함께 받는다. */
.film-idx{
  display:block;margin-bottom:12px;
  font-size:13px;font-weight:500;font-style:italic;letter-spacing:.02em;
  color:rgba(251,250,247,.55);
}
.film-caption h3{font-size:clamp(22px,3vw,38px);font-weight:650;letter-spacing:-0.03em;line-height:1.3}
.film-caption p{margin-top:10px;font-size:15px;color:#c9c9c2}
@media(max-width:720px){ .film-scale{width:84vw} }

/* ---------- feature sections ---------- */
.block{padding-top:clamp(80px,9vw,140px);padding-bottom:clamp(90px,10vw,160px)}
/* 섹션 사이 여백: 배경색이 전이되는 빈 구간 */
.statement,#film,.tech-sec,.ux,.mgmt,.custom-sec,.case,.contact{margin-top:clamp(50px,10svh,120px)} /* gapzone이 간격 담당 */
.feat-grid{
  display:grid;grid-template-columns:1fr 1fr;gap:0;
  border-top:1px solid var(--line);
}
.feat{
  padding:clamp(28px,3.5vw,48px) clamp(0px,2.5vw,40px) clamp(28px,3.5vw,48px) 0;
  border-bottom:1px solid var(--line);
}
.feat:nth-child(odd){border-right:1px solid var(--line)}
.feat:nth-child(even){padding-left:clamp(20px,2.5vw,40px)}
.feat h3{font-size:clamp(18px,1.8vw,23px);font-weight:700;letter-spacing:-0.025em;margin-bottom:10px}
.feat p{font-size:15px;color:var(--ink-soft);max-width:46ch}
@media(max-width:720px){
  .feat-grid{grid-template-columns:1fr}
  .feat:nth-child(odd){border-right:none}
  .feat:nth-child(even){padding-left:0}
}
/* v49: 브랜드 스토리 밸류 — feat-grid 문법(Technology와 동일 헤어라인)로 좌측 1컬럼 스택.
   우측은 QR 플립(540px). 본체 규칙 뒤에 둬야 캐스케이드에서 이김. */
.value-list{grid-template-columns:1fr;max-width:560px;position:relative;z-index:2}
.value-list .feat{border-right:none;padding-left:0;padding-right:0}
.value-list .feat:last-child{border-bottom:none}   /* v50-8: 마지막(프리미엄 가챠) 밑선은 세션 전폭 rule로 대체 */
.statement .value-rule{border-top:1px solid var(--line);position:relative;z-index:2}   /* v50-8: 프리미엄 가챠 밑 라인 — sec-inner 전폭(=세션 우단)까지. rv 페이드는 유지 */

/* ---------- ux ---------- */

.step-grid{display:grid;grid-template-columns:repeat(3,1fr);gap:clamp(16px,2vw,28px)}
.step:nth-child(2){margin-top:clamp(24px,3.5vw,56px)}
.step .ph{aspect-ratio:4/3;overflow:hidden;background:var(--paper-deep);border-radius:4px}
/* 호버 줌: 이미지별 포커스(--zox/--zoy = 핸드폰 중심)로 확대. origin이 [0,100]%·scale≥1이라 빈공간 불가.
   값은 assets/ux_zoom.json → ux-zoom.js가 주입. H 디버그 패널로 튜닝. */
.step .ph img{width:100%;height:100%;object-fit:cover;
  transform-origin:var(--zox,50%) var(--zoy,50%);transition:transform .6s cubic-bezier(.2,.8,.2,1)}
.step:hover .ph img{transform:scale(var(--zs,1.06))}
/* UX 줌 튜닝 모드(H): 프레임 아웃라인 + 조정 중 이미지엔 호버 없이 실시간 줌 표시 */
body.ux-tune .step .ph{outline:2px dashed rgba(58,109,240,.75);outline-offset:2px;cursor:grab}
body.ux-tune .step .ph img.ux-live{transform:scale(var(--zs,1.06))}

/* ============ 문의 모달 (v49) — 색은 아래 5개 변수로 일괄 조정(럭키그랩 톤, 추후 변경 용이) ============ */
.inq-overlay{
  /* v49.2: 아이엠파인 본사 Project Inquiries 모달 문법 이식(사용자 승인 B안) —
     핑크 통짜 카드(#D985B6 실측) + 검정 잉크 + 흰 밑줄 + 필드 앞 →/↓ 글리프 + 보더 박스 X */
  --inq-card:#D985B6; --inq-ink:#141412; --inq-soft:rgba(20,20,18,.58);
  --inq-accent:#FBFAF7; --inq-line:rgba(255,255,255,.9); --inq-dim:rgba(42,42,44,.78);
  --inq-neon:#D8FF3A;   /* 제출 검증 실패 하이라이트(야광) */
  position:fixed; inset:0; z-index:2000; display:flex; align-items:center; justify-content:center;
  padding:24px; background:var(--inq-dim); opacity:0; transition:opacity .25s ease;
  /* v49: backdrop-filter 블러 제거 — 뒤 WebGL 공이 매 프레임 변해 전체화면 블러 재계산=저사양 비용↑.
     반투명 딤만 유지(합성 비용 ~0). 블러 필요 시 배경 애니 정지 후 적용이 정석. */
}
.inq-overlay[hidden]{display:none}
.inq-overlay.inq-open{opacity:1}
.inq-card{
  position:relative; width:min(528px,100%); max-height:88svh; overflow-y:auto;   /* v49.3: 가로 +20%(사용자) */
  scrollbar-width:none;
  background:var(--inq-card); color:var(--inq-ink); border-radius:0;   /* 레퍼런스: 각진 카드 */
  padding:clamp(26px,4vw,40px); box-shadow:0 30px 80px rgba(0,0,0,.4);
  transform:translateY(14px) scale(.985); transition:transform .3s cubic-bezier(.2,.8,.2,1);
}
.inq-open .inq-card{transform:none}
/* X = 맨몸 대형 얇은 스트로크(레퍼런스 실사이트 — 보더 박스 없음, 사용자 확인) */
.inq-close{position:absolute; top:18px; right:18px; width:48px; height:48px;
  display:flex; align-items:center; justify-content:center;
  border:0; border-radius:0; background:none;
  color:var(--inq-ink); cursor:pointer; opacity:.9; transition:opacity .15s}
.inq-close svg{width:30px; height:30px}
.inq-close:hover{opacity:1}
/* 필드 앞 →/↓ 글리프 */
.inq-ico{position:absolute; left:1px; top:50%; transform:translateY(-50%);
  font-size:16px; line-height:1; color:#fff; pointer-events:none; transition:color .15s}
.inq-ico.ta{top:12px; transform:none}
.inq-lead{font-size:clamp(17px,2.4vw,20px); font-weight:600; line-height:1.45; letter-spacing:-.02em;
  margin:2px 60px 26px 0}
.inq-form{display:flex; flex-direction:column; gap:15px}
.inq-form[hidden]{display:none}   /* .inq-form의 display:flex가 UA [hidden]을 이겨서 안 숨는 것 방지 */
.inq-row{display:flex; flex-direction:column; position:relative}
.inq-row input, .inq-row select, .inq-row textarea{
  width:100%; border:0; border-bottom:1px solid var(--inq-line); background:transparent;
  /* v50-71: 15px → **16px**. iOS 사파리는 font-size가 16px 미만인 폼 컨트롤을 탭하면 페이지를 자동 확대하고,
     viewport에 maximum-scale이 없어(=접근성상 넣지 않는 게 맞다) **확대된 채로 돌아오지 않는다**.
     주력 CTA의 첫 인터랙션에서 터지고, position:fixed인 낙하공 캔버스까지 함께 확대돼 화면이 망가진다.
     input·select·textarea를 한 규칙이 덮으므로 여기 한 줄이면 세 종류 모두 해결.
     ⚠maximum-scale=1로 막는 우회는 쓰지 말 것 — 핀치 줌을 죽여 접근성을 해치고 iOS는 무시하기도 한다. */
  color:var(--inq-ink); font:inherit; font-size:16px; padding:9px 2px 9px 26px; outline:none;   /* 좌 26px = 앞 →/↓ 글리프 자리 */
  transition:border-color .2s;
}
/* 상태 체계(사용자 스펙): 초기=흰(플레이스홀더·밑줄·화살표) → 값이 생기면 검정 → 제출 검증 실패=야광 */
.inq-row input::placeholder, .inq-row textarea::placeholder{color:#fff}
.inq-row input, .inq-row select, .inq-row textarea{caret-color:var(--inq-ink)}
.inq-row:has(input:not(:placeholder-shown)) .inq-ico,
.inq-row:has(textarea:not(:placeholder-shown)) .inq-ico,
.inq-sel.filled .inq-ico{color:var(--inq-ink)}
.inq-row input:not(:placeholder-shown), .inq-row textarea:not(:placeholder-shown),
.inq-sel.filled select{border-bottom-color:var(--inq-ink)}
.inq-sel select{color:#fff}
.inq-sel.filled select{color:var(--inq-ink)}
.inq-row.inq-err input, .inq-row.inq-err select, .inq-row.inq-err textarea{border-bottom-color:var(--inq-neon) !important}
.inq-row.inq-err .inq-ico{color:var(--inq-neon) !important}
.inq-row.inq-err input::placeholder{color:var(--inq-neon)}
.inq-agree.inq-err span{color:var(--inq-neon)}
.inq-agree.inq-err .inq-policy-link{color:var(--inq-neon)}
.inq-row textarea{resize:vertical; min-height:78px; line-height:1.5; scrollbar-width:none}
.inq-row textarea::-webkit-scrollbar, .inq-card::-webkit-scrollbar{width:0;height:0;display:none}
.inq-sel select{
  appearance:none; -webkit-appearance:none; cursor:pointer; padding-right:24px;
  background-image:linear-gradient(45deg,transparent 50%,#fff 50%),linear-gradient(135deg,#fff 50%,transparent 50%);
  background-position:calc(100% - 12px) 55%, calc(100% - 7px) 55%; background-size:5px 5px,5px 5px; background-repeat:no-repeat;
}
.inq-sel select option{color:#161614}
/* 파일 첨부 행 — 다른 필드와 동일 상태 체계: 초기 흰 → 첨부 시 파일명 검정 + 취소 X 등장 */
.inq-file{flex-direction:row; align-items:center; justify-content:space-between; gap:12px;
  border-bottom:1px solid var(--inq-line); padding-bottom:4px; margin-top:4px}
.inq-fileleft{display:inline-flex; align-items:center; gap:10px}
.inq-filebtn{display:inline-flex; align-items:center; gap:9px; cursor:pointer; font-size:15px; padding:6px 2px; color:#fff; transition:color .15s}
.inq-filebtn .fico{font-size:17px; line-height:1}
.inq-filemax{font-size:12px; color:rgba(255,255,255,.75); white-space:nowrap}
.inq-file.has-file{border-bottom-color:var(--inq-ink)}
.inq-file.has-file .inq-filebtn{color:var(--inq-ink)}
.inq-file.has-file .ftxt{font-weight:600}
.inq-file.has-file .inq-filemax{color:var(--inq-soft)}
.inq-filecancel{display:flex; align-items:center; justify-content:center; width:22px; height:22px;
  border:0; background:none; color:var(--inq-ink); cursor:pointer; opacity:.85}
.inq-filecancel:hover{opacity:1}
.inq-filecancel[hidden]{display:none}
.inq-file.err{border-bottom-color:var(--inq-neon)}
.inq-file.err .inq-filebtn{color:var(--inq-neon)}
.inq-foot{display:flex; align-items:center; justify-content:space-between; gap:16px; margin-top:12px; flex-wrap:wrap}
.inq-agree{display:flex; align-items:flex-start; gap:9px; font-size:13.5px; color:var(--inq-soft); cursor:pointer; line-height:1.4}
.inq-agree input{appearance:none; -webkit-appearance:none; width:17px; height:17px; margin-top:1px;
  border:1px solid var(--inq-ink); border-radius:0; background:transparent; cursor:pointer; flex:none}
.inq-agree input:checked{background:var(--inq-ink)}   /* 체크 = 검은 사각형 가득(레퍼런스) */
.inq-policy-link{border:0; background:none; padding:0; font:inherit; font-size:inherit; color:var(--inq-ink);
  text-decoration:underline; text-underline-offset:2px; cursor:pointer}
.inq-send{border:0; background:none; padding:8px 2px; font:inherit; font-size:16px; font-weight:700;
  color:var(--inq-ink); cursor:pointer; text-decoration:underline; text-underline-offset:4px; white-space:nowrap}
.inq-send:hover{color:var(--inq-accent)}
/* v50-94: 전송 중 = 중복 제출 가드(HANDOFF §5-4). 눌린 걸 눈으로도 알 수 있어야 연타를 안 한다.
   ⚠`pointer-events:none`은 쓰지 않는다 — 버튼이 사라진 것처럼 보여 더 연타한다. 흐리게 + 커서로 알린다. */
.inq-send[disabled]{opacity:.45; cursor:progress; text-decoration:none}
.inq-send[disabled]:hover{color:var(--inq-ink)}
/* v50-94: 전송 실패 인라인 배너(HANDOFF §5-3). 폼 위에 뜨고 입력값은 그대로 남는다. */
.inq-fail{margin:14px 0 0; padding:10px 12px; border-left:2px solid var(--inq-neon);
  font-size:13.5px; line-height:1.5; color:var(--inq-neon)}
.inq-fail[hidden]{display:none}
.inq-done{display:flex; flex-direction:column; align-items:center; gap:22px; text-align:center;
  padding:48px 10px; font-size:17px; font-weight:600; line-height:1.5}
.inq-done[hidden]{display:none}
/* 개인정보처리방침 서브 패널 */
.inq-policy{position:absolute; inset:0; z-index:5; display:flex; align-items:center; justify-content:center;
  padding:24px; background:rgba(16,16,14,.5)}
.inq-policy[hidden]{display:none}
/* 정책 카드 = 다크 차콜 + 자주 보더 + 흰 텍스트(레퍼런스 이미지) */
/* v49.4(사용자): 핑크 보더 제거 · 타이틀/Confirm은 고정 레이어(스크롤은 중앙 내용만) · 세로 1/3 축소 */
.inq-policy-card{width:min(400px,92%); max-height:47svh; background:#48484b;
  display:flex; flex-direction:column; overflow:hidden;
  color:#FBFAF7; border:0; border-radius:0; padding:clamp(26px,4vw,42px); box-shadow:0 24px 60px rgba(0,0,0,.5)}
.inq-policy-card h3{font-size:clamp(24px,3vw,30px); font-weight:500; margin-bottom:26px}
.inq-policy-body{font-size:13px; color:rgba(251,250,247,.85); line-height:1.75; display:flex; flex-direction:column; gap:12px;
  flex:1; min-height:0; overflow-y:auto; scrollbar-width:none; padding-right:10px}
.inq-policy-body::-webkit-scrollbar{width:0;height:0;display:none}
.inq-policy-body b{color:#FBFAF7}
.inq-hr{border:0; border-top:1px solid rgba(251,250,247,.25); margin:8px 0}
.inq-policy-confirm{margin-top:24px; margin-left:auto; display:block; border:0; background:none; padding:6px 2px;
  font:inherit; font-weight:600; color:#FBFAF7; text-decoration:underline; text-underline-offset:4px; cursor:pointer}
.inq-policy-confirm:hover{color:var(--inq-neon)}
/* 정책 팝업 스크롤 구슬 — 페이지 우측 커스텀 스크롤(cscroll)과 동일 문법의 작은 원 */
.inq-dot{position:absolute; width:10px; height:10px; border-radius:50%; background:#fff;
  mix-blend-mode:difference;   /* 페이지 우측 커스텀 스크롤과 동일 문법 — 어떤 배경에서도 보임 */
  z-index:6; cursor:grab; touch-action:none; display:none}
.inq-dot:active{cursor:grabbing}
@media(max-width:520px){ .inq-card{max-height:92svh} .inq-foot{gap:12px} }

/* ============ v49 브랜드 스토리 QR 스플릿플랩 v3 (랩 확정본 이식 — qrflip.js가 카드 생성) ============
   7×5 세로긴 카드: 위장(투명) → 물결 물질화(슬롯·광택·이음새) → 다회 촤라라라(겹침 발사, WAAPI)
   → 감쇠 다중 바운스 → 호버/탭 토글. 성능: 플랩 풀링·조기 회수·라이트 중간낙하·contain.
   ⚠ 본편 위장은 '투명'(랩은 라임) — 배경색 전환 중에도 보드가 절대 안 비침. */
/* [캡슐 테스트] 플립과 동일 박스에 캡슐 캔버스 */
/* [캡슐] 인터랙션 무대 = 우하단 랜드스케이프 박스(흩뿌림 담김). 탭 활성(touch-action으로 세로 스크롤은 유지) */
/* ⚠박스는 유리 투과 백드롭 때문에 불투명 → 텍스트를 덮으면 가림. 헤드라인 아래·좌측 텍스트 오른쪽만 차지하게 제한.
   pointer-events:none → 스크롤/탭 통과(탭은 capsule3d가 window 레이캐스트). 카메라를 이 박스에 맞춰 캡슐 크기 유지. */
/* 우측을 뷰포트 오른쪽 끝까지(섹션 여백 밖으로 풀블리드) — 좌측 끝은 그대로라 캡슐 위치 불변 */
/* 좌: 텍스트 섹션 왼쪽 단(sec-inner 좌단, left:0)까지 / 우: 뷰포트 오른쪽 끝까지.
   ⚠canvas는 replaced element라 width:auto면 좌우(left/right)가 아니라 내재 버퍼폭을 씀 → 폭 고정 버그.
   반드시 명시 width: sec-inner 좌단(=(vw-1280)/2)부터 뷰포트 우단(vw)까지 = vw - (vw-1280)/2 = 50vw + 640px. */
.qr-capsule{position:absolute;bottom:0;left:0;width:calc(50vw + 640px);z-index:1;
  height:710px;display:block;pointer-events:none}
/* v50-15: 모바일 = 풀블리드 캔버스. 좌우 화면끝(width:100vw + 상쇄마진, 섹션 20px 패딩 무시) + 상단 화면위(margin-top:-28svh로 캔버스 top≈0까지 끌어올림).
   height:80svh = 빈영역 52svh + 끌어올린 28svh → 음수마진 상쇄로 flow공간은 52svh 유지(feat 위치 불변). 캡슐 렌더 위치·크기는 capsule3d FRAME(camR/laY/tgt)로 이 큰 캔버스에 맞춰 재중앙. pointer-events:none이라 제목·버튼 뒤 지나가도 클릭 통과. */
@media(max-width:860px){ .qr-capsule{position:static;width:100vw;height:80svh;margin:-28svh 0 0 calc(50% - 50vw)} }
/* 이 섹션 한정: 라벨·헤드라인을 캔버스 위로 올려 백드롭에 안 가리게(피처 value-list는 이미 z2) */
.statement .sec-head,.statement .headline{position:relative;z-index:2}
/* H패널 '캔버스영역 빨간선' 토글용 — 켤 때만 클래스 부착(csShowArea) */
.qr-capsule.show-area{outline:2px solid #ff3366;outline-offset:-2px}
/* 회전 글린트 — 회전 중 빛을 받는 순간의 광(opacity만 키잉, 검은 면 입체감용).
   v49.1: 좁은 밴드(선처럼 보임, 사용자 지적) → 면 전체를 부드럽게 씻는 넓은 워시로 */
/* 힌지 플러그 — 분할선 양끝의 금속 핀(참고: 공항 플립보드 축 장치). 시임과 같은 z1300(플랩 위),
   3px 셀 간격으로 살짝 돌출. 위장 땐 opacity 0 → 물질화 때 시임과 함께 페이드인 */
/* ============ v49 커스텀 스크롤바 — 우측 작은 동그라미(위치 표시 + 드래그 스크롤) ============
   배경색이 구간마다(라임/검정/흰/그린/핑크) 바뀌므로 배경 밝기 판정으로 2색 전환(밝은 배경=검정 점·어두운 배경=흰 점, scrollbar.js paintColor).
   z=1500(모달 z2000 아래 → 모달 열리면 딤 뒤로 가려짐).
   ⚠ v49 mix-blend-mode:difference는 .cscroll-thumb의 fixed+transform+will-change가 만든 격리 스택 컨텍스트 탓에
     ::after가 페이지 아닌 부모(투명)와만 블렌딩돼 반전 실패(흰 배경서 흰색) → v50-10 2색 방식으로 교체. */
/* v49: top 대신 transform(--sy) 이동 = 합성 전용(스크롤마다 리플로 없음).
   스케일 연출은 ::after(원)로 분리 — 이동 transform과 전환이 안 섞이게. */
.cscroll-thumb{
  position:fixed; right:9px; top:14px; width:10px; height:10px;   /* 데스크톱은 v49 원값 유지(사용자) */
  z-index:1500; cursor:grab; touch-action:none;
  transform:translateY(var(--sy,0px)); will-change:transform;
}
.cscroll-thumb::after{content:''; position:absolute; inset:0; border-radius:50%;
  background:var(--dot-col,#111); transition:background-color .25s ease, transform .18s ease}   /* v50-10: 배경 밝기 따라 #111(밝은 배경)/#fff(어두운 배경) — scrollbar.js paintColor. (mix-blend은 격리로 반전 실패라 교체) */
.cscroll-thumb:hover::after{transform:scale(1.35)}
.cscroll-thumb.drag{cursor:grabbing}
.cscroll-thumb.drag::after{transform:scale(1.5)}
/* v50-43: 터치 기기 = **스크롤 중에만 표시**(아이폰 기본 스크롤바 거동). 드래그는 막고 위치 표시 전용.
   기존 `display:none`은 시스템 스크롤바까지 전역으로 없앤 상태와 겹쳐 **모바일에 위치 표시가 전무**했음
   (이 페이지는 화면 27개분 = 18,000px+). [원복: 아래 블록을 display:none 한 줄로]. */
@media(pointer:coarse){
  /* v50-44: 가로 위치 = **문의하기 버튼 오른끝 ↔ 화면 오른끝의 정중앙**(사용자). 모바일(터치)에만 적용 —
     데스크톱은 기존 right:9px 유지(사용자: "데스크톱은 원래대로").
     버튼 오른끝은 항상 페이지 좌우 여백(--pad)만큼 안쪽이므로(실측 393/375/360/430 모두 20px) 그 중앙 = 여백의 절반.
     right = --pad/2 − 반지름(5px). [원복: 이 right 선언 삭제]. */
  .cscroll-thumb{ right:calc(var(--pad)/2 - 5px);
                  pointer-events:none; opacity:0; transition:opacity .35s ease }
  .cscroll-thumb.show{ opacity:1; transition:opacity .12s ease }
  .cscroll-thumb:hover::after{ transform:none }   /* 터치 hover 잔상 방지 */
}
@media(prefers-reduced-motion:reduce){ .cscroll-thumb::after{transition:none} }
.step h3{margin-top:18px;font-size:clamp(18px,1.9vw,24px);font-weight:700;letter-spacing:-0.02em}
/* v49: 스텝 번호 이탤릭 span 제거 — 다른 콘텐츠 섹션(밸류·feat)과 동일하게 볼드 제목만(사용자 통일) */
.step p{margin-top:6px;font-size:14.5px;color:var(--ink-soft)}
.anticheat{
  margin-top:clamp(32px,4vw,52px);padding:20px 24px;
  border:1px solid var(--line);border-radius:6px;
  font-size:13.5px;color:var(--ink-soft);max-width:720px;
}
.anticheat b{color:var(--ink);display:block;margin-bottom:4px;font-size:13px;letter-spacing:.05em}
@media(max-width:720px){.step-grid{grid-template-columns:1fr}.step:nth-child(2){margin-top:0}}

/* ---------- management ---------- */
.mgmt{color:var(--cream)}
.mgmt .sec-head{border-top-color:rgba(243,234,219,.25)}
.mgmt .sec-head .idx{color:rgba(243,234,219,.6)}
.mgmt .feat-grid{border-top-color:rgba(243,234,219,.25)}
.mgmt .feat{border-bottom-color:rgba(243,234,219,.25)}
.mgmt .feat:nth-child(odd){border-right-color:rgba(243,234,219,.25)}
.mgmt .feat p{color:rgba(243,234,219,.72)}

/* 다크 배경 위 섹션 (Technology) */
.inv{color:var(--paper)}
.inv .sec-head{border-top-color:rgba(251,250,247,.25)}
.inv .sec-head .idx{color:rgba(251,250,247,.55)}
.inv .feat-grid{border-top-color:rgba(251,250,247,.25)}
.inv .feat{border-bottom-color:rgba(251,250,247,.25)}
.inv .feat:nth-child(odd){border-right-color:rgba(251,250,247,.25)}
.inv .feat p{color:rgba(251,250,247,.68)}
/* ---------- customizing ---------- */
.custom-grid{display:grid;grid-template-columns:repeat(3,1fr);gap:clamp(16px,2.4vw,36px);align-items:start} /* v50-3: 기본 stretch면 figure가 이미지보다 세로로 늘어나(콜라이더=figure가 이미지보다 큼·회전중심 어긋남) → start로 figure=이미지 높이 고정 */
.custom-grid figure:nth-child(2){margin-top:clamp(30px,5vw,80px)}
.custom-grid figure:nth-child(3){margin-top:clamp(14px,2.4vw,38px)}
.custom-grid figure img{border-radius:4px}
.custom-grid figure{transition:opacity .8s cubic-bezier(.2,.8,.2,1)} /* v50-5: .rv의 transform 트랜지션(.8s)이 line89의 물리 transform(--press 눌림·--rot 기울기)을 뭉개 이미지가 콜라이더보다 느리게 반응하던 버그 → transition을 opacity만 남겨 물리 반응 즉시화(콜라이더와 동기). 리빌 슬라이드는 line89 !important가 이미 덮어써 원래 없어 손실 없음, 페이드는 유지. */
.custom-list{margin-top:clamp(46px,6vw,80px);display:grid;grid-template-columns:repeat(3,1fr);gap:clamp(20px,3vw,48px)}
.custom-list h3{font-size:clamp(17px,1.7vw,21px);font-weight:700;letter-spacing:-0.02em;margin-bottom:8px}
.custom-list p{font-size:14.5px;color:var(--ink-soft)}
@media(max-width:720px){
  .custom-grid{grid-template-columns:1fr;max-width:420px}
  .custom-grid figure:nth-child(2),.custom-grid figure:nth-child(3){margin-top:0}
  .custom-list{grid-template-columns:1fr;gap:28px}
}

/* ---------- case (collage) ---------- */
/* v41: .case overflow:hidden 제거 — sticky 핀을 죽이던 원인. 클리핑은 .case-stick이 담당 */
.case-stick{position:sticky;top:0;height:100svh;overflow:hidden;display:flex;flex-direction:column}
.case-head-inner{
  padding-top:clamp(40px,7svh,90px);
  /* v42: v41 좌측 앵커(6vw) 해제 — 다른 섹션과 동일한 중앙 컨테이너(.sec-inner 1280px) 복귀.
     스트립은 계속 풀블리드(6vw 시작) — 헤딩만 컨테이너 정렬.
     ⚠ width:100% 필수 — 부모(.case-stick)가 flex column이라 가로 auto 마진이 stretch를 끄고
     콘텐츠 폭으로 수축(721px 중앙 배치)하던 것을 명시 폭으로 복원. */
  width:100%;
}
.case-strip{position:relative;flex:1;min-height:0}
/* v39: 아이템은 JS가 --gx/--gy로 배치. 눌림·기울기 변수는 합성 유지, --gs는 폭발 팽창용 */
.case-strip .c{
  position:absolute;left:0;top:0;height:calc(48svh * var(--chf,1));overflow:hidden;border-radius:4px;
  /* v50-38: placeholder 배경 제거(투명). 이 구간 페이지 배경은 **분홍**(rgb206,137,195)인데
     카드 배경이 밝은 회백(#E2DFD8)이라, 이미지가 준비되기 전 카드만 먼저 그려지면 분홍 위에
     **밝은 빈 박스**가 떠 "흰색으로 튐"으로 보였다(사용자 지적·실측: 카드는 보이는데 이미지 미준비
     보통 59회/느린회선 120회, 반면 .flash 오버레이는 0회로 무관). 투명이면 준비 전엔 아예 안 보인다.
     ⚠.step .ph 등 다른 placeholder는 밝은 배경 위라 그대로 둔다. [원복: background:var(--paper-deep) 복원] */
  will-change:transform;
  transform:translate3d(var(--gx,0px), calc(var(--gy,0px) + var(--press,0px)), 0)
            rotate(var(--rot,0deg)) scale(var(--gs,1)) !important;
}
.case-strip .c.r34{aspect-ratio:3/4}
.case-strip .c.r43{aspect-ratio:4/3}
.case-strip .c.r169{aspect-ratio:16/9}
.case-strip .c .shake{position:absolute;inset:0}
.case-strip img{width:100%;height:100%;object-fit:cover;display:block}
.case-strip .c .flash{position:absolute;inset:0;background:#fff;opacity:0;pointer-events:none;z-index:2}
/* v50-63: 경계 760 → 720 합류(사용자 결정). 760은 이 규칙 **하나만** 지배하던 유일한 이상치였고,
   그 탓에 폭 760→761 단 1px에서 카드가 563x317 → 751x422로 33% 점프 = 아이패드 mini(744)는 작은 카드,
   일반 아이패드(768)는 큰 카드로 갈렸음. 720에 합치면 태블릿이 전부 큰 카드(48svh)로 통일되고,
   경계가 520/640/720/860 4개로 줄면서 720 = "1단 쌓기" 단계로 의미가 명확해짐(.feat-grid/.step-grid/.custom-grid와 동일 단계).
   변하는 구간은 폭 720~760px뿐 — 그 이하(폰)와 그 이상(태블릿·데스크톱)은 불변. */
@media(max-width:720px){
  .case-strip .c{height:calc(36svh * var(--chf,1))}
}
/* ---------- contact ---------- */
.contact{
  /* v47: z-index 6->1 = fall-canvas(5) 아래로 -> 낙하 공이 contact 위에 그려짐(텍스트 회피 자동).
     라이트 통일 -> 흰 배경/어두운 글씨 정적(과거 검정→흰 스크럽 타임라인 제거). */
  position:relative;z-index:1;background:#FFFFFF;color:#161614;
  min-height:100svh;display:flex;flex-direction:column;overflow:hidden;
}
.contact-inner{
  position:relative;z-index:2;
  padding:clamp(90px,12vw,160px) var(--pad) 0;
  max-width:1280px;margin:0 auto;width:100%;
}
.contact .found{
  font-size:13px;font-weight:600;letter-spacing:.05em;color:#70706a;
  margin-bottom:22px;font-variant-numeric:tabular-nums;
}
.contact .found b{color:#161614}
.contact h2{
  font-size:clamp(32px,5vw,66px);font-weight:650;
  letter-spacing:-0.04em;line-height:1.22;margin-bottom:clamp(30px,4vw,48px);
}
.contact-cta{display:flex;gap:12px;flex-wrap:wrap;margin-bottom:clamp(40px,5vw,64px)}
.btn-xl{padding:16px 34px;font-size:16px}
.btn-paper{background:var(--paper);color:var(--ink)}
.btn-paper:hover{background:#fff}
.btn-outline{border:1px solid rgba(251,250,247,.35);color:var(--paper)}
.btn-outline:hover{border-color:var(--paper)}
/* v50-88: 좌=연락처 / 우=채널 좌우 분리.
   기존엔 항목이 그냥 flex 나열이라 왼쪽에 몰리고 오른쪽이 크게 비었다(실측 1440서 우측 658px 공백).
   `justify-content:space-between` + 그룹 2개로 바꾼다.
   ⚠**그룹에도 같은 gap**을 줘야 항목 간격이 좌우에서 동일해 보인다.
   ⚠좁은 화면에선 두 그룹이 줄바꿈되며 space-between이 무의미해지므로, 그때는 왼쪽 정렬로 되돌린다(아래 MQ). */
.contact-info{
  display:flex;justify-content:space-between;align-items:flex-start;
  gap:clamp(28px,5vw,80px);flex-wrap:wrap;
  padding-top:26px;border-top:1px solid rgba(22,22,20,.14);
  font-size:14px;color:#70706a;
}
.contact-info .ci-group{ display:flex; gap:clamp(28px,5vw,80px); flex-wrap:wrap; }
@media(max-width:860px){
  /* 줄바꿈이 일어나는 폭부터는 좌우 분리가 의미 없다 — 왼쪽 정렬로 통일해 들쭉날쭉함을 막는다. */
  .contact-info{ justify-content:flex-start; }
}
.contact-info b{display:block;color:#161614;font-size:15px;margin-bottom:2px;font-weight:600}
.contact-box-stage{
  /* v45: 흐름(in-flow) 배치. box.top=stage.top(개구부), box.floorDoc=stage.bottom(바닥).
     v46: 타이틀~박스 갭(~700px)은 앞의 .box-scroll-cue 높이가 담당(margin 대신). */
  position:relative;z-index:1;flex:0 0 auto;
  height:min(74svh,820px);
  margin-top:0;
  pointer-events:none;
}
/* v46: 스크롤 인디케이터 겸 타이틀~박스 갭. 이 높이가 곧 박스가 얼마나 아래에 있는지(=~700px).
   갭 중앙에 'Scroll' + 얇은 라인. 스크롤 내리며 페이드아웃(main.js). */
.box-scroll-cue{
  min-height:700px;
  display:flex;flex-direction:column;align-items:center;justify-content:center;gap:16px;
  position:relative;z-index:2;pointer-events:none;
}
/* v50-23: 모바일 = 타이틀↔박스 700px 갭이 거의 한 뷰포트라 집게·공더미 씬이 한참 아래서 나옴(사용자). 갭 축소 → 박스 씬 sooner. 순수 레이아웃이라 box 물리·핸드오프·집게(page% 트리거)는 measureBox 재계산으로 자동 적응. [원복: 이 줄 삭제] */
.box-scroll-cue span{
  font-size:12px;letter-spacing:.3em;text-transform:uppercase;font-weight:600;
  color:rgba(22,22,20,.45);
}
.box-scroll-cue i{
  display:block;width:1px;height:46px;
  background:linear-gradient(rgba(22,22,20,.5), rgba(22,22,20,0));
}
/* v50-24: 모바일 box-scroll-cue = 120px→7svh(현재의 반)·비율기반(폰 크기 달라도 같은 %; DPR 차이는 px·svh 무관). 단 인디케이터 콘텐츠(줄46+텍스트=81px)가 7svh(59px)보다 커서 바닥을 잡으므로, 줄·간격도 축소해 콘텐츠<7svh → 비율값이 실제 바인딩. ⚠기본 .box-scroll-cue i 규칙 '뒤'에 둬야 override됨(소스순서). [원복: 이 @media 삭제] */
/* v50-30: 모바일 컨택트↔공더미 갭 축소 — 700px는 화면 1.4개라 "컨택트 끝나고 한참 내려야 바닥이 보임"(사용자).
   700→200px = 거리 1.4→0.85화면. 순수 레이아웃이라 박스 물리·핸드오프·집게(page% 트리거)는 measureBox 재계산으로 자동 적응.
   ⚠v50-26에서 원복했던 축소를 되살린 것 — 당시 "축소하면 우수수"는 **박스 문서위치가 바뀔 때 바닥만 움직이고 공은 안 따라간**
     v50-27 버그였고 그건 shiftPileToFloor로 해결됨. 재검증: 갭 700/300/200/127/81/0 전부에서 중력낙하 0건
     (하단 리프레시·고속스크롤·화면내 갭변경 포함, 바닥 1868px 점프에도 공 추종오차 0~1px). → DEVLOG "하한 10svh" 주장은 폐기.
   ⚠하한의 정체: 거리 = (헤더여유) + (최종 화면상 더미높이 ~600px). 컨택트 글자가 최하단서 헤더에 안 끼려면 헤더여유≥0
     → **거리 하한 ~0.7화면**은 CSS로 못 넘음. stage 축소도 같은 예산이라 이득 0(37svh 실패 원인). 더 줄이려면 3D 더미를 올려야 함(넘침 연출 소멸).
   ⚠헤더 충돌 분기점은 화면 높이마다 다름(844→131px, 932→154px, 667→51px) — 200px면 여유 56~79px. 폰트 교체 시 재측정 권장.
   ⚠기본 .box-scroll-cue i 규칙 '뒤'에 둘 것(소스 순서 — 앞에 두면 안 먹음, v50-24 함정). [원복: 이 @media 삭제] */
@media(max-width:640px){ .box-scroll-cue{min-height:200px} }
/* 캔버스는 body 직속 fixed. 평소 숨김 -> contact 구간에서만 표시(JS가 .box-active 토글).
   v45: 검정 페이드(.contact-box-fade) 제거 — 낙하하는 공을 가려서 뺌.
        벽 높이는 contact-box.js의 WALL_HEAD로 개구부 근처에 유지되므로 페이드 없이도 상단이 화면을 안 덮음. */
#contact-box-gl{
  position:fixed;inset:0;z-index:6;width:100%;height:100%;pointer-events:none;
  /* v50-33: 페이드 .3s→.15s — 초고속 플릭(20000px/s)이면 rootMargin 2400px 리드가 120ms라 .3s 페이드가
     집게 하강과 겹쳐 "반투명 집게가 화면 안에서 나타남". 벽이 흰색이라 짧게 해도 등장이 튀지 않음. */
  opacity:0;transition:opacity .15s;
}
body.box-active #contact-box-gl{ opacity:1; }
.footer{
  /* v46: body 직속(section 밖)으로 이동 + z7 -> 박스 캔버스(z6) 위에 그려져 공 위에 크레딧.
     라이트 테마 — 박스 등장 시점엔 배경이 이미 흰색이라 footer는 항상 흰 배경 위 -> 검정 텍스트. */
  position:relative;z-index:7;
  /* v50-60: 로고 + 저작권 2요소. **로고 하단 기준 정렬**(사용자).
     v50-61: flex-end → baseline. flex-end는 *박스* 하단을 맞추는데, 텍스트는 line-height 때문에
     글자 아래 여백(하프리딩+디센더 공간)을 갖고 로고 SVG는 글자에 딱 맞아 실제로는 텍스트가 5~6px 떠 보였음.
     baseline이면 "텍스트 기준선 = 로고 div 하단 마진엣지"(SVG만 든 블록의 베이스라인 규칙)로 정확히 맞음.
     실측 어긋남 flex-end -5.0/-6.0px → baseline 1.0/0.0px (폰/데스크톱). */
  display:flex;justify-content:space-between;align-items:baseline;gap:14px;flex-wrap:wrap;
  padding:22px var(--pad);
  font-size:12.5px;color:#161614;
}
.footer a{border-bottom:1px solid transparent;transition:border-color .2s}
.footer a:hover{border-color:rgba(22,22,20,.5)}
.footer .f-logo{width:52px;color:#161614}   /* v50-59: 회색(#8a8a83) → 검정(사용자). 푸터 본문 글자색과 동일 */
.footer .f-logo svg{width:100%;height:auto;display:block;
  /* v50-62: 로고 박스 바닥 ≠ 로고 기준선 보정. viewBox 바닥은 500인데 GRAB의 평평한 글자(R·A·B) 바닥 = 498.59
     (G만 499.551 = 둥근 글자 오버슛). 즉 박스가 기준선보다 1.41 유저단위 아래에서 끝나고,
     align-items:baseline은 이 박스 바닥에 텍스트 기준선을 맞추므로 텍스트가 그만큼 내려가 있었음.
     1.41/278 = 0.507%. **세로 마진의 %는 컨테이닝 블록의 폭 기준**이라 로고 폭이 바뀌어도 자동 스케일.
     핵심은 값이 아니라 어긋남을 정확히 0으로 만드는 것 — 0이면 두 좌표가 같은 수라 어떤 화면·어떤
     소수점 위치에서도 같은 픽셀 행으로 반올림됨. (보정 전엔 폰 .454/.531로 갈라지고 데스크톱 .969/.047로
     모여서, 상수 보정으론 한쪽을 고치면 다른 쪽이 깨졌음.)
     **값이 0.507%가 아니라 0.6%인 이유**: 기하 보정분이 0.507%이고 나머지 0.09%(≈0.05px)는 폰트가
     기준선을 아래쪽 디바이스 픽셀로 스냅하는 걸 상쇄. 벡터(SVG)는 스냅하지 않아 둘이 갈라짐.
     10개 화면 실측 스윕 결과 0.507%=3건 어긋남 / **0.6%=1건**(그것도 +0.38px = 디바이스 1픽셀, 물리적 최소).
     ⚠ 이 미세 보정분은 Blink/Windows 기준 — WebKit(iOS)은 래스터라이저가 달라 다르게 반올림할 수 있음.
     기하 보정분(0.507%)은 엔진 무관하게 유효하고, 차이 0.05px은 dpr3에서 1/8픽셀이라 위험은 낮음. */
  margin-bottom:-0.6%}

/* ---------- reveal ---------- */
.rv{opacity:0;transform:translateY(26px);transition:opacity .8s cubic-bezier(.2,.8,.2,1),transform .8s cubic-bezier(.2,.8,.2,1)}
.rv.on{opacity:1;transform:none}
@media(prefers-reduced-motion:reduce){
  .rv{opacity:1;transform:none;transition:none}
  .scroll-cue::after{animation:none}
  .hero-logo{animation:none}
}

/* ---------- 텍스트 볼 회피 ---------- */
span.wv{display:inline-block}

/* ============ 박스 개발용 오버레이 (H키 토글, 평소 hidden — 클라이언트엔 안 보임) ============
   lab/contact3d.html 컨트롤 패널 이식. 전부 #box-dev 스코프라 본편 스타일에 누출 없음. */
#box-dev[hidden]{display:none}
#box-dev .panel{
  position:fixed;top:16px;left:16px;z-index:120;width:266px;
  background:rgba(20,20,18,.86);backdrop-filter:blur(10px);
  border:1px solid rgba(251,250,247,.14);border-radius:14px;
  padding:16px 16px 14px;color:var(--paper);
  font-family:ui-monospace,SFMono-Regular,Menlo,monospace;font-size:11px;
  max-height:calc(100svh - 32px);overflow-y:auto;
}
#box-dev .panel h3{font-size:11px;letter-spacing:.12em;text-transform:uppercase;opacity:.5;margin-bottom:12px;font-weight:600}
#box-dev .grp{margin-bottom:14px;padding-bottom:12px;border-bottom:1px solid rgba(251,250,247,.08)}
#box-dev .grp:last-of-type{border-bottom:none}
#box-dev .row{display:flex;align-items:center;justify-content:space-between;margin-bottom:9px;gap:10px}
#box-dev label{opacity:.8;white-space:nowrap}
#box-dev input[type=range]{flex:1;height:3px;accent-color:#DD6FC4;cursor:pointer}
/* v50-14: 폰(?debug)에서 손가락 조작 — range 히트영역·행간·패널폭 확대 */
@media(max-width:860px){ #box-dev .panel{width:min(300px,88vw)} #box-dev input[type=range]{height:24px} #box-dev .row{margin-bottom:12px} }
#box-dev input[type=color]{width:28px;height:22px;border:none;border-radius:4px;background:none;cursor:pointer;padding:0}
#box-dev .val{min-width:34px;text-align:right;opacity:.6;font-variant-numeric:tabular-nums}
#box-dev .chk{display:flex;align-items:center;gap:6px;opacity:.8;cursor:pointer}
#box-dev .btns{display:flex;gap:8px;margin-top:12px}
#box-dev .btns button{flex:1;padding:9px;border-radius:8px;border:1px solid rgba(251,250,247,.2);background:rgba(251,250,247,.06);color:var(--paper);cursor:pointer;font-family:inherit;font-size:11px}
#box-dev .btns button:hover{background:rgba(251,250,247,.14)}
#box-dev .btns button.primary{background:var(--paper);color:var(--ink);border-color:var(--paper)}
#box-dev .hint{opacity:.4;font-size:10px;margin-top:8px;line-height:1.4}
#box-dev .panel.collapsed .body{display:none}
#box-dev .toggle{position:absolute;top:14px;right:14px;cursor:pointer;opacity:.5;font-size:14px;line-height:1}
#box-dev .lab-ui{position:fixed;top:16px;right:16px;z-index:120;display:flex;gap:8px;font-size:12px}
#box-dev .lab-ui button{padding:8px 14px;border-radius:999px;border:1px solid rgba(251,250,247,.3);background:rgba(22,22,20,.6);color:var(--paper);cursor:pointer;backdrop-filter:blur(6px);font-family:inherit}
#box-dev #box-hud{position:fixed;top:56px;right:16px;z-index:120;background:rgba(20,20,18,.82);backdrop-filter:blur(10px);border:1px solid rgba(251,250,247,.14);border-radius:10px;padding:10px 12px;color:var(--paper);font-family:ui-monospace,SFMono-Regular,Menlo,monospace;font-size:11px;line-height:1.7;min-width:118px}
#box-dev #box-hud div{display:flex;justify-content:space-between;gap:12px}
#box-dev #box-hud span{opacity:.5}
#box-dev #box-hud b{font-variant-numeric:tabular-nums}
#box-dev .dev-hintbar{position:fixed;left:16px;bottom:14px;z-index:120;font-family:ui-monospace,SFMono-Regular,Menlo,monospace;font-size:10px;color:var(--paper);opacity:.4;letter-spacing:.04em}
