01ジューススプラッシュのヒーロー
クリーム背景の上でオレンジ・ライム・グレープフルーツの3つの水滴がぷるんと跳ねながら位置を入れ替え、手前の白いカードは跳ねるたびに少し沈みます。影もグレーではなくオレンジ色の影を使います。
使いどころスムージー・ジュースブランド、美容ブランドのLP最初の画面
3색 드롭 바운스색 그림자radius 16

<main class="stage">
<section class="herocitrus">
<span class="herocitrus__drop herocitrus__drop--a" aria-hidden="true"></span>
<span class="herocitrus__drop herocitrus__drop--b" aria-hidden="true"></span>
<span class="herocitrus__drop herocitrus__drop--c" aria-hidden="true"></span>
<div class="herocitrus__card">
<p class="herocitrus__eyebrow">スクイーズ</p>
<h1 class="herocitrus__title">今日も爽やかに</h1>
<p class="herocitrus__desc">果汁たっぷりのランディングキット</p>
<button class="herocitrus__cta" type="button">無料で始める</button>
</div>
</section>
</main>@use "../../../../site/static/demo-tokens" as *;
$duration: $dur-loop; // 방울 세 개가 한 바퀴 튀어 도는 주기
$easing: $ease-spring; // 통통 튀어 오르는 곡선
$color: $stage-ink; // 글자 기본(토큰) — 아래 시트러스 잉크로 덮는다
// 시트러스 팔레트 — 값은 tailwind.config.js · tokens.css 와 같다. 카드류는 잉크 대비 4.5:1 이상 확보한 밝은 톤, 진한 톤은 그림자·그라디언트 전용(접근성 섹션 참고)
$citrus-cream: #fffaf0; // 크림 바탕
$citrus-orange: #d8c1b1; // 오렌지 — 카드 표면용(대비 4.9:1)
$citrus-orange-deep: #bd967a; // 오렌지 — 그림자·그라디언트 전용(진한 톤)
$citrus-lime: #c4ce9c; // 라임 — 카드 표면용
$citrus-grapefruit: #ebd6da; // 자몽 — 카드 표면용
$citrus-lemon: #dfd8be; // 레몬 — 카드 표면용
$citrus-ink: #204a17; // 잎사귀 잉크 — 글자는 항상 이 색(흰 배경 대비 10:1)
@include stage($citrus-cream);
.herocitrus {
position: relative;
width: clamp(220px, 76vw, 360px);
}
// 물방울 — 비대칭 반경(물방울 모양)을 45도 돌려 만든다. 위치·크기는 부모가, 모양 각도는 고정
.herocitrus__drop {
position: absolute;
width: clamp(46px, 16vw, 64px);
aspect-ratio: 1;
pointer-events: none;
}
.herocitrus__drop::before {
content: "";
display: block;
width: 100%;
height: 100%;
border-radius: 50% 50% 50% $r-xs;
transform: rotate(45deg);
}
.herocitrus__drop--a {
top: -18px;
left: -14px;
animation: dropA $duration $easing infinite;
}
.herocitrus__drop--a::before { background: $citrus-orange-deep; box-shadow: 0 8px 16px rgba($citrus-orange-deep, .55); }
.herocitrus__drop--b {
right: -18px;
top: 30%;
animation: dropB $duration $easing infinite;
animation-delay: calc($duration / -3);
}
.herocitrus__drop--b::before { background: mix($citrus-lime, $citrus-ink, 85%); box-shadow: 0 8px 16px rgba($citrus-lime, .6); }
.herocitrus__drop--c {
left: 10%;
bottom: -20px;
animation: dropA $duration $easing infinite;
animation-delay: calc($duration / -3 * 2);
}
.herocitrus__drop--c::before { background: $citrus-grapefruit; box-shadow: 0 8px 16px rgba($citrus-grapefruit, .55); }
.herocitrus__card {
position: relative;
box-sizing: border-box;
width: 100%;
display: flex;
flex-direction: column;
align-items: flex-start;
gap: $sp-2;
padding: $sp-5;
border-radius: $r-card;
background: $stage-paper;
box-shadow: 0 10px 24px rgba($citrus-orange-deep, .4);
animation: cardBob $duration $easing infinite;
}
.herocitrus__eyebrow {
margin: 0;
color: $citrus-ink;
font-weight: 700; font-size: clamp(10px, 2.6vw, 12px); line-height: 1;
font-family: inherit;
letter-spacing: .08em;
text-transform: uppercase;
}
.herocitrus__title {
margin: 0;
color: $citrus-ink;
font-weight: 700; font-size: clamp(18px, 4.6vw, 24px); line-height: 1.2;
font-family: inherit;
}
.herocitrus__desc {
margin: 0;
color: rgba($citrus-ink, .72);
font-weight: 500; font-size: clamp(12px, 2.8vw, 14px); line-height: 1.4;
font-family: inherit;
}
.herocitrus__cta {
margin-top: $sp-1;
border: 0;
border-radius: $r-pill;
background: $citrus-orange-deep;
color: $subject-ink;
padding: $sp-2 $sp-5;
font-weight: 700; font-size: clamp(12px, 2.8vw, 14px); line-height: 1;
font-family: inherit;
box-shadow: 0 6px 14px rgba($citrus-orange-deep, .6);
}
.herocitrus__cta:focus-visible {
outline: 3px solid $citrus-ink;
outline-offset: 2px;
}
// 데모: 물방울 세 개가 각자 다른 위상으로 튀어 오르고, 카드는 그때마다 살짝 눌렸다 뜬다 (WAAPI 시계가 잡을 수 있게 keyframes)
@keyframes dropA {
0%, 100% { transform: translate(0, 0) scale(1) rotate(0deg); }
50% { transform: translate(8%, -10%) scale(1.15) rotate(-8deg); }
}
@keyframes dropB {
0%, 100% { transform: translate(0, 0) scale(1) rotate(0deg); }
50% { transform: translate(-7%, 9%) scale(.86) rotate(10deg); }
}
@keyframes cardBob {
0%, 100% { transform: translateY(0); box-shadow: 0 10px 24px rgba($citrus-orange-deep, .4); }
50% { transform: translateY(-7px); box-shadow: 0 16px 30px rgba($citrus-orange-deep, .32); }
}
// 반응형: 320×200 처럼 세로가 짧은 화면에선 방울 크기와 카드 속을 줄인다(BD9 — 217 실측대로 카드 자체 높이가 넘침의 주 원인이라
// 패딩·글자·버튼까지 함께 줄인다. 217-01 은 mist 를 blur 원으로만 그려 카드 밖으로 안 삐져나왔지만 이 편은 물방울을 카드 모서리
// 밖으로 튀어나오게 그려 bottom 오프셋이 남으면 213px 로 넘쳤다 — 실측)
@media (max-width: 340px), (max-height: 220px) {
.herocitrus__drop { width: clamp(22px, 8vw, 30px); }
.herocitrus__drop--a { top: -4px; left: -4px; }
.herocitrus__drop--b { right: -4px; top: 12%; }
.herocitrus__drop--c { left: 8%; bottom: -4px; }
.herocitrus__card { padding: $sp-2 $sp-3; gap: $sp-1; }
.herocitrus__eyebrow { display: none; }
.herocitrus__title { font-size: 15px; line-height: 1.15; }
.herocitrus__desc { display: none; }
.herocitrus__cta { padding: $sp-1 $sp-4; margin-top: 0; }
}
@media (prefers-reduced-motion: reduce) {
.herocitrus__drop, .herocitrus__card { 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: #fffaf0;
font-family: -apple-system, "Segoe UI", "Noto Sans KR", sans-serif;
padding: clamp(8px, 4vw, 24px);
}
.herocitrus {
position: relative;
width: clamp(220px, 76vw, 360px);
}
.herocitrus__drop {
position: absolute;
width: clamp(46px, 16vw, 64px);
aspect-ratio: 1;
pointer-events: none;
}
.herocitrus__drop::before {
content: "";
display: block;
width: 100%;
height: 100%;
border-radius: 50% 50% 50% 4px;
transform: rotate(45deg);
}
.herocitrus__drop--a {
top: -18px;
left: -14px;
animation: dropA 2s cubic-bezier(0.2, 0.8, 0.2, 1) infinite;
}
.herocitrus__drop--a::before {
background: #bd967a;
box-shadow: 0 8px 16px rgba(189, 150, 122, 0.55);
}
.herocitrus__drop--b {
right: -18px;
top: 30%;
animation: dropB 2s cubic-bezier(0.2, 0.8, 0.2, 1) infinite;
animation-delay: -0.6666666667s;
}
.herocitrus__drop--b::before {
background: rgb(67.2156862745%, 73.0196078431%, 53.3529411765%);
box-shadow: 0 8px 16px rgba(196, 206, 156, 0.6);
}
.herocitrus__drop--c {
left: 10%;
bottom: -20px;
animation: dropA 2s cubic-bezier(0.2, 0.8, 0.2, 1) infinite;
animation-delay: -1.3333333333s;
}
.herocitrus__drop--c::before {
background: #ebd6da;
box-shadow: 0 8px 16px rgba(235, 214, 218, 0.55);
}
.herocitrus__card {
position: relative;
box-sizing: border-box;
width: 100%;
display: flex;
flex-direction: column;
align-items: flex-start;
gap: 8px;
padding: 20px;
border-radius: 16px;
background: #ffffff;
box-shadow: 0 10px 24px rgba(189, 150, 122, 0.4);
animation: cardBob 2s cubic-bezier(0.2, 0.8, 0.2, 1) infinite;
}
.herocitrus__eyebrow {
margin: 0;
color: #204a17;
font-weight: 700;
font-size: clamp(10px, 2.6vw, 12px);
line-height: 1;
font-family: inherit;
letter-spacing: 0.08em;
text-transform: uppercase;
}
.herocitrus__title {
margin: 0;
color: #204a17;
font-weight: 700;
font-size: clamp(18px, 4.6vw, 24px);
line-height: 1.2;
font-family: inherit;
}
.herocitrus__desc {
margin: 0;
color: rgba(32, 74, 23, 0.72);
font-weight: 500;
font-size: clamp(12px, 2.8vw, 14px);
line-height: 1.4;
font-family: inherit;
}
.herocitrus__cta {
margin-top: 4px;
border: 0;
border-radius: 999px;
background: #bd967a;
color: #17141a;
padding: 8px 20px;
font-weight: 700;
font-size: clamp(12px, 2.8vw, 14px);
line-height: 1;
font-family: inherit;
box-shadow: 0 6px 14px rgba(189, 150, 122, 0.6);
}
.herocitrus__cta:focus-visible {
outline: 3px solid #204a17;
outline-offset: 2px;
}
@keyframes dropA {
0%, 100% {
transform: translate(0, 0) scale(1) rotate(0deg);
}
50% {
transform: translate(8%, -10%) scale(1.15) rotate(-8deg);
}
}
@keyframes dropB {
0%, 100% {
transform: translate(0, 0) scale(1) rotate(0deg);
}
50% {
transform: translate(-7%, 9%) scale(0.86) rotate(10deg);
}
}
@keyframes cardBob {
0%, 100% {
transform: translateY(0);
box-shadow: 0 10px 24px rgba(189, 150, 122, 0.4);
}
50% {
transform: translateY(-7px);
box-shadow: 0 16px 30px rgba(189, 150, 122, 0.32);
}
}
@media (max-width: 340px), (max-height: 220px) {
.herocitrus__drop {
width: clamp(22px, 8vw, 30px);
}
.herocitrus__drop--a {
top: -4px;
left: -4px;
}
.herocitrus__drop--b {
right: -4px;
top: 12%;
}
.herocitrus__drop--c {
left: 8%;
bottom: -4px;
}
.herocitrus__card {
padding: 8px 12px;
gap: 4px;
}
.herocitrus__eyebrow {
display: none;
}
.herocitrus__title {
font-size: 15px;
line-height: 1.15;
}
.herocitrus__desc {
display: none;
}
.herocitrus__cta {
padding: 4px 16px;
margin-top: 0;
}
}
@media (prefers-reduced-motion: reduce) {
.herocitrus__drop, .herocitrus__card {
animation: none !important;
transform: none;
}
}import type { CSSProperties } from "react";
import styles from "./HeroCitrus.module.scss";
export type HeroCitrusProps = {
eyebrow?: string;
title?: string;
desc?: string;
cta?: string;
/** 한 주기(기본 2000ms) */
duration?: number;
easing?: string;
color?: string;
};
type Vars = CSSProperties & { "--duration"?: string; "--easing"?: string; "--color"?: string };
export default function HeroCitrus({
eyebrow = "스퀴즈",
title = "오늘도 상큼하게",
desc = "과즙 가득한 랜딩 키트",
cta = "무료로 시작",
duration = 2000,
easing = "cubic-bezier(.2,.8,.2,1)",
color = "#ff6a00",
}: HeroCitrusProps) {
const vars: Vars = { "--duration": `${duration}ms`, "--easing": easing, "--color": color };
return (
<section className={styles.herocitrus} style={vars}>
<span className={`${styles.drop} ${styles.dropA}`} aria-hidden="true" />
<span className={`${styles.drop} ${styles.dropB}`} aria-hidden="true" />
<span className={`${styles.drop} ${styles.dropC}`} aria-hidden="true" />
<div className={styles.card}>
<p className={styles.eyebrow}>{eyebrow}</p>
<h1 className={styles.title}>{title}</h1>
<p className={styles.desc}>{desc}</p>
<button type="button" className={styles.cta}>{cta}</button>
</div>
</section>
);
}01 ジューススプラッシュのヒーロー — 計測 累積面積 10.797% · 動いたフレーム 23/23GODRICH オリジナル · SCSS と React は zip に同梱 · ビタミンカラー デザイン LPキット、シトラスカラーのセクション9選
このデモが属する記事
ビタミンカラー デザイン LPキット、シトラスカラーのセクション9選ビタミンカラー デザインは、オレンジ・ライム・グレープフルーツ・レモンのように彩度の高いフルーツカラーをクリームの地に重ね、カードごとに同系色の影を落として、パステルより一段強く、夏のドリンクブランドのようにみずみずしく見せるスタイルです。 この記事のデモをすべて見る


