09클린 버튼·인풋
버튼은 마우스를 올리면 배경이 살짝 짙어지고 1px 위로 떠오르며, 입력창은 포커스를 받으면 얇은 회색 테두리가 파란 두 줄 링으로 부드럽게 바뀝니다. 신뢰 키트의 손맛을 하나로 묶은 항목입니다.
쓰임폼 제출 버튼, 로그인 입력창
1px lift 호버focus 2중 링radius 12

<main class="stage">
<div class="controls">
<label class="controls__field">
<span class="controls__label">이메일</span>
<input class="controls__input" type="text" placeholder="[email protected]">
</label>
<button class="controls__btn" type="button">계속하기</button>
</div>
</main>@use "../../../../site/static/demo-tokens" as *;
$duration: $dur-loop;
$easing: $ease-out;
$color: $subject-blue;
$trust-mint: #eaf6f1;
$trust-ink: $subject-ink;
$trust-slate: #475569;
$trust-blue: $subject-blue;
$trust-blue-deep: #7386ba;
@include stage($trust-mint);
.controls {
box-sizing: border-box;
width: clamp(220px, 78vw, 280px);
display: flex;
flex-direction: column;
gap: $sp-4;
}
.controls__field {
display: flex;
flex-direction: column;
gap: $sp-1;
}
.controls__label {
color: $trust-slate;
font-weight: 600; font-size: 11px; line-height: 1.4;
font-family: inherit;
}
.controls__input {
box-sizing: border-box;
width: 100%;
border: 1.5px solid #e2e8f0;
border-radius: $r-sm;
background: $stage-paper;
color: $trust-ink;
padding: $sp-2 $sp-3;
font-weight: 500; font-size: 13px; line-height: 1.4;
font-family: inherit;
outline: none;
animation: ringPulse $duration $easing infinite;
}
.controls__input::placeholder {
color: $trust-slate;
opacity: .65;
}
.controls__btn {
border: 0;
border-radius: $r-control;
background: $trust-blue;
color: $stage-paper;
padding: $sp-2 $sp-5;
font-weight: 700; font-size: 13px; line-height: 1;
font-family: inherit;
box-shadow: 0 6px 14px rgba($trust-blue, .28);
animation: btnDarken $duration $easing infinite;
}
// 데모: 입력창은 포커스를 받은 것처럼 얇은 테두리가 두 겹 파란 링으로 부드럽게 퍼졌다 가라앉고, 버튼은 배경이 살짝 짙어지며 1px 떠오른다
@keyframes ringPulse {
0%, 60%, 100% { border-color: #e2e8f0; box-shadow: none; }
25% { border-color: $trust-blue; box-shadow: 0 0 0 4px rgba(47, 109, 246, .18); }
}
@keyframes btnDarken {
0%, 60%, 100% { transform: translateY(0); background: $trust-blue; box-shadow: 0 6px 14px rgba(47, 109, 246, .28); }
25% { transform: translateY(-1px); background: #7386ba; box-shadow: 0 10px 18px rgba(29, 78, 216, .34); }
}
@media (max-width: 340px), (max-height: 220px) {
.controls { gap: $sp-2; }
.controls__input { padding: $sp-1 $sp-2; }
.controls__btn { padding: $sp-1 $sp-4; }
}
@media (prefers-reduced-motion: reduce) {
.controls__input, .controls__btn { animation: none !important; transform: none; }
.controls__input { border-color: #e2e8f0; box-shadow: none; }
.controls__btn { background: $trust-blue; }
}html, body {
margin: 0;
overflow: hidden;
}
.stage {
box-sizing: border-box;
min-height: 100vh;
display: grid;
place-items: center;
margin: 0;
background: #eaf6f1;
font-family: -apple-system, "Segoe UI", "Noto Sans KR", sans-serif;
padding: clamp(8px, 4vw, 24px);
}
.controls {
box-sizing: border-box;
width: clamp(220px, 78vw, 280px);
display: flex;
flex-direction: column;
gap: 16px;
}
.controls__field {
display: flex;
flex-direction: column;
gap: 4px;
}
.controls__label {
color: #475569;
font-weight: 600;
font-size: 11px;
line-height: 1.4;
font-family: inherit;
}
.controls__input {
box-sizing: border-box;
width: 100%;
border: 1.5px solid #e2e8f0;
border-radius: 8px;
background: #ffffff;
color: #17141a;
padding: 8px 12px;
font-weight: 500;
font-size: 13px;
line-height: 1.4;
font-family: inherit;
outline: none;
animation: ringPulse 2s ease-out infinite;
}
.controls__input::placeholder {
color: #475569;
opacity: 0.65;
}
.controls__btn {
border: 0;
border-radius: 12px;
background: #2f6df6;
color: #ffffff;
padding: 8px 20px;
font-weight: 700;
font-size: 13px;
line-height: 1;
font-family: inherit;
box-shadow: 0 6px 14px rgba(47, 109, 246, 0.28);
animation: btnDarken 2s ease-out infinite;
}
@keyframes ringPulse {
0%, 60%, 100% {
border-color: #e2e8f0;
box-shadow: none;
}
25% {
border-color: #2f6df6;
box-shadow: 0 0 0 4px rgba(47, 109, 246, 0.18);
}
}
@keyframes btnDarken {
0%, 60%, 100% {
transform: translateY(0);
background: #2f6df6;
box-shadow: 0 6px 14px rgba(47, 109, 246, 0.28);
}
25% {
transform: translateY(-1px);
background: #7386ba;
box-shadow: 0 10px 18px rgba(29, 78, 216, 0.34);
}
}
@media (max-width: 340px), (max-height: 220px) {
.controls {
gap: 8px;
}
.controls__input {
padding: 4px 8px;
}
.controls__btn {
padding: 4px 16px;
}
}
@media (prefers-reduced-motion: reduce) {
.controls__input, .controls__btn {
animation: none !important;
transform: none;
}
.controls__input {
border-color: #e2e8f0;
box-shadow: none;
}
.controls__btn {
background: #2f6df6;
}
}import type { CSSProperties } from "react";
import styles from "./ButtonsInputsTrust.module.scss";
export type ButtonsInputsTrustProps = {
label?: string;
placeholder?: string;
cta?: string;
duration?: number;
easing?: string;
color?: string;
};
type Vars = CSSProperties & { "--duration"?: string; "--easing"?: string; "--color"?: string };
export default function ButtonsInputsTrust({
label = "이메일",
placeholder = "[email protected]",
cta = "계속하기",
duration = 2000,
easing = "ease-out",
color = "#2f6df6",
}: ButtonsInputsTrustProps) {
const vars: Vars = { "--duration": `${duration}ms`, "--easing": easing, "--color": color };
return (
<div className={styles.controls} style={vars}>
<label className={styles.field}>
<span className={styles.label}>{label}</span>
<input className={styles.input} type="text" placeholder={placeholder} />
</label>
<button type="button" className={styles.btn}>{cta}</button>
</div>
);
}09 클린 버튼·인풋 — 측정 누적면적 10.641% · 움직인 프레임 12/23GODRICH 원작 · zip 에 SCSS·React 포함 · saas 랜딩페이지 신뢰감 디자인 키트, 클린 섹션 9개
이 데모가 속한 글
saas 랜딩페이지 신뢰감 디자인 키트, 클린 섹션 9개saas 랜딩페이지 디자인은 흰색과 오프화이트 두 톤 배경 위에 파란색 브랜드 컬러 하나만 얹고, 그림자는 회색 계열로 얕게, 모서리는 절제된 반경으로 통일해 화려하지 않으면서도 진지해 보이게 만드는 스타일입니다. 이 글의 데모 전부 보기


