05유리 인레이 배지
브러시드 메탈 판에 박힌 유리 배지를 비스듬한 하이라이트 막대가 왼쪽에서 오른쪽으로 훑고, 유리 안 코어가 한 번 밝아집니다.
쓰임프리미엄 배지, 등급 표시, 제품 씰
하이라이트 훑기translateX 광선inset 깊이

<main class="stage">
<section class="glassbadge">
<div class="glassbadge__plate">
<p class="glassbadge__caption">정회원 배지</p>
<div class="glassbadge__inlay" role="img" aria-label="유리 배지">
<span class="glassbadge__core" 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="M232 128c0 12.51-17.82 21.95-22.68 33.69c-4.68 11.32 1.42 30.65-7.78 39.85s-28.53 3.1-39.85 7.78C150 214.18 140.5 232 128 232s-22-17.82-33.69-22.68c-11.32-4.68-30.65 1.42-39.85-7.78s-3.1-28.53-7.78-39.85C41.82 150 24 140.5 24 128s17.82-22 22.68-33.69c4.68-11.31-1.42-30.65 7.78-39.85s28.54-3.1 39.85-7.78C106.05 41.82 115.5 24 128 24s22 17.82 33.69 22.68c11.32 4.68 30.65-1.42 39.85 7.78s3.1 28.53 7.78 39.85C214.18 106.05 232 115.5 232 128" opacity=".2"/><path d="M225.86 102.82c-3.77-3.94-7.67-8-9.14-11.57c-1.36-3.27-1.44-8.69-1.52-13.94c-.15-9.76-.31-20.82-8-28.51s-18.75-7.85-28.51-8c-5.25-.08-10.67-.16-13.94-1.52c-3.56-1.47-7.63-5.37-11.57-9.14C146.28 23.51 138.44 16 128 16s-18.27 7.51-25.18 14.14c-3.94 3.77-8 7.67-11.57 9.14c-3.25 1.36-8.69 1.44-13.94 1.52c-9.76.15-20.82.31-28.51 8s-7.8 18.75-8 28.51c-.08 5.25-.16 10.67-1.52 13.94c-1.47 3.56-5.37 7.63-9.14 11.57C23.51 109.72 16 117.56 16 128s7.51 18.27 14.14 25.18c3.77 3.94 7.67 8 9.14 11.57c1.36 3.27 1.44 8.69 1.52 13.94c.15 9.76.31 20.82 8 28.51s18.75 7.85 28.51 8c5.25.08 10.67.16 13.94 1.52c3.56 1.47 7.63 5.37 11.57 9.14c6.9 6.63 14.74 14.14 25.18 14.14s18.27-7.51 25.18-14.14c3.94-3.77 8-7.67 11.57-9.14c3.27-1.36 8.69-1.44 13.94-1.52c9.76-.15 20.82-.31 28.51-8s7.85-18.75 8-28.51c.08-5.25.16-10.67 1.52-13.94c1.47-3.56 5.37-7.63 9.14-11.57c6.63-6.9 14.14-14.74 14.14-25.18s-7.51-18.27-14.14-25.18m-11.55 39.29c-4.79 5-9.75 10.17-12.38 16.52c-2.52 6.1-2.63 13.07-2.73 19.82c-.1 7-.21 14.33-3.32 17.43s-10.39 3.22-17.43 3.32c-6.75.1-13.72.21-19.82 2.73c-6.35 2.63-11.52 7.59-16.52 12.38S132 224 128 224s-9.15-4.92-14.11-9.69s-10.17-9.75-16.52-12.38c-6.1-2.52-13.07-2.63-19.82-2.73c-7-.1-14.33-.21-17.43-3.32s-3.22-10.39-3.32-17.43c-.1-6.75-.21-13.72-2.73-19.82c-2.63-6.35-7.59-11.52-12.38-16.52S32 132 32 128s4.92-9.15 9.69-14.11s9.75-10.17 12.38-16.52c2.52-6.1 2.63-13.07 2.73-19.82c.1-7 .21-14.33 3.32-17.43s10.39-3.22 17.43-3.32c6.75-.1 13.72-.21 19.82-2.73c6.35-2.63 11.52-7.59 16.52-12.38S124 32 128 32s9.15 4.92 14.11 9.69s10.17 9.75 16.52 12.38c6.1 2.52 13.07 2.63 19.82 2.73c7 .1 14.33.21 17.43 3.32s3.22 10.39 3.32 17.43c.1 6.75.21 13.72 2.73 19.82c2.63 6.35 7.59 11.52 12.38 16.52S224 124 224 128s-4.92 9.15-9.69 14.11m-40.65-43.77a8 8 0 0 1 0 11.32l-56 56a8 8 0 0 1-11.32 0l-24-24a8 8 0 0 1 11.32-11.32L112 148.69l50.34-50.35a8 8 0 0 1 11.32 0"/></g></svg>
</span>
<span class="glassbadge__sheen" aria-hidden="true"></span>
<span class="glassbadge__flare" aria-hidden="true"></span>
<span class="glassbadge__gloss" aria-hidden="true"></span>
</div>
</div>
<p class="glassbadge__note">한 달 이용자 한정</p>
</section>
</main>@use "../../../../site/static/demo-tokens" as *;
// 스큐어모픽 유리 인레이 — 브러시드 메탈 판에 파인 자리(inset)에 민트 코어를 박고 유리 광이 훑고 지나간다.
$brush-hi: #565b66; // 브러시 밝은 결
$brush-lo: #31353e; // 브러시 어두운 결
$inset-rim: #22252c; // 인레이 파인 테두리
$core: $subject-mint; // 유리 안 코어 (토큰)
$duration: $dur-loop; // 광선이 한 번 훑고 지나가는 주기
$easing: $ease-out; // 광선은 감속하며 지나간다
$color: $core;
@include stage($stage-ink);
.glassbadge {
display: flex;
flex-direction: column;
align-items: center;
gap: $sp-3;
}
// 브러시드 메탈 판 — 1px 결을 가로로 촘촘하게 깐다 (이미지 아님)
.glassbadge__plate {
box-sizing: border-box;
display: flex;
flex-direction: column;
align-items: center;
gap: $sp-2;
width: clamp(212px, 66vw, 300px);
padding: $sp-4;
border-radius: $r-card;
background:
repeating-linear-gradient(90deg, $brush-hi 0 1px, $brush-lo 1px 3px, $brush-hi 3px 4px, $inset-rim 4px 7px);
box-shadow: inset 0 1px 0 rgba(255, 255, 255, .14), inset 0 -2px 0 rgba(0, 0, 0, .5), 0 10px 16px rgba(0, 0, 0, .5);
}
.glassbadge__caption {
margin: 0;
color: #ffffff;
font-weight: 800; font-size: clamp(12px, 3vw, 15px); line-height: 1;
font-family: inherit;
letter-spacing: .08em;
}
// 유리 인레이 — 판보다 낮게 파인 자리. overflow 로 광선을 자른다
.glassbadge__inlay {
position: relative;
width: clamp(104px, 32vw, 140px);
aspect-ratio: 1;
border-radius: 50%;
overflow: hidden;
background: radial-gradient(130% 130% at 32% 26%, rgba(255, 255, 255, .3), transparent 46%), $inset-rim;
box-shadow: inset 0 4px 8px rgba(0, 0, 0, .75), inset 0 -2px 4px rgba(255, 255, 255, .12);
}
// 민트 코어 — 유리 안에서 한 단 낮게 떠 있는 인레이
.glassbadge__core {
position: absolute;
top: 16%; left: 16%; right: 16%; bottom: 16%;
display: grid;
place-items: center;
border-radius: 50%;
color: #0c2c20;
font-size: clamp(26px, 8vw, 36px);
background: radial-gradient(120% 120% at 34% 28%, #d6ebe2, $core 58%, #4fa183);
box-shadow: inset 0 -3px 6px rgba(0, 0, 0, .35), 0 2px 5px rgba(0, 0, 0, .55);
}
// 플레어 — 광선이 코어를 지나는 순간 코어가 한 번 밝아진다 (opacity 만)
.glassbadge__flare {
position: absolute;
top: 16%; left: 16%; right: 16%; bottom: 16%;
border-radius: 50%;
background: radial-gradient(120% 120% at 42% 34%, rgba(255, 255, 255, .55), transparent 64%);
opacity: 0;
animation: flareUp $duration $easing infinite;
}
// 광선 — 배지보다 길게 만들고 translateX 로 민다 (transform 이니 합성기가 처리한다)
.glassbadge__sheen {
position: absolute;
top: -20%; left: 0;
width: 44%;
height: 140%;
transform: translateX(-140%) rotate(24deg);
background: linear-gradient(100deg, transparent, rgba(255, 255, 255, .4) 45%, rgba(255, 255, 255, .55) 50%, rgba(255, 255, 255, .4) 55%, transparent);
animation: sheenSweep $duration $easing infinite;
}
// 유리 위쪽 고광 — 정적인 초승달
.glassbadge__gloss {
position: absolute;
top: 6%; left: 18%;
width: 64%;
height: 36%;
border-radius: 50%;
background: linear-gradient(180deg, rgba(255, 255, 255, .34), transparent 70%);
}
.glassbadge__note {
margin: 0;
color: rgba(255, 255, 255, .82);
font-weight: 500; font-size: clamp(11px, 2.8vw, 13px); line-height: 1;
font-family: inherit;
}
// 광선: 왼쪽 바깥에서 출발 → 중앙(코어 위) 을 지나 → 오른쪽 바깥으로. 처음과 끝이 같다
@keyframes sheenSweep {
0%, 12% { transform: translateX(-140%) rotate(24deg); }
82%, 100% { transform: translateX(340%) rotate(24deg); }
}
// 코어 플레어는 광선이 지나가는 40~52% 구간에만 잠깐 올랐다 진다 (유리를 통과하는 빛)
@keyframes flareUp {
0%, 36% { opacity: 0; }
44%, 50% { opacity: 1; }
58%, 100% { opacity: 0; }
}
@media (max-width: 340px), (max-height: 220px) {
.glassbadge__plate { padding: $sp-3; gap: $sp-1; }
.glassbadge__note { display: none; }
}
@media (prefers-reduced-motion: reduce) {
.glassbadge__sheen { animation: none !important; transform: translateX(120%) rotate(24deg); }
.glassbadge__flare { animation: none !important; opacity: 0; }
}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);
}
.glassbadge {
display: flex;
flex-direction: column;
align-items: center;
gap: 12px;
}
.glassbadge__plate {
box-sizing: border-box;
display: flex;
flex-direction: column;
align-items: center;
gap: 8px;
width: clamp(212px, 66vw, 300px);
padding: 16px;
border-radius: 16px;
background: repeating-linear-gradient(90deg, #565b66 0 1px, #31353e 1px 3px, #565b66 3px 4px, #22252c 4px 7px);
box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.14), inset 0 -2px 0 rgba(0, 0, 0, 0.5), 0 10px 16px rgba(0, 0, 0, 0.5);
}
.glassbadge__caption {
margin: 0;
color: #ffffff;
font-weight: 800;
font-size: clamp(12px, 3vw, 15px);
line-height: 1;
font-family: inherit;
letter-spacing: 0.08em;
}
.glassbadge__inlay {
position: relative;
width: clamp(104px, 32vw, 140px);
aspect-ratio: 1;
border-radius: 50%;
overflow: hidden;
background: radial-gradient(130% 130% at 32% 26%, rgba(255, 255, 255, 0.3), transparent 46%), #22252c;
box-shadow: inset 0 4px 8px rgba(0, 0, 0, 0.75), inset 0 -2px 4px rgba(255, 255, 255, 0.12);
}
.glassbadge__core {
position: absolute;
top: 16%;
left: 16%;
right: 16%;
bottom: 16%;
display: grid;
place-items: center;
border-radius: 50%;
color: #0c2c20;
font-size: clamp(26px, 8vw, 36px);
background: radial-gradient(120% 120% at 34% 28%, #d6ebe2, #4cd4a6 58%, #4fa183);
box-shadow: inset 0 -3px 6px rgba(0, 0, 0, 0.35), 0 2px 5px rgba(0, 0, 0, 0.55);
}
.glassbadge__flare {
position: absolute;
top: 16%;
left: 16%;
right: 16%;
bottom: 16%;
border-radius: 50%;
background: radial-gradient(120% 120% at 42% 34%, rgba(255, 255, 255, 0.55), transparent 64%);
opacity: 0;
animation: flareUp 2s ease-out infinite;
}
.glassbadge__sheen {
position: absolute;
top: -20%;
left: 0;
width: 44%;
height: 140%;
transform: translateX(-140%) rotate(24deg);
background: linear-gradient(100deg, transparent, rgba(255, 255, 255, 0.4) 45%, rgba(255, 255, 255, 0.55) 50%, rgba(255, 255, 255, 0.4) 55%, transparent);
animation: sheenSweep 2s ease-out infinite;
}
.glassbadge__gloss {
position: absolute;
top: 6%;
left: 18%;
width: 64%;
height: 36%;
border-radius: 50%;
background: linear-gradient(180deg, rgba(255, 255, 255, 0.34), transparent 70%);
}
.glassbadge__note {
margin: 0;
color: rgba(255, 255, 255, 0.82);
font-weight: 500;
font-size: clamp(11px, 2.8vw, 13px);
line-height: 1;
font-family: inherit;
}
@keyframes sheenSweep {
0%, 12% {
transform: translateX(-140%) rotate(24deg);
}
82%, 100% {
transform: translateX(340%) rotate(24deg);
}
}
@keyframes flareUp {
0%, 36% {
opacity: 0;
}
44%, 50% {
opacity: 1;
}
58%, 100% {
opacity: 0;
}
}
@media (max-width: 340px), (max-height: 220px) {
.glassbadge__plate {
padding: 12px;
gap: 4px;
}
.glassbadge__note {
display: none;
}
}
@media (prefers-reduced-motion: reduce) {
.glassbadge__sheen {
animation: none !important;
transform: translateX(120%) rotate(24deg);
}
.glassbadge__flare {
animation: none !important;
opacity: 0;
}
}import type { CSSProperties } from "react";
import styles from "./GlassInlayBadge.module.scss";
export type GlassInlayBadgeProps = {
caption?: string;
note?: string;
/** 인레이 role="img" 라벨 (기본 "유리 배지") */
ariaLabel?: string;
/** 한 주기(기본 2000ms) */
duration?: number;
easing?: string;
color?: string;
};
type Vars = CSSProperties & { "--duration"?: string; "--easing"?: string; "--color"?: string };
export default function GlassInlayBadge({
caption = "정회원 배지",
note = "한 달 이용자 한정",
ariaLabel = "유리 배지",
duration = 2000,
easing = "ease-out",
color = "#4cd4a6",
}: GlassInlayBadgeProps) {
const vars: Vars = { "--duration": `${duration}ms`, "--easing": easing, "--color": color };
return (
<section className={styles.glassbadge} style={vars}>
<div className={styles.plate}>
<p className={styles.caption}>{caption}</p>
<div className={styles.inlay} role="img" aria-label={ariaLabel}>
<span className={styles.core} 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="M232 128c0 12.51-17.82 21.95-22.68 33.69c-4.68 11.32 1.42 30.65-7.78 39.85s-28.53 3.1-39.85 7.78C150 214.18 140.5 232 128 232s-22-17.82-33.69-22.68c-11.32-4.68-30.65 1.42-39.85-7.78s-3.1-28.53-7.78-39.85C41.82 150 24 140.5 24 128s17.82-22 22.68-33.69c4.68-11.31-1.42-30.65 7.78-39.85s28.54-3.1 39.85-7.78C106.05 41.82 115.5 24 128 24s22 17.82 33.69 22.68c11.32 4.68 30.65-1.42 39.85 7.78s3.1 28.53 7.78 39.85C214.18 106.05 232 115.5 232 128" opacity=".2"/><path d="M225.86 102.82c-3.77-3.94-7.67-8-9.14-11.57c-1.36-3.27-1.44-8.69-1.52-13.94c-.15-9.76-.31-20.82-8-28.51s-18.75-7.85-28.51-8c-5.25-.08-10.67-.16-13.94-1.52c-3.56-1.47-7.63-5.37-11.57-9.14C146.28 23.51 138.44 16 128 16s-18.27 7.51-25.18 14.14c-3.94 3.77-8 7.67-11.57 9.14c-3.25 1.36-8.69 1.44-13.94 1.52c-9.76.15-20.82.31-28.51 8s-7.8 18.75-8 28.51c-.08 5.25-.16 10.67-1.52 13.94c-1.47 3.56-5.37 7.63-9.14 11.57C23.51 109.72 16 117.56 16 128s7.51 18.27 14.14 25.18c3.77 3.94 7.67 8 9.14 11.57c1.36 3.27 1.44 8.69 1.52 13.94c.15 9.76.31 20.82 8 28.51s18.75 7.85 28.51 8c5.25.08 10.67.16 13.94 1.52c3.56 1.47 7.63 5.37 11.57 9.14c6.9 6.63 14.74 14.14 25.18 14.14s18.27-7.51 25.18-14.14c3.94-3.77 8-7.67 11.57-9.14c3.27-1.36 8.69-1.44 13.94-1.52c9.76-.15 20.82-.31 28.51-8s7.85-18.75 8-28.51c.08-5.25.16-10.67 1.52-13.94c1.47-3.56 5.37-7.63 9.14-11.57c6.63-6.9 14.14-14.74 14.14-25.18s-7.51-18.27-14.14-25.18m-11.55 39.29c-4.79 5-9.75 10.17-12.38 16.52c-2.52 6.1-2.63 13.07-2.73 19.82c-.1 7-.21 14.33-3.32 17.43s-10.39 3.22-17.43 3.32c-6.75.1-13.72.21-19.82 2.73c-6.35 2.63-11.52 7.59-16.52 12.38S132 224 128 224s-9.15-4.92-14.11-9.69s-10.17-9.75-16.52-12.38c-6.1-2.52-13.07-2.63-19.82-2.73c-7-.1-14.33-.21-17.43-3.32s-3.22-10.39-3.32-17.43c-.1-6.75-.21-13.72-2.73-19.82c-2.63-6.35-7.59-11.52-12.38-16.52S32 132 32 128s4.92-9.15 9.69-14.11s9.75-10.17 12.38-16.52c2.52-6.1 2.63-13.07 2.73-19.82c.1-7 .21-14.33 3.32-17.43s10.39-3.22 17.43-3.32c6.75-.1 13.72-.21 19.82-2.73c6.35-2.63 11.52-7.59 16.52-12.38S124 32 128 32s9.15 4.92 14.11 9.69s10.17 9.75 16.52 12.38c6.1 2.52 13.07 2.63 19.82 2.73c7 .1 14.33.21 17.43 3.32s3.22 10.39 3.32 17.43c.1 6.75.21 13.72 2.73 19.82c2.63 6.35 7.59 11.52 12.38 16.52S224 124 224 128s-4.92 9.15-9.69 14.11m-40.65-43.77a8 8 0 0 1 0 11.32l-56 56a8 8 0 0 1-11.32 0l-24-24a8 8 0 0 1 11.32-11.32L112 148.69l50.34-50.35a8 8 0 0 1 11.32 0"/></g></svg>
</span>
<span className={styles.sheen} aria-hidden="true" />
<span className={styles.flare} aria-hidden="true" />
<span className={styles.gloss} aria-hidden="true" />
</div>
</div>
<p className={styles.note}>{note}</p>
</section>
);
}05 유리 인레이 배지 — 측정 누적면적 10.794% · 움직인 프레임 11/23GODRICH 원작 · zip 에 SCSS·React 포함 · 스큐어모피즘 디자인 랜딩 키트, 질감 부품 9개
이 데모가 속한 글
스큐어모피즘 디자인 랜딩 키트, 질감 부품 9개스큐어모피즘 디자인은 가죽·금속·나무 같은 실물 질감을 화면에 옮겨 담는 스타일입니다. 사진 한 장 없이 가죽·금속·나무를 CSS 값만으로 만들어, 2024년 이후 제품 사이트에서 한두 군데씩 다시 돌아온 그 질감을 이 글의 데모 전부 보기


