diff --git a/.gitignore b/.gitignore
index 3ef83b5..e36edda 100644
--- a/.gitignore
+++ b/.gitignore
@@ -2,6 +2,9 @@
build/
build-*/
.rpmbuild-local/
+**/node_modules/
+tools/icon-generator/dist/
+tools/icon-generator/masters/
# Working/research files not for public release
gemini/
diff --git a/android/app/src/main/res/drawable-hdpi/ic_notification.png b/android/app/src/main/res/drawable-hdpi/ic_notification.png
index 19580ce..c3c4150 100644
Binary files a/android/app/src/main/res/drawable-hdpi/ic_notification.png and b/android/app/src/main/res/drawable-hdpi/ic_notification.png differ
diff --git a/android/app/src/main/res/drawable-mdpi/ic_notification.png b/android/app/src/main/res/drawable-mdpi/ic_notification.png
index 3edc913..aecdb62 100644
Binary files a/android/app/src/main/res/drawable-mdpi/ic_notification.png and b/android/app/src/main/res/drawable-mdpi/ic_notification.png differ
diff --git a/android/app/src/main/res/drawable-xhdpi/ic_notification.png b/android/app/src/main/res/drawable-xhdpi/ic_notification.png
index a1ab9bf..62dc893 100644
Binary files a/android/app/src/main/res/drawable-xhdpi/ic_notification.png and b/android/app/src/main/res/drawable-xhdpi/ic_notification.png differ
diff --git a/android/app/src/main/res/drawable-xxhdpi/ic_notification.png b/android/app/src/main/res/drawable-xxhdpi/ic_notification.png
index 9cffa76..0527155 100644
Binary files a/android/app/src/main/res/drawable-xxhdpi/ic_notification.png and b/android/app/src/main/res/drawable-xxhdpi/ic_notification.png differ
diff --git a/android/app/src/main/res/drawable-xxxhdpi/ic_notification.png b/android/app/src/main/res/drawable-xxxhdpi/ic_notification.png
index 84c4c3f..e8271ef 100644
Binary files a/android/app/src/main/res/drawable-xxxhdpi/ic_notification.png and b/android/app/src/main/res/drawable-xxxhdpi/ic_notification.png differ
diff --git a/android/app/src/main/res/drawable/ic_inputflow.xml b/android/app/src/main/res/drawable/ic_inputflow.xml
index 24074e0..4e72e03 100644
--- a/android/app/src/main/res/drawable/ic_inputflow.xml
+++ b/android/app/src/main/res/drawable/ic_inputflow.xml
@@ -3,53 +3,34 @@
android:height="1024dp"
android:viewportWidth="1024"
android:viewportHeight="1024">
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+ android:strokeColor="#FF4F46E5"
+ android:strokeWidth="64"
+ android:strokeLineCap="round"
+ android:strokeLineJoin="round"
+ android:pathData="M176 336c0-35.35 28.65-64 64-64h136c35.35 0 64 28.65 64 64v352c0 35.35-28.65 64-64 64h-136c-35.35 0-64-28.65-64-64z"/>
+
+
+
+
+
diff --git a/android/app/src/main/res/drawable/ic_launcher_foreground.xml b/android/app/src/main/res/drawable/ic_launcher_foreground.xml
index d088c64..02c5f2c 100644
--- a/android/app/src/main/res/drawable/ic_launcher_foreground.xml
+++ b/android/app/src/main/res/drawable/ic_launcher_foreground.xml
@@ -3,56 +3,34 @@
android:height="108dp"
android:viewportWidth="1024"
android:viewportHeight="1024">
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
diff --git a/android/app/src/main/res/drawable/ic_launcher_monochrome.xml b/android/app/src/main/res/drawable/ic_launcher_monochrome.xml
index 89df363..81837e2 100644
--- a/android/app/src/main/res/drawable/ic_launcher_monochrome.xml
+++ b/android/app/src/main/res/drawable/ic_launcher_monochrome.xml
@@ -4,18 +4,33 @@
android:viewportWidth="1024"
android:viewportHeight="1024">
+ android:strokeColor="#FF000000"
+ android:strokeWidth="64"
+ android:strokeLineCap="round"
+ android:strokeLineJoin="round"
+ android:pathData="M176 336c0-35.35 28.65-64 64-64h136c35.35 0 64 28.65 64 64v352c0 35.35-28.65 64-64 64h-136c-35.35 0-64-28.65-64-64z"/>
+ android:strokeColor="#FF000000"
+ android:strokeWidth="64"
+ android:strokeLineCap="round"
+ android:strokeLineJoin="round"
+ android:pathData="M584 336c0-35.35 28.65-64 64-64h136c35.35 0 64 28.65 64 64v352c0 35.35-28.65 64-64 64h-136c-35.35 0-64-28.65-64-64z"/>
+ android:strokeColor="#FF000000"
+ android:strokeWidth="64"
+ android:strokeLineCap="round"
+ android:strokeLineJoin="round"
+ android:pathData="M336 512h352"/>
+
+ android:pathData="M308 638a18 18 0 1 0 0 36 18 18 0 1 0 0-36z"/>
+ android:pathData="M716 638a18 18 0 1 0 0 36 18 18 0 1 0 0-36z"/>
diff --git a/android/app/src/main/res/mipmap-hdpi/ic_launcher.png b/android/app/src/main/res/mipmap-hdpi/ic_launcher.png
index 0f1e7f3..733a9dd 100644
Binary files a/android/app/src/main/res/mipmap-hdpi/ic_launcher.png and b/android/app/src/main/res/mipmap-hdpi/ic_launcher.png differ
diff --git a/android/app/src/main/res/mipmap-hdpi/ic_launcher_round.png b/android/app/src/main/res/mipmap-hdpi/ic_launcher_round.png
index c26b321..c81d507 100644
Binary files a/android/app/src/main/res/mipmap-hdpi/ic_launcher_round.png and b/android/app/src/main/res/mipmap-hdpi/ic_launcher_round.png differ
diff --git a/android/app/src/main/res/mipmap-mdpi/ic_launcher.png b/android/app/src/main/res/mipmap-mdpi/ic_launcher.png
index b79e7c4..e856407 100644
Binary files a/android/app/src/main/res/mipmap-mdpi/ic_launcher.png and b/android/app/src/main/res/mipmap-mdpi/ic_launcher.png differ
diff --git a/android/app/src/main/res/mipmap-mdpi/ic_launcher_round.png b/android/app/src/main/res/mipmap-mdpi/ic_launcher_round.png
index 4d6b93e..472c898 100644
Binary files a/android/app/src/main/res/mipmap-mdpi/ic_launcher_round.png and b/android/app/src/main/res/mipmap-mdpi/ic_launcher_round.png differ
diff --git a/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png b/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png
index b4ca372..cc7976c 100644
Binary files a/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png and b/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png differ
diff --git a/android/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png b/android/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png
index 585651b..d9dd04c 100644
Binary files a/android/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png and b/android/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png differ
diff --git a/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png b/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png
index c351dce..66c5c20 100644
Binary files a/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png and b/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png differ
diff --git a/android/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png b/android/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png
index d13b9ff..fe5897a 100644
Binary files a/android/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png and b/android/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png differ
diff --git a/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png b/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png
index ea98a7e..ea5086d 100644
Binary files a/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png and b/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png differ
diff --git a/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png b/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png
index 5adaa57..0b349d3 100644
Binary files a/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png and b/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png differ
diff --git a/assets/hicolor/128x128/apps/inputflow.png b/assets/hicolor/128x128/apps/inputflow.png
index d0c5811..beb38fc 100644
Binary files a/assets/hicolor/128x128/apps/inputflow.png and b/assets/hicolor/128x128/apps/inputflow.png differ
diff --git a/assets/hicolor/16x16/apps/inputflow.png b/assets/hicolor/16x16/apps/inputflow.png
index 09a01c1..108cb0d 100644
Binary files a/assets/hicolor/16x16/apps/inputflow.png and b/assets/hicolor/16x16/apps/inputflow.png differ
diff --git a/assets/hicolor/16x16/status/inputflow-tray-attention.png b/assets/hicolor/16x16/status/inputflow-tray-attention.png
index b32dcbd..e8ee76b 100644
Binary files a/assets/hicolor/16x16/status/inputflow-tray-attention.png and b/assets/hicolor/16x16/status/inputflow-tray-attention.png differ
diff --git a/assets/hicolor/16x16/status/inputflow-tray-busy.png b/assets/hicolor/16x16/status/inputflow-tray-busy.png
index 51d7d86..f0aefed 100644
Binary files a/assets/hicolor/16x16/status/inputflow-tray-busy.png and b/assets/hicolor/16x16/status/inputflow-tray-busy.png differ
diff --git a/assets/hicolor/16x16/status/inputflow-tray-offline.png b/assets/hicolor/16x16/status/inputflow-tray-offline.png
index 2c4aaa2..768ea14 100644
Binary files a/assets/hicolor/16x16/status/inputflow-tray-offline.png and b/assets/hicolor/16x16/status/inputflow-tray-offline.png differ
diff --git a/assets/hicolor/16x16/status/inputflow-tray.png b/assets/hicolor/16x16/status/inputflow-tray.png
index a1d7fec..a1b34ab 100644
Binary files a/assets/hicolor/16x16/status/inputflow-tray.png and b/assets/hicolor/16x16/status/inputflow-tray.png differ
diff --git a/assets/hicolor/22x22/status/inputflow-tray-attention.png b/assets/hicolor/22x22/status/inputflow-tray-attention.png
index 2362dfc..c915489 100644
Binary files a/assets/hicolor/22x22/status/inputflow-tray-attention.png and b/assets/hicolor/22x22/status/inputflow-tray-attention.png differ
diff --git a/assets/hicolor/22x22/status/inputflow-tray-busy.png b/assets/hicolor/22x22/status/inputflow-tray-busy.png
index 55ca06e..b350c49 100644
Binary files a/assets/hicolor/22x22/status/inputflow-tray-busy.png and b/assets/hicolor/22x22/status/inputflow-tray-busy.png differ
diff --git a/assets/hicolor/22x22/status/inputflow-tray-offline.png b/assets/hicolor/22x22/status/inputflow-tray-offline.png
index 77adb13..841cd0b 100644
Binary files a/assets/hicolor/22x22/status/inputflow-tray-offline.png and b/assets/hicolor/22x22/status/inputflow-tray-offline.png differ
diff --git a/assets/hicolor/22x22/status/inputflow-tray.png b/assets/hicolor/22x22/status/inputflow-tray.png
index 890cda2..7a79037 100644
Binary files a/assets/hicolor/22x22/status/inputflow-tray.png and b/assets/hicolor/22x22/status/inputflow-tray.png differ
diff --git a/assets/hicolor/24x24/apps/inputflow.png b/assets/hicolor/24x24/apps/inputflow.png
index ee65241..46e2866 100644
Binary files a/assets/hicolor/24x24/apps/inputflow.png and b/assets/hicolor/24x24/apps/inputflow.png differ
diff --git a/assets/hicolor/24x24/status/inputflow-tray-attention.png b/assets/hicolor/24x24/status/inputflow-tray-attention.png
index d5a3d25..14971ad 100644
Binary files a/assets/hicolor/24x24/status/inputflow-tray-attention.png and b/assets/hicolor/24x24/status/inputflow-tray-attention.png differ
diff --git a/assets/hicolor/24x24/status/inputflow-tray-busy.png b/assets/hicolor/24x24/status/inputflow-tray-busy.png
index f93e043..9d07a9f 100644
Binary files a/assets/hicolor/24x24/status/inputflow-tray-busy.png and b/assets/hicolor/24x24/status/inputflow-tray-busy.png differ
diff --git a/assets/hicolor/24x24/status/inputflow-tray-offline.png b/assets/hicolor/24x24/status/inputflow-tray-offline.png
index 74677bd..5867093 100644
Binary files a/assets/hicolor/24x24/status/inputflow-tray-offline.png and b/assets/hicolor/24x24/status/inputflow-tray-offline.png differ
diff --git a/assets/hicolor/24x24/status/inputflow-tray.png b/assets/hicolor/24x24/status/inputflow-tray.png
index 11f8547..13af85b 100644
Binary files a/assets/hicolor/24x24/status/inputflow-tray.png and b/assets/hicolor/24x24/status/inputflow-tray.png differ
diff --git a/assets/hicolor/256x256/apps/inputflow.png b/assets/hicolor/256x256/apps/inputflow.png
index 06265c7..0d3df1e 100644
Binary files a/assets/hicolor/256x256/apps/inputflow.png and b/assets/hicolor/256x256/apps/inputflow.png differ
diff --git a/assets/hicolor/32x32/apps/inputflow.png b/assets/hicolor/32x32/apps/inputflow.png
index 06cbb53..6746956 100644
Binary files a/assets/hicolor/32x32/apps/inputflow.png and b/assets/hicolor/32x32/apps/inputflow.png differ
diff --git a/assets/hicolor/32x32/status/inputflow-tray-attention.png b/assets/hicolor/32x32/status/inputflow-tray-attention.png
index 245bf17..556d4c2 100644
Binary files a/assets/hicolor/32x32/status/inputflow-tray-attention.png and b/assets/hicolor/32x32/status/inputflow-tray-attention.png differ
diff --git a/assets/hicolor/32x32/status/inputflow-tray-busy.png b/assets/hicolor/32x32/status/inputflow-tray-busy.png
index 2083819..fa97165 100644
Binary files a/assets/hicolor/32x32/status/inputflow-tray-busy.png and b/assets/hicolor/32x32/status/inputflow-tray-busy.png differ
diff --git a/assets/hicolor/32x32/status/inputflow-tray-offline.png b/assets/hicolor/32x32/status/inputflow-tray-offline.png
index ca2738b..ccd8c8e 100644
Binary files a/assets/hicolor/32x32/status/inputflow-tray-offline.png and b/assets/hicolor/32x32/status/inputflow-tray-offline.png differ
diff --git a/assets/hicolor/32x32/status/inputflow-tray.png b/assets/hicolor/32x32/status/inputflow-tray.png
index 482f25f..8f6e814 100644
Binary files a/assets/hicolor/32x32/status/inputflow-tray.png and b/assets/hicolor/32x32/status/inputflow-tray.png differ
diff --git a/assets/hicolor/48x48/apps/inputflow.png b/assets/hicolor/48x48/apps/inputflow.png
index 18b77df..572acc5 100644
Binary files a/assets/hicolor/48x48/apps/inputflow.png and b/assets/hicolor/48x48/apps/inputflow.png differ
diff --git a/assets/hicolor/48x48/status/inputflow-tray-attention.png b/assets/hicolor/48x48/status/inputflow-tray-attention.png
index 76ee897..6b9c8b6 100644
Binary files a/assets/hicolor/48x48/status/inputflow-tray-attention.png and b/assets/hicolor/48x48/status/inputflow-tray-attention.png differ
diff --git a/assets/hicolor/48x48/status/inputflow-tray-busy.png b/assets/hicolor/48x48/status/inputflow-tray-busy.png
index 00f329c..666b271 100644
Binary files a/assets/hicolor/48x48/status/inputflow-tray-busy.png and b/assets/hicolor/48x48/status/inputflow-tray-busy.png differ
diff --git a/assets/hicolor/48x48/status/inputflow-tray-offline.png b/assets/hicolor/48x48/status/inputflow-tray-offline.png
index 7749d52..de597e9 100644
Binary files a/assets/hicolor/48x48/status/inputflow-tray-offline.png and b/assets/hicolor/48x48/status/inputflow-tray-offline.png differ
diff --git a/assets/hicolor/48x48/status/inputflow-tray.png b/assets/hicolor/48x48/status/inputflow-tray.png
index 8f23907..81336be 100644
Binary files a/assets/hicolor/48x48/status/inputflow-tray.png and b/assets/hicolor/48x48/status/inputflow-tray.png differ
diff --git a/assets/hicolor/512x512/apps/inputflow.png b/assets/hicolor/512x512/apps/inputflow.png
index 316627e..7c0b606 100644
Binary files a/assets/hicolor/512x512/apps/inputflow.png and b/assets/hicolor/512x512/apps/inputflow.png differ
diff --git a/assets/hicolor/64x64/apps/inputflow.png b/assets/hicolor/64x64/apps/inputflow.png
index 4d3758f..da7bb1d 100644
Binary files a/assets/hicolor/64x64/apps/inputflow.png and b/assets/hicolor/64x64/apps/inputflow.png differ
diff --git a/assets/hicolor/scalable/apps/inputflow.svg b/assets/hicolor/scalable/apps/inputflow.svg
index 62d726a..a67c870 100644
--- a/assets/hicolor/scalable/apps/inputflow.svg
+++ b/assets/hicolor/scalable/apps/inputflow.svg
@@ -1,35 +1,14 @@
-
diff --git a/assets/hicolor/scalable/status/inputflow-tray-busy.svg b/assets/hicolor/scalable/status/inputflow-tray-busy.svg
index 7fd9f3e..f965d81 100644
--- a/assets/hicolor/scalable/status/inputflow-tray-busy.svg
+++ b/assets/hicolor/scalable/status/inputflow-tray-busy.svg
@@ -1,28 +1,18 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/assets/hicolor/scalable/status/inputflow-tray-offline.svg b/assets/hicolor/scalable/status/inputflow-tray-offline.svg
index 1a3e23a..2a97de4 100644
--- a/assets/hicolor/scalable/status/inputflow-tray-offline.svg
+++ b/assets/hicolor/scalable/status/inputflow-tray-offline.svg
@@ -1,27 +1,17 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/assets/hicolor/scalable/status/inputflow-tray.svg b/assets/hicolor/scalable/status/inputflow-tray.svg
index 8b9d71a..a189c97 100644
--- a/assets/hicolor/scalable/status/inputflow-tray.svg
+++ b/assets/hicolor/scalable/status/inputflow-tray.svg
@@ -1,23 +1,13 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/assets/icons/inputflow-desktop.svg b/assets/icons/inputflow-desktop.svg
index 62d726a..a67c870 100644
--- a/assets/icons/inputflow-desktop.svg
+++ b/assets/icons/inputflow-desktop.svg
@@ -1,35 +1,14 @@
-
-
-
-
-
-
-
-
+
+
+
-
-
-
-
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
diff --git a/assets/icons/inputflow-foreground.svg b/assets/icons/inputflow-foreground.svg
index 27c87e2..d24e68e 100644
--- a/assets/icons/inputflow-foreground.svg
+++ b/assets/icons/inputflow-foreground.svg
@@ -1,24 +1,11 @@
-
-
-
-
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
diff --git a/assets/icons/inputflow-glyph.svg b/assets/icons/inputflow-glyph.svg
index 91c19b5..14c205b 100644
--- a/assets/icons/inputflow-glyph.svg
+++ b/assets/icons/inputflow-glyph.svg
@@ -1,8 +1,11 @@
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
diff --git a/assets/icons/inputflow-logo-square.svg b/assets/icons/inputflow-logo-square.svg
index cb0019c..ce3adaa 100644
--- a/assets/icons/inputflow-logo-square.svg
+++ b/assets/icons/inputflow-logo-square.svg
@@ -1,22 +1,13 @@
-
-
-
-
-
-
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
diff --git a/assets/icons/inputflow-notification.svg b/assets/icons/inputflow-notification.svg
index 828bbe2..d24e68e 100644
--- a/assets/icons/inputflow-notification.svg
+++ b/assets/icons/inputflow-notification.svg
@@ -1,24 +1,11 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
diff --git a/assets/icons/inputflow-tray-attention.svg b/assets/icons/inputflow-tray-attention.svg
index 94b697d..016023a 100644
--- a/assets/icons/inputflow-tray-attention.svg
+++ b/assets/icons/inputflow-tray-attention.svg
@@ -1,28 +1,18 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/assets/icons/inputflow-tray-busy.svg b/assets/icons/inputflow-tray-busy.svg
index 7fd9f3e..f965d81 100644
--- a/assets/icons/inputflow-tray-busy.svg
+++ b/assets/icons/inputflow-tray-busy.svg
@@ -1,28 +1,18 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/assets/icons/inputflow-tray-offline.svg b/assets/icons/inputflow-tray-offline.svg
index 1a3e23a..2a97de4 100644
--- a/assets/icons/inputflow-tray-offline.svg
+++ b/assets/icons/inputflow-tray-offline.svg
@@ -1,27 +1,17 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/assets/icons/inputflow-tray.svg b/assets/icons/inputflow-tray.svg
index 8b9d71a..a189c97 100644
--- a/assets/icons/inputflow-tray.svg
+++ b/assets/icons/inputflow-tray.svg
@@ -1,23 +1,13 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/tools/icon-generator/README.md b/tools/icon-generator/README.md
index 815864b..79a8285 100644
--- a/tools/icon-generator/README.md
+++ b/tools/icon-generator/README.md
@@ -1,21 +1,19 @@
# InputFlow icon set
-App mark: a friendly **donkey** — the stubborn little pack animal that ferries your
-mouse and keyboard across the border between machines. Gradient squircle (cyan
-`#22D3EE` → indigo `#6366F1`), pale-grey donkey, and a small cursor that ties the
-mark back to "input flow." Everything below is regenerated by `build.js` from one
-shared art definition (`donkey.js`), so the colored logo and the monochrome tray /
-notification glyphs never drift apart.
+App mark: two device outlines connected by one directional flow path. The sparse
+geometry stays recognizable from the full launcher icon down to a 16 px tray slot.
+The brand tile uses a cyan-to-indigo gradient; monochrome tray, themed-icon, and
+notification variants come from the same `flow-mark.js` source.
## What's here
### `assets/icons/` — source SVG masters (commit these)
| File | Use |
|---|---|
-| `inputflow-logo.svg` | 1024² brand icon (squircle bg + cursor) |
+| `inputflow-logo.svg` | 1024² brand icon (gradient tile + flow mark) |
| `inputflow-logo-square.svg` | full-bleed variant (Play Store / adaptive bg source) |
-| `inputflow-foreground.svg` | donkey only, transparent (adaptive foreground / in-app) |
-| `inputflow-glyph.svg` | flat one-color silhouette (themed-icon source) |
+| `inputflow-foreground.svg` | flow mark only, transparent (adaptive foreground / in-app) |
+| `inputflow-glyph.svg` | one-color flow mark (themed-icon source) |
| `inputflow-tray{,-attention,-busy,-offline}.svg` | Linux tray, 4 states |
| `inputflow-notification.svg` | white silhouette for Android notifications |
@@ -45,12 +43,11 @@ gtk-update-icon-cache /usr/share/icons/hicolor
## Regenerate
```
-npm install @resvg/resvg-js svg2vectordrawable # + ImageMagick for the round crop
+npm ci # + ImageMagick for the round crop
node build-masters.js # rebuild the 6 master SVGs
node build.js # rebuild every Linux + Android output
```
## Tweaking
-Colors and shapes live in `donkey.js`. The gradient stops are the two `stop-color`
-values; the donkey greys are `#C7D0E4` (body) / `#EEF2FA` (muzzle+inner ear) /
-`#2E3440` (eyes, nostrils). Change them once there and re-run the two build steps.
+Colors and geometry live in `flow-mark.js`. Change them once there and re-run the
+two build steps.
diff --git a/tools/icon-generator/build-masters.js b/tools/icon-generator/build-masters.js
index 2115cf1..8e6615b 100644
--- a/tools/icon-generator/build-masters.js
+++ b/tools/icon-generator/build-masters.js
@@ -1,66 +1,65 @@
-// Builds the InputFlow master SVGs from a single shared donkey definition,
-// so the colored logo and the monochrome tray/notification glyphs stay identical.
+// Builds every InputFlow master SVG from one device-to-device flow definition.
const fs = require('fs');
const path = require('path');
-const { wrap, donkeyColor, donkeyMono, cursor, gradientDefs } = require('./donkey');
+const { wrap, flowGlyph, gradientDefs } = require('./flow-mark');
const OUT = path.join(__dirname, 'masters');
fs.mkdirSync(OUT, { recursive: true });
-// corner status badge sized for tiny system-tray slots.
function badge() {
- const cx = 768, cy = 760, r = 150; // bottom-right
- return { cx, cy, r };
+ return { cx: 780, cy: 768, r: 146 };
}
-// 1) BRAND LOGO (color, gradient squircle bg + donkey + cursor)
+// Brand logo: a restrained gradient tile and a single white flow glyph.
const logo = wrap(`${gradientDefs}
-
- ${donkeyColor}
- ${cursor}`);
-fs.writeFileSync(path.join(OUT,'inputflow-logo.svg'), logo);
+
+ ${flowGlyph('#FFFFFF')}`);
+fs.writeFileSync(path.join(OUT, 'inputflow-logo.svg'), logo);
-// foreground-only donkey (transparent) for Android adaptive + in-app, re-centred
-const fg = wrap(`${donkeyColor}`);
-fs.writeFileSync(path.join(OUT,'inputflow-foreground.svg'), fg);
-
-const trayViewBox = '0 0 1024 1024';
+// Transparent foreground for Android adaptive and in-app use.
+fs.writeFileSync(
+ path.join(OUT, 'inputflow-foreground.svg'),
+ wrap(flowGlyph('#FFFFFF')),
+);
function trayBase(ink) {
return `
-
- ${donkeyMono('tray-dk', '#FFFFFF')}`;
+
+ ${flowGlyph('#FFFFFF')}`;
}
-// 2) TRAY default (active/healthy)
-fs.writeFileSync(path.join(OUT,'inputflow-tray.svg'),
- wrap(trayBase('#10B981'), '', trayViewBox));
+fs.writeFileSync(
+ path.join(OUT, 'inputflow-tray.svg'),
+ wrap(trayBase('#0F766E')),
+);
-// tray variants: colored tile + white donkey + readable status badge.
function trayVariant(name, symbolInner, ink) {
const b = badge();
const inner = `
${trayBase(ink)}
${symbolInner(b)}`;
- fs.writeFileSync(path.join(OUT,`inputflow-tray-${name}.svg`), wrap(inner, '', trayViewBox));
+ fs.writeFileSync(
+ path.join(OUT, `inputflow-tray-${name}.svg`),
+ wrap(inner),
+ );
}
-// attention: "!" inside the white badge
trayVariant('attention', b => `
-
- `, '#EF4444');
+
+ `, '#DC2626');
-// busy: two pause bars inside the white badge
trayVariant('busy', b => `
-
- `, '#F59E0B');
+
+ `, '#D97706');
-// offline: diagonal slash inside the white badge
trayVariant('offline', b => `
- `, '#6B7280');
+ `, '#64748B');
-// 3) NOTIFICATION (white silhouette on transparent, Android tints it)
-fs.writeFileSync(path.join(OUT,'inputflow-notification.svg'), wrap(donkeyMono('mn','#FFFFFF')));
+// Android tints notification artwork, so keep it a single-color transparent mark.
+fs.writeFileSync(
+ path.join(OUT, 'inputflow-notification.svg'),
+ wrap(flowGlyph('#FFFFFF')),
+);
console.log('masters written:', fs.readdirSync(OUT).join(', '));
diff --git a/tools/icon-generator/build.js b/tools/icon-generator/build.js
index 4ffaf27..900ea07 100644
--- a/tools/icon-generator/build.js
+++ b/tools/icon-generator/build.js
@@ -3,7 +3,7 @@ const path = require('path');
const cp = require('child_process');
const { Resvg } = require('@resvg/resvg-js');
const s2v = require('svg2vectordrawable');
-const D = require('./donkey');
+const Mark = require('./flow-mark');
const ROOT = path.join(__dirname, 'dist', 'inputflow-icons');
const M = path.join(__dirname, 'masters');
@@ -23,11 +23,11 @@ const src = path.join(ROOT, 'assets', 'icons');
for (const f of fs.readdirSync(M)) fs.copyFileSync(path.join(M, f), path.join(mk(src), f));
// square (full-bleed) logo -> Play Store + adaptive raster fallback + bg
-const squareLogo = D.wrap(`${D.gradientDefs}
- ${D.donkeyColor}${D.cursor}`);
+const squareLogo = Mark.wrap(`${Mark.gradientDefs}
+ ${Mark.flowGlyph('#FFFFFF')}`);
write(path.join(src, 'inputflow-logo-square.svg'), squareLogo);
-// solid silhouette (themed-icon monochrome + vector source)
-write(path.join(src, 'inputflow-glyph.svg'), D.wrap(D.donkeySilhouette('#2E3440')));
+// solid monochrome source for themed icons.
+write(path.join(src, 'inputflow-glyph.svg'), Mark.wrap(Mark.flowGlyph('#172033')));
/* ----------------------------------------------------------------- LINUX */
const hicolor = path.join(ROOT, 'linux', 'hicolor');
@@ -63,20 +63,19 @@ async function toVD(svg, opts = {}) { return (await s2v(svg, opts)).replace(/\n\
`;
write(path.join(res, 'drawable', 'ic_launcher_background.xml'), await toVD(bgSvg, { floatPrecision: 2 }));
- // foreground: donkey centred in the 66dp safe zone of a 108 canvas.
- // native donkey centre ~ (512,478); map 1024->108 then nudge to centre.
+ // Foreground: compact flow mark centered in the adaptive-icon safe zone.
const fgSvg = `
- ${D.donkeyColor}`;
+ ${Mark.flowGlyph('#FFFFFF')}`;
write(path.join(res, 'drawable', 'ic_launcher_foreground.xml'), await toVD(fgSvg, { floatPrecision: 2 }));
- // monochrome layer for Android 13+ themed icons (solid silhouette)
+ // Monochrome layer for Android 13+ themed icons.
const monoSvg = `
- ${D.donkeySilhouette('#000000')}`;
+ ${Mark.flowGlyph('#000000')}`;
write(path.join(res, 'drawable', 'ic_launcher_monochrome.xml'), await toVD(monoSvg, { floatPrecision: 2 }));
- // in-app vector (colored donkey, no bg)
+ // In-app vector (brand-colored mark, no background).
write(path.join(res, 'drawable', 'ic_inputflow.xml'),
- await toVD(`${D.donkeyColor}`,
+ await toVD(`${Mark.flowGlyph('#4F46E5')}`,
{ floatPrecision: 2 }));
// adaptive icon descriptors
@@ -142,22 +141,20 @@ function buildReadmeAndZip() {
const README = `# InputFlow icon set
-App mark: a friendly **donkey** — the stubborn little pack animal that ferries your
-mouse and keyboard across the border between machines. Gradient squircle (cyan
-\`#22D3EE\` → indigo \`#6366F1\`), pale-grey donkey, and a small cursor that ties the
-mark back to "input flow." Everything below is regenerated by \`build.js\` from one
-shared art definition (\`donkey.js\`), so the colored logo and the monochrome tray /
-notification glyphs never drift apart.
+App mark: two device outlines connected by one directional flow path. The sparse
+geometry stays recognizable from the full launcher icon down to a 16 px tray slot.
+The brand tile uses a cyan-to-indigo gradient; monochrome tray, themed-icon, and
+notification variants come from the same \`flow-mark.js\` source.
## What's here
### \`assets/icons/\` — source SVG masters (commit these)
| File | Use |
|---|---|
-| \`inputflow-logo.svg\` | 1024² brand icon (squircle bg + cursor) |
+| \`inputflow-logo.svg\` | 1024² brand icon (gradient tile + flow mark) |
| \`inputflow-logo-square.svg\` | full-bleed variant (Play Store / adaptive bg source) |
-| \`inputflow-foreground.svg\` | donkey only, transparent (adaptive foreground / in-app) |
-| \`inputflow-glyph.svg\` | flat one-color silhouette (themed-icon source) |
+| \`inputflow-foreground.svg\` | flow mark only, transparent (adaptive foreground / in-app) |
+| \`inputflow-glyph.svg\` | one-color flow mark (themed-icon source) |
| \`inputflow-tray{,-attention,-busy,-offline}.svg\` | Linux tray, 4 states |
| \`inputflow-notification.svg\` | white silhouette for Android notifications |
@@ -187,13 +184,12 @@ gtk-update-icon-cache /usr/share/icons/hicolor
## Regenerate
\`\`\`
-npm install @resvg/resvg-js svg2vectordrawable # + ImageMagick for the round crop
+npm ci # + ImageMagick for the round crop
node build-masters.js # rebuild the 6 master SVGs
node build.js # rebuild every Linux + Android output
\`\`\`
## Tweaking
-Colors and shapes live in \`donkey.js\`. The gradient stops are the two \`stop-color\`
-values; the donkey greys are \`#C7D0E4\` (body) / \`#EEF2FA\` (muzzle+inner ear) /
-\`#2E3440\` (eyes, nostrils). Change them once there and re-run the two build steps.
+Colors and geometry live in \`flow-mark.js\`. Change them once there and re-run the
+two build steps.
`;
diff --git a/tools/icon-generator/donkey.js b/tools/icon-generator/donkey.js
deleted file mode 100644
index 1d4226c..0000000
--- a/tools/icon-generator/donkey.js
+++ /dev/null
@@ -1,75 +0,0 @@
-// Single source of truth for the InputFlow donkey art.
-const W = 1024;
-const wrap = (inner, extra='', vb=`0 0 ${W} ${W}`, w=W, h=W) =>
- `${extra}${inner}\n`;
-
-const earsColor = `
-
-
-
-
-
-
-
- `;
-
-const donkeyColor = `${earsColor}
-
-
-
-
-
-
-
-
- `;
-
-// flat single-colour silhouette (body shapes only, painter's model -> no holes).
-// Safe to convert to an Android VectorDrawable / themed-icon monochrome layer.
-const donkeySilhouette = (ink) => `
-
-
-
-
-
-
- `;
-
-const donkeyInkShapes = `
-
-
-
-
- `;
-
-const donkeyKnockoutShapes = `
-
-
-
-
-
- `;
-
-const donkeyMask = (id, extraKnockouts='') => `
-
-
- ${donkeyInkShapes}
-
- ${donkeyKnockoutShapes}${extraKnockouts}
-
-
-`;
-
-// masked monochrome: solid face with knocked-out eyes / inner-ears / nostrils.
-// Best for raster tray + notification PNGs (survives theme tinting).
-const donkeyMono = (id, ink, extraKnockouts='') => `${donkeyMask(id, extraKnockouts)}
- `;
-
-const cursor = `
-
- `;
-
-const gradientDefs = `
- `;
-
-module.exports = { W, wrap, donkeyColor, donkeySilhouette, donkeyMask, donkeyMono, cursor, gradientDefs };
diff --git a/tools/icon-generator/flow-mark.js b/tools/icon-generator/flow-mark.js
new file mode 100644
index 0000000..eba167d
--- /dev/null
+++ b/tools/icon-generator/flow-mark.js
@@ -0,0 +1,24 @@
+// Single source of truth for the InputFlow device-to-device flow mark.
+const W = 1024;
+const wrap = (inner, extra = '', vb = `0 0 ${W} ${W}`, w = W, h = W) =>
+ `${extra}${inner}\n`
+ .replace(/[ \t]+$/gm, '');
+
+const gradientDefs = `
+ `;
+
+// Two device outlines joined by one directional path. The geometry is deliberately
+// sparse so it remains recognizable as a monochrome 16 px tray/notification icon.
+const flowGlyph = (ink = '#FFFFFF') => `
+
+
+
+
+
+
+
+
+
+ `;
+
+module.exports = { W, wrap, gradientDefs, flowGlyph };
diff --git a/tools/icon-generator/package-lock.json b/tools/icon-generator/package-lock.json
new file mode 100644
index 0000000..d8b8fe4
--- /dev/null
+++ b/tools/icon-generator/package-lock.json
@@ -0,0 +1,637 @@
+{
+ "name": "inputflow-icons",
+ "version": "1.0.0",
+ "lockfileVersion": 3,
+ "requires": true,
+ "packages": {
+ "": {
+ "name": "inputflow-icons",
+ "version": "1.0.0",
+ "dependencies": {
+ "@resvg/resvg-js": "^2.6.2",
+ "svg2vectordrawable": "^2.9.1"
+ }
+ },
+ "node_modules/@resvg/resvg-js": {
+ "version": "2.6.2",
+ "resolved": "https://registry.npmjs.org/@resvg/resvg-js/-/resvg-js-2.6.2.tgz",
+ "integrity": "sha512-xBaJish5OeGmniDj9cW5PRa/PtmuVU3ziqrbr5xJj901ZDN4TosrVaNZpEiLZAxdfnhAe7uQ7QFWfjPe9d9K2Q==",
+ "license": "MPL-2.0",
+ "engines": {
+ "node": ">= 10"
+ },
+ "optionalDependencies": {
+ "@resvg/resvg-js-android-arm-eabi": "2.6.2",
+ "@resvg/resvg-js-android-arm64": "2.6.2",
+ "@resvg/resvg-js-darwin-arm64": "2.6.2",
+ "@resvg/resvg-js-darwin-x64": "2.6.2",
+ "@resvg/resvg-js-linux-arm-gnueabihf": "2.6.2",
+ "@resvg/resvg-js-linux-arm64-gnu": "2.6.2",
+ "@resvg/resvg-js-linux-arm64-musl": "2.6.2",
+ "@resvg/resvg-js-linux-x64-gnu": "2.6.2",
+ "@resvg/resvg-js-linux-x64-musl": "2.6.2",
+ "@resvg/resvg-js-win32-arm64-msvc": "2.6.2",
+ "@resvg/resvg-js-win32-ia32-msvc": "2.6.2",
+ "@resvg/resvg-js-win32-x64-msvc": "2.6.2"
+ }
+ },
+ "node_modules/@resvg/resvg-js-android-arm-eabi": {
+ "version": "2.6.2",
+ "resolved": "https://registry.npmjs.org/@resvg/resvg-js-android-arm-eabi/-/resvg-js-android-arm-eabi-2.6.2.tgz",
+ "integrity": "sha512-FrJibrAk6v29eabIPgcTUMPXiEz8ssrAk7TXxsiZzww9UTQ1Z5KAbFJs+Z0Ez+VZTYgnE5IQJqBcoSiMebtPHA==",
+ "cpu": [
+ "arm"
+ ],
+ "license": "MPL-2.0",
+ "optional": true,
+ "os": [
+ "android"
+ ],
+ "engines": {
+ "node": ">= 10"
+ }
+ },
+ "node_modules/@resvg/resvg-js-android-arm64": {
+ "version": "2.6.2",
+ "resolved": "https://registry.npmjs.org/@resvg/resvg-js-android-arm64/-/resvg-js-android-arm64-2.6.2.tgz",
+ "integrity": "sha512-VcOKezEhm2VqzXpcIJoITuvUS/fcjIw5NA/w3tjzWyzmvoCdd+QXIqy3FBGulWdClvp4g+IfUemigrkLThSjAQ==",
+ "cpu": [
+ "arm64"
+ ],
+ "license": "MPL-2.0",
+ "optional": true,
+ "os": [
+ "android"
+ ],
+ "engines": {
+ "node": ">= 10"
+ }
+ },
+ "node_modules/@resvg/resvg-js-darwin-arm64": {
+ "version": "2.6.2",
+ "resolved": "https://registry.npmjs.org/@resvg/resvg-js-darwin-arm64/-/resvg-js-darwin-arm64-2.6.2.tgz",
+ "integrity": "sha512-nmok2LnAd6nLUKI16aEB9ydMC6Lidiiq2m1nEBDR1LaaP7FGs4AJ90qDraxX+CWlVuRlvNjyYJTNv8qFjtL9+A==",
+ "cpu": [
+ "arm64"
+ ],
+ "license": "MPL-2.0",
+ "optional": true,
+ "os": [
+ "darwin"
+ ],
+ "engines": {
+ "node": ">= 10"
+ }
+ },
+ "node_modules/@resvg/resvg-js-darwin-x64": {
+ "version": "2.6.2",
+ "resolved": "https://registry.npmjs.org/@resvg/resvg-js-darwin-x64/-/resvg-js-darwin-x64-2.6.2.tgz",
+ "integrity": "sha512-GInyZLjgWDfsVT6+SHxQVRwNzV0AuA1uqGsOAW+0th56J7Nh6bHHKXHBWzUrihxMetcFDmQMAX1tZ1fZDYSRsw==",
+ "cpu": [
+ "x64"
+ ],
+ "license": "MPL-2.0",
+ "optional": true,
+ "os": [
+ "darwin"
+ ],
+ "engines": {
+ "node": ">= 10"
+ }
+ },
+ "node_modules/@resvg/resvg-js-linux-arm-gnueabihf": {
+ "version": "2.6.2",
+ "resolved": "https://registry.npmjs.org/@resvg/resvg-js-linux-arm-gnueabihf/-/resvg-js-linux-arm-gnueabihf-2.6.2.tgz",
+ "integrity": "sha512-YIV3u/R9zJbpqTTNwTZM5/ocWetDKGsro0SWp70eGEM9eV2MerWyBRZnQIgzU3YBnSBQ1RcxRZvY/UxwESfZIw==",
+ "cpu": [
+ "arm"
+ ],
+ "license": "MPL-2.0",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">= 10"
+ }
+ },
+ "node_modules/@resvg/resvg-js-linux-arm64-gnu": {
+ "version": "2.6.2",
+ "resolved": "https://registry.npmjs.org/@resvg/resvg-js-linux-arm64-gnu/-/resvg-js-linux-arm64-gnu-2.6.2.tgz",
+ "integrity": "sha512-zc2BlJSim7YR4FZDQ8OUoJg5holYzdiYMeobb9pJuGDidGL9KZUv7SbiD4E8oZogtYY42UZEap7dqkkYuA91pg==",
+ "cpu": [
+ "arm64"
+ ],
+ "libc": [
+ "glibc"
+ ],
+ "license": "MPL-2.0",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">= 10"
+ }
+ },
+ "node_modules/@resvg/resvg-js-linux-arm64-musl": {
+ "version": "2.6.2",
+ "resolved": "https://registry.npmjs.org/@resvg/resvg-js-linux-arm64-musl/-/resvg-js-linux-arm64-musl-2.6.2.tgz",
+ "integrity": "sha512-3h3dLPWNgSsD4lQBJPb4f+kvdOSJHa5PjTYVsWHxLUzH4IFTJUAnmuWpw4KqyQ3NA5QCyhw4TWgxk3jRkQxEKg==",
+ "cpu": [
+ "arm64"
+ ],
+ "libc": [
+ "musl"
+ ],
+ "license": "MPL-2.0",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">= 10"
+ }
+ },
+ "node_modules/@resvg/resvg-js-linux-x64-gnu": {
+ "version": "2.6.2",
+ "resolved": "https://registry.npmjs.org/@resvg/resvg-js-linux-x64-gnu/-/resvg-js-linux-x64-gnu-2.6.2.tgz",
+ "integrity": "sha512-IVUe+ckIerA7xMZ50duAZzwf1U7khQe2E0QpUxu5MBJNao5RqC0zwV/Zm965vw6D3gGFUl7j4m+oJjubBVoftw==",
+ "cpu": [
+ "x64"
+ ],
+ "libc": [
+ "glibc"
+ ],
+ "license": "MPL-2.0",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">= 10"
+ }
+ },
+ "node_modules/@resvg/resvg-js-linux-x64-musl": {
+ "version": "2.6.2",
+ "resolved": "https://registry.npmjs.org/@resvg/resvg-js-linux-x64-musl/-/resvg-js-linux-x64-musl-2.6.2.tgz",
+ "integrity": "sha512-UOf83vqTzoYQO9SZ0fPl2ZIFtNIz/Rr/y+7X8XRX1ZnBYsQ/tTb+cj9TE+KHOdmlTFBxhYzVkP2lRByCzqi4jQ==",
+ "cpu": [
+ "x64"
+ ],
+ "libc": [
+ "musl"
+ ],
+ "license": "MPL-2.0",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">= 10"
+ }
+ },
+ "node_modules/@resvg/resvg-js-win32-arm64-msvc": {
+ "version": "2.6.2",
+ "resolved": "https://registry.npmjs.org/@resvg/resvg-js-win32-arm64-msvc/-/resvg-js-win32-arm64-msvc-2.6.2.tgz",
+ "integrity": "sha512-7C/RSgCa+7vqZ7qAbItfiaAWhyRSoD4l4BQAbVDqRRsRgY+S+hgS3in0Rxr7IorKUpGE69X48q6/nOAuTJQxeQ==",
+ "cpu": [
+ "arm64"
+ ],
+ "license": "MPL-2.0",
+ "optional": true,
+ "os": [
+ "win32"
+ ],
+ "engines": {
+ "node": ">= 10"
+ }
+ },
+ "node_modules/@resvg/resvg-js-win32-ia32-msvc": {
+ "version": "2.6.2",
+ "resolved": "https://registry.npmjs.org/@resvg/resvg-js-win32-ia32-msvc/-/resvg-js-win32-ia32-msvc-2.6.2.tgz",
+ "integrity": "sha512-har4aPAlvjnLcil40AC77YDIk6loMawuJwFINEM7n0pZviwMkMvjb2W5ZirsNOZY4aDbo5tLx0wNMREp5Brk+w==",
+ "cpu": [
+ "ia32"
+ ],
+ "license": "MPL-2.0",
+ "optional": true,
+ "os": [
+ "win32"
+ ],
+ "engines": {
+ "node": ">= 10"
+ }
+ },
+ "node_modules/@resvg/resvg-js-win32-x64-msvc": {
+ "version": "2.6.2",
+ "resolved": "https://registry.npmjs.org/@resvg/resvg-js-win32-x64-msvc/-/resvg-js-win32-x64-msvc-2.6.2.tgz",
+ "integrity": "sha512-ZXtYhtUr5SSaBrUDq7DiyjOFJqBVL/dOBN7N/qmi/pO0IgiWW/f/ue3nbvu9joWE5aAKDoIzy/CxsY0suwGosQ==",
+ "cpu": [
+ "x64"
+ ],
+ "license": "MPL-2.0",
+ "optional": true,
+ "os": [
+ "win32"
+ ],
+ "engines": {
+ "node": ">= 10"
+ }
+ },
+ "node_modules/@types/q": {
+ "version": "1.5.8",
+ "resolved": "https://registry.npmjs.org/@types/q/-/q-1.5.8.tgz",
+ "integrity": "sha512-hroOstUScF6zhIi+5+x0dzqrHA1EJi+Irri6b1fxolMTqqHIV/Cg77EtnQcZqZCu8hR3mX2BzIxN4/GzI68Kfw==",
+ "license": "MIT"
+ },
+ "node_modules/abs-svg-path": {
+ "version": "0.1.1",
+ "resolved": "https://registry.npmjs.org/abs-svg-path/-/abs-svg-path-0.1.1.tgz",
+ "integrity": "sha512-d8XPSGjfyzlXC3Xx891DJRyZfqk5JU0BJrDQcsWomFIV1/BIzPW5HDH5iDdWpqWaav0YVIEzT1RHTwWr0FFshA==",
+ "license": "MIT"
+ },
+ "node_modules/ansi-styles": {
+ "version": "3.2.1",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz",
+ "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==",
+ "license": "MIT",
+ "dependencies": {
+ "color-convert": "^1.9.0"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/boolbase": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/boolbase/-/boolbase-1.0.0.tgz",
+ "integrity": "sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww==",
+ "license": "ISC"
+ },
+ "node_modules/chalk": {
+ "version": "2.4.2",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz",
+ "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==",
+ "license": "MIT",
+ "dependencies": {
+ "ansi-styles": "^3.2.1",
+ "escape-string-regexp": "^1.0.5",
+ "supports-color": "^5.3.0"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/coa": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/coa/-/coa-2.0.2.tgz",
+ "integrity": "sha512-q5/jG+YQnSy4nRTV4F7lPepBJZ8qBNJJDBuJdoejDyLXgmL7IEo+Le2JDZudFTFt7mrCqIRaSjws4ygRCTCAXA==",
+ "license": "MIT",
+ "dependencies": {
+ "@types/q": "^1.5.1",
+ "chalk": "^2.4.1",
+ "q": "^1.1.2"
+ },
+ "engines": {
+ "node": ">= 4.0"
+ }
+ },
+ "node_modules/color-convert": {
+ "version": "1.9.3",
+ "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz",
+ "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==",
+ "license": "MIT",
+ "dependencies": {
+ "color-name": "1.1.3"
+ }
+ },
+ "node_modules/color-name": {
+ "version": "1.1.3",
+ "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz",
+ "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==",
+ "license": "MIT"
+ },
+ "node_modules/commander": {
+ "version": "7.2.0",
+ "resolved": "https://registry.npmjs.org/commander/-/commander-7.2.0.tgz",
+ "integrity": "sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw==",
+ "license": "MIT",
+ "engines": {
+ "node": ">= 10"
+ }
+ },
+ "node_modules/css-select": {
+ "version": "4.3.0",
+ "resolved": "https://registry.npmjs.org/css-select/-/css-select-4.3.0.tgz",
+ "integrity": "sha512-wPpOYtnsVontu2mODhA19JrqWxNsfdatRKd64kmpRbQgh1KtItko5sTnEpPdpSaJszTOhEMlF/RPz28qj4HqhQ==",
+ "license": "BSD-2-Clause",
+ "dependencies": {
+ "boolbase": "^1.0.0",
+ "css-what": "^6.0.1",
+ "domhandler": "^4.3.1",
+ "domutils": "^2.8.0",
+ "nth-check": "^2.0.1"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/fb55"
+ }
+ },
+ "node_modules/css-tree": {
+ "version": "1.1.3",
+ "resolved": "https://registry.npmjs.org/css-tree/-/css-tree-1.1.3.tgz",
+ "integrity": "sha512-tRpdppF7TRazZrjJ6v3stzv93qxRcSsFmW6cX0Zm2NVKpxE1WV1HblnghVv9TreireHkqI/VDEsfolRF1p6y7Q==",
+ "license": "MIT",
+ "dependencies": {
+ "mdn-data": "2.0.14",
+ "source-map": "^0.6.1"
+ },
+ "engines": {
+ "node": ">=8.0.0"
+ }
+ },
+ "node_modules/css-what": {
+ "version": "6.2.2",
+ "resolved": "https://registry.npmjs.org/css-what/-/css-what-6.2.2.tgz",
+ "integrity": "sha512-u/O3vwbptzhMs3L1fQE82ZSLHQQfto5gyZzwteVIEyeaY5Fc7R4dapF/BvRoSYFeqfBk4m0V1Vafq5Pjv25wvA==",
+ "license": "BSD-2-Clause",
+ "engines": {
+ "node": ">= 6"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/fb55"
+ }
+ },
+ "node_modules/csso": {
+ "version": "4.2.0",
+ "resolved": "https://registry.npmjs.org/csso/-/csso-4.2.0.tgz",
+ "integrity": "sha512-wvlcdIbf6pwKEk7vHj8/Bkc0B4ylXZruLvOgs9doS5eOsOpuodOV2zJChSpkp+pRpYQLQMeF04nr3Z68Sta9jA==",
+ "license": "MIT",
+ "dependencies": {
+ "css-tree": "^1.1.2"
+ },
+ "engines": {
+ "node": ">=8.0.0"
+ }
+ },
+ "node_modules/dom-serializer": {
+ "version": "1.4.1",
+ "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-1.4.1.tgz",
+ "integrity": "sha512-VHwB3KfrcOOkelEG2ZOfxqLZdfkil8PtJi4P8N2MMXucZq2yLp75ClViUlOVwyoHEDjYU433Aq+5zWP61+RGag==",
+ "license": "MIT",
+ "dependencies": {
+ "domelementtype": "^2.0.1",
+ "domhandler": "^4.2.0",
+ "entities": "^2.0.0"
+ },
+ "funding": {
+ "url": "https://github.com/cheeriojs/dom-serializer?sponsor=1"
+ }
+ },
+ "node_modules/domelementtype": {
+ "version": "2.3.0",
+ "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-2.3.0.tgz",
+ "integrity": "sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw==",
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/fb55"
+ }
+ ],
+ "license": "BSD-2-Clause"
+ },
+ "node_modules/domhandler": {
+ "version": "4.3.1",
+ "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-4.3.1.tgz",
+ "integrity": "sha512-GrwoxYN+uWlzO8uhUXRl0P+kHE4GtVPfYzVLcUxPL7KNdHKj66vvlhiweIHqYYXWlw+T8iLMp42Lm67ghw4WMQ==",
+ "license": "BSD-2-Clause",
+ "dependencies": {
+ "domelementtype": "^2.2.0"
+ },
+ "engines": {
+ "node": ">= 4"
+ },
+ "funding": {
+ "url": "https://github.com/fb55/domhandler?sponsor=1"
+ }
+ },
+ "node_modules/domutils": {
+ "version": "2.8.0",
+ "resolved": "https://registry.npmjs.org/domutils/-/domutils-2.8.0.tgz",
+ "integrity": "sha512-w96Cjofp72M5IIhpjgobBimYEfoPjx1Vx0BSX9P30WBdZW2WIKU0T1Bd0kz2eNZ9ikjKgHbEyKx8BB6H1L3h3A==",
+ "license": "BSD-2-Clause",
+ "dependencies": {
+ "dom-serializer": "^1.0.1",
+ "domelementtype": "^2.2.0",
+ "domhandler": "^4.2.0"
+ },
+ "funding": {
+ "url": "https://github.com/fb55/domutils?sponsor=1"
+ }
+ },
+ "node_modules/entities": {
+ "version": "2.2.0",
+ "resolved": "https://registry.npmjs.org/entities/-/entities-2.2.0.tgz",
+ "integrity": "sha512-p92if5Nz619I0w+akJrLZH0MX0Pb5DX39XOwQTtXSdQQOaYH03S1uIQp4mhOZtAXrxq4ViO67YTiLBo2638o9A==",
+ "license": "BSD-2-Clause",
+ "funding": {
+ "url": "https://github.com/fb55/entities?sponsor=1"
+ }
+ },
+ "node_modules/escape-string-regexp": {
+ "version": "1.0.5",
+ "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz",
+ "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.8.0"
+ }
+ },
+ "node_modules/has-flag": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz",
+ "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/is-svg-path": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/is-svg-path/-/is-svg-path-1.0.2.tgz",
+ "integrity": "sha512-Lj4vePmqpPR1ZnRctHv8ltSh1OrSxHkhUkd7wi+VQdcdP15/KvQFyk7LhNuM7ZW0EVbJz8kZLVmL9quLrfq4Kg==",
+ "license": "MIT"
+ },
+ "node_modules/mdn-data": {
+ "version": "2.0.14",
+ "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.0.14.tgz",
+ "integrity": "sha512-dn6wd0uw5GsdswPFfsgMp5NSB0/aDe6fK94YJV/AJDYXL6HVLWBsxeq7js7Ad+mU2K9LAlwpk6kN2D5mwCPVow==",
+ "license": "CC0-1.0"
+ },
+ "node_modules/mkdirp": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz",
+ "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==",
+ "license": "MIT",
+ "bin": {
+ "mkdirp": "bin/cmd.js"
+ },
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/normalize-svg-path": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/normalize-svg-path/-/normalize-svg-path-1.1.0.tgz",
+ "integrity": "sha512-r9KHKG2UUeB5LoTouwDzBy2VxXlHsiM6fyLQvnJa0S5hrhzqElH/CH7TUGhT1fVvIYBIKf3OpY4YJ4CK+iaqHg==",
+ "license": "MIT",
+ "dependencies": {
+ "svg-arc-to-cubic-bezier": "^3.0.0"
+ }
+ },
+ "node_modules/nth-check": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/nth-check/-/nth-check-2.1.1.tgz",
+ "integrity": "sha512-lqjrjmaOoAnWfMmBPL+XNnynZh2+swxiX3WUE0s4yEHI6m+AwrK2UZOimIRl3X/4QctVqS8AiZjFqyOGrMXb/w==",
+ "license": "BSD-2-Clause",
+ "dependencies": {
+ "boolbase": "^1.0.0"
+ },
+ "funding": {
+ "url": "https://github.com/fb55/nth-check?sponsor=1"
+ }
+ },
+ "node_modules/parse-svg-path": {
+ "version": "0.1.2",
+ "resolved": "https://registry.npmjs.org/parse-svg-path/-/parse-svg-path-0.1.2.tgz",
+ "integrity": "sha512-JyPSBnkTJ0AI8GGJLfMXvKq42cj5c006fnLz6fXy6zfoVjJizi8BNTpu8on8ziI1cKy9d9DGNuY17Ce7wuejpQ==",
+ "license": "MIT"
+ },
+ "node_modules/picocolors": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz",
+ "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==",
+ "license": "ISC"
+ },
+ "node_modules/q": {
+ "version": "1.5.1",
+ "resolved": "https://registry.npmjs.org/q/-/q-1.5.1.tgz",
+ "integrity": "sha512-kV/CThkXo6xyFEZUugw/+pIOywXcDbFYgSct5cT3gqlbkBE1SJdwy6UQoZvodiWF/ckQLZyDE/Bu1M6gVu5lVw==",
+ "deprecated": "You or someone you depend on is using Q, the JavaScript Promise library that gave JavaScript developers strong feelings about promises. They can almost certainly migrate to the native JavaScript promise now. Thank you literally everyone for joining me in this bet against the odds. Be excellent to each other.\n\n(For a CapTP with native promises, see @endo/eventual-send and @endo/captp)",
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.6.0",
+ "teleport": ">=0.2.0"
+ }
+ },
+ "node_modules/sax": {
+ "version": "1.6.1",
+ "resolved": "https://registry.npmjs.org/sax/-/sax-1.6.1.tgz",
+ "integrity": "sha512-42tBVwLWnaQvW5zc4HbZrTuWccECCZfBi92FDuwtqxasH+JbPB3/FOKb1m222K42R4WxuxzzMsTswfzgtSu64Q==",
+ "license": "BlueOak-1.0.0",
+ "engines": {
+ "node": ">=11.0.0"
+ }
+ },
+ "node_modules/source-map": {
+ "version": "0.6.1",
+ "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
+ "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
+ "license": "BSD-3-Clause",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/stable": {
+ "version": "0.1.8",
+ "resolved": "https://registry.npmjs.org/stable/-/stable-0.1.8.tgz",
+ "integrity": "sha512-ji9qxRnOVfcuLDySj9qzhGSEFVobyt1kIOSkj1qZzYLzq7Tos/oUUWvotUPQLlrsidqsK6tBH89Bc9kL5zHA6w==",
+ "deprecated": "Modern JS already guarantees Array#sort() is a stable sort, so this library is deprecated. See the compatibility table on MDN: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/sort#browser_compatibility",
+ "license": "MIT"
+ },
+ "node_modules/supports-color": {
+ "version": "5.5.0",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz",
+ "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==",
+ "license": "MIT",
+ "dependencies": {
+ "has-flag": "^3.0.0"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/svg-arc-to-cubic-bezier": {
+ "version": "3.2.0",
+ "resolved": "https://registry.npmjs.org/svg-arc-to-cubic-bezier/-/svg-arc-to-cubic-bezier-3.2.0.tgz",
+ "integrity": "sha512-djbJ/vZKZO+gPoSDThGNpKDO+o+bAeA4XQKovvkNCqnIS2t+S4qnLAGQhyyrulhCFRl1WWzAp0wUDV8PpTVU3g==",
+ "license": "ISC"
+ },
+ "node_modules/svg-path-bounds": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/svg-path-bounds/-/svg-path-bounds-1.0.2.tgz",
+ "integrity": "sha512-H4/uAgLWrppIC0kHsb2/dWUYSmb4GE5UqH06uqWBcg6LBjX2fu0A8+JrO2/FJPZiSsNOKZAhyFFgsLTdYUvSqQ==",
+ "license": "MIT",
+ "dependencies": {
+ "abs-svg-path": "^0.1.1",
+ "is-svg-path": "^1.0.1",
+ "normalize-svg-path": "^1.0.0",
+ "parse-svg-path": "^0.1.2"
+ }
+ },
+ "node_modules/svg2vectordrawable": {
+ "version": "2.9.1",
+ "resolved": "https://registry.npmjs.org/svg2vectordrawable/-/svg2vectordrawable-2.9.1.tgz",
+ "integrity": "sha512-7WJIh4SzZLyEJtn45y+f8rREkgBiQMWfb0FoYkXuioywESjDWfbSuP0FQEmIiHP2zOi0oOO8pTG4VkeWJyidWw==",
+ "license": "MIT",
+ "dependencies": {
+ "coa": "^2.0.2",
+ "mkdirp": "^1.0.4",
+ "svg-path-bounds": "^1.0.1",
+ "svgo": "^2.8.0",
+ "svgpath": "^2.5.0"
+ },
+ "bin": {
+ "s2v": "bin/svg2vectordrawable",
+ "svg2android": "bin/svg2vectordrawable",
+ "svg2avd": "bin/svg2vectordrawable",
+ "svg2drawable": "bin/svg2vectordrawable",
+ "svg2vector": "bin/svg2vectordrawable",
+ "svg2vectordrawable": "bin/svg2vectordrawable"
+ },
+ "engines": {
+ "node": ">=8.0.0"
+ }
+ },
+ "node_modules/svgo": {
+ "version": "2.8.3",
+ "resolved": "https://registry.npmjs.org/svgo/-/svgo-2.8.3.tgz",
+ "integrity": "sha512-5EZD0pafXX6PphdwOGCiVLDSaV1xyuQao2blHajHLsPxr07q4mmEjdtXEWgG07ae2mIz8Ex2CDXNCTiXhy3Khw==",
+ "license": "MIT",
+ "dependencies": {
+ "commander": "^7.2.0",
+ "css-select": "^4.1.3",
+ "css-tree": "^1.1.3",
+ "csso": "^4.2.0",
+ "picocolors": "^1.0.0",
+ "sax": "^1.5.0",
+ "stable": "^0.1.8"
+ },
+ "bin": {
+ "svgo": "bin/svgo"
+ },
+ "engines": {
+ "node": ">=10.13.0"
+ }
+ },
+ "node_modules/svgpath": {
+ "version": "2.6.0",
+ "resolved": "https://registry.npmjs.org/svgpath/-/svgpath-2.6.0.tgz",
+ "integrity": "sha512-OIWR6bKzXvdXYyO4DK/UWa1VA1JeKq8E+0ug2DG98Y/vOmMpfZNj+TIG988HjfYSqtcy/hFOtZq/n/j5GSESNg==",
+ "license": "MIT",
+ "funding": {
+ "url": "https://github.com/fontello/svg2ttf?sponsor=1"
+ }
+ }
+ }
+}
diff --git a/tools/icon-generator/package.json b/tools/icon-generator/package.json
index 942e604..b02ede7 100644
--- a/tools/icon-generator/package.json
+++ b/tools/icon-generator/package.json
@@ -2,7 +2,7 @@
"name": "inputflow-icons",
"version": "1.0.0",
"private": true,
- "description": "InputFlow donkey icon set — Linux hicolor + Android adaptive/notification + Play Store",
+ "description": "InputFlow device-flow icon set — Linux hicolor + Android adaptive/notification + Play Store",
"scripts": {
"masters": "node build-masters.js",
"build": "node build.js"