diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000000000000000000000000000000000000..1e107f52e4702b33a7bed7c76d591f4b14fe36ff
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1 @@
+examples
diff --git a/src/main.qml b/src/main.qml
new file mode 100644
index 0000000000000000000000000000000000000000..5752fcce6eda2db6f05365ed7bf13d74b9dedeaf
--- /dev/null
+++ b/src/main.qml
@@ -0,0 +1,151 @@
+/// PersefoneDesktop - a GUI to the Persefone model of agriculture and ecosystems
+///
+/// This file defines the layout of the main window.
+///
+
+import QtQuick
+import QtQuick.Controls
+import QtQuick.Dialogs
+import QtQuick.Layouts
+import org.julialang
+
+ApplicationWindow {
+	id: mainWindow
+	title: "Persefone.jl Desktop"
+	width: 1024
+	height: 768
+	visible: true
+	
+	menuBar: MenuBar {
+		Menu {
+			title: "&Simulation"
+			Action { text: "&New Simulation" }
+			Action { text: "&Load Saved State" }
+			Action { text: "&Save Current State" }
+			MenuSeparator { }
+			Action {
+				text: "&Quit"
+				onTriggered: { mainWindow.close() }
+			}
+		}
+		Menu {
+			title: "&Help"
+			Action {
+				text: "&Documentation"
+				onTriggered: { Qt.openUrlExternally("https://persefone-model.eu/documentation") }
+			}
+			Action {
+				text: "&Website"
+				onTriggered: { Qt.openUrlExternally("https://persefone-model.eu/") }
+			}
+			Action {
+				text: "&About"
+				onTriggered: { aboutDialog.open() }
+			}
+		}
+	}
+	
+	MessageDialog {
+		id: aboutDialog
+		text: "Persefone.jl Desktop"
+		informativeText: "A mechanistic model of agricultural landscapes \
+and ecosystems in Europe.\n\n\
+© 2023 Daniel Vedder, Lea Kolb, Guy Pe'er\n\
+Distributed under the MIT license."
+	}
+
+	RowLayout {
+		anchors.fill: parent
+		
+		/* MakieViewport { */
+		/* 	id: viewport */
+		/* 	Layout.fillWidth: true */
+		/* 	Layout.fillHeight: true */
+		/* 	//renderFunction: render_callback //TODO */
+		/* } */
+
+		// the calendar is no longer a single widget, but needs to be
+		// constructed manually :-(
+		ColumnLayout {
+			id: calenderWidget
+			Layout.alignment: Qt.AlignHCenter
+			Text {
+				text: "<b>"+Qt.formatDate(new Date(), "MMM yyyy")+"</b>" //FIXME
+			}
+			DayOfWeekRow {
+				locale: grid.locale
+				Layout.column: 1
+				Layout.fillWidth: true
+			}
+			MonthGrid {
+				id: grid
+				//month: Calendar.December //FIXME
+				//year: 2015 //FIXME
+				locale: Qt.locale("en_GB")
+				Layout.fillWidth: true
+				Layout.fillHeight: true
+				delegate: Text {
+					horizontalAlignment: Text.AlignHCenter
+					verticalAlignment: Text.AlignVCenter
+					opacity: model.month === grid.month ? 1 : 0
+					text: model.today ? "<b>"+model.day+"</b>" : model.day
+					font: grid.font
+					required property var model
+				}
+			}
+		}
+	}
+
+	// the main control bar, with pause/step/run buttons, the progress
+	// bar and a speed slider
+	footer: ToolBar {
+		RowLayout {
+			id: controlBar
+			anchors.fill: parent
+			Layout.alignment: Qt.AlignVCenter
+			Layout.fillWidth: true
+			// anchors.topMargin: 5 //FIXME
+			// anchors.bottomMargin: 5
+			Button {
+				id: pauseButton
+				text: "||"
+				ToolTip.text: "Pause"
+				ToolTip.visible: hovered
+				//onClicked: //TODO
+			}
+			Button {
+				id: stepButton
+				text: ">"
+				ToolTip.text: "Step"
+				ToolTip.visible: hovered
+				//onClicked: //TODO
+			}
+			Button {
+				id: runButton
+				text: ">>"
+				ToolTip.text: "Run"
+				ToolTip.visible: hovered
+				//onClicked: //TODO
+			}
+			ProgressBar {
+				id: progressBar
+				from: 0
+				to: 100
+				value: 24
+				Layout.fillWidth: true
+				ToolTip.text: "Simulation progress"
+				ToolTip.visible: hovered
+			}
+			Slider {
+				id: speedSlider
+				from: 0.0
+				to: 2.0
+				value: 0.5
+				stepSize: 0.1
+				snapMode: Slider.SnapAlways
+				ToolTip.text: "Time delay between updates"
+				ToolTip.visible: hovered
+			}
+		}
+	}
+}
diff --git a/src/MainWindow.ui b/src/mockup.ui
similarity index 87%
rename from src/MainWindow.ui
rename to src/mockup.ui
index a2c6b267ceccc32c4d7a8dba20a7826bb4985428..19c710a6771b047d65cba91a8ed56f49252e3404 100644
--- a/src/MainWindow.ui
+++ b/src/mockup.ui
@@ -129,7 +129,11 @@
     <property name="title">
      <string>&amp;Menu</string>
     </property>
+    <addaction name="separator"/>
     <addaction name="action_New_run"/>
+    <addaction name="actionLoad_saved_state"/>
+    <addaction name="actionSave_current_state"/>
+    <addaction name="separator"/>
     <addaction name="action_Quit"/>
    </widget>
    <widget class="QMenu" name="menu_Help">
@@ -137,6 +141,7 @@
      <string>&amp;Help</string>
     </property>
     <addaction name="actionHelp"/>
+    <addaction name="actionWebsite"/>
     <addaction name="actionAbout"/>
    </widget>
    <addaction name="menu_Menu"/>
@@ -145,7 +150,7 @@
   <widget class="QStatusBar" name="statusbar"/>
   <action name="actionHelp">
    <property name="text">
-    <string>Help</string>
+    <string>Documentation</string>
    </property>
   </action>
   <action name="actionAbout">
@@ -163,6 +168,21 @@
     <string>&amp;Quit</string>
    </property>
   </action>
+  <action name="actionSave_current_state">
+   <property name="text">
+    <string>&amp;Save current state</string>
+   </property>
+  </action>
+  <action name="actionLoad_saved_state">
+   <property name="text">
+    <string>&amp;Load saved state</string>
+   </property>
+  </action>
+  <action name="actionWebsite">
+   <property name="text">
+    <string>Website</string>
+   </property>
+  </action>
  </widget>
  <resources/>
  <connections/>