ThemeForge:AIエージェントがワンクリックでインストールできる、ドロップイン式のCSSテーマシステム

公開日
2026年10月5日
更新日
2026年10月6日
著者
Jacob Lloyd — プロジェクト完了後、AIの支援を受けて執筆
読了時間
約62分で読めます

かんたんに言うと: ThemeForgeは、CSSと小さなスクリプトがまとめられた無料のパッケージです。これを使うことで、どんなウェブアプリにもテーマ選択機能や10種類のカラーテーマ、そしてあらかじめ用意されたボタンやフィールド、カード、ダイアログなどが追加されます。このパッケージは、AIコーディングエージェントが1行のコードだけでアプリに組み込めるように作られています。エージェントはリポジトリ内の短いファイルに従うだけで、アプリには機能するテーマ選択機能やシステムに準拠したデフォルト設定、さらにデザイン構築用の各種トークンも付与されます。

ほとんどのウェブアプリでは、3種類のテーマがそれぞれ別々の場所に記述されることになります。つまり、メインCSS内の :root ブロック、@media (prefers-color-scheme: dark) 以下にある2番目のブロック、そして開発者がピッカーを動作させるために任意の場所に追加した3番目のブロックです。その結果はいつも同じで、ホームページではある見た目になるテーマが、設定ページでは別の見た目になり、最終的には「なぜダークテーマにするとフッターが青くなるのか」という質問がIssueトラッカーに投稿されるのです。私はこのような問題を絶対に起こらなくするために ThemeForge を作成しました。これは ui-theme/ という1つのフォルダのみで構成されており、ランタイム、ベースレイヤー、コンポーネント用クラス、10種類すべてのテーマ用トークン、ピッカー、必要に応じて利用できるTailwindやQuasar用アダプター、そしてAIコーディングエージェント向けに書かれた短い AGENTS.md ファイルも含まれています。このフォルダをプロジェクトに追加し、ページのヘッド部分に4行ほど記述するだけで、アプリには正常に動作するテーマピッカーおよびシステム設定に準拠したデフォルトテーマが実装されます。インストールを担当するエージェントは1行のコマンドだけで作業を完了します。この記事の残りの部分は、内部仕組みを知りたい方々向けの内容となります。

この記事は、フォルダー内に実際に何があるか、10個のテーマとその用途、対比的な説明、そして残りの部分で参考用として提供されるデザイントークンやコンポーネントクラスについて解説するガイドです。後半部分は意図的に素早く閲覧できる参照用資料となっており、すべてのトークン、コンポーネント、公開メソッドが記載されています。これにより、コーディングエージェント(あるいは将来のあなた自身)がそのまま利用できるようになっています。

要約

  • 入手方法: github.com/LaserLloyd/ThemeForge — MITライセンスで無料です。下のダウンロード欄にもソースコードのZIPファイルがあります。
  • 内容: ui-theme/という単一のフォルダーだけで、どんなWebアプリにも導入可能です。10種類のカラーテーマ、テーマ選択機能、約250個のデザイントークン、ベースとなる要素レイヤー、テキストの標準規格、そしてボタン・フィールド・スイッチ・カード・ダイアログ・トースト・テーブル・アプリシェルなど、さまざまなコンポーネント用クラスがすべて含まれています。CSSのみとごく小さなスクリプトだけで構成されており、ビルド処理もNode.jsも依存ライブラリも一切不要です。
  • ワンラインインストール(READMEからそのまま引用): python3 -c "import urllib.request as u,sys;sys.argv=['update.py','--dest','static/ui-theme'];exec(u.urlopen('https://raw.githubusercontent.com/LaserLloyd/ThemeForge/main/ui-theme/update.py').read())"
  • ヘッドブロックの順序(重要です): まず ui-theme.js を読み込みます(通常通りで、deferやmodule属性は一切使用しません)。次に ui-theme-base.css と ui-components.css、続いてアプリ自身のCSSを読み込み、最後に ui-theme.css を読み込むことでテーマ設定が有効になります。
  • テーマ選択機能: 次のような要素のみが必要です:<select class="ui-select" data-ui-theme-picker aria-label="Theme"></select>。この要素は自動的にテーマリストを生成し、複数のタブ間でも同期されます。
  • 10種類のテーマ: 基本となる6種類(パープル、ミッドナイトゴールド、グレーシャー、フォレスト、ペーパー、デイライト)に加え、4種類のオプション用テーマ(エレクトリックイエロー、LaserLloyd、LaserLloyd Light、ナイトレッド)も用意されています。すべてのテーマはコントラスト基準を満たしており、不適合は一切ありません。
  • コントラスト水準: 本文テキストは7:1、補助的なテキストは6:1、あらゆる面でのテキストは4.5:1以上。コントロール要素の境界やオン/オフ状態も3:1以上のコントラストを確保しています。また、オン/選択済み/現在の状態は色だけでなく形状や塗りつぶし具合でも識別可能です。
  • AIエージェント向け設計: AGENTS.md にはインストール手順が文章形式で記載されており、どのAIエージェントにもこのファイルを指定するだけで一ステップでテーマ選択機能が利用可能になります。本リポジトリのCI(GitHub Actions、3つのジョブ)ではクローン作成、コントラストチェック、各JSファイルに対する node --check 検証、さらにヘッドレスChromeによるランタイムテストがすべて正常に実行されます。

どこで入手できますか

MITライセンス下で公開されているリポジトリがこちらです:github.com/LaserLloyd/ThemeForge。インストール用のスクリプトはAGENTS.mdに記載されており、監査用の資料としてはコントラストレポートが用意されています。ZIPファイルをご希望の場合は、このページの末尾にある「ダウンロード」欄から全ソースコードを入手できますし、サイト内のダウンロードページにも同様のファイルが掲載されています。Pythonがインストールされていない環境では、READMEにも記載されている通り、git clone --depth 1、npx degitといったコマンドや、プロトタイプ作成用に @v1.0.0 バージョンが指定されたjsDelivrの <script> URLも利用可能です。

最終的に得られるもの

ユーザーが好む見た目に近づけるための仕組みとして、あらゆるテーマを認識するピッカー付きのヘッダーがあります。OSに合わせて暗色系または明色系のデフォルトテーマが選ばれ、アプリケーションのコードベース内には次のような一行のCSSコードが記述されています:background: var(--surface-2) という具合です。これは #1d1d39 の代わりに使われます。テーマを選択してページを再読み込みすると、画面のちらつきは一切ありません。実行時スクリプトが <head> 内で同期的に実行され、タグ内の data-* 設定を読み取り、最初の描画前にテーマが適用されるからです。2つのタブでピッカーを開き、一方でテーマを変更すると、もう一方のタブもそれに合わせて再描画されます(これは storage イベントリスナーの働きです)。暗色系またはOLED用のテーマを選択して印刷すると、実行時環境は印刷作業中のみ明色系テーマに切り替えます(あるいは data-print-theme の設定に応じてナビゲーション部分を非表示にします)。こうすることで印刷されたページが紙上でも読みやすくなります。明色系テーマを選択した場合は、そのままの状態で印刷されます。

Notes

受信箱

ノートが3件あり、未読は1件です。

四半期ごとの振り返り ピン留め済み

第3四半期の振り返り用下書きです。金曜日までにもう2つ例を探しています。

