diff --git a/src/design-system/primitives/Label/Label.module.css b/src/design-system/primitives/Label/Label.module.css
new file mode 100644
index 0000000..b542bf7
--- /dev/null
+++ b/src/design-system/primitives/Label/Label.module.css
@@ -0,0 +1,11 @@
+.label {
+ font-family: var(--font-body);
+ font-size: 12px;
+ color: var(--text-primary);
+ font-weight: 500;
+}
+
+.asterisk {
+ color: var(--error);
+ margin-left: 2px;
+}
diff --git a/src/design-system/primitives/Label/Label.test.tsx b/src/design-system/primitives/Label/Label.test.tsx
new file mode 100644
index 0000000..afa2fb0
--- /dev/null
+++ b/src/design-system/primitives/Label/Label.test.tsx
@@ -0,0 +1,34 @@
+import { describe, it, expect } from 'vitest'
+import { render, screen } from '@testing-library/react'
+import { Label } from './Label'
+
+describe('Label', () => {
+ it('renders label text', () => {
+ render()
+ expect(screen.getByText('Email address')).toBeInTheDocument()
+ })
+
+ it('does not show asterisk when required is not set', () => {
+ render()
+ expect(screen.queryByText('*')).not.toBeInTheDocument()
+ })
+
+ it('shows asterisk when required', () => {
+ render()
+ expect(screen.getByText('*')).toBeInTheDocument()
+ })
+
+ it('passes htmlFor to the label element', () => {
+ render()
+ const label = screen.getByText('Email')
+ expect(label).toHaveAttribute('for', 'email-input')
+ })
+
+ it('forwards ref to the label element', () => {
+ let ref: HTMLLabelElement | null = null
+ render(
+
+ )
+ expect(ref).toBeInstanceOf(HTMLLabelElement)
+ })
+})
diff --git a/src/design-system/primitives/Label/Label.tsx b/src/design-system/primitives/Label/Label.tsx
new file mode 100644
index 0000000..d343c3f
--- /dev/null
+++ b/src/design-system/primitives/Label/Label.tsx
@@ -0,0 +1,20 @@
+import styles from './Label.module.css'
+import { forwardRef, type LabelHTMLAttributes, type ReactNode } from 'react'
+
+interface LabelProps extends LabelHTMLAttributes {
+ required?: boolean
+ children?: ReactNode
+ className?: string
+}
+
+export const Label = forwardRef(
+ ({ required, children, className, ...rest }, ref) => {
+ return (
+
+ )
+ },
+)
+Label.displayName = 'Label'