diff --git a/alfa-client/apps/demo/src/app/app.component.html b/alfa-client/apps/demo/src/app/app.component.html
index 458cfa1ddbe968a75d5f95492bafe385a4bb502d..24f25d365c37301b8ea9dc84a6aa0923372077bb 100644
--- a/alfa-client/apps/demo/src/app/app.component.html
+++ b/alfa-client/apps/demo/src/app/app.component.html
@@ -15,28 +15,42 @@
     </div>
     <main class="flex-auto bg-background-50 p-6">
       <form id="antrag_bescheiden_form" [formGroup]="exampleForm">
-        <div class="mb-6">
-          <label
-            for="default-input"
-            class="mb-2 block text-sm font-medium text-gray-900 dark:text-white"
-            >Default input</label
+        <div class="my-4">
+          <ods-text-input id="test-input-id1" label="Betreff" placeholder="Betreff hier eingeben" />
+        </div>
+        <div class="my-4">
+          <ods-textarea
+            id="messageText1"
+            name="messageText1"
+            ariaLabel="Ihre Nachricht"
+            rows="10"
+            placeholder="Nachrichtentext hier eingeben"
           >
-          <input
-            type="text"
-            id="default-input"
-            class="block w-full rounded-lg border border-gray-300 bg-background-50 p-2.5 text-base text-text focus:border-blue-500 focus:ring-blue-500"
-          />
+          </ods-textarea>
         </div>
-        <div>
+        <div class="my-4">
           <ods-text-input
             id="test-input-id"
             label="Betreff"
-            placeholder="hier muss der Betreff rein"
-          />
+            placeholder="Betreff hier eingeben"
+            variant="error"
+          >
+            <ods-error-message error="Betreff fehlt"></ods-error-message
+          ></ods-text-input>
         </div>
-        <div>
-          <ods-textarea />
+        <div class="my-4">
+          <ods-textarea
+            id="messageText"
+            name="messageText"
+            ariaLabel="Ihre Nachricht"
+            rows="10"
+            placeholder="Nachrichtentext hier eingeben"
+            variant="error"
+          >
+            <ods-error-message error="Nachrichtentext fehlt"></ods-error-message>
+          </ods-textarea>
         </div>
+
         <div class="my-10 flex gap-8">
           <ods-radio-button-card
             label="bewilligt"
diff --git a/alfa-client/apps/demo/src/app/app.component.ts b/alfa-client/apps/demo/src/app/app.component.ts
index 35c94d3162ac39e8ef00fd349a9a0c2ade313733..0a62c45b2eeeffd23cf57a69b266f92683e467ff 100644
--- a/alfa-client/apps/demo/src/app/app.component.ts
+++ b/alfa-client/apps/demo/src/app/app.component.ts
@@ -7,6 +7,7 @@ import {
   AttachmentComponent,
   ButtonCardComponent,
   ButtonComponent,
+  ErrorMessageComponent,
   FileUploadButtonComponent,
   IconComponent,
   RadioButtonCardComponent,
@@ -40,6 +41,8 @@ import { CustomStepperComponent } from './components/cdk-demo/custom-stepper.com
     SpinnerIconComponent,
     TextareaComponent,
     TextInputComponent,
+    TextareaComponent,
+    ErrorMessageComponent,
   ],
   selector: 'app-root',
   templateUrl: './app.component.html',
diff --git a/alfa-client/libs/design-system/src/index.ts b/alfa-client/libs/design-system/src/index.ts
index 00e8a89ec69168de4e4c66e0293a146c9cdfe629..1d024028f217117d49f28fa597e57bb9c8d3de49 100644
--- a/alfa-client/libs/design-system/src/index.ts
+++ b/alfa-client/libs/design-system/src/index.ts
@@ -1,6 +1,7 @@
 export * from './lib/attachment/attachment.component';
 export * from './lib/button-card/button-card.component';
 export * from './lib/button/button.component';
+export * from './lib/form/error-message/error-message.component';
 export * from './lib/form/file-upload-button/file-upload-button.component';
 export * from './lib/form/radio-button-card/radio-button-card.component';
 export * from './lib/form/text-input/text-input.component';
