Skip to content

🎴 Accessibility-First Card Components

Design Philosophy

GetCimple's card components prioritize clarity and accessibility for board directors who may:

  • Be 50+ years old with presbyopia
  • Use reading glasses
  • Review on tablets during meetings
  • Have limited time (2-3 minutes)
  • Prefer clear visual hierarchy

Card Component Specifications

Base Card Structure

<article class="gc-card" role="region" aria-labelledby="card-title-{id}">
  <header class="gc-card__header">
    <h2 id="card-title-{id}" class="gc-card__title">Card Title</h2>
    <span class="gc-card__badge" aria-label="Status">Status</span>
  </header>

  <div class="gc-card__body">
    <div class="gc-card__metric">
      <span class="gc-card__metric-value">85%</span>
      <span class="gc-card__metric-label">Complete</span>
    </div>
    <p class="gc-card__description">Brief description text</p>
  </div>

  <footer class="gc-card__footer">
    <button class="gc-card__action" aria-label="View details">
      View Details
    </button>
  </footer>
</article>

Visual Design Specifications

Typography

.gc-card {
  /* Base font size - Never below 16px */
  font-size: 16px;
  line-height: 1.6;
  font-family: 'Inter', system-ui, sans-serif;
}

.gc-card__title {
  font-size: 20px; /* 1.25rem */
  font-weight: 600;
  color: var(--gc-text-primary);
}

.gc-card__metric-value {
  font-size: 32px; /* 2rem */
  font-weight: 700;
  font-variant-numeric: tabular-nums;
}

.gc-card__metric-label {
  font-size: 14px; /* 0.875rem - Exception for labels */
  text-transform: uppercase;
  letter-spacing: 0.05em;
  color: var(--gc-text-secondary);
}

.gc-card__description {
  font-size: 16px;
  color: var(--gc-text-secondary);
}

Layout & Spacing

.gc-card {
  /* 4:3 aspect ratio for optimal scanning */
  aspect-ratio: 4 / 3;
  min-height: 240px;
  max-width: 400px;

  /* Generous padding for touch targets */
  padding: 24px;

  /* Clear visual boundaries */
  border: 2px solid var(--gc-border-default);
  border-radius: 12px;
  background: var(--gc-bg-card);

  /* Subtle elevation */
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.08);

  /* Smooth interactions */
  transition: all 0.2s ease;
}

.gc-card:hover,
.gc-card:focus-within {
  box-shadow: 0 4px 16px rgba(0, 0, 0, 0.12);
  border-color: var(--gc-border-hover);
}

.gc-card__header {
  display: flex;
  justify-content: space-between;
  align-items: flex-start;
  margin-bottom: 16px;
}

.gc-card__body {
  flex: 1;
  display: flex;
  flex-direction: column;
  gap: 12px;
}

.gc-card__footer {
  margin-top: auto;
  padding-top: 16px;
  border-top: 1px solid var(--gc-border-light);
}

Color System

Semantic Colors

:root {
  /* Status Colors - Traffic Light System */
  --gc-status-good: #10b981; /* Green */
  --gc-status-warning: #f59e0b; /* Amber */
  --gc-status-critical: #ef4444; /* Red */

  /* Informational */
  --gc-info: #3b82f6; /* Blue */
  --gc-inactive: #6b7280; /* Gray */

  /* Text Colors */
  --gc-text-primary: #111827;
  --gc-text-secondary: #4b5563;
  --gc-text-disabled: #9ca3af;

  /* Backgrounds */
  --gc-bg-card: #ffffff;
  --gc-bg-hover: #f9fafb;

  /* Borders */
  --gc-border-default: #e5e7eb;
  --gc-border-hover: #3b82f6;
  --gc-border-light: #f3f4f6;
}

/* High Contrast Mode */
@media (prefers-contrast: high) {
  :root {
    --gc-text-primary: #000000;
    --gc-text-secondary: #374151;
    --gc-border-default: #6b7280;
    --gc-status-good: #059669;
    --gc-status-warning: #d97706;
    --gc-status-critical: #dc2626;
  }
}

