vibeui
인터랙션무료새 카드

움직임 여섯 가지를 얹은 SaaS 랜딩

커서를 따라오는 버튼, 3D로 뒤집히는 단어, 흐려지며 바뀌는 숫자, 테두리를 도는 빛, 쌓이는 카드, 이어지는 입자. 여섯 가지를 한 랜딩에 자연스럽게 배치한다.

마지막 수정

프롬프트 보고 복사하기복사해서 새 대화에 그대로 붙이면 됩니다

이 프롬프트를 실제로 실행해 나온 화면입니다

영상 원본 받기결과물 HTML 받기더블클릭하면 브라우저에서 바로 열립니다
복사해서 새 대화에 그대로

붙일 프롬프트

프롬프트 언어
붙일 도구
결과 스택
Claude Code · HTML 단일 파일
56줄 · 4,464
너는 이 저장소에서 작업하는 프론트엔드 엔지니어다. 아래 지시를 읽고 먼저 계획을 3줄로 말한 뒤 바로 파일을 만들어라. 질문은 정말 막힐 때 한 번만 해라.

# 작업: 움직임 여섯 가지를 얹은 SaaS 랜딩

## 언제 쓰는 작업인가
제품 소개 랜딩에 움직임을 넣고 싶은데 라이브러리를 늘리기는 싫을 때 쓴다. 여섯 가지가 서로 독립이라 마음에 드는 것만 골라 쓰면 되고, 각각 스무 줄을 넘지 않는다.

## 준비물(이미 갖춰져 있다고 가정)
- 새 프로젝트다. Next.js 는 1번 뼈대가 깔려 있고, HTML 은 빈 index.html 에서 시작한다
- 제품명과 히어로 문구가 있다. 제목 두 줄, 설명 한 문단, 버튼 두 개
- 기능 3개, 단계 3개, 지표 3개의 제목과 한 줄 설명이 있다
- Framer Motion·GSAP·Lenis 는 설치하지 않는다

## 건드릴 범위
랜딩 한 장(히어로·기능 3열·단계 3단·마감 CTA)과 그 안의 움직임 여섯 가지까지다. 로그인·결제·대시보드 실물은 만들지 않는다. 화면 속 그래프는 막대 네 개로 대신한다.

## 결과가 이렇게 보여야 한다
배경은 따뜻한 오프화이트 한 색이고 강조는 인디고에서 보라로 넘어가는 그라디언트 하나뿐이다. 히어로 뒤에는 옅은 보라 곡선 일곱 가닥이 천천히 흘러간다. 제목 가운데 한 단어는 3D 축으로 뒤집히며 바뀌고, 그 아래 지표 숫자는 흐려지며 위로 빠지고 다음 숫자가 올라온다. 기능 카드 세 장은 테두리를 따라 빛 한 줄기가 돈다. 단계 패널 셋은 화면에 붙어 차례로 쌓이고 뒤 패널은 조금 줄며 어두워진다. 마지막 CTA 는 검은 판인데 그 안에서 작은 입자들이 떠다니며 가까운 것끼리 선으로 이어진다.

