Install
openclaw skills install @monikazapisekstudio/vertical-spacingUse when computing or fixing vertical spacing (margins, padding, Auto Layout gap) between text blocks or components against a grid base, accounting for vertical-trim state on any text layers involved.
openclaw skills install @monikazapisekstudio/vertical-spacingCompute vertical spacing (margin, padding, Auto Layout gap) as clean multiples of a grid base, applying the proximity rule (elements that relate should sit closer together than elements that don't), and correcting for vertical-trim state so the optical gap matches the set gap.
text-typesetting) or column width (line-length-optimizer).grid-base: default 8px (or 4px for denser UI); confirm which the project uses rather than assuming.component-type: card / page section / article / form.hierarchy-level: compact / standard / spacious.base-line-height (LH): the resolved line-height of the body text in the flow — required for Workflow step 5 (paragraph/list rhythm), since those gaps are defined as a fraction of it, not as fixed pixel values.textLeadingTrim state of any text layers inside the frame.grid-base (e.g. 8, 16, 24, 32, 48, 64, 96).gap, margin) or Tailwind utility classes, matching whichever convention the project already uses.paragraphSpacing, list-to-paragraph gap, and list-item gap, each shown as both the LH-fraction formula and the resulting pixel value (see Workflow step 5).Snap every value to grid-base. Reject or round any spacing value that isn't a clean multiple — flag existing off-grid values found in input CSS rather than silently leaving them.
Apply the proximity rule. Spacing above a heading (separating it from the previous, unrelated block) should be noticeably larger — roughly 2–3× — than the spacing below it (to the body text it introduces). E.g. margin-top: 48px / margin-bottom: 16px on a heading, not symmetric values on both sides.
Vertical-trim correction (critical when text is involved):
gap/margin value, because the font's built-in leading eats into it — e.g. a set gap: 16px optically reads as ~11px. Either compensate by increasing the set value, or (preferred) recommend turning vertical-trim on for those text layers so the set value and the optical value match exactly.Report, don't silently rewrite a stylesheet or Figma frame unless asked to apply directly.
Paragraph and list rhythm — all derived from LH (body text line-height), not fixed pixel guesses:
| Relationship | Formula | Example (LH = 24px) |
|---|---|---|
Between paragraphs (paragraphSpacing) | 0.50–0.75 × LH | 12–16px |
| Between a list block and the surrounding paragraph (before and after) | same as paragraphSpacing — treat the whole list as one paragraph-equivalent unit | 12–16px |
Between items inside one list (List_Item_To_Item_Gap) | 0.25–0.33 × LH — deliberately tighter than paragraphSpacing, so the list reads as one cohesive block (Gestalt proximity) rather than a series of unrelated paragraphs | 6–8px |
| Bullet/number to item text (horizontal indent) | fixed optical distance, not an LH fraction — one grid-base step or 1ch (the width of a "0" in the running font), whichever the project's existing spacing convention prefers | 8px |
paragraphSpacing and first-line paragraph indent (1em text-indent) together — pick one convention per project. If the input already shows one in use, match it rather than introducing the other.LH-fraction results to grid-base (step 1) where the two don't conflict; if grid-base and the LH-fraction range don't intersect cleanly (e.g. LH = 22px → 0.5–0.75× = 11–16.5px, and grid-base = 8 only offers 8 or 16), prefer the value inside the LH-fraction range over forcing a grid-base multiple — state which constraint won when they conflict, rather than silently picking one.text-typesetting's line-height output — if base-line-height isn't given, ask for it or compute it via that skill first rather than guessing a round number.Figma margin-collapse guard (a real Figma-specific gotcha, not a CSS concept): Figma's TextNode.paragraphSpacing only adds space below a paragraph, not above the next one — there's no browser-style margin-collapse behavior reconciling two adjacent blocks' spacing. If a heading node (H2, say) directly follows a paragraph node, the paragraph's paragraphSpacing alone is usually too small a gap above a heading (it was sized for paragraph-to-paragraph rhythm, not paragraph-to-heading), and the heading will visually "stick" to the text above it.
paragraphSpacing for this transition. Explicitly override the space above the heading — either via the parent Auto Layout frame's itemSpacing for that specific gap (if using per-item spacing / itemReverseZIndex gap overrides), or by giving the heading node its own leading space, sized to:
Margin_top_heading = 1.5 × LH_body
When running with Figma access, work against the selected FrameNode:
layoutMode (must be VERTICAL or HORIZONTAL — if NONE, this isn't an Auto Layout frame and gap/padding don't apply the same way; report that first), itemSpacing (= gap), paddingTop/paddingBottom/paddingLeft/paddingRight.textLeadingTrim on any child TextNodes — this is the input to Workflow step 3. Don't compute a spacing verdict for a frame containing text without checking it.TextNode.paragraphSpacing and TextNode.paragraphIndent directly when the node is a body-copy text node with multiple paragraphs — Figma exposes these as native text-node properties, not just Auto Layout itemSpacing, so check which one the content actually uses before recommending a fix.itemSpacing/padding aren't multiples of the confirmed grid-base, flag each offending value with the nearest clean multiple.gap: {itemSpacing}px rzeczywisty odstęp optyczny to ok. {estimate}px. Rekomenduję włączenie Vertical Trim: Cap height dla precyzyjnej siatki {grid-base}px." — give this as the concrete alert text when trim is off and the frame is otherwise on-grid.itemSpacing/padding, or paragraphSpacing/paragraphIndent for text-node-native rhythm, or textLeadingTrim on child text nodes, only on explicit request — never silently.grid-base.LH-fraction formula and the resulting px — never a bare pixel number with no derivation.paragraphSpacing (0.25–0.33×LH vs. 0.5–0.75×LH) — never emitted equal or reversed.paragraphSpacing and first-line indent not both recommended together; matches whichever convention the input already shows.text-typesetting noted when the fix is really "turn on vertical-trim" rather than a spacing-value change.FrameNode.layoutMode, FrameNode.itemSpacing, FrameNode.paddingTop/Right/Bottom/Left, TextNode.textLeadingTrim, TextNode.paragraphSpacing, TextNode.paragraphIndent.text-typesetting (vertical-trim and line-height source of truth), line-length-optimizer (horizontal measure — different axis, same text blocks).