plugins/octave/skills/get-brand-components/SKILL.md
Capture a brand's visual design system from its website and build a reusable component kit. Walks key pages on a domain (screenshots + HTML via the Octave scrape tool), derives design tokens (colors, type, spacing, radius, shadow), and produces a minimal component library (buttons, cards, headers, stats, tables, badges, hero, footer) as a self-contained HTML reference plus CSS tokens. Use when the user says "get brand components", "capture the brand", "build a component kit for [domain]", "make outputs look like [company]", wants other skills to generate on-brand HTML for a target company, or wants to reuse an already-published brand kit from the asset store or host/share a kit as a live link (via asset-manager).
npx skillsauth add octavehq/lfgtm get-brand-componentsInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
Walks the key pages of a target website, captures screenshots and HTML, derives the brand's design system (colors, typography, spacing, components), and produces a reusable component kit: design tokens (tokens.css), a self-contained component gallery (components.html), a machine-readable manifest (manifest.json), and a human-readable spec (brand-kit.md). Other skills (one-pagers, microsites, battlecards, decks, two-pagers) load this kit to generate outputs that look and feel like the target brand.
/octave:get-brand-components <domain-or-url> # Walk the site and build a brand component kit
/octave:get-brand-components <domain> refresh # Force a fresh re-walk, overwriting the cached kit
/octave:get-brand-components list # List saved brand kits
/octave:get-brand-components show <slug> # Display a saved kit (and open the gallery)
/octave:get-brand-components export <slug> # Zip the cached kit to ~/Desktop/<slug>-brand-kit.zip
/octave:get-brand-components delete <slug> # Remove a saved kit
<domain-or-url> accepts acme.com, https://www.acme.com, or https://www.acme.com/product (a specific seed URL).
Kits are cached at ~/.octave/brands/<slug>/ and reused by default — building a kit costs scrape credits + time, so don't rebuild what you already have. When a kit for the domain already exists, the default action is to load and reuse it (summarize + open the gallery), NOT re-walk the site. Re-walk only when the user explicitly asks (refresh, "rebuild", "re-scrape") or the kit is clearly stale. This applies whether the skill is called directly or by another skill needing the brand: check the cache first, reuse on hit, only build on miss.
Brand kits are stored under ~/.octave/brands/<slug>/:
~/.octave/brands/<slug>/
brand-kit.md # Human-readable design system spec + usage guide
tokens.css # :root design tokens (the reusable core)
components.html # Self-contained component gallery (live previews + snippets)
manifest.json # Machine-readable: slug, domain, pages, tokens summary, date
<slug>-logo.svg # Real logo, downloaded + inlined (not hotlinked)
icons.json # Real page icons lifted verbatim {name: {viewBox, inner}}
fonts/ # Real webfont files (.woff2/.woff) for base64 @font-face embedding
images/ # Real product screenshots + customer logos (for split/logos blocks)
screenshots/ # Reference PNGs of the walked pages
<slug> is the registrable domain, lowercased and hyphenated (e.g. acme.com → acme, acme-corp.io → acme-corp).
Primary capture tool — the Octave scrape_website MCP tool:
html or markdown, and optionally a full-page screenshot.format: "html" and includeScreenshot: true — you need both the DOM (for colors, fonts, structure, real class names) and the rendered visual (for layout, gradients, button shape, spacing rhythm the DOM hides).found: false (no charge) when a page is unreachable — keep the page count tight (≤ 6 pages).screenshotUrl (a signed URL). When present, persist it to screenshots/ with curl so the kit has reference images.Fallback when the Octave MCP scrape tool is unavailable: use WebFetch for text/HTML only and tell the user "No screenshot capture available — the kit is derived from HTML only, so visual fidelity (gradients, spacing, button shape) is lower. Connect the Octave MCP server for screenshot-backed analysis." Still produce the kit.
The whole value of this skill is that output looks like it came off the page, not "close-ish." A designer at the target company will instantly reject tasteful recreations as "AI slop." So the rule is: lift the brand's REAL atomic elements, never eyeball them.
brand-kit.md.https://www.<domain> if only a bare domain is given; keep an explicit URL as the seed).<slug> from the registrable domain.~/.octave/brands/<slug>/ (has manifest.json), reuse it by default: print a one-line summary from manifest.json, open the gallery, and stop — do not re-walk or spend scrape credits. Only proceed to Step 2 when the user passed refresh (or explicitly asked to rebuild/re-scrape), or the kit is missing/partial/stale. Mention they can pass refresh to rebuild.owner). If the Octave MCP asset tools aren't available, skip this silently and continue to Step 2.
assets_list MCP tool — an actual tool call, never a bash/python simulation, and never "assume" its result. If the assets_list result is not in your transcript, this check did not happen and you may not proceed to Step 2. Look for identifier <slug>-brand-kit — exact first, then fuzzy (identifier or description containing the slug/company name plus "brand").../asset-manager/SKILL.md — mint the token, then download-artifact.sh --uuid <uuid> --out "${TMPDIR:-/tmp}" (files land in ${TMPDIR:-/tmp}/<identifier>/, where <identifier> is the matched asset's actual identifier — for a fuzzy match it may not be exactly <slug>-brand-kit). Only if the download exits 0 and ${TMPDIR:-/tmp}/<identifier>/manifest.json exists, promote it: mkdir -p ~/.octave/brands && rm -rf ~/.octave/brands/<slug> && mv "${TMPDIR:-/tmp}/<identifier>" ~/.octave/brands/<slug> (the mkdir -p is required on a fresh machine — mv will not create the parent). If the download failed or manifest.json is missing, leave ~/.octave/brands/ untouched and continue to Step 2. Then treat it exactly like a local cache hit: summarize, open the gallery, stop — no scrape credits spent. Update the asset-manager registry per its rules.Scrape the homepage first (format: html, includeScreenshot: true). Then choose up to 5 more high-signal pages — these are where a brand's design system is most fully expressed. Discover them from the homepage's nav/footer links and prefer, in order:
/) — hero pattern, primary CTA, nav, color story (always)Skip pages that 404 or duplicate a pattern you already have. Aim for coverage of distinct component types, not page count. Report progress:
Walking <domain>…
✓ / (hero, nav, primary CTA)
✓ /product (feature cards, icon tiles)
✓ /pricing (plan cards, comparison table)
✓ /learn/post/x (article typography, callouts)
✓ /customers (testimonials, stat blocks)
Captured 5 pages. Deriving the design system…
For each scraped page, if screenshotUrl is present, save it:
mkdir -p ~/.octave/brands/<slug>/screenshots
curl -s "<screenshotUrl>" -o ~/.octave/brands/<slug>/screenshots/<page-slug>.png
The scrape gives you rendered HTML + a picture; the exact values live in the stylesheet bundle. Fetch and mine it directly. Use a browser User-Agent so you get the real markup.
UA="Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/124 Safari/537.36"
curl -s -A "$UA" https://www.<domain>/ -o /tmp/<slug>_home.html
# Next.js sites: CSS at /_next/static/css/*.css . Other stacks: grep the <link rel=stylesheet> hrefs.
for f in $(grep -oE '/_next/static/css/[^"]+\.css' /tmp/<slug>_home.html | sort -u); do
curl -s -A "$UA" "https://www.<domain>$f" >> /tmp/<slug>_all.css; echo >> /tmp/<slug>_all.css
done
Then extract the real values (don't transcribe a vibe):
grep -oE 'font-family:[^;}]+' and the @font-face/--font-* vars. Capture the true family and weight for headings vs body (many brands use a medium-weight display face for headings — defaulting to bold-700/800 would be wrong). Then EMBED the real webfont so output renders pixel-exact instead of in a fallback (a wrong heading face is the #1 "AI slop" tell):
@font-face src:url(...) for the heading family from the CSS (grep -oE "@font-face\{[^}]*}" all.css | grep -i <family>), curl the .woff2/.woff into ~/.octave/brands/<slug>/fonts/, then base64-embed it as an @font-face with a data: URL in tokens.css / the output <style>. Example:
curl -s -A "$UA" "https://www.<domain>/_next/static/media/<hash>.woff" -o ~/.octave/brands/<slug>/fonts/<family>-<wght>.woff
B64=$(base64 -i ~/.octave/brands/<slug>/fonts/<family>-<wght>.woff) # embed as: @font-face{font-family:'<Family>';src:url(data:font/woff;base64,$B64) format('woff');font-weight:...;font-display:swap}
brand-kit.md.button-primary/secondary/tertiary), the type scale (Heading*, Text*, Label*), cards. Copy exact border-radius, padding, box-shadow, background, inset rings, transitions.--brand-btn-{sm,md,lg}-{height,pad,font,radius} tokens and show all sizes in the gallery.grep -oE '#[0-9a-fA-F]{6}' all.css | tr 'A-F' 'a-f' | sort | uniq -c | sort -rn | head -30. Map the top hits to roles; confirm against the screenshot.background-clip:text), letter-spacing, italics, all-caps?--brand-emphasis: color #582ecc on light / #a384f6 on dark, same weight, no underline) and apply that, with the light/dark contrast variants below.background-image/gradient for things like highlighted-word underlines and icon-tile fills (these are what make it unmistakable). Capture light AND dark variants of each treatment — brands swap accent colors per background. (A brand's highlighted text might be a saturated accent on light but flip to white on dark, keeping the same underline in both — its CSS will carry both color rules.)max-width + responsive gutters, and the section vertical padding (grep the hero/section wrapper rules; section padding is often 4–6rem top/bottom). Brands look professional because they're airy — generous section padding, large headings, comfortable line-height. Reproduce that scale; do not pack content edge-to-edge.eyebrow label → balanced heading (one highlighted word) → muted subhead). Mirror the brand's actual pattern on every section.box-shadow:0 0 100px #01f846-style), gradient borders (border-image:linear-gradient(...) or a mask ring), layered surfaces, and any hero graphic / floating product chips. Capture these and use them — a dark hero must have glow + a graphic element, not be a plain block.--brand-texture (layered above the glow on dark bands; --brand-hero-texture for light heroes). Reusable CSS recipes — tint the rgba to the brand:
radial-gradient(rgba(255,255,255,.07) 1px, transparent 1.4px) 0 0/22px 22pxlinear-gradient(rgba(255,255,255,.05) 1px,transparent 1px) 0 0/30px 30px, linear-gradient(90deg,rgba(255,255,255,.05) 1px,transparent 1px) 0 0/30px 30pxfeTurbulence data-URI (<rect filter=fractalNoise opacity='0.12'>) — premium tooth on dark/gradient bands
Tune intensity per type: line/dot grids read at ≈5% alpha, but grain needs ≈10–14% (at 6% it's invisible at normal size). Keep it subtle enough not to hurt contrast, and confirm against the source — don't add texture a brand doesn't use.~1.5–2.5rem), whether sections float on a soft canvas (rounded sheet/cards) vs full-bleed, and any curved/wavy dividers between bands. Never emit a sharp full-bleed rectangle when the brand rounds its sections — round the hero/band/footer corners to the section radius (e.g. wrap the doc in a rounded sheet with overflow:hidden so even the top hero corners are rounded). Hard right-angle edges against the page are an instant "not from them" tell.2.5–4rem). Scaling them down to ~17px kills the brand feel; keep them big.Lift the real assets (download + inline, never hotlink):
<img alt="…Logo"> or the nav logo <svg>; curl it to ~/.octave/brands/<slug>/ and inline it. Capture BOTH lockups: the dark-text version for light backgrounds AND the white/light version for dark bands (look for logoFullWhite, logo-white, the nav logo on a dark hero, etc.). Use the right one per surface.
filter:brightness(0) invert(1) — it flattens a detailed/colored mark into a featureless white blob. Fetch the brand's actual inverse lockup instead.alt="logo" for many client logos in social-proof rows — none of which are the brand.) When the nav logo is ambiguous or you keep pulling client logos, the favicon / og:image is usually the reliable brand mark — and og:image often shows the full lockup. Prefer the asset actually rendered in the live nav, confirmed by eye.<svg> icons (match by <title>), save to ~/.octave/brands/<slug>/icons.json, and reuse them verbatim in cards/tiles. Do not substitute generic icons.Work primarily from the real CSS (Step 2.5) — the screenshots only confirm layout and visual truth. Extract:
3a. Color tokens. Find the real values, don't guess:
--color-*, :root blocks), inline style colors, background, color, border, fill/stroke, gradient stops, and box-shadow colors.bg / bg-alt (page + alternating section backgrounds)surface (card background), surface-dark (dark-section card)ink (primary text), muted (secondary text), on-dark text colorprimary (main brand/CTA color) + primary-ink (text on primary)accent / highlight (used to emphasize words, links, underlines)border, border-softpositive / negative (for ✓/✕ comparisons) if present, else derive tasteful defaults from the palettebackground: valueband token set.3b. Typography.
font-family. Note the web-font source if linkable (Google Fonts name, or a CDN/@font-face URL) so other skills can <link> it; otherwise pick the closest common fallback and say so.3c. Shape & depth.
border-radius.box-shadow.3d. Component inventory. Identify which of these the brand uses and how it styles each: buttons (primary/secondary/tertiary), badge/pill/eyebrow, card (plain + icon-tile), icon tile, section header (eyebrow + title + highlight + subtitle), hero/banner band, stat/metric block, comparison/feature table, quote/testimonial, checklist, CTA block, footer/brand bar, logo/wordmark treatment.
Quote a concrete observation for each major token (e.g. "primary CTA is a pill in the brand's accent color, radius 999px, with a trailing arrow") so the kit is grounded, not invented.
tokens.cssThe reusable core. A single :root block plus a web-font @import/comment. Use neutral, brand-agnostic token NAMES (so consuming skills reference the same names across brands) with this brand's VALUES. Use the full token template in references/tokens-template.md — it covers color roles, type (families, sizes, exact weights, the emphasis mechanism), shape (radii, shadows, the button size scale), layout & rhythm, depth (glow, gradient borders, texture), and the foundations (neutral ramp, semantic states, spacing/elevation scales, motion, icon stroke, signature gradients).
Light/dark theme pairing. If the brand ships both a light and dark theme, capture both: default mode in tokens, opposite-mode overrides in manifest.render.tokensDark (or tokensLight) — only the tokens that differ. The renderer's --theme light|dark merges them, so one kit renders either mode.
components.html (the template reference library)A self-contained HTML file (inlines the tokens from Step 4 — no external CSS dependency, web fonts via <link> allowed) that renders the minimal component kit. This is both a visual reference AND a copy-paste source for other skills. For each component show a live preview and, directly beneath it, the HTML snippet in a <pre><code> block.
Build these components, styled with the brand's tokens, composition, and depth. Atoms aren't enough — a kit of correctly-colored buttons on a cramped flat page still reads as "AI slop." Include the layout primitives:
Composition primitives (the part that makes it look designed):
--brand-radius-section container with glow, used to break up white sections and add rhythm.Atoms & blocks: 4. Buttons — primary, secondary, tertiary/ghost (real anatomy: pill/rect, arrow, size). 5. Badge / Pill / Eyebrow — the small label treatment (match case — many brands are sentence-case, not all-caps). 6. Card — plain + a card with an icon tile (real size, gradient/tint, and any glow shadow the brand uses). 7. Gradient-border element — if the brand uses gradient borders / glowing chips, include one. 8. Stat / metric block, Comparison ✕-vs-✓, Quote, Checklist, CTA band, Footer / brand bar — each in the brand's treatment. 9. Color + type swatches — token reference at the top, headings rendered at their real large sizes.
Faithful over minimal — it's a kit, not a clone of the whole site, but it must capture the brand's spacing, hierarchy, and depth, not only its colors. Inline the real logo SVG saved in Step 2.5 (downloaded, not hotlinked) and the brand's real icons from icons.json — do not recreate the wordmark as plain text or swap in lookalike icons. Match the real font weight, button anatomy, and signature treatments (highlight underline, gradient tiles). Add print-color-adjust: exact on dark bands so the components survive PDF export when reused in print collateral.
manifest.jsonMachine-readable summary so other skills can discover and load the kit programmatically:
{
"slug": "<slug>",
"company": "<Company Name>",
"domain": "<domain>",
"generated": "<YYYY-MM-DD>",
"pages": ["/", "/product", "/pricing", "..."],
"fonts": { "heading": "<name>", "body": "<name>", "link": "<webfont url or null>" },
"tokens": { "primary": "<hex>", "accent": "<hex>", "bg": "<hex>", "ink": "<hex>", "band": "<value>" },
"hasDarkBand": true,
"buttonStyle": "pill-with-arrow",
"files": { "tokens": "tokens.css", "components": "components.html", "spec": "brand-kit.md" },
"render": { "...": "the machine token contract the renderer consumes — see 'Generating collateral from a kit'" }
}
Always include the render block (the renderer's contract): hasDarkBand, docWidth, heroVisual, webfonts, fonts[], logo{onDark,onLight,lockup}, and the full --brand-* tokens map. Without it the kit is viewable but not renderable into collateral. See Generating collateral from a kit for the field list.
brand-kit.mdHuman-readable spec + usage guide. Sections:
# Brand Kit: <Company> (<domain>)
**Source pages:** <list>
**Generated:** <date>
## Brand at a glance
<2–3 sentences: the visual personality — e.g. "Dark, technical, modern. Mint-on-navy with electric-blue highlights. Tight, confident headings; clean white content sections.">
## Color tokens
<table: token name | hex | role / where used>
## Typography
<heading + body fonts, scale, AND the **emphasis mechanism** — exactly how key words are emphasized (color? weight? size? underline/wash/gradient-text? none?), with light/dark variants. Be explicit so consumers don't bolt on a device the brand doesn't use.>
## Shape & depth
<radius, shadow, spacing rhythm, button anatomy>
## Components
<one line per component on what's distinctive about the brand's version>
## Signature moves
<2–4 things that make output unmistakably this brand — e.g. "highlight one key word per heading in --brand-accent", "dark hero + dark footer bands", "icon tiles in a tinted rounded square">
## Using this kit in other skills
<the consumption guide — see the section below>
Don't ship blind. Render the output and score it against a source screenshot on a fixed rubric — this turns "looks close-ish" into a measurable gate. Applies to BOTH the kit's components.html AND any collateral generated from the kit (two-pagers, case studies, etc.).
1. Render. Use the bundled helper (don't rewrite a screenshot script each time — paths relative to this skill's directory):
python3 scripts/render.py --file <output.html> --out /tmp/out.png
# need a source frame too? python3 scripts/render.py --url https://<domain>/ --out /tmp/src.png
2. Score. View the rendered PNG next to a source screenshot (Step 2) and grade each dimension 0–5 (5 = indistinguishable from the brand). Be a harsh critic — this is the step that catches "AI slop" before the user does.
| # | Dimension | 5 = | Common miss (0–2) | |---|---|---|---| | 1 | Typography | real face + right weight + tracking | fallback font / bold where brand is medium | | 2 | Color/palette | exact hexes in the right roles | approximated or off-role colors | | 3 | Emphasis | brand's actual mechanism (color/weight/size) | a borrowed underline/wash the brand never uses | | 4 | Contrast/legibility | every line ≥ AA on its bg | accent text on a dark band, muddy wash | | 5 | Spacing & padding | airy rhythm; symmetric gutters; floating bands clear of edges on ALL sides | cramped; flush-to-edge band (e.g. footer jammed into the sheet's bottom corner); uneven L/R/top/bottom padding | | 6 | Depth | brand's real treatment (glow/shadow/imagery) | flat rectangles | | 7 | Edges/containers | rounded to the brand's radii | hard full-bleed corners | | 8 | Logo/assets | correct lockup, right brand, right surface | wrong/stale asset, filter-recolored blob, missing |
Report a compact scorecard + an overall /40 (≈ /100), and for every dimension < 4 give a specific fix ("heading rendered in a fallback face — embed the real woff2"; "comparison ✓ uses a mid-tone accent on a dark band — flip to the on-dark variant"). Pass: ≥ 85% (≈ 34/40) AND no dimension below 3. A wrong/missing logo (dim 8 = 0) is an automatic fail regardless of total.
3. Present the scorecard, then ASK the user how to proceed (default behavior — do not silently auto-fix or silently skip). Show the compact scorecard + per-dimension fixes, then offer:
The user can also set a standing preference per run ("always auto-fix", "skip the critique entirely") — honor it for that session. But absent that, ask.
open ~/.octave/brands/<slug>/components.html~/.octave/brands/<slug>/. Other skills can now generate on-brand output for <Company> — or run /octave:get-brand-components show <slug> to view it."The kit is built and reviewed — offer to publish it so it's reachable by link and reusable as a cache by future runs (Step 1.4). If the Octave MCP asset tools aren't available, skip the offer and mention export <slug> as the offline alternative.
Host for the workspace (Recommended) ("teammates can find, open, and reuse it") / Host it (public link) / Not now.../asset-manager/SKILL.md — it owns the token lifecycle and the registry — with these prefills (still user-confirmable per that skill's flow):
<slug>-brand-kit. Description: "Brand component kit for <Company> (<domain>) — design tokens, component gallery, fonts, and logo".--type website --entry-point components.html --status published; --privacy from the choice above (recommend workspace — that is what lets teammates find and reuse the kit instead of rebuilding it; public only when the user wants an open link).screenshots/ rebuild artifacts (keeps the upload well under the size cap):
STAGE="${TMPDIR:-/tmp}/<slug>-brand-kit" && rm -rf "$STAGE" && \
cp -R ~/.octave/brands/<slug> "$STAGE" && rm -rf "$STAGE/screenshots"
then upload the staged folder with zip-and-upload-artifact.sh.update-artifact.sh --uuid <uuid> --src "$STAGE" (full replace) — never create a duplicate. Only possible when the hosted kit is YOURS (owner: "me"); a teammate-owned kit is read-only — publish your own copy.
The entire hosting step is 2 MCP tool calls + the one-line staging + one upload command (see the asset-manager skill's "Exact Publish Sequence"). More shell than that means you're doing it wrong.preview: link for a zero-friction internal open, plus any share URL for people outside the workspace.~/.octave/brands/.manifest.json and show a table: Company | Domain | Pages | Primary color | Generated./octave:get-brand-components <domain> to build one."<slug> (exact then fuzzy match against directory names).brand-kit.md spec and the token summary from manifest.json.open ~/.octave/brands/<slug>/components.html (macOS) so the user sees the gallery.Zip a cached kit so it can be shared / handed to a designer. Self-contained (fonts, logo, components all inline).
<slug> (exact then fuzzy match against ~/.octave/brands/). If missing, offer to build it first.components.html headless to screenshots/components-preview.png (skip if Playwright isn't available).~/Desktop):
cd ~/.octave/brands && rm -f "<dest>/<slug>-brand-kit.zip" && \
zip -r -X "<dest>/<slug>-brand-kit.zip" "<slug>" -x '*.DS_Store'
unzip -l summary of what's inside (tokens.css, components.html, brand-kit.md, manifest.json, logo, fonts/, screenshots/)./octave:asset-manager.<slug>; show the company name from manifest.json.~/.octave/brands/<slug>/? Type 'yes' to confirm."The primary way to turn a kit into an on-brand asset is the bundled renderer — do NOT hand-write per-asset CSS. One engine composes any asset from any kit; the same content spec rendered through a different kit comes out fully on-brand for that brand (validated across multiple brands spanning dark, gradient, and light visual systems).
# scripts/ is relative to this skill's directory
python3 scripts/render_kit.py --kit <slug|path> --spec <content.json> --out <out.html> \
[--kit-dir <path>] [--theme light|dark] [--format doc|og|social-square|social-story|email]
--kit-dir renders a kit stored anywhere (kits don't have to live in ~/.octave/brands/).--theme picks the light or dark palette when the kit carries both (tokensDark/tokensLight).The same kit + spec can render to multiple formats — the brand kit is format-agnostic, so don't rebuild styling per format. --format sets the canvas: doc (default page), og (1200×630 share image), social-square (1080²), social-story (1080×1920), email (600px width). The spec controls content (a short hero/CTA spec makes a clean OG/social image).
Don't generate format variants by default — they cost extra renders and the user usually wants just the doc. After producing the main asset, ask whether they also want any format variants (e.g. an OG image, a square social tile), and only then render them.
scripts/render_kit.py — loads the kit, emits a self-contained HTML doc: <style> = :root{} from manifest.render.tokens + base64 @font-face from manifest.render.fonts + assets/kit_base.css; body = composed blocks; logo/icons inlined.assets/kit_base.css — brand-AGNOSTIC component stylesheet (every rule references a --brand-* token). This is the single source of truth for component CSS — fix a component once here and every asset for every brand inherits it.{ title, blocks: [...] }. Block types: hero, stats, about, quote, section, features, comparison, checklist, cta, footer, plus the imagery/marketing blocks:
split — image-paired feature row: {kicker, heading, paras[], bullets[], image, imageSide: left|right, cta}. The image is a kit-relative path (inlined) or URL; it's framed (rounded + shadow).logos — logo wall: {label, mono: bool, items:[{img}|{text}]}. mono greyscales color logos for a uniform wall.pricing — plan cards: {plans:[{name, price, period, blurb, cta, features[], featured, badge}]}; the featured plan gets the primary border + badge.surface: "dark" to render as a full-bleed dark band (e.g. a logo wall with white logos).**double asterisks**. hero.featured.logoKit pulls another kit's logo (customer logo in a vendor case study).images/ dir (downloaded during the walk) and reference them by relative path; the renderer inlines them as data-URIs (self-contained). Don't fake imagery with gradient placeholders when the real assets exist on the site — extract logo walls and a hero/product shot. (Apply the same logo-verification care: confirm a "customer logo" is real, not a stray asset.) Optional --brand-texture token layers a subtle pattern (dot/grid) onto dark bands.Place a kit's screenshots and logos only where they truthfully illustrate the specific point — never because the kit happens to have them. A product shot dropped into a split whose copy describes something the screenshot doesn't show, or a logo wall stamped onto every doc (including internal ones like battlecards), reads as filler and undercuts the asset.
mono greyscale / hard inversion can erase a logo's identity — only use it when a uniform wall genuinely serves the layout.The test for every image: does it make this exact point clearer, or is it decoration the kit made available? If the latter, cut it. (The earlier "Real imagery" note means don't fake imagery with placeholders — it does not mean force every real asset into every doc.)
manifest.render token contractFor a kit to be renderable it needs a render block in manifest.json:
hasDarkBand (bool — dark hero/footer/CTA vs light), docWidth, heroVisual (chips|masonry|none), webfonts (optional <link> URL for fallback faces)fonts: [{family, weight, style?, file, format}] — base64-embedded so output renders the real facelogo: {onDark, onLight, lockup} — per-surface logos. The renderer picks onDark on dark surfaces and onLight on light ones (this is what prevents white-logo-on-white-footer). lockup = {mark, markFill, wordmark, wordmarkWeight} for brands whose logo is a mark + wordmark.tokens: the --brand-* contract — colors (bg, canvas, surface, surface-dark, ink, muted, faint, on-dark, primary/-ink, link, border, negative, band, glow, tile-bg/-ink/-glow, grad-border), emphasis (emph-ink-light/-dark, emph-underline, emph-weight), type (font-heading/-body, weight-*, tracking-heading, h1/h2), shape (radius-section/-pill, shadow, btn-shadow), and the foundations (shadow-sm/-md/-xl elevation, ease/duration motion, icon-stroke, gray ramp, semantic states, spacing scale, gradients — see Step 4). hero-bg/cta-bg add a light-surface wash; heading-transform forces all-caps.tokensDark / tokensLight (optional): override maps for the opposite theme, merged when --theme is passed.defaultTheme (optional): light | dark.Add render when building a kit (Step 6). The verbose tokens.css + components.html remain the human-readable reference; render is the machine contract the engine consumes.
If a one-off needs a layout the block types don't cover, you can still inline tokens.css + assets/kit_base.css and write markup using the kit_base classes — but prefer adding a block type to the renderer over hand-CSS, so the fix compounds.
Reference token names are brand-agnostic, so the same spec restyles to any captured brand just by swapping --kit.
After producing an asset from a kit, you can run an optional QA pass before delivery — layout, brand adherence, narrative coherence, groundedness, and AI-slop. Offer it; don't force it. The rubric and the slop standard ("write like a human") live in the shared ../shared/asset-review.md, with its generation-time companion ../shared/presentation-principles.md. The key discipline: render the output and inspect the pixels — overflow, misalignment, and white-on-white only show in the render, not the source. (The document skills that consume this kit run this pass automatically.)
~/.octave/brands/<slug>/ automatically if missing.found: false, retry once with the bare apex domain (https://<domain> without www), then ask the user to confirm the URL.brand-kit.md.brand-kit.md.brand-kit.md.development
Turn one or more Octave GTM Explorer / Beats reports into a branded, shareable digest with selectable insight scope, evidence depth, and output format. Use when the user asks for a report digest, weekly or monthly insight recap, executive intelligence brief, magazine-style insight story, report deck, or a recurring published summary of Octave insights.
content-media
Product and feature launch planning with full content kit generation across channels and audiences. Use when user says "launch plan", "product launch", "feature announcement", "GTM plan for launch", "launch content kit", or mentions launching something new.
development
A dense internal deal room a rep hands to a champion so they can run the buying-committee sell without you in the room. Quantified business case, stakeholder map with per-seat ammo, objection handling, and a path to yes, rendered as self-contained HTML. Use when user says "champion deal room", "arm my champion", "help my champion sell internally", "internal business case for [deal]", or wants a champion enablement doc. For a customer-facing top-of-funnel page use /octave:microsite; for the formal closing proposal use /octave:proposal.
data-ai
Analyze email threads, call transcripts, and conversations for resonance, adherence to messaging, and competitive differentiation. Use when user says "analyze this call", "how did the email land", "score this thread", "conversation analysis", or pastes conversation content to evaluate.