MosaicIQ: An Equity Research Workspace
A full-stack architecture specification for an AI-native equity research platform — local-first server/client sandboxing, portfolio dashboards, financial models, investment memos, and a 14-agent collaborative pipeline where every agent feels like a trusted co-analyst, with built-in research & validation cycles — built on an editorial design system.
1. Overview
MosaicIQ is a single-page application that provides buy-side analysts with a unified workspace for equity research. It combines portfolio monitoring, company fundamental data, financial modeling, investment memo authoring, and AI agent orchestration into one editorial-grade interface. The design language borrows from print magazine conventions — serif display type, monospaced data, generous whitespace, restrained accent — to make financial content legible and authoritative.
The platform targets desktop web users working on 1440p+ displays. It is not a mobile-first product. Information density is a feature: analysts need to see holdings, charts, and factor tilts simultaneously without switching tabs.
Naming convention v3
The product name is MosaicIQ — this is the canonical name used in all user-facing text, documentation, and brand materials. "Meridian" appears in the prototype as an internal codename for the shell component; it should be replaced with "MosaicIQ" in implementation. The profile editor, logo, and topbar should all read "MosaicIQ".
Core principles
- Editorial posture. Serif display headings, monospace for all numerical data, sans-serif body. No rounded cards, no drop shadows, no gradients — borders and whitespace do the structural work.
- Agent-native, agent-as-collaborator. AI agents are not a sidebar feature — they are the primary production pipeline, and they should feel like collaborators, not tools. Every agent interaction is designed to mirror working with a skilled co-analyst: they surface assumptions, flag uncertainty, ask clarifying questions, and present findings for review rather than delivering final answers unilaterally.
- Local-first, sandboxed. The application is single-user and local-first. All data and the agent sandbox run locally with a clean server/client boundary — the client never reads storage directly, it goes through a typed RPC layer (§3.2). This architecture mirrors t3-code's approach and keeps the path open for future remote server support without changing the client.
- Spreadsheet-grade data. Financial models use tabular monospace with hairline borders, sticky headers, and explicit distinction between actuals (solid type) and forecasts (italic, muted).
- One accent, used twice. A single rust accent color appears on eyebrows and pull-quote rules. Green and red are reserved for directional meaning (positive/negative). All other color is from the near-greyscale palette.
- Research + validation cycles. No agent output ships without a structured validation loop. Every pipeline stage ends with a review checkpoint: sources are verified, assumptions are stress-tested by the Red Team agent, and the analyst can accept, reject, or revise any finding before it propagates downstream.
- Collapsible chrome. Left navigation panels collapse to 36px to give maximum space to content. The command bar persists across all screens as the agent control surface.
2. Design Tokens
All colors are specified in OKLch for perceptual uniformity. The palette is warm-neutral with a single saturated accent. No shadows, no gradients in production UI.
Typography
| Token | Stack | Usage |
|---|---|---|
--font-display | Iowan Old Style, Charter, Georgia, serif | Headlines, metric values, pull quotes |
--font-body | System UI stack (SF Pro, Segoe UI, etc.) | Body copy, button labels, navigation |
--font-mono | IBM Plex Mono, Menlo, monospace | Tickers, numbers, tables, code, metadata |
Spacing and radii
- All radii are
2pxor0. No rounded cards, no pill shapes except the avatar circle. - Border weight is
1px solid var(--border)universally. Total rows and section dividers use1px solid var(--fg). - Content padding:
28px 36pxin the center column.16pxin cards and metric cells. - The topbar is
48pxtall. The command bar is52pxminimum.
3. System Architecture
MosaicIQ is structured as a fixed chrome shell with swappable screen content. The shell consists of three persistent elements — topbar, main area, and command bar — that never unmount. Screen transitions swap the contents of .main.
Fig 2. Shell Structure
Screen routing
Screens are CSS-toggled: only one .screen has .active at a time. The topbar tabs call switchScreen(id), which removes .active from all screens and applies it to the target. No router, no URL changes — this is a single-page state machine.
| Screen ID | Label | Layout | Left Nav | Right Panel |
|---|---|---|---|---|
home | Home | Full-width center | None | None |
workspace | Workspace | Nav + center | Research sections (collapsible) | None |
model | Model | Toolbar + center | None | None |
memo | Memo | Nav + center + panel | Outline (collapsible) | Review tools + citations |
agents | Agents | Toolbar + grid + detail | None | Detail panel (slide-in) |
3.1 Data Layer
The application is local-first, single-user. All data and the agent sandbox run locally via SQLite through a typed server layer. The client never reads or writes storage directly — it communicates through the RPC interface defined in §3.2.
Fig 3. Data Layer Architecture
Key convention from t3-code
Settings split into ClientSettings (local UI prefs — theme, density, sidebar width) and ServerSettings (data-authoritative — agent configs, data sources, export pipelines). Client settings are a JSON file on disk; server settings live in SQLite. Both use schema-validated decode with defaults so missing keys never crash the app.
3.2 RPC Surface v3
The client communicates with the server exclusively through typed RPC methods. Transport is IPC in Electron, HTTP in browser. Every method has a typed request and response shape; the server validates inputs and returns structured errors. There are no REST endpoints — all calls go through a single /rpc entry point with a method name and JSON payload.
Company & Portfolio
| Method | Input | Output |
|---|---|---|
| portfolio.get | {} | { id, name, holdings[] } |
| portfolio.addHolding | { ticker } | { holding } |
| portfolio.removeHolding | { ticker } | { ok } |
| company.get | { companyId } | { company } — full profile + metrics |
| company.search | { query } | { results[] } — ticker, name, sector |
| company.setActive | { companyId } | { ok } |
Workspace & Research
| Method | Input | Output |
|---|---|---|
| workspace.getSection | { companyId, section } | { content, validationState } |
| workspace.listSources | { companyId } | { sources[] } |
| catalyst.list | { companyId } | { catalysts[] } |
| alert.list | { companyId?, since? } | { alerts[] } |
| risk.list | { companyId } | { risks[] } |
| risk.add | { companyId, risk } | { risk } |
| earnings.getSchedule | { companyId } | { schedule[] } |
| filing.list | { companyId, since? } | { filings[] } |
Financial Model
| Method | Input | Output |
|---|---|---|
| model.get | { companyId, tab } | { headers[], rows[] } |
| model.updateCell | { companyId, tab, row, col, value } | { ok, affectedCells[] } |
| model.runScenario | { companyId, scenario, overrides } | { headers[], rows[] } |
Memo
| Method | Input | Output |
|---|---|---|
| memo.get | { companyId } | { sections[], status } |
| memo.updateSection | { companyId, sectionId, content } | { ok } |
| memo.annotate | { companyId, sectionId, annotation } | { annotation } |
| memo.acceptEdit | { companyId, editId } | { ok } |
| memo.rejectEdit | { companyId, editId, reason? } | { ok } |
Agents
| Method | Input | Output |
|---|---|---|
| agent.list | { companyId? } | { agents[] } — status, progress, config |
| agent.start | { agentId, companyId } | { runId } |
| agent.pause | { agentId } | { ok } |
| agent.restart | { agentId } | { runId } |
| agent.chat | { agentId, message } | { response } — streamed via SSE |
| agent.configure | { agentId, config } | { ok } |
| agent.getTrace | { agentId, runId } | { steps[] } |
| agent.runPipeline | { companyId, pipeline } | { runIds[] } |
Export & Settings
| Method | Input | Output |
|---|---|---|
| export.list | { companyId? } | { exports[] } |
| export.create | { type, companyId, options } | { exportId } |
| export.download | { exportId } | binary stream |
| settings.get | { scope: 'client' | 'server' } | { settings } |
| settings.update | { scope, changes } | { ok } |
Error contract
Every RPC error returns a structured object: { code: string, message: string, detail?: any }. Standard error codes: NOT_FOUND, VALIDATION_ERROR, AGENT_FAILED, CONFLICT (e.g. trying to start an already-running agent), RATE_LIMITED.
3.3 Real-time Transport v3
Agent streaming and live updates use Server-Sent Events (SSE) over a single persistent connection. SSE was chosen over WebSockets because: the transport is server-to-client dominant (agent output streaming), it works over HTTP without special proxying, and it reconnects automatically with a Last-Event-ID header.
Event channel
The client opens one SSE connection at startup: GET /events?companyId={id}. The server pushes typed events:
| Event type | Payload | Frequency | Consumer |
|---|---|---|---|
agent.progress | { agentId, percent, currentAction } | Every 1–2s during run | Agent grid tiles, carousel, detail panel |
agent.output | { agentId, chunk, outputType } | Streaming (token-by-token or block-by-block) | Fullscreen overlay output column, memo body |
agent.status | { agentId, oldState, newState } | On state transitions | Agent grid, carousel dot, toast triggers |
agent.question | { agentId, question, options? } | When agent pauses for input | Command bar alert, chat overlay |
validation.result | { targetId, targetType, state, details } | On validation completion | Workspace section badges, memo citations |
filing.new | { companyId, formType, title } | On new SEC filing detected | Filing Watch, toast, Thesis Alerts |
alert.thesis | { companyId, impact, summary } | When thesis impact detected | Thesis Alerts, toast |
export.complete | { exportId, format, fileSize } | On export finish | Export Center, toast |
Connection lifecycle
- Connect: On app startup, after the first
portfolio.get. URL includes active company ID. - Reconnect: Browser auto-reconnects on drop. Server replays missed events via
Last-Event-ID. - Company switch: Client closes the SSE connection and opens a new one with the new
companyId. - Client → server: All client-to-server messages go through RPC (§3.2), not through SSE. SSE is receive-only.
Agent chat streaming
The agent.chat RPC method returns an SSE stream (not a JSON response). The server opens a new ephemeral SSE stream scoped to that chat session. The client renders agent.output events in the chat column as they arrive. The stream closes when the agent finishes its response.
3.4 State Shape
The state is split into server-authoritative data (SQLite) and client-only UI state (React/localStorage).
Server-authoritative state (SQLite)
interface AppState {
portfolio: {
id: string;
name: string;
holdings: Holding[];
};
activeCompanyId: string | null;
companies: {
[companyId: string]: {
workspace: WorkspaceState;
model: ModelState;
memo: MemoState;
agents: AgentRunState[];
};
};
settings: ServerSettings;
exports: ExportRecord[];
}
Client-only state (React / localStorage)
interface ClientState {
activeScreen: 'home' | 'workspace' | 'model' | 'memo' | 'agents';
navCollapsed: Record<string, boolean>;
activeModelTab: string;
memoReviewMode: boolean;
agentFullscreenOpen: boolean;
agentCarouselIndex: number;
settingsOverlayOpen: boolean;
settingsPanel: SettingsPanel;
searchQuery: string;
searchOpen: boolean;
clientSettings: ClientSettings;
}
settingsPanel enum v3
type SettingsPanel = | 'agents' | 'data-sources' | 'export' | 'display' | 'keybindings' | 'advanced';
Six panels. The Keybindings panel (missing from prototype) lets the analyst remap every shortcut listed in §9.1. Each shortcut is stored as a key binding entry in ClientSettings.keybindings.
Company selection is the root pivot. Choosing a holding refreshes the entire workspace — thesis, model, memo, agents all rebind to the new company. The client queries the server for the selected company's data on switch.
3.5 Persistence & Versioning
- Autosave: Debounced server writes — 2s after last keystroke for memo text, immediate for toggles, settings changes, and annotation actions. No explicit save button.
- Snapshots: The server stores a diff snapshot every 5 minutes during active editing sessions. Named checkpoints available via
⌘S. Snapshots listed in Settings → Advanced → Version History with timestamp and optional label. - Undo/redo: Standard
⌘Z/⌘⇧Zwithin the current session. Undo stack is session-scoped (cleared on page reload). For cross-session rollback, use version history.
Version History UI v3
Settings → Advanced → Version History shows a timeline of snapshots:
- Layout
- Left column: scrollable list of snapshot entries (auto-saved + manual). Right column: diff preview of the selected snapshot vs. current state.
- Snapshot entry
- Timestamp (mono), optional label (editable), type badge ("Auto" muted, "Manual" accent), number of changes. Click to preview.
- Diff preview
- Side-by-side or unified diff view. Additions highlighted with
--greenbackground tint, deletions with--redbackground tint. Memo sections shown as prose diffs; model cells shown as value changes. - Actions
- "Restore this version" (primary button, confirmation dialog), "Branch from here" (creates a new checkpoint from that state without discarding current), "Download snapshot" (JSON export).
3.6 First-Run Experience
No onboarding wizard, no modals, no video. The first-run experience is:
- Empty portfolio with a single centered card: "Add your first company" — a search/typeahead that queries a company database.
- Once added, the workspace opens with all research sections in "loading" state (skeleton).
- A 3-step tooltip sequence highlights: Thesis → Model → Memo.
- The first agent pipeline auto-queues (SEC Filings → Company Research → Financial Modeling).
- The agent carousel in the command bar pulses to draw attention to the first running agent.
4. Screen Specifications
4.1 Home Dashboard
The home screen is the analyst's morning briefing. It answers three questions at a glance: How is my portfolio doing? What needs my attention today? What are my agents working on?
Layout
Full-width center column with two stacked zones:
- Portfolio dashboard — a 3-column grid (holdings list | performance chart + metrics | sector treemap + factor tilt). The grid uses
gap: 1pxwithbackground: var(--border)to create hairline separators between sections. - Home grid — a 2-column CSS grid below the portfolio area containing: Earnings Calendar, Watchlist Alerts, Recent Reports & Exports (spans full width), Pending Reviews, Agent Status.
Portfolio dashboard components
- Holdings List
- Scrollable list (max-height 320px) with columns: ticker badge, price, change (green/red), weight percentage, actions menu (
⋯). Ticker badges use inverted colors (bg: var(--fg); color: var(--surface)). The⋯button opens a dropdown with: Open workspace, Run full research, Export report, Set as active, Remove from portfolio. - Performance Chart
- SVG area chart with 6-month price line, grid lines, labeled time axis, and a summary metrics grid (Total Value, Day P&L, Holdings count, Beta, Sharpe, Max Drawdown).
- Sector Treemap
- Nested flex rows sized by weight. Each cell shows sector name, percentage, and dollar value against a tinted background. Colors are categorical, not semantic.
- Factor Tilt
- Horizontal bar chart comparing portfolio factor exposure vs. S&P 500. Positive exposures tinted green, negative tinted red. Six factors: Value, Size, Momentum, Quality, Low Vol, Market Beta.
Home grid cards
- Earnings Calendar
- Grouped by date with BMO/AMC timing tags. Compact row layout: ticker badge + quarter label + timing + countdown.
- Watchlist Alerts
- Event feed with thesis impact tags (Thesis +/Thesis −/Filing). Click-through to relevant screen.
- Reports Library
- Full-width card grid (
repeat(auto-fill, minmax(200px, 1fr))). Each report thumb shows type label, title, and status metadata. - Pending Reviews
- Items awaiting human review with comment counts and unverified assumption flags.
- Agent Status
- Compact list of active agents with progress percentages and current actions. Links to full Agents screen.
4.2 Company Workspace
The workspace is a read-only research hub for a single company. It aggregates all structured data, reports, and source materials in one scrollable column with a collapsible section navigation sidebar.
Left navigation
240px wide, collapsible to 36px. Organized into four groups with dividers:
- Research — Company Snapshot, Business Description, Segment / Revenue Build, Margin Build, Historical Financials, Three-Statement Model, Key KPIs, Management & Strategy.
- Analysis — Competitive Landscape, Peer Comparison, Valuation Analysis, Investment Thesis, Risks & Mitigants, Catalyst Tracker (§4.6).
- Monitoring — Earnings Monitor (§4.9), Filing Watch (§4.10), Thesis Alerts (§4.7).
- Library — Source Library, Export Center (§4.11).
Active section indicated by a 3px accent bar on the left edge. Group headers use uppercase monospace at 10px.
Center content structure
- Header
- Category eyebrow (monospace, uppercase, accent color) + company display name + one-line summary (founded, HQ, locations, employees). Followed by a metric grid (12 cells in a 4-column auto-fill layout).
- Metric Grid
repeat(auto-fill, minmax(140px, 1fr))with 1px gap. Each cell: uppercase label (mono), display-font value, optional sub-text. Used for market cap, EV, price, P/E, margins, revenue, etc.- Body Sections
- H2 headings with top border divider. Prose paragraphs, data tables (spreadsheet class), and nested metric grids.
- Reports Grid
- Same card grid as home. Click-through to Memo or Model screens.
- Source Materials
- Stacked source cards showing type, title, metadata (pages, usage count). Types: SEC Filing, Earnings Transcript, Investor Presentation, Press Release.
4.3 Financial Model
The model screen is a spreadsheet-grade financial analysis environment. It presents tabular data with monospace numerics, explicit actual-vs-forecast distinction, and a tabbed navigation system for different model views.
Toolbar
Top toolbar with a <select> dropdown for model tabs: Revenue Build, Income Statement, Balance Sheet, Cash Flow Statement, Margin Build, Tax Build, LIFO/FIFO Conversion, Scenario Analysis, Charts. Right-aligned actions: Import Excel, AI Assist, Export to Excel.
Spreadsheet specification
- Font
12px/1.4 var(--font-mono)for all cells. Headers:10pxuppercase mono.- Layout
- Full-width table. First column is text-aligned left with font-weight 500. All other columns right-aligned. Minimum column width 200px for row labels.
- Actuals vs Forecasts
- Actual periods use default
var(--fg). Forecast columns get class.forecast:color: var(--muted); font-style: italic. - Hierarchy
- Indent rows (growth percentages) use
.indentwithpadding-left: 24px. Total rows use.totalwith a1px solid var(--fg)top border and bold weight. - Hover
- Row background shifts to
oklch(96% 0.008 80)on hover. - Sticky headers
- Table headers (
<th>) areposition: sticky; top: 0withbackground: var(--surface).
Model sub-tabs content
All model tabs share the same spreadsheet specification above (monospace, hairline borders, sticky headers, actual vs. forecast distinction). Content per tab:
| Tab | Row structure | Key metrics |
|---|---|---|
| Revenue Build | Segments → growth rates → total | Revenue by segment, YoY growth, blended rate |
| Income Statement | Revenue → COGS → gross profit → OpEx → EBIT → net income | Margins at each level, tax rate |
| Balance Sheet | Assets (current + non-current) → Liabilities → Equity | Working capital, D/E, net debt |
| Cash Flow | Operating → Investing → Financing → FCF | FCF conversion, capex ratio |
| Margin Build | Gross → operating → EBITDA → net | Margin drivers, expansion/compression |
| Tax Build | Effective rate → deferred → cash taxes | Tax rate bridge, NOL utilization |
| LIFO/FIFO | Inventory layers → COGS impact → reserve adjustment | LIFO reserve, COGS delta |
| Scenario Analysis | Bear / Base / Bull columns side-by-side | Key variable sensitivities, probability weights |
| Charts | 2-column grid of chart cards | Visual versions of the tab data |
4.4 Memo Editor
The memo screen is a structured writing environment for investment memos, IC memos, and research reports. It combines a content-editable center column with an outline sidebar and a review tools panel.
Three-column layout
| Column | Width | Contents |
|---|---|---|
| Left nav | 220px (collapsible to 36px) | Memo outline — hierarchical list of H2 sections and sub-items. Active section indicated by accent bar + bold. |
| Center | 720px max-width, centered | Sticky toolbar (status tag, Review Mode toggle, Export PDF, Publish) + memo blocks with eyebrows, headings, body text, citations, and AI edit suggestions. |
| Right panel | 300px | Review Tools (Highlight, Comment, Draw Box), Citations list, Review Status per section, Comments thread. |
Memo block structure
Each memo block (.memo-block) contains: an uppercase eyebrow in accent color, an H3 heading, body prose with inline citations (.citation — accent-colored mono brackets), and optional AI edit suggestions (yellow-tinted sidebar with Accept/Reject/Revise buttons).
Memo sections (8 total) v3
The memo outline includes these sections, all following the same .memo-block structure (eyebrow + H3 + body + citations). The prototype currently shows 4 sections (Thesis, Key Drivers, Variant Perception, Valuation). The remaining 4 sections — Business Quality, Financial Summary, Risks & Mitigants, Catalysts — should be added:
| Section | Content | Primary agent | Prototype status |
|---|---|---|---|
| Investment Thesis | Core bull case, time horizon, target price | mw | Built ✓ |
| Key Drivers | Top 3–5 revenue/earnings drivers with quantified impact | mw + fm | Built ✓ |
| Variant Perception | Where the analyst disagrees with consensus and why | mw + rt | Built ✓ |
| Valuation | Methodology, multiples, DCF summary, sensitivity table | va | Built ✓ |
| Business Quality | Moat analysis, ROIC trends, capital allocation, management quality | cr | Missing — add block |
| Financial Summary | Key financials table, trend analysis, margin drivers | fm | Missing — add block |
| Risks & Mitigants | Top risks with severity/likelihood and mitigation strategies | rk + rt | Missing — add block |
| Catalysts | Near-term events that could re-rate the stock | mn | Missing — add block |
Review mode
Toggling "Review Mode" activates an annotation system with four tools:
- Highlight — wraps selected text in
.highlight-annotationwith a tinted background and accent bottom border. Hover shows tooltip with reviewer comment. - Comment — same as highlight but prompts for a comment string stored in
data-comment. - Strikethrough — applies
text-decoration: line-throughwith red color at 60% opacity. - Draw Box — enters crosshair mode to draw a red bounding box with a "Review needed" label over any content area.
The annotation toolbar is positioned absolutely relative to the center column and appears at the selection position on mouseup.
Citations
Inline citations use numbered brackets linked to source cards in the right panel. Each source card shows: type (SEC Filing, Earnings Transcript, Analyst Report), title, page reference, and verification status (Verified / Unverified).
The memo editor is not a general-purpose rich text editor. It is a structured document with defined sections, each mapped to an outline entry. This constraint enables the AI agents to write, review, and iterate on specific sections independently.
4.5 Agent Orchestration
The agents screen is the control center for MosaicIQ's 14-agent research pipeline. It visualizes dependencies, progress, and real-time output across all agents.
Layout
Four stacked zones:
- Toolbar — agent count, running/queued status indicators, Pause All and Run Full Research buttons.
- Dependency tree — an SVG diagram showing the full agent pipeline with color-coded status. Two main pipelines (Research, Competitive & Risk) plus cross-cutting agents (Source Verification, Model QA, Monitoring, Export).
- Agent grid —
repeat(auto-fill, minmax(210px, 1fr))tiles. Each tile shows: icon badge, agent name, role description, status dot + label, progress bar. Hover reveals action buttons (Pause, Inspect, Start, Configure). Clicking opens the detail panel. - Activity feed — a scrollable log of timestamped agent events. Each entry: time, agent name (accent color), message.
Agent detail panel
A 360px slide-in panel on the right showing: agent name + status header, current task description, upstream inputs (dependency tags), downstream outputs, execution log (timestamped entries), and action buttons (Pause, Restart, Full Screen).
Fullscreen overlay
Clicking "Full Screen" opens a fixed overlay with: tab bar for switching between running agents, a live output column (rendered agent output — tables, text, charts), and an execution trace column (numbered steps with labels and detail text). A chat input at the bottom allows sending interrupts or instructions to the active agent.
Command bar
Persistent across all screens. Left section: agent carousel showing the currently active agent with a pulsing dot, name, current action, and prev/next navigation (320px). Right section: chat prompt with > icon and ⌘K keyboard hint. Clicking the carousel opens the agent fullscreen overlay.
4.6 Catalyst Tracker
A workspace sub-section under "Analysis". Lists upcoming catalysts for the active company. Data comes from the Monitoring agent (mn) and is validated by Source Verification (sv).
Layout
Full-width table with columns:
| Column | Spec |
|---|---|
| Date | Monospace, sorted ascending |
| Event | Earnings, FDA decision, product launch, regulatory filing |
| Expected Impact | High / Med / Low pill (confidence pill spec from §6.2) |
| Thesis Relevance | Alignment tag: supports / challenges / neutral |
| Source | Filing reference link |
HTML structure v3
<table class="spreadsheet">
<thead>
<tr>
<th>Date</th>
<th>Event</th>
<th>Impact</th>
<th>Thesis</th>
<th>Source</th>
</tr>
</thead>
<tbody>
<tr>
<td class="mono">Jun 5, 2026</td>
<td>Q3 FY25 Earnings</td>
<td><span class="tag red">High</span></td>
<td><span style="color:var(--green)">supports</span></td>
<td><span class="citation">[4]</span></td>
</tr>
<!-- more rows -->
</tbody>
</table>
4.7 Thesis Alerts
A workspace sub-section under "Monitoring" + a card on the home dashboard. Generated by the Monitoring agent (mn), triggered by: new filings, price moves exceeding threshold, earnings results vs. expectations, peer events.
Layout
Event feed with: timestamp, event type icon (filing, price move, earnings surprise), description, and impact assessment. Each alert has:
- A thesis impact tag:
[Thesis +](green),[Thesis −](red),[Neutral](muted) - "Review" button → navigates to the relevant memo section or workspace section
- Status:
New(accent) →Reviewed(muted) after analyst clicks
HTML structure v3
<div class="alert-feed">
<div class="card-row">
<span class="row-meta">2h ago</span>
<span class="row-name">Q2 FY25 earnings beat (+7.5% comp)</span>
<span class="tag green">Thesis +</span>
<button class="btn sm">Review</button>
<span class="tag accent">New</span>
</div>
</div>
4.8 Risk Register
A workspace sub-section under "Analysis". Structured list of identified risks. Populated by the Risk agent (rk) and stress-tested by Red Team (rt). Analysts can add manual risk entries via risk.add RPC.
Layout
| Column | Spec |
|---|---|
| Risk | Short description, left-aligned, font-weight 500 |
| Category | Business / Financial / Competitive / Regulatory / ESG — tag |
| Severity | High / Med / Low pill |
| Likelihood | High / Med / Low pill |
| Mitigation | One-line description, muted text |
| Status | Open / Mitigated / Accepted — tag |
Sorted by severity × likelihood. Top risks surface in the memo's "Risks & Mitigants" section automatically.
HTML structure v3
<table class="spreadsheet">
<thead>
<tr>
<th style="min-width:200px">Risk</th>
<th>Category</th>
<th>Severity</th>
<th>Likelihood</th>
<th>Mitigation</th>
<th>Status</th>
</tr>
</thead>
<tbody>
<tr>
<td>Amazon enters warehouse club segment</td>
<td><span class="tag">Competitive</span></td>
<td><span class="tag red">High</span></td>
<td><span class="tag">Low</span></td>
<td style="color:var(--muted)">Costco's 93% renewal rate creates switching cost</td>
<td><span class="tag">Open</span></td>
</tr>
</tbody>
</table>
4.9 Earnings Monitor
A workspace sub-section under "Monitoring" + the home dashboard calendar card. Beyond the calendar on home, the workspace section shows:
- Next 4 quarters with expected report dates
- Last 4 quarters with actual vs. expected results
- Consensus estimates grid (revenue, EPS, EBITDA)
- Post-earnings analysis links (if Earnings Call agent has run)
HTML structure v3
<div class="earnings-monitor">
<!-- Two stacked grids -->
<div class="metric-grid" style="grid-template-columns:repeat(auto-fill,minmax(160px,1fr))">
<div class="metric-cell">
<div class="label">Next Report</div>
<div class="value">Jun 5, 2026</div>
<div class="sub">Q3 FY25 · BMO</div>
</div>
<!-- more cells -->
</div>
<h2 class="section">Consensus Estimates</h2>
<table class="spreadsheet">
<thead><tr><th>Metric</th><th>Q2 FY25A</th><th>Q3 FY25E</th><th>FY25E</th></tr></thead>
<tbody>
<tr><td>Revenue</td><td>$62.5B</td><td class="forecast">$63.8B</td><td class="forecast">$242.3B</td></tr>
<tr><td>EPS</td><td>$4.28</td><td class="forecast">$4.35</td><td class="forecast">$16.82</td></tr>
</tbody>
</table>
</div>
4.10 Filing Watch
A workspace sub-section under "Monitoring". Tracks new SEC filings for the active company. Real-time monitoring via the Monitoring agent (mn), which checks for new filings and queues the SEC Filings agent (sf) automatically.
Layout
Feed of filing cards. Each card: form type (10-K, 10-Q, 8-K, etc.) as a tag, filing date, title, key changes summary (produced by SEC Filings agent), and "Review" button → opens the filing in the Source Library with agent annotations.
HTML structure v3
<div class="filing-feed">
<div class="source-card">
<div class="src-type">10-K Annual Report</div>
<div class="src-title">Annual Report FY2024</div>
<div class="src-meta">Filed Oct 2024 </div>
<div style="font-size:11px;color:var(--fg);margin-top:4px">
Key changes: Updated segment reporting, new warehouse commitments ($2.1B)
</div>
<button class="btn sm" style="margin-top:6px">Review</button>
</div>
</div>
4.11 Export Center
A workspace sub-section under "Library" + accessible from memo/model toolbars. Export is handled by the Export agent (ex).
Layout
Grid of export records. Each record: type icon, title, format tag (PDF/Excel/PPT), timestamp, file size, status (processing/complete/failed), "Download" action.
Trigger points
- Memo toolbar → "Export PDF"
- Model toolbar → "Export to Excel"
- Agent orchestration → "Export full report" (comprehensive package)
- Any screen →
⌘Ekeyboard shortcut opens an export quick-action menu
HTML structure v3
<div class="report-grid">
<div class="report-thumb">
<div class="rt-type">Excel</div>
<div class="rt-title">COST Model — Revenue Build FY25–FY27</div>
<div class="rt-meta">2.4 MB · Complete</div>
<button class="btn sm" style="margin-top:6px">Download</button>
</div>
</div>
5. Component Library
Topbar
| Element | Spec |
|---|---|
| Logo | font: 600 15px var(--font-display), clickable → Home. Text reads "MosaicIQ". |
| Ticker group | Hidden on Home screen. Shows: ticker badge (inverted), company name, price + change. |
| Screen tabs | Segmented control with 1px border. Active tab: bg: var(--fg); color: var(--surface). |
| Search | 180px input, var(--bg) background, mono placeholder. See §8.5 for search behavior. |
| Settings | 28×28px icon button, opens settings overlay. |
| Avatar | 28px circle, mono initials, hover → accent border. |
Tags
| Variant | Spec |
|---|---|
| Default | border: 1px solid var(--border); color: var(--muted) |
| Accent | border-color: var(--accent); color: var(--accent) |
| Green | border-color: var(--green); color: var(--green) |
| Red | border-color: var(--red); color: var(--red) |
All tags use font: 500 10px var(--font-mono); text-transform: uppercase; letter-spacing: 0.06em; padding: 3px 8px.
Buttons
| Variant | Spec |
|---|---|
| Default | bg: var(--surface); border: 1px solid var(--border); color: var(--fg). Hover: bg: var(--bg). |
| Primary | bg: var(--fg); color: var(--surface); border-color: var(--fg). Hover: opacity: 0.9. |
| Small | font-size: 10px; padding: 3px 8px |
Base spec: font: 500 12px var(--font-body); padding: 7px 14px; border-radius: 2px.
Source cards
border: 1px solid var(--border); padding: 10px 12px; background: var(--surface). Three rows: type (9px uppercase mono, accent color), title (12px body), meta (10.5px muted).
Report thumbs
border: 1px solid var(--border); background: var(--bg); padding: 14px. Hover → border-color: var(--muted). Three rows: type label (accent mono), title (bold body), metadata (muted).
Left navigation
240px wide (220px for memo variant). Collapsible to 36px via .collapsed class which hides all content except a 28px expand button. Transition: width 0.2s ease, opacity 0.2s ease. Active items: 3px accent bar on left edge, bold text. Group headers: 10px uppercase mono, muted.
Overlays
Full-screen overlays for Settings, Agent fullscreen, and Profile editor. Fixed position, z-index: 500 (600 for profile modal). Agent overlay includes a tab bar for switching between agents, with colored status dots.
Dropdown / select
| Property | Spec |
|---|---|
| Trigger | font: 400 12px var(--font-body); padding: 7px 28px 7px 12px; border: 1px solid var(--border); background: var(--surface); border-radius: 2px; appearance: none with custom chevron via background-image: url("data:image/svg+xml,...") |
| Panel | position: absolute; background: var(--surface); border: 1px solid var(--border); border-radius: 2px; box-shadow: 0 4px 12px oklch(0% 0 0 / 0.08) |
| Items | padding: 7px 12px; font-size: 12px. Hover: background: var(--bg). Active: font-weight: 600; color: var(--accent) |
Implementation note v3: The prototype currently uses native <select> elements as an interim solution. The custom dropdown above is the target implementation. Both approaches should produce visually consistent results — the custom dropdown adds keyboard navigation, type-ahead filtering, and full visual control.
Tooltips
| Property | Spec |
|---|---|
| Trigger | Hover with 300ms delay (show) / 100ms delay (hide). Or focus. |
| Position | Auto-positioned above trigger, flipping below if no space. |
| Style | background: var(--fg); color: var(--surface); font: 400 11px/1.4 var(--font-body); padding: 4px 8px; border-radius: 2px; max-width: 240px |
| Arrow | 6px CSS triangle, matching background color. |
| Content | Plain text only. No rich content — use the detail panel or a popover for that. |
Actions menu on holdings
The ⋯ button on each holding row opens a dropdown menu (same dropdown component spec as above):
| Item | Action |
|---|---|
| Open workspace | Switches to workspace screen for this company |
| Run full research | Queues all agents for this company |
| Export report | Opens export quick-action for this company |
| Set as active | Makes this the active company (topbar ticker updates) |
| Remove | Confirmation dialog → removes holding |
Annotation components v3
These classes are used by the review mode annotation system (§4.4) and in app.js but were previously undocumented in the component library:
| Class | CSS Spec | Usage |
|---|---|---|
.highlight-annotation | background: oklch(90% 0.06 80); border-bottom: 2px solid var(--accent); cursor: pointer. :hover::after shows tooltip via data-comment attribute. | Text highlight + comment annotations |
.box-annotation | position: absolute; border: 2px solid var(--red); pointer-events: none; z-index: 200 | Bounding box drawn via crosshair mode |
.box-label | position: absolute; top: -20px; left: 0; background: var(--red); color: var(--surface); font: 500 9px var(--font-mono); padding: 2px 6px | Label inside box annotations |
.comment-pin | display: inline-flex; width: 16px; height: 16px; background: var(--accent); color: var(--surface); border-radius: 50%; font: 600 8px var(--font-mono) | Inline comment indicator |
.annotation-toolbar | position: absolute; background: var(--fg); color: var(--surface); border-radius: 2px; padding: 4px; z-index: 300; box-shadow: 0 4px 12px oklch(20% 0.02 60 / 0.2) | Floating toolbar on text selection |
Focus ring (reusable pattern) v3
All interactive elements (buttons, links, inputs, nav items) must show a visible focus ring for keyboard navigation:
:focus-visible {
outline: 2px solid var(--accent);
outline-offset: 2px;
}
:focus:not(:focus-visible) {
outline: none;
}
This ensures keyboard users see the ring while mouse clicks do not produce a visible outline. The ring uses the accent color at 2px with a 2px offset from the element boundary.
Shimmer animation (skeleton loading) v3
@keyframes shimmer {
0% { background-position: -200% 0; }
100% { background-position: 200% 0; }
}
.skeleton {
background: linear-gradient(
90deg,
oklch(92% 0.008 80) 25%,
oklch(96% 0.008 80) 50%,
oklch(92% 0.008 80) 75%
);
background-size: 200% 100%;
animation: shimmer 1.5s ease-in-out infinite;
border-radius: 2px;
}
[data-theme="dark"] .skeleton {
background: linear-gradient(
90deg,
oklch(28% 0.01 80) 25%,
oklch(22% 0.01 80) 50%,
oklch(28% 0.01 80) 75%
);
background-size: 200% 100%;
}
6. Agent System
MosaicIQ's agent system is the primary content production pipeline. Agents ingest raw data (SEC filings, transcripts, market data), process it into structured outputs (financial models, company profiles, memos), and coordinate through a dependency graph. Critically, every agent is designed to feel like a collaborator — not a black box — surfacing its reasoning, flagging uncertainty, and deferring to the analyst at decision points.
Agent roster (14 agents)
| ID | Name | Role | Pipeline |
|---|---|---|---|
cr | Company Research | Structured profiles from filings, transcripts, external data | Main Research |
sf | SEC Filings | Segment data, KPIs, risk factors, accounting policies | Main Research |
fm | Financial Modeling | Revenue builds, margin models, three-statement frameworks | Main Research |
ec | Earnings Call | Management tone, guidance, KPIs, Q&A themes | Competitive & Risk |
ci | Competitive Intel | Peer analysis, market positioning, competitive threats | Competitive & Risk |
va | Valuation | DCF, trading comps, scenario analysis, multiples | Main Research |
rk | Risk | Business, financial, competitive, regulatory risks | Competitive & Risk |
mw | Memo Writing | Investment memos, research reports, IC memos | Main Research |
pa | Presentation | IC presentation drafts, slide outlines, exhibits | Main Research |
mn | Monitoring | Filing alerts, thesis changes, earnings events | Cross-cutting |
sv | Source Verification | Citation checking, source reliability, cross-referencing | Cross-cutting |
rt | Red Team | Thesis challenges, assumption stress-testing, bear cases | Competitive & Risk |
ex | Export | PDF, Excel, PowerPoint export pipelines | Cross-cutting |
qa | Model QA | Formula auditing, balance sheet checks, sanity tests | Cross-cutting |
Dependency graph
Agents execute in a directed acyclic graph with two main pipelines and a cross-cutting layer:
Fig 4. Agent Dependency Graph — with Research & Validation Cycle
Agent states
| State | Visual | Dot | Behavior |
|---|---|---|---|
| Running | Accent border + pulse animation | var(--accent) | Progress bar fills, live output streams |
| Completed | Green border + check | var(--green) | 100% bar, "View Output" action |
| Queued | Muted dashed border | oklch(70% 0.06 80) | 0% bar, "Start Now" override |
| Idle | Default border | var(--muted) | "Start" action available |
| Paused | Amber dot, frozen progress bar | oklch(58% 0.16 35) | Agent is waiting for analyst input via chat |
| Failed | Red border + error icon | var(--red) | Error detail shown, "Retry" action |
6.1 Agents as Collaborators
The agent system is built around a core interaction principle: agents should feel like skilled co-analysts sitting across the desk. This means they do not just produce outputs — they explain their reasoning, highlight where confidence is low, and actively invite the analyst into the loop.
Collaboration behaviours
- Assumption surfacing. Every agent output includes a visible "Assumptions" section listing the key premises behind its analysis.
- Confidence signals. Agents annotate their findings with confidence levels (High / Medium / Low), displayed as inline pills next to the relevant data.
- Proactive questions. When an agent encounters ambiguity, it pauses and surfaces a question to the analyst via the command bar.
- Transparent reasoning traces. The fullscreen agent overlay shows a step-by-step execution log.
- Iterative handoff. Agents never present a final answer without offering a revision cycle.
Carousel
The command bar carousel cycles through active agents (array activeAgents). It shows: pulsing dot, agent name, current action text, and a counter (1 / 3). Navigation via prev/next arrows or clicking the strip opens the fullscreen overlay.
6.2 Agent Interaction Model
All agent interaction flows through the command bar and fullscreen chat mode. The agent state is always visually clear in the supporting UI — the analyst should never wonder which agent they're interacting with or which part of the workspace is affected.
Agent chat layout spec v3
The chat interface renders in two contexts: the command bar (compact, single-line) and the fullscreen overlay (expanded, multi-line). Both use the same component structure:
| Element | CSS Classes | Spec |
|---|---|---|
| Agent message | .chat-msg.agent | max-width: 560px; background: var(--bg); border: 1px solid var(--border); padding: 12px 16px; border-radius: 2px. Agent name in 9px mono uppercase accent above the bubble. Left-aligned. |
| Analyst message | .chat-msg.analyst | Same base spec. background: var(--surface); border-color: var(--muted). Right-aligned with margin-left: auto. |
| Structured output (table) | .chat-msg .structured-table | Uses .spreadsheet class. Collapsed by default showing first 5 rows, with "Show all N rows" toggle. |
| Structured output (assumptions) | .chat-msg .assumption-list | Each assumption: checkbox (unchecked), text, confidence pill. "Accept all" / "Reject & re-run" buttons at bottom. |
| Quick actions | .chat-actions | Row of small buttons below agent message: "Accept assumptions", "Reject & re-run", "Show sources", "Revise". Flex row with gap: 6px. |
| Chat scroll area | .chat-scroll | flex: 1; overflow-y: auto; padding: 24px. Messages stack vertically with gap: 16px. Max-width 680px, centered. |
| Chat input | .chat-input | Full-width input bar at bottom: border-top: 1px solid var(--border); padding: 12px 24px. Input field + send button. ⌘Enter to send. |
Agent alert in the command bar
When an agent needs input, the command bar shows a persistent ! alert. The ! icon replaces the pulsing dot and turns amber, the agent name and a truncated question appear inline, and a "Respond" button opens the fullscreen overlay.
Visual clarity: which agent is being impacted
- Command bar carousel — always shows the active agent name + current action.
- Agent grid tiles — the active/interacting agent gets a 2px accent border + subtle glow.
- Workspace sections — each section has a small agent attribution badge:
[cr · Company Research]in 9px mono, muted. - Fullscreen overlay — tab bar with status dots. Active tab has accent underline.
- Section flash — when an agent needs input, the relevant workspace section gets a subtle accent left-border flash (1s pulse, twice).
Confidence signals UI
| Level | Colors |
|---|---|
| High | bg oklch(95% 0.04 145), border oklch(52% 0.12 145), text oklch(52% 0.12 145) |
| Medium | bg oklch(95% 0.04 60), border oklch(58% 0.16 35), text oklch(58% 0.16 35) |
| Low | bg oklch(95% 0.04 25), border oklch(52% 0.14 25), text oklch(52% 0.14 25) |
6.3 Agent Configuration Panel
Clicking "Configure" on an agent tile opens a slide-in panel (360px, same as agent detail panel) with:
| Section | Contents |
|---|---|
| Identity | Agent name, role description, icon |
| Data sources | Toggle switches for: SEC filings, transcripts, market data, analyst reports, press releases |
| Model preferences | LLM model selection dropdown, temperature slider (0–1, step 0.1), max tokens input (number) |
| Scheduling | Auto-run triggers: "On new filing", "On earnings date", "Daily", "Manual only" |
| Output format | Agent-specific: memo outline vs prose, model forecast period, report sections |
Config panel layout v3
Fig 5. Agent Configuration Panel Wireframe
7. Research & Validation Cycle
MosaicIQ enforces a structured research → validate → iterate cycle across the entire agent pipeline. No output reaches the analyst's desk without passing through at least one validation checkpoint.
Cycle stages
- Research. Agents gather data, build models, and draft analysis. Each agent marks its output with confidence levels and assumptions.
- Cross-verification. Source Verification (
sv) checks citations. Model QA (qa) audits formulas and sanity thresholds. Both return pass/fail reports. - Adversarial stress-test. Red Team (
rt) challenges the research — building bear cases, stress-testing assumptions, surfacing contradictions. - Analyst checkpoint. Reviewed output presented with: verified (green ✓), flagged (amber ⚑), unverified (grey —). Analyst accepts, revises, or rejects.
- Propagation. Approved sections propagate downstream. Upstream changes auto re-trigger affected agents.
7.1 Validation Flow Diagram v3
Fig 6. Validation Failure Flow — Sequence Diagram
Validation states in the UI
| State | Indicator | Meaning |
|---|---|---|
| ✓ Verified | Green check icon + muted border | Source Verification and Model QA have both passed. |
| ⚑ Flagged | Amber flag icon + accent border | Adversarial review raised concerns; analyst action recommended. |
| — Unverified | Grey dash + dashed border | Not yet through the validation cycle. |
| ✗ Failed | Red cross + red border | Verification failed. Routed back to the producing agent. |
Validation on actual content
- Workspace sections: Badge cluster in section header showing aggregate state:
✓ 3 passed,⚑ 1 flagged. - Model cells: Failed QA cells get a subtle red left-border with tooltip.
- Memo paragraphs: Inline validation follows the citation —
[12] ✓or[12] ⚑. - Accept/Reject/Revise: Right-click context menu on validated elements.
The validation cycle is the reason MosaicIQ's agents can be trusted: they do not just work fast, they work checked.
8. Interactive States
Every data-bound surface in MosaicIQ has defined rendering modes for loading, empty, error, and success states.
8.1 Loading & Skeleton States
Every data-bound surface has three rendering modes:
Skeleton (first load)
Grey placeholder blocks matching the layout shape of the real content. Uses the .skeleton class with the shimmer animation defined in §5. Skeleton shapes per surface:
| Surface | Skeleton HTML pattern |
|---|---|
| Metric grid cells | <div class="metric-cell"><div class="skeleton" style="height:12px;width:60px"></div><div class="skeleton" style="height:20px;width:80px;margin-top:4px"></div></div> |
| Spreadsheet rows | <tr><td colspan="N"><div class="skeleton" style="height:14px"></div></td></tr> × 6 rows |
| Memo blocks | <div class="memo-block"><div class="skeleton" style="height:10px;width:120px"></div><div class="skeleton" style="height:18px;width:80%;margin-top:8px"></div><div class="skeleton" style="height:14px;width:100%;margin-top:6px"></div></div> |
| Agent tiles | <div class="agent-tile"><div class="skeleton" style="height:28px;width:28px"></div><div class="skeleton" style="height:13px;width:70%;margin-top:10px"></div><div class="skeleton" style="height:10px;width:50%;margin-top:6px"></div></div> |
| Holdings list | <div class="pd-holding-row"><div class="skeleton" style="height:16px;width:36px"></div><div class="skeleton" style="height:12px;width:50%"></div><div class="skeleton" style="height:12px;width:40px"></div></div> × 4 |
Stale (background refresh)
Existing content shown at opacity: 0.7 with a thin accent bar at the top of the panel. No skeleton overlay.
Live (loaded)
Normal rendering. No visual treatment.
8.2 Empty States
Centered flex column with an icon/illustration, a title, a one-line description, and an optional action button:
| Surface | Icon | Title | Description | Action |
|---|---|---|---|---|
| Holdings list | Briefcase outline | No holdings yet | Add a company to begin research | "Add company" |
| Model spreadsheet | Grid icon | No model data | Run the Financial Modeling agent to build | "Run agent" |
| Memo body | Document icon | No memo drafted | Run the Memo Writing agent or start writing | "Start writing" |
| Agent grid | — | Show all 14 agents in "Idle" state | — | "Run Full Research" |
| Reports library | Folder icon | No reports yet | Reports appear as agents complete | — |
| Search results | Magnifier icon | No results | Try a different search term | — |
| Activity feed | Clock icon | No activity yet | Agent events will appear here | — |
8.3 Error States
A bordered panel with semantic coloring and an icon. The error alert replaces the content area of the failed section (not the whole screen). Dismissible via × in the corner.
| Error type | Variant | Icon | Title | Behavior |
|---|---|---|---|---|
| Agent failure | error (red border, red-tinted bg) | ! circle | "[Agent name] failed" | Shows error detail + "Retry" button |
| Network error (future) | warning (amber border) | Triangle | "Connection lost" | Shows retrying status, auto-reconnects |
| Data load failure | error | ! circle | "Failed to load [section]" | Inline in the section, "Retry" button |
| Validation failure | warning | Flag | "Validation flagged issues" | Links to the flagged items |
| Export failure | error | ! circle | "Export failed" | Shows error detail + "Retry" |
8.4 Toast & Notifications
Stacked toasts anchored top-right, below topbar (top: 56px). Typed variants: success, error, warning, info, loading.
Toast HTML structure v3
<div class="toast-container">
<div class="toast toast-success">
<div class="toast-icon">✓</div>
<div class="toast-body">
<div class="toast-title">SEC Filings Agent completed</div>
<div class="toast-desc">COST 10-K analysis ready</div>
</div>
<button class="toast-action">View output</button>
<button class="toast-dismiss">×</button>
</div>
</div>
Toast CSS v3
.toast-container {
position: fixed; top: 56px; right: 16px; z-index: 1000;
display: flex; flex-direction: column; gap: 8px;
max-width: 380px; pointer-events: none;
}
.toast {
display: flex; align-items: flex-start; gap: 10px;
background: var(--surface); border: 1px solid var(--border);
padding: 12px 14px; border-radius: 2px;
box-shadow: 0 4px 12px oklch(20% 0.02 60 / 0.08);
pointer-events: auto; animation: toast-in 200ms ease-out;
}
.toast.toast-success { border-left: 3px solid var(--green); }
.toast.toast-error { border-left: 3px solid var(--red); }
.toast.toast-warning { border-left: 3px solid var(--accent); }
.toast.toast-info { border-left: 3px solid var(--muted); }
.toast-icon {
font-size: 13px; flex-shrink: 0; margin-top: 1px;
}
.toast-success .toast-icon { color: var(--green); }
.toast-error .toast-icon { color: var(--red); }
.toast-warning .toast-icon { color: var(--accent); }
.toast-body { flex: 1; }
.toast-title { font: 500 12px/1.3 var(--font-body); }
.toast-desc { font-size: 11px; color: var(--muted); margin-top: 2px; }
.toast-action {
font: 500 10px var(--font-mono); color: var(--accent);
background: none; border: none; cursor: pointer;
text-transform: uppercase; letter-spacing: 0.04em;
white-space: nowrap; flex-shrink: 0;
}
.toast-dismiss {
background: none; border: none; color: var(--muted);
cursor: pointer; font-size: 14px; flex-shrink: 0;
padding: 0; line-height: 1;
}
@keyframes toast-in {
from { opacity: 0; transform: translateX(20px); }
to { opacity: 1; transform: translateX(0); }
}
Toast types in MosaicIQ
| Event | Type | Duration | Content |
|---|---|---|---|
| Agent completes | success | 4s auto-dismiss | "[Agent name] completed" + "View output" |
| Agent fails | error | Manual dismiss | "[Agent name] failed" + detail + "Retry" |
| Agent needs input | warning | Until dismissed | "[Agent name] needs input" + "Respond" |
| Thesis change | info | 6s auto-dismiss | "Thesis change: [ticker] — [summary]" + "View" |
| Filing alert | info | 6s auto-dismiss | "New filing: [form type] — [company]" + "Open" |
| Export complete | success | 4s auto-dismiss | "[Type] exported" + "Open file" |
| Validation pass | success | 3s auto-dismiss | "Source verification passed" |
| Validation flag | warning | Until dismissed | "[N] items flagged by [agent]" + "Review" |
8.5 Search Behavior
The search bar searches across four categories: companies, reports, files, and commands.
- Click search or press
⌘F→ search input expands, dropdown appears - Results stream in grouped by category
- Each result row: type icon, title, secondary text, keyboard shortcut if applicable
- Arrow keys navigate, Enter selects, Escape closes
⌘Kopens agent chat — separate from search
9. Interaction Patterns
9.1 Keyboard Shortcuts
| Shortcut | Action | Context |
|---|---|---|
⌘K | Open agent chat / command bar | Global |
⌘F | Focus search bar | Global |
⌘S | Create manual snapshot | Memo, Model |
⌘E | Open export quick-action menu | Global |
⌘\ | Toggle left nav collapse | Workspace, Memo |
⌘1–5 | Switch to screen 1–5 | Global |
⌘. | Toggle settings overlay | Global |
Escape | Close overlay / fullscreen / search | Overlay contexts |
↑ / ↓ | Navigate agent carousel, search results, model cells | Context-dependent |
Enter | Select / confirm | Context-dependent |
Tab | Move between memo sections | Memo |
⌘Z | Undo last edit | Memo, Model |
⌘⇧Z | Redo | Memo, Model |
All shortcuts configurable in Settings → Keybindings. The Keybindings panel (one of six settings tabs) shows every shortcut in an editable table: action name, current binding, "Record new shortcut" button. Bindings stored in ClientSettings.keybindings.
9.2 Dark Mode
Dark mode inverts the lightness axis while keeping hue/chroma relationships identical. Toggle via Settings → Display → Theme.
:root[data-theme="dark"] {
--bg: oklch(15% 0.012 80);
--surface: oklch(18% 0.008 80);
--fg: oklch(92% 0.008 80);
--muted: oklch(60% 0.01 80);
--border: oklch(28% 0.01 80);
--accent: oklch(65% 0.16 35);
--green: oklch(60% 0.12 145);
--red: oklch(60% 0.14 25);
}
Dark mode component handling v3
- Typography stacks: Unchanged.
- Skeleton shimmer: Uses inverted lighter shade (see shimmer animation in §5).
- Charts: Grid lines use
var(--border)(automatically darker). SVG area fills adjust opacity: reduce from 0.1 to 0.15 for visibility. - Treemap cells: Reduce saturation by ~20% in dark mode to avoid vibrating against the dark background. Add a
data-themeselector to override cell colors. - Inverted elements: Ticker badges (
bg: var(--fg); color: var(--surface)) auto-adapt through token swap — no component-level override needed. - Shadows: In dark mode, shadows should use
oklch(0% 0 0 / 0.3)instead ofoklch(20% 0.02 60 / 0.08)for the same perceived depth. - Toast borders: The left-border accent colors remain the same — they already have sufficient contrast on dark surfaces.
- Highlight annotations: Adjust to
background: oklch(28% 0.03 80)so the tinted highlight is visible on the dark bg.
9.3 Screen Transitions
| Transition | Duration | Easing | Detail |
|---|---|---|---|
| Screen switch | 150ms | ease-out | Fade: old screen opacity: 1 → 0, new screen opacity: 0 → 1. No slide. |
| Nav collapse | 200ms | ease | Width transition (existing) |
| Right panel slide-in | 200ms | ease-out | Transform translateX(100%) → translateX(0) |
| Overlay open | 150ms | ease-out | Backdrop opacity: 0 → 1, content scale(0.98) → scale(1) + fade |
| Overlay close | 100ms | ease-in | Reverse of open |
| Agent tile hover | 100ms | linear | Action buttons fade in |
Screen transition CSS v3
/* Screen switch — add to .screen */
.screen {
transition: opacity 150ms ease-out;
opacity: 0;
}
.screen.active {
opacity: 1;
}
/* Right panel slide-in */
.right-panel {
transform: translateX(100%);
transition: transform 200ms ease-out;
}
.right-panel.open {
transform: translateX(0);
}
/* Overlay */
.overlay {
opacity: 0;
transition: opacity 150ms ease-out;
}
.overlay .overlay-body {
transform: scale(0.98);
transition: transform 150ms ease-out;
}
.overlay.open {
opacity: 1;
}
.overlay.open .overlay-body {
transform: scale(1);
}
9.4 Accessibility
- All interactive elements have
role,aria-label, andtabindexattributes - Screen switches announce via
aria-live="polite"region - Agent status changes announced via
aria-live="assertive"for failures,politefor completions - Focus management: screen switches move focus to the main content area; overlay opens trap focus within the overlay
- Color contrast: all text meets WCAG AA
- Keyboard-only navigation: all actions accessible without a mouse. Focus ring pattern defined in §5.
9.5 Responsive Behavior
| Breakpoint | Behavior |
|---|---|
| ≥1440px (primary) | Full layout: nav + center + panel |
| 1280–1439px | Right panel becomes a slide-in overlay instead of persistent column |
| 1024–1279px | Left nav starts collapsed (36px). Agent grid goes 2-column. Memo outline becomes a dropdown. |
| <1024px | Not supported. App shows: "MosaicIQ requires a desktop display of 1024px or wider." |
Responsive floor implementation v3
@media (max-width: 1023px) {
body > *:not(.floor-message) { display: none !important; }
body::before {
content: '';
display: block;
position: fixed; top: 0; left: 0; right: 0; bottom: 0;
background: var(--bg);
}
body::after {
content: 'MosaicIQ requires a desktop display of 1024px or wider.';
display: flex;
position: fixed; top: 0; left: 0; right: 0; bottom: 0;
align-items: center; justify-content: center;
font: 400 16px/1.5 var(--font-body);
color: var(--muted); text-align: center;
padding: 40px;
}
}
9.6 Data Density Settings
Settings → Display → Data Density offers three options:
| Property | Comfortable (default) | Compact | Dense |
|---|---|---|---|
| Body font size | 15px | 14px | 13px |
| Line height | 1.7 | 1.5 | 1.4 |
| Card padding | 16px | 12px | 8px |
| Grid gap | 1px | 1px | 0px |
| Table cell padding | 8px 12px | 6px 10px | 4px 8px |
| Metric grid min-width | 140px | 120px | 100px |
| Nav width (expanded) | 240px | 220px | 200px |
index.html, styles.css, and app.js in the project root. Version 3.0 addresses all 20 gaps identified in the v2 review: RPC surface (28 methods), real-time transport (SSE), naming convention, sub-screen HTML structures, agent chat layout, config panel wireframe, skeleton/empty/error/toast HTML+CSS, dark mode component handling, screen transition CSS, validation flow diagram, version history UI, annotation component docs, focus ring pattern, shimmer keyframes, settingsPanel enum, dropdown implementation note, responsive floor, missing memo sections, and keybindings panel spec.