cbrowser 20.2.2 → 21.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (302) hide show
  1. package/README.md +2 -2
  2. package/dist/analysis/accessibility-empathy.d.ts +29 -1
  3. package/dist/analysis/accessibility-empathy.d.ts.map +1 -1
  4. package/dist/analysis/accessibility-empathy.js +69 -35
  5. package/dist/analysis/accessibility-empathy.js.map +1 -1
  6. package/dist/browser.d.ts.map +1 -1
  7. package/dist/browser.js +11 -7
  8. package/dist/browser.js.map +1 -1
  9. package/dist/cif-score.d.ts +56 -5
  10. package/dist/cif-score.d.ts.map +1 -1
  11. package/dist/cif-score.js +595 -346
  12. package/dist/cif-score.js.map +1 -1
  13. package/dist/cli.js +10 -8
  14. package/dist/cli.js.map +1 -1
  15. package/dist/cognitive/default-traits.d.ts +14 -0
  16. package/dist/cognitive/default-traits.d.ts.map +1 -0
  17. package/dist/cognitive/default-traits.js +36 -0
  18. package/dist/cognitive/default-traits.js.map +1 -0
  19. package/dist/cognitive/emotions.d.ts.map +1 -1
  20. package/dist/cognitive/emotions.js +104 -174
  21. package/dist/cognitive/emotions.js.map +1 -1
  22. package/dist/cognitive/index.d.ts +28 -0
  23. package/dist/cognitive/index.d.ts.map +1 -1
  24. package/dist/cognitive/index.js +353 -287
  25. package/dist/cognitive/index.js.map +1 -1
  26. package/dist/cognitive/temporal.d.ts +0 -24
  27. package/dist/cognitive/temporal.d.ts.map +1 -1
  28. package/dist/cognitive/temporal.js +45 -35
  29. package/dist/cognitive/temporal.js.map +1 -1
  30. package/dist/data/ctc-reference-v2-2026-10-24.d.ts +16 -0
  31. package/dist/data/ctc-reference-v2-2026-10-24.d.ts.map +1 -0
  32. package/dist/data/ctc-reference-v2-2026-10-24.js +1004 -0
  33. package/dist/data/ctc-reference-v2-2026-10-24.js.map +1 -0
  34. package/dist/ideal-profiles-gap.d.ts +1 -0
  35. package/dist/ideal-profiles-gap.d.ts.map +1 -1
  36. package/dist/ideal-profiles-gap.js +9 -1
  37. package/dist/ideal-profiles-gap.js.map +1 -1
  38. package/dist/ideal-profiles.d.ts +8 -0
  39. package/dist/ideal-profiles.d.ts.map +1 -1
  40. package/dist/ideal-profiles.js +28 -24
  41. package/dist/ideal-profiles.js.map +1 -1
  42. package/dist/mcp-server-remote.d.ts.map +1 -1
  43. package/dist/mcp-server-remote.js +7 -8
  44. package/dist/mcp-server-remote.js.map +1 -1
  45. package/dist/mcp-tools/account-personas.d.ts.map +1 -1
  46. package/dist/mcp-tools/account-personas.js +3 -1
  47. package/dist/mcp-tools/account-personas.js.map +1 -1
  48. package/dist/mcp-tools/base/answer-provenance.d.ts +28 -0
  49. package/dist/mcp-tools/base/answer-provenance.d.ts.map +1 -0
  50. package/dist/mcp-tools/base/answer-provenance.js +32 -0
  51. package/dist/mcp-tools/base/answer-provenance.js.map +1 -0
  52. package/dist/mcp-tools/base/audit-tools.d.ts +0 -3
  53. package/dist/mcp-tools/base/audit-tools.d.ts.map +1 -1
  54. package/dist/mcp-tools/base/audit-tools.js +152 -84
  55. package/dist/mcp-tools/base/audit-tools.js.map +1 -1
  56. package/dist/mcp-tools/base/capture-tools.js +1 -1
  57. package/dist/mcp-tools/base/capture-tools.js.map +1 -1
  58. package/dist/mcp-tools/base/chain-values.d.ts +38 -0
  59. package/dist/mcp-tools/base/chain-values.d.ts.map +1 -0
  60. package/dist/mcp-tools/base/chain-values.js +85 -0
  61. package/dist/mcp-tools/base/chain-values.js.map +1 -0
  62. package/dist/mcp-tools/base/cognitive-tools.d.ts.map +1 -1
  63. package/dist/mcp-tools/base/cognitive-tools.js +126 -120
  64. package/dist/mcp-tools/base/cognitive-tools.js.map +1 -1
  65. package/dist/mcp-tools/base/gif-tools.d.ts.map +1 -1
  66. package/dist/mcp-tools/base/gif-tools.js +23 -5
  67. package/dist/mcp-tools/base/gif-tools.js.map +1 -1
  68. package/dist/mcp-tools/base/persona-comparison-tools.d.ts.map +1 -1
  69. package/dist/mcp-tools/base/persona-comparison-tools.js +229 -172
  70. package/dist/mcp-tools/base/persona-comparison-tools.js.map +1 -1
  71. package/dist/mcp-tools/base/site-familiarity.d.ts +31 -0
  72. package/dist/mcp-tools/base/site-familiarity.d.ts.map +1 -0
  73. package/dist/mcp-tools/base/site-familiarity.js +30 -0
  74. package/dist/mcp-tools/base/site-familiarity.js.map +1 -0
  75. package/dist/mcp-tools/base/site-knowledge-tools.js +1 -1
  76. package/dist/mcp-tools/base/site-knowledge-tools.js.map +1 -1
  77. package/dist/mcp-tools/base/story-narrative.d.ts +50 -0
  78. package/dist/mcp-tools/base/story-narrative.d.ts.map +1 -0
  79. package/dist/mcp-tools/base/story-narrative.js +88 -0
  80. package/dist/mcp-tools/base/story-narrative.js.map +1 -0
  81. package/dist/mcp-tools/base/values-tools.d.ts.map +1 -1
  82. package/dist/mcp-tools/base/values-tools.js +19 -5
  83. package/dist/mcp-tools/base/values-tools.js.map +1 -1
  84. package/dist/mcp-tools/base/visual-testing-tools.d.ts +5 -5
  85. package/dist/mcp-tools/base/visual-testing-tools.d.ts.map +1 -1
  86. package/dist/mcp-tools/base/visual-testing-tools.js +38 -11
  87. package/dist/mcp-tools/base/visual-testing-tools.js.map +1 -1
  88. package/dist/mcp-tools/persona-creation-tools.js +6 -6
  89. package/dist/mcp-tools/persona-creation-tools.js.map +1 -1
  90. package/dist/mcp-tools/persona-lifecycle-tools.d.ts.map +1 -1
  91. package/dist/mcp-tools/persona-lifecycle-tools.js +5 -1
  92. package/dist/mcp-tools/persona-lifecycle-tools.js.map +1 -1
  93. package/dist/mcp-tools/tier-gate.js +1 -1
  94. package/dist/mcp-tools/tool-result-saver.d.ts +7 -0
  95. package/dist/mcp-tools/tool-result-saver.d.ts.map +1 -1
  96. package/dist/mcp-tools/tool-result-saver.js +11 -0
  97. package/dist/mcp-tools/tool-result-saver.js.map +1 -1
  98. package/dist/mcp-tools/trait-provenance.d.ts +109 -0
  99. package/dist/mcp-tools/trait-provenance.d.ts.map +1 -0
  100. package/dist/mcp-tools/trait-provenance.js +187 -0
  101. package/dist/mcp-tools/trait-provenance.js.map +1 -0
  102. package/dist/mcp-tools/ui-resources.d.ts +6 -7
  103. package/dist/mcp-tools/ui-resources.d.ts.map +1 -1
  104. package/dist/mcp-tools/ui-resources.js +162 -12
  105. package/dist/mcp-tools/ui-resources.js.map +1 -1
  106. package/dist/mcp-tools/widget-kit.d.ts +129 -3
  107. package/dist/mcp-tools/widget-kit.d.ts.map +1 -1
  108. package/dist/mcp-tools/widget-kit.js +507 -28
  109. package/dist/mcp-tools/widget-kit.js.map +1 -1
  110. package/dist/performance/metrics.d.ts.map +1 -1
  111. package/dist/performance/metrics.js +4 -1
  112. package/dist/performance/metrics.js.map +1 -1
  113. package/dist/persona-questionnaire.js +1 -1
  114. package/dist/persona-questionnaire.js.map +1 -1
  115. package/dist/personas.d.ts.map +1 -1
  116. package/dist/personas.js +133 -82
  117. package/dist/personas.js.map +1 -1
  118. package/dist/recording/engine.d.ts.map +1 -1
  119. package/dist/recording/engine.js +5 -2
  120. package/dist/recording/engine.js.map +1 -1
  121. package/dist/recording/saliency-overlay.d.ts +8 -3
  122. package/dist/recording/saliency-overlay.d.ts.map +1 -1
  123. package/dist/recording/saliency-overlay.js +14 -5
  124. package/dist/recording/saliency-overlay.js.map +1 -1
  125. package/dist/recording/types.js +1 -1
  126. package/dist/testing/nl-test-suite.d.ts.map +1 -1
  127. package/dist/testing/nl-test-suite.js +2 -1
  128. package/dist/testing/nl-test-suite.js.map +1 -1
  129. package/dist/trait-reference.d.ts +19 -2
  130. package/dist/trait-reference.d.ts.map +1 -1
  131. package/dist/trait-reference.js +19 -2
  132. package/dist/trait-reference.js.map +1 -1
  133. package/dist/types.d.ts +32 -21
  134. package/dist/types.d.ts.map +1 -1
  135. package/dist/types.js +62 -52
  136. package/dist/types.js.map +1 -1
  137. package/dist/values/persona-completeness.js +1 -1
  138. package/dist/values/persona-completeness.js.map +1 -1
  139. package/dist/visual/ab-comparison.d.ts.map +1 -1
  140. package/dist/visual/ab-comparison.js +4 -1
  141. package/dist/visual/ab-comparison.js.map +1 -1
  142. package/dist/visual/attention-quality.d.ts +1 -1
  143. package/dist/visual/attention-quality.js +1 -1
  144. package/dist/visual/attention-transport.d.ts +74 -10
  145. package/dist/visual/attention-transport.d.ts.map +1 -1
  146. package/dist/visual/attention-transport.js +353 -193
  147. package/dist/visual/attention-transport.js.map +1 -1
  148. package/dist/visual/cognitive-models.d.ts +77 -55
  149. package/dist/visual/cognitive-models.d.ts.map +1 -1
  150. package/dist/visual/cognitive-models.js +231 -104
  151. package/dist/visual/cognitive-models.js.map +1 -1
  152. package/dist/visual/cognitive-transport-chain.d.ts +328 -30
  153. package/dist/visual/cognitive-transport-chain.d.ts.map +1 -1
  154. package/dist/visual/cognitive-transport-chain.js +576 -353
  155. package/dist/visual/cognitive-transport-chain.js.map +1 -1
  156. package/dist/visual/cognitive-transport.d.ts +446 -13
  157. package/dist/visual/cognitive-transport.d.ts.map +1 -1
  158. package/dist/visual/cognitive-transport.js +1085 -245
  159. package/dist/visual/cognitive-transport.js.map +1 -1
  160. package/dist/visual/cross-browser.d.ts.map +1 -1
  161. package/dist/visual/cross-browser.js +8 -6
  162. package/dist/visual/cross-browser.js.map +1 -1
  163. package/dist/visual/ctc-bands.d.ts +91 -0
  164. package/dist/visual/ctc-bands.d.ts.map +1 -0
  165. package/dist/visual/ctc-bands.js +117 -0
  166. package/dist/visual/ctc-bands.js.map +1 -0
  167. package/dist/visual/ctc-reference.d.ts +287 -0
  168. package/dist/visual/ctc-reference.d.ts.map +1 -0
  169. package/dist/visual/ctc-reference.js +376 -0
  170. package/dist/visual/ctc-reference.js.map +1 -0
  171. package/dist/visual/demand-laws.d.ts +145 -0
  172. package/dist/visual/demand-laws.d.ts.map +1 -0
  173. package/dist/visual/demand-laws.js +220 -0
  174. package/dist/visual/demand-laws.js.map +1 -0
  175. package/dist/visual/distance-metrics.d.ts +23 -1
  176. package/dist/visual/distance-metrics.d.ts.map +1 -1
  177. package/dist/visual/distance-metrics.js +49 -18
  178. package/dist/visual/distance-metrics.js.map +1 -1
  179. package/dist/visual/dro-bound.d.ts +220 -0
  180. package/dist/visual/dro-bound.d.ts.map +1 -0
  181. package/dist/visual/dro-bound.js +341 -0
  182. package/dist/visual/dro-bound.js.map +1 -0
  183. package/dist/visual/exact-w1.d.ts +60 -0
  184. package/dist/visual/exact-w1.d.ts.map +1 -0
  185. package/dist/visual/exact-w1.js +247 -0
  186. package/dist/visual/exact-w1.js.map +1 -0
  187. package/dist/visual/human-input.d.ts.map +1 -1
  188. package/dist/visual/human-input.js +45 -41
  189. package/dist/visual/human-input.js.map +1 -1
  190. package/dist/visual/index.d.ts +2 -0
  191. package/dist/visual/index.d.ts.map +1 -1
  192. package/dist/visual/index.js +2 -0
  193. package/dist/visual/index.js.map +1 -1
  194. package/dist/visual/law-times-report.d.ts +49 -0
  195. package/dist/visual/law-times-report.d.ts.map +1 -0
  196. package/dist/visual/law-times-report.js +38 -0
  197. package/dist/visual/law-times-report.js.map +1 -0
  198. package/dist/visual/model-provenance.d.ts +151 -0
  199. package/dist/visual/model-provenance.d.ts.map +1 -0
  200. package/dist/visual/model-provenance.js +334 -0
  201. package/dist/visual/model-provenance.js.map +1 -0
  202. package/dist/visual/normal-cdf.d.ts +14 -0
  203. package/dist/visual/normal-cdf.d.ts.map +1 -0
  204. package/dist/visual/normal-cdf.js +26 -0
  205. package/dist/visual/normal-cdf.js.map +1 -0
  206. package/dist/visual/perceptual-transport.d.ts +28 -4
  207. package/dist/visual/perceptual-transport.d.ts.map +1 -1
  208. package/dist/visual/perceptual-transport.js +66 -32
  209. package/dist/visual/perceptual-transport.js.map +1 -1
  210. package/dist/visual/provenance/attention.d.ts +55 -0
  211. package/dist/visual/provenance/attention.d.ts.map +1 -0
  212. package/dist/visual/provenance/attention.js +188 -0
  213. package/dist/visual/provenance/attention.js.map +1 -0
  214. package/dist/visual/provenance/chain.d.ts +41 -0
  215. package/dist/visual/provenance/chain.d.ts.map +1 -0
  216. package/dist/visual/provenance/chain.js +66 -0
  217. package/dist/visual/provenance/chain.js.map +1 -0
  218. package/dist/visual/provenance/cif.d.ts +42 -0
  219. package/dist/visual/provenance/cif.d.ts.map +1 -0
  220. package/dist/visual/provenance/cif.js +116 -0
  221. package/dist/visual/provenance/cif.js.map +1 -0
  222. package/dist/visual/provenance/ctc-reference.d.ts +36 -0
  223. package/dist/visual/provenance/ctc-reference.d.ts.map +1 -0
  224. package/dist/visual/provenance/ctc-reference.js +96 -0
  225. package/dist/visual/provenance/ctc-reference.js.map +1 -0
  226. package/dist/visual/provenance/distance.d.ts +10 -0
  227. package/dist/visual/provenance/distance.d.ts.map +1 -0
  228. package/dist/visual/provenance/distance.js +72 -0
  229. package/dist/visual/provenance/distance.js.map +1 -0
  230. package/dist/visual/provenance/dro.d.ts +10 -0
  231. package/dist/visual/provenance/dro.d.ts.map +1 -0
  232. package/dist/visual/provenance/dro.js +2 -0
  233. package/dist/visual/provenance/dro.js.map +1 -0
  234. package/dist/visual/provenance/emotion.d.ts +26 -0
  235. package/dist/visual/provenance/emotion.d.ts.map +1 -0
  236. package/dist/visual/provenance/emotion.js +99 -0
  237. package/dist/visual/provenance/emotion.js.map +1 -0
  238. package/dist/visual/provenance/human-input.d.ts +19 -0
  239. package/dist/visual/provenance/human-input.d.ts.map +1 -0
  240. package/dist/visual/provenance/human-input.js +84 -0
  241. package/dist/visual/provenance/human-input.js.map +1 -0
  242. package/dist/visual/provenance/journey-group.d.ts +15 -0
  243. package/dist/visual/provenance/journey-group.d.ts.map +1 -0
  244. package/dist/visual/provenance/journey-group.js +15 -0
  245. package/dist/visual/provenance/journey-group.js.map +1 -0
  246. package/dist/visual/provenance/journey-mcp.d.ts +24 -0
  247. package/dist/visual/provenance/journey-mcp.d.ts.map +1 -0
  248. package/dist/visual/provenance/journey-mcp.js +54 -0
  249. package/dist/visual/provenance/journey-mcp.js.map +1 -0
  250. package/dist/visual/provenance/journey.d.ts +34 -0
  251. package/dist/visual/provenance/journey.d.ts.map +1 -0
  252. package/dist/visual/provenance/journey.js +184 -0
  253. package/dist/visual/provenance/journey.js.map +1 -0
  254. package/dist/visual/provenance/laws.d.ts +38 -0
  255. package/dist/visual/provenance/laws.d.ts.map +1 -0
  256. package/dist/visual/provenance/laws.js +40 -0
  257. package/dist/visual/provenance/laws.js.map +1 -0
  258. package/dist/visual/provenance/page-metrics.d.ts +42 -0
  259. package/dist/visual/provenance/page-metrics.d.ts.map +1 -0
  260. package/dist/visual/provenance/page-metrics.js +79 -0
  261. package/dist/visual/provenance/page-metrics.js.map +1 -0
  262. package/dist/visual/provenance/perceptual.d.ts +63 -0
  263. package/dist/visual/provenance/perceptual.d.ts.map +1 -0
  264. package/dist/visual/provenance/perceptual.js +115 -0
  265. package/dist/visual/provenance/perceptual.js.map +1 -0
  266. package/dist/visual/provenance/persona-rates.d.ts +84 -0
  267. package/dist/visual/provenance/persona-rates.d.ts.map +1 -0
  268. package/dist/visual/provenance/persona-rates.js +112 -0
  269. package/dist/visual/provenance/persona-rates.js.map +1 -0
  270. package/dist/visual/provenance/personas.d.ts +122 -0
  271. package/dist/visual/provenance/personas.d.ts.map +1 -0
  272. package/dist/visual/provenance/personas.js +298 -0
  273. package/dist/visual/provenance/personas.js.map +1 -0
  274. package/dist/visual/provenance/profiles.d.ts +39 -0
  275. package/dist/visual/provenance/profiles.d.ts.map +1 -0
  276. package/dist/visual/provenance/profiles.js +37 -0
  277. package/dist/visual/provenance/profiles.js.map +1 -0
  278. package/dist/visual/provenance/temporal.d.ts +21 -0
  279. package/dist/visual/provenance/temporal.d.ts.map +1 -0
  280. package/dist/visual/provenance/temporal.js +56 -0
  281. package/dist/visual/provenance/temporal.js.map +1 -0
  282. package/dist/visual/provenance/visual-distance.d.ts +22 -0
  283. package/dist/visual/provenance/visual-distance.d.ts.map +1 -0
  284. package/dist/visual/provenance/visual-distance.js +30 -0
  285. package/dist/visual/provenance/visual-distance.js.map +1 -0
  286. package/dist/visual/regression.d.ts.map +1 -1
  287. package/dist/visual/regression.js +14 -9
  288. package/dist/visual/regression.js.map +1 -1
  289. package/dist/visual/responsive.d.ts.map +1 -1
  290. package/dist/visual/responsive.js +4 -1
  291. package/dist/visual/responsive.js.map +1 -1
  292. package/dist/visual/scope-prose.js +2 -2
  293. package/dist/visual/scope-prose.js.map +1 -1
  294. package/dist/visual/seeded-random.d.ts +16 -0
  295. package/dist/visual/seeded-random.d.ts.map +1 -0
  296. package/dist/visual/seeded-random.js +25 -0
  297. package/dist/visual/seeded-random.js.map +1 -0
  298. package/dist/visual/stored-accessibility-traits.d.ts +27 -0
  299. package/dist/visual/stored-accessibility-traits.d.ts.map +1 -0
  300. package/dist/visual/stored-accessibility-traits.js +35 -0
  301. package/dist/visual/stored-accessibility-traits.js.map +1 -0
  302. package/package.json +1 -1
