# Lumotia — Design System

> **Think out loud.** A voice-first dictation app built for neurodivergent minds, by CORBEL.

## What is Lumotia?

Lumotia is a local-first dictation + thought-capture app. You press a hotkey, speak, and Lumotia transcribes, cleans, and — optionally — extracts tasks from what you said. Everything runs on your machine (Whisper / Parakeet models); nothing is sent anywhere.

**Company:** CORBEL — an AI consultancy and technology integrator that removes friction from day-to-day life and work.

**Product essence:** *Clarity without friction.* Every design decision is measured against it. If something adds cognitive load, it doesn't ship.

**Archetypes:** Sage (primary) + Magician (secondary). Lumotia listens more than it speaks.

**Visual reference points:** The Barbican, Muji, Amsterdam urban design, Nujabes album art — warm brutalism, honest materials, structural clarity. **Anti-references:** Notion-style feature density, generic blue/white SaaS, FAANG aesthetics.

---

## Sources

- **Repo:** `github.com/jakejars/lumotia` — Tauri + Svelte 5 + Tailwind v4 desktop app. Imported into `lumotia-source/` (lib components + routes).
- **Design brief:** Pasted in the initial message — complete token system, type scale, motion guidelines, ideology.
- **Key reads in `lumotia-source/`:**
  - `app.css` — @theme tokens, global base, zone + motion system
  - `lib/Sidebar.svelte` — navigation shell
  - `lib/pages/DictationPage.svelte` — record / transcribe (the hero screen)
  - `lib/pages/HistoryPage.svelte` — saved transcripts
  - `lib/pages/TasksPage.svelte` — inbox / today / soon / later buckets
  - `lib/pages/FilesPage.svelte` — audio file import
  - `lib/components/Card.svelte`, `Titlebar.svelte`, `EmptyState.svelte`, `ZonePicker.svelte`, `Toggle.svelte`, `ToastViewport.svelte`
  - `docs/icon-mapping.md` — Lucide migration audit

---

## Index — what's in this folder

| Path | What it is |
|---|---|
| `README.md` | This file. Start here. |
| `colors_and_type.css` | **The** stylesheet. CSS variables, semantic type classes, grain, zones. `@import` it. |
| `SKILL.md` | Agent-skill manifest (cross-compatible with Claude Code Agent Skills). |
| `assets/` | Logos, the sinhala wordmark glyph, grain texture, icon references |
| `preview/` | HTML spec cards shown in the Design System tab (swatches, specimens, components) |
| `ui_kits/lumotia-app/` | UI kit — pixel-level recreation of the Lumotia desktop app with interactive click-thru |
| `lumotia-source/` | Imported Svelte source — the ground truth for component structure |

No slide template was attached, so `slides/` is not created.

---

## Content Fundamentals

> **Voice:** A calm friend who has already done the anxious part for you.

**Person.** Addresses the user as *you*; never refers to itself as *I*. Brand name "Lumotia" appears sparingly — the product speaks, it doesn't narrate itself. *(Settings labels: "Save recordings", "British English" — never "I'll save your recordings".)*

**Sentence shape.** Short. Direct. Rarely more than ~12 words per line of UI copy. Never exclaims. Never hypes. Full stops inside UI labels are dropped; in prose (empty states, toasts) they're used naturally.

**Tone.**
- **Ambient, not demanding.** Empty states are *"Your words will appear here…"* — not *"Record your first transcript!"* Blank screens trigger freeze; Lumotia offers presence instead of prompting.
- **Calm on failure.** Failed transcription copy leads with *"Your audio is saved"* — the anxiety reducer, not the apology. Never red all-caps.
- **No guilt, no streaks.** No streak-shaming, no *"keep it up!"*, no urgency.
- **British English.** "Minimise", "finalising", "customise". `britishEnglish` is a first-class setting.

**Casing.**
- Sentence case for all headings and buttons. *"Start recording"*, *"Clear all"*, *"Sensory zone"* — never *Start Recording* or *START RECORDING*.
- Eyebrow labels (10px, uppercase, 0.12em tracking) are the **only** place all-caps appears — e.g. *THINK OUT LOUD* under the sidebar wordmark. Never apply uppercase to sentences.
- Brand name is always `Lumotia` (capital K, one lowercase letter).
- Product tagline — *"Think out loud"* — always sentence case.

**Buttons.** Verbs. *Record, Stop, Save, Copy, Clear, Export, Extract Tasks, Open viewer.* The one exception is *Tasks* (noun) as a sidebar toggle — consistent with its icon label.

**Status language.** State-driven, non-anthropomorphic. `Ready`, `Recording…`, `Loading model…`, `Finalising…`, `Error`. Not *"I'm listening"*.

