Markdown Plugins Restoration — Implementation Plan

For Claude: REQUIRED SUB-SKILL: Use superpowers:executing-plans to implement this plan task-by-task.

Goal: Restore [!TIP]/[!NOTE]/etc. callouts, heading anchors, TOC generation, and scrollable tables to the v-2026 branch.

Architecture: Add five remark/rehype plugins to app/astro.config.mjs (alongside existing R2 media plugins), install their packages, and write a custom CSS file for callout alert styling that matches the existing dark theme palette defined in BaseLayout.css.

Tech Stack: Astro 5, remark, rehype, Tailwind CSS v4, IBM Plex Mono font


Task 1: Install the five missing packages

Files:

  • Modify: app/package.json (dependencies section)

Step 1: Install packages

Run from the repo root (uses the just wrapper):

Terminal window
cd app && npm install remark-github-blockquote-alert remark-toc rehype-slug rehype-autolink-headings rehype-wrap

Step 2: Verify installation

Terminal window
node -e "
import('remark-github-blockquote-alert').then(() => console.log('alert ok'));
import('remark-toc').then(() => console.log('toc ok'));
import('rehype-slug').then(() => console.log('slug ok'));
import('rehype-autolink-headings').then(() => console.log('autolink ok'));
import('rehype-wrap').then(() => console.log('wrap ok'));
" 2>&1

Expected: five ok lines printed.

Step 3: Commit

Terminal window
git add app/package.json app/package-lock.json
git commit -m "chore: add remark/rehype markdown plugins"

Task 2: Wire plugins into astro.config.mjs

Files:

  • Modify: app/astro.config.mjs

Current top of file (imports section, lines 1-8):

import { defineConfig } from "astro/config";
import { loadEnv } from "vite";
import tailwindcss from "@tailwindcss/vite";
import astroExpressiveCode from "astro-expressive-code";
import pagefind from "astro-pagefind";
import remarkR2Media from "./src/plugins/remark-r2-media.mjs";
import rehypeR2Media from "./src/plugins/rehype-r2-media.mjs";

Step 1: Add imports after existing imports

Replace the imports block with:

import { defineConfig } from "astro/config";
import { loadEnv } from "vite";
import tailwindcss from "@tailwindcss/vite";
import astroExpressiveCode from "astro-expressive-code";
import pagefind from "astro-pagefind";
import remarkR2Media from "./src/plugins/remark-r2-media.mjs";
import rehypeR2Media from "./src/plugins/rehype-r2-media.mjs";
import { remarkAlert } from "remark-github-blockquote-alert";
import remarkToc from "remark-toc";
import rehypeSlug from "rehype-slug";
import rehypeAutolinkHeadings from "rehype-autolink-headings";
import rehypeWrap from "rehype-wrap";

Step 2: Update the markdown config block

Current markdown block (inside defineConfig):

markdown: {
remarkPlugins: [[remarkR2Media, { baseUrl: mediaBaseUrl }]],
rehypePlugins: [[rehypeR2Media, { baseUrl: mediaBaseUrl }]],
},

Replace with:

markdown: {
remarkPlugins: [
remarkAlert,
[remarkToc, { heading: "toc" }],
[remarkR2Media, { baseUrl: mediaBaseUrl }],
],
rehypePlugins: [
rehypeSlug,
rehypeAutolinkHeadings,
[rehypeWrap, { selector: "table", wrapper: "div.overflow-auto" }],
[rehypeR2Media, { baseUrl: mediaBaseUrl }],
],
},

Step 3: Verify the dev server starts without errors

Terminal window
just app::serve

Expected: Astro dev server starts, no import/plugin errors in console.

Stop the server (Ctrl+C).

Step 4: Commit

Terminal window
git add app/astro.config.mjs
git commit -m "feat: restore remark/rehype plugins (callouts, toc, heading anchors, table wrap)"

Task 3: Create callout alert styles

Files:

  • Create: app/src/styles/alerts.css

The remark-github-blockquote-alert plugin generates this HTML structure:

<div class="markdown-alert markdown-alert-tip">
<p class="markdown-alert-title">
<svg class="octicon octicon-light-bulb">...</svg>
Tip
</p>
<p>Alert body text</p>
</div>