package/dist/personas.js CHANGED
@@ -17,10 +17,23 @@ import { AGENT_PERSONAS, isAgentPersona, getAgentPersona, listAgentPersonas, isA
17
17
  import { scopedDataDir, scopedAccountId } from "./persona-scope.js";
18
18
  import { currentRequestIdentity } from "./request-context.js";
19
19
  import { TRAIT_DEFINITIONS, canonicalizeTraits } from "./trait-reference.js";
20
+ import { customReadingRateId, customReadingRule, displayReadingWpm } from "./visual/provenance/persona-rates.js";
20
21
  // ============================================================================
21
22
  // Custom Personas Storage
22
23
  // ============================================================================
23
- const DATA_DIR = process.env.CBROWSER_DATA_DIR || join(homedir(), ".cbrowser");
24
+ /**
25
+ * The unscoped data dir, read per call like the scoped one below.
26
+ *
27
+ * It was a constant read once at import. A process that never changes
28
+ * CBROWSER_DATA_DIR (the CLI, a server) sees no difference, but one that
29
+ * does kept the first value: in a `bun test` run, which shares one module
30
+ * registry across files, whichever file imported this first fixed the
31
+ * directory, and later files' temp CBROWSER_DATA_DIR were ignored, so their
32
+ * personas landed in ~/.cbrowser/personas (tests/real-personas-dir.test.ts).
33
+ */
34
+ function dataDir() {
35
+ return process.env.CBROWSER_DATA_DIR || join(homedir(), ".cbrowser");
36
+ }
24
37
  /**
25
38
  * Resolved per call, not once at module load.
26
39
  *
@@ -35,7 +48,7 @@ const DATA_DIR = process.env.CBROWSER_DATA_DIR || join(homedir(), ".cbrowser");
35
48
  * is the shape this codebase already removed from the billing path. (2026-08-01)
36
49
  */
37
50
  function personasDirFor() {
38
- return join(scopedDataDir() ?? DATA_DIR, "personas");
51
+ return join(scopedDataDir() ?? dataDir(), "personas");
39
52
  }
40
53
  // ============================================================================
41
54
  // Runtime Persona Registry (for Enterprise extensions)
@@ -76,8 +89,9 @@ function scopedAccountPersonas() {
76
89
  return id === undefined ? {} : ACCOUNT_PERSONAS.get(id) ?? {};
77
90
  }
78
91
  function ensurePersonasDir() {
79
- if (!existsSync(DATA_DIR)) {
80
- mkdirSync(DATA_DIR, { recursive: true });
92
+ const base = dataDir();
93
+ if (!existsSync(base)) {
94
+ mkdirSync(base, { recursive: true });
81
95
  }
82
96
  if (!existsSync(personasDirFor())) {
83
97
  mkdirSync(personasDirFor(), { recursive: true });
@@ -372,7 +386,11 @@ export function generatePersonaFromDescription(name, description) {
372
386
  let reactionMin = 200, reactionMax = 500;
373
387
  let clickDelayMin = 100, clickDelayMax = 300;
374
388
  let typeSpeedMin = 50, typeSpeedMax = 120;
375
- let readingSpeed = 250;
389
+ // 238 wpm (Brysbaert 2019) x the custom-persona reading rule's share: the
390
+ // reference unless the description names dyslexia, low vision or old age
391
+ // (provenance/persona-rates.ts). Replaced keyword guesses of 400 / 250 / 150 /
392
+ // 100 wpm that no source gave.
393
+ const readingSpeed = displayReadingWpm(customReadingRateId(customReadingRule({ name, description, ageRange })));
376
394
  let scrollPauseMin = 200, scrollPauseMax = 500;
377
395
  if (techLevel === "expert" || isImpatient) {
378
396
  reactionMin = 100;
@@ -381,7 +399,6 @@ export function generatePersonaFromDescription(name, description) {
381
399
  clickDelayMax = 150;
382
400
  typeSpeedMin = 30;
383
401
  typeSpeedMax = 80;
384
- readingSpeed = 400;
385
402
  scrollPauseMin = 100;
386
403
  scrollPauseMax = 300;
387
404
  }
@@ -392,7 +409,6 @@ export function generatePersonaFromDescription(name, description) {
392
409
  clickDelayMax = 800;
393
410
  typeSpeedMin = 100;
394
411
  typeSpeedMax = 200;
395
- readingSpeed = 150;
396
412
  scrollPauseMin = 500;
397
413
  scrollPauseMax = 1500;
398
414
  }
@@ -403,7 +419,6 @@ export function generatePersonaFromDescription(name, description) {
403
419
  clickDelayMax = Math.max(clickDelayMax, 1200);
404
420
  typeSpeedMin = Math.max(typeSpeedMin, 150);
405
421
  typeSpeedMax = Math.max(typeSpeedMax, 300);
406
- readingSpeed = Math.min(readingSpeed, 100);
407
422
  }
408
423
  // Calculate error parameters
409
424
  let misClickRate = 0.05;
@@ -1159,7 +1174,7 @@ export const BUILTIN_PERSONAS = {
1159
1174
  reactionTime: { min: 100, max: 300 },
1160
1175
  clickDelay: { min: 50, max: 150 },
1161
1176
  typeSpeed: { min: 30, max: 80 },
1162
- readingSpeed: 400,
1177
+ readingSpeed: displayReadingWpm("personaRate.power-user.reading"),
1163
1178
  scrollPauseTime: { min: 100, max: 300 },
1164
1179
  },
1165
1180
  errors: {
@@ -1238,7 +1253,7 @@ export const BUILTIN_PERSONAS = {
1238
1253
  reactionTime: { min: 500, max: 1500 },
1239
1254
  clickDelay: { min: 300, max: 800 },
1240
1255
  typeSpeed: { min: 100, max: 200 },
1241
- readingSpeed: 150,
1256
+ readingSpeed: displayReadingWpm("personaRate.first-timer.reading"),
1242
1257
  scrollPauseTime: { min: 500, max: 1500 },
1243
1258
  },
1244
1259
  errors: {
@@ -1261,7 +1276,7 @@ export const BUILTIN_PERSONAS = {
1261
1276
  },
1262
1277
  },
1263
1278
  cognitiveTraits: {
1264
- patience: 0.7, // Medium - willing to learn
1279
+ patience: 0.7, // High - willing to invest time learning; expects some initial friction
1265
1280
  riskTolerance: 0.3, // Low - hesitates before clicking
1266
1281
  comprehension: 0.3, // Low - doesn't know conventions
1267
1282
  persistence: 0.5, // Medium - tries a few times
@@ -1311,7 +1326,7 @@ export const BUILTIN_PERSONAS = {
1311
1326
  reactionTime: { min: 200, max: 600 },
1312
1327
  clickDelay: { min: 150, max: 400 },
1313
1328
  typeSpeed: { min: 80, max: 150 },
1314
- readingSpeed: 200,
1329
+ readingSpeed: displayReadingWpm("personaRate.mobile-user.reading"),
1315
1330
  scrollPauseTime: { min: 200, max: 500 },
1316
1331
  },
1317
1332
  errors: {
@@ -1384,7 +1399,7 @@ export const BUILTIN_PERSONAS = {
1384
1399
  reactionTime: { min: 300, max: 800 },
1385
1400
  clickDelay: { min: 200, max: 500 },
1386
1401
  typeSpeed: { min: 50, max: 120 },
1387
- readingSpeed: 250,
1402
+ readingSpeed: displayReadingWpm("personaRate.screen-reader-user.reading"),
1388
1403
  scrollPauseTime: { min: 300, max: 700 },
1389
1404
  },
1390
1405
  errors: {
@@ -1417,14 +1432,14 @@ export const BUILTIN_PERSONAS = {
1417
1432
  // Sources: Information Wayfinding of Screen Reader Users, ASSETS 2024
1418
1433
  // (dl.acm.org/doi/fullHtml/10.1145/3663548.3688539); Context-Aware
1419
1434
  // Guidance for Screen Reader Users, CHI 2026 (10.1145/3772318.3790661).
1420
- riskTolerance: 0.2, // Medium - careful but experienced
1435
+ riskTolerance: 0.2, // Low - unexpected behaviour disorients without visual context
1421
1436
  comprehension: 0.8, // High - expert at a11y patterns
1422
1437
  persistence: 0.9, // High - determination required
1423
1438
  curiosity: 0.2, // Low - structured navigation
1424
1439
  workingMemory: 0.7, // High - mental model essential
1425
1440
  readingTendency: 0.9, // Full - ALL content is read aloud
1426
1441
  resilience: 0.8, // High - experienced with setbacks (CD-RISC)
1427
- selfEfficacy: 0.7, // Medium - high in accessible sites, low otherwise (Bandura)
1442
+ selfEfficacy: 0.7, // High - confident despite environmental barriers; lower on inaccessible sites (Bandura)
1428
1443
  satisficing: 0.6, // Medium - relies on structured review content (Simon)
1429
1444
  trustCalibration: 0.6, // Medium - cautious from past a11y failures (Fogg)
1430
1445
  interruptRecovery: 0.6, // High - strong mental model aids recovery (Mark)
@@ -1434,7 +1449,7 @@ export const BUILTIN_PERSONAS = {
1434
1449
  anchoringBias: 0.4, // Medium - sequential exposure to info
1435
1450
  timeHorizon: 0.3, // Long-term - patient, thorough
1436
1451
  attributionStyle: 0.4, // Medium - blames inaccessible design
1437
- metacognitivePlanning: 0.7, // Very high - plans navigation carefully
1452
+ metacognitivePlanning: 0.7, // High - plans navigation carefully
1438
1453
  proceduralFluency: 0.8, // High - follows heading structure
1439
1454
  transferLearning: 0.7, // High - knows a11y patterns across sites
1440
1455
  authoritySensitivity: 0.5, // Medium - verifies with screen reader
@@ -1466,7 +1481,7 @@ export const BUILTIN_PERSONAS = {
1466
1481
  reactionTime: { min: 800, max: 2000 },
1467
1482
  clickDelay: { min: 500, max: 1200 },
1468
1483
  typeSpeed: { min: 150, max: 300 },
1469
- readingSpeed: 100,
1484
+ readingSpeed: displayReadingWpm("personaRate.elderly-user.reading"),
1470
1485
  scrollPauseTime: { min: 800, max: 2000 },
1471
1486
  },
1472
1487
  errors: {
@@ -1493,7 +1508,7 @@ export const BUILTIN_PERSONAS = {
1493
1508
  riskTolerance: 0.2, // Very low - afraid of mistakes
1494
1509
  comprehension: 0.2, // Low - unfamiliar with modern UI
1495
1510
  persistence: 0.6, // High - determined but confused
1496
- curiosity: 0.4, // Very low - just wants to finish
1511
+ curiosity: 0.4, // Low-medium - goal-focused, prefers familiar patterns
1497
1512
  workingMemory: 0.4, // Low - may forget steps
1498
1513
  readingTendency: 0.8, // High - reads everything carefully
1499
1514
  resilience: 0.3, // Low - frustration lingers longer (BRS age-related)
@@ -1537,7 +1552,7 @@ export const BUILTIN_PERSONAS = {
1537
1552
  // procedural schema at all.
1538
1553
  proceduralFluency: 0.5,
1539
1554
  transferLearning: 0.2, // Low - each new site is confusing
1540
- authoritySensitivity: 0.7, // Very high - trusts official-looking things
1555
+ authoritySensitivity: 0.7, // High - trusts official-looking things
1541
1556
  emotionalContagion: 0.6, // Medium-high - affected by stern warnings
1542
1557
  fearOfMissingOut: 0.3, // Low - not driven by urgency, confused by it
1543
1558
  socialProofSensitivity: 0.7, // High - relies on grandchildren's recommendations
@@ -1572,7 +1587,7 @@ export const BUILTIN_PERSONAS = {
1572
1587
  reactionTime: { min: 100, max: 400 },
1573
1588
  clickDelay: { min: 80, max: 200 },
1574
1589
  typeSpeed: { min: 40, max: 100 },
1575
- readingSpeed: 350,
1590
+ readingSpeed: displayReadingWpm("personaRate.impatient-user.reading"),
1576
1591
  scrollPauseTime: { min: 100, max: 300 },
1577
1592
  },
1578
1593
  errors: {
@@ -1599,21 +1614,21 @@ export const BUILTIN_PERSONAS = {
1599
1614
  riskTolerance: 0.6, // High - clicks first thing
1600
1615
  comprehension: 0.6, // Medium
1601
1616
  persistence: 0.2, // Very low - one strike and out
1602
- curiosity: 0.3, // Very low - no time to explore
1617
+ curiosity: 0.3, // Low - no time to explore
1603
1618
  workingMemory: 0.6, // Medium
1604
1619
  readingTendency: 0.1, // Almost none - scanning only
1605
- resilience: 0.3, // Very low - no recovery, abandons (BRS)
1620
+ resilience: 0.3, // Low - frustration escalates quickly, abandons (BRS)
1606
1621
  selfEfficacy: 0.6, // Medium - impatient doesn't mean incapable (Bandura)
1607
1622
  satisficing: 0.9, // Very high - definition of satisficing (Simon)
1608
1623
  trustCalibration: 0.7, // High - clicks through without reading (Fogg)
1609
1624
  interruptRecovery: 0.2, // Very low - abandons rather than resumes (Mark)
1610
1625
  // New traits (v15.0.0)
1611
1626
  informationForaging: 0.9, // Very high - follows first scent, moves on
1612
- changeBlindness: 0.7, // Medium - focused on task
1627
+ changeBlindness: 0.7, // High - misses changes while hunting for the CTA
1613
1628
  anchoringBias: 0.6, // Medium-high - goes with first option
1614
1629
  timeHorizon: 0.95, // Maximum short-term - no time for later
1615
1630
  attributionStyle: 0.3, // Low - blames slow site
1616
- metacognitivePlanning: 0.3, // Very low - no planning, just clicking
1631
+ metacognitivePlanning: 0.3, // Low - minimal planning, just clicking
1617
1632
  proceduralFluency: 0.6, // Medium - can follow if fast
1618
1633
  transferLearning: 0.7, // High - recognizes patterns quickly
1619
1634
  authoritySensitivity: 0.4, // Medium - only if it speeds things up
@@ -1643,7 +1658,7 @@ export const BUILTIN_PERSONAS = {
1643
1658
  humanBehavior: {
1644
1659
  timing: {
1645
1660
  reactionTime: { min: 250, max: 1400 }, clickDelay: { min: 120, max: 500 },
1646
- typeSpeed: { min: 25, max: 70 }, readingSpeed: 200,
1661
+ typeSpeed: { min: 25, max: 70 }, readingSpeed: displayReadingWpm("personaRate.distracted-user.reading"),
1647
1662
  scrollPauseTime: { min: 200, max: 1500 },
1648
1663
  },
1649
1664
  errors: { misClickRate: 0.09, doubleClickAccidental: 0.04, typoRate: 0.08, backtrackRate: 0.35 },
@@ -1671,7 +1686,7 @@ export const BUILTIN_PERSONAS = {
1671
1686
  humanBehavior: {
1672
1687
  timing: {
1673
1688
  reactionTime: { min: 600, max: 2500 }, clickDelay: { min: 300, max: 900 },
1674
- typeSpeed: { min: 30, max: 80 }, readingSpeed: 130,
1689
+ typeSpeed: { min: 30, max: 80 }, readingSpeed: displayReadingWpm("personaRate.careful-reader.reading"),
1675
1690
  scrollPauseTime: { min: 800, max: 3000 },
1676
1691
  },
1677
1692
  errors: { misClickRate: 0.02, doubleClickAccidental: 0.01, typoRate: 0.02, backtrackRate: 0.08 },
@@ -1698,7 +1713,7 @@ export const BUILTIN_PERSONAS = {
1698
1713
  humanBehavior: {
1699
1714
  timing: {
1700
1715
  reactionTime: { min: 200, max: 900 }, clickDelay: { min: 100, max: 350 },
1701
- typeSpeed: { min: 45, max: 110 }, readingSpeed: 250,
1716
+ typeSpeed: { min: 45, max: 110 }, readingSpeed: displayReadingWpm("personaRate.explorer.reading"),
1702
1717
  scrollPauseTime: { min: 200, max: 1200 },
1703
1718
  },
1704
1719
  errors: { misClickRate: 0.05, doubleClickAccidental: 0.02, typoRate: 0.04, backtrackRate: 0.25 },
@@ -1725,7 +1740,7 @@ export const BUILTIN_PERSONAS = {
1725
1740
  humanBehavior: {
1726
1741
  timing: {
1727
1742
  reactionTime: { min: 200, max: 800 }, clickDelay: { min: 100, max: 300 },
1728
- typeSpeed: { min: 40, max: 100 }, readingSpeed: 260,
1743
+ typeSpeed: { min: 40, max: 100 }, readingSpeed: displayReadingWpm("personaRate.task-focused.reading"),
1729
1744
  scrollPauseTime: { min: 150, max: 600 },
1730
1745
  },
1731
1746
  errors: { misClickRate: 0.04, doubleClickAccidental: 0.02, typoRate: 0.04, backtrackRate: 0.12 },
@@ -1819,7 +1834,7 @@ export const ACCESSIBILITY_PERSONAS = {
1819
1834
  reactionTime: { min: 600, max: 1500 },
1820
1835
  clickDelay: { min: 400, max: 1000 },
1821
1836
  typeSpeed: { min: 150, max: 300 },
1822
- readingSpeed: 200,
1837
+ readingSpeed: displayReadingWpm("personaRate.motor-impairment-tremor.reading"),
1823
1838
  scrollPauseTime: { min: 500, max: 1200 },
1824
1839
  },
1825
1840
  errors: {
@@ -1865,7 +1880,10 @@ export const ACCESSIBILITY_PERSONAS = {
1865
1880
  // Research: Motor issues make resumption harder but adaptation helps (Mark)
1866
1881
  // Re-acquiring a small target after an interruption repeats the hardest
1867
1882
  // part of the interaction.
1868
- interruptRecovery: 0.6,
1883
+ // (21.0: restored to the 0.4 this citation was written beside. The doc
1884
+ // reconciliation of 2026-08-02 had set 0.6, above neutral, which
1885
+ // contradicts the direction cited here.)
1886
+ interruptRecovery: 0.4,
1869
1887
  // Every pointing action costs time and repeat attempts, so tolerance for
1870
1888
  // slow interaction is built in -- the persona's own research note records
1871
1889
  // 1-15Hz tremor and misclicks as the primary barrier.
@@ -1924,7 +1942,7 @@ export const ACCESSIBILITY_PERSONAS = {
1924
1942
  reactionTime: { min: 400, max: 1000 },
1925
1943
  clickDelay: { min: 300, max: 700 },
1926
1944
  typeSpeed: { min: 100, max: 180 },
1927
- readingSpeed: 100, // Slower due to magnification
1945
+ readingSpeed: displayReadingWpm("personaRate.low-vision-magnified.reading"),
1928
1946
  scrollPauseTime: { min: 600, max: 1500 },
1929
1947
  },
1930
1948
  errors: {
@@ -1970,10 +1988,16 @@ export const ACCESSIBILITY_PERSONAS = {
1970
1988
  cognitiveTraits: {
1971
1989
  // Research: Visual impairment + self-efficacy (Brody et al., 2002 - AMD and depression)
1972
1990
  // Reduced vision correlates with lower confidence in task completion
1973
- selfEfficacy: 0.6,
1991
+ // (21.0: restored to the 0.45 this citation was written beside. The doc
1992
+ // reconciliation of 2026-08-02 had set 0.6, above neutral, which
1993
+ // contradicts the direction cited here.)
1994
+ selfEfficacy: 0.45,
1974
1995
  // Research: Limited information access increases satisficing (Pachur & Hertwig, 2006)
1975
1996
  // Seeing only 1/9th of screen at a time → accept accessible options
1976
- satisficing: 0.4,
1997
+ // (21.0: restored to the 0.65 this citation was written beside. The doc
1998
+ // reconciliation of 2026-08-02 had set 0.4, the maximiser side, which
1999
+ // contradicts the direction cited here.)
2000
+ satisficing: 0.65,
1977
2001
  // Research: Vision impairment increases caution (Brody 2002)
1978
2002
  trustCalibration: 0.4,
1979
2003
  // Research: Limited visible area makes context recovery harder (Mark)
@@ -1993,7 +2017,7 @@ export const ACCESSIBILITY_PERSONAS = {
1993
2017
  timeHorizon: 0.4, // Patient, knows it takes time
1994
2018
  attributionStyle: 0.5, // Balanced - knows about limitations
1995
2019
  metacognitivePlanning: 0.7, // Plans navigation with zoom
1996
- proceduralFluency: 0.6, // Harder with limited view
2020
+ proceduralFluency: 0.6, // Medium-high - builds routines for familiar sites; new layouts are harder with a limited view
1997
2021
  transferLearning: 0.6, // Standard
1998
2022
  authoritySensitivity: 0.5,
1999
2023
  emotionalContagion: 0.4,
@@ -2004,7 +2028,8 @@ export const ACCESSIBILITY_PERSONAS = {
2004
2028
  },
2005
2029
  "cognitive-adhd": {
2006
2030
  name: "cognitive-adhd",
2007
- // Research: 75-81% of ADHD cases show central executive WM impairment (PMC7483636)
2031
+ // Research: 75-81% of ADHD cases show central executive WM impairment
2032
+ // (Kofler et al. 2020, PMC7483636)
2008
2033
  // Impulsivity affects persistence and patience significantly
2009
2034
  description: "User with ADHD affecting focus and working memory",
2010
2035
  disabilityType: "Cognitive (ADHD/Attention)",
@@ -2025,7 +2050,7 @@ export const ACCESSIBILITY_PERSONAS = {
2025
2050
  reactionTime: { min: 150, max: 600 }, // Can be fast when hyperfocused
2026
2051
  clickDelay: { min: 100, max: 400 },
2027
2052
  typeSpeed: { min: 50, max: 120 },
2028
- readingSpeed: 250,
2053
+ readingSpeed: displayReadingWpm("personaRate.cognitive-adhd.reading"),
2029
2054
  scrollPauseTime: { min: 100, max: 400 },
2030
2055
  },
2031
2056
  errors: {
@@ -2088,7 +2113,17 @@ export const ACCESSIBILITY_PERSONAS = {
2088
2113
  // and "may blame self" beside 0.3 on a scale whose 1.0 end is "Blames
2089
2114
  // self". The prose was right every time; the digit was inverted.
2090
2115
  cognitiveTraits: {
2091
- workingMemory: 0.3, // Research: large magnitude impairment (d=1.63-2.03)
2116
+ // Norm-anchored (paper section 3.1.1): the percentile of the adult
2117
+ // population's mean on a normed instrument. Adults with ADHD average
2118
+ // 95.2 on the WAIS-IV Working Memory Index, 95% CI 92.5-98.0, against
2119
+ // the norm of 100 (SD 15) (Wilson 2024, Arch Clin Neuropsychol
2120
+ // 39(4):498-515, Table 5). Phi((95.2 - 100) / 15) = 0.37, interval
2121
+ // 0.31-0.45. Was 0.3, cited to Kofler et al. 2020 (Neuropsychology
2122
+ // 34(6):686-698, PMC7483636; d = 1.63-2.03), whose sample is 172
2123
+ // children aged 8-13; that study now gives the direction only.
2124
+ // Still a hypothesis: that the WMI measures this trait is our mapping.
2125
+ // research/persona-norms/applied.md.
2126
+ workingMemory: 0.37,
2092
2127
  patience: 0.2, // Impulsivity: low tolerance for waiting
2093
2128
  persistence: 0.3, // Low for unengaging tasks; can hyperfocus on interesting ones
2094
2129
  curiosity: 0.9, // High novelty-seeking
@@ -2102,7 +2137,7 @@ export const ACCESSIBILITY_PERSONAS = {
2102
2137
  // claims at face value" -- which is what impulsive clicking without
2103
2138
  // reading looks like.
2104
2139
  trustCalibration: 0.65,
2105
- interruptRecovery: 0.3, // Very low - WM deficits make recovery difficult (Mark)
2140
+ interruptRecovery: 0.3, // Low - WM deficits make recovery difficult (Mark)
2106
2141
  // New traits (v15.0.0)
2107
2142
  comprehension: 0.6, // Capable when engaged; this is UI-convention grasp, not reading
2108
2143
  informationForaging: 0.4, // Distractible; goes down tangential paths (doc; code had 0.6)
@@ -2116,7 +2151,7 @@ export const ACCESSIBILITY_PERSONAS = {
2116
2151
  // KEPT over the doc's 0.3. 1.0 is "Blames self (internal attribution)",
2117
2152
  // and the doc's own rationale for 0.3 was "may blame self".
2118
2153
  attributionStyle: 0.6,
2119
- metacognitivePlanning: 0.3, // Very low - impulsive, no planning
2154
+ metacognitivePlanning: 0.3, // Low - impulsive, little planning
2120
2155
  proceduralFluency: 0.4, // Inconsistent; routines help but are hard to establish
2121
2156
  transferLearning: 0.5, // Variable; depends on engagement level
2122
2157
  authoritySensitivity: 0.4, // Low - impulsive, ignores authority
@@ -2132,7 +2167,9 @@ export const ACCESSIBILITY_PERSONAS = {
2132
2167
  },
2133
2168
  "dyslexic-user": {
2134
2169
  name: "dyslexic-user",
2135
- // Research: Dyslexic adults read ~178 WPM vs 248 WPM controls (Scientific Reports 2021)
2170
+ // Research: students with dyslexia read 184.63 vs 243.64 wpm silently (Callens, Tops & Brysbaert 2012,
2171
+ // the registered rate); adults with dyslexia 178.09 vs 248.18 wpm, medians (Franzen, Stark & Johnson 2021,
2172
+ // Scientific Reports 11:6449).
2136
2173
  // About 72% of typical speed, with more fixations and regressions
2137
2174
  description: "User with dyslexia affecting reading and text processing",
2138
2175
  disabilityType: "Cognitive (Dyslexia/Reading)",
@@ -2153,7 +2190,7 @@ export const ACCESSIBILITY_PERSONAS = {
2153
2190
  reactionTime: { min: 400, max: 1000 },
2154
2191
  clickDelay: { min: 200, max: 500 },
2155
2192
  typeSpeed: { min: 80, max: 160 },
2156
- readingSpeed: 120, // Research: ~70% of normal (178/248 WPM)
2193
+ readingSpeed: displayReadingWpm("personaRate.dyslexic-user.reading"),
2157
2194
  scrollPauseTime: { min: 800, max: 2000 },
2158
2195
  },
2159
2196
  errors: {
@@ -2214,7 +2251,10 @@ export const ACCESSIBILITY_PERSONAS = {
2214
2251
  // Pulled down from 0.6 for documented secondary anxiety (Kapur & Agrawal
2215
2252
  // 2026), but not lower: the compensation literature describes adults
2216
2253
  // achieving academic success, so learned helplessness would overstate it.
2217
- resilience: 0.6,
2254
+ // (21.0: restored to the 0.5 this comment was written for. The doc
2255
+ // reconciliation of 2026-08-02 had moved it back to 0.6 by treating 0.5
2256
+ // as an unclaimed neutral, against this citation's direction.)
2257
+ resilience: 0.5,
2218
2258
  // Dyslexia is a strong predictor of lower academic self-efficacy in higher
2219
2259
  // education (PMC11488781; Nigerian undergraduate cohort).
2220
2260
  selfEfficacy: 0.3,
@@ -2277,7 +2317,7 @@ export const ACCESSIBILITY_PERSONAS = {
2277
2317
  reactionTime: { min: 200, max: 500 },
2278
2318
  clickDelay: { min: 100, max: 300 },
2279
2319
  typeSpeed: { min: 50, max: 100 },
2280
- readingSpeed: 250,
2320
+ readingSpeed: displayReadingWpm("personaRate.deaf-user.reading"),
2281
2321
  scrollPauseTime: { min: 300, max: 800 },
2282
2322
  },
2283
2323
  errors: {
@@ -2322,7 +2362,7 @@ export const ACCESSIBILITY_PERSONAS = {
2322
2362
  curiosity: 0.6,
2323
2363
  workingMemory: 0.6,
2324
2364
  informationForaging: 0.6, // Good visual navigation
2325
- changeBlindness: 0.3, // Very low - visually attentive
2365
+ changeBlindness: 0.3, // Low - visually attentive
2326
2366
  anchoringBias: 0.5,
2327
2367
  timeHorizon: 0.5,
2328
2368
  attributionStyle: 0.4, // Blames lack of captions
@@ -2330,7 +2370,7 @@ export const ACCESSIBILITY_PERSONAS = {
2330
2370
  proceduralFluency: 0.7, // Good with visual instructions
2331
2371
  transferLearning: 0.7, // Recognizes visual patterns
2332
2372
  authoritySensitivity: 0.5,
2333
- emotionalContagion: 0.6, // Less affected by audio tone
2373
+ emotionalContagion: 0.6, // Medium-high - reads visual emotional cues closely (facial expression)
2334
2374
  fearOfMissingOut: 0.4,
2335
2375
  socialProofSensitivity: 0.6, // Visual reviews/ratings
2336
2376
  mentalModelFlexibility: 0.65, // Good visual adaptation
@@ -2360,7 +2400,7 @@ export const ACCESSIBILITY_PERSONAS = {
2360
2400
  reactionTime: { min: 1000, max: 2500 },
2361
2401
  clickDelay: { min: 600, max: 1500 },
2362
2402
  typeSpeed: { min: 200, max: 400 },
2363
- readingSpeed: 80,
2403
+ readingSpeed: displayReadingWpm("personaRate.elderly-low-vision.reading"),
2364
2404
  scrollPauseTime: { min: 1000, max: 2500 },
2365
2405
  },
2366
2406
  errors: {
@@ -2417,22 +2457,22 @@ export const ACCESSIBILITY_PERSONAS = {
2417
2457
  curiosity: 0.3, // Low: prefers familiar patterns
2418
2458
  riskTolerance: 0.1, // Very cautious with unfamiliar interfaces
2419
2459
  comprehension: 0.3, // Unfamiliar with modern UI conventions
2420
- resilience: 0.6, // Low - frustration compounds with physical challenges (BRS)
2421
- selfEfficacy: 0.3, // Very low - often blame selves for tech issues (Bandura)
2460
+ resilience: 0.6, // Medium-high - adapted over time; repeated barriers still discourage (BRS)
2461
+ selfEfficacy: 0.3, // Low - often blame selves for tech issues (Bandura)
2422
2462
  satisficing: 0.7, // High - avoids complex decision trees (Simon)
2423
- trustCalibration: 0.4, // Very low - very skeptical of online requests (Fogg)
2424
- interruptRecovery: 0.3, // Very low - WM + vision decline makes recovery hard (Mark)
2463
+ trustCalibration: 0.4, // Low-medium - wary of online requests, though official-looking content can win trust (Fogg)
2464
+ interruptRecovery: 0.3, // Low - WM + vision decline makes recovery hard (Mark)
2425
2465
  // New traits (v15.0.0)
2426
2466
  readingTendency: 0.9,
2427
- informationForaging: 0.4, // Very low - exhaustive, uncertain
2467
+ informationForaging: 0.4, // Low-medium - systematic, exhaustive search
2428
2468
  changeBlindness: 0.7, // High - vision issues
2429
2469
  anchoringBias: 0.8, // High - sticks to first info
2430
2470
  timeHorizon: 0.4, // Medium - patient but unsure
2431
2471
  attributionStyle: 0.9, // Very high - blames self
2432
2472
  metacognitivePlanning: 0.2, // Low - doesn't know what to plan
2433
2473
  proceduralFluency: 0.4, // Low - struggles with sequences
2434
- transferLearning: 0.4, // Very low - each UI is confusing
2435
- authoritySensitivity: 0.7, // Very high - trusts official things
2474
+ transferLearning: 0.4, // Low-medium - each site needs new spatial and procedural learning
2475
+ authoritySensitivity: 0.7, // High - trusts official things
2436
2476
  emotionalContagion: 0.6, // Medium-high
2437
2477
  fearOfMissingOut: 0.2, // Low - not driven by urgency
2438
2478
  socialProofSensitivity: 0.7, // High - relies on family advice
@@ -2462,7 +2502,7 @@ export const ACCESSIBILITY_PERSONAS = {
2462
2502
  reactionTime: { min: 200, max: 600 }, // Slight delay on color-coded UI
2463
2503
  clickDelay: { min: 100, max: 400 },
2464
2504
  typeSpeed: { min: 50, max: 100 },
2465
- readingSpeed: 250,
2505
+ readingSpeed: displayReadingWpm("personaRate.color-blind-deuteranopia.reading"),
2466
2506
  scrollPauseTime: { min: 200, max: 500 },
2467
2507
  },
2468
2508
  errors: {
@@ -2571,7 +2611,7 @@ export const ACCESSIBILITY_PERSONAS = {
2571
2611
  reactionTime: { min: 400, max: 1200 },
2572
2612
  clickDelay: { min: 300, max: 900 },
2573
2613
  typeSpeed: { min: 80, max: 180 },
2574
- readingSpeed: 180,
2614
+ readingSpeed: displayReadingWpm("personaRate.autism-spectrum.reading"),
2575
2615
  scrollPauseTime: { min: 400, max: 1200 },
2576
2616
  },
2577
2617
  errors: {
@@ -2602,7 +2642,18 @@ export const ACCESSIBILITY_PERSONAS = {
2602
2642
  fatigueSusceptibility: 0.5, // Moderate - sensory overload increases fatigue
2603
2643
  },
2604
2644
  cognitiveTraits: {
2605
- workingMemory: 0.6, // Often good - detail-oriented (Happé & Frith 2006)
2645
+ // Norm-anchored (paper section 3.1.1): autistic adults without
2646
+ // intellectual disability score below typical controls on working
2647
+ // memory. Visuospatial WM accuracy, adult subgroup, d = -0.47, 95% CI
2648
+ // -0.91 to -0.03, 4 studies, controls matched on age and IQ, every
2649
+ // participant at IQ 70 or above (Habib et al. 2019, PLoS One
2650
+ // 14(4):e0216198, Table 6). Phi(-0.47) = 0.32, interval
2651
+ // 0.18-0.49. The adult phonological estimate is lower (d = -0.79,
2652
+ // Phi = 0.21); the smaller deficit is used. Was 0.6, "often good -
2653
+ // detail-oriented (Happe & Frith 2006)", which both adult estimates
2654
+ // exclude. Still a hypothesis: that these tasks measure this trait is
2655
+ // our mapping. research/persona-norms/applied.md.
2656
+ workingMemory: 0.32,
2606
2657
  patience: 0.65, // Moderate-high - persistent on structured tasks
2607
2658
  persistence: 0.7, // High on predictable tasks, drops on chaotic ones
2608
2659
  curiosity: 0.4, // Lower - prefers known patterns over exploration
@@ -2659,7 +2710,7 @@ export const ACCESSIBILITY_PERSONAS = {
2659
2710
  reactionTime: { min: 800, max: 2500 },
2660
2711
  clickDelay: { min: 500, max: 1500 },
2661
2712
  typeSpeed: { min: 200, max: 500 },
2662
- readingSpeed: 80, // Significantly slower
2713
+ readingSpeed: displayReadingWpm("personaRate.intellectual-disability.reading"),
2663
2714
  scrollPauseTime: { min: 800, max: 2000 },
2664
2715
  },
2665
2716
  errors: {
@@ -2696,7 +2747,7 @@ export const ACCESSIBILITY_PERSONAS = {
2696
2747
  curiosity: 0.3, // Low - prefers familiar paths
2697
2748
  riskTolerance: 0.2, // Very low - sticks to obvious elements
2698
2749
  readingTendency: 0.3, // Low - relies on images and icons
2699
- comprehension: 0.2, // Low - needs plain language
2750
+ comprehension: 0.2, // Low - needs explicit labels (UI conventions, not reading)
2700
2751
  resilience: 0.35, // Low - errors are discouraging (BRS)
2701
2752
  selfEfficacy: 0.3, // Low - often blames self for failures
2702
2753
  satisficing: 0.8, // High - takes first option that seems right
@@ -2746,7 +2797,7 @@ export const ACCESSIBILITY_PERSONAS = {
2746
2797
  reactionTime: { min: 600, max: 2000 },
2747
2798
  clickDelay: { min: 400, max: 1200 },
2748
2799
  typeSpeed: { min: 300, max: 800 }, // Text input very difficult
2749
- readingSpeed: 60, // Severely impaired language processing
2800
+ readingSpeed: displayReadingWpm("personaRate.aphasia-receptive.reading"),
2750
2801
  scrollPauseTime: { min: 600, max: 1500 },
2751
2802
  },
2752
2803
  errors: {
@@ -2783,7 +2834,7 @@ export const ACCESSIBILITY_PERSONAS = {
2783
2834
  curiosity: 0.3, // Low - new text-heavy pages are daunting
2784
2835
  riskTolerance: 0.25, // Low - unsure what labels mean
2785
2836
  readingTendency: 0.15, // Very low - avoids reading, seeks visual cues
2786
- comprehension: 0.25, // Low for text, normal for visual/spatial layouts
2837
+ comprehension: 0.25, // Low - UI conventions, not reading; the language deficit is in the reading rate
2787
2838
  resilience: 0.45, // Medium - accustomed to communication barriers
2788
2839
  selfEfficacy: 0.4, // Low-medium - knows they can think, frustrated by language
2789
2840
  satisficing: 0.7, // High - takes first visual match
@@ -2834,7 +2885,7 @@ export const ACCESSIBILITY_PERSONAS = {
2834
2885
  reactionTime: { min: 350, max: 900 },
2835
2886
  clickDelay: { min: 200, max: 500 },
2836
2887
  typeSpeed: { min: 80, max: 160 },
2837
- readingSpeed: 220, // Normal text reading speed
2888
+ readingSpeed: displayReadingWpm("personaRate.dyscalculia.reading"),
2838
2889
  scrollPauseTime: { min: 300, max: 800 },
2839
2890
  },
2840
2891
  errors: {
@@ -2874,7 +2925,7 @@ export const ACCESSIBILITY_PERSONAS = {
2874
2925
  curiosity: 0.6, // Normal - explores freely until numbers appear
2875
2926
  riskTolerance: 0.4, // Low-medium - cautious with purchases/quantities
2876
2927
  readingTendency: 0.65, // Medium-high - reads text normally, skips number-heavy sections
2877
- comprehension: 0.65, // Normal for text, low for numerical content
2928
+ comprehension: 0.65, // Medium-high - UI conventions (not reading, not numeracy)
2878
2929
  // Math anxiety is documented as intense and self-reinforcing: errors raise
2879
2930
  // anxiety, which lowers WM, which produces more errors.
2880
2931
  resilience: 0.35,
@@ -3018,7 +3069,7 @@ export const EMOTIONAL_PERSONAS = {
3018
3069
  reactionTime: { min: 400, max: 1200 }, // Slower due to deliberation
3019
3070
  clickDelay: { min: 300, max: 800 }, // Hesitates before clicking
3020
3071
  typeSpeed: { min: 80, max: 150 },
3021
- readingSpeed: 150, // Reads carefully
3072
+ readingSpeed: displayReadingWpm("personaRate.anxious-user.reading"),
3022
3073
  scrollPauseTime: { min: 400, max: 1000 },
3023
3074
  },
3024
3075
  errors: {
@@ -3041,15 +3092,15 @@ export const EMOTIONAL_PERSONAS = {
3041
3092
  },
3042
3093
  },
3043
3094
  cognitiveTraits: {
3044
- patience: 0.8, // Low - anxiety makes waiting feel worse
3095
+ patience: 0.8, // High - spends time making sure it is safe; thoroughness over speed
3045
3096
  riskTolerance: 0.2, // Very low - avoids uncertain outcomes
3046
3097
  comprehension: 0.6, // Medium - understands but worries
3047
- persistence: 0.6, // Low-medium - gives up when anxious
3098
+ persistence: 0.6, // Medium-high - persists while feeling safe; abandons when anxiety escalates
3048
3099
  curiosity: 0.3, // Low - prefers safe known paths
3049
3100
  workingMemory: 0.5, // Medium - anxiety can impair WM
3050
3101
  readingTendency: 0.9, // High - reads everything for reassurance
3051
- resilience: 0.3, // Very low - slow emotional recovery
3052
- selfEfficacy: 0.3, // Very low - doubts own abilities
3102
+ resilience: 0.3, // Low - slow emotional recovery
3103
+ selfEfficacy: 0.3, // Low - doubts own abilities
3053
3104
  satisficing: 0.3, // Low-medium - wants certainty
3054
3105
  trustCalibration: 0.2, // Low - skeptical and worried
3055
3106
  interruptRecovery: 0.4, // Low - anxiety compounds on interruption
@@ -3058,12 +3109,12 @@ export const EMOTIONAL_PERSONAS = {
3058
3109
  changeBlindness: 0.3, // Low - hypervigilant, notices changes
3059
3110
  anchoringBias: 0.7, // High - sticks to first safe option
3060
3111
  timeHorizon: 0.3, // Long-term - worries about consequences
3061
- attributionStyle: 0.7, // Very high - blames self for everything
3112
+ attributionStyle: 0.7, // High - blames self, fears being at fault
3062
3113
  metacognitivePlanning: 0.6, // Medium-high - plans to avoid anxiety
3063
3114
  proceduralFluency: 0.5, // Medium - follows carefully
3064
3115
  transferLearning: 0.4, // Medium
3065
3116
  authoritySensitivity: 0.7, // High - seeks reassurance from authority
3066
- emotionalContagion: 0.7, // Very high - absorbs UI emotional tone
3117
+ emotionalContagion: 0.7, // High - absorbs UI emotional tone
3067
3118
  fearOfMissingOut: 0.6, // Medium-high - anxiety about missing out
3068
3119
  socialProofSensitivity: 0.8, // High - seeks validation from others
3069
3120
  mentalModelFlexibility: 0.4, // Low-medium - struggles with unexpected
@@ -3095,7 +3146,7 @@ export const EMOTIONAL_PERSONAS = {
3095
3146
  reactionTime: { min: 150, max: 400 },
3096
3147
  clickDelay: { min: 80, max: 200 },
3097
3148
  typeSpeed: { min: 40, max: 100 },
3098
- readingSpeed: 300,
3149
+ readingSpeed: displayReadingWpm("personaRate.confident-user.reading"),
3099
3150
  scrollPauseTime: { min: 150, max: 400 },
3100
3151
  },
3101
3152
  errors: {
@@ -3118,7 +3169,7 @@ export const EMOTIONAL_PERSONAS = {
3118
3169
  },
3119
3170
  },
3120
3171
  cognitiveTraits: {
3121
- patience: 0.3, // Medium - not impatient but efficient
3172
+ patience: 0.3, // Low - expects quick outcomes; little tolerance for delays
3122
3173
  riskTolerance: 0.8, // High - willing to try things
3123
3174
  comprehension: 0.7, // High - understands quickly
3124
3175
  persistence: 0.7, // High - doesn't give up easily
@@ -3127,16 +3178,16 @@ export const EMOTIONAL_PERSONAS = {
3127
3178
  readingTendency: 0.2, // Low - scans efficiently
3128
3179
  resilience: 0.8, // Very high - bounces back immediately
3129
3180
  selfEfficacy: 0.9, // Very high - trusts own abilities
3130
- satisficing: 0.7, // Medium - balances speed and quality
3181
+ satisficing: 0.7, // High - accepts good-enough quickly, trusts first judgment
3131
3182
  trustCalibration: 0.7, // High - appropriate trust
3132
3183
  interruptRecovery: 0.7, // High - resumes easily
3133
3184
  // New traits (v15.0.0)
3134
3185
  informationForaging: 0.8, // High - efficient scent-following
3135
- changeBlindness: 0.6, // Low - notices changes
3186
+ changeBlindness: 0.6, // Medium-high - may miss changes while moving quickly
3136
3187
  anchoringBias: 0.3, // Low - evaluates options freely
3137
3188
  timeHorizon: 0.4, // Medium-long - thinks ahead
3138
3189
  attributionStyle: 0.2, // Low - blames system issues
3139
- metacognitivePlanning: 0.4, // High - plans efficiently
3190
+ metacognitivePlanning: 0.4, // Low-medium - minimal planning; trusts ability to adapt
3140
3191
  proceduralFluency: 0.7, // High - follows procedures well
3141
3192
  transferLearning: 0.8, // High - applies knowledge
3142
3193
  authoritySensitivity: 0.3, // Low-medium - independent judgment
@@ -3172,7 +3223,7 @@ export const EMOTIONAL_PERSONAS = {
3172
3223
  reactionTime: { min: 150, max: 600 }, // Variable based on mood
3173
3224
  clickDelay: { min: 100, max: 400 },
3174
3225
  typeSpeed: { min: 50, max: 130 },
3175
- readingSpeed: 220,
3226
+ readingSpeed: displayReadingWpm("personaRate.emotional-user.reading"),
3176
3227
  scrollPauseTime: { min: 200, max: 600 },
3177
3228
  },
3178
3229
  errors: {
@@ -3202,7 +3253,7 @@ export const EMOTIONAL_PERSONAS = {
3202
3253
  curiosity: 0.6, // Medium-high - excitement drives exploration
3203
3254
  workingMemory: 0.5, // Medium - emotions can interfere
3204
3255
  readingTendency: 0.6, // Medium
3205
- resilience: 0.4, // Very low - emotions linger long
3256
+ resilience: 0.4, // Low-medium - negative experiences linger
3206
3257
  selfEfficacy: 0.5, // Medium - mood dependent
3207
3258
  satisficing: 0.6, // Medium-high - wants quick resolution
3208
3259
  trustCalibration: 0.5, // Medium - emotional judgment
@@ -3249,7 +3300,7 @@ export const EMOTIONAL_PERSONAS = {
3249
3300
  reactionTime: { min: 250, max: 600 },
3250
3301
  clickDelay: { min: 150, max: 350 },
3251
3302
  typeSpeed: { min: 60, max: 120 },
3252
- readingSpeed: 220,
3303
+ readingSpeed: displayReadingWpm("personaRate.stoic-user.reading"),
3253
3304
  scrollPauseTime: { min: 250, max: 600 },
3254
3305
  },
3255
3306
  errors: {
@@ -3272,14 +3323,14 @@ export const EMOTIONAL_PERSONAS = {
3272
3323
  },
3273
3324
  },
3274
3325
  cognitiveTraits: {
3275
- patience: 0.7, // Very high - doesn't rush
3326
+ patience: 0.7, // High - doesn't rush
3276
3327
  riskTolerance: 0.5, // Medium - balanced judgment
3277
3328
  comprehension: 0.7, // High - clear thinking
3278
- persistence: 0.7, // Very high - never gives up
3329
+ persistence: 0.7, // High - persistent, not emotionally deterred
3279
3330
  curiosity: 0.4, // Medium - methodical exploration
3280
3331
  workingMemory: 0.7, // High - unaffected by emotion
3281
3332
  readingTendency: 0.7, // Medium-high - thorough
3282
- resilience: 0.8, // Maximum - emotions barely register
3333
+ resilience: 0.8, // Very high - errors are data points, not emotional events
3283
3334
  selfEfficacy: 0.6, // High - quiet confidence
3284
3335
  satisficing: 0.4, // Low - willing to be thorough
3285
3336
  trustCalibration: 0.7, // Medium-high - rational evaluation
@@ -3294,8 +3345,8 @@ export const EMOTIONAL_PERSONAS = {
3294
3345
  proceduralFluency: 0.6, // High - follows procedures precisely
3295
3346
  transferLearning: 0.7, // High - applies experience
3296
3347
  authoritySensitivity: 0.4, // Low-medium - independent judgment
3297
- emotionalContagion: 0.2, // Minimum - emotionally unaffected
3298
- fearOfMissingOut: 0.2, // Minimum - not driven by urgency
3348
+ emotionalContagion: 0.2, // Very low - emotionally unaffected
3349
+ fearOfMissingOut: 0.2, // Very low - not driven by urgency
3299
3350
  socialProofSensitivity: 0.4, // Low - evaluates independently
3300
3351
  mentalModelFlexibility: 0.7, // High - adapts methodically
3301
3352
  },