Y2K Web Design: 9 Chrome Holographic Sections
Y2K web design brings back the chrome shine of early-2000s CDs and holographic packaging, rebuilt in pure CSS.
One of the nine sections below puts that same holographic css shimmer on a spinning avatar ring rather than a card. Scroll through the assembled one-pager first — watch for where the chrome headline catches light and where it dims back down.

Each section is also broken out on its own below, arranged in a grid.
01 hero-chrome
02 nav-chrome
03 card-grid-chrome
04 feature-list-chrome
05 pricing-chrome
06 testimonial-chrome
07 cta-band-chrome
08 footer-chrome
09 buttons-inputs-chrome
Auto-plays · click a tile to jump to its section · all nine in one zip
- 01 Chrome headline hero
- 02 Brushed-metal nav
- 03 Holographic foil cards
- 04 Chrome ball icons
- 05 Holographic highlighted plan
- 06 CD-ring avatar quote
- 07 Brushed-aluminum CTA band
- 08 Holographic hairline footer
- 09 Chrome buttons, holographic focus
The order isn't arbitrary. It follows the path a visitor actually takes down the page: notice it, check what it does, see the price, read what someone else has to say about it, then press the button. Strip the chrome off and keep only the hard right-angle shadow and you land on Neobrutalism UI Kit; push the same metal toward an instrument panel instead and you get HUD Interface Design.
01Chrome headline hero
What moves
The headline is clipped to a background-clip: text window, and a six-stop chrome gradient — white through cream, yellow, blue, orange, and back to white — slides across it by shifting only background-position.

