Skip to main content

Overview

This guide provides comprehensive examples of using the ZKScore React SDK in real-world applications. All examples support both ZKS IDs and wallet addresses with automatic resolution.
All examples automatically handle ZKS ID resolution, so you can use either ZKS IDs (like alice.zks) or wallet addresses. The SDK will resolve them to the appropriate format.

Complete Profile Page

Full User Profile Component

import React from 'react';
import { 
  useScore, 
  useIdentity, 
  useAchievements, 
  useScoreHistory 
} from '@zkscore/sdk-react';

function UserProfile({ identity }) {
  const { data: score, loading: scoreLoading, error: scoreError } = useScore(identity, {
    includeBreakdown: true,
    realTime: true
  });
  
  const { data: identityData, loading: identityLoading, error: identityError } = useIdentity(identity);
  
  const { data: achievements, loading: achievementsLoading, error: achievementsError } = useAchievements(identity, {
    limit: 10
  });
  
  const { data: history, loading: historyLoading, error: historyError } = useScoreHistory(identity, {
    timeframe: '30d',
    interval: 'daily'
  });

  const loading = scoreLoading || identityLoading || achievementsLoading || historyLoading;
  const error = scoreError || identityError || achievementsError || historyError;

  if (loading) return <div className="loading">Loading profile...</div>;
  if (error) return <div className="error">Error: {error.message}</div>;

  return (
    <div className="user-profile">
      <div className="profile-header">
        <div className="identity-section">
          <img 
            src={identityData?.metadata?.avatar} 
            alt={identityData?.name || identity}
            className="avatar"
          />
          <div className="identity-info">
            <h1>{identityData?.name || identity}</h1>
            <p className="address">{identityData?.address}</p>
            <p className="bio">{identityData?.metadata?.bio}</p>
          </div>
        </div>
        
        <div className="score-section">
          <div className="score-display">
            <h2>ZKScore</h2>
            <div className="score-value">{score?.total || 0}</div>
            <div className="score-breakdown">
              <div className="breakdown-item">
                <span>DeFi</span>
                <span>{score?.breakdown?.defi || 0}</span>
              </div>
              <div className="breakdown-item">
                <span>NFT</span>
                <span>{score?.breakdown?.nft || 0}</span>
              </div>
              <div className="breakdown-item">
                <span>Social</span>
                <span>{score?.breakdown?.social || 0}</span>
              </div>
            </div>
          </div>
        </div>
      </div>

      <div className="profile-content">
        <div className="achievements-section">
          <h3>Recent Achievements</h3>
          <div className="achievements-grid">
            {achievements?.earned?.slice(0, 6).map(achievement => (
              <div key={achievement.id} className="achievement-card">
                <img src={achievement.icon} alt={achievement.name} />
                <h4>{achievement.name}</h4>
                <p>{achievement.description}</p>
                <span className="rarity">{achievement.rarity}</span>
              </div>
            ))}
          </div>
        </div>

        <div className="history-section">
          <h3>Score History (30 days)</h3>
          <div className="score-chart">
            {history?.map((point, index) => (
              <div 
                key={index}
                className="chart-bar"
                style={{ 
                  height: `${(point.total / 1000) * 100}%`,
                  backgroundColor: point.total > 500 ? '#28a745' : '#ffc107'
                }}
                title={`${point.total} on ${new Date(point.timestamp).toLocaleDateString()}`}
              />
            ))}
          </div>
        </div>
      </div>
    </div>
  );
}

export default UserProfile;

CSS Styling

.user-profile {
  max-width: 1200px;
  margin: 0 auto;
  padding: 20px;
  font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
}

.profile-header {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 40px;
  margin-bottom: 40px;
  padding: 30px;
  background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
  border-radius: 16px;
  color: white;
}

.identity-section {
  display: flex;
  align-items: center;
  gap: 20px;
}

.avatar {
  width: 80px;
  height: 80px;
  border-radius: 50%;
  border: 3px solid white;
}

.identity-info h1 {
  margin: 0 0 8px 0;
  font-size: 28px;
  font-weight: 700;
}

.address {
  font-family: 'Monaco', 'Menlo', monospace;
  font-size: 14px;
  opacity: 0.8;
  margin: 0 0 8px 0;
}

