# Lotus Chat — Work Backlog

**Repo:** `lotus` branch at `https://code.lotusguild.org/LotusGuild/cinny`  
**Deploy:** push to `lotus` → CI → auto-deploy to `chat.lotusguild.org` (~11 min)

---

## ⚠️ TDS DESIGN LAW — READ BEFORE TOUCHING ANY UI

> **ALL Lotus Terminal Design System (TDS) styling — colors, animations, glows, borders, fonts, spacing — MUST come exclusively from `/root/code/web_template/base.css` CSS variables.**
> Do NOT hardcode hex values. Do NOT invent new variable names. Do NOT deviate from the design tokens defined in that file.
> The canonical variable reference: `--lt-accent-orange`, `--lt-accent-cyan`, `--lt-accent-green`, `--lt-glow-orange`, `--lt-box-glow-*`, `--lt-border-color`, etc.
> Reference implementation for code patterns: `/root/code/tinker_tickets/` (markdown.js, base.js, ticket.css)
> This rule applies to EVERY task in this file without exception.

---

Completed features are documented in [LOTUS_FEATURES.md](./LOTUS_FEATURES.md).

---

Legend:

- `[AUDIT REQUIRED]` — at least one assumption needs code/server verification before implementing
- `[SERVER CHECK]` — depends on a Synapse feature or MSC; verify on `matrix.lotusguild.org`
- `[LOW PRIORITY]` — implement after all higher-priority items
- `[EXTREME COMPLEXITY]` — multi-sprint, plan separately before touching
- `[BLOCKED]` — cannot build until a server upgrade, upstream MSC, or dependency resolves
- `[IMPROVE]` — feature exists in upstream Cinny; this task enhances it for Lotus Chat

Status: `[ ]` pending · `[~]` in progress · `[x]` completed

---

## Server Capabilities (as of June 2026)

- **Homeserver:** `matrix.lotusguild.org`
- **Synapse version:** `1.153.0` (2026-05-19) — fully up to date
- **Matrix spec:** up to `v1.12` formally; newer MSC features via `unstable_features`

### Confirmed facts

| Finding                                                                                              | Impact                                                                         |
| ---------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------ |
| **MSC flags ON:** `msc4140` · `msc3771` · `msc3440.stable` · `msc4133.stable` · `simplified_msc3575` | All safe to use now                                                            |
| **MSC flags OFF:** `msc4306` (thread subscriptions) · `msc3882` · `msc3912` · `msc4155`              | These features are BLOCKED                                                     |
| **MSC3266** room summary: returns 404                                                                | Room Preview feature BLOCKED                                                   |
| **MSC3892** relation redaction: not in flags                                                         | Reaction Redaction feature BLOCKED                                             |
| **MSC4260** report user: server at v1.12, endpoint may not exist                                     | Report User feature BLOCKED                                                    |
| **MSC4151** report room: HTTP 405 on GET = endpoint exists (POST only)                               | Report Room live ✅                                                            |
| `folds AvatarImage` does NOT accept children                                                         | Add frame/overlay inside `UserAvatar.tsx` itself — optional `frameName` prop   |
| No in-app toast system exists (was)                                                                  | Built `ToastProvider` + Jotai queue; at `App.tsx:65`                           |
| `useUnverifiedDeviceCount()` hook exists                                                             | `src/app/hooks/useDeviceVerificationStatus.ts:65-106`                          |
| Voice player: `AudioContent.tsx:44-223`                                                              | Playback rate on hidden `<audio>` at line 217                                  |
| `CallControl.setMicrophone(bool)` at `CallControl.ts:206-212`                                        | For AFK auto-mute                                                              |
| `CallControl.toggleSound()` at `CallControl.ts:230-251`                                              | Push-to-deafen — just wire a hotkey to this                                    |
| matrix-js-sdk has NO arbitrary profile field methods                                                 | Use `mx.http.authedRequest()` for MSC4133                                      |
| Sanitizer (`sanitize.ts`) allows table, div, span, a, code, hr                                       | LFG HTML card is safe locally; test on Element/FluffyChat                      |
| Sanitizer STRIPS `<math>`/MathML tags                                                                | Math/LaTeX task must also modify sanitizer                                     |
| Service worker EXISTS at `src/sw.ts`                                                                 | Quick-reply task: add `notificationclick` handler                              |
| `knockSupported()` utility exists at `matrix.ts:376-391`                                             | Knock UX: only need "Request to Join" in `RoomIntro.tsx`                       |
| `KeywordMessages.tsx` already has custom keyword push rules                                          | Full push rule editor: only non-keyword rule types need new UI                 |
| `getMatrixToRoom()` in `matrix-to.ts` generates invite URLs                                          | Invite link: just add QR code to room settings                                 |
| Cindy CANNOT inject audio into EC call stream                                                        | In-call soundboard must be redesigned as local-only                            |
| Folds uses vanilla-extract in non-TDS, NOT CSS custom properties                                     | Custom accent color: must create new vanilla-extract theme variant dynamically |
| Theme presets need ~50 CSS custom properties each                                                    | Significant design work before coding                                          |
| `useCallSpeakers.ts` CSS MutationObserver polling                                                    | Visual speaking indicator: TDS ring animation on top of existing data          |
| MSC3489/3672 live location: BOTH false on server                                                     | Live Location BLOCKED                                                          |

