Rock Foundations
A church-grade UI component library built to align with Rock RMS v18 RockNextGen design tokens. 26 components. Dark mode. WCAG AA accessible. Zero build step.
Color Palette
Rock RMS v18 RockNextGen design tokens — every color has a purpose-driven name.
FoundationBrand Colors
Interface Scale
Semantic Colors
// Rock RMS v18 Primary Brand
@color-primary: #1E6EBF;
@color-primary-dark: #155499;
@color-primary-light: #EBF4FF;
@color-primary-soft: #DBEAFE;
// Semantic — Success
@color-success-strong: #15803D;
@color-success-soft: #DCFCE7;
// Semantic — Danger
@color-danger-strong: #B91C1C;
@color-danger-soft: #FEE2E2;
Typography
Inter for UI text, Merriweather for display headings. Eight size steps, four weights.
FoundationFont Sizes — Inter
Weights — Inter
Regular 400 — Body text
Medium 500 — Labels
Semibold 600 — Headings
Bold 700 — Stats & CTAs
Display Font — Merriweather
Give to Life Change
Your generosity transforms communities and changes lives.
Line Heights
Sunday morning services bring our congregation together for worship, teaching, and community.
Sunday morning services bring our congregation together for worship, teaching, and community.
Sunday morning services bring our congregation together for worship, teaching, and community.
// Typography tokens
font-family: @font-family-base; // Inter — all UI text
font-family: @font-family-display; // Merriweather — headings, giving widget
font-size: @font-size-base; // 14px — body
font-size: @font-size-md; // 16px — card titles
font-size: @font-size-xl; // 22px — section headings
font-weight: @font-weight-normal; // 400
font-weight: @font-weight-semibold; // 600 — headings
font-weight: @font-weight-bold; // 700 — stats, CTAs
line-height: @line-height-base; // 1.5 — body text
line-height: @line-height-tight; // 1.25 — headings
Spacing Scale
Seven consistent spacing tokens from 4px to 64px — used for padding, gaps, and margins throughout.
Foundation// Rock Foundations Spacing Scale
padding: @spacing-medium; // 16px
gap: @spacing-small; // 8px
margin-bottom: @spacing-xlarge; // 32px
Shadow Scale
Five levels of elevation from nearly imperceptible to dramatic depth.
Foundation// Apply shadows via Less variables
box-shadow: @shadow-xs; // Topbar, subtle borders
box-shadow: @shadow-sm; // Cards, default state
box-shadow: @shadow-md; // Cards on hover
box-shadow: @shadow-lg; // Dropdowns, panels
box-shadow: @shadow-xl; // Modals, overlays
Border Radius
Six radius tokens from sharp corners to fully circular pill shapes.
Foundation// Apply radius tokens via Less variables
border-radius: @rounded-xsmall; // 3px — buttons (sm), tags
border-radius: @rounded-small; // 5px — inputs, buttons (default)
border-radius: @rounded-medium; // 8px — cards, panels, modals
border-radius: @rounded-large; // 12px — action icons, media cards
border-radius: @rounded-xlarge; // 16px — feature cards
border-radius: @rounded-full; // 9999px — avatars, badges, pills
Form Inputs
Text inputs, select, checkbox, radio, toggle, and a complete realistic "New Person" form.
CoreNew Person Form — Full Example
<!-- Text Input with label and helper -->
<div class="rf-form-group">
<label class="rf-label" for="my-input">Full Name</label>
<input class="rf-input" id="my-input" type="text" placeholder="Enter name">
<div class="rf-field-help">Helper text below</div>
</div>
<!-- Error state -->
<input class="rf-input rf-input-error" aria-invalid="true"
aria-describedby="err-msg">
<div class="rf-field-error" id="err-msg">Error message</div>
<!-- Toggle Switch -->
<label class="rf-toggle-wrapper">
<input type="checkbox">
<div class="rf-toggle"></div>
<span class="rf-toggle-label">Email Opt-In</span>
</label>
Badges & Tags
Status indicators, removable tags, counter badges, and semantic color variants.
CoreFilled Variants
Soft Variants
Outline Variants
Sizes
Status Badges
Removable Tags
Counter Badge (notification overlay)
<!-- Filled badge -->
<span class="rf-badge rf-badge-primary">Primary</span>
<span class="rf-badge rf-badge-success">Success</span>
<!-- Soft (pale) badge -->
<span class="rf-badge rf-badge-warning-soft">Pending Review</span>
<!-- Status badge with dot -->
<span class="rf-status-badge rf-status-active">
<span class="rf-status-dot"></span>Active
</span>
<!-- Removable tag — JS handles removal on × click -->
<span class="rf-tag">
Worship Team
<button class="rf-tag-remove" aria-label="Remove">×</button>
</span>
<!-- Counter badge overlapping a button -->
<div class="rf-badge-counter-wrapper">
<button class="rf-btn rf-btn-ghost rf-btn-icon-only" aria-label="Notifications">
<i class="fa-solid fa-bell"></i>
</button>
<span class="rf-badge-counter">3</span>
</div>
Alerts
Contextual feedback messages for success, warning, danger, and informational states.
CoreSarah Mitchell has been added to the Young Adults group and will receive a welcome email shortly.
This person is missing a home campus and birthday. Some Rock RMS features may be limited until this information is added.
Unable to sync with Rock RMS. The last successful sync was 2 hours ago. Please check your connection and try again.
Rock RMS will be unavailable Saturday, April 26 from 2:00–4:00 AM CDT for a scheduled update to v18.1.
Inline Compact Alerts
<div class="rf-alert rf-alert-success" role="alert">
<i class="rf-alert-icon fa-solid fa-circle-check"></i>
<div class="rf-alert-body">
<div class="rf-alert-title">Success Title</div>
<p class="rf-alert-text">Details about what happened.</p>
</div>
<button class="rf-alert-dismiss" aria-label="Dismiss">×</button>
</div>
Avatars
CSS-generated initials avatars with status indicators, size scale, and group stacking. Zero external images.
CoreSizes
Color Variants
Icon Avatars
With Status Indicators
Avatar Group
<!-- Avatar with initials — sizes: xs sm md lg xl xxl -->
<div class="rf-avatar rf-avatar-md rf-avatar-blue">SM</div>
<!-- Color variants: blue green amber red teal purple pink indigo -->
<div class="rf-avatar rf-avatar-md rf-avatar-purple">JT</div>
<!-- Icon avatar -->
<div class="rf-avatar rf-avatar-md rf-avatar-green">
<i class="fa-solid fa-user"></i>
</div>
<!-- Avatar with status dot -->
<div class="rf-avatar-wrapper rf-avatar-md-wrap">
<div class="rf-avatar rf-avatar-md rf-avatar-blue">SM</div>
<div class="rf-avatar-status rf-status-online"></div>
</div>
<!-- Overlapping group -->
<div class="rf-avatar-group">
<div class="rf-avatar rf-avatar-md rf-avatar-blue">SM</div>
<div class="rf-avatar rf-avatar-md rf-avatar-green">JT</div>
<div class="rf-avatar-group-more">+3 more</div>
</div>
Cards
Versatile card patterns for displaying content, stats, media, and actions.
CoreThis small group meets weekly for Bible study, community, and prayer. All young adults ages 18–35 are welcome.
Easter Sunday Celebration
Join us for a special Easter service with live worship, powerful teaching, and community.
Submit and pray for requests from your congregation in real time.
Horizontal Card
Easter Sunday Celebration
Sun, April 20 · 9:00 AM · Main Auditorium
Pricing Card
- Unlimited members
- Check-in kiosks
- Online giving
- Group management
- Volunteer scheduling
<!-- Basic card with header / body / footer -->
<div class="rf-card">
<div class="rf-card-header">
<div class="rf-card-title">Card Title</div>
</div>
<div class="rf-card-body">Card content goes here.</div>
<div class="rf-card-footer">
<button class="rf-btn rf-btn-primary rf-btn-sm">Action</button>
</div>
</div>
<!-- Clickable card with hover lift -->
<div class="rf-card rf-card-clickable">...</div>
<!-- Stat card -->
<div class="rf-card-stat">
<div class="rf-card-stat-number">1,247</div>
<div class="rf-card-stat-label">Weekend Attendance</div>
<span class="rf-card-stat-trend rf-trend-up">
<i class="fa-solid fa-arrow-trend-up"></i> +8%
</span>
</div>
Panels
Rock-style collapsible panels with smooth animation and semantic color variants.
CoreDefault Panel — Group Details
Young Adults Wednesday meets weekly at 7:00 PM in Room 214. This small group focuses on building community through Bible study and shared life. Led by Pastor James Torres.
Primary Panel — Giving Summary
Total giving this month: $47,832. Goal: $50,000. You are 95.7% of the way to your monthly giving goal.
Success Panel — Attendance Goal Met
Weekend attendance reached 1,247 — surpassing the quarterly goal of 1,200. Great work, team!
Warning Panel — Missing Volunteer Slots
3 volunteer roles remain unfilled for the 9:00 AM service this Sunday. Please assign volunteers in the scheduling tool.
Danger Panel — System Alert
The Rock RMS integration has been disconnected. Contact your system administrator to restore the connection.
<!-- Default collapsible panel (JS toggles .is-open) -->
<div class="rf-panel">
<div class="rf-panel-header" role="button" aria-expanded="true">
<h3 class="rf-panel-title">Panel Title</h3>
<i class="rf-panel-toggle-icon fa-solid fa-chevron-down"></i>
</div>
<div class="rf-panel-body is-open">
Panel body content here.
</div>
</div>
<!-- Colour variants: rf-panel-primary / success / warning / danger -->
<div class="rf-panel rf-panel-primary">...</div>
Tables
Sortable, hoverable, striped tables with row actions, checkboxes, and pagination.
Core| Name | Campus | Role | Joined | Status | Actions | |
|---|---|---|---|---|---|---|
SM Sarah Mitchell |
Main Campus | Group Leader | Mar 2019 | Active | ||
JT James Torres |
North Campus | Pastor | Jan 2018 | Active | ||
LN Lisa Nguyen |
East Campus | Worship Lead | Sep 2020 | Pending | ||
PW Patricia Webb |
South Campus | Kids Leader | Jun 2017 | Active | ||
MR Marcus Rivera |
Main Campus | Deacon | Feb 2021 | Inactive | ||
EJ Emma Johnson |
North Campus | Volunteer | Oct 2022 | Active | ||
DP David Park |
East Campus | Member | Jul 2023 | Pending |
<table class="rf-table rf-table-hover rf-table-striped" aria-label="Group members">
<thead>
<tr>
<th class="rf-col-check"><input type="checkbox" class="rf-table-select-all"></th>
<th class="rf-sortable">Name <i class="fas fa-sort rf-sort-icon"></i></th>
<th class="rf-sortable">Role <i class="fas fa-sort rf-sort-icon"></i></th>
<th class="rf-sortable">Status <i class="fas fa-sort rf-sort-icon"></i></th>
<th>Actions</th>
</tr>
</thead>
<tbody>
<tr>
<td class="rf-col-check"><input type="checkbox" class="rf-table-row-check"></td>
<td>Sarah Mitchell</td>
<td>Group Leader</td>
<td><span class="rf-status-badge rf-status-active">Active</span></td>
<td>
<div class="rf-table-actions">
<button class="rf-table-action-btn" aria-label="View"><i class="fa-solid fa-eye"></i></button>
<button class="rf-table-action-btn" aria-label="Edit"><i class="fa-solid fa-pen-to-square"></i></button>
<button class="rf-table-action-btn rf-action-delete" aria-label="Delete"><i class="fa-solid fa-trash-can"></i></button>
</div>
</td>
</tr>
</tbody>
</table>
<!-- Pagination -->
<div class="rf-pagination">
<div class="rf-pagination-info">Showing 1–5 of 7 results</div>
<div class="rf-pagination-controls">
<button class="rf-page-btn" data-action="prev"><i class="fa-solid fa-chevron-left"></i></button>
<button class="rf-page-btn rf-page-active" data-page="1">1</button>
<button class="rf-page-btn" data-page="2">2</button>
<button class="rf-page-btn" data-action="next"><i class="fa-solid fa-chevron-right"></i></button>
</div>
</div>
Member Card
Person profile card with avatar, stats, and action buttons.
Church<div class="rf-member-card" tabindex="0" role="article" aria-label="Sarah Mitchell, Worship Team Lead">
<div class="rf-member-card-status">
<span class="rf-status-badge rf-status-active">Connected</span>
</div>
<div class="rf-member-card-avatar-area">
<div class="rf-avatar-wrapper rf-avatar-lg-wrap">
<div class="rf-avatar rf-avatar-lg rf-avatar-blue">SM</div>
<div class="rf-avatar-status rf-status-online"></div>
</div>
</div>
<div class="rf-member-card-name">Sarah Mitchell</div>
<div class="rf-member-card-role">Worship Team Lead</div>
<div class="rf-member-card-stats">
<span><strong>47</strong> Groups</span>
<span class="rf-stat-sep">·</span>
<span><strong>12</strong> Events</span>
</div>
<div class="rf-member-card-actions">
<button class="rf-btn rf-btn-ghost rf-btn-sm">Message</button>
<button class="rf-btn rf-btn-primary rf-btn-sm">+ Group</button>
</div>
</div>
Group Card
Ministry group listing with leader info, capacity bar, and join action.
Church- Wednesdays at 7:00 PM
- Main Campus — Room 214
- 14 / 20 Members
<div class="rf-group-card">
<div class="rf-group-card-header">
<div class="rf-group-icon"><i class="fa-solid fa-users"></i></div>
<div class="rf-group-title-area">
<div class="rf-group-name">Young Adults — Wednesday</div>
<span class="rf-badge rf-badge-primary-soft">Small Group</span>
</div>
</div>
<div class="rf-group-leader-row">
<div class="rf-avatar rf-avatar-sm rf-avatar-green">JT</div>
<span>Led by <strong>Pastor James Torres</strong></span>
</div>
<ul class="rf-group-info-list">
<li><i class="fa-solid fa-calendar-days"></i> Wednesdays at 7:00 PM</li>
<li><i class="fa-solid fa-location-dot"></i> Main Campus — Room 214</li>
<li><i class="fa-solid fa-users"></i> 14 / 20 Members</li>
</ul>
<div class="rf-group-capacity">
<div class="rf-group-capacity-label"><span>Capacity</span><strong>14 / 20</strong></div>
<div class="rf-progress"><div class="rf-progress-bar" style="width:70%;"></div></div>
</div>
<button class="rf-btn rf-btn-primary rf-w-full">Join Group</button>
</div>
Event Registration Block
Full event card with banner, metadata, capacity, countdown, and registration CTA.
ChurchEaster Sunday Celebration
Join us for a powerful Easter Sunday celebration! Experience moving worship, an inspiring message, and the joy of gathering together as a church family. Childcare available for ages 0–5 during both services.
<div class="rf-event-block">
<div class="rf-event-banner">
<div class="rf-event-banner-overlay"></div>
<div class="rf-event-banner-icon"><i class="fa-solid fa-church"></i></div>
</div>
<div class="rf-event-body">
<h3 class="rf-event-name">Easter Sunday Celebration</h3>
<ul class="rf-event-meta-list">
<li><i class="fa-solid fa-calendar-days"></i> Sunday, April 20, 2025</li>
<li><i class="fa-solid fa-clock"></i> 9:00 AM & 11:00 AM Services</li>
<li><i class="fa-solid fa-location-dot"></i> Main Auditorium</li>
</ul>
<div class="rf-event-capacity">
<div class="rf-progress"><div class="rf-progress-bar" style="width:62%;"></div></div>
</div>
<button class="rf-btn rf-btn-primary rf-w-full rf-btn-lg">Register Now</button>
</div>
</div>
Giving Widget
Preset amount buttons, fund selector, frequency tabs, and secure giving CTA.
Church<div class="rf-giving-widget">
<div class="rf-giving-title">Give to Life Change</div>
<div class="rf-giving-amounts">
<button class="rf-amount-btn" data-amount="25">$25</button>
<button class="rf-amount-btn rf-amount-active" data-amount="50">$50</button>
<button class="rf-amount-btn" data-amount="100">$100</button>
<button class="rf-amount-btn" data-amount="" data-custom="true">Custom</button>
</div>
<div class="rf-giving-fund rf-form-group">
<label class="rf-label" for="giving-fund">Give To</label>
<select class="rf-select" id="giving-fund">
<option>General Fund</option>
<option>Missions</option>
</select>
</div>
<div class="rf-freq-tabs" role="group" aria-label="Gift frequency">
<button class="rf-freq-tab rf-freq-active">One-Time</button>
<button class="rf-freq-tab">Weekly</button>
<button class="rf-freq-tab">Monthly</button>
</div>
<button class="rf-btn rf-btn-primary rf-w-full rf-btn-lg">
<i class="fa-solid fa-lock"></i> Give Now
</button>
</div>
Prayer Request Card
Prayer wall card with expandable text, tag filtering, and Vue-powered prayer counter.
ChurchPlease pray for my mother who is recovering from surgery. She has been struggling with her health for the past few months and we are trusting God for a full recovery. The doctors say it will be a long road, but we believe in the power of prayer and the healing hands of our Lord.
<div class="rf-prayer-card">
<div class="rf-prayer-header">
<div class="rf-prayer-author-info">
<div class="rf-avatar rf-avatar-sm rf-avatar-teal">MR</div>
<div>
<div class="rf-prayer-author-name">Marcus Rivera</div>
<div class="rf-prayer-time">2 hours ago</div>
</div>
</div>
</div>
<div class="rf-prayer-body">
<p class="rf-prayer-text" id="prayer-text-1">Prayer request text here...</p>
<button class="rf-prayer-read-more" aria-expanded="false" aria-controls="prayer-text-1">Read more</button>
</div>
<div class="rf-prayer-tags">
<span class="rf-badge rf-badge-info-soft">Health</span>
<span class="rf-badge rf-badge-warning-soft">Family</span>
</div>
<!-- Vue prayer counter mounts here -->
<div id="vue-prayer-counter"></div>
</div>
Attendance Stat Cards
Dashboard KPI row with sparklines and trend indicators.
Church<div class="rf-stat-grid">
<div class="rf-stat-card">
<div class="rf-stat-card-header">
<div class="rf-stat-icon rf-stat-icon-blue"><i class="fa-solid fa-users"></i></div>
<span class="rf-stat-trend rf-trend-up"><i class="fa-solid fa-arrow-trend-up"></i> +8%</span>
</div>
<div class="rf-stat-number">1,247</div>
<div class="rf-stat-label">Weekend Attendance</div>
<div class="rf-stat-footer">
<span>vs last week</span>
<div class="rf-stat-sparkline">
<svg width="60" height="28" viewBox="0 0 60 28" fill="none">
<polyline points="0,22 8,18 16,20 24,14 32,16 40,10 48,8 60,4"
stroke="#1E6EBF" stroke-width="1.5" fill="none"/>
</svg>
</div>
</div>
</div>
<!-- Repeat for each KPI: rf-stat-icon-green, purple, orange -->
</div>
Check-In Badge
Physical-style name badge for children's check-in with security code, allergy alerts, and barcode.
Church<div class="rf-checkin-badge">
<div class="rf-checkin-header">
<span class="rf-checkin-church-name">Rock Church</span>
<i class="rf-checkin-header-icon fa-solid fa-shield-halved"></i>
</div>
<div class="rf-checkin-body">
<div class="rf-checkin-code">4721</div>
<div class="rf-checkin-child-name">Emma Johnson</div>
<div class="rf-checkin-service">9:00 AM Service — Room K3</div>
<div class="rf-checkin-allergies">
<span class="rf-badge rf-badge-danger">
<i class="fa-solid fa-triangle-exclamation"></i> Nut Allergy
</span>
</div>
</div>
<div class="rf-checkin-barcode" role="img" aria-label="Security barcode"></div>
<button class="rf-btn rf-btn-primary rf-w-full rf-btn-sm">
<i class="fa-solid fa-print"></i> Print Badge
</button>
</div>
Volunteer Schedule
Scheduling table with role badges, status indicators, and confirm/decline actions.
Church<div class="rf-volunteer-table">
<div class="rf-volunteer-table-header">
<span>Volunteer</span>
<span>Role</span>
<span>Service</span>
<span>Status</span>
<span>Actions</span>
</div>
<div class="rf-volunteer-row">
<div class="rf-vol-person">
<div class="rf-avatar rf-avatar-sm rf-avatar-blue">SM</div>
<span class="rf-vol-name">Sarah Mitchell</span>
</div>
<div class="rf-vol-role"><span class="rf-badge rf-badge-primary-soft">Worship</span></div>
<div class="rf-vol-time">9:00 AM</div>
<div class="rf-vol-status">
<span class="rf-status-badge rf-status-active">Confirmed</span>
</div>
<div class="rf-vol-actions">
<button class="rf-vol-action-btn rf-vol-confirm" aria-label="Confirm"><i class="fa-solid fa-check"></i></button>
<button class="rf-vol-action-btn rf-vol-decline" aria-label="Decline"><i class="fa-solid fa-xmark"></i></button>
<button class="rf-vol-action-btn rf-vol-message" aria-label="Message"><i class="fa-regular fa-comment"></i></button>
</div>
</div>
</div>
Modal
Vue 3 modal with three size variants, backdrop dismiss, Escape key, body scroll lock, and focus trap.
Vue<!-- Modal trigger (Vue) -->
<button class="rf-btn rf-btn-primary" @click="openModal('md')">
Open Modal
</button>
<!-- Modal structure -->
<div class="rf-modal-backdrop" role="dialog" aria-modal="true">
<div class="rf-modal-box rf-modal-md">
<div class="rf-modal-header">
<h3 class="rf-modal-title">Modal Title</h3>
<button class="rf-modal-close" aria-label="Close">×</button>
</div>
<div class="rf-modal-body">Content here</div>
<div class="rf-modal-footer">
<button class="rf-btn rf-btn-ghost">Cancel</button>
<button class="rf-btn rf-btn-primary">Confirm</button>
</div>
</div>
</div>
Accessibility: role="dialog", aria-modal="true", Escape key closes, backdrop click closes, body scroll locked when open, focus returned to trigger on close.
Toast Notifications
Vue 3 toast stack with auto-dismiss, progress bar, and slide animations.
VueToasts appear in the bottom-right corner. Each auto-dismisses after 4 seconds.
<!-- Trigger a toast from Vue -->
<button class="rf-btn rf-btn-success" @click="addToast('success', 'Saved!', 'Changes saved successfully.')">
Success Toast
</button>
<!-- Toast container (Vue renders here) -->
<div class="rf-toast-container" aria-live="polite" role="status">
<transition-group name="rf-toast">
<div v-for="toast in toasts" :key="toast.id"
class="rf-toast" :class="'rf-toast-' + toast.type" role="alert">
<div class="rf-toast-content">
<strong>{{ toast.title }}</strong>
<span>{{ toast.message }}</span>
</div>
<div class="rf-toast-progress"></div>
</div>
</transition-group>
</div>
Accessibility: Container has aria-live="polite" and role="status". Individual toasts have role="alert". Progress bar indicates time remaining. Max 4 visible at once.
Dropdown Menu
Vue 3 dropdown with icon items, dividers, disabled states, and destructive actions.
Vue<!-- Dropdown trigger (Vue) -->
<div class="rf-dropdown-wrapper">
<button class="rf-btn rf-btn-ghost"
aria-haspopup="true"
:aria-expanded="isOpen.toString()"
@click="toggle">
Actions <i class="fa-solid fa-chevron-down"></i>
</button>
<div v-if="isOpen" class="rf-dropdown-menu" role="menu">
<button class="rf-dropdown-item" role="menuitem">
<i class="fa-solid fa-pen-to-square"></i> Edit
</button>
<button class="rf-dropdown-item" role="menuitem">
<i class="fa-solid fa-copy"></i> Duplicate
</button>
<div class="rf-dropdown-divider"></div>
<button class="rf-dropdown-item rf-dropdown-item-danger" role="menuitem">
<i class="fa-solid fa-trash-can"></i> Delete
</button>
</div>
</div>
Accessibility: aria-haspopup="true", aria-expanded updates on toggle, Escape key closes, click-outside closes. Menu items use role="menuitem".
Tabs
Vue 3 tabs with hash-based URL routing, meaningful church content, and fade transitions.
Vue<!-- Vue Tabs -->
<div class="rf-vue-tabs">
<div class="rf-vue-tab-list" role="tablist">
<button class="rf-vue-tab-btn active"
:aria-selected="activeTab === 'overview'"
@click="setTab('overview')">
Overview
</button>
</div>
<div class="rf-vue-tab-content">
<div v-if="activeTab === 'overview'">
<!-- Tab content -->
</div>
</div>
</div>