REF-268 asks for one shared, read-only CSV/TSV/XLSX viewer surfaced in four places: the documents preview pane, its triage twin, task attachments, and chat attachments. The grid itself is settled by the plan — values-grid fidelity, sheet tabs, sticky headers, download always one click away, truncate-never-spin. What is genuinely open is the container topology: what happens when a lawyer clicks a spreadsheet outside the panes, and in what order the viewer discloses what it knows. The three variants below take three defensible positions on exactly that. All data is fictional; tokens mirror apps/client/src/index.css.
A spreadsheet is a document like any other — so it goes where documents already live. The grid renders flush inside the existing preview panes, with sheet tabs in the product's underline-tab grammar and download in the toolbar where it already sits. A task attachment routes to the document's page in Records; a sent chat attachment does the same. The one place with no document to route to — a file just attached to the composer — gets a three-row peek in place. No new containers, no new elevation. Cheapest to build and most consistent with today's mental model; the cost is a navigation away from the task or thread you were in.
The grid replaces today's "Spreadsheets are not shown here" card. Underline sheet tabs sit under the pane toolbar; column letters and row numbers stay pinned while the grid scrolls both ways. Cell text is selectable — the D5 range shown mid-copy.
F1 · R6, R2, R4, R5. Sheet tabs are live — switch between the workbook's four visible sheets.
The triage twin embeds the same component. A 148 MB export renders its first 1,000 rows instantly; the truncation is named in a warning banner — icon + words, never color alone.
F2 · R6, R10. Truncate, never spin — the pane stays responsive.
Clicking the attachment opens the document's own page instead of navigating to the raw S3 URL. One viewer, one home; the trade is leaving the task to look.
Click → Records › Discovery log — RFP set two.xlsx (documents route, viewer as in F1). Back returns to the task.
F3 · R7, R9. No overlay to design or maintain; deep-linkable by construction.
A file attached to the composer has no document page yet, so the chip expands a three-row peek from local bytes. Sent attachments route to Records like task attachments.
F4 · R8. Honest but asymmetric: pre-send and post-send behave differently.
The pane goes full-width; tabs scroll horizontally; the grid pans both axes under pinned headers.
F5. Same component, no mobile-special chrome.
Loading. Skeleton rows where the grid will land; no layout jump.
It may be password-protected or damaged. Download it to open in your spreadsheet app.
Unparseable (R11). Product voice; no parser error reaches the user.
Sheet 1 of 1 is empty.
Empty sheet (AE8). A calm statement, not an error.
Outside the panes, a spreadsheet click presents the file for inspection — a floating glass viewer over the work you're in. Task and chat both open the same exhibit overlay, whether the bytes come from S3 or from a file still sitting in the composer; Esc puts you back exactly where you were. The file's name is set in Baskervville — a named thing earns the serif — and sheet tabs ride a bottom rail, where every spreadsheet application a lawyer has ever used keeps them. The documents and triage panes embed the same core flat, per the elevation model: glass belongs only to the floating layer. One answer for all four surfaces and both byte sources.
The taskboard stays visible behind glass. Serif filename, size and sheet count in the header, download and close on the right; the bottom rail carries sheet pills and a live row count.
F1 · R7, R9, R2. Bottom rail is live. Esc or ✕ returns to the task — context is never lost.
In-page surfaces don't get glass. The pane hosts the identical grid and bottom rail; only the shell differs. The triage twin is byte-for-byte this frame.
F2 · R6. One component, two shells; the rail keeps sheet position consistent everywhere.
A chip on a sent message opens from stored bytes; a chip still in the composer opens from local bytes. Same overlay, same rail — the user can't tell the difference, which is the point.
Either chip → the exhibit overlay (F1), stored or local bytes alike.
F3 · R8. Pre-send and post-send are symmetric — one behavior to learn.
The overlay becomes a full-height sheet. The rail stays at the bottom, inside thumb reach; download moves into the header.
F4. Sheet switching without reaching to the top of a phone screen.
It may be password-protected or damaged. Download it to open in your spreadsheet app.
Loading · oversize (R10) · unparseable (R11). The overlay opens instantly and fills in; it never blocks the click.
Before showing every cell, answer the question the lawyer actually has: what is this file, and am I seeing all of it? An abstract strip leads every preview — sheets, rows × columns, size, and an explicit complete/partial verdict — so truncation is structural fact, not a banner bolted on. Sheets switch through a compact picker that scales to workbooks with dozens of tabs. In task and chat, the chip expands in place into a bounded mini-grid: the evidence appears inside the conversation or task without any navigation or overlay, with "Open full view" as the escalation. Best oversize honesty and cheapest glance; the cost is a second step to reach the full grid.
The strip states the file's shape and completeness up front. The sheet picker replaces a tab row — one control whether the workbook has two sheets or forty.
F1 · R6, R2. The picker is live — it cycles the workbook's sheets.
On a partial preview the verdict slot itself carries the warning; the grid below needs no extra banner. Filing decisions get made on named facts.
F2 · R6, R10. Completeness is a first-class fact, not a footnote.
The attachment row unfolds into a bounded mini-grid right inside the task. Escalation to the full viewer is one click; nothing navigates away by default.
F3 · R7, R9. The glance is free; the full grid is one deliberate step.
Pre-send and sent chips expand identically, from local or stored bytes. The evidence sits inside the conversation the agent is having about it.
F4 · R8. No modal interrupts the thread for a four-row question.
The abstract stacks; the picker earns its keep where tab rows would wrap or scroll off-screen.
F5. One picker instead of a scrolling tab row.
Loading. The abstract lands first — name and progress before any cell.
It may be password-protected or damaged. Download it to open in your spreadsheet app.
Unparseable (R11). Shared fallback card across all three variants.
This sheet is empty.
Empty (AE8). The abstract says so plainly.
| 1 · Working Sheet | 2 · Exhibit | 3 · Abstract | |
|---|---|---|---|
| New containers | None — panes + routes only | One glass overlay | Mini-grid + full-view escalation |
| Task click (R7) | Routes to Records — context lost | Overlay over the board — context kept | Expands in place |
| Chat pre-send (R8) | Asymmetric — peek only, full view after send | Identical to sent — local bytes | Identical to sent — local bytes |
| Sheet switching (R2) | Underline tabs, top — product grammar | Pill rail, bottom — spreadsheet muscle memory | Picker — scales to 40-sheet workbooks |
| Oversize story (R10) | Warning banner above grid | Warning banner above grid | Structural — completeness is a named fact |
| Narrow / mobile | Nothing special to build | Full-screen sheet, rail in thumb reach | Good glance; full grid cramped in threads |
| Build cost | Lowest | Middle — one overlay, two shells | Highest — three embed sizes to keep coherent |
| Main risk | Navigation breaks task/chat flow; pre-send is a second, smaller viewer | Overlay must not grow editor ambitions — read-only stays the contract | Two steps to full grid; inline grids repeat poorly in long threads |
Variant 2 is the only topology that answers all four surfaces and both byte sources with one behavior: click a spreadsheet anywhere outside the panes and it opens over your work, stored or local bytes alike, Esc to return. That directly discharges the plan's open container question (R7/R8) without the Working Sheet's pre-send asymmetry or the Abstract's three embed sizes, and it lands exactly on the product's existing elevation model — flat core in the panes, glass only for the layer that floats.
Take one graft from Variant 3: replace the oversize banner with the Abstract's completeness fact in the toolbar meta slot — "First 1,000 of 482,310 rows" beside the size and sheet count — so truncation reads as a property of the file, not an alarm on top of it. Keep the bottom sheet rail in the overlay (spreadsheet muscle memory, thumb-reachable on mobile) but let the pane embeds use it too, so sheet position never moves between shells. Variant 1's routing survives as the deep link: the overflow menu offers "Open in Records" for stored documents. Estimated scope beyond Variant 1 is one overlay shell — a fair price for the only design with no asymmetric case to explain.