---

## Key File Reference

| What you need                    | File                                                          | Lines               |
| -------------------------------- | ------------------------------------------------------------- | ------------------- |
| Global keydown hook              | `src/app/hooks/useKeyDown.ts`                                 | whole file          |
| Room navigation                  | `src/app/hooks/useRoomNavigate.ts`                            | 19-72               |
| All room IDs atom                | `src/app/state/room-list/roomList.ts`                         | `allRoomsAtom`      |
| Room unread counts               | `src/app/state/room/roomToUnread.ts`                          | `roomToUnreadAtom`  |
| Overlay portal provider          | `src/app/pages/App.tsx`                                       | 65                  |
| Portal container div             | `index.html`                                                  | 101                 |
| Room settings tabs               | `src/app/features/room-settings/RoomSettings.tsx`             | 27-56               |
| State event read/write pattern   | `src/app/features/common-settings/general/RoomEncryption.tsx` | 42-52               |
| Power level checker              | `src/app/hooks/usePowerLevels.ts`                             | whole file          |
| Slash command registration       | `src/app/hooks/useCommands.ts`                                | 140-537             |
| Chat background picker           | `src/app/features/settings/general/General.tsx`               | 945-981             |
| Chat backgrounds definition      | `src/app/features/lotus/chatBackground.ts`                    | whole file          |
| Matrix.to URL builder            | `src/app/plugins/matrix-to.ts`                                | `getMatrixToRoom()` |
| Media event content types        | `src/app/types/matrix/common.ts`                              | 46-91               |
| Media URL conversion             | `src/app/utils/matrix.ts`                                     | `mxcUrlToHttp()`    |
| Message pagination (search)      | `src/app/features/message-search/useMessageSearch.ts`         | 74-121              |
| Infinite pagination pattern      | `src/app/features/message-search/MessageSearch.tsx`           | 234-365             |
| Poll event format                | `src/app/components/message/content/PollContent.tsx`          | 1-320               |
| Theme class application          | `src/app/hooks/useTheme.ts`                                   | 25-60               |
| Animations file                  | `src/app/styles/Animations.css.ts`                            | whole file          |
| Message status (EventStatus)     | `src/app/features/room/message/Message.tsx`                   | 84-142              |
| Call member change events        | `src/app/hooks/useCall.ts`                                    | 37-52               |
| Mic control in calls             | `src/app/plugins/call/CallControl.ts`                         | 206-212             |
| Device verification hook         | `src/app/hooks/useDeviceVerificationStatus.ts`                | 65-106              |
| Knock room support check         | `src/app/utils/matrix.ts`                                     | 376-391             |
| Room join button location        | `src/app/components/room-intro/RoomIntro.tsx`                 | 25-119              |
| Notification mute via push rules | `src/app/hooks/useRoomsNotificationPreferences.ts`            | 110-150             |
| Message text body CSS            | `src/app/components/message/layout/layout.css.ts`             | 182-205             |

---

## Priority 3 — Higher complexity / lower daily frequency

### [ ] P3-4 · Accessibility Improvements (WCAG 2.1 AA)

**What:** Comprehensive audit and fix pass targeting the critical user paths:

