From 949aa03db518efe0ed131d922aa24283bdbcfe5b Mon Sep 17 00:00:00 2001 From: Mark Date: Sun, 17 May 2026 16:02:56 +0200 Subject: [PATCH] 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) --- .planning/intel/assets-spec.md | 173 +++++++++++++++++ .planning/intel/design-system.md | 318 +++++++++++++++++++++++++++++++ 2 files changed, 491 insertions(+) create mode 100644 .planning/intel/assets-spec.md create mode 100644 .planning/intel/design-system.md diff --git a/.planning/intel/assets-spec.md b/.planning/intel/assets-spec.md new file mode 100644 index 0000000..9b4ba9f --- /dev/null +++ b/.planning/intel/assets-spec.md @@ -0,0 +1,173 @@ +# Mokosh Asset Specification + +Concrete deliverables list derived from `design-system.md`. Each entry tells a +contributor (you, an agent, a hired designer) exactly what file to produce, +what dimensions/format, what to draw, and where to commit it. Authored +2026-05-17 to unblock Plan 01-09's notification-icon failure + Plan 01-10's +welcome page. + +Status: `draft` — first iteration; revise as actual designs surface. + +--- + +## Priority 0 — blocks Plan 01-09 closeout + +These three icons unblock the notification + toolbar UX. Plan 01-09 cannot +land its operator-empirical UAT until valid versions exist. + +### A-01 — `icons/icon16.png` + +| | | +|---|---| +| **Path** | `icons/icon16.png` (commit to source tree; vite copies to `dist/icons/` on build) | +| **Dimensions** | 16 × 16 px | +| **Format** | PNG, RGBA (transparent background), 8-bit | +| **Min file size** | ≥ 200 bytes (current placeholder is 79 B — Chrome rejects it) | +| **Subject** | The Mokosh mark per `design-system.md` §5.2. At 16px most detail is lost; produce as a single recognizable silhouette. | +| **Color** | Single accent color OR transparent + accent. Recommended: a filled circle in `#212121` (near-black, neutral) for visibility on both light and dark Chrome themes. Adding the recording dot in `--mks-rec` makes this state-coloured, which conflicts with the "neutral mark + state via badge" decision (design-system §5.2). **Pick neutral.** | +| **Where used** | Chrome menu bars, Extensions page list, autocomplete popup | +| **Validation** | After committing: `npm run build && grep -q '"16"' dist/manifest.json && [ -s dist/icons/icon16.png ]` | + +### A-02 — `icons/icon48.png` + +| | | +|---|---| +| **Path** | `icons/icon48.png` | +| **Dimensions** | 48 × 48 px | +| **Format** | PNG, RGBA, 8-bit | +| **Min file size** | ≥ 500 bytes (current placeholder is 123 B) | +| **Subject** | Same mark as A-01, more visible internal detail. The frame/ring around the dot can resolve at this size. | +| **Color** | Same constraint: neutral. | +| **Where used** | Chrome Extensions page (chrome://extensions card icon), some context menus | +| **Validation** | `grep -q '"48"' dist/manifest.json && [ -s dist/icons/icon48.png ]` | + +### A-03 — `icons/icon128.png` + +| | | +|---|---| +| **Path** | `icons/icon128.png` | +| **Dimensions** | 128 × 128 px (REQUIRED minimum for `chrome.notifications.create({type:'basic'})`) | +| **Format** | PNG, RGBA, 8-bit | +| **Min file size** | ≥ 1 KB (current placeholder is 306 B — silently rejected by `chrome.imageUtil` per the empirical finding) | +| **Subject** | Full Mokosh mark, all detail visible. This is the primary brand asset. | +| **Color** | Neutral mark; the badge layer adds state colour. | +| **Where used** | Chrome Web Store thumbnail (someday), notification iconUrl (per `design-system.md` §8.2), about-extension dialogs | +| **Validation** | `[ $(stat -c%s dist/icons/icon128.png) -gt 1024 ]` AND `chrome.notifications.create` succeeds in smoke without `imageUtil` error | + +--- + +## Priority 1 — Plan 01-10 welcome page + +### A-04 — `icons/icon192.png` (optional, retina-safe notification icon) + +| | | +|---|---| +| **Path** | `icons/icon192.png` | +| **Dimensions** | 192 × 192 px | +| **Format** | PNG, RGBA, 8-bit | +| **Min file size** | ≥ 2 KB | +| **Subject** | Identical to A-03 at higher resolution; for hi-DPI displays in notification rendering | +| **Status** | Optional but recommended. If skipped, A-03 (128px) is the fallback. | + +### A-05 — Welcome page hero mark (Plan 01-10) + +| | | +|---|---| +| **Path** | `src/welcome/hero.svg` (preferred — vector) OR `src/welcome/hero.png` (1024×512 fallback) | +| **Format** | SVG (inline-safe, no external refs) OR PNG | +| **Subject** | Lockup of the Mark + the wordmark "Mokosh" OR "AI Call Recorder". Type lockup at large scale. Per `design-system.md` §10 ODD-4, default is "type-only hero" if no illustration exists — in that case the SVG can be a stylized rendering of the wordmark alone. | +| **Used by** | `src/welcome/welcome.html` (Plan 01-10) | +| **Status** | Required for Plan 01-10 closure. Acceptable interim: type-only HTML/CSS lockup (no asset file needed) | + +--- + +## Priority 2 — refinement passes (future phases) + +### A-06 — Status-glyph variants for badge composition + +The current architecture uses Chrome's badge API (text + background color) for +state communication. If a future phase wants richer state indication (e.g. a +recording-dot embedded in the toolbar icon itself, swapped via +`chrome.action.setIcon`), we'd need per-state icon variants: + +| Variant | Dimensions | When used | +|---|---|---| +| `icons/icon-rec-16.png` etc. | 16/48/128 | When recording active (red dot overlay) | +| `icons/icon-err-16.png` etc. | 16/48/128 | When in error state | +| `icons/icon-off-16.png` etc. | 16/48/128 | When idle | + +Recommendation: defer to Phase 5 hardening unless badge text proves insufficient. +The performance cost of setIcon swaps every state change is non-trivial. + +### A-07 — Popup polish + +| | | +|---|---| +| **Path** | `src/popup/popup-bg.svg` | +| **Subject** | Optional subtle background pattern OR colour for popup container; currently popup uses solid `--mks-popup-bg-dark/light` | +| **Status** | Skip; current solid background is fine | + +### A-08 — Operator runbook visuals (smoke.sh page enhancements) + +The smoke test page (in `smoke.sh`'s SMOKE_HTML) currently uses emoji and +inline CSS. Could be replaced with a properly-designed instructional page if +operators actually use it for onboarding. Currently dev-only; defer. + +--- + +## Implementation pathways for the contributor + +Pick ONE based on availability: + +### Path A — auto-generated solid-color placeholder set + +**Use case:** quickly unblock Plan 01-09 closeout. Replace placeholders with +real designed assets later. + +```bash +# Quick generator using ImageMagick (one-liner per size) +convert -size 16x16 xc:'#212121' -draw "fill #00C853 circle 8,8 8,4" icons/icon16.png +convert -size 48x48 xc:'#212121' -draw "fill #00C853 circle 24,24 24,12" icons/icon48.png +convert -size 128x128 xc:'#212121' -draw "fill #00C853 circle 64,64 64,32" icons/icon128.png +``` + +Produces dark-square + green-dot icons (~1 KB each). Functional, not branded. + +### Path B — design-first + +You produce the assets per the `design-system.md` constraints. Drop them at the +spec'd paths. Run `npm run build`, smoke.sh, confirm notification fires. + +### Path C — hire / commission + +Send `design-system.md` + this file to a designer. Acceptance: deliverables at +the listed paths, dimensions, formats, with file sizes above the floors. + +--- + +## Acceptance checklist (any pathway) + +Plan 01-09's operator UAT can resume when ALL of these are true: + +- [ ] `icons/icon16.png` exists, ≥ 200 bytes, is 16×16 PNG +- [ ] `icons/icon48.png` exists, ≥ 500 bytes, is 48×48 PNG +- [ ] `icons/icon128.png` exists, ≥ 1024 bytes, is 128×128 PNG +- [ ] `npm run build` mirrors them to `dist/icons/` +- [ ] Smoke run: `chrome.notifications.create` does NOT throw `imageUtil` error +- [ ] Recovery notification visibly appears after click "Stop sharing" in Chrome + +Once those pass + Plan 01-09 Bug B fix (state routing for `user-stopped-sharing` +→ `setIdleMode`) lands, the wave closes. + +--- + +## Related + +- `design-system.md` — visual + interaction language this spec realises +- `.planning/phases/01-stabilize-video-pipeline/01-09-PLAN.md` — the plan that + surfaced the icon need +- `.planning/debug/01-09-recovery-flow.md` — the debug session that confirmed + the icon files are the blocker +- `src/background/index.ts` lines 54, 833-840 — NOTIFICATION_ICON_PATH constant + + the chrome.notifications.create call site that needs valid icons +- `manifest.json` `icons` and `action.default_icon` — declare which sizes exist diff --git a/.planning/intel/design-system.md b/.planning/intel/design-system.md new file mode 100644 index 0000000..9addcf3 --- /dev/null +++ b/.planning/intel/design-system.md @@ -0,0 +1,318 @@ +# 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