GODRICH

키네틱 타이포그래피 랜딩페이지, 코드로 뜯어봤다

키네틱 타이포그래피는 헤드라인 글자가 화면 폭에 맞춰 커지고, 단어가 순서대로 튀어 오르고, 숫자가 굴러가듯 올라가는 디자인 방식입니다. 요즘 랜딩페이지 첫 화면을 다 이렇게 만들길래, 실제로 코드까지 뜯어서 아홉 조각으로 나눠봤습니다.

이 아홉 개 부품을 그대로 이어 붙인 원페이지 랜딩을 먼저 스크롤해 보십시오. 헤드라인이 단어 단위로 떠오르고, 카드 속 숫자가 실제 값까지 굴러 올라가고, 맨 아래 워드마크 위로 빛이 한 번 스쳐 지나가는지 확인하는 것이 핵심입니다.

새 창에서 원페이지 열기

이 화면을 이루는 아홉 조각은 아래 격자에서 하나씩 따로 클릭해서 열어 볼 수 있습니다. 나열한 순서는 인기순이 아니라 방문자가 실제 랜딩페이지를 위에서 아래로 훑는 동선(눈길이 먼저 가는 곳, 둘러보는 곳, 기능을 훑는 곳, 값을 따지는 곳, 신뢰를 확인하는 곳, 등 떠밀려 행동하는 곳, 마지막에 남는 곳) 그대로 따라간 것입니다.

자동 재생 · 눌러서 해당 항목으로 · 전부 한 zip

01히어로

헤드라인 세 단어가 순서대로 아래에서 위로 튀어 오르며 나타납니다. 각 단어는 보이지 않는 상자 안에 숨어 있다가 차례가 되면 튀어 올라오고, 글자 크기 자체도 화면 폭에 맞춰 clamp()로 자동으로 커지거나 작아집니다.

clamp() 가변폭단어 단위 staggeroverflow: hidden 마스크
<section class="flex flex-col items-center gap-6 py-24 text-center">
  <p class="text-xs font-bold uppercase tracking-[0.2em] text-accent">
    KINETIC TYPE
  </p>
  <h1 class="font-display text-6xl font-extrabold leading-[1.02]
             sm:text-7xl md:text-8xl">
    생각의 속도로<br>만든다
  </h1>
  <button class="rounded-pill bg-ink px-8 py-4 text-base font-bold text-cream">
    지금 시작
  </button>
</section>

02내비게이션

내비게이션 왼쪽 워드마크 글자가 저절로 작아졌다가 다시 커지기를 반복합니다. 실제 스크롤에 반응하는 건 아니고, 스크롤하면 로고가 줄어드는 흔한 스티키 헤더 효과를 무한 루프 데모로 미리 보여주는 방식이며, 바뀌는 값은 글자 크기 하나뿐이고 자간은 그대로입니다.

transform-origin: left centerletter-spacing 보간sticky 헤더
<header class="sticky top-0 z-20 px-6 pt-6">
  <nav class="mx-auto flex max-w-5xl items-center justify-between
              rounded-pill bg-ink px-6 py-3 shadow-bento">
    <span class="font-display text-xl font-extrabold text-cream">MOTIF</span>
    <div class="hidden items-center gap-8 sm:flex">
      <span class="text-sm font-semibold text-cream/70">소개</span>
      <span class="text-sm font-semibold text-cream/70">기능</span>
      <span class="text-sm font-semibold text-cream/70">가격</span>
    </div>
    <button class="rounded-pill bg-accent px-5 py-2 text-sm font-bold text-cream">
      시작하기
    </button>
  </nav>
</header>

03카드 격자

카드 안 숫자가 0에서 실제 값(248)까지 자릿수 그대로 올라갑니다. counter()로 그려낸 숫자는 스크린리더가 읽지 못해, 숫자가 다 오른 최종 값("프로젝트 248개")을 시각적으로만 숨긴 텍스트로 따로 붙여 뒀습니다.

@property 숫자 보간counter-resettabular-nums
<section class="py-14">
  <h2 class="mb-8 font-display text-3xl font-extrabold">숫자로 보는 결과</h2>
  <div class="grid grid-cols-1 gap-4 sm:grid-cols-3">
    <div class="rounded-tile bg-ink p-8 text-center shadow-bento">
      <p class="font-display text-6xl font-extrabold tabular-nums text-cream">
        248
      </p>
      <p class="mt-2 text-sm font-semibold text-cream/70">프로젝트</p>
    </div>
    <div class="rounded-tile bg-ink p-8 text-center shadow-bento">
      <p class="font-display text-6xl font-extrabold tabular-nums text-cream">
        99.9%
      </p>
      <p class="mt-2 text-sm font-semibold text-cream/70">가동률</p>
    </div>
  </div>
