m4: PWA install — manifest, icons, service worker
Make ThoughtSync installable ("Add to Home Screen") without going
offline-first (the Android app is the real offline client, M5):
- web app manifest (name, icons incl. maskable + SVG, standalone, theme)
- generated PNG icon set + apple-touch-icon + favicon, from committed
SVG sources (a linked-thoughts constellation on the brand tile)
- minimal service worker: installable shell only — caches just an
offline fallback page, never the app shell / hashed assets / API, so
data stays fresh and deploys never serve a stale shell
- register the SW in main.ts (progressive enhancement; failures ignored)
- index.html: manifest/icon links, apple-mobile meta, description
- backend: register the .webmanifest MIME type so it serves as
application/manifest+json
- README: note that install needs a secure context (HTTPS/localhost)
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FRgehjoz7Yv8LkUfADxACm
This commit is contained in:
@@ -0,0 +1,114 @@
|
||||
<!doctype html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<meta name="theme-color" content="#F5C518" />
|
||||
<title>Offline · ThoughtSync</title>
|
||||
<style>
|
||||
:root {
|
||||
color-scheme: light dark;
|
||||
}
|
||||
* {
|
||||
box-sizing: border-box;
|
||||
}
|
||||
html,
|
||||
body {
|
||||
height: 100%;
|
||||
margin: 0;
|
||||
}
|
||||
body {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
padding: 1.5rem;
|
||||
font-family:
|
||||
ui-sans-serif, system-ui, -apple-system, "Segoe UI", Roboto, Helvetica, Arial,
|
||||
sans-serif;
|
||||
background: #fafafa;
|
||||
color: #171717;
|
||||
}
|
||||
main {
|
||||
max-width: 22rem;
|
||||
text-align: center;
|
||||
}
|
||||
.icon {
|
||||
width: 72px;
|
||||
height: 72px;
|
||||
margin: 0 auto 1.25rem;
|
||||
display: block;
|
||||
}
|
||||
h1 {
|
||||
font-size: 1.25rem;
|
||||
font-weight: 700;
|
||||
letter-spacing: -0.01em;
|
||||
margin: 0 0 0.5rem;
|
||||
}
|
||||
p {
|
||||
font-size: 0.9rem;
|
||||
line-height: 1.5;
|
||||
color: #737373;
|
||||
margin: 0 0 1.5rem;
|
||||
}
|
||||
button {
|
||||
appearance: none;
|
||||
border: 0;
|
||||
cursor: pointer;
|
||||
font: inherit;
|
||||
font-weight: 600;
|
||||
font-size: 0.9rem;
|
||||
padding: 0.6rem 1.4rem;
|
||||
border-radius: 0.6rem;
|
||||
background: #f5c518;
|
||||
color: #18181b;
|
||||
}
|
||||
button:hover {
|
||||
filter: brightness(0.95);
|
||||
}
|
||||
button:focus-visible {
|
||||
outline: 2px solid #18181b;
|
||||
outline-offset: 2px;
|
||||
}
|
||||
@media (prefers-color-scheme: dark) {
|
||||
body {
|
||||
background: #0a0a0a;
|
||||
color: #f5f5f5;
|
||||
}
|
||||
p {
|
||||
color: #a3a3a3;
|
||||
}
|
||||
button:focus-visible {
|
||||
outline-color: #f5c518;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<main>
|
||||
<svg class="icon" viewBox="0 0 512 512" aria-hidden="true">
|
||||
<rect width="512" height="512" rx="112" fill="#F5C518" />
|
||||
<g stroke="#18181b" stroke-linecap="round" fill="none">
|
||||
<g stroke-width="14" opacity="0.26">
|
||||
<path d="M256 150 L166 336" />
|
||||
<path d="M166 336 L346 336" />
|
||||
<path d="M346 336 L256 150" />
|
||||
</g>
|
||||
<g stroke-width="22">
|
||||
<path d="M256 268 L256 150" />
|
||||
<path d="M256 268 L166 336" />
|
||||
<path d="M256 268 L346 336" />
|
||||
</g>
|
||||
</g>
|
||||
<g fill="#18181b">
|
||||
<circle cx="256" cy="150" r="34" />
|
||||
<circle cx="166" cy="336" r="34" />
|
||||
<circle cx="346" cy="336" r="34" />
|
||||
<circle cx="256" cy="268" r="26" />
|
||||
</g>
|
||||
</svg>
|
||||
<h1>You're offline</h1>
|
||||
<p>ThoughtSync needs a connection to your server to load. Reconnect and try again.</p>
|
||||
<button type="button" onclick="location.reload()">Retry</button>
|
||||
</main>
|
||||
</body>
|
||||
</html>
|
||||
Reference in New Issue
Block a user