feat(ui): app UX/UI redesign + marketing landing site

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).
This commit is contained in:
Macky
2026-08-19 15:46:21 +07:00
parent 4bff7db098
commit c263cc81df
14 changed files with 1782 additions and 206 deletions

View File

@@ -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 320768
> (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.

View File

@@ -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.

View File

@@ -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)