旅行用荷物リスト

パスポート、充電器、小型の懐中電灯です。

このアプリケーションは ui-app、ui-card、ui-btn、ui-switch といったコンポーネント、および --surface-*、--text-*、--accent といったトークンを使って構築されています。テーマ選択機能は <select data-ui-theme-picker> として実装されており、実行時に内容が自動的に設定・同期されます。

上記の図はページ内で動作するデモであり、別ファイルのスクリーンショットではありません。実際のサンプル、つまりあらゆるテーマに含まれるすべてのコンポーネントは、リポジトリ内の specimen/index.html にあります(python3 -m http.server を実行した後、/specimen/ から開くことができます)。

各部分がどのように連携するか

このランタイムは、ui-theme.jsというごく小さなスクリプト(約23KB、575行)です。このスクリプトは順番に3つの処理を行います。まず、自身が存在する <script> タグ内の data-* 属性を読み取ります(これにより設定内容がファイル自体と共に引き継がれます)。次に localStorage やOS側の明るい/暗いモードの設定も確認します。そして最初の描画前に、選択されたテーマを <html data-palette> へ、現在有効なテーマ名(amoled、dark、light のいずれか)を <html data-theme> へ書き込みます。その後、ドキュメント内にある <select data-ui-theme-picker> 要素を探し出し、利用可能なテーマ一覧でそれらを埋めます(また、後からフレームワークによって生成される要素にも対応します)。さらに window.UITheme を公開し、ui-components.js が読み込まれた際には window.UIComponents も公開します。加えて storage イベントのリスナーを設定することで、複数のタブ間でテーマ情報が同期されるようにしています。CSS側はごくシンプルです。ui-theme-base.css ではページ上のテキストやリンク、フォーカスリング、スクロールバー、および「減速モーション」設定のデフォルト値を定義しています。ui-components.css ではボタンや入力欄、スイッチ、カード、ダイアログ、トースト、テーブルなどが描画されます。一方で ui-theme.css だけが各テーマごとに内容が変わるファイルであり、[data-palette="…"] セレクタの下で10種類すべてのテーマ用の色やタイポグラフィ、余白、角丸度、影、アニメーションの各値を定義しています。紫色テーマは :root として表現されており、これは data-palette 属性が存在しない状態に相当します。つまりランタイムがテーマを選択し、CSSがそれを画面に描画する仕組みとなっています。

OSのテーマに自動で追随する機能は多くの方を驚かせる点です。data-default="auto"により、各ページ読み込み時にprefers-color-schemeが参照され、実行時にはユーザーが保存した選択内容やdata-default-darkおよびdata-default-lightと組み合わせてテーマが決定されます。OSのテーマを変更してページを再読み込みすると、自動的に切り替わります。またピッカーから明示的にテーマを選ぶことも可能で、その場合はユーザーが設定を解除するかUITheme.reset()を呼び出すまでその設定が優先されます。さらに実行時にはstorageイベントも設定されるため、同じアプリの複数タブ間でもサーバー通信なしに同期が行われます。

インストール方法

リポジトリ内のAGENTS.mdに詳細な手順が記載されておりますが、簡単な手順としては以下の一行コマンドと4つのタグからなるheadブロックを使用します。アプリのルートディレクトリから実行してください。

python3 -c "import urllib.request as u,sys;sys.argv=['update.py','--dest','static/ui-theme'];exec(u.urlopen('https://raw.githubusercontent.com/LaserLloyd/ThemeForge/main/ui-theme/update.py').read())"

このコマンドによりインストーラーがダウンロードされ、最新リリースを取得した上でfiles.jsonに記載されたSHA-256値と照合し、フォルダ内にファイル群を書き込みます。Windows環境ではpython3の代わりにpythonまたはpyを使用してください。このコマンドはPowerShell、cmd、bashのいずれでも同様です。各ページの<head>内に記述する4行は以下の通りです。

<script src="/static/ui-theme/ui-theme.js"
        data-themes="purple,midnight-gold,glacier,forest,paper,daylight"
        data-default="auto" data-default-dark="midnight-gold" data-default-light="daylight"
        data-storage-key="myapp.theme"></script>
<link rel="stylesheet" href="/static/ui-theme/ui-theme-base.css">
<link rel="stylesheet" href="/static/ui-theme/ui-components.css">
<!-- ご自身のスタイルシート -->
<link rel="stylesheet" href="/static/ui-theme/ui-theme.css">

これら3つのCSSファイルはそれぞれ重要な役割を担っております。ui-theme.jsはクラシックなブロッキングスクリプトであり、type="module"、defer、asyncといった属性は一切使用しません。これは自身のタグから設定値を読み取る必要があるためです(document.currentScriptを用いるのですが、モジュールスクリプトではこの値がnullとなってしまうためです)。また最初の描画前にテーマ設定を行う必要もあります。基本レイヤーおよびコンポーネントレイヤーのCSSはアプリ用CSSより先に読み込まれるため、同じ指定度合いを持つ場合でもアプリ側のルールが優先されます。ui-theme.cssはその後に読み込まれるため、古いアプリ変数がテーマトークンを上書きすることが防がれます。ピッカー自体は以下の一行だけで実装可能です:<select class="ui-select" data-ui-theme-picker aria-label="Theme"></select>。スクリプトからはUITheme.set('glacier')、UITheme.current()、UITheme.onChange(fn)といった呼び出しが可能です。AGENTS.mdの記載によれば、インストール全体には約5分程度しかかかりません。

実際にあるアプリへこの機能を一括で導入した際のエージェントの動作は次の通りです。ユーザーがAIコーディングエージェントに対し、ダークモードおよびテーマピッカーの実装を依頼しました。エージェントはAGENTS.mdを参照した上で、一行コマンドをstatic/ui-theme/ディレクトリ内で実行し、4つのheadタグをベーステンプレートに貼り付けました。さらに2箇所の色指定をvar(--surface-2)およびvar(--text-secondary)へ置き換え、ヘッダー部分にピッカーも追加しました。結果としてアプリ側の差分はわずか6行のみとなり、新たな依存関係も一切発生しませんでした。コントラスト監査機能により各コンポーネントが描画するすべての色ペアが確認済みであり、実行時にはOSテーマにも自動追随します。今後色指定をハードコーディングする場合に備えて、リント処理がその不備を検出できるだけとなっております。

テーマ一覧

最初の6つはアプリがデフォルトで提供するコアテーマです。追加で用意された4つは、アプリ側が明示的に指定した場合にのみ利用可能となります。すべてのテーマはコントラスト監査を通過しております(docs/contrast-report.md参照)。具体的には本文テキストは7:1、補助的なテキストは各背景色上で6:1、その他のテキスト階層は4.5:1以上、コントロールの縁やオン/オフ状態も3:1以上のコントラスト比を満たしており、すべてのテーマにおいて形状だけでなく色情報も用いて状態が判別できるようになっております。各テーマの詳細は以下の通りです。