- Room list navigation (keyboard-only)
- Reading messages in the timeline (screen reader announces new messages)
- Composing and sending a reply
- Opening and closing modals (focus trap, return focus)
- ARIA labels on all icon-only buttons  
  **Scope:** Do NOT attempt to make every corner of the app AA-compliant in one pass — focus on the golden path (open app → find room → read → reply → send).  
  **[AUDIT REQUIRED]** — Run an automated audit first: `npx axe-core` or browser DevTools accessibility tree. Document every violation before writing a single line of code. Prioritize by severity (critical > serious > moderate).  
  **Complexity:** Medium-High (audit is the main work).

---

### [x] P3-6 · Configurable Composer Toolbar

**What:** Let users rearrange or hide individual composer toolbar buttons (GIF, Sticker, Emoji, File, Voice, Location). Changes stored in `settingsAtom`. Access via a small "⚙ Customize toolbar" option in toolbar overflow.  
**[AUDIT REQUIRED]** — Audit the current toolbar button rendering in `RoomInput.tsx`. Understand the layout system (is it a fixed array or already mapped from config?). Drag-to-reorder may require a DnD library; consider whether reorder is worth the complexity vs just toggle-visibility.  
**Complexity:** Medium-High (drag reorder adds significant complexity).

---

### [ ] P3-8 · Thread Panel (full side drawer)

**⚠️ LARGEST FEATURE — requires its own planning session before implementation.**  
**What:** A right-side drawer for threaded conversations. Currently "Reply in Thread" exists but there is no panel to read or write thread replies.  
Features:

- Click "Reply in Thread" → opens thread drawer on the right
- Thread root event shown at the top of the panel
- Full message rendering for all in-thread replies (reuse timeline components)
- Reply input at the bottom (full composer with formatting, emoji, etc.)
- Unread count badge on the thread button in the main timeline
- Keyboard shortcut to close thread panel  
  **Architecture:**
- New Jotai atom: `activeThreadEventId: string | null`
- New component: `src/app/features/room/thread/ThreadPanel.tsx`
- Rendered alongside `RoomView` as a conditional right panel (mirror the members drawer pattern)
- Filter events in timeline to `m.thread` relation for the active root event ID
- Shares the same `mx` client and room reference as the main timeline  
  **[AUDIT REQUIRED]** — Deeply audit how `m.thread` relation events are currently stored and retrieved in the matrix-js-sdk. Understand the thread aggregation API: `GET /rooms/{roomId}/relations/{eventId}/m.thread`. Check if `RoomTimeline.tsx` currently filters out thread replies from the main timeline (it should — confirm).  
  **Complexity:** High.

---

## Priority 4 — Specialized, high complexity, or low priority

### [ ] P4-1 · Thread Notification Mode Per-Thread (MSC3771)

