diff --git a/frontend/src/lib/components/sessions/chatbox.svelte b/frontend/src/lib/components/sessions/chatbox.svelte
index febc06faf64846ca620faf554fcefdc4ae3aa32c..e706862e8b7b44482ce35b0b705e769da070bbad 100644
--- a/frontend/src/lib/components/sessions/chatbox.svelte
+++ b/frontend/src/lib/components/sessions/chatbox.svelte
@@ -24,7 +24,7 @@
 	});
 </script>
 
-<div class="flex flex-col md:my-8 min-w-fit w-full max-w-4xl border-2">
+<div class="flex flex-col md:my-8 min-w-fit w-full max-w-4xl border-2 rounded-b-lg">
 	<div class="flex-grow h-48 overflow-auto flex-col-reverse px-4 flex mb-2">
 		{#each messages.sort((a, b) => b.created_at.getTime() - a.created_at.getTime()) as message (message.id)}
 			<MessageC {message} />
@@ -37,7 +37,7 @@
 			Real-time sync lost. You may need to refresh the page to see new messages.
 		</div>
 	{/if}
-	<div class="flex flex-row h-20">
+	<div class="flex flex-row h-30">
 		<Writebox {session} />
 	</div>
 </div>
diff --git a/frontend/src/lib/components/sessions/writebox.svelte b/frontend/src/lib/components/sessions/writebox.svelte
index 6fde0cea827d9a74e064a4d6b7bcf512fab2e7a6..c5e00a054ef3871eed179c52afc9a3243ee1bd64 100644
--- a/frontend/src/lib/components/sessions/writebox.svelte
+++ b/frontend/src/lib/components/sessions/writebox.svelte
@@ -1,4 +1,5 @@
 <script lang="ts">
+	import config from '$lib/config';
 	import { _ } from '$lib/services/i18n';
 	import JWTSession from '$lib/stores/JWTSession';
 	import type Session from '$lib/types/session';
@@ -38,19 +39,33 @@
 	}
 </script>
 
-<textarea
-	class="flex-grow border-2 border-gray-300 rounded-md p-2 resize-none overflow-y-hidden"
-	placeholder={$_('chatbox.placeholder')}
-	bind:value={message}
-	on:keypress={(e) => keyPress(e)}
-	on:keypress={async (e) => {
-		if (e.key === 'Enter' && !e.shiftKey) {
-			await sendMessage();
-		} else {
-			keyPress(e);
-		}
-	}}
-/>
-<button class="w-12 button rounded-md" on:click={sendMessage}>
-	<Icon src={PaperAirplane} />
-</button>
+<div class="w-full">
+	<ul class="h-10 flex justify-around border-y-2 divide-x-2">
+		{#each config.SPECIAL_CHARS as char (char)}
+			<button
+				class="flex-grow hover:bg-gray-100"
+				on:click={() => {
+					message += char;
+				}}>{char}</button
+			>
+		{/each}
+	</ul>
+	<div class="w-full flex">
+		<textarea
+			class="flex-grow rounded-md p-2 resize-none overflow-y-hidden"
+			placeholder={$_('chatbox.placeholder')}
+			bind:value={message}
+			on:keypress={(e) => keyPress(e)}
+			on:keypress={async (e) => {
+				if (e.key === 'Enter' && !e.shiftKey) {
+					await sendMessage();
+				} else {
+					keyPress(e);
+				}
+			}}
+		/>
+		<button class="valid w-12 button rounded-md" on:click={sendMessage}>
+			<Icon src={PaperAirplane} />
+		</button>
+	</div>
+</div>
diff --git a/frontend/src/lib/config.ts b/frontend/src/lib/config.ts
index 7c296534b61ccf34b5d24b038d12031a179386b9..d9ea72ae3a98c2d3ce4511f0334b6180e3aaaba7 100644
--- a/frontend/src/lib/config.ts
+++ b/frontend/src/lib/config.ts
@@ -1,5 +1,24 @@
 export default {
 	API_URL: 'http://localhost:8000/api/v1',
 	WS_URL: 'ws://localhost:8000/api/v1/ws',
-	LEARNING_LANGUAGES: ['fr', 'en']
+	LEARNING_LANGUAGES: ['fr', 'en'],
+	SPECIAL_CHARS: [
+		'é',
+		'É',
+		'è',
+		'È',
+		'ê',
+		'Ê',
+		'ç',
+		'Ç',
+		'à',
+		'À',
+		'ù',
+		'Ù',
+		'ï',
+		'Ï',
+		'î',
+		'ÃŽ',
+		'€'
+	]
 };
diff --git a/frontend/src/routes/tests/typing/+page.svelte b/frontend/src/routes/tests/typing/+page.svelte
index ddef9ca16c134dd9842ca68518a8e579657c30cb..53aad46e2115b561d8d516c304749dd2fa9f2b43 100644
--- a/frontend/src/routes/tests/typing/+page.svelte
+++ b/frontend/src/routes/tests/typing/+page.svelte
@@ -6,6 +6,7 @@
 	import { createTestTypingAPI } from '$lib/api/users';
 	import JWTSession from '$lib/stores/JWTSession';
 	import { toastAlert } from '$lib/utils/toasts';
+	import config from '$lib/config';
 
 	const initialDuration = 60;
 
@@ -17,9 +18,12 @@
 	let lastInput = '';
 	let input = '';
 	let sent = false;
+	let textArea: HTMLTextAreaElement;
 
 	onMount(async () => {
 		if (!requireLogin()) return;
+
+		textArea.focus();
 	});
 
 	function start() {
@@ -80,6 +84,19 @@
 			{duration}s
 		</div>
 	</div>
+	<ul class="h-10 flex justify-around border-t-2 border-x-2 divide-x-2 text-center">
+		{#each config.SPECIAL_CHARS as char (char)}
+			<button
+				class="flex-grow"
+				on:click={() => {
+					input += char;
+				}}
+				on:mousedown={(e) => e.preventDefault()}
+			>
+				{char}
+			</button>
+		{/each}
+	</ul>
 	<div class="relative border-2 rounded text-xl select-none">
 		<div class="font-mono p-4">
 			<span class="text-inherit p-0 m-0 whitespace-pre-wrap"
@@ -99,6 +116,7 @@
 		</div>
 		<textarea
 			bind:value={input}
+			bind:this={textArea}
 			spellcheck="false"
 			disabled={!inProgress && duration <= 0}
 			on:input={(e) => {