</section>

04기능 목록

기능 목록 세 줄이 위에서부터 순서대로 오른쪽으로 살짝 밀렸다가 제자리로 돌아오고, 그 아래 밑줄도 같은 박자로 자랐다 사라집니다. 왼쪽 큰 번호는 코드 에디터의 줄 번호 같은 인상을 주는 장식이고, 실제 기능 이름은 항상 글자로 붙어 있어 번호만으로 의미가 끊기지 않습니다.

grid 번호 정렬호버 translateX@keyframes underline-grow
<ul class="divide-y divide-line rounded-tile bg-white shadow-bento">
  <li class="grid grid-cols-[auto_1fr] items-baseline gap-6 p-6">
    <span class="font-display text-3xl font-extrabold text-accent
                 tabular-nums">01</span>
    <span class="text-lg font-bold">실시간 협업</span>
  </li>
  <li class="grid grid-cols-[auto_1fr] items-baseline gap-6 p-6">
    <span class="font-display text-3xl font-extrabold text-accent
                 tabular-nums">02</span>
    <span class="text-lg font-bold">자동 배포</span>
  </li>
</ul>

05가격

가격 숫자가 월 요금(19,000원)과 연 요금(190,000원) 사이를 자동으로 오르내리며 반복 재생됩니다. 버튼을 눌러야 바뀌는 토글이 아니라 처음부터 끝까지 저절로 움직이는 데모이고, 실제 서비스에 붙일 때는 이 자리에 진짜 월간·연간 전환 버튼을 달면 됩니다.

숫자 롤 애니메이션@keyframes price-rolltabular-nums
<div class="flex flex-col items-end gap-4 sm:flex-row">
  <div class="flex-1 rounded-tile bg-white/60 p-8
              shadow-[0_6px_12px_rgba(23,20,26,.08)]">
    <p class="font-bold">무료</p>
    <p class="mt-2 font-display text-4xl font-extrabold tabular-nums">₩0</p>
  </div>
  <div class="relative flex-[1.1] rounded-tile bg-ink p-8 pt-10
              shadow-bento-hover">
    <span class="absolute -top-3 left-8 rounded-pill bg-accent px-3 py-1
                 text-xs font-bold text-cream">추천</span>
    <p class="font-bold text-cream/70">프로 플랜</p>
    <p class="mt-2 font-display text-5xl font-extrabold tabular-nums
              text-cream">
      ₩19,000<span class="text-lg font-semibold text-cream/60"> / 월</span>
    </p>
  </div>
</div>

06후기

초대형 인용문이 왼쪽부터 오른쪽으로 커튼을 걷듯 한 번에 드러납니다. 01번 헤드라인의 위아래 마스크와 달리 이번엔 clip-path로 좌우 방향으로 걷어내는 와이프 기법을 씁니다.

clip-path: inset()단어 단위 stagger@keyframes wipe-reveal
<section class="py-14">
  <h2 class="mb-8 font-display text-3xl font-extrabold">고객 후기</h2>
  <figure class="rounded-tile bg-white p-10 text-center shadow-bento">
    <p class="font-display text-3xl font-extrabold leading-snug sm:text-4xl">
      "속도가 팀의 문화를 바꿨다"
    </p>
    <figcaption class="mt-4 text-sm text-ink/60">박지훈 · 그로스 리드</figcaption>
  </figure>
</section>

07CTA 띠

가로로 긴 띠 안에서 CTA 문구가 끊김 없이 계속 흘러갑니다. 문구를 통째로 두 벌 이어 붙이고 정확히 절반(-50%)만큼 밀어야 이음새가 텔레포트처럼 매끄럽고, 간격은 gap이 아니라 항목마다 margin-right로 줘야 한 바퀴 돌 때마다 튀지 않습니다.

translateX(-50%) 루프margin 간격(gap 금지)hover 일시정지
<div class="relative overflow-hidden rounded-tile bg-accent py-8">
  <div class="flex w-max animate-marquee">
    <span class="mr-12 flex-shrink-0 whitespace-nowrap font-display
                 text-5xl font-extrabold text-cream">지금 시작하기 —</span>
    <span class="mr-12 flex-shrink-0 whitespace-nowrap font-display
                 text-5xl font-extrabold text-cream">지금 시작하기 —</span>
    <span class="mr-12 flex-shrink-0 whitespace-nowrap font-display
                 text-5xl font-extrabold text-cream" aria-hidden="true">지금 시작하기 —</span>
  </div>
