Skip to content

Commit 7f00186

Browse files
ineaguclaude
andcommitted
refactor(onboarding): reviewed notice designs + logo scaling + phpcs fix
Applies the workflow-decided implementations for the two onboarding notices, verified in a local wp-env Neve onboarding instance. - Subtitle: copy -> "Nearly 200 starter sites across every niche, with dozens added recently." (truthful, evergreen). Fix a WCAG AA contrast failure: $secondary-text #848484 (~3.5:1) -> mix(...) ~#6E6D6D (~4.6:1); subtle weight-only emphasis on the count, plus a small-screen scale step. - Upsell toast: two-line copy ("Unlock every premium template" / "Included with Neve Business. <See plans>"), white card, Neve mark scaled to 24px, role=status + accessible (type=button, aria-label) dismiss, focus-visible rings, reduced-motion, mobile full-width strip. - Logo: add viewBox="0 0 40 40" to SVG.logo so it scales instead of cropping when constrained below 40px (fixes the clipped mark in the toast). - phpcs: re-align the const block after the promo-notice constant removal. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01QrGf4K9upxDKhRPVCztoLs
1 parent 3faf837 commit 7f00186

6 files changed

Lines changed: 151 additions & 58 deletions

File tree

includes/Admin.php

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -24,9 +24,9 @@ class Admin {
2424
const IMPORTED_TEMPLATES_COUNT_OPT = 'tiob_premade_imported';
2525
const FEEDBACK_DISMISSED_OPT = 'tiob_feedback_dismiss';
2626

27-
const TC_REMOVED_KEY = 'tiob_tc_removed';
28-
const TC_NEW_NOTICE_DISMISSED = 'tiob_new_tc_notice_dismissed';
29-
const VISITED_LIBRARY_OPT = 'tiob_library_visited';
27+
const TC_REMOVED_KEY = 'tiob_tc_removed';
28+
const TC_NEW_NOTICE_DISMISSED = 'tiob_new_tc_notice_dismissed';
29+
const VISITED_LIBRARY_OPT = 'tiob_library_visited';
3030

3131
/**
3232
* Admin page slug

onboarding/src/Components/Steps/SiteList.js

Lines changed: 17 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -40,18 +40,16 @@ const SiteList = ( {
4040

4141
const toastMessage = createInterpolateElement(
4242
__(
43-
'Unlock every premium template with Neve Business. <a></a>',
43+
'Included with Neve Business. <a>See plans</a>',
4444
'templates-patterns-collection'
4545
),
4646
{
4747
a: (
4848
<a
4949
href={ tiobDash.onboardingUpsell.upgradeToast }
5050
target="_blank"
51-
rel="external noreferrer noopener"
52-
>
53-
{ __( 'Upgrade', 'templates-patterns-collection' ) }
54-
</a>
51+
rel="noopener noreferrer"
52+
/>
5553
),
5654
}
5755
);
@@ -218,9 +216,16 @@ const SiteList = ( {
218216
) }
219217
</h1>
220218
<p className="ob-subtitle">
221-
{ __(
222-
'Nearly 200 starter sites for every niche — fresh designs added regularly.',
223-
'templates-patterns-collection'
219+
{ createInterpolateElement(
220+
__(
221+
'<count>Nearly 200 starter sites</count> across every niche, with dozens added recently.',
222+
'templates-patterns-collection'
223+
),
224+
{
225+
count: (
226+
<span className="ob-subtitle__count" />
227+
),
228+
}
224229
) }
225230
</p>
226231
</div>
@@ -257,6 +262,10 @@ const SiteList = ( {
257262
setShowToast={ setShowToast }
258263
svgIcon={ SVG.logo }
259264
className={ showToast === true ? 'show' : '' }
265+
heading={ __(
266+
'Unlock every premium template',
267+
'templates-patterns-collection'
268+
) }
260269
message={ toastMessage }
261270
/>
262271
) }

onboarding/src/Components/Toast.js

Lines changed: 21 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,33 @@
11
import classnames from 'classnames';
2+
import { __ } from '@wordpress/i18n';
23

3-
const Toast = ( { svgIcon, message, className, setShowToast } ) => {
4+
const Toast = ( { svgIcon, heading, message, className, setShowToast } ) => {
45
const handleClose = () => {
56
setShowToast( 'dismissed' );
67
};
78

89
return (
9-
<div className={ classnames( 'ob-toast', className ) }>
10+
<div
11+
className={ classnames( 'ob-toast', className ) }
12+
role="status"
13+
aria-live="polite"
14+
>
15+
{ svgIcon && (
16+
<span className="ob-toast-icon" aria-hidden="true">
17+
{ svgIcon }
18+
</span>
19+
) }
1020
<div className="ob-toast-content">
11-
{ svgIcon && <div className="ob-toast-icon">{ svgIcon }</div> }
12-
{ message && <p>{ message }</p> }
21+
{ heading && <p className="ob-toast-heading">{ heading }</p> }
22+
{ message && <p className="ob-toast-message">{ message }</p> }
1323
</div>
14-
<button className="ob-toast-close" onClick={ handleClose }>
15-
&times;
24+
<button
25+
type="button"
26+
className="ob-toast-close"
27+
onClick={ handleClose }
28+
aria-label={ __( 'Dismiss', 'templates-patterns-collection' ) }
29+
>
30+
<span aria-hidden="true">&times;</span>
1631
</button>
1732
</div>
1833
);

onboarding/src/scss/_general.scss

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -149,11 +149,27 @@ iframe {
149149
}
150150

151151
.ob-subtitle {
152-
margin: 0;
153-
color: $secondary-text;
152+
margin: 6px 0 0;
153+
max-width: 56ch;
154+
// ~#6E6D6D on white ≈ 4.6:1 → passes WCAG AA while staying clearly secondary to the near-black h1.
155+
color: mix($main-text, $inverted-text, 56%);
154156
font-size: 14px;
155157
line-height: 20px;
156158
font-weight: 400;
159+
letter-spacing: 0.1px;
160+
161+
// Subtle emphasis on the catalog claim — weight only, no brand color (would read promotional).
162+
.ob-subtitle__count {
163+
font-weight: 600;
164+
color: $main-text;
165+
}
166+
}
167+
168+
@media (max-width: #{$tablet}) {
169+
.ob-subtitle {
170+
font-size: 13px;
171+
line-height: 19px;
172+
}
157173
}
158174

159175
/**

onboarding/src/scss/_toast.scss

Lines changed: 91 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -1,66 +1,118 @@
11
.ob-toast {
22
position: fixed;
33
bottom: 24px;
4-
right: 18px;
5-
opacity: 0;
6-
transform: translateY(20px); /* Start 20px below the final position */
7-
transition: opacity 0.5s ease, transform 0.5s ease; /* Add transition */
8-
display: inline-flex;
9-
padding: 10px 14px;
10-
align-items: center;
4+
right: 24px;
5+
z-index: 100;
6+
display: flex;
7+
align-items: flex-start;
118
gap: 10px;
12-
flex-shrink: 0;
139
max-width: 340px;
10+
padding: 12px 14px;
1411
border-radius: $button-radius;
1512
border: 1px solid $border;
16-
background: $light-bg;
17-
box-shadow: 4px 4px 24px 0px rgba(0, 0, 0, 0.18);
18-
font-size: 13px;
19-
font-style: normal;
20-
font-weight: 400;
13+
background: #fff;
14+
box-shadow: 0 6px 24px rgba(0, 0, 0, 0.12);
15+
opacity: 0;
16+
transform: translateY(12px);
17+
transition: opacity 0.35s ease, transform 0.35s ease;
18+
pointer-events: none;
2119
}
2220

