Six audit passes over everything shipped since v3.4.8 — React and Vue, components, blocks, templates and the npm packages. 30+ bugs fixed and two regression guards added, so the ones that kept coming back can't come back again.
♿ The accessibility sweep
20 icon-only controls had no accessible name. lucide marks its icons aria-hidden, so a button containing only an icon announces as a bare "button". The blog pagination pair was the worst of it — previous and next were indistinguishable to a screen reader. Fixed across templates, blocks and UI, and now enforced by npm run audit:icon-labels in CI.
Data conveyed only by icons now has text. ComparisonTable and PricingTemplate rendered ✓/✗ cells that read as empty — the entire payload of a comparison table, invisible. Added sr-only equivalents plus scope="col"/scope="row" so cells are announced with their feature and column.
Selection state is exposed, not just styled. aria-pressed on accent swatches and theme buttons, aria-current on dashboard nav. ProductTemplate's colour radios had no name at all.
Rating could drop out of the tab order entirely when given an out-of-range value. Now clamped.
🐛 Fixes
Progress ignored max. max={200} value={150} drew a full bar while telling assistive tech "50%". Both frameworks; Vue was a v3.5.0 regression that also dropped getValueText.
The Vue registry shipped a broken stylesheet. styles.json carried @import './motion.css' without shipping that file — shadcn-vue add failed on a clean project. The rules were already inlined, so the import was pure breakage. The build now strips it and refuses to ship any relative import without its sibling.
Vue's docs template called navigator.clipboard unguarded — unhandled rejection on http://, and the button claimed "COPIED" anyway.
The MCP server described a catalog it doesn't have — it advertised blocks and templates, so an agent would search, find nothing, and confidently tell you they don't exist.
Plus: ChartLoading missing from the Vue barrel, page transitions bleeding into the theme toggle, a countdown that ticked forever after expiry.
⚠️ Behaviour changes
LogoCloudWithStats no longer truncates. It silently capped at 9 logos with a console.warn that fired in production on every render. Pass maxLogos if you want a cap back.
Pricing CTAs actually do something. PricingTier gains ctaHref / onCtaClick (React) and a ctaClick emit (Vue); CheckoutSummary gains onCheckout. These buttons were previously inert.
Settings appearance persists to localStorage — SettingsPage rendered the appearance panel with no props, so the theme buttons were dead and nothing survived a reload.
📖 Blocks and templates are copy-paste only
They are not registry items in either framework — shadcn add cannot install one, and the MCP catalog cannot surface one. The docs previously implied otherwise. Making them installable is open feature work.
📦 Setup
No migration needed. Every fix is non-breaking except the three behaviour changes above.
npx shadcn@latest add "https://boldkit.dev/r/{component}.json" # React
npx shadcn-vue@latest add "https://boldkit.dev/r/vue/{component}.json" # VueInternals
React tests 590 → 610, Vue 59 → 66, MCP 12 → 14. src/lib/motion-core.ts was never in the sync script's file list, so its registry mirror could drift silently — added.
Bumps: React 3.5.0 → 3.5.1 · Vue 3.3.0 → 3.3.1 · @boldkit/mcp 0.1.0 → 0.2.0 · boldkit CLI 0.1.4 → 0.1.5
Full diff: v3.5.0...v3.5.1