01Rising-orb hero
Over a deep-ink background, a sphere built from stacked radial-gradient layers drifts slowly up and down (translateY) while its blurred halo pulses on the same 2s breath. The orb is pure decoration, so screen readers skip it.
Best forAI product landing first screens
radial-gradienttranslateYscalearia-hidden

<main class="stage">
<section class="ho">
<div class="ho__text">
<p class="ho__eyebrow">
<span class="ho__ico" aria-hidden="true"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 256 256" fill="currentColor"><path d="M194.82,151.43l-55.09,20.3-20.3,55.09a7.92,7.92,0,0,1-14.86,0l-20.3-55.09-55.09-20.3a7.92,7.92,0,0,1,0-14.86l55.09-20.3,20.3-55.09a7.92,7.92,0,0,1,14.86,0l20.3,55.09,55.09,20.3A7.92,7.92,0,0,1,194.82,151.43Z" opacity="0.2"/><path d="M197.58,129.06,146,110l-19-51.62a15.92,15.92,0,0,0-29.88,0L78,110l-51.62,19a15.92,15.92,0,0,0,0,29.88L78,178l19,51.62a15.92,15.92,0,0,0,29.88,0L146,178l51.62-19a15.92,15.92,0,0,0,0-29.88ZM137,164.22a8,8,0,0,0-4.74,4.74L112,223.85,91.78,169A8,8,0,0,0,87,164.22L32.15,144,87,123.78A8,8,0,0,0,91.78,119L112,64.15,132.22,119a8,8,0,0,0,4.74,4.74L191.85,144ZM144,40a8,8,0,0,1,8-8h16V16a8,8,0,0,1,16,0V32h16a8,8,0,0,1,0,16H184V64a8,8,0,0,1-16,0V48H152A8,8,0,0,1,144,40ZM248,88a8,8,0,0,1-8,8h-8v8a8,8,0,0,1-16,0V96h-8a8,8,0,0,1,0-16h8V72a8,8,0,0,1,16,0v8h8A8,8,0,0,1,248,88Z"/></svg></span>
New model is live
</p>
<h1 class="ho__title">Ask once, get the first draft</h1>
<p class="ho__sub">Meeting notes, decks and email — sorted in one pass.</p>
<a class="ho__cta" href="#" role="button">Start for free<span class="ho__arrow" aria-hidden="true"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 256 256" fill="currentColor"><path d="M216,128l-72,72V56Z" opacity="0.2"/><path d="M221.66,122.34l-72-72A8,8,0,0,0,136,56v64H40a8,8,0,0,0,0,16h96v64a8,8,0,0,0,13.66,5.66l72-72A8,8,0,0,0,221.66,122.34ZM152,180.69V75.31L204.69,128Z"/></svg></span></a>
</div>
<div class="ho__orbwrap" aria-hidden="true">
<span class="ho__halo"></span>
<span class="ho__orb"></span>
</div>
</section>
</main>@use "../../../../site/static/demo-tokens" as *;
// 변수 3개 — 변형은 이 셋만 바꾼다
$duration: $dur-loop; // 떠오름·맥박 한 주기 (설정 `초` 와 같은 2s)
$easing: ease-in-out; // 위아래 왕복은 양끝에서 멎어야 숨쉬듯 보인다
$color: $subject-sky; // 오브의 빛 색
// 이 편 아홉 항목은 전부 잉크 무대다 — 빛나는 오브는 어두운 바탕에서만 빛으로 읽힌다
@include stage($stage-ink);
.ho {
display: grid; grid-template-columns: 1fr auto; align-items: center; gap: $sp-5;
width: min(100%, 432px);
}
// 대비 실측(WCAG 상대휘도로 계산): 무대 $stage-ink 의 상대휘도 0.00757
.ho__eyebrow {
display: flex; align-items: center; gap: $sp-1; margin: 0 0 $sp-2;
font-weight: 700; font-size: 10px; line-height: 1; letter-spacing: .04em;
color: $color; // $subject-sky on $stage-ink = 9.87:1
}
.ho__ico { display: inline-flex; width: 12px; height: 12px; flex: 0 0 auto; }
.ho__ico svg { width: 100%; height: 100%; }
.ho__title {
margin: 0; font-weight: 800; font-size: clamp(17px, 5.2vw, 25px); line-height: 1.18;
letter-spacing: -.01em; color: $subject-cream; // $subject-cream on $stage-ink = 17.11:1
}
// keep-all 은 한국어에만 — 어절 가운데서 끊기지 않게 한다(묻기만 하면 / 초안이 나옵니다).
// 일본어에 걸면 띄어쓰기가 없어 줄바꿈 자리가 사라지고 가로로 넘친다 (ja 사본 480×300 실측 2026-09-12)
.ho__title:lang(ko) {
word-break: keep-all;
}
.ho__sub {
margin: $sp-2 0 0; font-weight: 500; font-size: clamp(10px, 2.8vw, 12px); line-height: 1.45;
color: rgba(255, 247, 230, .72); // 잉크 위에서 #beb7ad 로 합성 = 9.18:1
}
.ho__cta {
display: inline-flex; align-items: center; gap: $sp-1; margin-top: $sp-4;
padding: $sp-2 $sp-4; border-radius: $r-pill;
background: $subject-cream; color: $subject-ink; // 크림 위 잉크 글자 = 17.11:1
font-weight: 700; font-size: 11px; line-height: 1; text-decoration: none;
}
.ho__arrow { display: inline-flex; width: 12px; height: 12px; }
.ho__arrow svg { width: 100%; height: 100%; }
// ── 오브: 겹으로 쌓은 radial-gradient 네 겹 = 하이라이트 · 빛 · 반사 · 코어
.ho__orbwrap {
position: relative; width: 152px; height: 152px; flex: 0 0 auto;
display: grid; place-items: center;
}
.ho__orb {
position: relative; z-index: 1; width: 104px; height: 104px; border-radius: 50%;
background:
radial-gradient(circle at 34% 28%, rgba(255, 255, 255, .92), rgba(255, 255, 255, 0) 44%),
radial-gradient(circle at 28% 66%, rgba(110, 200, 255, .9), rgba(110, 200, 255, 0) 58%),
radial-gradient(circle at 74% 72%, rgba(185, 160, 255, .8), rgba(185, 160, 255, 0) 56%),
radial-gradient(circle at 50% 50%, rgba(47, 109, 246, .95) 10%, rgba(23, 20, 26, .96) 92%);
animation-name: hoFloat; animation-duration: $duration; animation-timing-function: $easing;
animation-iteration-count: infinite;
}
// 빛 무리 — 오브와 같은 2초 주기로 커졌다 작아진다. 자기 중심에서 커진다 (blog-demo 규칙 8)
.ho__halo {
position: absolute; inset: 0; border-radius: 50%; transform-origin: 50% 50%;
background: radial-gradient(circle at 50% 50%, rgba(110, 200, 255, .42), rgba(110, 200, 255, .16) 48%, rgba(110, 200, 255, 0) 72%);
animation-name: hoPulse; animation-duration: $duration; animation-timing-function: $easing;
animation-iteration-count: infinite;
}
// translateY 왕복 — 0%·100% 가 같은 값이라 루프 이음매가 없다
@keyframes hoFloat {
0%, 100% { transform: translateY(7px); }
50% { transform: translateY(-7px); }
}
// scale 최대가 1 — 커져도 감싼 상자(152px) 밖으로 안 나간다. 넘침(BD9) 방지
@keyframes hoPulse {
0%, 100% { transform: scale(.82); opacity: .5; }
50% { transform: scale(1); opacity: .9; }
}
// ── 320×200 폰 실측 대비 압축 (BD9)
@media (max-width: 340px), (max-height: 220px) {
.ho { gap: $sp-3; }
.ho__eyebrow { margin-bottom: $sp-1; font-size: 9px; }
.ho__title { font-size: 15px; }
.ho__sub { margin-top: $sp-1; font-size: 9px; }
.ho__cta { margin-top: $sp-2; padding: $sp-1 $sp-3; font-size: 10px; }
.ho__orbwrap { width: 96px; height: 96px; }
.ho__orb { width: 68px; height: 68px; }
}
@media (prefers-reduced-motion: reduce) {
.ho__orb, .ho__halo { animation: none !important; transform: none !important; opacity: .9 !important; }
}html, body {
margin: 0;
overflow: hidden;
}
.stage {
box-sizing: border-box;
min-height: 100vh;
display: grid;
place-items: center;
margin: 0;
background: #17141a;
font-family: -apple-system, "Segoe UI", "Noto Sans KR", sans-serif;
padding: clamp(8px, 4vw, 24px);
}
.ho {
display: grid;
grid-template-columns: 1fr auto;
align-items: center;
gap: 20px;
width: min(100%, 432px);
}
.ho__eyebrow {
display: flex;
align-items: center;
gap: 4px;
margin: 0 0 8px;
font-weight: 700;
font-size: 10px;
line-height: 1;
letter-spacing: 0.04em;
color: #6ec8ff;
}
.ho__ico {
display: inline-flex;
width: 12px;
height: 12px;
flex: 0 0 auto;
}
.ho__ico svg {
width: 100%;
height: 100%;
}
.ho__title {
margin: 0;
font-weight: 800;
font-size: clamp(17px, 5.2vw, 25px);
line-height: 1.18;
letter-spacing: -0.01em;
color: #fff7e6;
}
.ho__title:lang(ko) {
word-break: keep-all;
}
.ho__sub {
margin: 8px 0 0;
font-weight: 500;
font-size: clamp(10px, 2.8vw, 12px);
line-height: 1.45;
color: rgba(255, 247, 230, 0.72);
}
.ho__cta {
display: inline-flex;
align-items: center;
gap: 4px;
margin-top: 16px;
padding: 8px 16px;
border-radius: 999px;
background: #fff7e6;
color: #17141a;
font-weight: 700;
font-size: 11px;
line-height: 1;
text-decoration: none;
}
.ho__arrow {
display: inline-flex;
width: 12px;
height: 12px;
}
.ho__arrow svg {
width: 100%;
height: 100%;
}
.ho__orbwrap {
position: relative;
width: 152px;
height: 152px;
flex: 0 0 auto;
display: grid;
place-items: center;
}
.ho__orb {
position: relative;
z-index: 1;
width: 104px;
height: 104px;
border-radius: 50%;
background: radial-gradient(circle at 34% 28%, rgba(255, 255, 255, 0.92), rgba(255, 255, 255, 0) 44%), radial-gradient(circle at 28% 66%, rgba(110, 200, 255, 0.9), rgba(110, 200, 255, 0) 58%), radial-gradient(circle at 74% 72%, rgba(185, 160, 255, 0.8), rgba(185, 160, 255, 0) 56%), radial-gradient(circle at 50% 50%, rgba(47, 109, 246, 0.95) 10%, rgba(23, 20, 26, 0.96) 92%);
animation-name: hoFloat;
animation-duration: 2s;
animation-timing-function: ease-in-out;
animation-iteration-count: infinite;
}
.ho__halo {
position: absolute;
inset: 0;
border-radius: 50%;
transform-origin: 50% 50%;
background: radial-gradient(circle at 50% 50%, rgba(110, 200, 255, 0.42), rgba(110, 200, 255, 0.16) 48%, rgba(110, 200, 255, 0) 72%);
animation-name: hoPulse;
animation-duration: 2s;
animation-timing-function: ease-in-out;
animation-iteration-count: infinite;
}
@keyframes hoFloat {
0%, 100% {
transform: translateY(7px);
}
50% {
transform: translateY(-7px);
}
}
@keyframes hoPulse {
0%, 100% {
transform: scale(0.82);
opacity: 0.5;
}
50% {
transform: scale(1);
opacity: 0.9;
}
}
@media (max-width: 340px), (max-height: 220px) {
.ho {
gap: 12px;
}
.ho__eyebrow {
margin-bottom: 4px;
font-size: 9px;
}
.ho__title {
font-size: 15px;
}
.ho__sub {
margin-top: 4px;
font-size: 9px;
}
.ho__cta {
margin-top: 8px;
padding: 4px 12px;
font-size: 10px;
}
.ho__orbwrap {
width: 96px;
height: 96px;
}
.ho__orb {
width: 68px;
height: 68px;
}
}
@media (prefers-reduced-motion: reduce) {
.ho__orb, .ho__halo {
animation: none !important;
transform: none !important;
opacity: 0.9 !important;
}
}import styles from "./HeroOrb.module.scss";
export type HeroOrbProps = { duration?: string; easing?: string; color?: string };
export default function HeroOrb({ duration = "2s", easing = "ease-in-out", color = "#6ec8ff" }: HeroOrbProps) {
// 변수 3개는 props 로 — 오브가 한 번 떠올랐다 내려앉는 시간 · 그 이징 · 빛 색
const motion = { animationDuration: duration, animationTimingFunction: easing };
return (
<main className={styles.stage}>
<section className={styles.ho}>
<div className={styles.text}>
<p className={styles.eyebrow} style={{ color }}>
<span className={styles.ico} aria-hidden="true">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 256 256" fill="currentColor"><path d="M194.82,151.43l-55.09,20.3-20.3,55.09a7.92,7.92,0,0,1-14.86,0l-20.3-55.09-55.09-20.3a7.92,7.92,0,0,1,0-14.86l55.09-20.3,20.3-55.09a7.92,7.92,0,0,1,14.86,0l20.3,55.09,55.09,20.3A7.92,7.92,0,0,1,194.82,151.43Z" opacity="0.2"/><path d="M197.58,129.06,146,110l-19-51.62a15.92,15.92,0,0,0-29.88,0L78,110l-51.62,19a15.92,15.92,0,0,0,0,29.88L78,178l19,51.62a15.92,15.92,0,0,0,29.88,0L146,178l51.62-19a15.92,15.92,0,0,0,0-29.88ZM137,164.22a8,8,0,0,0-4.74,4.74L112,223.85,91.78,169A8,8,0,0,0,87,164.22L32.15,144,87,123.78A8,8,0,0,0,91.78,119L112,64.15,132.22,119a8,8,0,0,0,4.74,4.74L191.85,144ZM144,40a8,8,0,0,1,8-8h16V16a8,8,0,0,1,16,0V32h16a8,8,0,0,1,0,16H184V64a8,8,0,0,1-16,0V48H152A8,8,0,0,1,144,40ZM248,88a8,8,0,0,1-8,8h-8v8a8,8,0,0,1-16,0V96h-8a8,8,0,0,1,0-16h8V72a8,8,0,0,1,16,0v8h8A8,8,0,0,1,248,88Z"/></svg>
</span>
새 모델 공개
</p>
<h1 className={styles.title}>묻기만 하면 초안이 나옵니다</h1>
<p className={styles.sub}>회의록·기획서·메일을 한 번에 정리합니다.</p>
<a className={styles.cta} href="#" role="button" onClick={(e: { preventDefault: () => void }) => { e.preventDefault(); }}>
무료로 시작하기
<span className={styles.arrow} aria-hidden="true">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 256 256" fill="currentColor"><path d="M216,128l-72,72V56Z" opacity="0.2"/><path d="M221.66,122.34l-72-72A8,8,0,0,0,136,56v64H40a8,8,0,0,0,0,16h96v64a8,8,0,0,0,13.66,5.66l72-72A8,8,0,0,0,221.66,122.34ZM152,180.69V75.31L204.69,128Z"/></svg>
</span>
</a>
</div>
<div className={styles.orbwrap} aria-hidden="true">
<span className={styles.halo} style={motion} />
<span className={styles.orb} style={motion} />
</div>
</section>
</main>
);
}01 Rising-orb hero — Measured area 9.735% · moving frames 23/23Original by GODRICH · SCSS and React ship in the zip · AI Landing Page Design Kit: 9 Glowing Orb Sections
The post this demo lives in
AI Landing Page Design Kit: 9 Glowing Orb SectionsAI landing page design has gone AI-native without painting a gradient background. The page stays one flat dark color, an See all demos in this post


