Lossless Changelog
product

Mermaid charts through LFM — CDN runtime, theme parity, expand-to-modal UX

Fenced mermaid blocks now render as live diagrams in any document that goes through our markdown pipeline — themed to match the page, with a quiet expand affordance and a fullscreen modal for when a diagram outgrows the column.

Michael StatonMusic Editoraugmented with Claude Code on Claude Opus 4.7

What's new

Mermaid diagrams now render natively in any markdown rendered through @lossless-group/lfm. Authors write a fenced ```mermaid block in any memo, essay, or context-v document and the chart renders inline with full theme parity, an unobtrusive expand affordance, and a fullscreen modal for complex diagrams.

How it works

MERMAID
flowchart LR
  A[Markdown<br/>fenced ```mermaid] --> B[parseMarkdown<br/>@lossless-group/lfm]
  B --> C[MDAST code node<br/>lang: mermaid]
  C --> D{AstroMarkdown<br/>type === 'code'}
  D -- lang === mermaid --> E[MermaidChartDisplay]
  D -- other lang --> F[CodeBlock]
  E --> G[CDN: mermaid@10<br/>jsdelivr ESM]
  G --> H[Themed SVG<br/>+ expand modal]

LFM (the package) doesn't need to know about Mermaid — fenced code blocks come through as standard MDAST code nodes with lang: mermaid. The dispatch happens in the renderer: AstroMarkdown.astro's type === "code" branch checks lang === "mermaid" and hands off to MermaidChartDisplay. Everything else continues to flow through CodeBlock.

New components

  • src/components/markdown/MermaidChartDisplay.astro — the inline chart that renders inside the article body. Self-contained: inlines sanitizeMermaidCode (handles Obsidian wikilink and slash-path edge cases), inlines its expand/collapse SVG icons, themed via mpstaton-site's semantic tokens (--card, --brand-aqua, --brand-purple, --foreground) with hex fallbacks. CDN-loads mermaid@10 ESM from jsdelivr at runtime — zero build-time dependency on Mermaid.

  • src/components/markdown/MermaidChartInline.astro — minimal breakout variant for callers that want their own modal/expand integration. Same theming, optional ExpandIcon prop with a sensible inline-SVG default.

Renderer dispatch

  • src/components/markdown/AstroMarkdown.astro — added a single if (lang === "mermaid") branch inside the existing type === "code" handler. Non-mermaid code still routes to CodeBlock unchanged.

UX details

  • Subtle expand button. Default opacity 0.35, persistent thin aqua border, jumps to 0.85 when the chart shell is hovered/focused, full opacity + outline-offset glow when the button itself is the target. Designed to stay out of the reader's way.

  • Fullscreen modal. Click expand → mermaid re-renders into a 90vw × 90vh modal with focus trapping, Escape-to-close, ResizeObserver-driven SVG centering, and previous-element focus restoration on close. Close button mirrors the expand button's aqua-bordered hover treatment.

  • No flash on hot reload. A single global __MERMAID_LOADED__ guard prevents re-importing the CDN module across charts on the same page.

Theme parity

CSS custom properties are read at runtime via getComputedStyle(document.documentElement). The Mermaid themeVariables config maps to mpstaton tokens:

Mermaid conceptmpstaton token
primaryColor (node fill)--card
primaryTextColor--foreground
secondaryColor (decision/role)--brand-purple
lineColor / borders--brand-aqua
clusterBkg--muted
fontFamilyInter, system-ui

Switching [data-theme] on :root re-themes the diagrams on next render — the same way text and surface tokens already adapt.

Test content

  • src/content/promote/_demo/memo/v1.md — added a Deal-flow flowchart LR to the demo memo, reachable at /promote/_demo/memo/version-1. Exercises the LFM pipeline + the new dispatch + the expand modal end-to-end.

Provenance / next steps

  • Component approach ported from lossless-monorepo/site/src/components/codeblocks/MermaidChart.astro. Notable departures: theme-token-neutral (no --bastille/--lossless-accent--brightest bake-ins), no @assets/Icons dependency, debug console.log calls stripped, focus selectors hardened (:focus-visible).

  • Once the design is stable on this site, copy both components into packages/lfm-astro/components/ as the canonical source for sibling sites, and add the same lang === "mermaid" branch to that folder's AstroMarkdown.astro.

  • Spec: context-v/specs/Codifying-a-Comprehensive-Extended-Markdown-Flavor-and-Shared-Package.md — "Support Mermaid through CDN" is the first item under #### Next in the workflow status.