**Microcopy examples (lifted from the codebase):**
- Empty: *"Press record or Ctrl+Shift+R"* · *"Your transcriptions will be saved here"* · *"No matching transcripts"*
- Saved feedback: *"Saved · 3 tasks extracted"*
- Error toast: *"Could not start recording"* + *"device disconnected"* body
- Settings helper: *"Auto mode skips monitor sources and validates by RMS energy."*

**Emoji.** **Never.** Nothing in the codebase uses them. The one decorative character is the Sinhala letter ක (U+0D9A) next to the wordmark — a brand mark, not emoji.

**Numbers + units.** Tabular figures for timers, durations, word counts. Units always lowercase, no abbreviations in prose: *"3 tasks extracted"*, *"12 words"*, *"Dropped 2s of older audio"*.

---

## Visual Foundations

### Palette — warm, not beige
Three-layer surface system: `--bg` (60%) → `--bg-elevated` (30%) → `--bg-card` — all neutrals carry a warm amber undertone for cohesion. Never `#000` on `#fff` (halation). Accent `#e8a87c` (amber/copper) is **always meaningful** — interactivity, recording state, or brand identity. Never decorative. Three semantic colors only: `--success` moss green, `--danger` muted red, `--warning` honey amber. 60-30-10 split: 60% surface, 30% elevated, 10% amber.

### Sensory zones
Three environment modes — **Cave** (cool teal tint, focus), **Energy** (warm neutral, collaboration), **Reset** (muted sage, relaxation). Zones tint surfaces only; the amber accent never changes. Environment is the variable, brand is the constant. Zone transitions cross-fade 300–500ms (instant when reduce-motion is on).

### Type — Lexend everywhere, italic serif only for identity
- **UI + body:** Lexend (variable 300–700). Designed for reading difficulties; high x-height, generous spacing.
- **Display / wordmark:** Instrument Serif Italic 400. **Only** the wordmark and page titles. Never body, never UI.
- **Mono:** JetBrains Mono — file paths, durations, kbd.
- **User-selectable alternatives:** Atkinson Hyperlegible, OpenDyslexic.
- 16px floor for all body. 1.5× line-height minimum. Left-aligned only. Max 75ch. Sentence case. Never italic for extended reading. Never more than 3 weights per screen.

### Backgrounds
Flat warm surfaces, layered. **Grain texture** at 2.5% opacity dark / 1.5% light — a 200×200 noise tile, `pointer-events:none`, z-index 50, overlaid on the whole viewport. No gradients. No full-bleed photography. No hand-drawn illustrations. No repeating geometric patterns. The grain is the one and only texture.

### Imagery — when present
Warm grain wash: shift toward amber, noise overlay 2–3%, slight vignette (10–15%). Subjects are textured surfaces (wood grain, concrete) and **hands only** (writing, holding things — never faces or screens). Late-afternoon light, low-to-medium contrast. No stock photography of smiling people.

### Illustration
Abstract waveform / sound-ripple motifs in amber. 2px stroke. Flat colour with opacity variations — no gradients, no characters, no mascots.

### Motion — elderflower, not espresso
- **Easing:** `cubic-bezier(0.2, 0.8, 0.2, 1)` (ease-out).
- **UI:** 150–200ms. **Decorative:** 300–500ms. **Zone transitions:** 300–500ms cross-fade. **Waveform:** 2s ease-in-out amplitude pulse, clamped.
- **Never:** bounce, screen shake, slide-from-offscreen, auto-play, attention-grabbing.
- **Reduce motion is the default** — opt IN to animation.

### Hover + press states
- **Hover:** background shifts to `--hover` (a single step warmer than the underlying surface). Buttons: text colour step up (tertiary→secondary, secondary→text). Accent buttons: `--accent` → `--accent-hover` (slightly darker copper).
- **Press:** `active:scale-[0.93]` on circular actions (record button), `active:opacity-80` on standard buttons. No ripple. No pulse.
- **Active nav:** `--nav-active` background, text upgraded to primary, icon stroked 2.0 instead of 1.5, icon colour → amber.

### Borders
Two weights only: `--border` (visible) and `--border-subtle` (barely-there divider). Always 1px. Accent border appears only for focus rings, active selection, or recording indicators.

### Shadows
Low and warm. `shadow-sm` `0 1px 3px rgba(0,0,0,0.2)` for cards. `shadow-md` `0 4px 12px rgba(0,0,0,0.25)` for popovers. The **one signature shadow** is the accent glow on the record button at rest: `0 4px 20px rgba(232,168,124,0.3)`, plus the `pulse-warm` animation while recording.

