Files
mokosh/.planning/intel/design-system.md
Mark 949aa03db5 docs(intel): design system + assets spec for designer-team handoff
Two new cross-phase intel docs surfacing the visual + interaction
language and the concrete asset deliverables list.

Triggered by Plan 01-09's notification-icon failure: the original
placeholder PNGs (icons/icon{16,48,128}.png at 79/123/306 bytes)
are too small for chrome.notifications.create's imageUtil validation.
Plan 01-09 closeout blocks on valid replacement icons.

design-system.md captures:
- Brand voice (quietly competent operator-tool; not playful)
- Identity (Mokosh codename + "AI Call Recorder" display name)
- Color tokens (semantic state + UI surfaces; WCAG AA validated)
- Typography (system fonts only; type scale)
- Iconography (solid filled, 24px grid, neutral mark + state via badge)
- Spacing (4px base scale)
- Motion (conservative; reduced-motion-aware)
- Component conventions (toolbar action, notification, popup, welcome)
- Accessibility & i18n (Russian-first, contrast floors)
- Open design decisions (mark concept, pulsing badge, tagline)

assets-spec.md captures:
- Priority 0 (blocks Plan 01-09): icons 16/48/128 with min file sizes
  + dimension/format requirements + validation commands
- Priority 1 (Plan 01-10): welcome page hero, optional 192px icon
- Priority 2 (future phases): per-state icon variants, popup polish,
  runbook visuals
- Three implementation paths: auto-generated placeholders (interim),
  design-first (commission), hire/commission

User will delegate execution to designer team; specs are handoff-ready
with binding technical floor + designer-judgment aesthetic direction.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-17 16:02:56 +02:00

