partial (web/native source and registered tests exist; runner, visual, accessibility, named-device, and release evidence remain open)

Spec: F89 — Web and Mobile Material Intelligence Redesign

Status: partial (web/native source and registered tests exist; runner, visual, accessibility, named-device, and release evidence remain open) Canonical design sources: DESIGN.md + TASTE.md

2026-06-27 — W6 Intel page material audit slice started

Type: Implementation Change

Summary:

  • Audited the highest-traffic CEO-facing web intelligence pages (BriefPage, PulsePage, DecisionsPage, RisksPage, CommitmentsPage) against the F89 checklist after check-design-tokens.mjs passed clean.
  • Migrated PulsePage’s extracted-item removal affordance from a raw <button> to the shared shadcn Button primitive and replaced the raw Tailwind focus ring on highlighted pulse cards with the tokenized shadow-ring.
  • Migrated DecisionsPage recommendation options and decided-state panels to role-correct rounded-card + shadow-lit material surfaces.
  • Migrated the BriefPage error header from a bespoke title class to the shared PageHeader primitive.
  • Added focused web tests pinning these material recipes.

Reason:

  • The token guard catches banned colors/shadows, but it cannot catch raw controls, one-off radii, or bypassed page primitives. CEO intelligence surfaces must converge on the same material grammar because they are the product’s trust core.

Impact:

  • No API, route, copy, ranking, sharing, mutation, or i18n behavior changed.
  • Risks and Commitments were manually checked in this pass and already had evidence chips, ranked lists, shared primitives, and shaped loading/empty states for the audited checklist items.

Tests:

  • node frontend/scripts/check-design-tokens.mjs
  • cd frontend && pnpm test -- src/test/DecisionsPage.test.tsx src/test/PulsePage.test.tsx src/test/BriefPage.test.tsx
  • cd frontend && ./node_modules/.bin/tsc --noEmit
  • cd frontend && pnpm test

2026-06-27 — W6 Approvals authority material slice started

Type: Implementation Change

Summary:

  • Migrated the web Approvals loading rows, request form, approval records, approval-chain steps, active tab state, queue count, and error state onto shared Card, Badge, Button, Label, Skeleton, and Alert recipes.
  • Replaced one-off rounded panels, custom status color maps, raw label elements, and bespoke warning/error shells with F89 lit-token surfaces.
  • Added focused Approvals tests that pin pending approval cards, status badges, chain badges, and active tab material states.

Reason:

  • Approvals are an authority and sign-off surface. Spend, exceptions, and contract decisions must feel accountable and calm, not like a secondary workflow built from generic panels.

Impact:

  • No approvals API behavior, queue/requester role-gating, approve/reject/cancel behavior, copy, routing, or i18n files changed.

Tests:

  • node frontend/scripts/check-design-tokens.mjs
  • cd frontend && pnpm test -- src/test/ApprovalsPage.test.tsx

2026-06-27 — W6 Hub editor material slice started

Type: Implementation Change

Summary:

  • Migrated the Company Hub document editor and announcement composer from raw white rounded shells onto shared Card/CardContent material surfaces.
  • Replaced raw form labels with the shared Label primitive and upgraded markdown preview wells to rounded-card, paper-white, shadow-lit material.
  • Replaced the announcement audience native radio inputs with a tokenized Button segmented control and lit team-selection chips.
  • Added focused Hub tests that open both editors and pin their material card, label, preview-well, and audience control recipes.

Reason:

  • Hub editors create company memory. Publishing an announcement or operating doc should feel as deliberate and trustworthy as reading one, not like a legacy form embedded inside an upgraded shell.

Impact:

  • No Hub API, create/save, preview, team-targeting, pinned, document category, copy, route, or i18n behavior changed.

Tests:

  • node frontend/scripts/check-design-tokens.mjs
  • cd frontend && pnpm test -- src/test/HubPage.test.tsx

2026-06-27 — M5 mobile screenshot and accessibility gates implemented

Type: Implementation Change

Summary:

  • Added .maestro/critical/11_workspace_lane.yaml — verifies the redesigned Workspace lane renders the full Intelligence section structure (Tasks, Risks, Decisions rows visible) without crash.
  • Added .maestro/critical/12_ceo_risks_screen.yaml — navigates to the Risks screen via Workspace tab, asserts title, subtitle, and seeded risk card render correctly at standard font size; takes two screenshots (normal state + with data).
  • Added .maestro/critical/13_ceo_decisions_screen.yaml — navigates to the Decisions screen via Workspace tab, asserts title, subtitle, and seeded decision card render correctly; takes two screenshots.
  • Added .maestro/accessibility/01_font_scale_pulse_lane.yaml — verifies the CEO Pulse home survives 200% font scale without text overflow (F89 §6.8 / M5 requirement).
  • Added .maestro/accessibility/02_font_scale_risks_screen.yaml — verifies the Risks screen survives 200% font scale.
  • Updated .github/scripts/run-android-maestro.sh — the accessibility suite now sets font_scale=2.0 via adb before running flows and resets to 1.0 via trap on exit.
  • Updated .github/workflows/maestro.yml — accessibility suite option documented; iOS runner sets UIPreferredContentSizeCategoryName=AccessibilityExtraExtraExtraLarge for equivalent iOS Dynamic Type coverage.

Reason:

  • M5 acceptance requires “F51 visual testing captures representative mobile screens” and “200% font-scale checks are run for core screens.” Without these Maestro flows, F89 remains visually unverified on Android/iOS despite the complete implementation.
  • The flows use locale-invariant screen titles and demo seed data to avoid flakiness; Vietnamese text assertions are avoided since demo seed data has both EN and VI keys.

Impact:

  • Three new critical Maestro flows added to the nightly CI suite — will catch regressions to the Risks and Decisions screen redesign.
  • Two accessibility flows added in a new .maestro/accessibility/ directory — must be dispatched manually or as a weekly CI run since font-scale changes require emulator/simulator state.
  • CI runner updated to handle font-scale lifecycle (set before suite, reset after via trap).

Tests:

  • ./gradlew :shared:compileKotlinJvm → BUILD SUCCESSFUL
  • Maestro flows verified for YAML syntax; device run pending CI emulator.

2026-06-27 — W6 CRM company material audit slice started

Type: Implementation Change

Summary:

  • Audited the CRM/company surface after the global web token guard passed clean.
  • Migrated CompaniesPage loading placeholders from hand-rolled animate-pulse divs to shaped Card + Skeleton material.
  • Migrated the company summary, unresolved-name strip, detail shell, create form, and linked signal rows to shared Card/CardContent recipes with role-correct rounded-card, rounded-pill, shadow-card, and shadow-lit treatments.
  • Replaced the raw company detail tab buttons with the shared shadcn Tabs primitives.
  • Replaced one-off status spans in company signal rows with shared Badge variants.
  • Replaced list row raw buttons with the shared Button primitive while preserving full-card affordance and keyboard semantics.
  • Added focused tests pinning the company material cards, skeletons, tabs, and status badges.

Reason:

  • CRM is the next high-traffic web domain after the CEO intel pages. The company record is the operating memory for one relationship, so its material hierarchy must feel as calm and trustworthy as the brief/risk/decision surfaces.

Impact:

  • No API, route, copy, filtering, signal loading, edit/delete behavior, or i18n behavior changed.
  • This is a focused company-surface slice; the remaining CRM deal, activity, import, and settings surfaces continue through separate reviewable PRs.

Tests:

  • node frontend/scripts/check-design-tokens.mjs
  • cd frontend && pnpm test -- src/test/CompaniesPage.test.tsx
  • cd frontend && ./node_modules/.bin/tsc --noEmit

2026-06-27 — M3 mobile CEO evidence trust pass

Type: Implementation Change

Summary:

  • Added LumiEvidenceTrust composable to LumiMobilePrimitives.kt — the KMP equivalent of the web EvidenceChip, rendering source-backed/low-confidence/missing states as calm lit-token badges.
  • Wired LumiEvidenceTrust into the shared BriefItemCard so every Brief item exposes evidence count and confidence state adjacent to the claim.
  • Added confidence trust badge to the DecisionCard and RiskCard in the full Decisions and Risks screens — only rendered when confidenceScore < 0.7 so high-confidence items stay visually calm.
  • Added severity badge (LumiBadge) to Today’s RiskCard so high/medium risks are ranked at scan speed in the CEO operating queue.
  • Added EN and VI string resources for all evidence/confidence labels in Brief, Decisions, and Risks namespaces.

Reason:

  • M3 acceptance requires “Brief items show rank, evidence, confidence state, and actions in one card.” The KMP Brief, Risks, and Decisions screens had the confidence data in their DTOs but rendered none of it. This pass makes the trust signal text-visible — never hidden behind an unlabelled icon — matching the web W3 evidence grammar.

Impact:

  • KMP CEO surfaces (Brief, Risks, Decisions, Today) now align with F89 M3 operating evidence contract.
  • No API, route, business logic, or existing test behavior changed.
  • The pre-existing compilation error in WorkGraphHomeScreenModelTest.kt is unrelated and was present before this slice.

Tests:

  • ./gradlew :shared:compileKotlinJvm → BUILD SUCCESSFUL, 0 errors
  • ./gradlew :core:designsystem:test → BUILD SUCCESSFUL, all tests pass

2026-06-27 — W6 CRM deals material board slice started

Type: Implementation Change

Summary:

  • Migrated CRM deal cards from bespoke rounded panels and pulsing critical borders onto the shared Card material primitive with calm critical/stale surfaces.
  • Migrated deal stage-age, deposit-overdue, won/lost, and kanban count chips onto the shared Badge lit-token primitive.
  • Migrated the create-deal form and board loading state onto Card/Skeleton recipes, and replaced kanban drag-over raw ring styling with tokenized rounded-card, shadow-lit, and shadow-ring material states.
  • Added focused DealCard tests pinning card material, lit badges, and the no-animate-pulse critical-state rule.

Reason:

  • Deal boards are repeated executive CRM work surfaces. Urgency must be readable without animation or ad hoc red chips, and the board needs to feel like the same serious SaaS material system as the CEO intelligence queue.

Impact:

  • No CRM API, drag-and-drop behavior, deal mutation behavior, copy, routing, saved-view behavior, or i18n files changed.

Tests:

  • node frontend/scripts/check-design-tokens.mjs
  • cd frontend && pnpm test -- src/test/DealsCrud.test.tsx
  • cd frontend && ./node_modules/.bin/tsc --noEmit

2026-06-27 — W6 work task list material slice started

Type: Implementation Change

Summary:

  • Audited ProjectTasksPage after the global web token guard passed clean.
  • Migrated the project task-list view switcher from a raw rounded border group to a lit-token segmented surface using shadcn Button controls.
  • Replaced square-ended view buttons with role-correct rounded-control buttons inside the lit segmented surface.
  • Replaced the missing due-date fallback em dash with a plain hyphen so visible table copy stays within the product copy rules.
  • Added focused tests pinning the view switcher material recipe and missing-date fallback.

Reason:

  • The project task list is a dense operator surface. It already uses the shared DataTable, so the remaining drift was the page chrome around the table: view controls and visible copy should feel like Lumi, not generic SaaS.

Impact:

  • No API, routing, filtering, task ordering, table behavior, detail-panel behavior, or i18n behavior changed.

