カスタムテーマを作成する
NotyraはJSONファイルを使用してテーマのカスタマイズが可能です。ユーザーは独自のカラーテーマを作成し、Notyraの外観を完全に自分好みに変更できます。
テーマファイルの構造
テーマは以下の形式の単一 .json ファイルです。
{
"id": "my-theme",
"name": "My Theme",
"nameJa": "マイテーマ",
"description": "A short description in English",
"descriptionJa": "日本語での説明",
"swatches": ["#accent", "#background", "#subtle"],
"swatchesDark": ["#accent-dark", "#background-dark", "#subtle-dark"],
"light": {
"--background": "oklch(...)",
"--foreground": "oklch(...)",
"...": "..."
},
"dark": {
"--background": "oklch(...)",
"--foreground": "oklch(...)",
"...": "..."
}
}トップレベルフィールド
| フィールド | 型 | 必須 | 説明 |
|---|---|---|---|
id | string | Yes | 一意な識別子。小文字とハイフンを使用してください(例:"ocean-blue")。 |
name | string | Yes | 英語での表示名。 |
nameJa | string | Yes | 日本語での表示名。 |
description | string | No | 英語での短い説明。 |
descriptionJa | string | No | 日本語での短い説明。 |
swatches | string[] | Yes | ライトモードのプレビューチップ用の3色(hex):[アクセント, 背景, サブトル]。 |
swatchesDark | string[] | Yes | ダークモードのプレビューチップ用の3色(hex):[アクセント, 背景, サブトル]。 |
light | object | Yes | ライトモードで適用されるCSS変数マップ。 |
dark | object | Yes | ダークモードで適用されるCSS変数マップ。 |
CSS 変数リファレンス
light および dark の値はすべて element.style.setProperty() によって :root に設定されます。OKLch・hex・rgba()・他の変数への参照(var(--foreground) など)を含む任意の有効なCSS値を使用できます。
ベース変数(shadcn/ui 互換)
shadcn/ui の規約に従い、全体的なカラーパレットを制御します。
| 変数 | 説明 |
|---|---|
--background | ページ・パネルの背景色 |
--foreground | デフォルトのテキスト色 |
--card | カードの背景色 |
--card-foreground | カード上のテキスト色 |
--popover | ポップオーバー・ドロップダウンの背景色 |
--popover-foreground | ポップオーバー内のテキスト色 |
--primary | プライマリインタラクション色(ボタン等) |
--primary-foreground | プライマリ色上のテキスト色 |
--secondary | セカンダリサーフェス(コードブロック等) |
--secondary-foreground | セカンダリサーフェス上のテキスト色 |
--muted | 控えめな背景(タグ・バッジ・ミュートエリア) |
--muted-foreground | 控えめ・サブテキスト色 |
--accent | ホバー・フォーカス時のハイライト背景 |
--accent-foreground | アクセント背景上のテキスト色 |
--destructive | 破壊的操作の色 |
--destructive-foreground | 破壊的操作上のテキスト色 |
--border | デフォルトのボーダー色 |
--input | 入力フィールドのボーダー色 |
--ring | フォーカスリングの色 |
--radius | 基本の角丸(例:"0.5rem") |
サイドバー変数
| 変数 | 説明 |
|---|---|
--sidebar | サイドバーパネルの背景色 |
--sidebar-foreground | サイドバーのテキスト色 |
--sidebar-primary | サイドバーのプライマリ色 |
--sidebar-primary-foreground | サイドバープライマリ上のテキスト色 |
--sidebar-accent | サイドバーのホバー・フォーカス背景 |
--sidebar-accent-foreground | サイドバーアクセント上のテキスト色 |
--sidebar-border | サイドバーのボーダー色 |
--sidebar-ring | サイドバーのフォーカスリング色 |
チャート変数
--chart-1 ~ --chart-5 — データビジュアライゼーション要素に使用される5色(基本的なテーマ作成では必須ではありません)。
テーマ固有変数
Notyra 独自の変数です。エディタの見出し・アクティブな選択状態・リンク・バッジ・グラデーション装飾など、UIのアクセントカラーを制御します。
| 変数 | 説明 | 例(ライト) | 例(ダーク) |
|---|---|---|---|
--theme-accent | メインのアクセントカラー。選択中アイテム・アクティブアイコン・見出し色(設定時)・インタラクティブなハイライトに使用されます。 | "#7c3aed" | "#c084fc" |
--theme-accent-hover | ソリッドなアクセント背景のホバー時に使用される、アクセントの暗いバリアント。 | "#6d28d9" | "#e879f9" |
--theme-accent-subtle | アクセントの非常に薄い色調。選択アイテムの背景・バッジの背景・フォルダヘッダーのグラデーションに使用されます。ライトモードでは白に近い色、ダークモードでは半透明にするのが適切です。 | "#faf5ff" | "rgba(76, 29, 149, 0.2)" |
--theme-accent-subtle-hover | ホバー時に使用される --theme-accent-subtle のやや強いバリアント。 | "#ede9fe" | "rgba(76, 29, 149, 0.3)" |
--theme-gradient-from | 装飾グラデーションの開始色(アプリロゴのラインなど)。 | "#a78bfa" | "#a78bfa" |
--theme-gradient-to | 装飾グラデーションの終了色。 | "#c084fc" | "#c084fc" |
--theme-link | Markdownプレビューのハイパーリンク色。 | "#8250df" | "#a371f7" |
--theme-link-hover | ホバー時のリンク色。 | "#a371f7" | "#c084fc" |
--theme-heading-color | エディタとプレビュー両方の Markdown 見出し(h1〜h5)に適用される色。中立的な(黒/白)見出しにするには "var(--foreground)" を、アクセントカラーの見出しにするには hex 値を設定します。 | "var(--foreground)" | "var(--foreground)" |
カラーフォーマットのヒント
Notyra はベースパレット変数に OKLch を、テーマ固有のアクセント変数に hex / rgba を使用します。
OKLch
OKLch は知覚的に均一なカラースペースです:oklch(L C H) の形式で指定します。
- L — 明度(0 = 黒、1 = 白)
- C — 彩度(0 = グレー、高いほど鮮やか)
- H — 色相角(0〜360度)
oklch(0.99 0.006 285) → ごくわずかに紫がかった、ほぼ白
oklch(0.13 0.04 285) → ごくわずかに紫がかった、ほぼ黒(ダーク背景)
oklch(0.45 0.18 250) → 中明度の青(プライマリボタン)ヒント: 背景変数(--background、--card、--sidebar)は彩度(C)を非常に低く保つことで、主張しすぎない絶妙な色調を実現できます。0.004〜0.01 程度が適切です。
Hex / rgba
テーマ固有変数(--theme-*)には hex を使用してください。これらは鮮明で読みやすい必要があります。
"--theme-accent": "#059669"
"--theme-accent-subtle": "rgba(5, 150, 105, 0.15)" ← ダークモード用カスタムテーマの作り方
- サンプルテーマのいずれかをベースとしてコピーします。
id・name・nameJa・必要に応じてdescription・descriptionJaを変更します。swatchesとswatchesDarkを3色の hex プレビューカラー[アクセント, 背景, サブトル]に更新します。--backgroundの色相(OKLch の第3値H)を目的の色系統に合わせて調整します。彩度(C)は0.004〜0.01程度に保ちます。light・dark両セクションの--theme-*変数をアクセントカラーに合わせて更新します。- Notyra で 設定 → カラーテーマ → インポート からJSONファイルを選択します。
最小構成テンプレート
以下のテンプレートには最もよくカスタマイズする変数のみを含めています。記載のない変数はグレースケールのデフォルト値にフォールバックします。
{
"id": "my-custom-theme",
"name": "My Custom Theme",
"nameJa": "カスタムテーマ",
"description": "My custom color theme",
"descriptionJa": "カスタムカラーテーマ",
"swatches": ["#ACCENT_HEX", "#F9FAFB", "#F0F0FF"],
"swatchesDark": ["#ACCENT_DARK_HEX", "#111118", "#1E1E2E"],
"light": {
"--background": "oklch(0.99 0.006 HUE)",
"--foreground": "oklch(0.13 0 0)",
"--card": "oklch(0.99 0.006 HUE)",
"--card-foreground": "oklch(0.13 0 0)",
"--popover": "oklch(1 0 0)",
"--popover-foreground": "oklch(0.13 0 0)",
"--primary": "oklch(0.45 0.18 HUE)",
"--primary-foreground": "oklch(0.98 0 0)",
"--secondary": "oklch(0.965 0.008 HUE)",
"--secondary-foreground": "oklch(0.2 0 0)",
"--muted": "oklch(0.965 0.008 HUE)",
"--muted-foreground": "oklch(0.5 0 0)",
"--accent": "oklch(0.955 0.01 HUE)",
"--accent-foreground": "oklch(0.18 0 0)",
"--destructive": "oklch(0.577 0.245 27.325)",
"--destructive-foreground": "oklch(0.577 0.245 27.325)",
"--border": "oklch(0.91 0.01 HUE)",
"--input": "oklch(0.91 0.01 HUE)",
"--ring": "oklch(0.55 0.18 HUE)",
"--radius": "0.5rem",
"--sidebar": "oklch(0.975 0.008 HUE)",
"--sidebar-foreground": "oklch(0.13 0 0)",
"--sidebar-primary": "oklch(0.45 0.18 HUE)",
"--sidebar-primary-foreground": "oklch(0.98 0 0)",
"--sidebar-accent": "oklch(0.955 0.01 HUE)",
"--sidebar-accent-foreground": "oklch(0.18 0 0)",
"--sidebar-border": "oklch(0.91 0.01 HUE)",
"--sidebar-ring": "oklch(0.55 0.18 HUE)",
"--theme-accent": "#ACCENT_HEX",
"--theme-accent-hover": "#ACCENT_DARKER_HEX",
"--theme-accent-subtle": "#SUBTLE_HEX",
"--theme-accent-subtle-hover": "#SUBTLE_HOVER_HEX",
"--theme-gradient-from": "#GRADIENT_FROM_HEX",
"--theme-gradient-to": "#GRADIENT_TO_HEX",
"--theme-link": "#LINK_HEX",
"--theme-link-hover": "#LINK_HOVER_HEX",
"--theme-heading-color": "var(--foreground)"
},
"dark": {
"--background": "oklch(0.13 0.04 HUE)",
"--foreground": "oklch(0.94 0 0)",
"--card": "oklch(0.155 0.04 HUE)",
"--card-foreground": "oklch(0.94 0 0)",
"--popover": "oklch(0.13 0.04 HUE)",
"--popover-foreground": "oklch(0.94 0 0)",
"--primary": "oklch(0.65 0.18 HUE)",
"--primary-foreground": "oklch(0.1 0 0)",
"--secondary": "oklch(0.22 0.045 HUE)",
"--secondary-foreground": "oklch(0.94 0 0)",
"--muted": "oklch(0.22 0.045 HUE)",
"--muted-foreground": "oklch(0.62 0 0)",
"--accent": "oklch(0.26 0.05 HUE)",
"--accent-foreground": "oklch(0.94 0 0)",
"--destructive": "oklch(0.396 0.141 25.723)",
"--destructive-foreground": "oklch(0.637 0.237 25.331)",
"--border": "oklch(0.24 0.045 HUE)",
"--input": "oklch(0.24 0.045 HUE)",
"--ring": "oklch(0.55 0.18 HUE)",
"--radius": "0.5rem",
"--sidebar": "oklch(0.17 0.042 HUE)",
"--sidebar-foreground": "oklch(0.94 0 0)",
"--sidebar-primary": "oklch(0.65 0.18 HUE)",
"--sidebar-primary-foreground": "oklch(0.1 0 0)",
"--sidebar-accent": "oklch(0.22 0.045 HUE)",
"--sidebar-accent-foreground": "oklch(0.94 0 0)",
"--sidebar-border": "oklch(0.24 0.045 HUE)",
"--sidebar-ring": "oklch(0.55 0.18 HUE)",
"--theme-accent": "#ACCENT_DARK_HEX",
"--theme-accent-hover": "#ACCENT_DARK_HOVER_HEX",
"--theme-accent-subtle": "rgba(R, G, B, 0.15)",
"--theme-accent-subtle-hover": "rgba(R, G, B, 0.25)",
"--theme-gradient-from": "#GRADIENT_FROM_DARK_HEX",
"--theme-gradient-to": "#GRADIENT_TO_DARK_HEX",
"--theme-link": "#LINK_DARK_HEX",
"--theme-link-hover": "#LINK_DARK_HOVER_HEX",
"--theme-heading-color": "var(--foreground)"
}
}HUE の部分を目的の色の OKLch 色相角に置き換えてください(例:青 → 250、緑 → 160、アンバー → 55、パープル → 285、ローズ → 10)。
TypeScript インターフェース
Notyra テーマを扱うツールを開発する場合、テーマの型定義は以下の通りです。
interface ColorTheme {
id: string
name: string
nameJa: string
description?: string
descriptionJa?: string
/** [アクセント, 背景, サブトル] — ライトモードプレビューチップ用 hex カラー */
swatches: string[]
/** [アクセント, 背景, サブトル] — ダークモードプレビューチップ用 hex カラー */
swatchesDark: string[]
/** ライトモードで適用される CSS 変数マップ */
light: Record<string, string>
/** ダークモードで適用される CSS 変数マップ */
dark: Record<string, string>
}インポート時には以下の最低条件が検証されます。
idが空でない文字列であることnameが空でない文字列であることswatchesが空でない配列であることswatchesDarkが空でない配列であることlightとdarkが null 以外のオブジェクトであること