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>
14 KiB
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':
{
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-recbackground, 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: reduceby 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 bothmanifest.jsoniconsANDaction.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'simageUtilvalidation. - All popup HTML/CSS lives in
src/popup/. All welcome HTML/CSS lives insrc/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 systemsrc/background/index.ts— implements toolbar action + notification per §8src/popup/index.html— implements popup per §8.3src/welcome/welcome.html— implements welcome per §8.4 (Plan 01-10).planning/phases/01-stabilize-video-pipeline/01-CONTEXT.mdD-16-toolbar, D-15-display-surface amendments — interaction model this design system visually realises