For members
Access your pension information, tools, and resources to plan your retirement with confidence.
Learn more about member benefitsComponent Contract
A flexible content-grouping component for displaying headings, summaries, images, icons, and links across CAAT digital properties.
Rendered
Access your pension information, tools, and resources to plan your retirement with confidence.
Learn more about member benefitsDiscover how CAAT helps you offer a secure, sustainable pension plan to your employees.
Explore employer solutionsReview our investment strategy, funding status, and annual performance reports.
View plan performanceRendered
Everything you need to know about planning for a secure retirement with CAAT.
Read the guideReview CAAT's investment performance, membership growth, and financial highlights.
Download the reportRendered
Each card type uses one standard ratio from the Card Image Ratios foundation. One ratio per grid.
Blog listing — 16:9
Rendered
How a modern pension shifts the recruiting equation.
New data on Canadians' retirement readiness.
A milestone for Canada's modern pension.
Leadership bios — 1:1, face-centred
Rendered
Chief Investment Officer
VP, Member Services
Head of Plan Design
General Counsel
Resource call-outs — 4:3
Rendered
Your pension is backed by a robust funding framework.
Your pension is backed by a robust funding framework.
HTML
<!-- Icon card -->
<article class="card caat-card"
data-analytics-component="card"
data-analytics-category="icon-card"
data-analytics-label="for-members">
<div class="card-body text-center">
<span class="icon-token mb-3" aria-hidden="true">
<i class="bi bi-people-fill"></i>
</span>
<h3 class="card-title">For members</h3>
<p class="card-text">Access your pension information…</p>
<a href="/en/members" class="stretched-link">Learn more</a>
</div>
</article>
<!-- Image card with kicker -->
<article class="card caat-card">
<img src="/content/dam/caat/images/hero.jpg"
class="card-img-top"
alt="Descriptive alt text">
<div class="card-body">
<span class="caat-card-kicker">Resources</span>
<h3 class="card-title">Retirement planning guide</h3>
<p class="card-text">Everything you need to know…</p>
<a href="/en/resources/guide" class="stretched-link">Read the guide</a>
</div>
</article>
<!-- Media overlay card -->
<article class="card caat-card caat-card--overlay">
<img src="/content/dam/caat/images/event.jpg"
class="card-img"
alt="Presenter at corporate event">
<div class="card-img-overlay overlay-panel d-flex flex-column justify-content-end">
<span class="caat-card-kicker text-white">Event</span>
<h3 class="card-title text-white">Pension webinar</h3>
<p class="card-text text-white">Join our experts…</p>
<a href="/en/events/webinar" class="stretched-link text-white">Register</a>
</div>
</article>
| Component name | Card |
|---|---|
| AEM component name | caat/components/card |
| Recommended implementation | Extend the AEM Core Teaser component (core/wcm/components/teaser/v2/teaser) |
| Component group | CAAT Design System |
| Purpose | Display grouped content with a heading, summary, image or icon, and link — suitable for value propositions, resource listings, event promotions, and audience pathway navigation |
| Existing AEM components replaced | Card Grid Component (#25), Container with Card Style (#28), Multi Tile Listing (#43) |
| Token | Value (reference) | Purpose |
|---|---|---|
--caat-grey-200 | #dfe6ef | Card border colour |
--caat-blue-100 | #e7f4fb | Icon-token background tint |
--caat-blue-300 | #9dd2ed | Icon-token icon colour |
--caat-blue-900 | #003750 | Card heading colour, link colour |
--caat-green-100 | #e8f5e6 | Kicker background tint |
--caat-green-700 | #367f32 | Kicker text colour |
--caat-blue-700 | #0b5a80 | Link hover colour |
--caat-radius | .75rem | Card border radius (standard) |
--caat-radius-lg | 1.25rem | Card border radius (large / overlay variant) |
--caat-shadow | 0 .5rem 1rem rgba(0,0,0,.08) | Card hover elevation shadow |
--caat-shadow-sm | 0 .125rem .25rem rgba(0,0,0,.05) | Card resting shadow |
.caat-card--compact) — reduced padding and smaller typography for dense layouts| Field | Type | Required | Default | Notes |
|---|---|---|---|---|
| Heading | Text field | Yes | — | Card title. Max 80 characters recommended. |
| Heading level | Dropdown | No | h3 | h2 | h3 | h4. Allows authors to maintain heading hierarchy. |
| Summary | Text area | No | — | Short description. Max 160 characters recommended. |
| Link URL | Path browser | Yes* | — | Required for clickable cards. Internal or external URL. |
| Link label | Text field | No | — | Visible link text. If empty, the stretched-link is visually hidden but accessible. |
| Image | Image picker | No | — | DAM image reference. Used for Image and Overlay variants. |
| Image alt text | Text field | Conditional | — | Required when an image is provided. Decorative images should use empty alt. |
| Kicker | Text field | No | — | Small label above heading (e.g. "Resources", "Event"). Max 3 words. |
| Icon | Dropdown | No | None | Icon for the Icon card variant. Options: none, people, building, graph, shield, calendar, document. |
| Field | Type | Required | Default | Notes |
|---|---|---|---|---|
| Variant | Dropdown | Yes | Image card | icon | image | overlay | content |
| Card height | Dropdown | No | Auto | auto | fixed (equal-height cards in a row) |
| Image aspect ratio | Dropdown | No | 16:9 | 16:9 | 4:3 | 1:1. Only shown for Image and Overlay variants. |
| Field | Type | Required | Default | Notes |
|---|---|---|---|---|
| Link target | Checkbox | No | Same tab | If checked, opens in new tab and adds rel="noopener". |
| Analytics label | Text field | No | — | Custom label for analytics reporting. Auto-generated from heading if empty. |
rel="noopener" to the rendered anchor.<article class="card caat-card">
<div class="card-body text-center">
<span class="icon-token" aria-hidden="true">
<i class="bi bi-people-fill"></i>
</span>
<h3 class="card-title">For members</h3>
<p class="card-text">Access your pension information and tools.</p>
<a href="/en/members" class="stretched-link">Learn more about member benefits</a>
</div>
</article>
<article class="card caat-card">
<img src="/content/dam/caat/images/guide.jpg"
class="card-img-top"
alt="Couple reviewing financial documents">
<div class="card-body">
<span class="caat-card-kicker">Resources</span>
<h3 class="card-title">Retirement planning guide</h3>
<p class="card-text">Everything you need to plan your retirement.</p>
<a href="/en/resources/guide" class="stretched-link">Read the guide</a>
</div>
</article>
<article class="card caat-card caat-card--overlay">
<img src="/content/dam/caat/images/event.jpg"
class="card-img"
alt="Presenter at corporate webinar">
<div class="card-img-overlay overlay-panel d-flex flex-column justify-content-end">
<span class="caat-card-kicker text-white">Upcoming event</span>
<h3 class="card-title text-white">Pension planning webinar</h3>
<p class="card-text text-white">Join our experts for a live session.</p>
<a href="/en/events/webinar" class="stretched-link text-white">Register</a>
</div>
</article>
The card component relies on the global token layer defined in /assets/css/tokens.css.
All component-specific styles live in
/assets/css/components/card.css.
.caat-card {
border: 1px solid var(--caat-grey-200, #e9ecef);
border-radius: var(--caat-radius, .75rem);
box-shadow: var(--caat-shadow-sm);
transition: box-shadow .18s ease, transform .18s ease;
overflow: hidden;
}
.caat-card:hover {
box-shadow: var(--caat-shadow);
transform: translateY(-2px);
}
/* Icon token */
.caat-card .icon-token {
display: inline-flex;
align-items: center;
justify-content: center;
width: 3.5rem;
height: 3.5rem;
border-radius: 50%;
background: var(--caat-blue-100);
color: var(--caat-blue-300);
font-size: 1.5rem;
}
/* Kicker */
.caat-card-kicker {
display: inline-block;
font-size: .75rem;
font-weight: 700;
text-transform: uppercase;
letter-spacing: .06em;
color: var(--caat-green-700);
margin-bottom: .5rem;
}
/* Overlay variant */
.caat-card--overlay {
border-radius: var(--caat-radius-lg, 1rem);
}
.caat-card--overlay .overlay-panel {
background: linear-gradient(to top, rgba(0,55,80,.85) 0%, transparent 100%);
padding: 1.5rem;
}
/* Focus ring on stretched-link */
.caat-card .stretched-link:focus-visible {
box-shadow: var(--caat-focus);
outline: 0;
}
/* Image — pick ONE ratio per grid (see Card Image Ratios foundation).
A ratio modifier is required (legacy fixed heights have been removed). */
.caat-card-image { width: 100%; object-fit: cover; }
.caat-card-image--16-9 { aspect-ratio: 16 / 9; } /* blog / article cards */
.caat-card-image--4-3 { aspect-ratio: 4 / 3; } /* resource call-outs */
.caat-card-image--1-1 { aspect-ratio: 1 / 1; } /* bios / thumbnails */
.caat-card-image--4-5 { aspect-ratio: 4 / 5; } /* editorial portrait */
.caat-card-image--3-2 { aspect-ratio: 3 / 2; } /* editorial photography*/
.caat-card-image--face { object-position: 50% 22%; } /* keep faces in frame */
var(--caat-blue-900))
so that theme changes propagate automatically.
| Requirement | Acceptance criteria |
|---|---|
| Keyboard access | Cards using .stretched-link must be focusable and activatable via Tab and Enter. The entire card surface acts as the hit area. |
| Focus state | A visible focus ring (var(--caat-focus)) must appear on the stretched-link on :focus-visible. The ring must meet a 3 : 1 contrast ratio. |
| Image alt text | All card images must have descriptive alt text. Purely decorative images may use alt="" but must not omit the attribute. |
| Heading hierarchy | Card headings must fit within the page's heading hierarchy. Authors can choose h2, h3, or h4 via the authoring dialog. |
| Article landmark | Each card is rendered as an <article> element, providing a meaningful landmark for assistive technologies. |
| Colour contrast | Text-to-background contrast must meet WCAG 2.1 AA in all variants, including overlay cards with gradient backgrounds. |
href attributes that resolve to valid, crawlable URLs.alt text that supports image search indexing.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.
This component consolidates and replaces three existing AEM components:
Rebuild Rebuild to new brand standards. Consolidate three legacy components into a single, token-driven card component.
Create a proxy component at /apps/caat/components/card that extends the
AEM Core Teaser v2 (core/wcm/components/teaser/v2/teaser).
Override teaser.html to emit the CAAT class names, semantic <article> wrapper, and data attributes.
caat.components.cardcaat.base (tokens + base styles)card.csscard.js (analytics wiring, impression observer)card/
├── _cq_dialog/
│ └── .content.xml # Touch UI dialog
├── _cq_editConfig.xml # Edit configuration
├── .content.xml # Component node definition
├── card.html # HTL template
├── clientlibs/
│ ├── .content.xml
│ ├── css/
│ │ └── card.css
│ └── js/
│ └── card.js
└── README.md # Dev notes
Simplified model — shows field intent and Granite UI resource types, not the literal cq:dialog node tree (e.g. select options are authored as child items nodes).
# caat/components/card — Touch UI Dialog
# _cq_dialog/.content.xml (YAML representation)
dialog:
jcr:primaryType: nt:unstructured
sling:resourceType: cq/gui/components/authoring/dialog
content:
jcr:primaryType: nt:unstructured
sling:resourceType: granite/ui/components/coral/foundation/container
items:
tabs:
jcr:primaryType: nt:unstructured
sling:resourceType: granite/ui/components/coral/foundation/tabs
items:
# ── Content tab ──────────────────────────────
content:
jcr:title: Content
items:
heading:
sling:resourceType: granite/ui/components/coral/foundation/form/textfield
name: ./heading
fieldLabel: Heading
required: true
maxlength: 80
headingLevel:
sling:resourceType: granite/ui/components/coral/foundation/form/select
name: ./headingLevel
fieldLabel: Heading level
items:
- { text: H2, value: h2 }
- { text: H3, value: h3 }
- { text: H4, value: h4 }
summary:
sling:resourceType: granite/ui/components/coral/foundation/form/textarea
name: ./summary
fieldLabel: Summary
maxlength: 160
linkURL:
sling:resourceType: granite/ui/components/coral/foundation/form/pathfield
name: ./linkURL
fieldLabel: Link URL
rootPath: /content
linkLabel:
sling:resourceType: granite/ui/components/coral/foundation/form/textfield
name: ./linkLabel
fieldLabel: Link label
image:
sling:resourceType: granite/ui/components/coral/foundation/form/fileupload
name: ./image
fieldLabel: Image
fileReferenceParameter: ./fileReference
imageAltText:
sling:resourceType: granite/ui/components/coral/foundation/form/textfield
name: ./imageAltText
fieldLabel: Image alt text
kicker:
sling:resourceType: granite/ui/components/coral/foundation/form/textfield
name: ./kicker
fieldLabel: Kicker
maxlength: 30
icon:
sling:resourceType: granite/ui/components/coral/foundation/form/select
name: ./icon
fieldLabel: Icon
items:
- { text: None, value: none }
- { text: People, value: people }
- { text: Building, value: building }
- { text: Graph, value: graph }
- { text: Shield, value: shield }
- { text: Calendar, value: calendar }
- { text: Document, value: document }
# ── Style tab ────────────────────────────────
style:
jcr:title: Style
items:
variant:
sling:resourceType: granite/ui/components/coral/foundation/form/select
name: ./variant
fieldLabel: Variant
required: true
items:
- { text: Icon card, value: icon }
- { text: Image card, value: image }
- { text: Media overlay, value: overlay }
- { text: Content card, value: content }
cardHeight:
sling:resourceType: granite/ui/components/coral/foundation/form/select
name: ./cardHeight
fieldLabel: Card height
items:
- { text: Auto, value: auto }
- { text: Fixed, value: fixed }
imageAspectRatio:
sling:resourceType: granite/ui/components/coral/foundation/form/select
name: ./imageAspectRatio
fieldLabel: Image aspect ratio
items:
- { text: "16:9", value: "16-9" }
- { text: "4:3", value: "4-3" }
- { text: "1:1", value: "1-1" }
# ── Behaviour tab ────────────────────────────
behaviour:
jcr:title: Behaviour
items:
linkTarget:
sling:resourceType: granite/ui/components/coral/foundation/form/checkbox
name: ./linkTarget
text: Open in new tab
value: _blank
analyticsLabel:
sling:resourceType: granite/ui/components/coral/foundation/form/textfield
name: ./analyticsLabel
fieldLabel: Analytics label
| Area | Done means |
|---|---|
| Design | Figma component matches this contract. All variants (icon, image, overlay, content) and sizes are documented. Tokens are used — no hard-coded colour values. |
| Development | AEM proxy component created extending Core Teaser. HTL template emits semantic HTML per Section 6. CSS uses design tokens. JS wires analytics events. Unit tests pass. |
| QA | All items in the QA Acceptance Checklist (Section 13) pass. Manual accessibility audit completed. Cross-browser tested (Chrome, Firefox, Safari, Edge). |
| Launch | Component deployed to AEM production. Legacy components (#25, #28, #43) deprecated. Content authors trained. Documentation published. Analytics dashboards confirmed receiving events. |