# Blossom Server Sidenav Section

## Overview

Add a **Blossom Servers** section to the sidenav on **all pages**, mirroring the existing relay section pattern. This replaces the current server management UI that lives only in the `blobs.html` sidenav body with a compact, fixed-position section visible across the entire app.

## Current Architecture

### Relay Section Pattern (to mirror)

The relay section follows this architecture across all 20 pages:

1. **HTML** — A `#divRelaySection` div sits between `#divSideNavBody` and `#divVersionBar` in the sidenav
2. **CSS** — Global styles in `www/css/client.css` define `#divRelaySection`, `#divRelaySectionTitle`, `#divRelayList`
3. **Module** — `www/js/relay-ui.mjs` exports `initSidenavRelaySection()` and `updateSidenavRelaySection()`
4. **Per-page wiring** — Each page imports from `relay-ui.mjs`, calls `initSidenavRelaySection()` at startup, and `updateSidenavRelaySection()` in its periodic `UpdateFooter()` loop

### Current Blossom Server Management (blobs.html only)

- Server list stored in `USER_SERVER_LIST` array with health status
- Server list fetched via Nostr kind 10063 subscription
- Full management UI (add/remove/test/publish) rendered in `loadSideNav()` into `#divSideNavBody`
- Health checking via `checkServerHealth()` function

## Proposed Architecture

```mermaid
graph TD
    A[www/js/blossom-ui.mjs] --> B[initBlossomSection]
    A --> C[updateBlossomSection]
    A --> D[getBlossomServers]
    
    B --> E[Creates HamburgerMorphing indicators]
    C --> F[Updates health status indicators]
    D --> G[Subscribes to kind 10063 events]
    D --> H[Checks server health]
    
    I[www/css/client.css] --> J[#divBlossomSection]
    I --> K[#divBlossomSectionTitle]
    I --> L[#divBlossomList]
    
    M[Every HTML page] --> N[HTML: divBlossomSection in sidenav]
    M --> O[JS: import and call blossom-ui.mjs]
```

### Sidenav Layout Order

```
#divSideNav
  ├── #divSideNavHeader
  ├── #divSideNavBody        (flex: 1, scrollable)
  ├── #divRelaySection       (fixed, max-height: 200px)
  ├── #divBlossomSection     (fixed, max-height: 200px)  ← NEW
  └── #divVersionBar         (fixed height)
```

## Implementation Steps

### 1. Create `www/js/blossom-ui.mjs`

A new module mirroring `relay-ui.mjs` with these exports:

- **`initBlossomSection()`** — Called once at page init. Sets up the section, subscribes to kind 10063 events via `subscribe()` from `init-ndk.mjs`
- **`updateBlossomSection()`** — Called periodically from `UpdateFooter()`. Refreshes server health indicators
- **`getBlossomServers()`** — Returns the current server list array (for use by `blobs.html` and other pages that need server data)

The module will:
- Subscribe to kind 10063 events to get the user's blossom server list
- Parse server tags from the event
- Perform health checks on each server
- Render a compact list in `#divBlossomList` showing:
  - Server domain name
  - Health status indicator (HamburgerMorphing shape: circle=unchecked, plus=healthy, x=unhealthy)
  - Upload/mirror capability indicators

### 2. Add CSS to `www/css/client.css`

Add styles for `#divBlossomSection`, `#divBlossomSectionTitle`, `#divBlossomList` — identical structure to the relay section styles:

```css
#divBlossomSection {
  flex-shrink: 0;
  max-height: 200px;
  overflow-y: auto;
  background-color: var(--secondary-color);
  border-top: 3px solid var(--primary-color);
  padding: 10px;
}

#divBlossomSectionTitle {
  font-family: pageKanji;
  font-size: 100%;
  font-weight: bold;
  margin-bottom: 10px;
  padding-bottom: 5px;
  border-bottom: 1px solid var(--muted-color);
}

#divBlossomList {
  font-size: 70%;
  font-family: var(--font-family);
}
```

### 3. Add HTML to all 20 pages

Insert between `#divRelaySection` and `#divVersionBar`:

```html
<div id="divBlossomSection">
  <div id="divBlossomSectionTitle">ブロッサム</div>
  <div id="divBlossomList">Loading servers...</div>
</div>
```

### 4. Update all 20 pages JavaScript

Add import and initialization calls:

```javascript
// Import
import { initBlossomSection, updateBlossomSection } from './js/blossom-ui.mjs';

// In main init
initBlossomSection();

// In UpdateFooter
await updateBlossomSection();
```

### 5. Refactor `blobs.html`

- Remove the server management UI from `loadSideNav()` (the サーバー管理 section)
- Import `getBlossomServers` from `blossom-ui.mjs` instead of maintaining its own `USER_SERVER_LIST`
- Keep blob-specific functionality (upload, delete, sync, grid/list view) but source server data from the shared module
- The sidenav body can be repurposed for blob-specific controls or left minimal

## Pages to Update (20 total)

1. `www/ai.html`
2. `www/blobs.html`
3. `www/cal.html`
4. `www/cashu.html`
5. `www/db.html`
6. `www/didactyl.html`
7. `www/event.html`
8. `www/index.html`
9. `www/links.html`
10. `www/msg.html`
11. `www/music.html`
12. `www/note.html`
13. `www/npub.html`
14. `www/post.html`
15. `www/profile.html`
16. `www/relays.html`
17. `www/skills-demo.html`
18. `www/strudel.html`
19. `www/template.html`
20. `www/todo.html`
21. `www/tools.html`

## Key Design Decisions

1. **Japanese title**: ブロッサム (Burossamu = Blossom) to match リレー pattern
2. **Health indicators**: Use HamburgerMorphing shapes consistent with relay indicators
3. **Shared state**: The module manages its own server list state, exposed via `getBlossomServers()` for pages like `blobs.html` that need to interact with servers
4. **Subscription**: Each page subscribes to kind 10063 independently through the shared NDK worker — the module handles deduplication
5. **Health check frequency**: Health checks run on init and then periodically (every 60 seconds) to avoid excessive network requests
