diff --git a/assets/css/create.css b/assets/css/create.css
new file mode 100644
index 0000000000000000000000000000000000000000..d39ec0c61d042a4748ebcb93116cbf1586cd832d
--- /dev/null
+++ b/assets/css/create.css
@@ -0,0 +1,31 @@
+form {
+    display: flex;
+    flex-direction: column;
+    align-items: stretch;
+
+    padding: 1rem;
+
+    input, textarea {
+        &.error {
+            border-color: red;
+            background-color: rgba(255, 0, 0, 0.1);
+        }
+    }
+
+    p {
+        margin-top: 0;
+    }
+
+    button {
+        align-self: flex-end;
+        padding: 1rem;
+        background-color: var(--primary-light);
+        border-radius: 1rem;
+        border: none;
+        cursor: pointer;
+
+        &:hover {
+            box-shadow: 3px 3px 10px var(--text-action);
+        }
+    }
+}
\ No newline at end of file
diff --git a/assets/img/save/1741942598.png b/assets/img/save/1741942598.png
new file mode 100644
index 0000000000000000000000000000000000000000..570fddd340f82a5b54b5cb44a47fb718cf9ea91d
Binary files /dev/null and b/assets/img/save/1741942598.png differ
diff --git a/assets/js/form.js b/assets/js/form.js
new file mode 100644
index 0000000000000000000000000000000000000000..f364c1a04cb7d7868c8d0b3e103c103b9012af8d
--- /dev/null
+++ b/assets/js/form.js
@@ -0,0 +1,66 @@
+document.querySelector('form')
+        ?.addEventListener('submit', function (e) {
+            console.log(e);
+            e.preventDefault();
+
+            let hasError = false;
+
+            const title = document.getElementById('title');
+            if (title.value === '' || title.value.length > 100) {
+                hasError = true;
+                title.classList.add('error');
+
+                title.nextElementSibling.innerText = 'Le titre doit avoir entre 0 et 100 caractères';
+
+                title.addEventListener('input', () => {
+                    if (title.value !== '' && title.value.length <= 100) {
+                        if (title.classList.contains('error')) {
+                            title.classList.remove('error');
+                            title.nextElementSibling.innerText = '';
+                        }
+                    } else {
+                        title.classList.add('error');
+                        title.nextElementSibling.innerText = 'Le titre doit avoir entre 0 et 100 caractères';
+                    }
+                });
+            }
+
+            const description = document.getElementById('description');
+            if (description.value === '') {
+                hasError = true;
+                description.classList.add('error');
+
+                description.nextElementSibling.innerText = 'La description est obligatoire';
+
+                description.addEventListener('input', () => {
+                    if (description.value !== '') {
+                        if (description.classList.contains('error')) {
+                            description.classList.remove('error');
+                            description.nextElementSibling.innerText = '';
+                        }
+                    } else {
+                        description.classList.add('error');
+                        description.nextElementSibling.innerText = 'La description est obligatoire';
+                    }
+                });
+            }
+
+            if (!hasError) {
+                this.submit();
+            }
+        });
+
+/*// Validation d'un champ avec format spécifique, exemple: email
+const title = document.getElementById('title');
+title.addEventListener('input', () => {
+    // 1ère méthode
+    /^[a-zA-Z0-9.-_]+@[a-zA-Z0-9.-_]+\.[a-z]{2,}$/.test(title.value);
+
+    // 2ème méthode
+    const reg = new RegExp(/^[a-zA-Z0-9.-_]+@[a-zA-Z0-9.-_]+\.[a-z]{2,}$/);
+    reg.test(title.value);
+
+    // 3ème méthode
+    title.value.match(/^[a-zA-Z0-9.-_]+@[a-zA-Z0-9.-_]+\.[a-z]{2,}$/);
+});*/
+
diff --git a/assets/php/db.sqlite b/assets/php/db.sqlite
index a54f231cb294630a6b4e772224e38d466d873d36..b75635b4ea953daaf6ec0d3e1ce5e5396923694e 100644
Binary files a/assets/php/db.sqlite and b/assets/php/db.sqlite differ
diff --git a/create.php b/create.php
index cf1ab724e66b184afa32c7d755965276d3793fed..aa230e9e20d982c1ffc9bfd72d35d55c850c4fe2 100644
--- a/create.php
+++ b/create.php
@@ -10,6 +10,9 @@ require_once 'assets/locales/trad.php';
   <title>Créer une recette</title>
 
   <link rel="stylesheet" href="assets/css/style.css">
+  <link rel="stylesheet" href="assets/css/create.css">
+
+  <script type="module" src="assets/js/form.js"></script>
 </head>
 <body>
 <?php
@@ -21,16 +24,19 @@ include_once 'assets/php/navbar.php';
       <?= $t['create']['form']['thumbnail'] ?>
   </label>
   <input type="file" name="thumbnail" id="thumbnail" accept="image/*"/>
-
+  <p></p>
+  
   <label for="title">
       <?= $t['create']['form']['title'] ?>
   </label>
   <input name="title" type="text" placeholder="Titre" id="title"/>
+  <p></p>
 
   <label for="description">
       <?= $t['create']['form']['description'] ?>
   </label>
   <textarea name="description" id="description" cols="30" rows="10"></textarea>
+  <p></p>
 
   <button type="submit">
       <?= $t['core']['save'] ?>