+
diff --git a/projects/packages/seo/_inc/screens/overview/site-verification-card.tsx b/projects/packages/seo/_inc/screens/overview/site-verification-card.tsx
index e8e10c23ff9e..05193531de4b 100644
--- a/projects/packages/seo/_inc/screens/overview/site-verification-card.tsx
+++ b/projects/packages/seo/_inc/screens/overview/site-verification-card.tsx
@@ -1,7 +1,8 @@
import { __ } from '@wordpress/i18n';
-import { Button, Card } from '@wordpress/ui';
+import { Button, Card, Stack } from '@wordpress/ui';
import { VERIFICATION_SERVICES } from '../../data/verification-services';
import StatusDot from './status-dot';
+import styles from './style.module.scss';
import type { SiteVerification } from '../../data/overview-types';
import type { FC } from 'react';
@@ -20,19 +21,25 @@ const SiteVerificationCard: FC< Props > = ( { data, onManage } ) => (
{ __( 'Site verification', 'jetpack-seo' ) }
-
+ } direction="column" className={ styles.cardContent }>
{ VERIFICATION_SERVICES.map( ( { key, label } ) => (
-
+
{ data[ key ] ? setLabel : notSetLabel }
-
+
) ) }
-
+
{ __( 'Manage verification', 'jetpack-seo' ) }
-
-
+
+
);
diff --git a/projects/packages/seo/_inc/screens/overview/site-visibility-card.tsx b/projects/packages/seo/_inc/screens/overview/site-visibility-card.tsx
index eb9f0b812aa1..e76c8e9ec678 100644
--- a/projects/packages/seo/_inc/screens/overview/site-visibility-card.tsx
+++ b/projects/packages/seo/_inc/screens/overview/site-visibility-card.tsx
@@ -1,6 +1,7 @@
import { __ } from '@wordpress/i18n';
import { Button, Card, Stack } from '@wordpress/ui';
import StatusDot from './status-dot';
+import styles from './style.module.scss';
import type { OverviewResponse } from '../../data/overview-types';
import type { FC } from 'react';
@@ -30,7 +31,7 @@ const SiteVisibilityCard: FC< Props > = ( { data, onManage } ) => {
{ __( 'Site visibility', 'jetpack-seo' ) }
-
+ } direction="column" className={ styles.cardContent }>
= ( { data, onManage } ) => {
label={ data.seo_tools_active ? seoToolsActiveLabel : seoToolsInactiveLabel }
/>
-
+
{ __( 'Manage visibility', 'jetpack-seo' ) }
-
-
+
+
);
};
diff --git a/projects/packages/seo/_inc/screens/overview/status-dot.module.scss b/projects/packages/seo/_inc/screens/overview/status-dot.module.scss
new file mode 100644
index 000000000000..2ce75f16ca5e
--- /dev/null
+++ b/projects/packages/seo/_inc/screens/overview/status-dot.module.scss
@@ -0,0 +1,21 @@
+.root {
+ inline-size: 10px;
+ block-size: 10px;
+ flex-shrink: 0;
+ border-radius: 50%;
+}
+
+// The `-weak` tokens are the vivid indicator colors; the plain
+// `fg-content-*` tokens are the darkest text shades (near-black) and read
+// as black on a status dot.
+.ok {
+ background: var(--wpds-color-foreground-content-success-weak);
+}
+
+.warn {
+ background: var(--wpds-color-foreground-content-warning-weak);
+}
+
+.err {
+ background: var(--wpds-color-foreground-content-error-weak);
+}
diff --git a/projects/packages/seo/_inc/screens/overview/status-dot.scss b/projects/packages/seo/_inc/screens/overview/status-dot.scss
deleted file mode 100644
index fe95b8ef64a9..000000000000
--- a/projects/packages/seo/_inc/screens/overview/status-dot.scss
+++ /dev/null
@@ -1,23 +0,0 @@
-.jetpack-seo-status-dot {
- display: inline-block;
- width: 10px;
- height: 10px;
- border-radius: 50%;
- margin-inline-end: var(--wpds-dimension-gap-sm);
- vertical-align: middle;
-
- // The `-weak` tokens are the vivid indicator colors; the plain
- // `fg-content-*` tokens are the darkest text shades (near-black) and read
- // as black on a status dot.
- &.is-ok {
- background: var(--wpds-color-foreground-content-success-weak);
- }
-
- &.is-warn {
- background: var(--wpds-color-foreground-content-warning-weak);
- }
-
- &.is-err {
- background: var(--wpds-color-foreground-content-error-weak);
- }
-}
diff --git a/projects/packages/seo/_inc/screens/overview/status-dot.tsx b/projects/packages/seo/_inc/screens/overview/status-dot.tsx
index 087c042c31aa..2874ffd9f793 100644
--- a/projects/packages/seo/_inc/screens/overview/status-dot.tsx
+++ b/projects/packages/seo/_inc/screens/overview/status-dot.tsx
@@ -1,5 +1,6 @@
+import { Stack } from '@wordpress/ui';
import clsx from 'clsx';
-import './status-dot.scss';
+import styles from './status-dot.module.scss';
import type { FC } from 'react';
interface Props {
@@ -8,17 +9,10 @@ interface Props {
}
const StatusDot: FC< Props > = ( { status, label } ) => (
-
-
+ } direction="row" align="center" gap="sm">
+
{ label }
-
+
);
export default StatusDot;
diff --git a/projects/packages/seo/_inc/screens/overview/style.scss b/projects/packages/seo/_inc/screens/overview/style.module.scss
similarity index 51%
rename from projects/packages/seo/_inc/screens/overview/style.scss
rename to projects/packages/seo/_inc/screens/overview/style.module.scss
index fff44f69cd38..e277c44d8a4a 100644
--- a/projects/packages/seo/_inc/screens/overview/style.scss
+++ b/projects/packages/seo/_inc/screens/overview/style.module.scss
@@ -1,90 +1,61 @@
// Centered content column. Wider than the Settings tab (which is a single 660px
// form column) because the Overview lays cards out side-by-side — matches the
// My Jetpack page's content width.
-.jetpack-seo-overview {
+.root {
max-inline-size: 1128px;
margin-inline: auto;
}
-.jetpack-seo-overview__grid {
+.grid {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
gap: var(--wpds-dimension-gap-lg);
align-items: stretch;
}
-// Make each Overview card a flex column so its body stretches and equal-height
-// cards line up across the row. Targets Card.Root's last child (Card.Content),
-// since @wordpress/ui uses hashed (non-stable) class names.
-.jetpack-seo-overview__grid > * {
- display: flex;
- flex-direction: column;
- height: 100%;
-}
-
-.jetpack-seo-overview__grid > * > *:last-child {
- display: flex;
- flex-direction: column;
+// Let each status card's content fill the equal-height grid row so its action
+// stays pinned to the bottom.
+.cardContent {
flex: 1 1 auto;
}
// A status row in the Site verification card: indicator + label on the left,
// "Verified"/"Not set" on the right.
-.jetpack-seo-overview__stat-row {
- display: flex;
- align-items: center;
- justify-content: space-between;
- padding: var(--wpds-dimension-gap-xs) 0;
+.statRow {
+ padding-block: var(--wpds-dimension-gap-xs);
}
// Card action row (Manage button), pinned to the bottom-right of the card.
-.jetpack-seo-overview__card-footer {
- display: flex;
- justify-content: flex-end;
- margin-top: auto;
- padding-top: var(--wpds-dimension-gap-md);
+.footer {
+ margin-block-start: auto;
+ padding-block-start: var(--wpds-dimension-gap-md);
}
// Content SEO card: factual coverage rings. An auto-fit grid (matching the
// Overview card grid above) so the rings flow into as many columns as fit
// (up to four) and stack down to a single column as the screen narrows —
// rather than shrinking to share a single row at every width.
-.jetpack-seo-overview__coverage-rings {
+.rings {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(160px, 1fr));
gap: var(--wpds-dimension-gap-lg);
}
-.jetpack-seo-overview__coverage-ring {
- display: flex;
- flex-direction: column;
- align-items: center;
+.ring {
text-align: center;
- gap: var(--wpds-dimension-gap-xs);
// Let the cell shrink below its content width so long labels wrap inside
// the grid track instead of forcing the column wider.
- min-width: 0;
-}
-
-.jetpack-seo-overview__coverage-count {
- font-weight: 600;
-}
-
-.jetpack-seo-overview__coverage-label {
- // Inherit the card's text color rather than the muted `-neutral-weak` variant,
- // so the metric labels match the rest of the text on the page.
- font-size: 12px;
+ min-inline-size: 0;
}
// The Content SEO card sits below the two status cards, spanning the full
// width of its own row. Margin matches the grid gap above it.
-.jetpack-seo-overview__content-card {
- margin-top: var(--wpds-dimension-gap-lg);
+.contentCard {
+ margin-block-start: var(--wpds-dimension-gap-lg);
}
// Low-emphasis "disable SEO tools" off-ramp at the foot of the Overview.
-.jetpack-seo-overview__disable {
- margin-top: var(--wpds-dimension-gap-lg);
+.disable {
+ margin-block-start: var(--wpds-dimension-gap-lg);
color: var(--wpds-color-foreground-content-neutral-weak);
- font-size: 13px;
}
diff --git a/projects/packages/seo/_inc/screens/settings/social-previews-card.tsx b/projects/packages/seo/_inc/screens/settings/social-previews-card.tsx
index 79e8e6f657eb..e50bb50d2955 100644
--- a/projects/packages/seo/_inc/screens/settings/social-previews-card.tsx
+++ b/projects/packages/seo/_inc/screens/settings/social-previews-card.tsx
@@ -1,7 +1,7 @@
/* eslint-disable jsdoc/require-param, jsdoc/require-returns */
import { __ } from '@wordpress/i18n';
-import { Card, CollapsibleCard } from '@wordpress/ui';
+import { Card, CollapsibleCard, Stack, Text } from '@wordpress/ui';
import getSite from '../../data/get-site';
import type { SiteData } from '../../data/get-site';
import type { FC } from 'react';
@@ -68,14 +68,22 @@ const XIcon: FC = () => (
/** How the home page appears as a Google search result. */
const GooglePreview: FC< PreviewProps > = ( { site, description } ) => (
-
-
+
+
{ site.icon && }
- { hostname( site.url ) }
-
-
{ site.title }
- { description &&
{ description }
}
-
+
+ { hostname( site.url ) }
+
+
+
+ { site.title }
+
+ { description && (
+
+ { description }
+
+ ) }
+
);
/**
@@ -91,11 +99,17 @@ const LinkCardPreview: FC< PreviewProps > = ( { site, description } ) => (
style={ { backgroundImage: `url(${ site.image })` } }
/>
) }
-
-
{ hostname( site.url ) }
-
{ site.title }
- { description &&
{ description }
}
-
+
+
+ { hostname( site.url ) }
+
+ { site.title }
+ { description && (
+
+ { description }
+
+ ) }
+
);
@@ -132,37 +146,45 @@ const SocialPreviewsCard: FC< Props > = ( { description } ) => {
);
diff --git a/projects/packages/seo/_inc/screens/settings/style.scss b/projects/packages/seo/_inc/screens/settings/style.scss
index 2f446792e3d9..7c1a9cbbfdac 100644
--- a/projects/packages/seo/_inc/screens/settings/style.scss
+++ b/projects/packages/seo/_inc/screens/settings/style.scss
@@ -50,7 +50,7 @@
// spaced between adjacent rows.
.jetpack-seo-settings__title-row + .jetpack-seo-settings__title-row {
padding-block-start: var(--wpds-dimension-gap-lg);
- border-block-start: 1px solid var(--wpds-color-stroke-surface-neutral-weak);
+ border-block-start: var(--wpds-border-width-xs) solid var(--wpds-color-stroke-surface-neutral-weak);
}
// The insert-placeholder buttons and their caption, grouped tight under the
@@ -173,31 +173,6 @@
min-block-size: 40px;
}
-// Intro copy above the preview list.
-.jetpack-seo-settings__preview-intro {
- margin: 0 0 var(--wpds-dimension-gap-xl);
-}
-
-// The previews stack with generous separation between them. Each preview is
-// bordered individually (below); there's no bordered group wrapping a heading
-// together with its preview, which avoids the box-in-box look.
-.jetpack-seo-settings__preview-list {
- display: flex;
- flex-direction: column;
- gap: var(--wpds-dimension-gap-2xl);
-}
-
-// Platform label above each preview: brand icon + name, prominent enough to
-// scan, with clear space before the card it describes.
-.jetpack-seo-settings__preview-label {
- display: flex;
- align-items: center;
- gap: 8px;
- margin: 0 0 var(--wpds-dimension-gap-md);
- font-size: 15px;
- font-weight: 600;
-}
-
.jetpack-seo-preview__platform-icon {
inline-size: 18px;
block-size: 18px;
@@ -208,11 +183,9 @@
// the look of each platform with plain markup.
.jetpack-seo-preview {
max-inline-size: 500px;
- font-size: 14px;
- line-height: 1.4;
}
-.jetpack-seo-preview__desc {
+.jetpack-seo-preview__muted {
color: var(--wpds-color-foreground-content-neutral-weak);
}
@@ -220,36 +193,19 @@
// otherwise), set off as a result beneath its heading.
.jetpack-seo-preview--google {
padding: var(--wpds-dimension-padding-md);
- border: 1px solid var(--wpds-color-stroke-surface-neutral-weak);
+ border: var(--wpds-border-width-xs) solid var(--wpds-color-stroke-surface-neutral-weak);
border-radius: var(--wpds-border-radius-md);
- .jetpack-seo-preview__google-site {
- display: flex;
- align-items: center;
- gap: 8px;
- }
-
.jetpack-seo-preview__favicon {
inline-size: 26px;
block-size: 26px;
border-radius: 50%;
- border: 1px solid var(--wpds-color-stroke-surface-neutral-weak);
+ border: var(--wpds-border-width-xs) solid var(--wpds-color-stroke-surface-neutral-weak);
object-fit: cover;
}
- .jetpack-seo-preview__google-url {
- font-size: 12px;
- color: #4d5156;
- }
-
.jetpack-seo-preview__google-title {
- margin-block-start: 4px;
- font-size: 20px;
- color: #1a0dab;
- }
-
- .jetpack-seo-preview__desc {
- margin-block-start: 4px;
+ color: var(--wpds-color-foreground-interactive-brand);
}
}
@@ -258,7 +214,7 @@
// its heading.
.jetpack-seo-preview--card {
overflow: hidden;
- border: 1px solid var(--wpds-color-stroke-surface-neutral-weak);
+ border: var(--wpds-border-width-xs) solid var(--wpds-color-stroke-surface-neutral-weak);
border-radius: var(--wpds-border-radius-md);
.jetpack-seo-preview__image {
@@ -279,17 +235,7 @@
}
.jetpack-seo-preview__card-domain {
- font-size: 12px;
text-transform: uppercase;
color: var(--wpds-color-foreground-content-neutral-weak);
}
-
- .jetpack-seo-preview__card-title {
- margin-block-start: 2px;
- font-weight: 600;
- }
-
- .jetpack-seo-preview__desc {
- margin-block-start: 2px;
- }
}
diff --git a/projects/packages/seo/changelog/migrate-seo-dashboard-styles-to-css-modules b/projects/packages/seo/changelog/migrate-seo-dashboard-styles-to-css-modules
new file mode 100644
index 000000000000..5feadf885d67
--- /dev/null
+++ b/projects/packages/seo/changelog/migrate-seo-dashboard-styles-to-css-modules
@@ -0,0 +1,4 @@
+Significance: patch
+Type: changed
+Comment: Migrate shared, Content, and Overview dashboard styles to CSS Modules without changing user-facing behavior.
+