diff --git a/src/rust/Cargo.lock b/src/rust/Cargo.lock
index 4bb13606b30ad8af394080599f4d9994d52a029d..4ac8b0ed93150fb25aaf04c8b98700414147e201 100644
--- a/src/rust/Cargo.lock
+++ b/src/rust/Cargo.lock
@@ -4,9 +4,9 @@ version = 3
 
 [[package]]
 name = "ab_glyph"
-version = "0.2.19"
+version = "0.2.20"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e5568a4aa5ba8adf5175c5c460b030e27d8893412976cc37bef0e4fbc16cfbba"
+checksum = "fe21446ad43aa56417a767f3e2f3d7c4ca522904de1dd640529a76e9c5c3b33c"
 dependencies = [
  "ab_glyph_rasterizer",
  "owned_ttf_parser",
@@ -1250,9 +1250,9 @@ checksum = "c4a1e36c821dbe04574f602848a19f742f4fb3c98d40449f11bcad18d6b17421"
 
 [[package]]
 name = "hyper"
-version = "0.14.23"
+version = "0.14.24"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "034711faac9d2166cb1baf1a2fb0b60b1f277f8492fd72176c17f3515e1abd3c"
+checksum = "5e011372fa0b68db8350aa7a248930ecc7839bf46d8485577d69f117a75f164c"
 dependencies = [
  "bytes",
  "futures-channel",
@@ -1482,12 +1482,12 @@ dependencies = [
 
 [[package]]
 name = "io-lifetimes"
-version = "1.0.4"
+version = "1.0.5"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e7d6c6f8c91b4b9ed43484ad1a938e393caf35960fce7f82a040497207bd8e9e"
+checksum = "1abeb7a0dd0f8181267ff8adc397075586500b81b28a73e8a0208b00fc170fb3"
 dependencies = [
  "libc",
- "windows-sys 0.42.0",
+ "windows-sys 0.45.0",
 ]
 
 [[package]]
@@ -2143,7 +2143,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "3742b2c103b9f06bc9fff0a37ff4912935851bee6d36f3c02bcc755bcfec228f"
 dependencies = [
  "lock_api",
- "parking_lot_core 0.9.6",
+ "parking_lot_core 0.9.7",
 ]
 
 [[package]]
@@ -2162,15 +2162,15 @@ dependencies = [
 
 [[package]]
 name = "parking_lot_core"
-version = "0.9.6"
+version = "0.9.7"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ba1ef8814b5c993410bb3adfad7a5ed269563e4a2f90c41f5d85be7fb47133bf"
+checksum = "9069cbb9f99e3a5083476ccb29ceb1de18b9118cafa53e90c9551235de2b9521"
 dependencies = [
  "cfg-if",
  "libc",
  "redox_syscall",
  "smallvec",
- "windows-sys 0.42.0",
+ "windows-sys 0.45.0",
 ]
 
 [[package]]
@@ -2508,16 +2508,16 @@ dependencies = [
 
 [[package]]
 name = "rustix"
-version = "0.36.7"
+version = "0.36.8"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d4fdebc4b395b7fbb9ab11e462e20ed9051e7b16e42d24042c776eca0ac81b03"
+checksum = "f43abb88211988493c1abb44a70efa56ff0ce98f233b7b276146f1f3f7ba9644"
 dependencies = [
  "bitflags",
  "errno",
  "io-lifetimes",
  "libc",
  "linux-raw-sys",
- "windows-sys 0.42.0",
+ "windows-sys 0.45.0",
 ]
 
 [[package]]
@@ -2955,9 +2955,9 @@ dependencies = [
 
 [[package]]
 name = "tinyvec_macros"
-version = "0.1.0"
+version = "0.1.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "cda74da7e1a664f795bb1f8a87ec406fb89a02522cf6e50620d016add6dbbf5c"
+checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20"
 
 [[package]]
 name = "tokio"
@@ -3590,6 +3590,30 @@ dependencies = [
  "windows_x86_64_msvc 0.42.1",
 ]
 
+[[package]]
+name = "windows-sys"
+version = "0.45.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "75283be5efb2831d37ea142365f009c02ec203cd29a3ebecbc093d52315b66d0"
+dependencies = [
+ "windows-targets",
+]
+
+[[package]]
+name = "windows-targets"
+version = "0.42.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8e2522491fbfcd58cc84d47aeb2958948c4b8982e9a2d8a2a35bbaed431390e7"
+dependencies = [
+ "windows_aarch64_gnullvm",
+ "windows_aarch64_msvc 0.42.1",
+ "windows_i686_gnu 0.42.1",
+ "windows_i686_msvc 0.42.1",
+ "windows_x86_64_gnu 0.42.1",
+ "windows_x86_64_gnullvm",
+ "windows_x86_64_msvc 0.42.1",
+]
+
 [[package]]
 name = "windows_aarch64_gnullvm"
 version = "0.42.1"
diff --git a/src/rust/amadeus/src/amadeus/client.rs b/src/rust/amadeus/src/amadeus/client.rs
index 11863ff9945bd35e9d59f51156d37652b310d143..17ba5880e18adde31a3ad9402a6615a7e2570b4d 100644
--- a/src/rust/amadeus/src/amadeus/client.rs
+++ b/src/rust/amadeus/src/amadeus/client.rs
@@ -1,4 +1,8 @@
-use crate::{address::Address, amadeus::action, AmadeusConfig};
+use crate::{
+    address::Address,
+    amadeus::{action, constants::*},
+    AmadeusConfig,
+};
 use commons::{log, Report};
 use iced::{
     futures::lock::Mutex,
@@ -154,15 +158,14 @@ impl Client {
     }
 
     pub fn view(&self) -> Element<Message> {
-        const SIZE: u16 = 20;
         match self.state {
-            State::Offline => button(text("offline").size(SIZE))
+            State::Offline => button(text("offline").size(TEXT_SIZE))
                 .on_press(Message::Connect)
                 .padding(0)
                 .into(),
-            State::Online(_) => text("online").size(SIZE).into(),
+            State::Online(_) => text("online").size(TEXT_SIZE).into(),
             State::AskConnection(ref addr) => {
-                text(format!("connecting to {addr}")).size(SIZE).into()
+                text(format!("connecting to {addr}")).size(TEXT_SIZE).into()
             }
         }
     }
diff --git a/src/rust/amadeus/src/amadeus/constants.rs b/src/rust/amadeus/src/amadeus/constants.rs
new file mode 100644
index 0000000000000000000000000000000000000000..d9931d36bf72b6a97f03d709444fdd670d39f40b
--- /dev/null
+++ b/src/rust/amadeus/src/amadeus/constants.rs
@@ -0,0 +1,2 @@
+pub(super) const TEXT_SIZE: u16 = 20;
+pub(super) const TITLE_SIZE: u16 = 30;
diff --git a/src/rust/amadeus/src/amadeus/mod.rs b/src/rust/amadeus/src/amadeus/mod.rs
index 1dfd093a2741d4213f80ef8c65d5917a1f7ae217..a9b3ed4b94d740f9c176ce2ffb0c54ab154ec9b7 100644
--- a/src/rust/amadeus/src/amadeus/mod.rs
+++ b/src/rust/amadeus/src/amadeus/mod.rs
@@ -1,20 +1,26 @@
 mod action;
 mod client;
+mod constants;
 mod queue_control;
+mod side_panel;
+mod window_content;
 
 use crate::AmadeusConfig;
 use iced::{
     executor, subscription,
-    widget::{column, row},
-    Alignment, Application, Command, Element, Event, Subscription, Theme,
+    widget::{column, horizontal_rule, horizontal_space, row, vertical_rule},
+    Application, Command, Element, Event, Length, Subscription, Theme,
 };
 
 /// The Amadeus application state.
 #[derive(Debug)]
 pub struct Amadeus {
+    flags: AmadeusConfig,
+
     client: client::Client,
     queue_control: queue_control::QueueControl,
-    flags: AmadeusConfig,
+    side_panel: side_panel::SidePanel,
+    window_content: window_content::WindowContent,
 }
 
 #[derive(Debug, Clone)]
@@ -41,6 +47,13 @@ pub enum Message {
     /// The queue controler sent a message / the message must be dispatched to
     /// the queue controller (update its status).
     QueueControl(queue_control::Message),
+
+    /// Got a message from / for the side panel.
+    SidePanel(side_panel::Message),
+
+    /// Got a message for the different tabs inside the window / the main
+    /// content returned a message.
+    WindowContent(window_content::Message),
 }
 
 impl Application for Amadeus {
@@ -54,9 +67,11 @@ impl Application for Amadeus {
     fn new(flags: Self::Flags) -> (Self, Command<Self::Message>) {
         (
             Self {
+                flags,
                 client: client::Client::new(),
                 queue_control: queue_control::QueueControl::new(),
-                flags,
+                side_panel: side_panel::SidePanel::new(),
+                window_content: window_content::WindowContent::new(),
             },
             Command::none(),
         )
@@ -117,6 +132,15 @@ impl Application for Amadeus {
                     })
             }
 
+            // Dispatch to side panel.
+            Message::SidePanel(message) => self.side_panel.update(message).map(Message::SidePanel),
+
+            // Dispatch to main window content.
+            Message::WindowContent(message) => self
+                .window_content
+                .update(message)
+                .map(Message::WindowContent),
+
             // On notifications we update only the queue controler for now, in
             // the future we may update something else.
             Message::Notification(message) => self.update(Message::QueueControl(
@@ -134,12 +158,20 @@ impl Application for Amadeus {
 
     /// Display the whole application.
     fn view(&self) -> Element<Self::Message> {
-        column![row![
-            self.queue_control.view().map(Message::QueueControl),
-            self.client.view().map(Message::Client)
-        ]]
-        .padding(20)
-        .align_items(Alignment::Center)
+        column![
+            // The header of the window
+            row![
+                self.queue_control.view().map(Message::QueueControl),
+                horizontal_space(Length::Fill),
+                self.client.view().map(Message::Client),
+            ],
+            horizontal_rule(2),
+            row![
+                column![self.side_panel.view().map(Message::SidePanel)].padding(10),
+                vertical_rule(2),
+                column![self.window_content.view().map(Message::WindowContent)].padding(10),
+            ]
+        ]
         .into()
     }
 
diff --git a/src/rust/amadeus/src/amadeus/queue_control.rs b/src/rust/amadeus/src/amadeus/queue_control.rs
index 252953f52a6f9bcdcc7cad715c5ef92e988bacdd..82fb9faa661e44d33500692cee42b3a1b06362fe 100644
--- a/src/rust/amadeus/src/amadeus/queue_control.rs
+++ b/src/rust/amadeus/src/amadeus/queue_control.rs
@@ -1,4 +1,4 @@
-use crate::amadeus::action;
+use crate::amadeus::{action, constants::*};
 use iced::{widget::text, Command, Element};
 
 #[derive(Debug, Clone, Copy)]
@@ -79,13 +79,12 @@ impl QueueControl {
     /// View the queue controller. Depending on its state, we may want to send
     /// commands to lektord.
     pub fn view(&self) -> Element<Message> {
-        const SIZE: u16 = 20;
         use amalib::LektorState::*;
         match self.state.0 {
-            Some(Pause(pos)) => text(format!("pause({pos})")).size(SIZE).into(),
-            Some(Play(pos)) => text(format!("play({pos})")).size(SIZE).into(),
-            Some(Stopped) => text("stopped").size(SIZE).into(),
-            None => text("unk").size(SIZE).into(),
+            Some(Pause(pos)) => text(format!("pause({pos})")).size(TEXT_SIZE).into(),
+            Some(Play(pos)) => text(format!("play({pos})")).size(TEXT_SIZE).into(),
+            Some(Stopped) => text("stopped").size(TEXT_SIZE).into(),
+            None => text("unk").size(TEXT_SIZE).into(),
         }
     }
 }
diff --git a/src/rust/amadeus/src/amadeus/side_panel.rs b/src/rust/amadeus/src/amadeus/side_panel.rs
new file mode 100644
index 0000000000000000000000000000000000000000..4b58190a530076c427c05d9d4b4d97bb8dd93a1f
--- /dev/null
+++ b/src/rust/amadeus/src/amadeus/side_panel.rs
@@ -0,0 +1,25 @@
+use super::constants::*;
+use iced::{widget::text, Command, Element};
+
+#[derive(Debug, Clone, Copy)]
+pub enum Message {}
+
+#[derive(Debug, Clone)]
+struct State {}
+
+#[derive(Debug, Clone)]
+pub struct SidePanel {}
+
+impl SidePanel {
+    pub fn new() -> Self {
+        Self {}
+    }
+
+    pub fn update(&mut self, message: Message) -> Command<Message> {
+        Command::none()
+    }
+
+    pub fn view(&self) -> Element<Message> {
+        text("side panel").size(TITLE_SIZE).into()
+    }
+}
diff --git a/src/rust/amadeus/src/amadeus/window_content.rs b/src/rust/amadeus/src/amadeus/window_content.rs
new file mode 100644
index 0000000000000000000000000000000000000000..c8c29dee6e9edb48915d56a218255ca170ab536c
--- /dev/null
+++ b/src/rust/amadeus/src/amadeus/window_content.rs
@@ -0,0 +1,25 @@
+use super::constants::*;
+use iced::{widget::text, Command, Element};
+
+#[derive(Debug, Clone, Copy)]
+pub enum Message {}
+
+#[derive(Debug, Clone)]
+struct State {}
+
+#[derive(Debug, Clone)]
+pub struct WindowContent {}
+
+impl WindowContent {
+    pub fn new() -> Self {
+        Self {}
+    }
+
+    pub fn update(&mut self, message: Message) -> Command<Message> {
+        Command::none()
+    }
+
+    pub fn view(&self) -> Element<Message> {
+        text("window content...").size(TEXT_SIZE).into()
+    }
+}