Overview
Design Philosophy
Our button system is built on trauma-informed design principles that prioritize user safety, autonomy, and emotional well-being. Every button interaction is designed to reduce anxiety, provide clear choices, and maintain user control throughout their learning journey.
Core Principle: Buttons should feel inviting, not demanding. They provide opportunities rather than obligations, always respecting the user's agency and emotional state.
Emergency Exit
Immediate escape from potentially triggering content. Always visible, never requires confirmation.
When to use: Content warnings, difficult topics, overwhelming situations
Primary Actions
Main pathways that guide users forward in their learning journey. Uses invitational language.
When to use: Continue learning, start modules, save progress
Secondary & Tertiary
Alternative pathways and supplementary actions that provide choice without pressure.
When to use: Browse content, view details, optional actions
Trauma-Informed Design Principles
Emotional Safety: Calming colors and gentle transitions that don't startle or overwhelm users
Clear Communication: Supportive language that invites rather than demands action
User Control: Always provide escape routes and optional pathways
Accessibility: High contrast, keyboard navigation, and adequate touch targets (44x44px minimum)
Predictability: Consistent behavior and visual patterns across all interactions
Gentle Feedback: Subtle visual states that confirm actions without overwhelming
Trauma-Informed Button Language
✅ Supportive & Invitational
"Continue when you're ready"
"Explore this topic"
"Save your progress"
"Take a break"
"Return to safe space"
❌ Demanding & Pressuring
"You must complete this"
"Don't skip this step"
"Submit now"
"Click here immediately"
"Required action"
1. Emergency Exit Button System
Emergency exit buttons provide immediate escape from potentially triggering content without confirmation dialogs. They use rhodochrosite-rose color for instant recognition and are always visible.
Live Demo - Fixed Position Emergency Exit
This button is fixed to the bottom-right corner. Hover to see the tooltip, click to exit to Google.
Size Variations
Small (40px)
Compact for tight spaces
Medium (44px) - Default
Standard touch target
Large (48px)
Enhanced visibility
Extra Large (52px)
Maximum visibility
Full Width
Ideal for mobile interfaces and critical situations
Interactive States
Default
Hover
Focus
Active
Implementation Example
<!-- Emergency Exit Button with Alpine.js -->
<div class="fixed bottom-4 right-4 z-50" x-data="emergencyExit()">
<div x-data="{ hover: false }" class="relative">
<button
@mouseenter="hover = true"
@mouseleave="hover = false"
@focus="hover = true"
@blur="hover = false"
@click="exit()"
class="bg-rhodochrosite-rose hover:bg-rhodochrosite-rose-600 text-selenite-white-50 transition-all duration-300 flex items-center space-x-2 rounded-md shadow-soft"
:class="{
'px-sm py-xs text-small': window.innerWidth < 768,
'px-md py-sm': window.innerWidth >= 768
}"
aria-label="Emergency exit - Click to leave immediately"
>
<svg :class="{...}" viewBox="0 0 20 20" fill="currentColor">
<!-- X icon path -->
</svg>
<span>Emergency Exit</span>
</button>
<!-- Tooltip -->
<div x-show="hover" x-transition:enter="..." class="...">
Click to exit immediately
</div>
</div>
</div>
<!-- Initialize in JavaScript -->
<script>
Alpine.data('emergencyExit', () => ({
exit() {
window.location.href = 'https://www.google.com';
}
}));
</script>
2. Primary Button System
Primary buttons guide users through main actions and navigation paths. They use calming chrysocolla-green color to reduce anxiety and feature invitational rather than demanding language.
Live Demo - Interactive Primary Button
Click the button to see loading states, success feedback, and error handling. Hover for tooltips.
Size Variations
Small (44px min)
Compact actions
Medium (44px) - Default
Standard actions
Large (52px)
Enhanced prominence
Extra Large (60px)
Hero actions
Full Width
Perfect for forms and mobile interfaces
Interactive States
Default
Hover
Focus
Active
Disabled
Implementation Example
<!-- Primary Button with Alpine.js -->
<div x-data="primaryButton({
label: 'Continue Learning',
tooltip: 'Proceed to next section',
onClick: async () => {
// Custom action handler
await submitForm();
}
})" class="relative">
<button
@mouseenter="hover = true"
@mouseleave="hover = false"
@click="primaryAction()"
class="bg-chrysocolla-green hover:bg-chrysocolla-green-600 text-selenite-white-50 rounded-md shadow-soft transition-all duration-300 flex items-center justify-center space-x-2"
:class="{
'px-md py-sm text-base min-h-[44px]': size === 'md',
'opacity-75 cursor-wait': loading
}"
:disabled="loading"
>
<!-- Loading spinner -->
<svg x-show="loading" class="animate-spin h-4 w-4" ...></svg>
<span x-text="getButtonLabel()"></span>
</button>
<!-- Tooltip -->
<div x-show="hover && !loading" ...>
<span x-text="tooltip"></span>
</div>
</div>
3. Secondary Button System
Secondary buttons support alternative actions and pathways. They use outlined styling to provide clear visual hierarchy without aggressive styling, maintaining brand consistency through gentle hover states.
Live Demo - Interactive Secondary Button
Secondary buttons provide alternative options with subtle hover effects and processing states.
Size Variations
Small (44px min)
Compact alternatives
Medium (44px) - Default
Standard alternatives
Large (52px)
Prominent alternatives
Extra Large (60px)
Maximum alternative prominence
Full Width
Ideal for secondary CTAs and mobile interfaces
Interactive States
Default
Hover
Focus
Active
Disabled
Implementation Example
<!-- Secondary Button with Alpine.js -->
<div x-data="secondaryButton({
label: 'Save for Later',
tooltip: 'Save your progress without submitting',
onClick: async () => {
// Custom action handler
await saveProgress();
}
})" class="relative">
<button
@mouseenter="hover = true"
@mouseleave="hover = false"
@focus="focused = true"
@blur="focused = false"
@click="secondaryAction()"
class="border-2 border-chrysocolla-green text-chrysocolla-green rounded-md transition-all duration-300 flex items-center justify-center"
:class="{
'bg-chrysocolla-green-50': hover || focused,
'opacity-75 cursor-wait': processing
}"
:disabled="processing"
>
<!-- Processing indicator -->
<svg x-show="processing" class="animate-pulse h-4 w-4 mr-2" ...></svg>
<span x-text="label"></span>
</button>
<!-- Tooltip -->
<div x-show="(hover || focused) && !processing" ...>
<span x-text="tooltip"></span>
</div>
</div>
4. Tertiary/Text Button System
Tertiary buttons provide subtle actions and navigational elements with minimal visual weight. They reduce cognitive load through gentle styling while maintaining accessible touch targets and clear interaction feedback.
Live Demo - Interactive Tertiary Button
Tertiary buttons provide minimal visual weight for optional actions. Some may require confirmation.
Size Variations
Small (44px min)
Subtle links
Medium (44px) - Default
Standard text actions
Large (52px)
Prominent text actions
Extra Large (60px)
Maximum text prominence
Full Width
Perfect for information disclosure and progressive enhancement
Interactive States
Default
Hover
Focus
Active
Disabled
Implementation Example
<!-- Tertiary Button with Alpine.js -->
<div x-data="tertiaryButton({
label: 'Skip This Step',
tooltip: 'Continue without completing this section',
requiresConfirmation: true,
confirmLabel: 'Click to confirm',
onClick: () => {
// Navigate to next step
navigateToNext();
}
})" class="relative">
<button
@mouseenter="hover = true"
@mouseleave="hover = false"
@focus="focused = true"
@blur="focused = false"
@click="tertiaryAction()"
class="text-azurite-blue-600 transition-all duration-300 flex items-center justify-center space-x-2 focus:outline-none focus:ring-2 focus:ring-azurite-blue-400 focus:ring-opacity-50 rounded-sm"
:class="{
'text-azurite-blue-700': hover || focused,
'opacity-75': confirming
}"
:disabled="confirming"
>
<!-- Left-side skip arrow that slides in on hover -->
<svg
x-show="hover"
x-transition:enter="transition ease-out duration-300"
x-transition:enter-start="opacity-0 transform translate-x-[-0.25rem]"
x-transition:enter-end="opacity-100 transform translate-x-0"
class="h-5 w-5"
viewBox="0 0 20 20"
fill="currentColor"
>
<path fill-rule="evenodd" d="M10.293 5.293a1 1 0 011.414 0l4 4a1 1 0 010 1.414l-4 4a1 1 0 01-1.414-1.414L12.586 11H5a1 1 0 110-2h7.586l-2.293-2.293a1 1 0 010-1.414z" clip-rule="evenodd"/>
</svg>
<span x-show="confirming" class="text-xs opacity-75 mr-1">Confirm?</span>
<span x-text="confirming ? confirmLabel : label"></span>
</button>
<!-- Tooltip -->
<div x-show="(hover || focused) && !confirming" ...>
<span x-text="tooltip"></span>
</div>
</div>
Implementation Guidelines & Best Practices
Trauma-Informed Button Combinations
Interactive Learning Module Actions
Safe Form Submission
Share Your Learning Goals (Optional)
This information helps us personalize your experience. You can skip this and add it later.
You can always come back to complete this later
Accessibility & Testing Checklist
Technical Accessibility
Trauma-Informed Testing
Responsive Button Behavior
📱 Mobile (320px+)
• Larger touch targets: py-3 px-6 (48px height)
• Full-width buttons for primary actions
• Stacked layout for multiple buttons
• Emergency exit always accessible
📱 Tablet (768px+)
• Balanced sizing: py-2.5 px-5 (42px height)
• Side-by-side primary & secondary
• Flexible widths based on content
• Generous spacing between actions
💻 Desktop (1024px+)
• Compact sizing: py-2 px-4 (36px height)
• Inline grouping for related actions
• Hover states more prominent
• Keyboard shortcuts supported
CSS Implementation Reference
Base Button Classes
/* Base button foundation */
.btn-base {
@apply font-medium rounded-md transition-all duration-300
focus:outline-none shadow-gentle;
}
/* Responsive sizing */
.btn-sm { @apply py-1.5 px-3 sm:py-1 sm:px-2 text-sm sm:text-xs; }
.btn-md { @apply py-3 px-6 sm:py-2 sm:px-4 text-base sm:text-sm; }
.btn-lg { @apply py-4 px-8 sm:py-3 sm:px-6 text-lg sm:text-base; }
Button Variants
/* Emergency Exit */
.btn-emergency {
@apply bg-rhodochrosite-rose text-selenite-white-50
hover:bg-rhodochrosite-rose-600
focus:ring-4 focus:ring-rhodochrosite-rose-200;
}
/* Primary Action */
.btn-primary {
@apply bg-chrysocolla-green text-selenite-white-50
hover:bg-chrysocolla-green-600
focus:ring-4 focus:ring-azurite-blue-200;
}