diff --git a/AGENTS.md b/AGENTS.md index 57846e0..affd06f 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -29,7 +29,8 @@ BalanceWatch/ ├── README.md ├── .github/workflows/build.yml # CI: сборка для симулятора и устройства ├── docs/CONTRACT_V2.md # общий контракт экосистемы v2 (копия) -├── branding/ # аватар репозитория, не входит в бандл +├── branding/ # icon.svg, avatar, banner, render.sh; не входит в бандл +├── docs/ # CONTRACT_V2.md, скриншоты для баннера ├── BalanceWatch.xcodeproj/ # один таргет и одна схема — BalanceWatch └── BalanceWatch/ ├── App/ @@ -210,3 +211,11 @@ SwiftData/SwiftUI, а `FinanceCalculations` работает через прот - [ ] Секреты и токены не попали в репозиторий и логи. - [ ] CI собирает проект для симулятора и для устройства. - [ ] README/AGENTS.md обновлены, если поменялась структура или сборка. + +## Оформление + +- Цвета интерфейса — только из `BalancePalette` (`Shared/AppTheme.swift`), + палитра «Лес», общая с BalanceFlutter. Не возвращай indigo/purple. +- Иконка, аватар и баннер рендерятся из SVG: `bash branding/render.sh` + (нужен `resvg`). PNG в `AppIcon.appiconset` руками не правь. +- Аватар репозитория в Gitea обновляется из `branding/avatar.png`. diff --git a/BalanceWatch/App/BalanceWatchApp.swift b/BalanceWatch/App/BalanceWatchApp.swift index 2d32453..e1aae93 100644 --- a/BalanceWatch/App/BalanceWatchApp.swift +++ b/BalanceWatch/App/BalanceWatchApp.swift @@ -11,7 +11,7 @@ struct BalanceWatchApp: App { WindowGroup { WatchRootView() .id(ledgerScope) - .tint(.indigo) + .tint(BalancePalette.accent) .preferredColorScheme(AppTheme(rawValue: appTheme)?.colorScheme) .modelContainer(containers.container(for: ledgerScope)) } diff --git a/BalanceWatch/App/WatchAccountsView.swift b/BalanceWatch/App/WatchAccountsView.swift index 5af6157..feb0796 100644 --- a/BalanceWatch/App/WatchAccountsView.swift +++ b/BalanceWatch/App/WatchAccountsView.swift @@ -80,7 +80,7 @@ struct WatchAccountsView: View { VStack(alignment: .leading) { Text(title).lineLimit(1) Text(Money.double(cents).formattedCurrency(code: code)) - .font(.caption2).foregroundStyle(cents < 0 ? .red : .secondary) + .font(.caption2).foregroundStyle(cents < 0 ? BalancePalette.expense : .secondary) } } } diff --git a/BalanceWatch/App/WatchFeatures.swift b/BalanceWatch/App/WatchFeatures.swift index f6389f6..33053f9 100644 --- a/BalanceWatch/App/WatchFeatures.swift +++ b/BalanceWatch/App/WatchFeatures.swift @@ -55,8 +55,8 @@ struct WatchAnalyticsView: View { } Section("Итоги") { - metric("Доходы", summary.income, .green) - metric("Расходы", summary.expenses, .red) + metric("Доходы", summary.income, BalancePalette.income) + metric("Расходы", summary.expenses, BalancePalette.expense) LabeledContent("Результат", value: summary.balance.formattedCurrency(code: currencyCode)) LabeledContent( "Сбережения", @@ -100,7 +100,7 @@ struct WatchAnalyticsView: View { private func tint(for item: CategorySpending) -> Color { item.colorName == "auto" - ? FinanceCategory.find(named: item.name)?.tint ?? .indigo + ? FinanceCategory.find(named: item.name)?.tint ?? BalancePalette.forest : FinanceCategory.color(named: item.colorName) } } @@ -173,7 +173,7 @@ struct WatchTransactionsView: View { private func tint(_ transaction: FinanceTransaction) -> Color { transaction.categoryColorName == "auto" - ? FinanceCategory.find(named: transaction.categoryName)?.tint ?? .indigo + ? FinanceCategory.find(named: transaction.categoryName)?.tint ?? BalancePalette.forest : FinanceCategory.color(named: transaction.categoryColorName) } } diff --git a/BalanceWatch/App/WatchRootView.swift b/BalanceWatch/App/WatchRootView.swift index 433c71a..39ce147 100644 --- a/BalanceWatch/App/WatchRootView.swift +++ b/BalanceWatch/App/WatchRootView.swift @@ -33,9 +33,13 @@ private struct WatchHomeView: View { ScrollView { VStack(alignment: .leading, spacing: 12) { VStack(alignment: .leading, spacing: 3) { - Text("Общий баланс") - .font(.caption) - .foregroundStyle(.secondary) + HStack(spacing: 5) { + Image(systemName: "wallet.bifold") + .font(.caption2.weight(.semibold)) + Text("Общий баланс") + .font(.caption) + } + .foregroundStyle(BalancePalette.mint.opacity(0.85)) Text(total.value.formattedCurrency(code: currencyCode)) .font(.title3.bold()) .minimumScaleFactor(0.7) @@ -49,7 +53,7 @@ private struct WatchHomeView: View { .padding(12) .background( LinearGradient( - colors: [.indigo, .purple], + colors: [BalancePalette.cardTop, BalancePalette.cardBottom], startPoint: .topLeading, endPoint: .bottomTrailing ), @@ -60,13 +64,15 @@ private struct WatchHomeView: View { HStack(spacing: 8) { watchMetric( title: "Доходы", + symbol: "arrow.down.left", amount: monthSummary.income, - tint: .green + tint: BalancePalette.income ) watchMetric( title: "Расходы", + symbol: "arrow.up.right", amount: monthSummary.expenses, - tint: .red + tint: BalancePalette.expense ) } @@ -77,6 +83,7 @@ private struct WatchHomeView: View { .frame(maxWidth: .infinity) } .buttonStyle(.borderedProminent) + .tint(BalancePalette.forest) VStack(spacing: 4) { if account.supportsV2 { @@ -137,7 +144,7 @@ private struct WatchHomeView: View { Text((transaction.kind == .income ? "+" : "−") + transaction.amount.formattedCurrency(code: currency.currency(of: transaction))) .font(.caption2.weight(.semibold)) - .foregroundStyle(transaction.kind == .income ? .green : .secondary) + .foregroundStyle(transaction.kind == .income ? BalancePalette.income : .secondary) } Spacer() } @@ -158,25 +165,38 @@ private struct WatchHomeView: View { } } - private func watchMetric(title: String, amount: Double, tint: Color) -> some View { + private func watchMetric(title: String, symbol: String, amount: Double, tint: Color) -> some View { VStack(alignment: .leading, spacing: 3) { - Text(title) + Label(title, systemImage: symbol) .font(.caption2) .foregroundStyle(.secondary) + .labelStyle(TintedIconLabelStyle(tint: tint)) Text(amount.formattedCurrency(code: currencyCode)) .font(.caption.bold()) + .foregroundStyle(tint) .lineLimit(1) .minimumScaleFactor(0.65) } .frame(maxWidth: .infinity, alignment: .leading) .padding(9) - .background(tint.opacity(0.12), in: RoundedRectangle(cornerRadius: 12)) + .background(tint.opacity(0.14), in: RoundedRectangle(cornerRadius: 12)) } private func transactionTint(_ transaction: FinanceTransaction) -> Color { if transaction.categoryColorName == "auto" { - return FinanceCategory.find(named: transaction.categoryName)?.tint ?? .indigo + return FinanceCategory.find(named: transaction.categoryName)?.tint ?? BalancePalette.forest } return FinanceCategory.color(named: transaction.categoryColorName) } } + +/// Иконка метрики в цвете метрики, подпись — вторичным цветом. +private struct TintedIconLabelStyle: LabelStyle { + let tint: Color + func makeBody(configuration: Configuration) -> some View { + HStack(spacing: 3) { + configuration.icon.foregroundStyle(tint) + configuration.title + } + } +} diff --git a/BalanceWatch/Assets.xcassets/AppIcon.appiconset/BalanceIcon-100.png b/BalanceWatch/Assets.xcassets/AppIcon.appiconset/BalanceIcon-100.png index 5375cd4..94e3168 100644 Binary files a/BalanceWatch/Assets.xcassets/AppIcon.appiconset/BalanceIcon-100.png and b/BalanceWatch/Assets.xcassets/AppIcon.appiconset/BalanceIcon-100.png differ diff --git a/BalanceWatch/Assets.xcassets/AppIcon.appiconset/BalanceIcon-102.png b/BalanceWatch/Assets.xcassets/AppIcon.appiconset/BalanceIcon-102.png index bd70565..f764bdf 100644 Binary files a/BalanceWatch/Assets.xcassets/AppIcon.appiconset/BalanceIcon-102.png and b/BalanceWatch/Assets.xcassets/AppIcon.appiconset/BalanceIcon-102.png differ diff --git a/BalanceWatch/Assets.xcassets/AppIcon.appiconset/BalanceIcon-1024.png b/BalanceWatch/Assets.xcassets/AppIcon.appiconset/BalanceIcon-1024.png index 2c212db..52ce2df 100644 Binary files a/BalanceWatch/Assets.xcassets/AppIcon.appiconset/BalanceIcon-1024.png and b/BalanceWatch/Assets.xcassets/AppIcon.appiconset/BalanceIcon-1024.png differ diff --git a/BalanceWatch/Assets.xcassets/AppIcon.appiconset/BalanceIcon-108.png b/BalanceWatch/Assets.xcassets/AppIcon.appiconset/BalanceIcon-108.png index 6c375f4..64d25e6 100644 Binary files a/BalanceWatch/Assets.xcassets/AppIcon.appiconset/BalanceIcon-108.png and b/BalanceWatch/Assets.xcassets/AppIcon.appiconset/BalanceIcon-108.png differ diff --git a/BalanceWatch/Assets.xcassets/AppIcon.appiconset/BalanceIcon-172.png b/BalanceWatch/Assets.xcassets/AppIcon.appiconset/BalanceIcon-172.png index 043000f..68243a6 100644 Binary files a/BalanceWatch/Assets.xcassets/AppIcon.appiconset/BalanceIcon-172.png and b/BalanceWatch/Assets.xcassets/AppIcon.appiconset/BalanceIcon-172.png differ diff --git a/BalanceWatch/Assets.xcassets/AppIcon.appiconset/BalanceIcon-196.png b/BalanceWatch/Assets.xcassets/AppIcon.appiconset/BalanceIcon-196.png index 3983c3d..7862670 100644 Binary files a/BalanceWatch/Assets.xcassets/AppIcon.appiconset/BalanceIcon-196.png and b/BalanceWatch/Assets.xcassets/AppIcon.appiconset/BalanceIcon-196.png differ diff --git a/BalanceWatch/Assets.xcassets/AppIcon.appiconset/BalanceIcon-216.png b/BalanceWatch/Assets.xcassets/AppIcon.appiconset/BalanceIcon-216.png index 2f00659..e14c6b2 100644 Binary files a/BalanceWatch/Assets.xcassets/AppIcon.appiconset/BalanceIcon-216.png and b/BalanceWatch/Assets.xcassets/AppIcon.appiconset/BalanceIcon-216.png differ diff --git a/BalanceWatch/Assets.xcassets/AppIcon.appiconset/BalanceIcon-234.png b/BalanceWatch/Assets.xcassets/AppIcon.appiconset/BalanceIcon-234.png index 7dc91af..5bcb394 100644 Binary files a/BalanceWatch/Assets.xcassets/AppIcon.appiconset/BalanceIcon-234.png and b/BalanceWatch/Assets.xcassets/AppIcon.appiconset/BalanceIcon-234.png differ diff --git a/BalanceWatch/Assets.xcassets/AppIcon.appiconset/BalanceIcon-258.png b/BalanceWatch/Assets.xcassets/AppIcon.appiconset/BalanceIcon-258.png index 6be4a87..62d4619 100644 Binary files a/BalanceWatch/Assets.xcassets/AppIcon.appiconset/BalanceIcon-258.png and b/BalanceWatch/Assets.xcassets/AppIcon.appiconset/BalanceIcon-258.png differ diff --git a/BalanceWatch/Assets.xcassets/AppIcon.appiconset/BalanceIcon-48.png b/BalanceWatch/Assets.xcassets/AppIcon.appiconset/BalanceIcon-48.png index 990b9a8..7bd2d90 100644 Binary files a/BalanceWatch/Assets.xcassets/AppIcon.appiconset/BalanceIcon-48.png and b/BalanceWatch/Assets.xcassets/AppIcon.appiconset/BalanceIcon-48.png differ diff --git a/BalanceWatch/Assets.xcassets/AppIcon.appiconset/BalanceIcon-55.png b/BalanceWatch/Assets.xcassets/AppIcon.appiconset/BalanceIcon-55.png index 9abc1e5..4f7132f 100644 Binary files a/BalanceWatch/Assets.xcassets/AppIcon.appiconset/BalanceIcon-55.png and b/BalanceWatch/Assets.xcassets/AppIcon.appiconset/BalanceIcon-55.png differ diff --git a/BalanceWatch/Assets.xcassets/AppIcon.appiconset/BalanceIcon-58.png b/BalanceWatch/Assets.xcassets/AppIcon.appiconset/BalanceIcon-58.png index 726cb0d..fe17a43 100644 Binary files a/BalanceWatch/Assets.xcassets/AppIcon.appiconset/BalanceIcon-58.png and b/BalanceWatch/Assets.xcassets/AppIcon.appiconset/BalanceIcon-58.png differ diff --git a/BalanceWatch/Assets.xcassets/AppIcon.appiconset/BalanceIcon-80.png b/BalanceWatch/Assets.xcassets/AppIcon.appiconset/BalanceIcon-80.png index 73f3023..f83d323 100644 Binary files a/BalanceWatch/Assets.xcassets/AppIcon.appiconset/BalanceIcon-80.png and b/BalanceWatch/Assets.xcassets/AppIcon.appiconset/BalanceIcon-80.png differ diff --git a/BalanceWatch/Assets.xcassets/AppIcon.appiconset/BalanceIcon-87.png b/BalanceWatch/Assets.xcassets/AppIcon.appiconset/BalanceIcon-87.png index 4608e52..5f5fb77 100644 Binary files a/BalanceWatch/Assets.xcassets/AppIcon.appiconset/BalanceIcon-87.png and b/BalanceWatch/Assets.xcassets/AppIcon.appiconset/BalanceIcon-87.png differ diff --git a/BalanceWatch/Assets.xcassets/AppIcon.appiconset/BalanceIcon-88.png b/BalanceWatch/Assets.xcassets/AppIcon.appiconset/BalanceIcon-88.png index b81ecc8..be8d9a6 100644 Binary files a/BalanceWatch/Assets.xcassets/AppIcon.appiconset/BalanceIcon-88.png and b/BalanceWatch/Assets.xcassets/AppIcon.appiconset/BalanceIcon-88.png differ diff --git a/BalanceWatch/Assets.xcassets/AppIcon.appiconset/BalanceIcon-92.png b/BalanceWatch/Assets.xcassets/AppIcon.appiconset/BalanceIcon-92.png index 4a41132..b280e52 100644 Binary files a/BalanceWatch/Assets.xcassets/AppIcon.appiconset/BalanceIcon-92.png and b/BalanceWatch/Assets.xcassets/AppIcon.appiconset/BalanceIcon-92.png differ diff --git a/BalanceWatch/Shared/AppTheme.swift b/BalanceWatch/Shared/AppTheme.swift index 56347e6..3358d86 100644 --- a/BalanceWatch/Shared/AppTheme.swift +++ b/BalanceWatch/Shared/AppTheme.swift @@ -23,3 +23,20 @@ enum AppTheme: String, CaseIterable, Identifiable { } } } + +/// Палитра «Лес» — та же, что у пресета по умолчанию во Flutter-клиенте и у +/// иконки приложения. +enum BalancePalette { + /// Акцент интерфейса (кнопки, ссылки, выбор) — мятный, читается на чёрном. + static let accent = Color(red: 0x7f / 255, green: 0xd6 / 255, blue: 0xb9 / 255) + /// Основной цвет пресета «Лес». + static let forest = Color(red: 0x35 / 255, green: 0x68 / 255, blue: 0x59 / 255) + /// Градиент карточки общего баланса (как фон иконки). + static let cardTop = Color(red: 0x3f / 255, green: 0x7d / 255, blue: 0x6b / 255) + static let cardBottom = Color(red: 0x1a / 255, green: 0x4a / 255, blue: 0x3e / 255) + /// Текст на карточке баланса. + static let mint = Color(red: 0xbd / 255, green: 0xf7 / 255, blue: 0xe3 / 255) + /// Доходы — teal, расходы — deep orange, как во Flutter. + static let income = Color(red: 0x26 / 255, green: 0xb3 / 255, blue: 0xa3 / 255) + static let expense = Color(red: 0xff / 255, green: 0x6e / 255, blue: 0x40 / 255) +} diff --git a/BalanceWatch/Utilities/CurrencyFormatting.swift b/BalanceWatch/Utilities/CurrencyFormatting.swift index 04b78d8..7eeed58 100644 --- a/BalanceWatch/Utilities/CurrencyFormatting.swift +++ b/BalanceWatch/Utilities/CurrencyFormatting.swift @@ -10,10 +10,13 @@ enum SupportedCurrency: String, CaseIterable, Identifiable { } extension Double { + /// Целые суммы без копеек, остальные — ровно с двумя знаками («8 480,50 ₽»), + /// как во Flutter-клиенте. func formattedCurrency(code: String) -> String { - formatted( + let whole = (self * 100).rounded().truncatingRemainder(dividingBy: 100) == 0 + return formatted( .currency(code: code) - .precision(.fractionLength(0 ... 2)) + .precision(.fractionLength(whole ? 0 : 2)) .presentation(.narrow) ) } diff --git a/README.md b/README.md index 4fddfc8..54675e7 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,5 @@

