Per the design rule "italic is for emphasis, not for design", removed
every chrome `font-style: italic` declaration across the frontend.
42 declarations gone across 24 files: empty-state placeholder copy,
loading messages, "no results" hints, ghost text, voice/role labels,
field placeholder text, brand wordmark, et al.
Markdown content emphasis is unaffected — `<em>` and `<i>` tags from
`*emphasis*` markup still render italic via browser default styling
(prose.css doesn't override em behavior). User-typed emphasis in
notes, journal entries, and chat messages keeps its italic.
Specific spots that lost the decorative italic:
- KnowledgeView .filter-label, .empty-narrator
- NoteEditorView .ef-label, link-suggest related
- ChatPanel .empty-msg, .empty-greeting, .role-label
- ChatMessage .role-assistant .role-label (the "Fable" voice tag —
was italic per the doc's Illuminated Transcript spec, but per the
new typography rule the speaker tag stays regular and lets the
border-left + glow do the bubble framing on their own)
- AppHeader .brand-text ("Fabled" wordmark)
- editor-shared.css .title-input::placeholder
- ProjectView .project-title-input::placeholder
- HomeView .urgency-loading
- WorkspaceTaskPanel .empty-group
- WeatherCard .weather-unavailable
- SharedWithMeView .empty-msg
- DiffView empty-state spans
- ToolCallCard .tool-event-more
- SettingsView 7 spots (.you-label, .geo-pending, hint text, etc.)
- + several other empty-state / hint text spots
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Per the surface-phase spec for the Notes/Tasks viewers and editors:
Long-form line-height
- prose.css: bumped global .prose from 1.6 to 1.7. Applies to Note
viewer body, Task viewer body, anywhere markdown renders into a
reading surface. Chat assistant bubble already had the explicit
override; now consistent with the rest.
Button reclassification per Hybrid rule
- Shared editor-shared.css:
- btn-save: accent gradient → Moss (action-primary). Saving is
"operating the software", not a brand moment.
- btn-delete: --color-danger (Error terracotta) → Oxblood
(action-destructive). Layout updated for inline-flex so the
Trash2 icon at call sites lines up alongside the label.
- NoteEditorView, TaskEditorView: Delete buttons now contain a
Trash2 icon per Hybrid's "destructive paired with icon" rule.
- NoteViewerView, TaskViewerView:
- btn-edit (and TaskViewer's btn-advance): accent gradient → Moss.
Switching to edit / advancing status are workflow actions.
- btn-convert, btn-share: ghost-on-hover-to-accent → Bronze
action-secondary (alternate paths).
Two-weights-only
- Snapped every font-weight: 600/700 to 500 across editor-shared.css
and the five Knowledge-cluster views.
Out of scope for this PR (deliberate punt)
- Smaller utility buttons (.btn-suggest-tags, .btn-link-all,
.btn-add-subtask, the AI-assist generate/proofread/accept/reject
set, etc.) — currently ghost-styled, generally compliant. Will
revisit only if they read off in practice.
- Filter chip / sub-task list-row border audit — deferred since
current styles already lean on background tint for affordance.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Applies the FabledSword + Scribe iteration palette to theme.css end to
end: indigo (#7c3aed) → dusty violet (#5B4A8A) accent, cool grey →
Obsidian/Iron/Pewter dark surfaces, warm parchment (#F5F1E8) light
mode, Inter body + JetBrains Mono code loaded alongside Fraunces, and
neutral hairline scrollbars (chrome is structural, not branded).
Adds the action token set (--color-action-primary Moss,
--color-action-secondary Bronze, --color-action-destructive Oxblood,
--color-action-ghost-border Pewter) but does not yet reclassify any
buttons — surface-phase work. Buttons remain dusty-violet gradients in
the meantime, by design.
Removes deprecated --color-accent-warm; replaces concrete usages with
--color-text-secondary (dates, flavor copy) or --color-warning (paused
status). Sweeps hardcoded indigo literals in component scoped CSS so
they don't bypass the token system.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Phase B of chat view refinement. Bumps chat reading column to 1200px,
lifts the RAG scope chip out of the footer and into the ChatView header
(next to the title), and collapses the listen toggle / volume slider /
stop-playback buttons into a single speaker popover on the input bar.
Listen mode + TTS are now available in briefing and workspace chats too,
since the controls live on the shared ChatInputBar.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Replaces the full-variant flex layout with a single CSS grid owning the
messages column, input bar, and context sidebar. Messages and input bar
share a centered ~820px reading track (--chat-reading-width token) so
the mic button can't get pushed off-screen on wide monitors, and the
context sidebar spans grid-row 1/-1 so it runs the full height from the
chat header down to the bottom edge instead of stopping above the input
bar.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- renderMarkdown() accepts interactiveCheckboxes option: removes disabled=""
and stamps data-task-index on each checkbox in the marked HTML output
- NoteViewerView detects list notes by body content (- [ ] / - [x] pattern)
and passes interactiveCheckboxes: true when rendering
- onBodyChange() handles checkbox change events: toggles the matching line
in the body, optimistically updates the store, then PATCHes the note
- prose.css adds .prose--checklist rules for marked output: no bullet,
flex row, accent-color, line-through on checked items via :has()
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Define --color-surface in theme.css (light: #f0f0f8, dark: #1a1b22)
— was used across 10+ components with no-op fallbacks; now properly
defined alongside --color-bg and --color-bg-card
- Extract shared date formatters into utils/dateFormat.ts:
fmtTime, fmtDateTime, fmtRelativeDateTime, fmtDayLabel, fmtCompact
- Replace duplicate inline formatters in CalendarView, HomeView
(formatUpcomingTime), and KnowledgeView (formatEventDate)
- CalendarView: replace hardcoded rgba(99,102,241,0.4) hover colour
with color-mix(in srgb, var(--color-primary) 40%, transparent);
fix --color-input-bg fallback to use var(--color-bg); remove
hardcoded hex fallbacks now that --color-surface is defined
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- theme.css: darken user bubble text (#3a3a4a light / #b0b0c8 dark) for better readability
- AppHeader: highlight Chat nav link when on any /chat/* route (was only active on exact /chat)
- summary.md: document workspace, graph, queue persistence, ToolCallCard direct-API, dedup scoping
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Design direction: "Illuminated Transcript" — the AI response is the
primary artifact; user prompts are subordinate margin notes.
ChatMessage.vue:
- User bubble: ghosted background (rgba 3-4% opacity), muted text,
thin near-invisible border. De-emphasized, recessed.
- Assistant bubble: left indigo accent border (2px), elevated shadow
via --color-bubble-asst-shadow. Commands attention.
- Assistant role label: indigo (var(--color-primary)); user label muted.
- Removed old white-override content rules (no longer on dark bg).
- Thinking block: full border → left-only indigo accent bar (35% opacity),
removed inner top border.
ChatView.vue:
- Streaming bubble: same left accent + shadow as assistant bubbles.
- Streaming role label: indigo to match ChatMessage.
- Thinking block in streaming: same treatment as ChatMessage.
theme.css:
- Added --color-bubble-user-bg/border/text for light + dark.
- Added --color-bubble-asst-shadow for light + dark.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- App.vue: e → edit on viewer pages; / → focus search (custom event); c → focus
chat on home or navigate to /chat; update shortcuts panel with Lists + Chat sections
- theme.css: add a:focus-visible to focus-ring rules (router-link cards now show
visible keyboard focus outline)
- SearchBar.vue: expose focus() via defineExpose for cross-component focus dispatch
- NotesListView / TasksListView: j/k vim-style navigation with kb-active-item
highlight; listen for shortcut:focus-search; cleanup on unmount
- HomeView.vue: listen for shortcut:focus-chat, call chatInputRef.focus()
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Replace pure white backgrounds with off-white indigo-tinted values to
reduce glare, and switch the primary/accent color from Google blue to
the app's brand indigo (#6366f1) for consistency with the header and
email templates.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Backend security & correctness:
- Add rate_limit.py: sliding-window rate limiter (asyncio) applied to login,
register, forgot/reset password endpoints (10/60s or 5/300s per IP)
- app.py: add security headers in after_request (X-Frame-Options, CSP,
X-Content-Type-Options, Referrer-Policy) using setdefault to preserve SSE headers
- auth.py: refactor duplicate login_required/admin_required into shared _check_auth()
- config.py: add TRUST_PROXY_HEADERS for proxy-aware client IP resolution
- routes/auth.py: rate limiting, _client_ip() helper, cleaned-up reset_password route
- routes/chat.py, notes.py, tasks.py: int() DoS fix on last_event_id; limit capped
at 500; date.fromisoformat() wrapped in try/except → 400 on invalid dates
- services/auth.py: fix Setting.user_id update bug (filter on NULL not user.id);
reset_password_with_token returns int|None (user_id) instead of bool
- services/backup.py: add _security_notice to full backup JSON export
- services/assist.py: system prompt explicitly preserves markdown list structure
and nested indented sub-items
Infrastructure:
- docker-compose.yml: add healthcheck on app service (/api/health, 10s interval)
- .dockerignore: prevent secrets/node_modules/__pycache__/.env.* leaking into build
Frontend bug fixes:
- TaskCard.vue, TaskViewerView.vue: fix isOverdue() timezone bug (ISO string compare)
- useAssist.ts: accept() now resets state to idle when document changed since proposal
- stores/chat.ts: fix memory leak in _pollUntilLoaded() (try/catch around fetchStatus)
- TiptapEditor.vue: selection offset uses closest-match strategy (not first-match)
- utils/markdown.ts: explicit DOMPurify config with FORCE_BODY; remove as const
(DOMPurify expects mutable string[])
New features:
- Auto-save (5-minute interval) in NoteEditorView and TaskEditorView — only when
editing an existing dirty record; silent on error, shows "Auto-saved" toast
- sectionParser.ts: top-level bullet/numbered list items are now individual sections
in the AI Assist panel (previously treated as one undifferentiated block)
- editor-shared.css: extracted ~500 lines of CSS duplicated between both editors;
includes .inline-assist-btn at global scope (required for teleported elements)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Replace plain textarea with Tiptap (ProseMirror) WYSIWYG editor for notes
and tasks. Headings, bold, lists, and code blocks now render inline while
editing. Tags and wikilinks get visual highlighting via decoration plugins,
and autocomplete uses @tiptap/suggestion with heading disambiguation.
Layout: pin navbar with app-shell flex column (100dvh), sticky editor
toolbar above scrolling content, AI Assist panel fixed at bottom 1/3 with
full-height section selector and prompt. Increase max-width to 960px
across all views. Hide assist controls during streaming/review.
Other fixes: markdown paste handling, auto-syncing assist sections via
body watcher, trailing newline on AI accept, ChatView height fix.
Add README.md describing the app, usage guide, and technical overview.
Update summary.md with Phase 5.2 roadmap and current status.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Improve chat context: build_context() now returns metadata about auto-found
notes, emitted as an SSE event so the frontend can display context pills
showing which notes influenced the response. Users can promote notes for
deeper context (+) or exclude irrelevant ones (x). A note picker lets users
manually attach notes. Multi-word search uses per-term AND matching, and
auto-search iterates keywords individually for broader OR-style coverage.
Standardize styling: introduce CSS design tokens (--radius-sm/md/lg/pill,
--color-success/warning/overlay, --focus-ring) and migrate all components
to use them. Fix header alignment to full-width, add active nav link state,
replace hardcoded colors with CSS variables, and normalize button padding.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>