diff --git a/app/Libraries/ViewComponents/Component.php b/app/Libraries/ViewComponents/Component.php
index 779d12c298ce530651bd9769a7677d502d4104b1..2aa0a9135b155ac1c0cee3aa0a103a3c959d5150 100644
--- a/app/Libraries/ViewComponents/Component.php
+++ b/app/Libraries/ViewComponents/Component.php
@@ -22,11 +22,12 @@ class Component implements ComponentInterface
      */
     public function __construct(array $attributes)
     {
+        helper('viewcomponents');
+
         if ($attributes !== []) {
             $this->hydrate($attributes);
         }
         // overwrite default attributes if set
-
         $this->attributes = array_merge($this->attributes, $attributes);
     }
 
diff --git a/app/Libraries/ViewComponents/ComponentRenderer.php b/app/Libraries/ViewComponents/ComponentRenderer.php
index ccac323990b45a2cd4392500110e370c89ac1efd..37a16eee1e30194931e01a584495686a839814e5 100644
--- a/app/Libraries/ViewComponents/ComponentRenderer.php
+++ b/app/Libraries/ViewComponents/ComponentRenderer.php
@@ -109,7 +109,7 @@ class ComponentRenderer
     private function renderPairedTags(string $output): string
     {
         $pattern = '/<\s*(?<name>[A-Z][A-Za-z0-9\.]*?)(?<attributes>[\s\S\=\'\"]*)>(?<slot>.*)<\/\s*\1\s*>/uUsm';
-
+        ini_set('pcre.backtrack_limit', '-1');
         /*
             $matches[0] = full tags matched and all of its content
             $matches[name] = pascal cased tag name
diff --git a/app/Libraries/ViewComponents/Helpers/viewcomponents_helper.php b/app/Libraries/ViewComponents/Helpers/viewcomponents_helper.php
new file mode 100644
index 0000000000000000000000000000000000000000..1555f937f2aad2589894f24c2529697942d146b1
--- /dev/null
+++ b/app/Libraries/ViewComponents/Helpers/viewcomponents_helper.php
@@ -0,0 +1,33 @@
+<?php
+
+declare(strict_types=1);
+
+if (! function_exists('flatten_attributes')) {
+    /**
+     * Stringify attributes for use in HTML tags.
+     *
+     * Helper function used to convert a string, array, or object of attributes to a string.
+     *
+     * @param mixed $attributes string, array, object
+     */
+    function flatten_attributes($attributes, bool $js = false): string
+    {
+        $atts = '';
+
+        if ($attributes === null) {
+            return $atts;
+        }
+
+        if (is_string($attributes)) {
+            return ' ' . $attributes;
+        }
+
+        $attributes = (array) $attributes;
+
+        foreach ($attributes as $key => $val) {
+            $atts .= ($js) ? $key . '=' . esc($val, 'js') . ',' : ' ' . $key . '="' . $val . '"';
+        }
+
+        return rtrim($atts, ',');
+    }
+}
diff --git a/app/Resources/js/modules/xml-editor.ts b/app/Resources/js/modules/xml-editor.ts
index 81a8b254e240ff5b261f36e5899d6ebea8f31679..100a701b46dfdd351f817810475cd617c6e314b8 100644
--- a/app/Resources/js/modules/xml-editor.ts
+++ b/app/Resources/js/modules/xml-editor.ts
@@ -57,12 +57,17 @@ export class XMLEditor extends LitElement {
 
   static styles = css`
     .cm-wrap {
-      border: 1px solid #6b7280;
+      border-radius: 0.5rem;
+      overflow: hidden;
+      border: 3px solid #000000;
       background-color: #ffffff;
     }
     .cm-editor.cm-focused {
       outline: 2px solid transparent;
-      box-shadow: 0 0 0 1px #2563eb;
+      box-shadow: 0 0 0 2px #e7f9e4, 0 0 0 calc(4px) #009486;
+    }
+    .cm-gutters {
+      background-color: #ffffff !important;
     }
   `;
 
diff --git a/app/Resources/styles/breadcrumb.css b/app/Resources/styles/breadcrumb.css
index 0a89fe55b8f673b83698c2be32deae79a773d698..ac4a3fabb633a44b7fd2c86d1e6e5d7969be0286 100644
--- a/app/Resources/styles/breadcrumb.css
+++ b/app/Resources/styles/breadcrumb.css
@@ -1,5 +1,5 @@
 .breadcrumb {
-  @apply inline-flex flex-wrap px-1 py-2 text-sm;
+  @apply inline-flex flex-wrap px-1 text-sm;
 }
 
 .breadcrumb-item + .breadcrumb-item::before {
diff --git a/app/Resources/styles/choices.css b/app/Resources/styles/choices.css
index 073342617d0930e70b784105d76aad6cb1216511..d9cffcb384cbb06eae28ddb49c3841b36e8263b5 100644
--- a/app/Resources/styles/choices.css
+++ b/app/Resources/styles/choices.css
@@ -138,8 +138,9 @@
   }
 
   .choices__inner {
-    @apply p-2 bg-white border border-gray-700;
+    @apply p-2 bg-white border-black rounded-lg border-3;
 
+    box-shadow: 2px 2px 0 black;
     display: inline-block;
     vertical-align: top;
     width: 100%;
@@ -158,11 +159,11 @@
   }
 
   .is-open .choices__inner {
-    border-radius: 0;
+    @apply rounded-b-none;
   }
 
   .is-flipped.is-open .choices__inner {
-    border-radius: 0;
+    @apply rounded-t-none rounded-b-lg border-b-3;
   }
 
   .choices__list {
@@ -172,9 +173,7 @@
   }
 
   .choices__list--single {
-    @apply pr-4;
-    display: inline-block;
-    width: 100%;
+    @apply inline-block w-full pr-4;
   }
 
   [dir="rtl"] .choices__list--single {
@@ -191,7 +190,7 @@
   }
 
   .choices__list--multiple .choices__item {
-    @apply inline-block px-2 py-1 mb-1 mr-1 text-sm text-white align-middle bg-pine-600;
+    @apply inline-block px-2 py-1 mb-1 mr-1 text-sm text-white align-middle rounded bg-pine-500;
 
     word-break: break-all;
     box-sizing: border-box;
@@ -216,12 +215,11 @@
   }
 
   .choices__list--dropdown {
+    @apply z-50 border-2 border-black shadow-lg;
     visibility: hidden;
-    z-index: 1;
     position: absolute;
     width: 100%;
     background-color: #ffffff;
-    border: 1px solid #dddddd;
     top: 100%;
     margin-top: -1px;
     overflow: hidden;
@@ -234,10 +232,11 @@
   }
 
   .is-open .choices__list--dropdown {
-    border-color: #b7b7b7;
+    @apply border-t-0 rounded-b-lg;
   }
 
   .is-flipped .choices__list--dropdown {
+    @apply border-b-0 rounded-t-lg rounded-b-none border-t-3;
     top: auto;
     bottom: 100%;
     margin-top: 0;
diff --git a/app/Resources/styles/radioBtn.css b/app/Resources/styles/radioBtn.css
index 0abe1a6e6501b8d4616bff95b0d60da837223697..d882d606a918a7f80432bffcb36076f14a207025 100644
--- a/app/Resources/styles/radioBtn.css
+++ b/app/Resources/styles/radioBtn.css
@@ -1,26 +1,17 @@
 @layer components {
   .form-radio-btn {
-    @apply absolute opacity-0;
+    @apply absolute mt-3 ml-3 border-black border-3 text-pine-500 focus:ring-2 focus:ring-pine-800;
   }
 
   .form-radio-btn:focus + label {
-    @apply ring;
+    @apply ring ring-pine-100;
   }
 
   .form-radio-btn + label {
-    @apply inline-block px-2 py-1 text-sm text-black bg-white border rounded cursor-pointer;
-
-    &:hover {
-      @apply bg-pine-100;
-    }
+    @apply inline-block py-2 pl-8 pr-2 text-sm font-semibold text-gray-500 bg-white border-black rounded-lg cursor-pointer border-3;
   }
 
   .form-radio-btn:checked + label {
-    @apply text-white bg-pine-600;
-
-    &::before {
-      @apply mr-2 text-pine-200;
-      content: "✓";
-    }
+    @apply text-black border-pine-500;
   }
 }
diff --git a/app/Resources/styles/switch.css b/app/Resources/styles/switch.css
index 3d8a7f3d150ef0064e740d93871b444bee8680f5..b124f0f43f5d52ac54448bf80f8142458cc4787c 100644
--- a/app/Resources/styles/switch.css
+++ b/app/Resources/styles/switch.css
@@ -3,26 +3,37 @@
     @apply absolute w-0 h-0 opacity-0;
 
     &:checked + .form-switch-slider {
-      @apply bg-pine-600;
+      @apply bg-pine-500;
     }
 
     &:focus + .form-switch-slider {
-      @apply ring;
+      @apply ring ring-offset-2 ring-pine-500 ring-offset-pine-100;
     }
 
     &:checked + .form-switch-slider::before {
-      @apply transform translate-x-5;
+      @apply transform translate-x-8;
+    }
+
+    &:checked + .form-switch-slider::after {
+      @apply transform translate-x-1;
+      content: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' fill='%23ffffff'%3E%3Cpath fill='none' d='M0 0h24v24H0z'/%3E%3Cpath d='m10 15.172 9.192-9.193 1.415 1.414L10 18l-6.364-6.364 1.414-1.414z'/%3E%3C/svg%3E%0A");
     }
   }
 
   .form-switch-slider {
-    @apply relative inset-0 flex-shrink-0 w-10 h-5 transition duration-200 bg-gray-400 rounded-full cursor-pointer;
+    @apply relative inset-0 flex-shrink-0 w-[72px] h-10 transition duration-200 bg-gray-400 border-black rounded-full cursor-pointer border-3;
 
     &::before {
-      @apply absolute w-4 h-4 transition duration-200 bg-white rounded-full ring-1 ring-black ring-opacity-5;
+      @apply absolute z-10 w-[28px] h-[28px] transition duration-200 bg-white rounded-full ring-1 ring-black ring-opacity-5 shadow;
       content: "";
-      left: 2px;
-      bottom: 2px;
+      left: 3px;
+      bottom: 3px;
+    }
+
+    &::after {
+      @apply absolute w-6 h-6 transition duration-150 transform translate-x-8 top-1 left-1;
+
+      content: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24'%3E%3Cpath fill='none' d='M0 0h24v24H0z'/%3E%3Cpath d='m12 10.586 4.95-4.95 1.414 1.414-4.95 4.95 4.95 4.95-1.414 1.414-4.95-4.95-4.95 4.95-1.414-1.414 4.95-4.95-4.95-4.95L7.05 5.636z'/%3E%3C/svg%3E%0A");
     }
   }
 }
