@@ -181,100 +181,173 @@ const StepLabel = styled(Typography)`
181181 transition: all 0.3s ease;
182182` ;
183183
184+ const ProviderCategoryHeader = styled ( Box ) `
185+ display: flex;
186+ align-items: center;
187+ gap: 12px;
188+ margin: 0 0 16px;
189+ animation: ${ fadeIn } 0.4s ease;
190+
191+ &::after {
192+ content: '';
193+ flex: 1;
194+ height: 1px;
195+ background: linear-gradient(90deg, ${ colors . border } , transparent);
196+ }
197+ ` ;
198+
199+ const ProviderCategoryLabel = styled ( Typography ) `
200+ font-size: 12px;
201+ font-weight: 600;
202+ letter-spacing: 0.08em;
203+ text-transform: uppercase;
204+ color: ${ colors . textLight } ;
205+ ` ;
206+
207+ const ProviderCategoryHint = styled . span `
208+ font-size: 11px;
209+ font-weight: 500;
210+ padding: 3px 10px;
211+ border-radius: 999px;
212+ background: ${ colors . primaryLight } ;
213+ color: ${ colors . primary } ;
214+ letter-spacing: 0.02em;
215+ text-transform: none;
216+ ` ;
217+
184218const ProvidersGrid = styled ( Box ) `
185219 display: grid;
186- grid-template-columns: repeat(2 , 1fr);
187- gap: 20px ;
188- margin-bottom: 24px ;
220+ grid-template-columns: repeat(3 , 1fr);
221+ gap: 16px ;
222+ margin: 0 auto 28px ;
189223 animation: ${ slideIn } 0.5s ease;
190- max-width: 800px;
191- margin-left: auto;
192- margin-right: auto;
224+ max-width: 960px;
225+
226+ @media (max-width: 960px) {
227+ grid-template-columns: repeat(2, 1fr);
228+ }
229+ @media (max-width: 600px) {
230+ grid-template-columns: 1fr;
231+ }
193232` ;
194233
234+ /**
235+ * Redesigned provider tile.
236+ *
237+ * Portrait aspect-ratio was dropped — the old 1:1 tiles forced the
238+ * provider name into a narrow column so "Microsoft OAuth" and
239+ * "Yahoo Mail OAuth" were getting squeezed. The new layout is a
240+ * breathable landscape card with:
241+ * - a prominent icon row (68px),
242+ * - a bold, high-contrast title,
243+ * - a one-line tagline that explains what the provider actually is,
244+ * - a clearly visible selection ring with success-green check badge.
245+ *
246+ * Colours are taken from the plugin palette and dark-mode-safe: the
247+ * card background falls back to a transparent wash that sits cleanly
248+ * on top of the admin panel surface in both light and dark themes.
249+ */
195250const ProviderCard = styled ( Box ) `
196- background: ${ props => props . $selected ? colors . successLight : props . theme . colors . neutral0 } ;
197- border: 2px solid ${ props => props . $selected ? colors . success : colors . border } ;
198- border-radius: 12px;
199- padding: 24px;
251+ background: ${ props => props . $selected
252+ ? `linear-gradient(180deg, ${ colors . successLight } , rgba(92, 177, 118, 0.04))`
253+ : 'var(--colors-neutral100, rgba(255,255,255,0.02))' } ;
254+ border: 1.5px solid ${ props => props . $selected ? colors . success : colors . border } ;
255+ border-radius: 14px;
256+ padding: 22px 20px 20px;
200257 cursor: pointer;
201- transition: all 0.2s cubic-bezier(0.4, 0, 0.2, 1);
202- text-align: center;
203- aspect-ratio: 1;
204- min-height: 180px;
258+ transition: transform 0.2s cubic-bezier(0.4, 0, 0.2, 1), box-shadow 0.2s, border-color 0.2s, background 0.2s;
205259 display: flex;
206260 flex-direction: column;
207- align-items: center;
208- justify-content: center;
209- gap: 12px;
261+ align-items: flex-start;
262+ gap: 14px;
210263 position: relative;
211264 overflow: hidden;
212-
265+ min-height: 170px;
266+
213267 &::before {
214268 content: '';
215269 position: absolute;
216- top: 0;
217- left: 0;
218- right: 0;
219- bottom: 0;
220- background: linear-gradient(135deg, transparent, rgba(73, 69, 255, 0.05));
270+ inset: 0;
271+ background: linear-gradient(135deg, transparent 60%, rgba(73, 69, 255, 0.06));
221272 opacity: 0;
222- transition: opacity 0.3s;
273+ transition: opacity 0.25s;
274+ pointer-events: none;
223275 }
224-
276+
225277 &:hover {
226- transform: translateY(-4px );
227- box-shadow: 0 8px 24px rgba(73, 69, 255, 0.12 );
278+ transform: translateY(-3px );
279+ box-shadow: 0 10px 28px rgba(73, 69, 255, 0.18 );
228280 border-color: ${ props => props . $selected ? colors . success : colors . primary } ;
229-
281+
230282 &::before {
231283 opacity: 1;
232284 }
233285 }
234-
235- ${ props => props . $selected && `
286+
287+ &:focus-visible {
288+ outline: 2px solid ${ colors . primary } ;
289+ outline-offset: 2px;
290+ }
291+
292+ ${ props => props . $selected && css `
293+ box-shadow: 0 0 0 1px ${ colors . success } , 0 10px 28px rgba(92, 177, 118, 0.18);
294+
236295 &::after {
237296 content: '✓';
238297 position: absolute;
239- top: 8px ;
240- right: 8px ;
298+ top: 12px ;
299+ right: 12px ;
241300 width: 24px;
242301 height: 24px;
243302 background: ${ colors . success } ;
244- color: white ;
303+ color: #fff ;
245304 border-radius: 50%;
246305 display: flex;
247306 align-items: center;
248307 justify-content: center;
249- font-size: 14px;
250- font-weight: bold;
308+ font-size: 13px;
309+ font-weight: 700;
310+ box-shadow: 0 2px 6px rgba(92, 177, 118, 0.35);
251311 }
252312 ` }
253313` ;
254314
255315const ProviderIcon = styled . div `
256- width: 56px ;
257- height: 56px ;
316+ width: 48px ;
317+ height: 48px ;
258318 border-radius: ${ props => props . $round ? '50%' : '12px' } ;
259- background: ${ props => props . $bgColor || colors . primaryLight } ;
319+ /* Dark-mode-friendly: mix the accent colour onto an opaque surface
320+ instead of using a semi-transparent wash. Semi-transparent colours
321+ disappeared against the plugin's dark modal background. */
322+ background: ${ props => props . $bgColor || 'rgba(73, 69, 255, 0.2)' } ;
260323 display: flex;
261324 align-items: center;
262325 justify-content: center;
263- font-size: ${ props => props . $fontSize || '24px ' } ;
264- font-weight: bold ;
326+ font-size: ${ props => props . $fontSize || '22px ' } ;
327+ font-weight: 700 ;
265328 color: ${ props => props . $color || colors . primary } ;
266- box-shadow: 0 4px 12px ${ props => props . $shadowColor || 'rgba(73, 69, 255, 0.15)' } ;
329+ box-shadow: 0 4px 14px ${ props => props . $shadowColor || 'rgba(73, 69, 255, 0.25)' } ;
330+ flex-shrink: 0;
331+ ` ;
332+
333+ const ProviderTextBlock = styled ( Box ) `
334+ display: flex;
335+ flex-direction: column;
336+ gap: 4px;
337+ margin-top: auto;
267338` ;
268339
269340const ProviderName = styled ( Typography ) `
270341 font-weight: 600;
271- font-size: 15px;
342+ font-size: 16px;
343+ line-height: 1.25;
272344 color: ${ colors . text } ;
273345 margin: 0;
274346` ;
275347
276348const ProviderTagline = styled ( Typography ) `
277- font-size: 12px;
349+ font-size: 12.5px;
350+ line-height: 1.4;
278351 color: ${ colors . textLight } ;
279352 margin: 0;
280353` ;
@@ -938,80 +1011,137 @@ const AddAccountModal = ({ isOpen, onClose, onAccountAdded, editAccount = null }
9381011 { /* Step 1: Choose Provider */ }
9391012 { currentStep === 1 && (
9401013 < Box >
1014+ < ProviderCategoryHeader >
1015+ < ProviderCategoryLabel > OAuth Providers</ ProviderCategoryLabel >
1016+ < ProviderCategoryHint > Recommended</ ProviderCategoryHint >
1017+ </ ProviderCategoryHeader >
9411018 < ProvidersGrid >
942- < ProviderCard
1019+ < ProviderCard
9431020 $selected = { provider === 'gmail-oauth' }
9441021 onClick = { ( ) => setProvider ( 'gmail-oauth' ) }
1022+ role = "button"
1023+ tabIndex = { 0 }
1024+ onKeyDown = { ( e ) => ( e . key === 'Enter' || e . key === ' ' ) && setProvider ( 'gmail-oauth' ) }
9451025 >
946- < ProviderIcon
947- $round
948- $bgColor = "#4285F433"
1026+ < ProviderIcon
1027+ $round
1028+ $bgColor = "rgba(66, 133, 244, 0.22)"
9491029 $color = "#4285F4"
950- $shadowColor = "rgba(66, 133, 244, 0.2 )"
1030+ $shadowColor = "rgba(66, 133, 244, 0.3 )"
9511031 >
9521032 G
9531033 </ ProviderIcon >
954- < ProviderName > Gmail OAuth</ ProviderName >
1034+ < ProviderTextBlock >
1035+ < ProviderName > Gmail</ ProviderName >
1036+ < ProviderTagline > Google Workspace & personal accounts · 1 - click OAuth </ ProviderTagline >
1037+ </ ProviderTextBlock >
9551038 </ ProviderCard >
9561039
957- < ProviderCard
1040+ < ProviderCard
9581041 $selected = { provider === 'microsoft-oauth' }
9591042 onClick = { ( ) => setProvider ( 'microsoft-oauth' ) }
1043+ role = "button"
1044+ tabIndex = { 0 }
1045+ onKeyDown = { ( e ) => ( e . key === 'Enter' || e . key === ' ' ) && setProvider ( 'microsoft-oauth' ) }
9601046 >
961- < ProviderIcon
962- $round
963- $bgColor = "#00A4EF33"
1047+ < ProviderIcon
1048+ $round
1049+ $bgColor = "rgba(0, 164, 239, 0.22)"
9641050 $color = "#00A4EF"
965- $shadowColor = "rgba(0, 164, 239, 0.2 )"
1051+ $shadowColor = "rgba(0, 164, 239, 0.3 )"
9661052 >
9671053 M
9681054 </ ProviderIcon >
969- < ProviderName > Microsoft OAuth</ ProviderName >
1055+ < ProviderTextBlock >
1056+ < ProviderName > Microsoft 365</ ProviderName >
1057+ < ProviderTagline > Outlook · Exchange · Azure AD · 1-click OAuth</ ProviderTagline >
1058+ </ ProviderTextBlock >
9701059 </ ProviderCard >
9711060
972- < ProviderCard
1061+ < ProviderCard
9731062 $selected = { provider === 'yahoo-oauth' }
9741063 onClick = { ( ) => setProvider ( 'yahoo-oauth' ) }
1064+ role = "button"
1065+ tabIndex = { 0 }
1066+ onKeyDown = { ( e ) => ( e . key === 'Enter' || e . key === ' ' ) && setProvider ( 'yahoo-oauth' ) }
9751067 >
976- < ProviderIcon
977- $round
978- $bgColor = "#6001D233"
979- $color = "#6001D2 "
980- $shadowColor = "rgba(96, 1, 210, 0.2 )"
1068+ < ProviderIcon
1069+ $round
1070+ $bgColor = "rgba(96, 1, 210, 0.22)"
1071+ $color = "#9C6BF0 "
1072+ $shadowColor = "rgba(96, 1, 210, 0.3 )"
9811073 >
9821074 Y
9831075 </ ProviderIcon >
984- < ProviderName > Yahoo Mail OAuth</ ProviderName >
1076+ < ProviderTextBlock >
1077+ < ProviderName > Yahoo Mail</ ProviderName >
1078+ < ProviderTagline > Yahoo & AOL accounts · 1 - click OAuth </ ProviderTagline >
1079+ </ ProviderTextBlock >
9851080 </ ProviderCard >
1081+ </ ProvidersGrid >
9861082
987- < ProviderCard
1083+ < ProviderCategoryHeader >
1084+ < ProviderCategoryLabel > Custom & Transactional APIs </ ProviderCategoryLabel >
1085+ </ ProviderCategoryHeader >
1086+ < ProvidersGrid >
1087+ < ProviderCard
9881088 $selected = { provider === 'smtp' }
9891089 onClick = { ( ) => setProvider ( 'smtp' ) }
1090+ role = "button"
1091+ tabIndex = { 0 }
1092+ onKeyDown = { ( e ) => ( e . key === 'Enter' || e . key === ' ' ) && setProvider ( 'smtp' ) }
9901093 >
991- < ProviderIcon >
992- < Server style = { { width : 28 , height : 28 } } />
1094+ < ProviderIcon
1095+ $bgColor = "rgba(73, 69, 255, 0.22)"
1096+ $color = "#7B78FF"
1097+ $shadowColor = "rgba(73, 69, 255, 0.3)"
1098+ >
1099+ < Server style = { { width : 26 , height : 26 } } />
9931100 </ ProviderIcon >
994- < ProviderName > SMTP</ ProviderName >
1101+ < ProviderTextBlock >
1102+ < ProviderName > SMTP</ ProviderName >
1103+ < ProviderTagline > Any SMTP server · full control over host, port & auth </ ProviderTagline >
1104+ </ ProviderTextBlock >
9951105 </ ProviderCard >
9961106
997- < ProviderCard
1107+ < ProviderCard
9981108 $selected = { provider === 'sendgrid' }
9991109 onClick = { ( ) => setProvider ( 'sendgrid' ) }
1110+ role = "button"
1111+ tabIndex = { 0 }
1112+ onKeyDown = { ( e ) => ( e . key === 'Enter' || e . key === ' ' ) && setProvider ( 'sendgrid' ) }
10001113 >
1001- < ProviderIcon $bgColor = "#1E90FF22" $color = "#1E90FF" $shadowColor = "rgba(30, 144, 255, 0.2)" >
1002- < Cloud style = { { width : 28 , height : 28 } } />
1114+ < ProviderIcon
1115+ $bgColor = "rgba(30, 144, 255, 0.22)"
1116+ $color = "#4FA8FF"
1117+ $shadowColor = "rgba(30, 144, 255, 0.3)"
1118+ >
1119+ < Cloud style = { { width : 26 , height : 26 } } />
10031120 </ ProviderIcon >
1004- < ProviderName > SendGrid</ ProviderName >
1121+ < ProviderTextBlock >
1122+ < ProviderName > SendGrid</ ProviderName >
1123+ < ProviderTagline > Transactional API · high deliverability · analytics</ ProviderTagline >
1124+ </ ProviderTextBlock >
10051125 </ ProviderCard >
10061126
1007- < ProviderCard
1127+ < ProviderCard
10081128 $selected = { provider === 'mailgun' }
10091129 onClick = { ( ) => setProvider ( 'mailgun' ) }
1130+ role = "button"
1131+ tabIndex = { 0 }
1132+ onKeyDown = { ( e ) => ( e . key === 'Enter' || e . key === ' ' ) && setProvider ( 'mailgun' ) }
10101133 >
1011- < ProviderIcon $bgColor = "#FF6B6B22" $color = "#FF6B6B" $shadowColor = "rgba(255, 107, 107, 0.2)" >
1012- < Mail style = { { width : 28 , height : 28 } } />
1134+ < ProviderIcon
1135+ $bgColor = "rgba(255, 107, 107, 0.22)"
1136+ $color = "#FF8A8A"
1137+ $shadowColor = "rgba(255, 107, 107, 0.3)"
1138+ >
1139+ < Mail style = { { width : 26 , height : 26 } } />
10131140 </ ProviderIcon >
1014- < ProviderName > Mailgun</ ProviderName >
1141+ < ProviderTextBlock >
1142+ < ProviderName > Mailgun</ ProviderName >
1143+ < ProviderTagline > Developer-first API · EU/US regions · routes & webhooks </ ProviderTagline >
1144+ </ ProviderTextBlock >
10151145 </ ProviderCard >
10161146 </ ProvidersGrid >
10171147 </ Box >
0 commit comments