diff --git a/alfa-client/libs/design-system/src/lib/form/error-message/error-message.component.spec.ts b/alfa-client/libs/design-system/src/lib/form/error-message/error-message.component.spec.ts
new file mode 100644
index 0000000000000000000000000000000000000000..841f14c8b7ce7b54a913e221b416ba95fc53f422
--- /dev/null
+++ b/alfa-client/libs/design-system/src/lib/form/error-message/error-message.component.spec.ts
@@ -0,0 +1,21 @@
+import { ComponentFixture, TestBed } from '@angular/core/testing';
+import { ErrorMessageComponent } from './error-message.component';
+
+describe('ErrorMessageComponent', () => {
+  let component: ErrorMessageComponent;
+  let fixture: ComponentFixture<ErrorMessageComponent>;
+
+  beforeEach(async () => {
+    await TestBed.configureTestingModule({
+      imports: [ErrorMessageComponent],
+    }).compileComponents();
+
+    fixture = TestBed.createComponent(ErrorMessageComponent);
+    component = fixture.componentInstance;
+    fixture.detectChanges();
+  });
+
+  it('should create', () => {
+    expect(component).toBeTruthy();
+  });
+});
diff --git a/alfa-client/libs/design-system/src/lib/form/error-message/error-message.component.ts b/alfa-client/libs/design-system/src/lib/form/error-message/error-message.component.ts
new file mode 100644
index 0000000000000000000000000000000000000000..14676069eea4d270c58fc711ba9e1720dafef696
--- /dev/null
+++ b/alfa-client/libs/design-system/src/lib/form/error-message/error-message.component.ts
@@ -0,0 +1,12 @@
+import { CommonModule } from '@angular/common';
+import { Component, Input } from '@angular/core';
+
+@Component({
+  selector: 'ods-error-message',
+  standalone: true,
+  imports: [CommonModule],
+  template: `<p *ngIf="error" error class="text-error mt-2 text-sm">{{ error }}</p>`,
+})
+export class ErrorMessageComponent {
+  @Input() error: string;
+}
diff --git a/alfa-client/libs/design-system/src/lib/form/text-input/text-input.component.ts b/alfa-client/libs/design-system/src/lib/form/text-input/text-input.component.ts
index 634781aaefeb341fc1b4b2a723969085b5f06abe..3cc78ba8722ceb007b3610349d979f54ec567d0f 100644
--- a/alfa-client/libs/design-system/src/lib/form/text-input/text-input.component.ts
+++ b/alfa-client/libs/design-system/src/lib/form/text-input/text-input.component.ts
@@ -1,24 +1,44 @@
 import { CommonModule } from '@angular/common';
 import { Component, Input } from '@angular/core';
+import { VariantProps, cva } from 'class-variance-authority';
+
+import { ErrorMessageComponent } from '../error-message/error-message.component';
+
+const textInputVariants = cva(
+  'block w-full rounded-lg border bg-background-50 p-2.5 text-base text-text focus:border-primary focus:ring-primary',
+  {
+    variants: {
+      variant: {
+        default: 'border-primary-600/50',
+        error: 'border-error',
+      },
+    },
+    defaultVariants: {
+      variant: 'default',
+    },
+  },
+);
+type TextInputVariants = VariantProps<typeof textInputVariants>;
 
 @Component({
   selector: 'ods-text-input',
   standalone: true,
-  imports: [CommonModule],
+  imports: [CommonModule, ErrorMessageComponent],
   template: `
     <div>
-      <label [for]="id" class="block text-sm font-medium leading-6 text-gray-900">{{
+      <label [for]="id" class="mb-2 block text-sm font-medium leading-6 text-text">{{
         label
       }}</label>
       <div class="mt-2">
         <input
           type="text"
-          name="email"
           [id]="id"
-          class="block w-full rounded-lg border border-gray-300 bg-background-50 p-2.5 text-base text-text focus:border-blue-500 focus:ring-blue-500"
+          [ngClass]="textInputVariants({ variant })"
           [placeholder]="placeholder"
+          [autocomplete]="autocomplete"
         />
       </div>
+      <ng-content select="[error]"></ng-content>
     </div>
   `,
 })
@@ -26,4 +46,9 @@ export class TextInputComponent {
   @Input({ required: true }) id!: string;
   @Input() label: string = '';
   @Input() placeholder: string = '';
+  @Input() error: string;
+  @Input() autocomplete: string = 'off';
+  @Input() variant: TextInputVariants['variant'];
+
+  textInputVariants = textInputVariants;
 }
diff --git a/alfa-client/libs/design-system/src/lib/form/textarea/textarea.component.ts b/alfa-client/libs/design-system/src/lib/form/textarea/textarea.component.ts
index 3ec25e20a3281e068323d2fe34d51f86d114d8c4..9969e8e27c31de674ebcf42147ae476a788e6806 100644
--- a/alfa-client/libs/design-system/src/lib/form/textarea/textarea.component.ts
+++ b/alfa-client/libs/design-system/src/lib/form/textarea/textarea.component.ts
@@ -1,31 +1,54 @@
 import { CommonModule } from '@angular/common';
 import { Component, Input } from '@angular/core';
