init slint project

This commit is contained in:
rizary 2025-06-27 07:27:24 +07:00
commit e1326e529c
Signed by untrusted user who does not match committer: rizary
GPG key ID: 2CE8D69D02F1CEB5
56 changed files with 12692 additions and 0 deletions

24
.gitignore vendored Normal file
View file

@ -0,0 +1,24 @@
target/
**/target/
dist/
node_modules/
diff
# Environment files
.env
.env.prod
.logs/
.logs/**
docker.dev/**/.env
**/.env
.env.*local
*address.json
cex_database*
Config.toml
.cursor/
*.crt
*.key
*.p12

7
.vscode/extensions.json vendored Normal file
View file

@ -0,0 +1,7 @@
{
"recommendations": [
"rust-lang.rust-analyzer",
"vadimcn.vscode-lldb",
"Slint.slint"
]
}

3
.vscode/settings.json vendored Normal file
View file

@ -0,0 +1,3 @@
{
"files.autoSave": "off"
}

8738
Cargo.lock generated Normal file

File diff suppressed because it is too large Load diff

25
Cargo.toml Normal file
View file

@ -0,0 +1,25 @@
[package]
name = "ziya-slint"
version = "0.2.0"
edition = "2021"
description = "One stop shop for your trading habit - Slint version"
authors = ["rizary"]
license = "MIT"
[dependencies]
slint = "1.12.0"
i-slint-backend-winit = "1.12.0"
tokio = { version = "1.0", features = ["full"] }
serde = { version = "1.0", features = ["derive"] }
serde_json = "1.0"
reqwest = { version = "0.12", features = ["json"] }
anyhow = "1.0"
log = "0.4"
env_logger = "0.11"
solana-sdk = "2.3.0"
chrono = { version = "0.4.39", features = ["serde"] }
chrono-tz = "0.10.3"
image = { version = "0.25.6", default-features = false, features = [ "ico", "jpeg", "gif", "webp", "tiff" ] }
[build-dependencies]
slint-build = "1.12.0"

21
LICENSE Normal file
View file

@ -0,0 +1,21 @@
MIT License
Copyright (c) <year> <copyright holders>
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

155
README.md Normal file
View file

