Uses HTML form attribute to associate the submit button with the
person-edit-form from outside the form tag. Page now reads:
Personendaten -> Namensverlauf -> Danger zone -> Save bar.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Verifies alias rendering, empty state, firstName fallback,
and type label display. 5 browser-based Svelte tests.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Screen readers now announce which alias is being deleted, e.g.
"Entfernen de Gruyter" instead of just "Entfernen".
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Removes the {#if} guard so the card with empty state message is
always visible for feature discoverability.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
NameHistoryEditCard with add form (type dropdown + name fields),
delete with confirmation modal, and IDOR-safe client-side fetch
calls. Placed between Personendaten and DangerZone cards.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Shows historical name aliases in the left column with type labels
and firstName fallback. Fetches aliases in parallel with other data.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
PDF viewer collapses to 70px on mobile in read mode, expandable to
50vh. Toggle button with chevron. Paragraph tap auto-expands strip.
Mode toggle abbreviates to "Bearb." on small screens.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Paragraph click flashes the PDF annotation outline (1.5s fade).
Annotation click highlights the paragraph with a background flash.
Both directions scroll the target into view.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Adds TranscriptionPanelHeader and TranscriptionReadView to the
document detail page. Default mode is 'read' when blocks exist,
'edit' otherwise. Annotations dimmed in read mode.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Aligns the top/bottom padding of the Briefwechsel results view with
the document search page wrapper (both py-8).
Refs: #179
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Swap button: stack right/left arrows vertically at h-3.5 for a
compact look. Timeline: replace → ← text with Long-Arrow icons on
each letter entry and the distribution bar summary.
Refs: #179
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Remove border-dashed and bg-canvas conditional styles so the
receiver input matches the sender input styling. The placeholder
"Alle Korrespondenten" already communicates the optional state.
Refs: #179
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Only navigate (applyFilters) when a person is actually selected, not
when the sender input is cleared. Combined with showHero checking
data.filters.senderId, the user stays in the search bar view after
clearing — no jump back to the hero.
Refs: #179
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Remove custom placeholder props so DateInput falls back to its default
format hint (TT.MM.JJJJ / DD.MM.YYYY / DD.MM.AAAA) instead of
repeating the label text above.
Refs: #179
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Replace native <input type="date"> on the document search page with
the custom DateInput component (German dd.mm.yyyy format with auto-dot
insertion). Align both pages' date input styling: add rounded-md,
border, bg-surface, px-3, text-ink, placeholder color, and focus ring
to match all other inputs in the card.
Refs: #179
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Replace ↑↓ text with Long-Arrow-Up/Down-MD.svg on the document search
SortDropdown and the Briefwechsel sort button. Rotate the swap button
SVG 90° so arrows point left/right matching the horizontal person
field layout.
Refs: #179
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Replace tiny ↑↓ text with Long-Arrow-Up/Down-MD.svg icons from the
brand icon set for better visibility and consistency.
Refs: #179
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Chevrons indicate collapsible elements, not sort direction. Match
the document search SortDropdown pattern using ↑/↓ text arrows.
Refs: #179
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Move sort button and filter toggle to the person row, matching the
document search page pattern (sort + filter + count inline). Date
range inputs are now a collapsible section behind the filter toggle,
using slide transition and the same grid layout as the document
search advanced filters. Fix date input padding (add px-3).
Refs: #179
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Wrap person bar + filter controls in a card matching the document
search page (rounded-sm border p-6 shadow-sm). Switch PersonTypeahead
to default mode with matching label/input overrides. Bump date inputs
and sort button to text-sm py-2.5. Filter row uses border-t separator
like the document search advanced section.
Refs: #179
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Restores early return when id is empty, preventing a wasteful
navigation to /briefwechsel with no senderId param.
Refs: #179
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Adds conv_hero_divider to de/en/es messages and uses it in the
CorrespondenzHero divider. Fixes i18n blocker from review.
Refs: #179
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Add px-3 to person bar, filter controls, and hint bar so inputs
don't sit flush against the container edge.
Refs: #179
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Move strips inside the max-w-7xl container so person bar, filter
controls, and hint bar are no longer full-bleed. Remove duplicate
side padding from strip components — the parent container handles it.
Refs: #179
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Align person bar, filter controls, and hint bar side padding to
px-4 sm:px-6 lg:px-8, matching the standard layout of all other
overview pages. Override person bar inputs from compact h-9 to h-12
for better touch targets in the results state.
Refs: #179
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Hero state (no senderId): centred CorrespondenzHero with discovery
headline, cross-link, large typeahead, recent persons. No person bar
or filter controls shown. Results state (senderId set): full-width
strips then content area with max-w-7xl responsive padding matching
other overview pages. Removes focus delegation hack.
Refs: #179
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
New centred hero component for the Briefwechsel page: headline
"Wessen Briefe möchten Sie lesen?", cross-link to document search,
h-14 PersonTypeahead, and recent persons chips. Adds `large` prop
to PersonTypeahead and `conv_hero_crosslink` message key.
Refs: #179
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Update all internal links (AppNav, CoCorrespondentsList, goto) to the
new URL. No redirect needed — no production URLs exist yet.
Refs: #179
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- isDashboard was ignoring tagQ so typing in tag filter showed dashboard
- addTag now calls onTextInput('') to clear tagQ when a chip is selected
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Comment text:
- Body and quote bumped from text-sm (14px) to text-base (16px)
to visually match the font-sans author name at text-sm
Annotation reload on delete:
- Add annotationReloadKey prop through DocumentViewer → PdfViewer
- Increment key after block delete in +page.svelte
- PdfViewer reloads annotations when key changes
- Annotation rectangle disappears immediately, not just after refresh
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Pass activeAnnotationId to TranscriptionEditView. An $effect watches
it and sets activeBlockId to the block matching the annotation,
activating its turquoise focus border.
2 new tests (RED/GREEN):
- activates block matching activeAnnotationId (turquoise border)
- no block activated when activeAnnotationId is null
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Mobile layout (< 768px):
- Split view stacks vertically: PDF top (min 40vh), blocks below
- Blocks panel gets border-top instead of border-left
- PDF remains interactive for drawing in stacked mode
Scroll-sync (block → PDF):
- Clicking a block sets activeAnnotationId
- PdfViewer effect watches activeAnnotationId, navigates to the
annotation's page if different from current, then scrolls the
annotation element into view (double-rAF for async render timing)
- Works across pages: block on page 3 navigates PDF to page 3
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Own comments:
- Click the text to open inline edit (textarea replaces text)
- Enter saves, Escape cancels
- Small trash icon always visible in bottom-right corner
- Hover on text shows cursor-text + subtle bg highlight
Other people's comments: read-only, no edit/delete affordances.
Re-add currentUserId prop chain for ownership check.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Add blockNumbers prop through AnnotationLayer → PdfViewer → DocumentViewer.
Each turquoise annotation rectangle now shows a numbered badge (top-left,
matching the block card number in the right panel).
Block numbers are derived from sorted transcriptionBlocks, mapped by
annotationId, creating a visual link between PDF regions and block cards.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
When clicking a turquoise annotation on the PDF:
- If not in transcribe mode, enters it and loads blocks
- Waits for DOM render, then scrolls to the corresponding block card
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
The yellow annotation+comment system is now redundant. Transcription
blocks handle the same use case (mark region → discuss) but better,
because they also produce a transcription.
Removed:
- annotateMode state and all wiring through page/topbar/viewer/pdfviewer
- Annotate/Stop annotate buttons from DocumentTopBar
- AnnotateHintStrip import and rendering
- AnnotationSidePanel from document detail page
- canAnnotate prop from DocumentTopBar
- Color picker from PdfViewer
- Comment count badges and loadCommentCounts from PdfViewer
- Delete button from AnnotationLayer (blocks own annotation lifecycle)
- dimColor prop from AnnotationLayer
Simplified:
- AnnotationLayer: only canDraw + color + onDraw + onAnnotationClick
- PdfViewer: only draws in transcribeMode with turquoise
- Clicking annotation in transcribe mode scrolls to corresponding block
- canComment derived from canWrite (no longer needs canAnnotate)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
TranscriptionBlock.svelte:
- "Kommentieren" button opens expandable comment thread per block
- Text selection in textarea captured as quoted text (> "...") prefix
- Quote hint "Text markieren für Zitat" shown when block is active/focused
- Comment thread uses existing CommentThread with blockId prop
CommentThread.svelte:
- Add blockId prop for block-level comments URL routing
- Add quotedText prop — pre-fills comment input with markdown blockquote
- commentsBase now supports 3 URL patterns: document, annotation, block
TranscriptionEditView.svelte:
- Pass canComment + currentUserId through to block components
3 new frontend tests:
- Kommentieren button present
- Quote hint shown when active
- Quote hint hidden when inactive
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>