diff --git a/README.md b/README.md
index cba8f56..0c7d85f 100644
--- a/README.md
+++ b/README.md
@@ -28,13 +28,17 @@
Проверки: полный клиентский прогон — 1189 прошли, 3 пропущены; сервер — 150 прошли, без пропусков. Анализ `lib` и `test` не выявил ошибок и предупреждений, остались 42 информационных замечания стиля. Проверены выбор качества видео, сохранение темы, доступ к расшифрованному тексту, жесты, переключение невидимости, переподключение и сохранение публичной активности при обновлении схемы. Локальные отчёты: `artifacts/komet-full-flutter-tests.log`, `artifacts/komet-server-tests.log`, `artifacts/komet-implementation-analyze.log`.
-Эти изменения относятся к исходникам клиента и сервера. Для использования на телефоне нужны обновление сервера и сборка нового APK; текущий опубликованный выпуск их не содержит. Новый APK, развёртывание и проверка этих изменений на телефоне в этой задаче не выполнялись.
+Рабочий API обновлён до `releases/20261007-komet`. Проверены совпадение SHA-256 серверной сборки, целостность рабочей базы и резервной копии, новая колонка публичной активности, `/health`, отсутствие перезапусков API и сохранность соседних контейнеров. Резервная копия перед обновлением: `/mnt/data/ikar_server/backups/ikar-20261007T191617Z.tar.gz`; предыдущий выпуск сохранён для отката. Через публичный HTTPS прошли 15 общих проверок API, 8 проверок невидимости и 5 проверок видео. Они охватывают регистрацию, доставку и историю, права доступа, файлы, речь на Pi, группы, каналы, реакции, опросы, отложенную отправку и сигнализацию звонков. Невидимая сессия получает сообщения и приглашения звонка, не меняя публичное время активности. Отчёты: `artifacts/deployment-komet.json`, `artifacts/ghost-live-verification.json`, `artifacts/live-smoke.json`, `artifacts/video-live-verification.json`.
+
+Главная иконка содержит только рисунок Икара без надписей. Размер рисунка — около 90% диаметра круглой области; адаптивный слой учитывает расширение Android с 72 до 108 dp. Исходный рисунок — `assets/ikar_mark.png`, основные ресурсы — `assets/ikar_icon.png` и `assets/ikar.png`. Пересоздание: `dart run tool/make_ikar_icons.dart`, затем `dart run flutter_launcher_icons`. Ресурсы основной иконки обновлены для Android, iOS, Windows и macOS; альтернативная иконка сохранена.
+
+Новая иконка и клиентские изменения требуют нового APK; текущий опубликованный выпуск их не содержит. Выпуск APK и проверка этих клиентских изменений на телефоне в этой задаче не выполнялись.
## Размещение на Pi
Внешний диск: `/mnt/data` (`/dev/sdb1`, ext4). Корень новой установки: `/mnt/data/ikar_server`.
-- `current` — ссылка на действующий выпуск в `releases/20261007-video`;
+- `current` — ссылка на действующий выпуск в `releases/20261007-komet`;
- `shared/data` — SQLite, вложения, данные устройств и публикация APK;
- `shared/server.env`, `shared/turn.env` — закрытые настройки, доступ 0600;
- `backups` — ежедневные согласованные копии SQLite и вложений, хранение 14 дней;
diff --git a/android/app/src/main/res/drawable-hdpi/ic_launcher_foreground.png b/android/app/src/main/res/drawable-hdpi/ic_launcher_foreground.png
index 8729deb..d122dba 100644
Binary files a/android/app/src/main/res/drawable-hdpi/ic_launcher_foreground.png and b/android/app/src/main/res/drawable-hdpi/ic_launcher_foreground.png differ
diff --git a/android/app/src/main/res/drawable-mdpi/ic_launcher_foreground.png b/android/app/src/main/res/drawable-mdpi/ic_launcher_foreground.png
index ac7da43..e793c69 100644
Binary files a/android/app/src/main/res/drawable-mdpi/ic_launcher_foreground.png and b/android/app/src/main/res/drawable-mdpi/ic_launcher_foreground.png differ
diff --git a/android/app/src/main/res/drawable-xhdpi/ic_launcher_foreground.png b/android/app/src/main/res/drawable-xhdpi/ic_launcher_foreground.png
index dd946df..382eeb6 100644
Binary files a/android/app/src/main/res/drawable-xhdpi/ic_launcher_foreground.png and b/android/app/src/main/res/drawable-xhdpi/ic_launcher_foreground.png differ
diff --git a/android/app/src/main/res/drawable-xxhdpi/ic_launcher_foreground.png b/android/app/src/main/res/drawable-xxhdpi/ic_launcher_foreground.png
index e096210..eae8e19 100644
Binary files a/android/app/src/main/res/drawable-xxhdpi/ic_launcher_foreground.png and b/android/app/src/main/res/drawable-xxhdpi/ic_launcher_foreground.png differ
diff --git a/android/app/src/main/res/drawable-xxxhdpi/ic_launcher_foreground.png b/android/app/src/main/res/drawable-xxxhdpi/ic_launcher_foreground.png
index e230b01..c667494 100644
Binary files a/android/app/src/main/res/drawable-xxxhdpi/ic_launcher_foreground.png and b/android/app/src/main/res/drawable-xxxhdpi/ic_launcher_foreground.png differ
diff --git a/android/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml b/android/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml
index c79c58a..c0be12a 100644
--- a/android/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml
+++ b/android/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml
@@ -4,6 +4,6 @@
+ android:inset="0%" />
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 1f1def6..a07e094 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-mdpi/ic_launcher.png b/android/app/src/main/res/mipmap-mdpi/ic_launcher.png
index 8a2a551..2cd0051 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-xhdpi/ic_launcher.png b/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png
index 7d31012..3f4cd85 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-xxhdpi/ic_launcher.png b/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png
index 22a3a0e..562f7e2 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-xxxhdpi/ic_launcher.png b/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png
index 9250ea8..7d5d84f 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/values/colors.xml b/android/app/src/main/res/values/colors.xml
index 7d5be24..e6dce57 100644
--- a/android/app/src/main/res/values/colors.xml
+++ b/android/app/src/main/res/values/colors.xml
@@ -1,5 +1,5 @@
- #000000
+ #FFFFFF
#000000
\ No newline at end of file
diff --git a/assets/ikar.png b/assets/ikar.png
index c386a28..ebfa5c0 100644
Binary files a/assets/ikar.png and b/assets/ikar.png differ
diff --git a/assets/ikar_icon.png b/assets/ikar_icon.png
index c27464b..f36f83e 100644
Binary files a/assets/ikar_icon.png and b/assets/ikar_icon.png differ
diff --git a/assets/ikar_mark.png b/assets/ikar_mark.png
new file mode 100644
index 0000000..1869e09
Binary files /dev/null and b/assets/ikar_mark.png differ
diff --git a/assets/ikar_mark.prompt.txt b/assets/ikar_mark.prompt.txt
new file mode 100644
index 0000000..d9cda28
--- /dev/null
+++ b/assets/ikar_mark.prompt.txt
@@ -0,0 +1,8 @@
+Mode: built-in image_gen imagegen tool.
+Edit targets: original assets/ikar_icon.png and assets/ikar.png.
+Generated source: assets/ikar_mark.png.
+
+Use case: precise-object-edit / background-extraction. Edit target: image 1 is the existing IKAR app emblem, image 2 shows the same existing emblem with text that must be removed. Produce one clean square PNG launcher foreground with real transparent background. Keep ONLY the existing illustrated winged Icarus figure and its two chat bubbles and golden sun, exactly matching the existing shapes, pose, colors and visual identity. Remove ALL text including ИКАР, МЕССЕНДЖЕР, underlines, sparkle, and remove the near-white background and the ground/drop shadow. Do not redesign, do not add objects, do not turn chat bubbles into text. Center the complete emblem as a single composition, scale it to occupy approximately 90 percent of a circle centered in the square: entire emblem must fit fully inside a circle of radius 45 percent of canvas side, with nothing clipped. Preserve the cyan/blue wings, golden wing and sun, white bubble interiors and dotted bubble details. Output is just the cleaned icon art on genuine alpha transparency; no circle outline, no mockup, no labels, no watermark.
+
+Launcher packaging: tool/make_ikar_icons.dart scales and centers the generated artwork for a 90 percent circular footprint. Android adaptive foreground uses a 72/108 viewport ratio and 0 percent additional XML inset. Background is white.
+Android layer reference: https://developer.android.com/develop/ui/compose/system/icon_design_adaptive
diff --git a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png
index 39a6c10..b7f95ce 100644
Binary files a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png and b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png differ
diff --git a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png
index 688aa27..bd9be3e 100644
Binary files a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png and b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png differ
diff --git a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png
index 5eb3f45..22beb5e 100644
Binary files a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png and b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png differ
diff --git a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png
index 8f47d1a..fd3bb43 100644
Binary files a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png and b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png differ
diff --git a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png
index 8be303b..3c3bb99 100644
Binary files a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png and b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png differ
diff --git a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png
index 236ff14..c97ae49 100644
Binary files a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png and b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png differ
diff --git a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png
index b6f1101..f62f088 100644
Binary files a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png and b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png differ
diff --git a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png
index 5eb3f45..22beb5e 100644
Binary files a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png and b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png differ
diff --git a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png
index c91493d..99fa1a2 100644
Binary files a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png and b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png differ
diff --git a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png
index 7915106..8f89acf 100644
Binary files a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png and b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png differ
diff --git a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-50x50@1x.png b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-50x50@1x.png
index 409a1dc..f5b00c9 100644
Binary files a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-50x50@1x.png and b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-50x50@1x.png differ
diff --git a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-50x50@2x.png b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-50x50@2x.png
index 2d739a9..499e091 100644
Binary files a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-50x50@2x.png and b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-50x50@2x.png differ
diff --git a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-57x57@1x.png b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-57x57@1x.png
index 2ed78bc..61145fa 100644
Binary files a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-57x57@1x.png and b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-57x57@1x.png differ
diff --git a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-57x57@2x.png b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-57x57@2x.png
index 82444eb..0012467 100644
Binary files a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-57x57@2x.png and b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-57x57@2x.png differ
diff --git a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png
index 7915106..8f89acf 100644
Binary files a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png and b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png differ
diff --git a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png
index 98c42ab..01a6113 100644
Binary files a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png and b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png differ
diff --git a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-72x72@1x.png b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-72x72@1x.png
index be7a197..9ceee33 100644
Binary files a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-72x72@1x.png and b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-72x72@1x.png differ
diff --git a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-72x72@2x.png b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-72x72@2x.png
index fc76b4f..699f45c 100644
Binary files a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-72x72@2x.png and b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-72x72@2x.png differ
diff --git a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png
index c8c8ea3..5ef8eb6 100644
Binary files a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png and b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png differ
diff --git a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png
index 00226da..9ef27ec 100644
Binary files a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png and b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png differ
diff --git a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png
index 6df7d16..de4e972 100644
Binary files a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png and b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png differ
diff --git a/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_1024.png b/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_1024.png
index 9d0de26..f36f83e 100644
Binary files a/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_1024.png and b/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_1024.png differ
diff --git a/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_128.png b/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_128.png
index 842463a..0a5dc58 100644
Binary files a/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_128.png and b/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_128.png differ
diff --git a/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_16.png b/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_16.png
index 2f66cd3..e9b9053 100644
Binary files a/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_16.png and b/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_16.png differ
diff --git a/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_256.png b/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_256.png
index 7d78e0e..089c3f1 100644
Binary files a/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_256.png and b/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_256.png differ
diff --git a/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_32.png b/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_32.png
index 07a6eec..c0e0741 100644
Binary files a/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_32.png and b/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_32.png differ
diff --git a/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_512.png b/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_512.png
index 4071979..0c202f7 100644
Binary files a/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_512.png and b/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_512.png differ
diff --git a/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_64.png b/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_64.png
index 5f5b5d7..d7e8209 100644
Binary files a/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_64.png and b/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_64.png differ
diff --git a/pubspec.yaml b/pubspec.yaml
index d20060a..af12d1c 100644
--- a/pubspec.yaml
+++ b/pubspec.yaml
@@ -140,9 +140,10 @@ flutter_launcher_icons:
android: "ic_launcher"
ios: true
remove_alpha_ios: true
- background_color_ios: "#000000"
- adaptive_icon_background: "#000000"
+ background_color_ios: "#FFFFFF"
+ adaptive_icon_background: "#FFFFFF"
adaptive_icon_foreground: "assets/ikar.png"
+ adaptive_icon_foreground_inset: 0
windows:
generate: true
image_path: "assets/ikar_icon.png"
diff --git a/tool/make_ikar_icons.dart b/tool/make_ikar_icons.dart
new file mode 100644
index 0000000..25ae651
--- /dev/null
+++ b/tool/make_ikar_icons.dart
@@ -0,0 +1,84 @@
+import 'dart:io';
+import 'dart:math' as math;
+import 'package:image/image.dart' as img;
+
+const _size = 1024;
+const _coverage = 0.90;
+
+void main() {
+ final source = img.decodePng(File('assets/ikar_mark.png').readAsBytesSync())!;
+ var left = source.width;
+ var top = source.height;
+ var right = 0;
+ var bottom = 0;
+ for (final pixel in source) {
+ if (pixel.a < 128) continue;
+ left = math.min(left, pixel.x);
+ top = math.min(top, pixel.y);
+ right = math.max(right, pixel.x);
+ bottom = math.max(bottom, pixel.y);
+ }
+ final artwork = img.copyCrop(
+ source,
+ x: left,
+ y: top,
+ width: right - left + 1,
+ height: bottom - top + 1,
+ );
+ var radius = 0.0;
+ for (final pixel in artwork) {
+ if (pixel.a < 128) continue;
+ final dx = pixel.x + 0.5 - artwork.width / 2;
+ final dy = pixel.y + 0.5 - artwork.height / 2;
+ radius = math.max(radius, math.sqrt(dx * dx + dy * dy));
+ }
+
+ img.Image render(double viewportFraction, {required bool opaque}) {
+ final targetRadius = _size * viewportFraction * _coverage / 2 - 1;
+ final scale = targetRadius / radius;
+ final scaled = img.copyResize(
+ artwork,
+ width: (artwork.width * scale).round(),
+ height: (artwork.height * scale).round(),
+ interpolation: img.Interpolation.cubic,
+ );
+ final canvas = img.Image(width: _size, height: _size, numChannels: 4);
+ if (opaque) img.fill(canvas, color: img.ColorRgba8(255, 255, 255, 255));
+ img.compositeImage(
+ canvas,
+ scaled,
+ dstX: (_size - scaled.width) ~/ 2,
+ dstY: (_size - scaled.height) ~/ 2,
+ );
+ return canvas;
+ }
+
+ final icon = render(1, opaque: true);
+ final foreground = render(72 / 108, opaque: false);
+ File('assets/ikar_icon.png').writeAsBytesSync(img.encodePng(icon));
+ File('assets/ikar.png').writeAsBytesSync(img.encodePng(foreground));
+ Directory('artifacts').createSync(recursive: true);
+ final preview = img.copyResize(icon, width: 512, height: 512);
+ for (final pixel in preview) {
+ final dx = pixel.x + 0.5 - 256;
+ final dy = pixel.y + 0.5 - 256;
+ if (dx * dx + dy * dy > 256 * 256) pixel.a = 0;
+ }
+ File(
+ 'artifacts/ikar-icon-circle.png',
+ ).writeAsBytesSync(img.encodePng(preview));
+ var actualRadius = 0.0;
+ for (final pixel in foreground) {
+ if (pixel.a < 128) continue;
+ final dx = pixel.x + 0.5 - _size / 2;
+ final dy = pixel.y + 0.5 - _size / 2;
+ actualRadius = math.max(actualRadius, math.sqrt(dx * dx + dy * dy));
+ }
+ final actualCoverage = actualRadius / (_size * (72 / 108) / 2);
+ if ((actualCoverage - _coverage).abs() > 0.01) {
+ throw StateError('Unexpected circular coverage: $actualCoverage');
+ }
+ stdout.writeln(
+ 'Circular artwork coverage: ${(actualCoverage * 100).toStringAsFixed(1)}%',
+ );
+}
diff --git a/windows/runner/resources/app_icon.ico b/windows/runner/resources/app_icon.ico
index 6ffea8a..2005a21 100644
Binary files a/windows/runner/resources/app_icon.ico and b/windows/runner/resources/app_icon.ico differ