Skip to content

スタイリングガイド

本アプリケーションのデザインは、学術書らしい上品さ雑誌のような洗練されたレイアウトを融合させた「Editorial Academic Elegance」をコンセプトとしています。

主な特徴:

  • 大胆な余白の使用
  • 視覚的階層の明確化
  • 読みやすさを重視したタイポグラフィ
  • 品のあるアニメーション効果

アプリケーション全体で使用するカラーパレットは、Tailwindの@themeディレクティブでCSS変数として定義されています。

@theme {
--color-rs-bg: #fafcfd; /* 背景色(ごく淡い) */
--color-rs-bg-white: #ffffff; /* 背景色(純白) */
--color-rs-text-primary: #0a1f26; /* メインテキスト(非常に濃い青緑) */
--color-rs-text-secondary: #2d4a54; /* セカンダリテキスト */
--color-rs-accent: #009d9a; /* アクセント/リンク(ティール) */
--color-rs-accent-light: #3ddbd9; /* 明るめティール(ボタンやハイライト用) */
--color-rs-accent-pale: #e6f7f7; /* 淡いティール(背景用) */
--color-rs-border: #d8e5e8; /* ボーダー */
}

Tailwindのユーティリティクラスまたは@applyディレクティブで使用できます。

  • 背景: bg-rs-bg または bg-rs-bg-white
  • 見出し: text-rs-text-primary
  • 本文: text-rs-text-primary または text-rs-text-secondary
  • リンク・ボタン: text-rs-accent または bg-rs-accent
  • 装飾的な背景: bg-rs-accent-pale
  • ボーダー: border-rs-border

/* Google Fonts から読み込み */
@import url('https://fonts.googleapis.com/css2?family=Crimson+Pro:wght@400;600;700&family=Noto+Serif+JP:wght@400;600;700&family=Noto+Sans+JP:wght@400;500;600&display=swap');
用途フォントファミリー
タイトル・見出し'Crimson Pro', 'Noto Serif JP', serifページタイトル、セクション見出し
本文(日本語)'Noto Sans JP', sans-serif説明文、メタ情報
本文(セリフ体)'Noto Serif JP', serif引用、特別な強調
  • 超大見出し (h1): 3.5rem (56px) デスクトップ / 2.25rem (36px) モバイル
  • 大見出し (h2): 2.25rem (36px) デスクトップ / 1.5rem (24px) モバイル
  • 中見出し (h3): 1.125rem (18px)
  • 本文: 1.0625rem (17px) 基本 / 0.875rem (14px) 補助情報
  • 小サイズ: 0.875rem (14px) ラベル、タグなど

すべてのカスタムクラスにはapp-プレフィックスが付いています。

ページ全体のコンテナ。カテゴリー、サブカテゴリー、分野一覧ページで使用。

<div class="app-fields-container">
<!-- ページ全体のコンテンツ -->
</div>

書籍詳細ページ全体のコンテナ。

<div class="book-show-container">
<!-- ページ全体のコンテンツ -->
</div>

カテゴリー・分野一覧ページのヒーローセクション。グラデーション背景付き。

ヒーロー内のコンテンツコンテナ。

大きなページタイトル(56px→36pxレスポンシブ)。

<div class="app-fields-hero">
<div class="app-fields-hero-content">
<h1 class="app-fields-title">カテゴリー</h1>
<p class="font-sans text-lg text-rs-text-secondary mt-4 leading-relaxed">
興味のあるカテゴリーを選択してください
</p>
</div>
</div>

ページ上部のヒーローセクション(グラデーション背景付き)。

ヒーロー内のコンテンツ。デスクトップではグリッドレイアウト。

<div class="hero-section">
<div class="hero-content">
<div class="hero-text"><!-- タイトル等 --></div>
<div class="hero-image"><!-- 画像 --></div>
</div>
</div>

書籍タイトル用の大きなテキスト。

著者名やISBNなどのメタ情報用。

書籍カバー画像。ホバー時に浮き上がるエフェクト付き。

