From Tamir's Superpowers
Use when the user asks to build a UI, interactive explainer, dashboard, visualizer, diagram, reference tool, or any artifact that needs a consistent visual design system in the "engineer's field-notebook" aesthetic. Trigger on: "build a UI for", "create an interactive", "make a visualizer", "generate an artifact", "design a component", "create a dashboard", "make an explainer", or any request to produce a React/HTML artifact with content to display. Also trigger when the user says "make it look like the field-notebook style" or references the warm stone-paper aesthetic.
How this skill is triggered — by the user, by Claude, or both
Slash command
/tamirs-superpowers:field-notebook-ui [what to build — e.g. "k8s glossary", "helm explainer", "auth flow diagram"]When to use
User says: "build a UI for X", "create an interactive explainer", "make a visualizer", "generate a React artifact", "design a dashboard", "create a reference tool", "make it look like the field-notebook style", "use the warm stone-paper aesthetic", or asks for any interactive component that should share a coherent design language without re-specifying the token system each time.
[what to build — e.g. "k8s glossary", "helm explainer", "auth flow diagram"]claude-sonnet-4-6bashThis skill is limited to the following tools:
The summary Claude sees in its skill listing — used to decide when to auto-load this skill
Generates React artifacts in a warm "engineer's field-notebook" visual system.
Generates React artifacts in a warm "engineer's field-notebook" visual system. Every artifact you produce using this skill must feel like a page from a physical technical notebook — structured, readable, purposeful — translated to an interactive screen.
Copy these tokens verbatim into every artifact. Never invent replacements.
const T = {
// Backgrounds
bg: "#ECE9DF", // stone-paper — the page itself
surface: "#E5E1D5", // slightly darker for cards / panels
surfaceB: "#DDD9CC", // code block background
// Text
ink: "#172423", // petrol-black — primary text
inkMid: "#3D4F4E", // secondary text
inkDim: "#6E7D7C", // captions, placeholders
rule: "#C8C3B4", // dividers, borders
ruleHair: "#B8B2A2", // hairline card borders
// Primary
green: "#0F6E56", // petrol-green — primary actions, success, structural
greenFill: "#0F6E5612", // low-alpha fill
greenBg: "#0F6E5620",
// Semantic accents (use 2–3 per view, never all at once)
rust: "#B94A2C", // errors, rollback, danger
rustFill: "#B94A2C14",
amber: "#C17D11", // warnings, overrides, caution
amberFill: "#C17D1114",
purple: "#5B3F8C", // model, template, AI concepts
purpleFill:"#5B3F8C12",
blue: "#1B5FA8", // agent, commands, informational
blueFill: "#1B5FA812",
};
Three fonts, three distinct roles. Never swap them.
| Role | Font | Usage |
|---|---|---|
| Display | Space Grotesk | Headings, labels on cards, tab names |
| Body | Inter | Prose, descriptions, detail text |
| Mono | JetBrains Mono | Eyebrows, code, technical labels, metadata |
Always load via Google Fonts in a useEffect:
useEffect(() => {
const link = document.createElement("link");
link.rel = "stylesheet";
link.href = "https://fonts.googleapis.com/css2?family=Space+Grotesk:wght@400;500;600;700&family=Inter:wght@400;500;600&family=JetBrains+Mono:wght@400;500;700&display=swap";
document.head.appendChild(link);
}, []);
Every section opens with a spaced uppercase mono eyebrow, then a sentence-case Space Grotesk heading.
// Eyebrow component
function Eyebrow({ children, color = T.green }) {
return (
<div style={{
fontFamily: "'JetBrains Mono', monospace",
fontSize: "9px",
fontWeight: 700,
letterSpacing: "2.5px",
textTransform: "uppercase",
color,
marginBottom: "5px",
}}>
{children}
</div>
);
}
// Usage: always eyebrow THEN heading
<Eyebrow>Chart structure</Eyebrow>
<h2 style={{ fontFamily: "'Space Grotesk', sans-serif", fontWeight: 600, fontSize: "16px" }}>
File anatomy
</h2>
The standard content container. Hairline border, soft radius (0 on left to meet the accent stripe).
function Card({ accent = T.green, fill, children, style = {} }) {
return (
<div style={{
background: fill || T.surface,
border: `1px solid ${T.ruleHair}`,
borderLeft: `3px solid ${accent}`,
borderRadius: "0 6px 6px 0",
padding: "12px 14px",
...style,
}}>
{children}
</div>
);
}
A dashed enclosure with a small corner label. Use this for Paragon-specific context, important notes, security warnings, or any annotation that must stand apart. This is the single most distinctive element of the design — use it deliberately, not on every card.
function AirGap({ label = "note", children }) {
return (
<div style={{
position: "relative",
border: `1.5px dashed ${T.green}`,
borderRadius: "6px",
padding: "18px 16px 14px",
marginTop: "20px",
}}>
<div style={{
position: "absolute",
top: "-9px",
left: "12px",
background: T.bg,
padding: "0 6px",
fontFamily: "'JetBrains Mono', monospace",
fontSize: "8px",
fontWeight: 700,
letterSpacing: "2px",
textTransform: "uppercase",
color: T.green,
}}>
╴{label}╶
</div>
<div style={{ fontFamily: "'Inter', sans-serif", fontSize: "12px", color: T.inkMid, lineHeight: "1.8" }}>
{children}
</div>
</div>
);
}
Left accent border in the relevant semantic color. Mono font, surfaceB background.
function CodeBlock({ children, accent = T.blue }) {
return (
<div style={{
background: T.surfaceB,
border: `1px solid ${T.rule}`,
borderLeft: `3px solid ${accent}`,
borderRadius: "0 5px 5px 0",
padding: "12px 14px",
overflowX: "auto",
}}>
<pre style={{
fontFamily: "'JetBrains Mono', monospace",
fontSize: "11px",
lineHeight: "1.8",
color: T.inkMid,
whiteSpace: "pre",
margin: 0,
}}>
{children}
</pre>
</div>
);
}
Active state: green background, white text. Inactive: transparent, dimmed mono label.
function TabBtn({ active, onClick, children }) {
return (
<button onClick={onClick} style={{
fontFamily: "'JetBrains Mono', monospace",
fontSize: "10px",
fontWeight: active ? 700 : 500,
letterSpacing: "1px",
textTransform: "uppercase",
padding: "7px 16px",
background: active ? T.green : "transparent",
color: active ? "#fff" : T.inkDim,
border: `1px solid ${active ? T.green : T.rule}`,
borderRadius: "4px",
cursor: "pointer",
transition: "background 0.15s, color 0.15s, border-color 0.15s",
}}>
{children}
</button>
);
}
Use for timeline steps, glossary terms, layered diagrams. Always show a ▼/▲ indicator.
Manage state with useState({}) keyed by item id.
const [expanded, setExpanded] = useState({});
const toggle = (id) => setExpanded(p => ({ ...p, [id]: !p[id] }));
// In render:
<button onClick={() => toggle(item.id)} style={{ /* card styles */ }}>
<span>{item.title}</span>
{item.hasDetail && <span>{expanded[item.id] ? "▲" : "▼"}</span>}
</button>
{expanded[item.id] && <div>{item.detail}</div>}
All interactive elements: transition: "background 0.15s, color 0.15s, border-color 0.15s".
Nothing else. No transforms, no shadows on hover.
Every interactive element must have visible focus. Inject once via a style tag:
useEffect(() => {
const style = document.createElement("style");
style.textContent = `
.nb-focus:focus-visible {
outline: 2px solid ${T.green};
outline-offset: 2px;
border-radius: 3px;
}
@media (prefers-reduced-motion: reduce) {
* { transition: none !important; }
}
`;
document.head.appendChild(style);
return () => style.remove();
}, []);
Add className="nb-focus" to every <button>.
Header — always present. Contains:
CONTEXT · DOMAIN (e.g., PARAGON INTERVIEW PREP · INFRASTRUCTURE)Tabs — horizontal pill row below header when content has multiple views. Use JetBrains Mono uppercase. Gap: 8px. Wrap on narrow viewports.
Two-column layout — nav/list on left (fixed ~200–260px), detail on right (flex: 1).
Both panels scroll independently. Left panel: background T.bg, right: T.bg.
Divider: 1px solid T.rule.
Single-column — max-width 760px for prose-heavy content. Padding 28px.
Footer / status bar — optional single-line summary at bottom. T.surface background, mono text, T.inkDim color.
Pick 2–3 accents per artifact based on what they encode. Be consistent within one artifact.
| Concept type | Accent |
|---|---|
| Success, primary action, structural | green |
| Error, danger, rollback, removal | rust |
| Warning, override, caution, change | amber |
| AI model, template, generative | purple |
| Command, agent, informational, link | blue |
| Neutral, disabled, secondary | inkDim |
Never use an accent purely decoratively. It must encode meaning.
useEffect at component mountclassName="nb-focus" and transition: "... 0.15s"The artifact must be a self-contained React component with a default export. All tokens, components, and styles are defined inline — no external imports beyond React.
Always write the artifact to a .jsx file. Never output it inline in chat.
Steps:
helm_explainer.jsx, k8s_glossary.jsx).jsx file using the Write toolDo not paste the JSX into the conversation. Do not use a code block as the deliverable. The file is the deliverable.
import { useState, useEffect } from "react";
const T = { /* paste token block here */ };
export default function App() {
const [tab, setTab] = useState("overview");
useEffect(() => {
// Inject fonts + global CSS (focus ring, reduced-motion)
}, []);
return (
<div style={{ background: T.bg, minHeight: "100vh", color: T.ink,
fontFamily: "'Inter', sans-serif" }}>
{/* Header */}
<header style={{ padding: "20px 28px 16px", borderBottom: `1px solid ${T.rule}` }}>
<Eyebrow>context · domain</Eyebrow>
<h1 style={{ fontFamily: "'Space Grotesk', sans-serif", fontSize: "22px",
fontWeight: 700, color: T.ink }}>
Artifact title
</h1>
</header>
{/* Tabs */}
<div style={{ display: "flex", gap: "8px", padding: "14px 28px",
borderBottom: `1px solid ${T.rule}`, flexWrap: "wrap" }}>
{["Overview", "Detail", "Reference"].map(t => (
<TabBtn key={t} active={tab === t.toLowerCase()} onClick={() => setTab(t.toLowerCase())}>
{t}
</TabBtn>
))}
</div>
{/* Content */}
<main style={{ padding: "24px 28px", maxWidth: "760px" }}>
{/* Cards, AirGap, CodeBlocks here */}
</main>
</div>
);
}
npx claudepluginhub tamircohen28/plugins --plugin tamirs-superpowersCreates bite-sized, testable implementation plans from specs or requirements, with file structure and task decomposition. Activates before coding multi-step tasks.