<main class="stage">
<section class="hero-c">
<p class="hero-c__eyebrow">CHROME</p>
<h2 class="hero-c__title">The first screen, shining again</h2>
<button class="hero-c__cta" type="button">Start for free</button>
</section>
</main>@use "../../../../site/static/demo-tokens" as *;
// ── 변수 3개 ──────────────────────────────────────────
$duration: $dur-loop; // 크롬 밴드가 한 바퀴 흐르는 시간
$easing: $ease-out;
$color: $subject-blue; // 그라디언트 안 포인트 색 하나
@include stage($stage-ink);
.hero-c {
position: relative;
overflow: hidden;
box-sizing: border-box;
width: clamp(260px, 86vw, 400px);
min-height: clamp(172px, 48vw, 220px);
border-radius: $r-card;
background: $stage-ink;
box-shadow: $shadow-raised;
padding: $sp-6;
display: flex;
flex-direction: column;
justify-content: center;
gap: $sp-3;
}
.hero-c__eyebrow {
position: relative;
z-index: 1;
margin: 0;
color: $stage-yellow;
font-weight: 700;
font-size: clamp(10px, 2.4vw, 12px);
line-height: 1;
letter-spacing: .06em;
text-transform: uppercase;
font-family: -apple-system, "Segoe UI", "Noto Sans KR", sans-serif;
}
// 헤드라인 — 크롬 그라디언트를 글자 모양으로 잘라내고, 그 안의 밝은 밴드가 background-position 만 바뀌며 흐른다 (유일한 애니메이션)
.hero-c__title {
position: relative;
z-index: 1;
margin: 0;
font-weight: 800;
font-size: clamp(18px, 4.6vw, 23px);
line-height: 1.2;
font-family: -apple-system, "Segoe UI", "Noto Sans KR", sans-serif;
background: linear-gradient(100deg,
$stage-paper 0%, rgba($stage-paper, .35) 14%, $subject-cream 28%,
$stage-yellow 40%, $color 52%, $stage-orange 64%,
$stage-paper 80%, rgba($stage-paper, .4) 100%);
background-size: 240% 100%;
-webkit-background-clip: text;
background-clip: text;
color: transparent;
animation: chromeFlow $duration $easing infinite;
}
.hero-c__cta {
position: relative;
z-index: 1;
align-self: flex-start;
border: 0;
border-radius: $r-pill;
background: linear-gradient(100deg, $subject-cream, $stage-paper, $subject-cream);
color: $stage-ink;
padding: $sp-2 $sp-5;
font-weight: 700;
font-size: clamp(11px, 2.6vw, 13px);
line-height: 1;
font-family: inherit;
}
@keyframes chromeFlow { 0% { background-position: 0% 50%; } 100% { background-position: 240% 50%; } }
@media (prefers-reduced-motion: reduce) {
.hero-c__title { animation: none; }
}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);
}
.hero-c {
position: relative;
overflow: hidden;
box-sizing: border-box;
width: clamp(260px, 86vw, 400px);
min-height: clamp(172px, 48vw, 220px);
border-radius: 16px;
background: #17141a;
box-shadow: 0 14px 24px rgba(23, 20, 26, 0.32);
padding: 24px;
display: flex;
flex-direction: column;
justify-content: center;
gap: 12px;
}
.hero-c__eyebrow {
position: relative;
z-index: 1;
margin: 0;
color: #ffd23f;
font-weight: 700;
font-size: clamp(10px, 2.4vw, 12px);
line-height: 1;
letter-spacing: 0.06em;
text-transform: uppercase;
font-family: -apple-system, "Segoe UI", "Noto Sans KR", sans-serif;
}
.hero-c__title {
position: relative;
z-index: 1;
margin: 0;
font-weight: 800;
font-size: clamp(18px, 4.6vw, 23px);
line-height: 1.2;
font-family: -apple-system, "Segoe UI", "Noto Sans KR", sans-serif;
background: linear-gradient(100deg, #ffffff 0%, rgba(255, 255, 255, 0.35) 14%, #fff7e6 28%, #ffd23f 40%, #2f6df6 52%, #ff4d1f 64%, #ffffff 80%, rgba(255, 255, 255, 0.4) 100%);
background-size: 240% 100%;
-webkit-background-clip: text;
background-clip: text;
color: transparent;
animation: chromeFlow 2s ease-out infinite;
}
.hero-c__cta {
position: relative;
z-index: 1;
align-self: flex-start;
border: 0;
border-radius: 999px;
background: linear-gradient(100deg, #fff7e6, #ffffff, #fff7e6);
color: #17141a;
padding: 8px 20px;
font-weight: 700;
font-size: clamp(11px, 2.6vw, 13px);
line-height: 1;
font-family: inherit;
}
@keyframes chromeFlow {
0% {
background-position: 0% 50%;
}
100% {
background-position: 240% 50%;
}
}
@media (prefers-reduced-motion: reduce) {
.hero-c__title {
animation: none;
}
}import type { CSSProperties } from "react";
import styles from "./HeroChrome.module.scss";
export type HeroChromeProps = {
eyebrow?: string;
title?: string;
cta?: string;
/** 한 주기(기본 2000ms) */
duration?: number;
easing?: string;
color?: string;
};
type Vars = CSSProperties & { "--duration"?: string; "--easing"?: string; "--color"?: string };
export default function HeroChrome({
eyebrow = "CHROME",
title = "The first screen, shining again",
cta = "Start for free",
duration = 2000,
easing = "ease-out",
color = "#2f6df6",
}: HeroChromeProps) {
const vars: Vars = { "--duration": `${duration}ms`, "--easing": easing, "--color": color };
return (
<section className={styles.hero} style={vars}>
<p className={styles.eyebrow}>{eyebrow}</p>
<h2 className={styles.title}>{title}</h2>
<button type="button" className={styles.cta}>{cta}</button>
</section>
);
}01 · Chrome headline hero — Measured area 1.539% · moving frames 23/23Original by GODRICH · SCSS and React ship in the zip · See the password
In the code
No text color is painted directly; the gradient is the only source of color.
.hero-c__title {
background: linear-gradient(100deg,
$stage-paper 0%, rgba($stage-paper, .35) 14%, $subject-cream 28%,
$stage-yellow 40%, $color 52%, $stage-orange 64%,
$stage-paper 80%, rgba($stage-paper, .4) 100%);
background-size: 240% 100%;
-webkit-background-clip: text;
background-clip: text;
color: transparent;
animation: chromeFlow $duration $easing infinite;
}
@keyframes chromeFlow {
0% { background-position: 0% 50%; }
100% { background-position: 240% 50%; }
}
02Brushed-metal nav
What moves
The bar's background alternates ink tones to fake a brushed-metal surface, and a single thin white streak crosses it left to right by animating left.

<main class="stage">
<nav class="nav-c">
<span class="nav-c__brand">Chroma</span>
<div class="nav-c__menu">
<span class="nav-c__label nav-c__label--active">Home</span>
<span class="nav-c__label">Features</span>
<span class="nav-c__label">Pricing</span>
</div>
<button class="nav-c__cta" type="button">Try it free</button>
</nav>
</main>@use "../../../../site/static/demo-tokens" as *;
$duration: $dur-loop;
$easing: linear;
$color: $subject-blue;
@include stage($stage-yellow);
.nav-c {
position: relative;
overflow: hidden;
box-sizing: border-box;
display: flex;
align-items: center;
gap: $sp-3;
width: clamp(240px, 84vw, 380px);
padding: $sp-2 $sp-3;
border-radius: $r-pill;
background: linear-gradient(100deg, rgba($stage-ink, .92) 0%, rgba($stage-ink, .78) 22%, rgba($stage-ink, .95) 40%, rgba($stage-ink, .8) 60%, rgba($stage-ink, .95) 100%);
}
// 브러시드 메탈 하이라이트 — 가는 빛줄기가 바 전체를 좌우로 훑는다 (이 항목의 유일한 애니메이션)
.nav-c::after {
content: "";
position: absolute;
top: 0;
left: -20%;
width: 14%;
height: 100%;
background: linear-gradient(90deg, transparent, rgba($stage-paper, .55), transparent);
animation: glint $duration $easing infinite;
}
.nav-c__brand {
position: relative;
z-index: 1;
flex-shrink: 0;
white-space: nowrap;
padding-left: $sp-2;
color: $stage-paper;
font-weight: 700;
font-size: clamp(12px, 3vw, 14px);
line-height: 1;
font-family: -apple-system, "Segoe UI", "Noto Sans KR", sans-serif;
}
.nav-c__menu { position: relative; z-index: 1; min-width: 0; flex: 1; display: flex; }
.nav-c__label {
flex: 1;
white-space: nowrap;
text-align: center;
padding: $sp-2 0;
color: rgba($stage-paper, .8);
font-weight: 600;
font-size: clamp(10.5px, 2.6vw, 12px);
line-height: 1;
font-family: inherit;
}
.nav-c__label--active { color: $stage-paper; border-radius: $r-pill; background: rgba($stage-paper, .12); }
.nav-c__cta {
position: relative;
z-index: 1;
flex-shrink: 0;
white-space: nowrap;
border: 0;
border-radius: $r-pill;
background: $stage-paper;
color: $stage-ink;
padding: $sp-2 $sp-4;
font-weight: 700;
font-size: clamp(10.5px, 2.6vw, 12px);
line-height: 1;
font-family: inherit;
}
@keyframes glint { 0% { left: -20%; } 100% { left: 106%; } }
@media (prefers-reduced-motion: reduce) {
.nav-c::after { animation: none; opacity: 0; }
}html, body {
margin: 0;
overflow: hidden;
}
.stage {
box-sizing: border-box;
min-height: 100vh;
display: grid;
place-items: center;
margin: 0;
background: #ffd23f;
font-family: -apple-system, "Segoe UI", "Noto Sans KR", sans-serif;
padding: clamp(8px, 4vw, 24px);
}
.nav-c {
position: relative;
overflow: hidden;
box-sizing: border-box;
display: flex;
align-items: center;
gap: 12px;
width: clamp(240px, 84vw, 380px);
padding: 8px 12px;
border-radius: 999px;
background: linear-gradient(100deg, rgba(23, 20, 26, 0.92) 0%, rgba(23, 20, 26, 0.78) 22%, rgba(23, 20, 26, 0.95) 40%, rgba(23, 20, 26, 0.8) 60%, rgba(23, 20, 26, 0.95) 100%);
}
.nav-c::after {
content: "";
position: absolute;
top: 0;
left: -20%;
width: 14%;
height: 100%;
background: linear-gradient(90deg, transparent, rgba(255, 255, 255, 0.55), transparent);
animation: glint 2s linear infinite;
}
.nav-c__brand {
position: relative;
z-index: 1;
flex-shrink: 0;
white-space: nowrap;
padding-left: 8px;
color: #ffffff;
font-weight: 700;
font-size: clamp(12px, 3vw, 14px);
line-height: 1;
font-family: -apple-system, "Segoe UI", "Noto Sans KR", sans-serif;
}
.nav-c__menu {
position: relative;
z-index: 1;
min-width: 0;
flex: 1;
display: flex;
}
.nav-c__label {
flex: 1;
white-space: nowrap;
text-align: center;
padding: 8px 0;
color: rgba(255, 255, 255, 0.8);
font-weight: 600;
font-size: clamp(10.5px, 2.6vw, 12px);
line-height: 1;
font-family: inherit;
}
.nav-c__label--active {
color: #ffffff;
border-radius: 999px;
background: rgba(255, 255, 255, 0.12);
}
.nav-c__cta {
position: relative;
z-index: 1;
flex-shrink: 0;
white-space: nowrap;
border: 0;
border-radius: 999px;
background: #ffffff;
color: #17141a;
padding: 8px 16px;
font-weight: 700;
font-size: clamp(10.5px, 2.6vw, 12px);
line-height: 1;
font-family: inherit;
}
@keyframes glint {
0% {
left: -20%;
}
100% {
left: 106%;
}
}
@media (prefers-reduced-motion: reduce) {
.nav-c::after {
animation: none;
opacity: 0;
}
}import type { CSSProperties } from "react";
import styles from "./NavChrome.module.scss";
export type NavChromeProps = {
brand?: string;
links?: string[];
activeIndex?: number;
cta?: string;
/** 한 주기(기본 2000ms) */
duration?: number;
easing?: string;
color?: string;
};
type Vars = CSSProperties & { "--duration"?: string; "--easing"?: string; "--color"?: string };
export default function NavChrome({
brand = "Chroma",
links = ["Home", "Features", "Pricing"],
activeIndex = 0,
cta = "Try it free",
duration = 2000,
easing = "linear",
color = "#2f6df6",
}: NavChromeProps) {
const vars: Vars = { "--duration": `${duration}ms`, "--easing": easing, "--color": color };
return (
<nav className={styles.nav} style={vars}>
<span className={styles.brand}>{brand}</span>
<div className={styles.menu}>
{links.map((label, i) => (
<span key={label} className={i === activeIndex ? `${styles.label} ${styles.labelActive}` : styles.label}>
{label}
</span>
))}
</div>
<button type="button" className={styles.cta}>{cta}</button>
</nav>
);
}02 · Brushed-metal nav — Measured area 9.886% · moving frames 22/23Original by GODRICH · SCSS and React ship in the zip · See the password
In the code
The active link only gets a paler patch behind it — it doesn't move on its own.
.nav-c::after {
content: "";
position: absolute;
top: 0; left: -20%; width: 14%; height: 100%;
background: linear-gradient(90deg, transparent, rgba($stage-paper, .55), transparent);
animation: glint $duration linear infinite;
}
@keyframes glint { 0% { left: -20%; } 100% { left: 106%; } }
03Holographic foil cards
What moves
A diagonal foil band sits on top of the card surface with mix-blend-mode: overlay and slides across it as background-position shifts.

<main class="stage">
<article class="card-c">
<span class="card-c__icon" aria-hidden="true"></span>
<h3 class="card-c__title">Live preview</h3>
<p class="card-c__desc">Every change reflects on screen instantly.</p>
</article>
</main>@use "../../../../site/static/demo-tokens" as *;
$duration: $dur-loop;
$easing: linear;
$color: $subject-blue;
@include stage($stage-orange);
.stage { padding: clamp(8px, 3vw, 20px); }
.card-c {
position: relative;
overflow: hidden;
box-sizing: border-box;
width: min(240px, 78vw);
border-radius: $r-card;
background: $stage-ink;
box-shadow: $shadow-raised;
padding: $sp-5;
display: flex;
flex-direction: column;
gap: $sp-2;
}
// 홀로그램 포일 띠 — mix-blend-mode 로 카드 표면 위에 얹혀 대각선으로 한 바퀴씩 지나간다 (유일한 애니메이션)
.card-c::after {
content: "";
position: absolute;
inset: -30% -10%;
pointer-events: none;
mix-blend-mode: overlay;
opacity: .8;
background: repeating-linear-gradient(115deg,
transparent 0 18px,
rgba($color, .55) 18px 30px,
rgba($stage-yellow, .55) 30px 42px,
rgba($subject-cream, .6) 42px 54px,
transparent 54px 72px);
background-size: 200% 200%;
animation: foilSweep $duration $easing infinite;
}
.card-c__icon { position: relative; z-index: 1; width: $sp-8; height: $sp-8; border-radius: $r-sm; background: radial-gradient(circle at 30% 30%, $subject-cream, $color 55%, $stage-ink 100%); }
.card-c__title {
position: relative;
z-index: 1;
margin: 0;
color: $stage-paper;
font-weight: 700;
font-size: clamp(13px, 3.2vw, 15px);
line-height: 1.3;
font-family: -apple-system, "Segoe UI", "Noto Sans KR", sans-serif;
}
.card-c__desc {
position: relative;
z-index: 1;
margin: 0;
color: rgba($stage-paper, .7);
font-weight: 500;
font-size: clamp(11px, 2.6vw, 12.5px);
line-height: 1.4;
font-family: inherit;
}
@keyframes foilSweep { 0% { background-position: 0% 0%; } 100% { background-position: -140% -140%; } }
@media (prefers-reduced-motion: reduce) {
.card-c::after { animation: none; }
}html, body {
margin: 0;
overflow: hidden;
}
.stage {
box-sizing: border-box;
min-height: 100vh;
display: grid;
place-items: center;
margin: 0;
background: #ff4d1f;
font-family: -apple-system, "Segoe UI", "Noto Sans KR", sans-serif;
padding: clamp(8px, 4vw, 24px);
}
.stage {
padding: clamp(8px, 3vw, 20px);
}
.card-c {
position: relative;
overflow: hidden;
box-sizing: border-box;
width: min(240px, 78vw);
border-radius: 16px;
background: #17141a;
box-shadow: 0 14px 24px rgba(23, 20, 26, 0.32);
padding: 20px;
display: flex;
flex-direction: column;
gap: 8px;
}
.card-c::after {
content: "";
position: absolute;
inset: -30% -10%;
pointer-events: none;
mix-blend-mode: overlay;
opacity: 0.8;
background: repeating-linear-gradient(115deg, transparent 0 18px, rgba(47, 109, 246, 0.55) 18px 30px, rgba(255, 210, 63, 0.55) 30px 42px, rgba(255, 247, 230, 0.6) 42px 54px, transparent 54px 72px);
background-size: 200% 200%;
animation: foilSweep 2s linear infinite;
}
.card-c__icon {
position: relative;
z-index: 1;
width: 32px;
height: 32px;
border-radius: 8px;
background: radial-gradient(circle at 30% 30%, #fff7e6, #2f6df6 55%, #17141a 100%);
}
.card-c__title {
position: relative;
z-index: 1;
margin: 0;
color: #ffffff;
font-weight: 700;
font-size: clamp(13px, 3.2vw, 15px);
line-height: 1.3;
font-family: -apple-system, "Segoe UI", "Noto Sans KR", sans-serif;
}
.card-c__desc {
position: relative;
z-index: 1;
margin: 0;
color: rgba(255, 255, 255, 0.7);
font-weight: 500;
font-size: clamp(11px, 2.6vw, 12.5px);
line-height: 1.4;
font-family: inherit;
}
@keyframes foilSweep {
0% {
background-position: 0% 0%;
}
100% {
background-position: -140% -140%;
}
}
@media (prefers-reduced-motion: reduce) {
.card-c::after {
animation: none;
}
}import type { CSSProperties } from "react";
import styles from "./CardGridChrome.module.scss";
export type CardGridChromeProps = {
title?: string;
desc?: string;
/** 한 주기(기본 2000ms) */
duration?: number;
easing?: string;
color?: string;
};
type Vars = CSSProperties & { "--duration"?: string; "--easing"?: string; "--color"?: string };
export default function CardGridChrome({
title = "Live preview",
desc = "Every change reflects on screen instantly.",
duration = 2000,
easing = "linear",
color = "#2f6df6",
}: CardGridChromeProps) {
const vars: Vars = { "--duration": `${duration}ms`, "--easing": easing, "--color": color };
return (
<article className={styles.card} style={vars}>
<span className={styles.icon} aria-hidden="true" />
<h3 className={styles.title}>{title}</h3>
<p className={styles.desc}>{desc}</p>
</article>
);
}03 · Holographic foil cards — Measured area 10.607% · moving frames 23/23Original by GODRICH · SCSS and React ship in the zip · See the password
In the code
It's built to mimic the rainbow flash you get from tilting a real holo sticker — the card itself stays a fixed dark ink so the reflection reads clearly against it.
.card-c::after {
content: "";
position: absolute;
inset: -30% -10%;
pointer-events: none;
mix-blend-mode: overlay;
opacity: .8;
background: repeating-linear-gradient(115deg,
transparent 0 18px,
rgba($color, .55) 18px 30px,
rgba($stage-yellow, .55) 30px 42px,
rgba($subject-cream, .6) 42px 54px,
transparent 54px 72px);
background-size: 200% 200%;
animation: foilSweep $duration linear infinite;
}
04Chrome ball icons
What moves
Each icon badge is a radial-gradient sphere with its highlight fixed toward the upper-left, like light hitting a small chrome ball.

<main class="stage">
<ul class="feat-c">
<li class="feat-c__row">
<span class="feat-c__icon" aria-hidden="true"></span>
<p class="feat-c__text">One-click deploy</p>
</li>
<li class="feat-c__row">
<span class="feat-c__icon" aria-hidden="true"></span>
<p class="feat-c__text">Auto save</p>
</li>
<li class="feat-c__row">
<span class="feat-c__icon" aria-hidden="true"></span>
<p class="feat-c__text">Live co-editing</p>
</li>
</ul>
</main>@use "../../../../site/static/demo-tokens" as *;
$duration: $dur-loop;
$easing: steps(8, jump-none); // 부드러운 곡선은 프레임 간 변화가 너무 작아 강도 측정에 안 잡힌다
$color: $subject-blue;
@include stage($stage-paper);
.feat-c {
margin: 0;
list-style: none;
box-sizing: border-box;
display: flex;
flex-direction: column;
gap: $sp-3;
width: clamp(240px, 80vw, 360px);
padding: $sp-5;
border-radius: $r-card;
background: $stage-ink;
box-shadow: $shadow-raised;
}
.feat-c__row { margin: 0; display: flex; align-items: center; gap: $sp-3; }
// 크롬 구슬 — radial-gradient 하이라이트의 위치만 천천히 옮겨 광원이 표면을 도는 느낌을 낸다 (유일한 애니메이션)
.feat-c__icon {
flex: none;
width: $sp-8;
height: $sp-8;
border-radius: $r-pill;
background: radial-gradient(circle at 30% 30%, $stage-paper, $color 40%, $stage-ink 82%);
background-size: 280% 280%;
animation: ballShine $duration $easing infinite;
}
.feat-c__text {
margin: 0;
color: $stage-paper;
font-weight: 600;
font-size: clamp(11.5px, 2.8vw, 13px);
line-height: 1.4;
font-family: -apple-system, "Segoe UI", "Noto Sans KR", sans-serif;
}
@keyframes ballShine { 0% { background-position: 0% 0%; } 100% { background-position: 180% 180%; } }
@media (prefers-reduced-motion: reduce) {
.feat-c__icon { animation: none; }
}html, body {
margin: 0;
overflow: hidden;
}
.stage {
box-sizing: border-box;
min-height: 100vh;
display: grid;
place-items: center;
margin: 0;
background: #ffffff;
font-family: -apple-system, "Segoe UI", "Noto Sans KR", sans-serif;
padding: clamp(8px, 4vw, 24px);
}
.feat-c {
margin: 0;
list-style: none;
box-sizing: border-box;
display: flex;
flex-direction: column;
gap: 12px;
width: clamp(240px, 80vw, 360px);
padding: 20px;
border-radius: 16px;
background: #17141a;
box-shadow: 0 14px 24px rgba(23, 20, 26, 0.32);
}
.feat-c__row {
margin: 0;
display: flex;
align-items: center;
gap: 12px;
}
.feat-c__icon {
flex: none;
width: 32px;
height: 32px;
border-radius: 999px;
background: radial-gradient(circle at 30% 30%, #ffffff, #2f6df6 40%, #17141a 82%);
background-size: 280% 280%;
animation: ballShine 2s steps(8, jump-none) infinite;
}
.feat-c__text {
margin: 0;
color: #ffffff;
font-weight: 600;
font-size: clamp(11.5px, 2.8vw, 13px);
line-height: 1.4;
font-family: -apple-system, "Segoe UI", "Noto Sans KR", sans-serif;
}
@keyframes ballShine {
0% {
background-position: 0% 0%;
}
100% {
background-position: 180% 180%;
}
}
@media (prefers-reduced-motion: reduce) {
.feat-c__icon {
animation: none;
}
}import type { CSSProperties } from "react";
import styles from "./FeatureListChrome.module.scss";
export type FeatureListChromeProps = {
items?: string[];
/** 한 주기(기본 2000ms) */
duration?: number;
easing?: string;
color?: string;
};
type Vars = CSSProperties & { "--duration"?: string; "--easing"?: string; "--color"?: string };
export default function FeatureListChrome({
items = ["One-click deploy", "Auto save", "Live co-editing"],
duration = 2000,
easing = "steps(8, jump-none)",
color = "#2f6df6",
}: FeatureListChromeProps) {
const vars: Vars = { "--duration": `${duration}ms`, "--easing": easing, "--color": color };
return (
<ul className={styles.list} style={vars}>
{items.map((text) => (
<li key={text} className={styles.row}>
<span className={styles.icon} aria-hidden="true" />
<p className={styles.text}>{text}</p>
</li>
))}
</ul>
);
}04 · Chrome ball icons — Measured area 1.75% · moving frames 7/23Original by GODRICH · SCSS and React ship in the zip · See the password
In the code
Only that highlight's position drifts, and all three icons share one keyframes rule.
.feat-c__icon {
background: radial-gradient(circle at 30% 30%, $stage-paper, $color 40%, $stage-ink 82%);
background-size: 280% 280%;
animation: ballShine $duration steps(8, jump-none) infinite;
}
@keyframes ballShine {
0% { background-position: 0% 0%; }
100% { background-position: 180% 180%; }
}
05Holographic highlighted plan
What moves
Only the recommended plan carries a five-stop gradient background that drifts across via background-position, making the pitch obvious without needing a comparison table.

<main class="stage">
<section class="pricing-c">
<div class="pricing-c__plan">
<p class="pricing-c__name">Free</p>
<p class="pricing-c__price">₩0</p>
</div>
<div class="pricing-c__plan pricing-c__plan--pro">
<span class="pricing-c__badge">Recommended</span>
<p class="pricing-c__name">Pro</p>
<p class="pricing-c__price">$15/mo</p>
</div>
</section>
</main>@use "../../../../site/static/demo-tokens" as *;
$duration: $dur-loop;
$easing: linear;
$color: $subject-blue;
@include stage($stage-ink);
.pricing-c { display: flex; align-items: flex-end; gap: $sp-4; width: clamp(240px, 82vw, 380px); }
.pricing-c__plan {
flex: 1;
border-radius: $r-card;
padding: $sp-5 $sp-4;
background: rgba($stage-paper, .06);
border: 1px solid rgba($stage-paper, .12);
}
.pricing-c__plan--pro {
position: relative;
overflow: hidden;
flex: 1.15;
padding-top: $sp-8;
box-shadow: $shadow-raised;
}
// 추천 플랜만 다색 홀로그램 그라디언트가 배경 위치를 흐르며 이동한다 (유일한 애니메이션). 무료 플랜은 무광 회색 그대로
.pricing-c__plan--pro::before {
content: "";
position: absolute;
inset: 0;
background: linear-gradient(100deg, $color, $stage-yellow, $stage-orange, $subject-cream, $color);
background-size: 320% 100%;
animation: holoShift $duration $easing infinite;
}
.pricing-c__badge {
position: relative;
z-index: 1;
display: inline-block;
margin-bottom: $sp-2;
border-radius: $r-pill;
background: rgba($stage-ink, .4);
color: $stage-paper;
padding: $sp-1 $sp-3;
font-weight: 700;
font-size: clamp(9.5px, 2.2vw, 11px);
line-height: 1;
font-family: -apple-system, "Segoe UI", "Noto Sans KR", sans-serif;
}
.pricing-c__name {
position: relative;
z-index: 1;
margin: 0 0 $sp-1;
color: $stage-paper;
font-weight: 700;
font-size: clamp(12px, 3vw, 14px);
line-height: 1.3;
font-family: -apple-system, "Segoe UI", "Noto Sans KR", sans-serif;
}
.pricing-c__price {
position: relative;
z-index: 1;
margin: 0;
color: rgba($stage-paper, .75);
font-weight: 600;
font-size: clamp(11px, 2.6vw, 12.5px);
line-height: 1.3;
font-family: inherit;
}
.pricing-c__plan--pro .pricing-c__name { color: $stage-ink; }
.pricing-c__plan--pro .pricing-c__price { color: rgba($stage-ink, .8); }
@keyframes holoShift { 0% { background-position: 0% 50%; } 100% { background-position: 320% 50%; } }
@media (prefers-reduced-motion: reduce) {
.pricing-c__plan--pro::before { animation: none; }
}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);
}
.pricing-c {
display: flex;
align-items: flex-end;
gap: 16px;
width: clamp(240px, 82vw, 380px);
}
.pricing-c__plan {
flex: 1;
border-radius: 16px;
padding: 20px 16px;
background: rgba(255, 255, 255, 0.06);
border: 1px solid rgba(255, 255, 255, 0.12);
}
.pricing-c__plan--pro {
position: relative;
overflow: hidden;
flex: 1.15;
padding-top: 32px;
box-shadow: 0 14px 24px rgba(23, 20, 26, 0.32);
}
.pricing-c__plan--pro::before {
content: "";
position: absolute;
inset: 0;
background: linear-gradient(100deg, #2f6df6, #ffd23f, #ff4d1f, #fff7e6, #2f6df6);
background-size: 320% 100%;
animation: holoShift 2s linear infinite;
}
.pricing-c__badge {
position: relative;
z-index: 1;
display: inline-block;
margin-bottom: 8px;
border-radius: 999px;
background: rgba(23, 20, 26, 0.4);
color: #ffffff;
padding: 4px 12px;
font-weight: 700;
font-size: clamp(9.5px, 2.2vw, 11px);
line-height: 1;
font-family: -apple-system, "Segoe UI", "Noto Sans KR", sans-serif;
}
.pricing-c__name {
position: relative;
z-index: 1;
margin: 0 0 4px;
color: #ffffff;
font-weight: 700;
font-size: clamp(12px, 3vw, 14px);
line-height: 1.3;
font-family: -apple-system, "Segoe UI", "Noto Sans KR", sans-serif;
}
.pricing-c__price {
position: relative;
z-index: 1;
margin: 0;
color: rgba(255, 255, 255, 0.75);
font-weight: 600;
font-size: clamp(11px, 2.6vw, 12.5px);
line-height: 1.3;
font-family: inherit;
}
.pricing-c__plan--pro .pricing-c__name {
color: #17141a;
}
.pricing-c__plan--pro .pricing-c__price {
color: rgba(23, 20, 26, 0.8);
}
@keyframes holoShift {
0% {
background-position: 0% 50%;
}
100% {
background-position: 320% 50%;
}
}
@media (prefers-reduced-motion: reduce) {
.pricing-c__plan--pro::before {
animation: none;
}
}import type { CSSProperties } from "react";
import styles from "./PricingChrome.module.scss";
export type PricingChromeProps = {
freeName?: string;
freePrice?: string;
proName?: string;
proPrice?: string;
badge?: string;
/** 한 주기(기본 2000ms) */
duration?: number;
easing?: string;
color?: string;
};
type Vars = CSSProperties & { "--duration"?: string; "--easing"?: string; "--color"?: string };
export default function PricingChrome({
freeName = "Free",
freePrice = "$0",
proName = "Pro",
proPrice = "$15/mo",
badge = "Recommended",
duration = 2000,
easing = "linear",
color = "#2f6df6",
}: PricingChromeProps) {
const vars: Vars = { "--duration": `${duration}ms`, "--easing": easing, "--color": color };
return (
<section className={styles.pricing} style={vars}>
<div className={styles.plan}>
<p className={styles.name}>{freeName}</p>
<p className={styles.price}>{freePrice}</p>
</div>
<div className={`${styles.plan} ${styles.plaPro}`}>
<span className={styles.badge}>{badge}</span>
<p className={styles.name}>{proName}</p>
<p className={styles.price}>{proPrice}</p>
</div>
</section>
);
}05 · Holographic highlighted plan — Measured area 15.662% · moving frames 23/23Original by GODRICH · SCSS and React ship in the zip · See the password
In the code
The other plan stays flat, matte gray for contrast.
.pricing-c__plan--pro::before {
content: "";
position: absolute;
inset: 0;
background: linear-gradient(100deg, $color, $stage-yellow, $stage-orange, $subject-cream, $color);
background-size: 320% 100%;
animation: holoShift $duration linear infinite;
}
.pricing-c__plan--pro .pricing-c__name { color: $stage-ink; }
06CD-ring avatar quote
What moves
The avatar sits beside the quote card inside a conic-gradient ring that spins slowly, like the edge of a CD catching light.

<main class="stage">
<figure class="test-c">
<div class="test-c__avatar" aria-hidden="true">
<div class="test-c__avatar-fill"></div>
</div>
<blockquote class="test-c__card">
<p class="test-c__quote">"Our click-through rate doubled in launch week"</p>
<figcaption class="test-c__name">Jieun Park · Marketing Lead</figcaption>
</blockquote>
</figure>
</main>@use "../../../../site/static/demo-tokens" as *;
$duration: $dur-loop;
$easing: linear;
$color: $subject-blue;
@include stage($stage-yellow);
.test-c {
margin: 0;
position: relative;
box-sizing: border-box;
width: clamp(240px, 82vw, 360px);
padding: $sp-5;
display: flex;
flex-direction: row;
align-items: flex-start;
gap: $sp-3;
}
.test-c__avatar { position: relative; flex-shrink: 0; width: $sp-10; height: $sp-10; border-radius: 50%; }
// CD 테두리처럼 도는 conic-gradient 링 — mask 로 링 모양만 남기고 회전만 시킨다 (유일한 애니메이션)
.test-c__avatar::before {
content: "";
position: absolute;
inset: 0;
border-radius: 50%;
padding: $sp-1;
background: conic-gradient($color, $stage-orange, $subject-cream, $stage-ink, $color);
-webkit-mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
-webkit-mask-composite: xor;
mask-composite: exclude;
animation: cdSpin $duration $easing infinite;
}
.test-c__avatar-fill { position: absolute; inset: $sp-1; border-radius: 50%; background: $stage-ink; }
.test-c__card {
margin: 0;
min-width: 0;
position: relative;
border-radius: $r-card;
padding: $sp-5;
background: $stage-ink;
border: 1px solid rgba($stage-paper, .18);
outline: 1px solid rgba($subject-cream, .35);
outline-offset: -4px;
}
.test-c__quote {
margin: 0 0 $sp-3;
color: $stage-paper;
font-weight: 600;
font-size: clamp(12px, 3vw, 13.5px);
line-height: 1.5;
font-family: -apple-system, "Segoe UI", "Noto Sans KR", sans-serif;
}
.test-c__name {
margin: 0;
color: rgba($stage-paper, .7);
font-weight: 600;
font-size: clamp(10.5px, 2.4vw, 11.5px);
line-height: 1.3;
font-family: inherit;
}
@keyframes cdSpin { to { transform: rotate(360deg); } }
@media (prefers-reduced-motion: reduce) {
.test-c__avatar::before { animation: none; }
}html, body {
margin: 0;
overflow: hidden;
}
.stage {
box-sizing: border-box;
min-height: 100vh;
display: grid;
place-items: center;
margin: 0;
background: #ffd23f;
font-family: -apple-system, "Segoe UI", "Noto Sans KR", sans-serif;
padding: clamp(8px, 4vw, 24px);
}
.test-c {
margin: 0;
position: relative;
box-sizing: border-box;
width: clamp(240px, 82vw, 360px);
padding: 20px;
display: flex;
flex-direction: row;
align-items: flex-start;
gap: 12px;
}
.test-c__avatar {
position: relative;
flex-shrink: 0;
width: 40px;
height: 40px;
border-radius: 50%;
}
.test-c__avatar::before {
content: "";
position: absolute;
inset: 0;
border-radius: 50%;
padding: 4px;
background: conic-gradient(#2f6df6, #ff4d1f, #fff7e6, #17141a, #2f6df6);
-webkit-mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
-webkit-mask-composite: xor;
mask-composite: exclude;
animation: cdSpin 2s linear infinite;
}
.test-c__avatar-fill {
position: absolute;
inset: 4px;
border-radius: 50%;
background: #17141a;
}
.test-c__card {
margin: 0;
min-width: 0;
position: relative;
border-radius: 16px;
padding: 20px;
background: #17141a;
border: 1px solid rgba(255, 255, 255, 0.18);
outline: 1px solid rgba(255, 247, 230, 0.35);
outline-offset: -4px;
}
.test-c__quote {
margin: 0 0 12px;
color: #ffffff;
font-weight: 600;
font-size: clamp(12px, 3vw, 13.5px);
line-height: 1.5;
font-family: -apple-system, "Segoe UI", "Noto Sans KR", sans-serif;
}
.test-c__name {
margin: 0;
color: rgba(255, 255, 255, 0.7);
font-weight: 600;
font-size: clamp(10.5px, 2.4vw, 11.5px);
line-height: 1.3;
font-family: inherit;
}
@keyframes cdSpin {
to {
transform: rotate(360deg);
}
}
@media (prefers-reduced-motion: reduce) {
.test-c__avatar::before {
animation: none;
}
}import type { CSSProperties } from "react";
import styles from "./TestimonialChrome.module.scss";
export type TestimonialChromeProps = {
quote?: string;
name?: string;
/** 한 주기(기본 2000ms) */
duration?: number;
easing?: string;
color?: string;
};
type Vars = CSSProperties & { "--duration"?: string; "--easing"?: string; "--color"?: string };
export default function TestimonialChrome({
quote = "Our click-through rate doubled in launch week.",
name = "Jieun Park · Marketing Lead",
duration = 2000,
easing = "linear",
color = "#2f6df6",
}: TestimonialChromeProps) {
const vars: Vars = { "--duration": `${duration}ms`, "--easing": easing, "--color": color };
return (
<figure className={styles.test} style={vars}>
<div className={styles.avatar} aria-hidden="true">
<div className={styles.avatarFill} />
</div>
<blockquote className={styles.card}>
<p className={styles.quote}>“{quote}”</p>
<figcaption className={styles.name}>{name}</figcaption>
</blockquote>
</figure>
);
}06 · CD-ring avatar quote — Measured area 0.397% · moving frames 23/23Original by GODRICH · SCSS and React ship in the zip · See the password
In the code
A mask cuts the gradient down to a thin donut so only the ring itself is visible.
.test-c__avatar::before {
content: "";
position: absolute;
inset: 0;
border-radius: 50%;
padding: 3px;
background: conic-gradient($color, $stage-orange, $subject-cream, $stage-ink, $color);
-webkit-mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
mask-composite: exclude;
animation: cdSpin $duration linear infinite;
}
@keyframes cdSpin { to { transform: rotate(360deg); } }
07Brushed-aluminum CTA band
What moves
Two sets of translucent cream-and-white diagonal stripes drift across the full-width band via background-position, standing in for light catching brushed aluminum as it passes.

<main class="stage">
<section class="cta-c">
<h3 class="cta-c__title">Switch your screen today</h3>
<button class="cta-c__btn" type="button">Start for free</button>
</section>
</main>@use "../../../../site/static/demo-tokens" as *;
$duration: $dur-loop;
$easing: linear;
$color: $subject-cream;
@include stage($stage-orange);
.stage { padding: clamp(8px, 4vw, 24px); }
.cta-c {
position: relative;
overflow: hidden;
box-sizing: border-box;
width: clamp(260px, 90vw, 420px);
border-radius: $r-card;
padding: $sp-8 $sp-6;
background: $stage-ink;
}
// 브러시드 알루미늄 — 대각선 빛줄기 두 가닥이 천천히 흘러간다 (유일한 애니메이션)
.cta-c::before {
content: "";
position: absolute;
inset: 0;
background: repeating-linear-gradient(115deg,
rgba($stage-ink, 0) 0 60px,
rgba($color, .28) 60px 70px,
rgba($stage-ink, 0) 70px 160px,
rgba($stage-paper, .22) 160px 172px,
rgba($stage-ink, 0) 172px 260px);
background-size: 220% 100%;
animation: bandSweep $duration $easing infinite;
}
.cta-c__title {
position: relative;
z-index: 1;
margin: 0 0 $sp-4;
color: $stage-paper;
font-weight: 700;
font-size: clamp(16px, 4vw, 20px);
line-height: 1.3;
font-family: -apple-system, "Segoe UI", "Noto Sans KR", sans-serif;
}
.cta-c__btn {
position: relative;
z-index: 1;
border: 0;
border-radius: $r-pill;
background: linear-gradient(100deg, $color, $stage-paper, $color);
color: $stage-ink;
padding: $sp-2 $sp-6;
font-weight: 700;
font-size: clamp(11px, 2.6vw, 13px);
line-height: 1;
font-family: inherit;
}
@keyframes bandSweep { 0% { background-position: 0% 50%; } 100% { background-position: -220% 50%; } }
@media (prefers-reduced-motion: reduce) {
.cta-c::before { animation: none; }
}html, body {
margin: 0;
overflow: hidden;
}
.stage {
box-sizing: border-box;
min-height: 100vh;
display: grid;
place-items: center;
margin: 0;
background: #ff4d1f;
font-family: -apple-system, "Segoe UI", "Noto Sans KR", sans-serif;
padding: clamp(8px, 4vw, 24px);
}
.stage {
padding: clamp(8px, 4vw, 24px);
}
.cta-c {
position: relative;
overflow: hidden;
box-sizing: border-box;
width: clamp(260px, 90vw, 420px);
border-radius: 16px;
padding: 32px 24px;
background: #17141a;
}
.cta-c::before {
content: "";
position: absolute;
inset: 0;
background: repeating-linear-gradient(115deg, rgba(23, 20, 26, 0) 0 60px, rgba(255, 247, 230, 0.28) 60px 70px, rgba(23, 20, 26, 0) 70px 160px, rgba(255, 255, 255, 0.22) 160px 172px, rgba(23, 20, 26, 0) 172px 260px);
background-size: 220% 100%;
animation: bandSweep 2s linear infinite;
}
.cta-c__title {
position: relative;
z-index: 1;
margin: 0 0 16px;
color: #ffffff;
font-weight: 700;
font-size: clamp(16px, 4vw, 20px);
line-height: 1.3;
font-family: -apple-system, "Segoe UI", "Noto Sans KR", sans-serif;
}
.cta-c__btn {
position: relative;
z-index: 1;
border: 0;
border-radius: 999px;
background: linear-gradient(100deg, #fff7e6, #ffffff, #fff7e6);
color: #17141a;
padding: 8px 24px;
font-weight: 700;
font-size: clamp(11px, 2.6vw, 13px);
line-height: 1;
font-family: inherit;
}
@keyframes bandSweep {
0% {
background-position: 0% 50%;
}
100% {
background-position: -220% 50%;
}
}
@media (prefers-reduced-motion: reduce) {
.cta-c::before {
animation: none;
}
}import type { CSSProperties } from "react";
import styles from "./CtaBandChrome.module.scss";
export type CtaBandChromeProps = {
title?: string;
cta?: string;
/** 한 주기(기본 2000ms) */
duration?: number;
easing?: string;
color?: string;
};
type Vars = CSSProperties & { "--duration"?: string; "--easing"?: string; "--color"?: string };
export default function CtaBandChrome({
title = "Switch your screen today",
cta = "Start for free",
duration = 2000,
easing = "linear",
color = "#fff7e6",
}: CtaBandChromeProps) {
const vars: Vars = { "--duration": `${duration}ms`, "--easing": easing, "--color": color };
return (
<section className={styles.cta} style={vars}>
<h3 className={styles.title}>{title}</h3>
<button type="button" className={styles.btn}>{cta}</button>
</section>
);
}07 · Brushed-aluminum CTA band — Measured area 36.008% · moving frames 23/23Original by GODRICH · SCSS and React ship in the zip · See the password
In the code
Since the whole band is the moving subject, this section has the largest changed-pixel area in the set, at 36.01%.
.cta-c::before {
content: "";
position: absolute;
inset: 0;
background: repeating-linear-gradient(115deg,
rgba($stage-ink, 0) 0 60px,
rgba($color, .28) 60px 70px,
rgba($stage-ink, 0) 70px 160px,
rgba($stage-paper, .22) 160px 172px,
rgba($stage-ink, 0) 172px 260px);
background-size: 220% 100%;
animation: bandSweep $duration linear infinite;
}
08Holographic hairline footer
What moves
A 3px line traces the footer's top edge, carrying a four-color gradient that drifts through background-position.

<main class="stage">
<footer class="footer-c">
<div class="footer-c__col">
<p class="footer-c__label">Product</p>
<p class="footer-c__link">Pricing</p>
</div>
<div class="footer-c__col">
<p class="footer-c__label">Company</p>
<p class="footer-c__link">About the team</p>
</div>
</footer>
</main>@use "../../../../site/static/demo-tokens" as *;
$duration: $dur-loop;
$easing: linear;
$color: $subject-blue;
@include stage($stage-paper);
.footer-c {
position: relative;
box-sizing: border-box;
width: clamp(260px, 88vw, 400px);
border-radius: $r-card;
padding: $sp-6;
background: $stage-ink;
display: grid;
grid-template-columns: 1fr 1fr;
gap: $sp-4;
}
// 상단 경계의 홀로그램 실선 — 색이 자리를 옮기며 은은하게 반짝인다 (유일한 애니메이션)
.footer-c::before {
content: "";
position: absolute;
top: 0;
left: $sp-6;
right: $sp-6;
height: 3px;
border-radius: $r-pill;
background: linear-gradient(90deg, $color, $stage-yellow, $stage-orange, $subject-cream, $color);
background-size: 260% 100%;
animation: hairlineShift $duration $easing infinite;
}
.footer-c__col { position: relative; z-index: 1; border-radius: $r-sm; background: rgba($stage-paper, .05); padding: $sp-3; display: flex; flex-direction: column; gap: $sp-1; }
.footer-c__label {
margin: 0;
color: rgba($stage-paper, .5);
font-weight: 700;
font-size: clamp(9.5px, 2.2vw, 10.5px);
line-height: 1;
font-family: -apple-system, "Segoe UI", "Noto Sans KR", sans-serif;
text-transform: uppercase;
letter-spacing: .06em;
}
.footer-c__link {
margin: 0;
color: $stage-paper;
font-weight: 600;
font-size: clamp(11px, 2.6vw, 12px);
line-height: 1.4;
font-family: inherit;
}
@keyframes hairlineShift { 0% { background-position: 0% 50%; } 100% { background-position: 260% 50%; } }
@media (prefers-reduced-motion: reduce) {
.footer-c::before { animation: none; }
}html, body {
margin: 0;
overflow: hidden;
}
.stage {
box-sizing: border-box;
min-height: 100vh;
display: grid;
place-items: center;
margin: 0;
background: #ffffff;
font-family: -apple-system, "Segoe UI", "Noto Sans KR", sans-serif;
padding: clamp(8px, 4vw, 24px);
}
.footer-c {
position: relative;
box-sizing: border-box;
width: clamp(260px, 88vw, 400px);
border-radius: 16px;
padding: 24px;
background: #17141a;
display: grid;
grid-template-columns: 1fr 1fr;
gap: 16px;
}
.footer-c::before {
content: "";
position: absolute;
top: 0;
left: 24px;
right: 24px;
height: 3px;
border-radius: 999px;
background: linear-gradient(90deg, #2f6df6, #ffd23f, #ff4d1f, #fff7e6, #2f6df6);
background-size: 260% 100%;
animation: hairlineShift 2s linear infinite;
}
.footer-c__col {
position: relative;
z-index: 1;
border-radius: 8px;
background: rgba(255, 255, 255, 0.05);
padding: 12px;
display: flex;
flex-direction: column;
gap: 4px;
}
.footer-c__label {
margin: 0;
color: rgba(255, 255, 255, 0.5);
font-weight: 700;
font-size: clamp(9.5px, 2.2vw, 10.5px);
line-height: 1;
font-family: -apple-system, "Segoe UI", "Noto Sans KR", sans-serif;
text-transform: uppercase;
letter-spacing: 0.06em;
}
.footer-c__link {
margin: 0;
color: #ffffff;
font-weight: 600;
font-size: clamp(11px, 2.6vw, 12px);
line-height: 1.4;
font-family: inherit;
}
@keyframes hairlineShift {
0% {
background-position: 0% 50%;
}
100% {
background-position: 260% 50%;
}
}
@media (prefers-reduced-motion: reduce) {
.footer-c::before {
animation: none;
}
}import type { CSSProperties } from "react";
import styles from "./FooterChrome.module.scss";
export type FooterCol = { label: string; link: string };
export type FooterChromeProps = {
columns?: FooterCol[];
/** 한 주기(기본 2000ms) */
duration?: number;
easing?: string;
color?: string;
};
type Vars = CSSProperties & { "--duration"?: string; "--easing"?: string; "--color"?: string };
export default function FooterChrome({
columns = [
{ label: "Product", link: "Pricing" },
{ label: "Company", link: "About" },
],
duration = 2000,
easing = "linear",
color = "#2f6df6",
}: FooterChromeProps) {
const vars: Vars = { "--duration": `${duration}ms`, "--easing": easing, "--color": color };
return (
<footer className={styles.footer} style={vars}>
{columns.map((col) => (
<div key={col.label} className={styles.col}>
<p className={styles.label}>{col.label}</p>
<p className={styles.link}>{col.link}</p>
</div>
))}
</footer>
);
}08 · Holographic hairline footer — Measured area 0.733% · moving frames 23/23Original by GODRICH · SCSS and React ship in the zip · See the password
In the code
It's the thinnest moving element in the set — its changed area is only 0.73%, one of the smallest of the nine — but the color contrast is sharp enough to read as a clear shimmer.
.footer-c::before {
content: "";
position: absolute;
top: 0; left: $sp-6; right: $sp-6; height: 3px;
border-radius: $r-pill;
background: linear-gradient(90deg, $color, $stage-yellow, $stage-orange, $subject-cream, $color);
background-size: 260% 100%;
animation: hairlineShift $duration linear infinite;
}
09Chrome buttons, holographic focus
What moves
Pressing the button flips its top highlight down to the bottom, mimicking the way light slides off real metal under pressure.

<main class="stage">
<form class="bi-c is-demo">
<input class="bi-c__input" type="email" placeholder="Email address" readonly>
<button class="bi-c__btn" type="button">Sign up</button>
</form>
</main>@use "../../../../site/static/demo-tokens" as *;
$duration: $dur-loop;
$easing: $ease-out;
$color: $subject-cream;
@include stage($stage-ink);
.bi-c { display: flex; flex-direction: column; gap: $sp-4; width: clamp(220px, 78vw, 320px); }
.bi-c__input {
border: 0;
border-radius: $r-control;
padding: $sp-3 $sp-4;
background: rgba($stage-paper, .06);
color: $stage-paper;
font-weight: 500;
font-size: clamp(12px, 3vw, 13.5px);
line-height: 1.3;
font-family: -apple-system, "Segoe UI", "Noto Sans KR", sans-serif;
box-shadow: 0 0 0 2px rgba($subject-blue, .5), 0 0 16px rgba($stage-yellow, .4), 0 0 22px rgba($stage-orange, .3);
}
.bi-c__input::placeholder { color: rgba($stage-paper, .4); }
// 버튼 — 위에 있던 스펙큘러 하이라이트가 눌리면 아래로 뒤집힌다 (유일한 애니메이션, .is-demo 로 강제 발동)
.bi-c__btn {
position: relative;
overflow: hidden;
align-self: flex-start;
border: 0;
border-radius: $r-control;
padding: $sp-3 $sp-6;
color: $stage-ink;
font-weight: 700;
font-size: clamp(12px, 3vw, 13.5px);
line-height: 1;
font-family: inherit;
background: linear-gradient(180deg, $color, $stage-paper 55%, rgba($stage-paper, .85));
}
.bi-c__btn::after {
content: "";
position: absolute;
inset: 0;
background: linear-gradient(180deg, rgba($stage-paper, .9), transparent 55%);
}
.is-demo .bi-c__btn::after,
.bi-c__btn:hover::after,
.bi-c__btn:focus-visible::after {
animation: pressFlip $duration $easing infinite;
}
@keyframes pressFlip {
0%, 40% { transform: translateY(0); opacity: 1; }
50%, 60% { transform: translateY(100%); opacity: .7; }
70%, 100% { transform: translateY(0); opacity: 1; }
}
@media (prefers-reduced-motion: reduce) {
.is-demo .bi-c__btn::after, .bi-c__btn:hover::after, .bi-c__btn:focus-visible::after { animation: none; }
}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);
}
.bi-c {
display: flex;
flex-direction: column;
gap: 16px;
width: clamp(220px, 78vw, 320px);
}
.bi-c__input {
border: 0;
border-radius: 12px;
padding: 12px 16px;
background: rgba(255, 255, 255, 0.06);
color: #ffffff;
font-weight: 500;
font-size: clamp(12px, 3vw, 13.5px);
line-height: 1.3;
font-family: -apple-system, "Segoe UI", "Noto Sans KR", sans-serif;
box-shadow: 0 0 0 2px rgba(47, 109, 246, 0.5), 0 0 16px rgba(255, 210, 63, 0.4), 0 0 22px rgba(255, 77, 31, 0.3);
}
.bi-c__input::placeholder {
color: rgba(255, 255, 255, 0.4);
}
.bi-c__btn {
position: relative;
overflow: hidden;
align-self: flex-start;
border: 0;
border-radius: 12px;
padding: 12px 24px;
color: #17141a;
font-weight: 700;
font-size: clamp(12px, 3vw, 13.5px);
line-height: 1;
font-family: inherit;
background: linear-gradient(180deg, #fff7e6, #ffffff 55%, rgba(255, 255, 255, 0.85));
}
.bi-c__btn::after {
content: "";
position: absolute;
inset: 0;
background: linear-gradient(180deg, rgba(255, 255, 255, 0.9), transparent 55%);
}
.is-demo .bi-c__btn::after,
.bi-c__btn:hover::after,
.bi-c__btn:focus-visible::after {
animation: pressFlip 2s ease-out infinite;
}
@keyframes pressFlip {
0%, 40% {
transform: translateY(0);
opacity: 1;
}
50%, 60% {
transform: translateY(100%);
opacity: 0.7;
}
70%, 100% {
transform: translateY(0);
opacity: 1;
}
}
@media (prefers-reduced-motion: reduce) {
.is-demo .bi-c__btn::after, .bi-c__btn:hover::after, .bi-c__btn:focus-visible::after {
animation: none;
}
}import type { CSSProperties } from "react";
import styles from "./ButtonsInputsChrome.module.scss";
export type ButtonsInputsChromeProps = {
placeholder?: string;
cta?: string;
/** 한 주기(기본 2000ms) */
duration?: number;
easing?: string;
color?: string;
};
type Vars = CSSProperties & { "--duration"?: string; "--easing"?: string; "--color"?: string };
export default function ButtonsInputsChrome({
placeholder = "Email address",
cta = "Sign up",
duration = 2000,
easing = "ease-out",
color = "#fff7e6",
}: ButtonsInputsChromeProps) {
const vars: Vars = { "--duration": `${duration}ms`, "--easing": easing, "--color": color };
return (
<form className={styles.form} style={vars}>
<input className={styles.input} type="email" placeholder={placeholder} readOnly />
<button type="button" className={styles.btn}>{cta}</button>
</form>
);
}09 · Chrome buttons, holographic focus — Measured area 1.061% · moving frames 6/23Original by GODRICH · SCSS and React ship in the zip · See the password
In the code
The input doesn't animate at all — it just carries a constant three-color box-shadow glow in blue, yellow, and orange.
.bi-c__btn::after {
content: "";
position: absolute;
inset: 0;
background: linear-gradient(180deg, rgba($stage-paper, .9), transparent 55%);
}
.bi-c__btn:hover::after, .bi-c__btn:focus-visible::after {
animation: pressFlip $duration $ease-out infinite;
}
.bi-c__input {
box-shadow: 0 0 0 2px rgba($subject-blue, .5), 0 0 16px rgba($stage-yellow, .4), 0 0 22px rgba($stage-orange, .3);
}
Custom tailwind.config
One config file holds every color and radius the nine sections share, so retinting the palette here updates all of them at once — except for a single utility. backgroundImage.chrome repeats the same six hex values as literals instead of pulling from colors above, so changing a color there alone leaves that gradient stale. Update both spots together whenever the palette shifts.
theme: {
extend: {
colors: {
ink: "#17141a", cream: "#fff7e6", paper: "#ffffff",
blue: "#2f6df6", yellow: "#ffd23f", orange: "#ff4d1f",
},
borderRadius: { tile: "16px", control: "12px", pill: "999px" },
backgroundImage: {
chrome: "linear-gradient(100deg, #ffffff, #fff7e6, #ffd23f, #2f6df6, #ff4d1f, #ffffff)",
},
},
},
Vibe-coding prompt
Paste the config in first, and from then on a short fragment is enough for Claude Code or Cursor to pick up the style. The complete prompt sits inside prompt.md in the zip.
Clip headline text with background-clip: text and slide a six-stop
white-cream-yellow-blue-orange-white gradient across it with a
background-position animation only.
Layer holographic bands onto card surfaces with mix-blend-mode: overlay,
only on ink-dark cards.
On press, flip the button's highlight from top to bottom.
Running this fragment against page/index.html and capturing the full page at a 1280px viewport produced the screenshot below.

Where it breaks (the trap)
y2k style web design — where does it break?
Chrome and holographic effects measure as motionless if the curve is too smooth. Building section 04's chrome ball icon with ease-out swinging back and forth first, the render measurement came back with an intensity of 14.6 — just 0.4 under the 15 needed to pass. Switching the timing to an 8-step steps(8, jump-none) and widening the travel distance pushed intensity up to 96.2 — motion needs to land in visible jumps, not a smooth blur, to register as motion at all. Section 06's CD-ring avatar hit a different trap: stacking the avatar above the quote card vertically overflowed the 320px-wide viewport (the measurement flagged it directly). Placing them side by side instead brought it back under the viewport with no scrollbar. How much of a chrome gradient survives once it has been pasted into an email body is checked separately in Marketing Email Design. The zip bundling all nine sections and the full one-page source needs the password hxqy3hr4 to open, and the button below starts the download right away.
The last trap is restraint. Turning on gradient, spin, and glow on every section at once doesn't read as shiny — it reads as noisy. Keeping the chrome effect to one or two focal sections, with everything else left flat and matte, is what makes the shine stand out at all.
Accessibility
What we checked
Every animated section — the highlight flip on the section 09 button included — is wrapped in the prefers-reduced-motion media query, documented at MDN's prefers-reduced-motion page, so a visitor with reduced motion enabled only ever sees a static gradient. Section 06's mask-composite ring follows MDN's mask-composite documentation and keeps the older -webkit-mask-composite fallback alongside the standard value. Outside the hero's chrome headline itself, headline and button text always sit as a bright color on ink or ink on a bright surface, never directly on the moving gradient, so contrast doesn't drift while the colors do.
Where to go next
If chrome isn't the trend you're after, the rest of the set lives in the design trends category, and the about page explains what this site covers.
FAQ
Can css chrome text and holographic effects be built with CSS alone?
Yes. None of the nine sections here use a single line of JavaScript. Even the press response on the section 09 button runs entirely on :hover and :focus-visible; the only script involved forces the animation to play while capturing the demo for the gif and mp4.
Does chrome gradient text show up in every browser?
background-clip: text has broad support in current browsers, but pairing it with the -webkit-background-clip prefix still matters for older Safari and some mobile browsers. Check current coverage on caniuse, and set a plain color fallback so text stays visible even where the clip isn't supported.
Can the holographic card effect work on a light background?
The gradient itself still works on a light background, but the mix-blend-mode: overlay foil band here assumes a dark ink card underneath for contrast. On a light background, switching the blend mode to multiply or soft-light and lowering the band's opacity keeps the text from losing contrast. Testimonial cards built to sit on that lighter ground are collected in Testimonial Section Design.









