Commit 1457a9c
Onboarding v4 design feedback and polish (#2319)
* Bump @duckduckgo/design-tokens to v0.13.0
Required for onboarding.css which provides .theme-light/.theme-dark tokens.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
* Onboarding v4: replace hardcoded colours with design token CSS vars
Import @duckduckgo/design-tokens onboarding.css and apply theme-light/
theme-dark classes to <main> via isDarkMode from EnvironmentProvider.
Replace all hardcoded hex/rgba colours across v4 CSS modules with --ds-*
custom properties, collapsing paired @media (prefers-color-scheme: dark)
overrides where both themes share the same token name.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
* Onboarding v4: replace systemSettings SVG with lottie Dax illustration
Replace the static SVG Dax illustration on the systemSettings step with
layered lottie animations (background body/circle behind the bubble,
foreground wing in front). Move illustration rendering from Bubble into
SingleStep so layers sit correctly in the stacking order. Add fade-out
animation on step exit matching the existing getStarted pattern.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* Onboarding v4: simplify Background to vertical slide animation
Replace CSS background-image with inline <picture>/<img> elements for
SVG illustrations. Animate straight up/down (translateY) instead of
diagonal offsets, using the default timings for all steps.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* Onboarding v4: unify vertical positioning into App container
Move the top offset to a single padding-top on App's container using
max(--sp-5, 45vh - 310px) so the tallest step (~620px) is centered
near 45% of the viewport. Remove per-component top margins/padding
and drop the unnecessary min-height: 100vh from WelcomeContent.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* Onboarding v4: keep background SVG at natural size
Stop stretching the illustration to 100% width. Render at intrinsic
size, centered horizontally and pinned to the bottom of the viewport.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* Onboarding v4: increase welcome Dax logo to 96x96
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* Onboarding v4: extend welcome title fade-in to match slide-up duration
The fade-in was only ~200ms (13–20% of 3s), making it barely visible.
Extend it to 29.67% so opacity and position arrive together over ~500ms.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* Onboarding v4: delay getStarted bubble entrance by 150ms
Gives the Dax lottie animation more time before the bubble slides in,
creating better overlap between the two intro animations.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* Onboarding v4: fix bubble resize timing and align content fade-in
- Add contentWidth prop to Bubble so the content measurement div
immediately uses the target width. This prevents ResizeObserver from
measuring at an intermediate width during width transitions, which
caused a double-resize on getStarted -> makeDefaultSingle.
- Delay content fade-in from 233ms to 400ms so it starts after the
bubble finishes resizing (67ms delay + 333ms duration).
- Align comparison table tick bounce-in base delay to 400ms to match
the content fade-in timing.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* Onboarding v4: smooth bubble split transition and delay right tail
- Pre-size the hidden top bubble to match the bottom bubble's height so
the makeDefaultSingle → systemSettings transition looks like a smooth
split rather than the top bubble growing from zero.
- Delay right tail slide-out to 400ms so it appears after the bubble
finishes resizing.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* Onboarding v4: bounce only the bubble frame, not content
Extract visual styles (background, border, radius, shadow) and tails
into a .frame div that receives the scale-bounce animation. Content
sits as a sibling and stays perfectly still during the bounce.
Remove unused useMergedRef hook and measureBubbleHeight function.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* Onboarding v4: pin progress badge to bubble top edge during bounce
Move the progress badge into Bubble so it tracks the frame's
scale-bounce animation. The badge animates translateY in sync with the
frame's 1→1.07→1 scale, offsetting by (scale-1)/2 * height to stay
pinned to the top border. Also replaces the hardcoded BORDER_WIDTH
constant with measureHeight() reading from computed styles.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* Onboarding v4: move bubble sizing and positioning from JS to CSS
Replace inline styles and JS constants (NARROW_WIDTH, WIDE_WIDTH, GAP)
with CSS custom properties (--bubble-width, --bubble-height, --bubble-leading,
--bubble-top-height, --bubble-bottom-height). Bubble content measurement now
uses an inherited --bubble-width via CSS class instead of a contentWidth prop.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* Onboarding v4: keep Dax illustration stable as bottom bubble grows
Position the illustration with an absolute offset that compensates for
changes in --bubble-bottom-height, so Dax stays visually anchored while
system settings rows are added.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* Bump size of star icon in addressBarMode step
* Fix invalid transition-timing-function value failing stylelint
Remove stray `67ms` from cubic-bezier value — the delay is already
specified via transition-delay.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* Fix background image paths broken on CDN preview
Remove `../` prefix from asset paths in Background.js to match the
convention used by all other v4 components. The `../` navigated above
the served root, causing 404s on CDN while working locally.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* Add sparkle lottie animation to makeDefault and duckPlayer steps
Play a sparkle effect at the top-left of the title when it transitions
from "Protections activated!" to "Excellent! Let's move on.", and at
the top-left of the Duck Player promo image when that step appears.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* Onboarding v4: support default Duck Player variant with Rive animation toggle
The duckPlayerSingle step previously always showed static ad-free copy.
Now it checks the variant from stepDefinitions: ad-free shows the static
promo image, while the default (no variant) shows the Rive before/after
animation with "See With/Without Duck Player" toggle buttons, matching
the v3 behaviour.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* Fix package-lock.json regression for @duckduckgo/design-tokens
The merge from main downgraded the lockfile entry from v0.13.0 to
v0.11.0, breaking the onboarding.css import added in this branch.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* Address design feedback: background alignment, content position, Dax spacing
- Right-align background illustration on welcome step via data-current selector
- Lift welcome logo and step bubbles from 45vh to 40vh
- Increase min bubble leading from sp-5 to sp-10
- Nudge Dax illustration down 8px for more gap from Import button
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* Fix Windows button ordering: primary action on left, secondary on right
On Windows, primary actions (Make Default, Pin to Taskbar, Import Now, Next)
should appear to the left of secondary actions (Skip). Adds platform-aware
`order: -1` on `[data-platform-name="windows"]` to the button containers in
MakeDefaultContent, SettingsContent, and DuckPlayerContent, matching the v3
convention. macOS ordering (primary on right) is unaffected.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* Vertically center star icon in address bar footer
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* Refine address bar preview: softened corners, detailing, and fix fillOpacity rendering
Update SVG with rounded corners (rx=20), browser tab shapes, window dots,
decorative wave, and corrected colors from Figma. Fix Preact fillOpacity
bug where the JSX attribute wasn't converted to the SVG fill-opacity
attribute — moved all opacity values to style props instead.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* Fix .bubble CSS selector targeting nonexistent class
* Show all X marks in v4 comparison grid for non-DDG browsers
Remove partial support statuses so Chrome and Safari columns
consistently show "not supported" across all comparison rows.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* Replace Rive animation with MP4 videos for Duck Player onboarding step
Swap the Rive-based before/after preview with two short mp4 videos
(duck-player-enabled.mp4 and duck-player-disabled.mp4) for more
efficient playback and direct control. Implements a 7-state FSM via
useReducer to handle auto-play, toggle, mid-playback reverse queuing,
and reduced-motion (seek to last frame with NaN-duration guard).
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* Add dark mode Lottie animations for v4 onboarding
Use dark mode variants for dax-in-spotlight-thumbs-up, dax-in-spotlight-pointing-background,
and sparkle animations when the user prefers dark color scheme. The LottieAnimation component
now accepts an optional darkSrc prop and preserves the current frame when switching themes.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* Use package-lock.json from main
* Fix WebKit CI failure in duck player video state-machine tests
Disable reduced motion after page load in the mid-playback and double-toggle
tests. In reduced motion mode, playVideo() seeks to video.duration which fires
the 'ended' event immediately in WebKit, skipping past the transitional states
the tests need to assert. Switching to no-preference after setup keeps the fast
page load while letting playVideo() call video.play() for deterministic control.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* Fix systemSettings illustration placement and background dark mode theming
- Move systemSettings illustration config from inside bottomBubble to
top-level step config so SingleStep can render it (matches getStarted)
- Use class-based .theme-dark selector instead of @media prefers-color-scheme
for background color, consistent with the rest of v4 theming
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* Rewrite DuckPlayerDefault to simplify video toggle state management
Replace the 7-state FSM with a simple { target, phase, reverse } state
object. Side effects (play/reset) live directly in toggle, handleEnd,
and autoPlay callbacks. Pre-seeks the hidden video to frame 0 when
queuing a reverse to prevent flash of old end-frame on transition.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* Polish onboarding v4 code quality: DRY components, consistent patterns, readability
- Extract shared Container and Title components from repeated layout/heading styles
- Thread updateSystemValue as prop from data.js into content components, removing
raw dispatch({ kind: 'update-system-value' }) calls
- Replace handle* callback prefixes with action-describing names (settle, complete,
advance, apply, select)
- Use advance from useStepConfig in SingleStep instead of duplicating dispatch
- Consistent class prop usage (className → class) in ComparisonTable + AddressBarPreview
- Add px comments to all standalone var(--sp-*) CSS usages
- Convert raw px values to calc(N * var(--px-in-rem)) or var(--sp-N) tokens
- Add prefers-reduced-motion: reduce to Background slide animations
- Fix arialLabel typo, t parameter shadowing, pendingId string|false → string|null
- Remove dead useEffect in AddressBarContent, empty <caption>, unused dispatch imports
- Add typed AddressBarOption union, comment for magic slice(2) in progress calc
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* Preload sparkle animation in MakeDefaultContent to eliminate load delay
LottieAnimation gains autoplay and animationRef props so callers can
preload without playing and trigger playback imperatively. The sparkle
is now always mounted (hidden via visibility) and played from frame 6
when the success title appears, avoiding a visible fetch/parse delay.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* Hide Dax illustration and tail on short viewports for getStarted step
Add shared useMediaQuery hook and use it to reactively hide the
illustration and bottom-left tail when viewport height is below 550px.
Also refactor EnvironmentProvider to use the hook for dark mode detection.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* Remove right tail from duckPlayer, customize, and addressBarMode steps
These screens don't have a Dax illustration, so the speech bubble
tail pointing at empty space is unnecessary.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* Share background illustrations across onboarding steps and remove unused assets
Map multiple steps to the same background image so transitions
are skipped when consecutive steps share the same illustration.
Delete 6 unused background SVGs and renumber the remaining files.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* Add ?bubbleWidth query param for onboarding v4 bubble width override
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* Set default bubble width to 530px and add line breaks to Duck Player step
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* Fix double-toggle during initial phase not cancelling queued reverse
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* Fix auto-play useEffect re-firing when reduced motion changes after mount
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* Add v4 onboarding screenshot tests (#2400)
* Add v4 onboarding screenshot tests
Mirror the existing v3 screenshot test approach for the v4 onboarding flow.
Covers all 7 steps: welcome, getStarted, makeDefaultSingle, systemSettings,
duckPlayerSingle, customize, and addressBarMode. Masks Rive canvas on the
duck player step to avoid flaky animation comparisons.
Baseline images will be generated by CI on macOS.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* Updated snapshots via workflow
* Update screenshot tests
---------
Co-authored-by: exe.dev user <exedev@falcon-ion.exe.xyz>
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
* Fix unhandled promise rejection from video.play() in DuckPlayerContent
Add .catch() handler to video.play() call to prevent unhandled promise
rejection warnings that can occur during rapid toggling or DOM changes.
Applied via @cursor push command
* Restore package.json
* Fix lint error
* Restructure videos dir
* Fix background alignment
* Update screenshot tests
---------
Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-authored-by: exe.dev user <exedev@falcon-ion.exe.xyz>
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
Co-authored-by: Cursor Agent <cursoragent@cursor.com>1 parent c5e8615 commit 1457a9c
File tree
103 files changed
+1933
-2212
lines changed- special-pages
- pages/onboarding
- app
- v3/components
- v4
- components
- data
- hooks
- integration-tests
- onboarding.screenshots.spec.js-snapshots
- public
- assets
- img/v4
- lottie/v4
- videos
- v4
- locales/en
Some content is hidden
Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.
103 files changed
+1933
-2212
lines changedLines changed: 1 addition & 1 deletion
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
15 | 15 | | |
16 | 16 | | |
17 | 17 | | |
18 | | - | |
| 18 | + | |
19 | 19 | | |
20 | 20 | | |
21 | 21 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
1 | 1 | | |
2 | | - | |
3 | 2 | | |
4 | | - | |
| 3 | + | |
5 | 4 | | |
6 | 5 | | |
7 | 6 | | |
| |||
14 | 13 | | |
15 | 14 | | |
16 | 15 | | |
17 | | - | |
| 16 | + | |
18 | 17 | | |
19 | | - | |
20 | | - | |
| 18 | + | |
| 19 | + | |
21 | 20 | | |
22 | 21 | | |
23 | 22 | | |
| |||
27 | 26 | | |
28 | 27 | | |
29 | 28 | | |
30 | | - | |
| 29 | + | |
31 | 30 | | |
32 | 31 | | |
33 | 32 | | |
| |||
40 | 39 | | |
41 | 40 | | |
42 | 41 | | |
| 42 | + | |
| 43 | + | |
| 44 | + | |
| 45 | + | |
43 | 46 | | |
44 | 47 | | |
45 | 48 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
1 | 1 | | |
| 2 | + | |
2 | 3 | | |
3 | 4 | | |
4 | 5 | | |
5 | 6 | | |
6 | 7 | | |
7 | 8 | | |
8 | 9 | | |
9 | | - | |
10 | | - | |
| 10 | + | |
| 11 | + | |
11 | 12 | | |
12 | 13 | | |
13 | 14 | | |
14 | | - | |
15 | | - | |
16 | | - | |
17 | | - | |
18 | | - | |
19 | 15 | | |
Lines changed: 19 additions & 26 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
1 | 1 | | |
2 | | - | |
| 2 | + | |
3 | 3 | | |
4 | 4 | | |
5 | | - | |
| 5 | + | |
6 | 6 | | |
7 | 7 | | |
8 | 8 | | |
9 | 9 | | |
| 10 | + | |
10 | 11 | | |
11 | 12 | | |
12 | 13 | | |
| 14 | + | |
| 15 | + | |
13 | 16 | | |
14 | 17 | | |
15 | 18 | | |
16 | 19 | | |
| 20 | + | |
| 21 | + | |
| 22 | + | |
| 23 | + | |
17 | 24 | | |
18 | | - | |
| 25 | + | |
19 | 26 | | |
20 | 27 | | |
21 | | - | |
22 | 28 | | |
23 | | - | |
24 | | - | |
25 | | - | |
26 | | - | |
27 | | - | |
28 | | - | |
29 | | - | |
30 | | - | |
31 | | - | |
32 | | - | |
33 | | - | |
34 | 29 | | |
35 | | - | |
36 | | - | |
37 | | - | |
| 30 | + | |
| 31 | + | |
38 | 32 | | |
39 | | - | |
| 33 | + | |
| 34 | + | |
40 | 35 | | |
41 | 36 | | |
42 | | - | |
| 37 | + | |
43 | 38 | | |
44 | 39 | | |
45 | | - | |
46 | | - | |
47 | 40 | | |
48 | | - | |
| 41 | + | |
49 | 42 | | |
50 | 43 | | |
51 | 44 | | |
52 | 45 | | |
53 | 46 | | |
54 | 47 | | |
55 | 48 | | |
56 | | - | |
| 49 | + | |
57 | 50 | | |
58 | 51 | | |
59 | 52 | | |
60 | 53 | | |
61 | | - | |
| 54 | + | |
62 | 55 | | |
63 | 56 | | |
64 | 57 | | |
| |||
70 | 63 | | |
71 | 64 | | |
72 | 65 | | |
73 | | - | |
| 66 | + | |
74 | 67 | | |
75 | 68 | | |
Lines changed: 19 additions & 28 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
1 | 1 | | |
2 | | - | |
3 | | - | |
4 | | - | |
5 | | - | |
6 | | - | |
| 2 | + | |
7 | 3 | | |
8 | 4 | | |
9 | 5 | | |
| |||
22 | 18 | | |
23 | 19 | | |
24 | 20 | | |
25 | | - | |
26 | | - | |
27 | | - | |
28 | | - | |
29 | | - | |
30 | | - | |
| 21 | + | |
| 22 | + | |
| 23 | + | |
| 24 | + | |
| 25 | + | |
| 26 | + | |
31 | 27 | | |
32 | 28 | | |
33 | | - | |
34 | | - | |
35 | | - | |
36 | | - | |
37 | | - | |
38 | | - | |
39 | | - | |
40 | | - | |
| 29 | + | |
| 30 | + | |
| 31 | + | |
| 32 | + | |
| 33 | + | |
| 34 | + | |
| 35 | + | |
| 36 | + | |
41 | 37 | | |
42 | 38 | | |
43 | 39 | | |
44 | 40 | | |
45 | | - | |
| 41 | + | |
46 | 42 | | |
47 | 43 | | |
48 | 44 | | |
49 | 45 | | |
50 | 46 | | |
51 | 47 | | |
52 | | - | |
53 | | - | |
| 48 | + | |
| 49 | + | |
54 | 50 | | |
55 | 51 | | |
56 | 52 | | |
57 | 53 | | |
58 | 54 | | |
59 | 55 | | |
60 | | - | |
61 | | - | |
62 | | - | |
63 | | - | |
64 | | - | |
| 56 | + | |
65 | 57 | | |
66 | 58 | | |
67 | 59 | | |
| |||
71 | 63 | | |
72 | 64 | | |
73 | 65 | | |
74 | | - | |
0 commit comments