diff --git a/frontend/css/style.css b/frontend/css/style.css
new file mode 100644
index 0000000..af95928
--- /dev/null
+++ b/frontend/css/style.css
@@ -0,0 +1,92 @@
+/* Basic styles - to be expanded */
+body {
+ font-family: sans-serif;
+ line-height: 1.6;
+ margin: 0;
+ padding: 0;
+ background-color: #f4f4f4;
+ color: #333;
+}
+
+header {
+ background: #333;
+ color: #fff;
+ padding: 1rem 0;
+ text-align: center;
+}
+
+main {
+ padding: 20px;
+ max-width: 960px;
+ margin: auto;
+}
+
+section {
+ background: #fff;
+ padding: 20px;
+ margin-bottom: 20px;
+ border-radius: 5px;
+}
+
+hr {
+ margin: 20px 0;
+ border: 0;
+ border-top: 1px solid #eee;
+}
+
+button {
+ padding: 10px 15px;
+ background: #333;
+ color: #fff;
+ border: none;
+ border-radius: 5px;
+ cursor: pointer;
+ margin-right: 5px; /* Add some margin between buttons */
+}
+
+button:hover {
+ background: #555;
+}
+
+input[type='text'], input[type='file'] {
+ padding: 8px;
+ margin-bottom: 10px;
+ border: 1px solid #ddd;
+ border-radius: 4px;
+ width: calc(100% - 20px); /* Adjust width considering padding */
+}
+
+label {
+ display: block;
+ margin-bottom: 5px;
+}
+
+#speaker-list {
+ list-style: none;
+ padding: 0;
+}
+
+#speaker-list li {
+ padding: 5px 0;
+ border-bottom: 1px dotted #eee;
+}
+
+#speaker-list li:last-child {
+ border-bottom: none;
+}
+
+pre {
+ background: #eee;
+ padding: 10px;
+ border-radius: 4px;
+ white-space: pre-wrap; /* Allow wrapping */
+ word-wrap: break-word; /* Break long words */
+}
+
+footer {
+ text-align: center;
+ padding: 20px;
+ background: #333;
+ color: #fff;
+ margin-top: 30px;
+}
diff --git a/frontend/index.html b/frontend/index.html
new file mode 100644
index 0000000..4b8472c
--- /dev/null
+++ b/frontend/index.html
@@ -0,0 +1,87 @@
+
+
+
+
+
+ Chatterbox TTS Frontend
+
+
+
+
+
+
+
+ Speaker Management
+
+
+
+
+
+
+
+ Dialog Editor
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Results
+
+
Log:
+
(Generation log will appear here)
+
+
+
Concatenated Audio:
+
+
+
+
Download Archive:
+
Download ZIP
+
(ZIP download link will appear here)
+
+
+
+
+
+
+
+
+
+
diff --git a/frontend/js/api.js b/frontend/js/api.js
new file mode 100644
index 0000000..9c33263
--- /dev/null
+++ b/frontend/js/api.js
@@ -0,0 +1,131 @@
+// frontend/js/api.js
+
+const API_BASE_URL = 'http://localhost:8000/api'; // Assuming backend runs on port 8000
+
+/**
+ * Fetches the list of available speakers.
+ * @returns {Promise>} A promise that resolves to an array of speaker objects.
+ * @throws {Error} If the network response is not ok.
+ */
+export async function getSpeakers() {
+ const response = await fetch(`${API_BASE_URL}/speakers/`);
+ if (!response.ok) {
+ const errorData = await response.json().catch(() => ({ message: response.statusText }));
+ throw new Error(`Failed to fetch speakers: ${errorData.detail || errorData.message || response.statusText}`);
+ }
+ return response.json();
+}
+
+// We will add more functions here: addSpeaker, deleteSpeaker, generateDialog
+
+// ... (keep API_BASE_URL and getSpeakers)
+
+/**
+ * Adds a new speaker.
+ * @param {FormData} formData - The form data containing speaker name and audio file.
+ * Example: formData.append('name', 'New Speaker');
+ * formData.append('audio_sample_file', fileInput.files[0]);
+ * @returns {Promise