319 lines
14 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Mokosh Design System
Cross-phase visual + interaction language for the Mokosh extension (user-facing
name "AI Call Recorder", internal codename "Mokosh"). Authored 2026-05-17 in
response to Plan 01-09's notification-icon discovery that the original
placeholder PNGs (`icons/icon{16,48,128}.png` at 79/123/306 bytes) fail Chrome's
notification API. Surfaces the visual decisions so any contributor (you, an
agent, a future designer) can produce assets that fit the same language.
Status: `draft` — first iteration; expect amendments as actual designs surface.
---
## 1. Brand voice
**Mokosh is an operator's silent helper.** It records continuously, surfaces
itself only when needed, and stays out of the operator's way the rest of the
time. The visual identity should reflect that:
- **Quietly competent.** Not playful, not flashy. Dependable industrial.
- **Diagnostic, not decorative.** Every visual choice serves an operator goal:
is recording active? did the bug get captured? where do I click to save?
- **Low chrome, high clarity.** When the extension is invisible (recording
silently), it should genuinely be invisible. When it shows itself (badge,
notification, popup), it should be unambiguous about state.
- **Russian-first wording, internationally legible visuals.** Operators read
Russian (per SPEC). Visuals must not depend on any language for legibility —
symbols + color + position carry meaning.
Anti-patterns to avoid:
- Animated icons that draw attention during normal operation
- Decorative imagery in a tool that should fade into background
- Brand-marketing tone in operator-facing copy ("Hi there!", emojis)
- Color-only state indication (must pair color with text/shape)
---
## 2. Identity
| | |
|---|---|
| Codename | Mokosh — Slavic goddess of fate, weaving, and the earth |
| User-facing display name | "AI Call Recorder" (Russian-speaking operator-tool name) |
| Tagline candidates (TBD) | "Записывает, чтобы вы могли воспроизвести." ("Records so you can reproduce.") |
| Mark concept | A thread/spool/weave motif evokes the codename without overpowering. Alternative: a simple recording dot inside a frame, more conventional. **Decision deferred** — see Section 10. |
---
## 3. Color tokens
All extension surfaces draw from this palette. Color values are RGB; CSS
variable names are how implementation references them.
### 3.1 Semantic state (operator-visible)
| Token | Hex | Use |
|---|---|---|
| `--mks-rec` | `#00C853` | Recording active. Match `BADGE_REC_COLOR` in src/background/index.ts. Material Green A700; widely recognised "go/record" affordance. |
| `--mks-off` | `#9E9E9E` | Idle / not recording. Neutral gray, not red (red implies error). Material Gray 500. |
| `--mks-error` | `#FFB300` | Recoverable error (codec failure, buffer empty, etc.). Match `BADGE_ERROR_COLOR`. Material Amber 600 — caution not catastrophe. |
| `--mks-fatal` | `#D32F2F` | Unrecoverable state (rare). Material Red 700. |
**Accessibility constraint:** All four colors must meet WCAG AA 4.5:1 contrast
when paired with their badge text color. White text on `--mks-rec` and
`--mks-fatal`; black text on `--mks-off` and `--mks-error`.
### 3.2 UI surfaces
| Token | Hex | Use |
|---|---|---|
| `--mks-surface-bg` | `#222222` | Smoke-test page background (current); also acceptable for popup dark mode |
| `--mks-surface-text` | `#EEEEEE` | Text on dark surfaces |
| `--mks-surface-code` | `#444444` | Inline code background (dark theme) |
| `--mks-popup-bg-light` | `#FFFFFF` | Popup background, light Chrome theme |
| `--mks-popup-bg-dark` | `#1F1F1F` | Popup background, dark Chrome theme |
| `--mks-popup-fg-light` | `#202124` | Popup text, light theme (matches Chrome's Material 3) |
| `--mks-popup-fg-dark` | `#E8EAED` | Popup text, dark theme |
### 3.3 Diagnostic / dev-only
| Token | Hex | Use |
|---|---|---|
| `--mks-diag-bg` | `#000000` | Smoke-test timer overlay background |
| `--mks-diag-fg` | `#00FF00` | Smoke-test timer overlay text (high-contrast monospace) |
---
## 4. Typography
**System fonts only.** No web-font loads — keeps the extension CSP simple and
load-time near-zero. Falls back gracefully on every OS.
| Family token | Stack | Use |
|---|---|---|
| `--mks-font-ui` | `-apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif` | All UI text (popup, welcome page, notifications-rendered-as-pages) |
| `--mks-font-mono` | `"SF Mono", Menlo, Consolas, "Courier New", monospace` | Diagnostic overlays, code, timer |
### 4.1 Type scale
| Token | Size | Line-height | Use |
|---|---|---|---|
| `--mks-text-xs` | 11px | 1.3 | Badge labels, status pills, footnotes |
| `--mks-text-sm` | 13px | 1.4 | Secondary UI text, captions |
| `--mks-text-base` | 15px | 1.5 | Body text, popup messages, notification body |
| `--mks-text-lg` | 18px | 1.4 | Section headings within popup |
| `--mks-text-xl` | 24px | 1.3 | Welcome page H1, primary call-to-action |
| `--mks-text-xxl` | 32px | 1.2 | Diagnostic timer (smoke), large status |
### 4.2 Weights
- 400 (regular): all body text
- 500 (medium): UI labels, badge text
- 700 (bold): primary CTAs, status indicators (REC/OFF/ERROR)
Avoid 600 / italic — keep the weight ladder tight.
---
## 5. Iconography
### 5.1 Style
- **Solid filled** (not outline). Solid icons read better at 16px/48px sizes
where extension icons live; outline detail is lost at small sizes.
- **24×24 source grid** with 2px padding (effective icon area 20×20). Standard
Material/Apple icon-grid convention; ensures consistent visual weight.
- **Single accent color or two-tone max.** Reserve color complexity for badges
and notifications.
### 5.2 Mark concept (action.default_icon)
The extension's primary mark serves 3 roles simultaneously:
- Browser toolbar icon (16/32 — tiny; needs immediately-readable silhouette)
- Extensions page icon (48 — moderate; can carry a bit more detail)
- Chrome Web Store + notification icon (128 — full detail)
**Recommended motif: a "recording dot inside a thread spool / frame".** A
red-or-green circle inside a hexagonal/circular frame. Reads as: "this thing
records." The frame nods at the Mokosh "weaving" theme without literally
showing thread (which would be unreadable at 16px).
Alternative (cleaner, more conventional): just a filled red circle with a thin
white inner ring — looks like a record button, no thematic baggage. Slightly
less distinctive but immediately understood.
**Color in the mark:** the mark uses `--mks-rec` (green) when REC overlay would
be added by Chrome's badge anyway, OR a neutral mark with state communicated
purely via badge. Recommended: **neutral mark, state via badge.** Keeps the
icon recognizable across all states.
### 5.3 Inline glyphs
For popup and welcome page:
| Concept | Glyph | Notes |
|---|---|---|
| Save / download | ⬇ filled-arrow-into-tray | 20px in popup |
| Stop | ■ filled-square | Reserved for explicit stop control (see Section 10) |
| Recording active | ● solid-circle in `--mks-rec` | Pulsing optional (see Section 7) |
| Error | ▲ filled-triangle with `!` | `--mks-error` background |
| Settings | ⚙ filled-gear | Reserved; not currently surfaced |
| Welcome / intro | 🧵 thread/spool emoji is currently used in smoke; replace with custom glyph at design time |
---
## 6. Spacing
Base unit: **4px.** All spacing values are multiples of this base.
| Token | Value | Use |
|---|---|---|
| `--mks-space-1` | 4px | Tight padding within badges |
| `--mks-space-2` | 8px | Default padding inside controls |
| `--mks-space-3` | 12px | Padding inside popup containers |
| `--mks-space-4` | 16px | Section separation |
| `--mks-space-6` | 24px | Welcome page section gaps |
| `--mks-space-8` | 32px | Welcome page hero spacing |
### 6.1 Surface sizing
| Surface | Size | Notes |
|---|---|---|
| Popup default | 320×200 | Chrome auto-sizes; this is the comfortable target |
| Welcome page | full viewport, max-width 720px content column | Plan 01-10 |
| Notification | Chrome-controlled (basic type, ~360px wide) | iconUrl + title + message |
| Toolbar badge text | max 4 chars | Chrome truncates beyond |
---
## 7. Motion
Conservative. Motion draws attention; the extension should draw attention only
on state change.
| Motion | Duration | Easing | Use |
|---|---|---|---|
| Hover transitions | 150ms | `ease-out` | Buttons, links |
| Badge state change | instant | — | REC/OFF/ERROR transitions; no animation |
| Recording pulse (optional) | 1000ms loop | `ease-in-out` | Subtle 0.85→1.0 opacity loop on REC badge if surface allows. Currently used in smoke `.flash` class — adopt for badge if Chrome's badge API allows (it doesn't natively; would need an action.setIcon swap on interval, which has perf cost — recommend OFF for now). |
| Notification slide | Chrome default | — | We don't control |
| Welcome page CTA hover | 200ms | `ease-out` | Background-color + scale 1.0→1.02 |
---
## 8. Component conventions
### 8.1 Toolbar action (chrome.action)
States:
- **Idle** — neutral mark, badge text empty (or `""`), background transparent
- **REC** — neutral mark + badge text `"REC"` + background `--mks-rec`
- **ERROR** — neutral mark + badge text `"ERR"` + background `--mks-error`
- **OFF** (post-stop, awaiting restart) — neutral mark + badge text `"OFF"` + background `--mks-off`
Tooltip (`chrome.action.setTitle`) communicates current state in Russian:
- Idle: "Mokosh — щёлкните, чтобы начать запись"
- REC: "Mokosh — идёт запись (00:42)" (with live duration)
- ERROR: "Mokosh — ошибка записи, щёлкните для восстановления"
- OFF: "Mokosh — запись остановлена, щёлкните, чтобы начать снова"
### 8.2 Notification
Use `chrome.notifications.create` with `type: 'basic'`:
```js
{
type: 'basic',
iconUrl: chrome.runtime.getURL('icons/icon128.png'), // hi-res required
title: 'Mokosh', // short, branded
message: 'Recording started.' | 'Recording stopped.' | etc., // Russian
priority: 1, // default; 2 only for urgent
}
```
Notifications fire on:
- Startup prompt (every Chrome session) — until operator clicks once
- Recovery prompt (after user-stopped-sharing) — once
- Save complete (optional acknowledgement) — Phase 5 candidate
Avoid notification spam — at most one notification per state transition.
### 8.3 Popup (SAVE-only per Plan 01-09)
- Compact: 320×200 max
- Single primary CTA: "Сохранить отчёт об ошибке" (full-width)
- Status line above CTA: "Запись активна, последние 30 сек захвачены"
- Footer: small text with recording duration ("XX:XX") for trust
- No secondary actions in REC mode
- ERROR mode: replace CTA with restart-recording action; status line shows
error reason
### 8.4 Welcome page (Plan 01-10)
- Full viewport, dark theme matching `--mks-popup-bg-dark`
- Hero: large mark + name + 1-line tagline
- Body: 2-3 short bullets explaining what Mokosh does (operator-readable Russian)
- Primary CTA: "Начать запись" button — large, `--mks-rec` background, white text
- Footer: privacy note ("Mokosh записывает только ваш экран; данные остаются у вас")
---
## 9. Accessibility & internationalization
- **Contrast:** WCAG AA (4.5:1 normal, 3:1 large text). All semantic-state
pairings pre-validated above.
- **Focus:** visible focus rings on all interactive elements (popup buttons,
welcome page CTA). Use Chrome's default `outline: 2px solid auto`.
- **Color-independence:** every color-coded state pairs with text (REC/OFF/ERR
badge labels; never color alone).
- **Localization:** all user-facing strings are Russian per SPEC. UI scaffolding
must support future English/other-locale strings via standard Chrome
`_locales/` mechanism (deferred — no MVP requirement).
- **Reduced motion:** if recording-pulse animation is ever enabled (see §7),
honor `prefers-reduced-motion: reduce` by falling back to static.
---
## 10. Open design decisions
These are visual choices that need a human design pass before locking:
| # | Question | Default if undecided |
|---|---|---|
| ODD-1 | Mark concept: thread/spool motif OR clean record-button | Clean record-button (faster to produce; recognizable; no thematic risk) |
| ODD-2 | Pulsing REC badge animation | OFF (Chrome badge API doesn't support; would need setIcon interval; perf cost) |
| ODD-3 | Tagline final wording | "Записывает, чтобы вы могли воспроизвести." (above) |
| ODD-4 | Welcome page hero illustration | None — type-only hero |
| ODD-5 | Notification iconUrl: same as toolbar mark OR distinct? | Same — operator should recognise the source |
| ODD-6 | Dark/light theme detection in popup | Auto via `prefers-color-scheme` (uses Chrome theme by default) |
---
## 11. Implementation notes
- All extension contexts (SW, offscreen, popup, welcome page) share the same
CSP. No external font/asset loads. Everything bundled or `chrome.runtime.getURL`.
- Icons must be in `dist/icons/` and declared in both `manifest.json` `icons`
AND `action.default_icon`.
- Notification iconUrl uses `chrome.runtime.getURL('icons/icon128.png')` — at
least 128×128, ideally 192×192 for retina. Smaller icons silently fail
Chrome's `imageUtil` validation.
- All popup HTML/CSS lives in `src/popup/`. All welcome HTML/CSS lives in
`src/welcome/` (Plan 01-10).
- Inline SVG preferred over PNG where the surface permits — sharper at all
DPIs. Chrome's notification API REQUIRES PNG iconUrl though.
---
## 12. Related
- `assets-spec.md` — concrete deliverables list (specific files, sizes, formats)
derived from this design system
- `src/background/index.ts` — implements toolbar action + notification per §8
- `src/popup/index.html` — implements popup per §8.3
- `src/welcome/welcome.html` — implements welcome per §8.4 (Plan 01-10)
- `.planning/phases/01-stabilize-video-pipeline/01-CONTEXT.md` D-16-toolbar,
D-15-display-surface amendments — interaction model this design system
visually realises