/* Dark Mode */
@media (prefers-color-scheme: dark) {
  :root {
    --gc-text-primary: #f9fafb;
    --gc-text-secondary: #d1d5db;
    --gc-bg-card: #1f2937;
    --gc-bg-hover: #374151;
    --gc-border-default: #4b5563;
    --gc-border-hover: #60a5fa;
  }
}

Accessibility Features

Keyboard Navigation

.gc-card:focus-visible,
.gc-card__action:focus-visible {
  outline: 3px solid var(--gc-info);
  outline-offset: 2px;
}

.gc-card__action {
  /* Large touch target (minimum 44x44px) */
  min-height: 44px;
  padding: 12px 24px;

  /* Clear interaction states */
  cursor: pointer;
  background: var(--gc-info);
  color: white;
  border: none;
  border-radius: 8px;
  font-size: 16px;
  font-weight: 500;

  transition: background 0.2s ease;
}

.gc-card__action:hover {
  background: #2563eb;
}

.gc-card__action:active {
  transform: scale(0.98);
}

Screen Reader Support

<!-- Status Badge with Context -->
<span
  class="gc-card__badge gc-card__badge--success"
  role="status"
  aria-label="Status: Compliant"
>
  <span aria-hidden="true">βœ“</span>
  Compliant
</span>

<!-- Progress Indicator -->
<div
  class="gc-card__progress"
  role="progressbar"
  aria-valuenow="85"
  aria-valuemin="0"
  aria-valuemax="100"
  aria-label="85% complete"
>
  <div class="gc-card__progress-bar" style="width: 85%"></div>
</div>

<!-- Time Estimate -->
<time class="gc-card__time" datetime="PT3M">
  <span class="sr-only">Estimated time:</span>
  3 minutes
</time>

Card Variants

1. Status Card

Used for compliance status, maturity levels, and framework progress.

<article class="gc-card gc-card--status">
  <header class="gc-card__header">
    <h2>Essential Eight</h2>
    <span class="gc-card__badge gc-card__badge--warning">ML1</span>
  </header>
  <div class="gc-card__body">
    <div class="gc-card__metric">
      <span class="gc-card__metric-value">40%</span>
      <span class="gc-card__metric-label">Current Maturity</span>
    </div>
    <div class="gc-card__target">Target: ML2 (70%)</div>
    <div class="gc-card__progress" role="progressbar">
      <div class="gc-card__progress-bar" style="width: 40%"></div>
    </div>
  </div>
  <footer class="gc-card__footer">
    <button class="gc-card__action">Review Details</button>
  </footer>
</article>

2. Action Card

For board decisions and approvals.

<article class="gc-card gc-card--action">
  <header class="gc-card__header">
    <h2>Board Decision Required</h2>
    <time class="gc-card__time">3 min</time>
  </header>
  <div class="gc-card__body">
    <p class="gc-card__highlight">
      Set target maturity level for Essential Eight
    </p>
    <ul class="gc-card__options">
      <li>ML1: Basic Protection ($50k)</li>
      <li>ML2: Industry Standard ($150k)</li>
      <li>ML3: Advanced ($400k)</li>
    </ul>
  </div>
  <footer class="gc-card__footer">
    <button class="gc-card__action gc-card__action--primary">
      Make Decision
    </button>
  </footer>
</article>

3. Metric Card

For key performance indicators.

<article class="gc-card gc-card--metric">
  <div class="gc-card__body">
    <div class="gc-card__metric gc-card__metric--large">
      <span class="gc-card__metric-value">92%</span>
      <span class="gc-card__metric-label">Compliance Score</span>
    </div>
    <div class="gc-card__trend gc-card__trend--up">
      <span aria-label="Increased by">↑ 5%</span>
      from last quarter
    </div>
  </div>
</article>

4. Summary Card

For aggregated information.