.bio {
  margin: 0;
  opacity: 0.9;
}

.score-section {
  display: flex;
  align-items: center;
  justify-content: center;
}

.score-display {
  text-align: center;
}

.score-display h2 {
  margin: 0 0 16px 0;
  font-size: 18px;
  opacity: 0.9;
}

.score-value {
  font-size: 48px;
  font-weight: 700;
  margin-bottom: 20px;
}

.score-breakdown {
  display: flex;
  gap: 20px;
  justify-content: center;
}

.breakdown-item {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 4px;
}

.breakdown-item span:first-child {
  font-size: 12px;
  opacity: 0.8;
}

.breakdown-item span:last-child {
  font-size: 16px;
  font-weight: 600;
}

.profile-content {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 40px;
}

.achievements-section h3,
.history-section h3 {
  margin: 0 0 20px 0;
  font-size: 20px;
  color: #333;
}

.achievements-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
  gap: 16px;
}

.achievement-card {
  padding: 16px;
  background: white;
  border-radius: 12px;
  box-shadow: 0 2px 8px rgba(0,0,0,0.1);
  text-align: center;
  transition: transform 0.2s;
}

.achievement-card:hover {
  transform: translateY(-2px);
}

.achievement-card img {
  width: 48px;
  height: 48px;
  margin-bottom: 12px;
}

.achievement-card h4 {
  margin: 0 0 8px 0;
  font-size: 14px;
  color: #333;
}

.achievement-card p {
  margin: 0 0 8px 0;
  font-size: 12px;
  color: #666;
}

.rarity {
  display: inline-block;
  padding: 4px 8px;
  background: #e3f2fd;
  color: #1976d2;
  border-radius: 12px;
  font-size: 10px;
  font-weight: 600;
  text-transform: uppercase;
}

.score-chart {
  display: flex;
  align-items: end;
  gap: 4px;
  height: 200px;
  padding: 20px;
  background: white;
  border-radius: 12px;
  box-shadow: 0 2px 8px rgba(0,0,0,0.1);
}

.chart-bar {
  flex: 1;
  min-height: 4px;
  border-radius: 2px 2px 0 0;
  transition: opacity 0.2s;
}

.chart-bar:hover {
  opacity: 0.8;
}

.loading {
  display: flex;
  align-items: center;
  justify-content: center;
  height: 200px;
  font-size: 18px;
  color: #666;
}

.error {
  display: flex;
  align-items: center;
  justify-content: center;
  height: 200px;
  font-size: 18px;
  color: #dc3545;
  background: #f8d7da;
  border: 1px solid #f5c6cb;
  border-radius: 8px;
}

Leaderboard Component

Interactive Leaderboard

import React, { useState } from 'react';
import { useLeaderboard } from '@zkscore/sdk-react';

function Leaderboard({ category = 'all', metric = 'score' }) {
  const [timeframe, setTimeframe] = useState('30d');
  const [limit, setLimit] = useState(20);
  
  const { data: leaderboard, loading, error } = useLeaderboard({
    category,
    metric,
    timeframe,
    limit
  });

  if (loading) return <div className="loading">Loading leaderboard...</div>;
  if (error) return <div className="error">Error: {error.message}</div>;

  return (
    <div className="leaderboard">
      <div className="leaderboard-header">
        <h2>Top {category} {metric} Leaderboard</h2>
        <div className="controls">
          <select 
            value={timeframe} 
            onChange={(e) => setTimeframe(e.target.value)}
            className="timeframe-select"
          >
            <option value="7d">Last 7 days</option>
            <option value="30d">Last 30 days</option>
            <option value="90d">Last 90 days</option>
            <option value="1y">Last year</option>
            <option value="all">All time</option>
          </select>
          <select 
            value={limit} 
            onChange={(e) => setLimit(Number(e.target.value))}
            className="limit-select"
          >
            <option value={10}>Top 10</option>
            <option value={20}>Top 20</option>
            <option value={50}>Top 50</option>
            <option value={100}>Top 100</option>
          </select>
        </div>
      </div>

      <div className="leaderboard-content">
        <div className="leaderboard-list">
          {leaderboard?.rankings?.map((entry, index) => (
            <div key={entry.identity} className="leaderboard-item">
              <div className="rank">
                {index + 1}
              </div>
              <div className="user-info">
                <div className="avatar">
                  <img 
                    src={entry.avatar || '/default-avatar.png'} 
                    alt={entry.identity}
                  />
                </div>
                <div className="details">
                  <h3>{entry.identity}</h3>
                  <p>{entry.address}</p>
                </div>
              </div>
              <div className="score">
                <div className="score-value">{entry.score}</div>
                <div className="score-label">{metric}</div>
              </div>
              <div className="trend">
                {entry.trend > 0 ? '📈' : entry.trend < 0 ? '📉' : '➡️'}
              </div>
            </div>
          ))}
        </div>
      </div>
    </div>
  );
}

