You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Context. Scriptty is a Tauri desktop app (macOS / Windows / Linux). This audit is desktop-only — recommendations that the source skill carried over from iOS/Android (44pt touch targets, swipe gestures, system gesture conflicts, tap delay, mobile haptics, safe-area insets, RN-specific guidance) have been filtered out. What's left is desktop-applicable: keyboard parity, screen-reader naming, focus management, reduced-motion, hover-discoverability, and empty / error states. Click target minimum used here is 32×32 visual (mouse precision); a 44px hit area via padding is fine but not required.
What
Comprehensive UI/UX audit of every Scriptty surface (Welcome, Editor, TitleBar, StatusBar, Scene Navigator, Scene Cards, Story Mode, Episode Cards, Outline Peek, all modals, both toasts, FormatBubble, Find/Replace bar, Command Palette). Aesthetic is locked — this issue is purely interaction quality, accessibility, and onboarding.
The editorial-vocabulary chrome is well-applied across surfaces; what's missing is a layer of accessibility scaffolding (reduced-motion, aria-labelledby on modals/toasts, drag keyboard alternatives, aria-pressed/current parity) and a few onboarding gaps (empty states on Cards / Episodes / Stats, recent-file path validation).
Findings below are grouped by severity, with file references. Use the checkboxes to track progress; sub-issues can split a row off if it's heavier than expected.
⛔ Must fix
Either blocks accessibility (keyboard / screen-reader users can't complete a flow) or actively misleads new writers.
Global prefers-reduced-motion support is missing. Every keyframe / transition (modal-in, backdrop-fade, dp-in, bubble-in, import-slide-in, update-slide-in, all panel slide / chevron / hover transitions across TitleBar / StatusBar / FormatBubble / OutlinePeek / LeftPanel / SceneNavigator / SeriesEpisodeList / DatePicker / Editor) declares its own duration without honouring the media query. Add a single rule to src/routes/+layout.svelte (@media (prefers-reduced-motion: reduce) { *, *::before, *::after { animation-duration: 0.01ms !important; transition-duration: 0.01ms !important; animation-iteration-count: 1 !important; } }) plus reset --motion-fast/base/slow tokens to 0ms so all timed work snaps. Verified missing in src/routes/+layout.svelte, MetadataModal.svelte, UpdateToast.svelte:177, ImportSummaryToast.svelte, FormatBubble.svelte:233, OutlinePeek.svelte:184, LeftPanel.svelte:34, SceneNavigator.svelte:895, SeriesEpisodeList.svelte:528/598/624/791, DatePicker.svelte:592–619, Editor.svelte:799–804, TitleBar.svelte:789–797.
Scene reorder has no keyboard path.SceneNavigator.svelte:614 (six-dot drag handle) is mouse-only. Keyboard users can't reorder scenes at all. Add Alt+ArrowUp / Alt+ArrowDown (or a "Move up / Move down" affordance that appears on item focus) and announce the move via aria-live. Same fix needed for SeriesEpisodeList.svelte:278.
Episode list lacks keyboard navigation.SeriesEpisodeList.svelte doesn't implement the ArrowUp/Down/Home/End roving-tabindex pattern that SceneNavigator.svelte:108–126 already has. Lift the helper or duplicate the keymap so series writers get parity with film writers.
ImportSummaryToast + UpdateToast + HelpModal + AboutModal + MetadataModal (header) are missing aria-labelledby.aria-modal="true" is set but the title isn't linked, so VoiceOver / NVDA reads "dialog" with no name. Add aria-labelledby="<title-id>" on the modal-backdrop element + matching id on the .mh-title. Same one-line fix applies to both toasts: link the role-status container to the title span. Refs: HelpModal.svelte:116, AboutModal.svelte:48, ImportSummaryToast.svelte:93, UpdateToast.svelte:25.
FindReplaceBar is unlabeled for screen readers.FindReplaceBar.svelte:151–157 — Find/Replace inputs use only placeholder= (no aria-label); the SVG prev/next buttons (174–197) have title but no aria-label. Add aria-label="Find in document" / "Replace with" to inputs and aria-label="Previous match (Shift+Enter)" / "Next match (Enter)" to the icon buttons.
SceneCardsView empty state is empty.SceneCardsView.svelte:972–1255 — a fresh screenplay shows a bare grid with no guidance. Add a centered empty card explaining how scene cards relate to scene headings ("Scene cards are auto-created from scene headings in the editor — switch to Writing and add INT. ROOM — DAY to populate this grid").
EpisodeCardsView rename / delete buttons disappear at rest.EpisodeCardsView.svelte:711–722 — .ep-actions { opacity: 0.55 } at rest, full only on hover. Keyboard-only users see no affordance and the resting state misleads even mouse users. Pin to opacity: 1 (or 0.85) at rest; brighten further on hover.
Close buttons fall below the 32×32 desktop minimum across modals. Quick sweep needed:
MetadataModal.svelte:502–517 — 30×30
SettingsModal.svelte:438–459 — 26×26
ImportWizardModal.svelte:84–86 — 24×24
NewProjectDialog.svelte:202–206 — 28×28
PasteScriptDialog.svelte:218–239 — 28×28
FindReplaceBar.svelte:304–325.bar-btn — 26×26
Bump to 32×32 (visual) with 44×44 hit area via padding so click latency stops mattering.
⚠️ Should fix
Real UX gaps; the writer can complete the flow but the surface trips them.
StatusBar save-state dot conveys meaning by colour alone.StatusBar.svelte:155, 330–340 — amber pip vs green dot. CVD users can't distinguish "saved" from "unsaved". Add a tiny inline glyph (✓ / ●) or a text label, or rely on the existing dirty-pip in TitleBar plus an aria-label on the StatusBar dot.
Dirty pip and incomplete-meta pip have no accessible name.TitleBar.svelte:219 (dirty), TitleBar.svelte:397 (meta-incomplete). Wrap both with <span aria-label="…" title="…"> so the screen reader and the hover tooltip both speak the meaning.
LeftPanel doesn't move focus inward when it opens.LeftPanel.svelte — keyboard users press Cmd+\, the panel slides open, focus stays on the toggle button. Move focus to the active scene/episode item on open so subsequent ArrowUp/Down works without a Tab.
StoryModeView tabs aren't a real ARIA tablist.StoryModeView.svelte:189–204 — Left/Right arrow keys don't cycle. Add the standard tablist keymap (role="tablist" is on the parent; just wire the arrow handler).
SeriesEpisodeList non-active episode subtree is muted but still tab-focusable.SeriesEpisodeList.svelte:388 — .non-active { opacity: 0.78 } reads as "this is somewhere else", but Tab still lands inside. Either suppress focus there with inert (Svelte 5: {@attach inert} or tabindex="-1" on every descendant), or add a clear "Switch to this episode first" message when focused.
Drag-handle drag state is invisible to AT.SceneNavigator.svelte:557–559 and SeriesEpisodeList drag — no aria-grabbed / aria-dropeffect / aria-live announcement. When the keyboard reorder lands (must-fix above), make sure the live region narrates "Scene 5 moved to position 3".
Welcome recent-file list breaks silently when the path is gone.WelcomeScreen.svelte:156–170 — clicking a deleted/moved .screenplay should remove it from the list and surface a toast ("File moved or deleted — removed from recents"). Today the open-flow probably surfaces a backend error string.
StoryModeView ↔ Writing view loses cursor position. Cross-view switch (+page.svelte view-switcher) doesn't restore the editor's selection or scroll offset on return. Stash editorStore.view.state.selection per-view and restore on re-entry.
StatisticsModal sort preference resets on every open.StatisticsModal.svelte:204–229 — if intentional, surface "Sort preference resets when reopened" in the column-header tooltip; otherwise persist to component-local state (or localStorage).
EpisodeCardsView status pill (Outline/Draft/Revision/Final) doesn't read as interactive. Lines 370–381 — clicking cycles, but cursor stays default and there's no hover treatment. Add cursor: pointer + a subtle box-shadow or background change on hover; tooltip "Click to advance: Outline → Draft → Revision → Final".
SettingsModal custom dropdown lacks the listbox-pattern wiring.SettingsModal.svelte:114–166 — role="listbox" is on the wrapper but the trigger button doesn't carry aria-controls / aria-expanded / aria-haspopup="listbox", and individual options aren't role="option" with aria-selected. Either flesh out the pattern or fall back to a native <select> with custom styling.
SceneCardsView "Group by location" silently disables drag-reorder. Lines 1022–1034 — when grouping is on, the gutter handle is disabled; the title attribute changes but visual state doesn't. Add .card-gutter[disabled] { opacity: 0.4; cursor: not-allowed; }.
ExportModal async buttons need a verified aria-busy state. Lines 70–72, 1120–1232 — confirm Plain text / Fountain / PDF buttons all show the spinner and set aria-busy="true"andaria-disabled="true" during in-flight; cancel-during-export should be impossible.
StatusBar lacks a landmark role.StatusBar.svelte:171 — add role="contentinfo" so AT users can jump there with the landmark shortcut.
+page.svelte editor area lacks role="main" / <main> semantic. Already wrapped in <main> (line 1004); just confirm there's no nested role="main" and that the OutlinePeek + StatusBar live outside it.
CTA hierarchy on Welcome muddles "New Film" vs "New Series".WelcomeScreen.svelte:95–104 — both look equally weighted to a first-time visitor. Add a one-line explainer below each ("One screenplay" / "Multiple episodes in one file").
✨ Nice to have
Polish and discoverability — improves perceived quality but no one is blocked.
Cmd+1 / Cmd+2 / Cmd+3 direct-select for Writing / Cards / Story.+page.svelte:610–702 already has the View menu listeners; add the keyboard shortcuts so power users skip the toggle commands.
StoryModeView word-count is only in StatusBar. Add a muted in-view badge under the section title ("№ 02 · Synopsis · 427 words") so the writer doesn't need to glance away.
StatisticsModal empty-doc state.StatisticsModal.svelte:42–72 — when stats.sceneCount === 0, the Overview tab is a wall of zeros. Show "Write a scene to populate statistics" with a "Switch to Writing" button.
Editor first-launch hint.Editor.svelte:491 — when the editor mounts on a brand-new doc with one empty scene_heading, render a placeholder cue ("Start with a scene heading like INT. ROOM — DAY"). Disappears on first keystroke.
WelcomeScreen recent-files keyboard nav.WelcomeScreen.svelte:156–170 — Arrow Up/Down to move focus, Enter to open. Currently Tab-only.
EpisodeCardsView inline rename has no commit feedback.EpisodeCardsView.svelte:265–282 — show a brief check-mark or accent flash when blur commits the rename so the writer knows it landed.
EpisodeCardsView scene-peek "+ N more scenes" is a label, not a button.EpisodeCardsView.svelte:346–365 — make it a button (or change copy to "Open episode to see all scenes") so the drill-down path is explicit.
OutlinePeek segment timeline uses role="list" with non-list children.OutlinePeek.svelte:106 — switch to role="presentation" (or migrate to role="tablist" since segments behave like tabs).
OutlinePeek may scale poorly past ~200 scenes.OutlinePeek.svelte:106 — virtualise segments outside the viewport; today the entire timeline is in the DOM.
TitleBar view tabs lack aria-current.TitleBar.svelte view tabs — add aria-current="page" (or "true") on the active tab so AT users know which view is up.
Episode popover active episode lacks aria-current.TitleBar.svelte:188–216 — .ep-pop-row.active should carry aria-current="true".
CommandPalette listbox is unnamed.CommandPalette.svelte:158 — aria-label="Filtered commands" on the role=listbox container.
Standardise motion durations on the design tokens.+layout.svelte:243–246 defines --motion-fast/base/slow but most components hardcode 120ms/160ms/200ms literals. Sweep + replace; this also makes the reduced-motion override (must-fix Add build and release badge #1) a single token override.
SceneCardsView "Compact view" toggle has low discoverability.SceneCardsView.svelte:940–960 — first-mount tooltip ("Toggle between roomy cards and a one-line-per-scene overview") would help.
PasteScriptDialog placeholder text wraps awkwardly under ~720px.PasteScriptDialog.svelte:104–119 — placeholder is multi-line; below the modal's max-width: 92vw it can collide. Consider truncation or a help-text block above the textarea.
Story-mode placeholder voice is inconsistent.StoryModeView.svelte:45–64 — mix of "The core premise. One to three lines." vs "Full narrative prose". Standardise to the editorial-masthead voice used elsewhere.
NewProjectDialog title input is bottom-border-only.NewProjectDialog.svelte:256–282 — on the cream paper field in light mode the border is hard to spot; add a subtle focus background. Also missing aria-required="true".
ImportSummaryToast middle-dot count separator reads as "dot" to screen readers.ImportSummaryToast.svelte:178–189 — {counts.join(' · ')} — wrap each count in its own <span> so the SR hears them as a list, or override the aria-label to a comma-joined version.
SceneCardsView DatePicker is hidden inside a disclosure.SceneCardsView.svelte:1197–1202 — add a hint in the production-summary text so writers know clicking expands a calendar picker.
Out of scope (this issue)
Aesthetic / vocabulary changes — locked per CLAUDE.md.
New features (autosave indicator beyond dirty-pip, undo for destructive actions, draft history) — separate issues.
RTL support — DatePicker.svelte:121 flagged the future-proofing concern but RTL isn't a v1 goal.
Acceptance
This issue is done when:
Every must-fix box is ticked (or explicitly closed with a sub-issue and rationale).
A reduced-motion smoke test passes (set OS-level reduce-motion, open every modal + drawer + view-switch + import flow → no animations should run).
A keyboard-only smoke test passes the New Film → write a scene → open Cards → reorder a scene → open Stats → close → quit flow without the mouse.
VoiceOver smoke test announces every modal title on open and every dirty/incomplete pip on focus.
What
Comprehensive UI/UX audit of every Scriptty surface (Welcome, Editor, TitleBar, StatusBar, Scene Navigator, Scene Cards, Story Mode, Episode Cards, Outline Peek, all modals, both toasts, FormatBubble, Find/Replace bar, Command Palette). Aesthetic is locked — this issue is purely interaction quality, accessibility, and onboarding.
The editorial-vocabulary chrome is well-applied across surfaces; what's missing is a layer of accessibility scaffolding (reduced-motion, aria-labelledby on modals/toasts, drag keyboard alternatives, aria-pressed/current parity) and a few onboarding gaps (empty states on Cards / Episodes / Stats, recent-file path validation).
Findings below are grouped by severity, with file references. Use the checkboxes to track progress; sub-issues can split a row off if it's heavier than expected.
⛔ Must fix
prefers-reduced-motionsupport is missing. Every keyframe / transition (modal-in, backdrop-fade, dp-in, bubble-in, import-slide-in, update-slide-in, all panel slide / chevron / hover transitions across TitleBar / StatusBar / FormatBubble / OutlinePeek / LeftPanel / SceneNavigator / SeriesEpisodeList / DatePicker / Editor) declares its own duration without honouring the media query. Add a single rule tosrc/routes/+layout.svelte(@media (prefers-reduced-motion: reduce) { *, *::before, *::after { animation-duration: 0.01ms !important; transition-duration: 0.01ms !important; animation-iteration-count: 1 !important; } }) plus reset--motion-fast/base/slowtokens to0msso all timed work snaps. Verified missing insrc/routes/+layout.svelte,MetadataModal.svelte,UpdateToast.svelte:177,ImportSummaryToast.svelte,FormatBubble.svelte:233,OutlinePeek.svelte:184,LeftPanel.svelte:34,SceneNavigator.svelte:895,SeriesEpisodeList.svelte:528/598/624/791,DatePicker.svelte:592–619,Editor.svelte:799–804,TitleBar.svelte:789–797.SceneNavigator.svelte:614(six-dot drag handle) is mouse-only. Keyboard users can't reorder scenes at all. AddAlt+ArrowUp/Alt+ArrowDown(or a "Move up / Move down" affordance that appears on item focus) and announce the move viaaria-live. Same fix needed forSeriesEpisodeList.svelte:278.SeriesEpisodeList.sveltedoesn't implement theArrowUp/Down/Home/Endroving-tabindex pattern thatSceneNavigator.svelte:108–126already has. Lift the helper or duplicate the keymap so series writers get parity with film writers.ImportSummaryToast+UpdateToast+HelpModal+AboutModal+MetadataModal(header) are missingaria-labelledby.aria-modal="true"is set but the title isn't linked, so VoiceOver / NVDA reads "dialog" with no name. Addaria-labelledby="<title-id>"on the modal-backdrop element + matchingidon the.mh-title. Same one-line fix applies to both toasts: link the role-status container to the title span. Refs:HelpModal.svelte:116,AboutModal.svelte:48,ImportSummaryToast.svelte:93,UpdateToast.svelte:25.FindReplaceBaris unlabeled for screen readers.FindReplaceBar.svelte:151–157— Find/Replace inputs use onlyplaceholder=(noaria-label); the SVG prev/next buttons (174–197) havetitlebut noaria-label. Addaria-label="Find in document"/"Replace with"to inputs andaria-label="Previous match (Shift+Enter)"/"Next match (Enter)"to the icon buttons.SceneCardsViewempty state is empty.SceneCardsView.svelte:972–1255— a fresh screenplay shows a bare grid with no guidance. Add a centered empty card explaining how scene cards relate to scene headings ("Scene cards are auto-created from scene headings in the editor — switch to Writing and addINT. ROOM — DAYto populate this grid").EpisodeCardsViewrename / delete buttons disappear at rest.EpisodeCardsView.svelte:711–722—.ep-actions { opacity: 0.55 }at rest, full only on hover. Keyboard-only users see no affordance and the resting state misleads even mouse users. Pin toopacity: 1(or 0.85) at rest; brighten further on hover.MetadataModal.svelte:502–517— 30×30SettingsModal.svelte:438–459— 26×26ImportWizardModal.svelte:84–86— 24×24NewProjectDialog.svelte:202–206— 28×28PasteScriptDialog.svelte:218–239— 28×28FindReplaceBar.svelte:304–325.bar-btn— 26×26Bump to 32×32 (visual) with 44×44 hit area via
paddingso click latency stops mattering.StatusBarsave-state dot conveys meaning by colour alone.StatusBar.svelte:155, 330–340— amber pip vs green dot. CVD users can't distinguish "saved" from "unsaved". Add a tiny inline glyph (✓ / ●) or a text label, or rely on the existing dirty-pip in TitleBar plus anaria-labelon the StatusBar dot.TitleBar.svelte:219(dirty),TitleBar.svelte:397(meta-incomplete). Wrap both with<span aria-label="…" title="…">so the screen reader and the hover tooltip both speak the meaning.LeftPaneldoesn't move focus inward when it opens.LeftPanel.svelte— keyboard users pressCmd+\, the panel slides open, focus stays on the toggle button. Move focus to the active scene/episode item on open so subsequent ArrowUp/Down works without a Tab.StoryModeViewtabs aren't a real ARIA tablist.StoryModeView.svelte:189–204— Left/Right arrow keys don't cycle. Add the standard tablist keymap (role="tablist"is on the parent; just wire the arrow handler).SeriesEpisodeListnon-active episode subtree is muted but still tab-focusable.SeriesEpisodeList.svelte:388—.non-active { opacity: 0.78 }reads as "this is somewhere else", but Tab still lands inside. Either suppress focus there withinert(Svelte 5:{@attach inert}ortabindex="-1"on every descendant), or add a clear "Switch to this episode first" message when focused.SceneNavigator.svelte:557–559andSeriesEpisodeListdrag — noaria-grabbed/aria-dropeffect/aria-liveannouncement. When the keyboard reorder lands (must-fix above), make sure the live region narrates "Scene 5 moved to position 3".WelcomeScreen.svelte:156–170— clicking a deleted/moved.screenplayshould remove it from the list and surface a toast ("File moved or deleted — removed from recents"). Today the open-flow probably surfaces a backend error string.StoryModeView↔ Writing view loses cursor position. Cross-view switch (+page.svelteview-switcher) doesn't restore the editor's selection or scroll offset on return. StasheditorStore.view.state.selectionper-view and restore on re-entry.StatisticsModalsort preference resets on every open.StatisticsModal.svelte:204–229— if intentional, surface "Sort preference resets when reopened" in the column-header tooltip; otherwise persist to component-local state (orlocalStorage).EpisodeCardsViewstatus pill (Outline/Draft/Revision/Final) doesn't read as interactive. Lines370–381— clicking cycles, but cursor stays default and there's no hover treatment. Addcursor: pointer+ a subtlebox-shadoworbackgroundchange on hover; tooltip "Click to advance: Outline → Draft → Revision → Final".SettingsModalcustom dropdown lacks the listbox-pattern wiring.SettingsModal.svelte:114–166—role="listbox"is on the wrapper but the trigger button doesn't carryaria-controls/aria-expanded/aria-haspopup="listbox", and individual options aren'trole="option"witharia-selected. Either flesh out the pattern or fall back to a native<select>with custom styling.SceneCardsView"Group by location" silently disables drag-reorder. Lines1022–1034— when grouping is on, the gutter handle is disabled; the title attribute changes but visual state doesn't. Add.card-gutter[disabled] { opacity: 0.4; cursor: not-allowed; }.ExportModalasync buttons need a verifiedaria-busystate. Lines70–72, 1120–1232— confirm Plain text / Fountain / PDF buttons all show the spinner and setaria-busy="true"andaria-disabled="true"during in-flight; cancel-during-export should be impossible.StatusBarlacks a landmark role.StatusBar.svelte:171— addrole="contentinfo"so AT users can jump there with the landmark shortcut.+page.svelteeditor area lacksrole="main"/<main>semantic. Already wrapped in<main>(line 1004); just confirm there's no nestedrole="main"and that the OutlinePeek + StatusBar live outside it.WelcomeScreen.svelte:95–104— both look equally weighted to a first-time visitor. Add a one-line explainer below each ("One screenplay" / "Multiple episodes in one file").✨ Nice to have
Cmd+1/Cmd+2/Cmd+3direct-select for Writing / Cards / Story.+page.svelte:610–702already has the View menu listeners; add the keyboard shortcuts so power users skip the toggle commands.StoryModeViewword-count is only in StatusBar. Add a muted in-view badge under the section title ("№ 02 · Synopsis · 427 words") so the writer doesn't need to glance away.StatisticsModalempty-doc state.StatisticsModal.svelte:42–72— whenstats.sceneCount === 0, the Overview tab is a wall of zeros. Show "Write a scene to populate statistics" with a "Switch to Writing" button.Editorfirst-launch hint.Editor.svelte:491— when the editor mounts on a brand-new doc with one emptyscene_heading, render a placeholder cue ("Start with a scene heading like INT. ROOM — DAY"). Disappears on first keystroke.WelcomeScreenrecent-files keyboard nav.WelcomeScreen.svelte:156–170— Arrow Up/Down to move focus, Enter to open. Currently Tab-only.EpisodeCardsViewinline rename has no commit feedback.EpisodeCardsView.svelte:265–282— show a brief check-mark or accent flash when blur commits the rename so the writer knows it landed.EpisodeCardsViewscene-peek "+ N more scenes" is a label, not a button.EpisodeCardsView.svelte:346–365— make it a button (or change copy to "Open episode to see all scenes") so the drill-down path is explicit.OutlinePeeksegment timeline usesrole="list"with non-list children.OutlinePeek.svelte:106— switch torole="presentation"(or migrate torole="tablist"since segments behave like tabs).OutlinePeekmay scale poorly past ~200 scenes.OutlinePeek.svelte:106— virtualise segments outside the viewport; today the entire timeline is in the DOM.aria-current.TitleBar.svelteview tabs — addaria-current="page"(or"true") on the active tab so AT users know which view is up.aria-current.TitleBar.svelte:188–216—.ep-pop-row.activeshould carryaria-current="true".CommandPalettelistbox is unnamed.CommandPalette.svelte:158—aria-label="Filtered commands"on the role=listbox container.+layout.svelte:243–246defines--motion-fast/base/slowbut most components hardcode120ms/160ms/200msliterals. Sweep + replace; this also makes the reduced-motion override (must-fix Add build and release badge #1) a single token override.SceneCardsView"Compact view" toggle has low discoverability.SceneCardsView.svelte:940–960— first-mount tooltip ("Toggle between roomy cards and a one-line-per-scene overview") would help.PasteScriptDialogplaceholder text wraps awkwardly under ~720px.PasteScriptDialog.svelte:104–119— placeholder is multi-line; below the modal'smax-width: 92vwit can collide. Consider truncation or a help-text block above the textarea.StoryModeView.svelte:45–64— mix of "The core premise. One to three lines." vs "Full narrative prose". Standardise to the editorial-masthead voice used elsewhere.NewProjectDialogtitle input is bottom-border-only.NewProjectDialog.svelte:256–282— on the cream paper field in light mode the border is hard to spot; add a subtle focus background. Also missingaria-required="true".ImportSummaryToastmiddle-dot count separator reads as "dot" to screen readers.ImportSummaryToast.svelte:178–189—{counts.join(' · ')}— wrap each count in its own<span>so the SR hears them as a list, or override thearia-labelto a comma-joined version.SceneCardsViewDatePicker is hidden inside a disclosure.SceneCardsView.svelte:1197–1202— add a hint in the production-summary text so writers know clicking expands a calendar picker.Out of scope (this issue)
DatePicker.svelte:121flagged the future-proofing concern but RTL isn't a v1 goal.Acceptance
This issue is done when:
Total: 9 must-fix · 14 should-fix · 18 nice-to-have across 23 surfaces.