Add branding: Focus mark, wordmark, banner, social preview
- assets/branding/: icon (SVG + 512px PNG for Gitea avatar), adaptive-icon foreground/background layers, path-only wordmark for dark/light grounds, 1200x300 README banner, 1280x640 social preview (SVG + PNG) - README: banner hero - build-status: branding decision log (includes the pending website section from the parallel web/ session, interleaved in the same file) Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@@ -1,3 +1,7 @@
|
|||||||
|
<p align="center">
|
||||||
|
<img src="assets/branding/banner.svg" alt="echolot — measure, don't guess" width="100%">
|
||||||
|
</p>
|
||||||
|
|
||||||
# Echolot
|
# Echolot
|
||||||
|
|
||||||
Free software for detecting and debugging **local network issues** from an Android phone —
|
Free software for detecting and debugging **local network issues** from an Android phone —
|
||||||
|
|||||||
@@ -0,0 +1,39 @@
|
|||||||
|
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1200 300">
|
||||||
|
<rect width="1200" height="300" fill="#071522"/>
|
||||||
|
<!-- graduated rule -->
|
||||||
|
<path d="M 0 250 H 1200" fill="none" stroke="#0F2E3D" stroke-width="1.5"/>
|
||||||
|
<path d="M 30 255 H 1180" fill="none" stroke="#0F2E3D" stroke-width="9" stroke-dasharray="1.5 58.5"/>
|
||||||
|
<!-- glyph: focus -->
|
||||||
|
<g transform="translate(60,15) scale(2.8)">
|
||||||
|
<g fill="#1E4A5C">
|
||||||
|
<circle cx="24" cy="24" r="2.6"/><circle cx="48" cy="24" r="2.6"/><circle cx="72" cy="24" r="2.6"/>
|
||||||
|
<circle cx="24" cy="48" r="2.6"/><circle cx="72" cy="48" r="2.6"/>
|
||||||
|
<circle cx="24" cy="72" r="2.6"/><circle cx="48" cy="72" r="2.6"/><circle cx="72" cy="72" r="2.6"/>
|
||||||
|
</g>
|
||||||
|
<circle cx="48" cy="48" r="8" fill="none" stroke="#FFB454" stroke-opacity="0.3" stroke-width="2"/>
|
||||||
|
<circle cx="48" cy="48" r="4.5" fill="#FFB454"/>
|
||||||
|
<g fill="none" stroke="#35E0C4" stroke-width="3.5" stroke-linecap="round" stroke-linejoin="round">
|
||||||
|
<path d="M 33 41 V 33 H 41"/>
|
||||||
|
<path d="M 55 33 H 63 V 41"/>
|
||||||
|
<path d="M 63 55 V 63 H 55"/>
|
||||||
|
<path d="M 41 63 H 33 V 55"/>
|
||||||
|
</g>
|
||||||
|
</g>
|
||||||
|
<!-- wordmark -->
|
||||||
|
<g transform="translate(350,182)">
|
||||||
|
<g fill="none" stroke="#E8F4F2" stroke-width="11" stroke-linecap="round">
|
||||||
|
<path d="M 0 -24 H 48"/>
|
||||||
|
<path d="M 48 -24 A 24 24 0 1 0 40.97 -7.03"/>
|
||||||
|
<path d="M 110.97 -40.97 A 24 24 0 1 0 110.97 -7.03"/>
|
||||||
|
<path d="M 140 -76 V 0"/>
|
||||||
|
<path d="M 140 -24 A 24 24 0 0 1 188 -24 L 188 0"/>
|
||||||
|
<circle cx="234" cy="-24" r="24"/>
|
||||||
|
<path d="M 280 -76 V 0"/>
|
||||||
|
<circle cx="326" cy="-24" r="24" stroke="#35E0C4"/>
|
||||||
|
<path d="M 372 -48 H 402"/>
|
||||||
|
<path d="M 387 -68 V 0"/>
|
||||||
|
</g>
|
||||||
|
<circle cx="326" cy="-24" r="6.5" fill="#FFB454"/>
|
||||||
|
</g>
|
||||||
|
<text x="352" y="228" font-family="ui-monospace,'Cascadia Code','SF Mono',Menlo,Consolas,monospace" font-size="19" letter-spacing="3.5" fill="#5E8B96">measure, don't guess</text>
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 1.9 KiB |
@@ -0,0 +1,10 @@
|
|||||||
|
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 108 108">
|
||||||
|
<!-- Android adaptive-icon background layer: full-bleed, launcher applies the mask -->
|
||||||
|
<defs>
|
||||||
|
<linearGradient id="tile" x1="0" y1="0" x2="0" y2="1">
|
||||||
|
<stop offset="0" stop-color="#0E2433"/>
|
||||||
|
<stop offset="1" stop-color="#071522"/>
|
||||||
|
</linearGradient>
|
||||||
|
</defs>
|
||||||
|
<rect width="108" height="108" fill="url(#tile)"/>
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 404 B |
@@ -0,0 +1,18 @@
|
|||||||
|
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 108 108">
|
||||||
|
<!-- Android adaptive-icon foreground layer: 108dp canvas, art kept inside the 66dp safe circle -->
|
||||||
|
<g transform="translate(54,54) scale(0.8) translate(-48,-48)">
|
||||||
|
<g fill="#1E4A5C">
|
||||||
|
<circle cx="24" cy="24" r="2.6"/><circle cx="48" cy="24" r="2.6"/><circle cx="72" cy="24" r="2.6"/>
|
||||||
|
<circle cx="24" cy="48" r="2.6"/> <circle cx="72" cy="48" r="2.6"/>
|
||||||
|
<circle cx="24" cy="72" r="2.6"/><circle cx="48" cy="72" r="2.6"/><circle cx="72" cy="72" r="2.6"/>
|
||||||
|
</g>
|
||||||
|
<circle cx="48" cy="48" r="8" fill="none" stroke="#FFB454" stroke-opacity="0.3" stroke-width="2"/>
|
||||||
|
<circle cx="48" cy="48" r="4.5" fill="#FFB454"/>
|
||||||
|
<g fill="none" stroke="#35E0C4" stroke-width="3.5" stroke-linecap="round" stroke-linejoin="round">
|
||||||
|
<path d="M 33 41 V 33 H 41"/>
|
||||||
|
<path d="M 55 33 H 63 V 41"/>
|
||||||
|
<path d="M 63 55 V 63 H 55"/>
|
||||||
|
<path d="M 41 63 H 33 V 55"/>
|
||||||
|
</g>
|
||||||
|
</g>
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 1005 B |
|
After Width: | Height: | Size: 23 KiB |
@@ -0,0 +1,24 @@
|
|||||||
|
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 96 96">
|
||||||
|
<defs>
|
||||||
|
<linearGradient id="tile" x1="0" y1="0" x2="0" y2="1">
|
||||||
|
<stop offset="0" stop-color="#0E2433"/>
|
||||||
|
<stop offset="1" stop-color="#071522"/>
|
||||||
|
</linearGradient>
|
||||||
|
</defs>
|
||||||
|
<rect width="96" height="96" rx="21" fill="url(#tile)"/>
|
||||||
|
<!-- the network, at rest -->
|
||||||
|
<g fill="#1E4A5C">
|
||||||
|
<circle cx="24" cy="24" r="2.6"/><circle cx="48" cy="24" r="2.6"/><circle cx="72" cy="24" r="2.6"/>
|
||||||
|
<circle cx="24" cy="48" r="2.6"/> <circle cx="72" cy="48" r="2.6"/>
|
||||||
|
<circle cx="24" cy="72" r="2.6"/><circle cx="48" cy="72" r="2.6"/><circle cx="72" cy="72" r="2.6"/>
|
||||||
|
</g>
|
||||||
|
<!-- one node, under examination -->
|
||||||
|
<circle cx="48" cy="48" r="8" fill="none" stroke="#FFB454" stroke-opacity="0.3" stroke-width="2"/>
|
||||||
|
<circle cx="48" cy="48" r="4.5" fill="#FFB454"/>
|
||||||
|
<g fill="none" stroke="#35E0C4" stroke-width="3.5" stroke-linecap="round" stroke-linejoin="round">
|
||||||
|
<path d="M 33 41 V 33 H 41"/>
|
||||||
|
<path d="M 55 33 H 63 V 41"/>
|
||||||
|
<path d="M 63 55 V 63 H 55"/>
|
||||||
|
<path d="M 41 63 H 33 V 55"/>
|
||||||
|
</g>
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 1.1 KiB |
|
After Width: | Height: | Size: 26 KiB |
@@ -0,0 +1,39 @@
|
|||||||
|
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1280 640">
|
||||||
|
<rect width="1280" height="640" fill="#071522"/>
|
||||||
|
<!-- graduated rule -->
|
||||||
|
<path d="M 0 560 H 1280" fill="none" stroke="#0F2E3D" stroke-width="1.5"/>
|
||||||
|
<path d="M 40 565 H 1240" fill="none" stroke="#0F2E3D" stroke-width="9" stroke-dasharray="1.5 58.5"/>
|
||||||
|
<!-- glyph: focus -->
|
||||||
|
<g transform="translate(481.6,30) scale(3.3)">
|
||||||
|
<g fill="#1E4A5C">
|
||||||
|
<circle cx="24" cy="24" r="2.6"/><circle cx="48" cy="24" r="2.6"/><circle cx="72" cy="24" r="2.6"/>
|
||||||
|
<circle cx="24" cy="48" r="2.6"/><circle cx="72" cy="48" r="2.6"/>
|
||||||
|
<circle cx="24" cy="72" r="2.6"/><circle cx="48" cy="72" r="2.6"/><circle cx="72" cy="72" r="2.6"/>
|
||||||
|
</g>
|
||||||
|
<circle cx="48" cy="48" r="8" fill="none" stroke="#FFB454" stroke-opacity="0.3" stroke-width="2"/>
|
||||||
|
<circle cx="48" cy="48" r="4.5" fill="#FFB454"/>
|
||||||
|
<g fill="none" stroke="#35E0C4" stroke-width="3.5" stroke-linecap="round" stroke-linejoin="round">
|
||||||
|
<path d="M 33 41 V 33 H 41"/>
|
||||||
|
<path d="M 55 33 H 63 V 41"/>
|
||||||
|
<path d="M 63 55 V 63 H 55"/>
|
||||||
|
<path d="M 41 63 H 33 V 55"/>
|
||||||
|
</g>
|
||||||
|
</g>
|
||||||
|
<!-- wordmark, centered -->
|
||||||
|
<g transform="translate(356,442) scale(1.4)">
|
||||||
|
<g fill="none" stroke="#E8F4F2" stroke-width="11" stroke-linecap="round">
|
||||||
|
<path d="M 0 -24 H 48"/>
|
||||||
|
<path d="M 48 -24 A 24 24 0 1 0 40.97 -7.03"/>
|
||||||
|
<path d="M 110.97 -40.97 A 24 24 0 1 0 110.97 -7.03"/>
|
||||||
|
<path d="M 140 -76 V 0"/>
|
||||||
|
<path d="M 140 -24 A 24 24 0 0 1 188 -24 L 188 0"/>
|
||||||
|
<circle cx="234" cy="-24" r="24"/>
|
||||||
|
<path d="M 280 -76 V 0"/>
|
||||||
|
<circle cx="326" cy="-24" r="24" stroke="#35E0C4"/>
|
||||||
|
<path d="M 372 -48 H 402"/>
|
||||||
|
<path d="M 387 -68 V 0"/>
|
||||||
|
</g>
|
||||||
|
<circle cx="326" cy="-24" r="6.5" fill="#FFB454"/>
|
||||||
|
</g>
|
||||||
|
<text x="640" y="505" text-anchor="middle" font-family="ui-monospace,'Cascadia Code','SF Mono',Menlo,Consolas,monospace" font-size="22" letter-spacing="4" fill="#5E8B96">measure, don't guess</text>
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 2.0 KiB |
@@ -0,0 +1,17 @@
|
|||||||
|
<svg xmlns="http://www.w3.org/2000/svg" viewBox="-10 -92 433 104">
|
||||||
|
<!-- "echolot" — hand-drawn monoline letterforms (no font dependency). For dark grounds. -->
|
||||||
|
<g fill="none" stroke="#E8F4F2" stroke-width="11" stroke-linecap="round">
|
||||||
|
<path d="M 0 -24 H 48"/>
|
||||||
|
<path d="M 48 -24 A 24 24 0 1 0 40.97 -7.03"/>
|
||||||
|
<path d="M 110.97 -40.97 A 24 24 0 1 0 110.97 -7.03"/>
|
||||||
|
<path d="M 140 -76 V 0"/>
|
||||||
|
<path d="M 140 -24 A 24 24 0 0 1 188 -24 L 188 0"/>
|
||||||
|
<circle cx="234" cy="-24" r="24"/>
|
||||||
|
<path d="M 280 -76 V 0"/>
|
||||||
|
<circle cx="326" cy="-24" r="24" stroke="#35E0C4"/>
|
||||||
|
<path d="M 372 -48 H 402"/>
|
||||||
|
<path d="M 387 -68 V 0"/>
|
||||||
|
</g>
|
||||||
|
<!-- the finding -->
|
||||||
|
<circle cx="326" cy="-24" r="6.5" fill="#FFB454"/>
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 742 B |
@@ -0,0 +1,17 @@
|
|||||||
|
<svg xmlns="http://www.w3.org/2000/svg" viewBox="-10 -92 433 104">
|
||||||
|
<!-- "echolot" — hand-drawn monoline letterforms (no font dependency). For light grounds. -->
|
||||||
|
<g fill="none" stroke="#1B3540" stroke-width="11" stroke-linecap="round">
|
||||||
|
<path d="M 0 -24 H 48"/>
|
||||||
|
<path d="M 48 -24 A 24 24 0 1 0 40.97 -7.03"/>
|
||||||
|
<path d="M 110.97 -40.97 A 24 24 0 1 0 110.97 -7.03"/>
|
||||||
|
<path d="M 140 -76 V 0"/>
|
||||||
|
<path d="M 140 -24 A 24 24 0 0 1 188 -24 L 188 0"/>
|
||||||
|
<circle cx="234" cy="-24" r="24"/>
|
||||||
|
<path d="M 280 -76 V 0"/>
|
||||||
|
<circle cx="326" cy="-24" r="24" stroke="#0E9384"/>
|
||||||
|
<path d="M 372 -48 H 402"/>
|
||||||
|
<path d="M 387 -68 V 0"/>
|
||||||
|
</g>
|
||||||
|
<!-- the finding -->
|
||||||
|
<circle cx="326" cy="-24" r="6.5" fill="#E08A1E"/>
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 743 B |
@@ -33,6 +33,31 @@ Could NOT be compiled in the cloud sandbox: dl.google.com (Google Maven) and ser
|
|||||||
are proxy-blocked, and no device is reachable for on-device runs. Build + iterate locally
|
are proxy-blocked, and no device is reachable for on-device runs. Build + iterate locally
|
||||||
(Android Studio / Claude Code). Wrapper is pinned to Gradle 8.14.3.
|
(Android Studio / Claude Code). Wrapper is pinned to Gradle 8.14.3.
|
||||||
|
|
||||||
|
## Website — `web/` (2026-07-30)
|
||||||
|
Single-page site for echo-lot.app on Cloudflare Workers: static `public/` from the edge, a small
|
||||||
|
Worker for the stable short URLs (`/apk`, `/apk.sha256`, `/fdroid`, `/source`) and `/api/latest`.
|
||||||
|
Version info is resolved from the Gitea releases API at request time (edge-cached 5 min), so
|
||||||
|
tagging a release is the only publish step — the homepage shows the latest version/date/size via
|
||||||
|
progressive-enhancement JS and falls back to pre-release copy otherwise. Auto light/dark via
|
||||||
|
`prefers-color-scheme`: dark = sonar display, light = chart-recorder printout, same amber-accent
|
||||||
|
token system. Deploy: `npx wrangler deploy` from `web/`, or CI via
|
||||||
|
`.gitea/workflows/deploy-site.yml` (needs `CLOUDFLARE_API_TOKEN` + `CLOUDFLARE_ACCOUNT_ID`
|
||||||
|
secrets); full story in `web/README.md`. Open: favicon/wordmark are placeholders until the
|
||||||
|
branding assets land (in progress in a parallel session).
|
||||||
|
|
||||||
|
## Branding — `assets/branding/` (2026-07-30)
|
||||||
|
Identity chosen: the **Focus** mark — a quiet lattice of nodes with exactly one under examination
|
||||||
|
(amber) inside teal viewfinder brackets. Tone is surgical measurement, not scanning (sonar-sweep
|
||||||
|
visuals and the "sound out your network" tagline were explicitly rejected); tagline is
|
||||||
|
**"measure, don't guess"**. Palette: abyss `#071522`, tile `#0E2433`, instrument teal `#35E0C4`,
|
||||||
|
finding amber `#FFB454`, foam `#E8F4F2` — teal is always the instrument, the single amber point is
|
||||||
|
the finding. The wordmark is hand-drawn monoline SVG paths (zero font dependency); the second "o"
|
||||||
|
is the signature teal ring + amber ping. Assets: `icon.svg` (+ `icon.png` 512² — Gitea avatars reject SVG), `icon-adaptive-{foreground,background}.svg`
|
||||||
|
(108dp adaptive-icon layers, art inside the 66dp safe circle), `wordmark-on-{dark,light}.svg`,
|
||||||
|
`banner.svg` (1200×300, wired into the repo README), `social-preview.svg`/`.png` (1280×640, for the
|
||||||
|
Gitea/GitHub social-preview slot). The website's placeholder favicon/wordmark can now be replaced
|
||||||
|
from these.
|
||||||
|
|
||||||
## Next steps
|
## Next steps
|
||||||
1. Build locally, run on several physical devices (varied Android versions/vendors), collect the
|
1. Build locally, run on several physical devices (varied Android versions/vendors), collect the
|
||||||
JSON reports — especially the real per-device Shizuku dump formats.
|
JSON reports — especially the real per-device Shizuku dump formats.
|
||||||
|
|||||||