Per-screen audit + 6 design principles + per-screen mockups + commit-by-commit implementation plan + 7 open questions. Boldest moves: collapse the 5-button-per-row admin list into a hover-revealed ⋯ menu with clickable status pill; fold the standalone Share section into the detail-page header as an inline link strip; drop the JSON-questions textarea from /new behind a <details> disclosure so the common path reads as four inputs and a button. No code touched — design only. Awaiting m's go before coder shift.
39 KiB
fdbck — minimalist UI redesign
Status: design proposal, not yet approved.
Branch: mai/cronus/fdbck-minimalist-ui.
Author: cronus, 2026-05-06.
m's brief: "While our app is quite simple, the layout of it seems overly complex and crowded. I want clearer separation (by negative space) between the different elements and smarter control buttons for a smooth UX."
The app is already small (1 stylesheet, 2 reusable components, 5 routes). The
problem isn't features — it's that the existing screens fight minimalism with
always-visible action rows, redundant copy, inline style="..." patches,
and tight vertical rhythm. This doc proposes per-screen edits that hold
features constant but trade visible buttons for whitespace and progressive
disclosure.
1. Audit
1.1 / (landing)
┌────────────────────────────────────────┐
│ fdbck │ ← 1.75rem h1
│ Private feedback forms and live chat… │
│ │
│ This page is only reachable through… │
│ [ Admin sign-in ] │ ← ghost button
└────────────────────────────────────────┘
- Already close to minimalist — 20 lines of markup, two paragraphs, one ghost button. Mostly fine.
- The wordmark
fdbckis the brand moment but renders at the same size as every other page h1 (1.75rem). It should feel like a logo on the landing page, not a generic heading. - Two paragraphs ("Private feedback forms…" / "This page is only reachable…") partly say the same thing. The second one is a near-tautology — the user is already on the page, so "you got here through a private link" is implicit.
- Vertical rhythm is tight:
1.5rembetween subtitle and section, then the button sits right under one short sentence. - Tiny: a marketing-blank landing for a tool whose CTA is "sign in" feels hollow. Either lean further into emptiness (just the wordmark + sign-in) or add one line of confidence-building text. We'll lean into emptiness.
1.2 /login
┌────────────────────────────────────────┐
│ Sign in │
│ Admin access only. │
│ │
│ Email [______________] │
│ Password [______________] │
│ [ Sign in → ] │
└────────────────────────────────────────┘
- "Sign in" + "Admin access only" is mild redundancy — the page is the form.
- Error banner sits between the password field and the submit button, which pushes the button down on error and feels like a layout glitch. Better position: above the form (page-level error) or beneath the button as an inline string.
- Two fields, one button, no dark patterns — already minimalist. Just needs more vertical breathing room and a quieter subtitle (or none).
1.3 /admin/feedback (list)
┌──────────────────────────────────────────────────────────────────┐
│ Feedback forms [ + New form ] │
│ Collect feedback through forms or live chat. Share a private… │
│ │
│ Your forms (4) │
│ ┌──────────────────────────────────────────────────────────┐ │
│ │ Title (link) [Form+chat] [open] │ │
│ │ 12 responses · 7 messages · created 2026-05-01 │ │
│ │ /f/long-slug-shown-raw │ │
│ │ [Edit] [Copy link] [Open] [Close] [Delete] ← 5 buttons │ │
│ └──────────────────────────────────────────────────────────┘ │
│ … │
└──────────────────────────────────────────────────────────────────┘
- The biggest offender. Five always-visible buttons per row (Edit, Copy link, Open, Close/Reopen, Delete) wrap onto multiple lines on narrow widths. Even on desktop they read as a noisy strip.
- Each row has border + shadow + bg + padding + status pill + mode pill + raw slug + meta line + button strip. Nine visual objects per row.
- Inline
style="…"everywhere (+page.svelte:108-156). Should be classes infeedback.cssso dark-mode and rhythm tokens stay consistent. - The raw
/f/<slug>line is shown but has no purpose for the admin — they use Copy link or Open. It's just text noise. - Header repeats the page title in the body (
<h1>Feedback forms</h1>) and then the section heading (<h2>Your forms (N)</h2>). The H2 mostly duplicates the H1, just with a count.
1.4 /admin/feedback/new
┌──────────────────────────────────────────────────────────────────┐
│ [← All forms] │
│ Create a new form │
│ Set up a feedback form, a live chat session, or both. You'll… │
│ │
│ Title [______________________________] │
│ Description [______________________________] │
│ ☑ Enable live chat │
│ Questions (JSON, optional) [ + Insert sample ] │
│ ┌──────────────────────────────────────────────────────────┐ │
│ │ { … 14-row JSON textarea, monospace … } │ │
│ └──────────────────────────────────────────────────────────┘ │
│ Leave empty for chat-only feedback. You can edit questions… │
│ │
│ [ ✓ Create form ] │
└──────────────────────────────────────────────────────────────────┘
- The JSON textarea is a power-user escape hatch dropped into the same surface as a beginner-friendly title/description form. It dominates the page (14 rows, monospace font), even though the visual builder on the detail page is the recommended path.
- "Insert sample" sits to the right of the label, inside the field's header — visually clever but also noise.
- The chat checkbox is a single inline item floating in its own block. It
looks afterthought-y. (It also reuses
.fb-option-rowstyling, which is meant for question options.) - Helper text under the JSON is good, but it's the third descriptive
paragraph on the page (
<p>Set up a feedback form…</p>,placeholder="…",<div class="fb-question__help">).
1.5 /admin/feedback/[id] (detail)
┌────────────────────────────────────────────────────────────────────────┐
│ [← All forms] │
│ My session feedback │
│ Some optional description text shown if present. │
│ [open] /f/long-slug [Copy link] [Preview] [Close] [CSV] [JSON] [Delete] ← 8 chips/buttons in one row
│ │
│ ┌── Share ─────────────────────────────────────────────────────────┐ │
│ │ Memorable short link — resolves to /f/long-slug. │ │
│ │ https://msbls.de/vote [ Copy ] [ Open ↗ ] │ │
│ │ ▸ Replace with a different short link │ │
│ └──────────────────────────────────────────────────────────────────┘ │
│ │
│ [ Chat (3) ] [ Results (12) ] [ Responses (12) ] [ Edit ] │
│ …active tab body… │
└────────────────────────────────────────────────────────────────────────┘
- Header is the densest surface in the app. Eight clickable controls in a flex-wrap row: status pill, raw slug, Copy link, Preview, Close/Reopen, CSV, JSON, Delete. On a 1024px viewport this wraps onto two lines.
- "Copy link / Preview" in the header and a separate Share section and the slug shown raw — three different ways to access the same URL.
- CSV / JSON download buttons sit between Close and Delete — they're not
in the same gravitational tier (export is benign, Delete is nuclear), but
they look identical (both
fb-btn--ghost fb-btn--sm). - The Share section (recently added) was bolted onto the layout rather than designed into it. It sits between header and tabs, breaking the "header → tab → tab body" mental model.
- The Edit tab's form has its own internal mini-toolbar (Visual / JSON toggle), which is correct but visually clashes with the parent tab strip one screen up.
- Polling
setInterval(refresh, 5000)is right; no UX change needed there.
1.6 /f/[slug] (participant)
┌──────────────────────────────────────────┐
│ Title │
│ Optional description │
│ [⚠ closed banner if closed] │
│ │
│ Dein Name (optional): [Anonym______] ← inline label + full-width input collide
│ │
│ ┌── Live-Feedback ──────────────────┐ │
│ │ scroll list of posts │ │
│ │ [textarea] │ │
│ │ [ Senden ] │ │
│ └───────────────────────────────────┘ │
│ │
│ ┌── Fragebogen ─────────────────────┐ │
│ │ q1 [...] │ │
│ │ q2 [...] │ │
│ │ [ Absenden ] │ │
│ └───────────────────────────────────┘ │
│ │
│ fdbck.msbls.de │
└──────────────────────────────────────────┘
- Already simple. Needs more breathing room between Chat and Form sections — they read as two equally-weighted siblings, but in practice one of them is what the user came for.
- The
Dein Name (optional):label sits inline left of a full-width input (fb-name-row), while every other label in the participant form is on its own line above the input. The inline-label pattern is the only one of its kind on this page — kill it. - Footer
fdbck.msbls.deis fine as a quiet trust signal. - Closed banner uses
--color-warningpalette which reads as alert; for a closed-form neutral state, a quieter visual is better. - Locale mix: admin pages use English (
Sign in,Edit,Delete), but the participant page is German (Senden,Absenden,Fragebogen). Probably intentional (admins are us, participants are German-speaking) — flagging it so we don't accidentally homogenise during the redesign. Not in scope to change.
2. Principles
The following six rules apply to every screen. They are the lens for §3.
- Whitespace over dividers. Replace borders/shadows/dividers with
generous vertical space. The rule of thumb: if a card is bordered on a
page that's already on a coloured
--gradient-bg, the card competes with the page background — drop the border, keep the radius+padding, lean on negative space. Spacing scale:0.5rem(within a row),1.25rem(between form fields),2.5rem(between sections),4rem(above page footer). - One primary action per page. Per screen, exactly one button uses the
solid
.fb-btn(filled green). Everything else is--secondaryor--ghostor icon-only. Today most screens have 2–8 solid-or-near-solid actions competing for attention. - Smarter controls — collapse rows. Anywhere we currently render 3+
buttons in a strip, the redesign keeps one primary inline (or zero —
"the row itself is the button") and tucks the rest behind a
⋯menu (<details>summary or a small popover). Status flips become pill toggles instead of buttons. Destructive actions live only inside the⋯menu, never as a top-level visible button. - Visual hierarchy via type weight, not borders. Inter is loaded — use
weight
700for page-h1,600for section-h2,500for form labels,400for body. Tracking-0.02emon headings (already in the CSS for h1) extended to h2. This lets us drop a lot of decorative chrome. - Optimistic UX. Delete a row → row disappears immediately, with an
undo toast for ~6s. Toggle status → pill switches instantly, network
call in background. Errors revert the optimistic change and show a small
inline message. We already have Svelte 5
$stateeverywhere, so this is plumbing, not architecture. - No inline
style="..."for layout. Every inline style currently in the .svelte files moves to a class infeedback.css. Two reasons: dark mode lives in@media (prefers-color-scheme: dark)rules and inline styles bypass it; and inline styles defeat the spacing-scale rule (1).
Optional principle 7 (suggest, but waiting for m): list, not cards. A naked padded list with hover-revealed actions beats card-grids for a small N (≈ <50 forms). Keeps the page feeling like content, not a dashboard.
3. Per-screen redesigns
3.1 / (landing)
┌────────────────────────────────────────┐
│ │
│ │
│ fdbck │ ← 2.5rem, weight 700, tracked -0.03em
│ feedback by link │ ← muted, 1rem, weight 400
│ │
│ │
│ [ Admin sign-in → ] │ ← single ghost button, sized fb-btn--lg
│ │
└────────────────────────────────────────┘
↑ massive vertical centering
- Centre the page vertically (max-width 480px,
min-height: 100vh,display: grid; place-items: center;). - Drop the "This page is only reachable through a private link…" sentence — if a participant lands here they're not lost; the wordmark + sign-in is enough.
- Wordmark grows to
2.5rem, weight700, tracking-0.03em. Subtitle shrinks to1remmuted. - Single CTA,
fb-btn--lg fb-btn--ghostwith the existingarrow-righticon (already used on login submit).
3.2 /login
┌────────────────────────────────────────┐
│ │
│ Sign in │ ← drop "Admin access only"
│ │
│ Email │
│ [______________________] │
│ │
│ Password │
│ [______________________] │
│ │
│ ⓘ inline error appears here, muted │
│ │
│ [ Sign in → ] │
└────────────────────────────────────────┘
- Drop the "Admin access only." subtitle (the URL says it).
- Vertical-centre the form (same grid trick as landing).
- Inline error: render as a small muted line below the submit button
rather than an
fb-banner--errorblock above it. Less alarming, no layout shift. - Keep the existing primary
fb-btnwith arrow-right icon.
3.3 /admin/feedback (list) — the biggest change
┌────────────────────────────────────────────────────────────────────┐
│ Forms [ + New ] │ ← terse h1, primary CTA
│ ───────── │
│ │
│ My session feedback ●open ⋯ │ ← row hover-reveals ⋯
│ Form + chat · 12 responses · 7 messages │
│ │
│ ┌── 2.5rem of pure whitespace ──┐ │
│ │
│ Sprint 4 retro ○closed ⋯ │
│ Form · 0 responses │
│ │
│ ┌── 2.5rem of pure whitespace ──┐ │
│ │
│ Quick chat ●open ⋯ │
│ Chat · 21 messages │
└────────────────────────────────────────────────────────────────────┘
Row anatomy:
- The whole row title is a link → goes to detail (today's "Edit" button becomes implicit).
- Subtitle: mode + counts only. Drop the raw
/f/<slug>line, thecreated DATE("created" word), and the mode pill — fold mode into the subtitle text ("Form + chat · 12 responses"). - Right side: a status dot+label (●open / ○closed) that is the toggle — click flips it (optimistic). One control replaces today's pill-+-Close-button pair.
- Trailing
⋯menu (<details>summary or popover) opens:- Copy link
- Open ↗
- Edit (explicit jump, even though row is also a link)
- ──────
- Delete (red)
- Drop
border + shadow + bgon the row container. Rely on row-padding2.5remgap between rows. Hover state: faint--color-bg-tertiarybackground, no border.
- Mobile (
< 640px): keep the⋯always visible; on desktop reveal on hover for a calmer default state.
Header:
- Drop the descriptive paragraph ("Collect feedback through forms…"). The user already knows what fdbck is.
- H1 reads "Forms" (terser than "Feedback forms", since we're already at
/admin/feedback). - Drop the H2 "Your forms (N)" — the count moves into the H1 area as a small muted number, or drops entirely (the rows themselves are the count).
- Keep one solid
+ Newbutton on the right.
Empty state: generous whitespace + "No forms yet — create your first
one." + the same + New button as primary CTA.
Optimistic delete: after confirming, row disappears immediately; toast at the bottom: "Form deleted. [Undo]" for 6s.
3.4 /admin/feedback/new
┌────────────────────────────────────────────────────────────────────┐
│ ← Forms │ ← terse back-link, no chip
│ │
│ New form │
│ │
│ Title │
│ [______________________________________________] │
│ │
│ Description (optional) │
│ [______________________________________________] │
│ │
│ ☐ Enable live chat │
│ │
│ ▸ Add questions now (advanced) │ ← collapsed by default
│ │
│ [ ✓ Create form ] │
└────────────────────────────────────────────────────────────────────┘
- Title + Description + chat checkbox are the common path. They occupy the full page width without any JSON noise.
- The JSON textarea moves behind a
<details>disclosure labelled "Add questions now (advanced)". Inside the disclosure we keep:- the
Insert samplebutton (now sits inside the disclosure, where it belongs) - the textarea
- the helper paragraph
- the
- Rationale: the visual builder on the detail page is the canonical path for adding questions; offering JSON paste at creation is power-user speed-up, not the default. By collapsing it, the new-form page reads like 4 inputs and a button.
- Replace the back-link button with a plain
← Formstext-link in muted weight 500, no chip styling. - Drop the page subtitle ("Set up a feedback form…"). The label "New form"
- the form below carry the meaning.
- Move the chat toggle from a faux-
fb-option-rowcheckbox to a proper.fb-togglewith a clean label-on-the-left layout (new class — small CSS addition).
3.5 /admin/feedback/[id] (detail) — the second-biggest change
┌────────────────────────────────────────────────────────────────────────┐
│ ← Forms │
│ │
│ My session feedback ●open ⋯ │ ← title + clickable status pill + ⋯
│ Some optional description shown if present. │
│ │
│ msbls.de/vote [ Copy ] [ Open ↗ ] [ Replace ] │ ← share-link strip, INLINE in header
│ │
│ ───────────────────────────────────────────────────────────────── │ ← whitespace, no border
│ │
│ [ Chat (3) ] [ Results (12) ] [ Responses (12) ] [ Edit ] │
│ │
│ …active tab body, with 2.5rem top-padding… │
└────────────────────────────────────────────────────────────────────────┘
Header collapse — 8 controls → 3 visible:
| today's control | redesign |
|---|---|
| status pill (display only) | status pill, clickable to toggle (optimistic) |
/f/slug raw text |
dropped (the share strip below has the link) |
| Copy link button | inside share strip |
| Preview button | inside share strip ("Open ↗") |
| Close / Reopen button | merged into status pill |
| CSV button | inside ⋯ menu |
| JSON button | inside ⋯ menu |
| Delete button | inside ⋯ menu (red, last) |
⋯ menu contents (in order, with separators):
- Copy link (when the share strip is hidden on mobile)
- Export CSV
- Export JSON
- ──────
- Delete (red)
Share section disappears as a separate block. The short URL is shown inline in the header as one strip:
- If
inst.short_urlexists: show it + Copy + Open ↗ + Replace (Replace opens a small inline form under the strip — same<details>pattern as today, but compact). - If it doesn't: show "No short link · [ Create one ]" → click reveals the slug input + create button.
This kills today's awkward "section between header and tabs" structure and folds share into the place where the user expects "where do I share this".
Tabs unchanged in count and labels. They stay: Chat / Results /
Responses / Edit. Selection style stays the segmented-pill (fb-tabs /
fb-tab--active). Whitespace between tab strip and tab body grows from
1.25rem to 2.5rem so the tab body breathes.
Edit tab inline polish:
- Drop the duplicate
<h2>Edit · v3</h2>heading inside the tab — the active tab pill already says "Edit". Save the version pill for a quiet spot next to the Save button. - The
Visual/JSONtoggle becomes a small segmented control in the same shape as the tab pills (consistency). - Save button is the page's primary action while this tab is active. No other solid button on the page in that state.
Banner about responses-already-received ({submissions.length} responses already received…) becomes a single muted line above the form,
not a banner box.
3.6 /f/[slug] (participant)
┌──────────────────────────────────────────┐
│ │
│ Title │ ← h1, room above
│ Optional description │
│ │
│ ⓘ closed (only if closed, neutral) │ ← muted not yellow when closed
│ │
│ ───────────────────────────────────── │ ← 3rem gap
│ │
│ Live-Feedback │
│ ┌── chat list ──────────────────────┐ │
│ │ … │ │
│ └───────────────────────────────────┘ │
│ [ textarea (full width) ] │
│ [Senden]│
│ │
│ ───────────────────────────────────── │ ← 3rem gap (same as above)
│ │
│ Fragebogen │
│ q1 │
│ q2 │
│ │
│ [ Absenden ] │
│ │
│ │
│ fdbck.msbls.de │
└──────────────────────────────────────────┘
-
Drop the inline-label name row. Replace with a normal labelled field matching the rest of the form:
Dein Name (optional) [Anonym__________________________]Or move it below the chat/form sections as a footer-style "Du schreibst als: Anonym ✎" with click-to-edit. (Suggested — see open question #5.) For v1 keep it at top but normalise its layout.
-
Increase section gap from
1.75remto3rembetween the chat block and the form block, so they read as two distinct activities. -
Closed banner: switch from amber
--color-warningpalette to a quiet neutral muted style (1px top border + small italic line) — closed is a state, not an alert. -
Drop the
border-color: var(--color-primary)on.fb-chat__post--minein favour of a subtle left-border-only accent (3px,--color-primary). The current full pill-with-coloured-border treatment is loud. -
Footer
fdbck.msbls.de→ wrap as a permalink to/, very muted.
4. Implementation plan
The redesign is only CSS + small .svelte markup edits. No new
components, no new dependencies, no schema changes. Suggested commit order
(each commit is independently mergeable and testable):
Commit 1 — CSS foundation: spacing scale + typography rhythm
src/lib/styles/feedback.css:- Add a spacing scale as CSS custom properties (
--space-1through--space-7, or named--gap-row / --gap-field / --gap-section / --gap-foot). - Bump
.fb-sectionmargin-bottom from1.75rem→--gap-section(≈2.5rem). .fb-header h1weight stays 700;.fb-section h2weight bumps from600→600(no change) but tracking-0.01emalready there.- Add
.fb-page-narrow(max-width480px) and.fb-page-center(vertical grid centre) modifiers for landing/login. - Add
.fb-togglefor label-left+switch-right boolean fields. - Add
.fb-rowfor spacious list rows (no border, no shadow, hover bg) plus.fb-row__title,.fb-row__meta,.fb-row__actions. - Add
.fb-status-pill(clickable open/closed pill). - Add
.fb-menu(the⋯dropdown — implemented as<details>+<summary>+ a positioned panel). - Add
.fb-share-strip(the inline header share row in 3.5).
- Add a spacing scale as CSS custom properties (
- No structural Svelte changes in this commit — verify in the browser that the existing pages still render fine since added classes are unused additions.
Commit 2 — landing + login (cheap wins)
src/routes/+page.svelte: drop the second paragraph; wrap shell infb-page-center fb-page-narrow; bump wordmark size.src/routes/login/+page.svelte: drop the "Admin access only." subtitle; wrap infb-page-center fb-page-narrow; move error fromfb-banner--errorblock to a small inline muted line.- Verify both routes in the browser at 375px / 1024px / 1440px.
Commit 3 — /admin/feedback/new
src/routes/admin/feedback/new/+page.svelte:- Drop the page subtitle.
- Replace the chat-checkbox block with
.fb-toggle. - Wrap "Questions (JSON, optional)" + sample button + textarea +
helper inside a
<details>with summary "Add questions now (advanced)". - Remove inline
style="..."on the back-link block; replace with a.fb-back-linkclass (text-only, muted).
Commit 4 — /admin/feedback (list) — biggest change, isolated commit
src/routes/admin/feedback/+page.svelte:- Drop the H1 paragraph.
- Drop the H2 "Your forms (N)".
- Replace each row (today's bordered card with 5 buttons) with the
.fb-rowpattern from commit 1: title is a link to detail, subtitle merges mode + counts, right side is.fb-status-pill(toggle) +.fb-menutrigger. - Move all inline
style="..."to classes (no new feature). - Add the
⋯menu component inline using<details>— no JS framework needed; click-outside-to-close via a smalladdEventListenerinonMount.
- Add optimistic delete with undo toast (small
<aside>element fixed to bottom-centre,setTimeout6s, callsDELETEonly after timeout expires). - Verify the live deployed list still looks right after deploy.
Commit 5 — /admin/feedback/[id] (detail) — second-biggest change
src/routes/admin/feedback/[id]/+page.svelte:- Header collapse per 3.5: status becomes
.fb-status-pill, drop raw/f/slugtext, drop inline Copy/Preview/Close/Reopen/CSV/ JSON/Delete buttons. - Add
.fb-share-stripdirectly under the title/description in the header (replaces the standalone Share section below). - Add
.fb-menuwith Copy link / Export CSV / Export JSON / ────── / Delete. - Delete the standalone
<section data-fb-share>block — its contents are now in the header strip + a "Replace" inline form. - Inside Edit tab: drop the
<h2>Edit · v3</h2>, move version pill next to Save; turn Visual/JSON into a segmented pill control matching.fb-tabs. - Move
submissions.lengthwarning from.fb-bannerto muted line. - Replace inline
style="..."with classes throughout.
- Header collapse per 3.5: status becomes
Commit 6 — /f/[slug] participant polish
src/routes/f/[slug]/+page.svelte:- Replace the inline-label name row with a stacked-label field.
- Increase gap between Chat and Form sections (use
--gap-section). - Switch "(closed)" banner to neutral muted style (a new
.fb-status-line--mutedmodifier on.fb-banneror a dedicated.fb-closed-lineclass). - Adjust
.fb-chat__post--minestyling: drop full coloured border, addborder-left: 3px solid var(--color-primary)only. - Wrap footer text in an
<a href="/">witharia-label="fdbck home".
Commit 7 — sweep: optimistic toggles, hover-reveal actions
- Add the optimistic-update + undo-toast pattern to
setStatuson the detail page (status pill instant flip, server call after). - Apply the same to per-row
toggleStatuson the list page. - Verify dark-mode pass: walk all five routes in dark mode (browser
emulator) since multiple inline
style="..."strings were converted to classes that inherit from:root/prefers-color-scheme.
5. Open questions for m
These are decisions m should weigh in on before implementation. Each has my recommendation, but they're all reversible.
- Cards vs spacious list for
/admin/feedback. I'm proposing a spacious list (no border, lots of whitespace, hover-revealed⋯). The brief mentions cards as an option. My recommendation: list. Cards add visual chrome (border + shadow) which is the opposite of "negative space". Cards earn their keep when each item has rich content (image, multi-line preview); fdbck rows have title + 2 meta lines. - Optimistic delete with 6s undo, or keep the
confirm()modal? Today both list and detail useconfirm("…cannot be undone"). The undo toast is smoother but trades safety for fluency. My recommendation: undo toast — the row reappears identically if undone, the destructive call only fires after timeout, no data is actually at risk during the 6s window. Keepconfirm()only on detail-page Delete (deleting from the detail page is a more deliberate action and merits an extra step). - Share-link strip in the detail header — does it belong there? I'm folding the standalone Share section into the header (3.5). Alternative: keep Share as a section but move it below the tabs, so the header stays minimal. My recommendation: in the header. Sharing the link is the second-most-common action after viewing results; it belongs near the title.
- Drop the Edit tab body's inner H2? Today every tab body has an
<h2>echoing the tab name (<h2>Live chat</h2>,<h2>Results</h2>, etc.). I want to drop these — the tab strip already labels the active section. But this is a stylistic call. My recommendation: drop the inner H2s, add2remof top padding to the tab body so the active tab pill alone titles the section. - Participant name field — top, bottom-as-footer, or bottom-as- "edit"? Today it's at the top with an inline label. I'm proposing stacking it the same as other fields. A bolder alternative: move it to a footer-style "Du schreibst als: Anonym ✎" below all sections. My recommendation for v1: stacked label, top. Bolder move waits for v2.
- Locale homogenisation. Admin pages are English, participant page is German. Out of scope for this redesign — flagging only so we don't accidentally translate one of them while doing the markup pass. Confirm this stays as-is.
- Accent on
--color-primary. Same green stays per brief. But today some screens havebox-shadow: 0 0 0 3px rgb(22 163 74 / 0.15)on focus and others have0.25opacity — minor inconsistency. Worth normalising during commit 1? My recommendation: yes, normalise to one focus-ring rule (0.2 opacity, 3px).
6. Anti-scope (explicitly NOT in this redesign)
- Palette: no new colours, no new accent.
- Stack: still SvelteKit + vanilla CSS + Inter. No new deps.
- Routes: unchanged URL structure.
- Data model: unchanged.
- Locale: no homogenisation (see Q6).
- Polling intervals (5s admin, 3s chat): unchanged.
- Auth flow / share-link backend: unchanged (only the display of the share link in the detail header changes).