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.
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 intokens.csswhere the semantic layer is remapped, not in the component CSS. Light mode deepens lime/cyan/aqua against--foregroundso neon accents read on bone backgrounds; dark mode desaturates loud accents against--cardso they don't burn at full saturation.The
infohero variant carries--fx-glow-opacityand--fx-glow-spreadper 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 CSSmask-image, so the badge inherits the callout accent color viabackground-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) andoffset-{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 byYouTubePlaylistScroller, 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 queryThe 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 →
notefallback, foldable[!info]-empty header, missing title default label, rich content (lists, code, links) inside calloutsAll four
llm-responsebrand-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.
