Repository: Automattic/wp-calypso
Pull request #103029: Add PoweredBy component
Author: login: dsas
Created: 2025-04-30T20:53:15Z | Merged: 2025-05-08T11:29:11Z

<!--
Link a related issue to this PR. If the PR does not immediately resolve the issue,
for example, it requires a separate deployment to production, avoid
using the "fixes" keyword and instead attach the [Status] Fix Inbound label to
the linked issue.
-->

Related to #102185 / DS-54

## Proposed Changes

Add a PoweredBy automattic/component like in this figma: [dhW7zYBamXJIeJIE3wy5f4-fi-111_474](https://href.li/?https://www.figma.com/file/dhW7zYBamXJIeJIE3wy5f4/?node-id=111-474)
Make it available in the branding colours, and in black and white

## Why are these changes being made?
<!--
It's easy to see what a PR does but much harder to find out why it was made,
particularly when researching old changes in history. Record an explanation of
the motivation behind this change and how it will help.
-->

The PoweredBy component will be used to bring consistency to the product across WordPress.com and beyond. Sometimes we say " powered" and sometimes we say "Powered by ", this state of affairs cannot continue.

## Testing Instructions

<!--
Add as many details as possible to help others reproduce the issue and test the fix.
"Before / After" screenshots can also be very helpful when the change is visual.
-->

### PoweredBy

1. Checkout the branch locally
2. Run `yarn && yarn run start` as normal
3. Run `yarn components:storybook:start`
4. Go to the `PoweredBy` component and have a play

You should see it looks like this:

![Screen Shot 2025-04-30 at 21 54 11-fullpage](https://github.com/user-attachments/assets/b92b4cf4-5f6a-447b-8cfb-29f08f248e83)



If you look at the JetpackLogo and WooLogo components, you will see that by default they look identically to how they do in the trunk storybook.

## Pre-merge Checklist

<!--
Complete applicable items on this checklist **before** merging into trunk. Inapplicable items can be left unchecked.

Both the PR author and reviewer are responsible for ensuring the checklist is completed.
-->

- [ ] Has the general commit checklist been followed? (PCYsg-hS-p2)
- [ ] [Have you written new tests](https://wpcalypso.wordpress.com/devdocs/docs/testing/index.md) for your changes?
- [ ] Have you tested the feature in Simple (P9HQHe-k8-p2), Atomic (P9HQHe-jW-p2), and self-hosted Jetpack sites (PCYsg-g6b-p2)?
- [ ] Have you checked for TypeScript, React or other console errors?
- [ ] Have you used memoizing on expensive computations? More info in [Memoizing with create-selector](https://github.com/Automattic/wp-calypso/blob/trunk/packages/state-utils/src/create-selector/README.md) and [Using memoizing selectors](https://react-redux.js.org/api/hooks#using-memoizing-selectors) and [Our Approach to Data](https://github.com/Automattic/wp-calypso/blob/trunk/docs/our-approach-to-data.md)
- [ ] Have we added the "[Status] String Freeze" label as soon as any new strings were ready for translation (p4TIVU-5Jq-p2)?
    - [ ] For UI changes, have we tested the change in various languages (for example, ES, PT, FR, or DE)? The length of text and words vary significantly between languages. 
- [ ] For changes affecting Jetpack: Have we added the "[Status] Needs Privacy Updates" label if this pull request changes what data or activity we track or use (p4TIVU-aUh-p2)?



Diff:
diff --git a/packages/components/src/index.ts b/packages/components/src/index.ts
index db6644b153a2..82eb1a2bf86e 100644
--- a/packages/components/src/index.ts
+++ b/packages/components/src/index.ts
@@ -71,3 +71,4 @@ export { ExperienceControl } from './experience-control';
 export { default as SummaryButton } from './summary-button';
 export { default as CoreBadge } from './core-badge';
 export { default as Menu } from './menu';
+export { PoweredBy } from './powered-by';
diff --git a/packages/components/src/logos/jetpack-logo/index.tsx b/packages/components/src/logos/jetpack-logo/index.tsx
index 67287343bc71..19d2c35adae2 100644
--- a/packages/components/src/logos/jetpack-logo/index.tsx
+++ b/packages/components/src/logos/jetpack-logo/index.tsx
@@ -8,6 +8,8 @@ const PALETTE = colorStudio.colors;
 const COLOR_JETPACK = PALETTE[ 'Jetpack Green 40' ];
 const COLOR_WHITE = PALETTE[ 'White' ]; // eslint-disable-line dot-notation
 
+export type JetpackLogoColorVariant = 'color' | 'black' | 'white';
+
 type JetpackLogoProps = {
 	/**
 	 * Whether to render the full logo.
@@ -24,27 +26,46 @@ type JetpackLogoProps = {
 	 * @default false
 	 */
 	monochrome?: boolean;
+	/**
+	 * Color variant
+	 * @default 'color'
+	 */
+	colorVariant?: JetpackLogoColorVariant;
+	className?: string;
 };
 
-const LogoPathSize32 = ( { monochrome = false }: Pick< JetpackLogoProps, 'monochrome' > ) => {
-	const primary = monochrome ? 'white' : COLOR_JETPACK;
-	const secondary = monochrome ? 'black' : COLOR_WHITE;
+const getJetpackColors = ( colorVariant: JetpackLogoColorVariant ) => {
+	switch ( colorVariant ) {
+		case 'black':
+			return { primary: 'black', secondary: 'white' };
+		case 'white':
+			return { primary: 'white', secondary: 'black' };
+		case 'color':
+		default:
+			return { primary: COLOR_JETPACK, secondary: COLOR_WHITE };
+	}
+};
 
+const LogoPathSize32 = ( {
+	colorVariant = 'color',
+	monochrome = false,
+}: Pick< JetpackLogoProps, 'colorVariant' | 'monochrome' > ) => {
+	const { primary, secondary } = getJetpackColors( colorVariant );
 	return (
 		<>
 			<path
 				className="jetpack-logo__icon-circle"
-				fill={ primary }
+				fill={ monochrome ? 'white' : primary }
 				d="M16,0C7.2,0,0,7.2,0,16s7.2,16,16,16s16-7.2,16-16S24.8,0,16,0z"
 			/>
 			<polygon
 				className="jetpack-logo__icon-triangle"
-				fill={ secondary }
+				fill={ monochrome ? 'black' : secondary }
 				points="15,19 7,19 15,3 "
 			/>
 			<polygon
 				className="jetpack-logo__icon-triangle"
-				fill={ secondary }
+				fill={ monochrome ? 'black' : secondary }
 				points="17,29 17,13 25,13 "
 			/>
 		</>
@@ -64,22 +85,40 @@ const LogoPathSize32Monochrome = () => (
 	</>
 );
 
+/**
+ * JetpackLogo component
+ *
+ * The 'colorVariant' prop controls the color scheme of the logo: 'color', 'black', or 'white'.
+ * - 'color': Uses Jetpack green and white (default).
+ * - 'black': Renders the logo in black and white.
+ * - 'white': Renders the logo in white and black (for dark backgrounds).
+ *
+ * The 'monochrome' prop, when true, overrides the 'colorVariant' and renders the logo and text in a single color scheme:
+ * - The icon is white, and the text and triangles are black, regardless of the 'colorVariant'.
+ */
 export const JetpackLogo = ( {
 	full = false,
 	monochrome = false,
 	size = 32,
+	colorVariant = 'color',
 	className,
 	...props
 }: JetpackLogoProps & React.SVGProps< SVGSVGElement > ) => {
 	const classes = clsx( 'jetpack-logo', className );
 
 	if ( full === true ) {
+		const textFill = colorVariant === 'white' && ! monochrome ? '#fff' : '#151E25';
 		return (
 			<svg height={ size } className={ classes } viewBox="0 0 118 32" { ...props }>
 				<title>Jetpack</title>
-				{ monochrome ? <LogoPathSize32Monochrome /> : <LogoPathSize32 /> }
+				{ monochrome ? (
+					<LogoPathSize32Monochrome />
+				) : (
+					<LogoPathSize32 colorVariant={ colorVariant } />
+				) }
 				<path
 					className="jetpack-logo__text"
+					fill={ textFill }
 					d="M41.3 26.6c-.5-.7-.9-1.4-1.3-2.1 2.3-1.4 3-2.5 3-4.6V8h-3V6h6v13.4C46 22.8 45 24.8 41.3 26.6zM58.5 21.3c-1.5.5-2.7.6-4.2.6-3.6 0-5.8-1.8-5.8-6 0-3.1 1.9-5.9 5.5-5.9s4.9 2.5 4.9 4.9c0 .8 0 1.5-.1 2h-7.3c.1 2.5 1.5 2.8 3.6 2.8 1.1 0 2.2-.3 3.4-.7C58.5 19 58.5 21.3 58.5 21.3zM56 15c0-1.4-.5-2.9-2-2.9-1.4 0-2.3 1.3-2.4 2.9C51.6 15 56 15 56 15zM65 18.4c0 1.1.8 1.3 1.4 1.3.5 0 2-.2 2.6-.4v2.1c-.9.3-2.5.5-3.7.5-1.5 0-3.2-.5-3.2-3.1V12H60v-2h2.1V7.1H65V10h4v2h-4V18.4zM71 10h3v1.3c1.1-.8 1.9-1.3 3.3-1.3 2.5 0 4.5 1.8 4.5 5.6s-2.2 6.3-5.8 6.3c-.9 0-1.3-.1-2-.3V28h-3V10zM76.5 12.3c-.8 0-1.6.4-2.5 1.2v5.9c.6.1.9.2 1.8.2 2 0 3.2-1.3 3.2-3.9C79 13.4 78.1 12.3 76.5 12.3zM93 22h-3v-1.5c-.9.7-1.9 1.5-3.5 1.5-1.5 0-3.1-1.1-3.1-3.2 0-2.9 2.5-3.4 4.2-3.7l2.4-.3v-.3c0-1.5-.5-2.3-2-2.3-.7 0-2.3.5-3.7 1.1L84 11c1.2-.4 3-1 4.4-1 2.7 0 4.6 1.4 4.6 4.7L93 22zM90 16.4l-2.2.4c-.7.1-1.4.5-1.4 1.6 0 .9.5 1.4 1.3 1.4s1.5-.5 2.3-1V16.4zM104.5 21.3c-1.1.4-2.2.6-3.5.6-4.2 0-5.9-2.4-5.9-5.9 0-3.7 2.3-6 6.1-6 1.4 0 2.3.2 3.2.5V13c-.8-.3-2-.6-3.2-.6-1.7 0-3.2.9-3.2 3.6 0 2.9 1.5 3.8 3.3 3.8.9 0 1.9-.2 3.2-.7V21.3zM110 15.2c.2-.3.2-.8 3.8-5.2h3.7l-4.6 5.7 5 6.3h-3.7l-4.2-5.8V22h-3V6h3V15.2z"
 				/>
 			</svg>
@@ -96,7 +135,11 @@ export const JetpackLogo = ( {
 
 	return (
 		<svg className={ classes } height={ size } width={ size } viewBox="0 0 32 32" { ...props }>
-			{ monochrome ? <LogoPathSize32Monochrome /> : <LogoPathSize32 /> }
+			{ monochrome ? (
+				<LogoPathSize32Monochrome />
+			) : (
+				<LogoPathSize32 colorVariant={ colorVariant } />
+			) }
 		</svg>
 	);
 };
diff --git a/packages/components/src/logos/jetpack-logo/stories/index.stories.tsx b/packages/components/src/logos/jetpack-logo/stories/index.stories.tsx
index d76b2d04d03b..a4130c7887f6 100644
--- a/packages/components/src/logos/jetpack-logo/stories/index.stories.tsx
+++ b/packages/components/src/logos/jetpack-logo/stories/index.stories.tsx
@@ -9,16 +9,44 @@ export default meta;
 
 type Story = StoryObj< typeof JetpackLogo >;
 
-export const Default: Story = {};
+export const Color: Story = {
+	args: { colorVariant: 'color' },
+};
+
+export const Black: Story = {
+	args: { colorVariant: 'black' },
+};
+
+export const White: Story = {
+	args: { colorVariant: 'white' },
+	decorators: [
+		( Story ) => (
+			<div style={ { background: '#000', padding: '20px' } }>
+				<Story />
+			</div>
+		),
+	],
+};
+
+export const FullColor: Story = {
+	args: { full: true, colorVariant: 'color' },
+};
+
+export const FullBlack: Story = {
+	args: { full: true, colorVariant: 'black' },
+};
 
-export const Full: Story = {
-	args: {
-		full: true,
-	},
+export const FullWhite: Story = {
+	args: { full: true, colorVariant: 'white' },
+	decorators: [
+		( Story ) => (
+			<div style={ { background: '#000', padding: '20px' } }>
+				<Story />
+			</div>
+		),
+	],
 };
 
 export const Monochrome: Story = {
-	args: {
-		monochrome: true,
-	},
+	args: { monochrome: true },
 };
diff --git a/packages/components/src/logos/woo-logo/index.tsx b/packages/components/src/logos/woo-logo/index.tsx
index 4ef4f9c85929..83bf66866fb9 100644
--- a/packages/components/src/logos/woo-logo/index.tsx
+++ b/packages/components/src/logos/woo-logo/index.tsx
@@ -1,42 +1,60 @@
-export const WooLogo = ( props: React.SVGProps< SVGSVGElement > ) => (
-	<svg
-		version="1.1"
-		id="Layer_1"
-		xmlns="http://www.w3.org/2000/svg"
-		xmlnsXlink="http://www.w3.org/1999/xlink"
-		x="0px"
-		y="0px"
-		width="30"
-		height="19"
-		viewBox="0 0 183.6 47.5"
-		{ ...props }
-	>
-		<style type="text/css">
-			{ `
-				.st0{fill-rule:evenodd;clip-rule:evenodd;fill:#873EFF;}
-				.st1{fill-rule:evenodd;clip-rule:evenodd;}
-				.st2{fill:#873EFF;}
-				.st3{fill-rule:evenodd;clip-rule:evenodd;fill:#FFFFFF;}
-				.st4{fill:#FFFFFF;}
-			` }
-		</style>
-		<g>
-			<path
-				className="st0"
-				d="M77.4,0c-4.3,0-7.1,1.4-9.6,6.1L56.4,27.6V8.5c0-5.7-2.7-8.5-7.7-8.5s-7.1,1.7-9.6,6.5L28.3,27.6V8.7
-				c0-6.1-2.5-8.7-8.6-8.7H7.3C2.6,0,0,2.2,0,6.2s2.5,6.4,7.1,6.4h5.1v24.1c0,6.8,4.6,10.8,11.2,10.8s9.6-2.6,12.9-8.7l7.2-13.5v11.4
-				c0,6.7,4.4,10.8,11.1,10.8s9.2-2.3,13-8.7l16.6-28C87.8,4.7,85.3,0,77.3,0C77.3,0,77.3,0,77.4,0z"
-			/>
-			<path
-				className="st0"
-				d="M108.6,0C95,0,84.7,10.1,84.7,23.8s10.4,23.7,23.9,23.7s23.8-10.1,23.9-23.7C132.5,10.1,122.1,0,108.6,0z
-				 M108.6,32.9c-5.1,0-8.6-3.8-8.6-9.1s3.5-9.2,8.6-9.2s8.6,3.9,8.6,9.2S113.8,32.9,108.6,32.9z"
-			/>
-			<path
-				className="st0"
-				d="M159.7,0c-13.5,0-23.9,10.1-23.9,23.8s10.4,23.7,23.9,23.7s23.9-10.1,23.9-23.7S173.2,0,159.7,0z M159.7,32.9
-				c-5.2,0-8.5-3.8-8.5-9.1s3.4-9.2,8.5-9.2s8.6,3.9,8.6,9.2S164.9,32.9,159.7,32.9z"
-			/>
-		</g>
-	</svg>
-);
+import colorStudio from '@automattic/color-studio';
+
+const PALETTE = colorStudio.colors;
+const COLOR_WOO_PURPLE = PALETTE[ 'WooCommerce Purple 40' ];
+
+export type WooLogoColorVariant = 'color' | 'black' | 'white';
+
+interface WooLogoProps extends React.SVGProps< SVGSVGElement > {
+	colorVariant?: WooLogoColorVariant;
+	height?: number;
+	width?: number;
+}
+
+export const WooLogo = ( {
+	colorVariant = 'color',
+	height = 19,
+	width = 30,
+	...props
+}: WooLogoProps ) => {
+	let fill = COLOR_WOO_PURPLE;
+	if ( colorVariant === 'white' ) {
+		fill = '#fff';
+	} else if ( colorVariant === 'black' ) {
+		fill = '#000';
+	}
+
+	return (
+		<svg
+			version="1.1"
+			id="Layer_1"
+			xmlns="http://www.w3.org/2000/svg"
+			xmlnsXlink="http://www.w3.org/1999/xlink"
+			x="0px"
+			y="0px"
+			width={ width }
+			height={ height }
+			viewBox="0 0 183.6 47.5"
+			{ ...props }
+		>
+			<g>
+				<path
+					fill={ fill }
+					d="M77.4,0c-4.3,0-7.1,1.4-9.6,6.1L56.4,27.6V8.5c0-5.7-2.7-8.5-7.7-8.5s-7.1,1.7-9.6,6.5L28.3,27.6V8.7
+					c0-6.1-2.5-8.7-8.6-8.7H7.3C2.6,0,0,2.2,0,6.2s2.5,6.4,7.1,6.4h5.1v24.1c0,6.8,4.6,10.8,11.2,10.8s9.6-2.6,12.9-8.7l7.2-13.5v11.4
+					c0,6.7,4.4,10.8,11.1,10.8s9.2-2.3,13-8.7l16.6-28C87.8,4.7,85.3,0,77.3,0C77.3,0,77.3,0,77.4,0z"
+				/>
+				<path
+					fill={ fill }
+					d="M108.6,0C95,0,84.7,10.1,84.7,23.8s10.4,23.7,23.9,23.7s23.8-10.1,23.9-23.7C132.5,10.1,122.1,0,108.6,0z
+					 M108.6,32.9c-5.1,0-8.6-3.8-8.6-9.1s3.5-9.2,8.6-9.2s8.6,3.9,8.6,9.2S113.8,32.9,108.6,32.9z"
+				/>
+				<path
+					fill={ fill }
+					d="M159.7,0c-13.5,0-23.9,10.1-23.9,23.8s10.4,23.7,23.9,23.7s23.9-10.1,23.9-23.7S173.2,0,159.7,0z M159.7,32.9
+					c-5.2,0-8.5-3.8-8.5-9.1s3.4-9.2,8.5-9.2s8.6,3.9,8.6,9.2S164.9,32.9,159.7,32.9z"
+				/>
+			</g>
+		</svg>
+	);
+};
diff --git a/packages/components/src/logos/woo-logo/stories/index.stories.tsx b/packages/components/src/logos/woo-logo/stories/index.stories.tsx
index 38aa703e5301..66525e3a4ef1 100644
--- a/packages/components/src/logos/woo-logo/stories/index.stories.tsx
+++ b/packages/components/src/logos/woo-logo/stories/index.stories.tsx
@@ -9,4 +9,21 @@ export default meta;
 
 type Story = StoryObj< typeof WooLogo >;
 
-export const Default: Story = {};
+export const Color: Story = {
+	args: { colorVariant: 'color' },
+};
+
+export const Black: Story = {
+	args: { colorVariant: 'black' },
+};
+
+export const White: Story = {
+	args: { colorVariant: 'white' },
+	decorators: [
+		( Story ) => (
+			<div style={ { background: '#000', padding: '20px' } }>
+				<Story />
+			</div>
+		),
+	],
+};
diff --git a/packages/components/src/powered-by/README.md b/packages/components/src/powered-by/README.md
new file mode 100644
index 000000000000..21b261c73462
--- /dev/null
+++ b/packages/components/src/powered-by/README.md
@@ -0,0 +1,27 @@
+# PoweredBy (JSX)
+
+A React component for displaying "Powered by" branding with a logo for Jetpack, WooCommerce, or WordPress.com.
+
+---
+
+## How to use
+
+```js
+import { PoweredBy } from '@automattic/components';
+
+export default function Example() {
+	return (
+		<div>
+			<PoweredBy brand="jetpack" />
+			<PoweredBy brand="woocommerce" colorVariant="black" />
+			<PoweredBy brand="wpcom" colorVariant="white" />
+		</div>
+	);
+}
+```
+
+## Props
+
+- `brand` : (string, required) One of `'jetpack'`, `'woocommerce'`, `'wpcom'`
+- `colorVariant` : (string) One of `'color'`, `'black'`, `'white'`. Default is `'color'`
+- `className` : (string) Additional CSS class names
diff --git a/packages/components/src/powered-by/index.tsx b/packages/components/src/powered-by/index.tsx
new file mode 100644
index 000000000000..7bdec472ec09
--- /dev/null
+++ b/packages/components/src/powered-by/index.tsx
@@ -0,0 +1,82 @@
+import './style.scss';
+
+import colorStudio from '@automattic/color-studio';
+import { createInterpolateElement } from '@wordpress/element';
+import { __ } from '@wordpress/i18n';
+import clsx from 'clsx';
+import React from 'react';
+import { JetpackLogo } from '../logos/jetpack-logo';
+import { WooLogo } from '../logos/woo-logo';
+import WordPressWordmark from '../wordpress-wordmark';
+
+const PALETTE = colorStudio.colors;
+const COLOR_WPCOM_BLUE = PALETTE[ 'Blue 50' ];
+const COLOR_WHITE = PALETTE[ 'White' ];
+const COLOR_BLACK = PALETTE[ 'Black' ];
+
+export type PoweredByBrand = 'jetpack' | 'woocommerce' | 'wpcom';
+export type PoweredByVariant = 'color' | 'black' | 'white';
+
+interface PoweredByProps {
+	brand: PoweredByBrand;
+	colorVariant?: PoweredByVariant;
+	className?: string;
+}
+
+const getBrandName = ( brand: PoweredByBrand ) => {
+	switch ( brand ) {
+		case 'jetpack':
+			return 'Jetpack';
+		case 'woocommerce':
+			return 'WooCommerce';
+		case 'wpcom':
+			return 'WordPress.com';
+	}
+};
+
+const getWordPressWordmarkColor = ( colorVariant: PoweredByVariant ) => {
+	switch ( colorVariant ) {
+		case 'white':
+			return COLOR_WHITE;
+		case 'black':
+			return COLOR_BLACK;
+		default:
+			return COLOR_WPCOM_BLUE;
+	}
+};
+
+const PoweredBy = ( { brand, colorVariant = 'color', className }: PoweredByProps ) => {
+	let LogoComponent: React.ReactNode = null;
+
+	switch ( brand ) {
+		case 'jetpack':
+			LogoComponent = <JetpackLogo colorVariant={ colorVariant } size={ 25 } full />;
+			break;
+		case 'woocommerce':
+			LogoComponent = <WooLogo colorVariant={ colorVariant } height={ 25 } width={ 66 } />;
+			break;
+		case 'wpcom':
+			LogoComponent = (
+				<WordPressWordmark
+					color={ getWordPressWordmarkColor( colorVariant ) }
+					size={ { height: 25, width: 'auto' } }
+				/>
+			);
+			break;
+	}
+
+	return (
+		<p className={ clsx( 'powered-by', className, `is-${ brand }`, `is-${ colorVariant }` ) }>
+			{ createInterpolateElement( __( '<text>Powered by</text> <logo/>', 'calypso' ), {
+				text: <span className="powered-by__text" />,
+				logo: (
+					<span className="powered-by__logo" aria-label={ getBrandName( brand ) }>
+						{ LogoComponent }
+					</span>
+				),
+			} ) }
+		</p>
+	);
+};
+
+export { PoweredBy };
diff --git a/packages/components/src/powered-by/powered-by.stories.tsx b/packages/components/src/powered-by/powered-by.stories.tsx
new file mode 100644
index 000000000000..b4da24da177c
--- /dev/null
+++ b/packages/components/src/powered-by/powered-by.stories.tsx
@@ -0,0 +1,91 @@
+import { PoweredBy } from './index';
+import type { Meta, StoryObj } from '@storybook/react';
+
+const meta: Meta< typeof PoweredBy > = {
+	title: 'packages/components/PoweredBy',
+	component: PoweredBy,
+};
+export default meta;
+
+type Story = StoryObj< typeof PoweredBy >;
+
+export const Jetpack: Story = {
+	args: {
+		brand: 'jetpack',
+	},
+};
+
+export const JetpackBlack: Story = {
+	args: {
+		brand: 'jetpack',
+		colorVariant: 'black',
+	},
+};
+
+export const JetpackWhite: Story = {
+	args: {
+		brand: 'jetpack',
+		colorVariant: 'white',
+	},
+	decorators: [
+		( Story ) => (
+			<div style={ { background: '#000', padding: '20px' } }>
+				<Story />
+			</div>
+		),
+	],
+};
+
+export const WPCom: Story = {
+	args: {
+		brand: 'wpcom',
+	},
+};
+
+export const WPComBlack: Story = {
+	args: {
+		brand: 'wpcom',
+		colorVariant: 'black',
+	},
+};
+
+export const WPComWhite: Story = {
+	args: {
+		brand: 'wpcom',
+		colorVariant: 'white',
+	},
+	decorators: [
+		( Story ) => (
+			<div style={ { background: '#000', padding: '20px' } }>
+				<Story />
+			</div>
+		),
+	],
+};
+
+export const WooCommerce: Story = {
+	args: {
+		brand: 'woocommerce',
+	},
+};
+
+export const WooCommerceBlack: Story = {
+	args: {
+		brand: 'woocommerce',
+		colorVariant: 'black',
+	},
+};
+
+export const WooCommerceWhite: Story = {
+	args: {
+		brand: 'woocommerce',
+		colorVariant: 'white',
+	},
+	decorators: [
+		( Story ) => (
+			<div style={ { background: '#000', padding: '20px' } }>
+				<Story />
+			</div>
+		),
+	],
+};
diff --git a/packages/components/src/powered-by/style.scss b/packages/components/src/powered-by/style.scss
new file mode 100644
index 000000000000..28ed2b3ba453
--- /dev/null
+++ b/packages/components/src/powered-by/style.scss
@@ -0,0 +1,30 @@
+@import '@wordpress/base-styles/variables';
+
+.powered-by {
+	display: inline-flex;
+	flex-wrap: wrap;
+	align-items: center;
+	gap: $grid-unit-10;
+	margin: 20px;
+
+	&__text {
+		color: var( --color-text );
+		white-space: nowrap;
+	}
+
+	&__logo {
+		display: inline-flex;
+
+		.wpcom-wordmark {
+			margin-top: -4px; // Adjust vertical alignment for WordPress.com wordmark
+		}
+	}
+
+	&.is-white &__text {
+		color: #fff;
+	}
+
+	.powered-by-logo {
+		display: block;
+	}
+}
\ No newline at end of file


Reviews:
user: login: BogdanUngureanu
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-05-07T09:34:21Z
user: login: dsas
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-05-07T09:40:29Z
user: login: dsas
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-05-07T09:41:04Z
user: login: BogdanUngureanu
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-05-07T10:03:19Z
user: login: dsas
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-05-07T10:20:02Z
user: login: BogdanUngureanu
body: LGTM!
state: APPROVED
author_association: CONTRIBUTOR
submitted_at: 2025-05-07T10:31:03Z
user: login: ciampo
body: Thank you for working on this component!

I didn't notice the PR before it got merged, but I've got a few suggestions for improving the API layer of the components affected by this change.

Given that we're planning on releasing a new version of the package soon (see https://github.com/Automattic/wp-calypso/pull/103160), I wonder if we should consider reverting this PR to avoid releasing APIs that we may soon change (which would be a breaking change) and/or to otherwise delay the upcoming release.

cc @Automattic/team-calypso @youknowriad  @simison 
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-05-08T20:48:36Z
user: login: dsas
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-05-08T20:57:28Z
user: login: dsas
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-05-09T09:59:52Z
user: login: dsas
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-05-09T10:07:49Z
user: login: dsas
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-05-09T10:11:20Z
user: login: jameskoster
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-05-09T12:59:59Z
user: login: ciampo
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-05-09T21:44:53Z

Review comments:
diff_hunk: @@ -0,0 +1,82 @@
+import './style.scss';
+
+import colorStudio from '@automattic/color-studio';
+import { createInterpolateElement } from '@wordpress/element';
+import { __ } from '@wordpress/i18n';
+import clsx from 'clsx';
+import React from 'react';
+import { JetpackLogo } from '../logos/jetpack-logo';
+import { WooLogo } from '../logos/woo-logo';
+import WordPressWordmark from '../wordpress-wordmark';
+
+const PALETTE = colorStudio.colors;
+const COLOR_WPCOM_BLUE = PALETTE[ 'Blue 50' ];
+const COLOR_WHITE = PALETTE[ 'White' ];
+const COLOR_BLACK = PALETTE[ 'Black' ];
+
+export type PoweredByBrand = 'jetpack' | 'woocommerce' | 'wpcom';
+export type PoweredByVariant = 'color' | 'black' | 'white';
+
+interface PoweredByProps {
+	brand: PoweredByBrand;
+	colorVariant?: PoweredByVariant;
+	className?: string;
+}
+
+const getBrandName = ( brand: PoweredByBrand ) => {
+	switch ( brand ) {
+		case 'jetpack':
+			return 'Jetpack';
+		case 'woocommerce':
+			return 'WooCommerce';
+		case 'wpcom':
+			return 'WordPress.com';
+	}
+};
+
+const getWordPressWordmarkColor = ( colorVariant: PoweredByVariant ) => {
+	switch ( colorVariant ) {
+		case 'white':
+			return COLOR_WHITE;
+		case 'black':
+			return COLOR_BLACK;
+		default:
+			return COLOR_WPCOM_BLUE;
+	}
+};
+
+const PoweredBy = ( { brand, colorVariant = 'color', className }: PoweredByProps ) => {
+	let LogoComponent: React.ReactNode = null;
+
+	switch ( brand ) {
+		case 'jetpack':
+			LogoComponent = <JetpackLogo colorVariant={ colorVariant } size={ 25 } full />;
+			break;
+		case 'woocommerce':
+			LogoComponent = <WooLogo colorVariant={ colorVariant } height={ 25 } width={ 66 } />;
+			break;
+		case 'wpcom':
+			LogoComponent = (
+				<WordPressWordmark
+					color={ getWordPressWordmarkColor( colorVariant ) }
+					size={ { height: 25, width: 'auto' } }
+				/>
+			);
+			break;
+	}
+
+	return (
+		<p className={ clsx( 'powered-by', className, `is-${ brand }`, `is-${ colorVariant }` ) }>
+			{ createInterpolateElement( __( '<text>Powered by</text> <logo/>', 'calypso' ), {
path: packages/components/src/powered-by/index.tsx
user: login: BogdanUngureanu
body: Should this text be translatable? 
created_at: 2025-05-07T09:34:21Z
author_association: CONTRIBUTOR
diff_hunk: @@ -0,0 +1,82 @@
+import './style.scss';
+
+import colorStudio from '@automattic/color-studio';
+import { createInterpolateElement } from '@wordpress/element';
+import { __ } from '@wordpress/i18n';
+import clsx from 'clsx';
+import React from 'react';
+import { JetpackLogo } from '../logos/jetpack-logo';
+import { WooLogo } from '../logos/woo-logo';
+import WordPressWordmark from '../wordpress-wordmark';
+
+const PALETTE = colorStudio.colors;
+const COLOR_WPCOM_BLUE = PALETTE[ 'Blue 50' ];
+const COLOR_WHITE = PALETTE[ 'White' ];
+const COLOR_BLACK = PALETTE[ 'Black' ];
+
+export type PoweredByBrand = 'jetpack' | 'woocommerce' | 'wpcom';
+export type PoweredByVariant = 'color' | 'black' | 'white';
+
+interface PoweredByProps {
+	brand: PoweredByBrand;
+	colorVariant?: PoweredByVariant;
+	className?: string;
+}
+
+const getBrandName = ( brand: PoweredByBrand ) => {
+	switch ( brand ) {
+		case 'jetpack':
+			return 'Jetpack';
+		case 'woocommerce':
+			return 'WooCommerce';
+		case 'wpcom':
+			return 'WordPress.com';
+	}
+};
+
+const getWordPressWordmarkColor = ( colorVariant: PoweredByVariant ) => {
+	switch ( colorVariant ) {
+		case 'white':
+			return COLOR_WHITE;
+		case 'black':
+			return COLOR_BLACK;
+		default:
+			return COLOR_WPCOM_BLUE;
+	}
+};
+
+const PoweredBy = ( { brand, colorVariant = 'color', className }: PoweredByProps ) => {
+	let LogoComponent: React.ReactNode = null;
+
+	switch ( brand ) {
+		case 'jetpack':
+			LogoComponent = <JetpackLogo colorVariant={ colorVariant } size={ 25 } full />;
+			break;
+		case 'woocommerce':
+			LogoComponent = <WooLogo colorVariant={ colorVariant } height={ 25 } width={ 66 } />;
+			break;
+		case 'wpcom':
+			LogoComponent = (
+				<WordPressWordmark
+					color={ getWordPressWordmarkColor( colorVariant ) }
+					size={ { height: 25, width: 'auto' } }
+				/>
+			);
+			break;
+	}
+
+	return (
+		<p className={ clsx( 'powered-by', className, `is-${ brand }`, `is-${ colorVariant }` ) }>
+			{ createInterpolateElement( __( '<text>Powered by</text> <logo/>', 'calypso' ), {
path: packages/components/src/powered-by/index.tsx
user: login: dsas
body: I don't see why it shouldn't be
created_at: 2025-05-07T09:40:29Z
author_association: CONTRIBUTOR
diff_hunk: @@ -0,0 +1,82 @@
+import './style.scss';
+
+import colorStudio from '@automattic/color-studio';
+import { createInterpolateElement } from '@wordpress/element';
+import { __ } from '@wordpress/i18n';
+import clsx from 'clsx';
+import React from 'react';
+import { JetpackLogo } from '../logos/jetpack-logo';
+import { WooLogo } from '../logos/woo-logo';
+import WordPressWordmark from '../wordpress-wordmark';
+
+const PALETTE = colorStudio.colors;
+const COLOR_WPCOM_BLUE = PALETTE[ 'Blue 50' ];
+const COLOR_WHITE = PALETTE[ 'White' ];
+const COLOR_BLACK = PALETTE[ 'Black' ];
+
+export type PoweredByBrand = 'jetpack' | 'woocommerce' | 'wpcom';
+export type PoweredByVariant = 'color' | 'black' | 'white';
+
+interface PoweredByProps {
+	brand: PoweredByBrand;
+	colorVariant?: PoweredByVariant;
+	className?: string;
+}
+
+const getBrandName = ( brand: PoweredByBrand ) => {
+	switch ( brand ) {
+		case 'jetpack':
+			return 'Jetpack';
+		case 'woocommerce':
+			return 'WooCommerce';
+		case 'wpcom':
+			return 'WordPress.com';
+	}
+};
+
+const getWordPressWordmarkColor = ( colorVariant: PoweredByVariant ) => {
+	switch ( colorVariant ) {
+		case 'white':
+			return COLOR_WHITE;
+		case 'black':
+			return COLOR_BLACK;
+		default:
+			return COLOR_WPCOM_BLUE;
+	}
+};
+
+const PoweredBy = ( { brand, colorVariant = 'color', className }: PoweredByProps ) => {
+	let LogoComponent: React.ReactNode = null;
+
+	switch ( brand ) {
+		case 'jetpack':
+			LogoComponent = <JetpackLogo colorVariant={ colorVariant } size={ 25 } full />;
+			break;
+		case 'woocommerce':
+			LogoComponent = <WooLogo colorVariant={ colorVariant } height={ 25 } width={ 66 } />;
+			break;
+		case 'wpcom':
+			LogoComponent = (
+				<WordPressWordmark
+					color={ getWordPressWordmarkColor( colorVariant ) }
+					size={ { height: 25, width: 'auto' } }
+				/>
+			);
+			break;
+	}
+
+	return (
+		<p className={ clsx( 'powered-by', className, `is-${ brand }`, `is-${ colorVariant }` ) }>
+			{ createInterpolateElement( __( '<text>Powered by</text> <logo/>', 'calypso' ), {
path: packages/components/src/powered-by/index.tsx
user: login: dsas
body: though it doesn't need the 'calypso' there 🤔 
created_at: 2025-05-07T09:41:04Z
author_association: CONTRIBUTOR
diff_hunk: @@ -0,0 +1,82 @@
+import './style.scss';
+
+import colorStudio from '@automattic/color-studio';
+import { createInterpolateElement } from '@wordpress/element';
+import { __ } from '@wordpress/i18n';
+import clsx from 'clsx';
+import React from 'react';
+import { JetpackLogo } from '../logos/jetpack-logo';
+import { WooLogo } from '../logos/woo-logo';
+import WordPressWordmark from '../wordpress-wordmark';
+
+const PALETTE = colorStudio.colors;
+const COLOR_WPCOM_BLUE = PALETTE[ 'Blue 50' ];
+const COLOR_WHITE = PALETTE[ 'White' ];
+const COLOR_BLACK = PALETTE[ 'Black' ];
+
+export type PoweredByBrand = 'jetpack' | 'woocommerce' | 'wpcom';
+export type PoweredByVariant = 'color' | 'black' | 'white';
+
+interface PoweredByProps {
+	brand: PoweredByBrand;
+	colorVariant?: PoweredByVariant;
+	className?: string;
+}
+
+const getBrandName = ( brand: PoweredByBrand ) => {
+	switch ( brand ) {
+		case 'jetpack':
+			return 'Jetpack';
+		case 'woocommerce':
+			return 'WooCommerce';
+		case 'wpcom':
+			return 'WordPress.com';
+	}
+};
+
+const getWordPressWordmarkColor = ( colorVariant: PoweredByVariant ) => {
+	switch ( colorVariant ) {
+		case 'white':
+			return COLOR_WHITE;
+		case 'black':
+			return COLOR_BLACK;
+		default:
+			return COLOR_WPCOM_BLUE;
+	}
+};
+
+const PoweredBy = ( { brand, colorVariant = 'color', className }: PoweredByProps ) => {
+	let LogoComponent: React.ReactNode = null;
+
+	switch ( brand ) {
+		case 'jetpack':
+			LogoComponent = <JetpackLogo colorVariant={ colorVariant } size={ 25 } full />;
+			break;
+		case 'woocommerce':
+			LogoComponent = <WooLogo colorVariant={ colorVariant } height={ 25 } width={ 66 } />;
+			break;
+		case 'wpcom':
+			LogoComponent = (
+				<WordPressWordmark
+					color={ getWordPressWordmarkColor( colorVariant ) }
+					size={ { height: 25, width: 'auto' } }
+				/>
+			);
+			break;
+	}
+
+	return (
+		<p className={ clsx( 'powered-by', className, `is-${ brand }`, `is-${ colorVariant }` ) }>
+			{ createInterpolateElement( __( '<text>Powered by</text> <logo/>', 'calypso' ), {
path: packages/components/src/powered-by/index.tsx
user: login: BogdanUngureanu
body: IMHO translating branding is more complicated than simply translating a text. 

For example, in Stats footer we right now display "Propulsate de Jetpack (logo)" for Romanian (it should be Propulsat de X, but that's not important). 

However, a literal translation in Romanian doesn't make much sense. Every Romanian site (or ads, or anything) I have seen uses the English version (Powered by X) - I haven't seen someone say "Propulsat de X". 

On a side note, in Romanian Propulsat is more used as "propelled", which is a bit funny for "Jetpack". 

What I'm trying to say is that branding might also be related to cultural usage(?). :) 
created_at: 2025-05-07T10:03:19Z
author_association: CONTRIBUTOR
diff_hunk: @@ -0,0 +1,82 @@
+import './style.scss';
+
+import colorStudio from '@automattic/color-studio';
+import { createInterpolateElement } from '@wordpress/element';
+import { __ } from '@wordpress/i18n';
+import clsx from 'clsx';
+import React from 'react';
+import { JetpackLogo } from '../logos/jetpack-logo';
+import { WooLogo } from '../logos/woo-logo';
+import WordPressWordmark from '../wordpress-wordmark';
+
+const PALETTE = colorStudio.colors;
+const COLOR_WPCOM_BLUE = PALETTE[ 'Blue 50' ];
+const COLOR_WHITE = PALETTE[ 'White' ];
+const COLOR_BLACK = PALETTE[ 'Black' ];
+
+export type PoweredByBrand = 'jetpack' | 'woocommerce' | 'wpcom';
+export type PoweredByVariant = 'color' | 'black' | 'white';
+
+interface PoweredByProps {
+	brand: PoweredByBrand;
+	colorVariant?: PoweredByVariant;
+	className?: string;
+}
+
+const getBrandName = ( brand: PoweredByBrand ) => {
+	switch ( brand ) {
+		case 'jetpack':
+			return 'Jetpack';
+		case 'woocommerce':
+			return 'WooCommerce';
+		case 'wpcom':
+			return 'WordPress.com';
+	}
+};
+
+const getWordPressWordmarkColor = ( colorVariant: PoweredByVariant ) => {
+	switch ( colorVariant ) {
+		case 'white':
+			return COLOR_WHITE;
+		case 'black':
+			return COLOR_BLACK;
+		default:
+			return COLOR_WPCOM_BLUE;
+	}
+};
+
+const PoweredBy = ( { brand, colorVariant = 'color', className }: PoweredByProps ) => {
+	let LogoComponent: React.ReactNode = null;
+
+	switch ( brand ) {
+		case 'jetpack':
+			LogoComponent = <JetpackLogo colorVariant={ colorVariant } size={ 25 } full />;
+			break;
+		case 'woocommerce':
+			LogoComponent = <WooLogo colorVariant={ colorVariant } height={ 25 } width={ 66 } />;
+			break;
+		case 'wpcom':
+			LogoComponent = (
+				<WordPressWordmark
+					color={ getWordPressWordmarkColor( colorVariant ) }
+					size={ { height: 25, width: 'auto' } }
+				/>
+			);
+			break;
+	}
+
+	return (
+		<p className={ clsx( 'powered-by', className, `is-${ brand }`, `is-${ colorVariant }` ) }>
+			{ createInterpolateElement( __( '<text>Powered by</text> <logo/>', 'calypso' ), {
path: packages/components/src/powered-by/index.tsx
user: login: dsas
body: That sounds like it's maybe an issue with the Romanian localisation rather than an issue with the internationalisation.

If the norm in Romanian is to use the English phrase "powered by", then the Romanian translators can freely do that.
created_at: 2025-05-07T10:20:02Z
author_association: CONTRIBUTOR
diff_hunk: @@ -0,0 +1,82 @@
+import './style.scss';
+
+import colorStudio from '@automattic/color-studio';
+import { createInterpolateElement } from '@wordpress/element';
+import { __ } from '@wordpress/i18n';
+import clsx from 'clsx';
+import React from 'react';
+import { JetpackLogo } from '../logos/jetpack-logo';
+import { WooLogo } from '../logos/woo-logo';
+import WordPressWordmark from '../wordpress-wordmark';
+
+const PALETTE = colorStudio.colors;
+const COLOR_WPCOM_BLUE = PALETTE[ 'Blue 50' ];
+const COLOR_WHITE = PALETTE[ 'White' ];
+const COLOR_BLACK = PALETTE[ 'Black' ];
+
+export type PoweredByBrand = 'jetpack' | 'woocommerce' | 'wpcom';
+export type PoweredByVariant = 'color' | 'black' | 'white';
+
+interface PoweredByProps {
+	brand: PoweredByBrand;
+	colorVariant?: PoweredByVariant;
+	className?: string;
+}
+
+const getBrandName = ( brand: PoweredByBrand ) => {
+	switch ( brand ) {
+		case 'jetpack':
+			return 'Jetpack';
+		case 'woocommerce':
+			return 'WooCommerce';
+		case 'wpcom':
+			return 'WordPress.com';
+	}
+};
+
+const getWordPressWordmarkColor = ( colorVariant: PoweredByVariant ) => {
+	switch ( colorVariant ) {
+		case 'white':
+			return COLOR_WHITE;
+		case 'black':
+			return COLOR_BLACK;
+		default:
+			return COLOR_WPCOM_BLUE;
+	}
+};
+
+const PoweredBy = ( { brand, colorVariant = 'color', className }: PoweredByProps ) => {
+	let LogoComponent: React.ReactNode = null;
+
+	switch ( brand ) {
+		case 'jetpack':
+			LogoComponent = <JetpackLogo colorVariant={ colorVariant } size={ 25 } full />;
+			break;
+		case 'woocommerce':
+			LogoComponent = <WooLogo colorVariant={ colorVariant } height={ 25 } width={ 66 } />;
+			break;
+		case 'wpcom':
+			LogoComponent = (
+				<WordPressWordmark
+					color={ getWordPressWordmarkColor( colorVariant ) }
+					size={ { height: 25, width: 'auto' } }
+				/>
+			);
+			break;
+	}
+
+	return (
+		<p className={ clsx( 'powered-by', className, `is-${ brand }`, `is-${ colorVariant }` ) }>
+			{ createInterpolateElement( __( '<text>Powered by</text> <logo/>', 'calypso' ), {
path: packages/components/src/powered-by/index.tsx
user: login: ciampo
body: If the context of in which the text is translated can make a difference (eg. WordPress.com, Jetpack, WooCommerce...), why hardcode `calypso`  though?
created_at: 2025-05-08T20:15:44Z
author_association: CONTRIBUTOR
diff_hunk: @@ -64,22 +85,40 @@ const LogoPathSize32Monochrome = () => (
 	</>
 );
 
+/**
+ * JetpackLogo component
+ *
+ * The 'colorVariant' prop controls the color scheme of the logo: 'color', 'black', or 'white'.
+ * - 'color': Uses Jetpack green and white (default).
+ * - 'black': Renders the logo in black and white.
+ * - 'white': Renders the logo in white and black (for dark backgrounds).
+ *
+ * The 'monochrome' prop, when true, overrides the 'colorVariant' and renders the logo and text in a single color scheme:
+ * - The icon is white, and the text and triangles are black, regardless of the 'colorVariant'.
+ */
path: packages/components/src/logos/jetpack-logo/index.tsx
user: login: ciampo
body: Having props that conditionally override other props can cause confusion in the consumers of the component. A better alternative is to have a single "variant" prop with all the options.

Also, I'm not convinced about `white` and `black` variants, as they don't take theming into account. For example, would a white variant change to black on a dark theme?

Also, we actually don't use pure black for our text color, meaning that the variant name may be misleading, and that currently the text and the logo don't use the same color in the `black` variant.

Maybe we could just have a `currentColor` variant and use whatever text color is inherited from the CSS cascade (ie. `currentColor`)?

(cc @jameskoster )
created_at: 2025-05-08T20:22:26Z
author_association: CONTRIBUTOR
diff_hunk: @@ -1,42 +1,60 @@
-export const WooLogo = ( props: React.SVGProps< SVGSVGElement > ) => (
-	<svg
-		version="1.1"
-		id="Layer_1"
-		xmlns="http://www.w3.org/2000/svg"
-		xmlnsXlink="http://www.w3.org/1999/xlink"
-		x="0px"
-		y="0px"
-		width="30"
-		height="19"
-		viewBox="0 0 183.6 47.5"
-		{ ...props }
-	>
-		<style type="text/css">
-			{ `
-				.st0{fill-rule:evenodd;clip-rule:evenodd;fill:#873EFF;}
-				.st1{fill-rule:evenodd;clip-rule:evenodd;}
-				.st2{fill:#873EFF;}
-				.st3{fill-rule:evenodd;clip-rule:evenodd;fill:#FFFFFF;}
-				.st4{fill:#FFFFFF;}
-			` }
-		</style>
-		<g>
-			<path
-				className="st0"
-				d="M77.4,0c-4.3,0-7.1,1.4-9.6,6.1L56.4,27.6V8.5c0-5.7-2.7-8.5-7.7-8.5s-7.1,1.7-9.6,6.5L28.3,27.6V8.7
-				c0-6.1-2.5-8.7-8.6-8.7H7.3C2.6,0,0,2.2,0,6.2s2.5,6.4,7.1,6.4h5.1v24.1c0,6.8,4.6,10.8,11.2,10.8s9.6-2.6,12.9-8.7l7.2-13.5v11.4
-				c0,6.7,4.4,10.8,11.1,10.8s9.2-2.3,13-8.7l16.6-28C87.8,4.7,85.3,0,77.3,0C77.3,0,77.3,0,77.4,0z"
-			/>
-			<path
-				className="st0"
-				d="M108.6,0C95,0,84.7,10.1,84.7,23.8s10.4,23.7,23.9,23.7s23.8-10.1,23.9-23.7C132.5,10.1,122.1,0,108.6,0z
-				 M108.6,32.9c-5.1,0-8.6-3.8-8.6-9.1s3.5-9.2,8.6-9.2s8.6,3.9,8.6,9.2S113.8,32.9,108.6,32.9z"
-			/>
-			<path
-				className="st0"
-				d="M159.7,0c-13.5,0-23.9,10.1-23.9,23.8s10.4,23.7,23.9,23.7s23.9-10.1,23.9-23.7S173.2,0,159.7,0z M159.7,32.9
-				c-5.2,0-8.5-3.8-8.5-9.1s3.4-9.2,8.5-9.2s8.6,3.9,8.6,9.2S164.9,32.9,159.7,32.9z"
-			/>
-		</g>
-	</svg>
-);
+import colorStudio from '@automattic/color-studio';
+
+const PALETTE = colorStudio.colors;
+const COLOR_WOO_PURPLE = PALETTE[ 'WooCommerce Purple 40' ];
+
+export type WooLogoColorVariant = 'color' | 'black' | 'white';
+
+interface WooLogoProps extends React.SVGProps< SVGSVGElement > {
+	colorVariant?: WooLogoColorVariant;
+	height?: number;
+	width?: number;
path: packages/components/src/logos/woo-logo/index.tsx
user: login: ciampo
body: We may not need to define `width` and `height` explicitly, as they should be already defined in `React.SVGProps< SVGSVGElement >`
created_at: 2025-05-08T20:26:12Z
author_association: CONTRIBUTOR
diff_hunk: @@ -0,0 +1,82 @@
+import './style.scss';
+
+import colorStudio from '@automattic/color-studio';
+import { createInterpolateElement } from '@wordpress/element';
+import { __ } from '@wordpress/i18n';
+import clsx from 'clsx';
+import React from 'react';
+import { JetpackLogo } from '../logos/jetpack-logo';
+import { WooLogo } from '../logos/woo-logo';
+import WordPressWordmark from '../wordpress-wordmark';
+
+const PALETTE = colorStudio.colors;
+const COLOR_WPCOM_BLUE = PALETTE[ 'Blue 50' ];
+const COLOR_WHITE = PALETTE[ 'White' ];
+const COLOR_BLACK = PALETTE[ 'Black' ];
+
+export type PoweredByBrand = 'jetpack' | 'woocommerce' | 'wpcom';
+export type PoweredByVariant = 'color' | 'black' | 'white';
+
+interface PoweredByProps {
+	brand: PoweredByBrand;
+	colorVariant?: PoweredByVariant;
+	className?: string;
+}
+
+const getBrandName = ( brand: PoweredByBrand ) => {
+	switch ( brand ) {
+		case 'jetpack':
+			return 'Jetpack';
+		case 'woocommerce':
+			return 'WooCommerce';
+		case 'wpcom':
+			return 'WordPress.com';
+	}
+};
+
+const getWordPressWordmarkColor = ( colorVariant: PoweredByVariant ) => {
+	switch ( colorVariant ) {
+		case 'white':
+			return COLOR_WHITE;
+		case 'black':
+			return COLOR_BLACK;
+		default:
+			return COLOR_WPCOM_BLUE;
+	}
+};
+
+const PoweredBy = ( { brand, colorVariant = 'color', className }: PoweredByProps ) => {
+	let LogoComponent: React.ReactNode = null;
+
+	switch ( brand ) {
+		case 'jetpack':
+			LogoComponent = <JetpackLogo colorVariant={ colorVariant } size={ 25 } full />;
+			break;
+		case 'woocommerce':
+			LogoComponent = <WooLogo colorVariant={ colorVariant } height={ 25 } width={ 66 } />;
+			break;
+		case 'wpcom':
+			LogoComponent = (
+				<WordPressWordmark
+					color={ getWordPressWordmarkColor( colorVariant ) }
+					size={ { height: 25, width: 'auto' } }
+				/>
+			);
+			break;
+	}
+
+	return (
+		<p className={ clsx( 'powered-by', className, `is-${ brand }`, `is-${ colorVariant }` ) }>
path: packages/components/src/powered-by/index.tsx
user: login: ciampo
body: Let's prefix our classnames with `a8c-components-*` to avoid global scope clashes
created_at: 2025-05-08T20:28:08Z
author_association: CONTRIBUTOR
diff_hunk: @@ -0,0 +1,82 @@
+import './style.scss';
+
+import colorStudio from '@automattic/color-studio';
+import { createInterpolateElement } from '@wordpress/element';
+import { __ } from '@wordpress/i18n';
+import clsx from 'clsx';
+import React from 'react';
+import { JetpackLogo } from '../logos/jetpack-logo';
+import { WooLogo } from '../logos/woo-logo';
+import WordPressWordmark from '../wordpress-wordmark';
+
+const PALETTE = colorStudio.colors;
+const COLOR_WPCOM_BLUE = PALETTE[ 'Blue 50' ];
+const COLOR_WHITE = PALETTE[ 'White' ];
+const COLOR_BLACK = PALETTE[ 'Black' ];
+
+export type PoweredByBrand = 'jetpack' | 'woocommerce' | 'wpcom';
+export type PoweredByVariant = 'color' | 'black' | 'white';
+
+interface PoweredByProps {
+	brand: PoweredByBrand;
+	colorVariant?: PoweredByVariant;
+	className?: string;
+}
+
+const getBrandName = ( brand: PoweredByBrand ) => {
+	switch ( brand ) {
+		case 'jetpack':
+			return 'Jetpack';
+		case 'woocommerce':
+			return 'WooCommerce';
+		case 'wpcom':
+			return 'WordPress.com';
+	}
+};
+
+const getWordPressWordmarkColor = ( colorVariant: PoweredByVariant ) => {
+	switch ( colorVariant ) {
+		case 'white':
+			return COLOR_WHITE;
+		case 'black':
+			return COLOR_BLACK;
+		default:
+			return COLOR_WPCOM_BLUE;
+	}
+};
+
+const PoweredBy = ( { brand, colorVariant = 'color', className }: PoweredByProps ) => {
path: packages/components/src/powered-by/index.tsx
user: login: ciampo
body: Do we ever foresee a need for changing the size of the logo?
created_at: 2025-05-08T20:30:42Z
author_association: CONTRIBUTOR
diff_hunk: @@ -0,0 +1,30 @@
+@import '@wordpress/base-styles/variables';
+
+.powered-by {
+	display: inline-flex;
+	flex-wrap: wrap;
+	align-items: center;
+	gap: $grid-unit-10;
+	margin: 20px;
+
+	&__text {
+		color: var( --color-text );
+		white-space: nowrap;
+	}
+
+	&__logo {
+		display: inline-flex;
+
+		.wpcom-wordmark {
+			margin-top: -4px; // Adjust vertical alignment for WordPress.com wordmark
+		}
+	}
+
+	&.is-white &__text {
+		color: #fff;
+	}
+
+	.powered-by-logo {
+		display: block;
+	}
path: packages/components/src/powered-by/style.scss
user: login: ciampo
body: I believe this code can be deleted?
created_at: 2025-05-08T20:33:02Z
author_association: CONTRIBUTOR
diff_hunk: @@ -0,0 +1,27 @@
+# PoweredBy (JSX)
+
+A React component for displaying "Powered by" branding with a logo for Jetpack, WooCommerce, or WordPress.com.
+
+---
+
+## How to use
+
+```js
+import { PoweredBy } from '@automattic/components';
+
+export default function Example() {
+	return (
+		<div>
+			<PoweredBy brand="jetpack" />
+			<PoweredBy brand="woocommerce" colorVariant="black" />
+			<PoweredBy brand="wpcom" colorVariant="white" />
+		</div>
+	);
+}
+```
+
+## Props
+
+- `brand` : (string, required) One of `'jetpack'`, `'woocommerce'`, `'wpcom'`
+- `colorVariant` : (string) One of `'color'`, `'black'`, `'white'`. Default is `'color'`
path: packages/components/src/powered-by/README.md
user: login: ciampo
body: Same re. `white` and `black` as in a previous comment
created_at: 2025-05-08T20:40:26Z
author_association: CONTRIBUTOR
diff_hunk: @@ -0,0 +1,30 @@
+@import '@wordpress/base-styles/variables';
+
+.powered-by {
+	display: inline-flex;
+	flex-wrap: wrap;
+	align-items: center;
+	gap: $grid-unit-10;
+	margin: 20px;
path: packages/components/src/powered-by/style.scss
user: login: ciampo
body: Let's not add default margins to our components, as it limits their reusability
created_at: 2025-05-08T20:42:28Z
author_association: CONTRIBUTOR
diff_hunk: @@ -0,0 +1,82 @@
+import './style.scss';
+
+import colorStudio from '@automattic/color-studio';
+import { createInterpolateElement } from '@wordpress/element';
+import { __ } from '@wordpress/i18n';
+import clsx from 'clsx';
+import React from 'react';
+import { JetpackLogo } from '../logos/jetpack-logo';
+import { WooLogo } from '../logos/woo-logo';
+import WordPressWordmark from '../wordpress-wordmark';
+
+const PALETTE = colorStudio.colors;
+const COLOR_WPCOM_BLUE = PALETTE[ 'Blue 50' ];
+const COLOR_WHITE = PALETTE[ 'White' ];
+const COLOR_BLACK = PALETTE[ 'Black' ];
+
+export type PoweredByBrand = 'jetpack' | 'woocommerce' | 'wpcom';
+export type PoweredByVariant = 'color' | 'black' | 'white';
+
+interface PoweredByProps {
+	brand: PoweredByBrand;
+	colorVariant?: PoweredByVariant;
+	className?: string;
+}
+
+const getBrandName = ( brand: PoweredByBrand ) => {
+	switch ( brand ) {
+		case 'jetpack':
+			return 'Jetpack';
+		case 'woocommerce':
+			return 'WooCommerce';
+		case 'wpcom':
+			return 'WordPress.com';
+	}
+};
+
+const getWordPressWordmarkColor = ( colorVariant: PoweredByVariant ) => {
+	switch ( colorVariant ) {
+		case 'white':
+			return COLOR_WHITE;
+		case 'black':
+			return COLOR_BLACK;
+		default:
+			return COLOR_WPCOM_BLUE;
+	}
+};
+
+const PoweredBy = ( { brand, colorVariant = 'color', className }: PoweredByProps ) => {
+	let LogoComponent: React.ReactNode = null;
+
+	switch ( brand ) {
+		case 'jetpack':
+			LogoComponent = <JetpackLogo colorVariant={ colorVariant } size={ 25 } full />;
+			break;
+		case 'woocommerce':
+			LogoComponent = <WooLogo colorVariant={ colorVariant } height={ 25 } width={ 66 } />;
+			break;
+		case 'wpcom':
+			LogoComponent = (
+				<WordPressWordmark
+					color={ getWordPressWordmarkColor( colorVariant ) }
+					size={ { height: 25, width: 'auto' } }
+				/>
+			);
+			break;
+	}
+
+	return (
+		<p className={ clsx( 'powered-by', className, `is-${ brand }`, `is-${ colorVariant }` ) }>
path: packages/components/src/powered-by/index.tsx
user: login: ciampo
body: Why use a `p` tag, if later we set its display to be inline? We should probably use a `span` instead.
created_at: 2025-05-08T20:43:14Z
author_association: CONTRIBUTOR
diff_hunk: @@ -0,0 +1,82 @@
+import './style.scss';
+
+import colorStudio from '@automattic/color-studio';
+import { createInterpolateElement } from '@wordpress/element';
+import { __ } from '@wordpress/i18n';
+import clsx from 'clsx';
+import React from 'react';
+import { JetpackLogo } from '../logos/jetpack-logo';
+import { WooLogo } from '../logos/woo-logo';
+import WordPressWordmark from '../wordpress-wordmark';
+
+const PALETTE = colorStudio.colors;
+const COLOR_WPCOM_BLUE = PALETTE[ 'Blue 50' ];
+const COLOR_WHITE = PALETTE[ 'White' ];
+const COLOR_BLACK = PALETTE[ 'Black' ];
+
+export type PoweredByBrand = 'jetpack' | 'woocommerce' | 'wpcom';
+export type PoweredByVariant = 'color' | 'black' | 'white';
+
+interface PoweredByProps {
+	brand: PoweredByBrand;
+	colorVariant?: PoweredByVariant;
+	className?: string;
+}
+
+const getBrandName = ( brand: PoweredByBrand ) => {
+	switch ( brand ) {
+		case 'jetpack':
+			return 'Jetpack';
+		case 'woocommerce':
+			return 'WooCommerce';
+		case 'wpcom':
+			return 'WordPress.com';
+	}
+};
+
+const getWordPressWordmarkColor = ( colorVariant: PoweredByVariant ) => {
+	switch ( colorVariant ) {
+		case 'white':
+			return COLOR_WHITE;
+		case 'black':
+			return COLOR_BLACK;
+		default:
+			return COLOR_WPCOM_BLUE;
+	}
+};
+
+const PoweredBy = ( { brand, colorVariant = 'color', className }: PoweredByProps ) => {
path: packages/components/src/powered-by/index.tsx
user: login: dsas
body: Basically immediately :), https://github.com/Automattic/wp-calypso/pull/103245 to match an existing use
created_at: 2025-05-08T20:57:28Z
author_association: CONTRIBUTOR
diff_hunk: @@ -0,0 +1,30 @@
+@import '@wordpress/base-styles/variables';
+
+.powered-by {
+	display: inline-flex;
+	flex-wrap: wrap;
+	align-items: center;
+	gap: $grid-unit-10;
+	margin: 20px;
path: packages/components/src/powered-by/style.scss
user: login: dsas
body: Makes sense, I think I just took it from the figma.

I think a lot of uses will be in the footer of a page, they'll likely want the same margin and also to be center aligned.
created_at: 2025-05-09T09:59:52Z
author_association: CONTRIBUTOR
diff_hunk: @@ -0,0 +1,82 @@
+import './style.scss';
+
+import colorStudio from '@automattic/color-studio';
+import { createInterpolateElement } from '@wordpress/element';
+import { __ } from '@wordpress/i18n';
+import clsx from 'clsx';
+import React from 'react';
+import { JetpackLogo } from '../logos/jetpack-logo';
+import { WooLogo } from '../logos/woo-logo';
+import WordPressWordmark from '../wordpress-wordmark';
+
+const PALETTE = colorStudio.colors;
+const COLOR_WPCOM_BLUE = PALETTE[ 'Blue 50' ];
+const COLOR_WHITE = PALETTE[ 'White' ];
+const COLOR_BLACK = PALETTE[ 'Black' ];
+
+export type PoweredByBrand = 'jetpack' | 'woocommerce' | 'wpcom';
+export type PoweredByVariant = 'color' | 'black' | 'white';
+
+interface PoweredByProps {
+	brand: PoweredByBrand;
+	colorVariant?: PoweredByVariant;
+	className?: string;
+}
+
+const getBrandName = ( brand: PoweredByBrand ) => {
+	switch ( brand ) {
+		case 'jetpack':
+			return 'Jetpack';
+		case 'woocommerce':
+			return 'WooCommerce';
+		case 'wpcom':
+			return 'WordPress.com';
+	}
+};
+
+const getWordPressWordmarkColor = ( colorVariant: PoweredByVariant ) => {
+	switch ( colorVariant ) {
+		case 'white':
+			return COLOR_WHITE;
+		case 'black':
+			return COLOR_BLACK;
+		default:
+			return COLOR_WPCOM_BLUE;
+	}
+};
+
+const PoweredBy = ( { brand, colorVariant = 'color', className }: PoweredByProps ) => {
+	let LogoComponent: React.ReactNode = null;
+
+	switch ( brand ) {
+		case 'jetpack':
+			LogoComponent = <JetpackLogo colorVariant={ colorVariant } size={ 25 } full />;
+			break;
+		case 'woocommerce':
+			LogoComponent = <WooLogo colorVariant={ colorVariant } height={ 25 } width={ 66 } />;
+			break;
+		case 'wpcom':
+			LogoComponent = (
+				<WordPressWordmark
+					color={ getWordPressWordmarkColor( colorVariant ) }
+					size={ { height: 25, width: 'auto' } }
+				/>
+			);
+			break;
+	}
+
+	return (
+		<p className={ clsx( 'powered-by', className, `is-${ brand }`, `is-${ colorVariant }` ) }>
+			{ createInterpolateElement( __( '<text>Powered by</text> <logo/>', 'calypso' ), {
path: packages/components/src/powered-by/index.tsx
user: login: dsas
body: I don't think the logo context does change how to translate the text.

The Calypso domain was a mistake, which I acknowledged elsewhere and then failed to actually fix. 😞 
created_at: 2025-05-09T10:07:49Z
author_association: CONTRIBUTOR
diff_hunk: @@ -0,0 +1,82 @@
+import './style.scss';
+
+import colorStudio from '@automattic/color-studio';
+import { createInterpolateElement } from '@wordpress/element';
+import { __ } from '@wordpress/i18n';
+import clsx from 'clsx';
+import React from 'react';
+import { JetpackLogo } from '../logos/jetpack-logo';
+import { WooLogo } from '../logos/woo-logo';
+import WordPressWordmark from '../wordpress-wordmark';
+
+const PALETTE = colorStudio.colors;
+const COLOR_WPCOM_BLUE = PALETTE[ 'Blue 50' ];
+const COLOR_WHITE = PALETTE[ 'White' ];
+const COLOR_BLACK = PALETTE[ 'Black' ];
+
+export type PoweredByBrand = 'jetpack' | 'woocommerce' | 'wpcom';
+export type PoweredByVariant = 'color' | 'black' | 'white';
+
+interface PoweredByProps {
+	brand: PoweredByBrand;
+	colorVariant?: PoweredByVariant;
+	className?: string;
+}
+
+const getBrandName = ( brand: PoweredByBrand ) => {
+	switch ( brand ) {
+		case 'jetpack':
+			return 'Jetpack';
+		case 'woocommerce':
+			return 'WooCommerce';
+		case 'wpcom':
+			return 'WordPress.com';
+	}
+};
+
+const getWordPressWordmarkColor = ( colorVariant: PoweredByVariant ) => {
+	switch ( colorVariant ) {
+		case 'white':
+			return COLOR_WHITE;
+		case 'black':
+			return COLOR_BLACK;
+		default:
+			return COLOR_WPCOM_BLUE;
+	}
+};
+
+const PoweredBy = ( { brand, colorVariant = 'color', className }: PoweredByProps ) => {
+	let LogoComponent: React.ReactNode = null;
+
+	switch ( brand ) {
+		case 'jetpack':
+			LogoComponent = <JetpackLogo colorVariant={ colorVariant } size={ 25 } full />;
+			break;
+		case 'woocommerce':
+			LogoComponent = <WooLogo colorVariant={ colorVariant } height={ 25 } width={ 66 } />;
+			break;
+		case 'wpcom':
+			LogoComponent = (
+				<WordPressWordmark
+					color={ getWordPressWordmarkColor( colorVariant ) }
+					size={ { height: 25, width: 'auto' } }
+				/>
+			);
+			break;
+	}
+
+	return (
+		<p className={ clsx( 'powered-by', className, `is-${ brand }`, `is-${ colorVariant }` ) }>
path: packages/components/src/powered-by/index.tsx
user: login: dsas
body: @jameskoster [suggested](https://linear.app/a8c/issue/DS-54/branding-of-powered-by#comment-9a83b166) it might be a good way to contextually inherit the appropriate styles.
created_at: 2025-05-09T10:11:20Z
author_association: CONTRIBUTOR
diff_hunk: @@ -0,0 +1,82 @@
+import './style.scss';
+
+import colorStudio from '@automattic/color-studio';
+import { createInterpolateElement } from '@wordpress/element';
+import { __ } from '@wordpress/i18n';
+import clsx from 'clsx';
+import React from 'react';
+import { JetpackLogo } from '../logos/jetpack-logo';
+import { WooLogo } from '../logos/woo-logo';
+import WordPressWordmark from '../wordpress-wordmark';
+
+const PALETTE = colorStudio.colors;
+const COLOR_WPCOM_BLUE = PALETTE[ 'Blue 50' ];
+const COLOR_WHITE = PALETTE[ 'White' ];
+const COLOR_BLACK = PALETTE[ 'Black' ];
+
+export type PoweredByBrand = 'jetpack' | 'woocommerce' | 'wpcom';
+export type PoweredByVariant = 'color' | 'black' | 'white';
+
+interface PoweredByProps {
+	brand: PoweredByBrand;
+	colorVariant?: PoweredByVariant;
+	className?: string;
+}
+
+const getBrandName = ( brand: PoweredByBrand ) => {
+	switch ( brand ) {
+		case 'jetpack':
+			return 'Jetpack';
+		case 'woocommerce':
+			return 'WooCommerce';
+		case 'wpcom':
+			return 'WordPress.com';
+	}
+};
+
+const getWordPressWordmarkColor = ( colorVariant: PoweredByVariant ) => {
+	switch ( colorVariant ) {
+		case 'white':
+			return COLOR_WHITE;
+		case 'black':
+			return COLOR_BLACK;
+		default:
+			return COLOR_WPCOM_BLUE;
+	}
+};
+
+const PoweredBy = ( { brand, colorVariant = 'color', className }: PoweredByProps ) => {
+	let LogoComponent: React.ReactNode = null;
+
+	switch ( brand ) {
+		case 'jetpack':
+			LogoComponent = <JetpackLogo colorVariant={ colorVariant } size={ 25 } full />;
+			break;
+		case 'woocommerce':
+			LogoComponent = <WooLogo colorVariant={ colorVariant } height={ 25 } width={ 66 } />;
+			break;
+		case 'wpcom':
+			LogoComponent = (
+				<WordPressWordmark
+					color={ getWordPressWordmarkColor( colorVariant ) }
+					size={ { height: 25, width: 'auto' } }
+				/>
+			);
+			break;
+	}
+
+	return (
+		<p className={ clsx( 'powered-by', className, `is-${ brand }`, `is-${ colorVariant }` ) }>
path: packages/components/src/powered-by/index.tsx
user: login: jameskoster
body: I guess we'll inherit regardless. I think the main point is not to be opinionated about text styles in the component. 
created_at: 2025-05-09T12:59:59Z
author_association: CONTRIBUTOR
diff_hunk: @@ -0,0 +1,82 @@
+import './style.scss';
+
+import colorStudio from '@automattic/color-studio';
+import { createInterpolateElement } from '@wordpress/element';
+import { __ } from '@wordpress/i18n';
+import clsx from 'clsx';
+import React from 'react';
+import { JetpackLogo } from '../logos/jetpack-logo';
+import { WooLogo } from '../logos/woo-logo';
+import WordPressWordmark from '../wordpress-wordmark';
+
+const PALETTE = colorStudio.colors;
+const COLOR_WPCOM_BLUE = PALETTE[ 'Blue 50' ];
+const COLOR_WHITE = PALETTE[ 'White' ];
+const COLOR_BLACK = PALETTE[ 'Black' ];
+
+export type PoweredByBrand = 'jetpack' | 'woocommerce' | 'wpcom';
+export type PoweredByVariant = 'color' | 'black' | 'white';
+
+interface PoweredByProps {
+	brand: PoweredByBrand;
+	colorVariant?: PoweredByVariant;
+	className?: string;
+}
+
+const getBrandName = ( brand: PoweredByBrand ) => {
+	switch ( brand ) {
+		case 'jetpack':
+			return 'Jetpack';
+		case 'woocommerce':
+			return 'WooCommerce';
+		case 'wpcom':
+			return 'WordPress.com';
+	}
+};
+
+const getWordPressWordmarkColor = ( colorVariant: PoweredByVariant ) => {
+	switch ( colorVariant ) {
+		case 'white':
+			return COLOR_WHITE;
+		case 'black':
+			return COLOR_BLACK;
+		default:
+			return COLOR_WPCOM_BLUE;
+	}
+};
+
+const PoweredBy = ( { brand, colorVariant = 'color', className }: PoweredByProps ) => {
+	let LogoComponent: React.ReactNode = null;
+
+	switch ( brand ) {
+		case 'jetpack':
+			LogoComponent = <JetpackLogo colorVariant={ colorVariant } size={ 25 } full />;
+			break;
+		case 'woocommerce':
+			LogoComponent = <WooLogo colorVariant={ colorVariant } height={ 25 } width={ 66 } />;
+			break;
+		case 'wpcom':
+			LogoComponent = (
+				<WordPressWordmark
+					color={ getWordPressWordmarkColor( colorVariant ) }
+					size={ { height: 25, width: 'auto' } }
+				/>
+			);
+			break;
+	}
+
+	return (
+		<p className={ clsx( 'powered-by', className, `is-${ brand }`, `is-${ colorVariant }` ) }>
path: packages/components/src/powered-by/index.tsx
user: login: ciampo
body: Gotcha. I guess this should become a non-issue when we'll have Theming (supporting typography)
created_at: 2025-05-09T21:44:53Z
author_association: CONTRIBUTOR

PR comments:
user: login: github-actions[bot]
created_at: 2025-04-30T20:53:26Z
body: <details>
<summary>Calypso Live <a href="https://calypso.live?image=registry.a8c.com/calypso/app:build-143361">(direct link)</a></summary>
<table>
<tr>
<td>
<img src="https://chart.googleapis.com/chart?chs=150x150&cht=qr&chl=https%3A%2F%2Fcalypso.live%3Fimage%3Dregistry.a8c.com%2Fcalypso%2Fapp%3Abuild-143361%26flags%3Doauth&choe=UTF-8" />
</td>
<td>
<a href="https://calypso.live?image=registry.a8c.com/calypso/app:build-143361">https://calypso.live?image=registry.a8c.com/calypso/app:build-143361</a>
</td>
</tr>
</table>
</details>
<details>
<summary>Jetpack Cloud live <a href="https://calypso.live?image=registry.a8c.com/calypso/app:build-143361&env=jetpack">(direct link)</a></summary>
<table>
<tr>
<td>
<img src="https://chart.googleapis.com/chart?chs=150x150&cht=qr&chl=https%3A%2F%2Fcalypso.live%3Fimage%3Dregistry.a8c.com%2Fcalypso%2Fapp%3Abuild-143361%26env%3Djetpack%26flags%3Doauth&choe=UTF-8" />
</td>
<td>
<a href="https://calypso.live?image=registry.a8c.com/calypso/app:build-143361&env=jetpack">https://calypso.live?image=registry.a8c.com/calypso/app:build-143361&env=jetpack</a>
</td>
</tr>
</table>
</details>
<details>
<summary>Automattic for Agencies live <a href="https://calypso.live?image=registry.a8c.com/calypso/app:build-143361&env=a8c-for-agencies">(direct link)</a></summary>
<table>
<tr>
<td>
<img src="https://chart.googleapis.com/chart?chs=150x150&cht=qr&chl=https%3A%2F%2Fcalypso.live%3Fimage%3Dregistry.a8c.com%2Fcalypso%2Fapp%3Abuild-143361%26env%3Da8c-for-agencies%26flags%3Doauth&choe=UTF-8" />
</td>
<td>
<a href="https://calypso.live?image=registry.a8c.com/calypso/app:build-143361&env=a8c-for-agencies">https://calypso.live?image=registry.a8c.com/calypso/app:build-143361&env=a8c-for-agencies</a>
</td>
</tr>
</table>
</details>
<!--calypso-live-watermark:apr@v1-->
author_association: NONE
user: login: matticbot
created_at: 2025-04-30T20:54:12Z
body: **This PR modifies the release build for the following Calypso Apps:**

_For info about this notification, see here: PCYsg-OT6-p2_

* command-palette-wp-admin
* notifications

To test WordPress.com changes, run `install-plugin.sh $pluginSlug ds-54-branding-of-powered-by-two` on your sandbox.
<!--calypso-app-artifacts-watermark:apr@v1-->
author_association: CONTRIBUTOR
user: login: matticbot
created_at: 2025-04-30T20:55:50Z
body: <!-- icfy-watermark: c52822 -->
Here is how your PR affects size of JS and CSS bundles shipped to the user's browser:

**App Entrypoints** (~121 bytes added 📈 [gzipped])
<details>

```
name                 parsed_size           gzip_size
entry-subscriptions       +328 B  (+0.0%)     +121 B  (+0.0%)
```

Common code that is always downloaded and parsed every time the app is loaded, no matter which route is used.
</details>

**Sections** (~1423 bytes added 📈 [gzipped])
<details>

```
name                                parsed_size           gzip_size
switch-site                              +328 B  (+0.2%)     +103 B  (+0.2%)
stepper-user-step                        +328 B  (+0.0%)     +116 B  (+0.1%)
staging-site                             +328 B  (+0.0%)     +100 B  (+0.0%)
sites-dashboard                          +328 B  (+0.0%)     +100 B  (+0.0%)
site-settings                            +328 B  (+0.0%)     +100 B  (+0.0%)
site-performance                         +328 B  (+0.0%)     +100 B  (+0.0%)
site-monitoring                          +328 B  (+0.0%)     +100 B  (+0.0%)
site-logs                                +328 B  (+0.0%)     +100 B  (+0.0%)
reader                                   +328 B  (+0.0%)     +104 B  (+0.0%)
overview                                 +328 B  (+0.0%)     +100 B  (+0.0%)
jetpack-cloud-plugin-management          +328 B  (+0.0%)     +100 B  (+0.0%)
hosting                                  +328 B  (+0.0%)     +100 B  (+0.0%)
home                                     +328 B  (+0.0%)     +104 B  (+0.0%)
github-deployments                       +328 B  (+0.0%)     +100 B  (+0.0%)
entrepreneur-flow                        +328 B  (+0.2%)     +113 B  (+0.2%)
domains                                  +328 B  (+0.0%)     +100 B  (+0.0%)
async-step-use-my-domain                 +328 B  (+0.1%)     +116 B  (+0.1%)
async-step-unified-domains               +328 B  (+0.0%)     +103 B  (+0.0%)
a8c-for-agencies-sites                   +328 B  (+0.0%)     +107 B  (+0.0%)
a8c-for-agencies-plugins                 +328 B  (+0.0%)     +100 B  (+0.0%)
a8c-for-agencies-partner-directory       +328 B  (+0.1%)      +97 B  (+0.1%)
a8c-for-agencies-overview                +328 B  (+0.0%)     +107 B  (+0.0%)
a8c-for-agencies-marketplace             +328 B  (+0.0%)     +106 B  (+0.0%)
a8c-for-agencies-agency-tier             +328 B  (+0.1%)     +103 B  (+0.1%)
plugins                                  +236 B  (+0.0%)     +138 B  (+0.0%)
plans                                    +236 B  (+0.0%)     +138 B  (+0.0%)
jetpack-cloud-partner-portal             +236 B  (+0.0%)      +97 B  (+0.0%)
jetpack-app                              +236 B  (+0.1%)     +144 B  (+0.1%)
async-step-unified-plans                 +236 B  (+0.0%)     +148 B  (+0.1%)
a8c-for-agencies-referrals                -92 B  (-0.0%)      +20 B  (+0.0%)
```

Sections contain code specific for a given set of routes. Is downloaded and parsed only when a particular route is navigated to.
</details>

**Async-loaded Components** (~607 bytes added 📈 [gzipped])
<details>

```
name                                             parsed_size           gzip_size
async-load-signup-steps-domains                       +328 B  (+0.0%)     +103 B  (+0.0%)
async-load-design-blocks                              +328 B  (+0.0%)     +104 B  (+0.0%)
async-load-calypso-layout-command-palette             +328 B  (+0.1%)     +103 B  (+0.2%)
async-load-signup-steps-plans-theme-preselected       +236 B  (+0.0%)     +148 B  (+0.1%)
async-load-signup-steps-plans                         +236 B  (+0.0%)     +148 B  (+0.1%)
async-load-design                                     +236 B  (+0.0%)     +149 B  (+0.0%)
```

React components that are loaded lazily, when a certain part of UI is displayed for the first time.
</details>

**Legend**
<details>
<summary>What is parsed and gzip size?</summary>

**Parsed Size:** Uncompressed size of the JS and CSS files. This much code needs to be parsed and stored in memory.
**Gzip Size:** Compressed size of the JS and CSS files. This much data needs to be downloaded over network.
</details>

Generated by performance advisor bot at [iscalypsofastyet.com](http://iscalypsofastyet.com).
author_association: CONTRIBUTOR
user: login: dsas
created_at: 2025-04-30T20:58:47Z
body: There's more work to do
 * Other logos we could add - VIPLogo and wp.cloud already have logo components, and further there's a whole library full of them: XsZCukJOf5Rl7eESv17AAH-fi-0_1
 * Actually use this logo in Calypso

It felt like this is far enough to get some feedback though. The other work can be done as follow-up PRs.
author_association: CONTRIBUTOR
user: login: a8ci18n
created_at: 2025-05-08T13:21:04Z
body: This Pull Request is now available for translation here: https://translate.wordpress.com/deliverables/17454309

Some locales (Hebrew, Japanese) have been temporarily machine-translated due to translator availability. All other translations are usually ready within a few days. Untranslated and machine-translated strings will be sent for translation next Monday and are expected to be completed by the following Friday.

Thank you @dsas for including a screenshot in the description! This is really helpful for our translators.
author_association: NONE
user: login: dsas
created_at: 2025-05-08T20:53:16Z
body: > Given that we're planning on releasing a new version of the package soon (see #103160), I wonder if we should consider reverting this PR to avoid releasing APIs that we may soon change (which would be a breaking change) and/or to otherwise delay the upcoming release.

No objection. Feel free to revert it now, or I'll do it tomorrow morning (alongside looking at your other comments).
author_association: CONTRIBUTOR
user: login: ciampo
created_at: 2025-05-08T20:55:44Z
body: I'll prepare a revert PR in case we agree on reverting, but let's wait to make sure reverting makes sense
author_association: CONTRIBUTOR
user: login: mirka
created_at: 2025-05-09T07:38:35Z
body: As a quick fix (?) I [moved](https://github.com/Automattic/wp-calypso/pull/103146/commits/ae5158ee505096d9f8745ad0bbf5843fd2967d27) this component to the `Unaudited` section in Storybook.


author_association: MEMBER
user: login: ciampo
created_at: 2025-05-09T08:16:25Z
body: After discussing with @mirka, we decided to go ahead with the revert, with the main reason being the API changes to existing logo component (see DOTCOM-12752 in Linear)
author_association: CONTRIBUTOR
user: login: a8ci18n
created_at: 2025-05-09T10:30:29Z
body: Translation for this Pull Request [has now been finished](https://translate.wordpress.com/deliverables/overview/17454309).
author_association: NONE