カード型コンポーネント(Category/Field)

Section titled “カード型コンポーネント(Category/Field)”

カード一覧を含むセクション全体。

カードのグリッドレイアウト(1列→2列→3列のレスポンシブ)。

個別のカード。ホバー時に浮き上がり、ボーダーカラーが変化。クリック可能なリンクとしても使用可能。

カードヘッダー(タイトルとバッジを横並び)。

カード内のタイトルテキスト。

カード内のバッジ(グラデーション背景、円形)。

カード内の説明文。

カード内のリンクボタン(使用非推奨:カード全体をリンクにする方が推奨)。

<!-- クリック可能なカード(推奨) -->
<%= link_to category_path(category), class: "app-field-card group" do %>
<div class="app-field-card-header">
<h2 class="app-field-name">代数学</h2>
<span class="app-field-book-count" title="サブカテゴリー数">5</span>
</div>
<p class="app-field-description">
環、体、群などの代数的構造を研究する分野
</p>
<div class="flex items-center gap-2 text-rs-accent text-sm font-medium mt-auto">
<span>詳しく見る</span>
<svg class="w-4 h-4 transition-transform group-hover:translate-x-1">...</svg>
</div>
<% end %>
<!-- 通常のカード -->
<article class="app-field-card">
<div class="app-field-card-header">
<h3 class="app-field-name">代数学</h3>
<span class="app-field-book-count">12</span>
</div>
<p class="app-field-description">説明文...</p>
<%= link_to "詳細を見る", field_path(field), class: "app-field-link" %>
</article>

基本のタグスタイル。

分野タグ(ティールカラー)。

キーワードタグ(白背景)。

<span class="tag tag-field">代数学</span>
<span class="tag tag-keyword">群論</span>

有識者レビューのセクション全体。

セクションタイトル用の大きな見出し。

レビューカードのグリッドレイアウト。

個別のレビューカード。左ボーダー、引用符の装飾付き。

<section class="expert-section">
<h2 class="section-title">
<span class="title-icon">💬</span>
有識者レビュー
</h2>
<div class="expert-grid">
<article class="expert-card">
<div class="expert-header">
<h3 class="expert-name">代数幾何D1</h3>
</div>
<p class="expert-text">レビュー本文...</p>
</article>
</div>
</section>

書籍詳細情報のセクション。

詳細情報カードのグリッドレイアウト。

個別の詳細情報カード。

2カラム分の幅を持つカード。

ラベルテキスト(小文字の大文字表記)。

値テキスト。

<div class="detail-card">
<dt class="detail-label">難易度</dt>
<dd class="detail-value">★★★☆☆</dd>
</div>

星評価の表示用コンテナ。

個別の星。.activeクラスで色付き。

<div class="rating-display">
<span class="rating-star active"></span>
<span class="rating-star active"></span>
<span class="rating-star active"></span>
<span class="rating-star"></span>
<span class="rating-star"></span>
</div>

合宿回数を示すバッジ(グラデーション背景)。

詳細情報のアコーディオン(<details>要素)。

アコーディオンのトリガー。

アコーディオンの中身。

詳細情報のリスト(<dl>要素)。

個別の情報項目。

<details class="camp-details">
<summary class="camp-summary">詳細を見る</summary>
<div class="camp-content">
<dl class="camp-info">
<div class="camp-info-item">
<dt>班員の構成</dt>
<dd>...</dd>
</div>
</dl>
</div>
</details>

ページ下部のナビゲーションリンクコンテナ。

ナビゲーションリンクボタン。ホバー時に浮き上がり、背景色が変化。

<nav class="app-fields-nav">
<%= link_to "キーワード一覧", keywords_path, class: "app-nav-link" %>
<%= link_to "本一覧", books_path, class: "app-nav-link" %>
</nav>

「戻る」リンクのコンテナ。

「戻る」リンク。ホバー時に左に移動するアニメーション。

矢印アイコン用のspan。

