Primitive Token
primitiveセマンティック層から参照される生のスケール。コンポーネントから直接は使わないこと。
概要
Tailwind ベースのカラースケール。50〜950 の最大 11 段階。
ブランドカラー
brand-green と brand-yellow は relay 固有のカスタム。
鉄則
この層は直接コンポーネントに使わない。セマンティック層の参照先として使用する。
color
9 系統 × 11 段階 + white / black
brand-green / brand-yellow は relay 固有。slate / red / amber / green / blue は Tailwind 標準と一致。
opacity
CSS: opacity-*
0 から 100 まで 5% 刻みの 21 段階。市松模様の上に blue/600 を重ねて表示。
0
5
10
15
20
25
30
35
40
45
50
55
60
65
70
75
80
85
90
95
100
font
size / weight / leading / tracking / family / style
タイポグラフィの基本ユニット。組み合わせて semantic 層の型を作る。
size
xs
12px
sm
14px
base
16px
lg
20px
xl
24px
2xl
32px
3xl
40px
weight
thin
100
extralight
200
light
300
normal
400
medium
500
semibold
600
bold
700
extrabold
800
black
900
leading
Text
Text
4
16px
Text
Text
6
24px
Text
Text
8
32px
Text
Text
10
40px
Text
Text
12
48px
tracking
tighter
-0.05em
tight
-0.025em
normal
0em
wide
0.025em
wider
0.05em
widest
0.1em
family
事業承継をオープンに
Noto Sans JP
style
normal
italic
Semantic Token
semantic用途・役割で定義したトークン。コンポーネントは必ずこの層を参照する。
ステータス
7 系統 × 11 段階 — 用途で色を選ぶ
primary / secondary は relay ブランドの 2 色、それ以外は意味ベース(成功・警告・エラー・情報・中立)。
背景
CSS: bg-*
ページ全体・サーフェス・オーバーレイの 3 レイヤー構造。
レイヤー構造
- overlay (最前面)
- surface
- page / page-green
テキスト
CSS: text-*
優先度 (high / middle / low) と用途固有 (placeholder / disabled)、ダーク背景用の inverse。
light
inverse (dark background)
境界線
CSS: border-*
階層に応じて 3 段階。inverse はダーク背景の上で使う。
light
inverse
タイポグラフィー
Math.ceil((size × 1.3) / 8) × 8
8 の倍数の行間で 8×8 ベースグリッドに揃える。weight は body サイズが medium、display サイズが bold(font-bold / font-medium で上書き可)。
.typo-xsmall
medium
日本語 にほんご ニホンゴ 0123 1行目
日本語 にほんご ニホンゴ 0123 2行目
.typo-small
medium
日本語 にほんご ニホンゴ 0123 1行目
日本語 にほんご ニホンゴ 0123 2行目
.typo-medium (base)
medium
日本語 にほんご ニホンゴ 0123 1行目
日本語 にほんご ニホンゴ 0123 2行目
.typo-large
medium
日本語 にほんご ニホンゴ 0123 1行目
日本語 にほんご ニホンゴ 0123 2行目
.typo-xlarge
medium
日本語 にほんご ニホンゴ 0123 1行目
日本語 にほんご ニホンゴ 0123 2行目
.typo-2xlarge
bold
日本語 にほんご 0123 1行目
日本語 にほんご 0123 2行目
.typo-3xlarge
bold
日本語 にほんご 0123 1行目
日本語 にほんご 0123 2行目
余白
CSS: p-* / m-* / gap-* / space-*
8px グリッドを基本単位とする 9 段階。spacing/N は Tailwind の p-N / m-N / gap-N 等に対応。
spacing/0
p-0 / m-0 / gap-0
spacing/1
p-1 / m-1 / gap-1
spacing/2
p-2 / m-2 / gap-2
spacing/3
p-3 / m-3 / gap-3
spacing/4
p-4 / m-4 / gap-4
spacing/6
p-6 / m-6 / gap-6
spacing/8
p-8 / m-8 / gap-8
spacing/12
p-12 / m-12 / gap-12
spacing/16
p-16 / m-16 / gap-16
※ 8 の倍数を基本(2, 4, 8, 16, 24, 32, 48, 64)、spacing/3 = 12 と spacing/1 = 4 は微調整用。
角丸
CSS: rounded-*
none / xs / sm / md / lg / full の 6 段階。full はピル / 円形用。
rounded-none
なし
rounded-xs
細部
rounded-sm
小
rounded-md
中
rounded-lg
外側
rounded-full
ピル・円形
ヒエラルキー
入れ子では外側ほど大きく、内側ほど小さく揃える(lg → md → sm → xs)と、角が同心円状になって整って見える。
- 外側 → lg (24)
- 中 → md (16)
- 小 → sm (8)
- 細部 → xs (4)
- 中心 → full (●)
ドロップシャドウ
CSS: shadow-*
none / sm / md / lg の 4 段階+focus-ring / destructive のリング用 2 種。
none
no shadow
sm
0 1 3 · 10%
md
2 layers · 5%
lg
2 layers · 5%
focus-ring
0 0 0 3 · info/600
destructive
0 0 0 3 · negative/500
Icons
foundation
Lucide から 38 アイコンを SVG sprite として同梱(dist/icons.svg / npm export @light-right/design-system/icons)。JS 不要、currentColor で着色追従。
サイズ
.icon-xs (12) / .icon-sm (16) / .icon-md (20) / .icon-lg (24) / .icon-xl (32)
着色
currentColor を継承するので text-* ユーティリティで色付け可能
同梱されているアイコン
アイコンが足りない場合は scripts/build-icons.mjs の ICONS 配列に追加
使い方
consumer のプロダクトコードから
Vite / Next.js 等のバンドラ
import iconsUrl from "@light-right/design-system/icons";
<svg class="icon icon-md">
<use href={`${iconsUrl}#lucide-search`} />
</svg>
vanilla HTML
<svg class="icon icon-md"> <use href="./node_modules/@light-right/design-system/dist/icons.svg#lucide-search"></use> </svg>
ラベルコントロール
componentフォーム項目の上に置く、ラベル + バッジ + サポートテキストのセット。
size
default (label 16) / small (label 14)
default
サポートテキスト
small
サポートテキスト
バッジ
ラベルに付与できる 5 種
label-badge-required
赤の outlined
label-badge-optional
グレーの outlined
label-badge-disabled
塗りグレー
label-badge-private
白+グレー枠
label-badge-support
warning 系 + アイコン
使用例
input と組み合わせて
ログインに使用します
他のユーザーにも見えます
インプット
componentプロパティ: size × state × isInvalid
size × state
valid (isInvalid=false)
isInvalid=true
bg negative/50 · border 2px negative/500 (hover 600 / disabled 200)
使用例
Label Control と組み合わせて
ログインに使用します
8文字以上で入力してください
インプット(検索)
componentsmall サイズは検索アイコンのみ、medium / large は 検索ボタン 付き。入力済みのときは × でクリア。
size × state
valid (isInvalid=false)
isInvalid=true
bg negative/50 · border 2px negative/500
セレクター
componentネイティブ <select> をラップして、左アイコン・chevron・状態色を統一したコンポーネント。プロパティ: size × state × isInvalid × icon
size × state
valid · with icon
isInvalid=true
bg negative/50 · border 2px negative/500
icon: true / false
左アイコン slot は任意。省略すると text only.
icon: false
icon: true (場所)
テキストエリア
component複数行入力欄。プロパティ: size × state × isInvalid。エラーテキスト+文字カウンターを下に併設。
size × state
valid · maxlength=100
isInvalid=true
bg negative/50 · border 2px negative/500 · エラーテキスト+赤いカウンター
使用例
入力するとカウンターがリアルタイム更新
100文字以内で記入してください
改善のヒントを教えてください
チェックボックス
componentプロパティ: size × body (none / checked / indeterminate) × state × isInvalid
body × state
size = medium · isInvalid=false
isInvalid=true
境界線 / 塗りつぶしが negative 系
size
small (16) / medium (24)
small
medium
standalone checkbox
周りに他のチェックボックスは存在せず、視覚的に独立した専用のコンテナ内に配置される。
checkbox list
checkbox list では、それぞれのチェックボックスは独立して機能する。
nested checkbox
親チェックボックスの一部の子が選択されていれば、親チェックボックスは「不確定」状態になり、ハイフンで表示される。
NG パターン
チェックボックスのレイアウト原則チェックボックスを横並びで使用することは避けてください。視線が左右に飛び、選択肢同士のグルーピングが弱くなる上、選択肢の追加・改行で崩れやすくなります。
チェックボックスは縦並びで配置する。1 視線で全選択肢を上から下へ走査でき、選択肢が増えても自然に拡張できる。
ラジオボタン
componentプロパティ: size × body (none / checked) × state × isInvalid
body × state
size = medium · isInvalid=false
isInvalid=true
境界線 / 内側のドットが negative 系
size
small (16) / medium (24)
small
medium
使用例
Label Control と組み合わせて
設定はあとから変更できます
NG パターン
ラジオボタンのレイアウト原則ラジオボタンを横並びで使用することは避けてください。視線が左右に飛び、選択肢同士のグルーピングが弱くなり、選択肢の追加・改行で崩れやすくなります。
ラジオボタンは縦並びで配置する。1 視線で全選択肢を上から下へ走査でき、選択肢が増えても自然に拡張できる。
フィルターチップ
componentプロパティ: isSelected × state (enable / hover / disabled)
タグや単語を用いてコンテンツをフィルタリングするためのコンポーネント。
isSelected × state
未選択 / 選択 × enable / hover / disabled
使用例
複数チップを並べたフィルター UI — クリックで選択 / 解除をトグル
タブ
componentプロパティ: variant (solid / line) × isSelected × state (enable / hover / focus / disabled)
ユーザーが扱う情報をシンプルに保つためのディスクロージャー。
solid × state
isSelected: false / true × enable / hover / focus / disabled
line × state
isSelected: false / true × enable / hover / focus / disabled (count 表示は line variant のみ)
使用例 — solid
クリックで isSelected をトグル(兄弟同士の選択を排他にする JS は data-tabgroup で対応)
使用例 — line (with count)
タブ右側に件数バッジ。tab-count 要素を含めるだけ
シンプルテーブル
component
プロパティ: th(ラベル列、neutral/50 背景・bold)×
td(値列、white 背景・regular)。
必要に応じて rowspan で複数行をマージできる。
ユーザーが扱う情報を整理して縦に並べる、キー/バリュー形式のシンプルなテーブル。
基本
th が左の固定列(128px)、td が右の伸縮列
| プロジェクト名 | Relay Design System |
|---|---|
| 担当者 | 山田 太郎 |
| 作成日 | 2026-06-01 |
| ステータス | 進行中 |
| カテゴリ | UI / Design |
セル merge (rowspan)
複数行の th に対して 1 つの td を rowspan="N" で被せる
| 名前 | Aプロジェクト |
|---|---|
| 関連リンク | リンクテキスト |
| タグ A | |
| タグ B | |
| タグ C |
使用例 — td 内に任意の UI
td にバッジ、ボタン、リンク等を入れられる
| ステータス | 公開中 |
|---|---|
| 優先度 | 高 |
| 担当者 | 山田 太郎 |
| アクション |
Card
プロジェクト A
最終更新: 2026-05-25
これは標準的なカードです。ヘッダー・本文・フッターを持ちます。
Elevated カード
影付きのシンプルなレイアウト。
Badge
アラート
component画面内に直接埋め込む静的なインラインメッセージ。プロパティ: thema (neutral / success / negative / warning / info)
5 つのテーマ
インフォメーションタイトル
補足分が入ります。
インフォメーションタイトル
補足分が入ります。
インフォメーションタイトル
補足分が入ります。
インフォメーションタイトル
補足分が入ります。
インフォメーションタイトル
補足分が入ります。
バリエーション
タイトルのみ / 補足のみ / 閉じるボタン付き
保存しました
スマートフォンをお持ちでない場合は、お問い合わせからご連絡ください。別の方法をご案内します。
送信に失敗しました
時間をおいて再度お試しください。
NG パターン
チェックボックス / ラジオの設計ガイドライン複数選択なのに ◯ を使う
形状を入れ替えたり独自シェイプにすると、何個選べるのか直感的に判断できなくなる。
複数=□ チェック、単一=◯ ラジオ
形状で「複数選択可」「単一選択」が一目でわかる。標準を守ることが最大の親切。
見出し無しで複数グループを並列に
どこまでが 1 グループか判別できず、誤選択や混乱の原因に。
見出しと余白で明確に区切る
配送方法
支払方法
fieldset/legend や Label Control で囲い、別グループは余白で離す。
否定形のラベルで二重否定が発生
「チェックする = 受け取らない」のような二重否定はユーザを混乱させる。
能動的・肯定的に書く
チェック = 効く側に意味を寄せる。結果が明快になる。
3 個の選択肢を dropdown に隠す
クリックして開くまで選択肢が見えず、比較もしづらい。
少数 (2〜7) は radio で並べる
全選択肢が同時に見え、クリック数も減る。8 個以上ならドロップダウンを検討。
何も選択されていない初期状態
「常に 1 つ選ばれている」という radio の規約を破ってしまう。
最も安全 / 標準的な値を初期選択
ユーザの 80% が選ぶ値をデフォルトに。空状態が必要ならトグル等を検討。
想定したケースだけで網羅性が低い
該当なしのユーザは適当な選択肢を選ぶしかなく、データが歪む。
「その他」を最後に置く
「その他」選択時は自由入力欄を表示するとデータの質も上がる。
input だけクリック可、ラベルは別要素
小さな box しかクリックターゲットがなく、フィッツの法則を無視。スマホで特に押しにくい。
<label> でラップ
テキスト部分をクリックしても切り替わる。.checkbox-label / .radio-label で本デザインシステムは自動対応。
input だけ、ラベル関連なし
<input type="checkbox">
<span>Mail</span>
スクリーンリーダーが選択肢名を読み上げず、Tab で辿る順序も保証されない。
<label> + accesskey
<label>
<input type="checkbox" accesskey="m">
<u>M</u>ail
</label>
キーボード操作と支援技術の両方に対応。Native input + <label> でほぼ自動。
クリックで即フォーム送信
(選択した瞬間に切替・送信)
誤クリックがそのまま意図しないアクションに繋がり、取り消しが効かない。
選択 → 確定用ボタンでアクション
設定変更だけにとどめ、画面遷移や送信は ボタン で。ユーザの意志を待つ。
Web Accessibility
WCAG 2.1 AAA に向けてRelay Design System は WCAG 2.1 Level AAA を目指す設計です。コンポーネントを使うだけで自動的に担保される項目と、プロダクト側で実装が必要な項目を切り分けて把握できるようにしています。全 28 達成基準の実務チェックリストは docs/ACCESSIBILITY.md を参照してください。
✅ デザインシステムが担保する項目
標準コンポーネントを使うだけで自動的に満たされる WCAG 基準
-
コントラスト 7:1 以上 (1.4.6)
—
text-fg-high≈ 18:1 /text-fg-middle≈ 10.7:1 -
キーボード操作 (2.1.3)
— 全 interactive 要素に
:focus-visible+--shadow-focus-ring -
ARIA 状態 (4.1.2)
—
aria-pressed/aria-selected/disabledベースで状態を表現 - 閃光・点滅なし (2.3.2) — 1 秒 3 回以上の明滅は含まれていない
- 入力モダリティ非依存 (2.5.6) — キーボード / マウス / タッチすべてに対応
🔧 プロダクト側で実装が必要な項目
DS では担保しきれない、プロダクト固有の責務
- 動画・音声コンテンツ (1.2.6-9) — 手話通訳 / 拡張音声解説 / トランスクリプトの提供
-
フォーム属性とランドマーク (1.3.6)
—
autocomplete属性 /<header><nav><main>の配置 -
prefers-reduced-motion (2.3.3)
—
@media (prefers-reduced-motion: reduce)でアニメーション抑制 - セッションタイムアウト警告 (2.2.6) — 切断 20 秒以上前のモーダル警告と延長手段
- 具体的なリンク文言 (2.4.9) — 「こちら」「more」を避け、行き先を文言に含める
- 重要操作の確認ダイアログ (3.3.6) — 削除 / 課金など取消困難な操作には確認画面または undo を提供
ターゲットサイズ 44 × 44 CSS px には lg を使う (2.5.5)
WCAG AAA はポインタターゲットに 44 × 44 px 以上を要求します。.btn-md / .icon-btn-md / .input-md は 40px なので不足します。AAA を目指す画面では btn-lg / icon-btn-lg / input-lg を選んでください。
検証ツール
AAA は自動チェックだけでは検出しきれない項目が多い
自動チェック
- axe DevTools — ARIA / コントラスト
- Lighthouse — Accessibility スコア
- WAVE — 視覚的なエラーマップ
- WebAIM Contrast Checker
手動チェック
- キーボードのみで全操作 (Tab / Enter / Esc / 矢印)
- スクリーンリーダー (NVDA / VoiceOver / TalkBack)
- 200% ズームで横スクロール無しに読めるか
- OS の「視差効果を減らす」設定でアニメ確認