docs(intel): ingest designer-team handoff v1 + record 9 brand decisions

Designer-team delivered two bundles (2026-05-17):
- Mokosh.zip: presentation artifacts (Decision Brief + Surface Kit standalone HTMLs)
- Mokosh Design System.zip: implementation handoff (tokens.css + mark/lockup SVGs + memo)

Designer respected every contract: codename Mokosh preserved, MV3 CSP
acknowledged (flagged dev-only Google Fonts @import in tokens.css line 12
for engineering to replace), Cyrillic-first typography (IBM Plex Sans),
WCAG AA validation noted, made recommendations not unilateral decisions.

9 decisions resolved per user ack:
- D-01..06, D-08, D-09: accepted designer defaults
- D-07 OVERRIDE: B · "Mokosh — Session Capture" (vs designer's A · just "Mokosh")
  — operator-facing manifest:name surfaces capture purpose

Brand decisions persisted to brand-decisions-v1.md;
brand-identity.md Open Questions section marked resolved with backlink.

Designer artifacts staged at .planning/intel/design-incoming/ for Plan 01-12
(Design Integration) consumption. Mokosh.zip presentation HTMLs (3.4 MB)
preserved as audit/onboarding reference; can be pruned later if repo size
warrants.

Plan 01-12 implementation handoff catalogued in brand-decisions-v1.md
§"Implementation handoff" — covers tokens.css ingestion, WOFF2 self-hosting,
SVG → PNG rasterization, manifest:name + description update,
welcome layout, VITE_DEV smoke gating.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-05-17 21:00:54 +02:00
parent 66e6c4af74
commit 5efc2a89e3
7 changed files with 1018 additions and 0 deletions

View File

@@ -0,0 +1,43 @@
MOKOSH · HANDOFF BUNDLE
========================
Date 17 May 2026
From Design system (engineering-authored)
To Design team · brand team
Status draft — every choice is reversible
WHAT IS IN HERE
----------------
handoff.html The memo. Open in any browser. Self-contained — no
network requests except the dev font CDN (Google
Fonts) which one of the asks in §02 is to replace.
tokens.css The complete token system in production form. Drop
it next to your build's stylesheets to spec colours
and type from the real values.
assets/
mokosh-mark.svg The proposed brand mark. 2x2 weave intersection.
mokosh-lockup.svg Mark + wordmark lockup.
HOW TO USE
----------
1. Read handoff.html top-to-bottom (~5 min).
2. Reply on each of the 8 decisions in §01. Accept, override, or rewrite.
3. Drop the files I'm asking for in §02 into the project repo.
4. If anything in tokens.css needs to change, point at the token name —
it's one edit, the rest of the system re-threads automatically.
WHAT IS NOT IN HERE
-------------------
- The full preview cards. Those live in the design-system project under
preview/*.html — open the project for the 23 foundation cards split
across Type / Colors / Spacing / Components / Brand.
- The UI kit. Same project, under ui_kits/extension/.
- The original briefs from engineering — brand-identity.md, design-
system.md, assets-spec.md. Read them too if you have not seen them;
this handoff sits on top of them.
QUESTIONS
---------
Whatever's clearest. A reply inline on the .html, an updated tokens.css,
a Figma link, a screenshot, an angry voice memo. The system is wired to
accept overrides as small atomic edits, so partial answers are fine.

View File

@@ -0,0 +1,22 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 240 56" fill="none">
<g transform="translate(0, 12)" stroke="#181b2a" stroke-width="2.25" stroke-linecap="square">
<rect x="2.5" y="2.5" width="27" height="27" rx="3.5" ry="3.5"></rect>
<line x1="12" y1="2.5" x2="12" y2="11.5"></line>
<line x1="12" y1="14.5" x2="12" y2="17.5"></line>
<line x1="12" y1="20.5" x2="12" y2="29.5"></line>
<line x1="20" y1="2.5" x2="20" y2="11.5"></line>
<line x1="20" y1="14.5" x2="20" y2="17.5"></line>
<line x1="20" y1="20.5" x2="20" y2="29.5"></line>
<line x1="2.5" y1="13" x2="10.5" y2="13"></line>
<line x1="13.5" y1="13" x2="18.5" y2="13"></line>
<line x1="21.5" y1="13" x2="29.5" y2="13"></line>
<line x1="2.5" y1="19" x2="10.5" y2="19"></line>
<line x1="13.5" y1="19" x2="18.5" y2="19"></line>
<line x1="21.5" y1="19" x2="29.5" y2="19"></line>
</g>
<text x="48" y="40" class="mks-word">Mokosh</text>
</svg>

After

Width:  |  Height:  |  Size: 961 B

View File

@@ -0,0 +1,25 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 32" fill="none" stroke="#181b2a" stroke-width="2.25" stroke-linecap="square" stroke-linejoin="miter">
<rect x="2.5" y="2.5" width="27" height="27" rx="3.5" ry="3.5"></rect>
<line x1="12" y1="2.5" x2="12" y2="11.5"></line>
<line x1="12" y1="14.5" x2="12" y2="17.5"></line>
<line x1="12" y1="20.5" x2="12" y2="29.5"></line>
<line x1="20" y1="2.5" x2="20" y2="11.5"></line>
<line x1="20" y1="14.5" x2="20" y2="17.5"></line>
<line x1="20" y1="20.5" x2="20" y2="29.5"></line>
<line x1="2.5" y1="13" x2="10.5" y2="13"></line>
<line x1="13.5" y1="13" x2="18.5" y2="13"></line>
<line x1="21.5" y1="13" x2="29.5" y2="13"></line>
<line x1="2.5" y1="19" x2="10.5" y2="19"></line>
<line x1="13.5" y1="19" x2="18.5" y2="19"></line>
<line x1="21.5" y1="19" x2="29.5" y2="19"></line>
</svg>

After

Width:  |  Height:  |  Size: 877 B

View File

@@ -0,0 +1,601 @@
<!doctype html>
<html lang="en" data-screen-label="Handoff brief">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Mokosh · Handoff to design + brand</title>
<style>
/* ─────────────────────────────────────────────────────────────────────────
Mokosh Design System — colors_and_type.css
Single source of truth for foundational tokens.
Surfaces: Chrome MV3 popup, welcome page, notification copy, toolbar.
Audience: Russian-first operators. Cyrillic coverage required.
───────────────────────────────────────────────────────────────────── */
/* Fonts (bundled locally; MV3 CSP forbids remote @font-face at runtime).
Substitution flag — until licensed files arrive, these are loaded from
Google Fonts in PREVIEW HTML only. Production bundles ship the same
families locally from /fonts/. See fonts/README.md. */
@import url('https://fonts.googleapis.com/css2?family=Newsreader:ital,opsz,wght@0,6..72,400;0,6..72,500;0,6..72,600;1,6..72,400&family=IBM+Plex+Sans:wght@400;500;600;700&family=IBM+Plex+Mono:wght@400;500&display=swap');
:root {
/* ── Palette ──────────────────────────────────────────────────────────
The "loom" palette. Warm-earthy, NOT clinical-blue. Reads as
restrained, professional, slightly hand-made — distinct from the
standard SaaS Material defaults the engineering placeholder used.
Each step validated for WCAG AA against its intended pair. */
/* Linen — primary surface family (warm off-white through stone) */
--mks-linen-50: #faf7f1; /* page background */
--mks-linen-100: #f3eee4; /* card / popup surface */
--mks-linen-200: #e8e0d0; /* hairline / divider on linen */
--mks-linen-300: #d4c9b5; /* muted edge */
/* Ink — text + inverse surface family (warm near-black indigo) */
--mks-ink-900: #181b2a; /* primary text, deepest surface */
--mks-ink-800: #232639; /* dark surface */
--mks-ink-700: #2f3349; /* dark surface raised */
--mks-ink-500: #5b5f76; /* secondary text on linen */
--mks-ink-400: #7a7e94; /* tertiary text, captions */
--mks-ink-300: #a4a7b8; /* disabled text */
/* Accents — state colors. Each is a dye reference. */
--mks-madder-600: #b2543d; /* REC accent — Rubia tinctorum dye */
--mks-madder-700: #963f29; /* REC pressed */
--mks-madder-100: #f5e2db; /* REC tint */
--mks-moss-600: #5a7349; /* success / saved */
--mks-moss-700: #455a38;
--mks-moss-100: #e2e9da;
--mks-amber-600: #c98b3a; /* warning / recoverable error */
--mks-amber-100: #f6e6c8;
--mks-brick-600: #a23a2b; /* unrecoverable error */
--mks-brick-100: #f0d5cf;
/* Semantic — point these at the palette. Use these in components. */
--mks-surface: var(--mks-linen-50);
--mks-surface-raised: var(--mks-linen-100);
--mks-surface-sunken: var(--mks-linen-200);
--mks-surface-inverse: var(--mks-ink-900);
--mks-fg-1: var(--mks-ink-900); /* primary text */
--mks-fg-2: var(--mks-ink-500); /* secondary text */
--mks-fg-3: var(--mks-ink-400); /* tertiary / caption */
--mks-fg-disabled: var(--mks-ink-300);
--mks-fg-inverse: var(--mks-linen-50);
--mks-border: var(--mks-linen-200);
--mks-border-strong: var(--mks-linen-300);
--mks-border-focus: var(--mks-ink-900);
--mks-rec: var(--mks-madder-600);
--mks-success: var(--mks-moss-600);
--mks-warning: var(--mks-amber-600);
--mks-error: var(--mks-brick-600);
/* ── Type ─────────────────────────────────────────────────────────────
Three families. Newsreader for display (serif with calm character).
IBM Plex Sans for UI body (excellent Cyrillic; not Inter/Roboto).
IBM Plex Mono for diagnostic / timer overlays. */
--mks-font-display: "Newsreader", "Iowan Old Style", "Times New Roman", serif;
--mks-font-ui: "IBM Plex Sans", "Segoe UI", -apple-system, BlinkMacSystemFont, sans-serif;
--mks-font-mono: "IBM Plex Mono", "SF Mono", Menlo, Consolas, monospace;
/* Base type scale — ratio ~1.2, tuned for popup density.
Smallest size 11px is reserved for badge labels only. */
--mks-text-xs: 11px;
--mks-text-sm: 13px;
--mks-text-base: 15px;
--mks-text-md: 17px;
--mks-text-lg: 20px;
--mks-text-xl: 28px;
--mks-text-2xl: 40px;
--mks-text-3xl: 56px;
--mks-lh-tight: 1.15;
--mks-lh-snug: 1.3;
--mks-lh-base: 1.5;
--mks-weight-regular: 400;
--mks-weight-medium: 500;
--mks-weight-semibold: 600;
--mks-weight-bold: 700;
/* Display tracking — Newsreader at large sizes wants negative tracking */
--mks-tracking-display: -0.015em;
--mks-tracking-tight: -0.005em;
--mks-tracking-base: 0;
--mks-tracking-loose: 0.04em; /* eyebrow / caps labels */
--mks-tracking-caps: 0.08em; /* badge text REC / ERR */
/* ── Spacing ──────────────────────────────────────────────────────────
4px base. Steps named by px multiple for clarity. */
--mks-space-1: 4px;
--mks-space-2: 8px;
--mks-space-3: 12px;
--mks-space-4: 16px;
--mks-space-5: 20px;
--mks-space-6: 24px;
--mks-space-8: 32px;
--mks-space-10: 40px;
--mks-space-12: 48px;
--mks-space-16: 64px;
--mks-space-20: 80px;
/* ── Radius ───────────────────────────────────────────────────────────
Architectural. Sharp-ish — 4px base, 8px cards, 999 chips. NOT pillow. */
--mks-radius-sm: 2px; /* badge text container */
--mks-radius-md: 4px; /* default control */
--mks-radius-lg: 8px; /* card, popup body */
--mks-radius-xl: 12px; /* welcome hero card */
--mks-radius-full: 999px;/* chips, recording dot */
/* ── Borders + shadows ───────────────────────────────────────────────
One pixel hairline, low-elevation shadows.
Restrained — no big card drop-shadows. */
--mks-border-width: 1px;
/* Hairline shadow — for buttons */
--mks-shadow-1: 0 1px 0 rgba(24, 27, 42, 0.04),
0 1px 2px rgba(24, 27, 42, 0.06);
/* Card shadow — popup elevation */
--mks-shadow-2: 0 1px 2px rgba(24, 27, 42, 0.06),
0 4px 12px rgba(24, 27, 42, 0.08);
/* Floating — modal / tooltip */
--mks-shadow-3: 0 2px 4px rgba(24, 27, 42, 0.08),
0 12px 32px rgba(24, 27, 42, 0.12);
/* Inset — sunken surfaces, fields */
--mks-shadow-inset: inset 0 1px 0 rgba(24, 27, 42, 0.04);
/* Focus ring — visible against any surface, color-independent */
--mks-shadow-focus: 0 0 0 3px rgba(24, 27, 42, 0.18);
/* ── Motion ───────────────────────────────────────────────────────────
Quiet. No bounces. Reduced-motion is honored at the component level. */
--mks-dur-fast: 120ms;
--mks-dur-base: 200ms;
--mks-dur-slow: 320ms;
--mks-ease-out: cubic-bezier(0.2, 0.6, 0.2, 1);
--mks-ease-in-out: cubic-bezier(0.4, 0, 0.2, 1);
/* ── Layout ──────────────────────────────────────────────────────────*/
--mks-popup-w: 320px;
--mks-popup-min-h: 180px;
--mks-welcome-max-w: 720px;
}
/* Dark theme — applied via .dark on root OR @media (prefers-color-scheme).
Used for the dark popup variant, smoke diagnostic overlay, and any
future dark Chrome theme support. */
.dark, [data-theme="dark"] {
--mks-surface: var(--mks-ink-900);
--mks-surface-raised: var(--mks-ink-800);
--mks-surface-sunken: #11131e;
--mks-surface-inverse: var(--mks-linen-50);
--mks-fg-1: #ece7dc;
--mks-fg-2: #a4a7b8;
--mks-fg-3: #7a7e94;
--mks-fg-disabled: #5b5f76;
--mks-fg-inverse: var(--mks-ink-900);
--mks-border: rgba(243, 238, 228, 0.08);
--mks-border-strong: rgba(243, 238, 228, 0.14);
--mks-border-focus: var(--mks-linen-50);
--mks-shadow-focus: 0 0 0 3px rgba(243, 238, 228, 0.24);
}
/* ── Semantic typography helpers ──────────────────────────────────────
Apply these classes; do not redefine sizes ad-hoc. */
.mks-display-1 {
font-family: var(--mks-font-display);
font-size: var(--mks-text-3xl);
line-height: var(--mks-lh-tight);
letter-spacing: var(--mks-tracking-display);
font-weight: var(--mks-weight-regular);
color: var(--mks-fg-1);
}
.mks-display-2 {
font-family: var(--mks-font-display);
font-size: var(--mks-text-2xl);
line-height: var(--mks-lh-tight);
letter-spacing: var(--mks-tracking-display);
font-weight: var(--mks-weight-regular);
color: var(--mks-fg-1);
}
.mks-h1 {
font-family: var(--mks-font-display);
font-size: var(--mks-text-xl);
line-height: var(--mks-lh-tight);
letter-spacing: var(--mks-tracking-tight);
font-weight: var(--mks-weight-regular);
color: var(--mks-fg-1);
}
.mks-h2 {
font-family: var(--mks-font-ui);
font-size: var(--mks-text-lg);
line-height: var(--mks-lh-snug);
font-weight: var(--mks-weight-semibold);
color: var(--mks-fg-1);
}
.mks-h3 {
font-family: var(--mks-font-ui);
font-size: var(--mks-text-md);
line-height: var(--mks-lh-snug);
font-weight: var(--mks-weight-semibold);
color: var(--mks-fg-1);
}
.mks-body {
font-family: var(--mks-font-ui);
font-size: var(--mks-text-base);
line-height: var(--mks-lh-base);
color: var(--mks-fg-1);
}
.mks-body-sm {
font-family: var(--mks-font-ui);
font-size: var(--mks-text-sm);
line-height: var(--mks-lh-base);
color: var(--mks-fg-2);
}
.mks-caption {
font-family: var(--mks-font-ui);
font-size: var(--mks-text-xs);
line-height: var(--mks-lh-snug);
color: var(--mks-fg-3);
}
.mks-eyebrow {
font-family: var(--mks-font-ui);
font-size: var(--mks-text-xs);
line-height: var(--mks-lh-snug);
letter-spacing: var(--mks-tracking-caps);
text-transform: uppercase;
font-weight: var(--mks-weight-semibold);
color: var(--mks-fg-2);
}
.mks-mono {
font-family: var(--mks-font-mono);
font-size: var(--mks-text-sm);
line-height: var(--mks-lh-base);
color: var(--mks-fg-1);
}
.mks-badge-label {
font-family: var(--mks-font-ui);
font-size: var(--mks-text-xs);
line-height: 1;
letter-spacing: var(--mks-tracking-caps);
text-transform: uppercase;
font-weight: var(--mks-weight-bold);
}
/* Accessibility — honor reduced-motion */
@media (prefers-reduced-motion: reduce) {
:root {
--mks-dur-fast: 0ms;
--mks-dur-base: 0ms;
--mks-dur-slow: 0ms;
}
}
</style>
<style>
* { box-sizing: border-box; margin: 0; padding: 0; }
html, body { background: var(--mks-linen-50); color: var(--mks-fg-1); font-family: var(--mks-font-ui); -webkit-font-smoothing: antialiased; text-rendering: optimizeLegibility; }
body { padding: 56px 24px 96px; }
.page { max-width: 880px; margin: 0 auto; }
/* ── Masthead ──────────────────────────────────────────────────── */
.masthead { display: grid; grid-template-columns: 1fr auto; gap: 24px; align-items: end; padding-bottom: 22px; border-bottom: 1px solid var(--mks-border-strong); }
.masthead__doc { font-family: var(--mks-font-mono); font-size: 11px; color: var(--mks-fg-3); letter-spacing: 0.16em; text-transform: uppercase; margin-bottom: 14px; }
.masthead h1 { font-family: var(--mks-font-display); font-size: 56px; font-weight: 400; letter-spacing: -0.02em; line-height: 1.02; color: var(--mks-fg-1); }
.masthead h1 em { font-style: italic; color: var(--mks-madder-600); font-weight: 400; }
.masthead__meta { font-family: var(--mks-font-mono); font-size: 11px; color: var(--mks-fg-3); line-height: 1.7; text-align: right; }
.masthead__meta strong { color: var(--mks-fg-1); font-weight: 500; }
/* ── TL;DR ─────────────────────────────────────────────────────── */
.tldr { margin-top: 28px; padding: 22px 24px; background: var(--mks-linen-100); border-left: 3px solid var(--mks-ink-900); border-radius: 0 var(--mks-radius-md) var(--mks-radius-md) 0; }
.tldr p { font-family: var(--mks-font-display); font-size: 19px; line-height: 1.45; color: var(--mks-fg-1); letter-spacing: -0.005em; }
.tldr p + p { margin-top: 10px; font-family: var(--mks-font-ui); font-size: 14px; color: var(--mks-fg-2); line-height: 1.55; letter-spacing: 0; }
/* ── Section ───────────────────────────────────────────────────── */
section { margin-top: 56px; }
.sec-head { display: flex; align-items: baseline; gap: 16px; padding-bottom: 14px; border-bottom: 1px solid var(--mks-border); }
.sec-head__num { font-family: var(--mks-font-mono); font-size: 12px; color: var(--mks-madder-600); font-weight: 500; letter-spacing: 0.08em; }
.sec-head__h { font-family: var(--mks-font-display); font-size: 28px; font-weight: 400; letter-spacing: -0.01em; color: var(--mks-fg-1); line-height: 1.1; }
.sec-head__count { margin-left: auto; font-family: var(--mks-font-mono); font-size: 11px; color: var(--mks-fg-3); letter-spacing: 0.08em; }
.lede { font-size: 14.5px; color: var(--mks-fg-2); line-height: 1.6; margin: 18px 0 22px; max-width: 640px; }
/* ── Decision cards ────────────────────────────────────────────── */
.decisions { display: flex; flex-direction: column; gap: 12px; }
.decision { padding: 18px 20px; background: var(--mks-linen-50); border: 1px solid var(--mks-border); border-radius: var(--mks-radius-md); display: grid; grid-template-columns: 26px 1fr auto; gap: 14px; align-items: start; }
.decision__check { width: 18px; height: 18px; border: 1.5px solid var(--mks-border-strong); border-radius: 3px; background: var(--mks-linen-100); margin-top: 1px; }
.decision__body { min-width: 0; }
.decision__id { font-family: var(--mks-font-mono); font-size: 10.5px; color: var(--mks-fg-3); letter-spacing: 0.08em; text-transform: uppercase; }
.decision__q { font-family: var(--mks-font-display); font-size: 18px; font-weight: 500; letter-spacing: -0.005em; line-height: 1.3; color: var(--mks-fg-1); margin-top: 3px; }
.decision__prop { margin-top: 6px; font-size: 13.5px; line-height: 1.55; color: var(--mks-fg-2); }
.decision__prop b { font-weight: 600; color: var(--mks-fg-1); }
.decision__alts { margin-top: 6px; font-size: 12.5px; color: var(--mks-fg-3); font-family: var(--mks-font-mono); }
.decision__owner { font-family: var(--mks-font-mono); font-size: 10.5px; letter-spacing: 0.04em; color: var(--mks-ink-700); background: var(--mks-linen-100); padding: 4px 8px; border-radius: 999px; white-space: nowrap; align-self: start; }
/* ── Files needed ──────────────────────────────────────────────── */
.files { display: flex; flex-direction: column; }
.file { display: grid; grid-template-columns: 28px 1.2fr 1.4fr auto; gap: 14px; padding: 14px 0; border-top: 1px solid var(--mks-border); align-items: baseline; }
.file:first-of-type { border-top: 0; }
.file__priority { font-family: var(--mks-font-mono); font-size: 11px; font-weight: 600; }
.file__priority.p0 { color: var(--mks-madder-600); }
.file__priority.p1 { color: var(--mks-amber-600); }
.file__priority.p2 { color: var(--mks-fg-3); }
.file__path { font-family: var(--mks-font-mono); font-size: 12px; color: var(--mks-fg-1); word-break: break-all; }
.file__what { font-size: 13px; line-height: 1.5; color: var(--mks-fg-2); }
.file__what b { color: var(--mks-fg-1); font-weight: 500; }
.file__floor { font-family: var(--mks-font-mono); font-size: 10.5px; color: var(--mks-fg-3); white-space: nowrap; }
/* ── Acceptance ────────────────────────────────────────────────── */
.accept { display: grid; grid-template-columns: 1fr 1fr; gap: 12px; }
.accept-item { padding: 14px 16px; border: 1px solid var(--mks-border); background: var(--mks-linen-50); border-radius: var(--mks-radius-md); display: flex; flex-direction: column; gap: 4px; }
.accept-item__k { font-family: var(--mks-font-mono); font-size: 10.5px; color: var(--mks-madder-600); letter-spacing: 0.08em; }
.accept-item__v { font-size: 13px; line-height: 1.5; color: var(--mks-fg-1); }
.accept-item__v small { display: block; color: var(--mks-fg-3); font-size: 11.5px; margin-top: 4px; font-family: var(--mks-font-mono); }
/* ── Next steps ────────────────────────────────────────────────── */
.next { display: grid; grid-template-columns: auto 1fr; gap: 14px 18px; align-items: start; }
.next__when { font-family: var(--mks-font-mono); font-size: 11px; color: var(--mks-fg-3); letter-spacing: 0.08em; text-transform: uppercase; padding-top: 3px; }
.next__what { font-size: 14px; line-height: 1.55; color: var(--mks-fg-1); padding-bottom: 14px; border-bottom: 1px dashed var(--mks-border); }
.next__what:last-of-type, .next__when:last-of-type { border-bottom: 0; padding-bottom: 0; }
.next__what b { font-weight: 600; }
/* ── Footer ────────────────────────────────────────────────────── */
.foot { margin-top: 64px; padding-top: 22px; border-top: 1px solid var(--mks-border-strong); display: flex; justify-content: space-between; align-items: center; font-family: var(--mks-font-mono); font-size: 11px; color: var(--mks-fg-3); }
.foot__brand { display: flex; align-items: center; gap: 8px; font-family: var(--mks-font-display); font-size: 14px; color: var(--mks-fg-1); letter-spacing: -0.005em; }
/* Weave divider sized for section breaks */
.weave { height: 1px; background-image: repeating-linear-gradient(90deg, var(--mks-border-strong) 0 12px, transparent 12px 18px, var(--mks-border-strong) 18px 30px, transparent 30px 36px); }
@media (max-width: 720px) {
.masthead { grid-template-columns: 1fr; }
.masthead__meta { text-align: left; }
.masthead h1 { font-size: 40px; }
.file { grid-template-columns: 1fr; gap: 4px; }
.accept { grid-template-columns: 1fr; }
.decision { grid-template-columns: 26px 1fr; }
.decision__owner { grid-column: 2; margin-top: 6px; }
}
</style>
</head>
<body>
<div class="page">
<header class="masthead">
<div>
<div class="masthead__doc">Memo · design + brand handoff</div>
<h1>What I need<br>to finish, <em>and from whom.</em></h1>
</div>
<div class="masthead__meta">
<strong>From</strong> Design system (this project)<br>
<strong>To</strong> Design team · brand team<br>
<strong>Date</strong> 17 May 2026<br>
<strong>Status</strong> draft — every choice is reversible
</div>
</header>
<div class="tldr">
<p>I committed to a creative direction so the system would <em>run</em>. Eight decisions in that direction need a yes / override from you, and six files need to land in this repo before the extension can stop loading fonts from a CDN and stop shipping the placeholder square-and-dot PNG.</p>
<p>Nothing here is locked. Override anything; the tokens are wired so a re-skin is a single-file edit.</p>
</div>
<!-- ────────────────────────────────────────────────────────────── -->
<section>
<div class="sec-head">
<span class="sec-head__num">§ 01</span>
<h2 class="sec-head__h">Decisions to confirm or override</h2>
<span class="sec-head__count">8 items</span>
</div>
<p class="lede">Each one currently has a proposed direction shipping in <code class="mks-mono" style="font-size:12.5px">colors_and_type.css</code> and the UI kit. Tick the box if you accept; replace inline if you want a different answer.</p>
<div class="decisions">
<div class="decision">
<div class="decision__check"></div>
<div class="decision__body">
<div class="decision__id">D-01 · Public display name</div>
<div class="decision__q">Is <b>"Mokosh"</b> the right <code class="mks-mono">manifest.json:name</code>?</div>
<div class="decision__prop">Proposing the codename surfaces externally as the public name. Alternative is keeping "AI Call Recorder" for store discoverability, or coining something new.</div>
<div class="decision__alts">alt → "AI Call Recorder" · "Mokosh — Session Capture" · "Mokosh / АИ Регистратор"</div>
</div>
<span class="decision__owner">brand</span>
</div>
<div class="decision">
<div class="decision__check"></div>
<div class="decision__body">
<div class="decision__id">D-02 · Tagline</div>
<div class="decision__q">Confirm <b>«Тридцать секунд назад, всегда под рукой.»</b></div>
<div class="decision__prop">EN parallel: <i>Thirty seconds ago, always within reach.</i> Used on welcome hero + <code class="mks-mono">manifest.json:description</code>.</div>
</div>
<span class="decision__owner">brand</span>
</div>
<div class="decision">
<div class="decision__check"></div>
<div class="decision__body">
<div class="decision__id">D-03 · Voice register</div>
<div class="decision__q">Two-register copy — terse RU on toolbar / popup / notification; bilingual RU+EN on welcome only.</div>
<div class="decision__prop">Calm, operationally serious. Sentence case. Periods. No emoji. No exclamation marks. Address with «вы» on welcome; imperative verbs in popup.</div>
</div>
<span class="decision__owner">brand</span>
</div>
<div class="decision">
<div class="decision__check"></div>
<div class="decision__body">
<div class="decision__id">D-04 · Palette direction</div>
<div class="decision__q">"Loom" — linen + ink + dye-named accents. Light-primary with dark sibling.</div>
<div class="decision__prop">Madder rust for REC is the boldest call. Alt is conventional material-red (<code class="mks-mono">#D32F2F</code>) if rust reads off-brand.</div>
<div class="decision__alts">override → flag the WCAG-AA-validated hex you'd prefer for any of madder / moss / amber / brick</div>
</div>
<span class="decision__owner">design</span>
</div>
<div class="decision">
<div class="decision__check"></div>
<div class="decision__body">
<div class="decision__id">D-05 · Type pairing</div>
<div class="decision__q">Newsreader (display) · IBM Plex Sans (UI) · IBM Plex Mono (mono).</div>
<div class="decision__prop">All three OFL, all three cover Cyrillic. If a licensed face is preferred (e.g. an in-house family), name it and I'll rethread.</div>
</div>
<span class="decision__owner">design</span>
</div>
<div class="decision">
<div class="decision__check"></div>
<div class="decision__body">
<div class="decision__id">D-06 · Mark concept</div>
<div class="decision__q">2×2 weave intersection — see <code class="mks-mono">assets/mokosh-mark.svg</code>.</div>
<div class="decision__prop">References the goddess-of-weaving etymology without being illustrative. Holds at 16 px. Override with anything from a wordmark-only lockup to an illustrated scene.</div>
</div>
<span class="decision__owner">design</span>
</div>
<div class="decision">
<div class="decision__check"></div>
<div class="decision__body">
<div class="decision__id">D-07 · Iconography</div>
<div class="decision__q">Lucide — line, 1.5 stroke, 24 grid.</div>
<div class="decision__prop">Open-licensed (ISC). Bundle locally for MV3. Alternative is a custom set or Phosphor / Heroicons. Tabler is the other strong line option.</div>
</div>
<span class="decision__owner">design</span>
</div>
<div class="decision">
<div class="decision__check"></div>
<div class="decision__body">
<div class="decision__id">D-08 · Per-state icon swap</div>
<div class="decision__q">Stick with <b>neutral mark + dynamic badge</b>, or commission per-state PNG sets?</div>
<div class="decision__prop">Per-state requires 9 additional PNGs (3 sizes × 3 states) and a perf-costed <code class="mks-mono">chrome.action.setIcon</code> swap on every state change. Default direction stays with the badge.</div>
<div class="decision__alts">see <code class="mks-mono">assets-spec.md</code> A-06 for the deliverable list if you pick swap</div>
</div>
<span class="decision__owner">design</span>
</div>
</div>
</section>
<!-- ────────────────────────────────────────────────────────────── -->
<section>
<div class="sec-head">
<span class="sec-head__num">§ 02</span>
<h2 class="sec-head__h">Files I need landed in this repo</h2>
<span class="sec-head__count">6 deliverables</span>
</div>
<p class="lede">Priorities map to the engineering plan in the original <code class="mks-mono">assets-spec.md</code>. P0 unblocks shipping a real branded build; P1 finishes the welcome surface; P2 is polish.</p>
<div class="files">
<div class="file">
<span class="file__priority p0">P0</span>
<span class="file__path">fonts/newsreader-{400,500,600}.woff2<br>fonts/ibm-plex-sans-{400,500,600,700}.woff2<br>fonts/ibm-plex-mono-{400,500}.woff2</span>
<span class="file__what"><b>Webfont WOFF2 files.</b> Currently loaded from Google Fonts via <code class="mks-mono">@import</code>. MV3 CSP forbids remote <code class="mks-mono">@font-face</code> at runtime — production must bundle. I'll rewire <code class="mks-mono">colors_and_type.css</code> to local rules once these land.</span>
<span class="file__floor">Cyrillic ✓ · WOFF2</span>
</div>
<div class="file">
<span class="file__priority p0">P0</span>
<span class="file__path">assets/extension-icons/icon16.png<br>assets/extension-icons/icon48.png<br>assets/extension-icons/icon128.png</span>
<span class="file__what"><b>Branded extension icons.</b> The three files currently in that folder are the upstream engineering placeholders (dark square + green dot). Rasterise from <code class="mks-mono">assets/mokosh-mark.svg</code> — or supply a different mark if D-06 is overridden.</span>
<span class="file__floor">≥ 200 B · 500 B · 1 KB</span>
</div>
<div class="file">
<span class="file__priority p1">P1</span>
<span class="file__path">assets/extension-icons/icon192.png</span>
<span class="file__what"><b>Hi-DPI notification icon.</b> Optional but recommended for retina rendering of <code class="mks-mono">chrome.notifications.create</code>.</span>
<span class="file__floor">≥ 2 KB</span>
</div>
<div class="file">
<span class="file__priority p1">P1</span>
<span class="file__path">copy/welcome.ru.md</span>
<span class="file__what"><b>Final RU copy review.</b> Hero title, three step bodies, three privacy cards. My draft in <code class="mks-mono">ui_kits/extension/Welcome.jsx</code> is a working strawman.</span>
<span class="file__floor">brand sign-off</span>
</div>
<div class="file">
<span class="file__priority p1">P1</span>
<span class="file__path">copy/welcome.en.md</span>
<span class="file__what"><b>English parallel-text subhead.</b> One line under the hero title. Brand decides whether to extend bilingual treatment to the step bodies.</span>
<span class="file__floor">brand sign-off</span>
</div>
<div class="file">
<span class="file__priority p2">P2</span>
<span class="file__path">assets/icon-{rec,off,err}-{16,48,128}.png</span>
<span class="file__what"><b>Per-state icon variants</b> — only if D-08 lands on the swap direction. 9 files total.</span>
<span class="file__floor">conditional</span>
</div>
</div>
</section>
<!-- ────────────────────────────────────────────────────────────── -->
<section>
<div class="sec-head">
<span class="sec-head__num">§ 03</span>
<h2 class="sec-head__h">Acceptance criteria</h2>
<span class="sec-head__count">non-creative · binding</span>
</div>
<p class="lede">These are engineering / accessibility floors, not creative direction. Anything you ship has to clear them.</p>
<div class="accept">
<div class="accept-item"><span class="accept-item__k">WCAG AA</span><span class="accept-item__v">4.5 : 1 normal text, 3 : 1 large. <small>Current palette is pre-validated; overrides need re-validation.</small></span></div>
<div class="accept-item"><span class="accept-item__k">Cyrillic ✓</span><span class="accept-item__v">Every chosen face renders Russian glyphs without fallback. <small>Plex + Newsreader currently pass.</small></span></div>
<div class="accept-item"><span class="accept-item__k">MV3 CSP</span><span class="accept-item__v">No remote font / script loads at runtime. <small>Bundle everything locally in <code class="mks-mono" style="font-size:11px">dist/</code>.</small></span></div>
<div class="accept-item"><span class="accept-item__k">Notification floor</span><span class="accept-item__v"><code class="mks-mono" style="font-size:12px">iconUrl</code> ≥ 128 px PNG, ≥ 1 KB. <small>Chrome's <code class="mks-mono" style="font-size:11px">imageUtil</code> silently rejects smaller files.</small></span></div>
<div class="accept-item"><span class="accept-item__k">Badge floor</span><span class="accept-item__v">Badge text ≤ 4 characters. <small>Chrome truncates beyond. "REC" / "ERR" both fit.</small></span></div>
<div class="accept-item"><span class="accept-item__k">Reduced-motion</span><span class="accept-item__v">All transitions collapse to 0 ms under <code class="mks-mono" style="font-size:11px">prefers-reduced-motion</code>. <small>Wired in <code class="mks-mono" style="font-size:11px">colors_and_type.css</code>.</small></span></div>
<div class="accept-item"><span class="accept-item__k">Colour-independence</span><span class="accept-item__v">Every state pairs colour with text or shape. <small>Badge carries REC / ERR text alongside the colour.</small></span></div>
<div class="accept-item"><span class="accept-item__k">Focus visible</span><span class="accept-item__v">3 px halo on all interactive elements. <small><code class="mks-mono" style="font-size:11px">--mks-shadow-focus</code> works on any surface.</small></span></div>
</div>
</section>
<!-- ────────────────────────────────────────────────────────────── -->
<section>
<div class="sec-head">
<span class="sec-head__num">§ 04</span>
<h2 class="sec-head__h">What I will do once you reply</h2>
<span class="sec-head__count">turnaround</span>
</div>
<p class="lede">Round-trip cost so you can scope a review window.</p>
<div class="next">
<span class="next__when">+ 0 h</span>
<span class="next__what"><b>Acknowledge each decision.</b> If overridden, re-thread the token in <code class="mks-mono">colors_and_type.css</code> and re-render every preview card + UI-kit surface that depends on it.</span>
<span class="next__when">+ 1 h</span>
<span class="next__what"><b>Swap the font import to local <code class="mks-mono">@font-face</code></b> once the WOFF2 files arrive in <code class="mks-mono">fonts/</code>. Verify Cyrillic specimen still renders in <code class="mks-mono">preview/type-ui.html</code>.</span>
<span class="next__when">+ 1 h</span>
<span class="next__what"><b>Replace the placeholder PNGs</b> in <code class="mks-mono">assets/extension-icons/</code> the moment the rasterised versions arrive. Re-shoot <code class="mks-mono">preview/brand-extension-icons.html</code> so the card stops carrying the substitution flag.</span>
<span class="next__when">+ 2 h</span>
<span class="next__what"><b>Inline final RU + EN copy</b> in <code class="mks-mono">ui_kits/extension/Welcome.jsx</code>. Lock badge tooltips and notification strings in a single source-of-truth file for engineering to wire.</span>
<span class="next__when">+ ?</span>
<span class="next__what"><b>Optional follow-on:</b> dark-theme popup variant, smoke-test diagnostic overlay re-skin, animated icon (if D-08 chooses swap), and a tone audit of every Russian string in the original codebase against the agreed register.</span>
</div>
</section>
<div class="foot">
<div class="foot__brand">
<img src="assets/mokosh-mark.svg" width="18" height="18" alt="">
<span>Mokosh</span>
</div>
<span>handoff · v1 · 17.05.2026</span>
</div>
</div>
</body>
</html>

View File

@@ -0,0 +1,273 @@
/* ─────────────────────────────────────────────────────────────────────────
Mokosh Design System — colors_and_type.css
Single source of truth for foundational tokens.
Surfaces: Chrome MV3 popup, welcome page, notification copy, toolbar.
Audience: Russian-first operators. Cyrillic coverage required.
───────────────────────────────────────────────────────────────────── */
/* Fonts (bundled locally; MV3 CSP forbids remote @font-face at runtime).
Substitution flag — until licensed files arrive, these are loaded from
Google Fonts in PREVIEW HTML only. Production bundles ship the same
families locally from /fonts/. See fonts/README.md. */
@import url('https://fonts.googleapis.com/css2?family=Newsreader:ital,opsz,wght@0,6..72,400;0,6..72,500;0,6..72,600;1,6..72,400&family=IBM+Plex+Sans:wght@400;500;600;700&family=IBM+Plex+Mono:wght@400;500&display=swap');
:root {
/* ── Palette ──────────────────────────────────────────────────────────
The "loom" palette. Warm-earthy, NOT clinical-blue. Reads as
restrained, professional, slightly hand-made — distinct from the
standard SaaS Material defaults the engineering placeholder used.
Each step validated for WCAG AA against its intended pair. */
/* Linen — primary surface family (warm off-white through stone) */
--mks-linen-50: #faf7f1; /* page background */
--mks-linen-100: #f3eee4; /* card / popup surface */
--mks-linen-200: #e8e0d0; /* hairline / divider on linen */
--mks-linen-300: #d4c9b5; /* muted edge */
/* Ink — text + inverse surface family (warm near-black indigo) */
--mks-ink-900: #181b2a; /* primary text, deepest surface */
--mks-ink-800: #232639; /* dark surface */
--mks-ink-700: #2f3349; /* dark surface raised */
--mks-ink-500: #5b5f76; /* secondary text on linen */
--mks-ink-400: #7a7e94; /* tertiary text, captions */
--mks-ink-300: #a4a7b8; /* disabled text */
/* Accents — state colors. Each is a dye reference. */
--mks-madder-600: #b2543d; /* REC accent — Rubia tinctorum dye */
--mks-madder-700: #963f29; /* REC pressed */
--mks-madder-100: #f5e2db; /* REC tint */
--mks-moss-600: #5a7349; /* success / saved */
--mks-moss-700: #455a38;
--mks-moss-100: #e2e9da;
--mks-amber-600: #c98b3a; /* warning / recoverable error */
--mks-amber-100: #f6e6c8;
--mks-brick-600: #a23a2b; /* unrecoverable error */
--mks-brick-100: #f0d5cf;
/* Semantic — point these at the palette. Use these in components. */
--mks-surface: var(--mks-linen-50);
--mks-surface-raised: var(--mks-linen-100);
--mks-surface-sunken: var(--mks-linen-200);
--mks-surface-inverse: var(--mks-ink-900);
--mks-fg-1: var(--mks-ink-900); /* primary text */
--mks-fg-2: var(--mks-ink-500); /* secondary text */
--mks-fg-3: var(--mks-ink-400); /* tertiary / caption */
--mks-fg-disabled: var(--mks-ink-300);
--mks-fg-inverse: var(--mks-linen-50);
--mks-border: var(--mks-linen-200);
--mks-border-strong: var(--mks-linen-300);
--mks-border-focus: var(--mks-ink-900);
--mks-rec: var(--mks-madder-600);
--mks-success: var(--mks-moss-600);
--mks-warning: var(--mks-amber-600);
--mks-error: var(--mks-brick-600);
/* ── Type ─────────────────────────────────────────────────────────────
Three families. Newsreader for display (serif with calm character).
IBM Plex Sans for UI body (excellent Cyrillic; not Inter/Roboto).
IBM Plex Mono for diagnostic / timer overlays. */
--mks-font-display: "Newsreader", "Iowan Old Style", "Times New Roman", serif;
--mks-font-ui: "IBM Plex Sans", "Segoe UI", -apple-system, BlinkMacSystemFont, sans-serif;
--mks-font-mono: "IBM Plex Mono", "SF Mono", Menlo, Consolas, monospace;
/* Base type scale — ratio ~1.2, tuned for popup density.
Smallest size 11px is reserved for badge labels only. */
--mks-text-xs: 11px;
--mks-text-sm: 13px;
--mks-text-base: 15px;
--mks-text-md: 17px;
--mks-text-lg: 20px;
--mks-text-xl: 28px;
--mks-text-2xl: 40px;
--mks-text-3xl: 56px;
--mks-lh-tight: 1.15;
--mks-lh-snug: 1.3;
--mks-lh-base: 1.5;
--mks-weight-regular: 400;
--mks-weight-medium: 500;
--mks-weight-semibold: 600;
--mks-weight-bold: 700;
/* Display tracking — Newsreader at large sizes wants negative tracking */
--mks-tracking-display: -0.015em;
--mks-tracking-tight: -0.005em;
--mks-tracking-base: 0;
--mks-tracking-loose: 0.04em; /* eyebrow / caps labels */
--mks-tracking-caps: 0.08em; /* badge text REC / ERR */
/* ── Spacing ──────────────────────────────────────────────────────────
4px base. Steps named by px multiple for clarity. */
--mks-space-1: 4px;
--mks-space-2: 8px;
--mks-space-3: 12px;
--mks-space-4: 16px;
--mks-space-5: 20px;
--mks-space-6: 24px;
--mks-space-8: 32px;
--mks-space-10: 40px;
--mks-space-12: 48px;
--mks-space-16: 64px;
--mks-space-20: 80px;
/* ── Radius ───────────────────────────────────────────────────────────
Architectural. Sharp-ish — 4px base, 8px cards, 999 chips. NOT pillow. */
--mks-radius-sm: 2px; /* badge text container */
--mks-radius-md: 4px; /* default control */
--mks-radius-lg: 8px; /* card, popup body */
--mks-radius-xl: 12px; /* welcome hero card */
--mks-radius-full: 999px;/* chips, recording dot */
/* ── Borders + shadows ───────────────────────────────────────────────
One pixel hairline, low-elevation shadows.
Restrained — no big card drop-shadows. */
--mks-border-width: 1px;
/* Hairline shadow — for buttons */
--mks-shadow-1: 0 1px 0 rgba(24, 27, 42, 0.04),
0 1px 2px rgba(24, 27, 42, 0.06);
/* Card shadow — popup elevation */
--mks-shadow-2: 0 1px 2px rgba(24, 27, 42, 0.06),
0 4px 12px rgba(24, 27, 42, 0.08);
/* Floating — modal / tooltip */
--mks-shadow-3: 0 2px 4px rgba(24, 27, 42, 0.08),
0 12px 32px rgba(24, 27, 42, 0.12);
/* Inset — sunken surfaces, fields */
--mks-shadow-inset: inset 0 1px 0 rgba(24, 27, 42, 0.04);
/* Focus ring — visible against any surface, color-independent */
--mks-shadow-focus: 0 0 0 3px rgba(24, 27, 42, 0.18);
/* ── Motion ───────────────────────────────────────────────────────────
Quiet. No bounces. Reduced-motion is honored at the component level. */
--mks-dur-fast: 120ms;
--mks-dur-base: 200ms;
--mks-dur-slow: 320ms;
--mks-ease-out: cubic-bezier(0.2, 0.6, 0.2, 1);
--mks-ease-in-out: cubic-bezier(0.4, 0, 0.2, 1);
/* ── Layout ──────────────────────────────────────────────────────────*/
--mks-popup-w: 320px;
--mks-popup-min-h: 180px;
--mks-welcome-max-w: 720px;
}
/* Dark theme — applied via .dark on root OR @media (prefers-color-scheme).
Used for the dark popup variant, smoke diagnostic overlay, and any
future dark Chrome theme support. */
.dark, [data-theme="dark"] {
--mks-surface: var(--mks-ink-900);
--mks-surface-raised: var(--mks-ink-800);
--mks-surface-sunken: #11131e;
--mks-surface-inverse: var(--mks-linen-50);
--mks-fg-1: #ece7dc;
--mks-fg-2: #a4a7b8;
--mks-fg-3: #7a7e94;
--mks-fg-disabled: #5b5f76;
--mks-fg-inverse: var(--mks-ink-900);
--mks-border: rgba(243, 238, 228, 0.08);
--mks-border-strong: rgba(243, 238, 228, 0.14);
--mks-border-focus: var(--mks-linen-50);
--mks-shadow-focus: 0 0 0 3px rgba(243, 238, 228, 0.24);
}
/* ── Semantic typography helpers ──────────────────────────────────────
Apply these classes; do not redefine sizes ad-hoc. */
.mks-display-1 {
font-family: var(--mks-font-display);
font-size: var(--mks-text-3xl);
line-height: var(--mks-lh-tight);
letter-spacing: var(--mks-tracking-display);
font-weight: var(--mks-weight-regular);
color: var(--mks-fg-1);
}
.mks-display-2 {
font-family: var(--mks-font-display);
font-size: var(--mks-text-2xl);
line-height: var(--mks-lh-tight);
letter-spacing: var(--mks-tracking-display);
font-weight: var(--mks-weight-regular);
color: var(--mks-fg-1);
}
.mks-h1 {
font-family: var(--mks-font-display);
font-size: var(--mks-text-xl);
line-height: var(--mks-lh-tight);
letter-spacing: var(--mks-tracking-tight);
font-weight: var(--mks-weight-regular);
color: var(--mks-fg-1);
}
.mks-h2 {
font-family: var(--mks-font-ui);
font-size: var(--mks-text-lg);
line-height: var(--mks-lh-snug);
font-weight: var(--mks-weight-semibold);
color: var(--mks-fg-1);
}
.mks-h3 {
font-family: var(--mks-font-ui);
font-size: var(--mks-text-md);
line-height: var(--mks-lh-snug);
font-weight: var(--mks-weight-semibold);
color: var(--mks-fg-1);
}
.mks-body {
font-family: var(--mks-font-ui);
font-size: var(--mks-text-base);
line-height: var(--mks-lh-base);
color: var(--mks-fg-1);
}
.mks-body-sm {
font-family: var(--mks-font-ui);
font-size: var(--mks-text-sm);
line-height: var(--mks-lh-base);
color: var(--mks-fg-2);
}
.mks-caption {
font-family: var(--mks-font-ui);
font-size: var(--mks-text-xs);
line-height: var(--mks-lh-snug);
color: var(--mks-fg-3);
}
.mks-eyebrow {
font-family: var(--mks-font-ui);
font-size: var(--mks-text-xs);
line-height: var(--mks-lh-snug);
letter-spacing: var(--mks-tracking-caps);
text-transform: uppercase;
font-weight: var(--mks-weight-semibold);
color: var(--mks-fg-2);
}
.mks-mono {
font-family: var(--mks-font-mono);
font-size: var(--mks-text-sm);
line-height: var(--mks-lh-base);
color: var(--mks-fg-1);
}
.mks-badge-label {
font-family: var(--mks-font-ui);
font-size: var(--mks-text-xs);
line-height: 1;
letter-spacing: var(--mks-tracking-caps);
text-transform: uppercase;
font-weight: var(--mks-weight-bold);
}
/* Accessibility — honor reduced-motion */
@media (prefers-reduced-motion: reduce) {
:root {
--mks-dur-fast: 0ms;
--mks-dur-base: 0ms;
--mks-dur-slow: 0ms;
}
}