Component Contract
Spacing & Rhythm
Separate content with consistent spacing and vertical rhythm — not horizontal rules. (Formerly “Separator”.)
Live Demo
Stack — consistent vertical rhythm
.caat-stack puts one consistent gap between its children (and zeroes their own margins, so spacing has a single source). Pick the step from the scale.
Tight — --sm (16px)
Plan overview
Contribution rates
Benefit formula
Default — --md (24px)
Plan overview
Contribution rates
Benefit formula
Loose — --xl (48px)
Plan overview
Contribution rates
Benefit formula
Grouping by proximity
This is what replaces the divider: less space within a group, more between groups. The structure reads instantly — no lines needed. (Outer stack --xl, inner stacks --2xs.)
You can start an unreduced pension at your normal retirement date.
A bridge benefit tops up your income until age 65.
Your eligible survivor continues to receive a pension for life.
Spacer — explicit one-off gap
For the rare case you can't control spacing structurally. Prefer Stack or section padding.
Content above the gap.
Content after a --lg (48px) spacer.
Reserved — thematic break
A single 1px rule, only for a genuine change of topic in prose (HTML <hr>). There is no thick/accent rule — heavy bars fence the page.
…and that concludes how your pension is calculated.
On an unrelated note, here's how to update your beneficiary.
Reserved — “or” divider
The one case a visible line genuinely helps: choosing between two alternatives.
Anti-patterns
Rules as fences
Don't put a line between every section. Use spacing (and background tiers from Page Layout) to separate sections.
Spacers as structure
Don't stack empty Spacers to push content around. Use a Stack, grid gap, or section padding.
Inconsistent gaps
Don't hand-pick arbitrary margins. Every gap should be a step on the spacing scale.
1. Summary
| Component name | Spacing & Rhythm (file/resource type: separator) |
|---|---|
| AEM resource type | caat/components/separator |
| Tier | Base — consumes the spacing scale + semantic tokens |
| Purpose | Create separation through consistent spacing and vertical rhythm. Provides Stack and Spacer; a visible divider is reserved for thematic breaks and “or” choices. |
| Variants | Stack (rhythm) · Spacer (gap) · Divider (thematic, reserved) · “Or” divider |
| Status | Reworked |
| Removed | Thick & accent rules, “spaced” rule (heavy fences) — superseded by Stack/Spacer |
2. Design Tokens
| Token | Role |
|---|---|
--caat-space-2 … --caat-space-8 | Stack gap / Spacer height — every gap is a scale step |
--caat-stack-gap | Per-stack gap (set by size modifiers; defaults to --caat-space-5) |
--caat-color-border | Reserved divider line + “or” rules |
--caat-color-bg-page | “Or” label background (knockout) |
--caat-color-text-muted | “Or” label text |
3. Authoring Fields
| Field | Type | Required | Notes |
|---|---|---|---|
| Type | Select | Yes | Spacer · Divider · Or-divider. (Stack is a layout-container option applied to content groups, not a standalone drop-in.) |
| Size | Select | For Spacer/Stack | xs · sm · md · lg · xl — maps to the spacing scale |
| Label | Text | For Or-divider | Usually “or”. Max 24 characters. |
| Decorative | Checkbox | No | Divider only — adds aria-hidden="true" when it's purely visual. |
4. Validation Rules
No author-managed content beyond an accessible label, so there are no authoring validation rules. Accessibility requirements are covered in Section 8 (Accessibility).
5. Content Guidance
Do
- Separate with space, not lines. Use a Stack (or grid gap / section padding) so related items sit closer and groups sit further apart.
- Use the scale. Every gap is a step (
--caat-space-*). Consistent steps create rhythm. - Reserve the divider for a real change of topic in prose, or an “or” between two actions.
- Separate page sections with padding + background tiers (see Page Layout), not rules.
Don't
- Don't stack empty Spacers to force layout — use a Stack or container padding.
- Don't hand-pick arbitrary margins; pull from the scale.
- Don't reach for a thick/coloured rule for emphasis — there isn't one, by design.
6. Semantic HTML
<!-- Vertical rhythm: one consistent gap between children -->
<div class="caat-stack caat-stack--lg">
<h2>…</h2>
<p>…</p>
<a class="caat-button …">…</a>
</div>
<!-- Explicit one-off gap (rare) -->
<div class="caat-spacer--lg" aria-hidden="true"></div>
<!-- Reserved: thematic break -->
<hr class="caat-separator">
<!-- Reserved: "or" divider -->
<div class="caat-separator--with-label"><span class="caat-separator__label">or</span></div>
7. CSS Contract
| Selector | Purpose |
|---|---|
.caat-stack + --2xs … --2xl | Consistent gap between direct children (the rhythm tool) |
.caat-stack--split / .caat-stack__push | Flex-column stack that pins one child to the end |
.caat-spacer + --xs … --xl | Explicit vertical gap |
.caat-separator | Reserved 1px thematic break |
.caat-separator--with-label / .caat-separator__label | “Or” divider |
8. Accessibility
| Requirement | Implementation |
|---|---|
| Spacing is presentational | Stack/Spacer add no semantics and don't alter reading order — purely visual rhythm. |
| Divider role | <hr> has an implicit separator role. If purely decorative, add aria-hidden="true". |
| “Or” divider | The label text is real, in-DOM content read by AT. |
| No empty focusable gaps | Spacers are non-interactive and non-focusable. |
| Reduced motion | No animation; nothing to disable. (Global reduced-motion still applies.) |
9. SEO
Transient / structural UI with no indexable content of its own — no SEO markup required. Ensure any content this component wraps or reveals stays server-rendered and crawlable.
10. Analytics
Analytics are captured through the shared data-analytics-component attribute on the component root (emitted automatically) and reported to the central data layer. Event names and payloads follow the organisation's standard analytics schema — defined centrally with the analytics team, not invented per component — so no bespoke tracking is specified here.
11. AEM Implementation Notes
- Resource type:
caat/components/separator(kept for continuity). - Spacer/Divider/Or render from a
type+size/labelmodel. - Stack is best applied as a layout-container style on a parent (e.g. a content container policy), not dropped between components — author guidance over a drop-in.
- Size options are constrained to the spacing scale (no free-text).
12. Dialog Model (cq:dialog)
Not authored directly. The separator is a sub-element emitted and configured by its host component (or generated from page structure), so it has no standalone cq:dialog — any options are exposed through the host component's dialog.
13. QA Checklist
| # | Check | Pass? |
|---|---|---|
| 1 | Stack gaps are consistent and pull from the scale | |
| 2 | Grouping reads via proximity without any lines | |
| 3 | Spacer used only where structural spacing isn't possible | |
| 4 | Divider appears only at a genuine topic change / “or” | |
| 5 | No thick/accent/full-width fence rules anywhere | |
| 6 | Decorative dividers carry aria-hidden |
14. Definition of Done
- Stack & Spacer drive all routine separation; gaps come from the scale.
- Visible rules limited to thematic break + “or” divider.
- Thick/accent/spaced rule variants removed; no consumers broken.
- Page-section separation uses padding + background tiers (Page Layout).
- QA checklist signed off.