The theme palette (from BaseLayout.css):

  • --color-surface: #0d1f2d — matches codeBackground in expressive code config
  • --color-border: #152535
  • --color-text: #e8f0f8
  • --color-muted: #7a9ab5

Step 1: Create app/src/styles/alerts.css

/* Callout alerts generated by remark-github-blockquote-alert */
.markdown-alert {
border-left: 4px solid var(--alert-color, var(--color-border));
border-radius: 0.375rem;
background-color: var(--color-surface);
padding: 0.75rem 1rem;
margin: 1.5rem 0;
font-size: 0.875rem;
}
.markdown-alert > :first-child {
margin-top: 0;
}
.markdown-alert > :last-child {
margin-bottom: 0;
}
.markdown-alert-title {
display: flex;
align-items: center;
gap: 0.4rem;
font-weight: 600;
color: var(--alert-color, var(--color-muted));
margin-top: 0;
margin-bottom: 0.5rem;
text-transform: capitalize;
}
.markdown-alert-title .octicon {
width: 1em;
height: 1em;
flex-shrink: 0;
fill: currentColor;
}
/* Per-type colors */
.markdown-alert-note {
--alert-color: #60a5fa; /* blue-400 */
}
.markdown-alert-tip {
--alert-color: #4ade80; /* green-400 */
}
.markdown-alert-important {
--alert-color: #a78bfa; /* violet-400 */
}
.markdown-alert-warning {
--alert-color: #fb923c; /* orange-400 */
}
.markdown-alert-caution {
--alert-color: #f87171; /* red-400 */
}

Step 2: Commit

Terminal window
git add app/src/styles/alerts.css
git commit -m "feat: add dark-themed callout alert CSS"

Task 4: Import alert styles into the global stylesheet

Files:

  • Modify: app/src/layouts/BaseLayout/BaseLayout.css

Step 1: Add import at the top of BaseLayout.css

Current top of file (lines 1-3):

@import "tailwindcss";
@plugin "@tailwindcss/typography";
@plugin "@tailwindcss/forms";

Replace with:

@import "tailwindcss";
@import "./../../styles/alerts.css";
@plugin "@tailwindcss/typography";
@plugin "@tailwindcss/forms";

Note: Tailwind v4 uses @import for CSS files and @plugin for Tailwind plugins. The alerts.css path is relative from BaseLayout/BaseLayout.css to styles/alerts.css.

Step 2: Verify import path resolves

Terminal window
just app::build 2>&1 | head -40

Expected: Build completes without CSS import errors.

Step 3: Commit

Terminal window
git add app/src/layouts/BaseLayout/BaseLayout.css
git commit -m "feat: import alert styles into global stylesheet"

Task 5: Visual verification

Step 1: Start dev server

Terminal window
just app::serve

Step 2: Open a post that uses callouts

Navigate to the version post that uses all five callout types: app/src/content/versions/2025-astro-animated.md — contains [!NOTE], [!TIP], [!IMPORTANT], [!WARNING], [!CAUTION].

Find its URL in the running dev server (likely /versions/2025-astro-animated or similar) and open in browser.

Step 3: Verify each feature works

Check the following render correctly:

  • [!NOTE] — blue left border, “Note” title with icon
  • [!TIP] — green left border, “Tip” title with icon
  • [!IMPORTANT] — purple left border, “Important” title with icon
  • [!WARNING] — orange left border, “Warning” title with icon
  • [!CAUTION] — red left border, “Caution” title with icon
  • Headings have id attributes (inspect element)
  • Headings show a # anchor link on hover

Step 4: Check a recipe post

Navigate to Bang Bang Shrimp recipe — it uses [!TIP]. Verify it renders with green styling.

Step 5: Check a guide post

Navigate to the django-react-native-auth guide — it uses [!IMPORTANT] twice. Verify purple styling.

Step 6: Stop the server and commit any fixes

If adjustments were needed for CSS (spacing, colors), commit them:

Terminal window
git add -p
git commit -m "fix: adjust alert CSS spacing/colors after visual review"