From cd1d46a26b923260b6c87cc93a0723b8166c609e Mon Sep 17 00:00:00 2001
From: "kali kaneko (leap communications)" <kali@leap.se>
Date: Fri, 27 Aug 2021 19:45:41 +0200
Subject: [PATCH] [ui] refactor ui

---
 bitmask.pro                       |   9 +
 docs/hacking-qml.rst              |   6 +
 gui/backend.go                    |   2 +-
 gui/components/BoldLabel.qml      |  21 ++
 gui/components/Footer.qml         |  63 ++++++
 gui/components/Header.qml         |  32 +++
 gui/components/Help.qml           |  32 +++
 gui/components/Home.qml           |   8 +
 gui/components/Icon.qml           |   9 +
 gui/components/LightLabel.qml     |  19 ++
 gui/components/Locations.qml      |  63 ++++++
 gui/components/MainView.qml       | 131 ++++++++++++
 gui/components/MaterialButton.qml |  84 ++++++++
 gui/components/Preferences.qml    |  23 ++
 gui/components/Spinner.qml        |  63 ++++++
 gui/components/Splash.qml         |  64 ++++++
 gui/components/StatusBox.qml      | 125 +++++++++++
 gui/components/Style.qml          |  12 ++
 gui/components/Systray.qml        |  27 +++
 gui/components/VPNButtonBase.qml  |  56 +++++
 gui/components/VPNMouseArea.qml   |  37 ++++
 gui/components/VPNState.qml       | 193 +++++++++++++++++
 gui/components/VPNToggle.qml      | 338 ++++++++++++++++++++++++++++++
 gui/components/VerticalSpacer.qml |   6 +
 gui/gui.qrc                       |  46 +++-
 gui/main.cpp                      |  21 +-
 gui/main.qml                      | 116 ++++++++++
 gui/providers/providers.json      |   2 +-
 gui/qml/BackgroundImage.qml       |  16 +-
 gui/qml/BridgesItem.qml           |  16 +-
 gui/qml/VPNSwitch.qml             |   1 -
 gui/qml/VpnState.qml              |  13 +-
 gui/qml/main.qml                  |  65 +++---
 gui/qml/readme.txt                |   1 +
 gui/resources/about.svg           |  62 ++++++
 gui/resources/arrow-left.svg      |   3 +
 gui/resources/birds.svg           |   1 +
 gui/resources/bridge.png          | Bin 0 -> 5543 bytes
 gui/resources/close.svg           |   3 +
 gui/resources/donate.svg          |   4 +
 gui/resources/gear-fill.svg       |   3 +
 gui/resources/globe.svg           |   3 +
 gui/resources/help.svg            |   4 +
 gui/resources/icon-noshield.svg   |  68 ++++++
 gui/resources/location.svg        |  58 +++++
 gui/resources/power.svg           |  10 +
 gui/resources/quit.svg            |   4 +
 gui/resources/reception-0.svg     |   3 +
 gui/resources/reception-2.svg     |   3 +
 gui/resources/reception-4.svg     |   3 +
 gui/resources/riseup-icon.svg     |  80 +++++++
 gui/resources/riseup-logo.png     | Bin 0 -> 4943 bytes
 gui/resources/settings.svg        |  62 ++++++
 gui/resources/speed-green.svg     |  72 +++++++
 gui/resources/speed-red.svg       |  72 +++++++
 gui/resources/speed-yellow.svg    |  72 +++++++
 gui/resources/spy.gif             | Bin 0 -> 2662 bytes
 gui/resources/tools.svg           |   4 +
 gui/themes/themes.js              |  51 +++++
 pkg/backend/init.go               |   4 +-
 pkg/backend/status.go             |   1 +
 61 files changed, 2301 insertions(+), 69 deletions(-)
 create mode 100644 docs/hacking-qml.rst
 create mode 100644 gui/components/BoldLabel.qml
 create mode 100644 gui/components/Footer.qml
 create mode 100644 gui/components/Header.qml
 create mode 100644 gui/components/Help.qml
 create mode 100644 gui/components/Home.qml
 create mode 100644 gui/components/Icon.qml
 create mode 100644 gui/components/LightLabel.qml
 create mode 100644 gui/components/Locations.qml
 create mode 100644 gui/components/MainView.qml
 create mode 100644 gui/components/MaterialButton.qml
 create mode 100644 gui/components/Preferences.qml
 create mode 100644 gui/components/Spinner.qml
 create mode 100644 gui/components/Splash.qml
 create mode 100644 gui/components/StatusBox.qml
 create mode 100644 gui/components/Style.qml
 create mode 100644 gui/components/Systray.qml
 create mode 100644 gui/components/VPNButtonBase.qml
 create mode 100644 gui/components/VPNMouseArea.qml
 create mode 100644 gui/components/VPNState.qml
 create mode 100644 gui/components/VPNToggle.qml
 create mode 100644 gui/components/VerticalSpacer.qml
 create mode 100644 gui/main.qml
 create mode 100644 gui/qml/readme.txt
 create mode 100644 gui/resources/about.svg
 create mode 100644 gui/resources/arrow-left.svg
 create mode 100644 gui/resources/birds.svg
 create mode 100644 gui/resources/bridge.png
 create mode 100644 gui/resources/close.svg
 create mode 100644 gui/resources/donate.svg
 create mode 100644 gui/resources/gear-fill.svg
 create mode 100644 gui/resources/globe.svg
 create mode 100644 gui/resources/help.svg
 create mode 100644 gui/resources/icon-noshield.svg
 create mode 100644 gui/resources/location.svg
 create mode 100644 gui/resources/power.svg
 create mode 100644 gui/resources/quit.svg
 create mode 100644 gui/resources/reception-0.svg
 create mode 100644 gui/resources/reception-2.svg
 create mode 100644 gui/resources/reception-4.svg
 create mode 100644 gui/resources/riseup-icon.svg
 create mode 100644 gui/resources/riseup-logo.png
 create mode 100644 gui/resources/settings.svg
 create mode 100644 gui/resources/speed-green.svg
 create mode 100644 gui/resources/speed-red.svg
 create mode 100644 gui/resources/speed-yellow.svg
 create mode 100644 gui/resources/spy.gif
 create mode 100644 gui/resources/tools.svg
 create mode 100644 gui/themes/themes.js

diff --git a/bitmask.pro b/bitmask.pro
index 627e2d3b..25139440 100644
--- a/bitmask.pro
+++ b/bitmask.pro
@@ -1,6 +1,9 @@
 #TARGET = $$BINARY_NAME
 
+QT += quickcontrols2
+CONFIG += c++11
 CONFIG += qt staticlib
+CONFIG += qtquickcompiler
 CONFIG+=force_debug_info
 CONFIG+=debug_and_release
 #CONFIG+=release
@@ -11,6 +14,12 @@ QMAKE_MACOSX_DEPLOYMENT_TARGET = 10.11
 QMAKE_TARGET_BUNDLE_PREFIX = se.leap
 QMAKE_BUNDLE = $$TARGET
 
+# The following define makes your compiler emit warnings if you use
+# any feature of Qt which as been marked deprecated (the exact warnings
+# depend on your compiler). Please consult the documentation of the
+# deprecated API in order to know how to port your code away from it.
+DEFINES += QT_DEPRECATED_WARNINGS
+
 !defined(VENDOR_PATH, var):VENDOR_PATH="providers/riseup"
 
 message("[qmake] VENDOR_PATH: $$VENDOR_PATH")
diff --git a/docs/hacking-qml.rst b/docs/hacking-qml.rst
new file mode 100644
index 00000000..7e793ba3
--- /dev/null
+++ b/docs/hacking-qml.rst
@@ -0,0 +1,6 @@
+QML best practices
+==================
+* https://github.com/Furkanzmc/QML-Coding-Guide/blob/master/README.md
+* lint your qml files::
+
+  make qmllint
diff --git a/gui/backend.go b/gui/backend.go
index 04d1293a..bc056b90 100644
--- a/gui/backend.go
+++ b/gui/backend.go
@@ -83,7 +83,7 @@ func InitializeBitmaskContext(provider string,
 	opts.Obfs4 = obfs4
 	opts.DisableAutostart = disableAutostart
 	opts.StartVPN = startVPN
-	backend.InitializeBitmaskContext(opts)
+	go backend.InitializeBitmaskContext(opts)
 }
 
 //export InitializeTestBitmaskContext
