Interim fix for the free-text title-match footguns (issue #4); durable ULID
reference + seed migration tracked separately.
- New lib/cms.ts: single normCms() match key + cmsSlugByTitle / resolveCmsSlug,
used by all three join sites so a plugin can no longer link from its own page
yet vanish from a CMS list over case/whitespace drift.
- cms/index.astro + cms/[slug].astro: counts and "plugins from / targeting"
lists now use the normalized key (were exact-match).
- plugins/[slug].astro: drop the local normalize copy; link target_cms too
(was source-only) for parity.
- warnOrphanCmsRefs(): logs any source_cms/target_cms that resolves to no CMS,
so silent orphans surface in the server log.