모션

얼마나 오래, 어떤 곡선으로 움직이는지 정한다. 무엇이 움직이는지 정하면 시간이 따라온다.

시간

0.2초가 경계다. 버튼 눌림과 포커스, 회전 같은 마이크로 모션은 duration-4 이하를 쓴다. 팝업 개폐와 시트 슬라이드, 페이지 전환은 duration-4 를 넘는다.

색 · 테두리 · 배경 전환은 duration-3(150ms) 하나다. hover · error · disabled 로 바뀌는 순간 전부가 여기 해당하고, 눌림(duration-pressed)과 같은 시계다.

duration-150ms · 마이크로
duration-2100ms · 마이크로
duration-3150ms · 마이크로
duration-4200ms · 경계
duration-5250ms · 매크로
duration-6300ms · 매크로
duration-7350ms · 매크로 — 시트 슬라이드
duration-8400ms · 매크로 — 시트 슬라이드

막대 길이가 곧 시간이다. 4번이 경계선이다.

곡선

나타날 때와 사라질 때 다른 곡선을 쓴다. 나타날 때는 천천히 끝나 결과를 인지할 시간을 준다. 사라질 때는 빠르게 끝나 이미 끝난 일에 시간을 쓰지 않는다. 하나의 곡선으로 양방향을 처리하면 이 차이가 사라진다.

easing-enter
easing-exit

왼쪽 아래가 시작, 오른쪽 위가 끝이다. enter 는 초반에 가파르고 exit 는 후반에 가파르다.

토큰언제
--nui-easing-standard기능적 마이크로 — 색 · 테두리 전환
--nui-easing-enter나타남 — 빠르게 시작해 천천히 안착
--nui-easing-exit사라짐 — 천천히 시작해 빠르게 빠짐
--nui-easing-enter-emphasized강조가 필요한 등장
--nui-easing-exit-emphasized강조가 필요한 퇴장
--nui-easing-expand크기가 변하는 것 — 접힘/펼침. easing-enter 를 쓰지 않는다

모션 줄이기

OS 에서 동작 줄이기를 켜면 prefers-reduced-motion: reduce 가 전달되고 duration 토큰이 전부 1ms 가 된다. 라이브러리 컴포넌트는 이 설정을 따른다.

커스텀 애니메이션에 시간을 하드코딩하면 이 장치를 우회한다. 0.2s 라고 직접 적는 대신 duration 토큰을 참조한다.

framer-motion 은 CSS 토큰을 읽지 않는다. reducedMotion 기본값이 "never" useReducedMotion() 으로 분기해야 설정이 반영된다. 라이브러리의 PopupToast, Tooltip 은 분기해 두었다.
const shouldReduceMotion = useReducedMotion();

<motion.div
  initial={shouldReduceMotion ? { opacity: 0 } : { opacity: 0, y: -8, scale: 0.98 }}
  transition={shouldReduceMotion ? { duration: 0 } : motionTransition.popover}
/>

눌림

눌림은 배율과 시간, 곡선 세 축을 함께 쓴다. 하나만 골라 쓰면 같은 눌림이 컴포넌트마다 다르게 느껴진다.

토큰
변형량--nui-scale-94 작은 요소 · -96 중간 · -98 큰 요소
시간--nui-duration-pressed
곡선--nui-easing-pressed

큰 요소일수록 덜 줄여야 같은 정도로 눌린 느낌이 난다. 전면 버튼을 0.94 로 줄이면 과하게 움츠러들고 작은 버튼을 0.98 로 줄이면 티가 안 난다.

토큰비고
--nui-scale-940.94작은 요소 — 아이콘 버튼 · 칩
--nui-scale-960.96중간
--nui-scale-980.98큰 요소 — 전면 버튼 · 카드

전체 토큰

토큰비고
--nui-duration-150ms
--nui-duration-2100ms
--nui-duration-3150ms
--nui-duration-4200ms
--nui-duration-5250ms
--nui-duration-6300ms
--nui-duration-7350ms
--nui-duration-8400ms
--nui-easing-standardcubic-bezier(0.2, 0, 0, 1)기능적 마이크로
--nui-easing-entercubic-bezier(0, 0, 0.15, 1)ease-out 계열
--nui-easing-exitcubic-bezier(0.35, 0, 1, 1)ease-in 계열
--nui-easing-enter-emphasizedcubic-bezier(0.16, 1, 0.3, 1)
--nui-easing-exit-emphasizedcubic-bezier(0.35, 0, 0.95, 0.55)
--nui-easing-expandcubic-bezier(0.5, 1, 0.89, 1)
--nui-duration-pressedvar(--nui-duration-3)별칭
--nui-easing-pressedcubic-bezier(0, 0, 0.15, 1)