Communitygithub.com

motion-foundations

Motion 토큰, 스프링 프리셋, 성능 규칙, 기기 적응, 접근성 강제 및 React/Next.js용 motion/react의 SSR 안전성을 제공합니다. 기반 계층 — 다른 모든 motion 스킬이 이에 의존합니다. React 또는 Next.js에서 motion 토큰, 스프링 프리셋, reduced-motion 처리 또는 SSR 안전 애니메이션을 설정할 때 사용하세요.

motion-foundations란 무엇인가요?

Motion Foundations는 motion 시스템의 기본 계층으로, 모든 값, 제약 조건 및 규칙을 정의합니다. 이 스킬은 다운스트림 스킬(motion-patterns, motion-advanced)이 상속하는 공유 `motionTokens` 객체(duration, easing, distance, scale), `springs` 프리셋 맵(5개의 명명된 구성), 접근성 준수 애니메이션 기본값을 위한 `shouldAnimate()` 게이트 및 `useReducedMotion` 훅을 제공합니다. 또한 SSR 안전 초기 상태를 보장하여 수화 불일치 경고를 방지합니다. React/Next.js 환경에서 `motion/react`만 사용해야 하며, framer-motion과 혼용할 수 없습니다. 토큰과 스프링은 하드코딩 없이 미리 정의된 맵에서 가져와야 하며, reduced-motion 설정 시 모든 트랜스폼이 비활성화되고 opacity-only fade(≤0.2s)만 허용됩니다. layout 속성(width, height, top, left, margin, padding)의 애니메이션은 금지되며, 대신 transform과 opacity만 사용합니다. 이 스킬은 Cursor, Claude Code, Codex 등 주요 AI 에이전트 플랫폼에서 사용할 수 있으며, 애니메이션 작업을 시작하기 전에 반드시 로드해야 합니다.

지원 대상~Claude Code~Codex CLI~Cursor
npx skills add https://github.com/affaan-m/ECC/tree/main/skills/motion-foundations

즐겨 사용하는 AI에게 물어보기

이 에이전트 스킬이 미리 로드된 새 채팅을 엽니다.

문서

Motion Foundations

모션 시스템의 기본 계층입니다. 모든 값, 제약 조건, 규칙을 정의하며, 다운스트림 스킬(motion-patterns, motion-advanced)이 이를 상속받습니다. 애니메이션 작업을 시작하기 전에 이 스킬을 로드하세요.

활성화 시점

  • 처음부터 애니메이션 컴포넌트를 만들 때
  • 토큰, 스프링 프리셋, 이징 값을 설정할 때
  • prefers-reduced-motion 지원을 구현할 때
  • 애니메이션 초기 상태로 인한 수화 불일치를 디버깅할 때
  • 애니메이션이 존재해야 하는지 평가할 때

출력

이 스킬은 다음을 생성합니다:

  • 공유 motionTokens 객체 (duration, easing, distance, scale)
  • 공유 springs 프리셋 맵 (5개의 명명된 구성)
  • 모든 컴포넌트에서 사용하는 shouldAnimate() 게이트
  • useReducedMotion을 통한 접근성 준수 애니메이션 기본값
  • 수화 경고가 없는 SSR 안전 초기 상태

원칙

모션은 다음 중 하나 이상을 수행해야 하며, 그렇지 않으면 제거되어야 합니다:

  • 주의를 유도
  • 상태를 전달
  • 공간적 연속성을 유지

반응성은 항상 부드러움보다 우선합니다. 입력 지연을 유발하는 60fps 애니메이션은 애니메이션이 없는 것보다 나쁩니다.

규칙

이 규칙은 절대적으로 지켜야 합니다. 시스템의 모든 컴포넌트에 적용됩니다.

  1. motion/react만 사용하세요. 절대 framer-motion에서 가져오지 마세요. 같은 트리에서 둘을 섞지 마세요.
  2. initial은 서버 출력과 일치해야 합니다. 서버가 opacity: 1을 렌더링하면 initial prop도 opacity: 1이어야 합니다. 예외는 없습니다.
  3. Reduced motion이 모든 것을 재정의합니다. useReducedMotion()이 true를 반환하거나 prefersReduced가 true이면 모든 트랜스폼이 비활성화됩니다. ≤ 0.2초의 opacity-only 페이드만 허용되는 대체 수단입니다.
  4. 절대 layout 속성을 애니메이트하지 마세요. width, height, top, left, margin, padding은 animate에서 금지됩니다. transform과 opacity만 사용하세요.
  5. 모든 토큰 값은 motionTokens에서 가져옵니다. 컴포넌트 파일에 하드코딩된 duration과 easing은 금지됩니다.
  6. 모든 스프링 구성은 springs 맵에서 가져옵니다. 인라인 stiffness/damping 값은 금지됩니다.
  7. motion/react에서 import하는 모든 파일에는 "use client"가 필요합니다.
  8. 모듈 레벨에서 window나 navigator를 절대 읽지 마세요. 항상 typeof window !== "undefined"로 보호하세요.

