Skip to content

Restyle all plugin badges per the refreshed design system #13361

Closed

Description

@techanvil

Feature Description

The hub's cards carry badges — New, Paid service — and the design system has moved on since Site Kit's badges were built: corners are less rounded now, and the New badge's colours are the other way round, the lighter shade behind the darker text rather than the reverse.

The design system gives those colours badge by badge, naming each by the words it carries — New, Recommended, Beta, Paid service, and so on — and read across the set they fall into a handful of groups by what they tell the user. So this issue is as much about which badge belongs to which group as it is about the colours: Beta and Experimental are both grey today while they say quite different things, and New is shown one way in some places and another elsewhere.

This is a design-system change, not a hub one. Rather than have the hub style its own badges and leave the rest of the plugin looking dated beside it, the shared badge styling is updated once and every badge in Site Kit picks up the new look, with the hub simply using them as they come. The work is plugin-wide, and so is the check on it.

For reference, see the UI component architecture section in the design doc, and the refreshed badge designs in the Figma design system.


Do not alter or remove anything below. The following sections will be managed by moderators only.

Acceptance criteria

  • Every badge in Site Kit takes a reduced corner radius, and its colours from the refreshed design system. Those colours group into six treatments by what the badge tells the user, and every badge belongs to one of them wherever it appears:
    • Announcement — violet — New, Beta.
    • Recommendation — blue — Recommended.
    • Cost — green — Paid service.
    • Experimental — pink — Experimental.
    • Warning — amber — Action needed, Temporarily hidden, Partial data, Gathering data and Gathering breakdown data.
  • A badge these groups don't name joins the one whose meaning fits it, rather than keeping its old look or being given a colour of its own. And where the same text is styled differently in different places — New is plain grey in selection panels, Recommended has a style of its own on the setup splash screen — it converges on a single look.
  • Recommended for you and Requires plugin update are in the design system but unused in the plugin, so they're out of scope here.
  • The empty badges used only to reserve space, in the visitor group tiles and the dashboard data blocks, go on reserving exactly the space they do now and take no colour.
  • The badges whose text comes from data rather than a fixed label — the percentage change badges, and the PageSpeed ratings in the PDF report — keep the colours they have today and take the corner radius alone.
  • The corner radius reaches every badge, including those drawn into the PDF report from outside Site Kit's stylesheets, and reaches nothing else: the rounding shared with buttons, chips and tabs is left as it is.
  • The change is made to Site Kit's shared badges, so no hub-specific badge styling is left behind — including any the hub's cards introduced ahead of this issue (Build FeatureCard + EffortIndicator (Storybook) #13320).
  • The badges match the Figma design system.

Implementation Brief

Establish the shared badge system first, then roll it out and remove the styling it supersedes.

In assets/sass/config/_variables-mui3.scss

  • Add $br-xxs: 4px for the reduced corner radius. Do not change $br-lg, which resolves to 100px and is shared with buttons, chips and tabs.
  • Add a $c-badge-{group}-background / $c-badge-{group}-text pair for each semantic group in the ACs, pointing at existing ramps. Backgrounds take the -50 step and text -500, except warning, whose text is -700. Note the AC colour names do not all map to the ramp/token of the same name: green is $c-site-kit-sk-*, and amber is $c-yellow-y-*. Leave the $c-utility-* tokens in place — around fourteen non-badge rules still use them.

Create assets/js/components/Badge/constants.ts

  • Export a BADGE_VARIANTS const enum whose members are the semantic groups from the ACs, following Notice/constants.ts, including its per-member doc comments where a group needs explaining.

Move assets/js/components/Badge.js to assets/js/components/Badge/index.tsx

  • Convert to TypeScript as part of the move. Replace the PropTypes block with a colocated BadgeProps interface and the FC< BadgeProps > plus forwardRef< HTMLSpanElement, BadgeProps > form documented in component-conventions.md, keeping the types in the component file rather than a types.ts. The interface must admit arbitrary span attributes, since the component spreads the rest of its props and DataBlock/Content passes aria-hidden through it.
  • Move Badge.stories.js alongside it as index.stories.tsx, following Typography for the index.* naming and Notice for the TypeScript story form. Existing @/js/components/Badge imports resolve unchanged; only the story's relative import needs adjusting.
  • Add an optional variant prop typed against BADGE_VARIANTS, rendering googlesitekit-badge--${ variant } alongside the base class as Notice does with type. No default — omitting it must leave the badge uncoloured, which the space-reserving usage relies on. Keep className for layout and spacing.
  • Leave NewBadge.js and BadgeWithTooltip.js flat. SetupModule imports NewBadge with an explicit .js extension, which a move would break.

In assets/js/components/BadgeWithTooltip.js

  • Add the same variant prop, defaulting to the warning group and overridable — mirroring Notice's default and preserving current behaviour, since the component is hardcoded amber today. Note it renders its own element rather than composing Badge, so it applies the variant class itself. This file is modified in place rather than moved, so it stays JavaScript and validates the prop with PropTypes.oneOf( Object.values( BADGE_VARIANTS ) ), as Notice/Icon.js does against NOTICE_TYPES.

In assets/sass/components/global/_googlesitekit-badge.scss

  • Apply $br-xxs and add a rule per semantic group reading from the new badge tokens. Re-point the existing --warning modifier from $c-utility-warning-container / $c-utility-on-warning-container to the badge tokens; these resolve to the same values, so its colour is unchanged and only its radius moves. Variant rules should never read $c-utility-* or a raw ramp directly.
  • Remove the --primary, --beta and --warning colour modifiers once callers are migrated. Keep --hidden and --has-left-spacing, which are layout.

In assets/sass/components/global/_googlesitekit-badge-with-tooltip.scss and _googlesitekit-new-badge.scss

  • Take the badge and info-icon colours from the variant rather than hardcoding them; the icon should use the variant's text colour.
  • Reduce _googlesitekit-new-badge.scss to its spacing and tooltip rules, dropping the colours the announcement variant now provides.

In assets/sass/components/global/_googlesitekit-change-badge.scss

  • Apply $br-xxs only. Change badges are data-driven and keep their colours, as do the PageSpeed rating badges.

In assets/sass/components/key-metrics/_googlesitekit-chip-tab-group.scss

  • Remove the badge override, which re-declares violet by hand and is why "New" renders differently in the chip tabs. Spacing-only badge overrides elsewhere may remain.

In assets/sass/components/setup/_googlesitekit-splash.scss

  • Reduce the .googlesitekit-splash__analytics-recommended-badge selector to the spacing rules only (margin-left), dropping the colours and border-radius the variant now provides.

Across the badge call sites

  • Pass the appropriate variant per the groupings in the ACs, dropping the colour class where one is passed. 12 files need a variant added, 7 of which pass a colour class today. Note that Beta now belongs to the announcement group alongside New, so the four sites currently passing googlesitekit-badge--beta take the same variant as the New badges:
    • assets/js/components/NewBadge.js
    • assets/js/components/KeyMetrics/KeyMetricsNewBadge.js
    • assets/js/components/SelectionPanel/SelectionPanelItem.js
    • assets/js/components/settings/SettingsCardConsentMode.js
    • assets/js/components/settings/SetupModule.js — two badges, different variants
    • assets/js/components/settings/SettingsActiveModule/Header.js — two badges, different variants
    • assets/js/components/google-tag-gateway/GoogleTagGatewayToggle.js
    • assets/js/components/setup/SetupUsingProxyWithSignIn/AnalyticsOptIn.tsx
    • assets/js/modules/adsense/components/common/UseSnippetSwitch.js
    • assets/js/modules/sign-in-with-google/components/setup/SetupMain.js
    • assets/js/modules/pagespeed-insights/components/common/ReportMetric.js
    • assets/js/modules/reader-revenue-manager/components/settings/SettingsStatus.tsx — a warning-group label rendering Badge directly, so it must state its variant rather than inheriting BadgeWithTooltip's default
    • assets/js/components/feature-discovery/FeatureCard.tsx – Its badges come from a map of feature badge slugs to props carrying their labels, so each entry in that map needs a variant adding, rather than a variant being passed
  • Components consuming the NewBadge wrapper need no change, since the wrapper sets its own variant; nor do the BadgeWithTooltip callers, which are all warning-group and inherit its default.
  • Define the Cost group's token pair, style rule, and story, but do not introduce that badge into any existing UI, since nothing renders it yet. The two design-system badges the ACs omit are out of scope, since the plugin doesn't use them.
  • Leave the space-reserving badge in assets/js/components/DataBlock/Content.js as it is. It uses the --hidden modifier with a placeholder label to reserve height, passes no variant, and so keeps its current dimensions without colour.

In assets/js/components/pdf-export/

  • Apply the new radius to PDFBadge, whose radius is set in a React-PDF stylesheet rather than SCSS and so is not reached by the SCSS changes.
  • Align PDFPartialDataBadge with the warning group's text colour. It carries a fixed label rather than data-driven text, so the ACs' data-driven exemption does not cover it, and it currently takes its text from YELLOW_Y_600 — a step lighter than the warning token, so the PDF and on-screen versions of that badge differ today. This needs YELLOW_Y_700 adding to the PDF_COLORS map in pdf-theme.ts, which mirrors the SCSS tokens by hand with the token name in a trailing comment.

Test Coverage

  • Add unit tests for Badge and BadgeWithTooltip as .tsx, neither of which has any today, covering that each variant produces its modifier class, that omitting variant leaves Badge uncoloured while BadgeWithTooltip falls back to its default, that an explicit variant overrides that default, and that a caller-supplied className still applies.
  • Regenerate the four snapshots that capture badge markup — GoogleTagGatewayToggle, SetupUsingProxyWithSignIn, AudienceTilesWidget/AudienceTile and the site-goals IntroModalBanner. Two contain googlesitekit-badge--beta outright, and all four capture a className that changes once badges carry a variant.
  • Update the two PDF badge tests that assert on values this issue changes: PDFBadge.test.tsx asserts the old borderRadius twice, and PDFPartialDataBadge.test.tsx asserts YELLOW_Y_600. PDFChangeBadge.test.tsx asserts colours only and is unaffected.
  • No other existing unit tests need updating; the three that reference a badge class all query base classes that survive, and none asserts on the modifiers being removed.
  • No PHPUnit or E2E changes needed; badges are entirely client-side and no E2E test references one.
  • Add per-variant stories for both components, plus an aggregate "all variants" VRT story each, following the pattern used for buttons and links. This is required for capture — Backstop only emits a scenario for a story declaring a scenario object, and the current Badge story declares none, which is why no badge reference image exists today.
  • VRT changes expected: two new references from the aggregate stories, plus re-approval of the five existing scenarios that render badges — the tooltip badge, the forced-open new badge, the selection panel, and the two audience selection panel scenarios. The warning badge's colours do not change, so an unchanged warning badge is the expected result there.

QA Brief

Every badge in the plugin changes shape in this issue, and most also change colour, to match the Figma design linked in the issue. Buttons, chips and tabs keep their pill shape and must be unchanged.

  • Connect and complete setup for Analytics and AdSense.
  • In Site Kit Tester → General, enable the featureDiscoveryHub and setupFlowRefresh feature flags, and set Force initial Site Kit plugin version to 1.0.0. The version is what makes the hub show its New badges; setupFlowRefresh keeps the visitor groups and key metrics widgets from being hidden.
  • In Site Kit Tester → Analytics → General, set Force Analytics Audiences to has-site-kit-created-audiences and Force Analytics report data to all-reports-random-data.
  • In Site Kit Tester → Analytics → Partial Data, set Force Analytics audience partial data state to last-7-days.
  • Go to Site Kit → Add Features → All services and features. On the card Increase your visibility in Search, check there is a violet New badge and a green Paid service badge, both matching Figma.
  • Go to Site Kit → Settings → Connect More Services. Check the Beta badge beside Sign in with Google is violet — it was grey before this change.
  • Go to Site Kit → Settings → Connected Services → AdSense → Edit. Check the Recommended badge beside Let Site Kit place AdSense code on your site is blue.
  • Go to the Site Kit dashboard → Traffic tab and find the visitor groups tiles. Check each tile header shows an amber Partial data badge, and that the ⓘ icon inside the badge is the same dark amber as the badge's text — not grey.
  • In Site Kit Tester → Analytics → Conversion Reporting, set Force "New" badge for selected events to Force new badge for selected events and select every event under "New" badge events. Save, then open Change metrics on the Key metrics tab: the New badges are now pale violet with violet text, where they were solid violet with white text before this change. This is the only badge in the plugin that inverts, so it is worth looking at closely.
  • Open Select groups on the Traffic tab and check its New badges are the same pale violet. They were grey before this change.
  • On the Key metrics tab, add a numeric metric such as New visitors via Change metrics. Check its percentage change badge keeps its existing colours — green for a rise, red for a fall, grey for no change — with the Figma corner radius.
  • Use the Download PDF report icon in the top right of the dashboard header. Check the badges in the PDF have the same corner radius as on the dashboard, and that a Partial data badge in the PDF is the same amber as the dashboard one.
  • Across all of the above, check that buttons, chips and dashboard tabs still have their pill shape. Their radius must not change.

Notes for the tester

The Experimental variant has no instance anywhere in the plugin, so check it in Storybook under Components/Badge rather than hunting for a screen.

The empty space-reserving badge is invisible by design and nothing renders it, so there is nothing to look at. It is covered by unit and visual regression tests.

Changelog entry

  • Update all badges to match the new design.

Activity

  1. added
    Team MIssues for Squad 2
    and removed
    Team MIssues for Squad 2
    on Aug 18, 2026
  2. self-assigned this
    on Sep 2, 2026
  3. techanvil commented on Sep 7, 2026

    @techanvil
    CollaboratorAuthor

    Hi @ncoetzer! Thanks for drafting this IB, which is looking good. A few points:

    • It's worth a note that the splash screen "Recommended" badge needs its SCSS colour override removing.
    • PDFPartialDataBadge will need updating to align with the text warning colour.
    • All new files (including moves) should be TypeScript.
    • "No existing unit tests need updating" is not correct - some snapshots will need updating, and PDF badge tests will need a couple of tweaks.
    • I've raised the AA contrast issue with @sigal-teller on Figma, we should get this resolved during the definition phase for the issue.
  4. 19 remaining items

  5. ncoetzer commented on Sep 29, 2026

    @ncoetzer
    Collaborator

    A few things changed between writing the IB and executing it, mostly because the work for #13320 merged into develop in between:

    • Badge was already TypeScript. The conversion the IB describes was already on develop, so only the directory move and the variant prop were left to do.
    • FeatureCard is now a call site, via a FEATURE_BADGE_PROPS map carrying a // TODO: #13361 marker. This makes the Cost group live, where the IB expected it to be defined but unused — the Ads module declares it. The map's third entry, Recommended for you, is given the recommendation variant for consistency but stays unused in the plugin, as the ACs describe.
    • PDFChangeBadge.test.tsx needed updating. Test Coverage says it is unaffected; it also asserts borderRadius, so three PDF tests changed rather than two.
    • Variant rules set custom properties rather than colours directly. The audience and site goals tiles set their own color on .googlesitekit-info-tooltip, so a currentColor fill turned the tooltip icon grey; reading a custom property keeps the badge's text colour in any context.
    • VRT is 54 scenarios, not 7. The IB expected two new references plus five re-approvals. Most scenarios that render a badge give no hint of it in their name, so a plugin-wide badge change reaches most of the settings and dashboard chrome — 158 reference images in total.
    • Experimental and the space-reserving badge have no UI. EXPERIMENTAL_MODULES is empty and nothing passes experimental to the PageSpeed rows; nothing passes badge to DataBlock. Both are implemented and unit-tested but cannot be seen, which the QA Brief notes.

    I've left the IB and ACs as they are rather than editing them after the fact — happy to update either if you'd prefer.

  6. removed their assignment
    on Sep 29, 2026
  7. techanvil commented on Sep 29, 2026

    @techanvil
    CollaboratorAuthor

    Thanks for the context, @ncoetzer!

    Leave the IB and AC as they were is the right call at this stage.

  8. self-assigned this
    on Sep 30, 2026
  9. assigned and unassigned on Oct 7, 2026
  10. removed their assignment
    on Oct 7, 2026
  11. self-assigned this
    on Oct 8, 2026
  12. kelvinballoo commented on Oct 8, 2026

    @kelvinballoo
    Collaborator

    QA Update ⚠️

    This is mostly tested good.

    2 Items to flag however:

    ITEM 1:

    Based on Figma, the paddings are 4px top and bottom and 8 px on the sides.

    Details Image

    But our implementation shows 6px top, bottom and 10 px on the sides.
    Is that an intentional change?

    Details Image Image Image

    ITEM 2:

    I noticed that for the 'New' badges on the Key metrics selection panel, there is a 1px margin on the right side of the badges.
    Again, is that intentional?

    Details Image
  13. ncoetzer commented on Oct 8, 2026

    @ncoetzer
    Collaborator

    @kelvinballoo Thanks for the review and feedback. In short, both are real, but the spacing in both cases predates this PR.

    For item 1, the 6px/10px comes from the tooltip badge's own class. Badges without a tooltip are already 4px/8px. The same applies to item 2: the 1px margin was already there, and since the IB and AC only mentioned color and border radius updates, everything else was left as is.

    That said, this should be fixed, and to avoid delays for this issue moving forward, I created a separate issue for it (#13822) — it needs its own PR that will include additional VRT updates.

  14. removed their assignment
    on Oct 8, 2026
  15. kelvinballoo commented on Oct 9, 2026

    @kelvinballoo
    Collaborator

    QA Update ✅

    Thanks for the update @ncoetzer

    With that, i'll move this to approval as the badges reflect the new design, inclusive of the PDF generated.

    Details Image Image Image Image Image Image Image Image Image

    13361 - 08 - PDF.pdf

  16. removed their assignment
    on Oct 9, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    P0High priorityTeam MIssues for Squad 2Type: EnhancementImprovement of an existing feature

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions