feat(site): rewrite the landing page around verified facts and accessible controls
- Replace claims that contradicted the app: the default hotkey is Right Alt (hold to talk), local features are free with no daily cap, there is no 14-day trial, Team/SSO/SCIM/ZDR are not offered, and the repository is not public. Remove invented metrics, status badges, the competitor table, the ad-mediation changelog, the hash calculator and the duplicate demo. - Seven sections: hero with one labelled example, features, how it works, privacy, pricing (Free / Pro 2,900 / Pro+ 8,900 KRW a month), download, FAQ. Footer links the privacy policy, terms and account deletion pages. - All copy moves into i18n and every one of the 10 locales is translated. Pricing and cloud quotas come from site/src/pricing.ts. - Accessibility: skip link, labelled sections, aria-expanded with Esc and focus return for the menu, language list and FAQ, live status for the example, reduced-motion support, 44px targets, AA contrast on the primary button. Korean keep-all line breaking is scoped to :lang(ko) because Tailwind's break-keep blocked wrapping in Japanese and Chinese. - JS 111 -> 98 KB gzip, CSS 7.8 -> 5.2 KB gzip.
This commit is contained in:
parent
ad6bb70c20
commit
e689683b72
44 changed files with 2198 additions and 3782 deletions
|
|
@ -2,60 +2,79 @@
|
|||
@tailwind components;
|
||||
@tailwind utilities;
|
||||
|
||||
/* ── Base Reset & Globals ──────────────────────────────── */
|
||||
/* ── Base ─────────────────────────────────────────────── */
|
||||
@layer base {
|
||||
:root {
|
||||
--font-sans: "Pretendard Variable", Pretendard, -apple-system, BlinkMacSystemFont, system-ui, Roboto, "Helvetica Neue", "Segoe UI", "Apple SD Gothic Neo", "Noto Sans KR", "Malgun Gothic", sans-serif;
|
||||
--font-display: "Pretendard Variable", Pretendard, -apple-system, BlinkMacSystemFont, system-ui, sans-serif;
|
||||
--font-mono: "JetBrains Mono", "Fira Code", ui-monospace, monospace;
|
||||
--brand-blue: #3b82f6;
|
||||
--brand-blue-soft: rgba(255, 255, 255, 0.25);
|
||||
--brand-glow: rgba(59, 130, 246, 0.7);
|
||||
}
|
||||
|
||||
html {
|
||||
scroll-behavior: smooth;
|
||||
-webkit-font-smoothing: antialiased;
|
||||
-moz-osx-font-smoothing: grayscale;
|
||||
text-rendering: optimizeLegibility;
|
||||
font-family: var(--font-sans);
|
||||
}
|
||||
|
||||
::selection {
|
||||
background-color: rgba(59, 130, 246, 0.35);
|
||||
color: #ffffff;
|
||||
}
|
||||
|
||||
::-webkit-scrollbar {
|
||||
width: 8px;
|
||||
height: 8px;
|
||||
}
|
||||
::-webkit-scrollbar-track {
|
||||
background: #08090c;
|
||||
}
|
||||
::-webkit-scrollbar-thumb {
|
||||
background: #222838;
|
||||
border-radius: 4px;
|
||||
border: 2px solid #08090c;
|
||||
}
|
||||
::-webkit-scrollbar-thumb:hover {
|
||||
background: #363f57;
|
||||
@apply bg-surface-950 font-sans text-neutral-100;
|
||||
}
|
||||
|
||||
body {
|
||||
overflow-x: hidden;
|
||||
background-color: #08090c;
|
||||
color: #f4f4f5;
|
||||
}
|
||||
|
||||
/* Accessibility Focus Rings */
|
||||
::selection {
|
||||
@apply bg-brand-blue/35 text-white;
|
||||
}
|
||||
|
||||
:focus-visible {
|
||||
outline: 2px solid #3b82f6;
|
||||
outline-offset: 2px;
|
||||
@apply outline outline-2 outline-offset-2 outline-brand-blue-light;
|
||||
}
|
||||
|
||||
/* 고정 헤더(64px)가 앵커 대상의 머리를 가리지 않게 한다. */
|
||||
[id] {
|
||||
scroll-margin-top: 5rem;
|
||||
}
|
||||
|
||||
/* 의미적 강조는 세미볼드까지 — 볼드(700) 금지 (design.md 타이포 원칙 1) */
|
||||
strong, b { font-weight: 600; }
|
||||
|
||||
[hidden] { display: none !important; }
|
||||
}
|
||||
|
||||
/* ── Components ───────────────────────────────────────── */
|
||||
@layer components {
|
||||
.section {
|
||||
@apply py-20 md:py-28;
|
||||
}
|
||||
|
||||
/* 버튼: 최소 44px 터치 타깃. 흰 글자 대비 4.5:1 이상을 위해 채움색은 blue-dark 계열. */
|
||||
.btn {
|
||||
@apply inline-flex min-h-[44px] flex-wrap items-center justify-center gap-x-2 gap-y-1 rounded-xl px-5 py-2 text-center text-base font-medium leading-snug transition-colors duration-150;
|
||||
}
|
||||
.btn-sm {
|
||||
@apply min-h-[40px] px-4 text-sm;
|
||||
}
|
||||
.btn-lg {
|
||||
@apply min-h-[52px] px-7;
|
||||
}
|
||||
.btn-primary {
|
||||
@apply bg-brand-blue-dark text-white hover:bg-brand-blue-deep;
|
||||
}
|
||||
.btn-secondary {
|
||||
@apply border border-white/15 bg-surface-800 text-neutral-100 hover:border-white/30 hover:bg-surface-700;
|
||||
}
|
||||
|
||||
.link {
|
||||
@apply text-brand-blue-light underline decoration-brand-blue-light/40 underline-offset-4 transition-colors hover:decoration-brand-blue-light;
|
||||
}
|
||||
|
||||
.kbd {
|
||||
@apply inline-flex min-h-[32px] items-center rounded-md border border-white/15 border-b-white/25 bg-surface-700 px-2.5 font-sans text-sm text-neutral-100;
|
||||
}
|
||||
.kbd-accent {
|
||||
@apply border-brand-blue/50 border-b-brand-blue bg-brand-blue/15 text-brand-blue-light;
|
||||
}
|
||||
|
||||
.skip-link {
|
||||
@apply fixed left-4 top-3 z-[60] -translate-y-24 rounded-lg bg-surface-800 px-4 py-3 text-sm text-white shadow-chassis focus:translate-y-0;
|
||||
}
|
||||
}
|
||||
|
||||
/* ── Grid Background Pattern ──────────────────────────── */
|
||||
/* ── Grid Background Pattern (히어로) ─────────────────── */
|
||||
.bg-grid {
|
||||
background-image:
|
||||
linear-gradient(rgba(59, 130, 246, 0.035) 1px, transparent 1px),
|
||||
|
|
@ -63,24 +82,18 @@
|
|||
background-size: 64px 64px;
|
||||
}
|
||||
|
||||
.bg-grid-dense {
|
||||
background-image:
|
||||
linear-gradient(rgba(255, 255, 255, 0.025) 1px, transparent 1px),
|
||||
linear-gradient(90deg, rgba(255, 255, 255, 0.025) 1px, transparent 1px);
|
||||
background-size: 24px 24px;
|
||||
}
|
||||
|
||||
/* ── CRT Screen Effect (Crisp High-Contrast) ─────────── */
|
||||
/* ── CRT Screen (히어로 예시 화면의 계기판 재질) ─────── */
|
||||
.crt-screen {
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
background: linear-gradient(180deg, #05070a 0%, #0a0e14 100%);
|
||||
border: 1px solid rgba(59, 130, 246, 0.2);
|
||||
border: 1px solid rgba(59, 130, 246, 0.25);
|
||||
box-shadow:
|
||||
inset 0 2px 10px rgba(0, 0, 0, 0.9),
|
||||
0 0 32px rgba(59, 130, 246, 0.08);
|
||||
}
|
||||
|
||||
/* 정지된 주사선만 남긴다. 움직이는 스캔 효과는 읽기를 방해해 제거했다. */
|
||||
.crt-screen::before {
|
||||
content: '';
|
||||
position: absolute;
|
||||
|
|
@ -89,172 +102,67 @@
|
|||
0deg,
|
||||
transparent,
|
||||
transparent 2px,
|
||||
rgba(0, 0, 0, 0.2) 2px,
|
||||
rgba(0, 0, 0, 0.2) 4px
|
||||
rgba(0, 0, 0, 0.18) 2px,
|
||||
rgba(0, 0, 0, 0.18) 4px
|
||||
);
|
||||
pointer-events: none;
|
||||
z-index: 2;
|
||||
}
|
||||
|
||||
.crt-screen::after {
|
||||
content: '';
|
||||
position: absolute;
|
||||
inset: 0;
|
||||
background: linear-gradient(
|
||||
180deg,
|
||||
rgba(59, 130, 246, 0.03) 0%,
|
||||
transparent 50%,
|
||||
rgba(59, 130, 246, 0.015) 100%
|
||||
);
|
||||
animation: scan 8s linear infinite;
|
||||
pointer-events: none;
|
||||
z-index: 3;
|
||||
}
|
||||
|
||||
@keyframes scan {
|
||||
0% { transform: translateY(-100%); }
|
||||
100% { transform: translateY(100%); }
|
||||
}
|
||||
|
||||
/* ── Crosshair Decorations ─────────────────────────────── */
|
||||
.crosshair-box {
|
||||
--ch-size: 16px;
|
||||
--ch-color: rgba(59, 130, 246, 0.4);
|
||||
--ch-color: rgba(59, 130, 246, 0.45);
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.crosshair-box::before {
|
||||
content: '';
|
||||
position: absolute;
|
||||
top: -1px;
|
||||
left: -1px;
|
||||
width: var(--ch-size);
|
||||
height: var(--ch-size);
|
||||
border-top: 1.5px solid var(--ch-color);
|
||||
border-left: 1.5px solid var(--ch-color);
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
.crosshair-box::before,
|
||||
.crosshair-box::after {
|
||||
content: '';
|
||||
position: absolute;
|
||||
bottom: -1px;
|
||||
right: -1px;
|
||||
width: var(--ch-size);
|
||||
height: var(--ch-size);
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
.crosshair-box::before {
|
||||
top: -6px;
|
||||
left: -6px;
|
||||
border-top: 1.5px solid var(--ch-color);
|
||||
border-left: 1.5px solid var(--ch-color);
|
||||
}
|
||||
|
||||
.crosshair-box::after {
|
||||
bottom: -6px;
|
||||
right: -6px;
|
||||
border-bottom: 1.5px solid var(--ch-color);
|
||||
border-right: 1.5px solid var(--ch-color);
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
/* ── Instrument Noise Texture ──────────────────────────── */
|
||||
.noise-texture {
|
||||
position: relative;
|
||||
}
|
||||
.noise-texture::before {
|
||||
content: '';
|
||||
position: absolute;
|
||||
inset: 0;
|
||||
opacity: 0.03;
|
||||
background-image: url("data:image/svg+xml,%3Csvg viewBox='0 0 256 256' xmlns='http://www.w3.org/2000/svg'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.85' numOctaves='4' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)'/%3E%3C/svg%3E");
|
||||
background-repeat: repeat;
|
||||
background-size: 256px 256px;
|
||||
pointer-events: none;
|
||||
border-radius: inherit;
|
||||
}
|
||||
|
||||
/* ── Glass Surfaces & Double Bezel ─────────────────────── */
|
||||
.glass-panel {
|
||||
background: rgba(19, 22, 31, 0.75);
|
||||
backdrop-filter: blur(20px);
|
||||
-webkit-backdrop-filter: blur(20px);
|
||||
border: 1px solid rgba(255, 255, 255, 0.08);
|
||||
box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.08), 0 12px 32px -4px rgba(0, 0, 0, 0.5);
|
||||
}
|
||||
|
||||
.glass-panel-hover {
|
||||
transition: all 250ms cubic-bezier(0.16, 1, 0.3, 1);
|
||||
}
|
||||
.glass-panel-hover:hover {
|
||||
border-color: rgba(59, 130, 246, 0.35);
|
||||
background: rgba(26, 30, 43, 0.85);
|
||||
box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.12), 0 0 20px rgba(59, 130, 246, 0.15);
|
||||
}
|
||||
|
||||
/* ── Glow Button ───────────────────────────────────────── */
|
||||
.glow-btn {
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
transition: all 250ms cubic-bezier(0.16, 1, 0.3, 1);
|
||||
}
|
||||
.glow-btn::before {
|
||||
content: '';
|
||||
position: absolute;
|
||||
inset: -2px;
|
||||
background: linear-gradient(135deg, rgba(59, 130, 246, 0.45), rgba(59, 130, 246, 0) 65%);
|
||||
border-radius: inherit;
|
||||
opacity: 0;
|
||||
transition: opacity 250ms;
|
||||
z-index: 0;
|
||||
}
|
||||
.glow-btn:hover::before {
|
||||
opacity: 1;
|
||||
}
|
||||
.glow-btn:hover {
|
||||
box-shadow: 0 0 24px rgba(59, 130, 246, 0.35), 0 0 48px rgba(59, 130, 246, 0.12);
|
||||
transform: translateY(-1px);
|
||||
}
|
||||
.glow-btn:active {
|
||||
transform: translateY(0) scale(0.98);
|
||||
}
|
||||
|
||||
/* ── Accordion ─────────────────────────────────────────── */
|
||||
.accordion-content {
|
||||
display: grid;
|
||||
grid-template-rows: 0fr;
|
||||
transition: grid-template-rows 250ms cubic-bezier(0.16, 1, 0.3, 1), opacity 200ms ease;
|
||||
overflow: hidden;
|
||||
opacity: 0;
|
||||
visibility: hidden;
|
||||
}
|
||||
.accordion-content.open {
|
||||
grid-template-rows: 1fr;
|
||||
opacity: 1;
|
||||
visibility: visible;
|
||||
}
|
||||
.accordion-content > div {
|
||||
overflow: hidden;
|
||||
min-height: 0;
|
||||
}
|
||||
|
||||
/* ── Reveal Animation ──────────────────────────────────── */
|
||||
.reveal {
|
||||
opacity: 0;
|
||||
transform: translateY(16px);
|
||||
}
|
||||
.reveal.visible {
|
||||
animation: fade-in-up 0.5s cubic-bezier(0.16, 1, 0.3, 1) forwards;
|
||||
}
|
||||
|
||||
@keyframes fade-in-up {
|
||||
0% { opacity: 0; transform: translateY(16px); }
|
||||
100% { opacity: 1; transform: translateY(0); }
|
||||
}
|
||||
|
||||
/* ── Utilities ─────────────────────────────────────────── */
|
||||
@layer base {
|
||||
/* 의미적 강조는 세미볼드까지 — 볼드(700) 헤드라인 금지 (한글 과중 방지) */
|
||||
strong, b { font-weight: 600; }
|
||||
}
|
||||
@layer utilities {
|
||||
.text-balance {
|
||||
text-wrap: balance;
|
||||
}
|
||||
.break-keep {
|
||||
word-break: keep-all;
|
||||
/* 한글 어절 단위 줄바꿈. 중국어·일본어에 keep-all을 걸면 줄바꿈 기회가 사라지므로 한국어에만 적용한다. */
|
||||
.keep-ko {
|
||||
overflow-wrap: break-word;
|
||||
}
|
||||
.border-hairline {
|
||||
border-color: rgba(255, 255, 255, 0.08);
|
||||
.keep-ko:lang(ko) {
|
||||
word-break: keep-all;
|
||||
}
|
||||
}
|
||||
|
||||
/* ── Reduced motion ───────────────────────────────────── */
|
||||
@media (prefers-reduced-motion: reduce) {
|
||||
html {
|
||||
scroll-behavior: auto;
|
||||
}
|
||||
*,
|
||||
*::before,
|
||||
*::after {
|
||||
animation-duration: 0.01ms !important;
|
||||
animation-iteration-count: 1 !important;
|
||||
transition-duration: 0.01ms !important;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue