[Mappe·Shared] EmptyState — dashed, serif heading, German ellipsis (§7) #860
Open
opened 2026-06-16 10:53:57 +02:00 by marcel
·
0 comments
No Branch/Tag Specified
main
feat/issue-856-page-header
feat/issue-859-meta-line
feat/issue-858-card
feat/issue-860-empty-state
feat/issue-861-status-dot
feat/issue-855-avatar
feat/issue-857-segmented-control
feat/issue-850-inline-event-clustering
devops/issue-848-fork-exit-timeout
feat/issue-827-zeitstrahl-grouping
feat/issue-837-relationship-edit-dates
feat/issue-818-renovate-nightly-audit
feat/issue-803-geschichten-document-filter-chip
worktree-feat+issue-738-nl-search-backend
feat/issue-286-notification-bell-form-actions
feat/issue-580-sentry-backend
fix/issue-593-management-port-zero
worktree-feat+issue-557-upload-artifact-v3-pin
worktree-chore+issue-556-drop-client-branches-coverage-gate
fix/issue-514-prerender-crawl-bakes-redirects
fix/issue-472-prerender-entries
feat/issue-395-readme
feat/issue-345-bulk-mark-reviewed
feat/issue-344-bell-tooltip
feat/issue-341-annotieren-contrast
feat/issue-225-bulk-metadata-edit
feat/issue-317-bulk-upload
feat/issue-271-dashboard-redesign
docs/issue-240-mission-control-spec
refactor/issues-193-200
feat/issue-162-korrespondenz-redesign
feature/68-new-document-file-first
feat/81-discussion-discoverability
feat/62-document-bottom-panel
feature/56-backfill-file-hashes
feat/38-document-edit-history
fix/svelte5-test-delegation-and-login-auth
No results found.
Labels
Clear labels
P0-critical
P1-high
P2-medium
P3-later
audit
bug
cleanup
collaboration
conversation
descoped
devops
documentation
epic
feature
file-upload
legibility
needs-discussion
needs-review
notification
person
phase-1: security
phase-2: container-images
phase-3: prod-compose
phase-4: spring-prod-profile
phase-5: backups
phase-6: deployment-docs
phase-7: monitoring
redesign-mappe
refactor
security
spec-required
test
ui
user
Blocks a core user journey, causes data loss, or is a security/accessibility barrier. Work on this before P1+.
Significant friction on a main user journey; workaround exists but is non-obvious. Next up after P0.
Noticeable improvement; doesn't block anything; schedule opportunistically.
Cosmetic or parking-lot work; fine to stay open indefinitely.
Read-only audit / assessment work; produces a report rather than changing code
Something isn't working
Removal of dead code, vague comments, naming violations, and scratch artifacts
We want to extend the family archive to have more collaboration tools
We will do that later
README, ARCHITECTURE, GLOSSARY, CONTRIBUTING, per-domain docs
Marker for epic-level issues that group multiple child issues
Codebase Legibility Refactor — preparing the codebase for human evaluation and bus-factor reduction
Has an open decision or design question that must be resolved before implementation can start.
Spec is drafted and awaiting the multi-persona /review-issue gate.
Security hygiene — must be done first
Production-ready multi-stage Docker images
Production compose overlay + Caddy reverse proxy
Spring Boot production configuration profile
Database and object storage backup strategy
.env.example, DEPLOYMENT.md, runbook
Prometheus, Loki, Grafana, Alertmanager
Mappe visual redesign — consistency alignment across the app (shared components + pages). See the design_handoff bundle.
Code restructuring without behaviour change
Feature whose contract is its issue body (EARS REQ-NNN); the spec must pass review before implementation.
UI/UX and accessibility issues
Milestone
No items
No Milestone
Mappe Visual Redesign
Projects
Clear projects
No project
No Assignees
Notifications
Due Date
No due date set.
Dependencies
No dependencies set.
Reference: marcel/familienarchiv#860
Reference in New Issue
Block a user
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
Delete Branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Shared component · Story 4. Part of #853.
Context
ChronikEmptyStateand others are icon + sans-bold heading with a solid border — off-spec. Several pages roll their own.DESIGN_RULES §7wants a dashed, quiet, Sie-form empty state.Scope
Create
$lib/shared/primitives/EmptyState.svelte— dashed1px var(--c-line)border, centered, serif heading + Montserrat subline ending in the German ellipsis…. Props:heading,subline, optionalactionslot.Migration targets — all five are in scope for this issue:
$lib/activity/ChronikEmptyState.svelteaktivitaeten); the shared primitive carries neither. DeleteChronikEmptyStateafter migration; update or remove its two test files (*.spec.ts+*.test.ts).Migration scope — decided:
TranscribeCoachEmptyState($lib/shared/help/) is out of scope — it is a help-coach variant with its own layout intent, not a §7-quiet empty state; migrating it would leave a second competing empty-state API. It stays untouched.PersonsEmptyState(route-level) maps to the persons/review target above.ChronikEmptyState fate — decided: delete the component after migration (all three callers move to
EmptyStatedirectly); do not leave a dead thin wrapper. Update or remove both test files.EmptyStatestays leaf-level: the shared primitive must not import back up into any domain package ($lib/activity,$lib/person, etc.). Variant/string/icon logic stays in each caller.API
Security note (implementer):
heading,subline, and theactionslot must render through Svelte's default{…}escaping — never{@html}. Future callers that interpolate person names, tag labels, or document titles rely on this default for XSS prevention (CWE-79).Visual spec (DESIGN_RULES §7 / AUTHORING_KIT §10)
1px dashed var(--c-line)rounded-sm(neverrounded-lg)py-12 px-6(48 px / 24 px)font-serif, 20 px, default inkfont-sans(Montserrat), 13 px,text-ink-3…max-w-proseso it does not run edge-to-edge at 320 pxHeading semantics — decided: render heading as
<p class="font-serif …">(matching existingChronikEmptyState); wrap the whole block inrole="status"so screen readers announce the empty state. This avoids disrupting the page's heading hierarchy.actionslot: any link/button inside must carry a visiblefocus-visiblering (inherit from project focus styles). The slot itself imposes no markup — callers wrap in<a>or<button>as appropriate.i18n
All visible strings (
heading,subline) must be Paraglide message keys. Callers pass the result ofm.key(), not raw string literals.For each of the four newly migrated ad-hoc pages (documents list, themen, stammbaum, persons/review) add empty-state keys in
messages/de.json(authored),en.json, andes.json(stubs acceptable for en/es on first ship). Key naming convention:<page>_empty_heading/<page>_empty_subline.The Chronik keys already exist inside
ChronikEmptyState— keep them, move them to the caller (aktivitaeten).Tests
Create
$lib/shared/primitives/EmptyState.svelte.spec.ts(vitest-browser, copy pattern fromChronikEmptyState.svelte.spec.ts). Assert:rounded-smpresent,rounded-lgabsentfont-serifclass…actionslot renders when provided{@html}(static grep check — confirm no{@html}inEmptyState.svelte)Acceptance
1px dashed var(--c-line)border,rounded-sm, serif heading (20 px), Montserrat subline (13 pxtext-ink-3) ending…, no iconpy-12 px-6; subline capped atmax-w-prose— does not run edge-to-edge at 320 pxChronikEmptyStatedeleted; its test files updated or removedEmptyState.svelte.spec.tspasses (dashed border,font-serif,rounded-sm,…, action slot, no{@html})actionslot: focus-visible ring visible; keyboard-reachablefocus-visiblepreservedOut of Scope
TranscribeCoachEmptyState— out of scope (help-coach variant, not a §7 empty state)Depends on: none. Refs:
DESIGN_RULES §7,_AUTHORING_KIT.md §10,$lib/shared/primitives/BackButton.svelte(pattern).marcel referenced this issue2026-06-16 13:49:51 +02:00
marcel referenced this issue2026-06-16 13:59:16 +02:00
marcel referenced this issue2026-06-16 14:00:02 +02:00
marcel referenced this issue2026-06-16 14:00:06 +02:00
marcel referenced this issue2026-06-16 14:00:14 +02:00
marcel referenced this issue2026-06-16 14:00:26 +02:00