diff --git a/src/design-system/components/alert/Alert.scss b/src/design-system/components/alert/Alert.scss
new file mode 100644
index 000000000..55c4bb01b
--- /dev/null
+++ b/src/design-system/components/alert/Alert.scss
@@ -0,0 +1,121 @@
+@use '~scss/utilities' as *;
+
+.#{$prefix}alert {
+ --#{$prefix}alert-padding-x: #{get-var('space-2')};
+ --#{$prefix}alert-padding-y: #{get-var('space-1-5')};
+ --#{$prefix}alert-inner-gap: #{get-var('space-0')};
+ --#{$prefix}alert-font-size: #{get-var('font-size-sm')};
+ --#{$prefix}alert-font-weight: #{get-var('font-weight-regular')};
+ --#{$prefix}alert-line-height: #{get-var('line-height-md')};
+ --#{$prefix}alert-border-width: #{get-var('border-width-xs')};
+ --#{$prefix}alert-border-radius: #{get-var('border-radius-xs')};
+ --#{$prefix}alert-shadow: #{get-var('box-shadow-xs')};
+ --#{$prefix}alert-color: #{get-var('blue-gray-800')};
+
+ position: relative;
+ padding: get-var('alert-padding-y') get-var('alert-padding-x');
+ font-size: get-var('alert-font-size');
+ line-height: get-var('alert-line-height');
+ font-weight: get-var('alert-font-weight');
+ border-width: get-var('alert-border-width');
+ border-radius: get-var('alert-border-radius');
+ box-shadow: get-var('alert-shadow');
+ gap: get-var('alert-inner-gap');
+ color: get-var('alert-color');
+
+ & .MuiAlertTitle-root {
+ font-weight: $font-weight-medium;
+ font-size: $font-size-md;
+ line-height: $line-height-lg;
+ }
+
+ &.MuiAlert-filled {
+ color: $neutral-0;
+
+ .s2s-alert-close-button {
+ color: $blue-gray-50;
+ }
+ }
+
+ &.MuiAlert-outlined {
+ color: $neutral-0;
+
+ .s2s-alert-close-button {
+ color: $blue-gray-800;
+ }
+ }
+
+ &.MuiAlert-colorError {
+ border-color: $red-500;
+ }
+
+ &.MuiAlert-colorError.MuiAlert-filled {
+ color: $red-50;
+ background-color: $red-500;
+ }
+
+ &.MuiAlert-colorError.MuiAlert-outlined {
+ color: $red-800;
+ background-color: $red-50;
+ }
+
+ &.MuiAlert-colorWarning {
+ border-color: $yellow-500;
+ }
+
+ &.MuiAlert-colorWarning.MuiAlert-filled {
+ background-color: $yellow-500;
+ }
+
+ &.MuiAlert-colorWarning.MuiAlert-outlined {
+ color: $yellow-800;
+ background-color: $yellow-100;
+ }
+
+ &.MuiAlert-colorInfo {
+ border-color: $blue-500;
+ }
+
+ &.MuiAlert-colorInfo.MuiAlert-filled {
+ background-color: $blue-500;
+ }
+
+ &.MuiAlert-colorInfo.MuiAlert-outlined {
+ color: $blue-800;
+ background-color: $blue-100;
+ }
+
+ &.MuiAlert-colorSuccess {
+ border-color: $green-600;
+ }
+
+ &.MuiAlert-colorSuccess.MuiAlert-filled {
+ background-color: $green-600;
+ }
+
+ &.MuiAlert-colorSuccess.MuiAlert-outlined {
+ color: $green-800;
+ background-color: $green-100;
+ }
+
+ & .s2s-alert-close-button {
+ background: transparent;
+ border: none;
+ border-radius: $border-radius-md;
+ font-weight: $font-weight-medium;
+ font-size: $font-size-sm;
+ line-height: $line-height-sm;
+ cursor: pointer;
+ display: flex;
+ align-items: center;
+
+ &:hover {
+ background-color: rgba(0, 0, 0, 0.1);
+ }
+ }
+
+ & .s2s-alert-close-button-label {
+ margin: 0 0.5rem;
+ height: auto;
+ }
+}
diff --git a/src/design-system/components/alert/Alert.tsx b/src/design-system/components/alert/Alert.tsx
new file mode 100644
index 000000000..87ad71ff3
--- /dev/null
+++ b/src/design-system/components/alert/Alert.tsx
@@ -0,0 +1,87 @@
+import { SyntheticEvent, forwardRef, ButtonHTMLAttributes } from 'react'
+import {
+ Alert as MuiAlert,
+ AlertProps as MuiAlertProps,
+ AlertTitle as MuiAlertTitle,
+ AlertTitleProps
+} from '@mui/material'
+import {
+ ErrorOutline,
+ WarningAmberOutlined,
+ InfoOutlined,
+ CheckCircleOutline,
+ CloseRounded
+} from '@mui/icons-material'
+
+import { cn } from '~/utils/cn'
+
+import '~scss-components/alert/Alert.scss'
+
+export const AlertTitle = ({ children, ...props }: AlertTitleProps) => {
+ return {children}
+}
+
+AlertTitle.displayName = 'AlertTitle'
+
+interface CloseButtonProps extends ButtonHTMLAttributes {
+ label?: string
+}
+
+const CloseButton = ({ label }: CloseButtonProps) => {
+ return (
+
+ )
+}
+
+CloseButton.displayName = 'CloseButton'
+
+const iconMapping = {
+ error: ,
+ warning: ,
+ info: ,
+ success:
+}
+
+interface AlertProps extends MuiAlertProps {
+ title?: string
+ description?: string
+ label?: string
+}
+
+const Alert = forwardRef(
+ (
+ { title, label, description, children, icon, onClose, className, ...props },
+ ref
+ ) => {
+ const handleClose = (event: SyntheticEvent) => {
+ if (onClose) {
+ onClose(event)
+ }
+ }
+
+ return (
+
+ }}
+ {...props}
+ >
+ {title && {title}}
+ {description && {description}
}
+ {children}
+
+ )
+ }
+)
+
+Alert.displayName = 'Alert'
+
+export default Alert
diff --git a/src/design-system/stories/Alert.stories.tsx b/src/design-system/stories/Alert.stories.tsx
new file mode 100644
index 000000000..b53a58557
--- /dev/null
+++ b/src/design-system/stories/Alert.stories.tsx
@@ -0,0 +1,307 @@
+import { Meta, StoryObj } from '@storybook/react'
+
+import Alert from '~scss-components/alert/Alert'
+
+const meta: Meta = {
+ title: 'Components/Alert',
+ component: Alert,
+ tags: ['autodocs'],
+ parameters: {
+ docs: {
+ description: {
+ component:
+ "The `Alert` displays a short, important message in a way that attracts the user's attention without interrupting the user's task."
+ }
+ }
+ },
+ args: {
+ variant: 'standard',
+ label: 'Label',
+ title: 'Title',
+ description: 'Description',
+ severity: 'success'
+ },
+ argTypes: {
+ variant: {
+ description: 'The variant to use.',
+ control: 'radio',
+ options: ['filled', 'outlined', 'standard']
+ },
+ label: {
+ description: 'The label to display in the alert.',
+ control: 'text'
+ },
+ title: {
+ description: 'The title to display in the alert.',
+ control: 'text'
+ },
+ description: {
+ description: 'The description to display in the alert.',
+ control: 'text'
+ },
+ severity: {
+ description:
+ 'The severity of the alert. This defines the color and icon used.',
+ control: 'radio',
+ options: ['error', 'info', 'success', 'warning']
+ },
+ icon: {
+ description:
+ 'Override the icon displayed before the children. Unless provided, the icon is mapped to the value of the severity prop.'
+ },
+ children: {
+ description: 'The content of the alert.'
+ }
+ }
+}
+
+export default meta
+
+type Story = StoryObj
+
+export const Default: Story = {
+ args: {
+ label: 'Label',
+ title: 'Title',
+ description: 'Description'
+ },
+ parameters: {
+ docs: {
+ description: {
+ story:
+ 'This story displays a default alert with the `standard` variant and `success` severity.'
+ }
+ }
+ }
+}
+
+export const All: Story = {
+ render: (args) => (
+
+ ),
+ parameters: {
+ docs: {
+ description: {
+ story:
+ 'This story showcases all alert variants in two columns for easy comparison.'
+ }
+ }
+ }
+}
+
+export const FilledError: Story = {
+ args: {
+ variant: 'filled',
+ label: 'Label',
+ title: 'Title',
+ description: 'Description',
+ severity: 'error'
+ },
+ parameters: {
+ docs: {
+ description: {
+ story:
+ 'This story displays an alert with the `filled` variant and `error` severity. Use this style for critical error messages.'
+ }
+ }
+ }
+}
+
+export const FilledWarning: Story = {
+ args: {
+ variant: 'filled',
+ label: 'Label',
+ title: 'Title',
+ description: 'Description',
+ severity: 'warning'
+ },
+ parameters: {
+ docs: {
+ description: {
+ story:
+ 'This story displays an alert with the `filled` variant and `warning` severity. Ideal for cautionary messages.'
+ }
+ }
+ }
+}
+
+export const FilledInfo: Story = {
+ args: {
+ variant: 'filled',
+ label: 'Label',
+ title: 'Title',
+ description: 'Description',
+ severity: 'info'
+ },
+ parameters: {
+ docs: {
+ description: {
+ story:
+ 'This story displays an alert with the `filled` variant and `info` severity. Use this for informational messages.'
+ }
+ }
+ }
+}
+
+export const FilledSuccess: Story = {
+ args: {
+ variant: 'filled',
+ label: 'Label',
+ title: 'Title',
+ description: 'Description',
+ severity: 'success'
+ },
+ parameters: {
+ docs: {
+ description: {
+ story:
+ 'This story displays an alert with the `filled` variant and `success` severity. Use this for success confirmation messages.'
+ }
+ }
+ }
+}
+
+export const OutlinedError: Story = {
+ args: {
+ variant: 'outlined',
+ label: 'Label',
+ title: 'Title',
+ description: 'Description',
+ severity: 'error'
+ },
+ parameters: {
+ docs: {
+ description: {
+ story:
+ 'This story displays an alert with the `outlined` variant and `error` severity. Use this style for subtle but critical error messages.'
+ }
+ }
+ }
+}
+
+export const OutlinedWarning: Story = {
+ args: {
+ variant: 'outlined',
+ label: 'Label',
+ title: 'Title',
+ description: 'Description',
+ severity: 'warning'
+ },
+ parameters: {
+ docs: {
+ description: {
+ story:
+ 'This story displays an alert with the `outlined` variant and `warning` severity. Ideal for understated cautionary messages.'
+ }
+ }
+ }
+}
+
+export const OutlinedInfo: Story = {
+ args: {
+ variant: 'outlined',
+ label: 'Label',
+ title: 'Title',
+ description: 'Description',
+ severity: 'info'
+ },
+ parameters: {
+ docs: {
+ description: {
+ story:
+ 'This story displays an alert with the `outlined` variant and `info` severity. Use this for understated informational messages.'
+ }
+ }
+ }
+}
+
+export const OutlinedSuccess: Story = {
+ args: {
+ variant: 'outlined',
+ label: 'Label',
+ title: 'Title',
+ description: 'Description',
+ severity: 'success'
+ },
+ parameters: {
+ docs: {
+ description: {
+ story:
+ 'This story displays an alert with the `outlined` variant and `success` severity. Use this for subtle success confirmation messages.'
+ }
+ }
+ }
+}
diff --git a/tests/unit/design-system/components/Alert/Alert.spec.jsx b/tests/unit/design-system/components/Alert/Alert.spec.jsx
new file mode 100644
index 000000000..2037d7ed9
--- /dev/null
+++ b/tests/unit/design-system/components/Alert/Alert.spec.jsx
@@ -0,0 +1,56 @@
+import { render, screen } from '@testing-library/react'
+import { InfoOutlined } from '@mui/icons-material'
+
+import Alert from '~scss-components/alert/Alert'
+
+describe('Alert Component', () => {
+ test('renders the Alert component with the correct title and description', () => {
+ render()
+
+ expect(screen.getByText('Test Title')).toBeInTheDocument()
+ expect(screen.getByText('Test Description')).toBeInTheDocument()
+ })
+
+ test('renders children content', () => {
+ render(
+
+ Child Content
+
+ )
+
+ expect(screen.getByText('Child Content')).toBeInTheDocument()
+ })
+
+ test('renders the icon provided via the icon prop', () => {
+ render(} />)
+
+ expect(screen.getByTestId('custom-icon')).toBeInTheDocument()
+ })
+
+ test('renders the close button when the onClose prop is provided', () => {
+ const handleClose = vi.fn()
+ render()
+
+ const closeButton = screen.getByRole('button', { name: /.*close.*/i })
+ expect(closeButton).toBeInTheDocument()
+ })
+
+ test('renders the close button with a label when provided', () => {
+ render( {}} />)
+
+ expect(screen.getByText('Close')).toBeInTheDocument()
+ })
+
+ test('applies custom className to the Alert component', () => {
+ render()
+
+ const alertElement = screen.getByRole('alert')
+ expect(alertElement).toHaveClass('custom-class')
+ })
+
+ test('renders description as a paragraph', () => {
+ render()
+
+ expect(screen.getByText('Test Description').tagName).toBe('P')
+ })
+})