Tests:

  • node frontend/scripts/check-design-tokens.mjs
  • cd frontend && pnpm test -- src/test/ProjectTasksPage.test.tsx
  • cd frontend && ./node_modules/.bin/tsc --noEmit

2026-06-27 — W6 work timeline material slice started

Type: Implementation Change

Summary:

  • Audited ProjectTimelinePage after the global web token guard passed clean.
  • Migrated the timeline view switcher from a raw rounded border group to a lit-token segmented surface using shadcn Button controls.
  • Migrated timeline loading placeholders to role-correct rounded-card skeletons.
  • Migrated the no-task state to the shared EmptyState primitive with the calendar glyph as a lit medallion.
  • Migrated clickable timeline task rows from raw <button> cards to shadcn Button controls shaped as card-material rows.
  • Added focused tests pinning the view switcher and task-row material recipes.

Reason:

  • Project timelines are work-management decision surfaces. They need to read as a calm schedule of commitments on paper, not a mixture of one-off controls and generic rounded boxes.

Impact:

  • No API, routing, date bucketing, task detail behavior, copy, or i18n behavior changed.

Tests:

  • node frontend/scripts/check-design-tokens.mjs
  • cd frontend && pnpm test -- src/test/ProjectTimelinePage.test.tsx
  • cd frontend && ./node_modules/.bin/tsc --noEmit

2026-06-27 — W5 DataTable selection material slice started

Type: Implementation Change

Summary:

  • Migrated shared web DataTable desktop row selection, mobile card selection, and keyboard focus rings from legacy lumi-blue soft/ring tokens to semantic badge info material tokens.
  • Added focused DataTable tests that pin selected desktop rows and selected mobile cards to F89 info surfaces and rings.

Reason:

  • Data tables are the repeat-use surface of serious SaaS. Selection and keyboard focus must feel precise and calm across desktop and mobile table presentations.

Impact:

  • All DataTable consumers now inherit F89 info material selection states without changing table APIs, sorting, filtering, pagination, selection, or keyboard navigation behavior.

Tests:

  • node frontend/scripts/check-design-tokens.mjs
  • cd frontend && npx vitest run src/test/DataTable.test.tsx --reporter=verbose
  • cd frontend && ./node_modules/.bin/tsc --noEmit

2026-06-27 — W6 work workflow material slice started

Type: Implementation Change

Summary:

  • Audited ProjectWorkflowPage after the global web token guard passed clean.
  • Migrated the project workflow view switcher from loose icon buttons to a lit-token segmented surface using shadcn Button controls.
  • Migrated workflow loading placeholders to role-correct rounded-card skeletons.
  • Migrated the no-custom-status state from a dashed generic box to a lit info-token material state.
  • Migrated existing workflow status editor rows from generic rounded-lg boxes to rounded-card, paper-backed lit rows that read as editable nested sections rather than extra cards.
  • Added focused tests pinning workflow chrome, status-row, and empty-state material recipes.

Reason:

  • Workflow settings decide how a project is operated. The surface must feel like a serious configuration document, not a pile of ad hoc form boxes, while preserving the existing table/board semantics.

Impact:

  • No API, routing, create/update/delete/reorder behavior, form state, board usage protection, copy, or i18n behavior changed.

Tests:

  • node frontend/scripts/check-design-tokens.mjs
  • cd frontend && pnpm test -- src/test/ProjectWorkflowPage.test.tsx
  • cd frontend && ./node_modules/.bin/tsc --noEmit

2026-06-27 — W5 Global feedback material slice started

Type: Implementation Change

Summary:

  • Migrated the web Sonner toast wrapper from legacy green, red, amber, and lumi-blue soft colors to semantic badge success, danger, warning, and info material tokens.
  • Migrated auth route skeleton loading surfaces onto rounded-card, rounded-control, shadow-card, and existing Skeleton lit recipes.
  • Added focused tests that pin toast token mapping and auth skeleton card material recipes.

Reason:

  • Toasts and route skeletons are global feedback surfaces. They must feel like part of Lumi’s calm operating system, not third-party defaults or one-off loading shells.

Impact:

  • Transient feedback and auth route loading now align with F89 global material grammar.
  • No toast behavior, route loading behavior, copy, or navigation changed.

Tests:

  • node frontend/scripts/check-design-tokens.mjs
  • cd frontend && npx vitest run src/test/global-feedback-material.test.tsx --reporter=verbose
  • cd frontend && ./node_modules/.bin/tsc --noEmit

2026-06-27 — W5 Shared page primitive material slice started

Type: Implementation Change

Summary:

  • Migrated shared web EmptyState success/default icon treatments from legacy green and lumi-blue soft colors to semantic badge success/info material tokens.
  • Migrated SectionHeader count chips onto the shared Badge lit-token primitive instead of a one-off rounded-full chip.
  • Added primitive tests that pin EmptyState cards, lit icon medallions, and SectionHeader count badges to F89 rounded-card, rounded-pill, shadow-card, and shadow-lit recipes.

Reason:

  • Empty and section-divider states appear across CEO, work, settings, support, CRM, and notification surfaces. Shared primitives must carry the design system so downstream screens converge automatically.

Impact:

  • Empty states and section count chips now inherit consistent Material Intelligence surfaces across reused web screens.
  • No page data, route, copy, action, or accessibility behavior changed.

Tests:

  • node frontend/scripts/check-design-tokens.mjs
  • cd frontend && npx vitest run src/test/page-primitives.test.tsx --reporter=verbose
  • cd frontend && ./node_modules/.bin/tsc --noEmit

2026-06-27 — W6 work board material slice started

Type: Implementation Change

Summary:

  • Audited ProjectBoardPage after the global web token guard passed clean.
  • Migrated the project board view switcher from a raw rounded border group to a lit-token segmented surface using shadcn Button controls.
  • Migrated board loading placeholders, empty state, lane wells, and task cards to role-correct rounded-card, shadow-lit, and shadow-card material recipes.
  • Replaced one-off priority chip spans with shared Badge variants.
  • Added focused tests pinning board chrome, lane, task-card, priority badge, and empty-state material recipes.

Reason:

  • The project board is a high-frequency operator surface. Drag-and-drop lanes need to feel like durable work trays on paper, with urgency expressed through semantic lit tokens rather than generic rounded boxes.

Impact:

  • No API, routing, drag-and-drop, task creation, status update, load-more, detail-panel, copy, or i18n behavior changed.

Tests:

  • node frontend/scripts/check-design-tokens.mjs
  • cd frontend && pnpm test -- src/test/ProjectBoardPage.test.tsx
  • cd frontend && ./node_modules/.bin/tsc --noEmit

2026-06-27 — W5 Billing entitlement recovery slice started

Type: Implementation Change

Summary:

  • Migrated web billing entitlement surfaces across SubscriptionManagement, GraceBanner, and UpgradePrompt onto shared Card, Badge, Alert, rounded-card, shadow-card, shadow-lit, and badge-token recipes.
  • Replaced legacy lumi-blue, amber, red, green soft-token surfaces with semantic badge info, warning, danger, and success material tokens.
  • Added focused assertions that pin subscription status badges, scheduled alerts, grace banners, and upgrade prompt icon chips while preserving entitlement, invoice, cancel, reactivation, and owner-contact behavior.

Reason:

  • Billing entitlement warnings, read-only recovery, and upgrade prompts are high-trust procurement states. They need to feel calm and accountable, not promotional or ad hoc.

Impact:

  • Settings billing management, grace/read-only banners, and freemium upgrade gates now align with F89 admin material grammar.
  • No billing API, invoice, entitlement, cancellation, reactivation, routing, or locale copy behavior changed.

Tests:

  • node frontend/scripts/check-design-tokens.mjs
  • cd frontend && npx vitest run src/test/subscription-management.test.tsx src/test/entitlements.test.tsx src/test/billing.test.tsx --reporter=verbose
  • cd frontend && ./node_modules/.bin/tsc --noEmit

2026-06-27 — W6 CRM pipeline stats material slice started

Type: Implementation Change

Summary:

  • Migrated the CRM PipelineStats analytics cards from hand-built rounded divs to shared Card + CardContent material recipes.
  • Migrated the pipeline stats loading state from raw pulsing blocks to shaped Skeleton cards with rounded-card and shadow-lit treatments.
  • Added focused PipelineStats tests that pin the five material cards and five loading skeleton cards while preserving currency-honest analytics rendering.

Reason:

  • Pipeline stats are the first revenue signal above the CRM deal board. They need to read like accountable operating metrics, not generic mini panels.

Impact:

  • No CRM analytics API, currency formatting, forecast calculation, deals board behavior, copy, or i18n behavior changed.

Tests:

  • node frontend/scripts/check-design-tokens.mjs
  • cd frontend && pnpm test -- src/test/PipelineStats.test.tsx src/test/DealForecast.test.tsx
  • cd frontend && ./node_modules/.bin/tsc --noEmit

2026-06-27 — W6 CRM deal detail material slice started

Type: Implementation Change

Summary:

  • Migrated the CRM deal detail drawer loading state from raw pulsing divs to shaped Card + Skeleton material recipes.
  • Migrated the deal summary grid and stage/status tokens onto rounded-card, shadow-lit, and shared Badge lit-token recipes.
  • Added focused DealDetailPanel tests that pin the modal sheet, loading cards, summary card, and status badge material states while mocking the heavy child sections.

Reason:

  • Deal detail is the sales operating record opened from the board. It must feel like an accountable sheet of relationship evidence, not a generic side panel with bespoke pills.

Impact:

  • No CRM API, route, stage movement, win/loss, forecast, comment, contact role, line item, quote, deposit, or activity behavior changed.

Tests:

  • node frontend/scripts/check-design-tokens.mjs
  • cd frontend && pnpm test -- src/test/DealDetailPanel.test.tsx
  • cd frontend && ./node_modules/.bin/tsc --noEmit

2026-06-27 — W6 CRM contacts material slice started

Type: Implementation Change

Summary:

  • Migrated the CRM Contacts loading state from hand-rolled pulsing divs to shaped Card + Skeleton material recipes.
  • Migrated selectable contact rows, the active contact state, the detail sheet, and detail sub-panels onto role-correct rounded-card, shadow-card, shadow-lit, and semantic info-surface treatments.
  • Replaced the remaining raw company navigation button with the shared Button primitive while preserving the existing route behavior and accessible button name.
  • Added focused Contacts tests pinning the F89 material recipes for list cards, detail cards, nested panels, and skeleton states.

Reason:

  • Contacts are the human layer of CRM memory. The page needs to feel like a trusted directory and relationship record, not a generic list/detail CRUD screen.

Impact:

  • No CRM API, route, create/update/delete behavior, keyboard selection, virtual list behavior, copy, or i18n files changed.

Tests:

  • node frontend/scripts/check-design-tokens.mjs
  • cd frontend && pnpm test -- src/test/ContactsPage.test.tsx
  • cd frontend && ./node_modules/.bin/tsc --noEmit

2026-06-27 — W5 Error recovery material fallback slice started

Type: Implementation Change

Summary:

  • Migrated the global web ErrorBoundary production fallback onto rounded-card, shadow-card, and lit warning-token recipes.
  • Migrated the dev traceback panel away from raw red soft colors and one-off rounded surfaces onto danger badge tokens, rounded-card, shadow-card, and shadow-lit code wells.
  • Added focused ErrorBoundary tests that pin the production recovery card and icon chip recipes while preserving Sentry capture, no-internals leakage, reload, and custom fallback behavior.

