NextMyDay/internal/core/web/layout.html
Claus Lohmar dd865d4f27 feat(web): add the web shell and the PWA (SPEC-009)
- One base layout (layout.html) with the header, the nav from Registry.Nav()
  (D-038), a content slot and the CSRF token; every page renders inside it and
  a module supplies content only
- Embedded same-origin assets (app.css · app.js · webauthn.js · sw.js ·
  manifest.webmanifest · icons) served by the reserved `static` workflow
- webauthn.js drives the three ceremonies from data-* attributes — no inline
  script, so the CSP `script-src 'self'` holds (AC-3)
- manifest start_url "/" (D-011); the service worker never caches an
  authenticated response or /{GUID} (A5)
2026-10-14 10:53:57 +00:00

26 lines
1 KiB
HTML

<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>{{.Title}}</title>
<meta name="theme-color" content="#101828">
{{if .CSRF}}<meta name="csrf-token" content="{{.CSRF}}">{{end}}
<link rel="manifest" href="{{.StaticPath}}manifest.webmanifest">
<link rel="icon" type="image/png" sizes="192x192" href="{{.StaticPath}}icon-192.png">
<link rel="apple-touch-icon" href="{{.StaticPath}}icon-192.png">
<link rel="stylesheet" href="{{.StaticPath}}app.css">
<script src="{{.StaticPath}}app.js" defer></script>
<script src="{{.StaticPath}}webauthn.js" defer></script>
</head>
<body>
<header class="app-header">
<a class="brand" href="{{.HomeHref}}">{{.AppName}}</a>
{{if .Nav}}<nav aria-label="Main"><ul>{{range .Nav}}<li><a href="{{.Href}}"{{if .Active}} aria-current="page"{{end}}>{{.Label}}</a></li>{{end}}</ul></nav>{{end}}
</header>
{{if .Flash}}<p class="flash {{.FlashKind}}" role="status">{{.Flash}}</p>{{end}}
<main id="main"{{.MainAttrs}}>
{{.Content}}
</main>
</body>
</html>