export default Leaderboard;

CSS for Leaderboard

.leaderboard {
  max-width: 800px;
  margin: 0 auto;
  padding: 20px;
  background: white;
  border-radius: 16px;
  box-shadow: 0 4px 20px rgba(0,0,0,0.1);
}

.leaderboard-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 30px;
  padding-bottom: 20px;
  border-bottom: 2px solid #f0f0f0;
}

.leaderboard-header h2 {
  margin: 0;
  font-size: 24px;
  color: #333;
}

.controls {
  display: flex;
  gap: 12px;
}

.timeframe-select,
.limit-select {
  padding: 8px 12px;
  border: 1px solid #ddd;
  border-radius: 8px;
  background: white;
  font-size: 14px;
}

.leaderboard-list {
  display: flex;
  flex-direction: column;
  gap: 12px;
}

.leaderboard-item {
  display: grid;
  grid-template-columns: 60px 1fr auto 40px;
  align-items: center;
  gap: 20px;
  padding: 16px;
  background: #f8f9fa;
  border-radius: 12px;
  transition: all 0.2s;
}

.leaderboard-item:hover {
  background: #e9ecef;
  transform: translateX(4px);
}

.rank {
  font-size: 24px;
  font-weight: 700;
  color: #007bff;
  text-align: center;
}

.user-info {
  display: flex;
  align-items: center;
  gap: 12px;
}

.avatar img {
  width: 40px;
  height: 40px;
  border-radius: 50%;
  border: 2px solid #ddd;
}

.details h3 {
  margin: 0 0 4px 0;
  font-size: 16px;
  color: #333;
}

.details p {
  margin: 0;
  font-size: 12px;
  color: #666;
  font-family: 'Monaco', 'Menlo', monospace;
}

.score {
  text-align: center;
}

.score-value {
  font-size: 20px;
  font-weight: 700;
  color: #28a745;
}

.score-label {
  font-size: 12px;
  color: #666;
  text-transform: uppercase;
}

.trend {
  font-size: 20px;
  text-align: center;
}

Achievement Tracker

Real-time Achievement Tracker

import React, { useState, useEffect } from 'react';
import { useAchievements, useAchievementProgress } from '@zkscore/sdk-react';