23-
.ob-toast-content {
24-
display: flex;
25-
flex: 1;
26-
align-items: center;
27-
gap: 10px;
28-
p {
29-
margin: 0;
30-
color: $main-text;
31-
font-size: 13px;
32-
line-height: 18px;
21+
.ob-toast.show {
22+
opacity: 1;
23+
transform: translateY(0);
24+
pointer-events: auto;
25+
}
26+
27+
.ob-toast-icon {
28+
flex: 0 0 auto;
29+
line-height: 0;
30+
margin-top: 1px;
31+
32+
svg {
33+
width: 24px;
34+
height: 24px;
35+
display: block;
3336
}
37+
}
38+
39+
.ob-toast-content {
40+
flex: 1 1 auto;
41+
min-width: 0;
42+
}
43+
44+
.ob-toast-heading {
45+
margin: 0;
46+
color: $main-text;
47+
font-size: 13px;
48+
line-height: 18px;
49+
font-weight: 600;
50+
}
51+
52+
.ob-toast-message {
53+
margin: 2px 0 0;
54+
color: $secondary-text;
55+
font-size: 13px;
56+
line-height: 18px;
57+
font-weight: 400;
58+
3459
a {
35-
text-decoration: none;
3660
color: $primary;
37-
font-weight: 700;
61+
font-weight: 600;
62+
text-decoration: none;
3863
white-space: nowrap;
39-
}
40-
}
4164

42-
.ob-toast-icon {
43-
display: inline-flex;
44-
flex-shrink: 0;
65+
&:hover,
66+
&:focus-visible {
67+
text-decoration: underline;
68+
}
4569

46-
svg {
47-
width: 22px;
48-
height: 22px;
70+
&:focus-visible {
71+
outline: 2px solid $primary;
72+
outline-offset: 2px;
73+
border-radius: 2px;
74+
}
4975
}
5076
}
5177

5278
.ob-toast-close {
79+
flex: 0 0 auto;
80+
margin: -4px -4px 0 2px;
81+
padding: 4px;
5382
background: none;
5483
border: none;
55-
font-size: 18px;
5684
line-height: 1;
85+
font-size: 16px;
5786
color: $secondary-text;
5887
cursor: pointer;
59-
flex-shrink: 0;
88+
border-radius: 4px;
89+
90+
&:hover {
91+
color: $main-text;
92+
}
93+
94+
&:focus-visible {
95+
outline: 2px solid $primary;
96+
outline-offset: 1px;
97+
}
6098
}
6199

62-
/* Add a class to control the appearance */
63-
.ob-toast.show {
64-
opacity: 1; /* Show with full opacity */
65-
transform: translateY(0); /* Move to the final position */
100+
@media (prefers-reduced-motion: reduce) {
101+
.ob-toast {
102+
transition: opacity 0.2s ease;
103+
transform: none;
104+
}
105+
106+
.ob-toast.show {
107+
transform: none;
108+
}
109+
}
110+
111+
@media (max-width: #{$tablet}) {
112+
.ob-toast {
113+
left: 16px;
114+
right: 16px;
115+
bottom: 16px;
116+
max-width: none;
117+
}
66118
}

onboarding/src/utils/svg.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ const SVG = {
44
xmlns="http://www.w3.org/2000/svg"
55
width="40"
66
height="40"
7+
viewBox="0 0 40 40"
78
fill="none"
89
>
910
<path

0 commit comments

Comments
 (0)