<article class="gc-card gc-card--summary">
  <header class="gc-card__header">
    <h2>Quarterly Summary</h2>
  </header>
  <div class="gc-card__body">
    <dl class="gc-card__list">
      <div class="gc-card__list-item">
        <dt>Frameworks Tracked</dt>
        <dd>5</dd>
      </div>
      <div class="gc-card__list-item">
        <dt>Overall Compliance</dt>
        <dd>85%</dd>
      </div>
      <div class="gc-card__list-item">
        <dt>Actions Required</dt>
        <dd>2</dd>
      </div>
    </dl>
  </div>
  <footer class="gc-card__footer">
    <button class="gc-card__action">View Report</button>
  </footer>
</article>

Responsive Behavior

Desktop (1200px+)

  • Cards in 3-4 column grid
  • Full aspect ratio maintained
  • Hover states enabled

Tablet (768px - 1199px)

  • Cards in 2 column grid
  • Slightly reduced padding (20px)
  • Touch-optimized interactions

Mobile (< 768px)

  • Single column stack
  • Full width cards
  • Increased touch targets (48px minimum)
  • Simplified metrics display
@media (max-width: 767px) {
  .gc-card {
    aspect-ratio: auto;
    min-height: auto;
    max-width: 100%;
    padding: 20px;
  }

  .gc-card__metric-value {
    font-size: 28px;
  }

  .gc-card__action {
    width: 100%;
    min-height: 48px;
  }
}

Animation & Transitions

/* Smooth state changes */
.gc-card {
  transition:
    box-shadow 0.2s ease,
    border-color 0.2s ease,
    transform 0.2s ease;
}

/* Progress bar animation */
@keyframes progress-fill {
  from {
    width: 0;
  }
  to {
    width: var(--progress);
  }
}

.gc-card__progress-bar {
  animation: progress-fill 1s ease-out;
  transition: width 0.5s ease;
}

/* Badge pulse for attention */
@keyframes pulse {
  0%,
  100% {
    opacity: 1;
  }
  50% {
    opacity: 0.7;
  }
}

.gc-card__badge--critical {
  animation: pulse 2s infinite;
}

Implementation Examples

React Component

interface CardProps {
  title: string
  metric?: {
    value: string | number
    label: string
  }
  status?: 'success' | 'warning' | 'critical'
  action?: {
    label: string
    onClick: () => void
  }
  timeEstimate?: number // in minutes
}

export const Card: React.FC<CardProps> = ({
  title,
  metric,
  status,
  action,
  timeEstimate,
}) => {
  return (
    <article
      className="gc-card"
      role="region"
      aria-labelledby={`card-${title}`}
    >
      <header className="gc-card__header">
        <h2 id={`card-${title}`}>{title}</h2>
        {status && <StatusBadge status={status} />}
        {timeEstimate && <TimeEstimate minutes={timeEstimate} />}
      </header>

      {metric && (
        <div className="gc-card__body">
          <div className="gc-card__metric">
            <span className="gc-card__metric-value">{metric.value}</span>
            <span className="gc-card__metric-label">{metric.label}</span>
          </div>
        </div>
      )}

      {action && (
        <footer className="gc-card__footer">
          <button
            className="gc-card__action"
            onClick={action.onClick}
            aria-label={action.label}
          >
            {action.label}
          </button>
        </footer>
      )}
    </article>
  )
}

Testing Checklist

Accessibility Testing

  • Keyboard navigation works for all interactive elements
  • Screen reader announces card content correctly
  • Color contrast meets WCAG 2.1 AA (4.5:1 for normal text, 3:1 for large text)
  • Focus indicators are visible and clear
  • Touch targets are minimum 44x44px

Visual Testing

  • Cards maintain 4:3 aspect ratio on desktop
  • Text remains readable at 200% zoom
  • High contrast mode displays correctly
  • Dark mode maintains readability
  • Responsive breakpoints work smoothly

Performance Testing

  • Cards render within 16ms (60fps)
  • Animations use CSS transforms for GPU acceleration
  • No layout shift when content loads
  • Lazy loading for off-screen cards

Conclusion

These accessibility-first card components ensure GetCimple's interface is usable by all board directors, regardless of age, ability, or device. The design prioritizes clarity, readability, and quick comprehension - essential for time-pressed executives making critical governance decisions.