diff --git a/gui/components/BoldLabel.qml b/gui/components/BoldLabel.qml
new file mode 100644
index 00000000..6c6c3c34
--- /dev/null
+++ b/gui/components/BoldLabel.qml
@@ -0,0 +1,21 @@
+import QtQuick 2.5
+import QtQuick.Controls 2.14
+import "../themes/themes.js" as Theme
+import "../themes"
+
+Label {
+    FontLoader {
+        id: boldFont
+        source: "qrc:/oxanium-bold.ttf"
+    }
+
+    font.pixelSize: Theme.fontSize * 1.55555
+    //font.family: boldFont.name
+    font.bold: true
+    //color: Theme.fontColorDark
+    color: "black"
+    text: parent.text
+    //wrapMode: Text.WordWrap
+    Accessible.name: text
+    Accessible.role: Accessible.StaticText
+}
diff --git a/gui/components/Footer.qml b/gui/components/Footer.qml
new file mode 100644
index 00000000..2c7c875a
--- /dev/null
+++ b/gui/components/Footer.qml
@@ -0,0 +1,63 @@
+import QtQuick 2.0
+import QtQuick.Controls 2.4
+import QtQuick.Controls.Material 2.1
+import QtQuick.Layouts 1.14
+
+ToolBar {
+
+    Material.background: Material.backgroundColor
+    Material.foreground: "black"
+    Material.elevation: 0
+    visible: stackView.depth > 1 && ctx !== undefined ? false : true
+
+    Item {
+
+        id: footerRow
+        width: root.width
+
+        ToolButton {
+            id: gwButton
+            anchors.verticalCenter: parent.verticalCenter
+            anchors.leftMargin: 10
+            anchors.left: parent.left
+            anchors.verticalCenterOffset: 5
+            icon.source: stackView.depth > 1 ? "" : "../resources/globe.svg"
+            onClicked: stackView.push("Locations.qml")
+        }
+
+        Label {
+            id: locationLabel
+            anchors.left: gwButton.right
+            anchors.verticalCenter: parent.verticalCenter
+            anchors.verticalCenterOffset: 5
+            text: "Seattle"
+        }
+
+        Item {
+            Layout.fillWidth: true
+            height: gwButton.implicitHeight
+        }
+
+        Image {
+            id: bridge
+            height: 24
+            width: 24
+            source: "../resources/bridge.png"
+            anchors.verticalCenter: parent.verticalCenter
+            anchors.verticalCenterOffset: 5
+            anchors.right: gwQuality.left
+            anchors.rightMargin: 10
+        }
+
+        Image {
+            id: gwQuality
+            height: 24
+            width: 24
+            source: "../resources/reception-0.svg"
+            anchors.right: parent.right
+            anchors.rightMargin: 20
+            anchors.verticalCenter: parent.verticalCenter
+            anchors.verticalCenterOffset: 5
+        }
+    }
+}
diff --git a/gui/components/Header.qml b/gui/components/Header.qml
new file mode 100644
index 00000000..92f4bdde
--- /dev/null
+++ b/gui/components/Header.qml
@@ -0,0 +1,32 @@
+import QtQuick 2.0
+import QtQuick.Controls 2.4
+import QtQuick.Dialogs 1.2
+import QtQuick.Controls.Material 2.1
+
+ToolBar {
+    visible: stackView.depth > 1
+    Material.foreground: Material.Black
+    Material.background: "#ffffff"
+    Material.elevation: 0
+
+    contentHeight: settingsButton.implicitHeight
+
+    ToolButton {
+        id: settingsButton
+        anchors.left: parent.left
+        font.pixelSize: Qt.application.font.pixelSize * 1.6
+        icon.source: "../resources/arrow-left.svg"
+        onClicked: {
+            if (stackView.depth > 1) {
+                stackView.pop()
+            } else {
+                settingsDrawer.open()
+            }
+        }
+    }
+
+    Label {
+        text: stackView.currentItem.title
+        anchors.centerIn: parent
+    }
+}
diff --git a/gui/components/Help.qml b/gui/components/Help.qml
new file mode 100644
index 00000000..aced2731
--- /dev/null
+++ b/gui/components/Help.qml
@@ -0,0 +1,32 @@
+import QtQuick 2.9
+import QtQuick.Controls 2.2
+
+Page {
+    title: qsTr("Help")
+
+    Column {
+        anchors.centerIn: parent
+        spacing: 10
+
+        Button {
+            anchors.horizontalCenter: parent.horizontalCenter
+            text: qsTr("Donate")
+            onClicked: stackView.push("Donate.qml")
+        }
+        Button {
+            anchors.horizontalCenter: parent.horizontalCenter
+            text: qsTr("Terms of Service")
+            onClicked: stackView.push("Donate.qml")
+        }
+        Button {
+            anchors.horizontalCenter: parent.horizontalCenter
+            text: qsTr("Contact Support")
+            onClicked: stackView.push("Donate.qml")
+        }
+        Button {
+            anchors.horizontalCenter: parent.horizontalCenter
+            text: qsTr("Report bug")
+            onClicked: stackView.push("Donate.qml")
+        }
+    }
+}
diff --git a/gui/components/Home.qml b/gui/components/Home.qml
new file mode 100644
index 00000000..c9eab2a1
--- /dev/null
+++ b/gui/components/Home.qml
@@ -0,0 +1,8 @@
+import QtQuick 2.9
+import QtQuick.Controls 2.2
+import QtGraphicalEffects 1.0
+
+Page {
+
+    StatusBox {}
+}
diff --git a/gui/components/Icon.qml b/gui/components/Icon.qml
new file mode 100644
index 00000000..5dfd6ee8
--- /dev/null
+++ b/gui/components/Icon.qml
@@ -0,0 +1,9 @@
+import QtQuick 2.5
+import QtQuick.Layouts 1.14
+import "../themes/themes.js" as Theme
+
+Image {
+    sourceSize.height: 24
+    sourceSize.width: 24
+    fillMode: Image.PreserveAspectFit
+}
diff --git a/gui/components/LightLabel.qml b/gui/components/LightLabel.qml
new file mode 100644
index 00000000..78f82b65
--- /dev/null
+++ b/gui/components/LightLabel.qml
@@ -0,0 +1,19 @@
+import QtQuick 2.5
+import QtQuick.Controls 2.14
+import "../themes/themes.js" as Theme
+
+Text {
+    font.pixelSize: Theme.fontSize - 2
+    font.family: Theme.fontFamily
+    color: Theme.fontColor
+    width: parent.width * 0.80
+    text: parent.text
+
+    horizontalAlignment: Text.AlignHCenter
+    verticalAlignment: Text.AlignVCenter
+    //lineHeightMode: Text.FixedHeight
+    wrapMode: Text.Wrap
+
+    Accessible.role: Accessible.StaticText
+    Accessible.name: text
+}
diff --git a/gui/components/Locations.qml b/gui/components/Locations.qml
new file mode 100644
index 00000000..d3e0f5ad
--- /dev/null
+++ b/gui/components/Locations.qml
@@ -0,0 +1,63 @@
+import QtQuick 2.9
+import QtQuick.Controls 2.2
+
+import "../themes/themes.js" as Theme
+
+Page {
+    title: qsTr("Select Location")
+
+    ListView {
+        id: gwList
+        focus: true
+        currentIndex: -1
+        anchors.fill: parent
+        spacing: 1
+
+        delegate: ItemDelegate {
+            id: loc
+            Rectangle {
+                width: parent.width
+                height: 1
+                color: Theme.borderColor
+            }
+            width: parent.width
+            text: model.text
+            highlighted: ListView.isCurrentItem
+            icon.color: "transparent"
+            icon.source: model.icon
+            onClicked: {
+                model.triggered()
+                stackView.pop()
+            }
+            MouseArea {
+                property var onMouseAreaClicked: function () {
+                    parent.clicked()
+                }
+                id: mouseArea
+                anchors.fill: loc
+                cursorShape: Qt.PointingHandCursor
+                onReleased: {
+                    onMouseAreaClicked()
+                }
+            }
+        }
+
+        model: ListModel {
+            ListElement {
+                text: qsTr("Paris")
+                triggered: function () {}
+                icon: "../resources/reception-4.svg"
+            }
+            ListElement {
+                text: qsTr("Montreal")
+                triggered: function () {}
+                icon: "../resources/reception-4.svg"
+            }
+            ListElement {
+                text: qsTr("Seattle")
+                triggered: function () {}
+                icon: "../resources/reception-2.svg"
+            }
+        }
+    }
+}
diff --git a/gui/components/MainView.qml b/gui/components/MainView.qml
new file mode 100644
index 00000000..7ce723db
--- /dev/null
+++ b/gui/components/MainView.qml
@@ -0,0 +1,131 @@
+import QtQuick 2.0
+import QtQuick.Controls 2.4
+import QtQuick.Dialogs 1.2
+import QtQuick.Controls.Material 2.1
+import QtQuick.Layouts 1.14
+
+Page {
+
+    StackView {
+        id: stackView
+        anchors.fill: parent
+        initialItem: Home {}
+    }
+
+    Drawer {
+        id: settingsDrawer
+
+        width: Math.min(root.width, root.height) / 3 * 2
+        height: root.height
+
+        ListView {
+            focus: true
+            currentIndex: -1
+            anchors.fill: parent
+
+            delegate: ItemDelegate {
+                width: parent.width
+                text: model.text
+                highlighted: ListView.isCurrentItem
+                icon.color: "transparent"
+                icon.source: model.icon
+                onClicked: {
+                    settingsDrawer.close()
+                    model.triggered()
+                }
+            }
+
+            model: ListModel {
+                ListElement {
+                    text: qsTr("Preferences")
+                    icon: "../resources/tools.svg"
+                    triggered: function () {
+                        stackView.push("Preferences.qml")
+                    }
+                }
+                ListElement {
+                    text: qsTr("Donate")
+                    icon: "../resources/donate.svg"
+                    triggered: function () {
+                        aboutDialog.open()
+                    }
+                }
+                ListElement {
+                    text: qsTr("Help")
+                    icon: "../resources/help.svg"
+                    triggered: function () {
+                        stackView.push("Help.qml")
+                        settingsDrawer.close()
+                    }
+                } // -> can link to another dialog with report bug / support / contribute / FAQ
+                ListElement {
+                    text: qsTr("About")
+                    icon: "../resources/about.svg"
+                    triggered: function () {
+                        aboutDialog.open()
+                    }
+                }
+                ListElement {
+                    text: qsTr("Quit")
+                    icon: "../resources/quit.svg"
+                    triggered: function () {
+                        Qt.callLater(backend.quit)
+                    }
+                }
+            }
+
+            ScrollIndicator.vertical: ScrollIndicator {}
+        }
+    }
+
+    Drawer {
+        id: locationsDrawer
+
+        width: root.width
+        height: root.height
+
+        ListView {
+            focus: true
+            currentIndex: -1
+            anchors.fill: parent
+
+            delegate: ItemDelegate {
+                width: parent.width
+                text: model.text
+                highlighted: ListView.isCurrentItem
+                onClicked: {
+                    locationsDrawer.close()
+                    model.triggered()
+                }
+            }
+
+            model: ListModel {
+                ListElement {
+                    text: qsTr("Montreal, CA")
+                    triggered: function () {}
+                }
+                ListElement {
+                    text: qsTr("Paris, FR")
+                    triggered: function () {}
+                }
+            }
+
+            ScrollIndicator.vertical: ScrollIndicator {}
+        }
+    }
+
+    header: Header {}
+    footer: Footer {}
+
+    Dialog {
+        id: aboutDialog
+        title: qsTr("About")
+        Label {
+            anchors.fill: parent
+            text: qsTr("RiseupVPN\nhttps://riseupvpn.net/vpn")
+            horizontalAlignment: Text.AlignHCenter
+        }
+
+        standardButtons: StandardButton.Ok
+    }
+}
diff --git a/gui/components/MaterialButton.qml b/gui/components/MaterialButton.qml
new file mode 100644
index 00000000..25911f33
--- /dev/null
+++ b/gui/components/MaterialButton.qml
@@ -0,0 +1,84 @@
+import QtQuick 2.12
+import QtQuick.Templates 2.12 as T
+import QtQuick.Controls 2.12
+import QtQuick.Controls.impl 2.12
+import QtQuick.Controls.Material 2.12
+import QtQuick.Controls.Material.impl 2.12
+
+T.Button {
+    id: control
+
+    implicitWidth: Math.max(implicitBackgroundWidth + leftInset + rightInset,
+                            implicitContentWidth + leftPadding + rightPadding)
+    implicitHeight: Math.max(implicitBackgroundHeight + topInset + bottomInset,
+                             implicitContentHeight + topPadding + bottomPadding)
+
+    topInset: 6
+    bottomInset: 6
+    padding: 12
+    horizontalPadding: padding - 4
+    spacing: 6
+
+    icon.width: 24
+    icon.height: 24
+    icon.color: !enabled ? Material.hintTextColor : flat
+                           && highlighted ? Material.accentColor : highlighted ? Material.primaryHighlightedTextColor : Material.foreground
+
+    Material.elevation: flat ? control.down
+                               || control.hovered ? 2 : 0 : control.down ? 8 : 2
+    Material.background: flat ? "transparent" : undefined
+
+    contentItem: IconLabel {
+        spacing: control.spacing
+        mirrored: control.mirrored
+        display: control.display
+
+        icon: control.icon
+        text: control.text
+        font: control.font
+
+        color: !control.enabled ? control.Material.hintTextColor : control.flat
+                                  && control.highlighted ? control.Material.accentColor : control.highlighted ? control.Material.primaryHighlightedTextColor : control.Material.foreground
+    }
+
+    background: Rectangle {
+        implicitWidth: 64
+        implicitHeight: control.Material.buttonHeight
+
+        radius: 4
+        border.color: "black"
+        border.width: 1
+        color: !control.enabled ? control.Material.buttonDisabledColor : control.highlighted ? control.Material.highlightedButtonColor : control.Material.buttonColor
+
+        PaddedRectangle {
+            y: parent.height - 4
+            width: parent.width
+            height: 4
+            radius: 2
+            topPadding: -2
+            clip: true
+            visible: control.checkable && (!control.highlighted || control.flat)
+            color: control.checked
+                   && control.enabled ? control.Material.accentColor : control.Material.secondaryTextColor
+        }
+
+        // The layer is disabled when the button color is transparent so you can do
+        // Material.background: "transparent" and get a proper flat button without needing
+        // to set Material.elevation as well
+        layer.enabled: control.enabled && control.Material.buttonColor.a > 0
+        layer.effect: ElevationEffect {
+            elevation: control.Material.elevation
+        }
+
+        Ripple {
+            clipRadius: 2
+            width: parent.width
+            height: parent.height
+            pressed: control.pressed
+            anchor: control
+            active: control.down || control.visualFocus || control.hovered
+            color: control.flat
+                   && control.highlighted ? control.Material.highlightedRippleColor : control.Material.rippleColor
+        }
+    }
+}
diff --git a/gui/components/Preferences.qml b/gui/components/Preferences.qml
new file mode 100644
index 00000000..e5c48286
--- /dev/null
+++ b/gui/components/Preferences.qml
@@ -0,0 +1,23 @@
+import QtQuick 2.9
+import QtQuick.Controls 2.2
+
+Page {
+    title: qsTr("Preferences")
+
+    Column {
+        spacing: 2
+        topPadding: root.width * 0.2
+        leftPadding: root.width * 0.15
+        rightPadding: root.width * 0.15
+
+        Label {
+            text: qsTr("Anti-censorship")
+            font.bold: true
+        }
+
+        CheckBox {
+            checked: false
+            text: qsTr("Use Bridges")
+        }
+    }
+}
diff --git a/gui/components/Spinner.qml b/gui/components/Spinner.qml
new file mode 100644
index 00000000..9fc535f9
--- /dev/null
+++ b/gui/components/Spinner.qml
@@ -0,0 +1,63 @@
+import QtQuick 2.9
+import QtQuick.Controls 2.2
+import QtGraphicalEffects 1.0
+
+BusyIndicator {
+
+    id: control
+
+    anchors.horizontalCenter: parent.horizontalCenter
+
+    contentItem: Item {
+        implicitWidth: 64
+        implicitHeight: 64
+
+        Item {
+            id: item
+            x: parent.width / 2 - 32
+            y: parent.height / 2 - 32
+            width: 64
+            height: 64
+            opacity: control.running ? 1 : 0
+
+            Behavior on opacity {
+                OpacityAnimator {
+                    duration: 250
+                }
+            }
+
+            RotationAnimator {
+                target: item
+                running: control.visible && control.running
+                from: 0
+                to: 360
+                loops: Animation.Infinite
+                duration: 6200
+            }
+
+            Repeater {
+                id: repeater
+                model: 6
+
+                Rectangle {
+                    x: item.width / 2 - width / 2
+                    y: item.height / 2 - height / 2
+                    implicitWidth: 10
+                    implicitHeight: 10
+                    radius: 5
+                    color: "#21be2b"
+                    transform: [
+                        Translate {
+                            y: -Math.min(item.width, item.height) * 0.5 + 5
+                        },
+                        Rotation {
+                            angle: index / repeater.count * 360
+                            origin.x: 5
+                            origin.y: 5
+                        }
+                    ]
+                }
+            }
+        }
+    }
+}
diff --git a/gui/components/Splash.qml b/gui/components/Splash.qml
new file mode 100644
index 00000000..b4944947
--- /dev/null
+++ b/gui/components/Splash.qml
@@ -0,0 +1,64 @@
+import QtQuick 2.9
+import QtQuick.Controls 2.2
+import QtGraphicalEffects 1.0
+
+Page {
+    id: splash
+    property int timeoutInterval: 1600
+
+    Column {
+        width: parent.width * 0.8
+        anchors.horizontalCenter: parent.horizontalCenter
+        anchors.topMargin: 24
+
+        VerticalSpacer {
+            visible: true
+            height: root.height * 0.10
+        }
+
+        Image {
+            id: connectionImage
+            height: 200
+            anchors.horizontalCenter: parent.horizontalCenter
+            source: "../resources/icon-noshield.svg"
+            fillMode: Image.PreserveAspectFit
+        }
+
+        Spinner {}
+    }
+
+    Timer {
+        id: splashTimer
+    }
+
+    function delay(delayTime, cb) {
+        splashTimer.interval = delayTime
+        splashTimer.repeat = false
+        splashTimer.triggered.connect(cb)
+        splashTimer.start()
+    }
+
+    function loadMainViewWhenReady() {
+        console.debug("ready?")
+        if (ctx && ctx.isReady) {
+            console.debug("ready?", ctx.isReady)
+            // FIXME check errors == None
+            loader.source = "MainView.qml"
+        } else {
+            delay(100, loadMainViewWhenReady)
+        }
+    }
+
+    Timer {
+        interval: timeoutInterval
+        running: true
+        repeat: false
+        onTriggered: {
+            loadMainViewWhenReady()
+        }
+    }
+
+    Component.onCompleted: {
+
+    }
+}
diff --git a/gui/components/StatusBox.qml b/gui/components/StatusBox.qml
new file mode 100644
index 00000000..fa24cd89
--- /dev/null
+++ b/gui/components/StatusBox.qml
@@ -0,0 +1,125 @@
+import QtQuick 2.12
+import QtQuick.Controls 2.12
+import QtGraphicalEffects 1.14
+import QtQuick.Layouts 1.14
+
+import QtQuick.Templates 2.12 as T
+import QtQuick.Controls.impl 2.12
+import QtQuick.Controls.Material 2.12
+import QtQuick.Controls.Material.impl 2.12
+import "../themes/themes.js" as Theme
+
+Item {
+    id: statusbox
+    anchors.fill: parent
+
+    VPNState {
+        id: vpn
+    }
+
+    Rectangle {
+        id: statusBoxBackground
+        anchors.fill: parent
+        anchors.margins: 20
+        anchors.bottomMargin: 30
+        height: 300
+        radius: 10
+        color: Theme.bgColor
+        border.color: Theme.accentOff
+        border.width: 2
+        antialiasing: true
+    }
+
+    ToolButton {
+        id: settingsButton
+        objectName: "settingsButton"
+        opacity: 1
+
+        font.pixelSize: Qt.application.font.pixelSize * 1.6
+        anchors.top: parent.top
+        anchors.left: parent.left
+        anchors.topMargin: Theme.windowMargin + 10
+        anchors.leftMargin: Theme.windowMargin + 10
+
+        onClicked: {
+            if (stackView.depth > 1) {
+                stackView.pop()
+            } else {
+                settingsDrawer.open()
+            }
+        }
+
+        Icon {
+            id: settingsImage
+            width: 24
+            height: 24
+            // TODO move arrow left to toolbar top
+            source: stackView.depth
+                    > 1 ? "../resources/arrow-left.svg" : "../resources/gear-fill.svg"
+            anchors.centerIn: settingsButton
+        }
+    }
+
+    Column {
+        id: col
+        anchors.centerIn: parent
+        anchors.topMargin: 24
+        width: parent.width * 0.8
+
+        BoldLabel {
+            id: connectionState
+            text: ""
+            anchors.horizontalCenter: parent.horizontalCenter
+            horizontalAlignment: Text.AlignHCenter
+        }
+
+        VerticalSpacer {
+            id: spacerPreImg
+            visible: false
+            height: 40
+        }
+
+        Image {
+            id: connectionImage
+            height: 200
+            source: "../resources/spy.gif"
+            fillMode: Image.PreserveAspectFit
+        }
+
+        VerticalSpacer {
+            id: spacerPostImg
+            visible: false
+            height: 35
+        }
+
+        MaterialButton {
+            id: toggleVPN
+            anchors.horizontalCenter: parent.horizontalCenter
+            Layout.alignment: Qt.AlignBottom
+            font.capitalization: Font.Capitalize
+            spacing: 8
+
+            onClicked: {
+                if (vpn.state === "on") {
+                    console.debug("should turn off")
+                    backend.switchOff()
+                } else if (vpn.state === "off") {
+                    console.debug("should turn on")
+                    backend.switchOn()
+                } else {
+                    console.debug("unknown state")
+                }
+            }
+
+
+            /*
+             XXX this hijacks click events, so better no pointing for now.
+            MouseArea {
+                anchors.fill: toggleVPN
+                hoverEnabled: true
+                cursorShape: !hoverEnabled ? Qt.ForbiddenCursor : Qt.PointingHandCursor
+            }
+            */
+        }
+    }
+}
diff --git a/gui/components/Style.qml b/gui/components/Style.qml
new file mode 100644
index 00000000..acd6036e
--- /dev/null
+++ b/gui/components/Style.qml
@@ -0,0 +1,12 @@
+import "themes.js" as Theme
+
+Item {
+    property alias fontFoo: fontFooLoader.name
+    readonly property color colourBlackground: "#efefef"
+
+    // TODO use theme.background
+    FontLoader {
+        id: fontFooLoader
+        source: "qrc:/resources/fonts/Oxanium-Bold.ttf"
+    }
+}
diff --git a/gui/components/Systray.qml b/gui/components/Systray.qml
new file mode 100644
index 00000000..6fb10467
--- /dev/null
+++ b/gui/components/Systray.qml
@@ -0,0 +1,27 @@
+import QtQuick 2.0
+import QtQuick.Controls 2.4
+import Qt.labs.platform 1.0 as Labs
+
+Labs.SystemTrayIcon {
+
+    visible: systrayVisible
+    property alias statusItem: statusItem
+
+    menu: Labs.Menu {
+
+        id: systrayMenu
+
+        Labs.MenuItem {
+            id: statusItem
+            text: qsTr("Checking status…")
+            enabled: false
+        }
+
+        Labs.MenuSeparator {}
+
+        Labs.MenuItem {
+            text: qsTr("Quit")
+            onTriggered: backend.quit()
+        }
+    }
+}
diff --git a/gui/components/VPNButtonBase.qml b/gui/components/VPNButtonBase.qml
new file mode 100644
index 00000000..6f677102
--- /dev/null
+++ b/gui/components/VPNButtonBase.qml
@@ -0,0 +1,56 @@
+
+
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+import QtQuick 2.0
+import QtQuick.Controls 2.5
+import QtQuick.Layouts 1.14
+import "../themes/themes.js" as Theme
+
+RoundButton {
+    id: root
+
+    property var visualStateItem: root
+    property var uiState: Theme.uiState
+    property var loaderVisible: false
+    property var handleKeyClick: function () {
+        clicked()
+    }
+
+    focusPolicy: Qt.StrongFocus
+    Keys.onPressed: {
+        if (loaderVisible) {
+            return
+        }
+
+        if (event.key === Qt.Key_Return || event.key === Qt.Key_Space)
+            visualStateItem.state = uiState.statePressed
+    }
+    Keys.onReleased: {
+        if (loaderVisible) {
+            return
+        }
+        if (event.key === Qt.Key_Return || event.key === Qt.Key_Space) {
+            visualStateItem.state = uiState.stateDefault
+        }
+        if (event.key === Qt.Key_Return)
+            handleKeyClick()
+    }
+
+    Accessible.role: Accessible.Button
+    Accessible.onPressAction: handleKeyClick()
+    Accessible.focusable: true
+
+    onActiveFocusChanged: {
+        if (!activeFocus)
+            return visualStateItem.state = uiState.stateDefault
+
+        if (vpnFlickable && typeof (vpnFlickable.ensureVisible) !== "undefined")
+            return vpnFlickable.ensureVisible(visualStateItem)
+    }
+
+    background: Rectangle {
+        color: "transparent"
+    }
+}
diff --git a/gui/components/VPNMouseArea.qml b/gui/components/VPNMouseArea.qml
new file mode 100644
index 00000000..44d6465e
--- /dev/null
+++ b/gui/components/VPNMouseArea.qml
@@ -0,0 +1,37 @@
+import QtQuick 2.5
+import "../themes/themes.js" as Theme
+
+MouseArea {
+    id: mouseArea
+
+    property var targetEl: parent
+    property var uiState: Theme.uiState
+    property var onMouseAreaClicked: function () {
+        parent.clicked()
+    }
+
+    //function changeState(stateName) {
+    //    if (mouseArea.hoverEnabled)
+    //       targetEl.state = stateName;
+    //}
+    anchors.fill: parent
+    hoverEnabled: true
+    cursorShape: !hoverEnabled ? Qt.ForbiddenCursor : Qt.PointingHandCursor
+    //onPressed: {
+    //    console.debug("button pressed")
+    //changeState(uiState.statePressed)
+    //}
+    //onEntered: changeState(uiState.stateHovered)
+    //onExited: changeState(uiState.stateDefault)
+    //onCanceled: changeState(uiState.stateDefault)
+
+
+    /*
+    onReleased: {
+        if (hoverEnabled) {
+            changeState(uiState.stateDefault);
+            onMouseAreaClicked();
+        }
+    }
+*/
+}
diff --git a/gui/components/VPNState.qml b/gui/components/VPNState.qml
new file mode 100644
index 00000000..8856ad4a
--- /dev/null
+++ b/gui/components/VPNState.qml
@@ -0,0 +1,193 @@
+import QtQuick 2.0
+import QtQuick.Controls 2.12
+
+import "../themes/themes.js" as Theme
+
+StateGroup {
+
+    state: ctx ? ctx.status : "off"
+
+    states: [
+        State {
+            name: "initializing"
+        },
+        State {
+            name: "off"
+            PropertyChanges {
+                target: connectionState
+                text: qsTr("Connection\nUnsecured")
+            }
+            PropertyChanges {
+                target: statusBoxBackground
+                border.color: Theme.accentOff
+            }
+            PropertyChanges {
+                target: connectionImage
+                source: "../resources/spy.gif"
+                //anchors.right: parent.right
+                //anchors.rightMargin: -8
+                // XXX need to nulify horizontalcenter somehow,
+                // it gets fixed to parent.center
+            }
+            PropertyChanges {
+                target: toggleVPN
+                text: qsTr("Turn on")
+            }
+            PropertyChanges {
+                target: systray
+                icon.source: icons["off"]
+            }
+            PropertyChanges {
+                target: systray.statusItem
+                text: toHuman("off")
+            }
+            StateChangeScript {
+                script: {
+
+                }
+            }
+        },
+        State {
+            name: "on"
+            PropertyChanges {
+                target: connectionState
+                text: qsTr("Connection\nSecure")
+            }
+            PropertyChanges {
+                target: statusBoxBackground
+                border.color: Theme.accentOn
+            }
+            PropertyChanges {
+                target: connectionImage
+                source: "../resources/riseup-icon.svg"
+                // TODO need to offset the logo or increase the image
+                // to fixed height
+                height: 120
+            }
+            PropertyChanges {
+                target: spacerPreImg
+                visible: true
+            }
+            PropertyChanges {
+                target: spacerPostImg
+                visible: true
+            }
+            PropertyChanges {
+                target: toggleVPN
+                text: qsTr("Turn off")
+            }
+            PropertyChanges {
+                target: systray
+                tooltip: toHuman("on")
+                icon.source: icons["on"]
+            }
+            PropertyChanges {
+                target: systray.statusItem
+                text: toHuman("on")
+            }
+            StateChangeScript {
+                script: {
+
+                    // TODO check donation
+                    //if (needsDonate && !shownDonate) {
+                    //    donate.visible = true;
+                    //    shownDonate = true;
+                    //    backend.donateSeen();
+                    //}
+                }
+            }
+        },
+        State {
+            name: "starting"
+            //when: toggleVPN.pressed == true
+            PropertyChanges {
+                target: connectionState
+                text: qsTr("Connecting")
+            }
+            PropertyChanges {
+                target: statusBoxBackground
+                border.color: Theme.accentConnecting
+            }
+            PropertyChanges {
+                target: connectionImage
+                source: "../resources/birds.svg"
+                anchors.horizontalCenter: parent.horizontalCenter
+            }
+            PropertyChanges {
+                target: toggleVPN
+                text: qsTr("Cancel")
+            }
+            PropertyChanges {
+                target: systray
+                tooltip: toHuman("connecting")
+                icon.source: icons["wait"]
+            }
+            PropertyChanges {
+                target: systray.statusItem
+                text: toHuman("connecting")
+            }
+            StateChangeScript {
+                script: {
+
+                }
+            }
+        },
+        State {
+            name: "stopping"
+            PropertyChanges {
+                target: connectionState
+                text: "Switching\nOff"
+            }
+            PropertyChanges {
+                target: statusBoxBackground
+                border.color: Theme.accentConnecting
+            }
+            PropertyChanges {
+                target: systray
+                tooltip: toHuman("stopping")
+                icon.source: icons["wait"]
+            }
+            PropertyChanges {
+                target: systray.statusItem
+                text: toHuman("stopping")
+            }
+        },
+        State {
+            name: "failed"
+            // TODO
+        }
+    ]
+
+
+    /*
+    transitions: Transition {
+        from: "off"
+        to: "starting"
+        reversible: true
+
+        ParallelAnimation {
+            ColorAnimation { duration: 500 }
+        }
+    }
+    */
+    function toHuman(st) {
+        switch (st) {
+        case "off":
+            //: %1 -> application name
+            return ctx ? qsTr("%1 off").arg(ctx.appName) : qsTr("off")
+        case "on":
+            //: %1 -> application name
+            return qsTr("%1 on").arg(ctx.appName)
+        case "connecting":
+            //: %1 -> application name
+            return qsTr("Connecting to %1").arg(ctx.appName)
+        case "stopping":
+            //: %1 -> application name
+            return qsTr("Stopping %1").arg(ctx.appName)
+        case "failed":
+            //: %1 -> application name
+            return qsTr("%1 blocking internet").arg(
+                        ctx.appName) // TODO failed is not handled yet
+        }
+    }
+}
diff --git a/gui/components/VPNToggle.qml b/gui/components/VPNToggle.qml
new file mode 100644
index 00000000..4773869f
--- /dev/null
+++ b/gui/components/VPNToggle.qml
@@ -0,0 +1,338 @@
+
+
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+import QtQuick 2.5
+import QtQuick.Controls 2.5
+
+import "../themes/themes.js" as Theme
+
+VPNButtonBase {
+    id: toggleButton
+
+    property var connectionRetryOverX: VPNController.connectionRetry > 1
+    property var toggleColor: Theme.vpnToggleDisconnected
+    property var toolTipTitle: ""
+    Accessible.name: toolTipTitle
+
+    function handleClick() {
+        toolTip.close()
+        if (VPNController.state !== VPNController.StateOff) {
+            return VPN.deactivate()
+        }
+
+        return VPN.activate()
+    }
+
+    onClicked: handleClick()
+
+    // property in VPNButtonBase {}
+    visualStateItem: toggle
+    //state: VPNController.state
+    height: 32
+    width: 60
+    radius: 16
+    hoverEnabled: false
+
+    onActiveFocusChanged: {
+        if (!focus && toolTip.visible) {
+            toolTip.close()
+        }
+    }
+
+
+    /*
+    states: [
+        State {
+            name: VPNController.StateInitializing
+
+            PropertyChanges {
+                target: cursor
+                anchors.leftMargin: 4
+            }
+
+            PropertyChanges {
+                target: toggle
+                color: "#9E9E9E"
+                border.color: Theme.white
+            }
+
+            PropertyChanges {
+                target: toggleButton
+                toggleColor: Theme.vpnToggleDisconnected
+            }
+
+        },
+        State {
+            name: VPNController.StateOff
+
+            PropertyChanges {
+                target: cursor
+                anchors.leftMargin: 4
+            }
+
+            PropertyChanges {
+                target: toggle
+                color: "#9E9E9E"
+                border.color: Theme.white
+            }
+
+            PropertyChanges {
+                target: toggleButton
+                //% "Turn VPN on"
+                toolTipTitle: qsTrId("vpn.toggle.on")
+            }
+
+        },
+        State {
+            name: VPNController.StateConnecting
+
+            PropertyChanges {
+                target: cursor
+                anchors.leftMargin: 32
+                color: "#998DB2"
+            }
+
+            PropertyChanges {
+                target: toggle
+                color: "#387E8A"
+                border.color: Theme.ink
+            }
+
+            PropertyChanges {
+                target: toggleButton
+                //% "Turn VPN off"
+                toolTipTitle: qsTrId("vpn.toggle.off")
+                toggleColor: Theme.vpnToggleConnected
+            }
+
+        },
+        State {
+            name: VPNController.StateConfirming
+
+            PropertyChanges {
+                target: cursor
+                anchors.leftMargin: 32
+                color: connectionRetryOverX ? "#FFFFFF" : "#998DB2"
+            }
+
+            PropertyChanges {
+                target: toggle
+                color: "#387E8A"
+                border.color: Theme.ink
+            }
+
+            PropertyChanges {
+                target: toggleButton
+                //% "Turn VPN off"
+                toolTipTitle: qsTrId("vpn.toggle.off")
+                toggleColor: Theme.vpnToggleConnected
+            }
+
+        },
+        State {
+            name: VPNController.StateOn
+
+            PropertyChanges {
+                target: cursor
+                anchors.leftMargin: 32
+            }
+
+            PropertyChanges {
+                target: toggle
+                color: "#3FE1B0"
+                border.color: Theme.ink
+            }
+
+            PropertyChanges {
+                target: toggleButton
+                toolTipTitle: qsTrId("vpn.toggle.off")
+                toggleColor: Theme.vpnToggleConnected
+            }
+
+        },
+        State {
+            name: VPNController.StateDisconnecting
+
+            PropertyChanges {
+                target: cursor
+                anchors.leftMargin: 4
+            }
+
+            PropertyChanges {
+                target: toggle
+                color: "#CECECE"
+                border.color: Theme.white
+            }
+
+            PropertyChanges {
+                target: toggleButton
+                toolTipTitle: qsTrId("vpn.toggle.on")
+                toggleColor: Theme.vpnToggleDisconnected
+            }
+
+        },
+        State {
+            name: VPNController.StateSwitching
+
+            PropertyChanges {
+                target: cursor
+                anchors.leftMargin: 32
+                color: "#998DB2"
+            }
+
+            PropertyChanges {
+                target: toggle
+                color: "#387E8A"
+                border.color: Theme.ink
+            }
+
+            PropertyChanges {
+                target: toggleButton
+                toggleColor: Theme.vpnToggleConnected
+            }
+
+        }
+    ]
+    transitions: [
+        Transition {
+            ParallelAnimation {
+                NumberAnimation {
+                    target: cursor
+                    property: "anchors.leftMargin"
+                    duration: 200
+                }
+
+                ColorAnimation {
+                    target: cursor
+                    duration: 200
+                }
+
+            }
+
+        }
+    ]
+
+    // Focus rings
+    VPNFocusBorder {
+        id: focusHandler
+
+        anchors.fill: toggle
+        anchors.margins: -4
+        radius: height / 2
+        border.color: toggleColor.focusBorder
+        color: "transparent"
+        opacity: toggleButton.activeFocus && (VPNController.state === VPNController.StateOn || VPNController.state === VPNController.StateOff) ? 1 : 0
+
+        VPNFocusOutline {
+            id: vpnFocusOutline
+
+            anchors.fill: focusHandler
+            focusedComponent: focusHandler
+            setMargins: -6
+            radius: height / 2
+            border.width: 7
+            color: "transparent"
+            border.color: toggleColor.focusOutline
+            opacity: 0.25
+        }
+
+    }
+
+    // Faint outline visible on hover and press
+    Rectangle {
+        id: hoverPressHandler
+
+        color: "#C2C2C2"
+        state: toggle.state
+        opacity: {
+            if (state === uiState.stateDefault || toggleButton.activeFocus)
+                return 0;
+
+            if (state === uiState.stateHovered)
+                return 0.2;
+
+            if (state === uiState.statePressed)
+                return 0.3;
+
+        }
+        z: -1
+        anchors.fill: toggle
+        radius: height / 2
+        anchors.margins: -5
+
+        PropertyAnimation on opacity {
+            duration: 200
+        }
+
+    }
+    */
+    function toggleClickable() {
+        return VPN.state === VPN.StateMain
+                && (VPNController.state === VPNController.StateOn
+                    || VPNController.state === VPNController.StateOff
+                    || (VPNController.state === VPNController.StateConfirming
+                        && connectionRetryOverX))
+    }
+
+    // Toggle background color changes on hover and press
+    VPNUIStates {
+        itemToFocus: toggleButton
+        itemToAnchor: toggle
+        colorScheme: toggleColor
+        radius: height / 2
+        setMargins: -7
+        showFocusRings: false
+        opacity: toggleClickable() ? 1 : 0
+        z: 1
+
+        Behavior on opacity {
+            PropertyAnimation {
+                property: "opacity"
+                duration: 100
+            }
+        }
+    }
+
+    Rectangle {
+        id: cursor
+
+        height: 24
+        width: 24
+        radius: 12
+        anchors.left: parent.left
+        anchors.top: parent.top
+        anchors.topMargin: 4
+        z: 2
+    }
+
+    VPNMouseArea {
+        id: mouseArea
+
+        targetEl: toggle
+        anchors.fill: toggle
+        hoverEnabled: toggleClickable()
+        cursorShape: Qt.PointingHandCursor
+    }
+
+    VPNToolTip {
+        id: toolTip
+        text: toolTipTitle
+    }
+
+    background: Rectangle {
+        id: toggle
+
+        Component.onCompleted: state = uiState.stateDefault
+        border.width: 0
+        anchors.fill: toggleButton
+        radius: height / 2
+
+        Behavior on color {
+            ColorAnimation {
+                duration: 200
+            }
+        }
+    }
+}
diff --git a/gui/components/VerticalSpacer.qml b/gui/components/VerticalSpacer.qml
new file mode 100644
index 00000000..455e4daf
--- /dev/null
+++ b/gui/components/VerticalSpacer.qml
@@ -0,0 +1,6 @@
+import QtQuick 2.0
+
+Rectangle {
+    color: "transparent"
+    width: parent.width
+}
diff --git a/gui/gui.qrc b/gui/gui.qrc
index 30997279..dde4c8fd 100644
--- a/gui/gui.qrc
+++ b/gui/gui.qrc
@@ -1,7 +1,50 @@
 <RCC>
     <qresource prefix="/">
 