결정 가이드

Duration 선택

토큰사용 시점
instant툴팁 표시/숨기기, 포커스 링, 배지 업데이트
fast버튼 피드백, 아이콘 교체, 칩 토글
normal모달 열기, 카드 확장, 페이지 요소 진입
slow히어로 진입, 전체 페이지 전환
crawl의도적인 스토리텔링; 드물게 사용

Spring 선택

프리셋사용 시점
snappy기본 UI — 버튼, 칩, 네비게이션 아이템
gentle카드, 모달, 패널 부드럽게 안착
bouncy장난스러운 순간 — 빈 상태, 온보딩
instant툴팁, 팝오버, 드롭다운
release드래그 릴리스 — 자연스러운 물리 느낌

애니메이션을 완전히 비활성화해야 하는 경우

다음 경우에 shouldAnimate()가 false를 반환하도록 비활성화하세요:

  • prefersReduced가 true인 경우
  • isLowEnd가 true이고 애니메이션이 필수가 아닌 경우
  • 요소가 화면 밖에 있고 뷰포트에 진입하지 않을 경우
  • 애니메이션이 순수하게 장식적이며 UX 목적이 없는 경우

핵심 개념

토큰 시스템

// lib/motion-tokens.ts
export const motionTokens = {
  duration: {
    instant: 0.08,
    fast:    0.18,
    normal:  0.35,
    slow:    0.6,
    crawl:   1.0,
  },
  easing: {
    smooth: [0.22, 1, 0.36, 1],
    sharp:  [0.4, 0, 0.2, 1],
    bounce: [0.34, 1.56, 0.64, 1],
    linear: [0, 0, 1, 1],
  },
  distance: {
    xs: 4,
    sm: 8,
    md: 16,
    lg: 24,
    xl: 48,
  },
  scale: {
    subtle: 0.98,
    press:  0.95,
    pop:    1.04,
  },
}

export const springs = {
  snappy:  { type: "spring", stiffness: 300, damping: 30 },
  gentle:  { type: "spring", stiffness: 120, damping: 14 },
  bouncy:  { type: "spring", stiffness: 400, damping: 10 },
  instant: { type: "spring", stiffness: 600, damping: 35 },
  release: { type: "spring", stiffness: 200, damping: 20, restDelta: 0.001 },
}

런타임 플래그

// lib/motion-config.ts
export const motionConfig = {
  isLowEnd() {
    return (
      typeof navigator !== "undefined" &&
      navigator.hardwareConcurrency <= 4
    )
  },

  prefersReduced() {
    return (
      typeof window !== "undefined" &&
      window.matchMedia("(prefers-reduced-motion: reduce)").matches
    )
  },

  shouldAnimate({ essential = false } = {}) {
    if (this.prefersReduced()) return false
    if (!essential && this.isLowEnd()) return false
    return true
  },

  duration() {
    return this.isLowEnd() || this.prefersReduced()
      ? motionTokens.duration.instant
      : motionTokens.duration.normal
  },
}

접근성

우선순위 (높은 순에서 낮은 순):

  1. prefers-reduced-motion: reduce — 모든 트랜스폼을 비활성화하고 opacity 전환을 ≤ 0.2초로 제한
  2. 저사양 기기 감지 — duration을 줄이고 필수가 아닌 애니메이션 제거
  3. 디자인 선호도 — 그 외 모든 것

모션은 우아하게 저하되어야 합니다. 레이아웃 이동을 일으키거나 방향 감각을 혼란스럽게 하는 방식으로 갑자기 사라져서는 안 됩니다.

// hooks/use-reduced-motion.tsx
"use client"
import { useReducedMotion } from "motion/react"

export function useSafeMotion(fullY: number = 16) {
  const reduce = useReducedMotion()
  return {
    initial: { opacity: 0, y: reduce ? 0 : fullY },
    animate: { opacity: 1, y: 0 },
    exit:    { opacity: 0, y: reduce ? 0 : -fullY },
  }
}
/* globals.css */
@media (prefers-reduced-motion: reduce) {
  .motion-safe-transition  { transition: opacity 0.15s; }
  .motion-reduce-transform { transform: none !important; }
}
<!-- Tailwind -->
<div class="motion-safe:animate-fade motion-reduce:opacity-100"></div>

