06パターン帯の料金プラン
中央のおすすめプランだけが水玉の帯と丸いバッジを付け、6px浮いたり沈んだりし、バッジは逆位相で脈打ちます。
使いどころ料金表のおすすめプランの強調
translateYscaleradial-gradient

<main class="stage">
<section class="pricem">
<article class="pricem__plan">
<h2 class="pricem__tier">スターター</h2>
<p class="pricem__price">₩0</p>
<p class="pricem__per">ずっと無料</p>
</article>
<article class="pricem__plan pricem__plan--best">
<span class="pricem__badge">人気</span>
<h2 class="pricem__tier">プロ</h2>
<p class="pricem__price">₩9,000</p>
<p class="pricem__per">月あたり</p>
</article>
<article class="pricem__plan">
<h2 class="pricem__tier">チーム</h2>
<p class="pricem__price">₩39,000</p>
<p class="pricem__per">月あたり</p>
</article>
</section>
</main>@use "../../../../site/static/demo-tokens" as *;
// 멤피스 팔레트 — 01 과 같은 값
$mem-base: #fdf4ec;
$mem-sheet: #ffffff;
$mem-ink: #241f26;
$mem-stone: #5d5560;
$mem-coral: #d5aea9;
$mem-lemon: #cec29c;
$mem-sky: #82adc2;
$mem-mint: #71b9ab;
$mem-pink: #ebd6db;
$duration: $dur-loop; // 추천 플랜이 들렀다 앉는 한 주기
$easing: $ease-out; // 둥실 — 튕기지 않는다
$color: $mem-lemon; // 추천 플랜의 점 무늬 머리띠 색
@include stage($mem-base);
.pricem {
box-sizing: border-box;
display: flex;
align-items: flex-end;
gap: $sp-3;
width: clamp(280px, 88vw, 404px);
padding-top: $sp-3;
}
.pricem__plan {
position: relative;
box-sizing: border-box;
flex: 1 1 0;
padding: $sp-3 $sp-2 $sp-3;
border-radius: $r-card;
background: $mem-sheet;
border: 3px solid $mem-ink;
box-shadow: 0 6px 0 $mem-ink;
text-align: center;
}
// 추천 플랜 — 점 무늬 머리띠(반경 그라디언트)를 이고 혼자서 둥실 뜬다
.pricem__plan--best {
padding-top: $sp-10;
overflow: hidden;
animation: bestFloat $duration $easing infinite;
}
.pricem__plan--best::before {
content: "";
position: absolute;
left: 0;
right: 0;
top: 0;
height: 32px;
border-bottom: 3px solid $mem-ink;
background-color: $color;
background-image: radial-gradient(circle at 11px 16px, $mem-ink 0 3px, transparent 3.5px);
background-size: 22px 22px;
}
// 인기 배지 — 머리띠 위에 걸터앉은 동그라미. 플랜과 반대 위상으로 맥박친다
.pricem__badge {
position: absolute;
z-index: 1;
top: -14px;
left: 50%;
margin-left: -24px;
width: 48px;
padding: $sp-1 0;
border-radius: $r-pill;
background: $mem-coral;
border: 3px solid $mem-ink;
color: $mem-ink;
font-weight: 800; font-size: 12px; line-height: 1;
font-family: inherit;
animation: badgePulse $duration $easing infinite;
animation-delay: -1s; // 반 주기 딜레이 = 플랜과 반대 위상
}
.pricem__tier {
margin: 0;
color: $mem-stone;
font-weight: 700; font-size: clamp(11px, 2.6vw, 13px); line-height: 1;
font-family: inherit;
}
.pricem__price {
margin: $sp-2 0 0;
color: $mem-ink;
font-weight: 800; font-size: clamp(16px, 4vw, 22px); line-height: 1;
font-family: inherit;
}
.pricem__per {
margin: $sp-1 0 0;
color: $mem-stone;
font-weight: 500; font-size: clamp(10px, 2.4vw, 11px); line-height: 1;
font-family: inherit;
}
// 플랜은 6px 둥실, 배지는 그 반대 위상(반 주기 딜레이)으로 크기 맥박
@keyframes bestFloat {
0%, 100% { transform: translateY(0); }
50% { transform: translateY(-6px); }
}
@keyframes badgePulse {
0%, 100% { transform: scale(1); }
50% { transform: scale(1.12); }
}
@media (max-width: 340px), (max-height: 220px) {
.pricem { width: 248px; gap: $sp-2; }
.pricem__plan { padding: $sp-2 $sp-1; }
.pricem__plan--best { padding-top: $sp-8; }
.pricem__plan--best::before { height: 26px; }
.pricem__badge { width: 40px; margin-left: -20px; top: -12px; font-size: 10px; }
.pricem__price { font-size: 14px; }
}
@media (prefers-reduced-motion: reduce) {
.pricem__plan--best, .pricem__badge { animation: none !important; transform: none; }
}html, body {
margin: 0;
overflow: hidden;
}
.stage {
box-sizing: border-box;
min-height: 100vh;
display: grid;
place-items: center;
margin: 0;
background: #fdf4ec;
font-family: -apple-system, "Segoe UI", "Noto Sans KR", sans-serif;
padding: clamp(8px, 4vw, 24px);
}
.pricem {
box-sizing: border-box;
display: flex;
align-items: flex-end;
gap: 12px;
width: clamp(280px, 88vw, 404px);
padding-top: 12px;
}
.pricem__plan {
position: relative;
box-sizing: border-box;
flex: 1 1 0;
padding: 12px 8px 12px;
border-radius: 16px;
background: #ffffff;
border: 3px solid #241f26;
box-shadow: 0 6px 0 #241f26;
text-align: center;
}
.pricem__plan--best {
padding-top: 40px;
overflow: hidden;
animation: bestFloat 2s ease-out infinite;
}
.pricem__plan--best::before {
content: "";
position: absolute;
left: 0;
right: 0;
top: 0;
height: 32px;
border-bottom: 3px solid #241f26;
background-color: #cec29c;
background-image: radial-gradient(circle at 11px 16px, #241f26 0 3px, transparent 3.5px);
background-size: 22px 22px;
}
.pricem__badge {
position: absolute;
z-index: 1;
top: -14px;
left: 50%;
margin-left: -24px;
width: 48px;
padding: 4px 0;
border-radius: 999px;
background: #d5aea9;
border: 3px solid #241f26;
color: #241f26;
font-weight: 800;
font-size: 12px;
line-height: 1;
font-family: inherit;
animation: badgePulse 2s ease-out infinite;
animation-delay: -1s;
}
.pricem__tier {
margin: 0;
color: #5d5560;
font-weight: 700;
font-size: clamp(11px, 2.6vw, 13px);
line-height: 1;
font-family: inherit;
}
.pricem__price {
margin: 8px 0 0;
color: #241f26;
font-weight: 800;
font-size: clamp(16px, 4vw, 22px);
line-height: 1;
font-family: inherit;
}
.pricem__per {
margin: 4px 0 0;
color: #5d5560;
font-weight: 500;
font-size: clamp(10px, 2.4vw, 11px);
line-height: 1;
font-family: inherit;
}
@keyframes bestFloat {
0%, 100% {
transform: translateY(0);
}
50% {
transform: translateY(-6px);
}
}
@keyframes badgePulse {
0%, 100% {
transform: scale(1);
}
50% {
transform: scale(1.12);
}
}
@media (max-width: 340px), (max-height: 220px) {
.pricem {
width: 248px;
gap: 8px;
}
.pricem__plan {
padding: 8px 4px;
}
.pricem__plan--best {
padding-top: 32px;
}
.pricem__plan--best::before {
height: 26px;
}
.pricem__badge {
width: 40px;
margin-left: -20px;
top: -12px;
font-size: 10px;
}
.pricem__price {
font-size: 14px;
}
}
@media (prefers-reduced-motion: reduce) {
.pricem__plan--best, .pricem__badge {
animation: none !important;
transform: none;
}
}import type { CSSProperties } from "react";
import styles from "./PricingMemphis.module.scss";
export type PricingMemphisPlan = { tier: string; price: string; per: string; best?: boolean };
export type PricingMemphisProps = {
/** 플랜 3개. best 가 true 인 플랜이 점 무늬 머리띠를 이고 뜬다 */
plans?: PricingMemphisPlan[];
/** 추천 플랜 배지 글자 */
badge?: string;
/** 한 주기(기본 2000ms) */
duration?: number;
easing?: string;
/** 추천 플랜의 점 무늬 머리띠 색 */
color?: string;
};
type Vars = CSSProperties & { "--duration"?: string; "--easing"?: string; "--color"?: string };
export default function PricingMemphis({
plans = [
{ tier: "스타터", price: "₩0", per: "영구 무료" },
{ tier: "프로", price: "₩9,000", per: "한 달 기준", best: true },
{ tier: "팀", price: "₩39,000", per: "한 달 기준" },
],
badge = "인기",
duration = 2000,
easing = "ease-out",
color = "#ffcf33",
}: PricingMemphisProps) {
const vars: Vars = { "--duration": `${duration}ms`, "--easing": easing, "--color": color };
return (
<section className={styles.pricem} style={vars}>
{plans.map((p) => (
<article
key={p.tier}
className={p.best ? `${styles.plan} ${styles.planBest}` : styles.plan}
>
{p.best ? <span className={styles.badge}>{badge}</span> : null}
<h2 className={styles.tier}>{p.tier}</h2>
<p className={styles.price}>{p.price}</p>
<p className={styles.per}>{p.per}</p>
</article>
))}
</section>
);
}06 パターン帯の料金プラン — 計測 累積面積 5.376% · 動いたフレーム 23/23GODRICH オリジナル · SCSS と React は zip に同梱 · メンフィス デザインのLPパーツ9選、コピペOK
このデモが属する記事
メンフィス デザインのLPパーツ9選、コピペOKメンフィス デザインとは、1980年代のミラノ生まれの、水玉・波線・ジグザグなどの幾何学形を明るい色の上に繰り返すスタイルです。画像を一枚も使わず、CSSグラデーションのタイルと図形だけでこのパターンを再現し、ランディングのセクション9つに この記事のデモをすべて見る


