Additive token grammar (no renames, no replacements):
- --color-caution (dark #e8be4a, light #a08a1f) becomes the canonical
name for tuned-amber notice surfaces in the new wrapper grammar
- --color-warning is kept as a CSS var() alias of --color-caution so
every existing text-warning / bg-warning call site stays valid
- --color-info (dark #7a9ec0, light #3d6a8a) is the soft blue-grey
signal for the new LumotiaNotice info variant
- --color-accent-environment (dark #8fae9a, light #4a7058) is an
optional sage/moss support token for empty-state illustrations
and environment-neutral status dots. NOT a brand swap — amber/
copper --color-accent stays primary
Mirrored in src/design-system/colors_and_type.css (the buildless
preview pages bypass Tailwind so the duplication is intentional).
KI-05 resolved in the same commit, per the plan:
- src/lib/types/app.ts: drop `theme` from SettingsState
- src/lib/stores/page.svelte.ts: drop `theme: "Dark"` from defaults
- src/routes/+layout.svelte: drop the migration $effect, add a
one-shot migrateLegacyTheme() on mount that copies any historical
lumotia_settings.theme into preferences.theme and strips the
legacy field. Idempotent — subsequent loads short-circuit
- src/routes/{float,viewer,preview}/+layout@.svelte: drop the same
$effect; secondary windows inherit theme via PREFERENCES_CHANGED_EVENT
- src/lib/pages/SettingsPage.svelte: both SegmentedButton bindings
(quick-settings row at :1272, Appearance group at :2606) now use
Svelte 5 function bindings ({ get, set }) backed by prefs.theme
and updatePreferences. No SegmentedButton API change
Phase 3 per-page gate green: npm run check (0/0/4129 files),
npm test (13/13), npm run test:e2e (16/16). No regressions in
the Phase 1 smoke baseline.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Brand guidelines (docs/brand/magnotia-brand-guidelines.md §4) say "Never go
below 12px for any text" and "tertiary text must be ≥18px bold or ≥24px
regular". Audit found 246 sub-12px className sites and 166 cases of
text-text-tertiary paired with body sizes.
Bumped text-[9/10/11px] → text-[12px] across 26 .svelte files in src/lib
and src/routes. Promoted text-text-tertiary → text-text-secondary at body
sizes (12-14px) where context allowed; left placeholder pseudo-states,
ternary-conditional inactive states, and line-through "done" states alone
(8 residual pairings, all decorative).
Affects neurodivergent users on 1366×768 budget hardware most directly.
svelte-check: 0 errors, 0 warnings.
Side-stripe borders (border-left: 2px or 3px in an accent colour, with
the rest of the element having no border) are the textbook AI-coded-IDE
"selected-state" pattern. The brand vocabulary is colour-tint and
chevron, not stripe-and-fill.
Replaced eight sites:
- VirtualSegmentList active/match/default segment rows: bg-accent/10,
bg-warning/10, hover:bg-hover (drop the stripes; bg-warning bumped
/5 → /10 so it's visible without the stripe doing the work).
- viewer/+page.svelte: same pattern as VirtualSegmentList.
- TasksPage profile-list tabs: bg-accent/10 + font-medium for active,
hover:bg-hover for inactive. rounded-md added so the tint follows
the row outline.
- ToastViewport: replaced border-left + variant colour with full 1px
border + bg tint + border-color tint (color-mix() with the matching
semantic token at 35% / 10%). Also removed the orphan --moss /
--signal / --ember tokens — they were not defined in app.css and
fell back to hex literals.
- preview/+page.svelte: dropped the phase-coloured left stripe and
the borderColorClass derivation; the header already has a pulsing
dot / animated bars / spinner for each phase, so the stripe was
redundant.
Replace all instances of the legacy product names "Kon" and "Corbie" with
"Magnotia" across user-facing copy, code identifiers, package names, bundle
ids, file paths, and documentation. Preserves the unrelated "konsole" (KDE
terminal) reference and the parent CORBEL company name.
- Renames 10 Rust crates (kon-* → magnotia-*) and the tauri binary
- Updates package.json, tauri.conf.json (productName + identifier)
- Renames CSS classes (kon-rh-* → magnotia-rh-*) and animations
- Renames brand and roadmap docs
- Regenerates Cargo.lock and package-lock.json
Verified: svelte-check passes; pure-rust crates compile under new names.
Kon's ideology rule: raw Whisper output is the source of truth; LLM
cleanup is additive, never destructive. The preview overlay already
tracks both rawText and finalText across the listening → live →
cleanup → final phases — but until now the user had no one-click path
from final to raw if cleanup changed their meaning.
Frontend: a context-aware "Use raw" / "Copy raw" button appears in
the preview overlay's final phase, only when rawText and finalText
actually differ (Raw format mode or LLM-off leaves the button hidden).
Two behaviours depending on how the transcript reached the target:
- settings.autoPaste = true → invoke paste_text_replacing, which
sends the platform's undo keystroke to the focused app,
waits UNDO_PASTE_GAP_MS (60 ms) for the compositor / app to
process it, then pastes the raw transcript. The preview hides
itself beforehand so the keystroke doesn't race focus
(existing Wayland-hardening path).
- settings.autoPaste = false → nothing was pasted in the first
place, so just overwrite the clipboard with raw. User's own
paste yields raw.
Backend: new paste_text_replacing Tauri command plus a mirror of the
paste-backend matrix for undo (wtype -M ctrl z / xdotool key ctrl+z /
ydotool keycodes 29:1 44:1 44:0 29:0 / osascript cmd+z / SendKeys '^z').
Reuses the pick_linux_backend_order Wayland-vs-X11 preference.
Registered in the Tauri command handler.
Acceptance per the brief: "after paste, Ctrl+Z within 5 s replaces
LLM output with raw transcript" — satisfied via the 4 s auto-hide
window on the preview's final phase. The click extends auto-hide so
the user actually sees the confirmation.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Ported the best bits of OpenWhispr's TranscriptionPreviewOverlay into Kon's
window conventions. Off by default — toggle in Settings → Output → "Floating
preview when Kon is unfocused". Opens only when the main window isn't
focused at the start of a recording, so it never adds noise when the user
can already see the transcript in the main surface.
Phase state machine (src/routes/preview/+page.svelte):
- listening — pulsing dot, no text yet
- live — animated bars + streaming raw Whisper output
- cleanup — accent bars while the LLM cleanup pass runs
- final — checkmark + formatted text + 4s auto-hide
Data plumbing: raw segment text is captured before post_process_segments in
live.rs (new raw_text field on LiveResultMessage) and in transcription.rs
(new raw_text in the transcription-result payload). DictationPage forwards
raw_text to the overlay via Tauri global events — preview-listening on
start, preview-append per chunk, preview-cleanup before the LLM pass,
preview-final with the formatted text, preview-hide when a run produced no
transcript (empty recording / cancel).
Window is always_on_top, skip_taskbar, focused=false so it never steals
focus from whatever the user is dictating into. open_preview_window shows
an existing hidden preview or builds it fresh; close_preview_window hides
without destroying so the next open is instant.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>