+import { ReactiveFormsModule } from '@angular/forms';
+import { VariantProps, cva } from 'class-variance-authority';
+
+import { ErrorMessageComponent } from '../error-message/error-message.component';
+
+const textareaVariants = cva(
+  'block w-full rounded-lg border bg-background-50 p-2.5 text-base text-text focus:border-primary focus:ring-primary',
+  {
+    variants: {
+      variant: {
+        default: 'border-primary-600/50',
+        error: 'border-error',
+      },
+    },
+    defaultVariants: {
+      variant: 'default',
+    },
+  },
+);
+type TextareaVariants = VariantProps<typeof textareaVariants>;
 
 @Component({
   selector: 'ods-textarea',
   standalone: true,
-  imports: [CommonModule],
+  imports: [CommonModule, ReactiveFormsModule, ErrorMessageComponent],
   template: `
     <div class="mt-2">
+      <label *ngIf="ariaLabel" [for]="name" class="sr-only">{{ ariaLabel }}</label>
       <textarea
-        rows="4"
-        name="comment"
-        id="comment"
-        class="block w-full rounded-md border-0 py-1.5 text-gray-900 shadow-sm ring-1 ring-inset ring-gray-300 placeholder:text-gray-400 focus:ring-2 focus:ring-inset focus:ring-indigo-600 sm:text-sm sm:leading-6"
-      ></textarea>
-      <label for="description" class="sr-only">Description</label>
-      <textarea
-        rows="2"
-        name="description"
-        id="description"
-        class="block w-full resize-none border-0 py-0 text-gray-900 placeholder:text-gray-400 focus:ring-0 sm:text-sm sm:leading-6"
-        placeholder="Write a description..."
+        [id]="id"
+        [name]="name"
+        [rows]="rows"
+        [ngClass]="textareaVariants({ variant })"
+        [placeholder]="placeholder"
+        [autocomplete]="autocomplete"
       ></textarea>
+      <ng-content select="[error]"></ng-content>
     </div>
   `,
 })
 export class TextareaComponent {
-  @Input() label!: string;
-  @Input() placeholder: string = '';
-  @Input() value!: string;
+  @Input({ required: true }) id: string;
+  @Input({ required: true }) name: string;
+  @Input({ required: true }) ariaLabel: string;
+  @Input() placeholder!: string;
+  @Input() rows: number = 3;
+  @Input() error!: string;
+  @Input() autocomplete: string = 'off';
+  @Input() variant: TextareaVariants['variant'];
+
+  textareaVariants = textareaVariants;
 }
diff --git a/alfa-client/libs/design-system/src/lib/tailwind-preset/root.css b/alfa-client/libs/design-system/src/lib/tailwind-preset/root.css
index ee4388c87e0ea5bb4f717a24b78a1b3b0858f879..1ea5814ba45c6937e509f933e18a55fb36c55cf0 100644
--- a/alfa-client/libs/design-system/src/lib/tailwind-preset/root.css
+++ b/alfa-client/libs/design-system/src/lib/tailwind-preset/root.css
@@ -6,6 +6,7 @@
 
 :root {
   --warning: 38 92% 50%;
+  --color-error: 0 71% 49%;
 
   --color-background-secondary: 0 0% 98%;
   --color-mainbg: 0 0% 100%;
@@ -29,6 +30,8 @@
 }
 
 .dark {
+  --color-error: 0 71% 49%;
+
   --color-background-secondary: 0 0% 16%;
   --color-mainbg: 0 0% 14%;
   --text: 0 0% 100%;
diff --git a/alfa-client/libs/design-system/src/lib/tailwind-preset/tailwind.config.js b/alfa-client/libs/design-system/src/lib/tailwind-preset/tailwind.config.js
index 1ae7845a8f59331b2875f9f9620a33ad12545871..fa5e338aa989da33abca91ae6dcf894937180615 100644
--- a/alfa-client/libs/design-system/src/lib/tailwind-preset/tailwind.config.js
+++ b/alfa-client/libs/design-system/src/lib/tailwind-preset/tailwind.config.js
@@ -92,6 +92,7 @@ module.exports = {
         text: 'hsl(var(--text) / <alpha-value>)',
         whitetext: 'hsl(var(--color-text-white) / <alpha-value>)',
         warning: 'hsl(var(--warning))',
+        error: 'hsl(var(--color-error))',
       },
     },
   },