field-notebook-ui
Skill2 starsChanged 3 months agoMITView on GitHub
Use when a UI, explainer, dashboard, diagram or artifact should carry this repo's engineer's field-notebook look — warm stone-paper, hand-annotated margins, graph-paper grid. Trigger on: "field-notebook style", "warm stone-paper aesthetic", "the usual notebook look", or a second artifact that must match one already built in this style. Not for a generic UI with no stated aesthetic.
In this repository46 other files it gives its agents.
- AGENTS.mdAGENTS.md
- CLAUDE.mdCLAUDE.md
- .cursor/rules/commit-conventions.mdcCursor rule
- .cursor/rules/cross-platform-handoff.mdcCursor rule
- .cursor/rules/dev-files-workspace.mdcCursor rule
- .cursor/rules/documentation-standards.mdcCursor rule
- .cursor/rules/gh-cli-preference.mdcCursor rule
- .cursor/rules/github-repository-policy.mdcCursor rule
- .cursor/rules/git-worktree-agent-workflow.mdcCursor rule
- .cursor/rules/hooks-guide.mdcCursor rule
- .cursor/rules/plugin-structure.mdcCursor rule
- .cursor/rules/plugin-version-bump.mdcCursor rule
- .cursor/rules/skill-frontmatter.mdcCursor rule
- .cursor/rules/skill-quality-standards.mdcCursor rule
- .cursor/rules/skills-guide.mdcCursor rule
- .cursor/rules/user-facing-script-standards.mdcCursor rule
- run-tamirs-superpowersSkill
- diagnose-refusalSkill
- targeted-debugSkill
- decisionSkill
- deliver-devSkill
- diagnose-objectiveSkill
- orchestrate-devSkill
- plan-devSkill
- pr-devSkill
- start-devSkill
- switch-devSkill
- worker-devSkill
- changelog-reviewSkill
- dark-terminal-docSkill
- docs-reviewSkill
- platform-syncSkill
- mcp-builderSkill
- mcp-paginationSkill
- cleanupSkill
- github-policySkill
- multi-agent-repoSkill
- repo-scaffoldSkill
- repo-standardsSkill
- capture-configSkill
- find-skillSkill
- notify-setupSkill
- retroSkill
- session-reportSkill
- skill-creatorSkill
- usage-captureSkill
The file
Show its rules and text
We split this skill into the rules it gives an agent
21 rules. About 0 are common, 15 are distinctive, and 6 are very specific to this project.
≈0
Common · estimate
Many files like this have a rule of this kind.
≈15
Distinctive · estimate
This author's own choices. Worth a look.
6
Very specific
Tied to their project's names, files or tools. Probably skip.
- Common
- Distinctive
- Very specific
- Distinctive: line 53
Every artifact you produce using this skill must feel like a page from a physical technical notebook — structured, readable, purposeful — …
- Very specific: line 105
Always load via Google Fonts in a useEffect:
- Distinctive: line 118
Every section opens with a spaced uppercase mono eyebrow, then a sentence-case Space Grotesk heading.
- Very specific: line 272
Use for timeline steps, glossary terms, layered diagrams.
- Very specific: line 289
All interactive elements: transition: "background 0.15s, color 0.15s, border-color 0.15s".
- Distinctive: line 294
Every interactive element must have visible focus.
- Very specific: line 314
Add className="nb-focus" to every <button>.
- Distinctive: line 326
Use JetBrains Mono uppercase.
- Distinctive: line 352
Never use an accent purely decoratively.
- Distinctive: line 358
No drop shadows (not in the field-notebook aesthetic)
- Distinctive: line 359
No gradients on surfaces (the paper is flat)
- Distinctive: line 360
No emoji in content
- Distinctive: line 361
No bold text inside prose (use Space Grotesk headings instead)
- Very specific: line 362
No dark backgrounds, dark cards, or inverted panels — with one exception: a diagram inside the artifact is a Mermaid block using the dark …
- Distinctive: line 363
No generic sans-serif fallback without Space Grotesk / Inter loaded
- Distinctive: line 364
Do not use more than 3 accent colors in a single view
- Distinctive: line 365
Do not put the AirGap on more than 1–2 places per tab — it is a signature, not a pattern
- Distinctive: line 371
Read the user's prompt and identify: content domain, data shape, interaction model needed
- Very specific: line 377
Every interactive element gets className="nb-focus" and transition: "...
- Distinctive: line 397
Use Mode A when all of these hold:
- Distinctive: line 435
Write the complete file with the Write tool.
≈ “Common” is an estimate: at least 1 in 5 of the 350,495 skill files we read have a rule of the same kind, not the same words. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.
Files
Field-Notebook UI Skill
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.
Design token system
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",
};Typography
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);
}, []);Eyebrow pattern
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>Core components
Card with colored left border
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>
);
}AirGap — the signature element
A dashed enclosure with a small corner label. Use this for project-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>
);
}Code block
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>
);
}Tab button
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>
);
}Interaction patterns
Click-to-expand
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>}Hover transitions
All interactive elements: transition: "background 0.15s, color 0.15s, border-color 0.15s".
Nothing else. No transforms, no shadows on hover.
Keyboard focus
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>.
Layout rules
Header — always present. Contains:
- Eyebrow:
CONTEXT · DOMAIN(e.g.,SYSTEM DESIGN PREP · INFRASTRUCTURE) - H1 in Space Grotesk 700, sentence case
- Subtitle in Inter 13px, T.inkDim
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.
Semantic accent assignment
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.
What to avoid
- No drop shadows (not in the field-notebook aesthetic)
- No gradients on surfaces (the paper is flat)
- No emoji in content
- No bold text inside prose (use Space Grotesk headings instead)
- No dark backgrounds, dark cards, or inverted panels — with one exception: a diagram inside the artifact is a Mermaid block using the dark palette from
config/docs/mermaid-init.txt(rules/dev/documentation-standards.md), unless the user asks for another palette for this artifact - No generic sans-serif fallback without Space Grotesk / Inter loaded
- Do not use more than 3 accent colors in a single view
- Do not put the AirGap on more than 1–2 places per tab — it is a signature, not a pattern
Process for generating an artifact
- Read the user's prompt and identify: content domain, data shape, interaction model needed
- Choose which tabs / sections the artifact needs
- Assign semantic accents to content types (2–3 max per view)
- Decide where the AirGap annotation belongs (one key insight per tab)
- Build the artifact following the token system, components, and layout rules above
- Inject fonts and global CSS at mount (
useEffectin Mode A, a<style>block in Mode B) — always with a system-font fallback stack - Every interactive element gets
className="nb-focus"andtransition: "... 0.15s"
The output is self-contained: all tokens, components and styles defined inline, no external imports beyond the UI runtime itself.
Output delivery — pick the target before you write a line
The design system above is fully portable — tokens, spacing, type scale, components and layout rules are plain CSS values and carry to any target unchanged. What is not portable is the container the design ships in. Choose it deliberately.
Mode A — React component (.jsx)
A bare .jsx file with import { useState } from "react" and a default export is not a
runnable program. It runs only where a host supplies the React runtime and renders the
component for you — Claude Artifacts and Claude Desktop do this; a plain browser, a terminal
agent, and a repo with no bundler do not.
Use Mode A when all of these hold:
- the
artifactscapability is available on the current platform (core/capabilities/platforms.json), or the user has an existing React project to drop the component into; and - the user asked for a React component, or the destination is a React codebase.
Mode B — single-file HTML (.html) — the portable default
One .html file with inline <style> and inline <script>, opened directly from
file://. No build step, no bundler, no runtime supplied by a host. This is what you produce
whenever Mode A's conditions are not met — which includes every platform whose artifacts
capability is unsupported or unknown.
Mode B carries the identical design system. Translate the components the obvious way: the
token object becomes CSS custom properties on :root, useState becomes a small amount of
vanilla JS, tab switching becomes class toggling. Nothing in the aesthetic is lost.
Never do this
- Never emit a bare
.jsxon a platform with no React runtime and describe it as finished. That hands the user a file they cannot open. If you are unsure whether the host renders React, produce Mode B — it works everywhere, including inside a React host. - Never claim the output "will render as an artifact" unless the
artifactscapability is actually present. State which mode you produced and what is needed to view it. - Never require a build step, package install, or dev server in either mode.
Fonts and network
The template injects Google Fonts. That is a view-time network dependency, and it fails
offline and under a strict Content-Security-Policy. Always declare a real fallback stack —
'Space Grotesk', system-ui, sans-serif and 'Inter', system-ui, sans-serif — so the page
degrades to system faces rather than to a broken layout. Fonts are the only permitted remote
asset; everything else is inline.
Steps (both modes)
- Derive a short snake_case filename from the user's request (e.g.
helm_explainer,k8s_glossary) and append.jsx(Mode A) or.html(Mode B). - Write the complete file with the Write tool.
- Report the file path, the mode you chose, and why — plus how to view it.
Never paste the source into the conversation as the deliverable. The file is the deliverable, in both modes.
Quick-reference template
Mode A (React). For Mode B, the same structure with CSS custom properties on :root
and vanilla JS for the tab state — the tokens, components and layout rules are unchanged.
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', system-ui, sans-serif" }}>
{/* Header */}
<header style={{ padding: "20px 28px 16px", borderBottom: `1px solid ${T.rule}` }}>
<Eyebrow>context · domain</Eyebrow>
<h1 style={{ fontFamily: "'Space Grotesk', system-ui, 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>
);
}Does it work?
Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.
No reviews yet
People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.
- It worked
- Partly
- It didn't
Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.
Your trail
Files you open will collect here, so you can find them again.
Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.
Now do this for your own.
Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.

