Lossless Changelog
product

Support new LFM callout features in mpstaton-site

The site now speaks the full LFM callout vocabulary — ten canonical types over the brand palette, AI-source badges on model-generated blocks, and directive syntax that lets a callout break out into the margin like a print sidebar.

Michael StatonMusic Editoraugmented with Claude Code on Claude Opus 4.7

The site now consumes the full LFM Callout system — ten canonical types plus aliases, two-tier semantic tokens over the brand palette, AI-source brand badges on [!llm-response] callouts, smaller-body styling for long [!excerpt] copypasta, and directive-form positioning that lets a callout escape into the right or left margin like a print-magazine sidebar.

Why Care?

A callout is one of those primitives where the difference between "supported" and "supported well" is large. If callouts only get one accent color and one icon, they read as a single textbox style with rotating labels. If callouts have their own tokens, mode-aware accents, optional brand badges, smaller-body variants for long quotes, and the ability to escape the column for a sidebar effect, they become a real authoring vocabulary — the kind of thing where the page rhythm depends on which one you reach for.

The published @lossless-group/lfm had two bugs that were silently downgrading half of the existing essay drafts to plain blockquotes (multi-line first paragraphs and hyphenated type names like [!llm-response] both failed to parse). Both got fixed upstream this round. With the regex bugs out of the way, this site picks up the canonical Callout pattern from packages/lfm-astro/components/ and adapts it to the existing --brand-* palette via a clean two-tier token wiring.

What's New?

  • Ten canonical callout types — note, info, tip, success, warning, danger, quote, example, question, important — plus 19 aliases that route to canonicals (warn/caution/attention → warning; tldr/summary/abstract → info; alert → warning; idea → tip, etc.). Casing is irrelevant: [!INFO], [!Info], [!info] all resolve identically.

  • Two new canonical types specific to mpstaton-site authoring:

    • llm-response — sparkles icon, brand-purple accent. For verbatim AI/LLM output. The component scans the callout body for case-insensitive mentions of "Perplexity", "Claude", or "GPT" (also "ChatGPT", "OpenAI") and renders matching brand favicons stacked in the top-right. Perplexity is the default when no brand is mentioned, since it's the most common authoring source here. Multiple brands stack.

    • excerpt — file-text icon, muted graphite, smaller body font (0.85rem), italic, slight opacity dampening. Designed so multi-paragraph copypasta from another source recedes visually and the surrounding author voice stays foreground.

  • Two-tier semantic-token wiring in tokens.css. Each callout type gets a --callout-{type} semantic token defined under :root (light) and [data-theme='dark']. Components reference only semantic tokens — never --brand-* directly. Mode behavior lives in tokens.css where the semantic layer is remapped, not in the component CSS. Light mode deepens lime/cyan/aqua against --foreground so neon accents read on bone backgrounds; dark mode desaturates loud accents against --card so they don't burn at full saturation.

  • The info hero variant carries --fx-glow-opacity and --fx-glow-spread per mode, so the box-shadow glow is subtle in light mode and full-strength in dark. No hardcoded glow values anywhere in the component.

  • Brand favicons for the LLM-source detection live at public/icons/{claude,perplexity,gpt}.svg. Each is a single-color SVG loaded via CSS mask-image, so the badge inherits the callout accent color via background-color: var(--callout-accent) rather than rendering as a fixed-color sprite.

  • Column-escape positioning on desktop (≥1280px). Authors who want a callout to read as a margin sidebar use the directive form:

    MARKDOWN
    :::callout{type="info" position="escape-right"}
    This callout floats fully into the right gutter.
    :::

    Four positions: escape-{left,right} (callout sits entirely outside the article column, ~80% of the available margin width, prose flows past on the opposite side) and offset-{left,right} (callout extends 3rem past the column edge but most of its body still overlaps — a subtler signal). Below 1280px the position attribute is ignored and the callout flows in-column normally. The CSS arithmetic — (100vw - 100%) / 2 — matches the existing aside-escape recipe used by YouTubePlaylistScroller, so the two patterns line up visually if both appear on the same page.

How It's Wired

Three files under src/components/markdown/:

Callout.astro        # structure: icon, header, body slot, brand-badge stack, position class
callout-types.ts     # registry: 10 canonical types + aliases + inline SVG icon paths
callout.css          # base layout, per-type accents (semantic tokens), prose-restoration,
                     # info hero variant, brand-badge positioning, escape/offset media query

The split is along the data axis (one entry per type in callout-types.ts) rather than the file axis (one Astro file per type). A CalloutInfo.astro / CalloutWarning.astro setup would have been 95% duplicated markup with the structural code drifting between copies.

The component recurses children via <AstroMarkdown node={child} />, so every LFM feature works inside a callout: nested callouts, citations, code blocks, GFM tables, video embeds. This is intentional and codified in the LFM pipeline doc — see the matching changelog entry over in lfm/.

Test Surface

Reachable at /notes/from-the-rabbit-hole/callout-system-test. Exercises:

  • All 10 canonical types

  • All 19 aliases (warn, tldr, alert, idea, exerpt, etc.)

  • Casing variants ([!INFO], [!Warning], [!TIP])

  • Edge cases: unknown type → note fallback, foldable [!info]- empty header, missing title default label, rich content (lists, code, links) inside callouts

  • All four llm-response brand-detection paths (default → Perplexity, Claude-only, GPT+Claude stacked, explicit Perplexity)

  • All four position modes (escape-left, escape-right, offset-left, offset-right)

What This Unblocks

The legacy essay archive had ~12 callouts authored as [!info] plus ~6 as [!LLM-Response] plus a handful of [!EXCERPT] and [!brain]. Everything in there will start rendering correctly the next time those drafts get re-published — without touching the markdown source, since the bracket syntax is unchanged. The two new canonical types (llm-response, excerpt) plus the typo aliases (exerpt → excerpt, llm/llmresponse → llm-response) cover every shape that audit surfaced.