- BalanceWatch — учёт личных финансов на Apple Watch + BalanceWatch — личные финансы на Apple Watch

# BalanceWatch @@ -13,7 +13,8 @@ ```text BalanceWatch/ -├── branding/ # аватар и баннер для README (PNG + SVG-исходники) +├── branding/ # иконка, аватар и баннер (SVG-исходники, PNG, render.sh) +├── docs/ # скриншоты для баннера ├── docs/CONTRACT_V2.md # общий контракт экосистемы v2 (копия, одинаковая во всех репозиториях) ├── BalanceWatch.xcodeproj/ └── BalanceWatch/ @@ -75,3 +76,15 @@ Simulator и watchOS device (без подписи). Запускается на кода из монорепозитория. Протокол синхронизации и правила расчётов должны совпадать с остальными клиентами Balance: при изменении контракта на сервере переносите правки и сюда. + +## Оформление + +Палитра «Лес» — та же, что у пресета по умолчанию в BalanceFlutter: карточка +баланса в зелёном градиенте, доходы бирюзовые (↙), расходы оранжевые (↗), +мятный акцент (`BalancePalette` в `Shared/AppTheme.swift`). Иконка — тот же +рисунок, что у Flutter-приложения (`branding/icon.svg`). + +После правки SVG или скриншотов в `docs/` выполни `bash branding/render.sh` +(нужен `resvg`): скрипт перерисует все размеры иконки в +`Assets.xcassets/AppIcon.appiconset`, `branding/avatar.png` (512×512) и +`branding/banner.png` (1280×640). Шрифты Roboto лежат в `branding/fonts`. diff --git a/branding/avatar.png b/branding/avatar.png index d82c6c6..ca42d70 100644 Binary files a/branding/avatar.png and b/branding/avatar.png differ diff --git a/branding/avatar.svg b/branding/avatar.svg index 5549534..1220ded 100644 --- a/branding/avatar.svg +++ b/branding/avatar.svg @@ -1,60 +1,30 @@ - + + - - - + + + - - - + + + - - + + - - - - - - - - - - - - - - - - + + - - - - + - - - - - - - - - - - - - - - - - - - - + + + + + diff --git a/branding/banner.png b/branding/banner.png index 615434c..20cf132 100644 Binary files a/branding/banner.png and b/branding/banner.png differ diff --git a/branding/banner.svg b/branding/banner.svg index c1cc9ae..47fbb50 100644 --- a/branding/banner.svg +++ b/branding/banner.svg @@ -1,80 +1,78 @@ - + + - - - + + + - - - - - - - + + - - - + + + + - - - + + + + - - - - - - - - - - - + + - - + + + + + - - - - + + - - - - - - - - - - - - - + + + BalanceWatch + + Личные финансы на Apple Watch + Самостоятельное приложение для часов, + синхронизация с self-hosted BalanceServer + + + + watchOS 10+ + + SwiftUI + + SwiftData + + Счета и валюты + + Общие бюджеты - - - BalanceWatch - Учёт личных финансов на Apple Watch - - - - - watchOS 10+ - - SwiftUI - - SwiftData - - - - Sync с BalanceServer - + + + + + + + + + + + + + + + + + + + diff --git a/branding/fonts/LICENSE.txt b/branding/fonts/LICENSE.txt new file mode 100644 index 0000000..364bb75 --- /dev/null +++ b/branding/fonts/LICENSE.txt @@ -0,0 +1,203 @@ +Copyright 2011 Google Inc. All Rights Reserved. + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/branding/fonts/Roboto-Bold.ttf b/branding/fonts/Roboto-Bold.ttf new file mode 100644 index 0000000..d3f01ad Binary files /dev/null and b/branding/fonts/Roboto-Bold.ttf differ diff --git a/branding/fonts/Roboto-Medium.ttf b/branding/fonts/Roboto-Medium.ttf new file mode 100644 index 0000000..1a7f3b0 Binary files /dev/null and b/branding/fonts/Roboto-Medium.ttf differ diff --git a/branding/fonts/Roboto-Regular.ttf b/branding/fonts/Roboto-Regular.ttf new file mode 100644 index 0000000..2c97eea Binary files /dev/null and b/branding/fonts/Roboto-Regular.ttf differ diff --git a/branding/icon.svg b/branding/icon.svg new file mode 100644 index 0000000..0316743 --- /dev/null +++ b/branding/icon.svg @@ -0,0 +1,45 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/branding/render.sh b/branding/render.sh new file mode 100755 index 0000000..25b0354 --- /dev/null +++ b/branding/render.sh @@ -0,0 +1,21 @@ +#!/usr/bin/env bash +# Re-renders the watch app icon (every size in AppIcon.appiconset), avatar.png +# and banner.png from their SVG sources. Requires resvg +# (https://github.com/linebender/resvg). Uses the bundled Roboto fonts, so the +# result does not depend on system fonts. icon.svg is the same artwork as the +# BalanceFlutter app icon (palette «Лес»). +set -euo pipefail +cd "$(dirname "${BASH_SOURCE[0]}")" +fonts=( + --skip-system-fonts + --use-font-file fonts/Roboto-Regular.ttf + --use-font-file fonts/Roboto-Medium.ttf + --use-font-file fonts/Roboto-Bold.ttf +) +icons=../BalanceWatch/Assets.xcassets/AppIcon.appiconset +for file in "$icons"/BalanceIcon-*.png; do + size="${file##*-}"; size="${size%.png}" + resvg -w "$size" -h "$size" icon.svg "$file" +done +resvg "${fonts[@]}" -w 512 -h 512 avatar.svg avatar.png +resvg "${fonts[@]}" banner.svg banner.png diff --git a/docs/accounts.png b/docs/accounts.png new file mode 100644 index 0000000..492780d Binary files /dev/null and b/docs/accounts.png differ diff --git a/docs/home.png b/docs/home.png new file mode 100644 index 0000000..d928c9e Binary files /dev/null and b/docs/home.png differ