-        <file>qml/main.qml</file>
+        <file>main.qml</file>
+
+        <file>themes/themes.js</file>
+        <file>components/MainView.qml</file>
+        <file>components/Splash.qml</file>
+        <file>components/Home.qml</file>
+        <file>components/Header.qml</file>
+        <file>components/Footer.qml</file>
+        <file>components/StatusBox.qml</file>
+        <file>components/Spinner.qml</file>
+        <file>components/Systray.qml</file>
+        <file>components/Help.qml</file>
+        <file>components/Locations.qml</file>
+        <file>components/Preferences.qml</file>
+        <file>components/BoldLabel.qml</file>
+        <file>components/LightLabel.qml</file>
+        <file>components/VPNButtonBase.qml</file>
+        <file>components/VPNMouseArea.qml</file>
+        <file>components/VerticalSpacer.qml</file>
+        <file>components/Icon.qml</file>
+        <file>components/MaterialButton.qml</file>
+        <file>components/VPNState.qml</file>
+        <file>resources/icon-noshield.svg</file>
+        <file>resources/location.svg</file>
+        <file>resources/settings.svg</file>
+        <file>resources/power.svg</file>
+        <file>resources/close.svg</file>
+        <file>resources/donate.svg</file>
+        <file>resources/tools.svg</file>
+        <file>resources/help.svg</file>
+        <file>resources/about.svg</file>
+        <file>resources/bridge.png</file>
+        <file>resources/gear-fill.svg</file>
+        <file>resources/reception-0.svg</file>
+        <file>resources/reception-2.svg</file>
+        <file>resources/reception-4.svg</file>
+        <file>resources/arrow-left.svg</file>
+        <file>resources/globe.svg</file>
+        <file>resources/birds.svg</file>
+        <file>resources/riseup-icon.svg</file>
+        <file>resources/spy.gif</file>
+        <file>resources/quit.svg</file>
+
+        <!-- old, to remove -->
         <file>qml/VpnState.qml</file>
         <file>qml/AboutDialog.qml</file>
         <file>qml/DonateDialog.qml</file>
@@ -14,6 +57,7 @@
         <file>qml/VPNSwitch.qml</file>
         <file>qml/BridgesItem.qml</file>
         <file>qml/logic.js</file>
+        <!-- to remove -->
 
         <file>assets/icon/png/black/vpn_off.png</file>
         <file>assets/icon/png/black/vpn_on.png</file>
diff --git a/gui/main.cpp b/gui/main.cpp
index d10cb51c..d136c3c1 100644
--- a/gui/main.cpp
+++ b/gui/main.cpp
@@ -5,6 +5,7 @@
 #include <QTranslator>
 #include <QCommandLineParser>
 #include <QQuickWindow>
+#include <QQuickStyle>
 #include <QSystemTrayIcon>
 #include <QtQml>
 
@@ -137,9 +138,8 @@ int main(int argc, char **argv) {
         exit(0);
     }
 
