# Wivexx UI redesign — loop tracker

_Goal (user, 2026-07-04): redesign the whole system to look better AND be friendly for
new users so they don't get overwhelmed. Go systematically, part by part — windows,
tabs, animations, all systems. This file is the loop's working plan; each iteration
finishes a part, checks it off, and records verification notes._

## Principles (locked)
- **Brand stays**: ink `#0d0d0d` / bone / volt `#c1f73a`, Space Grotesk + Inter +
  Space Mono — same language as wivexx.com. The DOT is pinned (light, physics,
  green candy look) — redesign AROUND it, never relight/recolor it.
- **Progressive disclosure > feature removal**: nothing loses capability; advanced
  things move behind clear doors so first-run feels calm.
- **Every new string ships EN+ES** via `ui/i18n.js` (guarded DOM writes — only set
  `nodeValue`/attrs when CHANGED, never observe attributes).
- **Bridge contract stable**: anything the UI `call()`s must exist on `JsApi`
  (assert `hasattr(JsApi, name)`); no renamed settings keys.
- **Verify in the preview server** (`ui-preview`, port 8778) with snapshot/inspect —
  `preview_screenshot` TIMES OUT on WebGL rAF pages; use eval/snapshot instead.
- **Batch deploy**: redesign ships as ONE release at the end (P11), not per-part.

## Baseline audit (2026-07-04, v1.56)
Structure: `index.html` (166 ln) → topbar (brand+topstate+indicators+7 winbtns) ·
hero (dot+caption+status) · convo · dock (composer + goals/social/actions chips +
behaviors row) · slide-over `#panel` (all content from `panels.js`, 4573 ln) ·
toast · lightbox. `app.css` 1558 ln, `app.js` 975 ln. Renders standalone (bridge
queues), zero console errors.

Newcomer pain points found:
1. **No first-run experience** — full control room appears at once; only a no-API
   voice/setup message exists. No tour, no "try this".
2. **Empty state is passive** — one small mono text blob with quoted examples you
   must retype; nothing clickable.
3. **Unexplained jargon chips** — "goals · social · actions" have no icons or
   tooltips; behaviors row is unlabeled toggles that appear only when the bridge
   is live.
4. **Triple status** — topstate ("ready"), hero caption ("ready"), hero status
   ("starting…") say overlapping things in 3 places.
5. **Density in panels** — settings + hubs are long uncategorized stacks (panels.js);
   little visual grouping, few descriptions.
6. **Inconsistent micro-interactions** — some buttons have hover states, few have
   focus rings; overlays each style themselves slightly differently.

