PRIMITIVE
Flow
Vertical rhythm between siblings, so you never write a margin again. A step for tight, one for ordinary, one for loose, and nothing in between.
A section
Head, content, note β and not one child carries a margin. The container owns the gap.
Nothing here carries a margin. The container owns the gap.
<div class="flow" style="width:100%">
<div class="section-head">
<span class="section-head-kicker">01 β A SECTION</span>
<span class="section-head-rule"></span>
</div>
<div class="rule-stack rule-stack-on-sunk">
<div class="rule-row rule-row-spec"><span class="rule-row-key">STEP</span><span class="rule-row-value">--ds-flow</span></div>
<div class="rule-row rule-row-spec"><span class="rule-row-key">BETWEEN</span><span class="rule-row-value">every sibling</span></div>
</div>
<p class="placeholder-caption">Nothing here carries a margin. The container owns the gap.</p>
</div>The steps
<div class="flow flow-tight" style="width:100%">
<span class="section-head-kicker section-head-kicker-quiet">FLOW-TIGHT Β· 24px</span>
<div class="placeholder" style="--ratio:8/1"><span class="placeholder-note">blocks that belong to each other</span></div>
<div class="placeholder" style="--ratio:8/1"><span class="placeholder-note">β¦</span></div>
</div>
<div class="flow" style="width:100%">
<span class="section-head-kicker section-head-kicker-quiet">FLOW Β· the default step</span>
<div class="placeholder" style="--ratio:8/1"><span class="placeholder-note">a section head to its content</span></div>
<div class="placeholder" style="--ratio:8/1"><span class="placeholder-note">β¦</span></div>
</div>
<div class="flow flow-loose" style="width:100%">
<span class="section-head-kicker section-head-kicker-quiet">FLOW-LOOSE Β· the larger break</span>
<div class="placeholder" style="--ratio:8/1"><span class="placeholder-note">two ideas in one section</span></div>
<div class="placeholder" style="--ratio:8/1"><span class="placeholder-note">β¦</span></div>
</div>Reference
Read from primitives/flow.css when this page was built, so it cannot fall behind the stylesheet.
.flow.flow-tight.flow-loose--flow β falls back to --ds-flow--ds-flow-loose--ds-flow-tightNotes
Before it did, one page built on this system had grown five spellings of one gap β 24, 32, 36, 44 and 56 pixels β each a guess made at the moment it was needed. That is what a system without a named rhythm produces, however careful the person writing it.
The steps are measured off the source design rather than invented. It puts 44px after a section head twenty times and 56px before a larger break seventeen more. That is a rhythm, not a mood, and it transfers.
A margin collapses, needs a :first-child exception, and doubles up where two spaced blocks meet. A gap does none of that β and a block moved to the top of a stack stops having a top margin without anybody editing it.
Use .flow-tight or .flow-loose. For a one-off, set the variable on the container β style="--flow: β¦" β never a margin on a child. That is the only sanctioned override; a consuming site is where it can be enforced, and a check there should refuse the alternative.