tilfluktsrom/pwa/index.html

80 lines
3.9 KiB
HTML
Raw Permalink Normal View History

<!DOCTYPE html>
<html lang="en" dir="ltr">
<head>
<meta charset="UTF-8" />
<!-- WCAG 1.4.4 Resize Text: do not pin maximum-scale or disable user-scalable.
Leaflet handles its own touch gestures on the map; the rest of the page
(status bar, bottom sheet, dialogs) must remain zoomable for low-vision users. -->
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta name="theme-color" content="#1A1A2E" />
<meta name="description" content="Find the nearest public shelter in Norway" />
<!-- iOS home-screen/PWA integration: run in standalone mode, dark status bar, correct label. -->
<meta name="apple-mobile-web-app-capable" content="yes" />
<meta name="apple-mobile-web-app-status-bar-style" content="black-translucent" />
<meta name="apple-mobile-web-app-title" content="Tilfluktsrom" />
<meta http-equiv="Content-Security-Policy"
content="default-src 'self'; script-src 'self'; style-src 'self' 'unsafe-inline'; img-src 'self' data: https://*.tile.openstreetmap.org; connect-src 'self' https://*.tile.openstreetmap.org; font-src 'self'; worker-src 'self'" />
<title>Tilfluktsrom</title>
<link rel="manifest" href="manifest.webmanifest" />
<link rel="icon" type="image/png" sizes="192x192" href="icons/icon-192.png" />
<link rel="apple-touch-icon" href="icons/icon-192.png" />
</head>
<body>
<div id="app">
<!-- Status bar -->
<header id="status-bar" role="banner">
<span id="status-text" aria-live="polite"></span>
<button id="about-btn" aria-label="About">&#x2139;</button>
<button id="share-btn" aria-label="Share shelter">
<svg viewBox="0 0 24 24" width="20" height="20" fill="currentColor" aria-hidden="true" focusable="false">
<path d="M18 16.08c-.76 0-1.44.3-1.96.77L8.91 12.7c.05-.23.09-.46.09-.7s-.04-.47-.09-.7l7.05-4.11c.54.5 1.25.81 2.04.81 1.66 0 3-1.34 3-3s-1.34-3-3-3-3 1.34-3 3c0 .24.04.47.09.7L8.04 9.81C7.5 9.31 6.79 9 6 9c-1.66 0-3 1.34-3 3s1.34 3 3 3c.79 0 1.5-.31 2.04-.81l7.12 4.16c-.05.21-.08.43-.08.65 0 1.61 1.31 2.92 2.92 2.92s2.92-1.31 2.92-2.92-1.31-2.92-2.92-2.92z"/>
</svg>
</button>
<button id="refresh-btn" aria-label="Refresh data">&#x21bb;</button>
</header>
<!-- Main content: map or compass -->
<main id="main-content">
<div id="map-container" role="application" aria-label="Map"></div>
<div id="compass-container" role="img" aria-label="Compass">
<span id="compass-address"></span>
<span id="compass-distance" aria-live="polite"></span>
</div>
<!-- Toggle map/compass FAB -->
<button id="toggle-fab" aria-label="Toggle map/compass view">&#x1F9ED;</button>
<!-- Reset view button -->
<button id="reset-view-btn" aria-label="Reset view">&#x2316;</button>
</main>
<!-- No-cache warning banner -->
<div id="no-cache-banner" role="alert">
<span id="no-cache-text"></span>
<button id="cache-retry-btn"></button>
</div>
<!-- Bottom sheet with shelter info -->
<aside id="bottom-sheet" aria-label="Shelter info">
<div id="selected-shelter" aria-live="polite">
<canvas id="mini-arrow" width="96" height="96" role="img" aria-label="Direction to shelter"></canvas>
<div id="selected-shelter-info">
<div id="selected-shelter-address"></div>
<div id="selected-shelter-details"></div>
</div>
</div>
<div id="shelter-list" role="list" aria-label="Nearest shelters"></div>
</aside>
</div>
<!-- Loading overlay -->
<div id="loading-overlay" role="dialog" aria-modal="true" aria-label="Loading">
<div id="loading-spinner" aria-hidden="true"></div>
<div id="loading-text" aria-live="assertive" tabindex="-1"></div>
<div id="loading-button-row">
<button id="loading-skip-btn"></button>
<button id="loading-ok-btn"></button>
</div>
</div>
<script type="module" src="src/main.ts"></script>
</body>
</html>