diff --git a/packages/ui/src/components/symbol/components/logos/bt-logo.tsx b/packages/ui/src/components/symbol/components/logos/bt-logo.tsx
new file mode 100644
index 000000000..637092e13
--- /dev/null
+++ b/packages/ui/src/components/symbol/components/logos/bt-logo.tsx
@@ -0,0 +1,35 @@
+import { clsx } from 'clsx';
+import React from 'react';
+
+import { Symbol } from '../../symbol.component.js';
+import { type SymbolProps } from '../../symbol.types.js';
+
+export function BTLogo({
+ 'aria-label': ariaLabel = 'BT',
+ copyrightYear = '2025',
+ viewBoxWidth = 105,
+ viewBoxHeight = 43,
+ className,
+ ...props
+}: SymbolProps) {
+ return (
+
+
+
+
+
+ );
+}
diff --git a/packages/ui/src/components/symbol/components/logos/bt-multibrand-large-logo.tsx b/packages/ui/src/components/symbol/components/logos/bt-multibrand-large-logo.tsx
new file mode 100644
index 000000000..92045a462
--- /dev/null
+++ b/packages/ui/src/components/symbol/components/logos/bt-multibrand-large-logo.tsx
@@ -0,0 +1,42 @@
+import { clsx } from 'clsx';
+import React from 'react';
+
+import { Symbol } from '../../symbol.component.js';
+import { type SymbolProps } from '../../symbol.types.js';
+
+export function BTMultibrandLargeLogo({
+ 'aria-label': ariaLabel = 'BT',
+ copyrightYear = '2024',
+ viewBoxWidth = 180,
+ viewBoxHeight = 65,
+ align = 'left',
+ offset = [null, 52.59, 105.18],
+ className,
+ ...props
+}: SymbolProps) {
+ return (
+
+
+
+
+
+ );
+}
diff --git a/packages/ui/src/components/symbol/components/logos/bt-multibrand-small-logo.tsx b/packages/ui/src/components/symbol/components/logos/bt-multibrand-small-logo.tsx
new file mode 100644
index 000000000..df834b2c8
--- /dev/null
+++ b/packages/ui/src/components/symbol/components/logos/bt-multibrand-small-logo.tsx
@@ -0,0 +1,49 @@
+import { clsx } from 'clsx';
+import React from 'react';
+
+import { Symbol } from '../../symbol.component.js';
+import { type SymbolProps } from '../../symbol.types.js';
+
+export function BTMultibrandSmallLogo({
+ 'aria-label': ariaLabel = 'BT',
+ copyrightYear = '2025',
+ viewBoxWidth = 122,
+ viewBoxHeight = 44,
+ align = 'left',
+ offset = [null, 36.865, 73.73],
+ className,
+ ...props
+}: SymbolProps) {
+ return (
+
+
+
+
+
+
+
+
+
+
+
+
+ );
+}
diff --git a/packages/ui/src/components/symbol/components/logos/bt-panorama-logo.tsx b/packages/ui/src/components/symbol/components/logos/bt-panorama-logo.tsx
new file mode 100644
index 000000000..89cda414d
--- /dev/null
+++ b/packages/ui/src/components/symbol/components/logos/bt-panorama-logo.tsx
@@ -0,0 +1,76 @@
+import { clsx } from 'clsx';
+import React from 'react';
+
+import { Symbol } from '../../symbol.component.js';
+import { type SymbolProps } from '../../symbol.types.js';
+
+export function BTPanoramaLogo({
+ 'aria-label': ariaLabel = 'BT Panorama',
+ copyrightYear = '2025',
+ viewBoxWidth = 180,
+ viewBoxHeight = 22,
+ className,
+ ...props
+}: SymbolProps) {
+ return (
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ );
+}
diff --git a/packages/ui/src/components/symbol/components/logos/bt-panorama-multibrand-large-logo.tsx b/packages/ui/src/components/symbol/components/logos/bt-panorama-multibrand-large-logo.tsx
new file mode 100644
index 000000000..d83d31b8d
--- /dev/null
+++ b/packages/ui/src/components/symbol/components/logos/bt-panorama-multibrand-large-logo.tsx
@@ -0,0 +1,80 @@
+import { clsx } from 'clsx';
+import React from 'react';
+
+import { Symbol } from '../../symbol.component.js';
+import { type SymbolProps } from '../../symbol.types.js';
+
+export function BTPanoramaMultibrandLargeLogo({
+ 'aria-label': ariaLabel = 'BT Panorama',
+ copyrightYear = '2025',
+ viewBoxWidth = 180,
+ viewBoxHeight = 65,
+ align = 'left',
+ offset = [null, 4.09, 8.18],
+ className,
+ ...props
+}: SymbolProps) {
+ return (
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ );
+}
diff --git a/packages/ui/src/components/symbol/components/logos/bt-panorama-multibrand-small-logo.tsx b/packages/ui/src/components/symbol/components/logos/bt-panorama-multibrand-small-logo.tsx
new file mode 100644
index 000000000..f3a4941d0
--- /dev/null
+++ b/packages/ui/src/components/symbol/components/logos/bt-panorama-multibrand-small-logo.tsx
@@ -0,0 +1,80 @@
+import { clsx } from 'clsx';
+import React from 'react';
+
+import { Symbol } from '../../symbol.component.js';
+import { type SymbolProps } from '../../symbol.types.js';
+
+export function BTPanoramaMultibrandSmallLogo({
+ 'aria-label': ariaLabel = 'BT Panorama',
+ copyrightYear = '2025',
+ viewBoxWidth = 122,
+ viewBoxHeight = 44,
+ align = 'left',
+ offset = [null, 3.725, 7.45],
+ className,
+ ...props
+}: SymbolProps) {
+ return (
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ );
+}
diff --git a/packages/ui/src/components/symbol/components/logos/bt-panorama-reversed-logo.tsx b/packages/ui/src/components/symbol/components/logos/bt-panorama-reversed-logo.tsx
new file mode 100644
index 000000000..672f46883
--- /dev/null
+++ b/packages/ui/src/components/symbol/components/logos/bt-panorama-reversed-logo.tsx
@@ -0,0 +1,76 @@
+import { clsx } from 'clsx';
+import React from 'react';
+
+import { Symbol } from '../../symbol.component.js';
+import { type SymbolProps } from '../../symbol.types.js';
+
+export function BTPanoramaReversedLogo({
+ 'aria-label': ariaLabel = 'BT Panorama',
+ copyrightYear = '2025',
+ viewBoxWidth = 180,
+ viewBoxHeight = 22,
+ className,
+ ...props
+}: SymbolProps) {
+ return (
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ );
+}
diff --git a/packages/ui/src/components/symbol/components/logos/bt-reversed-logo.tsx b/packages/ui/src/components/symbol/components/logos/bt-reversed-logo.tsx
new file mode 100644
index 000000000..1c92c9800
--- /dev/null
+++ b/packages/ui/src/components/symbol/components/logos/bt-reversed-logo.tsx
@@ -0,0 +1,35 @@
+import { clsx } from 'clsx';
+import React from 'react';
+
+import { Symbol } from '../../symbol.component.js';
+import { type SymbolProps } from '../../symbol.types.js';
+
+export function BTReversedLogo({
+ 'aria-label': ariaLabel = 'BT',
+ copyrightYear = '2025',
+ viewBoxWidth = 105,
+ viewBoxHeight = 43,
+ className,
+ ...props
+}: SymbolProps) {
+ return (
+
+
+
+
+
+ );
+}
diff --git a/packages/ui/src/components/symbol/index.ts b/packages/ui/src/components/symbol/index.ts
index 801f14eb6..ad142f0e7 100644
--- a/packages/ui/src/components/symbol/index.ts
+++ b/packages/ui/src/components/symbol/index.ts
@@ -4,6 +4,14 @@ export { AppleStoreSymbol } from './components/symbols/apple-store-symbol.js';
export { BOMLogo } from './components/logos/bom-logo.js';
export { BOMMultibrandLargeLogo } from './components/logos/bom-multibrand-large-logo.js';
export { BOMMultibrandSmallLogo } from './components/logos/bom-multibrand-small-logo.js';
+export { BTReversedLogo } from './components/logos/bt-reversed-logo.js';
+export { BTPanoramaReversedLogo } from './components/logos/bt-panorama-reversed-logo.js';
+export { BTLogo } from './components/logos/bt-logo.js';
+export { BTPanoramaLogo } from './components/logos/bt-panorama-logo.js';
+export { BTMultibrandSmallLogo } from './components/logos/bt-multibrand-small-logo.js';
+export { BTMultibrandLargeLogo } from './components/logos/bt-multibrand-large-logo.js';
+export { BTPanoramaMultibrandSmallLogo } from './components/logos/bt-panorama-multibrand-small-logo.js';
+export { BTPanoramaMultibrandLargeLogo } from './components/logos/bt-panorama-multibrand-large-logo.js';
export { BOMShieldLogo } from './components/logos/bom-shield-logo.js';
export { BPayLandSymbol } from './components/symbols/bpay-land-symbol.js';
export { BPayPortSymbol } from './components/symbols/bpay-port-symbol.js';
diff --git a/packages/ui/src/components/symbol/symbol.stories.tsx b/packages/ui/src/components/symbol/symbol.stories.tsx
index b932cf13f..2f85ca468 100644
--- a/packages/ui/src/components/symbol/symbol.stories.tsx
+++ b/packages/ui/src/components/symbol/symbol.stories.tsx
@@ -27,15 +27,15 @@ export const Default: Story = {
export const Offset = () => (
Left
-
+
Center
-
+
Right
-
+
);
@@ -97,12 +97,12 @@ export const AllLogos = () => {
{Object.entries(multibrandLargeLogos).map(([key, Logo]) => (
<>
{align.map(align => (
-
+
{`<${key} align=${align} />`}
))}
@@ -114,12 +114,12 @@ export const AllLogos = () => {
{Object.entries(multibrandSmallLogos).map(([key, Logo]) => (
<>
{align.map(align => (
-
+
{`<${key} align=${align} />`}
))}
diff --git a/packages/ui/src/stories/foundation/colours.stories.tsx b/packages/ui/src/stories/foundation/colours.stories.tsx
index 1f34937a4..85e0ba130 100644
--- a/packages/ui/src/stories/foundation/colours.stories.tsx
+++ b/packages/ui/src/stories/foundation/colours.stories.tsx
@@ -290,6 +290,7 @@ export const BrandColors: Story = {
'pop',
'primary',
'text',
+ 'focus',
];
const TINTS = ['DEFAULT', 90, 80, 70, 60, 50, 40, 30, 20, 10, 5];
// NOTE: Below is ignored as we need global theme value from render
@@ -316,7 +317,7 @@ export const BrandColors: Story = {
{/* NOTE: Below disable tailwind classname warning for string interpolation */}
{/* eslint-disable-next-line tailwindcss/no-custom-classname */}
-
+
{color}
{`Tailwind eg: bg-${color}${tintString}`}
{/* Below comments to get rid of type nightmare when trying to get hex value */}
@@ -360,7 +361,7 @@ export const ReservedColors = () => {
{/* NOTE: Below disable tailwind classname warning for string interpolation */}
{/* eslint-disable-next-line tailwindcss/no-custom-classname */}
-
+
{color}
{`Tailwind eg: bg-${color}${tintString}`}
{/* Below comments to get rid of type nightmare when trying to get hex value */}
@@ -382,15 +383,15 @@ export const ReservedWithNoTints = () => (
-
+
black
{`Tailwind eg: bg-black`}
#000
-
-
+
+
white
{`Tailwind eg: bg-white`}
#FFF
@@ -431,7 +432,7 @@ export const DataVisualisationColors: Story = {
{/* NOTE: Below disable tailwind classname warning for string interpolation */}
{/* eslint-disable-next-line tailwindcss/no-custom-classname */}
-
+
{color}
{`Tailwind eg: bg-${color}`}
{/* Below comments to get rid of type nightmare when trying to get hex value */}
@@ -448,7 +449,7 @@ export const DataVisualisationColors: Story = {
{/* NOTE: Below disable tailwind classname warning for string interpolation */}
{/* eslint-disable-next-line tailwindcss/no-custom-classname */}
-
+
{color}
{`Tailwind eg: bg-${color}`}
{/* Below comments to get rid of type nightmare when trying to get hex value */}
@@ -465,7 +466,7 @@ export const DataVisualisationColors: Story = {
{/* NOTE: Below disable tailwind classname warning for string interpolation */}
{/* eslint-disable-next-line tailwindcss/no-custom-classname */}
-
+
{`${color}/30`}
{`Tailwind eg: bg-${color}/30`}
{/* Below comments to get rid of type nightmare when trying to get hex value */}
diff --git a/packages/ui/src/tailwind/themes/btpl.ts b/packages/ui/src/tailwind/themes/btpl.ts
new file mode 100644
index 000000000..2c4060297
--- /dev/null
+++ b/packages/ui/src/tailwind/themes/btpl.ts
@@ -0,0 +1,32 @@
+import { type BrandConfig } from '../index.js';
+import { generateColorTints } from '../utils/generate-color-tints.js';
+
+export const theme: BrandConfig = {
+ code: 'BTPL',
+ colors: {
+ ...generateColorTints({
+ background: '#F5F5F5',
+ border: '#D9D9D9',
+ heading: '#171717',
+ hero: '#00345A',
+ light: '#F9F9F9',
+ link: '#006DBC',
+ muted: '#666666',
+ neutral: '#2A2E42',
+ pop: '#672993',
+ primary: '#006DBC',
+ text: '#171717',
+ borderDark: '#949494',
+ focus: '#B470D7',
+ }),
+ pictogram: {
+ dark: '#00345A',
+ duo: {
+ highlight: '#006DBC',
+ outline: '#00345A',
+ },
+ },
+ },
+ brandFont: '',
+ name: 'BT Panorama',
+};