본문으로 건너뛰기
Dot Design System
v0.3.1

Motion

피드백, 공간 관계와 진행을 설명할 때만 움직임을 사용합니다.

목적

Dot의 motion은 상태 변화, 공간 관계, 진행 상황을 이해하게 한다. 움직임 자체로 즐거움을 만들기보다 무엇이 바뀌었고 어디에서 왔으며 다음에 무엇을 할 수 있는지 설명한다.

  • Flexible: 입력 방식, 성능, motion 선호에 맞게 강도를 조절하되 상태 의미는 유지한다.
  • Link: trigger와 결과, 이전과 다음 위치, 처리와 완료를 공간적으로 연결한다.
  • Glow: 불확실한 순간의 방향 안내에만 사용하고 상시 움직임으로 업무를 지배하지 않는다.

Motion을 사용하는 조건

다음 중 하나를 설명할 때만 사용한다.

  • 상태가 바뀌었다.
  • content가 어디에서 열리고 어디로 돌아가는지 보여준다.
  • selection과 detail 사이의 관계를 유지한다.
  • 실제 작업이 진행 중임을 알린다.
  • 사용자의 행동 결과가 특정 영역에 반영됐다.

motion이 없어도 정보와 interaction을 이해할 수 있어야 한다.

Duration

범위duration사용
interaction120–180mshover, focus, selected, 작은 상태 변화
overlay180–240msDialog, Sheet, Popover 열림·닫힘

현재 제공되는 기본 animation은 다음 범위에 있다.

  • fade-in: 180ms ease-out

  • slide-in-from-top: 180ms ease-out, 6px 이동

  • accordion open/close: 200ms ease-out

  • 짧은 상태는 즉각적으로 느껴지되 변화가 식별될 정도만 움직인다.

  • 큰 surface는 작은 control보다 약간 긴 duration을 사용할 수 있다.

  • 화면마다 새로운 duration을 만들지 않는다.

  • 같은 component의 open과 close는 관계를 이해할 수 있는 일관된 timing을 사용한다.

  • motion을 느리게 만들어 중요도를 표현하지 않는다.

Easing과 이동 거리

  • 등장과 overlay는 최종 위치에서 자연스럽게 멈추는 ease-out을 기본으로 한다.
  • 사라짐은 사용자의 다음 행동을 지연하지 않는다.
  • 작은 component 이동은 4–8px 범위의 짧은 거리로 충분하다.
  • 멀리 날아오거나 크게 확대되는 transition을 일반 제품 UI에 사용하지 않는다.
  • layout 전체를 움직이기보다 opacity와 transform으로 의미 있는 element만 전환한다.
  • spring, bounce, overshoot는 업무 결과와 오류를 가볍게 만들 수 있으므로 사용하지 않는 것을 기본으로 한다.

상태 변화

Hover와 focus

  • hover는 pointer 사용자를 위한 보조 피드백이며 필수 action을 새로 공개하지 않는다.
  • focus-visible은 animation보다 명확한 ring이 우선이다.
  • hover와 focus의 transition이 control 반응을 늦추지 않는다.
  • selected와 active는 transition 후에도 지속되는 상태로 구분한다.

Loading과 progress

  • 일반 content 최초 loading은 최종 구조와 닮은 Skeleton을 사용할 수 있다.
  • button loading은 label을 저장 중…처럼 유지하고 중복 실행을 막는다.
  • 정확한 progress를 알 수 있을 때만 determinate 표현을 사용한다.
  • background refresh는 기존 content를 지우지 않고 작은 상태로 알린다.
  • 무한 spinner를 화면의 유일한 설명으로 사용하지 않는다.

Success와 error

  • 성공 animation은 결과 확인을 보조할 수 있지만 다음 action을 지연하지 않는다.
  • error를 shake, flash, 반복 진동으로 표현하지 않는다.
  • field error는 문장, 관계, focus로 설명하고 animation은 필요하지 않다.
  • 일부 성공은 단일 축하 animation보다 성공·실패 범위를 구조화한다.

Overlay motion

  • Dialog와 Sheet의 움직임은 trigger와 layer 관계를 이해하게 한다.
  • Popover는 짧은 fade 또는 작은 위치 이동으로 충분하다.
  • Tooltip은 content를 읽기 전에 과도한 delay나 animation을 만들지 않는다.
  • overlay가 닫히면 focus가 trigger로 돌아가므로 motion 종료와 focus timing이 충돌하지 않게 한다.
  • nested overlay animation을 연속으로 쌓지 않는다.
  • screen edge에서 들어오는 Sheet는 실제 edge 관계와 방향이 일치해야 한다.

DotMotion

DotMotion은 별도 motion entrypoint에서 가져오며 실제 AI 맥락에만 사용한다.

processing

  • AI 생성, 채점, 분석이 실제로 진행 중일 때 사용한다.
  • 일반 API 요청, page loading, 자동 refresh에는 사용하지 않는다.
  • 무엇을 처리하는지 설명하는 ariaLabel과 시각 text를 제공한다.
  • 작업이 끝나면 motion도 끝내고 결과 상태로 전환한다.

