diff --git a/admin/api/designer.go b/admin/api/designer.go
index a31349d906a872a6f48e36620083ca68582bd9c0..0f22aceb8dd23be9ba6340b6b62c8e88b7e71a03 100644
--- a/admin/api/designer.go
+++ b/admin/api/designer.go
@@ -39,13 +39,12 @@ func createFontDesigner(w http.ResponseWriter, r *http.Request) {
 		return
 	}
 
+	w.WriteHeader(http.StatusCreated)
 	err = json.NewEncoder(w).Encode(newDesigner)
 	if err != nil {
 		http.Error(w, "Failed to encode body", http.StatusInternalServerError)
 		return
 	}
-
-	w.WriteHeader(http.StatusCreated)
 }
 
 func deleteFontDesigner(w http.ResponseWriter, r *http.Request) {
diff --git a/static/admin/css/cosmo-edits.css b/static/admin/css/cosmo-edits.css
index 974e15dccb06b99c54c6cdbdc9957679e1cc3bba..7309df9392ac3d63e023282e88d91b5d477e2db6 100644
--- a/static/admin/css/cosmo-edits.css
+++ b/static/admin/css/cosmo-edits.css
@@ -13,4 +13,8 @@
 
 .cosmo-tab__content.is--designer {
   height: calc(var(--page-height) - var(--tab-links-height) - var(--tab-gap) - var(--title-font-size) - 0.5rem);
-}
\ No newline at end of file
+}
+
+.cosmo-modal {
+  max-width: max(30vw, 30rem);
+}
diff --git a/static/admin/css/fonts.css b/static/admin/css/fonts.css
index 40624a57e0b977cf04c4c495bce6f1592ceed1bb..683d5c5cc3c6e24455fb391b4bdfe46568b3086c 100644
--- a/static/admin/css/fonts.css
+++ b/static/admin/css/fonts.css
@@ -11,3 +11,7 @@
 .is--loading {
   overflow: hidden;
 }
+
+.font-description {
+  width: 40rem;
+}
diff --git a/static/admin/css/form.css b/static/admin/css/form.css
index a30ad389797e9bcd46285117379d9dca9d1e158b..8e0b897a2b908729143847bcab07d151ff61a939 100644
--- a/static/admin/css/form.css
+++ b/static/admin/css/form.css
@@ -1,26 +1,26 @@
 .jinya-fieldset {
-    min-width: 0;
-    padding: 0;
-    margin: 0;
-    border: 0;
-    grid-column: span 2;
+  min-width: 0;
+  padding: 0;
+  margin: 0;
+  border: 0;
+  grid-column: span 2;
 }
 
 .jinya-legend {
-    font-size: var(--input-header-font-size);
-    height: var(--input-header-font-size);
-    font-weight: var(--font-weight-light);
-    font-family: var(--font-family-heading);
-    text-transform: uppercase;
-    grid-column: span 2;
-    margin-top: var(--input-group-gap);
-    margin-bottom: var(--input-group-gap);
+  font-size: var(--input-header-font-size);
+  height: var(--input-header-font-size);
+  font-weight: var(--font-weight-light);
+  font-family: var(--font-family-heading);
+  text-transform: uppercase;
+  grid-column: span 2;
+  margin-top: var(--input-group-gap);
+  margin-bottom: var(--input-group-gap);
 }
 
 jinya-toolbar-editor {
-    grid-column: span 2;
+  grid-column: span 2;
 }
 
 .top-gap {
-    margin-top: 1rem;
+  margin-top: 1rem;
 }
diff --git a/static/admin/js/font/detail.js b/static/admin/js/font/detail.js
index 778c98d66aa99dee4373b0534727ace94fd106dc..d5448c9bababc6cb59c8456d8a306eee7d1d6814 100644
--- a/static/admin/js/font/detail.js
+++ b/static/admin/js/font/detail.js
@@ -1,5 +1,5 @@
 import { Alpine } from '../../../lib/alpine.js';