@ -0,0 +1,155 @@
# Ziya - Slint Edition
**One stop shop for your trading habit** - Now powered by Slint and Rust!
> **/dˤiˈjaːʔ/**, "zeeyah" — *Proper noun, meaning "light"*
> A bismillahDAO creation
## Overview
This is a modern rewrite of the Ziya trading platform using [Slint](https://slint.dev/) for the UI and Rust for the backend logic. Slint provides a declarative UI language that makes it easy to create beautiful, native desktop applications.
## Features
- **Modern Native UI**: Built with Slint's declarative UI language
- **Fast Performance**: Native Rust performance with efficient rendering
- **Clean Architecture**: Separated UI and business logic
- **Async Operations**: Non-blocking token fetching and user management
- **Modular Design**: Well-organized codebase with clear separation of concerns
### Application States
- **Loading**: Initial app startup and initialization
- **Login**: User authentication interface
- **Dashboard**: Main trading dashboard with token search
- **Hunting Ground**: Advanced trading tools (placeholder)
- **Profile**: User profile and wallet information
## Project Structure
```
ziya-slint/
├── src/
│ ├── main.rs # Application entry point
│ ├── lib.rs # Module organization
│ ├── app_state.rs # Application state management
│ └── services/ # Business logic services
│ ├── mod.rs
│ ├── token_service.rs # Token data and search
│ └── user_service.rs # User authentication and profiles
├── ui/
│ └── app-window.slint # Main UI definition
├── Cargo.toml # Project dependencies
└── build.rs # Build configuration
```
## Getting Started
### Prerequisites
- Rust 1.70+ (recommended via [rustup](https://rustup.rs/))
- Git
### Installation
1. Clone the repository:
```bash
git clone <repository-url>
cd ziya-slint
```
2. Build and run:
```bash
cargo run
```
## Development
### Running in Development Mode
```bash
# Run with debug logging
RUST_LOG=debug cargo run
```
### Building for Release
```bash
cargo build --release
```
## Architecture
### UI Layer (Slint)
The UI is defined in `ui/app-window.slint` using Slint's declarative language. Key features:
- **State-based rendering**: Different UI states for loading, login, dashboard, etc.
- **Reactive properties**: Automatic UI updates when data changes
- **Component composition**: Reusable UI elements
- **Modern styling**: Clean, professional design
### Business Logic (Rust)
- **Services Pattern**: Separate services for different concerns
- **Async/Await**: Non-blocking operations for better UX
- **Error Handling**: Proper error propagation with `anyhow`
- **Type Safety**: Strong typing throughout the application
### Key Components
1. **TokenService**: Handles token data fetching and search
2. **UserService**: Manages user authentication and profiles
3. **AppState**: Central application state management
4. **Main**: Coordinates UI and business logic
## Comparison with Vue/Electron Version
| Aspect | Vue/Electron | Slint/Rust |
|--------|--------------|------------|
| **Performance** | ~50MB memory, slower startup | ~10MB memory, instant startup |
| **Bundle Size** | ~100MB with Node.js | ~5MB standalone binary |
| **Development** | Hot reload, web tools | Fast compilation, native debugging |
| **Deployment** | Requires Node.js runtime | Single self-contained binary |
| **UI Development** | HTML/CSS/JS knowledge required | Slint DSL (QML-like, simpler) |
| **Type Safety** | TypeScript (optional) | Full Rust type safety |
## Contributing
This is part of the bismillahDAO ecosystem. When contributing:
1. Follow Rust conventions and best practices
2. Keep UI logic in Slint files, business logic in Rust
3. Write tests for business logic
4. Update documentation for new features
## Migration Status
### ✅ Completed Features
- [x] Basic application structure
- [x] Loading, login, and dashboard states
- [x] Token list display and search
- [x] User profile management
- [x] Navigation between views
- [x] Mock data services
### 🚧 In Progress
- [ ] Real API integration
- [ ] Advanced token analysis
- [ ] Wallet integration
- [ ] Trading features
### 📋 Planned Features
- [ ] Real-time token price updates
- [ ] Advanced charting
- [ ] Portfolio tracking
- [ ] Trading automation
- [ ] Export/import functionality
## License
MIT License - see LICENSE file for details.
## About bismillahDAO
This project is created by bismillahDAO, focused on building ethical and innovative trading tools for the cryptocurrency community.

8
build.rs Normal file
View file

@ -0,0 +1,8 @@
fn main() {
// Use fluent-light as default, but we'll support dynamic switching
let config = slint_build::CompilerConfiguration::new()
.with_style("fluent-light".to_string());
slint_build::compile_with_config("ui/index.slint", config)
.expect("Slint build failed");
}

BIN
public/favicon.ico Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.2 KiB

View file

@ -0,0 +1,4 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg xmlns="http://www.w3.org/2000/svg" id="Layer_1" data-name="Layer 1" viewBox="0 0 24 24" style="filter: brightness(0) invert(1);">
<path fill="currentColor" d="m20.5,13c-1.204,0-2.268.612-2.898,1.54l-1.014-.563c.263-.607.411-1.275.411-1.977,0-2.757-2.243-5-5-5-.822,0-1.586.218-2.27.571l-.937-1.448c.734-.642,1.207-1.574,1.207-2.623,0-1.93-1.57-3.5-3.5-3.5s-3.5,1.57-3.5,3.5,1.57,3.5,3.5,3.5c.521,0,1.012-.122,1.457-.328l.934,1.443c-1.143.917-1.891,2.308-1.891,3.884,0,1.198.441,2.284,1.146,3.146l-2.56,2.56c-.584-.438-1.302-.707-2.086-.707-1.93,0-3.5,1.57-3.5,3.5s1.57,3.5,3.5,3.5,3.5-1.57,3.5-3.5c0-.785-.269-1.502-.707-2.086l2.56-2.56c.862.705,1.948,1.146,3.146,1.146,1.697,0,3.195-.854,4.099-2.151l1.08.6c-.106.334-.179.682-.179,1.051,0,1.93,1.57,3.5,3.5,3.5s3.5-1.57,3.5-3.5-1.57-3.5-3.5-3.5ZM4,3.5c0-1.378,1.121-2.5,2.5-2.5s2.5,1.122,2.5,2.5-1.121,2.5-2.5,2.5-2.5-1.122-2.5-2.5Zm-.5,19.5c-1.379,0-2.5-1.122-2.5-2.5s1.121-2.5,2.5-2.5,2.5,1.122,2.5,2.5-1.121,2.5-2.5,2.5Zm8.5-7c-2.206,0-4-1.794-4-4s1.794-4,4-4,4,1.794,4,4-1.794,4-4,4Zm8.5,3c-1.379,0-2.5-1.122-2.5-2.5s1.121-2.5,2.5-2.5,2.5,1.122,2.5,2.5-1.121,2.5-2.5,2.5Z"/>
</svg>

After

Width:  |  Height:  |  Size: 1.2 KiB

View file

@ -0,0 +1,2 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg xmlns="http://www.w3.org/2000/svg" id="Layer_1" data-name="Layer 1" viewBox="0 0 24 24" width="512" height="512"><path d="M20,12a3.994,3.994,0,0,0-3.172,1.566l-.07-.03a5,5,0,0,0-6.009-6.377l-.091-.172A3.995,3.995,0,1,0,8.879,7.9l.073.137a4.992,4.992,0,0,0-1.134,6.7L5.933,16.5a4,4,0,1,0,1.455,1.377l1.838-1.718a4.993,4.993,0,0,0,6.539-.871l.279.119A4,4,0,1,0,20,12ZM6,4A2,2,0,1,1,8,6,2,2,0,0,1,6,4ZM4,22a2,2,0,1,1,2-2A2,2,0,0,1,4,22Zm8-7a3,3,0,0,1-1.6-5.534l.407-.217A3,3,0,1,1,12,15Zm8,3a2,2,0,1,1,2-2A2,2,0,0,1,20,18Z"/></svg>

After

Width:  |  Height:  |  Size: 573 B

2
src/lib.rs Normal file
View file

@ -0,0 +1,2 @@
// This lib.rs is currently not used since we're building a binary application
// If needed in the future, add modules here

119
src/main.rs Normal file
View file

@ -0,0 +1,119 @@
// Prevent console window in addition to Slint window in Windows release builds when, e.g., starting the app via file manager. Ignored on other platforms.
#![cfg_attr(not(debug_assertions), windows_subsystem = "windows")]
use slint::*;
use i_slint_backend_winit::WinitWindowAccessor;
// Import the main window from our FSD-structured UI
slint::include_modules!();
fn main() -> Result<(), slint::PlatformError> {
// Create the main window
let ui = MainWindow::new()?;
// Clone handle for callbacks
let ui_handle = ui.as_weak();
// Handle navigation changes
ui.on_navigation_changed({
let ui_handle = ui_handle.clone();
move |page| {
println!("Navigation changed to: {}", page);
if let Some(ui) = ui_handle.upgrade() {
// Update current page state
ui.set_current_page(page.into());
}
}
});
// Handle theme toggle - using direct function call as per Slint discussion #5860
ui.on_theme_toggle_clicked({
let ui_handle = ui_handle.clone();
move || {
println!("Theme toggle callback received from UI");
if let Some(ui) = ui_handle.upgrade() {
// Call the public theme toggle function directly
ui.invoke_toggle_theme();
println!("Theme toggle function invoked successfully");
}
}
});
// Handle logout
ui.on_logout_clicked({
let _ui_handle = ui_handle.clone();
move || {
println!("Logout clicked");
// Implement logout logic here
}
});
// Handle buy action
ui.on_buy_clicked({
let _ui_handle = ui_handle.clone();
move || {
println!("Buy clicked");
// Implement buy logic here
}
});
// Handle sell action
ui.on_sell_clicked({
let _ui_handle = ui_handle.clone();
move || {
println!("Sell clicked");
// Implement sell logic here
}
});
// Window control handlers - simplified drag handling
ui.on_start_drag_window({
let ui_handle = ui_handle.clone();
move || {
if let Some(ui) = ui_handle.upgrade() {
let window = ui.window();
window.with_winit_window(|winit_window| {
if !window.is_maximized() {
let _ = winit_window.drag_window();
}
});
}
}
});
ui.on_minimize_window({
let ui_handle = ui_handle.clone();
move || {
if let Some(ui) = ui_handle.upgrade() {
let _ = ui.window().set_minimized(true);
}
}
});
ui.on_maximize_window({
let ui_handle = ui_handle.clone();
move || {
if let Some(ui) = ui_handle.upgrade() {
let window = ui.window();
let _ = window.set_maximized(!window.is_maximized());
}
}
});
ui.on_close_window({
let ui_handle = ui_handle.clone();
move || {
if let Some(ui) = ui_handle.upgrade() {
let _ = ui.window().hide();
let _ = slint::quit_event_loop();
}
}
});
// Set initial state
ui.set_current_page("Dashboard".into());
ui.set_user_initials("JD".into());
// Run the application
ui.run()
}

325
ui/app/index.slint Normal file
View file

@ -0,0 +1,325 @@
// App Layer - Main Application Entry Point
// This is the root of the application following Feature-Sliced Design
// No std-widgets needed since we're using Layout components
// Import from shared layer (design system, UI kit)
import { Theme } from "../shared/design-system/tokens/theme.slint";
// Import widgets (standalone UI blocks)
import { NavigationWidget } from "../widgets/navigation/index.slint";
// Import pages
import { Dashboard } from "../pages/dashboard/index.slint";
export component App {
width: 100%;
height: 100%;
// Application state
in-out property <string> current-page: "Dashboard";
in-out property <string> user-initials: "JD";
// Callbacks
callback navigation-changed(string);
callback theme-toggle-clicked();
callback logout-clicked();
callback buy-clicked();
callback sell-clicked();
callback start-drag-window();
callback minimize-window();
callback maximize-window();
callback close-window();
// Global drag area - covers entire window but sits behind interactive elements
TouchArea {
width: 100%;
height: 100%;
z: -1;
moved => {
if (self.pressed) {
root.start-drag-window();
}
}
}
VerticalLayout {
spacing: 0px;
// Title Bar - fixed height
Rectangle {
height: 32px;
background: Theme.surface;
HorizontalLayout {
padding: 4px;
spacing: 8px;
// Draggable area (left side) - takes most of the space
Rectangle {
horizontal-stretch: 1;
Text {
text: "Ziya Trading Platform";
color: Theme.text-primary;
font-size: 14px;
font-weight: 600;
vertical-alignment: center;
x: 8px;
}
}
// Theme Toggle Button - fixed size
Rectangle {
width: 40px;
height: 20px;
border-radius: 10px;
background: Theme.is-dark-mode ? Theme.primary : Theme.border;
Rectangle {
width: 16px;
height: 16px;
border-radius: 8px;
background: white;
x: Theme.is-dark-mode ? 22px : 2px;
y: 2px;
animate x { duration: 200ms; easing: ease-in-out; }
}
TouchArea {
clicked => {
theme-toggle-clicked();
}
}
}
// Window Controls - fixed size
HorizontalLayout {
spacing: 2px;
// Minimize Button
Rectangle {
width: 28px;
height: 24px;
border-radius: 2px;
background: minimize-area.pressed ? #30404040 : minimize-area.has-hover ? #20404040 : transparent;
Text {
text: "";
color: Theme.text-primary;
font-size: 14px;
font-weight: 400;
horizontal-alignment: center;
vertical-alignment: center;
}
minimize-area := TouchArea {
clicked => { minimize-window(); }
}
}
// Maximize Button
Rectangle {
width: 28px;
height: 24px;
border-radius: 2px;
background: maximize-area.pressed ? #30404040 : maximize-area.has-hover ? #20404040 : transparent;
Text {
text: "□";
color: Theme.text-primary;
font-size: 12px;
font-weight: 400;
horizontal-alignment: center;
vertical-alignment: center;
}
maximize-area := TouchArea {
clicked => { maximize-window(); }
}
}
// Close Button
Rectangle {
width: 28px;
height: 24px;
border-radius: 2px;
background: close-area.pressed ? #E53E3E : close-area.has-hover ? #C53030 : transparent;
Text {
text: "×";
color: close-area.has-hover ? white : Theme.text-primary;
font-size: 16px;
font-weight: 400;
horizontal-alignment: center;
vertical-alignment: center;
}
close-area := TouchArea {
clicked => { close-window(); }
}
}
}
}
}
// Main content area - stretches to fill remaining vertical space
HorizontalLayout {
spacing: 0px;
// Navigation Widget (Sidebar) - fixed width
NavigationWidget {
width: 280px;
current-page: root.current-page;
user-initials: root.user-initials;
navigation-changed(page) => {
root.current-page = page;
root.navigation-changed(page);
}
logout-clicked => { root.logout-clicked(); }
}
// Main content area - stretches to fill remaining horizontal space
Rectangle {
background: Theme.background;
// Page routing based on current-page
if current-page == "Dashboard": Dashboard {
user-initials: root.user-initials;
logout => { root.logout-clicked(); }
trade-buy(asset, amount) => { root.buy-clicked(); }
trade-sell(asset, amount) => { root.sell-clicked(); }
}
if current-page == "Trading": Rectangle {
background: Theme.background;
VerticalLayout {
padding: 24px;
spacing: 16px;
alignment: center;
Text {
text: "🎯 Trading Interface";
font-size: 32px;
font-weight: 700;
color: Theme.text-primary;
horizontal-alignment: center;
}
Text {
text: "Advanced trading features coming soon...";
font-size: 18px;
color: Theme.text-secondary;
horizontal-alignment: center;
}
}
}
if current-page == "Portfolio": Rectangle {
background: Theme.background;
VerticalLayout {
padding: 24px;
spacing: 16px;
alignment: center;
Text {
text: "💼 Portfolio Management";
font-size: 32px;
font-weight: 700;
color: Theme.text-primary;
horizontal-alignment: center;
}
Text {
text: "Portfolio tracking and management features coming soon...";
font-size: 18px;
color: Theme.text-secondary;
horizontal-alignment: center;
}
}
}
if current-page == "Markets": Rectangle {
background: Theme.background;
VerticalLayout {
padding: 24px;
spacing: 16px;
alignment: center;
Text {
text: "📈 Market Data";
font-size: 32px;
font-weight: 700;
color: Theme.text-primary;
horizontal-alignment: center;
}
Text {
text: "Real-time market data and analysis coming soon...";
font-size: 18px;
color: Theme.text-secondary;
horizontal-alignment: center;
}
}
}
if current-page == "HuntingGround": Rectangle {
background: Theme.background;
VerticalLayout {
padding: 24px;
spacing: 16px;
alignment: center;
Text {
text: "🎯 Token Hunting Ground";
font-size: 32px;
font-weight: 700;
color: Theme.text-primary;
horizontal-alignment: center;
}
Text {
text: "Discover and track new tokens coming soon...";
font-size: 18px;
color: Theme.text-secondary;
horizontal-alignment: center;
}
}
}
if current-page == "Profile": Rectangle {
background: Theme.background;
VerticalLayout {
padding: 24px;
spacing: 16px;
alignment: center;
Text {
text: "👤 User Profile";
font-size: 32px;
font-weight: 700;
color: Theme.text-primary;
horizontal-alignment: center;
}
Text {
text: "Profile management and settings coming soon...";
font-size: 18px;
color: Theme.text-secondary;
horizontal-alignment: center;
}
}
}
}
}
}
}

View file

@ -0,0 +1,2 @@
// Token Entity Public API
export { TokenListView } from "ui/token-list.slint";

View file

@ -0,0 +1,181 @@
import { Button, VerticalBox, HorizontalBox, LineEdit, ScrollView } from "std-widgets.slint";
// Token data structure
export struct TokenData {
name: string,
symbol: string,
price: string,
market-cap: string,
volume: string,
}
// Token list component
export component TokenListView {
in-out property <color> primary-color: #2563eb;
in-out property <color> background-color: #f8fafc;
in-out property <color> card-background: #ffffff;
in-out property <color> text-color: #1e293b;
in-out property <color> border-color: #e2e8f0;
in-out property <string> search-query: "";
in-out property <[TokenData]> tokens: [];
// Callbacks
callback search-changed(string);
callback token-selected(TokenData);
Rectangle {
background: background-color;
VerticalBox {
spacing: 20px;
padding: 20px;
// Header section
VerticalBox {
spacing: 15px;
Text {
text: "Token Explorer";
font-size: 24px;
color: text-color;
font-weight: 700;
}
// Search bar
LineEdit {
placeholder-text: "Search tokens...";
text <=> search-query;
height: 45px;
edited => {
search-changed(search-query);
}
}
}
// Token list
ScrollView {
viewport-height: 400px;
VerticalBox {
spacing: 10px;
for token in tokens: Rectangle {
height: 80px;
background: card-background;
border-radius: 12px;
border-width: 1px;
border-color: border-color;
drop-shadow-blur: 5px;
drop-shadow-color: #00000008;
HorizontalBox {
alignment: stretch;
spacing: 15px;
padding: 15px;
// Token icon placeholder
Rectangle {
width: 50px;
height: 50px;
border-radius: 25px;
background: primary-color.with-alpha(0.1);
Text {
text: token.symbol.to-uppercase();
color: primary-color;
font-weight: 700;
font-size: 14px;
}
}
// Token info
VerticalBox {
alignment: start;
spacing: 5px;
Text {
text: token.name;
font-size: 16px;
color: text-color;
font-weight: 600;
}
Text {
text: token.symbol.to-uppercase();
font-size: 12px;
color: text-color;
opacity: 0.7;
}
}
// Price info
VerticalBox {
alignment: end;
spacing: 5px;
Text {
text: "$" + token.price;
font-size: 16px;
color: text-color;
font-weight: 600;
horizontal-alignment: right;
}
HorizontalBox {
alignment: end;
spacing: 10px;
Text {
text: "MC: $" + token.market-cap;
font-size: 10px;
color: text-color;
opacity: 0.6;
}
Text {
text: "Vol: $" + token.volume;
font-size: 10px;
color: text-color;
opacity: 0.6;
}
}
}
}
TouchArea {
clicked => {
token-selected(token);
}
}
}
}
}
// Loading state or empty state
if tokens.length == 0: Rectangle {
height: 200px;
background: card-background;
border-radius: 12px;
border-width: 1px;
border-color: border-color;
VerticalBox {
alignment: center;
spacing: 10px;
Text {
text: search-query == "" ? "🔍" : "😔";
font-size: 32px;
}
Text {
text: search-query == "" ? "Loading tokens..." : "No tokens found";
color: text-color;
opacity: 0.7;
font-size: 14px;
}
}
}
}
}
}

75
ui/index.slint Normal file
View file

@ -0,0 +1,75 @@
// Main Entry Point - Following Feature-Sliced Design
// This is the root file that main.rs imports
// Following the pattern from moonlogs: index -> app -> pages/widgets/entities/shared
import { App } from "app/index.slint";
import { Theme } from "shared/design-system/index.slint";
export component MainWindow inherits Window {
// Window properties
preferred-width: 1280px;
preferred-height: 1024px;
min-width: 1080px;
min-height: 800px;
no-frame: true;
background: Theme.background;
// Properties
in-out property <string> current-page: "Dashboard";
in-out property <string> user-initials: "JD";
// Callbacks that will be handled by main.rs
callback navigation-changed(string);
callback theme-toggle-clicked();
callback logout-clicked();
callback buy-clicked();
callback sell-clicked();
callback start-drag-window();
callback minimize-window();
callback maximize-window();
callback close-window();
// Public function that can be called from Rust to toggle theme
public function toggle_theme() {
Theme.is-dark-mode = !Theme.is-dark-mode;
debug("Theme toggled from Rust. New state: " + (Theme.is-dark-mode ? "dark" : "light"));
}
// App component handles all the UI following FSD layers
App {
width: 100%;
height: 100%;
current-page: root.current-page;
user-initials: root.user-initials;
// Forward all callbacks to main.rs
navigation-changed(page) => {
root.current-page = page;
root.navigation-changed(page);
}
theme-toggle-clicked => {
root.theme-toggle-clicked();
}
logout-clicked => {
root.logout-clicked();
}
buy-clicked => {
root.buy-clicked();
}
sell-clicked => {
root.sell-clicked();
}
start-drag-window => {
root.start-drag-window();
}
minimize-window => {
root.minimize-window();
}
maximize-window => {
root.maximize-window();
}
close-window => {
root.close-window();
}
}
}

View file

@ -0,0 +1,2 @@
// Auth Page Public API
export { LoginView } from "ui/login-page.slint";

View file

@ -0,0 +1,155 @@
import { Button, VerticalBox, HorizontalBox, LineEdit } from "std-widgets.slint";
// Login component with branded interface
export component LoginView {
in-out property <color> primary-color: #2563eb;
in-out property <color> background-color: #f8fafc;
in-out property <color> text-color: #1e293b;
in-out property <string> app-version: "0.2.0";
// Login form state
in-out property <string> email: "";
in-out property <string> password: "";
// Callbacks
callback login-clicked(string, string);
callback navigate-to-dashboard();
Rectangle {
background: background-color;
VerticalBox {
alignment: center;
spacing: 30px;
padding: 40px;
// Logo and branding section
VerticalBox {
alignment: center;
spacing: 10px;
Rectangle {
width: 80px;
height: 80px;
border-radius: 40px;
background: primary-color.with-alpha(0.1);
// Logo placeholder
Rectangle {
width: 40px;
height: 40px;
background: primary-color;
border-radius: 20px;
}
}
Text {
text: "Ziya";
font-size: 48px;
color: text-color;
font-weight: 700;
}
Text {
text: "/dˤiˈjaːʔ/, \"zeeyah\" — Proper noun, meaning \"light\"";
font-size: 14px;
color: text-color;
opacity: 0.6;
}
Text {
text: "One stop shop trading solution";
font-size: 20px;
color: text-color;
opacity: 0.8;
}
Text {
text: "A bismillahDAO creation";
font-size: 12px;
color: primary-color;
font-weight: 600;
}
}
// Login form section
VerticalBox {
alignment: center;
spacing: 20px;
width: 400px;
// Email field
VerticalBox {
spacing: 8px;
Text {
text: "Email";
color: text-color;
font-weight: 500;
}
LineEdit {
placeholder-text: "Enter your email";
text <=> email;
height: 45px;
}
}
// Password field
VerticalBox {
spacing: 8px;
Text {
text: "Password";
color: text-color;
font-weight: 500;
}
LineEdit {
placeholder-text: "Enter your password";
text <=> password;
height: 45px;
}
}
// Login button
Button {
text: "Sign In";
primary: true;
height: 50px;
clicked => {
login-clicked(email, password);
}
}
// Quick access button
HorizontalBox {
spacing: 10px;
alignment: center;
Text {
text: "Quick access:";
color: text-color;
opacity: 0.7;
font-size: 12px;
}
Button {
text: "Demo Mode";
height: 35px;
clicked => {
navigate-to-dashboard();
}
}
}
Text {
text: "Version " + app-version;
font-size: 10px;
color: text-color;
opacity: 0.5;
}
}
}
}
}

View file

@ -0,0 +1,2 @@
// Dashboard Page Public API
export { Dashboard } from "ui/dashboard-page.slint";

View file

@ -0,0 +1,443 @@
import { ScrollView, Button, LineEdit, ComboBox } from "std-widgets.slint";
import { Theme } from "../../../shared/design-system/tokens/theme.slint";
// Professional dashboard component with global theme support
export component Dashboard {
width: 100%;
height: 100%;
in-out property <string> user-initials: "JD";
callback logout();
callback trade-buy(string, string);
callback trade-sell(string, string);
// Let the parent layout handle sizing
VerticalLayout {
spacing: 0px;
// Top navbar using HorizontalLayout for proper layout
Rectangle {
height: 64px;
background: Theme.surface;
border-width: 1px;
border-color: Theme.border;
HorizontalLayout {
padding: 16px;
alignment: stretch;
Text {
text: "Ziya Dashboard";
color: Theme.text-primary;
font-size: 20px;
font-weight: 700;
vertical-alignment: center;
}
// Spacer to push user profile to the right
Rectangle {
horizontal-stretch: 1;
}
// User profile button
Rectangle {
width: 40px;
height: 40px;
background: Theme.primary;
border-radius: 20px;
Text {
text: user-initials;
color: white;
font-size: 14px;
font-weight: 700;
horizontal-alignment: center;
vertical-alignment: center;
}
TouchArea {
clicked => { logout(); }
}
}
}
}
// Dashboard content - no scrollbar, just layout
VerticalLayout {
vertical-stretch: 1;
padding: 24px;
spacing: 24px;
// Stats cards row using HorizontalLayout with proper stretch
HorizontalLayout {
spacing: 24px;
alignment: stretch;
// Total Balance
Rectangle {
horizontal-stretch: 1;
background: Theme.card-background;
border-radius: 12px;
border-width: 1px;
border-color: Theme.card-border;
drop-shadow-blur: 8px;
drop-shadow-color: Theme.is-dark-mode ? #00000020 : #00000008;
VerticalLayout {
padding: 20px;
spacing: 8px;
Text {
text: "Total Balance";
color: Theme.text-secondary;
font-size: 14px;
font-weight: 500;
horizontal-alignment: left;
}
Text {
text: "$25,600";
color: Theme.primary;
font-size: 32px;
font-weight: 700;
horizontal-alignment: left;
}
Text {
text: "↗︎ 12% (30d)";
color: Theme.success;
font-size: 13px;
font-weight: 500;
horizontal-alignment: left;
}
}
}
// Active Positions
Rectangle {
horizontal-stretch: 1;
background: Theme.card-background;
border-radius: 12px;
border-width: 1px;
border-color: Theme.card-border;
drop-shadow-blur: 8px;
drop-shadow-color: Theme.is-dark-mode ? #00000020 : #00000008;
VerticalLayout {
padding: 20px;
spacing: 8px;
Text {
text: "Active Positions";
color: Theme.text-secondary;
font-size: 14px;
font-weight: 500;
horizontal-alignment: left;
}
Text {
text: "8";
color: Theme.warning;
font-size: 32px;
font-weight: 700;
horizontal-alignment: left;
}
Text {
text: "↗︎ 2 new today";
color: Theme.success;
font-size: 13px;
font-weight: 500;
horizontal-alignment: left;
}
}
}
// P&L Today
Rectangle {
horizontal-stretch: 1;
background: Theme.card-background;
border-radius: 12px;
border-width: 1px;
border-color: Theme.card-border;
drop-shadow-blur: 8px;
drop-shadow-color: Theme.is-dark-mode ? #00000020 : #00000008;
VerticalLayout {
padding: 20px;
spacing: 8px;
Text {
text: "P&L Today";
color: Theme.text-secondary;
font-size: 14px;
font-weight: 500;
horizontal-alignment: left;
}
Text {
text: "+$450";
color: Theme.success;
font-size: 32px;
font-weight: 700;
horizontal-alignment: left;
}
Text {
text: "↗︎ +2.1%";
color: Theme.success;
font-size: 13px;
font-weight: 500;
horizontal-alignment: left;
}
}
}
}
// Trading interface row using HorizontalLayout
HorizontalLayout {
spacing: 24px;
alignment: stretch;
// Quick Trade card
Rectangle {
horizontal-stretch: 2;
background: Theme.card-background;
border-radius: 16px;
border-width: 1px;
border-color: Theme.card-border;
drop-shadow-blur: 16px;
drop-shadow-color: Theme.is-dark-mode ? #00000020 : #00000008;
VerticalLayout {
padding: 24px;
spacing: 20px;
Text {
text: "Quick Trade";
color: Theme.text-primary;
font-size: 18px;
font-weight: 700;
horizontal-alignment: left;
}
// Token selector using HorizontalLayout
HorizontalLayout {
spacing: 12px;
alignment: start;
Text {
text: "Token:";
color: Theme.text-secondary;
font-size: 14px;
vertical-alignment: center;
}
ComboBox {
model: ["SOL", "BTC", "ETH", "USDC"];
current-value: "SOL";
}
}
// Amount input using HorizontalLayout
HorizontalLayout {
spacing: 12px;
alignment: start;
Text {
text: "Amount:";
color: Theme.text-secondary;
font-size: 14px;
vertical-alignment: center;
}
LineEdit {
placeholder-text: "0.00";
horizontal-stretch: 1;
}
}
// Trade buttons using HorizontalLayout
HorizontalLayout {
spacing: 12px;
alignment: stretch;
Button {
text: "Buy";
primary: true;
horizontal-stretch: 1;
clicked => {
trade-buy("SOL", "100");
}
}
Button {
text: "Sell";
horizontal-stretch: 1;
clicked => {
trade-sell("SOL", "50");
}
}
}
}
}
// Recent Activity card
Rectangle {
horizontal-stretch: 1;
background: Theme.card-background;
border-radius: 16px;
border-width: 1px;
border-color: Theme.card-border;
drop-shadow-blur: 16px;
drop-shadow-color: Theme.is-dark-mode ? #00000020 : #00000008;
VerticalLayout {
padding: 24px;
spacing: 16px;
Text {
text: "Recent Activity";
color: Theme.text-primary;
font-size: 18px;
font-weight: 700;
horizontal-alignment: left;
}
// Activity items using VerticalLayout
VerticalLayout {
spacing: 12px;
// Activity item 1
HorizontalLayout {
spacing: 12px;
alignment: stretch;
Rectangle {
width: 8px;
height: 8px;
border-radius: 4px;
background: Theme.success;
}
VerticalLayout {
spacing: 2px;
horizontal-stretch: 1;
Text {
text: "Bought 2.5 SOL";
color: Theme.text-primary;
font-size: 14px;
font-weight: 500;
}
Text {
text: "2 minutes ago";
color: Theme.text-secondary;
font-size: 12px;
}
}
}
// Activity item 2
HorizontalLayout {
spacing: 12px;
alignment: stretch;
Rectangle {
width: 8px;
height: 8px;
border-radius: 4px;
background: Theme.error;
}
VerticalLayout {
spacing: 2px;
horizontal-stretch: 1;
Text {
text: "Sold 1.0 ETH";
color: Theme.text-primary;
font-size: 14px;
font-weight: 500;
}
Text {
text: "1 hour ago";
color: Theme.text-secondary;
font-size: 12px;
}
}
}
// Activity item 3
HorizontalLayout {
spacing: 12px;
alignment: stretch;
Rectangle {
width: 8px;
height: 8px;
border-radius: 4px;
background: Theme.warning;
}
VerticalLayout {
spacing: 2px;
horizontal-stretch: 1;
Text {
text: "Staked 100 USDC";
color: Theme.text-primary;
font-size: 14px;
font-weight: 500;
}
Text {
text: "3 hours ago";
color: Theme.text-secondary;
font-size: 12px;
}
}
}
}
}
}
}
// Theme demonstration section
Rectangle {
background: Theme.surface;
border-radius: 12px;
border-width: 1px;
border-color: Theme.border;
VerticalLayout {
padding: 20px;
spacing: 12px;
Text {
text: "Theme Status";
color: Theme.text-primary;
font-size: 16px;
font-weight: 600;
}
Text {
text: "Current theme: " + (Theme.is-dark-mode ? "Dark Mode 🌙" : "Light Mode ☀️");
color: Theme.text-secondary;
font-size: 14px;
}
Text {
text: "All components are now using the global theme system for consistent theming across the application.";
color: Theme.text-secondary;
font-size: 12px;
}
}
}
}
}
}

View file

@ -0,0 +1,2 @@
// Hunting Ground Page Public API
export { HuntingGroundPage } from "ui/hunting-ground-page.slint";

View file

@ -0,0 +1,30 @@
import { VerticalBox } from "std-widgets.slint";
import { Theme } from "../../../shared/design-system/tokens/theme.slint";
// Hunting Ground Page Component
export component HuntingGroundPage {
Rectangle {
background: Theme.background;
VerticalBox {
padding: 32px;
spacing: 24px;
alignment: center;
Text {
text: "🎯 Hunting Ground";
color: Theme.text-primary;
font-size: 32px;
font-weight: 700;
horizontal-alignment: center;
}
Text {
text: "Advanced token hunting and discovery features";
color: Theme.text-secondary;
font-size: 16px;
horizontal-alignment: center;
}
}
}
}

View file

@ -0,0 +1,2 @@
// Markets Page Public API
export { MarketsPage } from "ui/markets-page.slint";

View file

@ -0,0 +1,30 @@
import { VerticalBox } from "std-widgets.slint";
import { Theme } from "../../../shared/design-system/tokens/theme.slint";
// Markets Page Component
export component MarketsPage {
Rectangle {
background: Theme.background;
VerticalBox {
padding: 32px;
spacing: 24px;
alignment: center;
Text {
text: "Markets";
color: Theme.text-primary;
font-size: 32px;
font-weight: 700;
horizontal-alignment: center;
}
Text {
text: "Market data and analysis will be displayed here";
color: Theme.text-secondary;
font-size: 16px;
horizontal-alignment: center;
}
}
}
}

View file

@ -0,0 +1,2 @@
// Portfolio Page Public API
export { PortfolioPage } from "ui/portfolio-page.slint";

View file

@ -0,0 +1,30 @@
import { VerticalBox } from "std-widgets.slint";
import { Theme } from "../../../shared/design-system/tokens/theme.slint";
// Portfolio Page Component
export component PortfolioPage {
Rectangle {
background: Theme.background;
VerticalBox {
padding: 32px;
spacing: 24px;
alignment: center;
Text {
text: "Portfolio";
color: Theme.text-primary;
font-size: 32px;
font-weight: 700;
horizontal-alignment: center;
}
Text {
text: "Your investment portfolio will be displayed here";
color: Theme.text-secondary;
font-size: 16px;
horizontal-alignment: center;
}
}
}
}

View file

@ -0,0 +1,2 @@
// Trading Page Public API
export { TradingPage } from "ui/trading-page.slint";

View file

@ -0,0 +1,78 @@
import { VerticalBox, HorizontalBox } from "std-widgets.slint";
import { Theme } from "../../../shared/design-system/tokens/theme.slint";
// Trading Page Component
export component TradingPage {
callback buy-clicked();
callback sell-clicked();
Rectangle {
background: Theme.background;
VerticalBox {
padding: 32px;
spacing: 24px;
alignment: center;
Text {
text: "Trading Page";
color: Theme.text-primary;
font-size: 32px;
font-weight: 700;
horizontal-alignment: center;
}
Text {
text: "Advanced trading features coming soon...";
color: Theme.text-secondary;
font-size: 16px;
horizontal-alignment: center;
}
HorizontalBox {
spacing: 16px;
alignment: center;
Rectangle {
width: 120px;
height: 40px;
background: #10b981;
border-radius: 8px;
Text {
text: "Buy";
color: white;
font-size: 14px;
font-weight: 600;
horizontal-alignment: center;
vertical-alignment: center;
}
TouchArea {
clicked => { buy-clicked(); }
}
}
Rectangle {
width: 120px;
height: 40px;
background: #ef4444;
border-radius: 8px;
Text {
text: "Sell";
color: white;
font-size: 14px;
font-weight: 600;
horizontal-alignment: center;
vertical-alignment: center;
}
TouchArea {
clicked => { sell-clicked(); }
}
}
}
}
}
}

View file

@ -0,0 +1,5 @@
// Shared Configuration Public API
// Export application configuration
// Currently no config defined
// export * from "app-config.slint";

View file

@ -0,0 +1,971 @@
// Fluent 2 Design System for Ziya Trading Platform
// Based on Microsoft Fluent 2 Design Language
// https://fluent2.microsoft.design/
// Complete Fluent UI Color System - All Themes Support
// Theme mode enumeration
export enum ColorMode { light, dark, team-light, team-dark }
export global FluentColors {
// Current theme mode
in-out property <ColorMode> current-mode: ColorMode.light;
// Theme switching callback
callback switch-theme(ColorMode);
// ===== LIGHT THEME COLORS =====
// Neutral Colors - Light
out property <color> neutral-foreground-1-light: #242424;
out property <color> neutral-foreground-2-light: #424242;
out property <color> neutral-foreground-3-light: #616161;
out property <color> neutral-foreground-4-light: #757575;
out property <color> neutral-foreground-disabled-light: #bdbdbd;
out property <color> neutral-foreground-inverted-light: #ffffff;
out property <color> neutral-foreground-inverted-2-light: #f5f5f5;
out property <color> neutral-foreground-on-brand-light: #ffffff;
out property <color> neutral-foreground-static-inverted-light: #ffffff;
out property <color> neutral-foreground-inverted-disabled-light: #ffffff;
// Interactive states - Light theme
out property <color> neutral-foreground-1-hover-light: #424242;
out property <color> neutral-foreground-1-pressed-light: #242424;
out property <color> neutral-foreground-2-hover-light: #616161;
out property <color> neutral-foreground-2-pressed-light: #424242;
out property <color> neutral-foreground-2-brand-hover-light: #0078d4;
out property <color> neutral-foreground-2-brand-pressed-light: #005a9e;
out property <color> neutral-foreground-2-brand-selected-light: #0078d4;
// Link colors - Light theme
out property <color> neutral-foreground-link-light: #0078d4;
out property <color> neutral-foreground-link-hover-light: #106ebe;
out property <color> neutral-foreground-link-pressed-light: #005a9e;
out property <color> neutral-foreground-link-selected-light: #0078d4;
out property <color> neutral-background-1-light: #ffffff;
out property <color> neutral-background-2-light: #fafafa;
out property <color> neutral-background-3-light: #f5f5f5;
out property <color> neutral-background-4-light: #f0f0f0;
out property <color> neutral-background-5-light: #ebebeb;
out property <color> neutral-background-6-light: #e1e1e1;
out property <color> neutral-background-inverted-light: #292929;
out property <color> neutral-background-static-light: #f0f0f0;
out property <color> neutral-background-alpha-light: #ffffff;
out property <color> neutral-background-alpha-2-light: #ffffff;
// Background interactive states - Light theme
out property <color> neutral-background-1-hover-light: #f5f5f5;
out property <color> neutral-background-1-pressed-light: #f0f0f0;
out property <color> neutral-background-1-selected-light: #ebebeb;
out property <color> neutral-background-2-hover-light: #f0f0f0;
out property <color> neutral-background-2-pressed-light: #ebebeb;
out property <color> neutral-background-2-selected-light: #e1e1e1;
out property <color> neutral-background-3-hover-light: #ebebeb;
out property <color> neutral-background-3-pressed-light: #e1e1e1;
out property <color> neutral-background-3-selected-light: #c7c7c7;
out property <color> neutral-stroke-1-light: #e1e1e1;
out property <color> neutral-stroke-2-light: #c7c7c7;
out property <color> neutral-stroke-3-light: #b3b3b3;
out property <color> neutral-stroke-accessible-light: #616161;
out property <color> neutral-stroke-focus-1-light: #ffffff;
out property <color> neutral-stroke-focus-2-light: #000000;
out property <color> neutral-stroke-disabled-light: #e1e1e1;
// Stroke interactive states - Light theme
out property <color> neutral-stroke-1-hover-light: #c7c7c7;
out property <color> neutral-stroke-1-pressed-light: #b3b3b3;
out property <color> neutral-stroke-1-selected-light: #b3b3b3;
out property <color> neutral-stroke-2-hover-light: #b3b3b3;
out property <color> neutral-stroke-2-pressed-light: #9e9e9e;
// ===== DARK THEME COLORS =====
// Neutral Colors - Dark
out property <color> neutral-foreground-1-dark: #ffffff;
out property <color> neutral-foreground-2-dark: #f5f5f5;
out property <color> neutral-foreground-3-dark: #ebebeb;
out property <color> neutral-foreground-4-dark: #cccccc;
out property <color> neutral-foreground-disabled-dark: #858585;
out property <color> neutral-foreground-inverted-dark: #242424;
out property <color> neutral-foreground-inverted-2-dark: #292929;
out property <color> neutral-foreground-on-brand-dark: #ffffff;
out property <color> neutral-foreground-static-inverted-dark: #ffffff;
out property <color> neutral-foreground-inverted-disabled-dark: #858585;
// Interactive states - Dark theme
out property <color> neutral-foreground-1-hover-dark: #f5f5f5;
out property <color> neutral-foreground-1-pressed-dark: #ffffff;
out property <color> neutral-foreground-2-hover-dark: #ebebeb;
out property <color> neutral-foreground-2-pressed-dark: #f5f5f5;
out property <color> neutral-foreground-2-brand-hover-dark: #62abf5;
out property <color> neutral-foreground-2-brand-pressed-dark: #77b7f7;
out property <color> neutral-foreground-2-brand-selected-dark: #479ef5;
// Link colors - Dark theme
out property <color> neutral-foreground-link-dark: #479ef5;
out property <color> neutral-foreground-link-hover-dark: #62abf5;
out property <color> neutral-foreground-link-pressed-dark: #77b7f7;
out property <color> neutral-foreground-link-selected-dark: #479ef5;
out property <color> neutral-background-1-dark: #1c1c1c;
out property <color> neutral-background-2-dark: #242424;
out property <color> neutral-background-3-dark: #292929;
out property <color> neutral-background-4-dark: #333333;
out property <color> neutral-background-5-dark: #3d3d3d;
out property <color> neutral-background-6-dark: #474747;
out property <color> neutral-background-inverted-dark: #ffffff;
out property <color> neutral-background-static-dark: #333333;
out property <color> neutral-background-alpha-dark: #1c1c1c;
out property <color> neutral-background-alpha-2-dark: #1c1c1c;
// Background interactive states - Dark theme
out property <color> neutral-background-1-hover-dark: #242424;
out property <color> neutral-background-1-pressed-dark: #292929;
out property <color> neutral-background-1-selected-dark: #333333;
out property <color> neutral-background-2-hover-dark: #292929;
out property <color> neutral-background-2-pressed-dark: #333333;
out property <color> neutral-background-2-selected-dark: #3d3d3d;
out property <color> neutral-background-3-hover-dark: #333333;
out property <color> neutral-background-3-pressed-dark: #3d3d3d;
out property <color> neutral-background-3-selected-dark: #474747;
out property <color> neutral-stroke-1-dark: #3d3d3d;
out property <color> neutral-stroke-2-dark: #525252;
out property <color> neutral-stroke-3-dark: #666666;
out property <color> neutral-stroke-accessible-dark: #cccccc;
out property <color> neutral-stroke-focus-1-dark: #ffffff;
out property <color> neutral-stroke-focus-2-dark: #000000;
out property <color> neutral-stroke-disabled-dark: #3d3d3d;
// Stroke interactive states - Dark theme
out property <color> neutral-stroke-1-hover-dark: #525252;
out property <color> neutral-stroke-1-pressed-dark: #666666;
out property <color> neutral-stroke-1-selected-dark: #666666;
out property <color> neutral-stroke-2-hover-dark: #666666;
out property <color> neutral-stroke-2-pressed-dark: #757575;
// ===== TEAM LIGHT THEME COLORS =====
// Neutral Colors - Team Light
out property <color> neutral-foreground-1-team-light: #242424;
out property <color> neutral-foreground-2-team-light: #424242;
out property <color> neutral-foreground-3-team-light: #616161;
out property <color> neutral-foreground-4-team-light: #757575;
out property <color> neutral-foreground-disabled-team-light: #bdbdbd;
out property <color> neutral-foreground-inverted-team-light: #ffffff;
out property <color> neutral-foreground-inverted-2-team-light: #f5f5f5;
out property <color> neutral-foreground-on-brand-team-light: #ffffff;
out property <color> neutral-foreground-static-inverted-team-light: #ffffff;
out property <color> neutral-foreground-inverted-disabled-team-light: #ffffff;
// Interactive states - Team Light theme
out property <color> neutral-foreground-1-hover-team-light: #424242;
out property <color> neutral-foreground-1-pressed-team-light: #242424;
out property <color> neutral-foreground-2-hover-team-light: #616161;
out property <color> neutral-foreground-2-pressed-team-light: #424242;
out property <color> neutral-foreground-2-brand-hover-team-light: #585a96;
out property <color> neutral-foreground-2-brand-pressed-team-light: #4c4e85;
out property <color> neutral-foreground-2-brand-selected-team-light: #6264a7;
// Link colors - Team Light theme
out property <color> neutral-foreground-link-team-light: #6264a7;
out property <color> neutral-foreground-link-hover-team-light: #585a96;
out property <color> neutral-foreground-link-pressed-team-light: #4c4e85;
out property <color> neutral-foreground-link-selected-team-light: #6264a7;
out property <color> neutral-background-1-team-light: #ffffff;
out property <color> neutral-background-2-team-light: #f8f8f8;
out property <color> neutral-background-3-team-light: #f3f2f1;
out property <color> neutral-background-4-team-light: #edebe9;
out property <color> neutral-background-5-team-light: #e1dfdd;
out property <color> neutral-background-6-team-light: #d2d0ce;
out property <color> neutral-background-inverted-team-light: #292929;
out property <color> neutral-background-static-team-light: #edebe9;
out property <color> neutral-background-alpha-team-light: #ffffff;
out property <color> neutral-background-alpha-2-team-light: #ffffff;
// Background interactive states - Team Light theme
out property <color> neutral-background-1-hover-team-light: #f8f8f8;
out property <color> neutral-background-1-pressed-team-light: #f3f2f1;
out property <color> neutral-background-1-selected-team-light: #edebe9;
out property <color> neutral-background-2-hover-team-light: #f3f2f1;
out property <color> neutral-background-2-pressed-team-light: #edebe9;
out property <color> neutral-background-2-selected-team-light: #e1dfdd;
out property <color> neutral-background-3-hover-team-light: #edebe9;
out property <color> neutral-background-3-pressed-team-light: #e1dfdd;
out property <color> neutral-background-3-selected-team-light: #d2d0ce;
out property <color> neutral-stroke-1-team-light: #d2d0ce;
out property <color> neutral-stroke-2-team-light: #c8c6c4;
out property <color> neutral-stroke-3-team-light: #b3b0ad;
out property <color> neutral-stroke-accessible-team-light: #605e5c;
out property <color> neutral-stroke-focus-1-team-light: #ffffff;
out property <color> neutral-stroke-focus-2-team-light: #000000;
out property <color> neutral-stroke-disabled-team-light: #d2d0ce;
// Stroke interactive states - Team Light theme
out property <color> neutral-stroke-1-hover-team-light: #c8c6c4;
out property <color> neutral-stroke-1-pressed-team-light: #b3b0ad;
out property <color> neutral-stroke-1-selected-team-light: #b3b0ad;
out property <color> neutral-stroke-2-hover-team-light: #b3b0ad;
out property <color> neutral-stroke-2-pressed-team-light: #a19f9d;
// ===== TEAM DARK THEME COLORS =====
// Neutral Colors - Team Dark
out property <color> neutral-foreground-1-team-dark: #ffffff;
out property <color> neutral-foreground-2-team-dark: #f3f2f1;
out property <color> neutral-foreground-3-team-dark: #edebe9;
out property <color> neutral-foreground-4-team-dark: #d2d0ce;
out property <color> neutral-foreground-disabled-team-dark: #8a8886;
out property <color> neutral-foreground-inverted-team-dark: #242424;
out property <color> neutral-foreground-inverted-2-team-dark: #292929;
out property <color> neutral-foreground-on-brand-team-dark: #ffffff;
out property <color> neutral-foreground-static-inverted-team-dark: #ffffff;
out property <color> neutral-foreground-inverted-disabled-team-dark: #8a8886;
// Interactive states - Team Dark theme
out property <color> neutral-foreground-1-hover-team-dark: #f3f2f1;
out property <color> neutral-foreground-1-pressed-team-dark: #ffffff;
out property <color> neutral-foreground-2-hover-team-dark: #edebe9;
out property <color> neutral-foreground-2-pressed-team-dark: #f3f2f1;
out property <color> neutral-foreground-2-brand-hover-team-dark: #9a9bd2;
out property <color> neutral-foreground-2-brand-pressed-team-dark: #a8a9db;
out property <color> neutral-foreground-2-brand-selected-team-dark: #8b8cc8;
// Link colors - Team Dark theme
out property <color> neutral-foreground-link-team-dark: #8b8cc8;
out property <color> neutral-foreground-link-hover-team-dark: #9a9bd2;
out property <color> neutral-foreground-link-pressed-team-dark: #a8a9db;
out property <color> neutral-foreground-link-selected-team-dark: #8b8cc8;
out property <color> neutral-background-1-team-dark: #252423;
out property <color> neutral-background-2-team-dark: #2d2c2b;
out property <color> neutral-background-3-team-dark: #323130;
out property <color> neutral-background-4-team-dark: #3b3a39;
out property <color> neutral-background-5-team-dark: #484644;
out property <color> neutral-background-6-team-dark: #605e5c;
out property <color> neutral-background-inverted-team-dark: #ffffff;
out property <color> neutral-background-static-team-dark: #3b3a39;
out property <color> neutral-background-alpha-team-dark: #252423;
out property <color> neutral-background-alpha-2-team-dark: #252423;
// Background interactive states - Team Dark theme
out property <color> neutral-background-1-hover-team-dark: #2d2c2b;
out property <color> neutral-background-1-pressed-team-dark: #323130;
out property <color> neutral-background-1-selected-team-dark: #3b3a39;
out property <color> neutral-background-2-hover-team-dark: #323130;
out property <color> neutral-background-2-pressed-team-dark: #3b3a39;
out property <color> neutral-background-2-selected-team-dark: #484644;
out property <color> neutral-background-3-hover-team-dark: #3b3a39;
out property <color> neutral-background-3-pressed-team-dark: #484644;
out property <color> neutral-background-3-selected-team-dark: #605e5c;
out property <color> neutral-stroke-1-team-dark: #484644;
out property <color> neutral-stroke-2-team-dark: #605e5c;
out property <color> neutral-stroke-3-team-dark: #797775;
out property <color> neutral-stroke-accessible-team-dark: #d2d0ce;
out property <color> neutral-stroke-focus-1-team-dark: #ffffff;
out property <color> neutral-stroke-focus-2-team-dark: #000000;
out property <color> neutral-stroke-disabled-team-dark: #484644;
// Stroke interactive states - Team Dark theme
out property <color> neutral-stroke-1-hover-team-dark: #605e5c;
out property <color> neutral-stroke-1-pressed-team-dark: #797775;
out property <color> neutral-stroke-1-selected-team-dark: #797775;
out property <color> neutral-stroke-2-hover-team-dark: #797775;
out property <color> neutral-stroke-2-pressed-team-dark: #8a8886;
// ===== BRAND COLORS (All Themes) =====
// Brand Colors - Light
out property <color> brand-background-1-light: #0078d4;
out property <color> brand-background-2-light: #106ebe;
out property <color> brand-background-3-light: #005a9e;
out property <color> brand-foreground-1-light: #ffffff;
out property <color> brand-foreground-2-light: #f3f2f1;
out property <color> brand-stroke-1-light: #0078d4;
out property <color> brand-stroke-2-light: #106ebe;
// Brand interactive states - Light theme
out property <color> brand-background-1-hover-light: #106ebe;
out property <color> brand-background-1-pressed-light: #005a9e;
out property <color> brand-background-1-selected-light: #0078d4;
out property <color> brand-background-2-hover-light: #005a9e;
out property <color> brand-background-2-pressed-light: #004578;
out property <color> brand-stroke-1-hover-light: #106ebe;
out property <color> brand-stroke-1-pressed-light: #005a9e;
// Brand Colors - Dark
out property <color> brand-background-1-dark: #479ef5;
out property <color> brand-background-2-dark: #62abf5;
out property <color> brand-background-3-dark: #77b7f7;
out property <color> brand-foreground-1-dark: #ffffff;
out property <color> brand-foreground-2-dark: #f3f2f1;
out property <color> brand-stroke-1-dark: #479ef5;
out property <color> brand-stroke-2-dark: #62abf5;
// Brand interactive states - Dark theme
out property <color> brand-background-1-hover-dark: #62abf5;
out property <color> brand-background-1-pressed-dark: #77b7f7;
out property <color> brand-background-1-selected-dark: #479ef5;
out property <color> brand-background-2-hover-dark: #77b7f7;
out property <color> brand-background-2-pressed-dark: #8cc8f8;
out property <color> brand-stroke-1-hover-dark: #62abf5;
out property <color> brand-stroke-1-pressed-dark: #77b7f7;
// Brand Colors - Team Light
out property <color> brand-background-1-team-light: #6264a7;
out property <color> brand-background-2-team-light: #585a96;
out property <color> brand-background-3-team-light: #4c4e85;
out property <color> brand-foreground-1-team-light: #ffffff;
out property <color> brand-foreground-2-team-light: #f3f2f1;
out property <color> brand-stroke-1-team-light: #6264a7;
out property <color> brand-stroke-2-team-light: #585a96;
// Brand interactive states - Team Light theme
out property <color> brand-background-1-hover-team-light: #585a96;
out property <color> brand-background-1-pressed-team-light: #4c4e85;
out property <color> brand-background-1-selected-team-light: #6264a7;
out property <color> brand-background-2-hover-team-light: #4c4e85;
out property <color> brand-background-2-pressed-team-light: #414374;
out property <color> brand-stroke-1-hover-team-light: #585a96;
out property <color> brand-stroke-1-pressed-team-light: #4c4e85;
// Brand Colors - Team Dark
out property <color> brand-background-1-team-dark: #8b8cc8;
out property <color> brand-background-2-team-dark: #9a9bd2;
out property <color> brand-background-3-team-dark: #a8a9db;
out property <color> brand-foreground-1-team-dark: #ffffff;
out property <color> brand-foreground-2-team-dark: #f3f2f1;
out property <color> brand-stroke-1-team-dark: #8b8cc8;
out property <color> brand-stroke-2-team-dark: #9a9bd2;
// Brand interactive states - Team Dark theme
out property <color> brand-background-1-hover-team-dark: #9a9bd2;
out property <color> brand-background-1-pressed-team-dark: #a8a9db;
out property <color> brand-background-1-selected-team-dark: #8b8cc8;
out property <color> brand-background-2-hover-team-dark: #a8a9db;
out property <color> brand-background-2-pressed-team-dark: #b6b7e4;
out property <color> brand-stroke-1-hover-team-dark: #9a9bd2;
out property <color> brand-stroke-1-pressed-team-dark: #a8a9db;
// ===== SEMANTIC COLORS (All Themes) =====
// Success Colors - All Themes
out property <color> success-background-1-light: #107c10;
out property <color> success-background-2-light: #0e6e0e;
out property <color> success-foreground-1-light: #ffffff;
out property <color> success-stroke-1-light: #107c10;
out property <color> success-background-1-dark: #54b054;
out property <color> success-background-2-dark: #6bb26b;
out property <color> success-foreground-1-dark: #ffffff;
out property <color> success-stroke-1-dark: #54b054;
out property <color> success-background-1-team-light: #237b4b;
out property <color> success-background-2-team-light: #1e6f42;
out property <color> success-foreground-1-team-light: #ffffff;
out property <color> success-stroke-1-team-light: #237b4b;
out property <color> success-background-1-team-dark: #5bb85b;
out property <color> success-background-2-team-dark: #6fc46f;
out property <color> success-foreground-1-team-dark: #ffffff;
out property <color> success-stroke-1-team-dark: #5bb85b;
// Warning Colors - All Themes
out property <color> warning-background-1-light: #fde047;
out property <color> warning-background-2-light: #facc15;
out property <color> warning-foreground-1-light: #323130;
out property <color> warning-stroke-1-light: #f7c52d;
out property <color> warning-background-1-dark: #ffb900;
out property <color> warning-background-2-dark: #ffc328;
out property <color> warning-foreground-1-dark: #323130;
out property <color> warning-stroke-1-dark: #ffb900;
out property <color> warning-background-1-team-light: #c19c00;
out property <color> warning-background-2-team-light: #a18600;
out property <color> warning-foreground-1-team-light: #ffffff;
out property <color> warning-stroke-1-team-light: #c19c00;
out property <color> warning-background-1-team-dark: #ffd43a;
out property <color> warning-background-2-team-dark: #ffda56;
out property <color> warning-foreground-1-team-dark: #323130;
out property <color> warning-stroke-1-team-dark: #ffd43a;
// Critical/Error Colors - All Themes
out property <color> critical-background-1-light: #d13438;
out property <color> critical-background-2-light: #b91c1c;
out property <color> critical-foreground-1-light: #ffffff;
out property <color> critical-stroke-1-light: #d13438;
out property <color> critical-background-1-dark: #ff6b6b;
out property <color> critical-background-2-dark: #ff8080;
out property <color> critical-foreground-1-dark: #ffffff;
out property <color> critical-stroke-1-dark: #ff6b6b;
out property <color> critical-background-1-team-light: #c50e1f;
out property <color> critical-background-2-team-light: #a80e1b;
out property <color> critical-foreground-1-team-light: #ffffff;
out property <color> critical-stroke-1-team-light: #c50e1f;
out property <color> critical-background-1-team-dark: #ff8080;
out property <color> critical-background-2-team-dark: #ff9494;
out property <color> critical-foreground-1-team-dark: #ffffff;
out property <color> critical-stroke-1-team-dark: #ff8080;
// ===== CURRENT THEME ACCESSORS =====
// These automatically switch based on current-mode
// Current Neutral Colors
out property <color> neutral-foreground-1: current-mode == ColorMode.light ? neutral-foreground-1-light :
current-mode == ColorMode.dark ? neutral-foreground-1-dark :
current-mode == ColorMode.team-light ? neutral-foreground-1-team-light : neutral-foreground-1-team-dark;
out property <color> neutral-foreground-2: current-mode == ColorMode.light ? neutral-foreground-2-light :
current-mode == ColorMode.dark ? neutral-foreground-2-dark :
current-mode == ColorMode.team-light ? neutral-foreground-2-team-light : neutral-foreground-2-team-dark;
out property <color> neutral-foreground-3: current-mode == ColorMode.light ? neutral-foreground-3-light :
current-mode == ColorMode.dark ? neutral-foreground-3-dark :
current-mode == ColorMode.team-light ? neutral-foreground-3-team-light : neutral-foreground-3-team-dark;
out property <color> neutral-foreground-disabled: current-mode == ColorMode.light ? neutral-foreground-disabled-light :
current-mode == ColorMode.dark ? neutral-foreground-disabled-dark :
current-mode == ColorMode.team-light ? neutral-foreground-disabled-team-light : neutral-foreground-disabled-team-dark;
out property <color> neutral-background-1: current-mode == ColorMode.light ? neutral-background-1-light :
current-mode == ColorMode.dark ? neutral-background-1-dark :
current-mode == ColorMode.team-light ? neutral-background-1-team-light : neutral-background-1-team-dark;
out property <color> neutral-background-2: current-mode == ColorMode.light ? neutral-background-2-light :
current-mode == ColorMode.dark ? neutral-background-2-dark :
current-mode == ColorMode.team-light ? neutral-background-2-team-light : neutral-background-2-team-dark;
out property <color> neutral-background-3: current-mode == ColorMode.light ? neutral-background-3-light :
current-mode == ColorMode.dark ? neutral-background-3-dark :
current-mode == ColorMode.team-light ? neutral-background-3-team-light : neutral-background-3-team-dark;
out property <color> neutral-background-4: current-mode == ColorMode.light ? neutral-background-4-light :
current-mode == ColorMode.dark ? neutral-background-4-dark :
current-mode == ColorMode.team-light ? neutral-background-4-team-light : neutral-background-4-team-dark;
out property <color> neutral-stroke-1: current-mode == ColorMode.light ? neutral-stroke-1-light :
current-mode == ColorMode.dark ? neutral-stroke-1-dark :
current-mode == ColorMode.team-light ? neutral-stroke-1-team-light : neutral-stroke-1-team-dark;
out property <color> neutral-stroke-2: current-mode == ColorMode.light ? neutral-stroke-2-light :
current-mode == ColorMode.dark ? neutral-stroke-2-dark :
current-mode == ColorMode.team-light ? neutral-stroke-2-team-light : neutral-stroke-2-team-dark;
out property <color> neutral-stroke-accessible: current-mode == ColorMode.light ? neutral-stroke-accessible-light :
current-mode == ColorMode.dark ? neutral-stroke-accessible-dark :
current-mode == ColorMode.team-light ? neutral-stroke-accessible-team-light : neutral-stroke-accessible-team-dark;
// Current Interactive States
out property <color> neutral-foreground-1-hover: current-mode == ColorMode.light ? neutral-foreground-1-hover-light :
current-mode == ColorMode.dark ? neutral-foreground-1-hover-dark :
current-mode == ColorMode.team-light ? neutral-foreground-1-hover-team-light : neutral-foreground-1-hover-team-dark;
out property <color> neutral-foreground-2-brand-hover: current-mode == ColorMode.light ? neutral-foreground-2-brand-hover-light :
current-mode == ColorMode.dark ? neutral-foreground-2-brand-hover-dark :
current-mode == ColorMode.team-light ? neutral-foreground-2-brand-hover-team-light : neutral-foreground-2-brand-hover-team-dark;
// Current Link Colors
out property <color> neutral-foreground-link: current-mode == ColorMode.light ? neutral-foreground-link-light :
current-mode == ColorMode.dark ? neutral-foreground-link-dark :
current-mode == ColorMode.team-light ? neutral-foreground-link-team-light : neutral-foreground-link-team-dark;
out property <color> neutral-foreground-link-hover: current-mode == ColorMode.light ? neutral-foreground-link-hover-light :
current-mode == ColorMode.dark ? neutral-foreground-link-hover-dark :
current-mode == ColorMode.team-light ? neutral-foreground-link-hover-team-light : neutral-foreground-link-hover-team-dark;
out property <color> neutral-foreground-link-pressed: current-mode == ColorMode.light ? neutral-foreground-link-pressed-light :
current-mode == ColorMode.dark ? neutral-foreground-link-pressed-dark :
current-mode == ColorMode.team-light ? neutral-foreground-link-pressed-team-light : neutral-foreground-link-pressed-team-dark;
// Current Background Interactive States
out property <color> neutral-background-1-hover: current-mode == ColorMode.light ? neutral-background-1-hover-light :
current-mode == ColorMode.dark ? neutral-background-1-hover-dark :
current-mode == ColorMode.team-light ? neutral-background-1-hover-team-light : neutral-background-1-hover-team-dark;
out property <color> neutral-background-1-pressed: current-mode == ColorMode.light ? neutral-background-1-pressed-light :
current-mode == ColorMode.dark ? neutral-background-1-pressed-dark :
current-mode == ColorMode.team-light ? neutral-background-1-pressed-team-light : neutral-background-1-pressed-team-dark;
// Current Stroke Interactive States
out property <color> neutral-stroke-1-hover: current-mode == ColorMode.light ? neutral-stroke-1-hover-light :
current-mode == ColorMode.dark ? neutral-stroke-1-hover-dark :
current-mode == ColorMode.team-light ? neutral-stroke-1-hover-team-light : neutral-stroke-1-hover-team-dark;
out property <color> neutral-stroke-1-pressed: current-mode == ColorMode.light ? neutral-stroke-1-pressed-light :
current-mode == ColorMode.dark ? neutral-stroke-1-pressed-dark :
current-mode == ColorMode.team-light ? neutral-stroke-1-pressed-team-light : neutral-stroke-1-pressed-team-dark;
// Current Brand Colors
out property <color> brand-background-1: current-mode == ColorMode.light ? brand-background-1-light :
current-mode == ColorMode.dark ? brand-background-1-dark :
current-mode == ColorMode.team-light ? brand-background-1-team-light : brand-background-1-team-dark;
out property <color> brand-background-2: current-mode == ColorMode.light ? brand-background-2-light :
current-mode == ColorMode.dark ? brand-background-2-dark :
current-mode == ColorMode.team-light ? brand-background-2-team-light : brand-background-2-team-dark;
out property <color> brand-foreground-1: current-mode == ColorMode.light ? brand-foreground-1-light :
current-mode == ColorMode.dark ? brand-foreground-1-dark :
current-mode == ColorMode.team-light ? brand-foreground-1-team-light : brand-foreground-1-team-dark;
// Current Brand Interactive States
out property <color> brand-background-1-hover: current-mode == ColorMode.light ? brand-background-1-hover-light :
current-mode == ColorMode.dark ? brand-background-1-hover-dark :
current-mode == ColorMode.team-light ? brand-background-1-hover-team-light : brand-background-1-hover-team-dark;
out property <color> brand-background-1-pressed: current-mode == ColorMode.light ? brand-background-1-pressed-light :
current-mode == ColorMode.dark ? brand-background-1-pressed-dark :
current-mode == ColorMode.team-light ? brand-background-1-pressed-team-light : brand-background-1-pressed-team-dark;
// Current Semantic Colors
out property <color> success-background-1: current-mode == ColorMode.light ? success-background-1-light :
current-mode == ColorMode.dark ? success-background-1-dark :
current-mode == ColorMode.team-light ? success-background-1-team-light : success-background-1-team-dark;
out property <color> warning-background-1: current-mode == ColorMode.light ? warning-background-1-light :
current-mode == ColorMode.dark ? warning-background-1-dark :
current-mode == ColorMode.team-light ? warning-background-1-team-light : warning-background-1-team-dark;
out property <color> critical-background-1: current-mode == ColorMode.light ? critical-background-1-light :
current-mode == ColorMode.dark ? critical-background-1-dark :
current-mode == ColorMode.team-light ? critical-background-1-team-light : critical-background-1-team-dark;
// Legacy compatibility and Trading-specific colors
out property <color> neutral-foreground-rest: neutral-foreground-1;
out property <color> profit-green: success-background-1;
out property <color> loss-red: critical-background-1;
out property <color> neutral-gray: neutral-foreground-3;
// Accent colors for trading UI
out property <color> accent-purple: #f000b8;
out property <color> accent-teal: #37cdbe;
out property <color> accent-blue: brand-background-1;
}
// Typography System - Official Fluent 2 Typography Tokens
// Based on: https://fluent2.microsoft.design/typography
export global FluentTypography {
// ===== FLUENT FONT STACKS =====
// Segoe - unmistakably Microsoft (Primary Web/Windows font stack)
out property <string> font-family-base: "Segoe UI Variable, Segoe UI, system-ui, sans-serif";
out property <string> font-family-web: "Segoe UI Variable, Segoe UI, system-ui, sans-serif";
out property <string> font-family-windows: "Segoe UI Variable, Segoe UI, system-ui, sans-serif";
// Platform-specific native font stacks for cross-platform consistency
out property <string> font-family-macos: "SF Pro Display, SF Pro Text, system-ui, sans-serif";
out property <string> font-family-ios: "SF Pro Display, SF Pro Text, system-ui, sans-serif";
out property <string> font-family-android: "Roboto, system-ui, sans-serif";
// Specialized font families
out property <string> font-family-monospace: "Cascadia Code, Cascadia Mono, Consolas, Courier New, monospace";
out property <string> font-family-numeric: "Bahnschrift, Segoe UI Variable, Segoe UI, system-ui, sans-serif";
// ===== FONT WEIGHTS - Fluent 2 Weight Scale =====
out property <int> font-weight-regular: 400; // Regular
out property <int> font-weight-medium: 500; // Medium (Android)
out property <int> font-weight-semibold: 600; // Semibold
out property <int> font-weight-bold: 700; // Bold
// ===== WEB TYPE RAMP - Official Fluent 2 Web Typography =====
// Caption styles
out property <length> font-size-caption-2: 10px; // Caption 2
out property <length> line-height-caption-2: 14px;
out property <int> font-weight-caption-2: font-weight-regular;
out property <int> font-weight-caption-2-strong: font-weight-semibold;
out property <length> font-size-caption-1: 12px; // Caption 1
out property <length> line-height-caption-1: 16px;
out property <int> font-weight-caption-1: font-weight-regular;
out property <int> font-weight-caption-1-strong: font-weight-semibold;
out property <int> font-weight-caption-1-stronger: font-weight-bold;
// Body styles
out property <length> font-size-body-1: 14px; // Body 1 (Default)
out property <length> line-height-body-1: 20px;
out property <int> font-weight-body-1: font-weight-regular;
out property <int> font-weight-body-1-strong: font-weight-semibold;
out property <int> font-weight-body-1-stronger: font-weight-bold;
// Subtitle styles
out property <length> font-size-subtitle-2: 16px; // Subtitle 2
out property <length> line-height-subtitle-2: 22px;
out property <int> font-weight-subtitle-2: font-weight-semibold;
out property <int> font-weight-subtitle-2-stronger: font-weight-bold;
out property <length> font-size-subtitle-1: 20px; // Subtitle 1
out property <length> line-height-subtitle-1: 26px;
out property <int> font-weight-subtitle-1: font-weight-semibold;
// Title styles
out property <length> font-size-title-3: 24px; // Title 3
out property <length> line-height-title-3: 32px;
out property <int> font-weight-title-3: font-weight-semibold;
out property <length> font-size-title-2: 28px; // Title 2
out property <length> line-height-title-2: 36px;
out property <int> font-weight-title-2: font-weight-semibold;
out property <length> font-size-title-1: 32px; // Title 1
out property <length> line-height-title-1: 40px;
out property <int> font-weight-title-1: font-weight-semibold;
// Large title and display
out property <length> font-size-large-title: 40px; // Large Title
out property <length> line-height-large-title: 52px;
out property <int> font-weight-large-title: font-weight-semibold;
out property <length> font-size-display: 68px; // Display
out property <length> line-height-display: 92px;
out property <int> font-weight-display: font-weight-semibold;
// ===== WINDOWS TYPE RAMP - Official Fluent 2 Windows Typography =====
// Windows-specific variants using Segoe UI Variable
out property <length> font-size-windows-caption: 12px; // Caption
out property <length> line-height-windows-caption: 16px;
out property <int> font-weight-windows-caption: font-weight-regular;
out property <length> font-size-windows-body: 14px; // Body
out property <length> line-height-windows-body: 20px;
out property <int> font-weight-windows-body: font-weight-regular;
out property <int> font-weight-windows-body-strong: font-weight-semibold;
out property <length> font-size-windows-body-large: 18px; // Body Large
out property <length> line-height-windows-body-large: 24px;
out property <int> font-weight-windows-body-large: font-weight-regular;
out property <length> font-size-windows-subtitle: 20px; // Subtitle
out property <length> line-height-windows-subtitle: 28px;
out property <int> font-weight-windows-subtitle: font-weight-semibold;
out property <length> font-size-windows-title: 28px; // Title
out property <length> line-height-windows-title: 36px;
out property <int> font-weight-windows-title: font-weight-semibold;
out property <length> font-size-windows-large-title: 40px; // Large Title
out property <length> line-height-windows-large-title: 52px;
out property <int> font-weight-windows-large-title: font-weight-semibold;
out property <length> font-size-windows-display: 68px; // Display
out property <length> line-height-windows-display: 92px;
out property <int> font-weight-windows-display: font-weight-semibold;
// ===== LEGACY NUMERIC TOKENS - For backward compatibility =====
out property <length> font-size-100: font-size-caption-2; // 10px
out property <length> font-size-200: font-size-caption-1; // 12px
out property <length> font-size-300: font-size-body-1; // 14px
out property <length> font-size-400: font-size-subtitle-2; // 16px
out property <length> font-size-500: 18px; // Custom
out property <length> font-size-600: font-size-subtitle-1; // 20px
out property <length> font-size-700: font-size-title-3; // 24px
out property <length> font-size-800: font-size-title-2; // 28px
out property <length> font-size-900: font-size-title-1; // 32px
out property <length> font-size-1000: font-size-large-title; // 40px
out property <length> font-size-1100: 48px; // Custom Large
out property <length> font-size-1200: font-size-display; // 68px
out property <length> line-height-100: line-height-caption-2; // 14px
out property <length> line-height-200: line-height-caption-1; // 16px
out property <length> line-height-300: line-height-body-1; // 20px
out property <length> line-height-400: line-height-subtitle-2; // 22px
out property <length> line-height-500: 24px; // Custom
out property <length> line-height-600: line-height-subtitle-1; // 26px
out property <length> line-height-700: line-height-title-3; // 32px
out property <length> line-height-800: line-height-title-2; // 36px
out property <length> line-height-900: line-height-title-1; // 40px
out property <length> line-height-1000: line-height-large-title; // 52px
out property <length> line-height-1100: 60px; // Custom
out property <length> line-height-1200: line-height-display; // 92px
// ===== TEXT STYLING UTILITIES =====
// Letter spacing for fine typography control
out property <length> letter-spacing-tight: -0.16px; // For large text
out property <length> letter-spacing-normal: 0px; // Standard
out property <length> letter-spacing-wide: 0.32px; // For small text
// Text decoration
out property <string> text-decoration-none: "none";
out property <string> text-decoration-underline: "underline";
out property <string> text-decoration-line-through: "line-through";
// Text transform (following Fluent guidance for sentence case)
out property <string> text-transform-none: "none";
out property <string> text-transform-uppercase: "uppercase";
out property <string> text-transform-lowercase: "lowercase";
out property <string> text-transform-capitalize: "capitalize";
// ===== USAGE EXAMPLES =====
// Caption 2: font-size: FluentTypography.font-size-caption-2; line-height: FluentTypography.line-height-caption-2; font-weight: FluentTypography.font-weight-caption-2;
// Body 1: font-size: FluentTypography.font-size-body-1; line-height: FluentTypography.line-height-body-1; font-weight: FluentTypography.font-weight-body-1;
// Title 1: font-size: FluentTypography.font-size-title-1; line-height: FluentTypography.line-height-title-1; font-weight: FluentTypography.font-weight-title-1;
// Display: font-size: FluentTypography.font-size-display; line-height: FluentTypography.line-height-display; font-weight: FluentTypography.font-weight-display;
}
// Spacing System - Fluent 2 Spacing Scale
export global FluentSpacing {
out property <length> space-2: 2px;
out property <length> space-4: 4px;
out property <length> space-6: 6px;
out property <length> space-8: 8px;
out property <length> space-10: 10px;
out property <length> space-12: 12px;
out property <length> space-16: 16px;
out property <length> space-20: 20px;
out property <length> space-24: 24px;
out property <length> space-28: 28px;
out property <length> space-32: 32px;
out property <length> space-36: 36px;
out property <length> space-40: 40px;
out property <length> space-48: 48px;
out property <length> space-64: 64px;
out property <length> space-80: 80px;
out property <length> space-96: 96px;
out property <length> space-120: 120px;
}
// Border Radius - Complete Fluent UI Border Radius System
export global FluentRadius {
// Corner Radius Scale
out property <length> border-radius-none: 0px;
out property <length> border-radius-small: 2px;
out property <length> border-radius-medium: 4px;
out property <length> border-radius-large: 6px;
out property <length> border-radius-x-large: 8px;
out property <length> border-radius-circular: 10000px;
// Legacy support
out property <length> radius-none: 0px;
out property <length> radius-small: 2px;
out property <length> radius-medium: 4px;
out property <length> radius-large: 6px;
out property <length> radius-xlarge: 8px;
out property <length> radius-circular: 10000px;
}
// Shadows - Complete Fluent UI Shadow System
// Based on: https://react.fluentui.dev/?path=/docs/theme-shadows--docs
export global FluentShadows {
// ===== SHADOW BRAND TOKENS =====
// These are the primary shadow tokens used throughout Fluent UI
// Shadow 2 - Subtle elevation (tooltips, dropdowns)
out property <length> shadow-2-x: 0px;
out property <length> shadow-2-y: 1px;
out property <length> shadow-2-blur: 2px;
out property <length> shadow-2-spread: 0px;
out property <color> shadow-2-color: #00000014; // 8% opacity black
// Shadow 4 - Low elevation (cards, buttons)
out property <length> shadow-4-x: 0px;
out property <length> shadow-4-y: 2px;
out property <length> shadow-4-blur: 4px;
out property <length> shadow-4-spread: 0px;
out property <color> shadow-4-color: #0000001f; // 12% opacity black
// Shadow 8 - Medium elevation (dialogs, menus)
out property <length> shadow-8-x: 0px;
out property <length> shadow-8-y: 4px;
out property <length> shadow-8-blur: 8px;
out property <length> shadow-8-spread: 0px;
out property <color> shadow-8-color: #0000001f; // 12% opacity black
// Shadow 16 - High elevation (modals, flyouts)
out property <length> shadow-16-x: 0px;
out property <length> shadow-16-y: 8px;
out property <length> shadow-16-blur: 16px;
out property <length> shadow-16-spread: 0px;
out property <color> shadow-16-color: #00000024; // 14% opacity black
// Shadow 28 - Very high elevation (teaching callouts)
out property <length> shadow-28-x: 0px;
out property <length> shadow-28-y: 14px;
out property <length> shadow-28-blur: 28px;
out property <length> shadow-28-spread: 0px;
out property <color> shadow-28-color: #00000024; // 14% opacity black
// Shadow 64 - Maximum elevation (panels, navigation)
out property <length> shadow-64-x: 0px;
out property <length> shadow-64-y: 32px;
out property <length> shadow-64-blur: 64px;
out property <length> shadow-64-spread: 0px;
out property <color> shadow-64-color: #00000033; // 20% opacity black
// ===== THEME-AWARE SHADOW COLORS =====
// Light theme shadow colors
out property <color> shadow-light-ambient: #0000000f; // 6% opacity black
out property <color> shadow-light-key: #00000014; // 8% opacity black
out property <color> shadow-light-ambient-darker: #00000014; // 8% opacity black
out property <color> shadow-light-key-darker: #0000001f; // 12% opacity black
out property <color> shadow-light-ambient-darkest: #0000001f; // 12% opacity black
out property <color> shadow-light-key-darkest: #00000024; // 14% opacity black
// Dark theme shadow colors
out property <color> shadow-dark-ambient: #0000001f; // 12% opacity black
out property <color> shadow-dark-key: #00000024; // 14% opacity black
out property <color> shadow-dark-ambient-darker: #00000024; // 14% opacity black
out property <color> shadow-dark-key-darker: #00000033; // 20% opacity black
out property <color> shadow-dark-ambient-darkest: #00000033; // 20% opacity black
out property <color> shadow-dark-key-darkest: #00000047; // 28% opacity black
// ===== SPECIALIZED SHADOW TOKENS =====
// Brand shadow (with brand color tint)
out property <length> shadow-brand-x: 0px;
out property <length> shadow-brand-y: 2px;
out property <length> shadow-brand-blur: 8px;
out property <length> shadow-brand-spread: 0px;
out property <color> shadow-brand-color: #0078d414; // Brand blue with 8% opacity
// Inset shadow (for pressed states)
out property <length> shadow-inset-x: 0px;
out property <length> shadow-inset-y: 1px;
out property <length> shadow-inset-blur: 2px;
out property <length> shadow-inset-spread: 0px;
out property <color> shadow-inset-color: #0000001f; // 12% opacity black
// Focus shadow (for accessibility)
out property <length> shadow-focus-x: 0px;
out property <length> shadow-focus-y: 0px;
out property <length> shadow-focus-blur: 0px;
out property <length> shadow-focus-spread: 2px;
out property <color> shadow-focus-color: #0078d4; // Brand blue
// ===== COMPONENT-SPECIFIC SHADOW TOKENS =====
// Button shadows
out property <color> shadow-button-rest: shadow-2-color;
out property <color> shadow-button-hover: shadow-4-color;
out property <color> shadow-button-pressed: shadow-inset-color;
// Card shadows
out property <color> shadow-card-rest: shadow-4-color;
out property <color> shadow-card-hover: shadow-8-color;
// Dialog shadows
out property <color> shadow-dialog: shadow-64-color;
// Flyout shadows
out property <color> shadow-flyout: shadow-16-color;
// Tooltip shadows
out property <color> shadow-tooltip: shadow-8-color;
// ===== LEGACY SHADOW SUPPORT =====
// Note: shadow-*-blur properties are already defined above in the main shadow tokens
// They can be used directly for backward compatibility
// ===== SHADOW UTILITY FUNCTIONS =====
// Helper properties for common shadow combinations
// Subtle shadow (for subtle elevation)
out property <length> subtle-shadow-x: shadow-2-x;
out property <length> subtle-shadow-y: shadow-2-y;
out property <length> subtle-shadow-blur: shadow-2-blur;
out property <color> subtle-shadow-color: shadow-2-color;
// Default shadow (for standard elevation)
out property <length> default-shadow-x: shadow-4-x;
out property <length> default-shadow-y: shadow-4-y;
out property <length> default-shadow-blur: shadow-4-blur;
out property <color> default-shadow-color: shadow-4-color;
// Deep shadow (for high elevation)
out property <length> deep-shadow-x: shadow-16-x;
out property <length> deep-shadow-y: shadow-16-y;
out property <length> deep-shadow-blur: shadow-16-blur;
out property <color> deep-shadow-color: shadow-16-color;
// ===== USAGE NOTES =====
// To apply shadows in components, use the individual tokens:
// Example: Rectangle { drop-shadow-offset-x: FluentShadows.shadow-4-x; drop-shadow-offset-y: FluentShadows.shadow-4-y; drop-shadow-blur: FluentShadows.shadow-4-blur; drop-shadow-color: FluentShadows.shadow-4-color; }
// For focus states: Rectangle { border-width: FluentShadows.shadow-focus-spread; border-color: FluentShadows.shadow-focus-color; }
}
// Component Tokens - Fluent 2 Component Specifications
export global FluentComponents {
// Button
out property <length> button-height-small: 24px;
out property <length> button-height-medium: 32px;
out property <length> button-height-large: 40px;
out property <length> button-padding-horizontal: 16px;
out property <length> button-border-radius: FluentRadius.border-radius-medium;
// Input
out property <length> input-height: 32px;
out property <length> input-padding-horizontal: 12px;
out property <length> input-border-radius: FluentRadius.border-radius-medium;
out property <length> input-border-width: 1px;
// Card
out property <length> card-padding: FluentSpacing.space-16;
out property <length> card-border-radius: FluentRadius.border-radius-large;
out property <length> card-border-width: 1px;
// Navigation
out property <length> nav-item-height: 40px;
out property <length> nav-item-padding: FluentSpacing.space-12;
out property <length> nav-item-border-radius: FluentRadius.border-radius-medium;
// Title Bar
out property <length> titlebar-height: 32px;
out property <length> titlebar-button-width: 46px;
// Sidebar
out property <length> sidebar-width: 280px;
out property <length> sidebar-collapsed-width: 48px;
}
// Animation & Motion - Fluent 2 Motion System
export global FluentMotion {
out property <duration> duration-ultra-fast: 50ms;
out property <duration> duration-faster: 100ms;
out property <duration> duration-fast: 150ms;
out property <duration> duration-normal: 200ms;
out property <duration> duration-slow: 300ms;
out property <duration> duration-slower: 400ms;
out property <duration> duration-ultra-slow: 500ms;
// Easing curves (represented as animation properties)
out property <easing> ease-accelerate: ease-in;
out property <easing> ease-decelerate: ease-out;
out property <easing> ease-standard: ease-in-out;
out property <easing> ease-max: ease;
}
// Layout Grid - Fluent 2 Layout System
export global FluentLayout {
// Breakpoints
out property <length> breakpoint-small: 480px;
out property <length> breakpoint-medium: 768px;
out property <length> breakpoint-large: 1024px;
out property <length> breakpoint-xlarge: 1440px;
// Container max widths
out property <length> container-small: 640px;
out property <length> container-medium: 768px;
out property <length> container-large: 1024px;
out property <length> container-xlarge: 1280px;
// Grid
out property <length> grid-gutter: FluentSpacing.space-24;
out property <int> grid-columns: 12;
}
// Z-Index Scale
export global FluentLayers {
out property <int> layer-base: 0;
out property <int> layer-dropdown: 1000;
out property <int> layer-sticky: 1020;
out property <int> layer-banner: 1030;
out property <int> layer-overlay: 1040;
out property <int> layer-modal: 1050;
out property <int> layer-popover: 1060;
out property <int> layer-tooltip: 1070;
out property <int> layer-toast: 1080;
}

View file

@ -0,0 +1,8 @@
// Design System Public API
// This file exports all design tokens and components from the design system
// Export design tokens
export { Theme } from "tokens/theme.slint";
// Export design system components
export * from "components/design-system.slint";

View file

@ -0,0 +1,29 @@
// Global theme management system
export global Theme {
in-out property <bool> is-dark-mode: false;
// Color scheme properties that automatically update based on theme
out property <color> background: is-dark-mode ? #1a1a1a : #ffffff;
out property <color> surface: is-dark-mode ? #2a2a2a : #f5f5f5;
out property <color> primary: #3b82f6;
out property <color> primary-variant: is-dark-mode ? #60a5fa : #2563eb;
out property <color> secondary: is-dark-mode ? #64748b : #475569;
out property <color> text-primary: is-dark-mode ? #ffffff : #1f2937;
out property <color> text-secondary: is-dark-mode ? #d1d5db : #6b7280;
out property <color> border: is-dark-mode ? #374151 : #e5e7eb;
out property <color> accent: is-dark-mode ? #22c55e : #16a34a;
out property <color> error: #ef4444;
out property <color> warning: #f59e0b;
out property <color> success: #10b981;
// Card and container colors
out property <color> card-background: is-dark-mode ? #2a2a2a : #ffffff;
out property <color> card-border: is-dark-mode ? #404040 : #e5e7eb;
// Navigation colors
out property <color> nav-background: is-dark-mode ? #1f1f1f : #f8fafc;
out property <color> nav-active: primary;
out property <color> nav-hover: is-dark-mode ? #374151 : #f1f5f9;
// Theme state is directly modified by components and Rust code
}

12
ui/shared/index.slint Normal file
View file

@ -0,0 +1,12 @@
// Shared Layer Public API
// This file exports all shared utilities, components, and design system
// Export design system
export { Theme, FluentColors, FluentTypography, FluentSpacing, FluentRadius, FluentShadows, FluentComponents, FluentMotion, FluentLayout, FluentLayers, ColorMode } from "design-system/index.slint";
// Export UI components
export { Button, Card, Input, LoadingView, Container, Grid } from "ui/index.slint";
// Export utilities and config - currently commented out in their index files
// export * from "lib/index.slint";
// export * from "config/index.slint";

View file

@ -0,0 +1,5 @@
// Shared Library Public API
// Export utility functions and helpers
// Currently no utilities defined
// export * from "utils/common-utils.slint";

View file

@ -0,0 +1,50 @@
import { VerticalBox, HorizontalBox } from "std-widgets.slint";
// Basic Button Component
export component Button {
in property <string> text;
in property <bool> enabled: true;
in property <color> background-color: #2563eb;
in property <color> text-color: white;
in property <color> hover-color: #1d4ed8;
in property <color> disabled-color: #94a3b8;
in property <length> border-radius: 6px;
in property <length> padding-horizontal: 16px;
in property <length> padding-vertical: 8px;
callback clicked();
min-width: 80px;
min-height: 36px;
Rectangle {
background: enabled ? (touch-area.has-hover ? hover-color : background-color) : disabled-color;
border-radius: border-radius;
HorizontalBox {
padding-left: padding-horizontal;
padding-right: padding-horizontal;
padding-top: padding-vertical;
padding-bottom: padding-vertical;
alignment: center;
Text {
text: root.text;
color: text-color;
font-size: 14px;
font-weight: 500;
horizontal-alignment: center;
vertical-alignment: center;
}
}
touch-area := TouchArea {
enabled: root.enabled;
clicked => {
if (root.enabled) {
root.clicked();
}
}
}
}
}

View file

@ -0,0 +1,2 @@
// Button Component Public API
export { Button } from "button.slint";

View file

@ -0,0 +1,27 @@
import { VerticalBox } from "std-widgets.slint";
// Basic Card Component
export component Card {
in property <color> background-color: white;
in property <color> border-color: #e2e8f0;
in property <length> border-radius: 8px;
in property <length> border-width: 1px;
in property <length> card-padding: 16px;
in property <length> shadow-blur: 4px;
in property <color> shadow-color: #00000010;
Rectangle {
background: background-color;
border-radius: border-radius;
border-width: border-width;
border-color: border-color;
drop-shadow-blur: shadow-blur;
drop-shadow-color: shadow-color;
drop-shadow-offset-y: 2px;
VerticalBox {
padding: root.card-padding;
@children
}
}
}

View file

@ -0,0 +1,2 @@
// Card Component Public API
export { Card } from "card.slint";

9
ui/shared/ui/index.slint Normal file
View file

@ -0,0 +1,9 @@
// UI Kit Public API
// This file exports all shared UI components
// Export basic components
export { Button } from "button/index.slint";
export { Card } from "card/index.slint";
export { Input } from "input/index.slint";
export { LoadingView } from "loading/index.slint";
export { Container, Grid } from "layout/index.slint";

View file

@ -0,0 +1,2 @@
// Input Component Public API
export { Input } from "input.slint";

View file

@ -0,0 +1,20 @@
import { LineEdit } from "std-widgets.slint";
// Basic Input Component
export component Input {
in-out property <string> text;
in property <string> placeholder;
in property <bool> enabled: true;
callback edited(string);
LineEdit {
text: root.text;
placeholder-text: root.placeholder;
enabled: root.enabled;
edited(t) => {
root.text = t;
root.edited(t);
}
}
}

View file

@ -0,0 +1,2 @@
// Layout Components Public API
export { Container, Grid } from "layout.slint";

View file

@ -0,0 +1,32 @@
import { VerticalBox, HorizontalBox } from "std-widgets.slint";
// Container Component
export component Container {
in property <length> container-max-width: 1200px;
in property <length> container-padding: 16px;
HorizontalBox {
alignment: center;
Rectangle {
max-width: root.container-max-width;
VerticalBox {
padding: root.container-padding;
@children
}
}
}
}
// Grid Component
export component Grid {
in property <length> gap: 16px;
in property <int> columns: 2;
// Basic grid implementation - can be enhanced
VerticalBox {
spacing: root.gap;
@children
}
}

View file

@ -0,0 +1,2 @@
// Loading Component Public API
export { LoadingView } from "loading.slint";

View file

@ -0,0 +1,54 @@
import { VerticalBox } from "std-widgets.slint";
// Loading component for app initialization
export component LoadingView {
in-out property <color> primary-color: #2563eb;
in-out property <color> background-color: #f8fafc;
in-out property <color> text-color: #1e293b;
in-out property <string> app-version: "0.2.0";
Rectangle {
background: background-color;
VerticalBox {
alignment: center;
spacing: 20px;
// Loading spinner
Rectangle {
width: 60px;
height: 60px;
border-radius: 30px;
background: primary-color;
// Pulsing animation effect
animate background {
duration: 1s;
iteration-count: -1;
easing: ease-in-out;
}
}
Text {
text: "Loading Ziya";
font-size: 24px;
color: text-color;
font-weight: 600;
}
Text {
text: "Initializing your trading environment...";
font-size: 14px;
color: text-color;
opacity: 0.7;
}
Text {
text: "Version " + app-version;
font-size: 10px;
color: text-color;
opacity: 0.5;
}
}
}
}

View file

@ -0,0 +1,2 @@
// Navigation Widget Public API
export { NavigationWidget } from "ui/navigation-widget.slint";

View file

@ -0,0 +1,291 @@
import { Theme } from "../../../shared/design-system/tokens/theme.slint";
// Navigation Widget (Sidebar)
export component NavigationWidget {
in-out property <string> current-page: "Dashboard";
in property <string> user-initials: "JD";
callback navigation-changed(string);
callback logout-clicked();
Rectangle {
width: 100%;
height: 100%;
background: Theme.nav-background;
VerticalLayout {
padding: 16px;
spacing: 20px;
alignment: space-between;
// Top section with logo and navigation
VerticalLayout {
spacing: 20px;
// Logo Section
HorizontalLayout {
spacing: 12px;
alignment: start;
padding-top: 16px;
Rectangle {
width: 40px;
height: 40px;
border-radius: 20px;
background: Theme.primary;
Text {
text: "Z";
color: white;
font-size: 20px;
font-weight: 700;
horizontal-alignment: center;
vertical-alignment: center;
}
}
VerticalLayout {
spacing: 2px;
Text {
text: "Ziya";
color: Theme.text-primary;
font-size: 18px;
font-weight: 700;
}
Text {
text: "Trading Platform";
color: Theme.text-secondary;
font-size: 12px;
}
}
}
// Navigation Menu
VerticalLayout {
spacing: 4px;
// Dashboard
Rectangle {
height: 44px;
border-radius: 8px;
background: current-page == "Dashboard" ? Theme.nav-active : transparent;
HorizontalLayout {
padding: 12px;
spacing: 12px;
alignment: start;
Text {
text: "📊";
font-size: 16px;
vertical-alignment: center;
}
Text {
text: "Dashboard";
color: current-page == "Dashboard" ? white : Theme.text-primary;
font-size: 14px;
font-weight: current-page == "Dashboard" ? 600 : 400;
vertical-alignment: center;
}
}
TouchArea {
clicked => {
root.current-page = "Dashboard";
root.navigation-changed("Dashboard");
}
}
}
// Trading
Rectangle {
height: 44px;
border-radius: 8px;
background: current-page == "Trading" ? Theme.nav-active : transparent;
HorizontalLayout {
padding: 12px;
spacing: 12px;
alignment: start;
Text {
text: "💹";
font-size: 16px;
vertical-alignment: center;
}
Text {
text: "Trading";
color: current-page == "Trading" ? white : Theme.text-primary;
font-size: 14px;
font-weight: current-page == "Trading" ? 600 : 400;
vertical-alignment: center;
}
}
TouchArea {
clicked => {
root.current-page = "Trading";
root.navigation-changed("Trading");
}
}
}
// Portfolio
Rectangle {
height: 44px;
border-radius: 8px;
background: current-page == "Portfolio" ? Theme.nav-active : transparent;
HorizontalLayout {
padding: 12px;
spacing: 12px;
alignment: start;
Text {
text: "💼";
font-size: 16px;
vertical-alignment: center;
}
Text {
text: "Portfolio";
color: current-page == "Portfolio" ? white : Theme.text-primary;
font-size: 14px;
font-weight: current-page == "Portfolio" ? 600 : 400;
vertical-alignment: center;
}
}
TouchArea {
clicked => {
root.current-page = "Portfolio";
root.navigation-changed("Portfolio");
}
}
}
// Markets
Rectangle {
height: 44px;
border-radius: 8px;
background: current-page == "Markets" ? Theme.nav-active : transparent;
HorizontalLayout {
padding: 12px;
spacing: 12px;
alignment: start;
Text {
text: "📈";
font-size: 16px;
vertical-alignment: center;
}
Text {
text: "Markets";
color: current-page == "Markets" ? white : Theme.text-primary;
font-size: 14px;
font-weight: current-page == "Markets" ? 600 : 400;
vertical-alignment: center;
}
}
TouchArea {
clicked => {
root.current-page = "Markets";
root.navigation-changed("Markets");
}
}
}
// Hunting Ground
Rectangle {
height: 44px;
border-radius: 8px;
background: current-page == "HuntingGround" ? Theme.nav-active : transparent;
HorizontalLayout {
padding: 12px;
spacing: 12px;
alignment: start;
Text {
text: "🎯";
font-size: 16px;
vertical-alignment: center;
}
Text {
text: "Hunting Ground";
color: current-page == "HuntingGround" ? white : Theme.text-primary;
font-size: 14px;
font-weight: current-page == "HuntingGround" ? 600 : 400;
vertical-alignment: center;
}
}
TouchArea {
clicked => {
root.current-page = "HuntingGround";
root.navigation-changed("HuntingGround");
}
}
}
}
}
// User Profile Section (bottom)
Rectangle {
height: 60px;
border-radius: 8px;
background: Theme.surface;
HorizontalLayout {
padding: 12px;
spacing: 12px;
alignment: start;
Rectangle {
width: 36px;
height: 36px;
border-radius: 18px;
background: Theme.primary;
Text {
text: user-initials;
color: white;
font-size: 14px;
font-weight: 600;
horizontal-alignment: center;
vertical-alignment: center;
}
}
VerticalLayout {
spacing: 2px;
Text {
text: "User";
color: Theme.text-primary;
font-size: 14px;
font-weight: 600;
}
Text {
text: "Logout";
color: Theme.text-secondary;
font-size: 12px;
}
}
}
TouchArea {
clicked => { root.logout-clicked(); }
}
}
}
}
}

View file

@ -0,0 +1,178 @@
import { VerticalBox, HorizontalBox, ScrollView } from "std-widgets.slint";
// Navigation menu item data structure
export struct MenuItem {
name: string,
icon: string,
active: bool,
}
// Professional sidebar navigation with direct styling
export component Sidebar {
in property <[MenuItem]> menu-items: [
{ name: "Dashboard", icon: "📊", active: true },
{ name: "Profile", icon: "👤", active: false },
{ name: "Trading", icon: "💹", active: false },
{ name: "Portfolio", icon: "💼", active: false },
{ name: "Markets", icon: "📈", active: false },
{ name: "Hunting Ground", icon: "🎯", active: false },
{ name: "Analytics", icon: "📊", active: false },
];
callback menu-item-clicked(string);
width: 256px;
Rectangle {
background: #f2f2f2;
border-width: 0px;
border-color: #e5e6e6;
ScrollView {
viewport-height: root.height;
VerticalBox {
padding: 16px;
spacing: 8px;
// Sidebar Header
Rectangle {
height: 60px;
VerticalBox {
alignment: center;
spacing: 8px;
// Logo area
Rectangle {
height: 32px;
HorizontalBox {
alignment: center;
spacing: 8px;
// App icon
Rectangle {
width: 24px;
height: 24px;
background: #570df8;
border-radius: 8px;
}
Text {
text: "Ziya";
color: #1f2937;
font-size: 18px;
font-weight: 700;
}
}
}
// Divider
Rectangle {
height: 1px;
background: #e5e6e6;
}
}
}
// Menu Items
for item[index] in menu-items: Rectangle {
height: 44px;
border-radius: 8px;
// Active/hover state styling
background: item.active ? #570df8 : transparent;
states [
active when item.active: {
background: #570df8;
}
hover when menu-area.has-hover && !item.active: {
background: #e5e6e6;
}
]
animate background { duration: 150ms; }
HorizontalBox {
padding-left: 16px;
padding-right: 16px;
alignment: start;
spacing: 12px;
// Icon
Text {
text: item.icon;
font-size: 16px;
vertical-alignment: center;
width: 20px;
}
// Menu item text
Text {
text: item.name;
color: item.active ? #ffffff : #1f2937;
font-size: 14px;
font-weight: item.active ? 600 : 500;
vertical-alignment: center;
}
// Active indicator
if item.active: Rectangle {
width: 4px;
height: 20px;
background: #ffffff;
border-radius: 2px;
}
}
menu-area := TouchArea {
clicked => { menu-item-clicked(item.name); }
}
}
// Spacer to push footer to bottom
Rectangle {
height: 1px;
}
// Sidebar Footer
Rectangle {
height: 60px;
VerticalBox {
alignment: center;
spacing: 8px;
// Divider
Rectangle {
height: 1px;
background: #e5e6e6;
}
// Status section
HorizontalBox {
alignment: center;
spacing: 8px;
// Status indicator
Rectangle {
width: 8px;
height: 8px;
background: #36d399;
border-radius: 4px;
}
Text {
text: "Connected";
color: #6b7280;
font-size: 12px;
}
}
}
}
}
}
}
}

View file

@ -0,0 +1,2 @@
// Trading Stats Widget Public API
export { StatsCard } from "ui/stats-card.slint";

View file

@ -0,0 +1,55 @@
import { VerticalBox } from "std-widgets.slint";
// Professional stats card component with direct styling
export component StatsCard {
in property <string> title: "Stat Title";
in property <string> value: "$0.00";
in property <string> change: "0%";
in property <bool> positive: true;
in property <color> accent-color: #570df8;
min-width: 200px;
height: 120px;
Rectangle {
background: #ffffff;
border-radius: 12px;
border-width: 1px;
border-color: #e5e6e6;
drop-shadow-blur: 8px;
drop-shadow-color: #00000008;
VerticalBox {
padding: 20px;
spacing: 8px;
alignment: start;
// Title
Text {
text: title;
color: #64748b;
font-size: 14px;
font-weight: 500;
horizontal-alignment: left;
}
// Main value
Text {
text: value;
color: accent-color;
font-size: 32px;
font-weight: 700;
horizontal-alignment: left;
}
// Change indicator
Text {
text: change;
color: positive ? #36d399 : #f87272;
font-size: 13px;
font-weight: 500;
horizontal-alignment: left;
}
}
}
}

View file

@ -0,0 +1,2 @@
// User Profile Widget Public API
export { ProfileView } from "ui/profile.slint";

View file

@ -0,0 +1,251 @@
import { Button, VerticalBox, HorizontalBox } from "std-widgets.slint";
// User profile structure
export struct UserProfile {
name: string,
email: string,
wallet-address: string,
}
// Profile component
export component ProfileView {
in-out property <color> primary-color: #2563eb;
in-out property <color> background-color: #f8fafc;
in-out property <color> card-background: #ffffff;
in-out property <color> text-color: #1e293b;
in-out property <color> border-color: #e2e8f0;
in-out property <UserProfile> user-profile;
// Callbacks
callback edit-profile();
callback view-wallet();
callback export-data();
Rectangle {
background: background-color;
VerticalBox {
spacing: 30px;
padding: 30px;
// Header
Text {
text: "Profile";
font-size: 28px;
color: text-color;
font-weight: 700;
}
// Profile card
Rectangle {
background: card-background;
border-radius: 16px;
border-width: 1px;
border-color: border-color;
drop-shadow-blur: 10px;
drop-shadow-color: #00000010;
VerticalBox {
spacing: 25px;
padding: 30px;
// Avatar section
HorizontalBox {
alignment: start;
spacing: 20px;
Rectangle {
width: 80px;
height: 80px;
border-radius: 40px;
background: primary-color.with-alpha(0.1);
Text {
text: user-profile.name != "" ? user-profile.name.to-uppercase() : "U";
color: primary-color;
font-size: 32px;
font-weight: 700;
}
}
VerticalBox {
alignment: start;
spacing: 8px;
Text {
text: user-profile.name != "" ? user-profile.name : "Demo User";
font-size: 24px;
color: text-color;
font-weight: 600;
}
Text {
text: user-profile.email != "" ? user-profile.email : "demo@ziya.app";
font-size: 14px;
color: text-color;
opacity: 0.7;
}
}
}
// Wallet section
VerticalBox {
spacing: 15px;
Text {
text: "Wallet Information";
font-size: 18px;
color: text-color;
font-weight: 600;
}
Rectangle {
background: #f1f5f9;
border-radius: 8px;
VerticalBox {
spacing: 10px;
padding: 15px;
Text {
text: "Wallet Address";
font-size: 12px;
color: text-color;
opacity: 0.7;
font-weight: 500;
}
Text {
text: user-profile.wallet-address != "" ?
user-profile.wallet-address :
"Demo123...Wallet456";
font-size: 14px;
color: text-color;
font-family: "monospace";
}
}
}
}
// Actions section
VerticalBox {
spacing: 15px;
Text {
text: "Profile Actions";
font-size: 18px;
color: text-color;
font-weight: 600;
}
VerticalBox {
spacing: 10px;
Button {
text: "✏️ Edit Profile";
height: 45px;
clicked => { edit-profile(); }
}
Button {
text: "👛 View Wallet Details";
height: 45px;
clicked => { view-wallet(); }
}
Button {
text: "📥 Export Data";
height: 45px;
clicked => { export-data(); }
}
}
}
}
}
// Stats card
Rectangle {
background: card-background;
border-radius: 16px;
border-width: 1px;
border-color: border-color;
drop-shadow-blur: 10px;
drop-shadow-color: #00000010;
VerticalBox {
spacing: 20px;
padding: 25px;
Text {
text: "Trading Stats";
font-size: 18px;
color: text-color;
font-weight: 600;
}
HorizontalBox {
alignment: stretch;
spacing: 20px;
VerticalBox {
alignment: center;
spacing: 5px;
Text {
text: "24";
font-size: 24px;
color: primary-color;
font-weight: 700;
}
Text {
text: "Trades";
font-size: 12px;
color: text-color;
opacity: 0.7;
}
}
VerticalBox {
alignment: center;
spacing: 5px;
Text {
text: "$1,234";
font-size: 24px;
color: #10b981;
font-weight: 700;
}
Text {
text: "Profit";
font-size: 12px;
color: text-color;
opacity: 0.7;
}
}
VerticalBox {
alignment: center;
spacing: 5px;
Text {
text: "67%";
font-size: 24px;
color: #10b981;
font-weight: 700;
}
Text {
text: "Win Rate";
font-size: 12px;
color: text-color;
opacity: 0.7;
}
}
}
}
}
}
}
}

View file

@ -0,0 +1,2 @@
// Window Controls Widget Public API
export { WindowControlsWidget } from "ui/window-controls-widget.slint";

View file

@ -0,0 +1,190 @@
import { Button, HorizontalBox } from "std-widgets.slint";
import { Theme } from "../../../shared/design-system/tokens/theme.slint";
// Professional title bar component with theme support
export component TitleBar {
// Window state
in-out property <bool> is-maximized: false;
// Callbacks for window controls
callback minimize-window();
callback maximize-window();
callback close-window();
callback toggle-theme();
callback start-drag-window();
height: 32px;
Rectangle {
background: Theme.surface;
border-width: 0px;
border-color: Theme.border;
// Drag area for the title bar
drag-area := TouchArea {
width: 100%;
height: 100%;
moved => {
if (self.pressed) {
start-drag-window();
}
}
}
HorizontalBox {
padding: 16px;
alignment: stretch;
// Left side - App branding
HorizontalBox {
alignment: start;
spacing: 8px;
// App icon
Rectangle {
width: 20px;
height: 20px;
// Ziya logo (layered rectangles)
Rectangle {
width: 16px;
height: 16px;
background: #570df8;
border-radius: 3px;
Rectangle {
x: 2px;
y: 2px;
width: 12px;
height: 12px;
background: #4506cb;
border-radius: 2px;
}
}
}
// App name
Text {
text: "Ziya";
color: Theme.text-primary;
font-size: 14px;
font-weight: 600;
vertical-alignment: center;
}
}
// Right side - Controls
HorizontalBox {
alignment: end;
spacing: 4px;
// Theme switcher
Rectangle {
width: 32px;
height: 32px;
border-radius: 4px;
states [
hover when theme-area.has-hover: {
background: Theme.nav-hover;
}
]
// Theme icon - shows current theme state
Text {
text: Theme.is-dark-mode ? "🌙" : "☀️";
font-size: 14px;
horizontal-alignment: center;
vertical-alignment: center;
}
theme-area := TouchArea {
clicked => {
Theme.toggle-theme();
toggle-theme();
}
}
}
// Minimize button
Rectangle {
width: 32px;
height: 32px;
border-radius: 4px;
states [
hover when min-area.has-hover: {
background: Theme.nav-hover;
}
]
// Minimize icon
Text {
text: "";
color: Theme.text-secondary;
font-size: 14px;
horizontal-alignment: center;
vertical-alignment: center;
}
min-area := TouchArea {
clicked => { minimize-window(); }
}
}
// Maximize/Restore button
Rectangle {
width: 32px;
height: 32px;
border-radius: 4px;
states [
hover when max-area.has-hover: {
background: Theme.nav-hover;
}
]
// Maximize icon
Text {
text: is-maximized ? "❐" : "□";
color: Theme.text-secondary;
font-size: 12px;
horizontal-alignment: center;
vertical-alignment: center;
}
max-area := TouchArea {
clicked => { maximize-window(); }
}
}
// Close button
Rectangle {
width: 32px;
height: 32px;
border-radius: 4px;
states [
hover when close-area.has-hover: {
background: #ef4444;
}
]
// Close icon
Text {
text: "✕";
color: close-area.has-hover ? #ffffff : Theme.text-secondary;
font-size: 10px;
horizontal-alignment: center;
vertical-alignment: center;
}
close-area := TouchArea {
clicked => { close-window(); }
}
}
}
}
}
}

View file

@ -0,0 +1,18 @@
import { TitleBar } from "title-bar.slint";
// Window Controls Widget
export component WindowControlsWidget {
callback theme-toggle-clicked();
callback minimize-clicked();
callback maximize-clicked();
callback close-clicked();
callback start-drag-window();
TitleBar {
toggle-theme => { root.theme-toggle-clicked(); }
minimize-window => { root.minimize-clicked(); }
maximize-window => { root.maximize-clicked(); }
close-window => { root.close-clicked(); }
start-drag-window => { root.start-drag-window(); }
}
}