# Code Request — Trinity Console PWA Phase 1

**Filed by:** Chronicler #88
**Date:** 2026-04-14
**Priority:** Medium
**Task DB:** task_number 117

---

## What To Build

Make Trinity Console installable as a Progressive Web App. Phase 1 only —
foundation that enables "Add to Home Screen" on Android and iOS.

---

## Files To Create

### 1. `src/public/manifest.json`

```json
{
  "name": "Trinity Console",
  "short_name": "Trinity",
  "description": "Firefrost Gaming Operations Console",
  "start_url": "/admin",
  "display": "standalone",
  "background_color": "#1a1a1a",
  "theme_color": "#06b6d4",
  "orientation": "portrait-primary",
  "icons": [
    {
      "src": "/images/trinity-icon-192.png",
      "sizes": "192x192",
      "type": "image/png",
      "purpose": "any maskable"
    },
    {
      "src": "/images/trinity-icon-512.png",
      "sizes": "512x512",
      "type": "image/png",
      "purpose": "any maskable"
    }
  ]
}
```

### 2. `src/public/sw.js` (Service Worker)

Cache static assets only. Never cache admin API responses or HTMX partials.

```javascript
const CACHE_NAME = 'trinity-console-v1';
const STATIC_ASSETS = [
  '/css/app.css',
  '/manifest.json'
];

self.addEventListener('install', event => {
  event.waitUntil(
    caches.open(CACHE_NAME).then(cache => cache.addAll(STATIC_ASSETS))
  );
});

self.addEventListener('fetch', event => {
  // Only cache GET requests for static assets
  if (event.request.method !== 'GET') return;
  if (event.request.url.includes('/admin/')) return; // Never cache admin routes
  
  event.respondWith(
    caches.match(event.request).then(cached => cached || fetch(event.request))
  );
});
```

### 3. Icon placeholders

Create simple placeholder PNGs at:
- `src/public/images/trinity-icon-192.png`
- `src/public/images/trinity-icon-512.png`

Use the cyan (#06b6d4) Firefrost color with a simple ❄️ or "T" — we'll replace
with proper branding later.

---

## Files To Modify

### `src/views/layout.ejs` — Add to `<head>`:

```html
<!-- PWA -->
<link rel="manifest" href="/manifest.json">
<meta name="theme-color" content="#06b6d4">
<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="Trinity">
<link rel="apple-touch-icon" href="/images/trinity-icon-192.png">

<!-- Service Worker Registration -->
<script>
  if ('serviceWorker' in navigator) {
    window.addEventListener('load', () => {
      navigator.serviceWorker.register('/sw.js').catch(err => console.log('SW registration failed:', err));
    });
  }
</script>
```

Make sure `<meta name="viewport" content="width=device-width, initial-scale=1">` 
exists in the head (add if missing).

---

## Notes

- Phase 2 (mobile layout) and Phase 3 (push notifications) are separate tasks
- Icons are placeholders — proper branding assets come later
- The service worker should be conservative — cache as little as possible to
  avoid stale admin data
- Test by opening Trinity Console in Chrome mobile → three-dot menu → 
  "Add to Home Screen"

---

**Fire + Frost + Foundation** 💙🔥❄️