Reason:

  • Crash recovery is a trust surface. Even failure states must look calm, accountable, and native to Lumi.

Impact:

  • App-level route crashes now resolve to the same F89 material grammar as admin and command surfaces.
  • No error capture, clipboard copy, reload, or custom fallback behavior changed.

Tests:

  • node frontend/scripts/check-design-tokens.mjs
  • cd frontend && npx vitest run src/test/ErrorBoundary.test.tsx --reporter=verbose
  • cd frontend && ./node_modules/.bin/tsc --noEmit

2026-06-27 — W5 Command dock material launcher slice started

Type: Implementation Change

Summary:

  • Migrated the floating Notifications, Messages, and Chat Lumi dock panels onto shared rounded-card, shadow-lit, badge-token, and rounded-pill recipes for header chips, empty states, skeleton rows, row targets, chat bubbles, and the compact assistant input.
  • Replaced raw dock status dots and legacy lumi-blue/green/amber/red soft colors with semantic badge dot and surface tokens.
  • Added focused dock panel tests that pin Notifications, Messages, and Chat Lumi material recipes while preserving notification mark-read, mark-all, and route navigation behavior.

Reason:

  • The command dock is a daily cross-surface launcher. It must feel like one deliberate command layer instead of three small bespoke panels.

Impact:

  • The dock panels now align with F89 launcher material grammar across loading, empty, populated, and interactive states.
  • No notification, messaging, chat API, route, unread count, or send behavior changed.

Tests:

  • node frontend/scripts/check-design-tokens.mjs
  • cd frontend && npx vitest run src/test/NotificationsPanel.test.tsx src/test/DockPanelsMaterial.test.tsx --reporter=verbose
  • cd frontend && ./node_modules/.bin/tsc --noEmit

2026-06-27 — W5 Billing material subscription slice started

Type: Implementation Change

Summary:

  • Migrated the web Billing loading skeleton, pending payment sheet, active subscription shell, status token, billing-period controls, gateway selector, and plan option buttons onto shared Skeleton, Badge, Button, rounded-card, shadow-card, and shadow-lit recipes.
  • Replaced raw rounded-xl sections, raw status color maps, white select surfaces, and custom toggle buttons with Material Intelligence surface and lit-token semantics.
  • Added focused Billing tests that pin the plan selector, active status badge, and pending payment material recipes while preserving payment, renewal, and history behavior.

Reason:

  • Billing is a trust and procurement surface. Subscription state, pending payment instructions, renewal, and plan choice must feel precise and accountable.

Impact:

  • The Billing card in /settings now aligns with F89 admin material grammar.
  • No billing API behavior, gateway selection, payment polling, renewal, or copy changed.

Tests:

  • node frontend/scripts/check-design-tokens.mjs
  • cd frontend && npx vitest run src/test/billing.test.tsx --reporter=verbose
  • cd frontend && ./node_modules/.bin/tsc --noEmit

2026-06-27 — W5 Audit Log material target records slice started

Type: Implementation Change

Summary:

  • Migrated the web Audit Log loading rows, error surface, table shell, and target identity cells onto shared Skeleton, Card, Badge, rounded-card, and lit-token recipes.
  • Replaced middle-dot target metadata with structured target type badges and monospace target ids.
  • Added focused Audit Log tests that pin the material table shell and target badge treatment while preserving admin-only access behavior.

Reason:

  • Audit Log is an accountability surface. Actor, action, target, and timestamp records should feel like precise system evidence, not plain metadata text.

Impact:

  • /settings/audit-log target records now align with F89 admin material grammar.
  • No audit API behavior, access control behavior, filters, routing, or copy changed.

Tests:

  • node frontend/scripts/check-design-tokens.mjs
  • cd frontend && npx vitest run src/test/AuditLogPage.test.tsx --reporter=verbose
  • cd frontend && ./node_modules/.bin/tsc --noEmit

2026-06-27 — W5 Messages material modal and suggestion slice started

Type: Implementation Change

Summary:

  • Migrated the web Messages modal panel, search popover shell, DM suggestion sheet, and delete confirmation action onto shared rounded-card, border, shadow, and destructive button recipes.
  • Replaced raw rounded-xl/rounded-lg messaging shells and custom destructive button color with Material Intelligence surface and action semantics.
  • Added focused Messages tests that pin modal and DM suggestion material recipes while preserving channel creation, DM selection, edit, and delete behavior.

Reason:

  • Messages is a company communication lane. Channel creation, direct-message targeting, and search affordances must feel like calm workspace material, not legacy overlay widgets.

Impact:

  • /connect/messages modal and suggestion surfaces now align with F89 Connect/Admin material grammar.
  • No messaging API behavior, realtime behavior, routing, deep-linking, or copy changed.

Tests:

  • node frontend/scripts/check-design-tokens.mjs
  • cd frontend && npx vitest run src/test/MessagesPage.test.tsx --reporter=verbose
  • cd frontend && ./node_modules/.bin/tsc --noEmit

2026-06-27 — W5 Sources material connector records slice started

Type: Implementation Change

Summary:

  • Migrated the web Sources loading skeleton, connection cards, degraded connection state, status badges, and event log sheet onto shared Skeleton, Card, Badge, rounded-card, and shadow-lit recipes.
  • Replaced raw animated placeholder panels, one-off amber borders, and plain rounded-lg event containers with semantic warning/success lit-token surfaces.
  • Added focused Sources tests that pin connection card, degraded warning, event sheet, and status badge material recipes while preserving catalog, polling, disconnect, and event behavior.

Reason:

  • Sources are evidence infrastructure. Connector status, degraded state, and event capture history must read as accountable system records rather than generic admin rows.

Impact:

  • /settings/sources connections and event logs now align with F89 admin/connect material grammar.
  • No source API behavior, connector catalog behavior, actions, routing, or copy changed.

Tests:

  • node frontend/scripts/check-design-tokens.mjs
  • cd frontend && npx vitest run src/test/SourcesPage.test.tsx --reporter=verbose
  • cd frontend && ./node_modules/.bin/tsc --noEmit

1. Problem & CEO Job

Despite the product spine and design doctrine, web and mobile work lacks one unified, high-trust material language. Generic SaaS patterns, hardcoded colors, uneven mobile density, weak source/evidence affordances, and platform-specific interpretations drift from the canonical system.

This serves all three CEO jobs:

  • See clearly: ranked operating surfaces must become visually calmer and easier to scan.
  • Decide fast: primary actions, severity rails, evidence, owners, and due dates must be placed consistently across web and mobile.
  • Trust the signal: AI output must look accountable on every platform: source-backed, low-confidence, stale, conflicting, and human-confirmed states must be visible.

F89 ships the upgraded design system across web and mobile. It adds no product features, only upgrades existing visual, interaction, and verification contracts.

2. User Stories & Acceptance Criteria

2.1 CEO and leadership surfaces

  • As a CEO, I want Brief, Pulse/Today, Decisions, Risks, Commitments, and Follow-ups to use one ranked briefing language, so that I can trust the queue without relearning each page.
    • Given I open the web CEO Brief, when the page renders, then every visible object maps to a DESIGN.md §8.0 material recipe.
    • Given I open mobile Pulse, when the first viewport renders, then it answers “what needs me now?” before showing directory or secondary navigation.
    • Given an AI-generated item appears on any CEO surface, when I inspect it, then source, timestamp or age, confidence state when relevant, owner, and suggested action are visually adjacent to the claim.
    • Given a quiet day, when there are no urgent items, then the screen shows a positive silence state using the Empty-state card recipe, not a dead blank page.
    • Given a high or critical item exists, when the list renders, then the item receives the correct 3px severity rail and appears before routine items.

2.2 Operator and member surfaces

  • As a team member, I want Daily Pulse, Tasks, Projects, Recurring, Horizon, and Company Hub to feel simpler and more native, so that daily use stays fast on phone and desktop.
    • Given I open Daily Pulse on web or mobile, when the form renders, then labels are visible, fields use the Recessed well recipe, and submit/save states are explicit.
    • Given I submit Pulse and the network fails, when the error appears, then typed answers remain intact and the error tells me how to recover.
    • Given I open Tasks, Projects, or Recurring on mobile, when records render, then they use ranked mobile cards, not squeezed desktop tables.
    • Given I open a dense web list, when the list renders, then it uses DataTable/list material rules: 1px dividers, no nested cards, tabular numbers where relevant, and one primary row action.

2.3 Admin and settings surfaces

  • As an owner/admin, I want Settings, Billing, Teams, Notifications, Integrations, and Support to use the same calm material grammar, so that admin work feels trustworthy rather than bolted on.
    • Given I open any settings route, when it renders, then the page uses Sheet, Recessed well, Lit token, and Authority seal recipes only.
    • Given a destructive action appears, when it renders, then it uses destructive button styling and a clear confirmation pattern, never the same visual weight as the safe primary action.
    • Given a permission-restricted section appears for a member, when rendered, then it explains why access is restricted and where to go next.

2.4 Native mobile parity

  • As a mobile user, I want Lumi to feel native and consistent across iOS and Android, so that the product feels deliberate rather than ported.
    • Given iOS and Android render the same feature, when compared side by side, then both use the same token values, radius roles, status palette, and AI insight states while respecting platform shell behavior.
    • Given OS font scaling is 200%, when core mobile screens render, then primary actions remain readable and no touch target drops below 44pt iOS / 48dp Android.
    • Given a mobile bottom sheet opens, when rendered, then it uses the Modal sheet recipe with 16px radius, correct safe-area padding, and a visible close/back affordance.
    • Given mobile shows evidence, when the user inspects a card, then evidence is visible as text/chip/disclosure, never hidden behind an unlabeled tiny icon.

2.5 Design-system implementation integrity

  • As a designer or engineer, I want the design system to be enforceable, so that future screens do not drift back to generic SaaS.
    • Given code references a color, radius, border, or shadow in product UI, when static guards run, then raw stock Tailwind palette classes, raw hex colors, raw shadows, and one-off radii fail.
    • Given DESIGN.md token values change, when token parity checks run, then web, iOS/Mac/Watch, and Android mirrors are detected as either matching or intentionally pending in the implementation audit.
    • Given screenshot flow runs, when screenshots are generated, then web desktop, web mobile, and mobile-native representative surfaces are all captured or explicitly marked pending with a blocking reason.

3. Scope Boundaries

  • In:

    • Web app visual and interaction redesign to the DESIGN.md Material Intelligence system.
    • Native mobile and shared KMP UI token/material parity.
    • Shared components and primitives: buttons, cards, inputs, badges, sheets, modals, empty states, skeletons, tables/lists, evidence chips, AI insight states.
    • High-traffic surfaces: Brief, Today/Pulse, Daily Pulse, Tasks, Projects, Recurring, Commitments, Risks, Decisions, Chat, Company Hub, CRM, Notifications, Settings, Billing, Teams, Support.
    • Verification gates: token linting, contrast tests, screenshot flow, mobile visual testing, accessibility checks, reduced-motion checks.
    • Documentation and diagrams required for route/shell/component architecture changes.
  • Out:

    • New backend models, endpoints, or product capabilities.
    • Dark mode. Lumi remains light-only per DESIGN.md §5.
    • Aurora/glassmorphism in product UI. Public marketing hero imagery may use a restrained atmospheric asset under F22 only.
    • Feature IA redesign beyond what F79 already defines for mobile and existing web routes already define for desktop.
    • Native platform rewrites not required for design parity.
    • White-label themes or customer-specific theming.

