validation-report-template.html 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319
  1. <!DOCTYPE html>
  2. <!--
  3. UX Design Validation Report — skeleton template.
  4. This file is a starter the synthesis pass fills in directly. There is no
  5. substitution engine. The LLM:
  6. 1. Reads {doc_workspace}/review-rubric.md and every review-{slug}.md from
  7. additional reviewers.
  8. 2. Copies this skeleton.
  9. 3. Replaces the placeholder content (everything between TEMPLATE markers)
  10. with the consolidated review, preserving the structure and CSS.
  11. 4. Writes the result to {doc_workspace}/validation-report.html.
  12. 5. Writes a markdown twin to {doc_workspace}/validation-report.md.
  13. Visual rules the LLM must preserve:
  14. - The container width, the color tokens, the typography.
  15. - One dimension = one collapsible <section class="dimension">.
  16. - Verdict pill uses the verdict-* class matching its judgment.
  17. - Severity badge uses the badge-sev-* class matching its level.
  18. - Each extra reviewer (accessibility, adversarial, etc.) gets its own
  19. collapsible section below the rubric dimensions.
  20. - The footer always shows the artifact paths and timestamp.
  21. -->
  22. <html lang="en">
  23. <head>
  24. <meta charset="utf-8">
  25. <title>UX Design Validation: TEMPLATE_UX_SPEC_NAME</title>
  26. <style>
  27. :root {
  28. --bg: #fafaf9;
  29. --surface: #ffffff;
  30. --border: #e7e5e4;
  31. --text: #1c1917;
  32. --muted: #78716c;
  33. --verdict-strong: #16a34a;
  34. --verdict-adequate: #65a30d;
  35. --verdict-thin: #d97706;
  36. --verdict-broken: #dc2626;
  37. --sev-low: #64748b;
  38. --sev-medium: #ca8a04;
  39. --sev-high: #ea580c;
  40. --sev-critical: #dc2626;
  41. }
  42. * { box-sizing: border-box; }
  43. html, body { margin: 0; padding: 0; }
  44. body {
  45. font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Inter, system-ui, sans-serif;
  46. background: var(--bg);
  47. color: var(--text);
  48. line-height: 1.6;
  49. font-size: 15px;
  50. }
  51. .container { max-width: 960px; margin: 0 auto; padding: 32px 24px 64px; }
  52. header.report-header {
  53. display: flex;
  54. align-items: flex-start;
  55. justify-content: space-between;
  56. gap: 24px;
  57. padding-bottom: 16px;
  58. border-bottom: 1px solid var(--border);
  59. margin-bottom: 24px;
  60. }
  61. .title h1 { margin: 0; font-size: 22px; font-weight: 600; letter-spacing: -0.01em; }
  62. .title .subtitle { color: var(--muted); font-size: 13px; margin-top: 4px; font-family: ui-monospace, "SF Mono", Menlo, monospace; }
  63. .synthesis {
  64. background: var(--surface);
  65. border: 1px solid var(--border);
  66. border-left: 3px solid var(--muted);
  67. border-radius: 8px;
  68. padding: 18px 22px;
  69. margin-bottom: 24px;
  70. font-size: 15.5px;
  71. }
  72. .synthesis p { margin: 0 0 10px; }
  73. .synthesis p:last-child { margin-bottom: 0; }
  74. .dimension-summary {
  75. display: grid;
  76. grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));
  77. gap: 10px;
  78. margin-bottom: 24px;
  79. }
  80. .dim-card {
  81. background: var(--surface);
  82. border: 1px solid var(--border);
  83. border-radius: 8px;
  84. padding: 12px 14px;
  85. }
  86. .dim-card .dim-name { font-size: 13px; color: var(--muted); margin-bottom: 6px; }
  87. .dim-card .dim-verdict { font-size: 14px; font-weight: 600; }
  88. section.dimension, section.reviewer-section { margin-bottom: 14px; }
  89. section.dimension details, section.reviewer-section details {
  90. background: var(--surface);
  91. border: 1px solid var(--border);
  92. border-radius: 8px;
  93. overflow: hidden;
  94. }
  95. section summary {
  96. padding: 14px 20px;
  97. cursor: pointer;
  98. user-select: none;
  99. list-style: none;
  100. display: flex;
  101. align-items: center;
  102. gap: 12px;
  103. }
  104. section summary::-webkit-details-marker { display: none; }
  105. section summary::before {
  106. content: "▸";
  107. display: inline-block;
  108. color: var(--muted);
  109. transition: transform 0.15s ease;
  110. }
  111. section details[open] summary::before { transform: rotate(90deg); }
  112. section summary h2 {
  113. display: inline;
  114. margin: 0;
  115. font-size: 16px;
  116. font-weight: 600;
  117. letter-spacing: -0.005em;
  118. flex: 1;
  119. }
  120. .verdict-pill {
  121. font-size: 11px;
  122. padding: 3px 10px;
  123. border-radius: 999px;
  124. font-weight: 600;
  125. text-transform: uppercase;
  126. letter-spacing: 0.04em;
  127. color: white;
  128. }
  129. .verdict-strong { background: var(--verdict-strong); }
  130. .verdict-adequate { background: var(--verdict-adequate); }
  131. .verdict-thin { background: var(--verdict-thin); }
  132. .verdict-broken { background: var(--verdict-broken); }
  133. .dim-body { padding: 4px 20px 18px; }
  134. .dim-judgment { color: var(--text); font-size: 14.5px; }
  135. .dim-judgment p { margin: 0 0 10px; }
  136. .findings-list { padding: 0 20px 4px; }
  137. article.finding {
  138. padding: 14px 0;
  139. border-top: 1px solid var(--border);
  140. }
  141. article.finding:first-child { border-top: none; }
  142. article.finding header {
  143. display: flex;
  144. align-items: center;
  145. gap: 10px;
  146. flex-wrap: wrap;
  147. margin-bottom: 6px;
  148. }
  149. .badge {
  150. font-size: 10.5px;
  151. padding: 3px 8px;
  152. border-radius: 4px;
  153. font-weight: 600;
  154. text-transform: uppercase;
  155. letter-spacing: 0.04em;
  156. line-height: 1.4;
  157. }
  158. .badge-sev-low { background: rgba(100, 116, 139, 0.12); color: var(--sev-low); }
  159. .badge-sev-medium { background: rgba(202, 138, 4, 0.14); color: var(--sev-medium); }
  160. .badge-sev-high { background: rgba(234, 88, 12, 0.14); color: var(--sev-high); }
  161. .badge-sev-critical { background: rgba(220, 38, 38, 0.14); color: var(--sev-critical); }
  162. .finding-title { margin: 0; font-size: 15px; font-weight: 500; flex: 1; min-width: 200px; }
  163. .finding-location { font-family: ui-monospace, "SF Mono", Menlo, monospace; font-size: 12.5px; color: var(--muted); }
  164. .finding-note, .finding-fix { margin-top: 6px; font-size: 14px; }
  165. .finding-fix strong { color: var(--muted); font-weight: 500; }
  166. .reviewer-source {
  167. font-size: 12px;
  168. color: var(--muted);
  169. font-family: ui-monospace, "SF Mono", Menlo, monospace;
  170. }
  171. .mechanical {
  172. background: var(--surface);
  173. border: 1px solid var(--border);
  174. border-radius: 8px;
  175. padding: 16px 20px;
  176. margin-top: 24px;
  177. font-size: 14px;
  178. }
  179. .mechanical h3 { margin: 0 0 10px; font-size: 14px; font-weight: 600; color: var(--muted); text-transform: uppercase; letter-spacing: 0.04em; }
  180. .mechanical ul { margin: 0; padding-left: 20px; }
  181. .mechanical li { margin-bottom: 4px; color: var(--text); }
  182. footer.report-footer {
  183. margin-top: 40px;
  184. padding-top: 16px;
  185. border-top: 1px solid var(--border);
  186. font-size: 12px;
  187. color: var(--muted);
  188. font-family: ui-monospace, "SF Mono", Menlo, monospace;
  189. }
  190. footer .meta { display: flex; gap: 24px; flex-wrap: wrap; }
  191. </style>
  192. </head>
  193. <body>
  194. <div class="container">
  195. <!-- TEMPLATE: header. Fill ux spec name and ux spec path. No overall grade —
  196. per-category verdicts and severity counts below carry the picture. -->
  197. <header class="report-header">
  198. <div class="title">
  199. <h1>TEMPLATE_UX_SPEC_NAME — UX Design Validation Report</h1>
  200. <div class="subtitle">TEMPLATE_UX_SPEC_PATH</div>
  201. </div>
  202. </header>
  203. <!-- TEMPLATE: overall synthesis paragraphs. Lift directly from
  204. review-rubric.md "Overall verdict" section; expand if extra reviewers
  205. (accessibility, adversarial, etc.) materially shift the picture.
  206. Wrap each paragraph in <p>. -->
  207. <div class="synthesis">
  208. <p>TEMPLATE_SYNTHESIS_PARAGRAPH</p>
  209. </div>
  210. <!-- TEMPLATE: dimension summary cards. One per rubric category, in this
  211. canonical order (from references/validate.md):
  212. 1. Flow coverage
  213. 2. Token completeness
  214. 3. Component coverage
  215. 4. State coverage
  216. 5. Visual reference coverage
  217. 6. Bloat & overspecification
  218. 7. Inheritance discipline
  219. 8. Shape fit
  220. The dim-verdict text uses one of: strong | adequate | thin | broken. -->
  221. <div class="dimension-summary">
  222. <div class="dim-card">
  223. <div class="dim-name">TEMPLATE_CATEGORY_NAME</div>
  224. <div class="dim-verdict" style="color: var(--verdict-TEMPLATE_VERDICT)">TEMPLATE_VERDICT_TEXT</div>
  225. </div>
  226. <!-- repeat for each of the eight rubric categories -->
  227. </div>
  228. <!-- TEMPLATE: one section per rubric category, same canonical order as the
  229. summary cards above. Skip a category entirely if the rubric review
  230. marked it n/a for this UX spec. Open the section by default if verdict
  231. is thin or broken. -->
  232. <section class="dimension">
  233. <details open>
  234. <summary>
  235. <h2>TEMPLATE_CATEGORY_NAME</h2>
  236. <span class="verdict-pill verdict-TEMPLATE_VERDICT">TEMPLATE_VERDICT_TEXT</span>
  237. </summary>
  238. <div class="dim-body">
  239. <div class="dim-judgment">
  240. <p>TEMPLATE_DIMENSION_JUDGMENT</p>
  241. </div>
  242. </div>
  243. <div class="findings-list">
  244. <!-- TEMPLATE: zero or more findings -->
  245. <article class="finding">
  246. <header>
  247. <span class="badge badge-sev-TEMPLATE_SEVERITY">TEMPLATE_SEVERITY</span>
  248. <h3 class="finding-title">TEMPLATE_FINDING_TITLE</h3>
  249. <span class="finding-location">TEMPLATE_LOCATION</span>
  250. </header>
  251. <div class="finding-note">TEMPLATE_FINDING_NOTE</div>
  252. <div class="finding-fix"><strong>Fix:</strong> TEMPLATE_SUGGESTED_FIX</div>
  253. </article>
  254. </div>
  255. </details>
  256. </section>
  257. <!-- TEMPLATE: one section per extra reviewer that ran (accessibility,
  258. adversarial, brand-conformance, etc.). Skip this block entirely if
  259. only the rubric walker ran. -->
  260. <section class="reviewer-section">
  261. <details>
  262. <summary>
  263. <h2>Accessibility review</h2>
  264. <span class="reviewer-source">TEMPLATE_REVIEWER_SOURCE_FILE</span>
  265. </summary>
  266. <div class="dim-body">
  267. <div class="dim-judgment">
  268. <p>TEMPLATE_REVIEWER_PREAMBLE</p>
  269. </div>
  270. </div>
  271. <div class="findings-list">
  272. <article class="finding">
  273. <header>
  274. <span class="badge badge-sev-TEMPLATE_SEVERITY">TEMPLATE_SEVERITY</span>
  275. <h3 class="finding-title">TEMPLATE_FINDING_TITLE</h3>
  276. <span class="finding-location">TEMPLATE_LOCATION</span>
  277. </header>
  278. <div class="finding-note">TEMPLATE_FINDING_NOTE</div>
  279. <div class="finding-fix"><strong>Fix:</strong> TEMPLATE_SUGGESTED_FIX</div>
  280. </article>
  281. </div>
  282. </details>
  283. </section>
  284. <!-- TEMPLATE: mechanical notes — short, bulleted. Skip if there are none. -->
  285. <div class="mechanical">
  286. <h3>Mechanical notes</h3>
  287. <ul>
  288. <li>TEMPLATE_MECHANICAL_NOTE</li>
  289. </ul>
  290. </div>
  291. <footer class="report-footer">
  292. <div class="meta">
  293. <span>Rubric: TEMPLATE_RUBRIC_PATH</span>
  294. <span>Generated: TEMPLATE_TIMESTAMP</span>
  295. </div>
  296. </footer>
  297. </div>
  298. </body>
  299. </html>