diff --git a/app/Views/Components/Forms/Field.php b/app/Views/Components/Forms/Field.php
new file mode 100644
index 0000000000000000000000000000000000000000..10ec65da3282c87541a64fa0e08f6b2d21201291
--- /dev/null
+++ b/app/Views/Components/Forms/Field.php
@@ -0,0 +1,48 @@
+<?php
+
+declare(strict_types=1);
+
+namespace App\Views\Components\Forms;
+
+class Field extends FormComponent
+{
+    protected string $as = 'Input';
+
+    protected string $label = '';
+
+    protected ?string $helperText = null;
+
+    protected ?string $hintText = null;
+
+    public function render(): string
+    {
+        $helperText = $this->helperText === null ? '' : '<Forms.Helper>' . $this->helperText . '</Forms.Helper>';
+
+        $labelAttributes = [
+            'for' => $this->id,
+            'isOptional' => $this->required ? 'false' : 'true',
+        ];
+        if ($this->hintText) {
+            $labelAttributes['hint'] = $this->hintText;
+        }
+        $labelAttributes = stringify_attributes($labelAttributes);
+
+        // remove field specific attributes to inject the rest to Form Component
+        $fieldComponentAttributes = $this->attributes;
+        unset($fieldComponentAttributes['as']);
+        unset($fieldComponentAttributes['label']);
+        unset($fieldComponentAttributes['class']);
+        unset($fieldComponentAttributes['helperText']);
+        unset($fieldComponentAttributes['hintText']);
+
+        $fieldComponentAttributes = flatten_attributes($fieldComponentAttributes);
+
+        return <<<HTML
+            <div class="flex flex-col {$this->class}">
+                <Forms.Label {$labelAttributes}>{$this->label}</Forms.Label>
+                <Forms.{$this->as} {$fieldComponentAttributes} class="mb-1"/>
+                {$helperText}
+            </div>
+        HTML;
+    }
+}
diff --git a/app/Views/Components/Forms/FormComponent.php b/app/Views/Components/Forms/FormComponent.php
new file mode 100644
index 0000000000000000000000000000000000000000..785c0496255e1cba7113410a3713f51a730d8441
--- /dev/null
+++ b/app/Views/Components/Forms/FormComponent.php
@@ -0,0 +1,32 @@
+<?php
+
+declare(strict_types=1);
+
+namespace App\Views\Components\Forms;
+
+use ViewComponents\Component;
+
+class FormComponent extends Component
+{
+    protected ?string $id = null;
+
+    protected string $name = '';
+
+    protected string $value = '';
+
+    protected bool $required = false;
+
+    public function __construct($attributes)
+    {
+        parent::__construct($attributes);
+
+        if ($this->id === null) {
+            $this->id = $this->name;
+        }
+    }
+
+    public function setRequired(string $value): void
+    {
+        $this->required = $value === 'true';
+    }
+}
diff --git a/app/Views/Components/Forms/Helper.php b/app/Views/Components/Forms/Helper.php
new file mode 100644
index 0000000000000000000000000000000000000000..05174678c4f08b24689909afe8bb78c1113dcc3a
--- /dev/null
+++ b/app/Views/Components/Forms/Helper.php
@@ -0,0 +1,22 @@
+<?php
+
+declare(strict_types=1);
+
+namespace App\Views\Components\Forms;
+
+class Helper extends FormComponent
+{
+    /**
+     * @var "default"|"error"
+     */
+    protected string $type = 'default';
+
+    public function render(): string
+    {
+        $class = 'text-gray-600';
+
+        return <<<HTML
+            <small class="{$class} {$this->class}">{$this->slot}</small>
+        HTML;
+    }
+}
diff --git a/app/Views/Components/Forms/Input.php b/app/Views/Components/Forms/Input.php
new file mode 100644
index 0000000000000000000000000000000000000000..7d771099773b23754405cfcfda7e7f6a7be4db6b
--- /dev/null
+++ b/app/Views/Components/Forms/Input.php
@@ -0,0 +1,37 @@
+<?php
+
+declare(strict_types=1);
+
+namespace App\Views\Components\Forms;
+
+class Input extends FormComponent
+{
+    protected string $type = 'text';
+
+    public function render(): string
+    {
+        $class = 'px-3 py-2 rounded-lg border-3 focus:ring-2 focus:ring-pine-500 focus:ring-offset-2 focus:ring-offset-pine-100 ' . $this->class;
+
+        if (session()->has('errors')) {
+            $error = session('errors')[$this->name];
+            if ($error) {
+                $class .= ' border-red';
+            }
+        } else {
+            $class .= ' border-black focus:border-black';
+        }
+
+        $data = [
+            'id' => $this->id,
+            'name' => $this->name,
+            'class' => $class,
+            'type' => $this->type,
+        ];
+
+        if ($this->required) {
+            $data['required'] = 'required';
+        }
+
+        return form_input($data, old($this->name, $this->value));
+    }
+}
diff --git a/app/Views/Components/Forms/Label.php b/app/Views/Components/Forms/Label.php
index 6ff709d4633e583c489dfbea737aaf93513eaa82..609780f656a40dcf5dc00a2689ab49f3eed05595 100644
--- a/app/Views/Components/Forms/Label.php
+++ b/app/Views/Components/Forms/Label.php
@@ -8,16 +8,9 @@ use ViewComponents\Component;
 
 class Label extends Component
 {
-    /**
-     * @var array<string, string>
-     */
-    protected array $attributes = [
-        'for' => '',
-        'name' => '',
-        'class' => '',
-    ];
+    protected ?string $for = null;
 
-    protected string $hint = '';
+    protected ?string $hint = null;
 
     protected bool $isOptional = false;
 
@@ -28,14 +21,14 @@ class Label extends Component
 
     public function render(): string
     {
-        $labelClass = $this->attributes['class'];
+        $labelClass = 'text-sm ' . $this->attributes['class'];
         unset($this->attributes['class']);
 
         $attributes = stringify_attributes($this->attributes);
         $optionalText = $this->isOptional ? '<small class="ml-1 lowercase">(' .
         lang('Common.optional') .
         ')</small>' : '';
-        $hint = $this->hint !== '' ? hint_tooltip($this->hint, 'ml-1') : '';
+        $hint = $this->hint === null ? '' : hint_tooltip($this->hint, 'ml-1');
 
         return <<<HTML
             <label class="{$labelClass}" {$attributes}>{$this->slot}{$optionalText}{$hint}</label>
diff --git a/app/Views/Components/Forms/MarkdownEditor.php b/app/Views/Components/Forms/MarkdownEditor.php
index febf2ebe044edf1a626bd7981efde116bb7bf628..4a729729c0775566ca0e2ab40dadf5fd5b5c5736 100644
--- a/app/Views/Components/Forms/MarkdownEditor.php
+++ b/app/Views/Components/Forms/MarkdownEditor.php
@@ -4,73 +4,68 @@ declare(strict_types=1);
 
 namespace App\Views\Components\Forms;
 
-use ViewComponents\Component;
-
-class MarkdownEditor extends Component
+class MarkdownEditor extends FormComponent
 {
     public function render(): string
     {
-        $editorClass = 'w-full flex flex-col bg-white border border-gray-500 focus-within:ring-1 focus-within:ring-blue-600';
-        if ($this->attributes['class'] !== '') {
-            $editorClass .= ' ' . $this->attributes['class'];
-            unset($this->attributes['class']);
-        }
+        $editorClass = 'w-full flex flex-col bg-white border-3 border-black rounded-lg overflow-hidden focus-within:ring-2 focus-within:ring-offset-2 focus-withing:ring-offset-pine-100 focus-within:ring-pine-500 ' . $this->class;
+
+        $this->attributes['class'] = 'border-none outline-none focus:border-none focus:outline-none focus:ring-0 w-full h-full';
+        $this->attributes['rows'] = 6;
 
-        $this->attributes['class'] = 'border-none outline-none focus:border-none focus:outline-none w-full h-full';
+        $textarea = form_textarea($this->attributes, old($this->name, $this->value, false));
+        $icons = [
+            'heading' => icon('heading'),
+            'bold' => icon('bold'),
+            'italic' => icon('italic'),
+            'list-unordered' => icon('list-unordered'),
+            'list-ordered' => icon('list-ordered'),
+            'quote' => icon('quote'),
+            'link' => icon('link'),
+            'image-add' => icon('image-add'),
+            'markdown' => icon(
+                'markdown',
+                'mr-1 text-lg text-gray-400'
+            ),
+        ];
+        $translations = [
+            'write' => lang('Common.forms.editor.write'),
+            'preview' => lang('Common.forms.editor.preview'),
+            'help' => lang('Common.forms.editor.help'),
+        ];
 
-        return '<div class="' . $editorClass . '">' .
-            '<header class="sticky top-0 z-20 flex flex-wrap justify-between bg-white border-b border-gray-500">' .
-                '<markdown-write-preview for="' . $this->attributes['id'] . '" class="relative inline-flex h-8">' .
-                    '<button type="button" slot="write" class="px-2 font-semibold focus:outline-none focus:ring-inset focus:ring-2 focus:ring-pine-600">' . lang(
-                        'Common.forms.editor.write'
-                    ) . '</button>' .
-                    '<button type="button" slot="preview" class="px-2 focus:outline-none focus:ring-inset focus:ring-2 focus:ring-pine-600">' . lang(
-                        'Common.forms.editor.preview'
-                    ) . '</button>' .
-                '</markdown-write-preview>' .
-                '<markdown-toolbar for="' . $this->attributes['id'] . '" class="flex gap-4 px-2 py-1">' .
-                    '<div class="inline-flex text-2xl gap-x-1">' .
-                        '<md-header class="opacity-50 hover:opacity-100 focus:outline-none focus:ring-2 focus:opacity-100 focus:ring-pine-600">' . icon(
-                            'heading'
-                        ) . '</md-header>' .
-                        '<md-bold class="opacity-50 hover:opacity-100 focus:outline-none focus:ring-2 focus:opacity-100 focus:ring-pine-600">' . icon(
-                            'bold'
-                        ) . '</md-bold>' .
-                        '<md-italic class="opacity-50 hover:opacity-100 focus:outline-none focus:ring-2 focus:opacity-100 focus:ring-pine-600">' . icon(
-                            'italic'
-                        ) . '</md-italic>' .
-                    '</div>' .
-                    '<div class="inline-flex text-2xl gap-x-1">' .
-                        '<md-unordered-list class="opacity-50 hover:opacity-100 focus:outline-none focus:ring-2 focus:opacity-100 focus:ring-pine-600">' . icon(
-                            'list-unordered'
-                        ) . '</md-unordered-list>' .
-                        '<md-ordered-list class="opacity-50 hover:opacity-100 focus:outline-none focus:ring-2 focus:opacity-100 focus:ring-pine-600">' . icon(
-                            'list-ordered'
-                        ) . '</md-ordered-list>' .
-                    '</div>' .
-                    '<div class="inline-flex text-2xl gap-x-1">' .
-                        '<md-quote class="opacity-50 hover:opacity-100 focus:outline-none focus:ring-2 focus:opacity-100 focus:ring-pine-600">' . icon(
-                            'quote'
-                        ) . '</md-quote>' .
-                        '<md-link class="opacity-50 hover:opacity-100 focus:outline-none focus:ring-2 focus:opacity-100 focus:ring-pine-600">' . icon(
-                            'link'
-                        ) . '</md-link>' .
-                        '<md-image class="opacity-50 hover:opacity-100 focus:outline-none focus:ring-2 focus:opacity-100 focus:ring-pine-600">' . icon(
-                            'image-add'
-                        ) . '</md-image>' .
-                    '</div>' .
-                '</markdown-toolbar>' .
-            '</header>' .
-            '<div class="relative">' .
-                form_textarea($this->attributes, $this->slot) .
-                '<markdown-preview for="' . $this->attributes['id'] . '" class="absolute top-0 left-0 hidden w-full h-full p-2 overflow-y-auto prose bg-gray-50" showClass="bg-white"></markdown-preview>' .
-            '</div>' .
-            '<footer class="flex px-2 py-1 bg-gray-100 border-t">' .
-                '<a href="https://commonmark.org/help/" class="inline-flex items-center text-xs font-semibold text-gray-500 hover:text-gray-700" target="_blank" rel="noopener noreferrer">' . icon(
-                    'markdown',
-                    'mr-1 text-lg text-gray-400'
-                ) . lang('Common.forms.editor.help') . '</a>' .
-            '</footer>' .
-        '</div>';
+        return <<<HTML
+            <div class="{$editorClass}">
+                <header class="sticky top-0 z-20 flex flex-wrap justify-between bg-white border-b border-black">
+                    <markdown-write-preview for="{$this->id}" class="relative inline-flex h-8">
+                        <button type="button" slot="write" class="px-2 font-semibold focus:outline-none focus:ring-inset focus:ring-2 focus:ring-pine-600">{$translations['write']}</button>
+                        <button type="button" slot="preview" class="px-2 focus:outline-none focus:ring-inset focus:ring-2 focus:ring-pine-600">{$translations['preview']}</button>
+                    </markdown-write-preview>
+                    <markdown-toolbar for=" {$this->id} " class="flex gap-4 px-2 py-1">
+                        <div class="inline-flex text-2xl gap-x-1">
+                            <md-header class="opacity-50 hover:opacity-100 focus:outline-none focus:ring-2 focus:opacity-100 focus:ring-pine-600">{$icons['heading']}</md-header>
+                            <md-bold class="opacity-50 hover:opacity-100 focus:outline-none focus:ring-2 focus:opacity-100 focus:ring-pine-600">{$icons['bold']}</md-bold>
+                            <md-italic class="opacity-50 hover:opacity-100 focus:outline-none focus:ring-2 focus:opacity-100 focus:ring-pine-600">{$icons['italic']}</md-italic>
+                        </div>
+                        <div class="inline-flex text-2xl gap-x-1">
+                            <md-unordered-list class="opacity-50 hover:opacity-100 focus:outline-none focus:ring-2 focus:opacity-100 focus:ring-pine-600">{$icons['list-unordered']}</md-unordered-list>
+                            <md-ordered-list class="opacity-50 hover:opacity-100 focus:outline-none focus:ring-2 focus:opacity-100 focus:ring-pine-600">{$icons['list-ordered']}</md-ordered-list>
+                        </div>
+                        <div class="inline-flex text-2xl gap-x-1">
+                            <md-quote class="opacity-50 hover:opacity-100 focus:outline-none focus:ring-2 focus:opacity-100 focus:ring-pine-600">{$icons['quote']}</md-quote>
+                            <md-link class="opacity-50 hover:opacity-100 focus:outline-none focus:ring-2 focus:opacity-100 focus:ring-pine-600">{$icons['link']}</md-link>
+                            <md-image class="opacity-50 hover:opacity-100 focus:outline-none focus:ring-2 focus:opacity-100 focus:ring-pine-600">{$icons['image-add']}</md-image>
+                        </div>
+                    </markdown-toolbar>
+                </header>
+                <div class="relative">
+                    {$textarea}
+                    <markdown-preview for=" {$this->id} " class="absolute top-0 left-0 hidden w-full h-full p-2 overflow-y-auto prose bg-gray-50" showClass="bg-white" />
+                </div>
+                <footer class="flex px-2 py-1 bg-gray-100 border-t">
+                    <a href="https://commonmark.org/help/" class="inline-flex items-center text-xs font-semibold text-gray-500 hover:text-gray-700" target="_blank" rel="noopener noreferrer">{$icons['markdown']}{$translations['help']}</a>
+                </footer>
+            </div>
+        HTML;
     }
 }
diff --git a/app/Views/Components/Forms/RadioButton.php b/app/Views/Components/Forms/RadioButton.php
new file mode 100644
index 0000000000000000000000000000000000000000..222afa1f2776b72bd1dd78c57657c56884228f3f
--- /dev/null
+++ b/app/Views/Components/Forms/RadioButton.php
@@ -0,0 +1,40 @@
+<?php
+
+declare(strict_types=1);
+
+namespace App\Views\Components\Forms;
+
+/**
+ * Form Checkbox Switch
+ *
+ * Abstracts form_label to stylize it as a switch toggle
+ */
+class RadioButton extends FormComponent
+{
+    protected bool $isChecked = false;
+
+    public function setIsChecked(string $value): void
+    {
+        $this->isChecked = $value === 'true';
+    }
+
+    public function render(): string
+    {
+        $radioInput = form_radio(
+            [
+                'id' => $this->value,
+                'name' => $this->name,
+                'class' => 'form-radio-btn',
+            ],
+            $this->value,
+            old($this->name) ? old($this->name) === $this->value : $this->isChecked,
+        );
+
+        return <<<HTML
+            <div>
+                {$radioInput}
+                <label for="{$this->value}">{$this->slot}</label>
+            </div>
+        HTML;
+    }
+}
diff --git a/app/Views/Components/Forms/Section.php b/app/Views/Components/Forms/Section.php
new file mode 100644
index 0000000000000000000000000000000000000000..38adec8703533a8c4413f6854e9e54fb47971f6f
--- /dev/null
+++ b/app/Views/Components/Forms/Section.php
@@ -0,0 +1,25 @@
+<?php
+
+declare(strict_types=1);
+
+namespace App\Views\Components\Forms;
+
+class Section extends FormComponent
+{
+    protected string $title = '';
+
+    protected ?string $subtitle = null;
+
+    public function render(): string
+    {
+        $subtitle = $this->subtitle === null ? '' : '<p class="text-sm text-gray-600 clear-left">' . $this->subtitle . '</p>';
+
+        return <<<HTML
+            <fieldset class="w-full max-w-xl p-8 bg-white border-2 border-black rounded-xl {$this->class}">
+                <Heading tagName="legend" class="float-left">{$this->title}</Heading>
+                {$subtitle}
+                <div class="flex flex-col gap-4 py-4 clear-left">{$this->slot}</div>
+            </fieldset>
+        HTML;
+    }
+}
diff --git a/app/Views/Components/Forms/Select.php b/app/Views/Components/Forms/Select.php
index 050c3cf334e82101a3cf971ba225cdaf124abd12..983a6be08d2d450fecab3f9bcc6b8f797a08ade4 100644
--- a/app/Views/Components/Forms/Select.php
+++ b/app/Views/Components/Forms/Select.php
@@ -4,28 +4,28 @@ declare(strict_types=1);
 
 namespace App\Views\Components\Forms;
 
-use ViewComponents\Component;
-
-class MultiSelect extends Component
+class Select extends FormComponent
 {
     /**
      * @var array<string, string>
      */
     protected array $options = [];
 
-    /**
-     * @var string[]
-     */
-    protected array $selected = [];
+    protected string $selected;
+
+    public function setOptions(string $value): void
+    {
+        // dd(json_decode(html_entity_decode(html_entity_decode($value)), true));
+        $this->options = json_decode(html_entity_decode($value), true);
+    }
 
     public function render(): string
     {
         $defaultAttributes = [
-            'data-class' => $this->attributes['class'],
-            'multiple' => 'multiple',
+            'data-class' => 'border-3 rounded-lg ' . $this->class,
         ];
         $extra = array_merge($defaultAttributes, $this->attributes);
 
-        return form_dropdown($this->attributes['name'], $this->options, $this->selected, $extra);
+        return form_dropdown($this->name, $this->options, $this->selected !== '' ? [$this->selected] : [], $extra);
     }
 }
diff --git a/app/Views/Components/Heading.php b/app/Views/Components/Heading.php
index 8333be2c0ca25a170f33ed211c71209cb0e36a19..8cfa379208ae1f1360cd7ab0dfb415a305411b6d 100644
--- a/app/Views/Components/Heading.php
+++ b/app/Views/Components/Heading.php
@@ -4,12 +4,11 @@ declare(strict_types=1);
 
 namespace App\Views\Components;
 
-use Exception;
 use ViewComponents\Component;
 
 class Heading extends Component
 {
-    protected string $level = '';
+    protected string $tagName = 'div';
 
     /**
      * @var "small"|"base"|"large"
@@ -18,21 +17,16 @@ class Heading extends Component
 
     public function render(): string
     {
-        if ($this->level === '') {
-            throw new Exception('level property must be set for Heading component.');
-        }
-
         $sizeClasses = [
             'small' => 'tracking-wide text-base',
             'base' => 'text-xl',
             'large' => 'text-3xl',
         ];
 
-        $class = 'relative z-10 font-bold text-pine-800 font-display before:w-full before:absolute before:h-1/2 before:left-0 before:bottom-0 before:rounded-full before:bg-pine-100 before:-z-10 ' . $sizeClasses[$this->size];
-        $level = $this->level;
+        $class = $this->class . ' relative z-10 font-bold text-pine-800 font-display before:w-full before:absolute before:h-1/2 before:left-0 before:bottom-0 before:rounded-full before:bg-pine-100 before:-z-10 ' . $sizeClasses[$this->size];
 
         return <<<HTML
-            <h{$level} class="{$class}">{$this->slot}</h{$level}>
+            <{$this->tagName} class="{$class}">{$this->slot}</{$this->tagName}>
         HTML;
     }
 }
diff --git a/phpstan.neon b/phpstan.neon
index 8db6aaed65e126eda28e9608a3cf8f54a5c66c27..88e1055aef8620445610761e9c1b9d49eb196315 100644
--- a/phpstan.neon
+++ b/phpstan.neon
@@ -33,3 +33,4 @@ parameters:
             paths:
                 - app/Helpers
                 - app/Common.php
+                - app/Libraries/ViewComponents/Helpers
diff --git a/tailwind.config.js b/tailwind.config.js
index b7cad2d8c73bdb4eb5e9694ce89516f31225a83f..cb142c44e666d00df04a72e667db274e547849ab 100644
--- a/tailwind.config.js
+++ b/tailwind.config.js
@@ -51,6 +51,12 @@ module.exports = {
       zIndex: {
         "-10": "-10",
       },
+      borderWidth: {
+        3: "3px",
+      },
+      ringWidth: {
+        3: "3px",
+      },
     },
   },
   variants: {},
diff --git a/themes/cp_admin/_layout.php b/themes/cp_admin/_layout.php
index 29f811561c219f1a92da0b5935490bcc3daea666..8da7748788b93eecae7e68eb2c84b6b65a044400 100644
--- a/themes/cp_admin/_layout.php
+++ b/themes/cp_admin/_layout.php
@@ -79,21 +79,17 @@
             ]) ?>
         </footer>
     </aside>
-    <main class="holy-grail__main">
-        <header class="bg-white">
-            <div class="container flex flex-wrap items-end justify-between px-2 py-10 mx-auto md:px-12 gap-y-6 gap-x-6">
-                <div class="flex flex-col">
-                    <?= render_breadcrumb('text-gray-800 text-xs') ?>
+    <main class="relative holy-grail__main">
+        <header class="flex-col py-10 bg-white">
+            <div class="container mx-auto">
+                <?= render_breadcrumb('text-gray-800 text-xs') ?>
+                <div class="flex justify-between">
                     <div class="flex flex-wrap items-center">
-                        <Heading level="1" size="large"><?= $this->renderSection(
-                'pageTitle',
-            ) ?></Heading>
+                        <Heading tagName="h1" size="large"><?= $this->renderSection('pageTitle') ?></Heading>
                         <?= $this->renderSection('headerLeft') ?>
                     </div>
+                    <div class="flex gap-1"><?= $this->renderSection('headerRight') ?></div>
                 </div>
-                <div class="flex flex-wrap"><?= $this->renderSection(
-                'headerRight',
-            ) ?></div>
             </div>
         </header>
         <div class="container px-2 py-8 mx-auto md:px-12">
diff --git a/themes/cp_admin/podcast/edit.php b/themes/cp_admin/podcast/edit.php
index 9fc0009938ee469fa42e0ee6e71055e3ea35f614..717409bd34dee23788d5697ad7fe899faf5e205a 100644
--- a/themes/cp_admin/podcast/edit.php
+++ b/themes/cp_admin/podcast/edit.php
@@ -12,373 +12,216 @@
 <?= lang('Podcast.edit') ?>
 <?= $this->endSection() ?>
 
+<?= $this->section('headerRight') ?>
+<Button variant="primary" type="submit" form="podcast-edit-form"><?= lang('Podcast.form.submit_edit') ?></Button>
+<?= $this->endSection() ?>
 
 <?= $this->section('content') ?>
 
 <?= form_open_multipart((string) route_to('podcast-edit', $podcast->id), [
+    'id' => 'podcast-edit-form',
     'method' => 'post',
     'class' => 'flex flex-col',
 ]) ?>
 
 <?= csrf_field() ?>
 
-<?= form_section(
-    lang('Podcast.form.identity_section_title'),
-    lang('Podcast.form.identity_section_subtitle'),
-) ?>
-
-<?= form_label(lang('Podcast.form.image'), 'image') ?>
-<img src="<?= $podcast->image->thumbnail_url ?>" alt="<?= $podcast->title ?>" class="object-cover w-32 h-32" />
-<?= form_input([
-    'id' => 'image',
-    'name' => 'image',
-    'class' => 'form-input',
-    'type' => 'file',
-    'accept' => '.jpg,.jpeg,.png',
-]) ?>
-
-
-<small class="mb-4 text-gray-600"><?= lang(
-    'Common.forms.image_size_hint',
-) ?></small>
-
-<?= form_label(lang('Podcast.form.title'), 'title') ?>
-
-<?= form_input([
-    'id' => 'title',
-    'name' => 'title',
-    'class' => 'form-input mb-1',
-    'value' => old('title', $podcast->title),
-    'required' => 'required',
-]) ?>
-
-<span class="mb-4 text-sm"><?= $podcast->link ?></span>
-
-<?= form_fieldset('', [
-    'class' => 'mb-4',
-]) ?>
-
-<legend><?= lang('Podcast.form.type.label') .
-            hint_tooltip(lang('Podcast.form.type.hint'), 'ml-1') ?>
-</legend>
-<?= form_radio(
-                [
-                    'id' => 'episodic',
-                    'name' => 'type',
-                    'class' => 'form-radio-btn',
-                ],
-                'episodic',
-                old('type') ? old('type') === 'episodic' : $podcast->type === 'episodic',
-            ) ?>
-<label for="episodic"><?= lang('Podcast.form.type.episodic') ?></label>
-<?= form_radio(
-                [
-                    'id' => 'serial',
-                    'name' => 'type',
-                    'class' => 'form-radio-btn',
-                ],
-                'serial',
-                old('type') ? old('type') === 'serial' : $podcast->type === 'serial',
-            ) ?>
-<label for="serial"><?= lang('Podcast.form.type.serial') ?></label>
-<?= form_fieldset_close() ?>
-
-<div class="mb-4">
-    <Forms.Label for="description"><?= lang('Podcast.form.description') ?></Forms.Label>
-    <Forms.MarkdownEditor id="description" name="description" required="required"><?= old('description', $podcast->description_markdown, false) ?></Forms.MarkdownEditor>
-</div>
-
-<?= form_section_close() ?>
-
-<?= form_section(
-                lang('Podcast.form.classification_section_title'),
-                lang('Podcast.form.classification_section_subtitle'),
-            ) ?>
-
-<?= form_label(lang('Podcast.form.language'), 'language') ?>
-
-<?= form_dropdown(
-                'language',
-                $languageOptions,
-                [old('language', $podcast->language_code)],
-                [
-                    'id' => 'language',
-                    'class' => 'form-select mb-4',
-                    'required' => 'required',
-                ],
-            ) ?>
-
-<?= form_label(lang('Podcast.form.category'), 'category') ?>
-<?= form_dropdown(
-                'category',
-                $categoryOptions,
-                [old('category', $podcast->category_id)],
-                [
-                    'id' => 'category',
-                    'class' => 'form-select mb-4',
-                    'required' => 'required',
-                ],
-            ) ?>
-
-<?= form_label(
-                lang('Podcast.form.other_categories'),
-                'other_categories',
-                [],
-                '',
-                true,
-            ) ?>
-
-<Forms.MultiSelect
-    id="other_categories"
-    name="other_categories[]"
-    class="mb-4"
-    data-max-item-count="2"
-    selected="<?= json_encode(old('other_categories', $podcast->other_categories_ids)) ?>"
-    options="<?= htmlspecialchars(json_encode($categoryOptions)) ?>" />
-
-<?= form_fieldset('', [
-    'class' => 'mb-4',
-]) ?>
-<legend><?= lang('Podcast.form.parental_advisory.label') .
-            hint_tooltip(lang('Podcast.form.parental_advisory.hint'), 'ml-1') ?></legend>
-<?= form_radio(
-                [
-                    'id' => 'undefined',
-                    'name' => 'parental_advisory',
-                    'class' => 'form-radio-btn',
-                ],
-                'undefined',
-                old('parental_advisory')
-    ? old('parental_advisory') === 'undefined'
-    : $podcast->parental_advisory === null,
-            ) ?>
-
-<label for="undefined"><?= lang(
-                'Podcast.form.parental_advisory.undefined',
-            ) ?></label>
-<?= form_radio(
-                [
-                    'id' => 'clean',
-                    'name' => 'parental_advisory',
-                    'class' => 'form-radio-btn',
-                ],
-                'clean',
-                old('parental_advisory')
-    ? old('parental_advisory') === 'clean'
-    : $podcast->parental_advisory === 'clean',
-            ) ?>
-
-<label for="clean"><?= lang(
-                'Podcast.form.parental_advisory.clean',
-            ) ?></label>
-<?= form_radio(
-                [
-                    'id' => 'explicit',
-                    'name' => 'parental_advisory',
-                    'class' => 'form-radio-btn',
-                ],
-                'explicit',
-                old('parental_advisory')
-    ? old('parental_advisory') === 'explicit'
-    : $podcast->parental_advisory === 'explicit',
-            ) ?>
-
-<label for="explicit"><?= lang(
-                'Podcast.form.parental_advisory.explicit',
-            ) ?></label>
-<?= form_fieldset_close() ?>
-<?= form_section_close() ?>
-
-<?= form_section(
-                lang('Podcast.form.author_section_title'),
-                lang('Podcast.form.author_section_subtitle'),
-            ) ?>
-
-<?= form_label(
-                lang('Podcast.form.owner_name'),
-                'owner_name',
-                [],
-                lang('Podcast.form.owner_name_hint'),
-            ) ?>
-
-<?= form_input([
-    'id' => 'owner_name',
-    'name' => 'owner_name',
-    'class' => 'form-input mb-4',
-    'value' => old('owner_name', $podcast->owner_name),
-    'required' => 'required',
-]) ?>
-
-<?= form_label(
-    lang('Podcast.form.owner_email'),
-    'owner_email',
-    [],
-    lang('Podcast.form.owner_email_hint'),
-) ?>
-
-<?= form_input([
-    'id' => 'owner_email',
-    'name' => 'owner_email',
-    'class' => 'form-input mb-4',
-    'value' => old('owner_email', $podcast->owner_email),
-    'type' => 'email',
-    'required' => 'required',
-]) ?>
-
-<?= form_label(
-    lang('Podcast.form.publisher'),
-    'publisher',
-    [],
-    lang('Podcast.form.publisher_hint'),
-    true,
-) ?>
-
-<?= form_input([
-    'id' => 'publisher',
-    'name' => 'publisher',
-    'class' => 'form-input mb-4',
-    'value' => old('publisher', $podcast->publisher),
-]) ?>
-
-<?= form_label(lang('Podcast.form.copyright'), 'copyright', [], '', true) ?>
-
-<?= form_input([
-    'id' => 'copyright',
-    'name' => 'copyright',
-    'class' => 'form-input mb-4',
-    'value' => old('copyright', $podcast->copyright),
-]) ?>
-
-<?= form_section_close() ?>
-
-<?= form_section(
-    lang('Podcast.form.location_section_title'),
-    lang('Podcast.form.location_section_subtitle'),
-) ?>
-
-<?= form_label(
-    lang('Podcast.form.location_name'),
-    'location_name',
-    [],
-    lang('Podcast.form.location_name_hint'),
-    true,
-) ?>
-
-<?= form_input([
-    'id' => 'location_name',
-    'name' => 'location_name',
-    'class' => 'form-input mb-4',
-    'value' => old('location_name', $podcast->location_name),
-]) ?>
-
-<?= form_section_close() ?>
-
-<?= form_section(
-    lang('Podcast.form.monetization_section_title'),
-    lang('Podcast.form.monetization_section_subtitle'),
-) ?>
-
-<?= form_label(
-    lang('Podcast.form.payment_pointer'),
-    'payment_pointer',
-    [],
-    lang('Podcast.form.payment_pointer_hint'),
-    true,
-) ?>
-
-<?= form_input([
-    'id' => 'payment_pointer',
-    'name' => 'payment_pointer',
-    'class' => 'form-input mb-4',
-    'value' => old('payment_pointer', $podcast->payment_pointer),
-]) ?>
-
-<?= form_label(lang('Podcast.form.partnership')) ?>
-<div class="flex flex-col mb-4 gap-x-2 gap-y-4 md:flex-row">
-    <div class="flex flex-col flex-shrink w-32">
-        <?= form_label(
-    lang('Podcast.form.partner_id'),
-    'partner_id',
-    [],
-    lang('Podcast.form.partner_id_hint'),
-    true,
-) ?>
-        <?= form_input([
-            'id' => 'partner_id',
-            'name' => 'partner_id',
-            'class' => 'form-input w-full',
-            'value' => old('partner_id', $podcast->partner_id),
-        ]) ?>
+<Forms.Section
+    class="mb-8"
+    title="<?= lang('Podcast.form.identity_section_title') ?>"
+    subtitle="<?= lang('Podcast.form.identity_section_subtitle') ?>" >
+
+<Forms.Field
+    name="image"
+    label="<?= lang('Podcast.form.image') ?>"
+    helperText="<?= lang('Common.forms.image_size_hint') ?>"
+    type="file"
+    accept=".jpg,.jpeg,.png" />
+
+<Forms.Field
+    name="title"
+    label="<?= lang('Podcast.form.title') ?>"
+    helperText="<?= $podcast->link ?>"
+    value="<?= $podcast->title ?>"
+    required="true" />
+
+<Forms.Field
+    as="MarkdownEditor"
+    name="description"
+    label="<?= lang('Podcast.form.description') ?>"
+    value="<?= $podcast->title ?>"
+    required="true" />
+
+<fieldset>
+    <legend><?= lang('Podcast.form.type.label') .
+                hint_tooltip(lang('Podcast.form.type.hint'), 'ml-1') ?></legend>
+    <div class="flex gap-2">
+        <Forms.RadioButton
+            value="episodic"
+            name="type"
+            isChecked="<?= $podcast->type === 'episodic' ? 'true' : 'false' ?>" ><?= lang('Podcast.form.type.episodic') ?></Forms.RadioButton>
+        <Forms.RadioButton
+            value="serial"
+            name="type"
+            isChecked="<?= $podcast->type === 'serial' ? 'true' : 'false' ?>" ><?= lang('Podcast.form.type.serial') ?></Forms.RadioButton>
     </div>
-    <div class="flex flex-col flex-1">
-        <?= form_label(
-            lang('Podcast.form.partner_link_url'),
-            'partner_link_url',
-            [],
-            lang('Podcast.form.partner_link_url_hint'),
-            true,
-        ) ?>
-        <?= form_input([
-            'id' => 'partner_link_url',
-            'name' => 'partner_link_url',
-            'class' => 'form-input w-full',
-            'value' => old('partner_link_url', $podcast->partner_link_url),
-        ]) ?>
+</fieldset>
+
+</Forms.Section>
+
+<Forms.Section
+    class="mb-8"
+    title="<?= lang('Podcast.form.classification_section_title') ?>"
+    subtitle="<?= lang('Podcast.form.classification_section_subtitle') ?>" >
+
+    <Forms.Field
+        as="Select"
+        name="language"
+        label="<?= lang('Podcast.form.language') ?>"
+        selected="<?= $podcast->language_code ?>"
+        required="true"
+        options="<?= esc(json_encode($languageOptions)) ?>" />
+
+    <Forms.Field
+        as="Select"
+        name="category"
+        label="<?= lang('Podcast.form.category') ?>"
+        selected="<?= $podcast->category_id ?>"
+        required="true"
+        options="<?= esc(json_encode($categoryOptions)) ?>" />
+
+    <Forms.Field
+        as="MultiSelect"
+        name="other_categories[]"
+        label="<?= lang('Podcast.form.other_categories') ?>"
+        selected="<?= json_encode(old('other_categories', $podcast->other_categories_ids)) ?>"
+        data-max-item-count="2"
+        options="<?= esc(json_encode($categoryOptions)) ?>" />
+
+    <fieldset class="mb-4">
+        <legend><?= lang('Podcast.form.parental_advisory.label') .
+                    hint_tooltip(lang('Podcast.form.parental_advisory.hint'), 'ml-1') ?></legend>
+        <div class="flex gap-2">
+            <Forms.RadioButton
+                value="undefined"
+                name="parental_advisory"
+                isChecked="<?= $podcast->parental_advisory === null ? 'true' : 'false' ?>" ><?= lang('Podcast.form.parental_advisory.undefined') ?></Forms.RadioButton>
+            <Forms.RadioButton
+                value="clean"
+                name="parental_advisory"
+                isChecked="<?= $podcast->parental_advisory === 'clean' ? 'true' : 'false' ?>" ><?= lang('Podcast.form.parental_advisory.clean', ) ?></Forms.RadioButton>
+            <Forms.RadioButton
+                value="explicit"
+                name="parental_advisory"
+                isChecked="<?= $podcast->parental_advisory === 'explicit' ? 'true' : 'false' ?>" ><?= lang('Podcast.form.parental_advisory.explicit', ) ?></Forms.RadioButton>
+        </div>
+    </fieldset>
+</Forms.Section>
+
+<Forms.Section
+    class="mb-8"
+    title="<?= lang('Podcast.form.author_section_title') ?>"
+    subtitle="<?= lang('Podcast.form.author_section_subtitle') ?>" >
+
+<Forms.Field
+    name="owner_name"
+    label="<?= lang('Podcast.form.owner_name') ?>"
+    value="<?= $podcast->owner_name ?>"
+    hintText="<?= lang('Podcast.form.owner_name_hint') ?>"
+    required="true" />
+
+<Forms.Field
+    name="owner_email"
+    type="email"
+    label="<?= lang('Podcast.form.owner_email') ?>"
+    value="<?= $podcast->owner_email ?>"
+    hintText="<?= lang('Podcast.form.owner_email_hint') ?>"
+    required="true" />
+
+<Forms.Field
+    name="publisher"
+    label="<?= lang('Podcast.form.publisher') ?>"
+    value="<?= $podcast->publisher ?>"
+    hintText="<?= lang('Podcast.form.publisher_hint') ?>" />
+
+<Forms.Field
+    name="copyright"
+    label="<?= lang('Podcast.form.copyright') ?>"
+    value="<?= $podcast->copyright ?>" />
+
+</Forms.Section>
+
+<Forms.Section
+    class="mb-8"
+    title="<?= lang('Podcast.form.location_section_title') ?>"
+    subtitle="<?= lang('Podcast.form.location_section_subtitle') ?>" >
+
+<Forms.Field
+    name="location_name"
+    label="<?= lang('Podcast.form.location_name') ?>"
+    value="<?= $podcast->location_name ?>"
+    hintText="<?= lang('Podcast.form.location_name_hint') ?>" />
+
+</Forms.Section>
+
+<Forms.Section
+    class="mb-8"
+    title="<?= lang('Podcast.form.monetization_section_title') ?>"
+    subtitle="<?= lang('Podcast.form.monetization_section_subtitle') ?>" >
+
+<Forms.Field
+    name="payment_pointer"
+    label="<?= lang('Podcast.form.payment_pointer') ?>"
+    value="<?= $podcast->payment_pointer ?>"
+    hintText="<?= lang('Podcast.form.payment_pointer_hint') ?>" />
+
+<fieldset class="flex flex-col items-start p-4 bg-gray-100 rounded">
+    <Heading tagName="legend" class="float-left" size="small"><?= lang('Podcast.form.partnership') ?></Heading>
+    <div class="flex flex-col w-full clear-left gap-x-2 gap-y-4 md:flex-row">
+        <div class="flex flex-col flex-shrink w-32">
+            <Forms.Label for="partner_id" hint="<?= lang('Podcast.form.partner_id_hint') ?>" isOptional="true"><?= lang('Podcast.form.partner_id') ?></Forms.Label>
+            <Forms.Input name="partner_id" value="<?= $podcast->partner_id ?>" />
+        </div>
+        <div class="flex flex-col flex-1">
+            <Forms.Label for="partner_link_url" hint="<?= lang('Podcast.form.partner_link_url_hint') ?>" isOptional="true"><?= lang('Podcast.form.partner_link_url') ?></Forms.Label>
+            <Forms.Input name="partner_link_url" value="<?= $podcast->partner_link_url ?>" />
+        </div>
     </div>
-    <div class="flex flex-col flex-1">
-        <?= form_label(
-            lang('Podcast.form.partner_image_url'),
-            'partner_image_url',
-            [],
-            lang('Podcast.form.partner_image_url_hint'),
-            true,
-        ) ?>
-    <?= form_input([
-        'id' => 'partner_image_url',
-        'name' => 'partner_image_url',
-        'class' => 'form-input w-full',
-        'value' => old('partner_image_url', $podcast->partner_image_url),
-    ]) ?>
+    <div class="flex flex-col w-full mt-2">
+        <Forms.Label for="partner_image_url" hint="<?= lang('Podcast.form.partner_image_url_hint') ?>" isOptional="true"><?= lang('Podcast.form.partner_image_url') ?></Forms.Label>
+        <Forms.Input name="partner_image_url" value="<?= $podcast->partner_image_url ?>" />
     </div>
-</div>
-<?= form_section_close() ?>
-
-<?= form_section(
-        lang('Podcast.form.advanced_section_title'),
-        lang('Podcast.form.advanced_section_subtitle'),
-    ) ?>
-
-<?= form_label(
-        lang('Podcast.form.custom_rss'),
-        'custom_rss',
-        [],
-        lang('Podcast.form.custom_rss_hint'),
-        true,
-    ) ?>
-<Forms.XMLEditor id="custom_rss" name="custom_rss"><?= old('custom_rss', $podcast->custom_rss_string, false) ?></Forms.XMLEditor>
-
-<?= form_section_close() ?>
-
-<?= form_section(
-        lang('Podcast.form.status_section_title'),
-        lang('Podcast.form.status_section_subtitle'),
-    ) ?>
-
-<Forms.Toggler class="mb-2" id="lock" name="lock" value="yes" checked="<?= old('complete', $podcast->is_locked) ?>" hint="<?= lang('Podcast.form.lock_hint') ?>">
-    <?= lang('Podcast.form.lock') ?>
-</Forms.Toggler>
-<Forms.Toggler class="mb-2" id="block" name="block" value="yes" checked="<?= old('complete', $podcast->is_blocked) ?>">
-    <?= lang('Podcast.form.block') ?>
-</Forms.Toggler>
-<Forms.Toggler id="complete" name="complete" value="yes" checked="<?= old('complete', $podcast->is_completed) ?>">
-    <?= lang('Podcast.form.complete') ?>
-</Forms.Toggler>
-
-<?= form_section_close() ?>
-
-<Button variant="primary" type="submit" class="self-end">
-<?= lang('Podcast.form.submit_edit') ?>
-</Button>
+</fieldset>
+</Forms.Section>
+
+<Forms.Section
+    class="mb-8"
+    title="<?= lang('Podcast.form.advanced_section_title') ?>"
+    subtitle="<?= lang('Podcast.form.advanced_section_subtitle') ?>" >
+
+<Forms.Field
+    as="XMLEditor"
+    name="custom_rss"
+    label="<?= lang('Podcast.form.custom_rss') ?>"
+    value="<?= $podcast->custom_rss_string ?>"
+    hintText="<?= lang('Podcast.form.custom_rss_hint') ?>" />
+
+</Forms.Section>
+
+<Forms.Section
+    class="mb-8"
+    title="<?= lang('Podcast.form.status_section_title') ?>"
+    subtitle="<?= lang('Podcast.form.status_section_subtitle') ?>" >
+    <Forms.Toggler class="mb-2" id="lock" name="lock" value="yes" checked="<?= old('complete', $podcast->is_locked) ?>" hint="<?= lang('Podcast.form.lock_hint') ?>">
+        <?= lang('Podcast.form.lock') ?>
+    </Forms.Toggler>
+    <Forms.Toggler class="mb-2" id="block" name="block" value="yes" checked="<?= old('complete', $podcast->is_blocked) ?>">
+        <?= lang('Podcast.form.block') ?>
+    </Forms.Toggler>
+    <Forms.Toggler id="complete" name="complete" value="yes" checked="<?= old('complete', $podcast->is_completed) ?>">
+        <?= lang('Podcast.form.complete') ?>
+    </Forms.Toggler>
+</Forms.Section>
 
 <?= form_close() ?>
 
diff --git a/themes/cp_admin/podcast/latest_episodes.php b/themes/cp_admin/podcast/latest_episodes.php
index bd4c78c5227aea2f221198a56d104cb9e1632423..540f993740a74d0d6943ef22dd0b45a803356e18 100644
--- a/themes/cp_admin/podcast/latest_episodes.php
+++ b/themes/cp_admin/podcast/latest_episodes.php
@@ -1,6 +1,6 @@
 <section class="flex flex-col">
     <header class="flex justify-between py-2">
-        <Heading level="2"><?= lang('Podcast.latest_episodes') ?></Heading>
+        <Heading tagName="h2"><?= lang('Podcast.latest_episodes') ?></Heading>
         <a href="<?= route_to(
     'episode-list',
     $podcast->id,