コンテンツにスキップ
OmniRoute source

OmniRoute — Design System & Visual Identity (日本語)

マーケティングサイト(viral.omniroute.online、why.omniroute.online、omniroute.online)と製品ダッシュボードは、1つの製品に見えるべきです。サイトはすでにダッシュボードのパレットを取り入れており、css/tokens.cssにも「パレットはOmniRouteダッシュボード(src/app/globals.css)を反映している」と記載されています。したがって、カラーの観点では、両者はすでに約80%統一されています。ダッシュボードに不足しているものは以下のとおりです:

  1. サイトがすべてのページで使用している方眼紙風グリッド壁紙。
  2. サイトにはあるものの、ダッシュボードにはない一部の共有デザイントークン(角丸スケール、ブランドグラデーション、surface-2、等幅フォント)。
  3. コンポーネントレベルの一貫性 — 多くのダッシュボードコンポーネントが、ハードコードされたhex/rgbaを使用してテーマトークンを迂回しています。

本ドキュメントでは、分析と計画を示します。


  • 信頼できる唯一の情報源 = src/app/globals.css。 サイトがダッシュボードを反映するのであり、その逆ではありません。新しいトークンは、まずglobals.cssに追加します。
  • リテラルではなく、常にトークンを使用する。 コンポーネントでは、生の#hexではなく、セマンティックトークン(bg-surface、text-primary、border-border)を使用します。
  • 目立たせず、控えめにする。 グリッドはコンテンツの背後に配置される淡い壁紙です。テキストのコントラストを低下させたり、UIと視覚的に競合したりしてはいけません。
  • テーマ対応。 すべてが.dark(製品を象徴する外観)とライトテーマの両方で機能します。
  • 段階的かつ的確に展開する。 まずグリッドとトークン(低リスクで視認性の高い変更)をリリースし、その後、コンポーネントのクリーンアップを段階的に進めます。

3. 現状 — すでに統一されているものと、されていないもの

Section titled “3. 現状 — すでに統一されているものと、されていないもの”

すべてのブランドカラーとサーフェスは、すでにサイトと値が一致しています(異なるのは名前のみで、ダッシュボードでは--color-プレフィックスが付きます)。src/app/globals.css:30-128で確認済みです:

概念 サイトのトークン(tokens.css) ダッシュボードのトークン(globals.css) 一致
プライマリ --primary #e54d5e --color-primary #e54d5e ✅
プライマリホバー --primary-hover #c93d4e --color-primary-hover #c93d4e ✅
アクセント --accent #6366f1 --color-accent #6366f1 ✅
アクセント2 --accent-2 #8b5cf6 --color-accent-hover #8b5cf6 ✅(改名)
アクセント3 --accent-3 #a855f7 --color-accent-light #a855f7 ✅(改名)
成功 / 警告 / エラー #22c55e / #f59e0b / #ef4444 同一 ✅
トラフィックライト #ff5f56 / #ffbd2e / #27c93f 同一 ✅
ダーク背景 / サーフェス / ボーダー #0b0e14 / #161b22 / rgba(255,255,255,.08) 同一 ✅
ライト背景 / サーフェス / テキスト #f9f9fb / #fff / #1a1a2e 同一 ✅

結論: カラー移行は不要です。ビジュアルアイデンティティはすでに共有されています。これは再構築ではなく、_仕上げ_です。

3.2 ギャップ — ダッシュボードに不足しているもの

Section titled “3.2 ギャップ — ダッシュボードに不足しているもの”
ギャップ サイト側 ダッシュボード 対応
グリッド壁紙 body::before の方眼紙、--grid-line、--grid-size 32px、--section-alt ✅ 追加済み(フェーズ1) パートA
角丸スケール --radius 14px、--radius-sm 9px --radius 14px を追加済み;-sm とコンポーネントの再割り当ては保留中 パートB / フェーズ2
ブランドグラデーション --grad-brand 135deg primary→accent-3 ✅ トークン追加済み(フェーズ1);フェーズ2で使用 パートB
ネストされたサーフェス --surface-2 #1c2230 ✅ 追加済み(フェーズ1) パートB
等幅フォント --font-mono(ui-monospace スタック) 保留中(フェーズ4、使用箇所と同時に対応) パートB
text-muted(ダーク) #8b8b9e #a1a1aa(zinc-400) 調整 — パートB

3.3 テーマ設定の仕組み(既存機能を壊さないために)