テーマ 種類 配色 説明
Purple コア dark 深いインディゴを背景に、バイオレットのアクセントと柔らかなラベンダー色のテキストが特徴です。基本テーマとして、その値が:rootのデフォルト値となります。
Midnight Gold コア OLED OLEDディスプレイ向けで、真っ黒な背景に温かみのあるゴールド色が配されています。
Glacier コア OLED 真っ黒な背景に氷色のテキストやシグネチャが映え、深いティール色のアクセントも特徴です。
Forest コア OLED 真っ黒な背景に淡いセージ色やリケン色が配され、茶色系の木肌色も組み合わされています。
Paper コア light 温かみのあるパーチメント色を基調とし、インクブラウン色のテキストや散文用のセリフ体、赤色のアクセントが特徴です。
Daylight コア light クリーンな白をベースに青色のアクセントが加えられています。
Electric Yellow オプトイン dark グラファイト色の背景に酸っぱいようなイエロー色が配され、角が丸くシャープな線も特徴です。
LaserLloyd オプトイン dark 近黒色のグラファイトを背景にレーザーブルーが配されており、作者のサイトでも使用されているテーマです。LaserLloyd Lightとセットで利用します。
LaserLloyd Light オプトイン light LaserLloydのライトバージョンとなります。
Night Red オプトイン OLED 低ブルーライトなナイトテーマで、真っ黒な背景に赤みを帯びたテキストが配されています。色構成には一切の青色成分が含まれておりません。

オプトインの4つは意図的に目立つ色合いとなっております。Electric Yellowは暗い環境でCSSレビューを行う際にエディタよりもページを目立たせたい場合に私が使用するテーマです。LaserLloydは本サイトのブルーとグラファイト色のデザインに合わせ、同じアプリ内でも統一感を出すために選ばれました。Night Redは「ナイトプロファイル」として特別な設定がなされており、コントラスト監査ツールでは通常171行分のテストデータ(標準的な147行に低照度環境向けの追加行を加えたもの)を用いて検証が行われます。またこのテーマではパレット内のすべてのトークンにおいて青色成分がゼロとなっております(docs/contrast-report.mdの「ゼロブルー監査」、README.mdのNight Red項目、docs/THEMES.mdのNight Red項目をご参照ください)。

注意点

  • CSSにハードコーディングされた色指定が問題であり、テーマ自体ではありません。 監査ではトークンのみをチェックします。アプリケーションコード内の color: #fff はどのテーマでも白く表示されます。tools/lint_colors.py(リポジトリ内)および AGENTS.md §8 の grep 処理でこれが検出されます。ただし CI でのリント処理ではそのステップが実行されないため、マージ前にローカルで実行してください。

  • ui-theme.js は <head> 内で最も先頭に記述される必要があり、かつ classic 属性を付けるべきです。 defer や module 属性は使用してはいけません。モジュールスクリプトでは document.currentScript が利用できず、ランタイムはタグ内の data-* 属性から情報を読み取ります。その結果、一時的に誤ったテーマが表示された後で正しいテーマに切り替わる現象が起こります。

  • ui-theme.css はアプリケーションの CSS の後に読み込まれる必要があります。 読み込み順序は「ベース → コンポーネント → アプリケーション → トークン」となります。トークンの後で読み込まれる同等の優先度を持つルールは無効になってしまいます。

  • data-themes によって選択肢として表示されるテーマが決まります。 data-themes に含まれていないスラッグを持つ保存済みテーマは次回の読み込み時に無視され、ランタイムはデフォルトテーマを使用します。テーマを削除する際には data-legacy-key および data-legacy-map を一度設定することで、保存済み値が適切に移行されます。

  • Tailwind の rounded-md や font-sans はインストール後に変化します。 これは仕様通りです。テーマ側で --radius- や --font- といったトークンが定義されており、そちらの値が優先されます。無理に上書きしないでください。

  • Next.js におけるハイドレーションの警告について。 <html> タグに suppressHydrationWarning を追加し、head ブロックに対する no-sync-scripts リントルールも無効化してください。ランタイムは React のハイドレーション処理前に <html> に属性を設定するためです。

  • 他のライブラリが <html> 上の data-theme を読み取る場合。 ランタイムはそこに data-theme="amoled|dark|light" を書き込みます。該当ライブラリがこの値に反応しないか確認してください。もし反応する場合は、data-mirror-attr を使って別の属性を設定してください。

  • ui-theme/ 内の内容は編集しないでください。 このフォルダはアップデート時に置き換えられるため、手動での編集が検出されるとインストール処理が編集済みファイルの上書きを拒否します。変更が必要な場合はアプリケーション自身の CSS に記述してください。

  • テーマ定義内で名前が挙げられているフォントはバンドルされません。 すべてのテーマではシステムフォントがフォールバックとして使用されます。Inter、JetBrains Mono、Space Grotesk、Archivo を利用したい場合はご自身で読み込んでください(インテグレーションのドキュメントに <link> タグのコピー用テキストが記載されています)。

  • prefers-contrast: more を指定すると線幅が太くなり、最も淡い色のテキストもはっきりと表示されます。 特別なテーマフラグは不要です。ランタイムがこれを検知し、CSS 側もそれに応答します。high-contrast というトークングループは同じ効果を得るための従来のオプションとなります。

この状況が私に与える影響

私が望んでいたのは、毎回一からテーマシステムを作成することなく、自分が作るすべてのアプリに本格的なテーマ機能を導入できる手段でした。ThemeForgeこそが、私が今後も使い続けたい形なのです。アプリに配置するフォルダーは現在 ui-theme/ と、アプリごとに必要なフォルダーとなっています。4種類のヘッドブロックタグやピッカーも、どのフレームワークでも同じ構造です。インストール用エージェントはSlackメッセージではなく AGENTS.md を読み取ります。コントラスト監査やヘッドレスChromeによるランタイムテスト、そして配布されるすべてのJSファイルに対して実施される node --check といった処理が、私に安心して開発を続けられる自信を与えてくれるのです。バージョンが1.0.0となっているのは、トークンが公開用APIであり、トークンの名前変更はメジャーバージョンアップに該当するからです。リリースはgitタグによって管理され、VERSION フォルダーの内容もそれと一致しています。またJSONファイルには update.py が照合するチェックサムリストによる署名も付与されています。このリポジトリ自体のCIはLinux、Windows、Python 3.9環境ですべて成功しており、このマシン上で新たにクローンを作成しても同様のチェックが通ります。

参考情報(AIエージェント用)

この記事の残りの部分は、コーディングエージェント(あるいは将来の私自身)がそのまま利用できるリファレンスカードとなっています。上記の前半部分が文章形式であり、後半部分は構造化されており、スキャンしやすく、ツールが読み取りやすい形になっています。window.UIThemeおよびwindow.UIComponentsに存在するすべてのトークン、各コンポーネントクラス、公開されているメソッド、テーマ、scriptタグ用の設定項目、アダプター、完全なインストールパス、コントラストに関する仕様、そしてバージョン情報などが以下に記載されています。

ファイルマニフェスト

このリポジトリには重要なツリーが2つあります。1つはアプリケーションがコピーするバンドル、もう1つはそのバンドルをビルドするための設計やツール類です。この記事では、そのバンドルについて説明します。

ドロップイン用バンドル — アプリがコピーする内容(ui-theme/):

