diff --git a/src/design-system/primitives/StatusText/StatusText.module.css b/src/design-system/primitives/StatusText/StatusText.module.css
new file mode 100644
index 0000000..20d2127
--- /dev/null
+++ b/src/design-system/primitives/StatusText/StatusText.module.css
@@ -0,0 +1,7 @@
+.statusText {}
+.success { color: var(--success); }
+.warning { color: var(--warning); }
+.error { color: var(--error); }
+.running { color: var(--running); }
+.muted { color: var(--text-muted); }
+.bold { font-weight: 600; }
diff --git a/src/design-system/primitives/StatusText/StatusText.test.tsx b/src/design-system/primitives/StatusText/StatusText.test.tsx
new file mode 100644
index 0000000..7b1bab7
--- /dev/null
+++ b/src/design-system/primitives/StatusText/StatusText.test.tsx
@@ -0,0 +1,47 @@
+import { describe, it, expect } from 'vitest'
+import { render, screen } from '@testing-library/react'
+import { StatusText } from './StatusText'
+
+describe('StatusText', () => {
+ it('renders children text', () => {
+ render(Online)
+ expect(screen.getByText('Online')).toBeInTheDocument()
+ })
+
+ it('renders as a span element', () => {
+ render(Status)
+ const el = screen.getByText('Status')
+ expect(el.tagName).toBe('SPAN')
+ })
+
+ it('applies variant class', () => {
+ render(Failed)
+ expect(screen.getByText('Failed')).toHaveClass('error')
+ })
+
+ it('applies bold class when bold=true', () => {
+ render(OK)
+ expect(screen.getByText('OK')).toHaveClass('bold')
+ })
+
+ it('does not apply bold class by default', () => {
+ render(OK)
+ expect(screen.getByText('OK')).not.toHaveClass('bold')
+ })
+
+ it('accepts custom className', () => {
+ render(Text)
+ expect(screen.getByText('Text')).toHaveClass('custom')
+ })
+
+ it('renders all 5 variant classes correctly', () => {
+ const variants = ['success', 'warning', 'error', 'running', 'muted'] as const
+ for (const variant of variants) {
+ const { unmount } = render(
+ {variant}
+ )
+ expect(screen.getByText(variant)).toHaveClass(variant)
+ unmount()
+ }
+ })
+})
diff --git a/src/design-system/primitives/StatusText/StatusText.tsx b/src/design-system/primitives/StatusText/StatusText.tsx
new file mode 100644
index 0000000..cc2798e
--- /dev/null
+++ b/src/design-system/primitives/StatusText/StatusText.tsx
@@ -0,0 +1,20 @@
+import styles from './StatusText.module.css'
+import type { ReactNode } from 'react'
+
+interface StatusTextProps {
+ variant: 'success' | 'warning' | 'error' | 'running' | 'muted'
+ bold?: boolean
+ children: ReactNode
+ className?: string
+}
+
+export function StatusText({ variant, bold = false, children, className }: StatusTextProps) {
+ const classes = [
+ styles.statusText,
+ styles[variant],
+ bold ? styles.bold : '',
+ className ?? '',
+ ].filter(Boolean).join(' ')
+
+ return {children}
+}
diff --git a/src/design-system/primitives/index.ts b/src/design-system/primitives/index.ts
index 23798e3..06cdb0b 100644
--- a/src/design-system/primitives/index.ts
+++ b/src/design-system/primitives/index.ts
@@ -30,6 +30,7 @@ export { Sparkline } from './Sparkline/Sparkline'
export { Spinner } from './Spinner/Spinner'
export { StatCard } from './StatCard/StatCard'
export { StatusDot } from './StatusDot/StatusDot'
+export { StatusText } from './StatusText/StatusText'
export { Tag } from './Tag/Tag'
export { Textarea } from './Textarea/Textarea'
export { TimeRangeDropdown } from './TimeRangeDropdown/TimeRangeDropdown'