How to read this
Four parts. Part 1 enumerates every feature in grouped tables — area, feature, where it lives, what actually happens. Part 2 diagnoses the one real bug found in the pass (the selection-op result panel). Part 3 ranks the UX issues High / Med / Low, each with the concrete fix. Part 4 is the opinionated pass — for each major feature, could it be done better? — grounded in how the best-in-class tools solve the same problem, ending with the three highest-leverage redesigns in order.
Honest by design. The product is genuinely good — a calm editor with a real trust model — so this review spends its ink on the seams, not the wins. Where something is already the right answer (the per-paragraph "Edit this idea" gesture), it says so and holds it up as the template.
Part 1 · Every feature, in detail
1 · Pages & money
| Area | Feature | Where | What happens |
|---|---|---|---|
| Pages | Landing | / | Marketing home: hero with a 3-pane product mock, a "the difference" section, feature grid, and the pricing block. The front door for a cold visitor. |
| Home · "Your desk" | /home | The signed-in landing: a real corpus-driven library, a ⌘K command palette, and it seeds memory on mount so a first-run desk is never empty. | |
| Onboarding | /onboarding | First-run flow to get a user from zero to a seeded corpus and their first document. | |
| Pricing | /pricing | Two tiers: Free CHF 0 and Pro CHF — (price is a placeholder — not yet locked). | |
| Upgrade modal | /upgrade | The in-app conversion surface with a usage meter — shows consumption against the free ceiling to motivate the upgrade. | |
| Checkout | /api/checkout | A deliberate 501 stub — no charge is wired. The button exists; the money path does not. This is the single revenue blocker. |
2 · Auth
| Area | Feature | Where | What happens |
|---|---|---|---|
| Auth | Magic-link sign-in | /login · /auth/verify | Passwordless: request a link, click it, get a 72h HS256 JWT in the oll_token cookie. Identity in the token, plan read live from /api/auth/me. |
| Route protection | middleware → /editor | Middleware gates the editor. On in production, off in dev for a frictionless local loop. | |
| Live entitlement | /api/auth/me | The plan (Free / Pro) is never baked into the token — it's fetched live, so an upgrade takes effect without re-issuing a JWT. |
3 · The editor
| Area | Feature | Where | What happens |
|---|---|---|---|
| Editor | Selection ✨ op menu | floating bubble on select | Edit: Improve · Rewrite… · Fix grammar · Change tone ▸ (Formal/Casual/Friendly/Professional/Confident). Length: Shorten · Expand. Transform: Bullets · Simplify · TL;DR. |
| "Edit this idea" | per-paragraph gutter ✨ | Hover a block → type a plain instruction → the paragraph is rewritten and shown as an inline word-diff. The whole-thought gesture, no selection needed. | |
| Word-diff redline | result surface | Edit-shaped ops render a word-level redline (deletions struck, insertions highlighted) before anything touches the document. | |
| Accept / Reject / Retry | result surface | Accept commits via real editor transforms; Reject restores the original; Retry re-runs the same op for a fresh take. | |
| Ink-in accept animation | on Accept | The new text "inks in" via a CSS clip-path sweep, left to right — the one delightful moment. Respects prefers-reduced-motion. | |
| Focus mode | ⇧⌘F | Dims every block except the one under the caret — the active line is the only lit thing. | |
| Manuscript ↔ Margin | mode toggle | Manuscript = the clean page. Margin = the editor-in-the-margin: AI marginalia in the right margin joined to the prose by leader lines. | |
| Model / provider toggle | top bar, persisted | Flips every op between Groq (Fast / free) and Claude (Quality / pro), threaded through the whole op pipeline. | |
| The top bar | editor chrome | Wordmark · live word-count + read-time · Voice · Draft · Check · Export · Focus. Idle-dims so the page is what you see. |
4 · The memory sidecar
| Area | Feature | Where | What happens |
|---|---|---|---|
| Left · Knowledge | Add / upload | left pane | Paste text or upload a file (incl. PDF) into your corpus; each doc lists with its chunk count. |
| Semantic search | left pane | Manual ranked search over your corpus, returning ChunkCards with provenance + similarity score. | |
| "As you write" cards | proactive lane | Related chunks pushed from the editor based on the paragraph under your cursor — retrieval you didn't ask for. | |
| Drag-to-cite | card → editor | Drag a knowledge card into the draft to cite it. (Interaction target — see §5; not fully wired.) | |
| Right · Chat | Grounded chat | right pane | Cited answers over only your corpus — every claim is one hover from its source chunk. |
| Honest abstention | right pane | When the corpus can't support an answer, it says so rather than inventing — the trust contract. | |
| Citation chips | in answers | [n] docId chips, hover for the chunk. A chip appears only for a real retrieved chunk — the citation trust-registry. | |
| First-run guide | right pane, empty state | A "What I found" intro + suggested questions so the empty chat teaches itself. |
5 · Rung-2/3 differentiators
| Area | Feature | Where | What happens |
|---|---|---|---|
| Differentiators | First-corpus guide + seed | onboarding / home | A source guide plus corpus seeding so the very first session has something to retrieve against. |
| Export → Markdown | Export | Export the manuscript to Markdown with citations preserved. | |
| Draft-from-bullets | Draft | Turn bullets into grounded, cited prose — and flag "needs a source" gaps where the corpus can't back a claim. | |
| Gap-chips "Check" | Check | Claim decomposition → amber/red gutter chips + a "what I need" checklist. Calibrated (flags the uncertain, not everything). | |
| Voice "write in my voice" | Voice | Learns a style profile from your writing → injects it into generation so ops sound like you. | |
| Citation trust-registry | cross-cutting | The invariant behind chat + draft: a citation chip is rendered only when it maps to a real retrieved chunk — never a fabricated reference. |
Part 2 · The paragraph-op bug, diagnosed
The selection-op result lands in the wrong place bug
When you run a selection op, the result renders in a fixed right-4 bottom-4 corner panel. On a 3-pane layout that corner sits on top of the right Chat column — so the suggestion reads as "coming from the chat side," disconnected from the text it's editing. Meanwhile the per-paragraph "Edit this idea" flow already anchors its identical redline inline, right under the paragraph. So the app has two surfaces for the same result — one right (inline), one wrong (a floating corner that collides with Chat).
as-you-write cards
you selected this sentence…
…but the result appeared over there ↘
corpus Q&A
collides with the Chat column — reads as "the chat side"
Fix: anchor the selection-op result inline at the selection (a popover under the selected text), or better — unify the two AI-edit surfaces into one inline result so selection-op and "Edit this idea" render identically. The per-paragraph flow is already the correct pattern; the selection op just needs to adopt it. (Fix in progress.)
Part 3 · Prioritized UX issues
High — blocks first use or the first dollar
Both side drawers open over the editor on narrow viewports High
On a narrow screen, Knowledge (left) and Chat (right) both open as drawers over the manuscript — so on load there's no editor visible. The first thing a user sees is two panels, not a page to write on.
Fix: on <1024px, default both drawers closed and let the editor own the viewport; open a pane on explicit tap, one at a time. The editor is the product — it should never load occluded.
The selection-op corner panel (the bug) High
Covered in Part 2 — the fixed right-4 bottom-4 result panel collides with Chat and disconnects the result from its text.
Fix: anchor inline / unify the two AI-edit surfaces (Part 2). Highest-value single fix in the editor.
Checkout 501 + CHF — price High
The money path is a deliberate 501 stub and the Pro price is a placeholder. Every conversion surface (pricing, upgrade modal, usage meter) leads to a dead end.
Fix: lock the price, then wire /api/checkout once to a Core checkout call (flip test→live keys + live webhook). This is the last mile, not a feature — do it after the layout fixes so the surface a payer lands on is clean.
Med — degrades the core loop
Margin mode + panes collide Med
Margin mode needs room in the right margin — but with the Chat pane open, the center column is squeezed to an unusable width and the marginalia fight the pane.
Fix: entering Margin mode should auto-collapse the Chat pane and widen the manuscript so the margin has room.
Focus mode is too subtle Med
Focus dims non-active blocks but leaves both side panes fully lit — so "focus" doesn't actually quiet the room around the writing.
Fix: make Focus a true typewriter mode — dim/collapse the panes and center the active line, not just dim sibling paragraphs.
/api/memory/suggest 502 with no fallback Med
When the proactive-suggest call 502s, the "as you write" lane just goes empty — no retry, no indication anything was attempted.
Fix: add a bounded retry + a quiet "couldn't reach your knowledge — retry" affordance, so a transient error doesn't look like an empty corpus.
Inconsistent accept shortcut Med
Accepting a suggestion is Enter in one surface and ⌘↵ in another — the muscle memory doesn't transfer between selection-op and "Edit this idea."
Fix: one accept shortcut everywhere (recommend ⌘↵, leaving Enter free for a newline inside an instruction field). Falls out naturally once the two surfaces are unified.
Missing dialog a11y descriptions Med
Modal dialogs (upgrade, onboarding) lack aria-describedby / labelled descriptions, so screen readers announce a title with no context.
Fix: add descriptions + focus trapping to each dialog. Cheap, and the kind of thing an academic/institutional buyer checks.
Low — polish & discoverability
Top-bar power features idle-dim to 35% Low
Voice / Draft / Check / Export idle-dim to ~35% opacity for calm — but that also makes the differentiating features nearly invisible, hurting discoverability.
Fix: dim less aggressively (or keep the differentiators at full opacity and only dim word-count/read-time), so the paid-tier features are discoverable.
Overloaded "mode/editor" naming Low
"Mode" means Manuscript/Margin and Focus; "editor" means the pane and the app. The vocabulary collides.
Fix: pick distinct words — e.g. "view" (Manuscript/Margin), "Focus" (a toggle, not a mode), "the page" (the writing surface).
Thin empty states Low
Empty knowledge / empty chat / empty library states are sparse — they don't teach the next action as well as the first-run chat guide does.
Fix: give every empty state the same treatment as the chat's "What I found" guide — one sentence of what it's for + one concrete first action.
Part 4 · Could it be done better?
- 3-pane → a single collapsible tabbed right rail (Sources / Chat as tabs) so the manuscript finally gets real width. The biggest layout win.
- Unify the two AI-edit surfaces into one inline result — fixes the reported bug (Part 2) and makes the whole editor consistent.
- Wire checkout once the price is locked — the last mile to the first dollar, done on a clean surface.
The selection menu
Now: a bubble of nine ops; picking one runs it and shows a result elsewhere.
Fold it into an inline instruction-or-op bar that appears under the selection: type a freeform instruction or click a preset op, and the diff renders right there, under the selected text. One surface for "improve" and "rewrite like X," with the result anchored to what it edits.
cf. Cursor's inline ⌘K edit bar · Notion AI's selection bar"Edit this idea" — the flagship
Now: hover a paragraph → gutter ✨ → plain instruction → inline word-diff.
This is the best interaction in the product and it should be the template everything else adopts: anchored to the unit of thought, freeform instruction, inline preview. Don't redesign it — propagate it. The selection menu and any future ops should feel like this.
the reference pattern — hold it up, copy it everywhereThe word-diff redline
Now: word-level inline redline for every edit-shaped op.
Word-diff is perfect for local edits. For structural transforms (Bullets, TL;DR, Simplify) a redline is noise — the whole thing changed. Show those as a before/after two-column preview instead, so the user compares shapes, not tracks a thousand strike-throughs.
cf. iA Writer / Ulysses side-by-side · GitHub split diffFocus mode
Now: dims non-active blocks; panes stay lit.
Make it a true typewriter mode: dim (or collapse) both side panes, hold the active caret line at a fixed vertical position, and let the text scroll under it. Focus should quiet the whole room, not just the neighboring paragraphs.
cf. iA Writer typewriter mode · Ulysses' focusMargin mode
Now: marginalia in the right margin — but it fights the Chat pane.
Entering Margin mode should auto-collapse the Chat pane and widen the room so the margin has somewhere to live. Margin is a layout, so it should own the layout while it's active — not compete with a pane that assumes a different one.
cf. Google Docs suggesting-mode margin commentsThe model toggle
Now: a persisted Groq ↔ Claude switch; result shows a provider · model meta line.
Surface which model ran more prominently on each result, and gate Claude visibly — a Free user sees "Quality (Claude) · Pro" and one click to upgrade. The toggle is the clearest teaching moment for the pay-once value; right now it's too quiet to convert.
cf. how Poe/ChatGPT surface the model + gate the premium oneThe 3-pane layout — the highest-leverage redesign
Now: Knowledge (left) · Editor (middle) · Chat (right), each collapsible.
Collapse the two side panes into one collapsible right rail with Sources and Chat as tabs. The manuscript gets the full left width by default; the rail slides in when you want knowledge or chat, and Sources/Chat share the same space instead of each claiming a third of the screen. This is the single change that most improves the writing surface.
cf. NotebookLM's Sources/Chat/Studio rail · Cursor's single right panelChat over your corpus
Now: grounded, cited answers — arriving whole, chips hover to the chunk.
Add streaming so the answer feels alive as it grounds, and an in-pane citation hover-preview that shows the source chunk without leaving the chat. Streaming is the single biggest perceived-speed win for a retrieval product.
cf. NotebookLM inline citations · Perplexity streaming + source hoverDraft & Check
Now: "Check" is a button that runs claim-decomposition on demand.
Surface Check as a persistent status in the chrome — a quiet "2 claims need a source" that updates as you write, click-through to the gutter chips. A hidden button gets forgotten; a live count makes the grounding discipline part of the ambient experience and is the honest-tool ethic made visible.
cf. Grammarly's live issue count · a linter's problem gutterollwrite — Feature Enumeration & UX Review · read-only pass on the running product · 2026-07-05. Companions: Feature Documentation (verified against code) · What Works, What Doesn't (live functional sweep) · Build-Out & GTM (the plan these fixes feed). Design language: oll-write design. Feeds Backlog.
A working design review, not marketing — honest about the seams so the tool can disappear. The three highest-leverage redesigns, in order: tabbed right rail · unified inline edit surface · wired checkout.