feat(site): loop a faithful copy of the app's recording capsule in the hero

Replace the press-to-play demo and the "see how it works" button with an
example that keeps playing on the right: hold Right Alt, the capsule appears
with live wave bars, elapsed time and the partial transcript, releasing shows
the processing bar, and the cleaned sentence is pasted at the cursor of a
notes window. It cycles through two samples per language.

- Same numbers as apps/desktop recording-tip: 9 bars with cos weights, 100 ms
  updates, 0.5 smoothing, +/-35% jitter, 2-28 px, per-bar colours, 120 px
  progress bar min(95, (1 - 1/(1 + 1.5t)) * 100)%.
- WCAG 2.2.2: a pause button; stops when off screen or the tab is hidden.
  Reduced motion shows one still frame. The animation is aria-hidden with a
  text description for screen readers. Chinese and Japanese transcripts
  appear three characters at a time.
- Add 404.html so unknown paths stop falling back to the landing page, delete
  the duplicate accept-invite.html (/accept-invite/ is canonical) and link it
  straight to /#download, and move the legal pages off the retired orange
  accent (primary button contrast 5.2:1).
This commit is contained in:
Yun Chan 2026-09-26 15:49:08 +09:00
parent dc43884e3e
commit 92978607da
23 changed files with 707 additions and 467 deletions

View file

@ -74,6 +74,173 @@
}
}
/* ── 히어로 예시: 입력 대상 창 ─────────────────────────── */
.demo-window {
position: relative;
overflow: hidden;
border-radius: 12px;
border: 1px solid rgba(255, 255, 255, 0.1);
background: #0f1116;
box-shadow: 0 24px 48px -12px rgba(0, 0, 0, 0.6);
}
.demo-titlebar {
display: flex;
align-items: center;
gap: 8px;
height: 36px;
padding: 0 14px;
border-bottom: 1px solid rgba(255, 255, 255, 0.07);
background: #151821;
font-size: 12px;
color: #a1a1aa;
}
.demo-app-icon {
width: 12px;
height: 12px;
border-radius: 3px;
background: #3b82f6;
}
.demo-win-glyph {
font-size: 11px;
line-height: 1;
}
.demo-doc {
min-height: 236px;
padding: 22px 22px 108px;
font-size: 15px;
line-height: 1.7;
}
.demo-typed {
border-radius: 3px;
animation: demo-paste 1.6s ease-out;
}
@keyframes demo-paste {
0% { background: rgba(59, 130, 246, 0.35); }
100% { background: transparent; }
}
.demo-caret {
display: inline-block;
width: 2px;
height: 1.15em;
margin-left: 1px;
vertical-align: text-bottom;
background: #f4f4f5;
animation: demo-caret 1.06s steps(1) infinite;
}
@keyframes demo-caret {
50% { opacity: 0; }
}
.demo-capsule-slot {
position: absolute;
left: 0;
right: 0;
bottom: 20px;
display: flex;
justify-content: center;
opacity: 0;
transform: translateY(6px) scale(0.98);
transition: opacity 180ms cubic-bezier(0.16, 1, 0.3, 1), transform 180ms cubic-bezier(0.16, 1, 0.3, 1);
pointer-events: none;
}
.demo-capsule-slot.is-visible {
opacity: 1;
transform: none;
}
/* ── 녹음 캡슐 — 앱 recording-tip/style.css 와 같은 값 ─── */
.capsule {
display: flex;
align-items: center;
gap: 10px;
padding: 8px 16px;
border-radius: 999px;
border: 1px solid rgba(255, 255, 255, 0.08);
background: rgba(15, 17, 22, 0.88);
box-shadow: 0 16px 36px rgba(0, 0, 0, 0.55), inset 0 1px 0 rgba(255, 255, 255, 0.12);
backdrop-filter: blur(28px);
-webkit-backdrop-filter: blur(28px);
}
.capsule:has(.capsule-partial) {
border-radius: 18px;
}
.capsule-recording {
display: flex;
flex-direction: column;
gap: 6px;
min-width: 160px;
max-width: 320px;
}
.capsule-row {
display: flex;
align-items: center;
gap: 10px;
}
.capsule-bars {
display: flex;
align-items: center;
gap: 3px;
height: 28px;
}
.capsule-bar {
display: block;
width: 3px;
min-height: 3px;
height: 2px;
border-radius: 999px;
transition: height 80ms ease-out;
}
.capsule-bar:nth-child(1) { background: #93c5fd; opacity: 0.85; }
.capsule-bar:nth-child(2) { background: #60a5fa; opacity: 0.9; }
.capsule-bar:nth-child(3) { background: #4f8dfa; opacity: 0.95; }
.capsule-bar:nth-child(4) { background: #3b82f6; }
.capsule-bar:nth-child(5) { background: #3b82f6; }
.capsule-bar:nth-child(6) { background: #5b75f7; }
.capsule-bar:nth-child(7) { background: #6e71f7; opacity: 0.95; }
.capsule-bar:nth-child(8) { background: #818cf8; opacity: 0.9; }
.capsule-bar:nth-child(9) { background: #a78bfa; opacity: 0.85; }
.capsule-duration {
min-width: 34px;
font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
font-size: 13px;
font-weight: 600;
font-variant-numeric: tabular-nums;
letter-spacing: 0.02em;
color: #f4f4f5;
}
.capsule-partial {
display: -webkit-box;
max-height: 38px;
overflow: hidden;
-webkit-line-clamp: 2;
-webkit-box-orient: vertical;
border-top: 1px solid rgba(255, 255, 255, 0.08);
padding-top: 6px;
font-size: 12px;
line-height: 1.45;
color: #f4f4f5;
}
.capsule-progress {
display: block;
width: 120px;
height: 4px;
overflow: hidden;
border-radius: 999px;
background: rgba(255, 255, 255, 0.08);
}
.capsule-progress-bar {
display: block;
width: 0;
height: 100%;
border-radius: 999px;
background: #3b82f6;
transition: width 100ms linear;
}
.capsule-thinking {
font-size: 12px;
font-weight: 500;
color: #a1a1aa;
}
/* ── Grid Background Pattern (히어로) ─────────────────── */
.bg-grid {
background-image:
@ -82,63 +249,6 @@
background-size: 64px 64px;
}
/* ── CRT Screen (히어로 예시 화면의 계기판 재질) ─────── */
.crt-screen {
position: relative;
overflow: hidden;
background: linear-gradient(180deg, #05070a 0%, #0a0e14 100%);
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;
inset: 0;
background: repeating-linear-gradient(
0deg,
transparent,
transparent 2px,
rgba(0, 0, 0, 0.18) 2px,
rgba(0, 0, 0, 0.18) 4px
);
pointer-events: none;
z-index: 2;
}
/* ── Crosshair Decorations ─────────────────────────────── */
.crosshair-box {
--ch-size: 16px;
--ch-color: rgba(59, 130, 246, 0.45);
position: relative;
}
.crosshair-box::before,
.crosshair-box::after {
content: '';
position: absolute;
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);
}
/* ── Utilities ─────────────────────────────────────────── */
@layer utilities {
.text-balance {