<div class="back-link-container">
<%= link_to books_path, class: "back-link" do %>
<span class="back-arrow"></span>
<span>本一覧に戻る</span>
<% end %>
</div>

データがない場合の表示。中央寄せ、白背景のカード。

<div class="app-empty-state">
<p>まだ分野がありません。</p>
</div>

主要な要素にスタッガード(遅延)アニメーションを適用しています:

  1. ページ全体: fadeIn (0.6s)
  2. ヒーローセクション: slideDown (0.8s)
  3. ヒーローテキスト: slideRight (0.8s, 0.2s遅延)
  4. ヒーロー画像: scaleIn (0.8s, 0.4s遅延)
  5. 有識者レビュー: fadeInUp (0.8s, 0.3s遅延)
  6. 書籍詳細: fadeInUp (0.8s, 0.5s遅延)

インタラクションアニメーション

Section titled “インタラクションアニメーション”
  • ホバー効果: transform: translateY(-8px) で浮き上がり
  • アコーディオン: expandDown で展開
  • リンク: 矢印が左に移動

すべてのトランジションは ease または ease-out を使用し、滑らかな動きを実現しています。


インタラクティブデザインパターン

Section titled “インタラクティブデザインパターン”

各ページで明確なアクションを促すメッセージを表示します。

<!-- カテゴリー選択ページ -->
<h1 class="app-fields-title">カテゴリー</h1>
<p class="font-sans text-lg text-rs-text-secondary mt-4 leading-relaxed">
興味のあるカテゴリーを選択してください
</p>
<!-- サブカテゴリー選択ページ -->
<!-- descriptionがあればそれを表示、なければメッセージなし(カード選択が自明) -->

カード全体がホバー時に反応し、ユーザーにクリック可能であることを示します。

  • 浮き上がり: hover:-translate-y-1
  • シャドウ拡大: hover:shadow-rs-lg
  • ボーダー色変化: hover:border-rs-accent-light
  • 矢印アニメーション: group-hover:translate-x-1

アクションボタンのバリエーション

Section titled “アクションボタンのバリエーション”

コンテキストに応じたアクションテキストを使用します。

ページアクション意図
カテゴリー一覧詳しく見るサブカテゴリーを探索
カテゴリー詳細詳しく見る分野を探索
サブカテゴリー詳細本を探す書籍一覧へ誘導
<!-- カテゴリー一覧 -->
<span>詳しく見る</span>
<!-- サブカテゴリー詳細 -->
<span>本を探す</span>

カスタムクラスとTailwindのユーティリティクラスを組み合わせて使用しています:

<!-- Tailwindのユーティリティクラスを使用 -->
<div class="flex flex-wrap gap-2 mt-6">
<!-- カスタムクラスを使用 -->
<%= link_to field.name, field_path(field), class: "tag tag-field" %>
</div>
  • レイアウト: flex, grid, gap-*
  • スペーシング: mt-*, mb-*, p-*
  • サイズ: w-*, h-*, max-w-*
  • テキスト: text-*, font-*

/* タブレット以下 */
@media (max-width: 1024px) { /* ... */ }
/* モバイル(横向き)以下 */
@media (max-width: 768px) { /* ... */ }
/* モバイル(縦向き)以下 */
@media (max-width: 480px) { /* ... */ }
  • レイアウト: グリッドから1カラムに変更
  • フォントサイズ: タイトルを小さく
  • パディング: スペースを縮小
  • 画像サイズ: 画像を小さく

1. Tailwindユーティリティクラスを使う

Section titled “1. Tailwindユーティリティクラスを使う”

新しいスタイルが必要な場合は、Tailwindのユーティリティクラスと@applyディレクティブを使用してください。

/* 悪い例 - 直接CSSプロパティを書く */
.my-element {
color: #009D9A;
padding: 8px;
border-radius: 6px;
}
/* 良い例 - @applyを使う */
.my-element {
@apply text-rs-accent p-2 rounded-md;
}