Section titled “3.3 テーマ設定の仕組み(既存機能を壊さないために)”
  • Tailwind v4、CSS-first(tailwind.config.* なし)。トークンは :root/.dark で定義され、@theme inline を介してユーティリティに公開されます(globals.css:130-179)。
  • ダークモードは <html> の .dark クラスで適用され(globals.css:22 の @custom-variant dark)、カスタム Zustand ストア(src/store/themeStore.ts)によって切り替えられます。デフォルトテーマ = system(src/shared/constants/appConfig.ts:11)。一方、サイトでは html[data-theme="light"] を使用していますが、両者の仕組みは異なり、交わることはありません(オリジンが別々のため)。そのため、ダッシュボードの .dark の仕組みを維持します。
  • 実行時のプライマリカラー上書きが存在します(themeStore.ts:85-97、プリセットは COLOR_THEMES)。ユーザーは --color-primary を変更できます。--color-primary を参照する新しいトークン(グラデーションなど)も、追加対応なしでこれらの上書きを継承します。✅
  • Tailwind v4 の予約済み角丸名: --radius-sm/md/lg/... は rounded-* ユーティリティの基盤です。これらを再定義すると、既存のすべての rounded-* に遡及的な変更が加わります(例:rounded-sm は12ファイルで使用されています)。そのため、小さい角丸値の変更とコンポーネントの再割り当ては、使用箇所を同時に変更するフェーズ2まで意図的に延期します。

4. パートA — 方眼紙グリッド背景(主要要望)— 実装済み(フェーズ1)

Section titled “4. パートA — 方眼紙グリッド背景(主要要望)— 実装済み(フェーズ1)”

サイト(_mono_repo/omnirouteSite/css/base.css)とまったく同じ実装です。ビューポート全体に固定された疑似要素で2つの1pxラインのグラデーションを描画し、すべてのコンテンツの背後に z-index:-1 で配置します。

body::before {
content: "";
position: fixed;
inset: 0;
z-index: -1;
pointer-events: none;
background-image:
linear-gradient(to right, var(--grid-line) 1px, transparent 1px),
linear-gradient(to bottom, var(--grid-line) 1px, transparent 1px);
background-size: var(--grid-size) var(--grid-size);
}

body に不透明な background-color が設定されていても機能する理由: z-index:-1 を持つ ::before は、要素自体の背景よりも_上_、通常フロー内のコンテンツよりも_下_に描画されます。そのため、--color-bg がベースの塗りつぶしとなり、その上にグリッドが重なり、さらにその上にアプリがレンダリングされます。

