05모서리 접힌 요금제
추천 플랜 카드의 오른쪽 위 모서리가 종이 뒷면 색으로 크게 접혔다가 거의 다 펴집니다.
쓰임요금제 표의 추천 플랜 표시
clip-path 삼각형transform-origin 100% 0radius 16

<main class="stage">
<section class="dogear">
<article class="dogear__plan">
<p class="dogear__name">낱장</p>
<p class="dogear__price">₩0</p>
<p class="dogear__note">부품 1개</p>
</article>
<article class="dogear__plan dogear__plan--pick">
<span class="dogear__fold" aria-hidden="true"></span>
<span class="dogear__star" aria-hidden="true">
<svg xmlns="http://www.w3.org/2000/svg" width="1em" height="1em" viewBox="0 0 256 256"><g fill="currentColor"><path d="m229.06 108.79l-48.7 42l14.88 62.79a8.4 8.4 0 0 1-12.52 9.17L128 189.09l-54.72 33.65a8.4 8.4 0 0 1-12.52-9.17l14.88-62.79l-48.7-42A8.46 8.46 0 0 1 31.73 94l63.91-5.2l24.62-59.6a8.36 8.36 0 0 1 15.48 0l24.62 59.6l63.91 5.2a8.46 8.46 0 0 1 4.79 14.79" opacity=".2"/><path d="M239.18 97.26A16.38 16.38 0 0 0 224.92 86l-59-4.76l-22.78-55.09a16.36 16.36 0 0 0-30.27 0L90.11 81.23L31.08 86a16.46 16.46 0 0 0-9.37 28.86l45 38.83L53 211.75a16.38 16.38 0 0 0 24.5 17.82l50.5-31.08l50.53 31.08A16.4 16.4 0 0 0 203 211.75l-13.76-58.07l45-38.83a16.43 16.43 0 0 0 4.94-17.59m-15.34 5.47l-48.7 42a8 8 0 0 0-2.56 7.91l14.88 62.8a.37.37 0 0 1-.17.48c-.18.14-.23.11-.38 0l-54.72-33.65a8 8 0 0 0-8.38 0l-54.72 33.67c-.15.09-.19.12-.38 0a.37.37 0 0 1-.17-.48l14.88-62.8a8 8 0 0 0-2.56-7.91l-48.7-42c-.12-.1-.23-.19-.13-.5s.18-.27.33-.29l63.92-5.16a8 8 0 0 0 6.72-4.94l24.62-59.61c.08-.17.11-.25.35-.25s.27.08.35.25L153 91.86a8 8 0 0 0 6.75 4.92l63.92 5.16c.15 0 .24 0 .33.29s0 .4-.16.5"/></g></svg>
</span>
<p class="dogear__name">한 묶음</p>
<p class="dogear__price">₩9<span>,900</span></p>
<p class="dogear__note">부품 9개 묶음</p>
</article>
</section>
</main>@use "../../../../site/static/demo-tokens" as *;
// 페이퍼컷 팔레트
$paper-base: #fbf6ec;
$paper-sheet: #ffffff;
$paper-ink: #2a2320;
$paper-stone: #5c5048;
$paper-coral: #b97b71;
$paper-sky: #6a8db5;
$paper-leaf: #2b7d5a;
$paper-butter: #d6c9ab;
$paper-edge: #e7dccb;
$paper-blush: #f6b3ab;
$duration: $dur-loop; // 모서리가 접혔다 펴지는 한 주기
$easing: $ease-out; // 종이가 스스로 펴지는 속도
$color: $paper-butter; // 접힌 모서리 안쪽(뒷면) 색
@include stage($paper-blush);
.dogear {
display: flex;
gap: $sp-3;
align-items: stretch;
}
.dogear__plan {
box-sizing: border-box;
position: relative;
width: 124px;
padding: $sp-4;
border-radius: $r-card;
background: $paper-sheet;
box-shadow: 0 6px 0 rgba($paper-ink, .16);
overflow: hidden;
}
.dogear__plan--pick {
background: $paper-sheet;
outline: 3px solid $paper-coral;
outline-offset: -3px;
}
// 오른쪽 위 접힌 모서리 — 종이 뒷면이 드러나는 삼각형
.dogear__fold {
position: absolute;
top: 0;
right: 0;
width: 40px;
height: 40px;
background: $color;
clip-path: polygon(100% 0, 0 0, 100% 100%);
transform-origin: 100% 0; // 규칙8: dog-ear 코너 경첩
animation: cornerFold $duration $easing infinite;
}
.dogear__star {
position: absolute;
top: $sp-3;
left: $sp-3;
color: $paper-coral;
font-size: 16px;
line-height: 1;
}
.dogear__name {
margin: $sp-5 0 $sp-1;
color: $paper-stone;
font-weight: 700; font-size: 11px; line-height: 1;
font-family: inherit;
letter-spacing: .08em;
text-transform: uppercase;
}
.dogear__plan:not(.dogear__plan--pick) .dogear__name { margin-top: 0; }
.dogear__price {
margin: 0 0 $sp-1;
color: $paper-ink;
font-weight: 800; font-size: 24px; line-height: 1.1;
font-family: inherit;
}
.dogear__price span { font-size: 15px; }
.dogear__note {
margin: 0;
color: $paper-stone;
font-weight: 500; font-size: 11px; line-height: 1.35;
font-family: inherit;
}
// 데모: 모서리가 크게 접혔다가 거의 다 펴진다. 삼각형 크기가 변해 눈에 띈다
@keyframes cornerFold {
0%, 100% { transform: scale(1); }
50% { transform: scale(.28); }
}
@media (max-width: 340px), (max-height: 220px) {
.dogear { gap: $sp-2; }
.dogear__plan { width: 96px; padding: $sp-3; }
.dogear__fold { width: 28px; height: 28px; }
.dogear__star { font-size: 13px; top: $sp-2; left: $sp-2; }
.dogear__name { margin-top: $sp-4; font-size: 9px; }
.dogear__price { font-size: 18px; }
.dogear__price span { font-size: 12px; }
.dogear__note { display: none; }
}
@media (prefers-reduced-motion: reduce) {
.dogear__fold { 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: #f6b3ab;
font-family: -apple-system, "Segoe UI", "Noto Sans KR", sans-serif;
padding: clamp(8px, 4vw, 24px);
}
.dogear {
display: flex;
gap: 12px;
align-items: stretch;
}
.dogear__plan {
box-sizing: border-box;
position: relative;
width: 124px;
padding: 16px;
border-radius: 16px;
background: #ffffff;
box-shadow: 0 6px 0 rgba(42, 35, 32, 0.16);
overflow: hidden;
}
.dogear__plan--pick {
background: #ffffff;
outline: 3px solid #b97b71;
outline-offset: -3px;
}
.dogear__fold {
position: absolute;
top: 0;
right: 0;
width: 40px;
height: 40px;
background: #d6c9ab;
clip-path: polygon(100% 0, 0 0, 100% 100%);
transform-origin: 100% 0;
animation: cornerFold 2s ease-out infinite;
}
.dogear__star {
position: absolute;
top: 12px;
left: 12px;
color: #b97b71;
font-size: 16px;
line-height: 1;
}
.dogear__name {
margin: 20px 0 4px;
color: #5c5048;
font-weight: 700;
font-size: 11px;
line-height: 1;
font-family: inherit;
letter-spacing: 0.08em;
text-transform: uppercase;
}
.dogear__plan:not(.dogear__plan--pick) .dogear__name {
margin-top: 0;
}
.dogear__price {
margin: 0 0 4px;
color: #2a2320;
font-weight: 800;
font-size: 24px;
line-height: 1.1;
font-family: inherit;
}
.dogear__price span {
font-size: 15px;
}
.dogear__note {
margin: 0;
color: #5c5048;
font-weight: 500;
font-size: 11px;
line-height: 1.35;
font-family: inherit;
}
@keyframes cornerFold {
0%, 100% {
transform: scale(1);
}
50% {
transform: scale(0.28);
}
}
@media (max-width: 340px), (max-height: 220px) {
.dogear {
gap: 8px;
}
.dogear__plan {
width: 96px;
padding: 12px;
}
.dogear__fold {
width: 28px;
height: 28px;
}
.dogear__star {
font-size: 13px;
top: 8px;
left: 8px;
}
.dogear__name {
margin-top: 16px;
font-size: 9px;
}
.dogear__price {
font-size: 18px;
}
.dogear__price span {
font-size: 12px;
}
.dogear__note {
display: none;
}
}
@media (prefers-reduced-motion: reduce) {
.dogear__fold {
animation: none !important;
transform: none;
}
}import type { CSSProperties } from "react";
import styles from "./DogEarPricing.module.scss";
export type PaperPlan = { name: string; price: string; sub?: string; note: string; pick?: boolean };
export type DogEarPricingProps = {
plans?: PaperPlan[];
/** 한 주기(기본 2000ms) */
duration?: number;
easing?: string;
/** 접힌 모서리(종이 뒷면) 색 */
color?: string;
};
type Vars = CSSProperties & { "--duration"?: string; "--easing"?: string; "--color"?: string };
const STAR = (
<svg xmlns="http://www.w3.org/2000/svg" width="1em" height="1em" viewBox="0 0 256 256"><g fill="currentColor"><path d="m229.06 108.79l-48.7 42l14.88 62.79a8.4 8.4 0 0 1-12.52 9.17L128 189.09l-54.72 33.65a8.4 8.4 0 0 1-12.52-9.17l14.88-62.79l-48.7-42A8.46 8.46 0 0 1 31.73 94l63.91-5.2l24.62-59.6a8.36 8.36 0 0 1 15.48 0l24.62 59.6l63.91 5.2a8.46 8.46 0 0 1 4.79 14.79" opacity=".2"/><path d="M239.18 97.26A16.38 16.38 0 0 0 224.92 86l-59-4.76l-22.78-55.09a16.36 16.36 0 0 0-30.27 0L90.11 81.23L31.08 86a16.46 16.46 0 0 0-9.37 28.86l45 38.83L53 211.75a16.38 16.38 0 0 0 24.5 17.82l50.5-31.08l50.53 31.08A16.4 16.4 0 0 0 203 211.75l-13.76-58.07l45-38.83a16.43 16.43 0 0 0 4.94-17.59m-15.34 5.47l-48.7 42a8 8 0 0 0-2.56 7.91l14.88 62.8a.37.37 0 0 1-.17.48c-.18.14-.23.11-.38 0l-54.72-33.65a8 8 0 0 0-8.38 0l-54.72 33.67c-.15.09-.19.12-.38 0a.37.37 0 0 1-.17-.48l14.88-62.8a8 8 0 0 0-2.56-7.91l-48.7-42c-.12-.1-.23-.19-.13-.5s.18-.27.33-.29l63.92-5.16a8 8 0 0 0 6.72-4.94l24.62-59.61c.08-.17.11-.25.35-.25s.27.08.35.25L153 91.86a8 8 0 0 0 6.75 4.92l63.92 5.16c.15 0 .24 0 .33.29s0 .4-.16.5"/></g></svg>
);
export default function DogEarPricing({
plans = [
{ name: "낱장", price: "₩0", note: "부품 1개" },
{ name: "한 묶음", price: "₩9", sub: ",900", note: "부품 9개 묶음", pick: true },
],
duration = 2000,
easing = "ease-out",
color = "#f6c453",
}: DogEarPricingProps) {
const vars: Vars = { "--duration": `${duration}ms`, "--easing": easing, "--color": color };
return (
<section className={styles.dogear} style={vars}>
{plans.map((p) => (
<article key={p.name} className={`${styles.plan} ${p.pick ? styles.pick : ""}`}>
{p.pick && <span className={styles.fold} aria-hidden="true" />}
{p.pick && <span className={styles.star} aria-hidden="true">{STAR}</span>}
<p className={styles.name}>{p.name}</p>
<p className={styles.price}>{p.price}{p.sub && <span>{p.sub}</span>}</p>
<p className={styles.note}>{p.note}</p>
</article>
))}
</section>
);
}05 모서리 접힌 요금제 — 측정 누적면적 0.525% · 움직인 프레임 23/23GODRICH 원작 · zip 에 SCSS·React 포함 · 종이 질감 디자인 랜딩 키트, 오려 붙인 섹션 9개
이 데모가 속한 글
종이 질감 디자인 랜딩 키트, 오려 붙인 섹션 9개종이 질감 디자인은 색종이를 가위로 오려 붙인 것처럼 면마다 흐림 없는 그림자로 두께를 주고, 색은 다섯 가지 안에서만 쓰는 스타일입니다. 종이 사진을 깔지 않고 그림자 값 하나만으로 종이처럼 보이게 만드는 것이 전 이 글의 데모 전부 보기


