Handbook
Feedback360 UX changelog
Every control that navigates away (tab switch, wiki link, hash jump) now carries a compact arrow button (nav-arrow-btn) with an explicit aria-label. KPI cards, move cards, and the hero bet card open their explainer…
Updated
Arrow navigation affordances (P260, 2026-07-11)
Every control that navigates away (tab switch, wiki link, hash jump) now carries a
compact arrow button (nav-arrow-btn) with an explicit aria-label. KPI cards,
move cards, and the hero bet card open their explainer flyout on a plain click; the
inner arrow performs navigation. Wiki how-to-read updated to describe the split.
Universal explainer flyouts (P250, 2026-07-11)
Click any underlined label, number, or chart element to open a right-side flyout with
element-specific explanation (value, computation, interpretation, sources). Content is
generated in metrics.explainers and recomputed with live parameter changes in the
dynamic app.
UX uplift of the static report report/360-report.html, executed as prompt phases A–K
(2026-07-09). UX score: 52.9 → 85.5 / 100. All six hard gates pass
(final audit: ux-evidence/final/results.json, exit code 0).
Statements v2 sprint — restore, back-port, group, analytics (2026-07-10/11) — 86.4 → 87.7
Final run ux-evidence/stmt2-final/, exit 0, all seven hard gates pass.
- Regeneration wipe incident —
report/360-report.htmlwas overwritten twice (2026-07-10 13:22 and 15:19) bypython -m feedback360re-runs from the Studio orchestration pipeline (phases P130+), whose templates never contained the UX work. Data files were untouched (hashes matched baseline); only presentation was lost. Mitigations: a new hard gatereport_contains_ux_sprint_markupinscripts/ux-audit.mjsfails loudly when the sprint markup (stmt-scale,stmt-view-title) is missing, and — - Template back-port (the durable fix) — the entire UX layer (sprints A–K,
statements declutter, and this sprint) was back-ported into
feedback360/templates/report_template.html(+~1,900 lines CSS/markup/JS) andfeedback360/render_html.py(statement row anatomy, moe-compact, data-driven statements blurb, empty JS-rendered PM/Johari hosts). Regeneration now produces the improved UI:--stage renderoutput is byte-identical to the shipped report (verified),check-30.pyDOM contract passes, and all 79 pipeline unit tests pass. Subject-specific copy (statements blurb, guided-summary hero) is now derived frommetrics.jsoninstead of hardcoded. Pipeline-era features (AI narrative, deck audit, SWOT, section strips, score signals) were preserved, not reverted. Spec + decisions archived inbackport/. - Column-aligned row meta —
.stmt-metais a fixed-column grid (badge 110px / scale 72px / avg 110px / spread 70px / flag 130px / chevron 16px) with explicitgrid-columnpinning, so badge, score dot, avg, spread, flag, and chevron align vertically down the list; rows without a flag keep the empty slot (probe:.stmt-avgx=881 identical on every visible row at 1280px). Mobile reverts to wrapping flex (0px overflow at 390px). - Competency analytics strip —
#stmt-analytics-stripabove the toolbar: an All chip plus 12 compact cards (short name, others-avg, flag count, color-coded score band on the left border), ordered worst-first, built client-side from embedded METRICS (no new data). Clicking a card routes through the existingsetSelectedCompetencypath — same as the select — updating hash (#statements/<slug>), focus bar, and filters; clicking the active card or All resets. Active state (aria-pressed) stays in sync no matter how the selection changes (select, deep link, focus-bar clear). Horizontal scroll row on mobile. Verified: Talent card → exactly 5 DEVELOPS TALENT rows, select + hash synced; card flag counts sum to the 52 flagged statements in metrics. - Three-mode view switcher — segmented control
Top 10 priorities|By competency|All 54replaces the two-state toggle. Grouped mode re-parents the same 54 server-rendered row nodes (no clones — expand state and listeners survive) into 12<details>sections ordered lowest others-avg first, all collapsed by default: full-list scroll drops from 54 rows to 12 headers. Section headers show short name, others-avg, flag count, lowest statement score, and a "N of M" count when filtered. Search / flag chips / competency filters work across groups (matching sections auto-expand, empty ones hide); sort applies within sections; deep links work in all three modes. Negative check verified: DOM always holds exactly 54 row nodes across all six mode transitions. - Docs — wiki
how-to-read.htmlStatements section rewritten (view modes + analytics strip); scorecard and this changelog updated. - Integrity —
data.json/metrics.jsonbyte-identical (gate PASS every phase). File size 679 → 704 KB, still fully offline, 0 console errors. Nav 4.6→4.8, CogLoad 4.5→4.7, Viz 4.4→4.5, Perf/Maint 4.2→4.6; no category regressed. Snapshot:snapshots/360-report.stmt2-grouping.html.
Statements declutter sprint (2026-07-10) — 85.5 → 86.4
Focused noise-reduction pass on the Statements tab (three phases, each audited;
final run ux-evidence/stmt-declutter/, exit 0, all six hard gates pass):
- Row anatomy — replaced the broken 4-column grid (
1fr auto auto autowith up to 9 children wrapping into arbitrary cells, producing full-width phantom pills) with a flex layout: statement text + right-aligned meta cluster + chevron. Avg and spread values now carry visible desktop labels ("Others avg", "Spread") instead of hover-only tooltips; mobile::beforepseudo-labels removed in favor of real elements. - One signal per row — collapsed rows show at most one flag chip, chosen by
severity (lowest overall → low score → manager low → self overrated → high
disagreement). All 84 flag chips plus the score-signal/verdict chips moved into the
expanded detail (
.stmt-detail-signals). Rationale: high-disagreement flagged 46 of 54 rows — a chip on 85% of rows carries no signal.data-flagsuntouched, so flag filtering behaves identically (verified: manager-low filter still returns 28 rows). - Inline score encoding — each row gets a 1–7 track with a positioned dot (warm < 5.3, accent mid, green ≥ 6.0) so scanning the list shows the score gradient without reading numbers.
- Named default view — heading "Top 10 development priorities" with a one-line ranking-basis note; switches to "All 54 statements" on toggle and appends "· N shown" when filters narrow the priority view below ten. Summary strip compressed from four lines to one sentence. Flag filter chips show counts (e.g. "high disagreement · 46"). Search, competency, sort, and view toggle merged into a single toolbar row; first data row now fully visible at 1280×800 without scrolling.
- Docs —
report/wiki/how-to-read.htmlStatements section rewritten to match. - Integrity —
data.json,metrics.json, embedded#report-databyte-identical (hash gate PASS every phase). Actions/Voices tabs pixel-identical (shared.comp-badgerule untouched). File size 652 KB → 679 KB (+4.2%), still fully offline. Cognitive-load 4.2 → 4.5, Data-viz clarity 4.3 → 4.4; no category regressed.
Score progression
| Phase | Total | Gate |
|---|---|---|
| A — baseline + harness | 52.9 | measurement system created |
| B — responsive navigation | 58.2 | +5 minimum met |
| C — guided Summary | 64.7 | Guided ≥ 3.7 met (4.1) |
| D — Matrix mobile | 68.2 | Mobile ≥ 2.8 met |
| E — Gaps/Divergence | 72.1 | Sprint 1 met (≥70, Mobile ≥3.2, A11y ≥3.2) |
| F+G — Perception/Statements | 76.7 | Mobile ≥ 3.4 met (3.9) |
| H+I — Voices/Actions | 81.5 | Actionability ≥ 4.3 met (4.4) |
| J — competency focus | 84.0 | Sprint 2 met (≥82) |
| K — final a11y/regression | 85.5 | A11y ≥ 4.0 (4.1), Mobile ≥ 3.8 (4.1) |
No category regressed more than 0.2 rating points at any phase.
UX changes by tab
- Global — sticky tab nav (mobile: single scrollable row, was a 150px wrapped block);
roving tabindex with Arrow/Home/End keys; hash deep links (
#matrix,#actions, …) plus#tab/competencydeep links (#statements/vision); global competency focus bar with cross-tab highlighting (matches accented, others dimmed, never hidden); 44px touch targets; 2px accent:focus-visibleoutlines everywhere. - Summary — "Start here" layout: hero development-bet card (Vision visibility gap) with evidence links, top-3 next moves from CTA data, main-risk and strengths cards; all original findings/KPIs behind "View all findings"; margin-of-error condensed to a one-line warning with expandable full text; confidence badge legend.
- Matrix — plain-English quadrant legend + axis helpers; 44px keyboard-focusable scatter points opening the detail dialog; mobile card view grouped by quadrant with the chart behind a "View chart" toggle.
- Gaps — legend (gap direction, self/others dot colors), labeled rank values, mobile overflow fixed 186→0px via scroll container with swipe hint.
- Divergence — rows sorted by divergence descending; color-scale legend; readable cell text; 48 heat cells keyboard-focusable (Enter/Space opens statement detail); overflow 34→0px.
- Perception — two plain-English section questions; mobile card-per-competency layout (overflow 146→0px); Johari quadrants explained one line each, mobile accordions.
- Statements — default top-10 priority view (flag-based ranking from existing row data) with "Show all 54" toggle; text search combined with existing filters/sort; labeled mobile values ("Others avg: 4.9", "Spread: 3"); dot-strip legend in expanded rows.
- Voices — themes collapsed except top 2, with sentiment labels ("Positive +0.49"), competency badges, preview excerpts, show-all-quotes controls; sentiment/competency/ keyword filters; confidentiality note above raw comments; duplicate summary removed from the visible layer.
- Actions — coaching-ready cards: why-priority bullets, 30/60/90 plan, success metric, evidence links; formula behind "Advanced scoring" disclosure; "Copy action plan" (offline-safe clipboard); "Reset weights" + weight-sum display with drift warning; slider recomputation preserved and verified.
- Accessibility (final pass) — competency detail panel is a proper dialog (role, aria-modal, labelled title, focus-in on open, Escape closes, focus returns to trigger, focus trapped) — verified via Playwright.
Data integrity statement
data.json, metrics.json, and the embedded #report-data JSON are byte-identical
to baseline (sha256 verified every phase against ux-evidence/baseline-hashes.json;
final run: data_files_unchanged: PASS). No ratings, metrics, comments, competency
names, priorities, or formulas were changed. computePriority untouched.
Evidence
Screenshots + DOM probes per phase under ux-evidence/ (baseline/, prompt-b/,
prompt-c2/, prompt-d/, prompt-e/, prompt-fg/, prompt-hi/, prompt-j/,
prompt-k/, final/). Per-phase HTML snapshots in snapshots/. Audit harness:
scripts/ux-audit.mjs (Playwright; run instructions in UX_SCORECARD.md).
Known limitations
- Header "How to read this report" link is 40px tall (below the 44px target; only remaining small target).
- Competency detail dialog exposes a single tabbable control (close button); the focus trap holds there rather than cycling multiple controls.
- Report file grew 600 KB → 652 KB (+8.6%, all inline CSS/JS; still fully offline, zero external requests, zero console errors).
- Focus-bar label uses short competency names (e.g. "Vision"), and hash slugs are
lowercased short names (
eifor Emotional Intelligence).