## 구현 순서
1. 자석 버튼: 버튼을 감싼 요소에 pointermove 를 { passive: true } 로 걸고, 커서와 버튼 중심의 거리가 90px 안일 때만 그 차이의 0.32 배만큼 translate 한다. 값을 바로 대입하지 말고 requestAnimationFrame 안에서 현재값 += (목표값 - 현재값) * 0.18 로 따라가게 한다. 스프링 물리 없이 이 한 줄로 충분히 부드럽다. hover 가 없는 기기(matchMedia '(hover: hover)')에서는 아예 걸지 않는다.
2. 3D 뒤집기 단어: 부모를 display inline-grid·perspective 900px 로 두고 자식들을 모두 grid-area 1/1 에 겹친다. 각 자식에 transform-style preserve-3d 와 backface-visibility hidden 을 준다. 바꿀 때는 새 요소를 rotateX(-92deg)·opacity 0 으로 붙였다가 다음 프레임에 0deg·1 로 보내고, 기존 요소는 rotateX(92deg)·opacity 0 으로 보낸 뒤 700ms 후 지운다. 92도를 쓰는 이유는 정확히 90도에서 면이 사라져 한 프레임 깜빡이기 때문이다.
3. 흐려지며 바뀌는 숫자: 높이를 고정하고 overflow hidden 인 상자 안에 숫자를 겹쳐 둔다. 새 숫자는 translateY(22px)·blur(7px)·opacity 0 에서 제자리로, 옛 숫자는 translateY(-22px)·blur(7px)·opacity 0 으로 내보낸다. 겹쳐 두려고 absolute 를 쓰면 상자가 폭을 못 잡아 글자가 잘린다. 상자에 min-width 와 white-space nowrap 을 같이 준다.
4. 테두리 광선: 카드를 padding 1px 짜리 겉껍질과 그 안의 흰 속으로 나눈다. 겉껍질의 ::before 를 inset -60% 로 키우고 conic-gradient(from var(--beam), transparent 0deg, 강조색 22deg, 보조색 40deg, transparent 62deg) 를 칠한다. @property --beam 을 syntax '<angle>' 로 선언해야 각도가 보간되어 실제로 돈다. 선언하지 않으면 0deg 와 360deg 를 오갈 뿐 아무 일도 일어나지 않는다. 카드마다 animation-delay 를 음수로 어긋나게 준다.
5. 카드 적층: 각 패널을 position sticky·top 92px 인 상자로 감싼다. 스크롤할 때 다음 패널이 화면 아래에서 올라온 비율을 (화면높이 - 다음패널.top) / (화면높이 * 0.72) 로 구해, 지금 패널을 scale 1 에서 0.945 로 줄이고 translateY 를 -14px 까지 올리고 brightness 를 0.88 까지 낮춘다. 마지막 패널은 건드리지 않는다.
6. 이어지는 입자: 캔버스 넓이 × 높이를 16000 으로 나눈 만큼 점을 만들되 90개를 넘기지 않는다. 매 프레임 조금씩 움직이고 화면 밖으로 나가면 반대편에서 다시 들어오게 한다. 점 사이 거리가 118px 미만일 때만 선을 긋고, 투명도를 (1 - 거리/118) * 0.3 으로 준다. 이 이중 반복문이 비용의 대부분이라 점 개수 상한이 성능을 정한다.
7. 흐르는 곡선 배경: SVG 를 viewBox 1200×620·preserveAspectRatio xMidYMid slice 로 깔고 곡선 일곱 가닥을 Q 명령으로 그린다. 한 줄은 150px 간격으로 위아래 번갈아 휘게 한다. 각 선에 stroke-dasharray '220 1400' 을 주면 짧은 선분 하나와 아주 긴 빈칸이 되고, stroke-dashoffset 을 -1620 까지 애니메이션하면 그 선분이 경로를 따라 흐른다. 선마다 길이와 지연을 어긋나게 준다.
8. 색과 글자를 먼저 못박는다. 배경 #FBFAF8, 글자 #17161C, 보조 글자는 같은 색 60% 투명, 경계선은 10% 투명이다. 강조는 #4B3BFF 에서 #A78BFA 로 가는 그라디언트 하나뿐이고 보조로 민트 #17C3A2 를 그래프에만 쓴다. 제목은 clamp(2.3rem, 5.6vw, 4.2rem) 에 letter-spacing -0.04em, 본문은 16px 에 line-height 1.7 이다.
9. 성능을 잡는다. 스크롤 계산은 자물쇠 변수 하나를 두고 requestAnimationFrame 한 프레임에 한 번만 한다. 캔버스는 IntersectionObserver 로 화면에 들어왔을 때만 돌리고 나갈 때 cancelAnimationFrame 한다. devicePixelRatio 는 2 로 자른다. 움직이는 요소에는 will-change transform 을 주되 열 개를 넘기지 않는다.
10. prefers-reduced-motion 이면 모든 animation 과 transition 을 none 으로 덮고, 뒤집기·숫자 교체·입자 순환을 시작하지 않는다. 자석 버튼도 걸지 않는다. 카드 적층은 변형 없이 그대로 쌓인 상태로 둔다. 400px 과 1440px 에서 가로 스크롤이 없는지 보고 빌드를 통과시킨다.

## 기본값(필요하면 바꿔라)
- 자석 반응 거리: 90px (바꿀 수 있는 범위: 50px ~ 160px(넓으면 커서가 멀리서도 끌려 산만하다))
- 자석 따라오는 비율: 0.18 (바꿀 수 있는 범위: 0.08 ~ 0.35)
- 테두리 광선 한 바퀴: 4.6초 (바꿀 수 있는 범위: 3초 ~ 9초)
- 입자 연결 거리: 118px (바꿀 수 있는 범위: 70px ~ 160px(넓을수록 선이 촘촘하고 무겁다))
- 뒤 카드가 줄어드는 정도: 0.945배 (바꿀 수 있는 범위: 0.9 ~ 1(1 이면 쌓여도 티가 안 난다))

