Phase 9 of the rebrand cascade. Sweep covers everything the Phase 8
frontend pass deliberately skipped: docs/, root markdown, scripts,
Cargo.toml descriptions, code comments that survived earlier
word-boundary sed, plus a handful of identifiers caught on the final
verify pass.
transcription-app changes:
- README.md, HANDOVER.md, KNOWN-ISSUES.md, run.sh — magnotia/Magnotia
-> lumotia/Lumotia.
- docs/ — sweep across all subdirs except docs/handovers/ (preserved
as immutable audit trail). Includes architecture-map references
to magnotia_core::*, magnotia_storage::*, etc. now pointing at
lumotia_*; dev-setup.md tracing output examples (lumotia_startup
target); brief/ + superpowers/ + issues/ + whisper-ecosystem/ +
audit/.
- Cargo.toml descriptions on 9 crates (core, audio, cloud-providers,
hotkey, llm, mcp, plus referenced others).
- crates/core/src/{error,hardware,recommendation,paths}.rs +
crates/audio/src/wav.rs + crates/llm/src/model_manager.rs +
crates/cloud-providers/src/keystore.rs + crates/mcp/src/lib.rs —
doc comments and a model-manager user-agent string.
- Caught on final pass: BroadcastChannel("magnotia_task_sync") -> ...
("lumotia_task_sync"); magnotia_locale i18n localStorage key
renamed + migration shim added; CSS keyframe names
magnotiaPulse / magnotiaBar / magnotiaFade renamed in the design-
system kit; magnotia_viewer_item / magnotia_viewer_mode handoff
keys renamed in HistoryPage + viewer/+page.svelte; src/assets/
wordmark.svg text.
- src-tauri/src/lib.rs comment cleanup ("magnotia era" was sed'd
to "lumotia era" earlier — restored).
Preserved (intentional):
- crates/core/src/paths.rs — keeps "magnotia" / "Magnotia" / ".magnotia"
legacy detection strings in legacy_and_target_paths() so the
migration shim can still find user data from the magnotia era.
- src/lib/stores/{page,focusTimer}.svelte.ts + src/lib/i18n/index.ts
— migration call sites reference the legacy magnotia keys
deliberately.
- docs/handovers/ — historical audit trail.
cargo build --workspace passes. npm run check: 0 errors / 0 warnings
(3958 files). cargo test --workspace: 339 pass / 0 fail.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
6.9 KiB
name, type, slice, last_verified
| name | type | slice | last_verified |
|---|---|---|---|
| App shell and styling | architecture-map-page | 01-frontend | 2026/05/09 |
App shell and styling
Where you are: Architecture map → Frontend → App shell and styling
Plain English summary. Where the visual chrome and CSS plumbing live. app.html is the SvelteKit document. app.css carries the Tailwind v4 import, the @theme token block, the brand @font-face declarations, the sensory zones, and the accessibility CSS variables. There is no separate tailwind.config.{js,ts}; Tailwind v4 is configured entirely in app.css. Fonts ship from src/fonts/ (bundled by Vite) and static/fonts/ (served as-is).
At a glance
- Path:
src/app.html,src/app.css,src/app.d.ts,src/fonts/,src/assets/,static/. - LOC: 13 (
app.html) + 583 (app.css) + 8 (app.d.ts). - Frameworks: Tailwind v4 via
@tailwindcss/vite. No PostCSS config. No standalone Tailwind config file. - Adapter:
@sveltejs/adapter-staticwithindex.htmlfallback (SPA,svelte.config.js).
What's in here
src/app.html (13 LOC)
Standard SvelteKit document. Sets lang="en", charset, viewport, favicon, title (Lumotia), and applies data-sveltekit-preload-data="hover" on <body>. The body content is wrapped in <div style="display: contents"> so the SvelteKit-injected children render inline.
src/app.d.ts (8 LOC)
Ambient declaration extending Window with __TAURI_INTERNALS__ and isTauri so utils/runtime.ts typechecks.
src/app.css (583 LOC)
Layered:
@import "tailwindcss"(Tailwind v4 entry).@font-facefor Lexend, Atkinson Hyperlegible Next, OpenDyslexic, JetBrains Mono, Instrument Serif Italic. URLs use root-absolute paths (/fonts/...) served fromstatic/fonts/by Vite.@themetoken block. Sets the design tokens that Tailwind v4 picks up as utility classes:- Colour tokens:
--color-bg,--color-bg-raised,--color-text,--color-text-secondary,--color-text-tertiary,--color-accent,--color-warning,--color-success,--color-border,--color-border-subtle,--color-hover,--color-nav-active, plus a sensory-zone palette family. - Typography tokens:
--font-display,--font-body,--font-mono, plus--font-size-*and--line-height-*. - Motion tokens:
--duration-ui,--duration-fast,--duration-slow. Easing tokens forcubic-beziercurves. - Shadow tokens:
--shadow-accent-md,--shadow-accent-glow, etc.
- Colour tokens:
- Sensory-zone overrides keyed on
[data-zone="..."]on<html>. Switches token values to dim, focus, etc. - Theme overrides keyed on
[data-theme="dark"]and[data-theme="light"]. Thepreferencesstore writes bothdata-themeanddata-zone. - Accessibility variables on
<html>:--font-family-body,--font-size-body,--letter-spacing-body,--line-height-body. Set by thepreferencesstore viaapplyToDOM(). - Base styles:
bodybackground, font, body font-family bound to the variable, scrollbar styling, focus ring. - Utility classes for grain texture (
.grainuses the noise asset underassets/grain.svg), CRT-style transcript surface, etc. - Animations:
@keyframes fade-in,@keyframes pulse, etc. Reduced motion guard at the bottom (@media (prefers-reduced-motion: reduce)).
src/fonts/ (bundled woff2)
atkinson-hyperlegible-next.woff2instrument-serif-italic.woff2jetbrains-mono.woff2lexend-variable.woff2opendyslexic.woff2
Bundled by Vite (referenced from app.css via /fonts/... paths that Vite resolves). The same files live in static/fonts/ for the static-served path. Confirm whether both paths are required; if Vite handles font copying, static/fonts/ may be redundant.
src/assets/
grain.svg. Noise texture used by the.grainutility class.waveform-mark.svg. Brand glyph.wordmark.svg. Brand wordmark.
static/
Served as-is from the webview root.
favicon.png. Site favicon.fonts/. Same five woff2 files assrc/fonts/. Likely the source ofapp.css /fonts/...URLs.pcm-processor.js. AudioWorklet processor (slice 02 owns the integration). 32-line file that converts microphone input to int16 PCM frames and posts them up.textures/grain.png. PNG version of the grain texture.svelte.svg,tauri.svg,vite.svg. SvelteKit defaults; technically unused. Candidate for removal.
How preferences map to the DOM
| Preference | DOM target |
|---|---|
theme ("light" / "dark" / "system") |
data-theme on <html>. system resolves to OS preference at apply time. |
zone ("default" / ...) |
data-zone on <html>. |
accessibility.fontFamily ("lexend" / "atkinson" / "opendyslexic") |
--font-family-body CSS variable on <html>. |
accessibility.fontSize |
--font-size-body (pixels). |
accessibility.letterSpacing |
--letter-spacing-body (em). |
accessibility.lineHeight |
--line-height-body (unitless). |
accessibility.bionicReading |
`<html data-bionic-reading="true |
accessibility.reduceMotion |
`<html data-reduce-motion="reduce |
Plus the legacy settings.fontSize writes --font-size-transcript on <body> directly (+layout.svelte:204). That is separate from accessibility.fontSize.
Tailwind v4 setup
- Installed via
@tailwindcss/viteinvite.config.js:3. - Entry:
src/app.cssline 1,@import "tailwindcss". - Tokens declared inline via
@themeblocks inapp.css. - No
tailwind.config.{js,ts}exists. Do not look for one. - Class scanning: Tailwind v4 scans the source tree by default. Custom paths can be configured with
@sourcedirectives if needed.
Watch outs
- Two font sources.
src/fonts/(Vite bundled) andstatic/fonts/(raw served). Confirm whether both are needed; redundancy bloats the bundle. - Mirror file
src/design-system/colors_and_type.cssmust be updated wheneverapp.css@themechanges. There is no automated check. prefers-reduced-motionhonoured by CSS but JS animations (e.g.CompletionSparkline's stagger) are guarded in component code, not via the media query alone.- Tailwind v4
@themeis class-scanning sensitive. If you put utility class strings inside conditional template literals that Tailwind cannot see at scan time, they will not be generated. - Removing default SvelteKit assets (
static/svelte.svg,vite.svg,tauri.svg) requires confirming nothing references them inapp.htmlorREADME.md. pcm-processor.jsis a static asset because AudioWorklet processors must be served from a same-origin URL. Bundling it through Vite would break the worklet registration. Leave it instatic/.
See also
- Design system. The reference mirror of
app.csstokens. - Stores. The
preferencesstore that writes the DOM. - Components. Where the utility classes are consumed.