# 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 and where to commit it. **Path / dimensions / format / file-size floors / validation are technical constraints from Chrome and MV3 — those are floors.** Subject, colors, illustration choices, and aesthetic intent are open and owned by the design team. Authored 2026-05-17 to unblock Plan 01-09's notification-icon failure + Plan 01-10's welcome page. Status: `draft` — every aesthetic description below is a starting suggestion; the design team picks the actual direction per `brand-identity.md` + `design-system.md`. --- ## What's locked vs what's open in this file | Cell | Status | |---|---| | **Path** | **FLOOR** — Chrome/manifest look at exact paths | | **Dimensions** | **FLOOR** — Chrome notification + extension APIs enforce | | **Format** (PNG/SVG) | **FLOOR** — Chrome API requirements per surface | | **Min file size** | **FLOOR** — Chrome `imageUtil` silent-rejection floors | | **Validation command** | **FLOOR** — these are the checks Chrome runs | | **Subject** | **OPEN** — design team picks the mark, motif, illustration | | **Color** | **OPEN** — per `design-system.md` palette direction | | **Style notes** | OPEN — engineering's sketch only | Floors are non-negotiable. Everything else is direction the design team owns. --- ## 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** **(FLOOR)** | `icons/icon16.png` (commit to source tree; vite copies to `dist/icons/` on build) | | **Dimensions** **(FLOOR)** | 16 × 16 px | | **Format** **(FLOOR)** | PNG, RGBA (transparent background), 8-bit | | **Min file size** **(FLOOR)** | ≥ 200 bytes (Chrome rejects below this) | | **Subject** *(OPEN — design team)* | Engineering currently ships a dark-square + green-dot placeholder. Design team picks the actual mark per `design-system.md` §5.3 — could be a recording-dot in a frame, a thread/spool motif, a wordmark fragment, an abstract glyph, or anything else. At 16 px most detail is lost; aim for a single recognizable silhouette. | | **Color** *(OPEN — design team)* | Engineering's placeholder uses neutral dark + accent green. Design team picks per palette direction. Note: if the team lands on "neutral mark + state via badge" (one of several options in `design-system.md` §5.2), the icon stays neutral across all states; if the team picks "per-state icon swaps", separate variants per state are needed (see Priority 2 A-06). | | **Where used** | Chrome menu bars, Extensions page list, autocomplete popup | | **Validation** **(FLOOR)** | `npm run build && grep -q '"16"' dist/manifest.json && [ -s dist/icons/icon16.png ]` | ### A-02 — `icons/icon48.png` | | | |---|---| | **Path** **(FLOOR)** | `icons/icon48.png` | | **Dimensions** **(FLOOR)** | 48 × 48 px | | **Format** **(FLOOR)** | PNG, RGBA, 8-bit | | **Min file size** **(FLOOR)** | ≥ 500 bytes | | **Subject** *(OPEN — design team)* | Same concept as A-01; this size carries more internal detail, so glyph elements that don't resolve at 16 px (frame, ring, secondary shape) can appear here. | | **Color** *(OPEN — design team)* | Same direction as A-01. | | **Where used** | Chrome Extensions page card icon, some context menus | | **Validation** **(FLOOR)** | `grep -q '"48"' dist/manifest.json && [ -s dist/icons/icon48.png ]` | ### A-03 — `icons/icon128.png` | | | |---|---| | **Path** **(FLOOR)** | `icons/icon128.png` | | **Dimensions** **(FLOOR)** | 128 × 128 px (REQUIRED minimum for `chrome.notifications.create({type:'basic'})`) | | **Format** **(FLOOR)** | PNG, RGBA, 8-bit | | **Min file size** **(FLOOR)** | ≥ 1 KB (Chrome's `imageUtil` silently rejects smaller files per the Plan 01-09 empirical finding) | | **Subject** *(OPEN — design team)* | Primary brand asset — full mark, every detail visible. Design team has full latitude. | | **Color** *(OPEN — design team)* | Same direction as A-01/A-02. | | **Where used** | Chrome Web Store thumbnail (someday), notification `iconUrl`, about-extension dialogs | | **Validation** **(FLOOR)** | `[ $(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** **(FLOOR if shipped)** | `icons/icon192.png` | | **Dimensions** **(FLOOR if shipped)** | 192 × 192 px | | **Format** **(FLOOR if shipped)** | PNG, RGBA, 8-bit | | **Min file size** | ≥ 2 KB (suggested) | | **Subject** *(OPEN)* | Identical concept to A-03 at higher resolution for hi-DPI notification rendering | | **Status** | Optional. Skip if not producing hi-DPI variants; A-03 is the fallback. | ### A-05 — Welcome page hero (Plan 01-10) | | | |---|---| | **Path** *(suggested)* | `src/welcome/hero.svg` (vector preferred) OR `src/welcome/hero.png` (≥ 1024 × 512 fallback) | | **Format** **(FLOOR)** | SVG (inline, no external refs **(FLOOR for CSP)**) OR PNG | | **Subject** *(OPEN — design team owns entirely)* | Could be wordmark-only lockup, mark + wordmark, illustrated scene, photographic backdrop, type-only treatment, video, or no hero at all (some welcome pages start with copy). Design team picks. | | **Used by** | `src/welcome/welcome.html` (Plan 01-10) | | **Status** | Required for Plan 01-10 closure IF the design team's welcome layout uses a hero. Acceptable interim: type-only HTML/CSS lockup (no asset file needed). | --- ## Priority 2 — refinement passes (future phases) ### A-06 — Per-state icon variants (only if "per-state icon swaps" direction is picked) `design-system.md` §5.2 lists two iconography directions: - **Neutral mark + state via badge** (Chrome's `chrome.action.setBadgeBackgroundColor` does the state work) — only A-01/A-02/A-03 needed - **Per-state icon swaps via `chrome.action.setIcon`** — needs full sets per state If the design team picks per-state swaps, the deliverables expand: | Variant set | Dimensions | When used | |---|---|---| | `icons/icon-rec-{16,48,128}.png` | 16/48/128 | When recording active | | `icons/icon-err-{16,48,128}.png` | 16/48/128 | When in error state | | `icons/icon-off-{16,48,128}.png` | 16/48/128 | When idle | Trade-off: visual richness vs. perf cost of `setIcon` swaps every state change. Design team weighs. ### A-07 — Popup polish *(OPEN — defer)* | | | |---|---| | **Path** *(suggested)* | `src/popup/popup-bg.svg` or similar | | **Subject** *(OPEN)* | Background pattern, gradient, illustration, or nothing (current placeholder is a solid color). | | **Status** | Defer until the design team picks popup direction. Solid background is the working placeholder. | ### A-08 — Operator runbook visuals (smoke-test page) The dev smoke page (`smoke.sh`'s SMOKE_HTML) currently uses Unicode emoji and inline CSS. Could be replaced with properly-designed instructional visuals if operators actually use it for onboarding. Currently dev-only; defer. --- ## Implementation pathways Pick ONE per asset: ### Path A — auto-generated placeholders (engineering's current default) **Use case:** unblock Plan 01-09 closeout immediately. Designer-team assets swap in cleanly later. The currently committed placeholders in working tree were produced this way. ```bash # Example placeholder generator using ImageMagick (one-liner per size) convert -size 16x16 xc:'' -draw "fill circle 8,8 8,4" icons/icon16.png convert -size 48x48 xc:'' -draw "fill circle 24,24 24,12" icons/icon48.png convert -size 128x128 xc:'' -draw "fill circle 64,64 64,32" icons/icon128.png ``` Engineering's current run used `'#212121'` background + `'#00C853'` accent (neither is direction — both are placeholder picks). Design team can either swap in branded assets per Path B/C, or rerun this command with different colors as a stepping-stone placeholder. Produces dark-square + accent-dot icons (~1 KB each at 128 px). Functional, not branded. ### Path B — design-first The design team produces the assets per `brand-identity.md` + `design-system.md` direction. Drop them at the spec'd paths. Run `npm run build`, smoke.sh, confirm notification fires. ### Path C — hire / commission Send `brand-identity.md` + `design-system.md` + this file to an external designer. Acceptance: deliverables at the listed paths, dimensions, formats, with file sizes above the floors. The design team or product owner approves brand fit independently of engineering. --- ## 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 **(FLOOR)** - [ ] `icons/icon48.png` exists, ≥ 500 bytes, is 48 × 48 PNG **(FLOOR)** - [ ] `icons/icon128.png` exists, ≥ 1024 bytes, is 128 × 128 PNG **(FLOOR)** - [ ] `npm run build` mirrors them to `dist/icons/` **(FLOOR)** - [ ] Smoke run: `chrome.notifications.create` does NOT throw `imageUtil` error **(FLOOR)** - [ ] Recovery notification visibly appears after clicking "Stop sharing" in Chrome Brand fit / design approval is a separate gate — owned by the design team and product, not blocking the functional Plan 01-09 closure. --- ## Related - `brand-identity.md` — naming + blurb + creative slate (Brief #1) - `design-system.md` — visual + interaction language this spec realises (engineering sketch + technical floors) - `.planning/phases/01-stabilize-video-pipeline/01-09-PLAN.md` — the plan that surfaced the icon need - `.planning/debug/resolved/01-09-recovery-flow.md` *(when written)* — 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 ship