From c263cc81df46b4ca466944795d6a8cece2ada689 Mon Sep 17 00:00:00 2001 From: Macky Date: Wed, 19 Aug 2026 15:46:21 +0700 Subject: [PATCH] feat(ui): app UX/UI redesign + marketing landing site MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit App (Vue SPA) — 100% presentational, global design-token rebuild in style.css + polished App/Login/Chat/MyBoard/Personas/Setup/Training. No logic/API/route/i18n changes (verified: build clean, 4/4 vitest, independent review PASS 5/5). website/ — new self-contained static marketing landing site (TH-primary + EN toggle, CSS chat mockup, Hallmark theme), verified responsive at 320-768 (no horizontal scroll). Pricing uses placeholders pending owner. Docs: engineering-log 2026-08-19 + HANDOFF updated. NOT pushed (push to main auto-deploys to EasyPanel production; operator approval + JWT_SECRET check required before deploy). --- docs/HANDOFF.md | 17 + docs/engineering-log.md | 2 + ...26-08-19-ux-redesign-and-marketing-site.md | 97 +++ frontend/src/App.vue | 76 +- frontend/src/style.css | 330 +++++++-- frontend/src/views/Chat.vue | 202 ++++-- frontend/src/views/Login.vue | 35 +- frontend/src/views/MyBoard.vue | 49 +- frontend/src/views/Personas.vue | 8 +- frontend/src/views/Setup.vue | 26 +- frontend/src/views/Training.vue | 49 +- website/README.md | 26 + website/index.html | 647 ++++++++++++++++++ website/main.css | 424 ++++++++++++ 14 files changed, 1782 insertions(+), 206 deletions(-) create mode 100644 docs/engineering-log/2026-08-19-ux-redesign-and-marketing-site.md create mode 100644 website/README.md create mode 100644 website/index.html create mode 100644 website/main.css diff --git a/docs/HANDOFF.md b/docs/HANDOFF.md index 55c071a..1bb4ecd 100644 --- a/docs/HANDOFF.md +++ b/docs/HANDOFF.md @@ -24,6 +24,16 @@ filesystem JSON storage (no SQL). i18n TH/EN. No self-registration (admin provis - **user** (trainee) — trains against personas, own board. ## Current state — local code/security gate passed; production-operation gate pending +> **2026-08-19:** app UX/UI redesign (8 files, 100% presentational: global design-token system +> rebuild in `style.css` + polish of App/Login/Chat/MyBoard/Personas/Setup/Training) AND a new +> self-contained marketing landing site (`website/index.html` + `main.css`, TH-primary with EN +> toggle, CSS chat mockup) were built in parallel subagents. Frontend `vite build` clean, vitest +> 4/4, independent reviewer PASS (5/5 checks), marketing site verified responsive at 320–768 +> (no horizontal scroll). **ALL UNCOMMITTED.** Pushing to `main` auto-deploys to EasyPanel — so +> the push needs operator approval. Confirm production `JWT_SECRET` is set before deploying +> (backend `validate_runtime_security` fails closed without a ≥32-char secret; that is the +> existing production-operation gate, not a regression). See +> `docs/engineering-log/2026-08-19-ux-redesign-and-marketing-site.md`. > **2026-08-18:** live-QA UX fixes landed (committed locally, not yet pushed): persona > replies can no longer leak raw JSON into the chat bubble; all persona openers are natural > greetings (wrong_text cools off only after the seller's first reply); and the chat now @@ -115,6 +125,13 @@ cd backend && uv run python run.py # Flask :5001 Responsive CSS (640px, single-column, `flex-wrap`, `.btn-back`) is present + deployed. ## Next actions / backlog (also docs/FUTURE_WORK.md) +- **2026-08-19 UX + marketing-site push (operator-approved):** the app UX/UI redesign (8 files) + and new `website/` landing site are uncommitted on `main`. Commit + push ships the redesign to + the live EasyPanel app AND adds the marketing site to the repo. **Confirm production + `JWT_SECRET` is set (≥32 chars) in EasyPanel env before/with the push** (backend fails closed + without it). Then re-verify the live bundle. Optionally deploy the `website/` landing page as a + standalone static site (e.g. nginx / EasyPanel static or another host) — serve from + `website/index.html`; set real pricing before public launch. - **Sprint 1 live-operation gate:** deploy behind restricted access, set/verify `BOOTSTRAP_ADMIN_PASSWORD`, rotate `JWT_SECRET` after the patch, inspect audit data, and run a fresh authenticated smoke. Do not open public access before this checklist. - **Sprint 2:** implementation and local regression gate complete; retain current tests as the contract. - **P1:** run real-provider QA and browser/mobile E2E; local contract tests use deterministic fakes. diff --git a/docs/engineering-log.md b/docs/engineering-log.md index e9ef96f..591832e 100644 --- a/docs/engineering-log.md +++ b/docs/engineering-log.md @@ -30,6 +30,7 @@ Informed by MiroFish (CrowdSight engine) + the hermes-brain-and-tools CrowdSight | S4.2 relational schema foundation | code/schema/dependency review passed after offline-dialect remediation; temporary-local PostgreSQL runtime/parity/schema rollback probe passed; target runtime cutover blocked | 2026-08-15 | `docs/engineering-log/2026-08-15-s4-2-schema-foundation.md`, `docs/engineering-log/2026-08-15-postgresql-runtime-gate.md`, `docs/test-evidence/2026-08-15-postgresql-runtime.md`, `backend/requirements.lock.txt` | run importer target parity/rollback and keep runtime cutover behind the production gate | | S4.3 org/users + groups/personas + sessions/messages repositories | exact-current independent review passed; runtime cutover intentionally not wired | 2026-08-15 | `docs/engineering-log/2026-08-15-s4-3-org-users-repositories.md`, `docs/engineering-log/2026-08-15-s4-3-offline-dialect-remediation.md` | address non-blocking hardening suggestions opportunistically; then importer/parity gate | | S4.4 JSON importer | local SQLite and temporary-local PostgreSQL dry-run/apply/idempotency/conflict-rollback gates passed; importer + error-handler hardening committed; target apply blocked | 2026-08-16 | `docs/engineering-log/2026-08-15-s4-4-json-import.md`, `docs/engineering-log/2026-08-15-postgresql-import-gate.md`, `docs/engineering-log/2026-08-16-s4-4-importer-errorhandler-commit.md`, `docs/test-evidence/2026-08-15-postgresql-import.md` | target snapshot checksum/count comparison, retained backup, and operator-approved rollback rehearsal | +| UX/UI redesign + marketing website | implemented + locally verified (build clean, 4/4 unit tests, independent review PASS, responsive verified); uncommitted; deploy pending operator approval | 2026-08-19 | `docs/engineering-log/2026-08-19-ux-redesign-and-marketing-site.md`, `website/`, `git diff` | operator approves push (auto-deploys); confirm production `JWT_SECRET` before deploy | ## Guardrails - No self-registration; admin provisions users. (Verified: register => 404.) @@ -67,3 +68,4 @@ Informed by MiroFish (CrowdSight engine) + the hermes-brain-and-tools CrowdSight - `2026-08-15-s4-4-json-import.md` — fail-closed dry-run/apply importer, idempotency, backup, and parity blockers. - `2026-08-16-s4-4-importer-errorhandler-commit.md` — re-verified from clean lock env (330 tests) and committed the staged S4.4 importer + error-handler hardening increment. - `2026-08-18-live-qa-ux-fixes.md` — live-QA UX fixes: persona JSON never leaks into bubble, natural greeting openers (wrong_text cools off only after first reply), auto-close + auto-summarize on buy/walk/try, no manual "สรุปผล" button (336 tests). +- `2026-08-19-ux-redesign-and-marketing-site.md` — parallel subagents: app UX/UI redesign (global token system, 8 files, 100% presentational) + new `website/` marketing landing site (responsive TH/EN); build clean, 4/4 unit tests, independent review PASS; uncommitted, deploy pending operator approval. diff --git a/docs/engineering-log/2026-08-19-ux-redesign-and-marketing-site.md b/docs/engineering-log/2026-08-19-ux-redesign-and-marketing-site.md new file mode 100644 index 0000000..84966ca --- /dev/null +++ b/docs/engineering-log/2026-08-19-ux-redesign-and-marketing-site.md @@ -0,0 +1,97 @@ +# 2026-08-19 — UX/UI redesign + marketing website (parallel subagents) + +Date: 2026-08-19 +Status: implemented + locally verified; deploy = repo's normal Gitea→EasyPanel path (operator runs it) + +## Context + +User asked (in Thai) to use the "brain" + existing agents to develop (a) the app's UX/UI and +(b) a marketing website to sell the Sales Trainer app. User chose to do **both in parallel via +subagents** (clarify → need both, separate workstreams). + +## What was done + +Two parallel subagents were dispatched: + +### Workstream A — App UX/UI redesign (subagent `sa-0-9ebe0fd8`) +Redesigned the Vue 3 SPA's visual + UX layer while preserving ALL functionality (no backend, +no API, no route, no i18n-key changes). Edited 8 files: +- `frontend/src/style.css` — **global token system rebuilt** into a cohesive premium design + system (indigo→violet brand tokens, refined type scale, spacing, shared component classes: + buttons `.primary/.soft/.danger`, badges, chat bubbles `.msg-seller/.msg-customer/.msg-system`, + skeleton, empty-state with `.empty-illust`, `.btn-back`, reduced-motion guard). Upgrades every + screen that consumes the shared tokens. +- `frontend/src/App.vue` — frosted-glass sticky top nav (backdrop blur), brand mark + target icon. +- `frontend/src/views/Login.vue` — brand block (violet squircle + target icon, Thai title + "ระบบฝึกทักษะการขาย"), centered elevated card. +- `frontend/src/views/Chat.vue` — polished the core training screen: scenario picker, thread, + customer/seller/system bubbles, debrief/reveal, coach block, reduced-motion. +- `frontend/src/views/MyBoard.vue` — dashboard header + empty-state illustration. +- `frontend/src/views/Personas.vue` — persona card + guide polish. +- `frontend/src/views/Setup.vue` — auth setup polish. +- `frontend/src/views/Training.vue` — training list card polish. +- **NOTE:** the subagent timed out at its 600s limit partway through its planned 8th edit; all + edits it made are complete and the global token rebuild in `style.css` benefits every view. + Remaining views (Analytics, WeakAreas, AdminUsers, GroupBuilder, GroupEdit, GroupReport, + MyPersonas, SessionDetail, Settings, Guide, PersonaForm) were not individually restyled but + inherit the new shared token layer automatically. + +### Workstream B — Marketing website (subagent `sa-1-aabba1c7`) +Built a new **self-contained static landing site** at `~/Gitea/Sales Trainer/website/`: +- `website/index.html` (57.5 KB, 647 lines) + `website/main.css` (25.1 KB, 424 lines). +- Hallmark Workbench macrostructure, warm cream + single coral-red accent, TH-primary with + EN toggle (JS `data-lang` swap). +- Sections: hero (with realistic CSS-only chat mockup incl. AI-coach card + rising score), + how it works, persona tiers A/B/C, value props, who it's for, pricing (placeholder amounts — + owner to confirm, no invented numbers), FAQ, strong CTA + footer. +- **Verified responsive at 320/375/414/768 via headless Chrome + automated check (no horizontal + scroll: `overflowPx:0`) + vision_analyze on desktop & mobile screenshots (clean/premium).** +- The subagent timed out during a final minor CSS patch; the responsive check immediately before + confirmed `horizontalScroll:false` at all widths, and a fresh screenshot after confirmed clean. + +## Verification evidence + +| Check | Result | +|---|---| +| Frontend `vite build` | **clean** (rebuilt `frontend/dist`) | +| Frontend vitest unit | **4/4 pass** | +| Static security scan of diff (+lines) | no secrets / eval / innerHTML / injection | +| Diff logic scan | **zero** script-logic changes — 100% presentational (CSS + template classes + icon imports) | +| Independent reviewer subagent (`deleg_21f491a4`) | **PASS** — 5/5: no logic changes · CSS class integrity · no security issues · no media-query removals (only `prefers-reduced-motion` added) · no undefined CSS vars / no new i18n keys | +| Marketing site responsive (320/375/414/768) | **no horizontal scroll** (`overflowPx:0`) — automated check + screenshots | +| Marketing site visuals | vision_analyze on desktop + mobile → clean, cohesive, premium; minor cosmetic nits only (marker-underline widths, column top alignment) — intentional design choices, left as designed | +| App login screen (redesigned) | rendered via static dist + screenshot → clean/premium; pale button in screenshot = `:disabled` state (correct) | +| `git diff --check` | passes (no whitespace errors) | + +## Files changed (uncommitted) + +``` + M frontend/src/App.vue + M frontend/src/style.css + M frontend/src/views/Chat.vue + M frontend/src/views/Login.vue + M frontend/src/views/MyBoard.vue + M frontend/src/views/Personas.vue + M frontend/src/views/Setup.vue + M frontend/src/views/Training.vue +?? website/ (index.html + main.css — new marketing landing site) +``` + +## Notes / blockers / next action + +- **Deploy**: pushes to `main` auto-deploy to EasyPanel (webhook, ~3 min). Per project rule, + **no remote push without asking** — operator must approve the push that ships these changes. + BEFORE pushing, also confirm the production `JWT_SECRET` is set (see below). +- **Local backend preview blocked** (by design): `Config.validate_runtime_security()` fails closed + without a ≥32-char `JWT_SECRET`; the local `.env` holds a placeholder. The SPA `dist/` was + previewed via static serving instead. This is the existing documented production-operation gate — + **not a regression from this work.** +- Remaining app views (Analytics/WeakAreas/AdminUsers/GroupBuilder/GroupEdit/GroupReport/ + MyPersonas/SessionDetail/Settings/Guide) inherit the new shared tokens but could get a deeper + per-view polish pass in a follow-up if the owner wants a fully bespoke feel on those screens. +- Marketing site pricing uses placeholder amounts ("—" + confirm labels) — owner to set real + prices before publishing publicly. + +## Related +- `docs/HANDOFF.md`, `docs/engineering-log.md` +- Skills used: `engineering-handoff`, `ui-ux-pro-max` (partial), `hallmark` (used by both subagents) diff --git a/frontend/src/App.vue b/frontend/src/App.vue index 96707db..3891140 100644 --- a/frontend/src/App.vue +++ b/frontend/src/App.vue @@ -1,7 +1,10 @@