src/app/landing/page.tsx:16-26 では、ページ単位ですでに同じグリッドが実装されています。ただし、赤色の線(#E54D5E、不透明度 0.06)を 50px 間隔で使用し、アニメーションするオーブも追加されています。したがって、このパターンはプロダクト内で実証済みです。今回の作業では、これをグローバルかつテーマ対応の壁紙へと昇格させます。

4.3 追加したトークン(globals.css 内)

Section titled “4.3 追加したトークン(globals.css 内)”
:root {
/* ライト — 密度の高いダッシュボード上でも壁紙が実際に見えるように、
サイトの0.045からグリッドの不透明度を上げて調整
(カードやクロームがビューポートの大部分を覆うため) */
--grid-line: rgba(0, 0, 0, 0.07);
--grid-size: 32px;
--section-alt: rgba(0, 0, 0, 0.022);
}
.dark {
/* ダーク — 同じ理由で0.035から上げて調整 */
--grid-line: rgba(255, 255, 255, 0.06);
--section-alt: rgba(255, 255, 255, 0.018);
}

4.4 唯一のブロッカー — 解消済み

Section titled “4.4 唯一のブロッカー — 解消済み”

グリッドは構造上グローバルです(パネル、auth/login、エラーページなど、すべてのルートを一度にカバーします)。パネル内でグリッドを隠していた要素は、厳密に1つだけでした。

  • src/shared/components/layouts/DashboardLayout.tsx — 外側のラッパーが不透明な bg-bg を描画していました。その下にある要素(<main>、スクロールコンテナ、max-w-7xl の内側要素)はすべてすでに透明です。そのため、bg-bg を削除することで、コンテンツ領域にbodyのグリッドが透けて見えるようになります(bodyの --color-bg は引き続きベースの塗りつぶしとして残ります)。

    <div className="flex h-dvh min-h-0 w-full overflow-hidden bg-bg">
    <div className="flex h-dvh min-h-0 w-full overflow-hidden">

4.5 クロームとの相互作用(サイドバー/ヘッダー)

Section titled “4.5 クロームとの相互作用(サイドバー/ヘッダー)”
  • Header(Header.tsx:207、bg-bg)と Sidebar(Sidebar.tsx:430、bg-sidebar)は不透明なままです。つまり、グリッドはコンテンツ領域にのみ表示され、その周囲を単色のクロームが囲みます。落ち着いたデフォルト表示であり、サイトがクロームとキャンバスを分離する方法とも一致します(決定D3 = 単色)。

4.6 ログイン/認証/エラーページ

Section titled “4.6 ログイン/認証/エラーページ”

これらは &lt;body&gt; の直下にレンダリングされるため(パネルクロームなし)、グローバルグリッドが自動的に背後へ表示されます。フェーズ5 — 完了: 独立したフルスクリーンラッパーは実際には不透明(min-h-screen … bg-bg。ここで bg-bg は &lt;body&gt; と同じ単色の塗りつぶし)であり、ログイン画面だけでなく、ダッシュボード以外のすべての画面でグリッドを隠していました。共有壁紙が透けて見えるように、現在はすべて透明になっています。対象は login、forgot-password、callback、maintenance、offline、status、terms、privacy、onboarding、および ErrorPageScaffold(400/401 をカバー)です。これにより、D4 が完了しました(ログイン画面のみから、すべての独立画面へ対象を拡張)。tests/unit/design-grid-background.test.ts で保護されています。

landing/page.tsx では、より表現豊かなアニメーション背景(オーブ+ビネット)を維持します。これは独自のマーケティング用スプラッシュ画面です(決定D5 = 現状維持)。


フェーズ1では、不活性で衝突のない識別用トークン(--surface-2/--color-surface-2、--grad-brand、--radius)を追加します。フェーズ2では角丸スケールをTailwindに接続してコンポーネントの参照先を変更し、フェーズ4では--font-monoとその利用箇所を追加します。

トークン 理由 フェーズ
--radius / --radius-sm 個別指定の6/8/12ではなく、単一の角丸スケール(14/9) 1(値)/ 2(接続+参照先変更)
--grad-brand サイトに合わせた、プライマリCTA用のブランドグラデーション(赤→紫) 1(トークン)/ 2(Button)
--surface-2 ネストされたパネル / テーブルヘッダー / インセット行 1
--font-mono コードブロック、ターミナル、ID、エンドポイント 4
--text-muted の調整 サイト↔パネル間で1つの値を選択(#a1a1aaを推奨) 2

D2(text-muted): サイトは#8b8b9e、ダッシュボードは#a1a1aa。**ダッシュボードの#a1a1aa**を維持し、合わせるために_サイト_側を更新することを推奨します。見た目のみの変更です。


6. パートC — コンポーネントの標準化(フェーズ2~4)

Section titled “6. パートC — コンポーネントの標準化(フェーズ2~4)”

カスタムコンポーネント(shadcn/Radix不使用)、Tailwind v4、セマンティックトークンはほぼ導入済みです(195ファイルが共有バレルをインポート)。作業内容は迂回実装の除去です。配置先:src/shared/components/。

# 項目 ファイル 問題 → 目標 フェーズ
C1 角丸の整合 Button.tsx:14-18、Card.tsx:39、Modal.tsx、Input.tsx、Select.tsx 6/8/12pxが混在 → --radius/--radius-sm(14/9) 2
C2 Buttonのグラデーション+accentバリアント Button.tsx:5-12 プライマリが単色の赤→赤。--grad-brandに合わせ、不足しているaccentバリアントを追加。約195箇所でインポート — 視認性が最も高い 2
C3 テーブル DataTable.tsx:122-176、logTableStyles.ts、globals.css:405-414 100%インライン指定されたハードコードのrgba+存在しない変数。トークンへ移行し、分岐したスタイルを廃止 3
C4 ステータスカラーの一元化 flow/edgeStyles.ts、TokenHealthBadge.tsx、DegradationBadge.tsx、ProviderCascadeNode.tsx、Badge.tsx+5個のヘルパー 同じ16進数カラーが6箇所以上に重複 → --color-success/warning/errorを基にした単一モジュール 3
C5 Cardのボーダー Card.tsx:39 border-white/5 → ブランドカラーの/8 2
C6 フォーカスリングの調整 ✅ 完了 globals.cssの--focus-ring(accent)とフォームコントロールのring-primary/30 グローバルリングに合わせ、赤いエラーリングと区別するため、**accent(紫)**に統一。エラーは赤のまま 4
C7 Checkbox+Textareaの追加 インラインのaccentColor:#6366f1を持つ生の&lt;input&gt;/&lt;textarea&gt; トークン駆動のプリミティブ 4
C8 ハードコードされた16進数カラーの一括除去 ConsoleLogViewer.tsx:240、ComboLiveStudio.tsx:306、Modalのドット、約14個のチャートファイル リテラル → トークン 4
C9 cn() → clsx+tailwind-merge src/shared/utils/cn.ts 競合するクラスが積み重なる。C1のオーバーライドに必要 2

すでにブランド準拠(トークン駆動で、必要なのは角丸のみ): Badge、Toggle、SegmentedControl、Input、Select。


  • フェーズ1 — グリッド + アイデンティティトークン(このPR)。 globals.css のグリッド + --surface-2/--grad-brand/--radius トークン、body::before の壁紙、妨げとなっていた bg-bg の削除、静的ガードテスト。低リスクで、1コミットで元に戻せます。
  • フェーズ2 — プリミティブ(C1、C2、C5)— このPRで完了。 セマンティックな角丸ユーティリティ rounded-card(14px)/ rounded-control(9px)を @theme 経由で追加(カスタム名のため、デフォルトの rounded-sm/md/lg/xl は変更されず、400ファイル規模の影響はありません)。Card/Modal → 14px、Button/Input/Select → 9px、Button の primary → --grad-brand(赤→バイオレット)+ 新しい accent バリアント、Card のボーダー → border-border トークン(0.08)。延期: cn()→tailwind-merge(C9)には新しい依存関係が必要です。場当たり的な rounded-lg の一括変更(326ファイル)は、プリミティブがサーフェスの大部分を担っているため、現状のままとします。
  • フェーズ3 — ステータスカラー + テーブル(C3、C4)— このPRで完了。 ✅ C4(src/shared/constants/statusColors.ts — STATUS_HEX を単一の情報源に統一。flow/edgeStyles.ts + TokenHealthBadge の参照先を変更し、同一の忠実な hex を維持)。✅ --font-mono トークン。✅ C3(DataTable) — すべてのインライン rgba と、機能していなかった var(--bg-table-header) / var(--text-secondary) のフォールバックを、--table-* トークンセット(--table-header-bg/-row-zebra/-row-hover/-cell-border/-row-selected)に置き換えました。dark の値は従来のハードコードされた rgba と完全に同一(dark はバイト単位で同一)で、light の値により、従来は常に暗くなっていたライトテーマを修正しています。ヘッダーのボーダー → --color-border、セカンダリテキスト → --color-text-muted。マージ前にビジュアル確認が必要です。(未変更: logTableStyles.ts とレガシーな Ant の .ant-table ルール。これらは別件で、優先度は低めです。)
  • フェーズ4 — クリーンアップ(C6、C7、C9は完了、C8は保留中)。 ✅ C9 cn() → twMerge(clsx(...))(clsx + tailwind-merge を依存関係として追加)— 呼び出し元の className が、競合するプリミティブのクラスと重複するのではなく、正しく_置き換える_ようになりました。✅ C7 新しい Checkbox + Textarea プリミティブ(トークン駆動で、barrel からエクスポート。追加のみの変更であり、32個の生の checkbox / 41個の生の textarea は段階的に移行できます)。✅ C6 フォーカスリングの整合 — フォームコントロール(Input/Select/Textarea/Toggle/Checkbox)は、グローバルな --focus-ring と一致し、赤いエラーリングとの競合を避けるため、フォーカス時に accent(バイオレット) のリングを使用するようになりました。赤いエラー状態は変更されていません。⏳ C8のhex一括置換は、無差別な検索・置換ではありません — _意図的_で維持すべき箇所として確認済みのもの: ConsoleLogViewer.tsx:240(常にdarkのターミナル)、TokenHealthBadge のポップオーバー、ReactFlow のSVGストローク。テーマ対応を意図したhexのみを移行します。

各フェーズ: npm run lint + npm run typecheck:core + ビジュアル確認。


  • D1 — Button の primary: 赤→赤を維持するか、赤→バイオレットの --grad-brand に切り替えるか? 推奨: 赤→バイオレット(フェーズ2)。
  • D2 — グリッド線の色: ブランドの赤ではなく、neutral(サイトのスタイル)を選択。サイズは 32px(オーナーのフィードバックを受け、元の46pxから約30%縮小。46pxのセルはダッシュボードレイアウトでは大きすぎる印象でした)。
  • D3 — Chromeの鮮やかさ: サイドバー/ヘッダーは solid を選択。
  • D4 — 認証/ログインのグリッド: ✅ 完了(フェーズ5) — ログインだけでなく、独立したすべてのフルスクリーンラッパーから不透明な bg-bg を削除し、すべての画面でグリッドが表示されるようにしました。§4.6を参照してください。
  • D5 — ランディングページ: アニメーション付きスプラッシュは現状のまま維持。選択済み。
  • D6 — 製品全体で角丸を14/9に統一: 推奨: はい(フェーズ2)。
  • D7 — フェーズ1を先にリリース: 選択済み。
  • D8 — レイアウト幅(フェーズ5): ダッシュボードのコンテンツシェルは max-w-7xl(1280px)に制限されていたため、大型モニターでは中央寄せになり、左右に広い空白が生じていました。✅ 完了 — 流動的な max-w-[3840px](真の4K)に引き上げました。コンテンツは約4Kまでビューポートに追従し、それを超えた場合にのみ中央寄せされます(DashboardLayout.tsx)。意図的に幅を狭くしているページは、設計どおり狭いままです(ProviderOnboardingWizard は max-w-5xl、Rtk/CavemanContextPageClient は max-w-6xl)。
  • D9 — 不透明なデータテーブル(フェーズ6): ダッシュボードのコンテンツ領域が透明になり(フェーズ5でグリッド壁紙が透けて見えるようになったため)、コンテナが不透明なサーフェスではないデータテーブルでは、透明な偶数行 / 低アルファのゼブラ行からグリッドが透けていました。✅ 完了 — Cardなしのすべてのテーブルが bg-surface を描画するようになりました(<DataTable> プリミティブでは、スクロールコンテナに background: var(--color-surface) を指定)。修正対象: DataTable(プリミティブ)、ProxyLogger/RequestLoggerV2(それらの <Card> に指定された bg-black/5 dark:bg-black/20 の色合いが、tailwind-mergeによってCardの bg-surface より優先され、約95%透明になっていました)、BatchListTab/FilesListTab/CacheEntriesTab/ReasoningCacheTab/cache page/FreePoolTab/ModelMappingTable/HeaderTable、およびcacheビュー内のCSSグリッド製「テーブル」2つ(bg-surface/35 → bg-surface)。すでに <Card>/Modal 内にあるテーブルは不透明であることを確認し、意図的に変更していません(そこでの bg-surface は冗長で効果のない指定です)。グリッド自体は変更不要でした。ダッシュボードの body::before はサイトとバイト単位で同一です(--grid-size: 32px)。実行中のインスタンスで「より大きなグリッド」が見える場合、それはコードによるものではなく、#4143 より前の古いビルドです。tests/unit/design-grid-background.test.ts(フェーズ6のブロック)でガードされています。

  • パレット変更なし — 色はすでに一致しており、不足しているトークンのみを追加します。製品の配色が変わるリスクはありません。
  • テーマエンジン変更なし — .dark + Zustand ストアを維持します。
  • 角丸の変更(フェーズ2)は広範囲 — すべてのカード、ボタン、入力に影響するため、マージ前に要素の多い画面(テーブル、モーダル)を目視確認します。
  • テーブル(C3) はハードコードされたスタイルが最も多く、回帰の影響範囲も最大です。専用のPRに分離します。

領域 パス
ダッシュボードのトークン src/app/globals.css(:root、.dark、@theme inline、body、body::before)
テーマストア src/store/themeStore.ts、src/shared/components/ThemeProvider.tsx、src/shared/constants/appConfig.ts:9-11
パネルシェル(ここでグリッドを有効化) src/shared/components/layouts/DashboardLayout.tsx
Chrome src/shared/components/Header.tsx:207、src/shared/components/Sidebar.tsx:430
グリッドの先行実装 src/app/landing/page.tsx:16-26
プリミティブ src/shared/components/{Button,Card,Input,Select,Badge,Modal,Toggle,SegmentedControl,Loading,Tooltip,DataTable}.tsx
ステータスカラーの定義元 flow/edgeStyles.ts、TokenHealthBadge.tsx、DegradationBadge.tsx、logTableStyles.ts
cn ユーティリティ src/shared/utils/cn.ts
フェーズ1のガードテスト tests/unit/design-grid-background.test.ts
サイトの参照元 _mono_repo/omnirouteSite/css/tokens.css、css/base.css

OmniRoute ソースコード (a58000c7685f)

HagiCode

HagiCode は構造化ワークフロー、マルチエージェント実行、Hero Dungeon ビューを備えたエージェント型コーディングワークスペースです。

よりスマートで速く、楽しいエージェント型ワークフローで、使いやすいソフトウェアを形にします。

HagiCode ライトテーマのメイン画面
  • Smart構造化ワークフローは意図をアイデアから変更のリリースまで実行可能な道筋にします。
  • Efficientマルチエージェントのワークフローで調査、実装、レビューを並行して進めます。
  • FunHero Dungeon により長時間のコーディングを視覚的で協力的な体験にします。
HagiCode を見る