### Corners
`--radius-sm` 6px (kbd, pills) · `--radius-md` 8px (buttons, inputs) · `--radius-lg` 12px (cards internal) · `--radius-xl` 16px (primary containers) · `--radius-2xl` 20px (the big transcript card). Record button is fully circular. Toasts, chips, badges are fully rounded (`rounded-full`).

### Cards
Card = `--bg-card` background + `--border-subtle` 1px + `rounded-2xl` + `shadow-sm`. No heavy drop shadows. No coloured left-border accents (the overused SaaS trope is explicitly avoided). Content sits directly on the card — no inner boxes stacked on boxes.

### Layout — fixed spine
Titlebar 32px · sidebar 48px collapsed / 210px expanded · optional right task rail 280px. Pages handle their own scroll; the shell does not. Left-aligned text everywhere. No centred hero sections.

### Transparency + blur
Used sparingly, only for: tooltips on collapsed sidebar items, the backdrop of the float window, the accent-subtle tint (`--accent 6%`) on selected/pressed accent buttons. No glassmorphism. No frosted nav bars.

### Iconography
Lucide icons, 2px stroke, rounded terminals. 16px in nav, 20px in features, 24px primary actions. Every icon paired with a visible text label — no standalone icons (exception: OS titlebar controls). Collapsed sidebar uses icon + aria-label + tooltip. Lucide is loaded from CDN.

### Focus rings
2px solid `--accent`, 3px offset, rendered **above** grain (z-index > 50). Tested on every theme × zone combination.

---

## Iconography

**Library:** [Lucide Icons](https://lucide.dev) (MIT). Every Lucide glyph Lumotia uses is listed in `lumotia-source/docs/icon-mapping.md`.

**Stroke weight:** 2px default · 2.5 on active sidebar items · 1 for empty-state illustrations (48px, opacity 40%).

**Sizes:**
- 14px — chevrons, inline status dots
- 16px — sidebar nav, toolbar icons, source tags
- 20px — feature-area icons (Dictation toolbar, Settings panels)
- 24px — primary actions
- 48px — empty-state illustrations

**Colour:**
- `--text-tertiary` at rest
- `--text-secondary` on hover (group hover)
- `--accent` when active, selected, or brand-significant (recording dot, active nav, play button)
- `--danger` for destructive and the recording state indicator
- `--success` for completion checks

**Core Lumotia set (from the audit):** `Mic` (Dictation), `FileText` (Files), `SquareCheck` (Tasks), `Clock` (History), `Settings`, `Circle`/`Square` (record/stop), `Play`/`Pause`, `Search`, `Upload`, `Download`, `Copy`, `ChevronDown`, `ChevronLeft`, `ChevronRight`, `X`, `Check`, `Plus`, `Pin`, `User`, `AlignLeft`, `AlertTriangle`, `Loader2`.

**Brand glyph:** The Sinhala letter **ක** (U+0D9A) sits next to the wordmark in `--accent`. Decorative only. During recording it spins slowly (2s linear infinite, `sinhala-spin`). A Unicode codepoint, not an SVG — scales perfectly, no asset needed.

**Emoji:** **Never used.**

**Bitmap icons, icon fonts, sprites:** **None.** Lucide covers everything.

**Loading indicator:** `Loader2` with `animate-spin` is the standard. The codebase also has `UnicodeSpinner.svelte` (◉ ◎ ○) as an ambient/decorative alternative when Lucide feels too mechanical.

**Delivery:** In HTML artefacts, load Lucide from CDN: `<script src="https://unpkg.com/lucide@latest"></script>` then `lucide.createIcons()`. Or use inline SVGs copied from [lucide.dev](https://lucide.dev). See `assets/icons/` for the handful pre-copied for design previews.

---

## Font substitution note

The repo ships bundled woff2 files (`/fonts/lexend-variable.woff2`, `/fonts/instrument-serif-italic.woff2`, `/fonts/jetbrains-mono.woff2`, `/fonts/atkinson-hyperlegible-next.woff2`, `/fonts/opendyslexic.woff2`) which were **not included** in the imported subset. `colors_and_type.css` loads the Google Fonts CDN equivalents of Lexend, Instrument Serif Italic, JetBrains Mono, and Atkinson Hyperlegible — visually identical.

**Missing:** OpenDyslexic (not on Google Fonts; needs to be self-hosted). Atkinson Hyperlegible **Next** is also not yet on Google Fonts — we substituted the original **Atkinson Hyperlegible** (very close; same designer, same metrics).

**Please drop the original woff2 files into `fonts/` when you have a chance.** The CSS paths under `@font-face` would then be `fonts/lexend-variable.woff2` etc., matching the app bundle exactly.