function AchievementTracker({ identity }) {
  const [selectedCategory, setSelectedCategory] = useState('all');
  const [showProgress, setShowProgress] = useState(true);
  
  const { data: achievements, loading, error } = useAchievements(identity, {
    category: selectedCategory === 'all' ? undefined : selectedCategory,
    realTime: true
  });

  const categories = ['all', 'defi', 'nft', 'social', 'trading', 'governance', 'gaming'];

  if (loading) return <div className="loading">Loading achievements...</div>;
  if (error) return <div className="error">Error: {error.message}</div>;

  return (
    <div className="achievement-tracker">
      <div className="tracker-header">
        <h2>Achievement Tracker</h2>
        <div className="controls">
          <div className="category-filter">
            <label>Category:</label>
            <select 
              value={selectedCategory} 
              onChange={(e) => setSelectedCategory(e.target.value)}
            >
              {categories.map(category => (
                <option key={category} value={category}>
                  {category.charAt(0).toUpperCase() + category.slice(1)}
                </option>
              ))}
            </select>
          </div>
          <label className="progress-toggle">
            <input 
              type="checkbox" 
              checked={showProgress}
              onChange={(e) => setShowProgress(e.target.checked)}
            />
            Show Progress
          </label>
        </div>
      </div>

      <div className="achievement-stats">
        <div className="stat">
          <div className="stat-value">{achievements?.earned?.length || 0}</div>
          <div className="stat-label">Earned</div>
        </div>
        <div className="stat">
          <div className="stat-value">{achievements?.claimable?.length || 0}</div>
          <div className="stat-label">Claimable</div>
        </div>
        <div className="stat">
          <div className="stat-value">{achievements?.inProgress?.length || 0}</div>
          <div className="stat-label">In Progress</div>
        </div>
        <div className="stat">
          <div className="stat-value">
            {achievements?.earned?.reduce((sum, a) => sum + a.points, 0) || 0}
          </div>
          <div className="stat-label">Total Points</div>
        </div>
      </div>

      <div className="achievement-sections">
        {achievements?.earned && achievements.earned.length > 0 && (
          <div className="achievement-section">
            <h3>✅ Earned Achievements</h3>
            <div className="achievement-grid">
              {achievements.earned.map(achievement => (
                <AchievementCard 
                  key={achievement.id} 
                  achievement={achievement} 
                  status="earned"
                />
              ))}
            </div>
          </div>
        )}

        {achievements?.claimable && achievements.claimable.length > 0 && (
          <div className="achievement-section">
            <h3>🎁 Claimable Achievements</h3>
            <div className="achievement-grid">
              {achievements.claimable.map(achievement => (
                <AchievementCard 
                  key={achievement.id} 
                  achievement={achievement} 
                  status="claimable"
                  identity={identity}
                />
              ))}
            </div>
          </div>
        )}

        {achievements?.inProgress && achievements.inProgress.length > 0 && (
          <div className="achievement-section">
            <h3>🚀 In Progress</h3>
            <div className="achievement-grid">
              {achievements.inProgress.map(achievement => (
                <AchievementCard 
                  key={achievement.id} 
                  achievement={achievement} 
                  status="in-progress"
                  identity={identity}
                  showProgress={showProgress}
                />
              ))}
            </div>
          </div>
        )}
      </div>
    </div>
  );
}

function AchievementCard({ achievement, status, identity, showProgress = false }) {
  const { data: progress } = useAchievementProgress(identity, achievement.id, {
    enabled: showProgress && status === 'in-progress'
  });

  const getStatusIcon = () => {
    switch (status) {
      case 'earned': return '✅';
      case 'claimable': return '🎁';
      case 'in-progress': return '🚀';
      default: return '⏳';
    }
  };

  const getRarityColor = (rarity) => {
    switch (rarity) {
      case 'common': return '#6c757d';
      case 'uncommon': return '#28a745';
      case 'rare': return '#007bff';
      case 'epic': return '#6f42c1';
      case 'legendary': return '#fd7e14';
      default: return '#6c757d';
    }
  };

  return (
    <div className={`achievement-card ${status}`}>
      <div className="achievement-header">
        <div className="achievement-icon">
          <img src={achievement.icon} alt={achievement.name} />
        </div>
        <div className="achievement-status">
          {getStatusIcon()}
        </div>
      </div>
      
      <div className="achievement-content">
        <h4>{achievement.name}</h4>
        <p>{achievement.description}</p>
        
        <div className="achievement-meta">
          <span 
            className="rarity"
            style={{ color: getRarityColor(achievement.rarity) }}
          >
            {achievement.rarity}
          </span>
          <span className="points">{achievement.points} pts</span>
        </div>

        {showProgress && progress && (
          <div className="achievement-progress">
            <div className="progress-bar">
              <div 
                className="progress-fill"
                style={{ width: `${progress.percentage}%` }}
              />
            </div>
            <div className="progress-text">
              {progress.current} / {progress.required} ({progress.percentage}%)
            </div>
          </div>
        )}

        {status === 'claimable' && (
          <button className="claim-button">
            Claim Achievement
          </button>
        )}
      </div>
    </div>
  );
}

export default AchievementTracker;

Real-world Integration Examples

DeFi Dashboard

import React from 'react';
import { useScore, useScoreHistory, useAchievements } from '@zkscore/sdk-react';