</div>

08푸터

푸터 맨 아래 거대한 워드마크 위로 빛줄기가 대각선으로 한 번 스치고 지나갑니다. background-clip: text로 그라디언트를 글자 모양 안에만 가두고, 한 번 스친 뒤에는 다시 정지 상태로 오래 쉬도록 시간표를 짰습니다.

background-clip: textgradient sweepclamp() 초대형 폰트
<footer class="py-14">
  <div class="grid grid-cols-2 gap-4 sm:grid-cols-3">
    <div class="rounded-tile bg-ink/[.04] p-5">
      <p class="mb-2 text-xs font-bold uppercase tracking-wide text-ink/50">
        제품
      </p>
      <p class="text-sm font-semibold">기능</p>
    </div>
    <div class="rounded-tile bg-ink/[.04] p-5">
      <p class="mb-2 text-xs font-bold uppercase tracking-wide text-ink/50">
        회사
      </p>
      <p class="text-sm font-semibold">이용약관</p>
    </div>
  </div>
  <p class="mt-10 text-center font-display text-7xl font-extrabold
            text-ink/[.06] sm:text-8xl">MOTIF</p>
</footer>

09버튼·입력

링크형 버튼 아래 밑줄이 가운데서부터 좌우로 자랐다가 다시 사그라듭니다. 마우스로 호버하지 않고 키보드로 포커스를 옮겨도 별도의 테두리가 항상 따로 나타나, 밑줄 애니메이션 하나에만 기대지 않고도 지금 어디에 있는지 알 수 있습니다.

transform: scaleXtransform-origin: centerfocus-visible 링
<div class="flex flex-col items-center gap-6 rounded-tile bg-ink p-10
            sm:flex-row sm:justify-center">
  <button class="relative border-0 bg-transparent font-display text-2xl
                 font-extrabold text-cream after:absolute after:-bottom-1
                 after:left-0 after:right-0 after:h-[2px] after:bg-accent">
    자세히 보기
  </button>
  <label class="relative w-full max-w-xs rounded-[12px] bg-cream/5">
    <input class="w-full rounded-[12px] border border-cream/30 bg-transparent
                  px-4 py-3 text-sm text-cream outline-none" type="email"
           placeholder="이메일 주소" readonly>
  </label>
</div>

tailwind.config 커스텀

지금까지 열어 본 아홉 조각과 맨 위 원페이지는 모두 이 설정 파일 하나를 공유해서 씁니다. 색·글꼴·반경·그림자 값을 여기 한 곳만 바꾸면 아홉 조각 전체의 톤이 동시에 맞춰집니다.

theme: {
  extend: {
    colors: {
      cream: "#fff7e6",
      ink: "#17141a",
      accent: "#2f6df6",
      line: "rgba(23,20,26,.08)",
    },
    fontFamily: {
      display: ["'Space Grotesk'", "system-ui", "sans-serif"],
      body: ["'Inter'", "system-ui", "sans-serif"],
    },
    borderRadius: { tile: "20px", pill: "999px" },
    boxShadow: {
      bento: "0 14px 24px rgba(23,20,26,.10)",
      "bento-hover": "0 20px 32px rgba(23,20,26,.16)",
    },
    spacing: { gutter: "14px" },
  },
},

바이브코딩 프롬프트

위 설정을 프로젝트에 붙여 넣었다면, Claude Code나 Cursor에게는 아래 몇 줄만 던져도 충분히 알아듣습니다. 지시문 전체는 줄이지 않은 원본 그대로 zip의 prompt.md에 들어 있습니다.

