Skip to content

UI Design: ランキング画面

機能は requirements.md、技術は design.md 参照。デザイントークンは home/ui-design.md を参照。


レイアウト

┌────────────────────────────────────────────┐
│ [← 候補者一覧へ戻る]                          │
│ 📈 候補者ランキング (display 大)              │
├────────────────────────────────────────────┤
│ 🏆 [1位] 🖼  名前        ████████ 100% 1234票│  ← 行全体クリックで /candidate/[id]
├────────────────────────────────────────────┤
│ 🥈 [2位] 🖼  名前        ██████  75%  925票  │
├────────────────────────────────────────────┤
│ 🥉 [3位] 🖼  名前        █████   60%  740票  │
├────────────────────────────────────────────┤
│ 🏅 [4位] 🖼  名前        ████    45%  555票  │
└────────────────────────────────────────────┘

最大幅: max-w-4xl mx-auto px-6

本画面は閲覧専用(要件で明示)。各行に投票ボタンは配置しない。投票したい場合は行全体をクリック → 候補者詳細画面 (/candidate/[id]) へ遷移し、そこで投票する。


コンポーネント別ビジュアル仕様

<RankingHeader>

  • flex items-center gap-3
  • TrendingUp アイコン (gold, 7×7)
  • タイトル「候補者ランキング」: display フォント、clamp(2rem, 4vw, 3rem)、weight 500

<RankingItem> (共通)

  • rounded-2xl p-5flex items-center gap-4
  • 行全体を <Link href={\/candidate/${candidate.id}`}> でラップ。hover で軽く浮き上がる(shadowを強める /-translate-y-0.5`)
  • フォーカスリング表示(focus-visible:ring-2 focus-visible:ring-[var(--gold)])、aria-label に「{name} の詳細を見る」を付与
  • 内部構造(左→右):
    1. 順位アイコン(円形背景に Trophy/Medal/Award)
    2. 順位バッジ + 候補者名(縦並び)
    3. 候補者画像(円形 or 角丸サムネ、64×64、alt={candidate.name})
    4. 得票率バー + 得票率テキスト + 得票数テキスト(縦並び)

順位別装飾

1位

項目
背景linear-gradient(135deg, rgba(212, 175, 55, 0.15), rgba(232, 180, 168, 0.15))
枠線2px solid var(--gold)
0 8px 30px rgba(212, 175, 55, 0.3)
アイコンTrophy (gold, 8×8)
バッジ背景var(--gold)
バッジ文字white
バー色var(--gold)

2位

項目
背景linear-gradient(135deg, rgba(192, 192, 192, 0.12), rgba(220, 220, 220, 0.12))
枠線2px solid #C0C0C0
0 6px 25px rgba(192, 192, 192, 0.2)
アイコンMedal (silver #C0C0C0, 7×7)
バッジ背景#C0C0C0
バー色#C0C0C0

3位

項目
背景linear-gradient(135deg, rgba(205, 127, 50, 0.12), rgba(230, 160, 120, 0.12))
枠線2px solid #CD7F32
0 6px 25px rgba(205, 127, 50, 0.2)
アイコンMedal (bronze #CD7F32, 7×7)
バッジ背景#CD7F32
バー色#CD7F32

4位以降

項目
背景white
枠線1px solid rgba(212, 175, 55, 0.2)
0 2px 10px rgba(0, 0, 0, 0.05)
アイコンAward (gold-light opacity 0.6, 6×6)
バッジ背景rgba(212, 175, 55, 0.2)
バッジ文字gold-dark
バー色var(--gold-light)

<VoteShareBar>

  • 高さ 6px、rounded-full、背景 gray-200
  • 内側バー: rounded-full、幅 share * 100% (share = maxVotes > 0 ? votes / maxVotes : 0)
  • アニメーション: 幅変更を transition-all duration-700 ease-out
  • バー上部に得票率 % と票数を並列表示
  • エッジケース: 全員 0 票(maxVotes === 0)のときは全行 share = 00% / 0票 表示。色だけに依存させず必ずテキストでも値を提示する(steering の WCAG AA 規約)

アニメーション

要素プロパティtiming
ヘッダー初期表示opacity, y(-20→0)duration 0.6s
各 RankingItem 初期表示opacity, x(-30→0)delay 0.1 + i*0.08s
バー幅(初期表示時)width transition700ms ease-out
行 hovershadow + -translate-y-0.5200ms ease-out

投票導線は本画面に存在しないため、投票後の順位変動アニメ(motion layout)は使用しない。


レスポンシブ

モバイル

  • アイテム内部は横並び維持(順位アイコン → 名前 → 画像 → バー)
  • バーが極端に細くならないよう、幅 100% を確保しつつ右端に得票率 % と票数を縦積みで表示
  • 順位アイコン縮小 (40×40)、画像も 48×48 に縮小

デスクトップ

  • 1 行レイアウト、得票率バーは中央〜右に配置

関連

  • requirements.md / design.md
  • ../home/ui-design.md — 共通デザイントークン