AgentStack
SKILL verified MIT Self-run

Vertical Spacing

skill-monikazapisek-design-engineering-playbook-vertical-spacing · by monikazapisek

Use 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.

No reviews yet
0 installs
0 views
view→install

Install

$ agentstack add skill-monikazapisek-design-engineering-playbook-vertical-spacing

✓ scanned · ✓ verified — works with Claude Code, Cursor, and more.

Security review

✓ Passed

No issues found. Passed automated security review. · v0.1.0 How review works →

  • Prompt-injection patterns
  • Secret / credential exfiltration
  • Dangerous shell & filesystem operations
  • Untrusted network calls
  • Known-malicious package signatures

What it can access

  • Network access No
  • Filesystem access No
  • Shell / process execution No
  • Environment & secrets No
  • Dynamic code execution No

From automated source analysis of v0.1.0. “Used” means the capability is present in the source — more access means more to trust, not that it’s unsafe.

Are you the author of Vertical Spacing? Claim this listing to set pricing, connect Stripe payouts, and keep 70% of every sale.
Sign up to claim

About

Vertical Spacing

Purpose

Compute 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.

When To Use

  • Reviewing or defining spacing for a card, section, article, or form.
  • Fixing an Auto Layout frame in Figma where gap/padding look inconsistent or off-grid.
  • Not for spacing within a single line of text (that's text-typesetting) or column width (line-length-optimizer).

Inputs

  • 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.
  • If available: Figma Auto Layout properties (see Figma Node Integration) and the textLeadingTrim state of any text layers inside the frame.

Outputs

  • Spacing values, all multiples of grid-base (e.g. 8, 16, 24, 32, 48, 64, 96).
  • CSS (flex/grid gap, margin) or Tailwind utility classes, matching whichever convention the project already uses.
  • A note on any vertical-trim-driven adjustment (see Workflow step 3).
  • For paragraph/list flow: 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).

Workflow

  1. 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.
  1. 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.
  1. Vertical-trim correction (critical when text is involved):
  • If the text layers in this spacing context have vertical-trim off (default), the visually perceived gap is smaller than the set 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.
  • If vertical-trim is on, the set spacing value is the true optical distance from baseline/cap-height to the next element — no compensation needed; this is the state to prefer for new work.
  • Always state which assumption is in effect — don't emit a spacing recommendation without saying whether it assumes trim on or off, since the correct pixel value differs between the two.
  1. Report, don't silently rewrite a stylesheet or Figma frame unless asked to apply directly.
  1. 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 |

  • Don't apply 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.
  • Snap the computed 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.
  • This step depends on 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.
  1. 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.
  • Fix: don't rely on the paragraph's trailing 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 ``

  • This is larger than the standard heading proximity ratio in step 2 specifically to counteract the missing collapse behavior — don't also apply step 2's 2–3× ratio on top of this value; they solve the same problem, use the larger of the two, not both stacked.

Figma Node Integration

When running with Figma access, work against the selected FrameNode:

  • Read: 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.
  • Also read 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.
  • Paragraph/list frames: read 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.
  • Verdict: if itemSpacing/padding aren't multiples of the confirmed grid-base, flag each offending value with the nearest clean multiple.
  • Alert pattern for missing trim: "Wykryłem brak vertical trimu w warstwach tekstowych w tej ramce. Przy 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.
  • Action back to Figma: set itemSpacing/padding, or paragraphSpacing/paragraphIndent for text-node-native rhythm, or textLeadingTrim on child text nodes, only on explicit request — never silently.

Quality Checklist

  • [ ] Every emitted spacing value is a stated multiple of grid-base.
  • [ ] Proximity rule applied asymmetrically around headings (top ≫ bottom), not symmetric padding by default.
  • [ ] Vertical-trim state checked for any text-containing frame before giving a final gap value; assumption stated explicitly if unknown.
  • [ ] Off-grid values found in existing input are flagged, not silently left or silently "fixed" without saying so.
  • [ ] Paragraph/list rhythm values (step 5) shown as both the LH-fraction formula and the resulting px — never a bare pixel number with no derivation.
  • [ ] List-item gap is visibly tighter than 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.
  • [ ] Figma writes (if any) only happen on explicit request.
  • [ ] Cross-reference to text-typesetting noted when the fix is really "turn on vertical-trim" rather than a spacing-value change.

References

  • Latin, M. (2017). Better Web Typography for a Better Web. — mathematical treatment of vertical rhythm and grid-base spacing.
  • Butterick, M. Practical Typography. — critique of rigid baseline-grid enforcement in favor of flexible, grid-base-multiple padding/gap.
  • Wertheimer, M. (1923). Gestalt principle of proximity — elements spaced closer together are perceived as grouped/related; the basis for list items sitting tighter than paragraphs.
  • Bringhurst, R. (2012). The Elements of Typographic Style (4th ed.). Hartley & Marks — paragraph spacing and first-line indent as alternative (not combined) conventions, both derived from line-height rather than arbitrary pixel values.
  • Figma Plugin API Docs: FrameNode.layoutMode, FrameNode.itemSpacing, FrameNode.paddingTop/Right/Bottom/Left, TextNode.textLeadingTrim, TextNode.paragraphSpacing, TextNode.paragraphIndent.
  • Related skills: [text-typesetting](../text-typesetting/README.md) (vertical-trim and line-height source of truth), [line-length-optimizer](../line-length-optimizer/README.md) (horizontal measure — different axis, same text blocks).

Source & license

This open-source skill is cataloged on AgentStack and links to its original source — we do not rehost the code.

Install and usage instructions live in the source repository linked above.

Reviews

No reviews yet — be the first.

Versions

  • v0.1.0 Imported from the upstream source.