Present Skill
SkillDocs & knowledgeape-present turns a blog post into a single self-contained HTML document built for walking people through an idea. The result is a readable long-form piece with animated diagrams and just enough text to carry the point. Once added, your AI can produce this kind of document from any post you give it.
Available today. Use it from your connected AI after setup.
No other account needed.
Give your AI a blog post and ask it to make this presentable or turn this post into a doc you can walk people through. It will return the finished document ready to share.
Then ask your AI: use the Present Skill skill
What your AI can do with it
- Convert a blog post into a single self-contained HTML document
- Shape the post into a readable long-form document
- Add animated diagrams that illustrate the idea
- Trim the writing down to only what carries the idea
- Produce a finished document you can present to a group
What this skill tells your AI
The instructions your AI receives, as published by arpitbbhayani/ape-skills in ape-present/SKILL.md and read by ahel’s review.
Takes a blog post and produces one HTML file that reads like a well-made internal document: a title, a summary, real headings and short paragraphs, and a figure for every idea -- diagrams that move to show the mechanism, numbers set large, a formula typeset where the formula is the point. The author opens it and walks people through it, or shares the link and people read it alone. Both must work.
It is a document, not a deck. No full-screen sections, no hero, no scroll-snapping, no progress bar, no slide feel. The first screen is the title and the summary, and the page scrolls like any other. Single file, real selectable text, comfortable line length with defined width limits (--measure for prose column, with visual elements permitted to break out to --wide or --max-width), full theme support matching present-md, and a fixed section skeleton -- summary, context, body, sources -- so every document has the same shape.
It is not the blog either. The post explained; this document shows and teaches. Each idea gets exactly enough prose to be understood, and no more -- the figure, code, or format diagram carries the weight, not the paragraph around it.
Audience: practicing engineers, not students. Favor concrete mechanics over abstract description -- pseudocode for algorithms, the on-disk or wire format for stored/transmitted structures, real code where the post has it. A mechanism explained only in prose gets translated into pseudocode or a format figure, not more prose.
The one rule that makes it look good
Assemble the system; design only when the concept earns it. The reference/ directory next to this file holds a finished design system: base.css, runtime.js, skeleton.html, svg-templates.md, and a verify.sh that checks the result. The document is built by pasting those verbatim and filling the slots, and most visuals are a template from svg-templates.md with the labels changed -- that stays the fast, safe default and should be your first move for every idea. But the catalogue is not a ceiling: when an idea's shape does not fit any row, or a different visual form would carry the concept more clearly than forcing it into an existing template, invent one. A custom visual is judged the same way a templated one is -- only the tokens base.css defines (never a new hex, never a gradient/blur/shadow/texture it doesn't already have), a <figure> with a <figcaption>, the mechanism-moves/evidence-stays-still rule, and every ban in Step 4 -- so it still reads as part of the same system rather than a different page bolted on. See "Going off-catalogue" in Step 2. What's gone is the requirement to force every idea into an existing box-and-arrow arrangement when a better shape exists.
Read skeleton.html, svg-templates.md, at least one post in reference/examples/ so you know what a source looks like, and examples/bitcask.spine.md -- a real spine for one of them, with the wrong spines it avoids -- before starting. Do not skip this because the task looks simple. Do not read base.css or runtime.js in full: they are injected mechanically in Step 5, never retyped, and everything you need from them (the component classes, the theme tokens) is documented in this file, the catalogue, and the skeleton's examples.
Input Handling
The user may provide input in any of these forms. Identify which it is before doing anything else.
- File path on disk: a path ending in
.md,.txt,.html, or similar. Read the file directly. - A URL: a string starting with
http://orhttps://. UseWebFetchto download the content, then strip navigation, sidebars, footers, and comments before working on the body. If the URL points to a PDF, download it withcurland extract the text -- preferpdftotextif available; otherwise read the PDF with theReadtool. - Pasted content: raw text in the message. Work on it in-memory.
- Ambiguous: if it is unclear whether the input is a path, URL, or pasted text, ask once. Do not guess.
Optional modifiers the user may add anywhere in the request:
- Audience: "for execs", "for new grads", "for the platform team". Changes how much is assumed and which numbers lead. Default: software engineers with 5-8 years of experience -- practical and implementation-minded; they want the pseudocode, the wire format, and the code, not just the concept.
- Length: "short" (the claim, the surprising idea, the main mechanism, the biggest number; 4-6 ideas) or "full" (every idea in the post). Default: full.
- Theme: "midnight", "tokyo", "nord", "dracula", "gruvbox", "rosepine", "forest", "neon", "daylight", "arctic", "solarized", "paper", "rosequartz", "swiss" (matching
present-md), or an accent hue ("amber", "teal", "violet"). Default: no theme -- the page follows the OS (daylight on light, midnight on dark). See "Applying a theme or accent" below. - Layout: "keep it left-aligned", "shift the body left", "give the right side more room for diagrams". Default: centered column, breakouts symmetric. See "Applying a layout mode" below.
- Output path: "write it to ~/docs/wal.html". Default:
<slug-of-title>.htmlnext to the source file; in the current directory for URL or pasted input.
Applying a theme or accent
A named theme is applied as data-theme on the html element: <html lang="en" data-theme="nord">. Omit the attribute for the default OS-following behaviour. Each named theme brings its own display font, which must replace Space Grotesk in the fonts <link> (IBM Plex Mono stays):
| Theme | Display font | Theme | Display font |
|---|---|---|---|
| midnight, daylight, neon | Space Grotesk (default link) | forest, solarized | Outfit |
| tokyo | Sora | rosepine, paper | Fraunces |
| nord, arctic | Manrope | rosequartz | Playfair Display |
| dracula | Syne | swiss | Archivo |
| gruvbox | Bricolage Grotesque |
An accent hue changes only the two --accent lines in the pasted base.css -- the one in the midnight block and the one in the daylight block (--accent-soft, --accent-line, and --glow derive from it automatically). Use these pairs; do not invent hexes:
| Accent | midnight (dark) | daylight (light) |
|---|---|---|
| violet (default) | #cba6f7 | #8839ef |
| blue | #89b4fa | #1e66f5 |
| sky | #89dceb | #04a5e5 |
| teal | #94e2d5 | #179299 |
| green | #a6e3a1 | #40a02b |
| amber | #f9e2af | #df8e1d |
| orange | #fab387 | #fe640b |
| red | #f38ba8 | #d20f39 |
| rose | #f5c2e7 | #ea76cb |
Applying a layout mode
By default the document sits in a single centered column (.doc), and wide figures (.wide/.breakout/.full-bleed) break out symmetrically around that same center point. Request a left layout to switch to an asymmetric mode instead: the whole document hangs off a left margin, and every breakout figure extends rightward from that same margin rather than centering on the viewport -- useful when the concept needs a run of wide diagrams, tables, or code and the document should keep the right side free for them throughout. Apply it as data-layout="left" on html, alongside any data-theme: <html lang="en" data-theme="nord" data-layout="left">. Omit the attribute for the default centered behaviour. This is a document-wide switch, not a per-figure choice, and it collapses back to the default full-width single column below the mobile breakpoint like everything else.
Step 1: Find the Spine
Read the whole post once before writing anything. Extract, in this order:
- The one-line claim. What the author would say with ten seconds. This is the dek under the title.
- The ideas, in order. Each idea is one thing the reader must understand to believe the claim. A typical post has 5-12. Each becomes one
h2in the body. The test for an idea: it is something a reader could be wrong about. "The write path" is a topic; "every write is appended, never seeks, and the index lives in memory" is an idea. One idea per paragraph, per heading, or per section of the blog are all wrong spines -- ideas cut across the post's structure. - For each idea, its visual form, chosen from the catalogue in Step 2 or designed custom when the catalogue underserves the idea (see "Going off-catalogue" in Step 2). If no picture carries it, the idea is a number (stat row), a sentence (quote), or context (prose only, no figure) -- or not an idea, and it is cut.
- The numbers. Every figure in the post that matters. These are the only things allowed in large type.
- The surprising claim. The thing a knowledgeable reader would not have guessed. It gets its own
h2and the quote treatment. - The code, pseudocode, and storage/wire format for every mechanism. Retain code the post shows (trim to essentials,
...for the rest,.hlon key lines, max 20 lines) or simplify it to pseudocode via [[ape-write-pseudocode]]. When the post describes an algorithm only in prose, write pseudocode for it anyway -- this is the default, not a fallback; every step must map to something the post says, but the form is code, not paragraphs. Same for a record layout, disk format, header, or wire format described in prose only: draw it as the wire-format figure ("Record, header, or wire-format layout" in Step 2) even without a source image. - The post's own figures. For each image, chart, or diagram in the source: if it carries an idea, it is redrawn from a template (never embedded, never linked, never base64); if it is decorative, it is dropped. Note the decision per figure. To read an image:
curl -sL <url> -o <scratchpad>/figN.png, then open it with theReadtool and transcribe what it shows (a formula to LaTeX, a plot to its shape and labelled points, a table to rows). If the download fails, work from the surrounding prose and say so in the closing block. - Tables and maths. A table in the source becomes the matrix figure with the relevant row highlighted. Inline maths stays as Unicode (
O(log n),λ = 0.7). A formula that is the idea of a section becomes a.formulafigure typeset with MathJax. Formulas the source shows as images are transcribed to LaTeX from the image; if the image cannot be read, the formula is written from the surrounding prose and flagged in the closing block. - The caveats. Every "only when", "except if", "we have not tested" in the post. Each attaches to its idea as an aside.
- The sources. The post itself, plus anything the post cites that the document mentions.
Write the spine as a plain list (NN. idea as sentence -> visual form) and print it. If the source is over 2,500 words or the spine has more than 10 ideas, stop here and wait for the user to confirm or trim. Otherwise the spine is informational and the build proceeds immediately.
Heading levels. Up to 8 ideas: each idea is an h2. More than 8: group them into 2-4 parts; each part is a short h2 (Structure, Operations -- the one place a topic heading is allowed) and each idea beneath it is an h3. Whatever the level, idea headings are sentences; the sentence rule in the checklist applies to idea headings only.
Step 2: Visual Catalogue
Every figure comes from one of these, or from a custom visual when the idea calls for it (see "Going off-catalogue" below). The template reference is where to copy from.
| Idea shape | Visual | Template |
|---|---|---|
| System, pipeline, request flow | Boxes and arrows, left to right, packets moving along it | svg-templates.md §1 + §10 |
| Data flow across complex components (stream processing, multi-stage routing) | Data Flow Graph, multiple components with fanning packets | §1c + §10 |
| Pub/Sub Broadcast, central message bus, hub-and-spoke | Central broker radiating out to multiple subscribers | §1d + §10 |
| Request/response, handshake, consensus round, race condition | Sequence diagram, time downward, packets per message | §2 + §10 (race: crossing --err arrows) |
| Parallel execution, blocking vs async, concurrency | Gantt / Swimlane diagram over time | §2b |
| Comparison of 2-6 magnitudes, before/after numbers | Race bars (horizontal meters filling to their targets) | §3a + skeleton.html race-bars example |
| Comparison of more than 6 magnitudes | SVG bar chart, labels on bars, no legend | §3 |
| Comparison of two conflicting axes (e.g. Write vs Read) | 2x2 Trade-off Matrix / Quadrants | §3b |
| Architecture Stack/Layer Breakdown (system overview, multi-tier comp) | Stack diagram of logical layers / modules | §3c + §10 |
| One quantity against another, a function's shape, a plot in the post | Function curve, one accent path, labelled endpoints | §3d |
| Sequential cost of one operation, "where the time goes" | Latency waterfall (static) | §3e |
| A distribution and its tail, percentiles (p50/p99) | Histogram with percentile markers (static) | §3f |
| Values spanning orders of magnitude ("ns to ms") | Magnitude ladder, log scale (static) | §3g |
| Two or three growth shapes compared (O(n) vs O(log n)) | Multi-curve comparison (static) | §3h |
| A metric over time with events marked ("then we deployed") | Annotated time series (static) | §3i |
| Tree, hash, linked, graph structure | Node-and-edge diagram | §4 |
| Circular distribution, consistent hashing, peer-to-peer rings | Ring Topology / Distributed Ring | §4b + §10 |
| Nested environments, Virtual Machines, Containers, sandboxes | Nested Boundaries / Containment Structure | §4c |
| Records/tables and the fields linking them (schema) | Titled boxes with field rows, FK arrow | §4d |
| Decision, branching logic, "if X then Y" | Flowchart with diamonds, packet on the taken branch | §7 + §10 |
| Lifecycle, modes, status transitions | State machine, states cycling | §8 + §10 |
| History, phases, "first we…, then we…" | Timeline | §9 |
| Several options, one chosen | Matrix table with .chosen row (figure.wide above 3 columns) | §5 |
| Memory, bytes, slots, array, hash buckets | Cell grid with .on / .bad cells, probe sequence cycling | §6 + §10 |
| Record, header, or wire-format layout | .cells.row with named fields | §6 |
| Load skew, hot spots, hit patterns across a grid | Heatmap cells, 3 accent intensity steps (static) | §6b |
| One source feeding two targets (or two into one) | Branching pipeline | §1b + §10 |
| A number that matters | Stat row with count-up | skeleton.html stats example |
| Sequence of steps, algorithm phases | .steps list (numbered) | base.css .steps |
| Principles, rules, requirements, "the N things" (not sequential) | .rules list (dashed) | base.css .rules |
| Two or three things contrasted, multi-card sets | Side-by-side .panels (or .panels.three, .wide / breakout permitted) | base.css .panels |
| The key insight, the surprising claim, in the post's own words | .quote | skeleton.html quote example |
| A section's core takeaway that is not a quotation | .callout.insight with .hl-pill terms | skeleton.html callout example |
| Multi-phase mechanism the reader steps through (3-6 phases on one diagram) | .stepper panes + data-step highlights on the figure's SVG | skeleton.html stepper example |
| Mechanism in code / Pseudocode | pre with hand-wrapped spans, 1-3 .hl lines | skeleton.html code example |
| The exact code change the post made (before/after lines) | pre.diff with .add/.del lines | skeleton.html diff example |
| A shell session the post shows (command and output) | pre.term with .prompt/.out | skeleton.html terminal example |
| Optional depth a skimmer can skip | <details class="deep-dive"> after the idea's figure | skeleton.html deep-dive example |
| A formula that is the point | .formula figure, MathJax, key term in accent | skeleton.html formula example |
Rules:
- Every mechanism diagram moves; every evidence figure stays still. A mechanism shows where data goes -- pipeline, sequence, flowchart, state machine, tree lookup, cell grid: add at least one motion primitive from
svg-templates.md§10 (a packet along the accent arrow at minimum), running only while the figure is on screen and never under reduced-motion. An evidence figure proves a claim -- stats, quotes, bar and race charts, waterfall, histogram, magnitude ladder, curves, time series, heatmap, matrices, timelines, schema, code / diff / terminal: no motion beyond the reveal, and every value or event label on it must be stated by the post. The magnitude ladder is the one non-linear scale permitted and keeps its "log scale" annotation. - Code and Pseudocode:
<pre><code>with hand-wrapped spans (span.k/.s/.c/.n) and 1-3.hllines on the key operation (see Step 1 item 6 for when to write pseudocode from scratch). When the post's point is a change, show it aspre.diff-- the post's own before/after lines,+/-prefixes,.add/.delper line, same 20-line cap. A shell session ispre.termwith.prompt/.out, transcribed exactly -- output numbers are claims. - Deep-dives (
<details class="deep-dive">): optional depth a skimmer can skip, attached under an idea after its figure. Never a caveat, never load-bearing -- the body must read complete with every deep-dive closed. At most two per document. - One figure per idea. An idea that needs two figures is two ideas.
- Every SVG and table sits in a
<figure>with a<figcaption>; 960-wide diagrams getclass="wide". - Stats & multi-card layouts: one row per idea, at most three numbers in it, and only for figures the post actually states. A metric without a value ("cycle time", "weeks to days") is not a stat -- it goes in prose or a
.ruleslist. Three-card layouts (three stats, three panels via.panels.three) are permitted and encouraged to break out beyond the prose container (.wide/.breakout) up to--wideso the cards have room to breathe rather than squeezing tightly inside--measure. - The catalogue is the default, not a cage. Reach for a custom visual -- not necessarily an SVG diagram in the §1-§9 grammar -- when an idea's shape does not fit any row, or when a different visual form would make the concept click faster than forcing it into an existing template. See "Going off-catalogue" below for what a custom visual must still honour.
- A
.stepperis user-driven interaction, not animation: use it when one diagram carries 3-6 phases the reader should walk at their own pace, withdata-step="1..N"on the SVG groups each phase is about. Each pane is prose and obeys the fidelity rules. At most one stepper per document; a mechanism with 2 phases is.panels, with continuous motion it is §10. - Two external resources are permitted, no others. The Google Fonts link from
skeleton.html(IBM Plex Mono for text; Space Grotesk for title and headings on the default themes -- a named theme swaps in its own display font per the table above; system fallbacks make the page readable offline), and MathJax -- only when the document has at least one.formula, with the exact pinned tags fromskeleton.html. Every.formulacarries a plain-text fallback indata-plain.
Going off-catalogue
The catalogue exists so most documents never need this section. Reach for it when an idea's shape genuinely does not map to any row, or when you can see a visual that would carry the idea more clearly than the nearest template forced into service.
A custom visual is free in form -- it does not have to be a box-and-arrow SVG on the 8px grid, and it does not have to reuse an existing §-numbered layout. It is not free in material: it must still be built only from the tokens base.css defines (no hex outside :root, no gradient/blur/shadow/texture beyond what the system already has), sit inside a <figure> with a <figcaption> like every other visual, follow the mechanism-moves/evidence-stays-still rule above, and obey every ban in Step 4. Judge it the way a templated figure is judged in the fidelity pass (Step 6): every element on it must correspond to something the post actually says.
Reach for a custom visual deliberately, not by default -- if a catalogue entry already fits, use it. A document that invents a new visual form for every idea stops reading as one coherent system and starts reading as a collection of one-offs.
Step 3: Document Structure
Follow skeleton.html exactly. Direct start (no chrome bars, eyebrows, or author clutter at the top):
<article class="doc">
<header class="doc-header"> h1 · dek (the one-line claim) -- clean, immediate start
<section id="summary"> .summary: 3-5 sentences
<section id="context"> h2 + 1-3 short paragraphs, the first with class="dropcap", optional .inspect-node links
<section id="body"> one heading per idea with data-n="NN" (margin folio): prose · figure + figcaption · optional aside; ends with <p class="end-mark">■</p>
<section id="sources"> h2 + <li cite="…"> one per source
</article>
<script> MathJax tags (only with a .formula), then runtime.js verbatim
Per-idea rules:
- Heading (
h2, orh3under parts): carriesdata-n="NN"(two digits, numbered across the whole body) so the folio prints in the margin; the idea as a full sentence. "Every write goes to the log first", not "Write path". Stable across versions -- reviewers anchor comments to headings. - Prose: What happens, in what order, why it works, with the numbers in it -- as few sentences as that takes. When the figure carries the idea, the prose gets shorter still: never restate in words what the picture already shows, point at it and move on. Depth only some readers want goes in a deep-dive, not the paragraph.
- Figure: from Step 2. The figcaption opens with a bold 3-6 word label, then one sentence saying what the picture shows that the prose cannot. A
.formulafigure also carries a.formula-legendnaming each symbol in one phrase (N documents in corpus), and its\class{term}{…}marks the one term the idea is about. A code or pseudocode figure wraps in<pre><code>with hand-wrapped spans and an explanatory figcaption highlighting what the critical lines accomplish. - Aside: only if the post had a caveat for this idea. Never drop a caveat to make a section cleaner.
.aside.errfor a failure condition. - Stagger:
style="--i:n"on each.pop/.drawinside an SVG, in reading order. Nothing else needs--i.
Word budget: the whole document (summary to sources, captions and diagram labels included) is 80-180 words per idea plus 150-300 for summary, context, and sources. Stay inside it by default; exceed it only when a sentence is load-bearing for understanding, not to be thorough for its own sake.
Step 4: What Not To Do
These are the patterns that make generated pages look generated, or turn a document into a deck. Each is a build failure.
Shortened here. Read the whole file on GitHub.
Signals
- GitHub stars
- 40
- Forks
- 3
- Last commit
- Sep 2026
Advanced
- Catalog kind
- skill
- Gateway key
ape-present- Source
- github.com/arpitbbhayani/ape-skills