SSR / 수화 안전성

규칙: initial은 항상 서버가 렌더링하는 것과 일치해야 합니다.

// 잘못된 예 — 서버는 opacity:1을 렌더링하지만 initial은 0 → 수화 불일치
<motion.div initial={{ opacity: 0 }} animate={{ opacity: 1 }} />

// 올바른 예 — AnimatePresence를 사용하거나 클라이언트 마운트로 지연
"use client"
const [mounted, setMounted] = useState(false)
useEffect(() => setMounted(true), [])

<motion.div
  initial={{ opacity: mounted ? 0 : 1 }}
  animate={{ opacity: 1 }}
/>

코드 예제

종합: 토큰 + 스프링 + 접근성 + SSR 가드

// components/fade-in-card.tsx
"use client"

import { useState, useEffect } from "react"
import { motion } from "motion/react"
import { motionTokens, springs } from "@/lib/motion-tokens"
import { useSafeMotion } from "@/hooks/use-reduced-motion"
import { motionConfig } from "@/lib/motion-config"

interface FadeInCardProps {
  children: React.ReactNode
  delay?: number
}

export function FadeInCard({ children, delay = 0 }: FadeInCardProps) {
  // SSR 가드 — initial은 서버 출력(opacity: 1)과 일치해야 함
  const [mounted, setMounted] = useState(false)
  useEffect(() => setMounted(true), [])

  // 접근성 — reduced motion이 선호되면 트랜스폼 비활성화
  const safeMotion = useSafeMotion(motionTokens.distance.md)

  // 기기 게이트 — 저사양 하드웨어에서 애니메이션 건너뛰기
  if (!motionConfig.shouldAnimate() || !mounted) {
    return <div>{children}</div>
  }

  return (
    <motion.div
      initial={safeMotion.initial}
      animate={safeMotion.animate}
      exit={safeMotion.exit}
      transition={{
        ...springs.gentle,
        delay,
      }}
      whileHover={{ scale: motionTokens.scale.pop }}
      whileTap={{ scale: motionTokens.scale.press }}
    >
      {children}
    </motion.div>
  )
}

제약 조건 / 비목표

이 스킬은 다음을 다루지 않습니다:

  • UI 컴포넌트 패턴 (버튼, 모달, 스태거) → motion-patterns 참고
  • 드래그, 제스처, SVG, 텍스트 애니메이션, 커스텀 훅 → motion-advanced 참고
  • CSS-only 애니메이션 또는 motion/react 없는 Tailwind animate-* 클래스
  • 서드파티 애니메이션 라이브러리 (GSAP, anime.js 등)
  • 모션 디자인 결정 (언제 애니메이트할지, 무엇을 강조할지) — 이는 코드 제약이 아닌 디자인 영역

안티 패턴

안티 패턴위반한 규칙수정 방법
import { motion } from "framer-motion"규칙 1motion/react 사용
SSR 컴포넌트에서 initial={{ opacity: 0 }}규칙 2마운트 가드 추가
useReducedMotion 확인 생략규칙 3useSafeMotion 훅 사용
animate={{ width: "100%" }}규칙 4대신 scaleX 트랜스폼 사용
인라인 transition={{ duration: 0.4 }}규칙 5motionTokens.duration.normal 사용
인라인 { stiffness: 300, damping: 30 }규칙 6springs.snappy 사용
"use client" 지시문 누락규칙 7파일 상단에 추가
모듈 레벨에서 navigator.hardwareConcurrency규칙 8typeof navigator !== "undefined"로 감싸기

관련 스킬

  • motion-patterns — 여기에 정의된 토큰과 스프링을 소비하여 버튼, 모달, 스태거, 페이지 전환, 스크롤 패턴을 구축합니다. 어떤 값도 재정의하지 않습니다.
  • motion-advanced — 여기에 정의된 토큰과 스프링을 소비하여 드래그, SVG, 텍스트, 제스처 패턴을 구현합니다. 이 기반 위에 useAnimate 시퀀스와 커스텀 훅을 추가합니다.

Individual skills in this repo

This repo contains 20 individual skills — each has its own dedicated page.

accessibility

Design, implement, and audit inclusive digital products using WCAG 2.2 Level AA. Use when building or auditing UI that must meet WCAG 2.2 Level AA, or when reviewing a change for keyboard, contrast, or screen-reader support.

affaan-m/content-engine

Create platform-native content systems for X, LinkedIn, TikTok, YouTube, newsletters, and repurposed multi-platform campaigns. Use when the user wants social posts, threads, scripts, content calendars, or one source asset adapted cleanly across platforms.

