.gitignore had "*.keystore" followed by "!debug.keystore", which
deliberately un-ignored a signing key. Nothing leaked - no keystore has
ever been in the tree - but had one landed there it would have been
committed silently. The negation is gone and *.jks is covered too.
public/fonts/ redistributes Space Grotesk and Space Mono, and the SIL
Open Font License requires its text to accompany the fonts. Both are
included, fetched from each typeface's own repository rather than
written from memory, and kept as separate files because the copyright
lines differ: Space Grotesk 2020, Space Mono 2016.
Added a README there recording which file is which family, why only the
latin subsets are shipped, and the two glyphs that fall outside them and
so render from a system fallback - which is why the pickers draw their
caret as SVG instead of typing it.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Vite builds to dist/, deliberately not www/. www/ is still produced by
sync-www.sh for the Phase 1 APK, which stays installable throughout the
port; cutover is a one-line webDir change in capacitor.config.json.
base is relative because Capacitor serves the bundle from the APK, where
absolute asset paths would 404.
index.html omits viewport-fit=cover on purpose. That string is what
makes Capacitor's SystemBars plugin pass insets through to the page;
without it the plugin pads the decor view and the layout is always
between the status and gesture bars. Phase 1 learned this the hard way.
Fonts are self-hosted for offline use, latin subsets only: three files
at 68K, against the 133K Barlow costs today. Space Grotesk is variable,
so one file covers 400-700. Dropped latin-ext and vietnamese.
Carets are drawn as SVG, not typed. U+25BE and U+23EE sit outside every
Latin subset and would fall back to a system font mid-label.
base.css carries the settled palette and the measured vertical budget as
tokens, so a component cannot quietly exceed it:
8 + 44 + 8 + 525 + 8 + 84 + 8 + 50 = 735
Verified: typecheck clean, 103 tests, vite build emits with the fonts
copied, and www/ is untouched.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Design inspiration is the Teenage Engineering EP-133 manual: flat fills,
heavy outlines, hard zero-blur offset shadows, one orange accent,
uppercase technical type, monospaced numerals.
Six artboards drawn at the real measured 360x735 with the actual
vertical budget (44px pickers, 485px panel, 116px info, 58px tabs), so
a mockup cannot fit in a way the device won't:
- Current the app as it stands, for comparison
- A Manual light ground, 2px black outlines, black pads
- B Blueprint pure black, 1px white hairlines, no fills
- Specimen type candidates and palette, incl. which orange
Type is identical across both directions so the light/dark choice is
not confounded with the font choice. Green/red drill feedback is
replaced by orange fill vs dashed outline - neither exists in this
palette.
The seeded canvas payload is gitignored; these files are its source.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Wraps reference/sp404-layers as a sideloadable APK without editing the
reference, which stays the frozen spec for the Phase 2 React port.
- sync-www.sh builds www/ from reference/ + native/, asserting each patch
anchor so a reference change fails loudly rather than shipping broken
- drops the service worker (would serve a stale app after an APK update)
- haptics via a navigator.vibrate override, so buzz() needs no change
- localStorage mirrored into Preferences; sync load()/save() untouched
- hardware back: sheet -> Explore tab -> exit
- edge-to-edge handled in MainActivity: Android 16 + targetSdk 36 removes
the opt-out, and a WebView never fills env(safe-area-inset-*), so insets
are pushed into CSS custom properties instead
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>