ファイル サイズ 行数 内容
ui-theme.js 23,515 B 575 実行時処理:保存されたテーマを最初の描画前に適用し、data-default="auto"によりOSの明るい/暗いモードに追随。ピッカーの設定やタブの同期も行い、window.UIThemeも公開します
ui-theme-base.css 13,255 B — 要素のデフォルト設定:本文テキスト、リンク、見出し、コード、フォーカスリング、スクロールバー、減速モーション設定、テキスト階層、.ui-markdown、highlight.js用の色設定など
ui-components.css 51,344 B — 各種コンポーネント:ボタン、入力欄、チェックボックス、ラジオボタン、スイッチ、カード、バッジ、コールアウト、タブ、セグメントコントロール、テーブル、ダイアログ、メニュー、ツールチップ、トースト、進行状況表示、コードブロック、アプリケーションシェルなど
ui-theme.css 86,389 B(gz圧縮後:21,197 B) — 10種類のテーマ用トークン群(gz圧縮後で約20 KB)
ui-components.js 5,441 B 135 任意で使用可能なconfirm()、alert()、prompt()、toast()関数です
ui-theme.d.ts 2,841 B — window.UIThemeおよびwindow.UIComponents用のTypeScript宣言ファイルです
update.py 16,081 B — フォルダーのインストール・更新処理を行い、各ファイルのSHA-256値も確認します
themes.json 4,089 B — テーマ一覧(名前、ファミリー、背景色、配色セット、スウォッチ、フォント情報)
files.json 1,401 B — update.pyが検証に用いるチェックサムの一覧です
VERSION 30 B — フォルダーのバージョン情報(ThemeForge 1.0.0 3db64d9f574f)
README.md 6,342 B — このパッケージの利用方法に関する説明書です
adapters/quasar.css 24,997 B — NiceGUI/Quasar用のマッピング設定です
adapters/quasar.js 1,468 B 40 NiceGUI/Quasar間のJavaScriptブリッジ機能です
adapters/tailwind.css 4,399 B — Tailwind CSS v4用の@theme inlineマッピング設定です
adapters/tailwind-v3.preset.js 2,915 B 54 Tailwind CSS v3用のプリセット設定ファイルです

バンドルを構築するための設計やツール類(アプリケーションにはコピーされません):

