oficina / sheets Public

Calma: Sheets' own accent, Onest and the new icons

Sheets adopts estilo's Calma (estilo decisions-table row 8, 5b2ce83):
theme.ForApp("sheets") in place of day, Onest served by estilo's
FontHandler and linked first, and Calma's Sheets icon on the web, iPhone
and Mac (distributed by estilo's brand/distribute.py). The theme test now
checks Sheets serves estilo's theme for sheets; a new test checks Onest
is linked and served. estilo's two Go-served mounts move to estilo.go to
keep app.go under the 300-line cap.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Paul Campbell pushed by paul@keymail.dev 8e2acf4413fc62ee39bdaf4103d9812330a63a07 parent 50a3427
13 files changed, +59 −25
  • go.mod +1 −1
  • go.sum +2 −0
  • internal/sheets/app.go +1 −2
  • internal/sheets/estilo.go +15 −0
  • internal/sheets/render.go +14 −1
  • internal/sheets/static/brand/apple-touch-icon.png binary
  • internal/sheets/static/brand/brand.css +2 −2
  • internal/sheets/static/brand/icon-32.png binary
  • internal/sheets/static/brand/icon.svg +1 −4
  • internal/sheets/templates/layout.html +1 −0
  • internal/sheets/theme_assets_test.go +22 −15
  • native/ios/Assets.xcassets/AppIcon.appiconset/AppIcon.png binary
  • native/macos/AppIcon.icns binary

CI passed — run details

CI log
amadan: .amadan/timeout: this job's budget is 15m0s (this runner allows up to 30m0s)
=== vet ===
CGO_ENABLED=0 go vet ./...
go: downloading amadan.net/oficina/estilo.git v0.0.0-20260929070530-5b2ce835e773
=== fmt ===
=== build ===
CGO_ENABLED=0 go build ./...
=== migrations ===
rastrillo migration check
rastrillo migration check: models and migrations agree
=== go-test ===
CGO_ENABLED=0 go test -count=1 ./...
?   	amadan.net/oficina/sheets/cmd/sheets	[no test files]
ok  	amadan.net/oficina/sheets/internal/guardstest	0.073s
ok  	amadan.net/oficina/sheets/internal/sheets	10.833s
ok  	amadan.net/oficina/sheets/internal/sheets/calc	0.009s
ok  	amadan.net/oficina/sheets/internal/sheets/format	0.003s
ok  	amadan.net/oficina/sheets/internal/sheets/live	0.053s
ok  	amadan.net/oficina/sheets/internal/sheets/seal	0.004s
ok  	amadan.net/oficina/sheets/internal/sheets/sealtest	0.004s
ok  	amadan.net/oficina/sheets/internal/sheets/store	2.743s
ok  	amadan.net/oficina/sheets/internal/sheets/xlsx	0.289s
?   	amadan.net/oficina/sheets/tools/gencorpus	[no test files]
=== race ===
go test -race -count=1 ./internal/sheets/store/... ./internal/sheets/live/...
ok  	amadan.net/oficina/sheets/internal/sheets/store	46.279s
ok  	amadan.net/oficina/sheets/internal/sheets/live	1.059s
diff --git a/go.mod b/go.mod
index bc8328a..c42e6ac 100644
--- a/go.mod
+++ b/go.mod
@@ -3,7 +3,7 @@ module amadan.net/oficina/sheets
go 1.25.0
require (
- amadan.net/oficina/estilo.git v0.0.0-20260924071126-894afdcb71a9
+ amadan.net/oficina/estilo.git v0.0.0-20260929070530-5b2ce835e773
amadan.net/oficina/home/connect v0.0.0-20260923190447-01166fcfc0a9
amadan.net/oficina/home/handoff v0.0.0-20260908102137-481d2d57f489
amadan.net/rastrillo/rastrillo v0.26.1-0.20260908075707-29e4491631bd
diff --git a/go.sum b/go.sum
index 0bb21ca..4ad3acd 100644
--- a/go.sum
+++ b/go.sum
@@ -1,5 +1,7 @@
amadan.net/oficina/estilo.git v0.0.0-20260924071126-894afdcb71a9 h1:vHOkWeJ7mRwLjPbMihf0f7aqz4CLSe0/NseQsHcJUYQ=
amadan.net/oficina/estilo.git v0.0.0-20260924071126-894afdcb71a9/go.mod h1:4u0jNBtIdMLOsJyrScfqoEuYDJF7BBM3qM9YWbzt6aw=
+amadan.net/oficina/estilo.git v0.0.0-20260929070530-5b2ce835e773 h1:9DIAhG3TaGG+LE2+8LvU73ZEhfK+oNn2y2p4kFjAAi0=
+amadan.net/oficina/estilo.git v0.0.0-20260929070530-5b2ce835e773/go.mod h1:4u0jNBtIdMLOsJyrScfqoEuYDJF7BBM3qM9YWbzt6aw=
amadan.net/oficina/home/connect v0.0.0-20260923190447-01166fcfc0a9 h1:K/PaOVdQqRMwifPD6ipiwLeGR5nbFSxm9FxjrDJlZcg=
amadan.net/oficina/home/connect v0.0.0-20260923190447-01166fcfc0a9/go.mod h1:YroavXe43Wietec+po8mtSk4a9Bir2h31Q3iAf4MWxI=
amadan.net/oficina/home/handoff v0.0.0-20260908102137-481d2d57f489 h1:RPKtyry/71i06o8L+gjAaUyexbmG56kO1YPs601URAM=
diff --git a/internal/sheets/app.go b/internal/sheets/app.go
index 3b7f3ea..01f106d 100644
--- a/internal/sheets/app.go
+++ b/internal/sheets/app.go
@@ -6,7 +6,6 @@ import (
nativeauth "amadan.net/rastrillo/native/server"
"net/http"
- "amadan.net/oficina/estilo.git/brand"
"amadan.net/oficina/estilo.git/chrome"
"amadan.net/oficina/home/connect"
"github.com/carlosframework/rastrillo/sessions"
@@ -189,7 +188,7 @@ func (a *App) Router() http.Handler {
// FS path.
r.Handle("/static/*", staticHandler())
// estilo serves the suite's app icons (the bar's brand).
- r.Handle(brand.Prefix+"*", brand.Handler())
+ mountEstilo(r)
// Light/dark is a per-person preference set by a form, so it works
// with scripting off. estilo's handler and cookie; inside the CSRF
// check above and outside the session group, so an expired session
diff --git a/internal/sheets/estilo.go b/internal/sheets/estilo.go
new file mode 100644
index 0000000..8fe4c17
--- /dev/null
+++ b/internal/sheets/estilo.go
@@ -0,0 +1,15 @@
+package sheets
+
+import (
+ "amadan.net/oficina/estilo.git/brand"
+ "amadan.net/oficina/estilo.git/theme"
+ "github.com/go-chi/chi/v5"
+)
+
+// mountEstilo serves what estilo ships from Go rather than as files in
+// static/: every app's icon (for the switcher) and Onest, Calma's
+// typeface. Both handlers serve closed sets under their own prefixes.
+func mountEstilo(r chi.Router) {
+ r.Handle(brand.Prefix+"*", brand.Handler())
+ r.Handle(theme.FontPrefix+"*", theme.FontHandler())
+}
diff --git a/internal/sheets/render.go b/internal/sheets/render.go
index 60e4d6b..5b51841 100644
--- a/internal/sheets/render.go
+++ b/internal/sheets/render.go
@@ -63,7 +63,9 @@ func sharedStaticFiles() fs.FS {
if err != nil {
panic(err)
}
- files["static/theme.css"] = &fstest.MapFile{Data: theme.CSS()}
+ // Calma, with Sheets' own accent from estilo's colour ring (estilo
+ // AGENTS.md, decisions table, row 8).
+ files["static/theme.css"] = &fstest.MapFile{Data: sheetsTheme}
// estilo's shared chrome, served under the app's own fingerprinted
// /static like the theme, in the suite's order: base, menu, chrome.
files["static/estilo/base.css"] = &fstest.MapFile{Data: base.CSS()}
@@ -73,6 +75,17 @@ func sharedStaticFiles() fs.FS {
return files
}
+// sheetsTheme is estilo's theme for Sheets. "sheets" is on the ring, so
+// ForApp cannot refuse it; a panic here is a broken estilo pin, found at
+// boot rather than on a page.
+var sheetsTheme = func() []byte {
+ css, ok := theme.ForApp("sheets")
+ if !ok {
+ panic("estilo's theme ring has no sheets")
+ }
+ return css
+}()
+
// pages is one parsed template tree per page.
//
// One tree each, rather than one tree holding everything, because every
diff --git a/internal/sheets/static/brand/apple-touch-icon.png b/internal/sheets/static/brand/apple-touch-icon.png
index 2487bbb..e8d6f94 100644
Binary files a/internal/sheets/static/brand/apple-touch-icon.png and b/internal/sheets/static/brand/apple-touch-icon.png differ
diff --git a/internal/sheets/static/brand/brand.css b/internal/sheets/static/brand/brand.css
index 2e194c6..27e25ad 100644
--- a/internal/sheets/static/brand/brand.css
+++ b/internal/sheets/static/brand/brand.css
@@ -1,4 +1,5 @@
-/* Oficina brand artwork. Source: oficina/estilo brand/. */
+/* Oficina brand artwork. Source: oficina/estilo brand/. The icons carry
+ their own squircle and transparent corners, so nothing here rounds them. */
[estilo-brand] {
display: inline-flex;
align-items: center;
@@ -10,7 +11,6 @@
flex-shrink: 0;
inline-size: 1.75rem;
block-size: 1.75rem;
- border-radius: 21%;
vertical-align: middle;
}
[estilo-brand-icon="listing"] {
diff --git a/internal/sheets/static/brand/icon-32.png b/internal/sheets/static/brand/icon-32.png
index b99fcb4..d7fb3a1 100644
Binary files a/internal/sheets/static/brand/icon-32.png and b/internal/sheets/static/brand/icon-32.png differ
diff --git a/internal/sheets/static/brand/icon.svg b/internal/sheets/static/brand/icon.svg
index 3739ca0..d7a3364 100644
--- a/internal/sheets/static/brand/icon.svg
+++ b/internal/sheets/static/brand/icon.svg
@@ -1,4 +1 @@
-<svg xmlns="http://www.w3.org/2000/svg" width="1024" height="1024" viewBox="0 0 1024 1024" role="img" aria-label="Sheets"><title>Sheets</title><rect x="0" y="0" width="1024" height="1024" rx="0" fill="#168049"/><g transform="translate(153.6 153.6) scale(29.866666666666664)" fill="none" stroke="white" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M12 3v18" />
- <rect width="18" height="18" x="3" y="3" rx="2" />
- <path d="M3 9h18" />
- <path d="M3 15h18" /></g></svg>
+<svg xmlns="http://www.w3.org/2000/svg" width="1024" height="1024" viewBox="0 0 100 100" role="img" aria-label="Sheets"><title>Sheets</title><defs><clipPath id="s"><path d="M96.00 50.00L95.97 64.13L95.90 68.64L95.77 71.90L95.60 74.54L95.37 76.79L95.09 78.76L94.75 80.51L94.37 82.10L93.92 83.54L93.43 84.86L92.87 86.07L92.26 87.19L91.59 88.22L90.85 89.17L90.05 90.05L89.17 90.85L88.22 91.59L87.19 92.26L86.07 92.87L84.86 93.43L83.54 93.92L82.10 94.37L80.51 94.75L78.76 95.09L76.79 95.37L74.54 95.60L71.90 95.77L68.64 95.90L64.13 95.97L50.00 96.00L35.87 95.97L31.36 95.90L28.10 95.77L25.46 95.60L23.21 95.37L21.24 95.09L19.49 94.75L17.90 94.37L16.46 93.92L15.14 93.43L13.93 92.87L12.81 92.26L11.78 91.59L10.83 90.85L9.95 90.05L9.15 89.17L8.41 88.22L7.74 87.19L7.13 86.07L6.57 84.86L6.08 83.54L5.63 82.10L5.25 80.51L4.91 78.76L4.63 76.79L4.40 74.54L4.23 71.90L4.10 68.64L4.03 64.13L4.00 50.00L4.03 35.87L4.10 31.36L4.23 28.10L4.40 25.46L4.63 23.21L4.91 21.24L5.25 19.49L5.63 17.90L6.08 16.46L6.57 15.14L7.13 13.93L7.74 12.81L8.41 11.78L9.15 10.83L9.95 9.95L10.83 9.15L11.78 8.41L12.81 7.74L13.93 7.13L15.14 6.57L16.46 6.08L17.90 5.63L19.49 5.25L21.24 4.91L23.21 4.63L25.46 4.40L28.10 4.23L31.36 4.10L35.87 4.03L50.00 4.00L64.13 4.03L68.64 4.10L71.90 4.23L74.54 4.40L76.79 4.63L78.76 4.91L80.51 5.25L82.10 5.63L83.54 6.08L84.86 6.57L86.07 7.13L87.19 7.74L88.22 8.41L89.17 9.15L90.05 9.95L90.85 10.83L91.59 11.78L92.26 12.81L92.87 13.93L93.43 15.14L93.92 16.46L94.37 17.90L94.75 19.49L95.09 21.24L95.37 23.21L95.60 25.46L95.77 28.10L95.90 31.36L95.97 35.87Z"/></clipPath><linearGradient id="g" x1="0" y1="0" x2="0" y2="1"><stop offset="0" stop-color="#5aa04a"/><stop offset="1" stop-color="#3d892a"/></linearGradient><filter id="h" x="-40%" y="-60%" width="180%" height="220%"><feGaussianBlur stdDeviation="5.5"/></filter></defs><g clip-path="url(#s)"><rect width="100" height="100" fill="url(#g)"/><g filter="url(#h)" opacity=".7"><rect x="4.00" y="44.8" width="0.65" height="11.0" fill="#accc9e"/><rect x="6.18" y="31.9" width="0.95" height="22.7" fill="#bff2b2"/><rect x="7.28" y="28.2" width="0.71" height="25.7" fill="#c5f4c4"/><rect x="9.26" y="35.2" width="0.69" height="17.4" fill="#bfeeb8"/><rect x="10.93" y="35.4" width="0.65" height="16.0" fill="#a3e19e"/><rect x="12.75" y="20.4" width="1.25" height="29.8" fill="#a8daa4"/><rect x="14.50" y="13.0" width="0.75" height="35.9" fill="#b1dbaf"/><rect x="16.53" y="23.7" width="0.71" height="23.9" fill="#c0e4b2"/><rect x="18.38" y="25.1" width="1.09" height="21.2" fill="#b2e4ab"/><rect x="19.99" y="16.2" width="0.89" height="29.2" fill="#a4cd9f"/><rect x="21.58" y="15.9" width="0.96" height="28.5" fill="#b9e5b5"/><rect x="23.79" y="31.6" width="0.77" height="11.8" fill="#a5d78e"/><rect x="25.07" y="31.9" width="0.66" height="11.0" fill="#c2e4b5"/><rect x="26.58" y="22.9" width="0.98" height="19.4" fill="#a0ce9d"/><rect x="28.56" y="15.8" width="0.92" height="26.1" fill="#9fd695"/><rect x="29.95" y="21.7" width="1.12" height="19.9" fill="#a5e5a1"/><rect x="32.03" y="23.5" width="0.62" height="18.0" fill="#a8cfa6"/><rect x="33.41" y="13.0" width="1.07" height="28.5" fill="#a6e9a5"/><rect x="35.27" y="5.0" width="1.01" height="36.6" fill="#aee1a1"/><rect x="36.51" y="11.2" width="1.11" height="30.5" fill="#c8efb6"/><rect x="38.77" y="23.0" width="0.86" height="19.1" fill="#baf9b4"/><rect x="40.86" y="15.0" width="1.00" height="27.6" fill="#c5f0c5"/><rect x="42.40" y="15.0" width="1.12" height="27.9" fill="#9ed798"/><rect x="43.52" y="23.1" width="0.92" height="20.2" fill="#a0d48f"/><rect x="45.48" y="32.7" width="0.61" height="11.0" fill="#a1da9f"/><rect x="46.71" y="30.4" width="0.80" height="13.6" fill="#97d298"/><rect x="48.73" y="17.7" width="0.80" height="26.7" fill="#c2f5b6"/><rect x="51.00" y="24.3" width="1.24" height="20.5" fill="#abdb9f"/><rect x="53.10" y="25.3" width="1.25" height="19.7" fill="#b5e9a8"/><rect x="54.21" y="17.1" width="1.28" height="28.0" fill="#9dce9a"/><rect x="55.73" y="8.4" width="1.09" height="36.8" fill="#bbeeb3"/><rect x="57.41" y="14.6" width="0.61" height="30.5" fill="#bde9b9"/><rect x="59.24" y="26.3" width="0.65" height="18.7" fill="#a1dda0"/><rect x="60.43" y="25.2" width="0.95" height="19.7" fill="#b9e4ad"/><rect x="62.25" y="16.8" width="0.71" height="27.8" fill="#b6e0a6"/><rect x="63.46" y="18.2" width="1.22" height="26.3" fill="#add9a9"/><rect x="65.01" y="29.2" width="0.93" height="15.0" fill="#b7dcad"/><rect x="66.39" y="33.0" width="1.23" height="11.0" fill="#c6e9b5"/><rect x="68.28" y="24.8" width="1.05" height="19.0" fill="#ade5ad"/><rect x="70.00" y="15.2" width="0.68" height="28.4" fill="#acdd95"/><rect x="71.92" y="21.5" width="0.83" height="22.0" fill="#b1e2ab"/><rect x="73.52" y="24.7" width="1.07" height="18.7" fill="#ccf1bc"/><rect x="75.03" y="15.8" width="1.18" height="27.6" fill="#addba9"/><rect x="76.44" y="7.2" width="0.90" height="36.4" fill="#baf3b1"/><rect x="78.59" y="15.9" width="0.76" height="28.0" fill="#a6de99"/><rect x="80.46" y="27.4" width="0.64" height="17.0" fill="#b7dca7"/><rect x="82.52" y="21.1" width="0.77" height="24.1" fill="#beefa4"/><rect x="84.53" y="21.3" width="0.86" height="24.8" fill="#c9efbc"/><rect x="86.73" y="36.3" width="0.87" height="11.0" fill="#b7e89e"/><rect x="88.29" y="35.8" width="0.73" height="12.4" fill="#a3ce95"/><rect x="89.91" y="24.1" width="0.69" height="25.2" fill="#b5e8ab"/><rect x="92.14" y="23.9" width="0.70" height="26.9" fill="#aad692"/><rect x="93.45" y="31.3" width="1.10" height="20.5" fill="#add0a0"/><rect x="95.03" y="31.3" width="0.65" height="21.7" fill="#c6f4c4"/></g></g><path d="M96.00 50.00L95.97 64.13L95.90 68.64L95.77 71.90L95.60 74.54L95.37 76.79L95.09 78.76L94.75 80.51L94.37 82.10L93.92 83.54L93.43 84.86L92.87 86.07L92.26 87.19L91.59 88.22L90.85 89.17L90.05 90.05L89.17 90.85L88.22 91.59L87.19 92.26L86.07 92.87L84.86 93.43L83.54 93.92L82.10 94.37L80.51 94.75L78.76 95.09L76.79 95.37L74.54 95.60L71.90 95.77L68.64 95.90L64.13 95.97L50.00 96.00L35.87 95.97L31.36 95.90L28.10 95.77L25.46 95.60L23.21 95.37L21.24 95.09L19.49 94.75L17.90 94.37L16.46 93.92L15.14 93.43L13.93 92.87L12.81 92.26L11.78 91.59L10.83 90.85L9.95 90.05L9.15 89.17L8.41 88.22L7.74 87.19L7.13 86.07L6.57 84.86L6.08 83.54L5.63 82.10L5.25 80.51L4.91 78.76L4.63 76.79L4.40 74.54L4.23 71.90L4.10 68.64L4.03 64.13L4.00 50.00L4.03 35.87L4.10 31.36L4.23 28.10L4.40 25.46L4.63 23.21L4.91 21.24L5.25 19.49L5.63 17.90L6.08 16.46L6.57 15.14L7.13 13.93L7.74 12.81L8.41 11.78L9.15 10.83L9.95 9.95L10.83 9.15L11.78 8.41L12.81 7.74L13.93 7.13L15.14 6.57L16.46 6.08L17.90 5.63L19.49 5.25L21.24 4.91L23.21 4.63L25.46 4.40L28.10 4.23L31.36 4.10L35.87 4.03L50.00 4.00L64.13 4.03L68.64 4.10L71.90 4.23L74.54 4.40L76.79 4.63L78.76 4.91L80.51 5.25L82.10 5.63L83.54 6.08L84.86 6.57L86.07 7.13L87.19 7.74L88.22 8.41L89.17 9.15L90.05 9.95L90.85 10.83L91.59 11.78L92.26 12.81L92.87 13.93L93.43 15.14L93.92 16.46L94.37 17.90L94.75 19.49L95.09 21.24L95.37 23.21L95.60 25.46L95.77 28.10L95.90 31.36L95.97 35.87Z" fill="none" stroke="#fff" stroke-opacity=".18" stroke-width="1"/><rect x="22" y="26" width="56" height="48" rx="6" fill="#fff"/><rect x="22" y="26" width="56" height="13" rx="6" fill="#26730e" opacity=".35"/><g stroke="#26730e" stroke-width="3"><path d="M42 26v48M22 52h56M22 64h56"/></g></svg>
diff --git a/internal/sheets/templates/layout.html b/internal/sheets/templates/layout.html
index ffe3073..e45d566 100644
--- a/internal/sheets/templates/layout.html
+++ b/internal/sheets/templates/layout.html
@@ -31,6 +31,7 @@
<link rel="icon" type="image/png" sizes="32x32" href="{{asset "static/brand/icon-32.png"}}">
<link rel="icon" type="image/svg+xml" href="{{asset "static/brand/icon.svg"}}">
<link rel="apple-touch-icon" sizes="180x180" href="{{asset "static/brand/apple-touch-icon.png"}}">
+<link rel="stylesheet" href="/static/estilo/fonts/v1/fonts.css">
<link rel="stylesheet" href="{{asset "static/tokens.css"}}">
<link rel="stylesheet" href="{{asset "static/theme.css"}}">
<link rel="stylesheet" href="{{asset "static/brand/brand.css"}}">
diff --git a/internal/sheets/theme_assets_test.go b/internal/sheets/theme_assets_test.go
index fd26cbb..e017514 100644
--- a/internal/sheets/theme_assets_test.go
+++ b/internal/sheets/theme_assets_test.go
@@ -19,26 +19,16 @@ func TestSharedThemeAssetFingerprintAndCache(t *testing.T) {
if page.Code != http.StatusOK {
t.Fatalf("signin status %d", page.Code)
}
- day, ok := ui.ThemeCSS("day")
- if !ok {
- t.Fatal("selected day missing")
- }
- body := func(css []byte) []byte {
- if bytes.HasPrefix(css, []byte("/*")) {
- if end := bytes.Index(css, []byte("*/")); end >= 0 {
- return css[end+2:]
- }
- }
- return css
- }
- if !bytes.Equal(body(theme.CSS()), body(day)) {
- t.Fatal("shared theme differs from selected day")
+ // Calma with Sheets' accent (estilo row 8), not rastrillo's day.
+ want, ok := theme.ForApp("sheets")
+ if !ok || !bytes.Equal(sheetsTheme, want) {
+ t.Fatal("Sheets does not serve estilo's theme for sheets")
}
for _, item := range []struct {
name string
data []byte
}{
- {"theme", theme.CSS()}, {"tokens", ui.TokensCSS()},
+ {"theme", sheetsTheme}, {"tokens", ui.TokensCSS()},
} {
sum := sha256.Sum256(item.data)
hashed := fmt.Sprintf("/static/%s.%x.css", item.name, sum[:8])
@@ -63,3 +53,20 @@ func TestSharedThemeAssetFingerprintAndCache(t *testing.T) {
}
}
}
+
+// The layout names Onest's stylesheet under estilo's versioned prefix, and
+// the app serves it there: when estilo moves the fonts, this fails rather
+// than every page quietly falling back to the system face.
+func TestOnestIsLinkedAndServed(t *testing.T) {
+ app := New(Config{})
+ page := do(t, app, httptest.NewRequest(http.MethodGet, "/signin", nil))
+ css := theme.FontPrefix + "fonts.css"
+ if !strings.Contains(page.Body.String(), `href="`+css+`"`) {
+ t.Fatalf("layout does not link %s", css)
+ }
+ for _, path := range []string{css, theme.FontPrefix + "onest-latin.woff2"} {
+ if res := do(t, app, httptest.NewRequest(http.MethodGet, path, nil)); res.Code != http.StatusOK {
+ t.Fatalf("GET %s = %d", path, res.Code)
+ }
+ }
+}
diff --git a/native/ios/Assets.xcassets/AppIcon.appiconset/AppIcon.png b/native/ios/Assets.xcassets/AppIcon.appiconset/AppIcon.png
index 40f5065..93dfdd9 100644
Binary files a/native/ios/Assets.xcassets/AppIcon.appiconset/AppIcon.png and b/native/ios/Assets.xcassets/AppIcon.appiconset/AppIcon.png differ
diff --git a/native/macos/AppIcon.icns b/native/macos/AppIcon.icns
index 9198a29..30b140b 100644
Binary files a/native/macos/AppIcon.icns and b/native/macos/AppIcon.icns differ