DBs created before the image upload feature had no thumbnail_path column
in the attachments table. Since CREATE TABLE IF NOT EXISTS is a no-op for
existing tables, the column was never added, causing silent insert failures.
Add idempotent ALTER TABLE migration for thumbnail_path and surface upload
errors via toast notifications instead of swallowing them silently.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Images are hidden from card thumbnails by default. Users explicitly
feature images via a star toggle in the upload panel, and only featured
images appear in the card header strip.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Clicking a thumbnail in the editor, closed-panel view, or note card
opens a full-screen overlay with the full-size image. Closes on Escape,
background click, or X button. Escape is scoped so it won't close the
editor underneath.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Instead of disabling the image button for unsaved notes, clicking it
now auto-saves the note first (with title "Untitled" if empty), then
opens the upload panel. This removes friction from the upload flow.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Use static test-image.png fixture instead of dynamic beforeAll creation
- Add thumbnail_path column to auto-create SQL in db/index.ts
- Hover on thumbnail before clicking remove button (group-hover:block CSS)
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Bump IDB version to 2, add pendingAttachments object store with noteId index
- Add CRUD helpers: addPendingAttachment, getPendingAttachments, removePendingAttachment
- ImageUpload stores blobs in IDB when offline, displays via blob URLs
- Show pending sync indicator (RefreshCw icon) on not-yet-uploaded images
- Add pushPendingAttachments to sync client, runs after note push
- Pending attachments auto-upload on reconnect via existing online event listener
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Import ImageUpload into NoteEditor with attachment state management
- Add $effect to fetch attachments for existing notes loaded from IDB
- Add upload/remove handlers and image toggle button in toolbar
- Show ImageUpload panel between content and formatting toolbar
- Add full-bleed thumbnail strip at top of NoteCard (up to 3 images)
- Use &thumb=1 URL for card previews with lazy loading
- Show +N badge when more than 3 attachments
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Add fetchAttachmentsForNotes() batch helper mirroring fetchTagsForNotes pattern
- Include attachments in all note API responses (list, single, sync)
- Fix ImageUpload.svelte URL bug (path-based → query param)
- Add client-side image optimization (resize, compress, WebP conversion)
- Add thumbnailPath column to attachments schema with migration
- Update saveAttachment/deleteAttachment for thumbnail file handling
- Update attachment API: accept thumbnail in POST, serve via &thumb=1 in GET
- Add Cache-Control immutable header for served attachments
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Apply the same max-md:opacity-100 pattern from NoteCard to Checklist
drag handles and remove buttons, making them visible on touch devices.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
On touch devices, hover states don't work, so the pin/archive/delete
buttons were invisible. Now they're always visible on screens below the
md breakpoint and only hover-toggled on desktop.
https://claude.ai/code/session_013DdAk1yj6r3VF6Ze4ycidp
- Increase gap between checkbox and text input (gap-1 → gap-2)
- Disable markdown toggle button in checklist mode
- Default to raw markdown mode when opening checklist notes as text
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Add X button to done/completed checklist items, matching the
existing remove button on active items.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Use dragHandleZone with grip icon instead of whole-card dragging,
so card interactions (checkboxes, pin, archive) still work
- Scope pinned/unpinned grids to separate dnd types to prevent
cross-zone drag bugs
- Add h-full to flip wrapper and NoteCard for equal card heights
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Completed items now consistently appear below unchecked items in both
the editor and the note card preview. Replaces the flaky two-state
hide/show toggle with a simple expand/collapse for the done section.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Add sort mode selector (Updated/Created/Custom) with localStorage persistence
- Sort notes client-side via derived stores based on selected mode
- Enable drag-to-reorder in Custom mode via svelte-dnd-action on NoteGrid
- Add POST /api/notes/reorder endpoint for bulk sortOrder updates
- E2E tests for sorting by updated/created and persistence across reload
Closes#12
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Add drag-to-reorder via svelte-dnd-action with grip handles
- Add "hide completed" toggle with collapsible done section
- Each checklist item gets a unique ID for stable drag operations
- E2E test for hide/show completed items
Closes#11
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
The allTags derived store now filters out archived and trashed notes
before collecting tags, so the sidebar tag filter only shows tags that
yield visible results.
Closes#9
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Sidebar filter and tag selection handlers now call onClose() on mobile
viewports (< 1024px), so the overlay dismisses after tapping a link.
Closes#10
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Move version badge from footer to bottom of sidebar (right-aligned)
- Update release script to sed-replace version in website/index.html
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Use the new favicon SVG in the header, login, setup, empty state,
and error pages. Keep the pretzel emoji in the footer tagline.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Create (auth) and (app) layout groups to isolate login/setup pages
from the main app chrome (header, sidebar, footer)
- Use window.location.href instead of goto() after login/setup to
ensure clean full-page load across layout groups
- Add reusable TagChip component, used in TagFilter and NoteCard
- Add fade-in/pop-in entrance animation to note editor overlay
- Add persistent clickable pin indicator on pinned cards (top-right
bookmark icon, replaces hover-only pin button for pinned notes)
- Improve "Add a crumb..." button with + icon and dashed border
- Update CLAUDE.md with retro parchment design system guidelines
- Add /.claude/ to .gitignore
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Replace hardcoded colors (gray-500, #b44, red-300/red-50/red-600,
green-600) with CSS variables for theme consistency. Add --destructive,
--error-*, --success-*, and --card-shadow variables to :root. Soften
default card borders from --border to --border-subtle and add 8-bit
style hard-offset shadows with hover effects. Apply accent-color for
themed checkboxes.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Add notesLoaded store flag set after IDB read completes. Gate the empty
state message behind it so it only shows once we know the store is empty.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Checklist toggle: SquareCheck (→ checklist) / Type (→ text).
Markdown toggle: FileCode (→ markdown) / FileText (→ rich text).
Icons now show what you'll switch to, not the current state.
Remove active color highlight since icon swap communicates state.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Change color picker popup from top-full to bottom-full so it appears
above the toolbar instead of overflowing below the editor.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Add a semi-transparent backdrop overlay (lg:hidden) behind the sidebar
on mobile. Clicking/tapping the backdrop closes the sidebar.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Remove scroll from toolbar, move undo/redo into More dropdown to fit
single line. All dropdowns now open upward (bottom-full) so they don't
overflow below the editor on small screens. Use Ellipsis icon for More.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Wrap editor content in a scrollable container with max-h-[60vh] so long
notes scroll within the editor instead of pushing it off-screen. Also make
the overlay itself scrollable with bottom padding for small viewports.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Reorganize toolbar: inline formatting (bold/italic/strike/underline) as
primary buttons, move blockquote/code/alignment/HR into a "More" dropdown.
Use overflow-x-auto instead of flex-wrap for single-line scrollable toolbar.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Markdown toggle: Eye (rich text) / Code (raw MD, highlighted).
Checklist toggle: List (text mode) / ListChecks (checklist, highlighted).
Icons now change on toggle so the active state is visually clear.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Constrain color picker popup width to viewport minus padding with a
max-width, preventing horizontal overflow on small screens.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Use --border-subtle for unselected swatches instead of transparent,
making each color option visually distinct.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
On mobile, show a search icon that expands into a full-width search bar
with a back arrow to close. Desktop keeps the always-visible search bar.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Swap every inline SVG across Header, SearchBar, NoteCard, NoteEditor,
Checklist, and ImageUpload for Lucide components. Use Palette for the
color picker icon instead of the paintbrush. Zero inline SVGs remain.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Replace green/blue/yellow/red with palette colors: --primary for synced,
--primary with opacity for syncing, --text-muted for offline, muted red
for error.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Load notes from IndexedDB first for instant display, then sync from
server in background. All mutations now persist to IDB when online,
keeping the cache always current. Eliminates empty state flash on load.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Remove lg:translate-x-0 override that forced sidebar open on desktop.
Main content and footer margin now conditional on sidebar state.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Checkboxes in the card preview are now interactive — clicking one toggles
the item without opening the editor. Uses stopPropagation to prevent
the card click handler from firing.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Import extractTags in notes store to populate tags on optimistic notes
- Re-extract tags on offline update when title or content changes
- Run extractTags + syncNoteTags in processSyncPush after transaction
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Extract toast store to standalone module so notes store can show toasts
- Add try/catch to all note mutations with optimistic updates + IDB queue on network error
- Wire up startSync/stopSync in layout to enable online/offline event listeners
- Reload notes from server after successful sync push to prevent data loss
- Connect SyncIndicator to real sync status with Lucide cloud icons
- Add 300ms minimum display time for status transitions
- Add e2e tests for offline create, edit, trash, and sync-on-reconnect
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Batch-fetch tags for notes in a single query instead of per-note loops
- Add composite indexes on notes, note_tags, and sync_log tables
- Wrap sync push in a transaction for atomicity
- Replace O(n) cleanExpiredSessions with single DELETE query
- Use SQL WHERE in getChangesSince instead of loading all notes
- Extract shared syncNoteTags utility to eliminate duplication
- Add root +error.svelte boundary matching app theme
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Replace the default dark/white theme with a warm parchment aesthetic
using CSS custom properties, retro pixel overlay, and JetBrains Mono
monospace font across all components. Bump version to 0.1.7.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Cast editor storage to Record<string, any> since tiptap-markdown
does not ship type declarations for its storage extension.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Replace all user-facing "note(s)" with "crumb(s)" — sidebar, search
placeholder, editor placeholders, empty states. Use Lucide icons
(StickyNote, Archive, Trash2, Tag) in sidebar for consistency.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Remove ThemeToggle component, theme store, dark: Tailwind variants,
and dark color values from NOTE_COLORS. Simplify color logic to use
a single bg property. Delete dark mode e2e tests.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Add a tick counter that increments on every TipTap transaction,
propagated from TiptapEditor through NoteEditor to FormattingToolbar.
This forces Svelte 5 to re-evaluate canUndo/canRedo state in the
template since plain object method calls aren't tracked reactively.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>