affaan-m/ECC

Multi-platform content distribution across X, LinkedIn, Threads, and Bluesky. Adapts content per platform using content-engine patterns. Never posts identical content cross-platform. Use when the user wants to distribute content across social platforms.

affaan-m/fal-ai-media

Unified media generation via fal.ai MCP — image, video, and audio. Covers text-to-image (Nano Banana), text/image-to-video (Seedance, Kling, Veo 3), text-to-speech (CSM-1B), and video-to-audio (ThinkSound). Use when the user wants to generate images, videos, or audio with AI.

affaan-m/manim-video

日本語翻訳:このファイルは manim-video 用の日本語翻訳が必要です

affaan-m/remotion-video-creation

Remotion のベストプラクティス - React で動画を作成する。3D、アニメーション、音声、字幕、チャート、トランジションなどをカバーするドメイン固有の29のルール。

affaan-m/video-editing

AI-assisted video editing workflows for cutting, structuring, and augmenting real footage. Covers the full pipeline from raw capture through FFmpeg, Remotion, ElevenLabs, fal.ai, and final polish in Descript or CapCut. Use when the user wants to edit video, cut footage, create vlogs, or build video content.

agent-architecture-audit

Full-stack diagnostic for agent and LLM applications. Audits the 12-layer agent stack for wrapper regression, memory pollution, tool discipline failures, hidden repair loops, and rendering corruption. Produces severity-ranked findings with code-first fixes. Essential for developers building agent applications, autonomous loops, or any LLM-powered feature. Use when an agent or LLM feature misbehaves and the failing layer is unknown, or before shipping an agent stack.

agent-eval

Head-to-head comparison of coding agents (Claude Code, Aider, Codex, etc.) on custom tasks with pass rate, cost, time, and consistency metrics. Use when choosing between coding agents, or when a change to an agent setup needs measured pass rate, cost, and time rather than an impression.

agent-harness-construction

Design and optimize AI agent action spaces, tool definitions, and observation formatting for higher completion rates. Use when defining or revising an agent

agentic-engineering

Operate as an agentic engineer using eval-first execution, decomposition, and cost-aware model routing. Use when planning or executing engineering work that agents will carry out end to end.

agentic-os

Build persistent multi-agent operating systems on Claude Code. Covers kernel architecture, specialist agents, slash commands, file-based memory, scheduled automation, and state management without external databases. Use when building a persistent multi-agent system on Claude Code with its own memory, commands, and scheduling.

agent-introspection-debugging

Structured self-debugging workflow for AI agent failures using capture, diagnosis, contained recovery, and introspection reports. Use when an agent run fails and you need a reproducible diagnosis instead of a retry.

agent-payment-x402

Add x402 payment execution to AI agents with per-task budgets, spending controls, and non-custodial wallets. Supports Base through agentwallet-sdk and X Layer through OKX Payments / OKX Agent Payments Protocol. Use when an agent must pay for something itself and needs per-task budgets, spending controls, and a non-custodial wallet.

agent-self-evaluation

Use after completing any non-trivial task. The agent self-rates its output on 5 axes — accuracy, completeness, clarity, actionability, conciseness — with concrete evidence per criterion. Produces a structured 1-5 scorecard with specific improvement suggestions.

agent-sort

Build an evidence-backed ECC install plan for a specific repo by sorting skills, commands, rules, hooks, and extras into DAILY vs LIBRARY buckets using parallel repo-aware review passes. Use when ECC should be trimmed to what a project actually needs instead of loading the full bundle.

ai-first-engineering

Engineering operating model for teams where AI agents generate a large share of implementation output. Use when setting team process, review gates, or ownership rules for a codebase largely written by agents.

ai-regression-testing

Regression testing strategies for AI-assisted development. Sandbox-mode API testing without database dependencies, automated bug-check workflows, and patterns to catch AI blind spots where the same model writes and reviews code. Use when adding regression coverage to AI-assisted code, or when the same model both wrote and reviewed a change.

android-clean-architecture

Clean Architecture patterns for Android and Kotlin Multiplatform projects — module structure, dependency rules, UseCases, Repositories, and data layer patterns. Use when structuring modules, layers, or data flow in an Android or KMP project.

angular-developer

Generates Angular code and provides architectural guidance. Trigger when creating projects, components, or services, or for best practices on reactivity (signals, linkedSignal, resource), forms, dependency injection, routing, SSR, accessibility (ARIA), animations, styling (component styles, Tailwind CSS), testing, or CLI tooling.

관련 스킬