@charset "utf-8";
/* ============================================================================
   MOTION-LITE — 의존성 0 진입 모션 계약 CSS (scripts/motion-lite.js 와 한 쌍)
   ----------------------------------------------------------------------------
   왜 생겼나 (2026-09-02)
     도도·오리콤 두 프로젝트가 연달아 GSAP 엔진(motion-engine.js) 대신 **의존성 없는 15KB 엔진**을
     각자 새로 썼고, 같은 함정(p116 0면적 사전상태 · p117 넘침 · p118 재진입 · p071 레이아웃 소실)에
     각자 빠졌다. 그 두 엔진에서 실측으로 확정된 규칙을 여기 한 벌로 모은다.

   원칙
     1. **모션 채널과 레이아웃 채널을 섞지 않는다.** 레이아웃 기하는 `transform`(또는 left/top/margin)에,
        모션은 `translate`·`scale`·`rotate`·`opacity`·`clip-path` 에만 싣는다. 완료 규칙은 모션 채널만 비운다.
     2. JS 가 없으면 **전부 보인다.** 사전 상태는 `html.js-motion` 아래에만 있다.
     3. 사전 오프셋은 가로 넘침을 만들지 않는다 — X 는 clamp 된 px 이고 좁은 폭에서는 0 이다.
     4. 기본은 play-once. 재진입은 `html[data-motion-replay="floor"]` 로만 켜고, 그때도 하한이 있다.
   ========================================================================== */
:root{
  --mo-shift: clamp(24px, 3.3vw, 64px);   /* 세로 진입 진폭 */
  --mo-x:     clamp(0px, 2vw, 40px);      /* 가로 진폭 — 작게. 좁은 폭에서 0 (p117) */
  --mo-scale: .94;
  --mo-dur:   .95s;
  --mo-stag:  90ms;
  --mo-ease:  cubic-bezier(.22,.61,.36,1);
}
@media (max-width:1023.98px){ :root{ --mo-shift:26px; --mo-x:0px; --mo-scale:.97; --mo-dur:.7s; --mo-stag:70ms } }

/* ── 진입 사전 상태 — 엔진이 살아 있을 때만 ────────────────────────────── */
html.js-motion [data-mo]{
  opacity:0;
  transition:opacity var(--mo-dur) var(--mo-ease),
             translate var(--mo-dur) var(--mo-ease),
             scale     var(--mo-dur) var(--mo-ease),
             rotate    var(--mo-dur) var(--mo-ease),
             clip-path var(--mo-dur) var(--mo-ease);
  transition-delay:calc(var(--i, 0) * var(--mo-stag));
}
html.js-motion [data-mo="up"]       { translate:0 var(--mo-shift) }
html.js-motion [data-mo="down"]     { translate:0 calc(var(--mo-shift) * -1) }
html.js-motion [data-mo="left"]     { translate:calc(var(--mo-x) * -1) 0 }
html.js-motion [data-mo="right"]    { translate:var(--mo-x) 0 }
html.js-motion [data-mo="pop"]      { translate:0 calc(var(--mo-shift) * .5); scale:var(--mo-scale) }
html.js-motion [data-mo="fade"]     { }
/* 0 면적 사전 상태 — 엔진이 **부모를 대신 관측**한다(p116). 자기 자신을 관측하면 영원히 안 보인다. */
html.js-motion [data-mo="clip-up"]   { clip-path:inset(0 0 100% 0); translate:0 calc(var(--mo-shift) * .35) }
html.js-motion [data-mo="clip-left"] { clip-path:inset(0 100% 0 0) }
html.js-motion [data-mo="clip-down"] { clip-path:inset(100% 0 0 0); translate:0 calc(var(--mo-shift) * -.35) }

/* in-state — 항등값. SF10 은 이 리셋이 있어야 위 사전 상태를 "레이아웃이 아니다" 로 판정한다 */
html.js-motion [data-mo].is-in{ opacity:1; translate:0 0; scale:1; rotate:0deg; clip-path:inset(0 0 0 0) }

/* 재진입 하한(floor) — html[data-motion-replay="floor"] 에서만. 한 번 본 요소는 완전히 사라지지 않는다(p118) */
html.js-motion[data-motion-replay="floor"] [data-mo].is-floor{ opacity:.55; transition-delay:0ms }
html.js-motion[data-motion-replay="floor"] [data-mo="up"].is-floor   { translate:0 calc(var(--mo-shift) * .45) }
html.js-motion[data-motion-replay="floor"] [data-mo="down"].is-floor { translate:0 calc(var(--mo-shift) * -.45) }
html.js-motion[data-motion-replay="floor"] [data-mo="pop"].is-floor  { translate:0 calc(var(--mo-shift) * .2); scale:.985 }
html.js-motion[data-motion-replay="floor"] [data-mo^="clip"].is-floor{ clip-path:inset(0 0 0 0) }

/* 완료 규칙 — **모션 채널만** 비운다. transform 은 건드리지 않는다(p071 · SF10).
   ★ 2026-09-30 (DAEMO) — in-state `[data-mo].is-in`(명시도 0,3,1)이 이 규칙(0,2,1)을 이겨 완료 뒤에도
   translate:0px · scale:1 · rotate:0deg 가 시안 좌표 노드에 남았다(MO7-b 21건). 같은 명시도의 선택자를 함께 둔다. */
html.js-motion [data-motion-done],html.js-motion [data-mo].is-in[data-motion-done]{ translate:none; scale:none; rotate:none; clip-path:none; transition:none }

/* ── 패럴랙스 (미디어·장식 전용 · p033) — translate 만 얹는다. 회전·좌표는 그대로 ── */
[data-parallax]{ will-change:translate }

/* ── 플로팅 CTA 도킹 (p127) — 숨기지 않는다. 푸터가 들어오면 absolute 로 착지한다 ── */
[data-dock-to]{ position:fixed; z-index:50; transition:translate .5s var(--mo-ease) }
[data-dock-to].is-docked{ position:absolute }
/* 도킹 좌표(우/하 여백)는 프로젝트 CSS 가 시안 값으로 정한다. 여기서는 상태만 정의한다. */

/* ── 접근성: 모션을 줄여 달라고 하면 전부 끈다 ────────────────────────── */
@media (prefers-reduced-motion:reduce){
  html.js-motion [data-mo]{ opacity:1 !important; translate:none !important; scale:none !important; rotate:none !important; clip-path:none !important; transition:none !important }
  [data-parallax]{ translate:none !important }
  [data-dock-to]{ transition:none }
}

/* ── 프로젝트 확장 (김종수 법률사무소) — 이미지 줌아웃 진입 · 마스크 안 이미지 ── */
html.js-motion [data-mo="zoom"]{ scale:1.08; --mo-dur:1.4s }
html.js-motion [data-mo="zoom"].is-in{ scale:1 }
html.js-motion[data-motion-replay="floor"] [data-mo="zoom"].is-floor{ scale:1.03 }