すべてのカスタムクラスにはapp-プレフィックスを付けます。

  • セクション: .app-{名前}-section
  • カード: .app-{名前}-card
  • グリッド: .app-{名前}-grid
  • コンテナ: .app-{名前}-container
  • トランジション時間: 0.2s - 0.3s (インタラクション用)
  • アニメーション時間: 0.6s - 0.8s (ページロード用)
  • イージング: ease または ease-out
  • 十分なコントラスト比を確保
  • ホバー状態を明確に
  • フォーカス状態を提供
  • キーボード操作に対応

カード型コンポーネントでは、カード全体をクリック可能にすることで、ユーザー体験を向上させます。

<!-- 推奨 -->
<%= link_to path, class: "app-field-card group" do %>
<h3 class="app-field-name">タイトル</h3>
<p class="app-field-description">説明</p>
<div class="flex items-center gap-2 text-rs-accent">
<span>詳しく見る</span>
<svg class="transition-transform group-hover:translate-x-1">...</svg>
</div>
<% end %>
<!-- 非推奨 -->
<article class="app-field-card">
<h3 class="app-field-name">タイトル</h3>
<p class="app-field-description">説明</p>
<%= link_to "詳しく見る", path, class: "app-field-link" %>
</article>

ポイント:

  • カード全体が<a>タグになる
  • groupクラスでホバー時の子要素アニメーションを制御
  • 矢印アイコンにgroup-hover:translate-x-1を使用
  • no-underlineクラスが自動適用される

技術用語(サブカテゴリー、分野一覧など)を避け、ユーザーが理解しやすい表現を使います。

<!-- 推奨 -->
<h1 class="app-fields-title">カテゴリー</h1>
<p>興味のあるカテゴリーを選択してください</p>
<!-- 非推奨 -->
<h1>サブカテゴリー一覧</h1>
<h2>分野一覧</h2>

ポイント:

  • 「サブカテゴリー」→ 見出しを削除してシンプルに表示
  • 「分野一覧を見る」→ 「詳しく見る」「本を探す」など具体的なアクション
  • データベース設計の用語をそのままUIに出さない

app/assets/
├── stylesheets/
│ ├── application.css # Sprocketsマニフェストファイル
│ ├── books.css # 書籍一覧用スタイル
│ ├── categories.css # カテゴリー一覧・詳細用スタイル(Tailwind移行済み)
│ ├── subcategories.css # サブカテゴリー詳細用スタイル(ほぼ空)
│ ├── fields.css # 分野一覧用スタイル(旧スタイル、参考)
│ ├── common.css # 共通コンポーネント(Tailwind + @apply)
│ └── books/
│ └── show.css # 書籍詳細用スタイル(旧スタイル)
└── tailwind/
└── application.css # Tailwindメインファイル(テーマ定義、インポート)

現在、スタイルシートをTailwindベースに統一中です。

✅ 移行済み:

  • common.css - カード型コンポーネント(@apply使用)
  • categories.css - カテゴリーページ(@apply使用)

⚠️ 未移行:

  • books/show.css - 書籍詳細ページ(CSS変数の重複あり)
  • fields.css - 旧スタイル(参考用)

common.cssで定義された共通カードデザインを使用してください。新しいページでカード型デザインを使用する場合は、このファイルを参考にしてください。

主な共通クラス:

  • .app-fields-container - ページ全体のコンテナ
  • .app-fields-hero - ヒーローセクション
  • .app-fields-grid - カードグリッド
  • .app-field-card - カード本体
  • .app-fields-nav - ナビゲーション
  • .app-empty-state - 空状態表示
<!-- Tailwindメインファイル(レイアウトで読み込み) -->
<%= stylesheet_link_tag "tailwind", "inter-font", "data-turbo-track": "reload" %>

app/assets/tailwind/application.cssが自動的に個別のCSSファイルをインポートします:

@import "../stylesheets/common.css";
@import "../stylesheets/books/show.css";
@import "../stylesheets/categories.css";
@import "../stylesheets/subcategories.css";