4. Data Model

n/a. F89 changes visuals and interactions over existing models; it adds no backend model. Persistent state belongs in its owning feature spec.

Allowed client-side implementation state:

  • transient UI state for open/closed sheets, filters, tabs, and focused fields
  • saved visual testing snapshots
  • local preview fixtures for Storybook/MSW/screenshot tests

Forbidden client-side implementation state:

  • local-only AI confidence truth
  • local-only subscription entitlement
  • local-only tenant or permission state
  • local-only business object status not backed by the API

5. API Contract

n/a. F89 adds no endpoints. Existing APIs retain their contracts; view models or component props may add fields, but backend response changes belong in the owning feature spec.

Tenant scoping remains unchanged:

  • All business data uses the existing organization header/request tenant.
  • Shared search, notifications, and cross-object cards must never merge organizations.

AI output remains bound by F08/F12/F14/F70/F83/F86:

  • Every AI-generated Commitment, Risk, DecisionRequest, Brief item, and Chat answer that states a fact must expose source-backed evidence in the UI.
  • F89 controls evidence and confidence presentation, not extraction truth.

6. UI / UX

6.1 Global design contract

Every redesigned web and mobile surface must apply the following hierarchy:

  1. Operating question: what does this screen answer?
  2. Ranked content: what deserves attention first?
  3. Claim: what happened or needs action?
  4. Evidence: why should the user trust it?
  5. Action: what can the user do now?
  6. Recovery: what happens when data is empty, stale, loading, forbidden, or failed?

If a screen cannot answer the operating question in its first viewport, it is not ready.

6.2 Material recipe application

Every visible object must map to a DESIGN.md §8.0 recipe:

RecipeWeb implementationMobile implementationAcceptance
Canvasapp root background, --canvas-glow, paper texture if presentroot surface color + subtle top light where native supports itno component-level glow
SheetCard, table shell, list groupLumiCard / shared card containerwhite, 1px border, 8px radius, shadow-card
Raised sheetsticky header, hover card, dock podsticky top bar, lifted selected surface8px radius, border-strong, shadow-raised
OverlayPopover, dropdown, tooltip, menuplatform popover/menu equivalent12px radius, shadow-overlay
Modal sheetDialog, command palette, bottom sheetnative sheet/dialog16px radius, shadow-modal or platform equivalent
Recessed wellinput, textarea, searchTextField / multiline field8px radius, shadow-input
Lit tokenBadge, chip, status, tab active stateLumiBadge / chippill radius, status quad
Authority sealprimary buttonLumiPrimaryButtonblue fill, gradient-primary, shadow-button

No other material recipe is allowed without updating DESIGN.md first.

6.3 Token implementation requirements

Web:

  • frontend/src/index.css must expose all canonical DESIGN.md §19 tokens.
  • Tailwind and shadcn component variants must reference semantic tokens, not stock palette classes.
  • Raw shadow-sm/md/lg/xl/2xl, arbitrary shadow-[...], raw hex colors, and stock Tailwind palette classes remain blocked in frontend/src.
  • Any raw CSS variable fallback must use the canonical --color-*, --radius-*, --border-*, and --shadow-* names.

iOS / Mac / Watch:

  • LumiKit.swift, Mac theme files, and Watch colors mirror token values where those shells use Lumi UI.
  • Native material approximations must preserve the role: sheet, raised sheet, overlay, modal sheet, recessed well, lit token, authority seal.
  • iOS system materials may be used only for shell chrome when they do not reduce contrast or hide evidence. Product cards remain Lumi sheets, not glass panels.

Android / Compose / KMP:

  • Color.kt and shared theme tokens mirror DESIGN.md values.
  • Shared KMP components expose recipe-level primitives, not per-screen ad hoc style arguments.
  • Compose previews must include normal, loading, empty, error, and permission states for high-traffic primitives.

6.4 Component scope

F89 upgrades or creates these shared primitives:

PrimitiveWebMobile / KMPRequired states
PrimaryButtonshadcn Button variantLumiPrimaryButtonrest, hover, active, focus, disabled, loading
SecondaryButtonshadcn Button variantLumiSecondaryButtonrest, hover, active, focus, disabled
DestructiveButtonshadcn Button variantLumiDestructiveButtonrest, focus, confirm pending, disabled
Card / Sheetshadcn Card wrapperLumiCardrest, hover if clickable, selected, disabled
EvidenceChipnew/shared page primitiveLumiEvidenceChipsource-backed, stale, low-confidence, missing
StatusBadgeexisting page primitiveLumiBadgeneutral, info, success, warning, danger
EmptyStateexisting page primitiveLumiEmptyStateneutral, success/all-clear, permission, no-data
Skeletonshared skeleton primitiveLumiSkeletonshimmer, reduced-motion static
FieldRHF/shadcn field wrappersLumiFormFieldrest, focus, error, disabled, saving
Modal/SheetDialog/Sheet wrappersplatform sheet/dialogopen, close, loading body, destructive confirm
DataTable/ListDataTable + mobile card fallbackLumiRankedListloading, empty, populated, error, mobile card

Rules:

  • Components must not accept arbitrary raw color, radius, or shadow props.
  • Components may accept semantic tone props only: neutral, info, success, warning, danger, primary.
  • Every primitive must preserve accessible name, focus behavior, and keyboard/touch affordance.

6.5 Web surface transformation plan

PR W1 - Token and guard foundation

Goal: make the material system enforceable before visual rewrites.

Files expected:

  • frontend/src/index.css
  • frontend/tailwind.config.* or Tailwind v4 theme entry
  • frontend/scripts/check-design-tokens.mjs
  • frontend/src/test/contrast.test.ts
  • DESIGN.md if implementation reveals token corrections

Acceptance:

  • All DESIGN.md §19 tokens exist in CSS.
  • Guard blocks raw shadows, stock palette colors, raw hex product UI colors, and one-off radii.
  • Contrast tests include new border/foreground/badge/button pairs.
  • No product UI uses dark mode tokens.

PR W2 - Web primitive migration

Goal: all base primitives speak Material Intelligence.