-    if (hideSystray) {
+    if (hideSystray)
         qDebug() << "Not showing systray icon because --no-systray option is set.";
-    }
 
     if (installHelpers) {
         qDebug() << "Will try to install helpers with sudo";
@@ -159,11 +159,13 @@ int main(int argc, char **argv) {
         availableSystray = false;
     }
 
+    /* set window icon */
+    app.setWindowIcon(QIcon(":/vendor/icon.svg"));
+
+    /* load translations */
     QTranslator translator;
     translator.load(QLocale(), QLatin1String("main"), QLatin1String("_"), QLatin1String(":/i18n"));
     app.installTranslator(&translator);
-    /* set window icon */
-    app.setWindowIcon(QIcon(":/vendor/icon.svg"));
 
 
     QQmlApplicationEngine engine;
@@ -172,6 +174,7 @@ int main(int argc, char **argv) {
     QJsonModel *model = new QJsonModel;
 
     QString desktop = QString::fromStdString(getEnv("XDG_CURRENT_DESKTOP"));
+    QString debug = QString::fromStdString(getEnv("DEBUG"));
 
     /* the backend handler has slots for calling back to Go when triggered by
        signals in Qml. */
@@ -185,8 +188,10 @@ int main(int argc, char **argv) {
     /* set some useful flags */
     ctx->setContextProperty("systrayVisible", !hideSystray);
     ctx->setContextProperty("systrayAvailable", availableSystray);
+    ctx->setContextProperty("qmlDebug", debug == "1");
 
-    engine.load(QUrl(QStringLiteral("qrc:/qml/main.qml")));
+    QQuickStyle::setStyle("Material");
+    engine.load(QUrl(QStringLiteral("qrc:/main.qml")));
 
     /* connect the jsonChanged signal explicitely.
         In the lambda, we reload the json in the model every time we receive an
@@ -215,9 +220,11 @@ int main(int argc, char **argv) {
             obfs4, disAutostart, toGoStr(startVPN));
 
     /* if requested, enable web api for controlling the VPN */
-    if (webAPI) {
+    if (webAPI)
         EnableWebAPI(toGoStr(webPort));
-    };
+
+    if (engine.rootObjects().isEmpty())
+        return -1;
 
     /* kick off your shoes, put your feet up */
     return app.exec();
diff --git a/gui/main.qml b/gui/main.qml
new file mode 100644
index 00000000..16677a27
--- /dev/null
+++ b/gui/main.qml
@@ -0,0 +1,116 @@
+/*
+ TODO (ui rewrite)
+ - [x] add systray
+ - [x] systray status
+ - [x] splash screen
+ - [ ] splash delay/transitions
+ - [ ] nested states
+ - [ ] splash init errors
+ - [ ] font: monserrat
+ - [ ] donation dialog
+ - [ ] add gateway to systray
+ - [ ] control actions from systray
+ - [ ] minimize/hide from systray
+ - [ ] parse ctx flags (need dialog, etc)
+ - [ ] gateway selector
+ - [ ] bridges
+*/
+
+import QtQuick 2.0
+import QtQuick.Controls 2.4
+import QtQuick.Dialogs 1.2
+import QtQuick.Controls.Material 2.1
+import QtQuick.Layouts 1.14
+
+import "./components"
+
+ApplicationWindow {
+
+    id: root
+
+    visible: true
+    width: 360
+    height: 520
+    minimumWidth: 300
+    maximumWidth: 300
+    minimumHeight: 500
+    maximumHeight: 500
+
+    title: ctx ? ctx.appName : "VPN"
+    Material.accent: Material.Green
+
+    property var ctx
+
+    property var icons: {
+        "off": "qrc:/assets/icon/png/white/vpn_off.png",
+        "on": "qrc:/assets/icon/png/white/vpn_on.png",
+        "wait": "qrc:/assets/icon/png/white/vpn_wait_0.png",
+        "blocked": "qrc:/assets/icon/png/white/vpn_blocked.png"
+    }
+
+    Loader {
+	id: loader
+	asynchronous: true
+	anchors.fill: parent
+    }
+
+    Systray {
+	id: systray
+    }
+
+    Connections {
+	target: jsonModel
+	function onDataChanged() {
+	    ctx = JSON.parse(jsonModel.getJson())
+            if (qmlDebug) {
+                console.debug(jsonModel.getJson())
+            }
+
+	    // FIXME -- use nested state machines for all these cases.
+
+	    //gwSelector.model = Object.keys(ctx.locations)
+
+	    /*
+	    if (ctx.donateDialog == 'true') {
+		Logic.setNeedsDonate(true);
+	    }
+	    if (ctx.loginDialog == 'true') {
+		console.debug(jsonModel.getJson())
+		console.debug("DEBUG: should display login")
+		login.visible = true
+	    }
+	    if (ctx.loginOk == 'true') {
+		loginOk.visible = true
+	    }
+	    if (ctx.errors) {
+		login.visible = false
+		if (ctx.errors == "nohelpers") {
+		    showInitFailure(
+				qsTr("Could not find helpers. Please check your installation"))
+		} else if (ctx.errors == "nopolkit") {
+		    showInitFailure(qsTr("Could not find polkit agent."))
+		} else {
+		    showInitFailure()
+		}
+	    }
+	    if (ctx.donateURL) {
+		donateItem.visible = true
+	    }
+
+	    if (ctx.status == "on") {
+		gwNextConnectionText.visible = false
+		gwReconnectText.visible = false
+	    }
+	    */
+	}
+    }
+
+    onSceneGraphError: function(error, msg) {
+        console.debug("ERROR while initializing scene")
+        console.debug(msg)
+    }
+
+    Component.onCompleted: {
+        loader.source = "components/Splash.qml"
+    }
+}
diff --git a/gui/providers/providers.json b/gui/providers/providers.json
index 8592ba05..52fcbf93 100644
--- a/gui/providers/providers.json
+++ b/gui/providers/providers.json
@@ -15,7 +15,7 @@
             "apiURL": "https://api.black.riseup.net/",
             "geolocationAPI": "https://api.black.riseup.net:9001/json",
             "caCertString": "-----BEGIN CERTIFICATE-----\nMIIFjTCCA3WgAwIBAgIBATANBgkqhkiG9w0BAQ0FADBZMRgwFgYDVQQKDA9SaXNl\ndXAgTmV0d29ya3MxGzAZBgNVBAsMEmh0dHBzOi8vcmlzZXVwLm5ldDEgMB4GA1UE\nAwwXUmlzZXVwIE5ldHdvcmtzIFJvb3QgQ0EwHhcNMTQwNDI4MDAwMDAwWhcNMjQw\nNDI4MDAwMDAwWjBZMRgwFgYDVQQKDA9SaXNldXAgTmV0d29ya3MxGzAZBgNVBAsM\nEmh0dHBzOi8vcmlzZXVwLm5ldDEgMB4GA1UEAwwXUmlzZXVwIE5ldHdvcmtzIFJv\nb3QgQ0EwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQC76J4ciMJ8Sg0m\nTP7DF2DT9zNe0Csk4myoMFC57rfJeqsAlJCv1XMzBmXrw8wq/9z7XHv6n/0sWU7a\n7cF2hLR33ktjwODlx7vorU39/lXLndo492ZBhXQtG1INMShyv+nlmzO6GT7ESfNE\nLliFitEzwIegpMqxCIHXFuobGSCWF4N0qLHkq/SYUMoOJ96O3hmPSl1kFDRMtWXY\niw1SEKjUvpyDJpVs3NGxeLCaA7bAWhDY5s5Yb2fA1o8ICAqhowurowJpW7n5ZuLK\n5VNTlNy6nZpkjt1QycYvNycffyPOFm/Q/RKDlvnorJIrihPkyniV3YY5cGgP+Qkx\nHUOT0uLA6LHtzfiyaOqkXwc4b0ZcQD5Vbf6Prd20Ppt6ei0zazkUPwxld3hgyw58\nm/4UIjG3PInWTNf293GngK2Bnz8Qx9e/6TueMSAn/3JBLem56E0WtmbLVjvko+LF\nPM5xA+m0BmuSJtrD1MUCXMhqYTtiOvgLBlUm5zkNxALzG+cXB28k6XikXt6MRG7q\nhzIPG38zwkooM55yy5i1YfcIi5NjMH6A+t4IJxxwb67MSb6UFOwg5kFokdONZcwj\nshczHdG9gLKSBIvrKa03Nd3W2dF9hMbRu//STcQxOailDBQCnXXfAATj9pYzdY4k\nha8VCAREGAKTDAex9oXf1yRuktES4QIDAQABo2AwXjAdBgNVHQ4EFgQUC4tdmLVu\nf9hwfK4AGliaet5KkcgwDgYDVR0PAQH/BAQDAgIEMAwGA1UdEwQFMAMBAf8wHwYD\nVR0jBBgwFoAUC4tdmLVuf9hwfK4AGliaet5KkcgwDQYJKoZIhvcNAQENBQADggIB\nAGzL+GRnYu99zFoy0bXJKOGCF5XUXP/3gIXPRDqQf5g7Cu/jYMID9dB3No4Zmf7v\nqHjiSXiS8jx1j/6/Luk6PpFbT7QYm4QLs1f4BlfZOti2KE8r7KRDPIecUsUXW6P/\n3GJAVYH/+7OjA39za9AieM7+H5BELGccGrM5wfl7JeEz8in+V2ZWDzHQO4hMkiTQ\n4ZckuaL201F68YpiItBNnJ9N5nHr1MRiGyApHmLXY/wvlrOpclh95qn+lG6/2jk7\n3AmihLOKYMlPwPakJg4PYczm3icFLgTpjV5sq2md9bRyAg3oPGfAuWHmKj2Ikqch\nTd5CHKGxEEWbGUWEMP0s1A/JHWiCbDigc4Cfxhy56CWG4q0tYtnc2GMw8OAUO6Wf\nXu5pYKNkzKSEtT/MrNJt44tTZWbKV/Pi/N2Fx36my7TgTUj7g3xcE9eF4JV2H/sg\ntsK3pwE0FEqGnT4qMFbixQmc8bGyuakr23wjMvfO7eZUxBuWYR2SkcP26sozF9PF\ntGhbZHQVGZUTVPyvwahMUEhbPGVerOW0IYpxkm0x/eaWdTc4vPpf/rIlgbAjarnJ\nUN9SaWRlWKSdP4haujnzCoJbM7dU9bjvlGZNyXEekgeT0W2qFeGGp+yyUWw8tNsp\n0BuC1b7uW/bBn/xKm319wXVDvBgZgcktMolak39V7DVO\n-----END CERTIFICATE-----",
-            "timeStamp": "2021-07-09 20:10:58"
+            "timeStamp": "2021-08-25 00:56:22"
         }
     ]
 }
\ No newline at end of file
diff --git a/gui/qml/BackgroundImage.qml b/gui/qml/BackgroundImage.qml
index 3071bf45..ba2a8af0 100644
--- a/gui/qml/BackgroundImage.qml
+++ b/gui/qml/BackgroundImage.qml
@@ -3,22 +3,22 @@ import QtQuick.Controls 2.4
 
 Rectangle {
 
-    anchors.fill: parent;
-    anchors.topMargin: 40;
+    anchors.fill: parent
+    anchors.topMargin: 40
 
     property var backgroundSrc
     property var backgroundVisible
 
     Image {
-        source: parent.backgroundSrc;
-        visible: parent.backgroundVisible;
-        fillMode: Image.PreserveAspectCrop;
-        anchors.fill: parent; 
-        opacity: 0.8;
+        source: parent.backgroundSrc
+        visible: parent.backgroundVisible
+        fillMode: Image.PreserveAspectCrop
+        anchors.fill: parent
+        opacity: 0.8
     }
 
     Component.onCompleted: {
         /* default for riseup, needs customizing */
-        backgroundSrc = "qrc:/assets/img/bird.jpg";
+        backgroundSrc = "qrc:/assets/img/bird.jpg"
     }
 }
diff --git a/gui/qml/BridgesItem.qml b/gui/qml/BridgesItem.qml
index 1343403a..f7ccb0f1 100644
--- a/gui/qml/BridgesItem.qml
+++ b/gui/qml/BridgesItem.qml
@@ -26,15 +26,15 @@ Item {
             anchors.horizontalCenter: parent.horizontalCenter
             onClicked: {
                 if (checked) {
-                    Logic.setNeedsReconnect(true);
-                    bridgeReconnect.visible = true;
-                    app.useBridges(true);
+                    Logic.setNeedsReconnect(true)
+                    bridgeReconnect.visible = true
+                    app.useBridges(true)
                 } else {
                     // This would also need a "needs reconnect" for de-selecting bridges the next time.
                     // better to wait and see the new connection widgets though
-                    Logic.setNeedsReconnect(false);
-                    bridgeReconnect.visible = false;
-                    app.useBridges(false);
+                    Logic.setNeedsReconnect(false)
+                    bridgeReconnect.visible = false
+                    app.useBridges(false)
                 }
             }
         }
@@ -45,7 +45,7 @@ Item {
             color: "grey"
             text: qsTr("Select a bridge only if you know that you need it to evade censorship in your country or local network.")
             anchors.horizontalCenter: parent.horizontalCenter
-            wrapMode: Text.WordWrap 
+            wrapMode: Text.WordWrap
             visible: !bridgeReconnect.visible
         }
 
@@ -56,7 +56,7 @@ Item {
             color: "red"
             text: qsTr("An obfs4 bridge will be used the next time you connect to the VPN.")
             anchors.horizontalCenter: parent.horizontalCenter
-            wrapMode: Text.WordWrap 
+            wrapMode: Text.WordWrap
             visible: false
         }
     }
diff --git a/gui/qml/VPNSwitch.qml b/gui/qml/VPNSwitch.qml
index 89c455f4..c58836e4 100644
--- a/gui/qml/VPNSwitch.qml
+++ b/gui/qml/VPNSwitch.qml
@@ -2,7 +2,6 @@ import QtQuick 2.9
 import QtQuick.Layouts 1.12
 import QtQuick.Controls 2.4
 