ファイル サイズ 内容
README.md 6,592 B リポジトリの説明書
AGENTS.md 19,063 B AIエージェント向けのインストール手順を記述した文書
CHANGELOG.md 4,425 B バージョン履歴(1.0.0が最初のリリースです)
CLAUDE.md 1,498 B Claude用のリポジトリ利用規則
CONTRIBUTING.md 4,476 B テーマ開発に関するガイドライン
LICENSE 1,067 B MITライセンス。著作権は2026年に帰属します(元のファイルでは著者名が個人名で記載されていますが、サイト上ではブランド名が使用されており、ディスク上の文字列は元のLICENSEファイルに記載されています)。ダウンロード用ZIPファイルには含まれていません(元の著作権記述では著者名が個人名で記載されており、サイト側のコンテンツ保護機能がこれを「確認不可能な個人情報の開示」と見なしているためです)。
docs/TOKENS.md 15,391 B 各グループごとの全トークン一覧
docs/COMPONENTS.md 13,889 B 各コンポーネントクラスとそのマークアップ例
docs/THEMES.md 8,081 B 各テーマ、デザインに関する注意点、テーマの追加方法
docs/INTEGRATIONS.md 10,604 B 各フレームワーク向けのインストール手順
docs/TEXT.md 5,465 B テキスト階層やMarkdown記法について
docs/UPDATING.md 4,134 B アップデート方法、バージョン固定の仕方、キャッシュの利用法、チェックサムの役割など
docs/contrast-report.md 124,372 B コントラスト評価結果(10種類のテーマ×147~171行分)
docs/theme-template.css 9,854 B tools/sync_theme.py用の空のテーマテンプレート
tokens/<theme>.json 各約57 KB 各テーマのW3C DTCG形式JSONによるトークン定義
examples/static-html/ 3,731 B(indexファイル) シンプルなHTML/CSS/JSの例
examples/fastapi-jinja/ 2,172 B(app.pyファイル) FastAPIとJinjaを使用した例
specimen/index.html 17,721 B すべてのテーマにおける各コンポーネントのプレビュー(ローカルで閲覧可能)
tools/check_contrast.py 43,171 B コントラスト評価用スクリプト(CI環境で実行されます)
tools/lint_colors.py 22,711 B アプリケーションのCSS内にある色指定記述をチェックするスクリプト
tools/sync_theme.py 41,671 B src/css/*.cssからui-theme.css、tokens/*.json、docs/contrast-report.mdを再生成するスクリプト
tools/update.py 16,081 B インストール・検証用スクリプト(ui-theme/update.pyと同様の機能を持ちます)
tools/screenshots.py 3,273 B docs/images/用のテーマプレビュー画像を生成するスクリプト
tests/test_tools.py 17,606 B Python単体テスト(このクローン版では32件のテストがあり、1件がスキップされています)
tests/run_browser_tests.py 3,570 B 実行時環境を対象としたヘッドレスChromeテスト用スクリプト
tests/runtime.html 24,930 B ブラウザテスト用のテストフレームワーク
.github/workflows/ci.yml — CI設定:コントラストチェック、node --check、単体テスト、ブラウザテスト、CRLFチェックをLinux・Windows・Python 3.9環境で実行します

このリポジトリ自体のCIでは、3つのジョブが実行されます(checksはUbuntu上でPython 3.12を使用、tools-on-windowsはWindows上でPython 3.11を使用、updater-on-oldest-pythonはUbuntu上でPython 3.9を使用)。ローカルにクローンした環境では、配布されるすべてのJSファイルに対してnode --checkが正常に実行され、コントラストツールでも監査結果の10行すべてが正しく再現されます。また、単体テストも問題なく通過しています(Linux環境、Python 3.14にて2026年10月5日に実施され、32 passed, 1 skipped in 1.212 sとなりました)。

デザイントークン(グループ、役割、例示値)

どのテーマでも、すべてのトークンが解決されます。以下に記載されている値はパープルテーマのもの(:root ベース)です。他のテーマにおいても、tokens/<theme>.json(DTCG形式のJSONファイル)内にそれぞれ独自の解決済み値が定義されています。var(--名前)を使ってトークンを利用してください。アプリケーションのCSS内でトークンを再定義してはいけません。アプリケーション用の変数にはアプリ固有の接頭辞(--myapp-sidebar-wなど)を付けるか、またはトークンの別名として定義する必要があります(例:--myapp-brand: var(--accent))。出典:docs/TOKENS.md。

グループ トークン 役割 例(紫色)
サーフェス --surface-void ページよりも暗い色(フルブリード) #08080f
サーフェス --surface-0 ページ自体 #0e0e1b
サーフェス --surface-1 ナビゲーション #14142a
サーフェス --surface-2 カード類 #1d1d39
サーフェス --surface-3 ホバー時の状態 #232342
サーフェス --surface-4 アクティブな状態 #262648
サーフェス --surface-sunken くぼんだ領域 #0a0a14
サーフェス --surface-overlay メニューやポップオーバー #1d1d39
サーフェス --glass-1/2/3 半透明なパネル rgba(29,29,57,.72/.84/.92)
サーフェス --glass-highlight ガラスの光沢効果 rgba(255,255,255,.055)
サーフェス --code-bg コードの背景色 #0b0b16
テキスト --text-primary 主要なテキスト #e8e8f0
テキスト --text-secondary ラベルや説明文 #a0a0bd
テキスト --text-tertiary ヒントや時刻情報 #8d8db0
テキスト --text-disabled 無効なコントロール用のテキスト #717195
テキスト --text-inverse 明るい背景上のテキスト #0e0e1b
テキスト --text-link / --text-link-hover リンクやアクセント用テキスト #a78bfa / #c4b5fd
テキスト --on-accent / --on-danger / --on-success / --on-warning / --on-media / --on-media-muted 各種背景色上のテキスト #ffffff / #2a0808 / …
アクセント --accent / --accent-hover / --accent-pressed ブランドカラーや主要なアクション用 #7c3aed / #8250f0 / #6d28d9
アクセント --accent-subtle / --accent-muted / --accent-glow 淡い背景色や光沢効果 rgba(124,58,237,.16/.26/.35)
アクセント --accent-rgb JavaScriptで使用するためのRGB値 124,58,237
アクセント --accent-2 / --accent-2-subtle 二次的なアクセント色 #5eead4
CTA --cta / --cta-hover / --cta-pressed / --on-cta 強力なアクション用の要素 #7c3aed / #8250f0 / #6d28d9 / #ffffff
CTA --cta-shadow / --cta-shadow-hover ドロップシャドウ効果 0 6px 20px rgba(124,58,237,.28) / .38
CTA --highlight / --highlight-subtle / --on-highlight マークやヒント用の色 #fcd34d / rgba(252,211,77,.12) / #251a00
線 --border-subtle / --border / --border-strong フォームコントロールの枠線。--border-strongは3:1のコントラスト比 #21213b / #292945 / #6f6f9c
線 --divider 細い分割線 #21213b
線 --focus-ring / --focus-ring-width / --focus-ring-offset フォーカスリングの設定 #a78bfa / 2px / 2px
線 --glass-stroke / --glass-stroke-strong ガラス風の枠線 rgba(255,255,255,.08/.16)
コントロール状態 --selected / --on-selected 選択済み/チェック済み/アクティブな状態 テーマごとに異なる
コントロール状態 --unselected-border / --unselected-fg 未選択時の枠線や色。各サーフェス上で3:1のコントラスト比 テーマごとに異なる
ステータス --success / --warning / --danger / --info 状態を示すドットやバー、塗りつぶし色 テーマごとに異なる
ステータス --success-text / --warning-text / --danger-text / --info-text 各ステータスにおけるテキスト色 テーマごとに異なる
ステータス --success-subtle / --warning-subtle / --danger-subtle / --info-subtle 各ステータスの淡い背景色 テーマごとに異なる
ステータス --success-border / --warning-border / --danger-border / --info-border 各ステータス用の枠線 テーマごとに異なる
ステータス --idle / --idle-text / --idle-subtle / --idle-border / --idle-hover 中立的な状態 テーマごとに異なる
ステータス --live / --live-text / --live-subtle / --live-border / --live-hover 「実行中」を示すインジケーター テーマごとに異なる
コード/構文 --syn-bg / --syn-fg / --syn-comment / --syn-keyword / --syn-string / --syn-number / --syn-function / --syn-attr / --syn-tag / --syn-builtin / --syn-type / --syn-variable / --syn-literal / --syn-operator / --syn-title / --syn-addition 構文ハイライト用の色 テーマごとに異なる
コード/構文 --code-header-bg / --code-stroke コードブロックの枠線や背景。全てのテーマで暗色 テーマごとに異なる
チャート --cat-1 … --cat-12 各シリーズ用の色。--surface-0上で3:1のコントラスト比 テーマごとに異なる
チャート --seq-1 … --seq-5 低から高へ変化する色のグラデーション テーマごとに異なる
チャート --div-1 … --div-5 悪い/中立/良いを示す色 テーマごとに異なる
チャート --chart-grid / --chart-axis チャートの枠線や軸 テーマごとに異なる
バブル --bubble-user-text / --bubble-assistant-text / --bubble-user-bg / --bubble-assistant-bg チャット用のバブル テーマごとに異なる
バブル --rp-speech / --rp-thought / --rp-shout / --rp-whisper / --rp-ooc / --rp-action / --rp-critical ロールプレイ用のバブル色 テーマごとに異なる
差分表示 --diff-add-bg / --diff-add-text / --diff-remove-bg / --diff-remove-text 差分表示用の色 テーマごとに異なる
タイポグラフィ --fs-xs / --fs-sm / --fs-md / --fs-lg / --fs-xl / --fs-2xl フォントサイズ テーマごとに異なる
タイポグラフィ --fw-medium / --fw-semibold / --fw-bold フォントの太さ テーマごとに異なる
タイポグラフィ --font-sans / --font-mono / --font-display 使用するフォント群 テーマごとに異なる
余白 --space-1 … --space-8 4~64ピクセルの余白値 テーマごとに異なる
角丸度 --radius-sm / --radius-md / --radius-lg / --radius-pill コントロールの角の形状 テーマごとに異なる
シャドウ --shadow-1 / --shadow-2 / --shadow-3 / --shadow-4 ドロップシャドウの強度 テーマごとに異なる
Zレイヤー --z-modal / --z-toast / --z-popover / --z-nav 要素の重なり順序 テーマごとに異なる
アニメーション --motion-fast / --motion-med / --motion-slow / --easing-standard アニメーションのタイミング。減速設定ではループが停止します テーマごとに異なる
Markdown --md-bold / --md-italic / --md-bolditalic / --md-bolditalic-glow アプリ内で使用するMarkdown用の装飾 テーマごとに異なる
その他 --mark-bg / --selection-text / --selection-bg / --media-filter / --quote-bar / --heartbeat-text / --heartbeat-hover / --offline-text / --on-offline / --canvas-handle その他の小さな機能用の設定 テーマごとに異なる

出典: docs/TOKENS.md(22のグループ、約270個のトークン。grep -oE '\| \(--[a-zA-Z][a-zA-Z0-9-]*)` |' docs/TOKENS.md | sort -u | wc -l`の実行結果は272個のユニークなトークン名となります)。

コンポーネントクラス(各修飾子ごとに1行ずつ)

状態はネイティブな属性(disabled、checked、aria-pressed、aria-selected、aria-current、aria-invalid、aria-busy、または [open])から取得します。追加のクラスは一切使用しません。ほとんどのセレクタは単一のクラスで構成されており、後から適用される同等の優先度を持つアプリ側のルールが有効になります。論理プロパティも全て使用可能で、右から左へ読む言語にも対応しています。「オン」「チェック済み」「押下中」「現在選択中」の状態には--selectedが適用され、「オフ」状態では枠線のみが表示されます。無効な状態では点線の枠線となり、塗りつぶしはありません。出典: docs/COMPONENTS.md。

クラス 修飾子/構成要素 説明
ui-stack — 縦方向の配置。--space-3の間隔を設定
ui-row — 折り返し可能な横並び。中央揃えで、--space-2の間隔
ui-grid --ui-grid-min 自動的に列を生成。minは要素上に指定
ui-container — 中央配置され、--content-maxの最大幅となる
ui-spacer — 行内の残り部分を最後へ押しやる役割
ui-app __header __nav __main アプリシェル(ヘッダー、サイドナビ、メインコンテンツ)。760ピクセル以下ではナビが非表示に
ui-brand — ヘッダー内のアプリタイトル
ui-nav __label __item サイドナビゲーション
ui-title / ui-heading / ui-subheading / ui-lead / ui-kicker / ui-small / ui-mono / ui-num / ui-kbd / ui-code / ui-divider — テキストの階層。<hr>は.ui-dividerとして機能
ui-text-primary / -secondary / -tertiary / -disabled / -link — テキスト階層用クラス。新規コードではトークンをご利用ください
ui-markdown — レンダリング済みMarkdownのコンテナ。docs/TEXT.mdも参照ください
ui-btn --primary --ghost --outline --danger --cta --sm --lg --icon --block ボタン。<a>要素にも適用可能。aria-pressed、aria-busy、disabledと組み合わせてご使用ください
ui-btn-group — 隣接するボタンが角を共有する設定
ui-field — フォームフィールドのコンテナ(ラベル+コントロール+ヘルプ文)
ui-label — フィールドのラベル
ui-input --sm テキスト入力欄
ui-select — スタイル付き<select>。data-ui-theme-pickerを指定するとテーマピッカーが表示されます
ui-textarea — スタイル付き<textarea>
ui-help — フィールドの補足説明(aria-describedbyと連動)
ui-error — フィールドのエラーメッセージ(aria-describedbyと連動)。aria-invalid="true"の際に表示されます
ui-input-group — 入力欄とボタンを組み合わせた構成(例:検索欄)
ui-check — チェックボックス/ラジオボタン/スイッチの行
ui-checkbox — ネイティブな<input type="checkbox">にスタイルを適用
ui-radio — ネイティブな<input type="radio">にスタイルを適用
ui-switch — role="switch"を持つチェックボックスで、スイッチ風の見た目となる
ui-switch-state data-on data-off 「オン」/「オフ」のラベル(aria-hidden)。スイッチ自体が状態を通知します
ui-range — ネイティブな範囲選択コントロール。--slider-colorで色付けされます
ui-segmented — ラジオボタンのように振る舞うボタン群
ui-tabs ui-tab タブリスト(<a aria-current="page">を使用したリンク型タブ)。キーボード操作はアプリ側で実装が必要です
ui-card __header __title __footer --raised --interactive カード。aria-selectedやaria-currentにより選択中のカードが強調されます
ui-well — くぼんだ領域(ログやプレビュー、補助的なコンテンツ用)
ui-stat __label __value ラベルと値を組み合わせた構成
ui-badge --success --warning --danger --info --live --accent --neutral 丸型のバッジ
ui-dot --success --warning --danger --info --live --neutral ステータスを示すドット
ui-count --accent --danger カウンター用のチップ
ui-callout --info --success --warning --danger __title 色付きの注意喚起用要素。エラー時はrole="alert"をご使用ください
ui-table-wrap — <table class="ui-table">を包み込み、ヘッダーの固定やスクロールを可能に
ui-table --hover --compact td.num テーブル用のスタイル
ui-dialog — スタイル付き<dialog>
ui-drawer — <dialog>上に表示されるサイドシート
ui-menu __item メニュー項目群
[data-ui-tooltip] data-ui-tooltip-side="bottom" 任意の要素にツールチップを設定
ui-progress — 線形のプログレスバー
ui-spinner — 読み込み中を示すスピナー
ui-skeleton — ローディング時のスケルトン表示
ui-breadcrumbs — パンくずリスト
ui-pagination — ページネーション
ui-avatar — 円形のアバター
ui-chip __remove 削除や選択が可能なチップ
ui-details — <details>を使ったアコーディオン
ui-fieldset — フィールドセットと説明テキスト
ui-codeblock __bar <figure>内に<figcaption class="ui-codeblock__bar">と<pre>を含む構成
ui-empty — 空状態用の表示
ui-bubble --user --assistant チャット用のバブル

window.UIThemeおよびwindow.UIComponentsに備わる公開メソッド

出典: ui-theme/ui-theme.d.ts(両グローバルオブジェクトに関するTypeScriptの宣言内容)。

window.UITheme(UIThemeApi):

メンバー 型 役割
version string(読み取り専用) フォルダーのバージョン。例:"1.0.0"
config object(読み取り専用) { themes, default, auto, storageKey, families, printTheme }
current() () => string 現在アクティブなテーマのスラッグ
theme([slug]) (slug?) => UIThemeInfo \| null 指定したテーマ(または現在のテーマ)に関する情報
list() () => UIThemeInfo[] 有効になっているすべてのテーマ
set(slug) (slug) => string 指定したテーマに切り替える。切り替えた後のスラッグを返す
reset() () => string デフォルトのテーマに戻す。戻した後のスラッグを返す
partner([slug]) (slug?) => string \| null 同じファミリー内にあるライト/ダーク版のテーマ名(例:laserlloyd ↔ laserlloyd-light)
toggleFamily() () => string \| null ライト/ダーク版のテーマ間を切り替える。切り替えた後のスラッグを返す
onChange(listener) (fn) => () => void 変更を監視するための登録を行う。登録解除用の関数も返す。detail.printは印刷時の切り替えを示す値となる
token(name, [el]) (name, element?) => string 指定したトークンの実際の値(例:"#7c3aed")を取得する
tokens(names, [el]) (names, element?) => Record<name, string> 複数のトークン値を一度に取得する
color(name) (name) => string キャンバス上で使用される色を rgb()形式で返す
colors(names) (names) => Record<name, string> 複数の色をキャンバス用に一度に取得する
mountPicker(target, [opts]) (elOrSel, options?) => HTMLSelectElement \| null セレクト要素をテーマ選択用のピッカーとして設定する。optionsには { label, coreLabel, optInLabel, systemLabel }を指定できる

ui-theme-changeイベントは document上で発火し、引数には { slug, theme, previous, print }が含まれます。

window.UIComponents(UIComponentsApi):(ui-components.jsが必要)

メソッド シグネチャ 役割
confirm (opts: UIDialogOptions \| string) => Promise<boolean> テーマ対応の confirm()。オプションは { title, message, label, confirmLabel, cancelLabel, danger }となる
alert (opts: UIDialogOptions \| string) => Promise<void> テーマ対応の alert()
prompt (opts: UIPromptOptions \| string) => Promise<string \| null> テーマ対応の prompt()。キャンセル時は nullとなる。追加オプションとして { value, placeholder, type }がある
toast (message, { kind?, timeout? }) => HTMLElement info/success/warning/dangerの種類を指定できるトーストを表示し、生成された要素を返す

window.UI_THEME_MANIFEST(任意設定。スクリプトタグで指定した値より優先される):{ themes, default, defaultDark, defaultLight, storageKey, families, legacy, mirrorAttr, fontsHref, printTheme }。themesには配列またはカンマ区切りの文字列を指定できます。

スクリプトタグで指定可能なオプション(<script>タグ上の data-*属性)

属性 デフォルト値 役割
data-themes 6つのコアテーマ(purple,midnight-gold,glacier,forest,paper,daylight) 有効にするテーマをカンマ区切りで指定。ピッカーの表示内容や保存される値の基準となる。data-themesが未設定の場合、ui-theme.jsでは set==="core"として6つのテーマが有効化される(ui-theme.js:147-149)
data-default 有効なテーマの中で最初のもの(data-themes内の最初のスラッグ、または有効なテーマがなくかつ autoでもない場合は purple) デフォルトのテーマスラッグ。autoを指定するとOSの設定に従う。文字列 auto自体が prefers-color-schemeを用いたOS設定の追随を示す(ui-theme.js:164)。属性が空または未指定の場合は最初に有効なテーマが選ばれる(ui-theme.js:177-179)
data-default-dark 有効なテーマの中で「light」でない最初のテーマ(ground !== "light"となるスラッグ)。該当するものがなければ最初に有効なテーマ、それもなければ purple autoモードにおけるダーク側のテーマ。ui-theme.js:168-175ではOSがダークモードを推奨しておりかつ明示的な値が指定されていない場合にこれが選ばれる
data-default-light 有効なテーマの中で「light」である最初のテーマ(ground === "light"となるスラッグ)。該当するものがなければ最初に有効なテーマ、それもなければ purple autoモードにおけるライト側のテーマ。同じコードパスを利用する(ui-theme.js:168-175)
data-storage-key ui-theme ユーザーの選択内容が保存される localStorage上のキー名(ui-theme.js:185)。AGENTS.md §3では <appname>.theme に上書きすることを推奨しており、同じオリジン上で複数のThemeForgeアプリが存在しても衝突しないようにするためである
data-families false ピッカー内でテーマをファミリー単位にグループ化するかどうか
data-print-theme auto ページの印刷時に使用するテーマ。autoの場合、現在のテーマがダークまたはOLED系であればそのファミリー内のライト版テーマ(または最初に有効なライトテーマ、それもなければ daylight)に切り替わる。特定のスラッグを指定すればそのテーマが印刷用に使用される。noneを指定すると切り替えは行われない。現在のテーマがライト系であればそのまま印刷される(ui-theme.js:474-490)
data-legacy-key — 一度だけ移行処理を行うための旧式のストレージキー(data-legacy-mapと併用)
data-legacy-map — 旧値から新値への対応表(JSON形式)
data-mirror-attr — 現在選択中のテーマ情報を別の属性にも反映させるための設定(他ライブラリがその属性を参照する場合向け)
data-fonts-href — テーマ専用のフォントスタックを読み込むためのスタイルシートのURL

出典:ui-theme.js:147-149, 164, 168-174, 185, 474-490(実行時のデフォルト値)および AGENTS.md §3、§12(推奨される上書き方法。例として data-themesには6つのコアテーマを、data-default="auto"とし、data-storage-key="<appname>.theme"とするなどが挙げられます)。

アダプター

アダプター ファイル 役割
NiceGUI/Quasar adapters/quasar.js+adapters/quasar.css ui-theme.jsの直後に adapters/quasar.jsを、また ui-theme.cssの直後に adapters/quasar.cssを読み込みます(ui.add_head_htmlを用いる)。Quasar側のトグルやチェックボックス、ラジオボタンは制御状態に応じたデザインとなり、無効化されたコントロールは不透明度100%で点線表示されます。ui.dark_mode()の呼び出しは不要です。アダプター側で処理されます
Tailwind CSS v4 adapters/tailwind.css @import "tailwindcss";の後に @import "./<path>/ui-theme/adapters/tailwind.css";と記述します。bg-surface-2、text-fg、text-fg-muted、bg-accent、text-on-accent、border-lineなどのトークンが利用可能になります。テキスト系の色指定には fg-*を用いる必要があります。これは text-*で指定されるサイズ表記がTailwind側の規定に属するためです
Tailwind CSS v3 adapters/tailwind-v3.preset.js presets: [require('./<path>/ui-theme/adapters/tailwind-v3.preset.js')]と記述します。v4アダプターと同じトークンが定義されており、これらはTailwind v3用のプリセットとして表現されます

Tailwind用アダプターはテーマのトークンをマッピングし、Quasar用アダプターはコンポーネントクラスをマッピングします。どちらも本バンドルの動作に必須ではありません。

完全なインストール手順(AGENTS.mdよりそのまま引用)

AGENTS.mdはAIコーディングエージェント向けに記述されたインストール手順書です。以下に最初の2セクションを全文掲載します。これがAIエージェントに提示されるプロンプトとなります。文字列は article-forgeスキルの§8ルールに従いエスケープされています(<blockquote>内ではMarkdownがそのまま解釈されるため、<、>、&はそれぞれ &lt;、&gt;、&amp;として記述されています)。

## 1. 一度だけ決める事項

| 質問 | デフォルトの回答 |
|---|---|
| フォルダーをどこに配置するか? | アプリケーションの静的ファイル用フォルダー内にそのまま設置。例:`static/ui-theme/`(Flask、FastAPI、Django)、`public/ui-theme/`(Vite、Next.js、Create React App)、`app/static/ui-theme/`、または単純なサイトの場合は `index.html`と同じ場所 |
| どのテーマを有効にするか? | 6つのコアテーマ:`purple,midnight-gold,glacier,forest,paper,daylight`。ユーザーから要望があった場合のみオプトイン用テーマ(`night-red`、`electric-yellow`、`laserlloyd`、`laserlloyd-light`)を追加してもよい |
| デフォルトのテーマは? | `auto`:訪問者のOS設定に基づくライト/ダークモードが適用され、ユーザーが手動で選択するまでその状態が維持される(`data-default-dark="midnight-gold"`、`data-default-light="daylight"`と指定) |
| ストレージキーは? | `<appname>.theme`例:`notes.theme` |

## 2. インストール

アプリケーションのルートフォルダーから実行します(Python 3.9以降が必要。`static/ui-theme`は先ほど決めた配置場所に置き換えてください):


python3 -c &quot;import urllib.request as u,sys;sys.argv=['update.py','--dest','static/ui-theme'];exec(u.urlopen('https://raw.githubusercontent.com/LaserLloyd/ThemeForge/main/ui-theme/update.py').read())&quot;
Windows環境では `python`または `py`を `python3`の代わりに使用します。PowerShell、cmd、bashでも記述は同一です。このコマンドによりインストーラーがダウンロードされ、GitHub上の最新リリース内容が取得された後、各ファイルのチェックサムと照合してフォルダー内に書き込まれます。以降の更新時には `python3 static/ui-theme/update.py`を実行します。オフライン環境では別途リリースアーカイブ(`.tar.gz`)を入手し、`update.py`が含まれる `ui-theme/`フォルダー内から `python3 update.py --source <archive> --dest static/ui-theme`と実行します。 Pythonが利用できない場合の代替手段: - **git:** `git clone --depth 1 https://github.com/LaserLloyd/ThemeForge.git ut-tmp`としてフォルダーを作成し、`ut-tmp/ui-theme`をアプリケーション内にコピーした後 `ut-tmp`を削除します - **Node:** `npx degit LaserLloyd/ThemeForge/ui-theme#v1.0.0 static/ui-theme`と実行します - **インストール不要(プロトタイプや単一HTMLファイル向け):** jsDelivrから特定のリリース版を指定してファイルを読み込みます。例:`https://cdn.jsdelivr.net/gh/LaserLloyd/ThemeForge@v1.0.0/ui-theme/ui-theme.js`(各CSSファイルも同様のパスで指定)。`@main`を指定しないようご注意ください。CDNでは最大12時間程度キャッシュされるためです。CDN上のページ内容は固定バージョン番号を変更することで更新できますが、この場合 `update.py`や下記8.5、9、10の手順は適用されません。

AGENTS.mdの残りのセクション(3~12)ではヘッドブロックの記述方法、ピッカーの実装例、トークンからの構築手順、各種ルール、チャート関連情報、検証方法、次のエージェントが同じ規約を継続できるようアプリケーション内の AGENTS.mdに追記すべき行、更新コマンド、トラブルシューティング表、そして上記の参照一覧などが説明されています。

コントラストチェック(各テーマの要約)

tools/check_contrast.pyはCI環境において各プッシュごとに実行されます。完全なレポートは docs/contrast-report.mdとして124KB程度存在し、各テーマごとの詳細と全体の要約が記載されています。その要約部分は以下の通りです。

| テーマ | セット | プロファイル | チェック数 | 失敗数 |
|---|---|---:|---:|
| purple | core | standard | 147 | 0 |
| midnight-gold | core | standard | 147 | 0 |
| glacier | core | standard | 147 | 0 |
| forest | core | standard | 147 | 0 |
| paper | core | standard | 147 | 0 |
| daylight | core | standard | 147 | 0 |
| electric-yellow | opt-in | standard | 147 | 0 |
| laserlloyd | opt-in | standard | 147 | 0 |
| laserlloyd-light | opt-in | standard | 147 | 0 |
| night-red | opt-in | night | 171 | 0 |

すべてのテーマが満たすべき基準:本文は7:1、補助的なテキストは6:1というコントラスト比を確保する必要があります(コントラストレポート内では「契約上の6:1要件」と表現され、docs/contrast-report.mdでは text-secondary on surface-2の各行にこの文言が付記されています)。その他にも、あらゆるテキスト階層は surface-2上で4.5:1以上、無効化されたコントロールは3:1以上、アクセント色やステータス関連の背景上のテキストも4.5:1以上、選択状態下のテキストは4.5:1以上、各種表面における選択中・未選択時の境界線や前景色も3:1以上、強調用の境界線やコントロールのトラック、フォーカスリングも3:1以上、構文ハイライト用の --syn-bg上の色は4.5:1以上(コメント部分は3.5:1以上)となります。形状によるオン/オフの区別としては、「オン」状態のコントロールには --selected色が塗られ、「オフ」状態のコントロールは --unselected-border色で輪郭のみが描かれます。スイッチ型の場合「オン」時にはノブにバーが付加され、「オフ」時にはリングが追加されます。無効化されたコントロールは、たとえオン状態であっても不透明度100%の点線で描かれます。

各種フレームワーク向け対応

docs/INTEGRATIONS.mdに記載されている通り、純粋なHTML、FastAPI・Flask・Starlette(Jinjaテンプレート)、Django、Vite、Vue、Svelte、SvelteKit、Astro、Next.js(app router)、NiceGUI(Quasar)、Tailwind CSS、Electron、Tauri、pywebview、フォント関連、チャート関連、Content Security Policyといった環境がサポート対象です。各フレームワークにおいては、ui-theme/を静的ファイル用のディレクトリ内に配置し、AGENTS.md §3で示されている順序通りにヘッドブロックを追加してください。また更新内容が即座に反映されるよう、そのフォルダーにはキャッシュ制御を施すかバージョン付きのURLを用いることが推奨されます。リポジトリ内には具体的な実装例として examples/static-html/(単一ページ用)および examples/fastapi-jinja/(FastAPI+Jinjaで、app.pyは2,172バイトのみ)が用意されています。

印刷・コントラスト・アニメーション

実行時環境では以下の3つの事象を監視しており、それぞれCSS側でも対応しています。なおこれらにはテーマごとの個別フラグは存在しません。

  • 印刷機能 — data-print-theme 属性により、何が印刷されるかが制御されます(ui-theme.js:474-490)。現在選択されているテーマがダークテーマまたはOLEDテーマの場合、auto と設定すると該当ファミリー内のライトテーマに自動的に切り替わります(有効なライトテーマが複数ある場合は最初のもの、それもなければ daylight テーマが使用されます)。none を指定すると切り替えは行われません。現在選択されているテーマがライトテーマの場合は、そのままページが印刷されます。印刷時にはサイドナビゲーション、トースト通知、メニュー、ドロワー、ツールチップなどは非表示になります。

  • prefers-contrast: more — すべてのテーマにおいて、線の太さがコントロール要素の境界線に近い強度まで増加し、三次色レベルのテキストも二次色レベルへと引き上げられます。

  • prefers-reduced-motion — アニメーションのループが停止し、その持続時間も短縮されます。また、--motion-* で定義される値はすべて0になります。

バージョン情報

この記事で説明しているリポジトリの最新状態(2026年10月5日にクローン取得)より:

$ git log -1 --format='%h %ci'
56fb665 2026-10-05 21:46:52 +0900        # ThemeForge 1.0.0

$ cat ui-theme/VERSION
ThemeForge 1.0.0 3db64d9f574f

$ wc -c ui-theme/*.js ui-theme/*.css ui-theme/*.ts ui-theme/*.py 2>/dev/null
  23515 ui-theme.js
   5441 ui-components.js
   2841 ui-theme.d.ts
  16081 update.py
  13255 ui-theme-base.css
  51344 ui-components.css
  86389 ui-theme.css

$ node --check ui-theme.js ui-components.js
(node v24.18.0) — 両ファイルとも問題なし。adapters/quasar.jsおよびadapters/tailwind-v3.preset.jsも同様に問題なし。

$ python -m unittest discover -s tests
32個のテストを1.212秒で実行しました。
OK(スキップされたテスト:1件)

$ python tools/check_contrast.py --fail-on any
…
## 概要
| テーマ | セット | プロファイル | チェック数 | 失敗数 |
| purple | core | standard | 147 | 0 |
| midnight-gold | core | standard | 147 | 0 |
| glacier | core | standard | 147 | 0 |
| forest | core | standard | 147 | 0 |
| paper | core | standard | 147 | 0 |
| daylight | core | standard | 147 | 0 |
| electric-yellow | opt-in | standard | 147 | 0 |
| laserlloyd | opt-in | standard | 147 | 0 |
| laserlloyd-light | opt-in | standard | 147 | 0 |
| night-red | opt-in | night | 171 | 0 |

対応ブラウザ:現在のChrome、Edge、Firefox、Safari(2024年以降版)。本機能は :has()、color-mix()、およびポップオーバーAPIを利用しています。古いブラウザでも色自体は維持されますが、一部のコンポーネントの状態やメニュー機能が正しく表示されなくなる場合があります。

関連記事: ChatForge:Copilot Key向けのローカルNPU AIアシスタント · StudioForge:GPU専用LLMサーバー · DisPatch:自己ホスティング型AIチャット · 私のローカルAIエージェントスタック · LLMを利用して任意のプロジェクトを自身のシステムに適応させる方法

ダウンロード

個人利用は無料です。役に立ったら、コーヒーをおごってもらえると嬉しいです。


← AIとローカルLLMをもっと見る