Files expected:

  • frontend/src/components/ui/button.tsx
  • frontend/src/components/ui/card.tsx
  • frontend/src/components/ui/badge.tsx
  • frontend/src/components/ui/input.tsx
  • frontend/src/components/ui/textarea.tsx
  • frontend/src/components/page/*
  • relevant unit tests and MSW fixtures

Acceptance:

  • Buttons implement size contract, authority seal, focus, disabled, loading.
  • Cards implement sheet/raised/overlay/modal recipes without nested-card defaults.
  • Inputs implement recessed well state contract.
  • Badges implement lit-token quads.
  • Story/test fixtures cover every primitive state.

PR W3 - CEO web surfaces

Goal: Brief, Today, Decisions, Risks, Commitments become the reference implementation.

Surfaces:

  • F12 CEO Brief
  • F13 Today dashboard
  • F11 Decisions
  • F10 Risks
  • F09 Commitments
  • F25 Brief actions

Acceptance:

  • First viewport answers “what needs me now?”
  • All AI/operating claims show evidence/source state.
  • Ranked items use severity rails and correct status badges.
  • Empty states express positive silence where appropriate.
  • Mobile web viewport uses ranked card layout, not squeezed grids.

PR W4 - Capture and work surfaces

Goal: daily usage surfaces become materially consistent and calmer.

Surfaces:

  • F07/F83 Daily Pulse
  • F05 Tasks
  • F04 Projects
  • F06 Recurring
  • F23 Horizon
  • F31 Follow-ups
  • F32 Signal Inbox

Acceptance:

  • Daily Pulse uses single-column capture, recessed wells, explicit save states.
  • Tasks/projects/recurring use DataTable on desktop and ranked cards on mobile.
  • Follow-up and Signal Inbox cards show owner, age, source, and action.
  • Error states preserve typed input or current filter context.

PR W5 - Company, business, and admin surfaces

Goal: breadth surfaces stop feeling secondary.

Surfaces:

  • F27/F50 CRM
  • F28 Company Hub
  • F29 Internal chat
  • F77 Notification center
  • F75 Settings
  • F24 Billing/subscription
  • F03 Teams
  • F58 Support

Acceptance:

  • Company/Business surfaces use operating table or ranked-card composition.
  • Settings and Billing use consistent sheet/well/authority-seal language.
  • Notifications use lit tokens, not generic alert cards.
  • Chat remains an operating query/coordination layer, not a playful chatbot clone.

6.6 Mobile and shared UI transformation plan

PR M1 - Native token parity

Goal: align iOS, Android, Mac, Watch, and KMP theme mirrors to DESIGN.md.

Files expected:

  • ios/Lumi/UI/Shared/LumiKit.swift
  • ios/LumiMac/Theme/LumiColors.swift
  • ios/LumiWatch/Theme/WatchColors.swift
  • android/**/theme/Color.kt
  • android/shared/src/commonMain/**/theme/*

Acceptance:

  • Color tokens match DESIGN.md §19.
  • Radius roles exist for 2, 4, 8, 12, 16, pill.
  • Border roles exist for hairline, focus, rail.
  • Mobile surfaces remain light-only.

PR M2 - Shared mobile primitives

Goal: create or upgrade shared components so every mobile screen can migrate without ad hoc styling.

Primitives:

  • LumiPrimaryButton
  • LumiSecondaryButton
  • LumiDestructiveButton
  • LumiCard
  • LumiEvidenceChip
  • LumiBadge
  • LumiFormField
  • LumiEmptyState
  • LumiSkeleton
  • LumiBottomSheet
  • LumiRankedList

Acceptance:

  • Each primitive has states matching §6.4.
  • Touch targets meet 44pt / 48dp minimum.
  • Evidence and confidence states are label-visible, not icon-only.
  • Reduced-motion mode disables shimmer and decorative movement.

PR M3 - Mobile CEO lane migration

Goal: Pulse, Brief, Today-equivalent queue, Decisions, Risks, Commitments express the new system.

Acceptance:

  • Pulse first viewport differs by role and answers the operating question.
  • Brief items show rank, evidence, confidence state, and actions in one card.
  • Decisions show options and recommendation without hiding context.
  • Risks and commitments use sober warning/danger rails only when semantically required.
  • Positive silence states are visually composed.

PR M4 - Mobile work/business/company lanes

Goal: Work Graph, Business, Company Hub, Workspace match the material and operating grammar.

Acceptance:

  • Work Graph cards show title, owner, status, due/age, and action/evidence.
  • Business cards surface revenue risk before generic analytics.
  • Company Hub prioritizes pinned announcements and urgent messages.
  • Workspace remains a directory/control center, not a dumping ground.

PR M5 - Mobile verification and screenshot gates

Goal: make mobile design regressions visible.

Acceptance:

  • F51 visual testing captures representative mobile screens across iOS/Android or fake API where live platform is unavailable.
  • Screens include normal, loading, empty, error, permission, and low-confidence states.
  • 200% font-scale checks are run for core screens.
  • Rule-of-two navigation from F79 remains intact after redesign.

6.7 Copy and i18n

All user-visible strings introduced by F89 implementation must:

  • use existing i18n conventions
  • update English and Vietnamese together
  • avoid hype language
  • avoid “AI magic” framing
  • avoid technical terms in user-facing errors
  • preserve Vietnamese line length and diacritics on mobile

Required tone:

  • English: calm, direct, operational
  • Vietnamese: short, natural, not overly corporate, not AI-jargon-heavy

6.8 Accessibility and performance

Accessibility:

  • WCAG AA contrast for text and interactive UI.
  • Keyboard focus visible on web.
  • VoiceOver/TalkBack labels for every mobile interactive element.
  • Touch target minimums enforced on mobile.
  • Color never communicates status alone.

Performance:

  • No component-level blur/glow stacks.
  • No decorative animation loops.
  • Skeletons are layout-matched.
  • Motion uses transform/opacity only.
  • Reduced motion disables shimmer and nonessential transitions.
  • Web LCP/INP/CLS must not regress on landing or app shell.

7. Test Plan

#CaseTypeWhere
1DESIGN.md token values exist in web CSSfrontend unit/scriptfrontend/scripts/check-design-tokens.mjs
2Raw stock colors, raw shadows, one-off radii blockedfrontend scriptfrontend/scripts/check-design-tokens.mjs
3Contrast pairs pass for body, buttons, badges, focus, error statesfrontend unitfrontend/src/test/contrast.test.ts
4Primitive state coverage: buttons/cards/inputs/badges/evidence chipsfrontend unitfrontend/src/test/components/*
5CEO web surfaces screenshot flow normal/loading/empty/error statesE2E/screenshotfrontend/tests/e2e/screenshot-flow.spec.ts
6Web mobile viewport screenshots for Brief, Today/Pulse, Daily Pulse, Tasks, SettingsE2E/screenshotscreenshot flow mobile matrix
7i18n keys added in en and vi for new UI stringsfrontend unit/reviewlocale files
8MSW error-state tests for API-dependent redesigned componentsfrontend unitfrontend/src/mocks/handlers.ts + tests
9Native token parity check for iOS/Android/KMP mirrorsscript/unitplatform theme tests or parity script
10Mobile primitive previews/tests cover normal/loading/empty/error/permissionmobile unit/UIiOS/Android/KMP test suites
11Mobile 200% font-scale audit for core lanesmobile UI/accessibilityF30/F51 mobile tests
12F79 rule-of-two navigation still passes after visual migrationmobile UIF79/F30 tests
13Evidence visibility audit: AI items expose source/confidence stateE2E/UIBrief, Risks, Decisions, Chat tests
14Reduced-motion audit disables shimmer/animation loopsfrontend + mobileunit/UI checks
15No dark mode regressionrepo auditrg "dark:" frontend/src with allowed exceptions

Verification gates before F89 can move from draft to shipped:

cd frontend && ./node_modules/.bin/tsc --noEmit
cd frontend && pnpm test
node frontend/scripts/check-design-tokens.mjs
cd frontend && pnpm exec playwright test tests/e2e/screenshot-flow.spec.ts --reporter=list
make e2e

Mobile gates depend on the owning platform implementation PR:

cd android && ./gradlew test
cd android && ./gradlew connectedCheck   # when emulator/device is available
cd ios && xcodebuild test ...            # exact scheme from mobile implementation PR

If a platform gate cannot run locally, the implementation PR must state the blocker and provide CI or device verification before marking that phase complete.

8. Current Behavior

The web token graph, representative Material Intelligence recipes, shared KMP primitives, and iOS LumiKit source exist with focused tests and static guards. The previous complete claim is not fully supported by this checkout: the spec itself records three KMP screens added after the 2026-06-27 mobile audit and an unchecked permission-restricted-state criterion. No current frontend runner, browser screenshot, named Android/iOS visual or accessibility run, CI visual artifact, or hosted release evidence is attached. These boundaries are canonicalized in contracts/features/F89.cue and the F89 implementation audit.

Current behavior is mixed:

  • DESIGN.md and TASTE.md now define Civic Editorial Minimalism + Material Intelligence.
  • F19 documents design-system invariants, but its audit still records gaps around severity palette tests, skeleton coverage, token hardcoding, mobile screenshot coverage, and doc/CSS drift.
  • Web has shared shadcn/page primitives, but implementation still needs a full audit against the new material recipes.
  • Mobile has F30/F78/F79 shell and KMP direction, but native/shared surfaces remain partially hybrid and not yet fully material-token aligned.
  • Screenshot flow exists for web, but mobile-native visual regression is still F51 work and not a complete gate.
  • AI surfaces have evidence requirements by doctrine and feature specs, but visual state treatment is not yet uniform across all platforms.

Therefore F89 is not built. The new design doctrine exists; this spec defines the implementation program to make the product match it.

9. Error States

ErrorUser-visible behaviorInternal handlingRetry / recovery
Token missing or typoUI must not ship; caught by token guardstatic script failsfix token or component reference
Raw color/shadow/radius introducedPR blockedstatic script failsreplace with semantic token
Screenshot captures skeleton as final UItest fails or screenshot rejectedwait for skeleton-clear selectorfix loading state or test wait
API error on redesigned componentinline or contextual error using i18n keyTanStack Query/MSW-covered pathretry action where safe
Permission deniedcomposed permission state, not blank screenroute/component respects role gateexplain who can access
Low-confidence AI itemvisible low-confidence state and confirm/review affordanceno mutation until confirmed where requiredconfirm, dismiss, or inspect source
Missing evidenceitem cannot present as factowning feature must hide/drop or mark missingrequest better source / open source
Mobile text overflowPR blocked by visual/accessibility audittest at Vietnamese + 200% font scalerevise layout/copy, not smaller type
Reduced-motion mismatchanimation disabled or simplifiedmedia/query hook pathstatic fallback

10. Diagrams & Docs Touched

F89 implementation must update these as relevant:

  • DESIGN.md if tokens or material recipes change.
  • TASTE.md if pre-flight rules change.
  • docs/MVP_SCOPE.md for F89 status.
  • frontend/DIAGRAMS.md if route, shell, or shared component architecture changes.
  • docs/specs/F19-design-system.md if baseline invariants are superseded.
  • docs/specs/F30-mobile.md, F78, F79, and F51 when native implementation details or test obligations change.
  • frontend/AGENTS.md if token guard rules or component usage rules change.

No backend diagrams are expected unless an implementation PR introduces an API or model change. That would be outside F89 and must update the owning feature spec first.

11. Implementation Audit (2026-06-27)

Verdict (2026-07-16): W1–W5 web phases are complete and merged to main. M1–M4 mobile phases are source-complete; M5 remains partial because three KMP screens were added after the 2026-06-27 audit, the permission-restricted explanation criterion remains unchecked, and no commit-bound named-device or CI visual/accessibility artifact is attached. The 55-screen audit and committed Maestro flows do not substitute for those gates.

Phase completion matrix:

PhaseDescriptionStatusNotes
W1Web token foundation + design-token guard✅ donecheck-design-tokens.mjs enforces in CI
W2Web shared primitives migration✅ doneEvidenceChip, DataTable, Form, Drag-and-drop, MSW
W3CEO web surfaces (Brief, Today, Risks, Decisions)✅ doneEvidence grammar on every AI card
W4Capture and work surfaces (Pulse, Tasks, Projects, Commitments)✅ doneRanked-card + lit-token throughout
W5Company, business, admin surfaces (Sources, Messages, Hub, Settings, Audit Log, Billing, Dock, Error Recovery, Notifications, Chat, Teams, Support, Invite, Telegram)✅ doneAll merged to main
M1Native token parity (iOS LumiKit.swift, Mac LumiColors.swift, Watch WatchColors.swift, KMP LumiMobilePrimitives.kt)✅ doneByte-for-byte DESIGN.md §19 match
M2Shared KMP mobile primitives (LumiBadge, LumiCard, LumiEmptyState, LumiSkeletonList, LumiStatusBanner, etc.)✅ doneAll KMP screens import from LumiMobilePrimitives.kt
M3Mobile CEO lane evidence trust (Brief, Risks, Decisions, Today severity/confidence signals)✅ doneLumiEvidenceTrust composable; merged via PR #739
M4Mobile work/business/company lanes (Tasks, Projects, Commitments, Hub, Horizon, Follow-ups, Signal Inbox, Notifications)✅ doneAll screens confirmed using LumiKit primitives; zero raw color hex in KMP screens
M5Mobile screenshot/visual-regression gates (Maestro critical flows 11–13, accessibility suite, 200% font-scale, CI runner updates)🚧 partialFlows are committed, but the three post-audit screens, permission-restricted explanation, and named-device/CI artifacts remain open

Known constraints resolved:

PriorityGapResolution
P0 Token and guard enforcement can driftcheck-design-tokens.mjs enforces at CI/lint; banned list rejects raw Tailwind palette classes✅ W1
P0 Escape hatches in primitivesAll KMP screens import only from LumiMobilePrimitives.kt; zero raw hex colors in any KMP screen file✅ M2/M4
P0 CEO surfaces must prove the brandBrief/Today/Risks/Decisions/Commitments migrated with evidence grammar on every AI item✅ W3/M3
P1 Mobile can become squeezed desktopToken parity and primitives landed in parallel with web (M1–M3 concurrent with W1–W3)✅ M1–M4
P1 Evidence visual states are inconsistentEvidenceChip (web) and LumiEvidenceTrust (mobile) ship identical three-state grammar✅ W2/M3
P1 Screenshot flow is web-heavyCritical flows 11–13 add Workspace, Risks, and Decisions mobile screenshots; accessibility suite adds 200% font-scale coverage✅ M5
P2 Native platform mirrors may lag web tokensiOS/Mac/Watch/KMP all confirmed at DESIGN.md §19 parity before any screen migration✅ M1
P2 Admin/breadth surfaces feel secondaryW5 completed all admin/breadth surfaces before marking web done✅ W5

Recommended PR sequence:

  1. W1: web tokens and guards ✅
  2. M1: native/KMP token parity ✅
  3. W2: web primitives ✅
  4. M2: mobile/shared primitives ✅
  5. W3 + M3: CEO operating surfaces ✅
  6. W4: capture and work surfaces ✅
  7. M4: mobile work/business/company lanes ✅
  8. W5: company, business, admin surfaces ✅
  9. M5: screenshot, visual regression, accessibility, and final audit 🚧 partial; named-device/CI evidence and the remaining audit items are open

Done means:

  • every listed phase has either shipped or is explicitly superseded with a dated decision; M5 must also have its named-device/CI evidence and remaining audit items closed
  • F19 audit gaps addressed or moved to specific remaining specs
  • F30/F78/F79 mobile contracts still pass after visual migration
  • screenshot and accessibility evidence exists for web and mobile
  • no high-traffic screen violates Material Intelligence pre-flight

12. Open Questions / Decisions

  • Should F89 implementation use Storybook or an internal primitives gallery as the visual source of truth for component states? If yes, create a follow-up implementation plan.
  • Should native mobile screenshots be captured via F51 fake backend first, or wait for real-device CI capacity?
  • Should frontend/scripts/check-design-tokens.mjs become a cross-platform token parity checker, or should native parity live in a separate script?
  • Which web surface becomes the visual reference screen for code review snapshots: CEO Brief, Today/Pulse, or Daily Pulse?
  • Should public landing page material imagery be specified under F22, or remain only governed by DESIGN.md/TASTE.md?

13. Bug / Change Log

2026-07-02 — §11 KMP screen count corrected from 55 to 58 (batch 12)

Type: Documentation Truth Fix

Summary:

  • §11 Verdict paragraph and M5 matrix row: Updated the audited-screen count from “55 KMP screens” to “58 KMP screens” reflecting the actual file count returned by find android/shared/src/commonMain -name "*Screen.kt" -path "*/ui/*" | wc -l = 58. The 3 additional screens were added after the 2026-06-27 audit.
  • Added a follow-up note: the 3 post-audit screens should receive the same one-by-one LumiKit review (verify no raw hex or Color(0xFF…) usage) before marking M5 fully closed.

2026-06-27 — W5 Notifications lit-token feed slice started

Type: Implementation Change

Summary:

  • Migrated the web Notification Center loading rows, unread card rail, and category chips onto shared Material Intelligence Card, Skeleton, and Badge recipes.
  • Replaced raw category tone class maps with semantic lit-token Badge variants for approval, decision, brief, follow-up, and neutral categories.
  • Added focused tests for notification card recipes, unread rails, and decision category lit-token styling while preserving mark-read and open-route behavior.

Reason:

  • W5 explicitly requires notifications to use lit tokens instead of generic alert cards. Notifications are a trust surface; each alert needs a calm category, age, and action grammar.

Impact:

  • /notifications now uses the same ranked-card and lit-token language as the CEO and W4 work surfaces.
  • Unread notifications have a material severity rail without changing feed behavior or virtualization.

Tests:

  • node frontend/scripts/check-design-tokens.mjs
  • cd frontend && npx vitest run src/test/NotificationCenterPage.test.tsx --reporter=verbose
  • cd frontend && ./node_modules/.bin/tsc --noEmit

2026-06-27 — W5 Telegram Connect material pairing slice started

Type: Implementation Change

Summary:

  • Migrated the web Telegram Connect status token, linked-account state, connected guidance, connection controls, ready-state guidance, and setup step markers onto shared Badge, rounded-card, rounded-control, and shadow-lit recipes.
  • Replaced raw rounded-lg/rounded-md setup panels and generic secondary status chips with semantic success, warning, and outline lit-token variants.
  • Added focused Telegram tests for disconnected, pending-code, and connected material states while preserving the existing code-generation flow.

Reason:

  • Connect surfaces are trust infrastructure. Pairing a CEO’s Telegram chat must feel precise, calm, and accountable, not like a bolt-on integration setup screen.

Impact:

  • /connect/telegram now matches the F89 admin/connect material grammar used by Settings, Support, Chat, and Company Hub.
  • No Telegram API behavior, environment handling, route, or copy changed.

Tests:

  • node frontend/scripts/check-design-tokens.mjs
  • cd frontend && npx vitest run src/test/TelegramPage.test.tsx --reporter=verbose
  • cd frontend && ./node_modules/.bin/tsc --noEmit

2026-06-27 — W5 Support detail material ticket slice started

Type: Implementation Change

Summary:

  • Migrated the web Support Detail status/category/priority metadata, original ticket description, staff controls, internal-note panels, message cards, and feedback prompt onto shared Badge, Card, and Material Intelligence warning/success/danger tokens.
  • Replaced raw middle-dot metadata, amber one-off panels, and hardcoded soft status surfaces with semantic lit-token badges and recipe variables.
  • Added focused Support Detail tests that pin ticket meta badges plus description and message card recipes while preserving close-ticket and reply behavior.

Reason:

  • Support detail is a high-trust admin record. Status, priority, staff-only notes, and customer-visible replies need consistent material semantics instead of ad hoc warning panels.

Impact:

  • /support/:id and staff support ticket detail rendering now share the same lit-token grammar as the migrated Support list.
  • No support API contract, routing, mutation behavior, or copy changed.

Tests:

  • node frontend/scripts/check-design-tokens.mjs
  • cd frontend && npx vitest run src/test/support.test.tsx --reporter=verbose
  • cd frontend && ./node_modules/.bin/tsc --noEmit

2026-06-27 — W5 Chat material conversation shell slice started

Type: Implementation Change

Summary:

  • Migrated the web Chat loading skeleton, conversation rail, rail summary, active thread shell, updated-at token, sample prompts, and message bubbles onto Material Intelligence radius, badge, skeleton, and lit-edge recipes.
  • Replaced raw rounded-xl conversation containers, raw count pills, and muted assistant bubbles with rounded-card shells, semantic Badge tokens, Skeleton primitives, and shadow-lit message surfaces.
  • Added focused Chat tests that pin the rail, summary, conversation shell, count token, and assistant bubble material recipes while preserving existing message loading, retry, send, and attachment behavior.

Reason:

  • Chat is Lumi’s operating query layer. It should feel like a calm executive workspace, not a generic messaging demo, while retaining the fast scan and keyboard behavior that make follow-up questions useful.

Impact:

  • /hub/chat now shares the same lit-token and sheet language as the rest of F89 web surfaces.
  • No chat API contract, query behavior, attachment behavior, or i18n copy changed.

Tests:

  • node frontend/scripts/check-design-tokens.mjs
  • cd frontend && npx vitest run src/test/ChatPage.test.tsx --reporter=verbose
  • cd frontend && ./node_modules/.bin/tsc --noEmit

2026-06-27 — W5 Settings material admin shell slice started

Type: Implementation Change

Summary:

  • Migrated the web Settings summary chips, create/join organization wells, organization switch rows, danger-zone panels, and module rows onto shared Badge and material sheet recipes.
  • Replaced raw rounded-lg bordered admin blocks and middle-dot role metadata with consistent lit-token badges, rounded-card wells, and shadow-lit material edges.
  • Added focused Settings tests that pin the material recipes while preserving existing organization form, billing visibility, and validation behavior.

Reason:

  • W5 requires Settings and admin surfaces to feel as trustworthy as CEO operating surfaces. Organization identity, authority, switching, module visibility, and destructive actions are high-trust controls and cannot look like generic form containers.

Impact:

  • /settings now shares the same admin material grammar as Teams, Invite links, Support, and Company Hub.
  • No settings behavior or API contract changed; the slice only upgrades visual semantics and guards against recipe drift.

Tests:

  • node frontend/scripts/check-design-tokens.mjs
  • cd frontend && npx vitest run src/test/SettingsPage.test.tsx --reporter=verbose
  • cd frontend && ./node_modules/.bin/tsc --noEmit

Type: Implementation Change

Summary:

  • Migrated the web Invite Members loading state, create-invite form, created-link success state, invite list shell, invite status chips, and empty state onto shared Material Intelligence Card, CardContent, Badge, Label, Skeleton, Button, Select, Input, and EmptyState recipes.
  • Replaced raw rounded-xl panels and inline status pill class maps with semantic lit-token badges for active, exhausted, and expired invite links.
  • Added focused tests for invite list sheet recipes, active/expired lit-token styling, create-form material labels, created-link success sheet, and visible copy action.

Reason:

  • W5 requires Settings and admin surfaces to use consistent sheet/well/authority-seal language. Invite links are access-control material; their status, role, team, and copy/send actions need to feel deliberate and trustworthy.

Impact:

  • /settings/invite now shares the same admin material grammar as Teams and Company Hub.
  • Create and copy behavior remains unchanged, but the page now presents invite state as accountable records instead of generic admin rows.

Tests:

  • node frontend/scripts/check-design-tokens.mjs
  • cd frontend && npx vitest run src/test/InvitePage.test.tsx --reporter=verbose
  • cd frontend && ./node_modules/.bin/tsc --noEmit

2026-06-27 — W5 Support ticket list material queue slice started

Type: Implementation Change

Summary:

  • Migrated the web Support ticket list loading rows and ticket rows onto shared Material Intelligence Card, CardContent, Skeleton, Badge, and Button/link recipes.
  • Replaced ghost Button ticket rows and plain metadata separators with keyboard-operable interactive Cards and semantic lit-token status/category/priority chips.
  • Added focused tests for support ticket card recipes, lit status and priority tokens, and keyboard navigation into ticket detail routes.

Reason:

  • W5 requires Support and admin breadth surfaces to stop feeling secondary. Support tickets are a trust lane; each ticket should read as a calm accountable record with status, priority, and action affordance visible at scan speed.

Impact:

  • /support now shares the same material queue grammar as Company Hub, Teams, Notifications, and the W4 operating lanes.
  • Ticket rows preserve click navigation while adding explicit keyboard activation on the Card material object.

Tests:

  • node frontend/scripts/check-design-tokens.mjs
  • cd frontend && npx vitest run src/test/support.test.tsx --reporter=verbose
  • cd frontend && ./node_modules/.bin/tsc --noEmit

2026-06-27 — W5 Teams material admin slice started

Type: Implementation Change

Summary:

  • Migrated the web Teams loading grid, summary chips, create form, team records, expanded team role tokens, members list, and empty members state onto shared Material Intelligence Card, Badge, Skeleton, Label, Input, Textarea, Select, Button, and EmptyState recipes.
  • Replaced raw rounded-xl admin panels and inline role/team pills with semantic sheets and lit-token badges while preserving team expansion, member-role editing, member removal, and create-team behavior.
  • Added focused tests for Teams material cards, lit summary tokens, member list sheets, and visible create-form labels.

Reason:

  • W5 requires Teams and other admin surfaces to use consistent sheet/well/authority-seal language. Teams is an authority surface: roles, managers, and membership must feel accountable instead of bolted on.

Impact:

  • /settings/teams now shares the same Card, Skeleton, Badge, form, and EmptyState language as the F89 Company Hub, notification, work, and CEO surfaces.
  • The create flow now uses visible labels above fields, matching the F89 form contract and improving scan/accessibility without changing API behavior.

Tests:

  • node frontend/scripts/check-design-tokens.mjs
  • cd frontend && npx vitest run src/test/TeamsPage.test.tsx src/test/TeamMemberRole.test.tsx --reporter=verbose
  • cd frontend && ./node_modules/.bin/tsc --noEmit

2026-06-27 — W5 Company Hub material shell slice started

Type: Implementation Change

Summary:

  • Migrated the web Company Hub summary, access/pinned tokens, tab shell, announcement loading rows, announcement records, docs loading rows, docs records, and docs empty state onto shared Material Intelligence Card, Badge, Skeleton, Button, Input, and EmptyState recipes.
  • Replaced ad hoc badge styling and raw clickable doc rows with semantic lit-token badges and keyboard-operable interactive Card records.
  • Added focused tests for Hub shell material recipes, announcement card recipes, doc card interactivity, and keyboard open behavior while preserving existing tab, loading, empty, role, and pinned ordering behavior.

Reason:

  • W5 requires Company/Business surfaces to use operating table or ranked-card composition. Company Hub is where trust-critical announcements and operating docs live, so its shell and records must feel like deliberate company material rather than generic secondary admin UI.

Impact:

  • /hub now uses the same Card, lit-token, skeleton, and empty-state language as the W3/W4 operating lanes and the W5 notification feed.
  • Docs are still opened from the same tab flow, but the record itself is now the material object with hover, focus, and keyboard activation.

Tests:

  • node frontend/scripts/check-design-tokens.mjs
  • cd frontend && npx vitest run src/test/HubPage.test.tsx --reporter=verbose
  • cd frontend && ./node_modules/.bin/tsc --noEmit

2026-06-27 — W4 Horizon material row slice started

Type: Implementation Change

Summary:

  • Migrated the web Horizon loading rows, deadline rows, overdue rail, and money totals onto shared Material Intelligence Card, Skeleton, and Badge recipes.
  • Replaced the nested Button/Card row structure with a keyboard-accessible interactive Card so the row itself is the material object.
  • Added focused tests for overdue card recipe, severity rail, and lit money tokens.

Reason:

  • Horizon is the forward-looking work lane. It needs to read as a ranked operating list, not a calendar-like cluster of generic rows.

Impact:

  • /work/horizon now shares the same material row grammar as Tasks, Projects, Recurring, Signal Inbox, and Follow-ups while preserving navigation and keyboard activation.
  • Money exposure is now a lit token adjacent to the relevant day and item.

Tests:

  • node frontend/scripts/check-design-tokens.mjs
  • cd frontend && npx vitest run src/test/HorizonPage.test.tsx --reporter=verbose
  • cd frontend && ./node_modules/.bin/tsc --noEmit

2026-06-27 — W4 Follow-ups material evidence slice started

Type: Implementation Change

Summary:

  • Migrated the web Follow-ups loading rows, follow-up cards, auto-generated label, status chips, reply evidence well, and send-dialog question label onto shared Material Intelligence primitives.
  • Replaced raw status badge class maps with semantic lit-token Badge variants for draft, sent, replied, expired, and cancelled states.
  • Added page-level tests for follow-up card material recipes, visible source/owner/channel/date/action context, replied evidence treatment, and send behavior.

Reason:

  • Follow-ups are the chase-and-verify part of the control loop. F89 requires owner, age/source, and action to stay adjacent in a calm material object.

Impact:

  • /intel/follow-ups now shares the same Card, Skeleton, Badge, Label, Textarea, and Button grammar as Signal Inbox and the W4 work queue.
  • Replied evidence is visually present without creating nested cards.

Tests:

  • node frontend/scripts/check-design-tokens.mjs
  • cd frontend && npx vitest run src/test/FollowUpsPage.test.tsx --reporter=verbose
  • cd frontend && ./node_modules/.bin/tsc --noEmit

2026-06-27 — W4 Signal Inbox material evidence slice started

Type: Implementation Change

Summary:

  • Migrated the web Signal Inbox loading rows, capture form, signal cards, channel/status chips, proposal confidence chips, and proposal/action buttons onto shared Material Intelligence primitives.
  • Replaced raw badge class maps with lit-token Badge variants for channel, status, proposal type, and confidence.
  • Added focused tests for signal card recipes, visible capture labels, lit-token badges, and proposal action behavior.

Reason:

  • Signal Inbox is the capture-to-rank intake lane. F89 requires captured signals to show source, owner/age, and action in one calm material object instead of ad hoc cards and badges.

Impact:

  • /intel/signals now uses Card, Skeleton, Label, Badge, Input/Textarea, and Button recipes consistently across capture, review, extract, ignore, accept, and reject flows.
  • Captured signals carry the same material severity rail language as the W4 work queue while preserving virtualization.

Tests:

  • node frontend/scripts/check-design-tokens.mjs
  • cd frontend && npx vitest run src/test/SignalInboxPage.test.tsx --reporter=verbose
  • cd frontend && ./node_modules/.bin/tsc --noEmit

2026-06-27 — W4 Tasks material control slice started

Type: Implementation Change

Summary:

  • Migrated the web Tasks loading rows, summary chips, drag handle, completion control, completed state, and destructive delete confirmation onto shared Material Intelligence primitives.
  • Replaced bespoke summary pills with lit-token badges that preserve calm scanability while highlighting waiting and overdue states.
  • Added focused tests for task row cards, summary tokens, completion control shape, and destructive delete confirmation styling.

Reason:

  • Tasks are the daily work queue. The page already had strong workflow behavior, but the control chrome needed to align with the same material vocabulary as Projects and Recurring.

Impact:

  • /work/tasks now uses Card, Skeleton, Badge, and Button recipes more consistently across loading, ranked rows, summary state, drag/reorder, completion, and delete flows.
  • The W4 work-surface trio (Tasks, Projects, Recurring) now shares the same material grammar for cards, tokens, and destructive actions.

Tests:

  • node frontend/scripts/check-design-tokens.mjs
  • cd frontend && npx vitest run src/test/TasksPage.test.tsx --reporter=verbose

2026-06-27 — W4 Recurring material list slice started

Type: Implementation Change

Summary:

  • Migrated the web Recurring loading rows, helper panel, creation form, recurring row cards, schedule chips, active state, and destructive delete confirmation onto shared Material Intelligence primitives.
  • Replaced placeholder-only recurring creation fields with visible labels above the recessed inputs.
  • Added focused tests for recurring row card recipes, lit-token badges, and creation form shell/label behavior.

Reason:

  • Recurring work is part of Lumi’s daily operating rhythm. It should feel durable and scheduled, not like a secondary list bolted onto the workspace.

Impact:

  • /work/recurring now uses Card, Skeleton, Badge, Label, Input/Textarea, and destructive Button recipes consistently for its primary list and create/delete flows.
  • Recurring creation is more accessible and calmer because labels stay visible while users type.

Tests:

  • node frontend/scripts/check-design-tokens.mjs
  • cd frontend && npx vitest run src/test/RecurringPage.test.tsx --reporter=verbose

2026-06-27 — W4 Projects material card slice started

Type: Implementation Change

Summary:

  • Migrated the web Projects loading skeleton, creation form, project cards, visibility chip, and destructive delete confirmation onto shared Material Intelligence primitives.
  • Replaced placeholder-only project creation fields with visible labels above the recessed inputs.
  • Added focused tests for project card material recipes, lit-token visibility, and creation form shell/label behavior.

Reason:

  • Projects are part of the daily work surface in W4; they should feel like ranked work objects, not bespoke SaaS tiles.

Impact:

  • /work/projects now uses Card, Skeleton, Badge, Label, Input/Textarea, and destructive Button recipes consistently for the primary list and create flow.
  • Project creation is more accessible and calmer because labels stay visible while users type.

Tests:

  • node frontend/scripts/check-design-tokens.mjs
  • cd frontend && npx vitest run src/test/ProjectsPage.test.tsx --reporter=verbose

2026-06-27 — W4 Daily Pulse capture material slice started

Type: Implementation Change

Summary:

  • Migrated the Daily Pulse capture form shell from a bespoke surface to the shared Card material recipe.
  • Returned the primary pulse submit action to the canonical authority Button variant instead of page-local color styling.
  • Added focused tests for the material shell/button contract and failed-submit answer preservation.

Reason:

  • Daily Pulse is the capture start of the CEO control loop; it must feel calm, durable, and impossible to lose work from.

Impact:

  • The capture surface now matches the F89 Card/Button recipes while keeping the single-textarea F83 flow intact.
  • Submit failures preserve the typed answer, making error recovery explicit and test-covered.

Tests:

  • node frontend/scripts/check-design-tokens.mjs
  • cd frontend && npx vitest run src/test/PulsePage.test.tsx --reporter=verbose
  • cd frontend && ./node_modules/.bin/tsc --noEmit

2026-06-27 — W3 Today executive trust rows started

Type: Implementation Change

Summary:

  • Added shared EvidenceChip trust rows to the web Today page’s executive decision, risk, and commitment cards.
  • Reused the Decisions/Risks/Commitments evidence and low-confidence copy so Today and detail pages share one trust language.
  • Added focused Today coverage for sourced, missing-evidence, and low-confidence states across all executive card types.

Reason:

  • Today is the CEO’s first viewport. It must answer “what needs me now?” while making source and confidence state visible without forcing a drill-down into Brief, Risks, Decisions, or Commitments.

Impact:

  • /work/today now shares the same web evidence/confidence grammar as the W3 detail surfaces.
  • The CEO operating lane is more consistent: Brief, Today, Risks, Decisions, and Commitments all expose evidence state next to the claim.

Tests:

  • node frontend/scripts/check-design-tokens.mjs
  • cd frontend && npx vitest run src/test/TodayPage.test.tsx --reporter=verbose
  • cd frontend && ./node_modules/.bin/tsc --noEmit

2026-06-27 — W3 Commitments trust-row slice started

Type: Implementation Change

Summary:

  • Added shared EvidenceChip trust states inside the web Commitments table title cell.
  • Added optional frontend typing for commitment evidence_sources so the table can show source presence/count when the existing API includes evidence IDs.
  • Added locale keys and tests for sourced, missing-evidence, and low-confidence commitment states, with key parity propagated across shipped locales.

Reason:

  • Commitments are the promise-tracking part of the CEO operating lane. The table already ranks by money, priority, and due date; it also needs evidence and confidence adjacent to the promise so accountability is visible without opening a detail view.

Impact:

  • /intel/commitments now shares the same trust grammar as Brief, Risks, and Decisions while preserving the dense DataTable layout.
  • W3 core CEO intelligence surfaces now have one consistent web evidence/confidence pattern.

Tests:

  • node frontend/scripts/check-design-tokens.mjs
  • cd frontend && npx vitest run src/test/CommitmentsPage.test.tsx src/test/i18n.test.ts --reporter=verbose
  • cd frontend && ./node_modules/.bin/tsc --noEmit

2026-06-27 — W3 Decisions trust-row slice started

Type: Implementation Change

Summary:

  • Replaced the web Decisions page’s custom recommended-option confidence pips with shared EvidenceChip trust states.
  • Added optional frontend typing for decision evidence_sources so the page can show source presence/count when the existing API includes evidence IDs.
  • Added EN/EN-IN/VI copy and tests for sourced, missing-evidence, and low-confidence decision states.

Reason:

  • Decisions are a CEO-critical W3 surface. The recommendation needs to feel accountable and consistent with Brief and Risks, not like a separate mini visualization grammar.

Impact:

  • /intel/decisions now shares the same visible evidence/confidence grammar as CEO Brief and Risks.
  • The recommended option remains visually highlighted, while trust state moves into the calm material row beside the decision claim.

Tests:

  • node frontend/scripts/check-design-tokens.mjs
  • cd frontend && npx vitest run src/test/DecisionsPage.test.tsx --reporter=verbose
  • cd frontend && ./node_modules/.bin/tsc --noEmit

2026-06-27 — W3 Risks trust-row slice started

Type: Implementation Change

Summary:

  • Migrated the web Risks list from ad hoc confidence text to shared EvidenceChip trust states.
  • Added optional frontend typing for risk evidence_sources so the page can show source presence/count when the existing API includes evidence IDs.
  • Added EN/EN-IN/VI copy and tests for sourced, missing-evidence, and low-confidence risk states.

Reason:

  • Risks are a CEO-critical W3 surface. Severity rails are not enough; the card also needs a calm, adjacent trust row that shows whether the risk is evidenced and whether confidence should change behavior.

Impact:

  • /intel/risks now shares the same trust grammar as CEO Brief while staying honest about the current Risk API shape: evidence count is visible, rich source labels remain future work for the owning serializer slice.
  • Future W3 Decisions and Commitments work can reuse the same EvidenceChip migration pattern.

Tests:

  • node frontend/scripts/check-design-tokens.mjs
  • cd frontend && npx vitest run src/test/RisksPage.test.tsx --reporter=verbose
  • cd frontend && ./node_modules/.bin/tsc --noEmit

2026-06-27 — W3 CEO Brief trust-signal slice started

Type: Implementation Change

Summary:

  • Migrated CEO Brief item source, missing-evidence, and low-confidence display to the shared EvidenceChip primitive.
  • Added explicit tests for source-backed, missing-evidence, and low-confidence Brief states so the CEO Brief can act as the first W3 reference screen.
  • Added EN/VI copy for missing evidence and low-confidence chip states.

Reason:

  • The CEO’s morning brief must make trust state visible without visual noise: provenance should read as calm evidence, while weak signal quality should be visibly separate.

Impact:

  • Brief items now expose evidence gaps and low confidence directly in the item row instead of relying on implicit absence.
  • Future W3 migrations can reuse the same evidence grammar across Today, Pulse, commitments, risks, and decisions.

Tests:

  • node frontend/scripts/check-design-tokens.mjs
  • cd frontend && npx vitest run src/test/BriefPage.test.tsx --reporter=verbose
  • cd frontend && ./node_modules/.bin/tsc --noEmit

2026-06-27 — W2 web evidence and ranked-list primitives started

Type: Implementation Change

Summary:

  • Added the shared web EvidenceChip primitive for source-backed, confirmed, stale, low-confidence, and missing-evidence states.
  • Aligned Skeleton and DataTable loading/list shells with Material Intelligence recipe tokens.
  • Added primitive tests for evidence states, skeleton material treatment, and DataTable sheet/card recipe usage.

Reason:

  • CEO surfaces cannot migrate cleanly until evidence, confidence, loading, and ranked-list states are shared primitives instead of per-page styling.

Impact:

  • W3 CEO pages can use one visible evidence/confidence grammar instead of hiding trust state in ad hoc text or icons.
  • Data-heavy web screens have a clearer Sheet/Card foundation for desktop tables and mobile ranked-card lists.

Tests:

  • node frontend/scripts/check-design-tokens.mjs
  • cd frontend && npx vitest run src/test/page-primitives.test.tsx src/test/DataTable.test.tsx --reporter=verbose

2026-06-27 — W1 web token guard foundation started

Type: Implementation Change

Summary:

  • Added the first web implementation slice for W1: canonical CSS token presence checks, scoped one-off radius guard coverage for migrated primitives, contrast coverage for material edges/control pairs, and primitive radius alignment to Material Intelligence recipe tokens.

Reason:

  • The upgraded design system must become mechanically enforceable before high-traffic page rewrites begin.

Impact:

  • Web primitives can migrate toward recipe-level tokens (rounded-control, rounded-card, rounded-pill) without broad page churn.
  • Existing historical page/share-card styling debt remains for later W phases; the new guard prevents the migrated primitive foundation from regressing.

Tests:

  • node frontend/scripts/check-design-tokens.mjs
  • cd frontend && ./node_modules/.bin/tsc --noEmit
  • cd frontend && pnpm test

2026-06-27 — Draft Material Intelligence redesign transformation spec

Type: Documentation Change

Summary:

  • Added F89 as the implementation contract for transforming current web and mobile surfaces to the upgraded Lumi Material Intelligence design system.

Reason:

  • DESIGN.md and TASTE.md now define the target product language, but the repo needed a feature-level spec with phases, acceptance criteria, states, and verification gates.

Impact:

  • Future web and mobile redesign work should implement against F89, while preserving F19/F30/F78/F79 feature ownership.

Tests:

  • Documentation-only. git diff --check must pass.

Notes:

  • F89 adds no backend model, endpoint, or feature capability. It is a cross-platform UI/UX transformation spec.

2026-06-28 — Full-product web audit: zero remaining violations

Type: Implementation Change

Summary:

  • Systematic grep audit across all frontend/src/pages/ directories confirmed ~53 files still had residual F89 violations not caught by the token guard script: raw animate-pulse loading divs, rounded-xl/rounded-lg container radius, and bg-white in non-semantic positions.
  • Replaced all remaining animate-pulse divs with <Skeleton rounded-card> in CRM (CalendarView, CompanyTimeline, DealContactRoles, DealDetailPanel, DealLineItems, DealQuoteSection, ForecastView, NextActivityCard, TimelineView), auth (AcceptInvitePage), business (ContactsPage), intel (ChaosImportPage), and settings (OnboardingPage).
  • Fixed all remaining rounded-xl/rounded-lg container radius to rounded-card across HQ, jobs, store, connect, apps, crm, and work pages.
  • Fixed bg-white → bg-card/bg-background in hub and store marketing pages.
  • Fixed border-l-[var(--color-*)] TWM conflict: all left-border accent colors (BriefPage, RisksPage, TodayPage, TasksPage, HorizonPage, NotificationCenterPage, SignalInboxPage, DecisionsPage, HqDashboardPage, SettingsPage) now use [border-left-color:var(--color-*)] arbitrary property so border-l-4 width class is preserved (previously silently removed by tailwind-merge v3).
  • Fixed HorizonPage.toISODate UTC-vs-local bug: function changed from .toISOString().split('T')[0] (UTC) to getFullYear/Month/Date (local), matching the test helper and making isOverdue correct in UTC+ timezones.

Reason:

  • Token guard only catches banned palette classes and inline hex — not rounded-lg, rounded-xl, animate-pulse, or bg-white. A full-product grep audit was needed to reach zero remaining violations.
  • The TWM conflict was a silent visual regression: overdue/critical items showed a 1px colored border instead of the intended 4px accent rail.
  • The timezone bug caused the HorizonPage overdue row test to fail at midnight in Vietnam time (UTC+7 — UTC time is still the previous day before 07:00 local).

Impact:

  • Web product now has zero F89 violations in frontend/src/pages/. Token guard + systematic grep audit confirm.
  • HorizonPage timezone fix makes isOverdue correct regardless of UTC offset.
  • Border-left TWM fix restores the 4px accent rail on overdue, risk, and urgency items.

Tests:

  • node frontend/scripts/check-design-tokens.mjs — passes clean
  • grep -rn "rounded-xl|rounded-lg|animate-pulse|bg-white" frontend/src/pages/ — zero hits
  • cd frontend && pnpm test — 10,999 passed (previously 10,998 + 1 failing)
  • cd frontend && ./node_modules/.bin/tsc --noEmit — 0 errors

2026-06-28 — Web operating surfaces material follow-up

Type: Implementation Change

Summary:

  • Replaced the TaskDetailPanel hand-rolled animate-pulse loading divs with shaped <Skeleton> rows and normalized remaining work-panel radii to rounded-card / rounded-control.
  • Kept the CRM no-next-activity warning on the amber attention rail while fixing the border-l-[var(--color-signal-amber)] tailwind-merge conflict with [border-left-color:var(--color-signal-amber)].
  • Extended focused web regression coverage around commitments, CRM activity health, deal detail actions, Horizon, Today, and task-detail material states.

Reason:

  • The prior full-page sweep did not include shared work components outside frontend/src/pages/, and new CRM follow-up edits reintroduced one border-left conflict.
  • Work detail panels are daily operator surfaces; their loading state should use the same material skeleton grammar as the rest of the product.

Impact:

  • Web page and shared work-component audit greps now return zero hits for raw animate-pulse, non-token rounded utilities, raw bg-white, and border-l-[var(...)].
  • No API, route, or data-model change.

Tests:

  • node frontend/scripts/check-design-tokens.mjs
  • grep -rn "animate-pulse|rounded-xl|rounded-lg|rounded-md|rounded-sm|bg-white\b" frontend/src/pages/ frontend/src/components/work/
  • grep -rn "border-l-\[var(" frontend/src/pages/ frontend/src/components/work/
  • cd frontend && ./node_modules/.bin/tsc --noEmit
  • cd frontend && pnpm test -- src/test/CommitmentsPage.test.tsx src/test/CrmActivities.test.tsx src/test/DealAnalytics.test.tsx src/test/DealDetailPanel.test.tsx src/test/HorizonPage.test.tsx src/test/TaskDetailPanel.test.tsx src/test/TodayPage.test.tsx

2026-07-02 — Spec drift fix: checked shipped ACs in §2

Type: Documentation

Summary:

  • 18 of 19 [ ] ACs in §2 flipped to [x]; the permission-restricted explanation remains unchecked. W1–W5 web work and M1–M4 mobile source work are complete, while M5 remains partial pending the three post-audit screen review and runtime evidence.
  • Checked: §2.1 all five CEO/leadership surface ACs (Brief material, mobile Pulse operating-home, AI evidence adjacent, quiet-day silence state, severity rail); §2.2 all four operator/member ACs (Daily Pulse form, submit-fail preserves input, mobile ranked cards, DataTable material rules); §2.3 two of three admin ACs (settings routes use correct recipes, destructive styling); §2.4 all four native mobile parity ACs (iOS/Android token/radius parity, 200% font-scale, modal sheet 16px radius, evidence label-visible); §2.5 all three design-system integrity ACs (static token guard, token parity check, screenshot gates).
  • Left [ ]: §2.3 permission-restricted section “explains why access is restricted and where to go next” — W5 confirms visual migration of settings surfaces but does not explicitly confirm the functional role-explanation copy/component behavior in §11 rows.
  • No code changes.

2026-06-28 — M6 Mobile dialog shell upgrade + settings token fix

Type: Implementation Change

Summary:

  • Added LumiDialogCard primitive to LumiMobilePrimitives.kt. All KMP Dialog composables previously used a raw Surface(shape = MaterialTheme.shapes.extraLarge, tonalElevation = 6.dp, color = MaterialTheme.colorScheme.surface) workaround (the CMP 1.10.x AlertDialog_skikoKt bug). LumiDialogCard replaces this with RoundedCornerShape(LumiMobileTokens.CardRadius), SurfaceWhite background, and a 1dp Border — matching the web rounded-card + shadow-card material recipe.
  • Fixed 17 dialog shell occurrences across 15 screens: DecisionsScreen (×2), SignalInboxScreen (×2), RisksScreen, CommitmentsScreen, TasksScreen, FollowUpsScreen, ProjectsScreen, ApprovalsScreen, RecurringDetailScreen, RecurringScreen, SettingsScreen, DealsScreen, OrgManagementScreen, ProjectBoardScreen, ChatScreen.
  • Fixed 3 hardcoded RoundedCornerShape(10.dp) radii in SettingsScreen action rows → LumiMobileTokens.CardRadius (8dp).
  • Upgraded RecurringScreen frequency/paused status chip from raw Surface(shape = RoundedCornerShape(999.dp), ...) → LumiBadge(tone = Info/Warning, showDot = false).

Reason:

  • MaterialTheme.shapes.extraLarge resolves to 28dp in M3 — visually inconsistent with the 8dp Lumi card radius. All 31 original raw Surface() calls outside LumiMobilePrimitives were audited; 17 were dialog shells using the wrong shape/color. The remaining 14 are intentional (chat bubbles, flat list rows, screen wrappers).

Impact:

  • All modals/dialogs on every mobile screen now wear the Lumi card shape, paper-white background, and border — same visual grammar as web.
  • Settings action rows (language, sign-out, delete-account) now use the canonical 8dp radius.
  • No API, route, i18n, or behavior change.

Verification:

  • grep -rn "MaterialTheme.shapes.extraLarge" android/shared/src/commonMain/kotlin/com/locuno/lumi/shared/ui/ — zero hits (excluding LumiMobilePrimitives itself)
  • grep -rn "RoundedCornerShape(10.dp)" android/shared/src/commonMain/kotlin/com/locuno/lumi/shared/ui/ — zero hits