배경은 cream(#fff7e6) 하나, 카드는 순백이 아니라 ink(#17141a) 배경 위에 cream 글자로 만든다.
제목과 큰 숫자에는 항상 font-display(Space Grotesk)를 쓰고, 본문 글자에는 font-body(Inter)를 쓴다.
강조가 필요한 곳(버튼·추천 배지·CTA 띠)에만 accent(#2f6df6)를 쓰고 두 번째 강조색을 넣지 않는다.
반경은 rounded-tile·rounded-pill 두 값만 쓴다.

위 지시문을 그대로 page/index.html에 붙여 넣어 얻은 화면을 1280px 너비 기준으로 통째로 캡처해 뒀습니다.

결과

어디서 깨지는가 — 함정

이 스타일에서 가장 흔한 함정은 배경·글자색을 theme() 함수로 <style> 태그 안에 직접 지정하는 것입니다. Tailwind Play CDN은 컴파일된 유틸리티 클래스(bg-cream 같은) 안의 theme() 값은 정상 처리하지만, <style> 태그 안에 직접 쓴 background: theme('colors.cream')는 조용히 무시하고 브라우저 기본값(투명 배경·검정 글자)으로 되돌아갑니다. 이 프로젝트도 처음엔 <body> 배경·글자색과 h2 글꼴까지 전부 <style> 태그의 theme()로 지정했다가, 실제로 렌더해 보니 배경이 투명하게 비치고 글자가 순검정으로 나와 크림·잉크 톤이 하나도 안 보이는 상태로 남을 뻔했습니다. <body class="bg-cream text-ink font-body">처럼 컴파일되는 유틸리티 클래스로 바꾸고, h2마다 font-display 클래스를 직접 달고 나서야 톤이 제대로 적용됐습니다. 두 번째 함정은 02번 워드마크입니다. 스크롤하면 줄어드는 스티키 헤더처럼 보이지만 실제로는 스크롤과 무관한 반복 데모라, 자간까지 함께 줄어들 거라 기대하고 코드를 그대로 옮기면 자간은 그대로인 채 크기만 바뀌어 의아할 수 있습니다. 아홉 조각과 원페이지 소스 전체를 압축한 zip 파일은 잠겨 있고, 여는 암호는 y9my63zg이며 이 아래 버튼을 눌러 내려받으실 수 있습니다.

세 번째 함정은 03번·05번의 숫자 애니메이션입니다. @property --num으로 정수 타입을 선언하지 않으면 브라우저가 0.5, 1.7 같은 소수 중간값으로 보간해 숫자가 깜빡이며 지나갑니다. syntax: '<integer>'를 반드시 선언해야 자릿수가 깔끔하게 하나씩 올라갑니다.

접근성

아홉 개 데모 전부 MDN prefers-reduced-motion 문서가 정의한 미디어 쿼리로 감쌌고, 동작 줄이기를 켠 방문자에게는 단어가 튀어 오르거나 숫자가 굴러가는 대신 정지된 최종 상태만 보입니다. 03번·05번처럼 counter()로 그린 숫자는 스크린리더가 읽지 못해 실제 값을 시각적으로만 숨긴 텍스트로 항상 함께 두었고, 07번 마퀴의 복제된 문구 절반은 aria-hidden으로 감춰 같은 말을 두 번 읽지 않게 했습니다. 09번은 밑줄 애니메이션과 별개로 :focus-visible 테두리를 항상 켜 둬, 움직임이 꺼진 환경에서도 지금 포커스가 어디 있는지 알 수 있습니다.

다른 유행 스타일도 궁금하시면 디자인 트렌드 카테고리에 더 모아 뒀고, 이 사이트를 운영하는 사람이 누구인지는 소개 페이지에서 확인하실 수 있습니다.

FAQ

MOTIF·KINETIC 같은 이름을 실제 서비스에 그대로 써도 되나요?

네, 문제없습니다. 이 편의 부품은 특정 실제 브랜드를 복제한 것이 아니라 핀터레스트에서 흔히 보이는 키네틱 타이포 스타일을 참고해 만든 가상의 이름(MOTIF)과 라벨(KINETIC)이라, 여러분의 서비스 이름으로 그대로 바꿔 써도 됩니다.

폰트를 Space Grotesk·Inter가 아닌 다른 걸로 바꿔도 되나요?

가능합니다. tailwind.config.jsfontFamily.display·fontFamily.body 두 값만 바꾸면 아홉 개 부품 전부에 새 글꼴이 한 번에 적용됩니다. 다만 큰 숫자·헤드라인처럼 굵고 눈에 띄는 자리(display)와 본문(body)의 역할 구분은 그대로 유지하는 것이 이 스타일의 핵심입니다.

Tailwind 없이 순수 CSS만으로도 이 부품들을 쓸 수 있나요?

가능합니다. zip에 든 tokens.csstailwind.config.js와 같은 값을 CSS 변수(--color-cream, --radius-tile 등)로 옮겨 담고 있어, Tailwind 클래스 대신 var(--radius-tile)처럼 직접 참조하면 색·반경·그림자를 동일하게 맞출 수 있습니다.

압축 비밀번호를 입력하세요

비밀번호는 이 글 본문 안에 있습니다. 읽다 보면 나옵니다.