function DeFiDashboard({ identity }) {
  const { data: score } = useScore(identity, { includeBreakdown: true });
  const { data: history } = useScoreHistory(identity, { 
    timeframe: '7d', 
    interval: 'daily' 
  });
  const { data: achievements } = useAchievements(identity, { 
    category: 'defi' 
  });

  const defiScore = score?.breakdown?.defi || 0;
  const defiTrend = calculateTrend(history?.map(h => h.breakdown?.defi || 0));

  return (
    <div className="defi-dashboard">
      <div className="dashboard-header">
        <h1>DeFi Dashboard</h1>
        <div className="score-overview">
          <div className="score-display">
            <span className="score-label">DeFi Score</span>
            <span className="score-value">{defiScore}</span>
            <span className={`score-trend ${defiTrend}`}>
              {defiTrend === 'up' ? '📈' : defiTrend === 'down' ? '📉' : '➡️'}
            </span>
          </div>
        </div>
      </div>

      <div className="dashboard-content">
        <div className="metrics-grid">
          <MetricCard 
            title="Total Value Locked"
            value="$12,450"
            change="+5.2%"
            trend="up"
          />
          <MetricCard 
            title="Active Protocols"
            value="8"
            change="+2"
            trend="up"
          />
          <MetricCard 
            title="Yield Generated"
            value="$1,234"
            change="+12.8%"
            trend="up"
          />
          <MetricCard 
            title="Risk Score"
            value="Low"
            change="-0.3"
            trend="down"
          />
        </div>

        <div className="achievements-section">
          <h3>DeFi Achievements</h3>
          <div className="achievement-list">
            {achievements?.earned?.slice(0, 5).map(achievement => (
              <div key={achievement.id} className="achievement-item">
                <img src={achievement.icon} alt={achievement.name} />
                <div className="achievement-info">
                  <h4>{achievement.name}</h4>
                  <p>{achievement.description}</p>
                </div>
                <span className="points">{achievement.points} pts</span>
              </div>
            ))}
          </div>
        </div>
      </div>
    </div>
  );
}

function MetricCard({ title, value, change, trend }) {
  return (
    <div className="metric-card">
      <h4>{title}</h4>
      <div className="metric-value">{value}</div>
      <div className={`metric-change ${trend}`}>
        {change}
      </div>
    </div>
  );
}

function calculateTrend(values) {
  if (values.length < 2) return 'stable';
  const first = values[0];
  const last = values[values.length - 1];
  if (last > first * 1.05) return 'up';
  if (last < first * 0.95) return 'down';
  return 'stable';
}

export default DeFiDashboard;

NFT Portfolio Tracker

import React from 'react';
import { useScore, useAchievements } from '@zkscore/sdk-react';

function NFTPortfolio({ identity }) {
  const { data: score } = useScore(identity, { includeBreakdown: true });
  const { data: achievements } = useAchievements(identity, { 
    category: 'nft' 
  });

  const nftScore = score?.breakdown?.nft || 0;
  const nftAchievements = achievements?.earned?.filter(a => a.category === 'nft') || [];

  return (
    <div className="nft-portfolio">
      <div className="portfolio-header">
        <h1>NFT Portfolio</h1>
        <div className="nft-score">
          <span className="score-label">NFT Score</span>
          <span className="score-value">{nftScore}</span>
        </div>
      </div>

      <div className="portfolio-content">
        <div className="nft-stats">
          <div className="stat-item">
            <span className="stat-label">Collections</span>
            <span className="stat-value">12</span>
          </div>
          <div className="stat-item">
            <span className="stat-label">Total NFTs</span>
            <span className="stat-value">47</span>
          </div>
          <div className="stat-item">
            <span className="stat-label">Floor Value</span>
            <span className="stat-value">2.4 ETH</span>
          </div>
          <div className="stat-item">
            <span className="stat-label">Rarity Score</span>
            <span className="stat-value">8.7/10</span>
          </div>
        </div>

        <div className="nft-achievements">
          <h3>NFT Achievements</h3>
          <div className="achievement-grid">
            {nftAchievements.map(achievement => (
              <div key={achievement.id} className="nft-achievement">
                <img src={achievement.icon} alt={achievement.name} />
                <h4>{achievement.name}</h4>
                <p>{achievement.description}</p>
                <span className="rarity">{achievement.rarity}</span>
              </div>
            ))}
          </div>
        </div>
      </div>
    </div>
  );
}

