| name | doc-conventions |
| description | Reference guide for Harness 3.0 documentation site conventions, component patterns, and styling rules. Auto-invoked when working on documentation pages, editing components in docs/pages/, or modifying docs-data.ts. Use explicitly to look up the correct pattern for a specific UI element. |
| argument-hint | ["component-name"] |
Harness 3.0 Documentation Conventions
Quick reference for all component patterns and conventions used in the documentation site. If $ARGUMENTS is provided, focus on that specific component or pattern.
Typography scale
| Element | Classes |
|---|
| Page h1 | text-3xl font-bold tracking-tight text-foreground lg:text-4xl |
| Section h2 | text-xl font-semibold text-foreground |
| Subsection h3 | text-base font-semibold text-foreground (with mt-6) |
| Body text | text-sm leading-relaxed text-muted-foreground |
| Page description | text-base leading-relaxed text-muted-foreground lg:text-lg |
Page structure
Every page follows this skeleton:
<div className="space-y-0">
<header id="overview" className="mt-6 scroll-mt-20">
Badge + Clock + date
h1 title
p description
</header>
<Separator className="my-8" />
<section id="..." className="scroll-mt-20">
h2 + content
</section>
<Separator className="my-8" />
...more sections...
</div>
Rules:
- Root div:
className="space-y-0"
- Header:
id="overview" with mt-6 scroll-mt-20
- Every section: must have
id + scroll-mt-20
- Separators:
<Separator className="my-8" /> between every section
- Props interface:
{ onNavigate?: (section: string, item: string) => void }
Component patterns
CodeBlock
<CodeBlock
code={`yaml or code content`}
language="yaml"
filename="pipeline.yaml"
showLineNumbers={true}
highlightLines={[2, 5]}
className="mt-4"
/>
Side-by-side comparison:
<div className="mt-5 grid gap-4 lg:grid-cols-2">
<CodeBlock code={`...`} language="yaml" filename="before.yaml" />
<CodeBlock code={`...`} language="yaml" filename="after.yaml" />
</div>
Callout
<Callout type="info" title="Title" className="mt-4">
Content with <code className="rounded bg-muted px-1 py-0.5 text-xs">inline code</code>.
</Callout>
Types and their colors:
info — blue, Info icon — general information
warning — orange, AlertTriangle icon — caution/important
tip — yellow, Lightbulb icon — helpful tip
success — green, CheckCircle icon — positive outcome
Tables
<div className="mt-4 overflow-x-auto">
<table className="w-full text-sm">
<thead>
<tr className="border-b border-border">
<th className="px-3 py-2 text-left font-semibold text-foreground">Header</th>
</tr>
</thead>
<tbody className="text-muted-foreground">
<tr className="border-b border-border">
<td className="px-3 py-2 font-medium text-foreground">Label</td>
<td className="px-3 py-2">Value</td>
</tr>
</tbody>
</table>
</div>
For repetitive tables, define a local sub-component in the same file:
function MyTable({ rows }: { rows: Array<{ label: string; value: string }> }) {
return (
<div className="mt-4 overflow-x-auto">
<table className="w-full text-sm">...</table>
</div>
)
}
Bullet lists
<ul className="mt-2 space-y-1.5 text-sm text-muted-foreground">
<li className="flex items-start gap-2">
<span className="mt-1.5 h-1.5 w-1.5 shrink-0 rounded-full bg-primary" />
Item text
</li>
</ul>
Numbered step cards
<div className="rounded-lg border border-border bg-card p-4">
<div className="flex items-center gap-3">
<span className="flex h-7 w-7 shrink-0 items-center justify-center rounded-full bg-primary text-xs font-bold text-primary-foreground">1</span>
<h3 className="text-sm font-semibold text-foreground">Step Title</h3>
</div>
<p className="mt-2 pl-10 text-sm text-muted-foreground">Step description.</p>
</div>
Inline code
<code className="rounded bg-muted px-1.5 py-0.5 text-xs font-mono text-foreground">text</code>
Cross-page navigation
<span
className="cursor-pointer text-primary hover:underline"
onClick={() => onNavigate?.("section-slug", "page-slug")}
>
Link text
</span>
For cards:
<div className="cursor-pointer" onClick={() => onNavigate?.("section-slug", "page-slug")}>
<QuickLinkCard title="..." description="..." />
</div>
External links
<a href="https://..." target="_blank" rel="noopener noreferrer"
className="inline-flex items-center gap-1 text-primary hover:underline">
Link text <ExternalLink className="h-3 w-3" />
</a>
Stat cards (grid)
<div className="mt-6 grid grid-cols-2 gap-4 sm:grid-cols-4">
<div className="rounded-lg border border-border bg-card p-4 text-center">
<div className="text-2xl font-bold text-primary">100+</div>
<div className="mt-1 text-xs text-muted-foreground">Description</div>
</div>
</div>
Badge conventions
In doc item registrations:
"new" — bg-accent text-accent-foreground
"beta" — bg-primary/15 text-primary
"updated" — bg-chart-4/15 text-chart-4
"coming-soon" — bg-muted text-muted-foreground
In page headers, use <Badge variant="secondary"> for the section category.
YAML v1 pipeline schema
All Harness pipeline YAML examples MUST use v1 format:
pipeline:
name: Deploy App
stages:
- name: Deploy to Dev
type: deploy
service: my_service
environment:
name: dev
deploy-to: k8s_dev
steps:
- name: Rolling Deploy
with:
skip_dry_run: false
Rules:
- No
projectIdentifier, orgIdentifier, identifier — inferred from context
- Flat stage types:
type: deploy or type: ci (NOT type: Deployment)
- Steps use
with: (NOT spec:)
service and environment are top-level stage fields (NOT serviceRef/environmentRef)
- Expression syntax:
${{ expression }} with snake_case (NOT <+expression> with camelCase)
File naming
- Page files:
components/docs/pages/<slug>.tsx
- Export name: PascalCase of slug + "Page" (e.g.,
ci-steps → CiStepsPage)
- Exception: if slug conflicts with reserved names, append
-page to filename (e.g., settings → settings-page.tsx)
Import conventions
Only import what you use. Common imports:
import { Separator } from "@/components/ui/separator"
import { CodeBlock } from "@/components/docs/code-block"
import { Callout } from "@/components/docs/callout"
import { Badge } from "@/components/ui/badge"
import { Clock } from "lucide-react"