## Parts (systematic order — check off as completed)
- [x] **P0 — this plan** (task #79)
- [x] **P1 — first-run welcome tour + starter suggestion chips** (task #80) — the
  core "don't overwhelm" feature; one-time, skippable, EN+ES, persisted via settings.
- [x] **P2 — design tokens + shell** (task #81) — spacing/radius/elevation/motion
  tokens; topbar hierarchy (ONE status story); focus states.
- [x] **P3 — hero + conversation** (task #82) — bubbles, enter animations, empty state.
- [x] **P4 — dock/composer + tools + behaviors** (task #83) — icons, tooltips,
  plain-language, overflow.
- [x] **P5 — panel framework** (task #84) — one skeleton every panel inherits.
- [x] **P6 — Settings simplification** (task #85).
- [x] **P7 — hub panels: goals/social/actions** (task #86).
- [x] **P8 — overlay windows** (task #87) — perf/timer/status/transfer/alert/goals.
- [x] **P9 — other windows parity** (task #88) — tk sidecar, ball overlay, phone web.
- [x] **P10 — animations + reduced-motion** (task #89).
- [x] **P11 — i18n sweep + QA + ONE batch deploy** (task #90). **← ALL PARTS DONE, v1.57 LIVE**

## Iteration log
- **2026-07-04 it.1**: baseline audit done (above), plan written, tasks #79–#90
  created. Preview server verified (snapshot clean, no console errors). Next: P1.
- **2026-07-04 it.2 — P1 DONE.** (1) Empty state now has 4 CLICKABLE starter chips
  ("what can you do?" / "take a screenshot" / "set a timer for 5 minutes" /
  "what's the weather?") — the chip's visible text IS the command sent, so the ES
  translations stay working commands (probe-verified: all 4 canonicalize via
  quick_english + classify as command in the intent gate, both languages).
  (2) First-run welcome tour: 3 steps, dots, skip / next→ / "let's go", Escape
  closes, volt-glow card; auto-opens ONCE when `welcome_done` is unset, persists
  via the (hidden, whitelisted) `welcome_done` key in wivexx_webgui._SETTING_DEFAULTS;
  replayable via window.wivexx.showWelcome(). New whenBridge() helper makes the
  boot-time get_settings read reliable. (3) Full EN+ES i18n (i18n.js entries;
  "skip" collision-checked). Verified in preview with a stubbed bridge: auto-open
  on welcome_done:false → skip → set_setting persist → chip click → send_text —
  all fired correctly; zero console errors. GOTCHA: the preview browser memory-caches
  app.js across location.reload — bust with fetch(f,{cache:"reload"}) then reload.
  Files: ui/index.html, ui/app.css, ui/app.js, ui/i18n.js, wivexx_webgui.py. Next: P2.
- **2026-07-04 it.3 — P2 DONE.** (1) Design tokens added to :root — --radius-s/m/l,
  --dur-fast/--dur/--dur-slow, --elev-1/-2 (applied to panel + toast; wider sweep in
  P10; existing :focus-visible + prefers-reduced-motion already global from an earlier
  pass — no work needed). (2) ONE status story: the titlebar #topstate word now
  COLLAPSES when idle (pip stays as a quiet heartbeat) and slides back in for
  listening/thinking/speaking — killing the "ready · ready · starting…" triplication.
  (3) Exception-based power chip: "full power" hidden entirely (class .quiet, default
  in HTML + toggled in setPower); only "low power" ever shows. DOM-verified: idle
  max-width 0/opacity 0 → "listening…" expands to 180px; power chip none →
  inline-flex "low power" → none; panel shadow elev-2 applied; zero console errors.
  Files: ui/app.css, ui/index.html, ui/app.js. Next: P3 (hero + conversation).
- **2026-07-04 it.4 — P3 DONE.** The transcript was already strong from the earlier
  design-alignment work (task #13: avatar'd assistant bubbles, volt edge, rise
  animation, empty state redone in P1) — P3 filled the real gaps: (1) hover
  TIMESTAMPS on every bubble (data-t attr + ::after in the 10px row gap; assistant
  left / user right / system suppressed; locale digits so no i18n needed);
  (2) motion tokens on the bubble rise + timestamp fade; (3) smooth scroll on new
  turns via CSS scroll-behavior (auto-disabled by the reduced-motion media query);
  (4) FOUND+FIXED an i18n gap: "wivexx is thinking" was untranslated → "wivexx está
  pensando" (i18n norm() collapses whitespace, so the trailing-space text node
  matches). DOM-verified: logTurn×3 + processing state → timestamps present, hidden
  by default (opacity 0), system ::after display:none, scroll-behavior smooth,
  thinking-row ES swap live; zero console errors. Files: ui/app.js, ui/app.css,
  ui/i18n.js. Next: P4 (dock/composer + tools + behaviors).
- **2026-07-04 it.5 — P4 DONE.** The dock was already a unified surface (ghost
  composer, / palette, behavior dots) and icons.js AUTO-ICONIZES emojis at runtime
  (the 📎 in source is intentional shorthand — NOT a brand violation; don't "fix").
  Real gaps closed: (1) the 3 hub chips (goals/social/actions) now carry brand
  line-icons (target/megaphone/bolt via WivexxIcons.get, inserted with
  insertAdjacentHTML so the text node — and its i18n — stays intact) + plain-language
  TOOLTIPS ("today's goals & to-dos" / "captions · tracking · deliver" /
  "autoclicker · macro recorder"), both EN+ES (title attrs are translated by i18n).
  (2) .chip is now inline-flex w/ icon opacity hover. DOM-verified at a realistic
  1000px viewport: icons present, tooltips translate live, dock-row single 33px line
  with all 4 behavior dots active (the 2-line wrap seen first was the 325px preview
  tab — flex-wrap handles narrow correctly); zero console errors. Files: ui/app.js,
  ui/app.css, ui/i18n.js. Next: P5 (panel framework).
- **2026-07-04 it.6 — P5 DONE.** Framework-level polish every slide-over panel
  inherits for free (pure CSS — panels.js untouched): (1) scrim now blurs the room
  behind it (backdrop blur 4px, matching lightbox/welcome) + motion tokens;
  (2) a volt brand TICK (3×15px bar) before every panel title via
  .panel-head h2::before — echoes the wordmark dot; (3) panel-body content rises in
  just after the slide on EVERY open (replays thanks to the .gone display:none
  reset). Verified: tick 3px×15px volt, body rise 0.32s, close transform restored,
  zero console errors. GOTCHA (logged for future verifs): the preview tab is often
  document.hidden → Chromium FREEZES CSS transitions at currentTime 0, so computed
  opacity reads its start value forever; the rule is fine — prove it with
  el.getAnimations()[0].finish() (scrim went 0→1). Files: ui/app.css. Next: P6
  (Settings simplification).
- **2026-07-04 it.7 — P6 DONE.** Settings was already well-organized (v1.35
  updates-first reorg; toggle rows have plain-language names+descs — audited, kept).
  Real gap closed: **"welcome tour" replay link** in Settings → manage (✨ sparkle
  icon via EMAP auto-iconize; act:"welcome" branch in the [data-lkey] handler hides
  the panel + calls wivexx.showWelcome()). EN+ES ("tour de bienvenida" / "vuelve a
  ver la intro rápida de 3 pasos"). Verified in preview: row renders iconized,
  click → panel hides + tour opens, ES strings live; zero console errors.
  Files: ui/panels.js, ui/i18n.js. Next: P7 (hub panels: goals/social/actions).
- **2026-07-04 it.8 — P7 DONE.** Hubs already share the P5 skeleton + hub-tabs bar;
  gaps closed: (1) hub tabs now PREVIEW their underline on hover (faint --line bar
  → obvious tab affordance) + motion tokens; (2) goals EMPTY STATE is now a guided
  teach-moment: "No goals yet — type one above, or just tell Wivexx: 'add a goal to
  finish the report'." (EN+ES) — the taught phrase is VERIFIED to route: EN
  classify=command 5.0; ES "agrega un objetivo de terminar el informe" →
  "add a goal to terminar el informe" (verb maps, title stays Spanish — correct).
  Emoji tab labels (📣 report / 🎭 mascot) auto-iconize to brand SVGs — confirmed in
  DOM. Verified: goals renders standalone (stats + form + new empty in EN/ES),
  actions hub tabs active-state OK; zero console errors. Files: ui/panels.js,
  ui/i18n.js, ui/app.css. Next: P8 (overlay windows).
- **2026-07-04 it.9 — P8 DONE.** Audited all 7 overlay windows (overlay/perf/timer/
  status/transfer/timer_alert/goals): already deeply on-brand from the earlier
  alignment pass (shared fonts, --ink cards, volt accents, ✕ affordances). Fixed the
  remaining drift: outer card radius unified to 16px (timer_alert was 18, overlay.html
  card was 20) and --line unified to rgba(242,240,234,0.12) (overlay+perf were 0.10,
  timer_alert 0.14). NOTE: window corner rounding is DWMWCP_ROUND (OS-standard,
  independent of CSS) — CSS radius changes are safe, no native region to match.
  Verified each in preview: radius 16px + line 0.12 computed on timer_alert,
  overlay (.card, WivexxDot boots), perf. Files: ui/timer_alert_overlay.html,
  ui/overlay.html, ui/perf_overlay.html. Next: P9 (tk sidecar + phone web parity).
- **2026-07-04 it.10 — P9 DONE.** tk sidecar / ball overlay / orb surfaces audited:
  already at parity (shared mascot spec, brand PNG icons from task #17, website-green
  orb everywhere) — no churn. Real gap closed: the PHONE WEB page (wivexx_web.py)
  had a completely BLANK chat for new users → added the P1-parity friendly empty
  state ("Connected to Wivexx on your PC. Ask anything, or try one:") + the same 4
  tappable starter chips (sendChip() → box → send(); hidden by addRaw on first
  message). The phone page loads the SAME ui/i18n.js with server-injected lang, so
  the P1 chip strings translate for free; only the new headline needed an ES entry.
  Verified by rendering _PAGE to a temp file under ui/ (served → /icons.js,
  /i18n.js resolve), loading it in preview: empty state + 4 chips render, hide on
  first message, headline + chips translate to ES; sendChip defined; py_compile OK;
  temp file DELETED. Files: wivexx_web.py, ui/i18n.js. Next: P10 (animations +
  reduced motion).
- **2026-07-04 it.11 — P10 DONE.** (1) MOTION TOKEN SWEEP: 90 hardcoded durations in
  app.css migrated to var(--dur-fast/--dur/--dur-slow) via ordered FIXED-STRING
  python replaces (never regex — 0-prefixed forms first so ".18s" can't mangle
  "0.18s"; line-count gate passed). Intentional outliers kept (.12s micro-fades,
  4.6s halo, welcome pops). NOTE: a python rewrite invalidates the Edit tool's
  read-state — re-Read before editing after any scripted file rewrite. (2) PRESS
  FEEDBACK: one uniform :active scale(0.96) across all primary controls (winbtn/
  chip/pbtn/sendbtn/iconbtn/hub-tab/schip/bctl/tc-btn/ma-chip/say-chip/wl-next);
  removed the two old per-control :active overrides. (3) Settings → "Reduce
  animations" now calms the WHOLE UI: setReduceMotion toggles body.reduce-motion,
  mirroring the prefers-reduced-motion kill block (was orb-only). DOM-verified:
  winbtn/chip 0.18s + panel 0.32s computed, press rule in CSSOM, halo 4.6s →
  1e-06s with the setting on → restored off; zero console errors. Files:
  ui/app.css, ui/app.js. Next: P11 (i18n sweep + QA + ONE batch deploy).
- **2026-07-04 it.12 — P11 DONE, REDESIGN COMPLETE, v1.57 LIVE.** Versions bumped
  (wivexx_api WIVEXX_VERSION + installer AppVer/SrcDir → 1.57). ALL SUITES GREEN:
  gate 111/111 kept (PASS) · flow 116/116 · ES cmd ALL PASS · inline ALL PASS ·
  i18n PASS · EN convo 0 route failures/0 memory misses (needs PYTHONIOENCODING=
  utf-8 — cp1252 console chokes on the suite's own → glyphs) · ES convo ALL PASS.
  Preview regression: 13/13 PASS covering P1 chips+tour, P2 collapsed topstate +
  quiet power + tokens, P3 timestamps, P4 chip icons+tooltips, P5 tick+scrim blur,
  P10 press rule + reduce-motion class, ES swap. Built: make_release 297 files,
  secret-scan CLEAN, 71.6MB zip; ISCC installer 82.3MB. Deployed via detached
  worktree off origin/main: staged EXACTLY route.ts (version 1.57 + redesign notes)
  + Wivexx-latest.zip + Wivexx-Setup.exe; commit b327085 pushed 518de3d..b327085;
  worktree removed; /api/version FLIPPED to 1.57 (attempt 7). The whole redesign
  shipped as ONE release, as planned.
