# 配色方案

> ColorScheme——从一个种子颜色生成整个应用的调色板（Material 3）。

Source: https://crossfly.dev/zh/docs/ui/theming/color-schemes — CrossFly documentation. Full docs as one file: https://crossfly.dev/llms-full.txt

# 配色方案（`ColorScheme`）

`ColorScheme` 是受 Material 3 启发的**语义化调色板**：从**一个种子颜色**出发，
框架为浅色**和**深色生成所有协调的颜色（primary、surface、error、outline……）。

## 完整示例（复制、粘贴并运行）
```java
package com.exemplo;

import dev.crossfly.ui.*;
import dev.crossfly.ui.layout.*;
import dev.crossfly.ui.style.*;   // Styles、ComponentStyle、ThemeMode
import dev.crossfly.ui.color.*;   // ColorScheme

/** 可执行的主界面。将 launcher 指向此类（classname）并运行：gradlew :lwjgl3:run */
public class MainWindow extends Window
{
   @Override
   public void onShow() throws Exception
   {
      super.onShow();

      // 由单个种子色生成整套调色板（Material 3），深色模式
      Styles.setColorScheme(0xFF6750A4, ThemeMode.DARK);

      setLayout(new VerticalLayout());

      // 读取全局调色板，并按语义角色为卡片设置样式
      ColorScheme cs = Styles.colorScheme();
      Label card = new Label("Cartão temático");
      card.style(new ComponentStyle()
         .backColor(cs.surface)             // 主题背景
         .textColor(cs.onSurface)           // 主题文本
         .borderColor(cs.outline.color())   // 细微边框（int ARGB）
         .borderRadius(0.6f)
         .ingap(Gap.ofFont(0.8f)));
      add(LAY_AUTO, card);

      Button primario = new Button("Ação principal");
      primario.style(Styles.button()
         .backColor(cs.primary)             // primary 角色 → 主按钮
         .textColor(cs.onPrimary));
      add(LAY_AUTO, primario);
   }
}
```
> 下面的片段**仅展示核心部分**（放入 `onShow()` 内的内容）。要运行它们，请放入上面的 `MainWindow` 骨架中。

## 一行应用
```java
// 由单个种子生成整套调色板（浅色）
Styles.setColorScheme(0xFF0173ED);

// 同一身份，深色模式
Styles.setColorScheme(0xFF6750A4, ThemeMode.DARK);
```
之后，**所有通过 `Skin` 创建的组件**都会自动使用该调色板。

## 创建 `ColorScheme` 的方式
```java
ColorScheme.fromSeed(0xFF6750A4);              // 1 个种子 → 浅色调色板
ColorScheme.fromSeed(0xFF6750A4, true);        // 1 个种子 → 深色调色板
ColorScheme.light(0xFF0066CC, 0xFF00AA44, 0xFFFF9900); // 3 种品牌色（primary/secondary/tertiary）
ColorScheme.materialPurple(false);             // 现成的预设
ColorScheme.iosBlue(false); ColorScheme.flutterTeal(false);
ColorScheme.forestGreen(false); ColorScheme.deepOrange(false); ColorScheme.oceanBlue(false);
```

## 语义化角色（按意图使用，而非按颜色）
| 角色 | 用于 |
|---|---|
| `primary` / `onPrimary` | 主按钮、活动指示器 / 其上的文本 |
| `primaryContainer` / `onPrimaryContainer` | 选中的卡片、活动的 chip |
| `secondary` / `tertiary` | 次要操作 / 强调 |
| `surface` / `onSurface` | 屏幕和卡片背景 / 主文本 |
| `surfaceVariant` / `onSurfaceVariant` | 微妙背景 / 副标题、提示、禁用 |
| `outline` / `outlineVariant` | 边框、分隔线 / 微妙边框 |
| `error` / `onError` | 验证、破坏性操作 / 错误上的文本 |

```java
ColorScheme cs = Styles.colorScheme();
card.style(new ComponentStyle()
   .backColor(cs.surface)          // 主题背景
   .textColor(cs.onSurface)        // 主题文本
   .borderColor(cs.outline.color()));
```

## 切换调色板的变体
```java
ColorScheme claro = ColorScheme.fromSeed(0xFF6750A4);
ColorScheme escuro = claro.toDark();        // 同一身份，深色调
ColorScheme oposto = claro.toggleDarkLight();
```

## 最佳实践
- 在启动时**只**设置一次种子；在各屏幕中使用角色（`cs.primary`、`cs.surface`）。
- 按**意图**选择颜色（破坏性用 `error`），而非按 RGB 值。
- 在静态初始化期间，优先使用 `setColorSchemeSilent(...)`（不会触发重新布局）。

## 常见错误
- 在 UI 中散布固定的 `0xFF...`，而非使用 `ColorScheme` 的角色（会破坏深色模式）。
- 在每个屏幕重新创建 `ColorScheme`——它是全局的；用 `Styles.colorScheme()` 读取。

## 另见
- [浅色/深色模式](/docs/ui/theming/dark-mode) · [组件样式](/docs/ui/theming/styling-components) · [皮肤](/docs/ui/theming/skins)
