bezel-theme 0.1.0

Design tokens for gpui — an environment-driven theme with designed light and dark palettes
Documentation
# bezel

A gpui component library, SwiftUI-lean: style flows through the environment,
never through parameters.

https://github.com/user-attachments/assets/6b5f16d0-9f58-48d6-8398-09acb1afa402

```rust
use bezel::ui::widgets::{ButtonStyle, Buttons};
theme.button("Save", ButtonStyle::Prominent, None)
```

## Install

```toml
[dependencies]
bezel = "0.1"
```

An app also names the two crates the facade cannot cover — `gpui` because
`actions!` expands to literal `gpui::` paths, and `gpui_platform` because the
facade re-exports gpui but not the platform. Both are our fork of gpui,
published under `bezel-gpui*`; the `package` key keeps the `gpui::` paths the
macros and gpui's own docs expect:

```toml
gpui = { package = "bezel-gpui", version = "0.3" }
gpui_platform = { package = "bezel-gpui-platform", version = "0.3", features = ["font-kit"] }
```

## Theme

To ship your own colors, register a custom palette:

```rust
use bezel::theme::{Theme, set_palette};

// before appearance::init
theme::set_palette(|appearance| {
    let mut theme = Theme::for_appearance(appearance);
    theme.accent = my_brand_accent(appearance);
    theme
}, cx);
```

One thing is not optional if you use hover fades — ask for frames in your root
render, or fades paint once and stick:

```rust
if bezel::motion::hover_fades_active() {
    window.request_animation_frame();
}
```

## Build an app

`apps/hello` is the smallest consumer — one window, a button, a toggle.
Every gpui *type* path goes through `bezel::gpui`, so a second gpui cannot
creep into the graph. The bootstrap, which is the part no snippet can skip:

```rust
use bezel::gpui::{App, AppContext as _, Bounds, WindowBounds, WindowOptions, px, size};
use bezel::theme::{self, Theme};
use bezel::ui;

fn main() {
    gpui_platform::application()
        .run(|cx: &mut App| {
            if let Err(err) = ui::register_fonts(cx) {
                eprintln!("FONT REGISTRATION FAILED: {err:?}");
            }
            theme::appearance::init(theme::appearance::AppearanceMode::System, cx);
            let bounds = Bounds::centered(None, size(px(520.0), px(360.0)), cx);
            cx.open_window(
                WindowOptions {
                    window_bounds: Some(WindowBounds::Windowed(bounds)),
                    ..Default::default()
                },
                |window, cx| {
                    theme::appearance::observe_window(window, cx).detach();
                    cx.new(Hello::new)
                },
            )
            .unwrap();
            cx.activate(true);
        });
}
```

`Hello` is a struct implementing `Render`; its `render` reads the theme with
`Theme::of(cx)` and builds elements through the `widgets` traits. Run
`cargo run -p hello` and read `apps/hello/src/main.rs` for the rest.

## Provenance

| What                   | From                               | License     |
| ---------------------- | ---------------------------------- | ----------- |
| Initial components     | [comet]                            | MIT         |
| Thinking orbs          | [gpui-thinking-orbs]               | MIT         |
| Blob avatars           | [blobatar]                         | MIT         |
| Syntax highlighting    | tree-sitter core and grammars      | MIT         |
| TypeScript/TSX queries | [nvim-treesitter]                  | Apache-2.0  |
| Icons                  | Solar Icons by 480 Design          | CC BY 4.0   |
| Fonts                  | Geist and Geist Mono © Vercel Inc. | SIL OFL 1.1 |

[gpui]: https://github.com/zed-industries/gpui
[comet]: https://github.com/zeronsh/comet
[gpui-thinking-orbs]: https://github.com/FrancoEscob/gpui-thinking-orbs
[blobatar]: https://github.com/Alain00/blobatar
[nvim-treesitter]: https://github.com/nvim-treesitter/nvim-treesitter