3 Commits

Author SHA1 Message Date
Keysat 211287aed5 Consolidate UI colors behind CSS custom properties; fix design drift
Phase 1 of the design-contract conformance cleanup. Add a canonical
:root token block (single source of truth, mirroring
design/tokens.tokens.json) to public/index.html's stylesheet and migrate
the whole <style> block to var(--token); give public/auth.html its own
subset :root and migrate it too.

Fix all color + weight drift across every surface (stylesheet, inline
styles, JS handlers, the SHARE_PAGE_CSS export):
- legacy indigos #6366f1/#4f46e5/#4338ca + rgba(99,102,241) ->
  #818cf8/#a5b4fc/rgba(129,140,248)
- blue #3b82f6 interactive buttons (incl. the whole auth screen) -> indigo
- legacy darks #0a0e17/#0b1120/#020617/#121828/#1f2942 -> the surface ladder
- #f5f9ff -> #f1f5f9, #312e81 -> #1e293b, weights 650->600 / 680->700

The meta theme-color stays a literal #0a0e1a. Verified: 144 tests pass,
both pages serve 200, all var() references resolve. Phase 2 (var-ifying
the long-tail inline styles, snapping off-scale font/radius) is in
ROADMAP.md.
2026-06-16 23:36:42 -05:00
Keysat 91af0b711e Harden iOS sign-in against stale-connection POST failures
iPad users hit a spurious "network error" on the first tap of
"Send sign-in link", with a second tap succeeding. Cause is iOS
Safari dispatching the POST onto a pooled keep-alive socket the
server/proxy already closed; unlike a GET it isn't transparently
re-sent, so it surfaces as a transport TypeError. The single 500ms
auto-retry was too quick and reused the same dead socket.

Both sign-in entry points (auth.html postWithRetry, index.html
fetchWithRetry) now retry 3x with growing backoff (0 -> +400ms ->
+1.6s) to outlast Safari evicting the socket. Frontend-only.

Ships as 0.2.156.
2026-06-15 16:35:13 -05:00
Keysat 0ae59f3550 Add multi-tenant cloud mode: self-serve purchase, credit metering, core-decoupling
Introduces RECAP_MODE=multi alongside single-mode self-host:
- Tenant auth + accounts (magic-link via System SMTP), per-tenant credit pool,
  anonymous trial minting with per-IP/-64 caps
- Self-serve Pro/Max purchase: inline Lightning (BTCPay) + card (Zaprite),
  prepaid 30-day periods, expiry-reminder emails
- Core-decoupling: relay owns cloud tier/expiry keyed by Recaps user-id
- SQLite (better-sqlite3) schema for multi-mode; filesystem unchanged for single
- StartOS actions/versions through 0.2.155
2026-06-13 14:25:05 -05:00