avatar

  • AI DOT의 실제 발화나 안내가 진행되는 동안 사용한다.
  • 대기 화면의 장식적 무한 반복이나 일반 profile image로 사용하지 않는다.
  • 발화·안내가 끝나면 정적 상태로 돌아간다.

Fallback

  • viewport 근처에서만 renderer를 불러오는 lazy behavior를 유지한다.
  • reduced motion, loading, renderer failure에서는 정적 fallback을 제공한다.
  • motion이 실패해도 text 상태와 주요 action은 유지한다.
  • 제품에서 JSON expression이나 asset path를 직접 수정해 우회하지 않는다.

Character와 Glow

  • 2D motion 표현은 제품 안의 처리·답변·안내처럼 기능에 가까운 맥락에 적합하다.
  • 3D character는 넓고 드문 브랜드 맥락이며 일반 transition 요소가 아니다.
  • 캐릭터의 형태, 색, 요소 관계, clear space를 animation을 위해 변형하지 않는다.
  • Glow를 움직이는 background나 항상 pulsating하는 focus로 사용하지 않는다.
  • 다음 방향을 안내해야 하는 짧고 의미 있는 순간에만 brand motion을 검토한다.

Scroll과 layout motion

  • 자동 scroll은 사용자의 위치를 잃게 할 수 있으므로 오류, 새 선택, 직접 요청처럼 이유가 명확할 때만 한다.
  • streaming AI 결과가 새 내용마다 viewport를 밀어내지 않게 한다.
  • list 갱신 시 row가 갑자기 재정렬되면 변경 원인과 현재 selection을 보존한다.
  • drag-and-drop에는 keyboard 대안을 제공하고 drop 결과를 알린다.
  • height animation이 긴 content를 가리거나 focus target을 잘라내지 않게 한다.
  • page route transition이 제목 focus와 읽기 시작을 지연하지 않게 한다.

Reduced motion

.dot-themeprefers-reduced-motion: reduce에서 다음을 적용한다.

  • scroll behavior를 즉시 전환한다.
  • animation duration을 사실상 제거한다.
  • 반복 횟수를 1회로 제한한다.
  • transition duration을 사실상 제거한다.

제품 component도 이 경계를 우회하지 않는다.

  • motion 제거 후에도 상태가 즉시 최종 모습으로 나타나야 한다.
  • 처리 상태는 text, aria-busy, static indicator로 유지한다.
  • 공간 관계가 중요한 disclosure는 expanded state와 heading 구조로 보완한다.
  • 자동 재생 video나 별도 canvas motion이 있다면 독립적인 pause/stop 정책을 검토한다.

상태와 접근성

  • motion만으로 성공, 오류, 선택, 진행을 전달하지 않는다.
  • 진행 상태에는 text와 필요한 live region을 제공한다.
  • flash, rapid blink, 반복 진동을 사용하지 않는다.
  • focus 이동과 animation이 동시에 사용자를 다른 위치로 끌지 않는다.
  • screen reader announcement는 visual animation frame이 아니라 의미 있는 상태 변경에 맞춘다.
  • pause, cancel, stop이 필요한 장시간 작업은 keyboard로도 조작할 수 있어야 한다.
  • motion asset의 대체 text는 animation 형태보다 실제 작업 상태를 설명한다.

예외와 피해야 할 사용

  • 모든 hover와 mount에 animation을 넣지 않는다.
  • 단순 중요도를 pulse, bounce, shake로 표현하지 않는다.
  • error에 반복적인 움직임을 사용하지 않는다.
  • 알 수 없는 진행률을 animation 속도나 percent로 꾸미지 않는다.
  • 일반 loading에 DotMotion processing을 사용하지 않는다.
  • 캐릭터와 Glow를 장식적으로 무한 반복하지 않는다.
  • reduced-motion CSS를 component override로 무효화하지 않는다.
  • animation이 끝날 때까지 action과 focus를 막지 않는다.

검토 질문

  • motion이 상태, 공간 관계, 진행 중 무엇을 설명하는가?
  • motion을 제거해도 같은 정보와 action을 이해할 수 있는가?
  • duration이 interaction 120–180ms, overlay 180–240ms 체계 안에 있는가?
  • 이동 거리와 easing이 component 크기와 관계에 비례하는가?
  • loading, success, error를 text와 구조로도 전달하는가?
  • DotMotion이 실제 AI 생성·채점·분석 또는 발화에만 쓰이는가?
  • 처리 완료와 함께 반복 motion이 끝나는가?
  • focus, scroll, selection이 animation 때문에 이동하거나 사라지지 않는가?
  • reduced motion에서 static fallback과 상태 문장이 유지되는가?
  • Glow와 character motion이 다음 방향을 밝히는 드문 순간에만 쓰였는가?