## 하지 말 것
- Framer Motion·GSAP·Lenis 를 설치하지 않는다. 여섯 가지 모두 스무 줄 안쪽이다.
- @property 선언 없이 conic-gradient 의 각도를 애니메이션하지 않는다. 보간이 안 돼 화면에 아무 변화가 없다.
- 겹쳐 둔 글자 상자에 min-width 를 빼먹지 않는다. absolute 자식만 있으면 상자가 폭을 못 잡아 숫자가 잘린다.
- 3D 뒤집기를 정확히 90도로 돌리지 않는다. 면이 사라지는 한 프레임에 글자가 깜빡인다.
- 입자를 150개 이상 만들지 않는다. 선을 긋는 이중 반복문이 제곱으로 늘어 노트북에서도 프레임이 떨어진다.
- 한 화면에 여섯 가지를 다 넣지 않는다. 히어로에 둘, 나머지는 섹션마다 하나씩이 상한이다.

## 출력 규칙 (HTML 단일 파일)
- 결과는 index.html 파일 하나로 저장한다. 외부 CDN 을 쓰지 않고 CSS·JS 를 파일 안에 넣는다.
- HTML 파일 하나로 완결한다. 별도 CSS·JS 파일을 만들지 않는다.
- 폰트는 시스템 폰트 스택을 기본으로 쓰고, 한글은 'Pretendard Variable', 'Apple SD Gothic Neo', 'Malgun Gothic' 순으로 폴백한다.
- 색·간격·둥글기는 :root 의 CSS 변수로 모아 두고, 본문에서는 변수만 참조한다.
- 1200px 데스크톱과 400px 모바일에서 가로 스크롤이 생기지 않아야 한다.
- 움직임은 prefers-reduced-motion 을 존중한다.

끝나면 만든 파일 목록과 브라우저에서 확인할 URL 을 한 줄씩 적어라.

복사한 뒤 Claude Code 새 대화에 그대로 붙이면 됩니다. 아래 값은 붙이기 전에 숫자만 바꿔도 결과가 달라집니다.

바꿔 볼 값

  • 자석 반응 거리90px

    50px ~ 160px(넓으면 커서가 멀리서도 끌려 산만하다)

  • 자석 따라오는 비율0.18

    0.08 ~ 0.35

  • 테두리 광선 한 바퀴4.6초

    3초 ~ 9초

  • 입자 연결 거리118px

    70px ~ 160px(넓을수록 선이 촘촘하고 무겁다)

  • 뒤 카드가 줄어드는 정도0.945배

    0.9 ~ 1(1 이면 쌓여도 티가 안 난다)

붙이기 전에 한 번

언제 쓰고, 뭐가 필요한가

언제 쓰나

제품 소개 랜딩에 움직임을 넣고 싶은데 라이브러리를 늘리기는 싫을 때 쓴다. 여섯 가지가 서로 독립이라 마음에 드는 것만 골라 쓰면 되고, 각각 스무 줄을 넘지 않는다.

준비물

  • 새 프로젝트다. Next.js 는 1번 뼈대가 깔려 있고, HTML 은 빈 index.html 에서 시작한다
  • 제품명과 히어로 문구가 있다. 제목 두 줄, 설명 한 문단, 버튼 두 개
  • 기능 3개, 단계 3개, 지표 3개의 제목과 한 줄 설명이 있다
  • Framer Motion·GSAP·Lenis 는 설치하지 않는다
복사해서 붙인 직후

결과는 이렇게 나옵니다

첫 화면에서 제목 가운데 단어가 2.4초마다 뒤집히며 바뀌고, 그 아래 지표 셋이 각자 다른 박자로 흐려지며 교체된다. 버튼에 커서를 가져가면 살짝 끌려온다. 내려가면 기능 카드 테두리를 빛이 돌고, 단계 패널이 화면에 붙어 차례로 쌓이며, 마지막 검은 판 안에서 입자들이 서로 이어졌다 끊어진다.

같이 쓰면 좋습니다

이어서 붙이면 좋은 카드