-import { get, httpDelete, post } from '../../../lib/jinya-http.js';
+import { get, httpDelete, post, put } from '../../../lib/jinya-http.js';
 
 import '../../lib/ui/toolbar-editor.js';
 import confirm from '../../lib/ui/confirm.js';
@@ -11,10 +11,23 @@ Alpine.data('fontDetailsData', () => ({
   font: null,
   activeDesigner: null,
   editDesignerOn: false,
+  editFontOpen: false,
   newDesigner: {
     name: '',
     bio: '',
   },
+  newFileOpen: false,
+  newFile: {
+    file: undefined,
+    weight: '400',
+    style: 'normal',
+  },
+  editFileOpen: false,
+  editFile: {
+    file: undefined,
+    weight: '400',
+    style: 'normal',
+  },
   get fontName() {
     return this.$router.params.name;
   },
@@ -29,11 +42,42 @@ Alpine.data('fontDetailsData', () => ({
     this.activeSideItem = item;
   },
   openEditFontDialog() {
+    this.font.editDescription = this.font.description;
+    this.font.editLicense = this.font.license;
+    this.font.editCategory = this.font.category;
+    this.editFontOpen = true;
+  },
+  openNewFileDialog() {
+    this.newFile = {
+      file: undefined,
+      weight: '400',
+      style: 'normal',
+    };
+    this.newFileOpen = true;
+  },
+  openEditFileDialog(file) {
+    this.editFile = {
+      file: undefined,
+      weight: file.weight,
+      style: file.style,
+    };
+    this.editFileOpen = true;
   },
   editDesigner() {
     this.activeDesigner.editBio = this.activeDesigner.bio;
     this.editDesignerOn = true;
   },
+  async updateFont() {
+    this.font.description = this.font.editDescription;
+    this.font.license = this.font.editLicense;
+    this.font.category = this.font.editCategory;
+    await put(`/api/admin/font/${this.fontName}`, {
+      description: this.font.editDescription,
+      license: this.font.editLicense,
+      category: this.font.editCategory,
+    });
+    this.editFontOpen = false;
+  },
   async createNewDesigner() {
     const newDesigner = await post(`/api/admin/font/${this.fontName}/designer`, this.newDesigner);
     this.font.designers = [...this.font.designers, newDesigner];
@@ -46,7 +90,7 @@ Alpine.data('fontDetailsData', () => ({
       bio: this.activeDesigner.editBio,
       name: this.activeDesigner.name,
     });
-    this.font.designers = [...this.font.designers.filter(d => d.name !== this.activeDesigner.name), updatedDesigner];
+    this.font.designers = [...this.font.designers.filter((d) => d.name !== this.activeDesigner.name), updatedDesigner];
     this.activeDesigner = updatedDesigner;
     this.activeDesigner.editBio = updatedDesigner.bio;
     this.editDesignerOn = false;
@@ -76,8 +120,41 @@ Alpine.data('fontDetailsData', () => ({
       })
     ) {
       await httpDelete(`/api/admin/font/${this.fontName}/designer/${this.activeDesigner.name}`);
-      this.font.designers = this.font.designers.filter(d => d.name !== this.activeDesigner.name);
+      this.font.designers = this.font.designers.filter((d) => d.name !== this.activeDesigner.name);
       this.activeDesigner = this.font.designers.at(0) ?? null;
     }
   },
+  async deleteFile(file) {
+    if (
+      await confirm({
+        title: localize({ key: 'delete-file-title' }),
+        approveLabel: localize({ key: 'delete-file-confirm-label' }),
+        declineLabel: localize({ key: 'delete-file-decline-label' }),
+        message: localize({
+          key: 'delete-file-message',
+          values: {
+            type: file.type,
+            weight: localize({ key: `font-weight-${file.weight}` }),
+            style: localize({ key: `font-style-${file.style}` }),
+          },
+        }),
+        negative: true,
+      })
+    ) {
+      await httpDelete(`/api/admin/font/${this.fontName}/file/${file.weight}.${file.style}.${file.type}`);
+      this.font.fonts = this.font.fonts.filter((f) => f.path !== file.path);
+    }
+  },
+  async createNewFile() {
+    const type = this.newFile.file.name.split('.').reverse()[0];
+    await post(`/api/admin/font/${this.fontName}/file/${this.newFile.weight}.${this.newFile.style}.${type}`, this.newFile.file);
+    this.font.fonts = await get(`/api/admin/font/${this.fontName}/file`);
+    this.newFileOpen = false;
+  },
+  async updateFile() {
+    const type = this.editFile.file.name.split('.').reverse()[0];
+    await post(`/api/admin/font/${this.fontName}/file/${this.editFile.weight}.${this.editFile.style}.${type}`, this.editFile.file);
+    this.font.fonts = await get(`/api/admin/font/${this.fontName}/file`);
+    this.editFileOpen = false;
+  },
 }));
diff --git a/static/admin/langs/messages.de.json b/static/admin/langs/messages.de.json
index dcdee3f28b28109f8e1a2b4e06868beda24262ca..b9c7acd1a9d2b28d5fe0033c2914e02a875d35ec 100644
--- a/static/admin/langs/messages.de.json
+++ b/static/admin/langs/messages.de.json
@@ -76,7 +76,7 @@
   "delete-file-title": "Datei entfernen",
   "delete-file-confirm-label": "Datei entfernen",
   "delete-file-decline-label": "Datei nicht entfernen",
-  "delete-file-message": "Soll die {name}-Datei mit der Stärke {style} im Stil {style}",
+  "delete-file-message": "Soll die {type}-Datei mit der Stärke {weight} im Stil {style} wirklich gelöscht werden?",
   "font-list-all-fonts": "Alle Schriften",
   "font-list-google-fonts": "Schriften von Google",
   "font-list-custom-fonts": "Eigene Schriften ",
diff --git a/static/admin/langs/messages.en.json b/static/admin/langs/messages.en.json
index 3d6f10e2d67753fdabcf713a74e48bf5bf66966e..367bc7fa8acc5f716c800b54c5b6eb8a8caa8cd2 100644
--- a/static/admin/langs/messages.en.json
+++ b/static/admin/langs/messages.en.json
@@ -76,7 +76,7 @@
   "delete-file-title": "Remove file",
   "delete-file-confirm-label": "Remove file",
   "delete-file-decline-label": "Keep file",
-  "delete-file-message": "Do you really want to remove the {name}-file with a weight of {weight} in font style {style}",
+  "delete-file-message": "Do you really want to remove the {type}-file with a weight of {weight} in font style {style}",
   "font-list-all-fonts": "All fonts",
   "font-list-google-fonts": "Google Fonts",
   "font-list-custom-fonts": "Custom fonts",
diff --git a/static/admin/langs/messages.json b/static/admin/langs/messages.json
index 3d6f10e2d67753fdabcf713a74e48bf5bf66966e..367bc7fa8acc5f716c800b54c5b6eb8a8caa8cd2 100644
--- a/static/admin/langs/messages.json
+++ b/static/admin/langs/messages.json
@@ -76,7 +76,7 @@
   "delete-file-title": "Remove file",
   "delete-file-confirm-label": "Remove file",
   "delete-file-decline-label": "Keep file",
-  "delete-file-message": "Do you really want to remove the {name}-file with a weight of {weight} in font style {style}",
+  "delete-file-message": "Do you really want to remove the {type}-file with a weight of {weight} in font style {style}",
   "font-list-all-fonts": "All fonts",
   "font-list-google-fonts": "Google Fonts",
   "font-list-custom-fonts": "Custom fonts",
diff --git a/static/admin/lib/ui/jodit.js b/static/admin/lib/ui/jodit.js
index d49ab3cdae1763e165eb7fd1dc181e18bfd96604..ed713dc5b69608e3ae8e41548e32db85b5dc226e 100755
--- a/static/admin/lib/ui/jodit.js
+++ b/static/admin/lib/ui/jodit.js
@@ -152,7 +152,7 @@ function getFullToolbar() {
   ];
 }
 
-export function createJodit(idOrElement, inline = false, height = undefined) {
+export function createJodit(idOrElement, inline = false, allowFullscreen = false, height = undefined) {
   setJoditIcons();
   const data = {
     toolbar: !inline,
@@ -161,7 +161,7 @@ export function createJodit(idOrElement, inline = false, height = undefined) {
     showXPathInStatusbar: false,
     minHeight: '11rem',
     disablePlugins:
-      'about,add-new-line,ai-assistant,class-span,clean-html,clipboard,copyformat,dtd,file,font,hr,iframe,image,image-properties,indent,key-arrow-outside,line-height,mobile,xpath,table-keyboard-navigation,tab,symbols,stat,spellcheck,speech-recognize,search,resize-cells,redo-undo,print,preview,powered-by-jodit,paste-storage,paste-from-word,video,wrap-nodes,limit',
+      'about,add-new-line,ai-assistant,class-span,clean-html,clipboard,copyformat,dtd,file,font,hr,iframe,image,image-properties,indent,key-arrow-outside,line-height,mobile,xpath,table-keyboard-navigation,tab,symbols,stat,spellcheck,speech-recognize,search,resize-cells,redo-undo,print,preview,powered-by-jodit,paste-storage,paste-from-word,video,wrap-nodes,limit,fullscreen',
     inline,
     toolbarInline: true,
     toolbarInlineForSelection: true,
@@ -177,7 +177,7 @@ export function createJodit(idOrElement, inline = false, height = undefined) {
   if (height) {
     data.height = height;
   }
-  if (!inline) {
+  if (allowFullscreen) {
     data.buttons = getFullToolbar();
     data.extraButtons = ['fullsize', 'source'];
   }
diff --git a/static/admin/lib/ui/toolbar-editor.js b/static/admin/lib/ui/toolbar-editor.js
index 3e3f1294e70558473208ff2c4b81b74cb83dcd1f..dff68f97050ebe28f3d3077619f93647119b8de0 100755
--- a/static/admin/lib/ui/toolbar-editor.js
+++ b/static/admin/lib/ui/toolbar-editor.js
@@ -18,7 +18,7 @@ class ToolbarEditorElement extends HTMLElement {
       </style>
       <textarea></textarea>
     `;
-    this.editor = createJodit(this.root.querySelector('textarea'), false, this.height);
+    this.editor = createJodit(this.root.querySelector('textarea'), false, false, this.height);
     this.editor.value = this.content;
     this.editor.events.on('change', (e) => {
       this.dispatchEvent(new EditorChangeEvent(e));
diff --git a/static/admin/templates/font/detail.html b/static/admin/templates/font/detail.html
index 1059052e32a178330ef45da7dad9a675838518fa..cafac3f8e3a4e050b0179b793868c15926a6f61a 100644
--- a/static/admin/templates/font/detail.html
+++ b/static/admin/templates/font/detail.html
@@ -47,7 +47,47 @@
             <dd x-boolean-display="font.googleFont"></dd>
           </dl>
           <h4 x-localize:font-description=""></h4>
-          <div x-html="font.description"></div>
+          <div class="font-description" x-html="font.description"></div>
+          <template x-if="editFontOpen">
+            <div class="cosmo-modal__container">
+              <form class="cosmo-modal" @submit.prevent="updateFont">
+                <h1 class="cosmo-modal__title" x-localize:edit-font-title="font"></h1>
+                <div class="cosmo-modal__content">
+                  <div class="cosmo-input__group">
+                    <label for="category" class="cosmo-label" x-localize:font-category=""></label>
+                    <select class="cosmo-select" id="category" x-model="font.editCategory">
+                      <option value="Sans Serif" x-localize:font-style-sans-serif=""></option>
+                      <option value="Serif" x-localize:font-style-serif=""></option>
+                      <option value="Monospace" x-localize:font-style-monospace=""></option>
+                      <option value="Display" x-localize:font-style-display=""></option>
+                      <option value="Handwriting" x-localize:font-style-handwriting=""></option>
+                    </select>
+                    <label for="license" class="cosmo-label" x-localize:font-license=""></label>
+                    <input required list="suggestedLicenses" type="text" id="license" class="cosmo-input" x-model="font.editLicense" />
+                    <template x-if="!font.editLicense">
+                      <span class="cosmo-input__message is--negative" x-localize:font-license-error=""></span>
+                    </template>
+                    <datalist id="suggestedLicenses">
+                      <option value="ufl"></option>
+                      <option value="ofl"></option>
+                      <option value="apache2"></option>
+                      <option value="mit"></option>
+                      <option value="cc0"></option>
+                    </datalist>
+                    <span class="cosmo-input__header" x-localize:font-description=""></span>
+                    <jinya-toolbar-editor
+                      :content="font.editDescription"
+                      @change="(e) => font.editDescription = e.value"
+                    ></jinya-toolbar-editor>
+                  </div>
+                </div>
+                <div class="cosmo-modal__button-bar">
+                  <button class="cosmo-button" @click="editFontOpen = false" x-localize:discard-changes=""></button>
+                  <button class="cosmo-button" type="submit" x-localize:save-font=""></button>
+                </div>
+              </form>
+            </div>
+          </template>
         </div>
       </template>
       <template x-if="activeSideItem === 'designers'">
@@ -81,18 +121,19 @@
                 <template x-if="!font.googleFont">
                   <div class="cosmo-toolbar">
                     <div class="cosmo-toolbar__group">
-                      <button class="cosmo-button" :disabled="editDesignerOn" @click="editDesigner"
-                              x-localize:edit=""></button>
+                      <button class="cosmo-button" :disabled="editDesignerOn" @click="editDesigner" x-localize:edit=""></button>
                       <button class="cosmo-button" @click="removeDesigner" x-localize:delete=""></button>
                     </div>
                   </div>
                 </template>
                 <template x-if="editDesignerOn">
                   <form class="top-gap" @submit.prevent="updateDesigner()">
-                    <jinya-toolbar-editor :content="activeDesigner.editBio" @change="(e) => activeDesigner.editBio = e.value"></jinya-toolbar-editor>
+                    <jinya-toolbar-editor
+                      :content="activeDesigner.editBio"
+                      @change="(e) => activeDesigner.editBio = e.value"
+                    ></jinya-toolbar-editor>
                     <div class="cosmo-button__container">
-                      <button class="cosmo-button" @click="editDesignerOn = false" type="reset"
-                              x-localize:discard-changes=""></button>
+                      <button class="cosmo-button" @click="editDesignerOn = false" type="reset" x-localize:discard-changes=""></button>
                       <button class="cosmo-button is--primary" type="submit" x-localize:save-designer=""></button>
                     </div>
                   </form>
@@ -131,40 +172,122 @@
           <template x-if="!font.googleFont">
             <div class="cosmo-toolbar">
               <div class="cosmo-toolbar__group">
-                <button class="cosmo-button" @click="addFileDialogOpen = true" x-localize:upload-file=""></button>
+                <button class="cosmo-button" @click="openNewFileDialog" x-localize:upload-file=""></button>
               </div>
             </div>
           </template>
           <table class="cosmo-table">
             <thead>
-            <tr>
-              <th x-localize:font-style=""></th>
-              <th x-localize:font-weight=""></th>
-              <th x-localize:font-file-type=""></th>
-              <th x-localize:actions=""></th>
-            </tr>
-            </thead>
-            <tbody>
-            <template x-for="file in font.fonts">
               <tr>
-                <td x-text="file.style"></td>
-                <td x-text="file.weight"></td>
-                <td x-text="file.type"></td>
-                <td>
-                  <div class="cosmo-toolbar__group">
-                    <a :href="file.path" class="cosmo-button" x-localize:download=""></a>
-                    <template x-if="!font.googleFont">
-                      <button class="cosmo-button" @click="openEditFile(file)" x-localize:edit=""></button>
-                    </template>
-                    <template x-if="!font.googleFont">
-                      <button class="cosmo-button" @click="openDeleteFile(file)" x-localize:delete=""></button>
-                    </template>
-                  </div>
-                </td>
+                <th x-localize:font-style=""></th>
+                <th x-localize:font-weight=""></th>
+                <th x-localize:font-file-type=""></th>
+                <th x-localize:actions=""></th>
               </tr>
-            </template>
+            </thead>
+            <tbody>
+              <template x-for="file in font.fonts">
+                <tr>
+                  <td x-text="file.style"></td>
+                  <td x-text="file.weight"></td>
+                  <td x-text="file.type"></td>
+                  <td>
+                    <div class="cosmo-toolbar__group">
+                      <a :href="file.path" native class="cosmo-button" x-localize:download=""></a>
+                      <template x-if="!font.googleFont">
+                        <button class="cosmo-button" @click="openEditFileDialog(file)" x-localize:edit=""></button>
+                      </template>
+                      <template x-if="!font.googleFont">
+                        <button class="cosmo-button" @click="deleteFile(file)" x-localize:delete=""></button>
+                      </template>
+                    </div>
+                  </td>
+                </tr>
+              </template>
             </tbody>
           </table>
+          <template x-if="newFileOpen">
+            <div class="cosmo-modal__container">
+              <form class="cosmo-modal" @submit.prevent="createNewFile">
+                <h1 class="cosmo-modal__title" x-localize:create-file-title=""></h1>
+                <div class="cosmo-modal__content">
+                  <div class="cosmo-input__group">
+                    <label for="weight" class="cosmo-label" x-localize:font-weight-label=""></label>
+                    <select class="cosmo-select" id="weight" x-model="newFile.weight">
+                      <option value="100" x-localize:font-weight-100=""></option>
+                      <option value="200" x-localize:font-weight-200=""></option>
+                      <option value="300" x-localize:font-weight-300=""></option>
+                      <option value="400" x-localize:font-weight-400=""></option>
+                      <option value="500" x-localize:font-weight-500=""></option>
+                      <option value="600" x-localize:font-weight-600=""></option>
+                      <option value="700" x-localize:font-weight-700=""></option>
+                      <option value="800" x-localize:font-weight-800=""></option>
+                      <option value="900" x-localize:font-weight-900=""></option>
+                    </select>
+                    <label for="style" class="cosmo-label" x-localize:font-style-label=""></label>
+                    <select class="cosmo-select" id="style" x-model="newFile.style">
+                      <option value="normal" x-localize:font-style-normal=""></option>
+                      <option value="italic" x-localize:font-style-italic=""></option>
+                    </select>
+                    <label for="file" class="cosmo-label" x-localize:font-file=""></label>
+                    <input
+                      required
+                      type="file"
+                      id="file"
+                      class="cosmo-input"
+                      accept="font/woff2, font/ttf"
+                      @change="(e) => newFile.file = e.target.files.item(0)"
+                    />
+                  </div>
+                </div>
+                <div class="cosmo-modal__button-bar">
+                  <button class="cosmo-button" type="button" @click="newFileOpen = false" x-localize:cancel=""></button>
+                  <button class="cosmo-button" type="submit" x-localize:upload-file=""></button>
+                </div>
+              </form>
+            </div>
+          </template>
+          <template x-if="editFileOpen">
+            <div class="cosmo-modal__container">
+              <form class="cosmo-modal" @submit.prevent="updateFile">
+                <h1 class="cosmo-modal__title" x-localize:upload-file=""></h1>
+                <div class="cosmo-modal__content">
+                  <div class="cosmo-input__group">
+                    <label for="style" class="cosmo-label" x-localize:font-style-label=""></label>
+                    <select disabled class="cosmo-select" id="style" x-model="editFile.style">
+                      <option value="normal" x-localize:font-style-normal=""></option>
+                      <option value="italic" x-localize:font-style-italic=""></option>
+                    </select>
+                    <label for="weight" class="cosmo-label" x-localize:font-weight-label=""></label>
+                    <select disabled class="cosmo-select" id="weight" x-model="editFile.weight">
+                      <option value="100" x-localize:font-weight-100=""></option>
+                      <option value="200" x-localize:font-weight-200=""></option>
+                      <option value="300" x-localize:font-weight-300=""></option>
+                      <option value="400" x-localize:font-weight-400=""></option>
+                      <option value="500" x-localize:font-weight-500=""></option>
+                      <option value="600" x-localize:font-weight-600=""></option>
+                      <option value="700" x-localize:font-weight-700=""></option>
+                      <option value="800" x-localize:font-weight-800=""></option>
+                      <option value="900" x-localize:font-weight-900=""></option>
+                    </select>
+                    <label for="file" class="cosmo-label" x-localize:font-file=""></label>
+                    <input
+                      required
+                      type="file"
+                      id="file"
+                      class="cosmo-input"
+                      accept="font/woff2, font/ttf"
+                      @change="(e) => editFile.file = e.target.files.item(0)"
+                    />
+                  </div>
+                </div>
+                <div class="cosmo-modal__button-bar">
+                  <button class="cosmo-button" type="button" @click="editFileOpen = false" x-localize:cancel=""></button>
+                  <button class="cosmo-button" type="submit" x-localize:upload-file=""></button>
+                </div>
+              </form>
+            </div>
+          </template>
         </div>
       </template>
     </div>
diff --git a/static/admin/templates/font/page.html b/static/admin/templates/font/page.html
index 02c982f73459c82767b874a1013e2008ae84ac83..3cbd0ab7ce6f8d65f59d9d5a513cf5de036f1d89 100644
--- a/static/admin/templates/font/page.html
+++ b/static/admin/templates/font/page.html
@@ -97,11 +97,9 @@
           <div class="cosmo-input__group">
             <label for="family" class="cosmo-label" x-localize:font-family=""></label>
             <input required type="text" id="family" class="cosmo-input" x-model="newFont.family" />
-            <span
-              class="cosmo-input__message is--negative"
-              :class="{ 'is--hidden': !newFont.family }"
-              x-localize:font-family-error=""
-            ></span>
+            <template x-if="!newFont.family">
+              <span class="cosmo-input__message is--negative" x-localize:font-family-error=""></span>
+            </template>
             <label for="category" class="cosmo-label" x-localize:font-category=""></label>
             <select class="cosmo-select" id="category" x-model="newFont.category">
               <option value="Sans Serif" x-localize:font-style-sans-serif=""></option>
@@ -112,11 +110,9 @@
             </select>
             <label for="license" class="cosmo-label" x-localize:font-license=""></label>
             <input required list="suggestedLicenses" type="text" id="license" class="cosmo-input" x-model="newFont.license" />
-            <span
-              class="cosmo-input__message is--negative"
-              :class="{ 'is--hidden': !newFont.license }"
-              x-localize:font-license-error=""
-            ></span>
+            <template x-if="!newFont.license">
+              <span class="cosmo-input__message is--negative" x-localize:font-license-error=""></span>
+            </template>
             <datalist id="suggestedLicenses">
               <option value="ufl"></option>
               <option value="ofl"></option>
@@ -125,7 +121,7 @@
               <option value="cc0"></option>
             </datalist>
             <span class="cosmo-input__header" x-localize:font-description=""></span>
-            <jinya-toolbar-editor x-model="newFont.description"></jinya-toolbar-editor>
+            <jinya-toolbar-editor :content="newFont.description" @change="(e) => newFont.description = e.value"></jinya-toolbar-editor>
           </div>
         </div>
         <div class="cosmo-modal__button-bar">
diff --git a/static/lib/jinya-http.js b/static/lib/jinya-http.js
index f9339b7f3261ce030e031234b2d054a60588f31d..cdb3ad08e391ae74af44fd2aabf7a75e4e0f3635 100644
--- a/static/lib/jinya-http.js
+++ b/static/lib/jinya-http.js
@@ -67,7 +67,7 @@ export async function send(
 
   const response = await fetch(url, request);
   if (response.ok) {
-    if (response.status !== 204) {
+    if (response.status !== 204 && response.headers.get('content-length') > 0) {
       if (plain) {
         return await response.text();
       }