Wave 3 of the 2026-09-28 design overhaul.
- Esc (no modifiers) cancels an in-progress dictation, recording or
processing: VoiceModeService.requestEscape() queues the dead 'escape'
action. Clicking the capsule cancels only while recording, so a stray
click during processing no longer throws the text away.
- Errors show in the user's language: bootstrap now passes error.code to
the tip (the translated branch never ran), and one core classifier
(voice-error-message) feeds both the tip and the main-window alert.
- Capsule: bars stay flat without input (no fake "alive" wobble before the
mic opens), an indeterminate bar replaces the made-up percentage, the
partial transcript stays visible while processing, an Esc hint, and a
brief "Inserted" state so success is visible.
- All six popups share popups/_shared (Pretendard, one panel radius,
selection, kbd hints, reduced motion). History/command popups get
titles, listbox roles and window sizes from popup-list-geometry (empty
states were clipped); the command popup's "0" key is registered;
result popup explains why it appeared and can be closed; captions keep
a theme-independent dark backing on purpose.
- Popup themes follow the OS when set to system and the document lang
follows the app language.
- Site hero demo mirrors the new capsule (done state, indeterminate bar,
Esc hint; 10 locales).
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).
- 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.
The download section described a release as pending while the product was
already installable, and its installer link pointed at a path the site build
never ships, so a visitor would have reached a missing file.
The section now states the released version and links the published update
feed that the desktop client itself uses, with the release notes and hash
metadata one click away. Repeated color literals behind the hero animation
moved into named tokens.