From 60ded246ee4957ea352aef2c07a206d71434cd74 Mon Sep 17 00:00:00 2001 From: flemming-it Date: Tue, 2 Jun 2026 01:35:53 +0200 Subject: [PATCH] chore: initial studio-theme-sunset 0.1.0 Signed-off-by: flemming-it --- .gitignore | 2 + Cargo.toml | 32 ++++++++++++++++ MODULE.de.md | 8 ++++ MODULE.md | 19 +++++++++ README.md | 22 +++++++++++ module.wasm | Bin 0 -> 53604 bytes module.yaml | 17 +++++++++ rust-toolchain.toml | 4 ++ src/lib.rs | 91 ++++++++++++++++++++++++++++++++++++++++++++ 9 files changed, 195 insertions(+) create mode 100644 .gitignore create mode 100644 Cargo.toml create mode 100644 MODULE.de.md create mode 100644 MODULE.md create mode 100644 README.md create mode 100644 module.wasm create mode 100644 module.yaml create mode 100644 rust-toolchain.toml create mode 100644 src/lib.rs diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..2c96eb1 --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +target/ +Cargo.lock diff --git a/Cargo.toml b/Cargo.toml new file mode 100644 index 0000000..5dac96c --- /dev/null +++ b/Cargo.toml @@ -0,0 +1,32 @@ +# Standalone Cargo.toml — targets wasm32-wasip2. +# +# Build: +# cargo build --release --target wasm32-wasip2 +# +# Output: target/wasm32-wasip2/release/studio_theme_sunset.wasm + +[package] +name = "studio_theme_sunset" +version = "0.1.0" +edition = "2021" +authors = ["Dr. Stefan Flemming "] +license = "Apache-2.0" +publish = false +description = "F∆I Studio plugin — Dusky pink / orange / violet Studio theme." +repository = "https://git.flemming.ai/fai-plugins/studio-theme-sunset" +rust-version = "1.85" + +[lib] +crate-type = ["cdylib"] + +[dependencies] +fai-plugin-sdk = { path = "../../fai_plugin_sdk_rust" } + +[package.metadata.component] +package = "fai:studio-plugin" + +[profile.release] +opt-level = "s" +lto = true +codegen-units = 1 +strip = true diff --git a/MODULE.de.md b/MODULE.de.md new file mode 100644 index 0000000..124adb0 --- /dev/null +++ b/MODULE.de.md @@ -0,0 +1,8 @@ +# sunset + +Sonnenuntergangs-Look in Pink / Orange / Violett. + +Eines der mit F∆I Studio gelieferten Theme-Plugins. Nach +Installation erscheint es unter **Einstellungen → Themes** +neben den eingebauten Hell- und Dunkel-Themes. Auswahl +schaltet die gesamte Studio-Oberfläche um — ohne Neustart. diff --git a/MODULE.md b/MODULE.md new file mode 100644 index 0000000..358fb1d --- /dev/null +++ b/MODULE.md @@ -0,0 +1,19 @@ +# sunset + +Dusky pink / orange / violet Studio theme. + +This is one of F∆I Studio's bundled theme plugins. When +installed, it appears in **Settings → Themes** alongside the +built-in light and dark themes. Select it and the entire +Studio UI re-themes immediately — no restart required. + +## When to pick this theme + +- Demo presentations — the palette photographs well +- Onboarding sessions where you want the UI to feel + welcoming rather than enterprise +- Operators who simply prefer warmer tones over cool ones + +Pink primary, orange secondary, purple tertiary. The +gradient feel matches FaiEditorStyle.modern (gradient +canvas backdrop) particularly well. diff --git a/README.md b/README.md new file mode 100644 index 0000000..fc2cb6c --- /dev/null +++ b/README.md @@ -0,0 +1,22 @@ +# studio-theme-sunset + +Dusky pink / orange / violet Studio theme. + +Ships a Material 3 ColorScheme pair (light + dark) through +the WIT `theme` export. Studio loads it as a +`studio.theme.sunset` capability and switches the app's +ColorScheme when the operator picks it from the themes +picker. + +## Build + +```bash +cargo build --release --target wasm32-wasip2 +``` + +Output: `target/wasm32-wasip2/release/studio_theme_sunset.wasm`. + +## Palette + +See `src/lib.rs` for the 14 ARGB tokens per brightness, in +Material 3 order (primary → on_primary → … → outline_variant). diff --git a/module.wasm b/module.wasm new file mode 100644 index 0000000000000000000000000000000000000000..caf2426b069903c945e2b084ebdf28bc74ce654f GIT binary patch literal 53604 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 literal 0 HcmV?d00001 diff --git a/module.yaml b/module.yaml new file mode 100644 index 0000000..db66b4b --- /dev/null +++ b/module.yaml @@ -0,0 +1,17 @@ +schema_version: 3 +provider: fai +name: studio-theme-sunset +version: 0.1.0 + +provides: + - capability: studio.theme.sunset + version: 0.1.0 + +inputs: {} +outputs: {} + +permissions: [] + +studio_extension: + hooks: + - theme diff --git a/rust-toolchain.toml b/rust-toolchain.toml new file mode 100644 index 0000000..32add0c --- /dev/null +++ b/rust-toolchain.toml @@ -0,0 +1,4 @@ +[toolchain] +channel = "1.86" +targets = ["wasm32-wasip2"] +components = ["rustfmt", "clippy"] diff --git a/src/lib.rs b/src/lib.rs new file mode 100644 index 0000000..5e52c83 --- /dev/null +++ b/src/lib.rs @@ -0,0 +1,91 @@ +//! `studio.theme.sunset` — warm dusk Studio theme. +//! +//! Pink / orange / violet gradient feel. Reads like the sky +//! 20 minutes after sunset: still bright at the horizon, +//! purple settling in above. Light mode keeps a warm-white +//! surface; dark mode drops into a deep mulberry navy. + +#![allow(clippy::result_large_err)] + +use fai_plugin_sdk::{bindings, export_plugin}; + +type ColorScheme = bindings::fai::studio_plugin::plugin_types::ColorScheme; +type PluginError = bindings::fai::studio_plugin::plugin_types::PluginError; +type RenderedOutput = bindings::fai::studio_plugin::plugin_types::RenderedOutput; + +const SUNSET_LIGHT: [u32; 14] = [ + 0xFFE91E63, // primary — pink 500 + 0xFFFFFFFF, // on_primary + 0xFFFF7043, // secondary — deep orange 400 + 0xFFFFFFFF, // on_secondary + 0xFF8E24AA, // tertiary — purple 600 + 0xFFFFFFFF, // on_tertiary + 0xFFC62828, // error + 0xFFFFFFFF, // on_error + 0xFFFFF5F0, // surface — warm whitespace + 0xFF38121F, // on_surface + 0xFFFFDDD0, // surface_variant + 0xFF804040, // on_surface_variant + 0xFFC97070, // outline + 0xFFE6BFB5, // outline_variant +]; + +const SUNSET_DARK: [u32; 14] = [ + 0xFFF48FB1, // primary — pink 200 + 0xFF38121F, // on_primary + 0xFFFFAB91, // secondary — deep orange 200 + 0xFF381200, // on_secondary + 0xFFCE93D8, // tertiary — purple 200 + 0xFF38003A, // on_tertiary + 0xFFEF5350, // error + 0xFF1A0000, // on_error + 0xFF2A0F1F, // surface — dark sunset + 0xFFFFD6E0, // on_surface + 0xFF4A2030, // surface_variant + 0xFFE6BFB5, // on_surface_variant + 0xFF806060, // outline + 0xFF4A2D38, // outline_variant +]; + +struct SunsetPlugin; + +impl bindings::exports::fai::studio_plugin::theme::Guest for SunsetPlugin { + fn theme_for(brightness: String) -> Result { + let tokens = match brightness.as_str() { + "light" => SUNSET_LIGHT.to_vec(), + "dark" => SUNSET_DARK.to_vec(), + other => { + return Err(PluginError::Declined(format!( + "sunset has no scheme for brightness '{other}' \ + (supported: light, dark)" + ))); + } + }; + Ok(ColorScheme { brightness, tokens }) + } +} + +impl bindings::exports::fai::studio_plugin::translate::Guest for SunsetPlugin { + fn translate( + _text: String, + _from_locale: String, + _to_locale: String, + ) -> Result { + Err(PluginError::Declined( + "sunset is a theme plugin and does not translate".to_string(), + )) + } +} + +impl bindings::exports::fai::studio_plugin::output_view::Guest for SunsetPlugin { + fn render( + _mime_type: String, + _data: Vec, + ) -> Result { + Err(PluginError::Declined( + "sunset is a theme plugin and does not render outputs".to_string(), + )) + } +} + +export_plugin!(SunsetPlugin);