Dr. G's Lab Logo

Button System

Our trauma-informed button system prioritizes emotional safety, clear communication, and user control through gentle interactions and predictable behavior patterns.

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.

1

Emergency Exit

Immediate escape from potentially triggering content. Always visible, never requires confirmation.

When to use: Content warnings, difficult topics, overwhelming situations

2

Primary Actions

Main pathways that guide users forward in their learning journey. Uses invitational language.

When to use: Continue learning, start modules, save progress

3

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.

Click to exit immediately

Size Variations

Small (40px)

Click to exit immediately

Compact for tight spaces

Medium (44px) - Default

Click to exit immediately

Standard touch target

Large (48px)

Click to exit immediately

Enhanced visibility

Extra Large (52px)

Click to exit immediately

Maximum visibility

Full Width

Click to exit immediately

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

Click to exit immediately

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;
}