-
 SwitchDelegate {
 
     text: qsTr("")
diff --git a/gui/qml/VpnState.qml b/gui/qml/VpnState.qml
index a4bb7791..31910c74 100644
--- a/gui/qml/VpnState.qml
+++ b/gui/qml/VpnState.qml
@@ -14,7 +14,7 @@ StateGroup {
         State {
             name: "off"
             StateChangeScript {
-                script: Logic.setStatus("off");
+                script: Logic.setStatus("off")
             }
             PropertyChanges {
                 target: systray
@@ -47,16 +47,15 @@ StateGroup {
             name: "on"
             StateChangeScript {
                 script: {
-                    Logic.setNeedsReconnect(false);
-                    brReconnect = false;
+                    Logic.setNeedsReconnect(false)
+                    brReconnect = false
 
                     if (needsDonate && !shownDonate) {
-                        donate.visible = true;
-                        shownDonate = true;
-                        backend.donateSeen();
+                        donate.visible = true
+                        shownDonate = true
+                        backend.donateSeen()
                     }
                 }
-
             }
             PropertyChanges {
                 target: systray
diff --git a/gui/qml/main.qml b/gui/qml/main.qml
index fef68cf2..2c94c80f 100644
--- a/gui/qml/main.qml
+++ b/gui/qml/main.qml
@@ -1,9 +1,10 @@
 import QtQuick 2.9
-import QtQuick.Dialogs 1.2 // TODO use native dialogs in labs.platform
+import QtQuick.Dialogs 1.2
+// TODO use native dialogs in labs.platform
 import QtQuick.Layouts 1.12
 import QtQuick.Controls 2.4
 
-import Qt.labs.platform 1.0
+import Qt.labs.platform 1.0 as Labs
 
 import "logic.js" as Logic
 
@@ -24,7 +25,7 @@ ApplicationWindow {
     property var needsDonate
     property var shownDonate
 
-    onSceneGraphError: function(error, msg) {
+    onSceneGraphError: function (error, msg) {
         console.debug("ERROR while initializing scene")
         console.debug(msg)
     }
@@ -116,8 +117,8 @@ ApplicationWindow {
 
                 anchors.centerIn: parent
                 spacing: 10
-                //width: parent.width
 
+                //width: parent.width
                 RadioButton {
                     id: autoSelectionButton
                     checked: !isManualLocation()
@@ -161,6 +162,7 @@ ApplicationWindow {
                             color: {
                                 "#ffffff"
                                 // FIXME locations is not defined when we launch
+
                                 /*
                                 const fullness = ctx.locations[modelData]
                                 if (fullness >= 0 && fullness < 0.4) {
@@ -181,7 +183,6 @@ ApplicationWindow {
                             color: "#000000"
                         }
                     }
-
                 }
 
                 Text {
@@ -190,7 +191,7 @@ ApplicationWindow {
                     width: 180
                     font.pixelSize: 12
                     color: "green"
-                    wrapMode: Text.WordWrap 
+                    wrapMode: Text.WordWrap
                     text: qsTr("Reconnecting to the selected gateway…")
                     visible: false
                 }
@@ -201,31 +202,29 @@ ApplicationWindow {
                     width: 180
                     font.pixelSize: 12
                     color: "green"
-                    wrapMode: Text.WordWrap 
+                    wrapMode: Text.WordWrap
                     text: qsTr("This gateway will be used for next connection.")
                     visible: false
                 }
-
             } // end column
         } // end item
 
         BridgesItem {
             id: bridgesTab
         }
-
     } // end stacklayout
 
     Connections {
         target: jsonModel
         function onDataChanged() {
             ctx = JSON.parse(jsonModel.getJson())
+
             // TODO pass QML_DEBUG variable to be hyper-verbose
             //console.debug(jsonModel.getJson())
-
             gwSelector.model = Object.keys(ctx.locations)
 
             if (ctx.donateDialog == 'true') {
-                Logic.setNeedsDonate(true);
+                Logic.setNeedsDonate(true)
             }
             if (ctx.loginDialog == 'true') {
                 console.debug(jsonModel.getJson())
@@ -294,11 +293,11 @@ ApplicationWindow {
 
     function hasMultipleGateways() {
         // could also count the gateways
-        let provider = Logic.getSelectedProvider(providers);
+        let provider = Logic.getSelectedProvider(providers)
         if (provider == "riseup") {
-            return true;
+            return true
         } else {
-            return false;
+            return false
         }
     }
 
@@ -319,35 +318,34 @@ ApplicationWindow {
     }
 
     function showMainWindow() {
-            bar.currentIndex = 0
-            app.visible = true
-            app.show()
-            app.raise()
+        bar.currentIndex = 0
+        app.visible = true
+        app.show()
+        app.raise()
     }
 
     Component.onCompleted: {
         Logic.debugInit()
         loginDone = false
         allowEmptyPass = Logic.shouldAllowEmptyPass(providers)
-        needsRestart = false;
-        shownDonate = false;
+        needsRestart = false
+        shownDonate = false
 
         /* this is a temporary workaround until general GUI revamp for 0.21.8 */
-        let provider = Logic.getSelectedProvider(providers);
+        let provider = Logic.getSelectedProvider(providers)
         if (provider == "calyx") {
-            background.color = "#8EA844";
-            background.backgroundVisible = false;
-            gwSelector.visible = false;
-            manualSelectionButton.visible = false;
+            background.color = "#8EA844"
+            background.backgroundVisible = false
+            gwSelector.visible = false
+            manualSelectionButton.visible = false
         }
 
         if (!systrayAvailable) {
-          app.visible = true
-          app.raise()
+            app.visible = true
+            app.raise()
         }
     }
 
-
     property var icons: {
         "off": "qrc:/assets/icon/png/white/vpn_off.png",
         "on": "qrc:/assets/icon/png/white/vpn_on.png",
@@ -364,6 +362,7 @@ ApplicationWindow {
         id: systray
         visible: systrayVisible
 
+
         /* the systray menu cannot be buried in a child qml file because
          * otherwise the ids are not available
          * from other components
@@ -501,9 +500,8 @@ ApplicationWindow {
                 if (Qt.platform.os === "windows") {
                     let appname = ctx ? ctx.appName : "VPN"
                     Logic.showNotification(
-                        ctx,
-                        appname
-                        + " is up and running. Please use system tray icon to control it.")
+                                ctx, appname
+                                + " is up and running. Please use system tray icon to control it.")
                 }
             }
         }
@@ -560,13 +558,12 @@ ApplicationWindow {
     }
 
     function useBridges(value) {
-        if (value==true) {
+        if (value == true) {
             backend.setTransport("obfs4")
         } else {
             backend.setTransport("openvpn")
         }
     }
 
-    property alias brReconnect:bridgesTab.displayReconnect
-
+    property alias brReconnect: bridgesTab.displayReconnect
 }
diff --git a/gui/qml/readme.txt b/gui/qml/readme.txt
new file mode 100644
index 00000000..e7d468c7
--- /dev/null
+++ b/gui/qml/readme.txt
@@ -0,0 +1 @@
+This folder will be deprecated.
diff --git a/gui/resources/about.svg b/gui/resources/about.svg
new file mode 100644
index 00000000..9a47ce3e
--- /dev/null
+++ b/gui/resources/about.svg
@@ -0,0 +1,62 @@
+<?xml version="1.0" encoding="iso-8859-1"?>
+<!-- Generator: Adobe Illustrator 16.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0)  -->
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
+<svg version="1.1" id="Capa_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
+	 width="90.946px" height="90.945px" viewBox="0 0 90.946 90.945" style="enable-background:new 0 0 90.946 90.945;"
+	 xml:space="preserve">
+<g>
+	<g>
+		<polygon points="68.801,9.457 67.946,12.356 69.498,11.851 		"/>
+		<polygon points="46.716,25.955 47.535,28.557 48.722,27.438 		"/>
+		<path d="M79.788,35.755c-2.208,1.979-5.452,4.616-8.333,7.148c-0.317-4.402-1.093-8.953-1.093-12.952
+			c0.009-6.419,0.688-15.586-0.876-16.621l-1.574,0.004c-1.254,1.424-0.876,8.642-1.177,14.274
+			c-0.217,4.113-0.603,9.976-0.784,15.173c-2.353-1.979-4.863-3.852-6.821-5.812c-3.533-3.542-8.271-8.913-9.739-8.579L48.484,29.3
+			c0.062,1.509,4.896,5.131,7.826,8.408c2.861,3.194,6.629,8.42,9.923,11.714c0.232,0.23,0.511,0.374,0.803,0.46
+			c0.471,0.319,1.045,0.516,1.67,0.516c0.584,0,1.088-0.205,1.528-0.492c0.356-0.078,0.698-0.21,0.981-0.466
+			c3.325-3.013,5.982-7.323,9.005-10.343c3.541-3.532,9.07-8.318,8.739-9.787l-0.91-0.904
+			C86.543,28.471,83.063,32.829,79.788,35.755z"/>
+		<polygon points="68.361,55.795 70.085,51.603 67.378,51.762 		"/>
+		<polygon points="88.666,27.691 90.061,28.529 90.946,26.198 		"/>
+		<polygon points="22.144,35.151 21.449,37.545 23,38.05 		"/>
+		<polygon points="43.411,54.25 44.23,51.647 42.224,53.131 		"/>
+		<path d="M31.815,62.665c-1.958,1.96-4.471,3.835-6.823,5.812c-0.18-5.196-0.568-11.059-0.783-15.174
+			c-0.303-5.63,0.078-12.848-1.179-14.272l-1.572-0.005c-1.566,1.032-0.886,10.203-0.879,16.622c0.003,3.997-0.772,8.55-1.09,12.952
+			c-2.882-2.532-6.125-5.169-8.333-7.148c-3.272-2.927-6.755-7.286-8.262-7.35l-0.911,0.905c-0.332,1.469,5.202,6.255,8.739,9.788
+			c3.022,3.016,5.681,7.329,9.007,10.343c0.28,0.25,0.624,0.388,0.979,0.465c0.441,0.287,0.943,0.493,1.527,0.493
+			c0.626,0,1.201-0.196,1.671-0.516c0.294-0.087,0.573-0.23,0.803-0.461c3.296-3.294,7.063-8.518,9.925-11.714
+			c2.929-3.277,7.76-6.899,7.825-8.407l-0.907-0.91C40.084,53.753,35.348,59.125,31.815,62.665z"/>
+		<polygon points="22.585,81.488 23.568,77.456 20.86,77.296 		"/>
+		<polygon points="0,51.892 0.885,54.223 2.281,53.386 		"/>
+	</g>
+</g>
+<g>
+</g>
+<g>
+</g>
+<g>
+</g>
+<g>
+</g>
+<g>
+</g>
+<g>
+</g>
+<g>
+</g>
+<g>
+</g>
+<g>
+</g>
+<g>
+</g>
+<g>
+</g>
+<g>
+</g>
+<g>
+</g>
+<g>
+</g>
+<g>
+</g>
+</svg>
diff --git a/gui/resources/arrow-left.svg b/gui/resources/arrow-left.svg
new file mode 100644
index 00000000..9d885017
--- /dev/null
+++ b/gui/resources/arrow-left.svg
@@ -0,0 +1,3 @@
+<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-arrow-left" viewBox="0 0 16 16">
+  <path fill-rule="evenodd" d="M15 8a.5.5 0 0 0-.5-.5H2.707l3.147-3.146a.5.5 0 1 0-.708-.708l-4 4a.5.5 0 0 0 0 .708l4 4a.5.5 0 0 0 .708-.708L2.707 8.5H14.5A.5.5 0 0 0 15 8z"/>
+</svg>
\ No newline at end of file
diff --git a/gui/resources/birds.svg b/gui/resources/birds.svg
new file mode 100644
index 00000000..cb2a1df0
--- /dev/null
+++ b/gui/resources/birds.svg
@@ -0,0 +1 @@
+<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 174.92 102.4"><title>Asset 1</title><g id="Layer_2" data-name="Layer 2"><g id="Layer_1-2" data-name="Layer 1"><g id="C0eYCH.tif"><image id="Layer_1-3" data-name="Layer 1" width="277" height="129" transform="translate(12.45) rotate(9.34) scale(0.59)" xlink:href="data:image/png;base64,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"/></g></g></g></svg>
\ No newline at end of file
diff --git a/gui/resources/bridge.png b/gui/resources/bridge.png
new file mode 100644
index 0000000000000000000000000000000000000000..d0a2c80189a6a60166aef9d785bcbd6e144bd32b
GIT binary patch
literal 5543
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
Sg1doOBuQ9I=-%Mj>3;$X%Q1HV

literal 0
HcmV?d00001

diff --git a/gui/resources/close.svg b/gui/resources/close.svg
new file mode 100644
index 00000000..ead8e169
--- /dev/null
+++ b/gui/resources/close.svg
@@ -0,0 +1,3 @@
+<svg width="24px" height="24px" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
+<path d="M6.22566 4.81096C5.83514 4.42044 5.20197 4.42044 4.81145 4.81096C4.42092 5.20148 4.42092 5.83465 4.81145 6.22517L10.5862 11.9999L4.81151 17.7746C4.42098 18.1651 4.42098 18.7983 4.81151 19.1888C5.20203 19.5793 5.8352 19.5793 6.22572 19.1888L12.0004 13.4141L17.7751 19.1888C18.1656 19.5793 18.7988 19.5793 19.1893 19.1888C19.5798 18.7983 19.5798 18.1651 19.1893 17.7746L13.4146 11.9999L19.1893 6.22517C19.5799 5.83465 19.5799 5.20148 19.1893 4.81096C18.7988 4.42044 18.1657 4.42044 17.7751 4.81096L12.0004 10.5857L6.22566 4.81096Z" fill="black"/>
+</svg>
diff --git a/gui/resources/donate.svg b/gui/resources/donate.svg
new file mode 100644
index 00000000..35d7c2be
--- /dev/null
+++ b/gui/resources/donate.svg
@@ -0,0 +1,4 @@
+<?xml version="1.0" standalone="no"?>
+<svg width="1024px" height="1024px" viewBox="0 0 1024 1024" xmlns="http://www.w3.org/2000/svg" class="icon">
+  <path d="M880 310H732.4c13.6-21.4 21.6-46.8 21.6-74 0-76.1-61.9-138-138-138-41.4 0-78.7 18.4-104 47.4-25.3-29-62.6-47.4-104-47.4-76.1 0-138 61.9-138 138 0 27.2 7.9 52.6 21.6 74H144c-17.7 0-32 14.3-32 32v200c0 4.4 3.6 8 8 8h40v344c0 17.7 14.3 32 32 32h640c17.7 0 32-14.3 32-32V550h40c4.4 0 8-3.6 8-8V342c0-17.7-14.3-32-32-32zm-334-74c0-38.6 31.4-70 70-70s70 31.4 70 70-31.4 70-70 70h-70v-70zm-138-70c38.6 0 70 31.4 70 70v70h-70c-38.6 0-70-31.4-70-70s31.4-70 70-70zM180 482V378h298v104H180zm48 68h250v308H228V550zm568 308H546V550h250v308zm48-376H546V378h298v104z"/>
+</svg>
diff --git a/gui/resources/gear-fill.svg b/gui/resources/gear-fill.svg
new file mode 100644
index 00000000..2aa36a1d
--- /dev/null
+++ b/gui/resources/gear-fill.svg
@@ -0,0 +1,3 @@
+<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-gear-fill" viewBox="0 0 16 16">
+  <path d="M9.405 1.05c-.413-1.4-2.397-1.4-2.81 0l-.1.34a1.464 1.464 0 0 1-2.105.872l-.31-.17c-1.283-.698-2.686.705-1.987 1.987l.169.311c.446.82.023 1.841-.872 2.105l-.34.1c-1.4.413-1.4 2.397 0 2.81l.34.1a1.464 1.464 0 0 1 .872 2.105l-.17.31c-.698 1.283.705 2.686 1.987 1.987l.311-.169a1.464 1.464 0 0 1 2.105.872l.1.34c.413 1.4 2.397 1.4 2.81 0l.1-.34a1.464 1.464 0 0 1 2.105-.872l.31.17c1.283.698 2.686-.705 1.987-1.987l-.169-.311a1.464 1.464 0 0 1 .872-2.105l.34-.1c1.4-.413 1.4-2.397 0-2.81l-.34-.1a1.464 1.464 0 0 1-.872-2.105l.17-.31c.698-1.283-.705-2.686-1.987-1.987l-.311.169a1.464 1.464 0 0 1-2.105-.872l-.1-.34zM8 10.93a2.929 2.929 0 1 1 0-5.86 2.929 2.929 0 0 1 0 5.858z"/>
+</svg>
\ No newline at end of file
diff --git a/gui/resources/globe.svg b/gui/resources/globe.svg
new file mode 100644
index 00000000..150a01eb
--- /dev/null
+++ b/gui/resources/globe.svg
@@ -0,0 +1,3 @@
+<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-globe2" viewBox="0 0 16 16">
+  <path d="M0 8a8 8 0 1 1 16 0A8 8 0 0 1 0 8zm7.5-6.923c-.67.204-1.335.82-1.887 1.855-.143.268-.276.56-.395.872.705.157 1.472.257 2.282.287V1.077zM4.249 3.539c.142-.384.304-.744.481-1.078a6.7 6.7 0 0 1 .597-.933A7.01 7.01 0 0 0 3.051 3.05c.362.184.763.349 1.198.49zM3.509 7.5c.036-1.07.188-2.087.436-3.008a9.124 9.124 0 0 1-1.565-.667A6.964 6.964 0 0 0 1.018 7.5h2.49zm1.4-2.741a12.344 12.344 0 0 0-.4 2.741H7.5V5.091c-.91-.03-1.783-.145-2.591-.332zM8.5 5.09V7.5h2.99a12.342 12.342 0 0 0-.399-2.741c-.808.187-1.681.301-2.591.332zM4.51 8.5c.035.987.176 1.914.399 2.741A13.612 13.612 0 0 1 7.5 10.91V8.5H4.51zm3.99 0v2.409c.91.03 1.783.145 2.591.332.223-.827.364-1.754.4-2.741H8.5zm-3.282 3.696c.12.312.252.604.395.872.552 1.035 1.218 1.65 1.887 1.855V11.91c-.81.03-1.577.13-2.282.287zm.11 2.276a6.696 6.696 0 0 1-.598-.933 8.853 8.853 0 0 1-.481-1.079 8.38 8.38 0 0 0-1.198.49 7.01 7.01 0 0 0 2.276 1.522zm-1.383-2.964A13.36 13.36 0 0 1 3.508 8.5h-2.49a6.963 6.963 0 0 0 1.362 3.675c.47-.258.995-.482 1.565-.667zm6.728 2.964a7.009 7.009 0 0 0 2.275-1.521 8.376 8.376 0 0 0-1.197-.49 8.853 8.853 0 0 1-.481 1.078 6.688 6.688 0 0 1-.597.933zM8.5 11.909v3.014c.67-.204 1.335-.82 1.887-1.855.143-.268.276-.56.395-.872A12.63 12.63 0 0 0 8.5 11.91zm3.555-.401c.57.185 1.095.409 1.565.667A6.963 6.963 0 0 0 14.982 8.5h-2.49a13.36 13.36 0 0 1-.437 3.008zM14.982 7.5a6.963 6.963 0 0 0-1.362-3.675c-.47.258-.995.482-1.565.667.248.92.4 1.938.437 3.008h2.49zM11.27 2.461c.177.334.339.694.482 1.078a8.368 8.368 0 0 0 1.196-.49 7.01 7.01 0 0 0-2.275-1.52c.218.283.418.597.597.932zm-.488 1.343a7.765 7.765 0 0 0-.395-.872C9.835 1.897 9.17 1.282 8.5 1.077V4.09c.81-.03 1.577-.13 2.282-.287z"/>
+</svg>
\ No newline at end of file
diff --git a/gui/resources/help.svg b/gui/resources/help.svg
new file mode 100644
index 00000000..06569c87
--- /dev/null
+++ b/gui/resources/help.svg
@@ -0,0 +1,4 @@
+<?xml version="1.0" standalone="no"?>
+<svg width="1024px" height="1024px" viewBox="0 0 1024 1024" xmlns="http://www.w3.org/2000/svg" class="icon">
+  <path d="M824.2 699.9a301.55 301.55 0 0 0-86.4-60.4C783.1 602.8 812 546.8 812 484c0-110.8-92.4-201.7-203.2-200-109.1 1.7-197 90.6-197 200 0 62.8 29 118.8 74.2 155.5a300.95 300.95 0 0 0-86.4 60.4C345 754.6 314 826.8 312 903.8a8 8 0 0 0 8 8.2h56c4.3 0 7.9-3.4 8-7.7 1.9-58 25.4-112.3 66.7-153.5A226.62 226.62 0 0 1 612 684c60.9 0 118.2 23.7 161.3 66.8C814.5 792 838 846.3 840 904.3c.1 4.3 3.7 7.7 8 7.7h56a8 8 0 0 0 8-8.2c-2-77-33-149.2-87.8-203.9zM612 612c-34.2 0-66.4-13.3-90.5-37.5a126.86 126.86 0 0 1-37.5-91.8c.3-32.8 13.4-64.5 36.3-88 24-24.6 56.1-38.3 90.4-38.7 33.9-.3 66.8 12.9 91 36.6 24.8 24.3 38.4 56.8 38.4 91.4 0 34.2-13.3 66.3-37.5 90.5A127.3 127.3 0 0 1 612 612zM361.5 510.4c-.9-8.7-1.4-17.5-1.4-26.4 0-15.9 1.5-31.4 4.3-46.5.7-3.6-1.2-7.3-4.5-8.8-13.6-6.1-26.1-14.5-36.9-25.1a127.54 127.54 0 0 1-38.7-95.4c.9-32.1 13.8-62.6 36.3-85.6 24.7-25.3 57.9-39.1 93.2-38.7 31.9.3 62.7 12.6 86 34.4 7.9 7.4 14.7 15.6 20.4 24.4 2 3.1 5.9 4.4 9.3 3.2 17.6-6.1 36.2-10.4 55.3-12.4 5.6-.6 8.8-6.6 6.3-11.6-32.5-64.3-98.9-108.7-175.7-109.9-110.9-1.7-203.3 89.2-203.3 199.9 0 62.8 28.9 118.8 74.2 155.5-31.8 14.7-61.1 35-86.5 60.4-54.8 54.7-85.8 126.9-87.8 204a8 8 0 0 0 8 8.2h56.1c4.3 0 7.9-3.4 8-7.7 1.9-58 25.4-112.3 66.7-153.5 29.4-29.4 65.4-49.8 104.7-59.7 3.9-1 6.5-4.7 6-8.7z"/>
+</svg>
diff --git a/gui/resources/icon-noshield.svg b/gui/resources/icon-noshield.svg
new file mode 100644
index 00000000..815a0d61
--- /dev/null
+++ b/gui/resources/icon-noshield.svg
@@ -0,0 +1,68 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<svg
+   xmlns:dc="http://purl.org/dc/elements/1.1/"
+   xmlns:cc="http://creativecommons.org/ns#"
+   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+   xmlns:svg="http://www.w3.org/2000/svg"
+   xmlns="http://www.w3.org/2000/svg"
+   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+   width="128"
+   height="128"
+   viewBox="0 0 33.866666 33.866668"
+   version="1.1"
+   id="svg896"
+   inkscape:version="1.0.2 (e86c870879, 2021-01-15)"
+   sodipodi:docname="icon-noshield.svg">
+  <defs
+     id="defs890" />
+  <sodipodi:namedview
+     id="base"
+     pagecolor="#d7d7d7"
+     bordercolor="#666666"
+     borderopacity="1.0"
+     inkscape:pageopacity="0"
+     inkscape:pageshadow="2"
+     inkscape:zoom="3.3834377"
+     inkscape:cx="-34.426658"
+     inkscape:cy="43.45762"
+     inkscape:document-units="px"
+     inkscape:current-layer="layer1"
+     showgrid="true"
+     units="px"
+     inkscape:window-width="1920"
+     inkscape:window-height="1032"
+     inkscape:window-x="0"
+     inkscape:window-y="25"
+     inkscape:window-maximized="1"
+     inkscape:document-rotation="0">
+    <inkscape:grid
+       type="xygrid"
+       id="grid1471"
+       empspacing="4" />
+  </sodipodi:namedview>
+  <metadata
+     id="metadata893">
+    <rdf:RDF>
+      <cc:Work
+         rdf:about="">
+        <dc:format>image/svg+xml</dc:format>
+        <dc:type
+           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+        <dc:title></dc:title>
+      </cc:Work>
+    </rdf:RDF>
+  </metadata>
+  <g
+     inkscape:label="Layer 1"
+     inkscape:groupmode="layer"
+     id="layer1"
+     transform="translate(0,-263.13332)">
+    <path
+       style="fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.264583"
+       d="m 17.51831,273.60678 c 0,0 -0.315707,-0.61165 -0.336761,-0.69601 -0.02106,-0.0844 -0.189431,-0.94909 -0.189431,-0.94909 l 0.210485,-0.37963 0.463046,-0.696 0.673531,-0.52727 0.168377,-0.0633 1.620684,-0.61164 0.147331,-0.14764 -0.168385,-0.25308 -0.231523,-0.12655 -0.424879,-0.10907 -1.064407,-0.10907 -0.825967,0.007 -0.568293,0.12654 -0.505146,-0.18981 -0.63143,-0.0844 -0.9261,-0.0211 -0.463054,-0.0211 -0.778761,0.29527 -1.178677,1.37091 -0.147339,0.52727 -0.08418,0.464 -0.399908,0.86473 -0.252577,0.82254 -0.126285,0.88582 v 0.18982 l -0.610384,0.92799 -0.336761,0.69601 v 0.99126 l 0.10523,2.04581 0.189431,0.73821 0.378861,0.6749 0.4841,0.44292 0.210477,0.8647 0.799815,1.77155 0.947154,1.13886 0.06311,0.0633 0.336761,1.70835 -1.157623,2.10911 -0.363408,0.28169 -0.272426,0.22054 -0.467179,-0.0129 -0.260603,0.13452 -0.316122,0.0134 -0.190994,0.19047 -0.408963,-0.0616 -0.404409,-0.0196 -0.3119827,0.24606 -0.04492,0.36556 0.2073657,-0.23472 0.348864,-0.10158 0.03654,0.33552 0.551268,-0.18726 0.316122,-0.0134 0.557721,0.0667 c 0,0 0.483518,-0.0316 0.567216,-0.0407 0.0837,-0.009 0.597276,0.0411 0.597276,0.0411 l 0.376644,-0.041 0.199723,0.0844 0.267456,-0.0716 0.290265,0.13818 0.418488,-0.0455 0.05401,-0.28169 -0.01596,-0.14678 0.28571,0.0962 0.232049,0.18692 0.150642,0.21701 -0.0088,-0.27495 -0.182953,-0.31946 c 0,0 -0.125159,-0.17737 -0.208857,-0.16824 -0.0837,0.009 -0.408971,-0.0616 -0.408971,-0.0616 l -0.223321,0.088 -0.243857,-0.10085 -0.239677,0.13226 -0.220665,-0.0822 -0.106491,-0.20049 -0.153322,-0.0471 0.164763,-0.42962 0.378861,-0.52859 0.505146,-0.84364 0.442,-0.5273 0.168385,-0.21088 c 0,0 0.210477,-0.31633 0.210477,-0.40071 0,-0.0844 0.04212,-0.97016 0.04212,-0.97016 l -0.273623,-0.56947 -0.126285,-0.46402 2.441546,0.59059 h 0.147331 l 2.083731,1.49744 0.294669,0.37959 0.10523,1.49729 -0.04212,0.33746 -0.147338,0.27419 -0.105358,0.16875 -0.09101,0.23675 -0.06215,0.1583 -0.386712,0.11988 -0.393086,-0.0709 -0.238209,-0.0294 -0.437428,0.0633 -0.184118,0.19713 -0.07084,0.24475 0.05712,0.24744 0.09172,-0.24769 0.124641,-0.16724 0.121984,-0.0388 0.0094,0.21174 0.163957,0.10406 0.338995,-0.15563 0.166646,-0.0242 0.05409,0.22658 0.508999,-0.01 0.345035,-0.11394 0.282886,0.0443 0.410893,0.047 0.142823,-0.0417 0.112881,-0.10156 0.182442,0.37841 0.0024,-0.42654 -0.176722,-0.48581 -0.256358,-0.15463 0.04324,-0.12712 -0.189423,-0.35849 0.02106,-1.37079 1.052392,1.2444 1.389154,1.09674 c 0,0 0.947146,0.33749 1.03133,0.33749 0.08419,0 0.736677,-0.0844 0.736677,-0.0844 l 0.420954,-0.69598 -0.315715,-0.94908 0.126284,-0.31642 -0.673531,-0.88574 -1.426794,-1.45279 -0.341213,-1.14141 0.02106,-0.78037 -0.315707,-0.82257 -0.357816,-0.65376 0.210477,-0.65377 -0.168377,-0.94904 -0.717785,-1.61568 0.265151,-0.0448 -0.444984,-0.77034 0.289101,-0.0918 -0.508218,-0.82847 0.213764,-0.11524 -0.380944,-0.62543 0.124202,-0.0696 -0.460971,-0.37337 0.168384,-0.0875 -1.199723,-0.84051 z"
+       id="path5892"
+       inkscape:connector-curvature="0"
+       sodipodi:nodetypes="csccccccccccccccccccccccccccccccccccccccccccccccccccccccscccccccccccccsccccccccccccscccccccccccccccccccccccccccccccccccccccccccscccccccccccccccccccccccc" />
+  </g>
+</svg>
diff --git a/gui/resources/location.svg b/gui/resources/location.svg
new file mode 100644
index 00000000..f738eb65
--- /dev/null
+++ b/gui/resources/location.svg
@@ -0,0 +1,58 @@
+<?xml version="1.0" encoding="iso-8859-1"?>
+<!-- Generator: Adobe Illustrator 16.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0)  -->
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
+<svg version="1.1" id="Capa_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
+	 width="31.603px" height="31.603px" viewBox="0 0 31.603 31.603" style="enable-background:new 0 0 31.603 31.603;"
+	 xml:space="preserve">
+<g>
+	<g>
+		<path d="M7.703,15.973c0,0,5.651-5.625,5.651-10.321C13.354,2.53,10.824,0,7.703,0S2.052,2.53,2.052,5.652
+			C2.052,10.614,7.703,15.973,7.703,15.973z M4.758,5.652c0-1.628,1.319-2.946,2.945-2.946s2.945,1.318,2.945,2.946
+			c0,1.626-1.319,2.944-2.945,2.944S4.758,7.278,4.758,5.652z"/>
+		<path d="M28.59,7.643l-0.459,0.146l-2.455,0.219l-0.692,1.106l-0.501-0.16l-1.953-1.76l-0.285-0.915l-0.377-0.977L20.639,4.2
+			l-1.446-0.283L19.159,4.58l1.418,1.384l0.694,0.817l-0.782,0.408l-0.636-0.188l-0.951-0.396l0.033-0.769l-1.25-0.514L17.27,7.126
+			l-1.258,0.286l0.125,1.007l1.638,0.316l0.284-1.609l1.353,0.201l0.629,0.368h1.011l0.69,1.384l1.833,1.859l-0.134,0.723
+			l-1.478-0.189l-2.553,1.289l-1.838,2.205l-0.239,0.976h-0.661l-1.229-0.566l-1.194,0.566l0.297,1.261l0.52-0.602l0.913-0.027
+			l-0.064,1.132l0.757,0.22l0.756,0.85l1.234-0.347l1.41,0.222l1.636,0.441l0.819,0.095l1.384,1.573l2.675,1.574l-1.729,3.306
+			l-1.826,0.849l-0.693,1.889l-2.643,1.765l-0.282,1.019c6.753-1.627,11.779-7.693,11.779-14.95
+			C31.194,13.038,30.234,10.09,28.59,7.643z"/>
+		<path d="M17.573,24.253l-1.12-2.078l1.028-2.146l-1.028-0.311l-1.156-1.159l-2.56-0.573l-0.85-1.779v1.057h-0.375l-1.625-2.203
+			c-0.793,0.949-1.395,1.555-1.47,1.629L7.72,17.384l-0.713-0.677c-0.183-0.176-3.458-3.315-5.077-7.13
+			c-0.966,2.009-1.52,4.252-1.52,6.63c0,8.502,6.891,15.396,15.393,15.396c0.654,0,1.296-0.057,1.931-0.135l-0.161-1.864
+			c0,0,0.707-2.77,0.707-2.863C18.28,26.646,17.573,24.253,17.573,24.253z"/>
+		<path d="M14.586,3.768l1.133,0.187l2.75-0.258l0.756-0.834l1.068-0.714l1.512,0.228l0.551-0.083
+			c-1.991-0.937-4.207-1.479-6.553-1.479c-1.096,0-2.16,0.128-3.191,0.345c0.801,0.875,1.377,1.958,1.622,3.163L14.586,3.768z
+			 M16.453,2.343l1.573-0.865l1.009,0.582l-1.462,1.113l-1.394,0.141L15.55,2.907L16.453,2.343z"/>
+	</g>
+</g>
+<g>
+</g>
+<g>
+</g>
+<g>
+</g>
+<g>
+</g>
+<g>
+</g>
+<g>
+</g>
+<g>
+</g>
+<g>
+</g>
+<g>
+</g>
+<g>
+</g>
+<g>
+</g>
+<g>
+</g>
+<g>
+</g>
+<g>
+</g>
+<g>
+</g>
+</svg>
diff --git a/gui/resources/power.svg b/gui/resources/power.svg
new file mode 100644
index 00000000..158bc3c9
--- /dev/null
+++ b/gui/resources/power.svg
@@ -0,0 +1,10 @@
+<?xml version='1.0' encoding='utf-8'?>
+<!DOCTYPE svg PUBLIC '-//W3C//DTD SVG 1.1//EN' 'http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd'>
+<svg version="1.1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" xmlns:xlink="http://www.w3.org/1999/xlink" enable-background="new 0 0 512 512">
+  <g>
+    <g>
+      <path d="m256,501c-120.6,0-218.7-98.1-218.7-218.7 0-91.6 57.9-174.1 144.2-205.4 10.6-3.9 22.3,1.6 26.2,12.2 3.8,10.6-1.6,22.3-12.2,26.2-70.1,25.5-117.3,92.6-117.3,167 0,98.1 79.8,177.8 177.8,177.8 98.1,0 177.8-79.8 177.8-177.8 0-74.4-47.1-141.6-117.3-167-10.6-3.8-16.1-15.6-12.2-26.2 3.8-10.6 15.6-16.1 26.2-12.2 86.2,31.3 144.2,113.8 144.2,205.4 0,120.6-98.1,218.7-218.7,218.7z"/>
+      <path d="m256,308.8c-11.3,0-20.4-9.1-20.4-20.4v-257c0-11.3 9.1-20.4 20.4-20.4 11.3,0 20.4,9.1 20.4,20.4v256.9c0,11.3-9.1,20.5-20.4,20.5z"/>
+    </g>
+  </g>
+</svg>
diff --git a/gui/resources/quit.svg b/gui/resources/quit.svg
new file mode 100644
index 00000000..2fbd5201
--- /dev/null
+++ b/gui/resources/quit.svg
@@ -0,0 +1,4 @@
+<?xml version="1.0" standalone="no"?>
+<svg width="1024px" height="1024px" viewBox="0 0 1024 1024" xmlns="http://www.w3.org/2000/svg" class="icon">
+  <path d="M705.6 124.9a8 8 0 0 0-11.6 7.2v64.2c0 5.5 2.9 10.6 7.5 13.6a352.2 352.2 0 0 1 62.2 49.8c32.7 32.8 58.4 70.9 76.3 113.3a355 355 0 0 1 27.9 138.7c0 48.1-9.4 94.8-27.9 138.7a355.92 355.92 0 0 1-76.3 113.3 353.06 353.06 0 0 1-113.2 76.4c-43.8 18.6-90.5 28-138.5 28s-94.7-9.4-138.5-28a353.06 353.06 0 0 1-113.2-76.4A355.92 355.92 0 0 1 184 650.4a355 355 0 0 1-27.9-138.7c0-48.1 9.4-94.8 27.9-138.7 17.9-42.4 43.6-80.5 76.3-113.3 19-19 39.8-35.6 62.2-49.8 4.7-2.9 7.5-8.1 7.5-13.6V132c0-6-6.3-9.8-11.6-7.2C178.5 195.2 82 339.3 80 506.3 77.2 745.1 272.5 943.5 511.2 944c239 .5 432.8-193.3 432.8-432.4 0-169.2-97-315.7-238.4-386.7zM480 560h64c4.4 0 8-3.6 8-8V88c0-4.4-3.6-8-8-8h-64c-4.4 0-8 3.6-8 8v464c0 4.4 3.6 8 8 8z"/>
+</svg>
diff --git a/gui/resources/reception-0.svg b/gui/resources/reception-0.svg
new file mode 100644
index 00000000..885bf3bb
--- /dev/null
+++ b/gui/resources/reception-0.svg
@@ -0,0 +1,3 @@
+<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-reception-0" viewBox="0 0 16 16">
+  <path d="M0 13.5a.5.5 0 0 1 .5-.5h2a.5.5 0 0 1 0 1h-2a.5.5 0 0 1-.5-.5zm4 0a.5.5 0 0 1 .5-.5h2a.5.5 0 0 1 0 1h-2a.5.5 0 0 1-.5-.5zm4 0a.5.5 0 0 1 .5-.5h2a.5.5 0 0 1 0 1h-2a.5.5 0 0 1-.5-.5zm4 0a.5.5 0 0 1 .5-.5h2a.5.5 0 0 1 0 1h-2a.5.5 0 0 1-.5-.5z"/>
+</svg>
\ No newline at end of file
diff --git a/gui/resources/reception-2.svg b/gui/resources/reception-2.svg
new file mode 100644
index 00000000..7dca57ac
--- /dev/null
+++ b/gui/resources/reception-2.svg
@@ -0,0 +1,3 @@
+<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-reception-2" viewBox="0 0 16 16">
+  <path d="M0 11.5a.5.5 0 0 1 .5-.5h2a.5.5 0 0 1 .5.5v2a.5.5 0 0 1-.5.5h-2a.5.5 0 0 1-.5-.5v-2zm4-3a.5.5 0 0 1 .5-.5h2a.5.5 0 0 1 .5.5v5a.5.5 0 0 1-.5.5h-2a.5.5 0 0 1-.5-.5v-5zm4 5a.5.5 0 0 1 .5-.5h2a.5.5 0 0 1 0 1h-2a.5.5 0 0 1-.5-.5zm4 0a.5.5 0 0 1 .5-.5h2a.5.5 0 0 1 0 1h-2a.5.5 0 0 1-.5-.5z"/>
+</svg>
\ No newline at end of file
diff --git a/gui/resources/reception-4.svg b/gui/resources/reception-4.svg
new file mode 100644
index 00000000..611bdf1b
--- /dev/null
+++ b/gui/resources/reception-4.svg
@@ -0,0 +1,3 @@
+<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-reception-4" viewBox="0 0 16 16">
+  <path d="M0 11.5a.5.5 0 0 1 .5-.5h2a.5.5 0 0 1 .5.5v2a.5.5 0 0 1-.5.5h-2a.5.5 0 0 1-.5-.5v-2zm4-3a.5.5 0 0 1 .5-.5h2a.5.5 0 0 1 .5.5v5a.5.5 0 0 1-.5.5h-2a.5.5 0 0 1-.5-.5v-5zm4-3a.5.5 0 0 1 .5-.5h2a.5.5 0 0 1 .5.5v8a.5.5 0 0 1-.5.5h-2a.5.5 0 0 1-.5-.5v-8zm4-3a.5.5 0 0 1 .5-.5h2a.5.5 0 0 1 .5.5v11a.5.5 0 0 1-.5.5h-2a.5.5 0 0 1-.5-.5v-11z"/>
+</svg>
\ No newline at end of file
diff --git a/gui/resources/riseup-icon.svg b/gui/resources/riseup-icon.svg
new file mode 100644
index 00000000..a19c6c61
--- /dev/null
+++ b/gui/resources/riseup-icon.svg
@@ -0,0 +1,80 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg
+   xmlns:dc="http://purl.org/dc/elements/1.1/"
+   xmlns:cc="http://creativecommons.org/ns#"
+   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+   xmlns:svg="http://www.w3.org/2000/svg"
+   xmlns="http://www.w3.org/2000/svg"
+   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+   width="128"
+   height="128"
+   viewBox="0 0 33.866666 33.866668"
+   version="1.1"
+   id="svg896"
+   inkscape:version="0.92.2 (5c3e80d, 2017-08-06)"
+   sodipodi:docname="riseupvpn-launcher.svg">
+  <defs
+     id="defs890" />
+  <sodipodi:namedview
+     id="base"
+     pagecolor="#d7d7d7"
+     bordercolor="#666666"
+     borderopacity="1.0"
+     inkscape:pageopacity="0"
+     inkscape:pageshadow="2"
+     inkscape:zoom="5.12"
+     inkscape:cx="26.899914"
+     inkscape:cy="56.22909"
+     inkscape:document-units="px"
+     inkscape:current-layer="layer1"
+     showgrid="true"
+     units="px"
+     inkscape:window-width="1869"
+     inkscape:window-height="1025"
+     inkscape:window-x="51"
+     inkscape:window-y="27"
+     inkscape:window-maximized="1">
+    <inkscape:grid
+       type="xygrid"
+       id="grid1471"
+       empspacing="4" />
+  </sodipodi:namedview>
+  <metadata
+     id="metadata893">
+    <rdf:RDF>
+      <cc:Work
+         rdf:about="">
+        <dc:format>image/svg+xml</dc:format>
+        <dc:type
+           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+        <dc:title></dc:title>
+      </cc:Work>
+    </rdf:RDF>
+  </metadata>
+  <g
+     inkscape:label="Layer 1"
+     inkscape:groupmode="layer"
+     id="layer1"
+     transform="translate(0,-263.13332)">
+    <path
+       style="fill:#006cb2;fill-opacity:1;stroke-width:0.26458335"
+       d="M 15.617988,295.66418 C 9.9401302,292.50672 5.6959906,287.52131 4.7342129,282.87951 4.4622971,281.56718 4.4516145,281.24899 4.4519256,274.47112 l 2.394e-4,-6.47461 0.5616386,-0.36177 c 2.3734615,-1.52883 4.8841786,-2.55103 7.4419094,-3.06699 5.221864,-1.05337 10.639669,0.003 15.485448,3.16684 l 0.398232,0.25998 v 6.50684 c 0,6.8044 -0.01093,7.13134 -0.280843,8.43104 -0.956329,4.6043 -4.632206,9.09553 -10.057782,12.28874 -1.576255,0.9277 -1.527525,0.91863 -2.382844,0.44299 z"
+       id="path5137"
+       inkscape:connector-curvature="0"
+       sodipodi:nodetypes="csccssscssscc" />
+    <path
+       inkscape:connector-curvature="0"
+       style="fill:#007cc3;fill-opacity:1;stroke-width:0.26458335"
+       d="m 16.396917,264.17336 c -1.317958,-4.7e-4 -2.635612,0.13103 -3.941076,0.39437 -2.5577318,0.51596 -5.068528,1.53812 -7.4419895,3.06696 l -0.5615828,0.36177 -4.707e-4,6.47466 c -2.394e-4,6.77787 0.010371,7.096 0.2822554,8.40832 0.9617776,4.64181 5.2059168,9.62724 10.8837756,12.7847 h 1.19e-4 c 0.368953,0.20517 0.569745,0.32326 0.805249,0.31706 v -31.80747 c -0.0088,-2e-5 -0.01755,-4.8e-4 -0.02641,-4.8e-4 z"
+       id="path887" />
+    <path
+       style="fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.26458338"
+       d="m 16.989143,272.54844 c 0,0 -0.315707,-0.61165 -0.336761,-0.69601 -0.02106,-0.0844 -0.189431,-0.94909 -0.189431,-0.94909 l 0.210485,-0.37963 0.463046,-0.696 0.673531,-0.52727 0.168377,-0.0633 1.620684,-0.61164 0.147331,-0.14764 -0.168385,-0.25308 -0.231523,-0.12655 -0.424879,-0.10907 -1.064407,-0.10907 -0.825967,0.007 -0.568293,0.12654 -0.505146,-0.18981 -0.63143,-0.0844 -0.9261,-0.0211 -0.463054,-0.0211 -0.778761,0.29527 -1.178677,1.37091 -0.147339,0.52727 -0.08418,0.464 -0.399908,0.86473 -0.252577,0.82254 -0.126285,0.88582 v 0.18982 l -0.610384,0.92799 -0.336761,0.69601 v 0.99126 l 0.10523,2.04581 0.189431,0.73821 0.378861,0.6749 0.4841,0.44292 0.210477,0.8647 0.799815,1.77155 0.947154,1.13886 0.06311,0.0633 0.336761,1.70835 -1.157623,2.10911 -0.363408,0.28169 -0.272426,0.22054 -0.467179,-0.0129 -0.260603,0.13452 -0.316122,0.0134 -0.190994,0.19047 -0.408963,-0.0616 -0.4044091,-0.0196 -0.311982,0.24606 -0.044916,0.36556 0.207365,-0.23472 0.3488649,-0.10158 0.03654,0.33552 0.5512672,-0.18726 0.316122,-0.0134 0.557721,0.0667 c 0,0 0.483518,-0.0316 0.567216,-0.0407 0.0837,-0.009 0.597276,0.0411 0.597276,0.0411 l 0.376644,-0.041 0.199723,0.0844 0.267456,-0.0716 0.290265,0.13818 0.418488,-0.0455 0.05401,-0.28169 -0.01596,-0.14678 0.28571,0.0962 0.232049,0.18692 0.150642,0.21701 -0.0088,-0.27495 -0.182953,-0.31946 c 0,0 -0.125159,-0.17737 -0.208857,-0.16824 -0.0837,0.009 -0.408971,-0.0616 -0.408971,-0.0616 l -0.223321,0.088 -0.243857,-0.10085 -0.239677,0.13226 -0.220665,-0.0822 -0.106491,-0.20049 -0.153322,-0.0471 0.164763,-0.42962 0.378861,-0.52859 0.505146,-0.84364 0.442,-0.5273 0.168385,-0.21088 c 0,0 0.210477,-0.31633 0.210477,-0.40071 0,-0.0844 0.04212,-0.97016 0.04212,-0.97016 l -0.273623,-0.56947 -0.126285,-0.46402 2.441546,0.59059 h 0.147331 l 2.083731,1.49744 0.294669,0.37959 0.10523,1.49729 -0.04212,0.33746 -0.147338,0.27419 -0.105358,0.16875 -0.09101,0.23675 -0.06215,0.1583 -0.386712,0.11988 -0.393086,-0.0709 -0.238209,-0.0294 -0.437428,0.0633 -0.184118,0.19713 -0.07084,0.24475 0.05712,0.24744 0.09172,-0.24769 0.124641,-0.16724 0.121984,-0.0388 0.0094,0.21174 0.163957,0.10406 0.338995,-0.15563 0.166646,-0.0242 0.05409,0.22658 0.508999,-0.01 0.345035,-0.11394 0.282886,0.0443 0.410893,0.047 0.142823,-0.0417 0.112881,-0.10156 0.182442,0.37841 0.0024,-0.42654 -0.176722,-0.48581 -0.256358,-0.15463 0.04324,-0.12712 -0.189423,-0.35849 0.02106,-1.37079 1.052392,1.2444 1.389154,1.09674 c 0,0 0.947146,0.33749 1.03133,0.33749 0.08419,0 0.736677,-0.0844 0.736677,-0.0844 l 0.420954,-0.69598 -0.315715,-0.94908 0.126284,-0.31642 -0.673531,-0.88574 -1.426794,-1.45279 -0.341213,-1.14141 0.02106,-0.78037 -0.315707,-0.82257 -0.357816,-0.65376 0.210477,-0.65377 -0.168377,-0.94904 -0.717785,-1.61568 0.265151,-0.0448 -0.444984,-0.77034 0.289101,-0.0918 -0.508218,-0.82847 0.213764,-0.11524 -0.380944,-0.62543 0.124202,-0.0696 -0.460971,-0.37337 0.168384,-0.0875 -1.199723,-0.84051 z"
+       id="path5892"
+       inkscape:connector-curvature="0"
+       sodipodi:nodetypes="csccccccccccccccccccccccccccccccccccccccccccccccccccccccscccccccccccccsccccccccccccscccccccccccccccccccccccccccccccccccccccccccscccccccccccccccccccccccc" />
+  </g>
+</svg>
diff --git a/gui/resources/riseup-logo.png b/gui/resources/riseup-logo.png
new file mode 100644
index 0000000000000000000000000000000000000000..e68cfe2cdc341fdb24013b7a9d3e3a17c105bc5f
GIT binary patch
literal 4943
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
R_wQd^7ACgFjfOr+{{#0Q)r<fD

literal 0
HcmV?d00001

diff --git a/gui/resources/settings.svg b/gui/resources/settings.svg
new file mode 100644
index 00000000..0469ed45
--- /dev/null
+++ b/gui/resources/settings.svg
@@ -0,0 +1,62 @@
+<?xml version="1.0" encoding="iso-8859-1"?>
+<!-- Generator: Adobe Illustrator 19.1.0, SVG Export Plug-In . SVG Version: 6.00 Build 0)  -->
+<svg version="1.1" id="Capa_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
+	 viewBox="0 0 478.703 478.703" style="enable-background:new 0 0 478.703 478.703;" xml:space="preserve">
+<g>
+	<g>
+		<path d="M454.2,189.101l-33.6-5.7c-3.5-11.3-8-22.2-13.5-32.6l19.8-27.7c8.4-11.8,7.1-27.9-3.2-38.1l-29.8-29.8
+			c-5.6-5.6-13-8.7-20.9-8.7c-6.2,0-12.1,1.9-17.1,5.5l-27.8,19.8c-10.8-5.7-22.1-10.4-33.8-13.9l-5.6-33.2
+			c-2.4-14.3-14.7-24.7-29.2-24.7h-42.1c-14.5,0-26.8,10.4-29.2,24.7l-5.8,34c-11.2,3.5-22.1,8.1-32.5,13.7l-27.5-19.8
+			c-5-3.6-11-5.5-17.2-5.5c-7.9,0-15.4,3.1-20.9,8.7l-29.9,29.8c-10.2,10.2-11.6,26.3-3.2,38.1l20,28.1
+			c-5.5,10.5-9.9,21.4-13.3,32.7l-33.2,5.6c-14.3,2.4-24.7,14.7-24.7,29.2v42.1c0,14.5,10.4,26.8,24.7,29.2l34,5.8
+			c3.5,11.2,8.1,22.1,13.7,32.5l-19.7,27.4c-8.4,11.8-7.1,27.9,3.2,38.1l29.8,29.8c5.6,5.6,13,8.7,20.9,8.7c6.2,0,12.1-1.9,17.1-5.5
+			l28.1-20c10.1,5.3,20.7,9.6,31.6,13l5.6,33.6c2.4,14.3,14.7,24.7,29.2,24.7h42.2c14.5,0,26.8-10.4,29.2-24.7l5.7-33.6
+			c11.3-3.5,22.2-8,32.6-13.5l27.7,19.8c5,3.6,11,5.5,17.2,5.5l0,0c7.9,0,15.3-3.1,20.9-8.7l29.8-29.8c10.2-10.2,11.6-26.3,3.2-38.1
+			l-19.8-27.8c5.5-10.5,10.1-21.4,13.5-32.6l33.6-5.6c14.3-2.4,24.7-14.7,24.7-29.2v-42.1
+			C478.9,203.801,468.5,191.501,454.2,189.101z M451.9,260.401c0,1.3-0.9,2.4-2.2,2.6l-42,7c-5.3,0.9-9.5,4.8-10.8,9.9
+			c-3.8,14.7-9.6,28.8-17.4,41.9c-2.7,4.6-2.5,10.3,0.6,14.7l24.7,34.8c0.7,1,0.6,2.5-0.3,3.4l-29.8,29.8c-0.7,0.7-1.4,0.8-1.9,0.8
+			c-0.6,0-1.1-0.2-1.5-0.5l-34.7-24.7c-4.3-3.1-10.1-3.3-14.7-0.6c-13.1,7.8-27.2,13.6-41.9,17.4c-5.2,1.3-9.1,5.6-9.9,10.8l-7.1,42
+			c-0.2,1.3-1.3,2.2-2.6,2.2h-42.1c-1.3,0-2.4-0.9-2.6-2.2l-7-42c-0.9-5.3-4.8-9.5-9.9-10.8c-14.3-3.7-28.1-9.4-41-16.8
+			c-2.1-1.2-4.5-1.8-6.8-1.8c-2.7,0-5.5,0.8-7.8,2.5l-35,24.9c-0.5,0.3-1,0.5-1.5,0.5c-0.4,0-1.2-0.1-1.9-0.8l-29.8-29.8
+			c-0.9-0.9-1-2.3-0.3-3.4l24.6-34.5c3.1-4.4,3.3-10.2,0.6-14.8c-7.8-13-13.8-27.1-17.6-41.8c-1.4-5.1-5.6-9-10.8-9.9l-42.3-7.2
+			c-1.3-0.2-2.2-1.3-2.2-2.6v-42.1c0-1.3,0.9-2.4,2.2-2.6l41.7-7c5.3-0.9,9.6-4.8,10.9-10c3.7-14.7,9.4-28.9,17.1-42
+			c2.7-4.6,2.4-10.3-0.7-14.6l-24.9-35c-0.7-1-0.6-2.5,0.3-3.4l29.8-29.8c0.7-0.7,1.4-0.8,1.9-0.8c0.6,0,1.1,0.2,1.5,0.5l34.5,24.6
+			c4.4,3.1,10.2,3.3,14.8,0.6c13-7.8,27.1-13.8,41.8-17.6c5.1-1.4,9-5.6,9.9-10.8l7.2-42.3c0.2-1.3,1.3-2.2,2.6-2.2h42.1
+			c1.3,0,2.4,0.9,2.6,2.2l7,41.7c0.9,5.3,4.8,9.6,10,10.9c15.1,3.8,29.5,9.7,42.9,17.6c4.6,2.7,10.3,2.5,14.7-0.6l34.5-24.8
+			c0.5-0.3,1-0.5,1.5-0.5c0.4,0,1.2,0.1,1.9,0.8l29.8,29.8c0.9,0.9,1,2.3,0.3,3.4l-24.7,34.7c-3.1,4.3-3.3,10.1-0.6,14.7
+			c7.8,13.1,13.6,27.2,17.4,41.9c1.3,5.2,5.6,9.1,10.8,9.9l42,7.1c1.3,0.2,2.2,1.3,2.2,2.6v42.1H451.9z"/>
+		<path d="M239.4,136.001c-57,0-103.3,46.3-103.3,103.3s46.3,103.3,103.3,103.3s103.3-46.3,103.3-103.3S296.4,136.001,239.4,136.001
+			z M239.4,315.601c-42.1,0-76.3-34.2-76.3-76.3s34.2-76.3,76.3-76.3s76.3,34.2,76.3,76.3S281.5,315.601,239.4,315.601z"/>
+	</g>
+</g>
+<g>
+</g>
+<g>
+</g>
+<g>
+</g>
+<g>
+</g>
+<g>
+</g>
+<g>
+</g>
+<g>
+</g>
+<g>
+</g>
+<g>
+</g>
+<g>
+</g>
+<g>
+</g>
+<g>
+</g>
+<g>
+</g>
+<g>
+</g>
+<g>
+</g>
+</svg>
diff --git a/gui/resources/speed-green.svg b/gui/resources/speed-green.svg
new file mode 100644
index 00000000..a25de124
--- /dev/null
+++ b/gui/resources/speed-green.svg
@@ -0,0 +1,72 @@
+<?xml version="1.0" encoding="iso-8859-1"?>
+<!-- Generator: Adobe Illustrator 19.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0)  -->
+<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
+	 viewBox="0 0 512.001 512.001" style="enable-background:new 0 0 512.001 512.001;" xml:space="preserve">
+<polyline style="fill:#CFF09E;" points="233.225,420.726 270.89,383.061 288.971,401.143 310.88,303.847 213.584,325.756 
+	231.665,343.837 174.547,400.955 "/>
+<g>
+	<path style="fill:#507C5C;" d="M233.226,435.168c-3.697,0-7.391-1.41-10.212-4.23c-5.64-5.64-5.64-14.784,0-20.424l37.663-37.665
+		c5.489-5.488,14.293-5.635,19.962-0.443l11.135-49.454l-49.452,11.135c2.431,2.656,3.787,6.132,3.787,9.748
+		c0,3.83-1.522,7.504-4.23,10.212l-57.119,57.118c-5.641,5.64-14.783,5.641-20.425,0c-5.64-5.64-5.64-14.784,0-20.424l46.906-46.906
+		l-7.869-7.869c-3.722-3.722-5.124-9.175-3.66-14.231c1.466-5.056,5.564-8.915,10.7-10.072l97.296-21.909
+		c4.824-1.086,9.881,0.375,13.385,3.878c3.502,3.502,4.965,8.554,3.878,13.385l-21.908,97.296
+		c-1.157,5.136-5.016,9.234-10.072,10.699c-5.058,1.464-10.508,0.062-14.231-3.66l-7.869-7.869l-27.451,27.453
+		C240.618,433.758,236.922,435.168,233.226,435.168z"/>
+	<path style="fill:#507C5C;" d="M256,512.001c-141.159,0-256-114.841-256-256s114.841-256,256-256
+		c53.115,0,104.062,16.122,147.333,46.62c6.519,4.595,8.079,13.606,3.483,20.125c-4.595,6.519-13.607,8.08-20.125,3.485
+		C348.318,43.181,303.126,28.885,256,28.885c-125.232,0-227.116,101.884-227.116,227.116S130.768,483.117,256,483.117
+		s227.116-101.884,227.116-227.116c0-34.43-7.503-67.493-22.3-98.275c-3.456-7.189-0.43-15.817,6.759-19.273
+		c7.191-3.453,15.817-0.429,19.274,6.759c16.691,34.719,25.152,71.993,25.152,110.789C512,397.16,397.159,512.001,256,512.001z"/>
+	<path style="fill:#507C5C;" d="M230.725,434.831c-0.728,0-1.464-0.055-2.205-0.169c-42.217-6.469-80.975-27.931-109.135-60.43
+		c-28.458-32.843-44.132-74.831-44.132-118.232c0-99.664,81.083-180.747,180.747-180.747s180.747,81.083,180.747,180.747
+		c0,7.976-6.467,14.442-14.442,14.442c-7.975,0-14.442-6.466-14.442-14.442c0-83.737-68.126-151.863-151.863-151.863
+		s-151.863,68.126-151.863,151.863c0,74.329,55.353,138.863,128.757,150.11c7.884,1.209,13.295,8.579,12.088,16.462
+		C243.889,429.718,237.735,434.831,230.725,434.831z"/>
+</g>
+<path style="fill:#CFF09E;" d="M256,164.947c50.208,0,91.054,40.846,91.054,91.054h75.253c0-91.701-74.604-166.305-166.305-166.305
+	S89.695,164.3,89.695,256.001h75.253C164.946,205.793,205.792,164.947,256,164.947z"/>
+<g>
+	<path style="fill:#507C5C;" d="M422.334,270.443c-0.007,0-0.017,0-0.029,0h-75.251c-7.975,0-14.442-6.466-14.442-14.442
+		c0-42.243-34.368-76.612-76.612-76.612s-76.612,34.368-76.612,76.612c0,7.976-6.467,14.442-14.442,14.442H89.695
+		c-7.975,0-14.442-6.466-14.442-14.442c0-99.664,81.083-180.747,180.747-180.747c99.342,0,180.223,80.566,180.744,179.788
+		c0.022,0.318,0.03,0.637,0.03,0.96C436.776,263.977,430.31,270.443,422.334,270.443z M360.511,241.559h46.671
+		c-7.298-76.989-72.315-137.421-151.183-137.421S112.113,164.57,104.816,241.559h46.671c7.065-51.36,51.24-91.054,104.511-91.054
+		S353.447,190.199,360.511,241.559z"/>
+	<path style="fill:#507C5C;" d="M216.293,187.292c-3.238,0-6.496-1.083-9.188-3.309l-59.817-49.406
+		c-6.149-5.079-7.017-14.182-1.938-20.331c5.079-6.149,14.181-7.019,20.331-1.938l59.817,49.406
+		c6.149,5.079,7.017,14.182,1.938,20.331C224.58,185.502,220.453,187.292,216.293,187.292z"/>
+	<path style="fill:#507C5C;" d="M295.707,187.292c-4.161,0-8.287-1.788-11.143-5.245c-5.081-6.149-4.211-15.252,1.938-20.331
+		l59.817-49.406c6.151-5.081,15.252-4.211,20.331,1.938c5.081,6.149,4.211,15.252-1.938,20.331l-59.817,49.406
+		C302.203,186.207,298.946,187.292,295.707,187.292z"/>
+</g>
+<g>
+</g>
+<g>
+</g>
+<g>
+</g>
+<g>
+</g>
+<g>
+</g>
+<g>
+</g>
+<g>
+</g>
+<g>
+</g>
+<g>
+</g>
+<g>
+</g>
+<g>
+</g>
+<g>
+</g>
+<g>
+</g>
+<g>
+</g>
+<g>
+</g>
+</svg>
diff --git a/gui/resources/speed-red.svg b/gui/resources/speed-red.svg
new file mode 100644
index 00000000..8ceb8580
--- /dev/null
+++ b/gui/resources/speed-red.svg
@@ -0,0 +1,72 @@
+<?xml version="1.0" encoding="iso-8859-1"?>
+<!-- Generator: Adobe Illustrator 19.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0)  -->
+<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
+	 viewBox="0 0 512.001 512.001" style="enable-background:new 0 0 512.001 512.001;" xml:space="preserve">
+<polyline style="fill:#F4B2B0;" points="233.225,420.726 270.89,383.061 288.971,401.143 310.88,303.847 213.584,325.756 
+	231.665,343.837 174.547,400.955 "/>
+<g>
+	<path style="fill:#B3404A;" d="M233.226,435.168c-3.697,0-7.391-1.41-10.212-4.23c-5.64-5.64-5.64-14.784,0-20.424l37.663-37.665
+		c5.489-5.488,14.293-5.635,19.962-0.443l11.135-49.454l-49.452,11.135c2.431,2.656,3.787,6.132,3.787,9.748
+		c0,3.83-1.522,7.504-4.23,10.212l-57.119,57.118c-5.641,5.64-14.783,5.641-20.425,0c-5.64-5.64-5.64-14.784,0-20.424l46.906-46.906
+		l-7.869-7.869c-3.722-3.722-5.124-9.175-3.66-14.231c1.466-5.056,5.564-8.915,10.7-10.072l97.296-21.909
+		c4.824-1.086,9.881,0.375,13.385,3.878c3.502,3.502,4.965,8.554,3.878,13.385l-21.908,97.296
+		c-1.157,5.136-5.016,9.234-10.072,10.699c-5.058,1.464-10.508,0.062-14.231-3.66l-7.869-7.869l-27.451,27.453
+		C240.618,433.758,236.922,435.168,233.226,435.168z"/>
+	<path style="fill:#B3404A;" d="M256,512.001c-141.159,0-256-114.841-256-256s114.841-256,256-256
+		c53.115,0,104.062,16.122,147.333,46.62c6.519,4.595,8.079,13.606,3.483,20.125c-4.595,6.519-13.607,8.08-20.125,3.485
+		C348.318,43.181,303.126,28.885,256,28.885c-125.232,0-227.116,101.884-227.116,227.116S130.768,483.117,256,483.117
+		s227.116-101.884,227.116-227.116c0-34.43-7.503-67.493-22.3-98.275c-3.456-7.189-0.43-15.817,6.759-19.273
+		c7.191-3.453,15.817-0.429,19.274,6.759c16.691,34.719,25.152,71.993,25.152,110.789C512,397.16,397.159,512.001,256,512.001z"/>
+	<path style="fill:#B3404A;" d="M230.725,434.831c-0.728,0-1.464-0.055-2.205-0.169c-42.217-6.469-80.975-27.931-109.135-60.43
+		c-28.458-32.843-44.132-74.831-44.132-118.232c0-99.664,81.083-180.747,180.747-180.747s180.747,81.083,180.747,180.747
+		c0,7.976-6.467,14.442-14.442,14.442c-7.975,0-14.442-6.466-14.442-14.442c0-83.737-68.126-151.863-151.863-151.863
+		s-151.863,68.126-151.863,151.863c0,74.329,55.353,138.863,128.757,150.11c7.884,1.209,13.295,8.579,12.088,16.462
+		C243.889,429.718,237.735,434.831,230.725,434.831z"/>
+</g>
+<path style="fill:#F4B2B0;" d="M256,164.947c50.208,0,91.054,40.846,91.054,91.054h75.253c0-91.701-74.604-166.305-166.305-166.305
+	S89.695,164.3,89.695,256.001h75.253C164.946,205.793,205.792,164.947,256,164.947z"/>
+<g>
+	<path style="fill:#B3404A;" d="M422.334,270.443c-0.007,0-0.017,0-0.029,0h-75.251c-7.975,0-14.442-6.466-14.442-14.442
+		c0-42.243-34.368-76.612-76.612-76.612s-76.612,34.368-76.612,76.612c0,7.976-6.467,14.442-14.442,14.442H89.695
+		c-7.975,0-14.442-6.466-14.442-14.442c0-99.664,81.083-180.747,180.747-180.747c99.342,0,180.223,80.566,180.744,179.788
+		c0.022,0.318,0.03,0.637,0.03,0.96C436.776,263.977,430.31,270.443,422.334,270.443z M360.511,241.559h46.671
+		c-7.298-76.989-72.315-137.421-151.183-137.421S112.113,164.57,104.816,241.559h46.671c7.065-51.36,51.24-91.054,104.511-91.054
+		S353.447,190.199,360.511,241.559z"/>
+	<path style="fill:#B3404A;" d="M216.293,187.292c-3.238,0-6.496-1.083-9.188-3.309l-59.817-49.406
+		c-6.149-5.079-7.017-14.182-1.938-20.331c5.079-6.149,14.181-7.019,20.331-1.938l59.817,49.406
+		c6.149,5.079,7.017,14.182,1.938,20.331C224.58,185.502,220.453,187.292,216.293,187.292z"/>
+	<path style="fill:#B3404A;" d="M295.707,187.292c-4.161,0-8.287-1.788-11.143-5.245c-5.081-6.149-4.211-15.252,1.938-20.331
+		l59.817-49.406c6.151-5.081,15.252-4.211,20.331,1.938c5.081,6.149,4.211,15.252-1.938,20.331l-59.817,49.406
+		C302.203,186.207,298.946,187.292,295.707,187.292z"/>
+</g>
+<g>
+</g>
+<g>
+</g>
+<g>
+</g>
+<g>
+</g>
+<g>
+</g>
+<g>
+</g>
+<g>
+</g>
+<g>
+</g>
+<g>
+</g>
+<g>
+</g>
+<g>
+</g>
+<g>
+</g>
+<g>
+</g>
+<g>
+</g>
+<g>
+</g>
+</svg>
diff --git a/gui/resources/speed-yellow.svg b/gui/resources/speed-yellow.svg
new file mode 100644
index 00000000..377a2d26
--- /dev/null
+++ b/gui/resources/speed-yellow.svg
@@ -0,0 +1,72 @@
+<?xml version="1.0" encoding="iso-8859-1"?>
+<!-- Generator: Adobe Illustrator 19.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0)  -->
+<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
+	 viewBox="0 0 512.001 512.001" style="enable-background:new 0 0 512.001 512.001;" xml:space="preserve">
+<polyline style="fill:#FEE187;" points="233.225,420.726 270.89,383.061 288.971,401.143 310.88,303.847 213.584,325.756 
+	231.665,343.837 174.547,400.955 "/>
+<g>
+	<path style="fill:#FFC61B;" d="M233.226,435.168c-3.697,0-7.391-1.41-10.212-4.23c-5.64-5.64-5.64-14.784,0-20.424l37.663-37.665
+		c5.489-5.488,14.293-5.635,19.962-0.443l11.135-49.454l-49.452,11.135c2.431,2.656,3.787,6.132,3.787,9.748
+		c0,3.83-1.522,7.504-4.23,10.212l-57.119,57.118c-5.641,5.64-14.783,5.641-20.425,0c-5.64-5.64-5.64-14.784,0-20.424l46.906-46.906
+		l-7.869-7.869c-3.722-3.722-5.124-9.175-3.66-14.231c1.466-5.056,5.564-8.915,10.7-10.072l97.296-21.909
+		c4.824-1.086,9.881,0.375,13.385,3.878c3.502,3.502,4.965,8.554,3.878,13.385l-21.908,97.296
+		c-1.157,5.136-5.016,9.234-10.072,10.699c-5.058,1.464-10.508,0.062-14.231-3.66l-7.869-7.869l-27.451,27.453
+		C240.618,433.758,236.922,435.168,233.226,435.168z"/>
+	<path style="fill:#FFC61B;" d="M256,512.001c-141.159,0-256-114.841-256-256s114.841-256,256-256
+		c53.115,0,104.062,16.122,147.333,46.62c6.519,4.595,8.079,13.606,3.483,20.125c-4.595,6.519-13.607,8.08-20.125,3.485
+		C348.318,43.181,303.126,28.885,256,28.885c-125.232,0-227.116,101.884-227.116,227.116S130.768,483.117,256,483.117
+		s227.116-101.884,227.116-227.116c0-34.43-7.503-67.493-22.3-98.275c-3.456-7.189-0.43-15.817,6.759-19.273
+		c7.191-3.453,15.817-0.429,19.274,6.759c16.691,34.719,25.152,71.993,25.152,110.789C512,397.16,397.159,512.001,256,512.001z"/>
+	<path style="fill:#FFC61B;" d="M230.725,434.831c-0.728,0-1.464-0.055-2.205-0.169c-42.217-6.469-80.975-27.931-109.135-60.43
+		c-28.458-32.843-44.132-74.831-44.132-118.232c0-99.664,81.083-180.747,180.747-180.747s180.747,81.083,180.747,180.747
+		c0,7.976-6.467,14.442-14.442,14.442c-7.975,0-14.442-6.466-14.442-14.442c0-83.737-68.126-151.863-151.863-151.863
+		s-151.863,68.126-151.863,151.863c0,74.329,55.353,138.863,128.757,150.11c7.884,1.209,13.295,8.579,12.088,16.462
+		C243.889,429.718,237.735,434.831,230.725,434.831z"/>
+</g>
+<path style="fill:#FEE187;" d="M256,164.947c50.208,0,91.054,40.846,91.054,91.054h75.253c0-91.701-74.604-166.305-166.305-166.305
+	S89.695,164.3,89.695,256.001h75.253C164.946,205.793,205.792,164.947,256,164.947z"/>
+<g>
+	<path style="fill:#FFC61B;" d="M422.334,270.443c-0.007,0-0.017,0-0.029,0h-75.251c-7.975,0-14.442-6.466-14.442-14.442
+		c0-42.243-34.368-76.612-76.612-76.612s-76.612,34.368-76.612,76.612c0,7.976-6.467,14.442-14.442,14.442H89.695
+		c-7.975,0-14.442-6.466-14.442-14.442c0-99.664,81.083-180.747,180.747-180.747c99.342,0,180.223,80.566,180.744,179.788
+		c0.022,0.318,0.03,0.637,0.03,0.96C436.776,263.977,430.31,270.443,422.334,270.443z M360.511,241.559h46.671
+		c-7.298-76.989-72.315-137.421-151.183-137.421S112.113,164.57,104.816,241.559h46.671c7.065-51.36,51.24-91.054,104.511-91.054
+		S353.447,190.199,360.511,241.559z"/>
+	<path style="fill:#FFC61B;" d="M216.293,187.292c-3.238,0-6.496-1.083-9.188-3.309l-59.817-49.406
+		c-6.149-5.079-7.017-14.182-1.938-20.331c5.079-6.149,14.181-7.019,20.331-1.938l59.817,49.406
+		c6.149,5.079,7.017,14.182,1.938,20.331C224.58,185.502,220.453,187.292,216.293,187.292z"/>
+	<path style="fill:#FFC61B;" d="M295.707,187.292c-4.161,0-8.287-1.788-11.143-5.245c-5.081-6.149-4.211-15.252,1.938-20.331
+		l59.817-49.406c6.151-5.081,15.252-4.211,20.331,1.938c5.081,6.149,4.211,15.252-1.938,20.331l-59.817,49.406
+		C302.203,186.207,298.946,187.292,295.707,187.292z"/>
+</g>
+<g>
+</g>
+<g>
+</g>
+<g>
+</g>
+<g>
+</g>
+<g>
+</g>
+<g>
+</g>
+<g>
+</g>
+<g>
+</g>
+<g>
+</g>
+<g>
+</g>
+<g>
+</g>
+<g>
+</g>
+<g>
+</g>
+<g>
+</g>
+<g>
+</g>
+</svg>
diff --git a/gui/resources/spy.gif b/gui/resources/spy.gif
new file mode 100644
index 0000000000000000000000000000000000000000..733d3eb514155744d432b508e4bef358580a9984
GIT binary patch
literal 2662
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
U+fZ5{H@NgailymJUpgQFJ2C#&egFUf

literal 0
HcmV?d00001

diff --git a/gui/resources/tools.svg b/gui/resources/tools.svg
new file mode 100644
index 00000000..41c63a15
--- /dev/null
+++ b/gui/resources/tools.svg
@@ -0,0 +1,4 @@
+<?xml version="1.0" standalone="no"?>
+<svg width="1024px" height="1024px" viewBox="0 0 1024 1024" xmlns="http://www.w3.org/2000/svg" class="icon">
+  <path d="M876.6 239.5c-.5-.9-1.2-1.8-2-2.5-5-5-13.1-5-18.1 0L684.2 409.3l-67.9-67.9L788.7 169c.8-.8 1.4-1.6 2-2.5 3.6-6.1 1.6-13.9-4.5-17.5-98.2-58-226.8-44.7-311.3 39.7-67 67-89.2 162-66.5 247.4l-293 293c-3 3-2.8 7.9.3 11l169.7 169.7c3.1 3.1 8.1 3.3 11 .3l292.9-292.9c85.5 22.8 180.5.7 247.6-66.4 84.4-84.5 97.7-213.1 39.7-311.3zM786 499.8c-58.1 58.1-145.3 69.3-214.6 33.6l-8.8 8.8-.1-.1-274 274.1-79.2-79.2 230.1-230.1s0 .1.1.1l52.8-52.8c-35.7-69.3-24.5-156.5 33.6-214.6a184.2 184.2 0 0 1 144-53.5L537 318.9a32.05 32.05 0 0 0 0 45.3l124.5 124.5a32.05 32.05 0 0 0 45.3 0l132.8-132.8c3.7 51.8-14.4 104.8-53.6 143.9z"/>
+</svg>
diff --git a/gui/themes/themes.js b/gui/themes/themes.js
new file mode 100644
index 00000000..265af9a4
--- /dev/null
+++ b/gui/themes/themes.js
@@ -0,0 +1,51 @@
+.pragma library
+
+const borderColor = "#6D6D6E";
+const fontColor = "#6D6D6E";
+const fontColorDark = "#3D3D3D";
+const fontFamily = "Metropolis";
+const fontBoldFamily = "OxaniumBold";
+const fontInterFamily = "InterUI";
+const fontSize = 15;
+const fontSizeLarge = 22;
+const fontSizeSmall = 13;
+const fontSizeSmallest = 11;
+const fontWeightBold = 600;
+const iconSize = 16;
+const labelLineHeight = 22;
+const cityListTopMargin = 18;
+const controllerInterLineHeight = 18;
+const hSpacing = 20;
+const vSpacing = 24;
+const vSpacingSmall = 16;
+const listSpacing = 8;
+const maxTextWidth = 296;
+const windowMargin = 16;
+const popupMargin = 24;
+const desktopAppHeight = 520;
+const desktopAppWidth = 360;
+const darkFocusBorder = fontColor;
+const lightFocusBorder = "#d5d3e0";
+
+const accentOff = "#af0909";
+const accentConnecting = "#FFCC33";
+const accentOn = "#669933";
+
+const blue = "#0060DF";
+const blueHovered = "#0250BB";
+const bluePressed = "#054096";
+const blueDisabled = "#a3c0f3";
+const blueFocusOutline = "#4d0a84ff";
+const blueFocusBorder = "#0a84ff";
+
+const blueButton = {
+    "defaultColor" : blue,
+    "buttonHovered": blueHovered,
+    "buttonPressed": bluePressed,
+    "buttonDisabled": blueDisabled,
+    "focusBgColor": blue,
+    "focusOutline": blueFocusOutline,
+    "focusBorder": blueFocusBorder,
+};
+
+const bgColor = "white";
diff --git a/pkg/backend/init.go b/pkg/backend/init.go
index b7469c1a..fcde725b 100644
--- a/pkg/backend/init.go
+++ b/pkg/backend/init.go
@@ -29,10 +29,11 @@ func initializeContext(opts *InitOpts) {
 		DonateDialog:    false,
 		Version:         version.VERSION,
 		Status:          st,
+		IsReady:         false,
 	}
 	errCh := make(chan string)
-	go trigger(OnStatusChanged)
 	go checkErrors(errCh)
+	// isReady is set after Bitmask initialization
 	initializeBitmask(errCh, opts)
 	go trigger(OnStatusChanged)
 	ctx.delayCheckForGateways()
@@ -86,6 +87,7 @@ func initializeBitmask(errCh chan string, opts *InitOpts) {
 		errCh <- "nopolkit"
 	}
 	ctx.bm = b
+	ctx.IsReady = true
 }
 
 func setConfigOpts(opts *InitOpts, conf *config.Config) {
diff --git a/pkg/backend/status.go b/pkg/backend/status.go
index 1ec5c4fe..0ffd8530 100644
--- a/pkg/backend/status.go
+++ b/pkg/backend/status.go
@@ -49,6 +49,7 @@ type connectionCtx struct {
 	CurrentLocation string             `json:"currentLocation"`
 	CurrentCountry  string             `json:"currentCountry"`
 	ManualLocation  bool               `json:"manualLocation"`
+	IsReady         bool               `json:"isReady"`
 	bm              bitmask.Bitmask
 	autostart       bitmask.Autostart
 	cfg             *config.Config
-- 
GitLab