feat: add PWA support and mobile-responsive layouts

- Add web app manifest, maskable/apple-touch icons, and a production-only
  service worker that caches the app shell for offline start
- Improve mobile UX: responsive breakpoints from ~320px, 44px touch
  targets, safe-area insets, dvh heights, 16px inputs to avoid iOS zoom
- Serve .webmanifest with correct content type in the Go static handler
- Document PWA behavior and mobile features in the README
This commit is contained in:
Tronax 2026-08-25 19:12:12 +02:00
parent f220d96e3b
commit cbc03c56bf
Signed by: Tronax
SSH key fingerprint: SHA256:2pKKXDZucWvaF/GzXNz0FY53EAO1YDLN80bqS+TTz/o
18 changed files with 277 additions and 9 deletions

View file

@ -0,0 +1,14 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512">
<defs>
<linearGradient id="g" x1="0" y1="0" x2="1" y2="1">
<stop offset="0" stop-color="#7db0ff"/>
<stop offset="1" stop-color="#b78cff"/>
</linearGradient>
</defs>
<!-- Apple Touch Icon: vollflächig, ohne Transparenz (iOS maskiert selbst) -->
<rect width="512" height="512" fill="url(#g)"/>
<rect x="112" y="132" width="288" height="268" rx="46" fill="#0b0f1a" opacity="0.88"/>
<path d="M186 104v52M326 104v52" stroke="#ffffff" stroke-width="26" stroke-linecap="round" opacity="0.95"/>
<path d="M118 198h276" stroke="#ffffff" stroke-width="10" stroke-linecap="round" opacity="0.22"/>
<path d="M186 272l52 52 92-92" stroke="#ffffff" stroke-width="34" stroke-linecap="round" stroke-linejoin="round" fill="none"/>
</svg>

After

Width:  |  Height:  |  Size: 819 B

View file

@ -0,0 +1,13 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512">
<defs>
<linearGradient id="g" x1="0" y1="0" x2="1" y2="1">
<stop offset="0" stop-color="#7db0ff"/>
<stop offset="1" stop-color="#b78cff"/>
</linearGradient>
</defs>
<!-- Maskable: Vollflächiger Hintergrund, Glyphe komplett in der 80%-Sicherheitszone -->
<rect width="512" height="512" fill="url(#g)"/>
<rect x="146" y="166" width="220" height="196" rx="36" fill="#0b0f1a" opacity="0.88"/>
<path d="M196 134v46M316 134v46" stroke="#ffffff" stroke-width="22" stroke-linecap="round" opacity="0.95"/>
<path d="M190 264l40 40 72-72" stroke="#ffffff" stroke-width="28" stroke-linecap="round" stroke-linejoin="round" fill="none"/>
</svg>

After

Width:  |  Height:  |  Size: 729 B

View file

@ -0,0 +1,13 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512">
<defs>
<linearGradient id="g" x1="0" y1="0" x2="1" y2="1">
<stop offset="0" stop-color="#7db0ff"/>
<stop offset="1" stop-color="#b78cff"/>
</linearGradient>
</defs>
<rect width="512" height="512" rx="112" fill="url(#g)"/>
<rect x="112" y="132" width="288" height="268" rx="46" fill="#0b0f1a" opacity="0.88"/>
<path d="M186 104v52M326 104v52" stroke="#ffffff" stroke-width="26" stroke-linecap="round" opacity="0.95"/>
<path d="M118 198h276" stroke="#ffffff" stroke-width="10" stroke-linecap="round" opacity="0.22"/>
<path d="M186 272l52 52 92-92" stroke="#ffffff" stroke-width="34" stroke-linecap="round" stroke-linejoin="round" fill="none"/>
</svg>

After

Width:  |  Height:  |  Size: 746 B

View file

@ -0,0 +1,22 @@
{
"name": "WannPassts",
"short_name": "WannPassts",
"description": "Deine freien Zeiten geteilt per Link. Verbinde Google-, iCloud- und andere Kalender und nimm Buchungsanfragen an, ohne deine Termine preiszugeben.",
"lang": "de",
"dir": "ltr",
"start_url": "/",
"scope": "/",
"display": "standalone",
"orientation": "any",
"background_color": "#05070c",
"theme_color": "#05070c",
"icons": [
{ "src": "/icons/icon-192.png", "sizes": "192x192", "type": "image/png", "purpose": "any" },
{ "src": "/icons/icon-512.png", "sizes": "512x512", "type": "image/png", "purpose": "any" },
{ "src": "/icons/icon-maskable-512.png", "sizes": "512x512", "type": "image/png", "purpose": "maskable" }
],
"shortcuts": [
{ "name": "Anfragen", "url": "/app?tab=requests" },
{ "name": "Kalender", "url": "/app?tab=calendars" }
]
}