**Spec:** MSC3771 (stable). Depends on Thread Panel (#P3-8).  
**What:** Per-thread notification toggle: "All messages" vs "Mentions only". Accessible from the thread panel header. Tracks unread counts separately per thread.  
**[AUDIT REQUIRED]** — Implement after Thread Panel. Requires understanding how the SDK tracks per-thread unread counts.  
**Complexity:** Medium (after thread panel exists).

---

### [ ] P4-2 · Thread Subscriptions (MSC4306) [BLOCKED]

**Spec:** MSC4306 (Synapse experimental). Depends on Thread Panel (#P3-8).  
**What:** "Follow thread" button to receive notifications for a thread you haven't posted in. Uses MSC4306 subscription endpoint.  
**[SERVER CHECK]** — `org.matrix.msc4306 = false` on `matrix.lotusguild.org` — BLOCKED until server enables it.  
**Complexity:** Medium (after thread panel exists).

---

### [x] P4-3 · Knock-to-join Notifications for Admins

**Note:** The basic knock-to-join UX is covered in P1-11 (completed). This task adds the admin notification side.  
**What:** Space/room admins see a notification badge when there are pending knock requests. A "Pending Join Requests" section in the members drawer or room settings. Approve (invite) or deny (kick) each knock.  
**Complexity:** Medium.

---

### [ ] P4-4 · Math / LaTeX Rendering in Messages (LOW PRIORITY)

**Spec:** CS-API §11.5 (stable) — `formatted_body` can contain LaTeX.  
**What:** Render `$...$` or `$$...$$` LaTeX expressions in message bodies. Use KaTeX (lightweight, ~100KB, renders server-side-compatible CSS). Must gracefully fall back to raw LaTeX text if KaTeX fails.  
**Note:** This is LOW PRIORITY — only useful for academic/technical communities. Implement last.  
**[AUDIT REQUIRED]** — Confirm KaTeX bundle size impact on the Vite bundle. Check if matrix-js-sdk's HTML sanitizer strips LaTeX before it reaches the renderer. The formatted_body sanitization pipeline is the main risk here.  
**Complexity:** Low-Medium.

---

### [ ] P4-5 · Live Location Sharing (MSC3489 + MSC3672) (LOW PRIORITY, HIGH COMPLEXITY) [BLOCKED]

**Spec:** MSC3489 + MSC3672. Implemented in Element Web.  
**Note:** Static location sharing is already implemented. This adds live/real-time GPS beacons. Very low priority per user preference.  
**What:** Start sharing live location → creates `m.beacon_info` state event → client posts `m.beacon` events on a timer → other users see your position update live on a map.  
**[SERVER CHECK]** — `org.matrix.msc3489 = false` AND `org.matrix.msc3672 = false` on `matrix.lotusguild.org` — BLOCKED.  
**Complexity:** High. Requires background geolocation API + live map rendering.

---

### [ ] P4-6 · OIDC / SSO Next-Gen Auth (MSC3861) (EXTREME COMPLEXITY, LOW PRIORITY)

**Spec:** MSC3861, merged Matrix spec v1.15. Uses Matrix Authentication Service (MAS).  
**Context:** ~80% of homeserver users have LLDAP/Authelia/SSO accounts. SSO is currently enabled on `matrix.lotusguild.org` but accounts are not yet linked. This would allow users to log in via their SSO credentials.  
**What:** OAuth 2.0 / OIDC login flow, token refresh, account management page linking Matrix identity to SSO identity.  
**EXTREME COMPLEXITY** — requires: MAS deployment/configuration on the homeserver, significant auth flow changes in the client, token refresh handling, session management overhaul.  
**[SERVER CHECK]** — Before any client work, audit whether MAS is already deployed on `compute-storage-01`. Check: `pct exec 151 -- systemctl status matrix-authentication-service` or similar.  
**Complexity:** Extreme. Multi-sprint project. Plan separately.

---

## Priority 5 — Gamer / Aesthetic / Customization

### [ ] P5-1 · Custom Accent Color Picker (non-TDS mode only)

**What:** A hex/HSL color picker in Settings → Appearance. Chosen color replaces the primary accent throughout the UI: buttons, badges, active states, highlights, presence dot, links. Applied via a CSS custom property override injected into `<head>`.  
**IMPORTANT:** This feature is completely inactive when TDS is enabled — TDS has its own fixed palette. Add this setting under a "Non-TDS Themes" section that is hidden when TDS is active.  
**[AUDIT REQUIRED]** Identify all CSS custom properties that constitute the "accent color" in non-TDS mode. Map them to the folds/vanilla-extract token names.  
**Complexity:** Medium.

---

### [ ] P5-2 · Additional Color Theme Presets

**What:** 5 new one-click theme presets alongside TDS. Each must be a complete, polished system with proper contrast ratios (WCAG AA). All implemented as vanilla-extract themes matching the existing TDS pattern.  
Themes:

1. **Cyberpunk** — deep navy bg (`#0a0015`), electric purple (`#bf5fff`) + hot pink (`#ff2d9b`) accents, neon glow
2. **Ocean** — deep sea blue bg (`#020b18`), teal (`#00c9b1`) + aqua (`#0096d6`) accents, soft feel
3. **Blood Red** — near-black bg (`#0d0203`), deep crimson (`#7a0010`) + bright red (`#ff2233`) accents
4. **Classic Matrix** — pure black bg (`#000000`), phosphor green (`#00ff41`) text + accents
5. **Midnight** — dark charcoal (`#111827`), cool blue-grey (`#6b7ca8`) accents, clean minimal  
   **[AUDIT REQUIRED]** Study `src/lotus-terminal.css.ts` for the full token list before designing themes. All tokens must be covered.  
   **Complexity:** Medium (design effort is the main cost).

---

### [MOVED] P5-9 · LFG (Looking for Group) Command → LotusBot

**Decision:** Implemented as `!lfg` in LotusBot rather than a client slash command. Bot-side rendering works consistently across all Matrix clients; client-side enhanced cards would only be visible to Lotus Chat users and require sanitizer auditing. The bot can also support richer flows (list active LFGs, DM interested players, auto-expire posts).

---

### [x] P5-10 · Voice Channel User Limit

**What:** Admins set max participants via custom state event `io.lotus.voice_limit: { max_users: N }`. Show "Channel Full (5/5)" to users over the limit. Local enforcement only.  
**[AUDIT REQUIRED]** Check if Element Call has its own participant limit that should be integrated with rather than duplicated.  
**Complexity:** Medium.  
**Done:** `RoomVoiceLimit` admin control in Room Settings → General → Voice; `CallPrescreen` disables Join + shows "Channel Full (N/N)" when at capacity (rejoiners exempt). State event `StateEvent.LotusVoiceLimit`. **Hard enforcement is server-side for ALL clients** via `voice-limit-guard` (matrix repo `livekit/voice-limit-guard.py`) — a fail-open sidecar fronting `lk-jwt-service` (guard `:8070`, lk-jwt `:8071`) that refuses the LiveKit JWT (403) when the room is at capacity. The client check is UX-only. EC has only a global `max_participants` (50), so per-room limits were not duplicating an EC feature.

---

### [x] P5-11 · AFK / Idle Auto-Mute in Voice

**What:** Auto-mute mic after X minutes of silence (detected via Web Audio AnalyserNode). Show "You were auto-muted due to inactivity" toast with click-to-unmute. Admin-configurable via `io.lotus.afk_timeout` state event. Disableable in Settings → Calls.  
**[AUDIT REQUIRED]** Verify auto-mute must go through the same CallControl bridge as manual mute.  
**Complexity:** Medium.

---

### [x] P5-12 · Seasonal / Event Themes

**What:** Automatic + manually toggleable seasonal overlays with CSS particle effects and accent color variants:

- **Halloween** (Oct 15–Nov 1): purple particles, orange accents, spider web pattern
- **Christmas** (Dec 10–Jan 2): snow fall, red/green accents, snowflake pattern
- **New Year** (Dec 31–Jan 1): firework burst animation, gold accents
- **Pride** (June): rainbow gradient accent cycle  
  All toggleable manually in Settings → Appearance regardless of date. Respects `prefers-reduced-motion`.  
  **[AUDIT REQUIRED]** Design against existing CSS animation system in `lotus-terminal.css.ts`.  
  **Complexity:** Medium.

---

### [x] P5-13 · Avatar Frame / Border Decorations

**What:** Decorative CSS rings/frames rendered around user avatars. Built-in options: TDS Glow (animated orange pulsing), Cyberpunk (rotating gradient), Minimal (thin ring), Gold (supporter cosmetic). Stored in Matrix account data `io.lotus.avatar_frame`. Only visible in Lotus Chat.  
**[AUDIT REQUIRED]** Verify folds Avatar component allows overlay decoration without breaking child-type constraints (see previous white-circle avatar bug).  
**Complexity:** Medium.

---

### [x] P5-14 · Animated Avatar Overlay Decorations (Discord-style)

**What:** Animated WebM/GIF overlays that float around avatars (transparent center showing avatar). Curated built-in set OR user-uploaded mxc:// overlay. Stored in account data. Only Lotus Chat users see them.  
**[AUDIT REQUIRED]** See #P5-13 audit. Also decide: curated set only vs user-uploadable.  
**Complexity:** Medium.

---

### [ ] P5-15 · In-Call Soundboard

**What:** Grid of short audio clips playable into the call audio stream via Web Audio API (AudioBufferSourceNode → MediaStreamDestinationNode → mixed with mic). Built-in clips + user-uploadable custom clips (stored as mxc://). Accessible from call controls bar.  
**[AUDIT REQUIRED]** Verify the Element Call integration exposes the mic MediaStream for mixing. This is the highest-risk part of this feature.  
**Complexity:** High.

---

### [x] P5-16 · Custom Join / Leave Sound Effects

**What:** Local-only sounds when participants join/leave a call you're in. Built-in options + per-user settable. Detect via Element Call participant list change events.  
**[AUDIT REQUIRED]** Find how Element Call exposes join/leave participant events to the parent window via postMessage bridge.  
**Complexity:** Medium.  
**Done:** Detected via `MatrixRTCSession` membership changes (`useCallMembersChange`) rather than the EC postMessage bridge — more reliable, identity tracked by `sender|deviceId`. Sounds synthesized with Web Audio (no assets). Styles Off/Chime/Soft/Retro in Settings → Calls. Hook `useCallJoinLeaveSounds`, util `callSounds.ts`.

---

### [ ] P5-20 · Quick Reply from Browser Notification

**What:** Inline reply field in browser notification toasts via Notification Actions API. Reply sends as threaded reply to the triggering message.  
**[AUDIT REQUIRED]** (1) Verify browser Notification Actions API support in target browsers. (2) This requires a Service Worker to handle the reply event — confirm if Lotus Chat has one or needs one.  
**Complexity:** Medium-High.

---

### [x] P5-21 · Custom @Mention Highlight Color

**What:** Each user sets their own mention highlight color in Settings → Appearance. Applied as `--user-mention-color` CSS property override on mention-highlighted message rows.  
**Complexity:** Low.

---

### [x] P5-22 · Font Selector for the UI

**What:** Font picker in Settings → Appearance. Options: JetBrains Mono, Inter, Geist, Fira Code, OpenDyslexic, System Default. Applied via CSS custom property overrides.  
**[AUDIT REQUIRED]** Check if any fonts are already globally loaded to avoid double-loading.  
**Complexity:** Low-Medium.

---

### [x] P5-27 · Notification Profile Presets (Gaming / Work / Sleep)

**What:** Saved presets that change all notification settings atomically. Gaming (mentions only), Work (DMs + mentions), Sleep (all off). Quick-switch from sidebar or settings.  
**Complexity:** Medium.

---

### [ ] P5-30 · Advanced ML Noise Suppression (Krisp-style)

**What:** High-end background noise cancellation using a pre-trained ML model (e.g. RNNoise) running in the browser. Removes dogs, fans, and keyboard clicks from the mic stream.  
**Note:** This is a top-tier feature request and an EXTREME COMPLEXITY project.  
**[AUDIT REQUIRED]** Must verify if mixing a processed stream into Element Call's WebRTC implementation causes latency or AEC (Echo Cancellation) issues.  
**Complexity:** Extreme.

---

### [ ] P5-31 · Granular Voice & Screenshare Quality Controls (Discord-style)

**What:** Let users (or room admins via room settings) adjust audio bitrates (e.g., 64kbps to 512kbps) and screenshare quality (resolution: 720p/1080p/Source, framerate: 15/30/60fps).  
**Note:** Requires tight integration with the LiveKit SFU and custom state events for per-room quality caps.  
**[AUDIT REQUIRED]** Must verify if current `lk-jwt-service` can be extended with custom bitrate/resolution claims or if a new sidecar (similar to `voice-limit-guard`) is needed for server-side enforcement.  
**Complexity:** Extreme.

---

### [x] P5-34 · User-to-User Private Notes

**What:** A private "Notes" field on user profiles visible only to you. Syncs across all your devices.  
**Matrix Tech:** Store in `io.lotus.user_notes` account data. Must be keyed by `userId`.  
**Complexity:** Medium.

---

### [ ] P5-35 · Desktop — Notification Click Opens Room (DEFERRED)

**What:** Clicking a system tray notification navigates to the relevant room. Quick-reply from the notification toast would send the reply without opening the window.  
**Status:** Deferred — `tauri-plugin-notification` has no Rust click/action callback API. Quick-reply would need a custom WinRT toast activator + COM registration, which can't be compile-tested without a Windows build environment.  
**Note:** Tray icon and `matrix:` deep links already bring the window forward on most interactions. Revisit when tauri-plugin-notification gains click handler support upstream.  
**Complexity:** High (platform-specific native code required).

---

### [ ] P5-36 · Desktop — Windows Jump List (DEFERRED)

**What:** Right-clicking the taskbar icon shows a jump list with recent/favorite rooms for quick navigation.  
**Status:** Deferred — implementing the Windows COM jump list API in Tauri requires iterating on C++/COM code that can only be compile-checked on Windows, making blind CI iteration impractical.  
**Action when unblocked:** Revisit when a Tauri plugin abstracts the Windows Shell `ICustomDestinationList` interface, or when a Windows build environment is available for local iteration.  
**Complexity:** High (Windows-only native COM).

---

## Blocked Features

These features are confirmed desirable but cannot be built until the listed dependency is resolved.
Check back after each Synapse upgrade — re-run `/matrix/client/versions` and `unstable_features` to see if they've become available.

### [BLOCKED] · Live Location Sharing (MSC3489 + MSC3672)

**Blocked by:** `org.matrix.msc3489 = false` AND `org.matrix.msc3672 = false` on `matrix.lotusguild.org` (confirmed from unstable_features).  
**What it would do:** Real-time GPS beacon streaming upgrading the existing static location share.  
**Action when unblocked:** Both MSCs must be enabled on the homeserver before any client work.

### [BLOCKED] · Reaction / Relation Redaction (MSC3892)

**Blocked by:** `org.matrix.msc3892` = false on `matrix.lotusguild.org`  
**What it would do:** Cleanly remove a reaction without redacting the parent message.  
**Current behavior:** Full event redaction — acceptable fallback, no user-facing issue.  
**Action when unblocked:** Find `onReactionToggle` redaction call site; swap in MSC3892 endpoint with fallback.

### [BLOCKED] · Room Preview Before Joining (MSC3266)

**Blocked by:** `GET /v1/rooms/{id}/summary` returns 404 — endpoint not available on this server  
**What it would do:** Show room name, topic, avatar, member count before joining.  
**Action when unblocked:** Build pre-join preview card; trigger on unjoined room navigation.

### [BLOCKED] · Thread Subscriptions (MSC4306)

**Blocked by:** `org.matrix.msc4306` = false on `matrix.lotusguild.org`  
**What it would do:** Follow a thread without posting; get notifications for replies.  
**Action when unblocked:** Add "Follow thread" button in the thread panel header (depends on #P3-8 Thread Panel).

### [BLOCKED] · Report User (MSC4260)

**Blocked by:** Server declares only spec v1.12; MSC4260 merged in v1.14 — endpoint may not exist  
**What it would do:** Report a specific user to homeserver admins (separate from reporting a message).  
**Note:** Report Message already exists in upstream Cinny. This would add Report User to the profile panel.  
**Action when unblocked:** Test `POST /_matrix/client/v3/users/{userId}/report`; if 200, add button to user profile.

---

## Pending Audits

### [ ] Audit-3 · Profile banner image — Matrix protocol support

Research whether Matrix spec or MSC4133 (v1.16) defines a standard profile banner field. `uk.tcpip.msc4133.stable = true` on our server — check if a `banner_url` or similar field is defined. If no cross-client standard exists, do not implement.

---

## Implementation Notes

### ⚠️ TDS DESIGN LAW (repeated here for emphasis)

> Every TDS color, animation, glow, border, shadow, and font value MUST come from `/root/code/web_template/base.css`.  
> Never hardcode hex values. Never invent CSS variable names.  
> Key variables: `--lt-accent-orange` · `--lt-accent-cyan` · `--lt-accent-green` · `--lt-glow-*` · `--lt-box-glow-*` · `--lt-border-color` · `--lt-font-mono`  
> Reference implementation: `/root/code/tinker_tickets/` (markdown.js, base.js, ticket.css)  
> This applies without exception to every task marked `[IMPROVE]`, `[Build]`, or any UI change.

### Design Rules

- All new components must respect both TDS dark (`LotusTerminalTheme`) and TDS light (`LotusTerminalLightTheme`) modes
- Non-TDS theme work (custom accent color, theme presets) uses vanilla-extract theme files — match the pattern in `src/lotus-terminal.css.ts`
- Code syntax highlighting token classes: `.tok-kw .tok-str .tok-num .tok-cmt .tok-fn` (defined in `web_template/base.css`)
- `folds AvatarImage` does NOT accept children — wrap Avatar components externally for overlays/frames/borders

### CI/CD Pipeline

```
edit → commit → git push origin lotus
→ Gitea Actions: tsc --noEmit, eslint, prettier (~3 min)
→ Webhook: lotus_deploy.sh on LXC 106 polls CI, then npm ci && npm run build → rsync
→ Live at chat.lotusguild.org (~11 min total)
```

### Per-Feature Checklist (before marking complete)

- [ ] `npx tsc --noEmit` — zero TypeScript errors
- [ ] `npx eslint src/` — zero new errors (warnings OK if pre-existing)
- [ ] `npx prettier --check src/` — formatting passes
- [ ] `README.md` updated (Lotus-custom features only — not upstream Cinny features)
- [ ] `landing/index.html` updated if the feature appears in the comparison table
- [ ] Visually tested at `chat.lotusguild.org` after CI deploys

### Homeserver Access (for server audits)

- **Synapse (Matrix):** LXC 151 on `compute-storage-01` — `pct exec 151 -- bash`
- **Config:** `/etc/matrix-synapse/homeserver.yaml`
- **Version check:** `curl -s https://matrix.lotusguild.org/_matrix/client/versions`
