OpenAI dotcom flow / process diagrams
The process diagrams in OpenAI posts (e.g. the "Quality assurance pipeline") are hand-arranged, not generated by a library. So this skill gives you the primitives and the look, and you assemble the layout for the specific diagram. Layout is deliberately manual — branching, alignment, and grouping are judgement calls that a generic auto-layout gets wrong.
Include assets/openai-figure.css, wrap everything in <div class="oai-figure">,
and drop in the arrow marker defs once. assets/flow-example.html is a complete,
working pipeline you can copy and edit.
Primitives (from openai-figure.css)
.box+.box-title— an outer stage box with a bold title..subbox— an inner step box (plain sentence-case text)..pill— a monospace UPPERCASE label (inputs, states, outputs). Text is uppercased by CSS, so write it normally; use\nin the text for a line break (the pill preserves newlines)..pill.accent— solid pink highlight (e.g. a "flagged" state)..pill.dotted— stippled pink variant (used to distinguish a parallel branch's outputs).- Layout:
.flow(horizontal row of stages),.col,.rows,.stack,.inline,.conn(a connector column),.scroller(wrap a wide diagram).
Arrows — the ---> open chevron
Every connector ends in a thin open chevron (a drawn >, never a filled
triangle). Define the marker once, then reference it with marker-end:
<svg width="0" height="0" style="position:absolute" aria-hidden="true"><defs>
<marker id="oai-arrow" markerUnits="userSpaceOnUse" markerWidth="13" markerHeight="13"
refX="9.5" refY="6" orient="auto-start-reverse">
<path d="M3 2 L9 6 L3 10" fill="none" stroke="var(--line)" stroke-width="1.5"
stroke-linecap="round" stroke-linejoin="round"/>
</marker>
</defs></svg>A straight arrow is then just a line whose end carries the marker:
<svg width="26" height="20" style="overflow:visible">
<line x1="0" y1="10" x2="18" y2="10" stroke="var(--line)" stroke-width="1.5"
marker-end="url(#oai-arrow)"/>
</svg>- Keep
overflow:visibleon inline arrow SVGs so the chevron isn't clipped. - A negative / "did not happen" branch uses a dashed shaft — add
stroke-dasharray="3 3"(the chevron itself stays solid, giving- - ->). stroke="var(--line)"in the marker makes the head inherit the near-black ink.
Connectors with rounded corners
When a connector turns a corner (e.g. a trunk that branches up and down into two
stages), round the bend with a quarter-circle (Q), radius ≈ 10. Draw each arm
as its own path so marker-end orients correctly. The connector SVG is absolutely
positioned over a .conn column (see the CSS) with a tall viewBox:
<div class="conn" style="flex:0 0 64px">
<svg viewBox="0 0 64 360" preserveAspectRatio="xMidYMid meet" height="360">
<g stroke="var(--line)" stroke-width="1.5" fill="none" stroke-linecap="round">
<path d="M2 180 H30"/> <!-- incoming stub -->
<path d="M30 180 V106 Q30 96 40 96 H56" marker-end="url(#oai-arrow)"/> <!-- up, round, right -->
<path d="M30 180 V254 Q30 264 40 264 H56" marker-end="url(#oai-arrow)"/> <!-- down, round, right -->
</g>
</svg>
</div>The recipe for one rounded arm: V <corner ∓ r> to approach the corner, then
Q <cornerX> <cornerY> <cornerX ± r> <cornerY> to sweep the quarter turn, then
H <end> to the arrowhead. Straight (non-branching) connectors are just a
<line marker-end>.
Layout approach
Model the diagram as a horizontal .flow of alternating stage columns and
connector columns:
[ Stage 1 box ] [.conn] [ Stage 2 / Stage 3 boxes ] [.conn] [ Output boxes ]- Give stage
.cols explicitflex:0 0 <width>so columns don't jostle. - Vertically center with
align-items:centeron.flow; the.connSVG overlays stretch to full height, so draw arm endpoints at the y-positions of the boxes they point into (measure once in the rendered output and adjust). - Wrap the whole
.flowin.scrollerif it's wider than the page. - Align first-column pill inputs → an "engine" box → output pills using
.inlinewith short arrow SVGs between them (see flow-example.html).
Gotcha
Do not put a literal ---> inside an HTML comment — the --> inside it
closes the comment early and leaks text onto the page. Write "open chevron"
instead.