export default NFTPortfolio;

Best Practices

1. Error Handling

import React from 'react';
import { useScore } from '@zkscore/sdk-react';

function ResilientScoreDisplay({ identity }) {
  const { data: score, loading, error, refetch } = useScore(identity);

  const handleRetry = () => {
    refetch();
  };

  if (loading) {
    return (
      <div className="loading-state">
        <div className="spinner" />
        <p>Loading score...</p>
      </div>
    );
  }

  if (error) {
    return (
      <div className="error-state">
        <div className="error-icon">⚠️</div>
        <h3>Failed to load score</h3>
        <p>{error.message}</p>
        <button onClick={handleRetry} className="retry-button">
          Try Again
        </button>
      </div>
    );
  }

  return (
    <div className="score-display">
      <h2>ZKScore</h2>
      <div className="score-value">{score?.total || 0}</div>
      <div className="score-breakdown">
        <div>DeFi: {score?.breakdown?.defi || 0}</div>
        <div>NFT: {score?.breakdown?.nft || 0}</div>
        <div>Social: {score?.breakdown?.social || 0}</div>
      </div>
    </div>
  );
}

2. Performance Optimization

import React, { memo, useMemo } from 'react';
import { useScore, useAchievements } from '@zkscore/sdk-react';

const OptimizedUserProfile = memo(function UserProfile({ identity }) {
  const { data: score } = useScore(identity, { includeBreakdown: true });
  const { data: achievements } = useAchievements(identity, { limit: 10 });

  const scoreDisplay = useMemo(() => {
    if (!score) return 'Loading...';
    return `Score: ${score.total}`;
  }, [score]);

  const achievementCount = useMemo(() => {
    return achievements?.earned?.length || 0;
  }, [achievements]);

  return (
    <div className="user-profile">
      <h2>{identity}</h2>
      <p>{scoreDisplay}</p>
      <p>Achievements: {achievementCount}</p>
    </div>
  );
});

export default OptimizedUserProfile;

3. Responsive Design

import React from 'react';
import { useScore } from '@zkscore/sdk-react';

function ResponsiveScoreCard({ identity }) {
  const { data: score, loading, error } = useScore(identity);

  if (loading) return <div className="loading">Loading...</div>;
  if (error) return <div className="error">Error: {error.message}</div>;

  return (
    <div className="responsive-score-card">
      <div className="score-header">
        <h2>ZKScore</h2>
        <div className="score-value">{score?.total || 0}</div>
      </div>
      
      <div className="score-breakdown">
        <div className="breakdown-item">
          <span>DeFi</span>
          <span>{score?.breakdown?.defi || 0}</span>
        </div>
        <div className="breakdown-item">
          <span>NFT</span>
          <span>{score?.breakdown?.nft || 0}</span>
        </div>
        <div className="breakdown-item">
          <span>Social</span>
          <span>{score?.breakdown?.social || 0}</span>
        </div>
      </div>
    </div>
  );
}

// CSS for responsive design
const styles = `
.responsive-score-card {
  padding: 20px;
  background: white;
  border-radius: 12px;
  box-shadow: 0 2px 8px rgba(0,0,0,0.1);
  margin: 20px 0;
}

.score-header {
  text-align: center;
  margin-bottom: 20px;
}

.score-value {
  font-size: 2.5rem;
  font-weight: 700;
  color: #007bff;
  margin: 10px 0;
}

.score-breakdown {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(100px, 1fr));
  gap: 16px;
}

.breakdown-item {
  display: flex;
  flex-direction: column;
  align-items: center;
  padding: 12px;
  background: #f8f9fa;
  border-radius: 8px;
}

.breakdown-item span:first-child {
  font-size: 12px;
  color: #666;
  margin-bottom: 4px;
}

.breakdown-item span:last-child {
  font-size: 18px;
  font-weight: 600;
  color: #333;
}

@media (max-width: 768px) {
  .score-value {
    font-size: 2rem;
  }
  
  .score-breakdown {
    grid-template-columns: repeat(2, 1fr);
  }
}

@media (max-width: 480px) {
  .score-breakdown {
    grid-template-columns: 1fr;
  }
}
`;

export default ResponsiveScoreCard;