diff --git a/CHANGELOG.md b/CHANGELOG.md index c5bdc4cd..25e771f9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,13 @@ Notable changes to Claude Code Usage Monitor are documented here, newest first. The format follows [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), with changes grouped into Added, Changed, Fixed, and Removed where applicable. +## [Unreleased] + +### Changed + +- Show Antigravity's Gemini usage labels at rest and reveal the Claude/GPT labels while the cursor is over the Antigravity tile, replacing the timed 8 s / 2 s alternation. +- With only one Antigravity pool enabled, hovering the Antigravity tile crossfades to the other pool's labels and gauges, the same way as with both pools enabled. + ## [2.22.4] - 2026-10-25 ### Fixed diff --git a/src/app_settings.rs b/src/app_settings.rs index d2e1d7f1..4e172ab2 100644 --- a/src/app_settings.rs +++ b/src/app_settings.rs @@ -72,6 +72,8 @@ pub struct SettingsFile { /// the widget counts down towards a limit rather than up from zero. #[serde(default)] pub usage_countdown: bool, + #[serde(default = "default_true")] + pub show_pace: bool, #[serde(default, skip_serializing_if = "Option::is_none")] pub active_theme_path: Option, #[serde(default, skip_serializing_if = "Option::is_none")] @@ -139,6 +141,7 @@ impl Default for SettingsFile { show_copilot: false, custom_theme_enabled: true, usage_countdown: false, + show_pace: true, active_theme_path: None, dashboard_width: None, dashboard_height: None, @@ -669,6 +672,27 @@ mod tests { assert_eq!(settings_json(&counting_down)["usage_countdown"], true); } + #[test] + fn show_pace_defaults_to_on_and_round_trips() { + let settings = SettingsFile::default(); + assert!(settings.show_pace); + assert_eq!(settings_json(&settings)["show_pace"], true); + + let legacy = decode_settings(r#"{"poll_interval_ms":900000}"#).unwrap(); + assert!(legacy.show_pace); + + for show_pace in [false, true] { + let settings = SettingsFile { + show_pace, + ..Default::default() + }; + let json = settings_json(&settings); + assert_eq!(json["show_pace"], show_pace); + let loaded = decode_settings(&json.to_string()).unwrap(); + assert_eq!(loaded.show_pace, show_pace); + } + } + #[test] fn settings_always_use_the_theme_widget() { let mut settings = SettingsFile { diff --git a/src/context_menu.rs b/src/context_menu.rs index bf87f113..74f67ba0 100644 --- a/src/context_menu.rs +++ b/src/context_menu.rs @@ -66,8 +66,13 @@ pub enum ContextMenuAction { }, ToggleAntigravityGemini, ToggleAntigravityExternal, + ToggleClaudeMain, + ToggleClaudeX, + ToggleCodexMain, + ToggleCodexX, ToggleStartup, ToggleTaskbarLock, + ToggleShowPace, ToggleWidget, /// Accepted only so menus saved by older versions can be loaded and /// cleaned up. New menus cannot create or execute this legacy action. @@ -310,7 +315,11 @@ pub fn rendered_label( "Refresh" => language.text("Refresh"), "Exit" => language.text("Exit"), "Claude Code" => language.text("Claude Code"), + "Claude Code (Main)" => language.text("Claude Code (Main)"), + "Claude Code X" => language.text("Claude Code X"), "Codex" => language.text("Codex"), + "Codex (Main)" => language.text("Codex (Main)"), + "Codex X" => language.text("Codex X"), "Antigravity" => language.text("Antigravity"), "OpenCode" => language.text("OpenCode"), "Cursor" => language.text("Cursor"), @@ -325,6 +334,7 @@ pub fn rendered_label( "Check for updates" => language.text("Check for updates"), "Lock in taskbar" => language.text("Lock in taskbar"), "Show widget" => language.text("Show widget"), + "Show pace" => language.text("Show pace"), _ => label, }; crate::theme_engine::format_template(translated, context) @@ -373,19 +383,17 @@ pub fn classic_context_menu() -> ContextMenuDocument { "Providers", vec![ ContextMenuItem::action( - "provider-claude", - "Claude Code", - Action::ToggleProvider { - provider: Provider::Claude, - }, + "provider-claude-main", + "Claude Code (Main)", + Action::ToggleClaudeMain, ), + ContextMenuItem::action("provider-claude-x", "Claude Code X", Action::ToggleClaudeX), ContextMenuItem::action( - "provider-codex", - "Codex", - Action::ToggleProvider { - provider: Provider::Codex, - }, + "provider-codex-main", + "Codex (Main)", + Action::ToggleCodexMain, ), + ContextMenuItem::action("provider-codex-x", "Codex X", Action::ToggleCodexX), ContextMenuItem::action( "provider-antigravity-gemini", "Antigravity (Gemini)", @@ -457,6 +465,7 @@ pub fn classic_context_menu() -> ContextMenuDocument { Action::ToggleStartup, ), ContextMenuItem::action("lock-taskbar", "Lock in taskbar", Action::ToggleTaskbarLock), + ContextMenuItem::action("show-pace", "Show pace", Action::ToggleShowPace), ContextMenuItem::submenu("language", "Language", languages), ContextMenuItem::separator("settings-separator"), ContextMenuItem::action( @@ -718,6 +727,23 @@ mod tests { assert!(menu.validate().is_empty()); assert!(menu.items.iter().any(|item| item.id == "refresh")); assert!(menu.items.iter().any(|item| item.id == "update-frequency")); + let settings = menu + .items + .iter() + .find(|item| item.id == "settings") + .unwrap(); + let ContextMenuItemKind::Submenu { items } = &settings.kind else { + panic!("Settings must be a submenu"); + }; + assert!(items.iter().any(|item| { + item.label == "Show pace" + && matches!( + &item.kind, + ContextMenuItemKind::Action { + action: ContextMenuAction::ToggleShowPace + } + ) + })); assert!(serde_json::to_string(&menu) .unwrap() .contains("provider-opencode")); diff --git a/src/localization/locales/de.toml b/src/localization/locales/de.toml index df432b1e..b4f8d902 100644 --- a/src/localization/locales/de.toml +++ b/src/localization/locales/de.toml @@ -123,10 +123,14 @@ copilot_window_title = "Copilot-Nutzungsmonitor" "Choose asset..." = "Medium auswählen..." "Choose one action for this context menu item." = "Wählen Sie eine Aktion für diesen Kontextmenüeintrag." "Claude Code" = "Claude Code" +"Claude Code (Main)" = "Claude Code (Main)" +"Claude Code X" = "Claude Code X" "Click" = "Click" "Close asset library" = "Close asset library" "Close Builder" = "Baukasten schließen" "Codex" = "Codex" +"Codex (Main)" = "Codex (Main)" +"Codex X" = "Codex X" "Collect usage from Anthropic" = "Nutzungsdaten von Anthropic abrufen" "Collect usage from GitHub" = "Nutzungsdaten von GitHub abrufen" "Collect usage from Google" = "Nutzungsdaten von Google abrufen" @@ -360,6 +364,7 @@ copilot_window_title = "Copilot-Nutzungsmonitor" "Short duration" = "Kurze Dauer" "Show context menu" = "Kontextmenü anzeigen" "Show dashboard" = "Dashboard anzeigen" +"Show pace" = "Show pace" "Show widget" = "Widget anzeigen" "Size" = "Größe" "Smaller value" = "Kleinerer Wert" diff --git a/src/localization/locales/en.toml b/src/localization/locales/en.toml index 2273418e..f9205876 100644 --- a/src/localization/locales/en.toml +++ b/src/localization/locales/en.toml @@ -123,10 +123,14 @@ copilot_window_title = "Copilot Usage Monitor" "Choose asset..." = "Choose asset..." "Choose one action for this context menu item." = "Choose one action for this context menu item." "Claude Code" = "Claude Code" +"Claude Code (Main)" = "Claude Code (Main)" +"Claude Code X" = "Claude Code X" "Click" = "Click" "Close asset library" = "Close asset library" "Close Builder" = "Close Builder" "Codex" = "Codex" +"Codex (Main)" = "Codex (Main)" +"Codex X" = "Codex X" "Collect usage from Anthropic" = "Collect usage from Anthropic" "Collect usage from GitHub" = "Collect usage from GitHub" "Collect usage from Google" = "Collect usage from Google" @@ -360,6 +364,7 @@ copilot_window_title = "Copilot Usage Monitor" "Short duration" = "Short duration" "Show context menu" = "Show context menu" "Show dashboard" = "Show dashboard" +"Show pace" = "Show pace" "Show widget" = "Show widget" "Size" = "Size" "Smaller value" = "Smaller value" diff --git a/src/localization/locales/es.toml b/src/localization/locales/es.toml index 41ac2ed6..fd18df1f 100644 --- a/src/localization/locales/es.toml +++ b/src/localization/locales/es.toml @@ -123,10 +123,14 @@ copilot_window_title = "Monitor de uso de Copilot" "Choose asset..." = "Elegir recurso..." "Choose one action for this context menu item." = "Elija una acción para este elemento del menú contextual." "Claude Code" = "Claude Code" +"Claude Code (Main)" = "Claude Code (Main)" +"Claude Code X" = "Claude Code X" "Click" = "Click" "Close asset library" = "Close asset library" "Close Builder" = "Cerrar Constructor" "Codex" = "Codex" +"Codex (Main)" = "Codex (Main)" +"Codex X" = "Codex X" "Collect usage from Anthropic" = "Recopilar uso de Anthropic" "Collect usage from GitHub" = "Recopilar uso de GitHub" "Collect usage from Google" = "Recopilar uso de Google" @@ -360,6 +364,7 @@ copilot_window_title = "Monitor de uso de Copilot" "Short duration" = "Duración corta" "Show context menu" = "Mostrar menú contextual" "Show dashboard" = "Mostrar panel" +"Show pace" = "Show pace" "Show widget" = "Mostrar widget" "Size" = "Tamaño" "Smaller value" = "Valor menor" diff --git a/src/localization/locales/fr.toml b/src/localization/locales/fr.toml index 34545dcf..cc33b79a 100644 --- a/src/localization/locales/fr.toml +++ b/src/localization/locales/fr.toml @@ -123,10 +123,14 @@ copilot_window_title = "Moniteur d'utilisation Copilot" "Choose asset..." = "Choisir une ressource..." "Choose one action for this context menu item." = "Choisissez une action pour cet élément du menu contextuel." "Claude Code" = "Claude Code" +"Claude Code (Main)" = "Claude Code (Main)" +"Claude Code X" = "Claude Code X" "Click" = "Click" "Close asset library" = "Close asset library" "Close Builder" = "Fermer le Constructeur" "Codex" = "Codex" +"Codex (Main)" = "Codex (Main)" +"Codex X" = "Codex X" "Collect usage from Anthropic" = "Collecter l'utilisation depuis Anthropic" "Collect usage from GitHub" = "Collecter l'utilisation depuis GitHub" "Collect usage from Google" = "Collecter l'utilisation depuis Google" @@ -360,6 +364,7 @@ copilot_window_title = "Moniteur d'utilisation Copilot" "Short duration" = "Durée courte" "Show context menu" = "Afficher le menu contextuel" "Show dashboard" = "Afficher le tableau de bord" +"Show pace" = "Show pace" "Show widget" = "Afficher le widget" "Size" = "Taille" "Smaller value" = "Valeur la plus petite" diff --git a/src/localization/locales/ja.toml b/src/localization/locales/ja.toml index 6d6de298..4387b89d 100644 --- a/src/localization/locales/ja.toml +++ b/src/localization/locales/ja.toml @@ -125,10 +125,14 @@ copilot_window_title = "Copilot 使用量モニター" "Choose asset..." = "アセットを選択..." "Choose one action for this context menu item." = "このコンテキストメニュー項目のアクションを1つ選択します。" "Claude Code" = "Claude Code" +"Claude Code (Main)" = "Claude Code (Main)" +"Claude Code X" = "Claude Code X" "Click" = "Click" "Close asset library" = "Close asset library" "Close Builder" = "ビルダーを閉じる" "Codex" = "Codex" +"Codex (Main)" = "Codex (Main)" +"Codex X" = "Codex X" "Collect usage from Anthropic" = "Anthropic から使用量を取得" "Collect usage from GitHub" = "GitHub から使用量を取得" "Collect usage from Google" = "Google から使用量を取得" @@ -362,6 +366,7 @@ copilot_window_title = "Copilot 使用量モニター" "Short duration" = "短い期間" "Show context menu" = "コンテキストメニューを表示" "Show dashboard" = "ダッシュボードを表示" +"Show pace" = "Show pace" "Show widget" = "ウィジェットを表示" "Size" = "サイズ" "Smaller value" = "小さい値" diff --git a/src/localization/locales/ko.toml b/src/localization/locales/ko.toml index 6d73478c..cc944b65 100644 --- a/src/localization/locales/ko.toml +++ b/src/localization/locales/ko.toml @@ -125,10 +125,14 @@ copilot_window_title = "Copilot 사용량 모니터" "Choose asset..." = "에셋 선택..." "Choose one action for this context menu item." = "이 컨텍스트 메뉴 항목에 사용할 작업 하나를 선택하세요." "Claude Code" = "Claude Code" +"Claude Code (Main)" = "Claude Code (Main)" +"Claude Code X" = "Claude Code X" "Click" = "Click" "Close asset library" = "Close asset library" "Close Builder" = "빌더 닫기" "Codex" = "Codex" +"Codex (Main)" = "Codex (Main)" +"Codex X" = "Codex X" "Collect usage from Anthropic" = "Anthropic에서 사용량 수집" "Collect usage from GitHub" = "GitHub에서 사용량 수집" "Collect usage from Google" = "Google에서 사용량 수집" @@ -362,6 +366,7 @@ copilot_window_title = "Copilot 사용량 모니터" "Short duration" = "간단한 기간" "Show context menu" = "컨텍스트 메뉴 표시" "Show dashboard" = "대시보드 표시" +"Show pace" = "Show pace" "Show widget" = "위젯 표시" "Size" = "크기" "Smaller value" = "더 작은 값" diff --git a/src/localization/locales/nl.toml b/src/localization/locales/nl.toml index 50550807..bc7c79a5 100644 --- a/src/localization/locales/nl.toml +++ b/src/localization/locales/nl.toml @@ -123,10 +123,14 @@ copilot_window_title = "Copilot-gebruiksmonitor" "Choose asset..." = "Media kiezen..." "Choose one action for this context menu item." = "Kies één actie voor dit contextmenu-item." "Claude Code" = "Claude Code" +"Claude Code (Main)" = "Claude Code (Main)" +"Claude Code X" = "Claude Code X" "Click" = "Click" "Close asset library" = "Mediabibliotheek sluiten" "Close Builder" = "Bouwer sluiten" "Codex" = "Codex" +"Codex (Main)" = "Codex (Main)" +"Codex X" = "Codex X" "Collect usage from Anthropic" = "Gebruiksgegevens ophalen bij Anthropic" "Collect usage from GitHub" = "Gebruiksgegevens ophalen bij GitHub" "Collect usage from Google" = "Gebruiksgegevens ophalen bij Google" @@ -360,6 +364,7 @@ copilot_window_title = "Copilot-gebruiksmonitor" "Short duration" = "Korte duur" "Show context menu" = "Contextmenu tonen" "Show dashboard" = "Dashboard tonen" +"Show pace" = "Show pace" "Show widget" = "Widget tonen" "Size" = "Grootte" "Smaller value" = "Kleinste waarde" diff --git a/src/localization/locales/pl.toml b/src/localization/locales/pl.toml index c743ce77..70e6965d 100644 --- a/src/localization/locales/pl.toml +++ b/src/localization/locales/pl.toml @@ -123,10 +123,14 @@ copilot_window_title = "Monitor zużycia Copilot" "Choose asset..." = "Wybierz zasób..." "Choose one action for this context menu item." = "Wybierz jedną akcję dla tego elementu menu kontekstowego." "Claude Code" = "Claude Code" +"Claude Code (Main)" = "Claude Code (Main)" +"Claude Code X" = "Claude Code X" "Click" = "Kliknięcie" "Close asset library" = "Zamknij bibliotekę zasobów" "Close Builder" = "Zamknij kreator" "Codex" = "Codex" +"Codex (Main)" = "Codex (Main)" +"Codex X" = "Codex X" "Collect usage from Anthropic" = "Zbieraj dane o zużyciu z Anthropic" "Collect usage from GitHub" = "Zbieraj dane o zużyciu z GitHuba" "Collect usage from Google" = "Zbieraj dane o zużyciu z Google" @@ -360,6 +364,7 @@ copilot_window_title = "Monitor zużycia Copilot" "Short duration" = "Skrócony czas trwania" "Show context menu" = "Pokaż menu kontekstowe" "Show dashboard" = "Pokaż panel" +"Show pace" = "Show pace" "Show widget" = "Pokaż widżet" "Size" = "Rozmiar" "Smaller value" = "Mniejsza z wartości" diff --git a/src/localization/locales/pt-BR.toml b/src/localization/locales/pt-BR.toml index 7719834b..99ada4fe 100644 --- a/src/localization/locales/pt-BR.toml +++ b/src/localization/locales/pt-BR.toml @@ -123,10 +123,14 @@ copilot_window_title = "Monitor de uso do Copilot" "Choose asset..." = "Escolher recurso..." "Choose one action for this context menu item." = "Escolha uma ação para este item do menu de contexto." "Claude Code" = "Claude Code" +"Claude Code (Main)" = "Claude Code (Main)" +"Claude Code X" = "Claude Code X" "Click" = "Click" "Close asset library" = "Close asset library" "Close Builder" = "Fechar Construtor" "Codex" = "Codex" +"Codex (Main)" = "Codex (Main)" +"Codex X" = "Codex X" "Collect usage from Anthropic" = "Coletar uso da Anthropic" "Collect usage from GitHub" = "Coletar uso do GitHub" "Collect usage from Google" = "Coletar uso do Google" @@ -360,6 +364,7 @@ copilot_window_title = "Monitor de uso do Copilot" "Short duration" = "Duração curta" "Show context menu" = "Mostrar menu de contexto" "Show dashboard" = "Mostrar painel" +"Show pace" = "Show pace" "Show widget" = "Mostrar widget" "Size" = "Tamanho" "Smaller value" = "Menor valor" diff --git a/src/localization/locales/ru.toml b/src/localization/locales/ru.toml index 19d8aa49..d15bf7d9 100644 --- a/src/localization/locales/ru.toml +++ b/src/localization/locales/ru.toml @@ -123,10 +123,14 @@ copilot_window_title = "Монитор использования Copilot" "Choose asset..." = "Выбрать ресурс..." "Choose one action for this context menu item." = "Выберите одно действие для этого пункта контекстного меню." "Claude Code" = "Claude Code" +"Claude Code (Main)" = "Claude Code (Основной)" +"Claude Code X" = "Claude Code X" "Click" = "Click" "Close asset library" = "Close asset library" "Close Builder" = "Закрыть конструктор" "Codex" = "Codex" +"Codex (Main)" = "Codex (Основной)" +"Codex X" = "Codex X" "Collect usage from Anthropic" = "Получать данные об использовании Anthropic" "Collect usage from GitHub" = "Получать данные об использовании GitHub" "Collect usage from Google" = "Получать данные об использовании Google" @@ -360,6 +364,7 @@ copilot_window_title = "Монитор использования Copilot" "Short duration" = "Краткая длительность" "Show context menu" = "Показать контекстное меню" "Show dashboard" = "Показать панель" +"Show pace" = "Показывать темп" "Show widget" = "Показать виджет" "Size" = "Размер" "Smaller value" = "Меньшее значение" diff --git a/src/localization/locales/th.toml b/src/localization/locales/th.toml index c2a936ee..d970fc7d 100644 --- a/src/localization/locales/th.toml +++ b/src/localization/locales/th.toml @@ -125,10 +125,14 @@ copilot_window_title = "ตัวติดตามการใช้งาน C "Choose asset..." = "เลือกแอสเซท..." "Choose one action for this context menu item." = "เลือกหนึ่งแอ็กชันสำหรับรายการเมนูนี้" "Claude Code" = "Claude Code" +"Claude Code (Main)" = "Claude Code (Main)" +"Claude Code X" = "Claude Code X" "Click" = "คลิก" "Close asset library" = "ปิดคลังแอสเซท" "Close Builder" = "ปิดตัวสร้าง" "Codex" = "Codex" +"Codex (Main)" = "Codex (Main)" +"Codex X" = "Codex X" "Collect usage from Anthropic" = "ดึงข้อมูลการใช้งานจาก Anthropic" "Collect usage from GitHub" = "ดึงข้อมูลการใช้งานจาก GitHub" "Collect usage from Google" = "ดึงข้อมูลการใช้งานจาก Google" @@ -362,6 +366,7 @@ copilot_window_title = "ตัวติดตามการใช้งาน C "Short duration" = "ระยะเวลาแบบสั้น" "Show context menu" = "แสดงเมนูคลิกขวา" "Show dashboard" = "แสดงแดชบอร์ด" +"Show pace" = "Show pace" "Show widget" = "แสดงวิดเจ็ต" "Size" = "ขนาด" "Smaller value" = "ค่าที่น้อยกว่า" diff --git a/src/localization/locales/tr.toml b/src/localization/locales/tr.toml index cf8706c8..365a3b06 100644 --- a/src/localization/locales/tr.toml +++ b/src/localization/locales/tr.toml @@ -123,10 +123,14 @@ copilot_window_title = "Copilot Kullanım İzleyicisi" "Choose asset..." = "Varlık seç..." "Choose one action for this context menu item." = "Bu bağlam menüsü öğesi için bir eylem seçin." "Claude Code" = "Claude Code" +"Claude Code (Main)" = "Claude Code (Main)" +"Claude Code X" = "Claude Code X" "Click" = "Click" "Close asset library" = "Close asset library" "Close Builder" = "Oluşturucuyu kapat" "Codex" = "Codex" +"Codex (Main)" = "Codex (Main)" +"Codex X" = "Codex X" "Collect usage from Anthropic" = "Anthropic kullanımını topla" "Collect usage from GitHub" = "GitHub kullanımını topla" "Collect usage from Google" = "Google kullanımını topla" @@ -360,6 +364,7 @@ copilot_window_title = "Copilot Kullanım İzleyicisi" "Short duration" = "Kısa süre" "Show context menu" = "Bağlam menüsünü göster" "Show dashboard" = "Panoyu göster" +"Show pace" = "Show pace" "Show widget" = "Pencere öğesini göster" "Size" = "Boyut" "Smaller value" = "Küçük değer" diff --git a/src/localization/locales/zh-CN.toml b/src/localization/locales/zh-CN.toml index 82c94804..b9bc0d51 100644 --- a/src/localization/locales/zh-CN.toml +++ b/src/localization/locales/zh-CN.toml @@ -125,10 +125,14 @@ copilot_window_title = "Copilot 使用量监控" "Choose asset..." = "选择资源..." "Choose one action for this context menu item." = "为此上下文菜单项选择一个操作。" "Claude Code" = "Claude Code" +"Claude Code (Main)" = "Claude Code (Main)" +"Claude Code X" = "Claude Code X" "Click" = "Click" "Close asset library" = "Close asset library" "Close Builder" = "关闭构建器" "Codex" = "Codex" +"Codex (Main)" = "Codex (Main)" +"Codex X" = "Codex X" "Collect usage from Anthropic" = "从 Anthropic 获取使用量" "Collect usage from GitHub" = "从 GitHub 获取使用量" "Collect usage from Google" = "从 Google 获取使用量" @@ -362,6 +366,7 @@ copilot_window_title = "Copilot 使用量监控" "Short duration" = "简短时长" "Show context menu" = "显示上下文菜单" "Show dashboard" = "显示仪表板" +"Show pace" = "Show pace" "Show widget" = "显示小组件" "Size" = "大小" "Smaller value" = "较小的值" diff --git a/src/localization/locales/zh-TW.toml b/src/localization/locales/zh-TW.toml index b0644822..c4154678 100644 --- a/src/localization/locales/zh-TW.toml +++ b/src/localization/locales/zh-TW.toml @@ -125,10 +125,14 @@ copilot_window_title = "Copilot 使用量監控" "Choose asset..." = "選擇資源..." "Choose one action for this context menu item." = "為此快顯功能表項目選擇一個動作。" "Claude Code" = "Claude Code" +"Claude Code (Main)" = "Claude Code (Main)" +"Claude Code X" = "Claude Code X" "Click" = "Click" "Close asset library" = "Close asset library" "Close Builder" = "關閉建構器" "Codex" = "Codex" +"Codex (Main)" = "Codex (Main)" +"Codex X" = "Codex X" "Collect usage from Anthropic" = "從 Anthropic 取得使用量" "Collect usage from GitHub" = "從 GitHub 取得使用量" "Collect usage from Google" = "從 Google 取得使用量" @@ -362,6 +366,7 @@ copilot_window_title = "Copilot 使用量監控" "Short duration" = "簡短時間" "Show context menu" = "顯示快顯功能表" "Show dashboard" = "顯示儀表板" +"Show pace" = "Show pace" "Show widget" = "顯示小工具" "Size" = "大小" "Smaller value" = "較小的值" diff --git a/src/studio_app/studio_context_menu_editor.rs b/src/studio_app/studio_context_menu_editor.rs index f0b588dc..bac680ae 100644 --- a/src/studio_app/studio_context_menu_editor.rs +++ b/src/studio_app/studio_context_menu_editor.rs @@ -323,8 +323,13 @@ pub(super) fn context_menu_action_script(action: &ContextMenuAction) -> String { } ContextMenuAction::ToggleAntigravityGemini => "toggle_antigravity_gemini()".into(), ContextMenuAction::ToggleAntigravityExternal => "toggle_antigravity_external()".into(), + ContextMenuAction::ToggleClaudeMain => "toggle_claude_main()".into(), + ContextMenuAction::ToggleClaudeX => "toggle_claude_x()".into(), + ContextMenuAction::ToggleCodexMain => "toggle_codex_main()".into(), + ContextMenuAction::ToggleCodexX => "toggle_codex_x()".into(), ContextMenuAction::ToggleStartup => "toggle_startup()".into(), ContextMenuAction::ToggleTaskbarLock => "toggle_taskbar_lock()".into(), + ContextMenuAction::ToggleShowPace => "toggle_show_pace()".into(), ContextMenuAction::ToggleWidget => "toggle_widget()".into(), ContextMenuAction::LegacyResetPosition => String::new(), ContextMenuAction::SetLanguage { language } => { @@ -352,6 +357,7 @@ pub(super) fn parse_context_menu_action_script(script: &str) -> Result Result ContextMenuAction::ToggleWidget, "toggle_startup" => ContextMenuAction::ToggleStartup, "toggle_taskbar_lock" => ContextMenuAction::ToggleTaskbarLock, + "toggle_show_pace" => ContextMenuAction::ToggleShowPace, "check_for_updates" => ContextMenuAction::CheckForUpdates, "exit" => ContextMenuAction::Exit, "set_update_frequency" => { diff --git a/src/studio_app/studio_native_menu.rs b/src/studio_app/studio_native_menu.rs index 663ae780..66986db8 100644 --- a/src/studio_app/studio_native_menu.rs +++ b/src/studio_app/studio_native_menu.rs @@ -573,8 +573,53 @@ pub(super) fn context_menu_preview_action_checked( settings.poll_interval_ms == seconds.saturating_mul(1_000) } ContextMenuAction::ToggleProvider { provider } => settings.provider_enabled(*provider), + ContextMenuAction::ToggleClaudeMain => { + settings.provider_enabled(crate::providers::ProviderId::Claude) + && settings + .accounts + .claude + .profiles + .iter() + .find(|p| p.id == "default") + .map(|p| p.enabled) + .unwrap_or(true) + } + ContextMenuAction::ToggleClaudeX => { + settings.provider_enabled(crate::providers::ProviderId::Claude) + && settings + .accounts + .claude + .profiles + .iter() + .find(|p| p.id == "claude_x") + .map(|p| p.enabled) + .unwrap_or(false) + } + ContextMenuAction::ToggleCodexMain => { + settings.provider_enabled(crate::providers::ProviderId::Codex) + && settings + .accounts + .codex + .profiles + .iter() + .find(|p| p.id == "default") + .map(|p| p.enabled) + .unwrap_or(true) + } + ContextMenuAction::ToggleCodexX => { + settings.provider_enabled(crate::providers::ProviderId::Codex) + && settings + .accounts + .codex + .profiles + .iter() + .find(|p| p.id == "codex_x") + .map(|p| p.enabled) + .unwrap_or(false) + } ContextMenuAction::ToggleStartup => startup_enabled, ContextMenuAction::ToggleTaskbarLock => settings.lock_taskbar, + ContextMenuAction::ToggleShowPace => settings.show_pace, ContextMenuAction::ToggleWidget => theme .surfaces .iter() diff --git a/src/studio_app/tests.rs b/src/studio_app/tests.rs index 257ef781..27076f83 100644 --- a/src/studio_app/tests.rs +++ b/src/studio_app/tests.rs @@ -1008,6 +1008,7 @@ fn context_menu_action_scripts_round_trip_every_action_kind() { }, ContextMenuAction::ToggleStartup, ContextMenuAction::ToggleTaskbarLock, + ContextMenuAction::ToggleShowPace, ContextMenuAction::ToggleWidget, ContextMenuAction::SetLanguage { language: "en-US".into(), diff --git a/src/theme_engine.rs b/src/theme_engine.rs index 373711c2..bf146701 100644 --- a/src/theme_engine.rs +++ b/src/theme_engine.rs @@ -1347,11 +1347,20 @@ pub struct ThemeRuntime { /// the `.display` values and summaries using them follow this; `.percentage` /// always means consumption so severity thresholds keep their meaning. pub countdown: bool, + pub show_pace: bool, pub surface_nest: SurfaceNest, pub floating_card_opacity: u8, pub antigravity_gemini_enabled: bool, pub antigravity_external_enabled: bool, pub crossfade_opacity: f64, + pub claude_crossfade_opacity: f64, + pub claude_hovered: bool, + pub claude_main_enabled: bool, + pub claude_x_enabled: bool, + pub codex_crossfade_opacity: f64, + pub codex_hovered: bool, + pub codex_main_enabled: bool, + pub codex_x_enabled: bool, host_width: u32, host_height: u32, } @@ -1364,11 +1373,20 @@ impl Default for ThemeRuntime { has_error: false, language: LanguageId::English, countdown: false, + show_pace: true, surface_nest: SurfaceNest::Taskbar, floating_card_opacity: 85, antigravity_gemini_enabled: true, antigravity_external_enabled: false, crossfade_opacity: 1.0, + claude_crossfade_opacity: 0.0, + claude_hovered: false, + claude_main_enabled: true, + claude_x_enabled: false, + codex_crossfade_opacity: 0.0, + codex_hovered: false, + codex_main_enabled: true, + codex_x_enabled: false, host_width: default_canvas_width(), host_height: default_canvas_height(), } @@ -1398,16 +1416,53 @@ impl ThemeRuntime { has_error: false, language: LanguageId::English, countdown: false, + show_pace: true, surface_nest: SurfaceNest::Taskbar, floating_card_opacity: 85, antigravity_gemini_enabled: agy, antigravity_external_enabled: false, crossfade_opacity: 1.0, + claude_crossfade_opacity: 0.0, + claude_hovered: false, + claude_main_enabled: true, + claude_x_enabled: false, + codex_crossfade_opacity: 0.0, + codex_hovered: false, + codex_main_enabled: true, + codex_x_enabled: false, host_width: default_canvas_width(), host_height: default_canvas_height(), } } + pub fn with_claude_state( + mut self, + hovered: bool, + main_enabled: bool, + x_enabled: bool, + crossfade_opacity: f64, + ) -> Self { + self.claude_hovered = hovered; + self.claude_main_enabled = main_enabled; + self.claude_x_enabled = x_enabled; + self.claude_crossfade_opacity = crossfade_opacity; + self + } + + pub fn with_codex_state( + mut self, + hovered: bool, + main_enabled: bool, + x_enabled: bool, + crossfade_opacity: f64, + ) -> Self { + self.codex_hovered = hovered; + self.codex_main_enabled = main_enabled; + self.codex_x_enabled = x_enabled; + self.codex_crossfade_opacity = crossfade_opacity; + self + } + pub fn with_antigravity_pools( mut self, gemini: bool, @@ -1447,6 +1502,11 @@ impl ThemeRuntime { self } + pub fn with_show_pace(mut self, show_pace: bool) -> Self { + self.show_pace = show_pace; + self + } + /// Supply the selected native host's 96-DPI logical dimensions. Theme /// expressions consume these as `host.width` and `host.height`. pub fn with_host_dimensions(mut self, width: u32, height: u32) -> Self { @@ -1468,6 +1528,20 @@ impl ThemeRuntime { } } +const FIVE_HOURS: std::time::Duration = std::time::Duration::from_secs(5 * 3600); +const WEEK: std::time::Duration = std::time::Duration::from_secs(7 * 24 * 3600); + +/// Percent of a window of `length` that has passed by now, given when it +/// resets; `None` when the reset is not within one window from now. +fn expected_used(resets_at: std::time::SystemTime, length: std::time::Duration) -> Option { + let left = resets_at + .duration_since(std::time::SystemTime::now()) + .ok()?; + // A minute of slack for poll latency right after a reset. + (!length.is_zero() && left <= length + std::time::Duration::from_secs(60)) + .then(|| (1.0 - left.min(length).as_secs_f64() / length.as_secs_f64()) * 100.0) +} + impl DataContext { pub fn from_usage(data: Option<&AppUsageData>, canvas: &Canvas) -> Self { Self::from_usage_with_runtime(data, canvas, ThemeRuntime::default()) @@ -1544,6 +1618,7 @@ impl DataContext { ); } context.insert("display.countdown", runtime.countdown as u8 as f64); + context.insert("display.show_pace", runtime.show_pace as u8 as f64); context.insert( "antigravity.gemini.enabled", runtime.antigravity_gemini_enabled as u8 as f64, @@ -1555,9 +1630,59 @@ impl DataContext { let agy_dual_mode = runtime.antigravity_gemini_enabled && runtime.antigravity_external_enabled; context.insert("antigravity.dual_mode", agy_dual_mode as u8 as f64); + let crossfade = runtime.crossfade_opacity.clamp(0.0, 1.0); + context.insert("antigravity.crossfade_opacity", crossfade); + context.insert("antigravity.normal.opacity", crossfade); + context.insert("antigravity.hover.opacity", 1.0 - crossfade); + let gemini_opacity = if crossfade > 0.5 { + (crossfade - 0.5) * 2.0 + } else { + 0.0 + }; + let external_opacity = if crossfade < 0.5 { + (0.5 - crossfade) * 2.0 + } else { + 0.0 + }; + // crossfade 1.0 shows the primary pool: Gemini in dual mode, otherwise + // the single enabled pool; hover fades toward the other one. + let (gemini_opacity, external_opacity) = match ( + runtime.antigravity_gemini_enabled, + runtime.antigravity_external_enabled, + ) { + (false, true) => (external_opacity, gemini_opacity), + (false, false) => (0.0, 0.0), + _ => (gemini_opacity, external_opacity), + }; + context.insert("antigravity.gemini.opacity", gemini_opacity); + context.insert("antigravity.external.opacity", external_opacity); + context.insert("claude.hovered", runtime.claude_hovered as u8 as f64); + let claude_crossfade = runtime.claude_crossfade_opacity.clamp(0.0, 1.0); + context.insert("claude.crossfade_opacity", claude_crossfade); + context.insert("claude.normal.opacity", 1.0 - claude_crossfade); + context.insert("claude.hover.opacity", claude_crossfade); + context.insert( + "claude.main.enabled", + runtime.claude_main_enabled as u8 as f64, + ); + context.insert("claude.x.enabled", runtime.claude_x_enabled as u8 as f64); + context.insert( + "claude.dual_mode", + (runtime.claude_main_enabled && runtime.claude_x_enabled) as u8 as f64, + ); + context.insert("codex.hovered", runtime.codex_hovered as u8 as f64); + let codex_crossfade = runtime.codex_crossfade_opacity.clamp(0.0, 1.0); + context.insert("codex.crossfade_opacity", codex_crossfade); + context.insert("codex.normal.opacity", 1.0 - codex_crossfade); + context.insert("codex.hover.opacity", codex_crossfade); context.insert( - "antigravity.crossfade_opacity", - runtime.crossfade_opacity.clamp(0.0, 1.0), + "codex.main.enabled", + runtime.codex_main_enabled as u8 as f64, + ); + context.insert("codex.x.enabled", runtime.codex_x_enabled as u8 as f64); + context.insert( + "codex.dual_mode", + (runtime.codex_main_enabled && runtime.codex_x_enabled) as u8 as f64, ); if let Some(data) = data { for account in &data.accounts { @@ -1579,6 +1704,58 @@ impl DataContext { runtime.countdown, ); } + if !data + .accounts + .iter() + .any(|a| a.provider == ProviderId::Claude && a.profile.id == "default") + { + let claude_usage = data.get(ProviderId::Claude); + context.insert_provider( + "accounts.claude.default", + claude_usage, + false, + runtime.countdown, + ); + } + if !data + .accounts + .iter() + .any(|a| a.provider == ProviderId::Claude && a.profile.id == "claude_x") + { + let claude_usage = data.get(ProviderId::Claude); + context.insert_provider( + "accounts.claude.claude_x", + claude_usage, + false, + runtime.countdown, + ); + } + if !data + .accounts + .iter() + .any(|a| a.provider == ProviderId::Codex && a.profile.id == "default") + { + let codex_usage = data.get(ProviderId::Codex); + context.insert_provider( + "accounts.codex.default", + codex_usage, + true, + runtime.countdown, + ); + } + if !data + .accounts + .iter() + .any(|a| a.provider == ProviderId::Codex && a.profile.id == "codex_x") + { + let codex_usage = data.get(ProviderId::Codex); + context.insert_provider( + "accounts.codex.codex_x", + codex_usage, + true, + runtime.countdown, + ); + } for descriptor in PROVIDER_DESCRIPTORS { if let Some(account) = data .accounts @@ -1738,6 +1915,40 @@ impl DataContext { display(weekly) }; self.insert(&format!("{name}.weekly.display"), shown_weekly); + // Pace: the share a window would have spent by now at an even rate. + // `expected_display` follows the countdown setting like `display`. + let five_hour_section = usage + .filter(|usage| usage.session.available) + .map(|usage| &usage.session); + let weekly_section = usage + .filter(|usage| usage.weekly.available) + .map(|usage| &usage.weekly); + let session_section = if use_codex_session_fallback { + weekly_section.map(|section| (section, WEEK)) + } else { + five_hour_section.map(|section| (section, FIVE_HOURS)) + }; + for (window, section) in [ + ("session", session_section), + ( + "five_hour", + five_hour_section.map(|section| (section, FIVE_HOURS)), + ), + ("weekly", weekly_section.map(|section| (section, WEEK))), + ] { + let expected = + section.and_then(|(section, length)| expected_used(section.resets_at?, length)); + self.insert( + &format!("{name}.{window}.expected_available"), + expected.is_some() as u8 as f64, + ); + let expected = expected.unwrap_or(0.0); + self.insert(&format!("{name}.{window}.expected"), expected); + self.insert( + &format!("{name}.{window}.expected_display"), + display(expected), + ); + } let monthly = usage.and_then(|usage| usage.monthly.as_ref()); self.insert_string(&format!("{name}.monthly.label"), "30d"); if let Some(monthly) = monthly { diff --git a/src/theme_engine/tests.rs b/src/theme_engine/tests.rs index 7b71480a..3dde4812 100644 --- a/src/theme_engine/tests.rs +++ b/src/theme_engine/tests.rs @@ -3449,12 +3449,60 @@ fn compact_fluent_quad_antigravity_dual_and_solo_modes() { assert!(find_render("antigravity-session-gemini-solo-dark")); assert!(!find_render("antigravity-session-external-solo-dark")); - assert!(!find_render("antigravity-session-gemini-dual-dark")); - assert!(!find_render("antigravity-session-external-dual-dark")); + assert!(!find_render("antigravity-gemini-5h-dark-normal")); + assert!(!find_render("antigravity-gemini-5h-dark-hover")); + assert!(!find_render("antigravity-external-5h-dark-normal")); + assert!(!find_render("antigravity-external-5h-dark-hover")); assert!(find_render("antigravity-session-gemini-value-dark")); assert!(!find_render("antigravity-session-external-value-dark")); } + // 1b. Solo Gemini while hovered: the hidden external pool fades in + { + let runtime = + ThemeRuntime::from_providers(ProviderSet::from_enabled([ProviderId::Antigravity])) + .with_antigravity_pools(true, false, 0.0); + let mut context = + DataContext::from_usage_with_runtime(Some(&usage), &Canvas::default(), runtime); + context.insert("system.dark", 1.0); + let find_render = |id: &str| { + theme.surfaces[0] + .children + .iter() + .find(|o| o.id == id) + .map(|o| evaluate(&o.render.0, &context).unwrap() != 0.0) + .unwrap_or(false) + }; + assert!(!find_render("antigravity-session-gemini-solo-dark")); + assert!(find_render("antigravity-session-external-solo-dark")); + assert!(!find_render("antigravity-gemini-5h-dark-normal")); + assert!(!find_render("antigravity-gemini-5h-dark-hover")); + assert!(!find_render("antigravity-external-5h-dark-normal")); + assert!(!find_render("antigravity-external-5h-dark-hover")); + assert!(find_render("antigravity-session-external-value-dark")); + assert_eq!( + evaluate("antigravity.external.opacity", &context).unwrap(), + 1.0 + ); + } + + // 1c. Solo External while hovered: Gemini fades in + { + let runtime = + ThemeRuntime::from_providers(ProviderSet::from_enabled([ProviderId::Antigravity])) + .with_antigravity_pools(false, true, 0.0); + let context = + DataContext::from_usage_with_runtime(Some(&usage), &Canvas::default(), runtime); + assert_eq!( + evaluate("antigravity.gemini.opacity", &context).unwrap(), + 1.0 + ); + assert_eq!( + evaluate("antigravity.external.opacity", &context).unwrap(), + 0.0 + ); + } + // 2. Solo External { let runtime = @@ -3484,15 +3532,17 @@ fn compact_fluent_quad_antigravity_dual_and_solo_modes() { assert!(!find_render("antigravity-session-gemini-solo-dark")); assert!(find_render("antigravity-session-external-solo-dark")); - assert!(!find_render("antigravity-session-gemini-dual-dark")); - assert!(!find_render("antigravity-session-external-dual-dark")); + assert!(!find_render("antigravity-gemini-5h-dark-normal")); + assert!(!find_render("antigravity-gemini-5h-dark-hover")); + assert!(!find_render("antigravity-external-5h-dark-normal")); + assert!(!find_render("antigravity-external-5h-dark-hover")); assert!(!find_render("antigravity-session-gemini-value-dark")); assert!(find_render("antigravity-session-external-value-dark")); } - // 3. Dual Mode Crossfade + // 3. Dual Mode Crossfade (Variant A) { - // At opacity 1.0 (Gemini holding) + // At opacity 1.0 (Normal: Gemini 6px, External 3px, Gemini text) let runtime = ThemeRuntime::from_providers(ProviderSet::from_enabled([ProviderId::Antigravity])) .with_antigravity_pools(true, true, 1.0); @@ -3512,30 +3562,20 @@ fn compact_fluent_quad_antigravity_dual_and_solo_modes() { assert!(!find_render("antigravity-session-gemini-solo-dark")); assert!(!find_render("antigravity-session-external-solo-dark")); - assert!(find_render("antigravity-session-gemini-dual-dark")); - assert!(find_render("antigravity-session-external-dual-dark")); - assert!(find_render("antigravity-session-gemini-value-dark")); - assert!(!find_render("antigravity-session-external-value-dark")); - - // At opacity 0.5 (Mid-transition) - let runtime_mid = - ThemeRuntime::from_providers(ProviderSet::from_enabled([ProviderId::Antigravity])) - .with_antigravity_pools(true, true, 0.5); - let mut context_mid = - DataContext::from_usage_with_runtime(Some(&usage), &Canvas::default(), runtime_mid); - context_mid.insert("system.dark", 1.0); - let find_render_mid = |id: &str| { - theme.surfaces[0] - .children - .iter() - .find(|o| o.id == id) - .map(|o| evaluate(&o.render.0, &context_mid).unwrap() != 0.0) - .unwrap_or(false) - }; - assert!(find_render_mid("antigravity-session-gemini-value-dark")); - assert!(find_render_mid("antigravity-session-external-value-dark")); - - // At opacity 0.0 (External holding) + assert!(find_render("antigravity-gemini-5h-dark-normal")); + assert!(find_render("antigravity-gemini-weekly-dark-normal")); + assert!(find_render("antigravity-external-5h-dark-normal")); + assert!(find_render("antigravity-external-weekly-dark-normal")); + assert!(!find_render("antigravity-gemini-5h-dark-hover")); + assert!(!find_render("antigravity-gemini-weekly-dark-hover")); + assert!(!find_render("antigravity-external-5h-dark-hover")); + assert!(!find_render("antigravity-external-weekly-dark-hover")); + assert!(find_render("antigravity-gemini-text-dark-normal")); + assert!(!find_render("antigravity-gemini-text-dark-hover")); + assert!(find_render("antigravity-external-text-dark-normal")); + assert!(!find_render("antigravity-external-text-dark-hover")); + + // At opacity 0.0 (Hover: Gemini 3px, External 6px, External text) let runtime_ext = ThemeRuntime::from_providers(ProviderSet::from_enabled([ProviderId::Antigravity])) .with_antigravity_pools(true, true, 0.0); @@ -3550,8 +3590,18 @@ fn compact_fluent_quad_antigravity_dual_and_solo_modes() { .map(|o| evaluate(&o.render.0, &context_ext).unwrap() != 0.0) .unwrap_or(false) }; - assert!(!find_render_ext("antigravity-session-gemini-value-dark")); - assert!(find_render_ext("antigravity-session-external-value-dark")); + assert!(!find_render_ext("antigravity-gemini-5h-dark-normal")); + assert!(!find_render_ext("antigravity-gemini-weekly-dark-normal")); + assert!(!find_render_ext("antigravity-external-5h-dark-normal")); + assert!(!find_render_ext("antigravity-external-weekly-dark-normal")); + assert!(find_render_ext("antigravity-gemini-5h-dark-hover")); + assert!(find_render_ext("antigravity-gemini-weekly-dark-hover")); + assert!(find_render_ext("antigravity-external-5h-dark-hover")); + assert!(find_render_ext("antigravity-external-weekly-dark-hover")); + assert!(!find_render_ext("antigravity-gemini-text-dark-normal")); + assert!(find_render_ext("antigravity-gemini-text-dark-hover")); + assert!(!find_render_ext("antigravity-external-text-dark-normal")); + assert!(find_render_ext("antigravity-external-text-dark-hover")); } } @@ -3581,3 +3631,290 @@ fn missing_antigravity_external_pool_draws_an_empty_gauge() { assert_eq!(value("antigravity.gemini.weekly.display"), 0.0); assert_eq!(value("antigravity.external.session.display"), 0.0); } + +#[test] +fn pace_expected_used_rejects_resets_outside_the_window() { + use std::time::{Duration, SystemTime}; + + let now = SystemTime::now(); + for length in [FIVE_HOURS, WEEK] { + let half = expected_used(now + length / 2, length).unwrap(); + assert!((half - 50.0).abs() < 0.1, "{half}"); + assert_eq!(expected_used(SystemTime::UNIX_EPOCH, length), None); + // A reset reported slightly past the window start still ticks at 0. + assert_eq!( + expected_used(now + length + Duration::from_secs(30), length), + Some(0.0) + ); + assert_eq!( + expected_used(now + length + Duration::from_secs(300), length), + None + ); + } + assert_eq!(expected_used(now + FIVE_HOURS, Duration::ZERO), None); +} + +#[test] +fn pace_bindings_follow_elapsed_time_and_countdown_for_each_pool() { + use crate::models::{UsageData, UsageSection}; + use std::time::{Duration, SystemTime}; + + let now = SystemTime::now(); + let section = |length: Duration, elapsed_quarters: u32| UsageSection { + available: true, + percentage: 90.0, + resets_at: Some(now + length * (4 - elapsed_quarters) / 4), + }; + for elapsed_quarters in [1, 2] { + let provider_usage = UsageData { + session: section(FIVE_HOURS, elapsed_quarters), + weekly: section(WEEK, elapsed_quarters), + external_pool: Some(Box::new(UsageData { + session: section(FIVE_HOURS, 4 - elapsed_quarters), + weekly: section(WEEK, 4 - elapsed_quarters), + ..Default::default() + })), + ..Default::default() + }; + let usage = AppUsageData::from_iter( + [ + ProviderId::Claude, + ProviderId::Codex, + ProviderId::Antigravity, + ] + .into_iter() + .map(|provider| (provider, provider_usage.clone())), + ); + for countdown in [false, true] { + let context = DataContext::from_usage_with_runtime( + Some(&usage), + &Canvas::default(), + ThemeRuntime::default().with_countdown(countdown), + ); + for name in [ + "claude", + "codex", + "antigravity.gemini", + "antigravity.external", + ] { + let expected = if name == "antigravity.external" { + (4 - elapsed_quarters) as f64 * 25.0 + } else { + elapsed_quarters as f64 * 25.0 + }; + for window in ["session", "five_hour", "weekly"] { + let base = format!("{name}.{window}"); + assert_eq!( + context.get(&format!("{base}.expected_available")), + Some(1.0) + ); + let used = context.get(&format!("{base}.expected")).unwrap(); + let display = context.get(&format!("{base}.expected_display")).unwrap(); + assert!((used - expected).abs() < 0.1, "{base}: {used}"); + assert!( + (display + - if countdown { + 100.0 - expected + } else { + expected + }) + .abs() + < 0.1, + "{base}: {display}" + ); + } + } + } + } +} + +#[test] +fn pace_bindings_hide_missing_windows_and_reset_times() { + use crate::models::{UsageData, UsageSection}; + use std::time::{Duration, SystemTime}; + + let now = SystemTime::now(); + for countdown in [false, true] { + for (available, resets_at) in [ + (true, None), + (false, Some(now + Duration::from_secs(60))), + (true, Some(SystemTime::UNIX_EPOCH)), + (true, Some(now + WEEK + Duration::from_secs(300))), + ] { + let section = UsageSection { + available, + percentage: 25.0, + resets_at, + }; + let usage = UsageData { + session: section.clone(), + weekly: section, + ..Default::default() + }; + let mut context = DataContext::default(); + for data in [None, Some(&usage)] { + context.insert_provider("claude", data, false, countdown); + for window in ["session", "five_hour", "weekly"] { + assert_eq!( + context.get(&format!("claude.{window}.expected_available")), + Some(0.0) + ); + assert_eq!(context.get(&format!("claude.{window}.expected")), Some(0.0)); + } + } + } + } +} + +#[test] +fn show_pace_binding_follows_the_setting() { + let defaults = crate::app_settings::SettingsFile::default(); + assert!(defaults.show_pace); + let context = DataContext::from_usage(None, &Canvas::default()); + assert_eq!(context.get("display.show_pace"), Some(1.0)); + for show_pace in [false, true] { + let mut settings = crate::app_settings::SettingsFile::default(); + settings.show_pace = show_pace; + let runtime = ThemeRuntime::from_providers(settings.enabled_providers()) + .with_show_pace(settings.show_pace); + let context = DataContext::from_usage_with_runtime(None, &Canvas::default(), runtime); + assert_eq!( + context.get("display.show_pace"), + Some(show_pace as u8 as f64) + ); + } +} + +#[test] +fn compact_pace_ticks_validate_and_stay_inside_their_gauges() { + let theme: ThemeDocument = + serde_json::from_str(include_str!("../themes/compact-fluent-quad.json")).unwrap(); + assert!(theme.validate().is_empty(), "{:?}", theme.validate()); + let children = &theme.surfaces[0].children; + for window in ["session", "weekly"] { + assert!(children + .iter() + .any(|object| object.id == format!("claude-{window}-segments-dark-pace"))); + } + let ticks = children + .iter() + .enumerate() + .filter(|(_, object)| object.id.ends_with("-pace")) + .collect::>(); + assert_eq!(ticks.len(), 64); + for (index, tick) in ticks { + let gauge = &children[index - 1]; + assert_eq!(tick.id, format!("{}-pace", gauge.id)); + assert!(matches!(&gauge.content, SceneContent::Progress { .. })); + assert!(matches!(&tick.content, SceneContent::None)); + assert_eq!(tick.parent, gauge.parent); + assert_eq!(tick.render.0, gauge.render.0); + let stripped = tick.visibility.0.strip_prefix("(100) * ").unwrap(); + let stripped = stripped + .strip_suffix(" * antigravity.gemini.opacity") + .or_else(|| stripped.strip_suffix(" * antigravity.external.opacity")) + .or_else(|| stripped.strip_suffix(" * antigravity.normal.opacity")) + .or_else(|| stripped.strip_suffix(" * antigravity.hover.opacity")) + .or_else(|| stripped.strip_suffix(" * claude.normal.opacity")) + .or_else(|| stripped.strip_suffix(" * claude.hover.opacity")) + .or_else(|| stripped.strip_suffix(" * codex.normal.opacity")) + .or_else(|| stripped.strip_suffix(" * codex.hover.opacity")) + .unwrap_or(stripped); + let binding = stripped + .strip_suffix(".expected_available * display.show_pace") + .unwrap(); + let LayerBackground::Colour { colour } = &tick.background else { + panic!("{} must have a colour background", tick.id); + }; + assert!(parse_color(&colour.color).is_some()); + let expected_colour = if tick.id.ends_with("-dark-pace") || tick.id.contains("-dark-") { + "#FFFFFFFF" + } else { + "#1A1A1AFF" + }; + assert_eq!(colour.color, expected_colour); + let mut context = DataContext::from_usage(None, &Canvas::default()); + context.insert("antigravity.gemini.opacity", 1.0); + context.insert("antigravity.external.opacity", 1.0); + context.insert("antigravity.normal.opacity", 1.0); + context.insert("antigravity.hover.opacity", 1.0); + context.insert("claude.normal.opacity", 1.0); + context.insert("claude.hover.opacity", 1.0); + context.insert("codex.normal.opacity", 1.0); + context.insert("codex.hover.opacity", 1.0); + for count in 1..=ProviderId::ALL.len() { + context.insert("providers.count", count as f64); + let start = evaluate(&gauge.x.0, &context).unwrap(); + let end = start + evaluate(&gauge.width.0, &context).unwrap(); + assert_eq!(evaluate(&tick.width.0, &context).unwrap(), 1.0); + assert_eq!( + evaluate(&tick.y.0, &context).unwrap(), + evaluate(&gauge.y.0, &context).unwrap() - 1.0 + ); + assert_eq!( + evaluate(&tick.height.0, &context).unwrap(), + evaluate(&gauge.height.0, &context).unwrap() + 2.0 + ); + assert_eq!(evaluate(&colour.opacity.0, &context).unwrap(), 0.9); + for available in [0.0, 1.0] { + context.insert(&format!("{binding}.expected_available"), available); + for show_pace in [0.0, 1.0] { + context.insert("display.show_pace", show_pace); + assert_eq!( + evaluate(&tick.visibility.0, &context).unwrap(), + available * show_pace * 100.0 + ); + } + } + for expected in [-10.0, 0.0, 0.1, 25.0, 50.0, 99.9, 100.0, 110.0] { + context.insert(&format!("{binding}.expected_display"), expected); + let x = evaluate(&tick.x.0, &context).unwrap(); + assert!(x >= start && x + 1.0 <= end, "{}: {x}", tick.id); + assert_eq!(x.fract(), 0.0); + if expected <= 0.0 { + assert_eq!(x, start); + } else if expected >= 100.0 { + assert_eq!(x + 1.0, end); + } + } + } + } +} + +#[test] +fn claude_dual_mode_and_crossfade_context_variables() { + let runtime = ThemeRuntime::default().with_claude_state(true, true, true, 0.75); + let canvas = Canvas::default(); + let ctx = DataContext::from_usage_with_runtime(None, &canvas, runtime); + assert_eq!(ctx.get("claude.hovered"), Some(1.0)); + assert_eq!(ctx.get("claude.main.enabled"), Some(1.0)); + assert_eq!(ctx.get("claude.x.enabled"), Some(1.0)); + assert_eq!(ctx.get("claude.dual_mode"), Some(1.0)); + assert_eq!(ctx.get("claude.crossfade_opacity"), Some(0.75)); + assert_eq!(ctx.get("claude.normal.opacity"), Some(0.25)); + assert_eq!(ctx.get("claude.hover.opacity"), Some(0.75)); +} + +#[test] +fn antigravity_normal_and_hover_opacity_context_variables() { + let runtime = ThemeRuntime::default().with_antigravity_pools(true, true, 0.3); + let canvas = Canvas::default(); + let ctx = DataContext::from_usage_with_runtime(None, &canvas, runtime); + assert_eq!(ctx.get("antigravity.crossfade_opacity"), Some(0.3)); + assert_eq!(ctx.get("antigravity.normal.opacity"), Some(0.3)); + assert_eq!(ctx.get("antigravity.hover.opacity"), Some(0.7)); +} + +#[test] +fn codex_dual_mode_and_crossfade_context_variables() { + let runtime = ThemeRuntime::default().with_codex_state(true, true, true, 0.75); + let canvas = Canvas::default(); + let ctx = DataContext::from_usage_with_runtime(None, &canvas, runtime); + assert_eq!(ctx.get("codex.hovered"), Some(1.0)); + assert_eq!(ctx.get("codex.main.enabled"), Some(1.0)); + assert_eq!(ctx.get("codex.x.enabled"), Some(1.0)); + assert_eq!(ctx.get("codex.dual_mode"), Some(1.0)); + assert_eq!(ctx.get("codex.crossfade_opacity"), Some(0.75)); + assert_eq!(ctx.get("codex.normal.opacity"), Some(0.25)); + assert_eq!(ctx.get("codex.hover.opacity"), Some(0.75)); +} diff --git a/src/theme_engine/theme_rendering.rs b/src/theme_engine/theme_rendering.rs index f5420b29..a5f54702 100644 --- a/src/theme_engine/theme_rendering.rs +++ b/src/theme_engine/theme_rendering.rs @@ -359,6 +359,35 @@ pub(super) fn resolve_objects_for<'a>( /// Return the topmost interactive layer at a logical canvas point. Non- /// interactive layers intentionally do not block layers beneath them, which /// lets visual decoration sit above a larger deliberate hit area. +/// Returns the rendered bounding box `(x, y, width, height)` of `object_id` on the given surface +/// in canvas logical coordinates (including horizontal surface padding), or `None` if not rendered. +pub fn object_bounds( + theme: &ThemeDocument, + surface_index: usize, + data: Option<&AppUsageData>, + runtime: ThemeRuntime, + object_id: &str, +) -> Option<(f64, f64, f64, f64)> { + let surface = theme.surfaces.get(surface_index)?; + if !surface_should_render(theme, surface_index, data, runtime) { + return None; + } + let (width, height) = resolve_object_size(surface, data, runtime, &mut Vec::new()); + let padding = surface_horizontal_padding(theme, surface_index, runtime) as f64; + let canvas = Canvas { + width, + width_expression: Some(surface.width.clone()), + height, + height_expression: Some(surface.height.clone()), + background: surface.background.canvas_paint(), + }; + let (resolved, _) = resolve_objects_for(surface, &canvas, &surface.children, data, runtime); + resolved + .into_iter() + .find(|object| object.source.id == object_id && object.width > 0.0 && object.height > 0.0) + .map(|object| (object.x + padding, object.y, object.width, object.height)) +} + pub fn hit_test_mouse_event( theme: &ThemeDocument, surface_index: usize, diff --git a/src/themes/compact-fluent-quad.json b/src/themes/compact-fluent-quad.json index 55250224..3c534798 100644 --- a/src/themes/compact-fluent-quad.json +++ b/src/themes/compact-fluent-quad.json @@ -21,7 +21,7 @@ "offset_x": 6, "offset_y": 0 }, - "width": "providers.count * (ceil(10 / max(1, providers.count)) * 11 - 1 + 4 + 62) + max(0, providers.count - 1) * 6 + providers.opencode.enabled * 28 + providers.cursor.enabled * 18 + providers.claude.enabled * claude.model.fable.available * 96", + "width": "providers.count * (ceil(10 / max(1, providers.count)) * 11 - 1 + 4 + 62) + max(0, providers.count - 1) * 6 + providers.opencode.enabled * 28 + providers.cursor.enabled * 18 + providers.claude.enabled * claude.model.fable.available * 96 + providers.codex.enabled * codex.dual_mode * 12 + providers.claude.enabled * claude.dual_mode * 12", "height": "46", "background": { "type": "none" @@ -64,7 +64,7 @@ "render": "system.dark", "visibility": "100", "parent": "cursor-provider", - "y": "11", + "y": "10", "width": "ceil(10 / max(1, providers.count)) * 11 - 1", "height": "9", "background": { @@ -100,7 +100,7 @@ "visibility": "100", "parent": "cursor-provider", "x": "ceil(10 / max(1, providers.count)) * 11 - 1 + 4", - "y": "9", + "y": "8", "width": "80", "height": "13", "background": { @@ -132,7 +132,7 @@ "render": "1 - system.dark", "visibility": "100", "parent": "cursor-provider", - "y": "11", + "y": "10", "width": "ceil(10 / max(1, providers.count)) * 11 - 1", "height": "9", "background": { @@ -168,7 +168,7 @@ "visibility": "100", "parent": "cursor-provider", "x": "ceil(10 / max(1, providers.count)) * 11 - 1 + 4", - "y": "9", + "y": "8", "width": "80", "height": "13", "background": { @@ -356,7 +356,7 @@ "render": "providers.claude.enabled", "visibility": "100", "parent": "provider-row", - "width": "ceil(10 / max(1, providers.count)) * 11 - 1 + 4 + 62", + "width": "ceil(10 / max(1, providers.count)) * 11 - 1 + 4 + 62 + (claude.dual_mode * 12)", "height": "46", "background": { "type": "none" @@ -373,10 +373,10 @@ { "id": "claude-session-segments-dark", "name": "dark Claude Code 5-hour segments", - "render": "system.dark", + "render": "(system.dark) && (!claude.dual_mode)", "visibility": "100", "parent": "claude-provider", - "y": "11", + "y": "10", "width": "ceil(10 / max(1, providers.count)) * 11 - 1", "height": "9", "background": { @@ -405,14 +405,40 @@ "segment_gap": "1" } }, + { + "id": "claude-session-segments-dark-pace", + "name": "dark Claude Code 5-hour segments pace tick", + "render": "(system.dark) && (!claude.dual_mode)", + "visibility": "(100) * claude.session.expected_available * display.show_pace", + "parent": "claude-provider", + "x": "round((ceil(10 / max(1, providers.count)) * 11 - 2) * clamp(claude.session.expected_display, 0, 100) / 100)", + "y": "(10) - 1", + "width": "1", + "height": "(9) + 2", + "background": { + "type": "colour", + "colour": { + "color": "#FFFFFFFF", + "opacity": "0.9" + } + }, + "border": null, + "corner_radius": "0", + "layout": "freeform", + "align": "start", + "gap": "0", + "content": { + "type": "none" + } + }, { "id": "claude-session-value-dark", "name": "dark Claude Code 5-hour value", - "render": "system.dark", + "render": "(system.dark) && (!claude.dual_mode)", "visibility": "100", "parent": "claude-provider", "x": "ceil(10 / max(1, providers.count)) * 11 - 1 + 4", - "y": "9", + "y": "8", "width": "62", "height": "13", "background": { @@ -441,10 +467,10 @@ { "id": "claude-session-segments-light", "name": "light Claude Code 5-hour segments", - "render": "1 - system.dark", + "render": "(1 - system.dark) && (!claude.dual_mode)", "visibility": "100", "parent": "claude-provider", - "y": "11", + "y": "10", "width": "ceil(10 / max(1, providers.count)) * 11 - 1", "height": "9", "background": { @@ -473,14 +499,40 @@ "segment_gap": "1" } }, + { + "id": "claude-session-segments-light-pace", + "name": "light Claude Code 5-hour segments pace tick", + "render": "(1 - system.dark) && (!claude.dual_mode)", + "visibility": "(100) * claude.session.expected_available * display.show_pace", + "parent": "claude-provider", + "x": "round((ceil(10 / max(1, providers.count)) * 11 - 2) * clamp(claude.session.expected_display, 0, 100) / 100)", + "y": "(10) - 1", + "width": "1", + "height": "(9) + 2", + "background": { + "type": "colour", + "colour": { + "color": "#1A1A1AFF", + "opacity": "0.9" + } + }, + "border": null, + "corner_radius": "0", + "layout": "freeform", + "align": "start", + "gap": "0", + "content": { + "type": "none" + } + }, { "id": "claude-session-value-light", "name": "light Claude Code 5-hour value", - "render": "1 - system.dark", + "render": "(1 - system.dark) && (!claude.dual_mode)", "visibility": "100", "parent": "claude-provider", "x": "ceil(10 / max(1, providers.count)) * 11 - 1 + 4", - "y": "9", + "y": "8", "width": "62", "height": "13", "background": { @@ -509,7 +561,7 @@ { "id": "claude-weekly-segments-dark", "name": "dark Claude Code 7-day segments", - "render": "system.dark", + "render": "(system.dark) && (!claude.dual_mode)", "visibility": "100", "parent": "claude-provider", "y": "27", @@ -541,10 +593,36 @@ "segment_gap": "1" } }, + { + "id": "claude-weekly-segments-dark-pace", + "name": "dark Claude Code 7-day segments pace tick", + "render": "(system.dark) && (!claude.dual_mode)", + "visibility": "(100) * claude.weekly.expected_available * display.show_pace", + "parent": "claude-provider", + "x": "round((ceil(10 / max(1, providers.count)) * 11 - 2) * clamp(claude.weekly.expected_display, 0, 100) / 100)", + "y": "(27) - 1", + "width": "1", + "height": "(9) + 2", + "background": { + "type": "colour", + "colour": { + "color": "#FFFFFFFF", + "opacity": "0.9" + } + }, + "border": null, + "corner_radius": "0", + "layout": "freeform", + "align": "start", + "gap": "0", + "content": { + "type": "none" + } + }, { "id": "claude-weekly-value-dark", "name": "dark Claude Code 7-day value", - "render": "(system.dark) && !claude.credits.available", + "render": "((system.dark) && !claude.credits.available) && (!claude.dual_mode)", "visibility": "100", "parent": "claude-provider", "x": "ceil(10 / max(1, providers.count)) * 11 - 1 + 4", @@ -577,7 +655,7 @@ { "id": "claude-weekly-segments-light", "name": "light Claude Code 7-day segments", - "render": "1 - system.dark", + "render": "(1 - system.dark) && (!claude.dual_mode)", "visibility": "100", "parent": "claude-provider", "y": "27", @@ -609,10 +687,36 @@ "segment_gap": "1" } }, + { + "id": "claude-weekly-segments-light-pace", + "name": "light Claude Code 7-day segments pace tick", + "render": "(1 - system.dark) && (!claude.dual_mode)", + "visibility": "(100) * claude.weekly.expected_available * display.show_pace", + "parent": "claude-provider", + "x": "round((ceil(10 / max(1, providers.count)) * 11 - 2) * clamp(claude.weekly.expected_display, 0, 100) / 100)", + "y": "(27) - 1", + "width": "1", + "height": "(9) + 2", + "background": { + "type": "colour", + "colour": { + "color": "#1A1A1AFF", + "opacity": "0.9" + } + }, + "border": null, + "corner_radius": "0", + "layout": "freeform", + "align": "start", + "gap": "0", + "content": { + "type": "none" + } + }, { "id": "claude-weekly-value-light", "name": "light Claude Code 7-day value", - "render": "(1 - system.dark) && !claude.credits.available", + "render": "((1 - system.dark) && !claude.credits.available) && (!claude.dual_mode)", "visibility": "100", "parent": "claude-provider", "x": "ceil(10 / max(1, providers.count)) * 11 - 1 + 4", @@ -668,7 +772,7 @@ "render": "system.dark", "visibility": "100", "parent": "fable-provider", - "y": "11", + "y": "10", "width": "floor((90 + 1) / 11) * 11 - 1", "height": "9", "background": { @@ -735,7 +839,7 @@ "render": "1 - system.dark", "visibility": "100", "parent": "fable-provider", - "y": "11", + "y": "10", "width": "floor((90 + 1) / 11) * 11 - 1", "height": "9", "background": { @@ -802,7 +906,7 @@ "render": "providers.codex.enabled", "visibility": "100", "parent": "provider-row", - "width": "ceil(10 / max(1, providers.count)) * 11 - 1 + 4 + 62", + "width": "ceil(10 / max(1, providers.count)) * 11 - 1 + 4 + 62 + (codex.dual_mode * 12)", "height": "46", "background": { "type": "none" @@ -819,10 +923,10 @@ { "id": "codex-session-segments-dark", "name": "dark Codex 5-hour segments", - "render": "system.dark", + "render": "(system.dark) && (!codex.dual_mode)", "visibility": "100", "parent": "codex-provider", - "y": "11", + "y": "10", "width": "ceil(10 / max(1, providers.count)) * 11 - 1", "height": "9", "background": { @@ -851,14 +955,40 @@ "segment_gap": "1" } }, + { + "id": "codex-session-segments-dark-pace", + "name": "dark Codex 5-hour segments pace tick", + "render": "(system.dark) && (!codex.dual_mode)", + "visibility": "(100) * codex.five_hour.expected_available * display.show_pace", + "parent": "codex-provider", + "x": "round((ceil(10 / max(1, providers.count)) * 11 - 2) * clamp(codex.five_hour.expected_display, 0, 100) / 100)", + "y": "(10) - 1", + "width": "1", + "height": "(9) + 2", + "background": { + "type": "colour", + "colour": { + "color": "#FFFFFFFF", + "opacity": "0.9" + } + }, + "border": null, + "corner_radius": "0", + "layout": "freeform", + "align": "start", + "gap": "0", + "content": { + "type": "none" + } + }, { "id": "codex-session-value-dark", "name": "dark Codex 5-hour value", - "render": "system.dark", + "render": "(system.dark) && (!codex.dual_mode)", "visibility": "100", "parent": "codex-provider", "x": "ceil(10 / max(1, providers.count)) * 11 - 1 + 4", - "y": "9", + "y": "8", "width": "62", "height": "13", "background": { @@ -887,10 +1017,10 @@ { "id": "codex-session-segments-light", "name": "light Codex 5-hour segments", - "render": "1 - system.dark", + "render": "(1 - system.dark) && (!codex.dual_mode)", "visibility": "100", "parent": "codex-provider", - "y": "11", + "y": "10", "width": "ceil(10 / max(1, providers.count)) * 11 - 1", "height": "9", "background": { @@ -919,14 +1049,40 @@ "segment_gap": "1" } }, + { + "id": "codex-session-segments-light-pace", + "name": "light Codex 5-hour segments pace tick", + "render": "(1 - system.dark) && (!codex.dual_mode)", + "visibility": "(100) * codex.five_hour.expected_available * display.show_pace", + "parent": "codex-provider", + "x": "round((ceil(10 / max(1, providers.count)) * 11 - 2) * clamp(codex.five_hour.expected_display, 0, 100) / 100)", + "y": "(10) - 1", + "width": "1", + "height": "(9) + 2", + "background": { + "type": "colour", + "colour": { + "color": "#1A1A1AFF", + "opacity": "0.9" + } + }, + "border": null, + "corner_radius": "0", + "layout": "freeform", + "align": "start", + "gap": "0", + "content": { + "type": "none" + } + }, { "id": "codex-session-value-light", "name": "light Codex 5-hour value", - "render": "1 - system.dark", + "render": "(1 - system.dark) && (!codex.dual_mode)", "visibility": "100", "parent": "codex-provider", "x": "ceil(10 / max(1, providers.count)) * 11 - 1 + 4", - "y": "9", + "y": "8", "width": "62", "height": "13", "background": { @@ -955,7 +1111,7 @@ { "id": "codex-weekly-segments-dark", "name": "dark Codex 7-day segments", - "render": "system.dark", + "render": "(system.dark) && (!codex.dual_mode)", "visibility": "100", "parent": "codex-provider", "y": "27", @@ -987,10 +1143,36 @@ "segment_gap": "1" } }, + { + "id": "codex-weekly-segments-dark-pace", + "name": "dark Codex 7-day segments pace tick", + "render": "(system.dark) && (!codex.dual_mode)", + "visibility": "(100) * codex.weekly.expected_available * display.show_pace", + "parent": "codex-provider", + "x": "round((ceil(10 / max(1, providers.count)) * 11 - 2) * clamp(codex.weekly.expected_display, 0, 100) / 100)", + "y": "(27) - 1", + "width": "1", + "height": "(9) + 2", + "background": { + "type": "colour", + "colour": { + "color": "#FFFFFFFF", + "opacity": "0.9" + } + }, + "border": null, + "corner_radius": "0", + "layout": "freeform", + "align": "start", + "gap": "0", + "content": { + "type": "none" + } + }, { "id": "codex-weekly-value-dark", "name": "dark Codex 7-day value", - "render": "(system.dark) && !codex.credits.available", + "render": "((system.dark) && !codex.credits.available) && (!codex.dual_mode)", "visibility": "100", "parent": "codex-provider", "x": "ceil(10 / max(1, providers.count)) * 11 - 1 + 4", @@ -1023,7 +1205,7 @@ { "id": "codex-weekly-segments-light", "name": "light Codex 7-day segments", - "render": "1 - system.dark", + "render": "(1 - system.dark) && (!codex.dual_mode)", "visibility": "100", "parent": "codex-provider", "y": "27", @@ -1055,10 +1237,36 @@ "segment_gap": "1" } }, + { + "id": "codex-weekly-segments-light-pace", + "name": "light Codex 7-day segments pace tick", + "render": "(1 - system.dark) && (!codex.dual_mode)", + "visibility": "(100) * codex.weekly.expected_available * display.show_pace", + "parent": "codex-provider", + "x": "round((ceil(10 / max(1, providers.count)) * 11 - 2) * clamp(codex.weekly.expected_display, 0, 100) / 100)", + "y": "(27) - 1", + "width": "1", + "height": "(9) + 2", + "background": { + "type": "colour", + "colour": { + "color": "#1A1A1AFF", + "opacity": "0.9" + } + }, + "border": null, + "corner_radius": "0", + "layout": "freeform", + "align": "start", + "gap": "0", + "content": { + "type": "none" + } + }, { "id": "codex-weekly-value-light", "name": "light Codex 7-day value", - "render": "(1 - system.dark) && !codex.credits.available", + "render": "((1 - system.dark) && !codex.credits.available) && (!codex.dual_mode)", "visibility": "100", "parent": "codex-provider", "x": "ceil(10 / max(1, providers.count)) * 11 - 1 + 4", @@ -1111,10 +1319,10 @@ { "id": "antigravity-session-gemini-solo-dark", "name": "dark Antigravity Gemini solo session segments", - "render": "system.dark && antigravity.gemini.enabled && !antigravity.dual_mode", - "visibility": "100", + "render": "system.dark && !antigravity.dual_mode && antigravity.gemini.opacity > 0.01", + "visibility": "100 * antigravity.gemini.opacity", "parent": "antigravity-provider", - "y": "11", + "y": "10", "width": "ceil(10 / max(1, providers.count)) * 11 - 1", "height": "9", "background": { @@ -1143,13 +1351,39 @@ "segment_gap": "1" } }, + { + "id": "antigravity-session-gemini-solo-dark-pace", + "name": "dark Antigravity Gemini solo session segments pace tick", + "render": "system.dark && !antigravity.dual_mode && antigravity.gemini.opacity > 0.01", + "visibility": "(100) * antigravity.gemini.session.expected_available * display.show_pace * antigravity.gemini.opacity", + "parent": "antigravity-provider", + "x": "round((ceil(10 / max(1, providers.count)) * 11 - 2) * clamp(antigravity.gemini.session.expected_display, 0, 100) / 100)", + "y": "(10) - 1", + "width": "1", + "height": "(9) + 2", + "background": { + "type": "colour", + "colour": { + "color": "#FFFFFFFF", + "opacity": "0.9" + } + }, + "border": null, + "corner_radius": "0", + "layout": "freeform", + "align": "start", + "gap": "0", + "content": { + "type": "none" + } + }, { "id": "antigravity-session-gemini-solo-light", "name": "light Antigravity Gemini solo session segments", - "render": "(1 - system.dark) && antigravity.gemini.enabled && !antigravity.dual_mode", - "visibility": "100", + "render": "(1 - system.dark) && !antigravity.dual_mode && antigravity.gemini.opacity > 0.01", + "visibility": "100 * antigravity.gemini.opacity", "parent": "antigravity-provider", - "y": "11", + "y": "10", "width": "ceil(10 / max(1, providers.count)) * 11 - 1", "height": "9", "background": { @@ -1178,13 +1412,39 @@ "segment_gap": "1" } }, + { + "id": "antigravity-session-gemini-solo-light-pace", + "name": "light Antigravity Gemini solo session segments pace tick", + "render": "(1 - system.dark) && !antigravity.dual_mode && antigravity.gemini.opacity > 0.01", + "visibility": "(100) * antigravity.gemini.session.expected_available * display.show_pace * antigravity.gemini.opacity", + "parent": "antigravity-provider", + "x": "round((ceil(10 / max(1, providers.count)) * 11 - 2) * clamp(antigravity.gemini.session.expected_display, 0, 100) / 100)", + "y": "(10) - 1", + "width": "1", + "height": "(9) + 2", + "background": { + "type": "colour", + "colour": { + "color": "#1A1A1AFF", + "opacity": "0.9" + } + }, + "border": null, + "corner_radius": "0", + "layout": "freeform", + "align": "start", + "gap": "0", + "content": { + "type": "none" + } + }, { "id": "antigravity-session-external-solo-dark", "name": "dark Antigravity External solo session segments", - "render": "system.dark && antigravity.external.enabled && !antigravity.dual_mode", - "visibility": "100", + "render": "system.dark && !antigravity.dual_mode && antigravity.external.opacity > 0.01", + "visibility": "100 * antigravity.external.opacity", "parent": "antigravity-provider", - "y": "11", + "y": "10", "width": "ceil(10 / max(1, providers.count)) * 11 - 1", "height": "9", "background": { @@ -1213,13 +1473,39 @@ "segment_gap": "1" } }, + { + "id": "antigravity-session-external-solo-dark-pace", + "name": "dark Antigravity External solo session segments pace tick", + "render": "system.dark && !antigravity.dual_mode && antigravity.external.opacity > 0.01", + "visibility": "(100) * antigravity.external.session.expected_available * display.show_pace * antigravity.external.opacity", + "parent": "antigravity-provider", + "x": "round((ceil(10 / max(1, providers.count)) * 11 - 2) * clamp(antigravity.external.session.expected_display, 0, 100) / 100)", + "y": "(10) - 1", + "width": "1", + "height": "(9) + 2", + "background": { + "type": "colour", + "colour": { + "color": "#FFFFFFFF", + "opacity": "0.9" + } + }, + "border": null, + "corner_radius": "0", + "layout": "freeform", + "align": "start", + "gap": "0", + "content": { + "type": "none" + } + }, { "id": "antigravity-session-external-solo-light", "name": "light Antigravity External solo session segments", - "render": "(1 - system.dark) && antigravity.external.enabled && !antigravity.dual_mode", - "visibility": "100", + "render": "(1 - system.dark) && !antigravity.dual_mode && antigravity.external.opacity > 0.01", + "visibility": "100 * antigravity.external.opacity", "parent": "antigravity-provider", - "y": "11", + "y": "10", "width": "ceil(10 / max(1, providers.count)) * 11 - 1", "height": "9", "background": { @@ -1249,14 +1535,40 @@ } }, { - "id": "antigravity-session-gemini-dual-dark", - "name": "dark Antigravity Gemini dual session segments", - "render": "system.dark && antigravity.dual_mode", - "visibility": "100", + "id": "antigravity-session-external-solo-light-pace", + "name": "light Antigravity External solo session segments pace tick", + "render": "(1 - system.dark) && !antigravity.dual_mode && antigravity.external.opacity > 0.01", + "visibility": "(100) * antigravity.external.session.expected_available * display.show_pace * antigravity.external.opacity", + "parent": "antigravity-provider", + "x": "round((ceil(10 / max(1, providers.count)) * 11 - 2) * clamp(antigravity.external.session.expected_display, 0, 100) / 100)", + "y": "(10) - 1", + "width": "1", + "height": "(9) + 2", + "background": { + "type": "colour", + "colour": { + "color": "#1A1A1AFF", + "opacity": "0.9" + } + }, + "border": null, + "corner_radius": "0", + "layout": "freeform", + "align": "start", + "gap": "0", + "content": { + "type": "none" + } + }, + { + "id": "antigravity-gemini-5h-dark-normal", + "name": "dark Antigravity Gemini 5h normal", + "render": "(system.dark) && (antigravity.dual_mode) && (antigravity.normal.opacity > 0.01)", + "visibility": "100 * antigravity.normal.opacity", "parent": "antigravity-provider", - "y": "11", + "y": "8", "width": "ceil(10 / max(1, providers.count)) * 11 - 1", - "height": "4", + "height": "6", "background": { "type": "none" }, @@ -1270,7 +1582,7 @@ "value": "antigravity.gemini.session.display", "direction": "left_to_right", "fill": { - "color": "#00D2B4FF", + "color": "#5EEAD4FF", "opacity": "1" }, "track": { @@ -1284,14 +1596,37 @@ } }, { - "id": "antigravity-session-gemini-dual-light", - "name": "light Antigravity Gemini dual session segments", - "render": "(1 - system.dark) && antigravity.dual_mode", - "visibility": "100", + "id": "antigravity-gemini-5h-dark-normal-pace", + "name": "dark Antigravity Gemini 5h normal pace", + "render": "(system.dark) && (antigravity.dual_mode) && (antigravity.normal.opacity > 0.01)", + "visibility": "(100) * antigravity.gemini.session.expected_available * display.show_pace * antigravity.normal.opacity", + "parent": "antigravity-provider", + "x": "round((ceil(10 / max(1, providers.count)) * 11 - 2) * clamp(antigravity.gemini.session.expected_display, 0, 100) / 100)", + "y": "7", + "width": "1", + "height": "8", + "background": { + "type": "colour", + "colour": { + "color": "#FFFFFFFF", + "opacity": "0.9" + } + }, + "border": null, + "corner_radius": "0", + "layout": "freeform", + "align": "start", + "gap": "0" + }, + { + "id": "antigravity-gemini-5h-dark-hover", + "name": "dark Antigravity Gemini 5h hover", + "render": "(system.dark) && (antigravity.dual_mode) && (antigravity.hover.opacity > 0.01)", + "visibility": "100 * antigravity.hover.opacity", "parent": "antigravity-provider", - "y": "11", + "y": "8", "width": "ceil(10 / max(1, providers.count)) * 11 - 1", - "height": "4", + "height": "3", "background": { "type": "none" }, @@ -1305,11 +1640,11 @@ "value": "antigravity.gemini.session.display", "direction": "left_to_right", "fill": { - "color": "#00A896FF", + "color": "#5EEAD4FF", "opacity": "1" }, "track": { - "color": "#AAAAAAFF", + "color": "#444444FF", "opacity": "1" }, "corner_radius": "1.5", @@ -1319,49 +1654,37 @@ } }, { - "id": "antigravity-session-external-dual-dark", - "name": "dark Antigravity External dual session segments", - "render": "system.dark && antigravity.dual_mode", - "visibility": "100", + "id": "antigravity-gemini-5h-dark-hover-pace", + "name": "dark Antigravity Gemini 5h hover pace", + "render": "(system.dark) && (antigravity.dual_mode) && (antigravity.hover.opacity > 0.01)", + "visibility": "(100) * antigravity.gemini.session.expected_available * display.show_pace * antigravity.hover.opacity", "parent": "antigravity-provider", - "y": "16", - "width": "ceil(10 / max(1, providers.count)) * 11 - 1", - "height": "4", + "x": "round((ceil(10 / max(1, providers.count)) * 11 - 2) * clamp(antigravity.gemini.session.expected_display, 0, 100) / 100)", + "y": "7", + "width": "1", + "height": "5", "background": { - "type": "none" - }, + "type": "colour", + "colour": { + "color": "#FFFFFFFF", + "opacity": "0.9" + } + }, "border": null, "corner_radius": "0", "layout": "freeform", "align": "start", - "gap": "0", - "content": { - "type": "progress", - "value": "antigravity.external.session.display", - "direction": "left_to_right", - "fill": { - "color": "#6EB4C8FF", - "opacity": "1" - }, - "track": { - "color": "#444444FF", - "opacity": "1" - }, - "corner_radius": "1.5", - "segments": 10, - "segments_expression": "ceil(10 / max(1, providers.count))", - "segment_gap": "1" - } + "gap": "0" }, { - "id": "antigravity-session-external-dual-light", - "name": "light Antigravity External dual session segments", - "render": "(1 - system.dark) && antigravity.dual_mode", - "visibility": "100", + "id": "antigravity-gemini-5h-light-normal", + "name": "light Antigravity Gemini 5h normal", + "render": "((1 - system.dark)) && (antigravity.dual_mode) && (antigravity.normal.opacity > 0.01)", + "visibility": "100 * antigravity.normal.opacity", "parent": "antigravity-provider", - "y": "16", + "y": "8", "width": "ceil(10 / max(1, providers.count)) * 11 - 1", - "height": "4", + "height": "6", "background": { "type": "none" }, @@ -1372,10 +1695,10 @@ "gap": "0", "content": { "type": "progress", - "value": "antigravity.external.session.display", + "value": "antigravity.gemini.session.display", "direction": "left_to_right", "fill": { - "color": "#4A8B9EFF", + "color": "#007A6CFF", "opacity": "1" }, "track": { @@ -1389,48 +1712,37 @@ } }, { - "id": "antigravity-session-gemini-value-dark", - "name": "dark Antigravity Gemini session value", - "render": "system.dark && antigravity.gemini.enabled && (!antigravity.dual_mode || antigravity.crossfade_opacity > 0.01)", - "visibility": "100", + "id": "antigravity-gemini-5h-light-normal-pace", + "name": "light Antigravity Gemini 5h normal pace", + "render": "((1 - system.dark)) && (antigravity.dual_mode) && (antigravity.normal.opacity > 0.01)", + "visibility": "(100) * antigravity.gemini.session.expected_available * display.show_pace * antigravity.normal.opacity", "parent": "antigravity-provider", - "x": "ceil(10 / max(1, providers.count)) * 11 - 1 + 4", - "y": "9", - "width": "62", - "height": "13", + "x": "round((ceil(10 / max(1, providers.count)) * 11 - 2) * clamp(antigravity.gemini.session.expected_display, 0, 100) / 100)", + "y": "7", + "width": "1", + "height": "8", "background": { - "type": "none" + "type": "colour", + "colour": { + "color": "#1A1A1AFF", + "opacity": "0.9" + } }, "border": null, "corner_radius": "0", "layout": "freeform", "align": "start", - "gap": "0", - "content": { - "type": "text", - "template": "{antigravity.gemini.session.display:usage_line}", - "font_family": "Segoe UI", - "font_size": "12", - "weight": "medium", - "rendering": "clear_type", - "contrast": "1", - "align": "left", - "color": { - "color": "#5EEAD4FF", - "opacity": "if(antigravity.dual_mode, antigravity.crossfade_opacity, 1.0)" - } - } + "gap": "0" }, { - "id": "antigravity-session-gemini-value-light", - "name": "light Antigravity Gemini session value", - "render": "(1 - system.dark) && antigravity.gemini.enabled && (!antigravity.dual_mode || antigravity.crossfade_opacity > 0.01)", - "visibility": "100", + "id": "antigravity-gemini-5h-light-hover", + "name": "light Antigravity Gemini 5h hover", + "render": "((1 - system.dark)) && (antigravity.dual_mode) && (antigravity.hover.opacity > 0.01)", + "visibility": "100 * antigravity.hover.opacity", "parent": "antigravity-provider", - "x": "ceil(10 / max(1, providers.count)) * 11 - 1 + 4", - "y": "9", - "width": "62", - "height": "13", + "y": "8", + "width": "ceil(10 / max(1, providers.count)) * 11 - 1", + "height": "3", "background": { "type": "none" }, @@ -1440,95 +1752,55 @@ "align": "start", "gap": "0", "content": { - "type": "text", - "template": "{antigravity.gemini.session.display:usage_line}", - "font_family": "Segoe UI", - "font_size": "12", - "weight": "medium", - "rendering": "clear_type", - "contrast": "1", - "align": "left", - "color": { + "type": "progress", + "value": "antigravity.gemini.session.display", + "direction": "left_to_right", + "fill": { "color": "#007A6CFF", - "opacity": "if(antigravity.dual_mode, antigravity.crossfade_opacity, 1.0)" - } + "opacity": "1" + }, + "track": { + "color": "#AAAAAAFF", + "opacity": "1" + }, + "corner_radius": "1.5", + "segments": 10, + "segments_expression": "ceil(10 / max(1, providers.count))", + "segment_gap": "1" } }, { - "id": "antigravity-session-external-value-dark", - "name": "dark Antigravity External session value", - "render": "system.dark && antigravity.external.enabled && (!antigravity.dual_mode || (1.0 - antigravity.crossfade_opacity) > 0.01)", - "visibility": "100", + "id": "antigravity-gemini-5h-light-hover-pace", + "name": "light Antigravity Gemini 5h hover pace", + "render": "((1 - system.dark)) && (antigravity.dual_mode) && (antigravity.hover.opacity > 0.01)", + "visibility": "(100) * antigravity.gemini.session.expected_available * display.show_pace * antigravity.hover.opacity", "parent": "antigravity-provider", - "x": "ceil(10 / max(1, providers.count)) * 11 - 1 + 4", - "y": "9", - "width": "62", - "height": "13", + "x": "round((ceil(10 / max(1, providers.count)) * 11 - 2) * clamp(antigravity.gemini.session.expected_display, 0, 100) / 100)", + "y": "7", + "width": "1", + "height": "5", "background": { - "type": "none" - }, - "border": null, - "corner_radius": "0", - "layout": "freeform", - "align": "start", - "gap": "0", - "content": { - "type": "text", - "template": "{antigravity.external.session.display:usage_line}", - "font_family": "Segoe UI", - "font_size": "12", - "weight": "medium", - "rendering": "clear_type", - "contrast": "1", - "align": "left", - "color": { - "color": "#98D0E0FF", - "opacity": "if(antigravity.dual_mode, 1.0 - antigravity.crossfade_opacity, 1.0)" + "type": "colour", + "colour": { + "color": "#1A1A1AFF", + "opacity": "0.9" } - } - }, - { - "id": "antigravity-session-external-value-light", - "name": "light Antigravity External session value", - "render": "(1 - system.dark) && antigravity.external.enabled && (!antigravity.dual_mode || (1.0 - antigravity.crossfade_opacity) > 0.01)", - "visibility": "100", - "parent": "antigravity-provider", - "x": "ceil(10 / max(1, providers.count)) * 11 - 1 + 4", - "y": "9", - "width": "62", - "height": "13", - "background": { - "type": "none" }, "border": null, "corner_radius": "0", "layout": "freeform", "align": "start", - "gap": "0", - "content": { - "type": "text", - "template": "{antigravity.external.session.display:usage_line}", - "font_family": "Segoe UI", - "font_size": "12", - "weight": "medium", - "rendering": "clear_type", - "contrast": "1", - "align": "left", - "color": { - "color": "#2D6F82FF", - "opacity": "if(antigravity.dual_mode, 1.0 - antigravity.crossfade_opacity, 1.0)" - } - } + "gap": "0" }, { - "id": "antigravity-weekly-gemini-solo-dark", - "name": "dark Antigravity Gemini solo weekly segments", - "render": "system.dark && antigravity.gemini.enabled && !antigravity.dual_mode", - "visibility": "100", + "id": "antigravity-gemini-weekly-dark-normal", + "name": "dark Antigravity Gemini weekly normal", + "render": "(system.dark) && (antigravity.dual_mode) && (antigravity.normal.opacity > 0.01)", + "visibility": "100 * antigravity.normal.opacity", "parent": "antigravity-provider", - "y": "27", + "y": "16", "width": "ceil(10 / max(1, providers.count)) * 11 - 1", - "height": "9", + "height": "3", "background": { "type": "none" }, @@ -1542,11 +1814,11 @@ "value": "antigravity.gemini.weekly.display", "direction": "left_to_right", "fill": { - "color": "#00D2B4FF", + "color": "#0D9488FF", "opacity": "1" }, "track": { - "color": "#444444FF", + "color": "#333333FF", "opacity": "1" }, "corner_radius": "1.5", @@ -1556,14 +1828,37 @@ } }, { - "id": "antigravity-weekly-gemini-solo-light", - "name": "light Antigravity Gemini solo weekly segments", - "render": "(1 - system.dark) && antigravity.gemini.enabled && !antigravity.dual_mode", - "visibility": "100", + "id": "antigravity-gemini-weekly-dark-normal-pace", + "name": "dark Antigravity Gemini weekly normal pace", + "render": "(system.dark) && (antigravity.dual_mode) && (antigravity.normal.opacity > 0.01)", + "visibility": "(100) * antigravity.gemini.weekly.expected_available * display.show_pace * antigravity.normal.opacity", "parent": "antigravity-provider", - "y": "27", + "x": "round((ceil(10 / max(1, providers.count)) * 11 - 2) * clamp(antigravity.gemini.weekly.expected_display, 0, 100) / 100)", + "y": "15", + "width": "1", + "height": "5", + "background": { + "type": "colour", + "colour": { + "color": "#FFFFFFFF", + "opacity": "0.9" + } + }, + "border": null, + "corner_radius": "0", + "layout": "freeform", + "align": "start", + "gap": "0" + }, + { + "id": "antigravity-gemini-weekly-dark-hover", + "name": "dark Antigravity Gemini weekly hover", + "render": "(system.dark) && (antigravity.dual_mode) && (antigravity.hover.opacity > 0.01)", + "visibility": "100 * antigravity.hover.opacity", + "parent": "antigravity-provider", + "y": "13", "width": "ceil(10 / max(1, providers.count)) * 11 - 1", - "height": "9", + "height": "6", "background": { "type": "none" }, @@ -1577,11 +1872,11 @@ "value": "antigravity.gemini.weekly.display", "direction": "left_to_right", "fill": { - "color": "#00A896FF", + "color": "#0D9488FF", "opacity": "1" }, "track": { - "color": "#AAAAAAFF", + "color": "#333333FF", "opacity": "1" }, "corner_radius": "1.5", @@ -1591,49 +1886,37 @@ } }, { - "id": "antigravity-weekly-external-solo-dark", - "name": "dark Antigravity External solo weekly segments", - "render": "system.dark && antigravity.external.enabled && !antigravity.dual_mode", - "visibility": "100", + "id": "antigravity-gemini-weekly-dark-hover-pace", + "name": "dark Antigravity Gemini weekly hover pace", + "render": "(system.dark) && (antigravity.dual_mode) && (antigravity.hover.opacity > 0.01)", + "visibility": "(100) * antigravity.gemini.weekly.expected_available * display.show_pace * antigravity.hover.opacity", "parent": "antigravity-provider", - "y": "27", - "width": "ceil(10 / max(1, providers.count)) * 11 - 1", - "height": "9", + "x": "round((ceil(10 / max(1, providers.count)) * 11 - 2) * clamp(antigravity.gemini.weekly.expected_display, 0, 100) / 100)", + "y": "12", + "width": "1", + "height": "8", "background": { - "type": "none" + "type": "colour", + "colour": { + "color": "#FFFFFFFF", + "opacity": "0.9" + } }, "border": null, "corner_radius": "0", "layout": "freeform", "align": "start", - "gap": "0", - "content": { - "type": "progress", - "value": "antigravity.external.weekly.display", - "direction": "left_to_right", - "fill": { - "color": "#6EB4C8FF", - "opacity": "1" - }, - "track": { - "color": "#444444FF", - "opacity": "1" - }, - "corner_radius": "1.5", - "segments": 10, - "segments_expression": "ceil(10 / max(1, providers.count))", - "segment_gap": "1" - } + "gap": "0" }, { - "id": "antigravity-weekly-external-solo-light", - "name": "light Antigravity External solo weekly segments", - "render": "(1 - system.dark) && antigravity.external.enabled && !antigravity.dual_mode", - "visibility": "100", + "id": "antigravity-gemini-weekly-light-normal", + "name": "light Antigravity Gemini weekly normal", + "render": "((1 - system.dark)) && (antigravity.dual_mode) && (antigravity.normal.opacity > 0.01)", + "visibility": "100 * antigravity.normal.opacity", "parent": "antigravity-provider", - "y": "27", + "y": "16", "width": "ceil(10 / max(1, providers.count)) * 11 - 1", - "height": "9", + "height": "3", "background": { "type": "none" }, @@ -1644,14 +1927,14 @@ "gap": "0", "content": { "type": "progress", - "value": "antigravity.external.weekly.display", + "value": "antigravity.gemini.weekly.display", "direction": "left_to_right", "fill": { - "color": "#4A8B9EFF", + "color": "#004D40FF", "opacity": "1" }, "track": { - "color": "#AAAAAAFF", + "color": "#CCCCCCFF", "opacity": "1" }, "corner_radius": "1.5", @@ -1661,14 +1944,37 @@ } }, { - "id": "antigravity-weekly-gemini-dual-dark", - "name": "dark Antigravity Gemini dual weekly segments", - "render": "system.dark && antigravity.dual_mode", - "visibility": "100", + "id": "antigravity-gemini-weekly-light-normal-pace", + "name": "light Antigravity Gemini weekly normal pace", + "render": "((1 - system.dark)) && (antigravity.dual_mode) && (antigravity.normal.opacity > 0.01)", + "visibility": "(100) * antigravity.gemini.weekly.expected_available * display.show_pace * antigravity.normal.opacity", "parent": "antigravity-provider", - "y": "27", + "x": "round((ceil(10 / max(1, providers.count)) * 11 - 2) * clamp(antigravity.gemini.weekly.expected_display, 0, 100) / 100)", + "y": "15", + "width": "1", + "height": "5", + "background": { + "type": "colour", + "colour": { + "color": "#1A1A1AFF", + "opacity": "0.9" + } + }, + "border": null, + "corner_radius": "0", + "layout": "freeform", + "align": "start", + "gap": "0" + }, + { + "id": "antigravity-gemini-weekly-light-hover", + "name": "light Antigravity Gemini weekly hover", + "render": "((1 - system.dark)) && (antigravity.dual_mode) && (antigravity.hover.opacity > 0.01)", + "visibility": "100 * antigravity.hover.opacity", + "parent": "antigravity-provider", + "y": "13", "width": "ceil(10 / max(1, providers.count)) * 11 - 1", - "height": "4", + "height": "6", "background": { "type": "none" }, @@ -1682,11 +1988,11 @@ "value": "antigravity.gemini.weekly.display", "direction": "left_to_right", "fill": { - "color": "#00D2B4FF", + "color": "#004D40FF", "opacity": "1" }, "track": { - "color": "#444444FF", + "color": "#CCCCCCFF", "opacity": "1" }, "corner_radius": "1.5", @@ -1696,14 +2002,4019 @@ } }, { - "id": "antigravity-weekly-gemini-dual-light", - "name": "light Antigravity Gemini dual weekly segments", - "render": "(1 - system.dark) && antigravity.dual_mode", + "id": "antigravity-gemini-weekly-light-hover-pace", + "name": "light Antigravity Gemini weekly hover pace", + "render": "((1 - system.dark)) && (antigravity.dual_mode) && (antigravity.hover.opacity > 0.01)", + "visibility": "(100) * antigravity.gemini.weekly.expected_available * display.show_pace * antigravity.hover.opacity", + "parent": "antigravity-provider", + "x": "round((ceil(10 / max(1, providers.count)) * 11 - 2) * clamp(antigravity.gemini.weekly.expected_display, 0, 100) / 100)", + "y": "12", + "width": "1", + "height": "8", + "background": { + "type": "colour", + "colour": { + "color": "#1A1A1AFF", + "opacity": "0.9" + } + }, + "border": null, + "corner_radius": "0", + "layout": "freeform", + "align": "start", + "gap": "0" + }, + { + "id": "antigravity-gemini-text-dark-normal", + "name": "dark Antigravity Gemini text normal", + "render": "(system.dark) && (antigravity.dual_mode) && (antigravity.normal.opacity > 0.01)", "visibility": "100", "parent": "antigravity-provider", - "y": "27", - "width": "ceil(10 / max(1, providers.count)) * 11 - 1", - "height": "4", + "x": "ceil(10 / max(1, providers.count)) * 11 - 1 + 4", + "y": "8", + "width": "62", + "height": "13", + "background": { + "type": "none" + }, + "border": null, + "corner_radius": "0", + "layout": "freeform", + "align": "start", + "gap": "0", + "content": { + "type": "text", + "template": "{antigravity.gemini.session.display:usage_line}", + "font_family": "Segoe UI", + "font_size": "12", + "weight": "medium", + "rendering": "clear_type", + "contrast": "1", + "align": "left", + "color": { + "color": "#5EEAD4FF", + "opacity": "antigravity.normal.opacity" + } + } + }, + { + "id": "antigravity-gemini-text-dark-hover", + "name": "dark Antigravity Gemini text hover", + "render": "(system.dark) && (antigravity.dual_mode) && (antigravity.hover.opacity > 0.01)", + "visibility": "100", + "parent": "antigravity-provider", + "x": "ceil(10 / max(1, providers.count)) * 11 - 1 + 4", + "y": "8", + "width": "62", + "height": "13", + "background": { + "type": "none" + }, + "border": null, + "corner_radius": "0", + "layout": "freeform", + "align": "start", + "gap": "0", + "content": { + "type": "text", + "template": "{antigravity.gemini.weekly.display:usage_line}", + "font_family": "Segoe UI", + "font_size": "12", + "weight": "medium", + "rendering": "clear_type", + "contrast": "1", + "align": "left", + "color": { + "color": "#0D9488FF", + "opacity": "antigravity.hover.opacity" + } + } + }, + { + "id": "antigravity-gemini-text-light-normal", + "name": "light Antigravity Gemini text normal", + "render": "((1 - system.dark)) && (antigravity.dual_mode) && (antigravity.normal.opacity > 0.01)", + "visibility": "100", + "parent": "antigravity-provider", + "x": "ceil(10 / max(1, providers.count)) * 11 - 1 + 4", + "y": "8", + "width": "62", + "height": "13", + "background": { + "type": "none" + }, + "border": null, + "corner_radius": "0", + "layout": "freeform", + "align": "start", + "gap": "0", + "content": { + "type": "text", + "template": "{antigravity.gemini.session.display:usage_line}", + "font_family": "Segoe UI", + "font_size": "12", + "weight": "medium", + "rendering": "clear_type", + "contrast": "1", + "align": "left", + "color": { + "color": "#007A6CFF", + "opacity": "antigravity.normal.opacity" + } + } + }, + { + "id": "antigravity-gemini-text-light-hover", + "name": "light Antigravity Gemini text hover", + "render": "((1 - system.dark)) && (antigravity.dual_mode) && (antigravity.hover.opacity > 0.01)", + "visibility": "100", + "parent": "antigravity-provider", + "x": "ceil(10 / max(1, providers.count)) * 11 - 1 + 4", + "y": "8", + "width": "62", + "height": "13", + "background": { + "type": "none" + }, + "border": null, + "corner_radius": "0", + "layout": "freeform", + "align": "start", + "gap": "0", + "content": { + "type": "text", + "template": "{antigravity.gemini.weekly.display:usage_line}", + "font_family": "Segoe UI", + "font_size": "12", + "weight": "medium", + "rendering": "clear_type", + "contrast": "1", + "align": "left", + "color": { + "color": "#004D40FF", + "opacity": "antigravity.hover.opacity" + } + } + }, + { + "id": "antigravity-external-5h-dark-normal", + "name": "dark Antigravity External 5h normal", + "render": "(system.dark) && (antigravity.dual_mode) && (antigravity.normal.opacity > 0.01)", + "visibility": "100 * antigravity.normal.opacity", + "parent": "antigravity-provider", + "y": "27", + "width": "ceil(10 / max(1, providers.count)) * 11 - 1", + "height": "6", + "background": { + "type": "none" + }, + "border": null, + "corner_radius": "0", + "layout": "freeform", + "align": "start", + "gap": "0", + "content": { + "type": "progress", + "value": "antigravity.external.session.display", + "direction": "left_to_right", + "fill": { + "color": "#98D0E0FF", + "opacity": "1" + }, + "track": { + "color": "#444444FF", + "opacity": "1" + }, + "corner_radius": "1.5", + "segments": 10, + "segments_expression": "ceil(10 / max(1, providers.count))", + "segment_gap": "1" + } + }, + { + "id": "antigravity-external-5h-dark-normal-pace", + "name": "dark Antigravity External 5h normal pace", + "render": "(system.dark) && (antigravity.dual_mode) && (antigravity.normal.opacity > 0.01)", + "visibility": "(100) * antigravity.external.session.expected_available * display.show_pace * antigravity.normal.opacity", + "parent": "antigravity-provider", + "x": "round((ceil(10 / max(1, providers.count)) * 11 - 2) * clamp(antigravity.external.session.expected_display, 0, 100) / 100)", + "y": "26", + "width": "1", + "height": "8", + "background": { + "type": "colour", + "colour": { + "color": "#FFFFFFFF", + "opacity": "0.9" + } + }, + "border": null, + "corner_radius": "0", + "layout": "freeform", + "align": "start", + "gap": "0" + }, + { + "id": "antigravity-external-5h-dark-hover", + "name": "dark Antigravity External 5h hover", + "render": "(system.dark) && (antigravity.dual_mode) && (antigravity.hover.opacity > 0.01)", + "visibility": "100 * antigravity.hover.opacity", + "parent": "antigravity-provider", + "y": "27", + "width": "ceil(10 / max(1, providers.count)) * 11 - 1", + "height": "3", + "background": { + "type": "none" + }, + "border": null, + "corner_radius": "0", + "layout": "freeform", + "align": "start", + "gap": "0", + "content": { + "type": "progress", + "value": "antigravity.external.session.display", + "direction": "left_to_right", + "fill": { + "color": "#98D0E0FF", + "opacity": "1" + }, + "track": { + "color": "#444444FF", + "opacity": "1" + }, + "corner_radius": "1.5", + "segments": 10, + "segments_expression": "ceil(10 / max(1, providers.count))", + "segment_gap": "1" + } + }, + { + "id": "antigravity-external-5h-dark-hover-pace", + "name": "dark Antigravity External 5h hover pace", + "render": "(system.dark) && (antigravity.dual_mode) && (antigravity.hover.opacity > 0.01)", + "visibility": "(100) * antigravity.external.session.expected_available * display.show_pace * antigravity.hover.opacity", + "parent": "antigravity-provider", + "x": "round((ceil(10 / max(1, providers.count)) * 11 - 2) * clamp(antigravity.external.session.expected_display, 0, 100) / 100)", + "y": "26", + "width": "1", + "height": "5", + "background": { + "type": "colour", + "colour": { + "color": "#FFFFFFFF", + "opacity": "0.9" + } + }, + "border": null, + "corner_radius": "0", + "layout": "freeform", + "align": "start", + "gap": "0" + }, + { + "id": "antigravity-external-5h-light-normal", + "name": "light Antigravity External 5h normal", + "render": "((1 - system.dark)) && (antigravity.dual_mode) && (antigravity.normal.opacity > 0.01)", + "visibility": "100 * antigravity.normal.opacity", + "parent": "antigravity-provider", + "y": "27", + "width": "ceil(10 / max(1, providers.count)) * 11 - 1", + "height": "6", + "background": { + "type": "none" + }, + "border": null, + "corner_radius": "0", + "layout": "freeform", + "align": "start", + "gap": "0", + "content": { + "type": "progress", + "value": "antigravity.external.session.display", + "direction": "left_to_right", + "fill": { + "color": "#2D6F82FF", + "opacity": "1" + }, + "track": { + "color": "#AAAAAAFF", + "opacity": "1" + }, + "corner_radius": "1.5", + "segments": 10, + "segments_expression": "ceil(10 / max(1, providers.count))", + "segment_gap": "1" + } + }, + { + "id": "antigravity-external-5h-light-normal-pace", + "name": "light Antigravity External 5h normal pace", + "render": "((1 - system.dark)) && (antigravity.dual_mode) && (antigravity.normal.opacity > 0.01)", + "visibility": "(100) * antigravity.external.session.expected_available * display.show_pace * antigravity.normal.opacity", + "parent": "antigravity-provider", + "x": "round((ceil(10 / max(1, providers.count)) * 11 - 2) * clamp(antigravity.external.session.expected_display, 0, 100) / 100)", + "y": "26", + "width": "1", + "height": "8", + "background": { + "type": "colour", + "colour": { + "color": "#1A1A1AFF", + "opacity": "0.9" + } + }, + "border": null, + "corner_radius": "0", + "layout": "freeform", + "align": "start", + "gap": "0" + }, + { + "id": "antigravity-external-5h-light-hover", + "name": "light Antigravity External 5h hover", + "render": "((1 - system.dark)) && (antigravity.dual_mode) && (antigravity.hover.opacity > 0.01)", + "visibility": "100 * antigravity.hover.opacity", + "parent": "antigravity-provider", + "y": "27", + "width": "ceil(10 / max(1, providers.count)) * 11 - 1", + "height": "3", + "background": { + "type": "none" + }, + "border": null, + "corner_radius": "0", + "layout": "freeform", + "align": "start", + "gap": "0", + "content": { + "type": "progress", + "value": "antigravity.external.session.display", + "direction": "left_to_right", + "fill": { + "color": "#2D6F82FF", + "opacity": "1" + }, + "track": { + "color": "#AAAAAAFF", + "opacity": "1" + }, + "corner_radius": "1.5", + "segments": 10, + "segments_expression": "ceil(10 / max(1, providers.count))", + "segment_gap": "1" + } + }, + { + "id": "antigravity-external-5h-light-hover-pace", + "name": "light Antigravity External 5h hover pace", + "render": "((1 - system.dark)) && (antigravity.dual_mode) && (antigravity.hover.opacity > 0.01)", + "visibility": "(100) * antigravity.external.session.expected_available * display.show_pace * antigravity.hover.opacity", + "parent": "antigravity-provider", + "x": "round((ceil(10 / max(1, providers.count)) * 11 - 2) * clamp(antigravity.external.session.expected_display, 0, 100) / 100)", + "y": "26", + "width": "1", + "height": "5", + "background": { + "type": "colour", + "colour": { + "color": "#1A1A1AFF", + "opacity": "0.9" + } + }, + "border": null, + "corner_radius": "0", + "layout": "freeform", + "align": "start", + "gap": "0" + }, + { + "id": "antigravity-external-weekly-dark-normal", + "name": "dark Antigravity External weekly normal", + "render": "(system.dark) && (antigravity.dual_mode) && (antigravity.normal.opacity > 0.01)", + "visibility": "100 * antigravity.normal.opacity", + "parent": "antigravity-provider", + "y": "35", + "width": "ceil(10 / max(1, providers.count)) * 11 - 1", + "height": "3", + "background": { + "type": "none" + }, + "border": null, + "corner_radius": "0", + "layout": "freeform", + "align": "start", + "gap": "0", + "content": { + "type": "progress", + "value": "antigravity.external.weekly.display", + "direction": "left_to_right", + "fill": { + "color": "#4A8B9EFF", + "opacity": "1" + }, + "track": { + "color": "#333333FF", + "opacity": "1" + }, + "corner_radius": "1.5", + "segments": 10, + "segments_expression": "ceil(10 / max(1, providers.count))", + "segment_gap": "1" + } + }, + { + "id": "antigravity-external-weekly-dark-normal-pace", + "name": "dark Antigravity External weekly normal pace", + "render": "(system.dark) && (antigravity.dual_mode) && (antigravity.normal.opacity > 0.01)", + "visibility": "(100) * antigravity.external.weekly.expected_available * display.show_pace * antigravity.normal.opacity", + "parent": "antigravity-provider", + "x": "round((ceil(10 / max(1, providers.count)) * 11 - 2) * clamp(antigravity.external.weekly.expected_display, 0, 100) / 100)", + "y": "34", + "width": "1", + "height": "5", + "background": { + "type": "colour", + "colour": { + "color": "#FFFFFFFF", + "opacity": "0.9" + } + }, + "border": null, + "corner_radius": "0", + "layout": "freeform", + "align": "start", + "gap": "0" + }, + { + "id": "antigravity-external-weekly-dark-hover", + "name": "dark Antigravity External weekly hover", + "render": "(system.dark) && (antigravity.dual_mode) && (antigravity.hover.opacity > 0.01)", + "visibility": "100 * antigravity.hover.opacity", + "parent": "antigravity-provider", + "y": "32", + "width": "ceil(10 / max(1, providers.count)) * 11 - 1", + "height": "6", + "background": { + "type": "none" + }, + "border": null, + "corner_radius": "0", + "layout": "freeform", + "align": "start", + "gap": "0", + "content": { + "type": "progress", + "value": "antigravity.external.weekly.display", + "direction": "left_to_right", + "fill": { + "color": "#4A8B9EFF", + "opacity": "1" + }, + "track": { + "color": "#333333FF", + "opacity": "1" + }, + "corner_radius": "1.5", + "segments": 10, + "segments_expression": "ceil(10 / max(1, providers.count))", + "segment_gap": "1" + } + }, + { + "id": "antigravity-external-weekly-dark-hover-pace", + "name": "dark Antigravity External weekly hover pace", + "render": "(system.dark) && (antigravity.dual_mode) && (antigravity.hover.opacity > 0.01)", + "visibility": "(100) * antigravity.external.weekly.expected_available * display.show_pace * antigravity.hover.opacity", + "parent": "antigravity-provider", + "x": "round((ceil(10 / max(1, providers.count)) * 11 - 2) * clamp(antigravity.external.weekly.expected_display, 0, 100) / 100)", + "y": "31", + "width": "1", + "height": "8", + "background": { + "type": "colour", + "colour": { + "color": "#FFFFFFFF", + "opacity": "0.9" + } + }, + "border": null, + "corner_radius": "0", + "layout": "freeform", + "align": "start", + "gap": "0" + }, + { + "id": "antigravity-external-weekly-light-normal", + "name": "light Antigravity External weekly normal", + "render": "((1 - system.dark)) && (antigravity.dual_mode) && (antigravity.normal.opacity > 0.01)", + "visibility": "100 * antigravity.normal.opacity", + "parent": "antigravity-provider", + "y": "35", + "width": "ceil(10 / max(1, providers.count)) * 11 - 1", + "height": "3", + "background": { + "type": "none" + }, + "border": null, + "corner_radius": "0", + "layout": "freeform", + "align": "start", + "gap": "0", + "content": { + "type": "progress", + "value": "antigravity.external.weekly.display", + "direction": "left_to_right", + "fill": { + "color": "#1F4E5BFF", + "opacity": "1" + }, + "track": { + "color": "#CCCCCCFF", + "opacity": "1" + }, + "corner_radius": "1.5", + "segments": 10, + "segments_expression": "ceil(10 / max(1, providers.count))", + "segment_gap": "1" + } + }, + { + "id": "antigravity-external-weekly-light-normal-pace", + "name": "light Antigravity External weekly normal pace", + "render": "((1 - system.dark)) && (antigravity.dual_mode) && (antigravity.normal.opacity > 0.01)", + "visibility": "(100) * antigravity.external.weekly.expected_available * display.show_pace * antigravity.normal.opacity", + "parent": "antigravity-provider", + "x": "round((ceil(10 / max(1, providers.count)) * 11 - 2) * clamp(antigravity.external.weekly.expected_display, 0, 100) / 100)", + "y": "34", + "width": "1", + "height": "5", + "background": { + "type": "colour", + "colour": { + "color": "#1A1A1AFF", + "opacity": "0.9" + } + }, + "border": null, + "corner_radius": "0", + "layout": "freeform", + "align": "start", + "gap": "0" + }, + { + "id": "antigravity-external-weekly-light-hover", + "name": "light Antigravity External weekly hover", + "render": "((1 - system.dark)) && (antigravity.dual_mode) && (antigravity.hover.opacity > 0.01)", + "visibility": "100 * antigravity.hover.opacity", + "parent": "antigravity-provider", + "y": "32", + "width": "ceil(10 / max(1, providers.count)) * 11 - 1", + "height": "6", + "background": { + "type": "none" + }, + "border": null, + "corner_radius": "0", + "layout": "freeform", + "align": "start", + "gap": "0", + "content": { + "type": "progress", + "value": "antigravity.external.weekly.display", + "direction": "left_to_right", + "fill": { + "color": "#1F4E5BFF", + "opacity": "1" + }, + "track": { + "color": "#CCCCCCFF", + "opacity": "1" + }, + "corner_radius": "1.5", + "segments": 10, + "segments_expression": "ceil(10 / max(1, providers.count))", + "segment_gap": "1" + } + }, + { + "id": "antigravity-external-weekly-light-hover-pace", + "name": "light Antigravity External weekly hover pace", + "render": "((1 - system.dark)) && (antigravity.dual_mode) && (antigravity.hover.opacity > 0.01)", + "visibility": "(100) * antigravity.external.weekly.expected_available * display.show_pace * antigravity.hover.opacity", + "parent": "antigravity-provider", + "x": "round((ceil(10 / max(1, providers.count)) * 11 - 2) * clamp(antigravity.external.weekly.expected_display, 0, 100) / 100)", + "y": "31", + "width": "1", + "height": "8", + "background": { + "type": "colour", + "colour": { + "color": "#1A1A1AFF", + "opacity": "0.9" + } + }, + "border": null, + "corner_radius": "0", + "layout": "freeform", + "align": "start", + "gap": "0" + }, + { + "id": "antigravity-external-text-dark-normal", + "name": "dark Antigravity External text normal", + "render": "(system.dark) && (antigravity.dual_mode) && (antigravity.normal.opacity > 0.01)", + "visibility": "100", + "parent": "antigravity-provider", + "x": "ceil(10 / max(1, providers.count)) * 11 - 1 + 4", + "y": "25", + "width": "62", + "height": "13", + "background": { + "type": "none" + }, + "border": null, + "corner_radius": "0", + "layout": "freeform", + "align": "start", + "gap": "0", + "content": { + "type": "text", + "template": "{antigravity.external.session.display:usage_line}", + "font_family": "Segoe UI", + "font_size": "12", + "weight": "medium", + "rendering": "clear_type", + "contrast": "1", + "align": "left", + "color": { + "color": "#98D0E0FF", + "opacity": "antigravity.normal.opacity" + } + } + }, + { + "id": "antigravity-external-text-dark-hover", + "name": "dark Antigravity External text hover", + "render": "(system.dark) && (antigravity.dual_mode) && (antigravity.hover.opacity > 0.01)", + "visibility": "100", + "parent": "antigravity-provider", + "x": "ceil(10 / max(1, providers.count)) * 11 - 1 + 4", + "y": "25", + "width": "62", + "height": "13", + "background": { + "type": "none" + }, + "border": null, + "corner_radius": "0", + "layout": "freeform", + "align": "start", + "gap": "0", + "content": { + "type": "text", + "template": "{antigravity.external.weekly.display:usage_line}", + "font_family": "Segoe UI", + "font_size": "12", + "weight": "medium", + "rendering": "clear_type", + "contrast": "1", + "align": "left", + "color": { + "color": "#4A8B9EFF", + "opacity": "antigravity.hover.opacity" + } + } + }, + { + "id": "antigravity-external-text-light-normal", + "name": "light Antigravity External text normal", + "render": "((1 - system.dark)) && (antigravity.dual_mode) && (antigravity.normal.opacity > 0.01)", + "visibility": "100", + "parent": "antigravity-provider", + "x": "ceil(10 / max(1, providers.count)) * 11 - 1 + 4", + "y": "25", + "width": "62", + "height": "13", + "background": { + "type": "none" + }, + "border": null, + "corner_radius": "0", + "layout": "freeform", + "align": "start", + "gap": "0", + "content": { + "type": "text", + "template": "{antigravity.external.session.display:usage_line}", + "font_family": "Segoe UI", + "font_size": "12", + "weight": "medium", + "rendering": "clear_type", + "contrast": "1", + "align": "left", + "color": { + "color": "#2D6F82FF", + "opacity": "antigravity.normal.opacity" + } + } + }, + { + "id": "antigravity-external-text-light-hover", + "name": "light Antigravity External text hover", + "render": "((1 - system.dark)) && (antigravity.dual_mode) && (antigravity.hover.opacity > 0.01)", + "visibility": "100", + "parent": "antigravity-provider", + "x": "ceil(10 / max(1, providers.count)) * 11 - 1 + 4", + "y": "25", + "width": "62", + "height": "13", + "background": { + "type": "none" + }, + "border": null, + "corner_radius": "0", + "layout": "freeform", + "align": "start", + "gap": "0", + "content": { + "type": "text", + "template": "{antigravity.external.weekly.display:usage_line}", + "font_family": "Segoe UI", + "font_size": "12", + "weight": "medium", + "rendering": "clear_type", + "contrast": "1", + "align": "left", + "color": { + "color": "#1F4E5BFF", + "opacity": "antigravity.hover.opacity" + } + } + }, + { + "id": "antigravity-session-gemini-value-dark", + "name": "dark Antigravity Gemini session value", + "render": "system.dark && !antigravity.dual_mode && antigravity.gemini.opacity > 0.01", + "visibility": "100", + "parent": "antigravity-provider", + "x": "ceil(10 / max(1, providers.count)) * 11 - 1 + 4", + "y": "8", + "width": "62", + "height": "13", + "background": { + "type": "none" + }, + "border": null, + "corner_radius": "0", + "layout": "freeform", + "align": "start", + "gap": "0", + "content": { + "type": "text", + "template": "{antigravity.gemini.session.display:usage_line}", + "font_family": "Segoe UI", + "font_size": "12", + "weight": "medium", + "rendering": "clear_type", + "contrast": "1", + "align": "left", + "color": { + "color": "#5EEAD4FF", + "opacity": "antigravity.gemini.opacity" + } + } + }, + { + "id": "antigravity-session-gemini-value-light", + "name": "light Antigravity Gemini session value", + "render": "(1 - system.dark && !antigravity.dual_mode) && antigravity.gemini.opacity > 0.01", + "visibility": "100", + "parent": "antigravity-provider", + "x": "ceil(10 / max(1, providers.count)) * 11 - 1 + 4", + "y": "8", + "width": "62", + "height": "13", + "background": { + "type": "none" + }, + "border": null, + "corner_radius": "0", + "layout": "freeform", + "align": "start", + "gap": "0", + "content": { + "type": "text", + "template": "{antigravity.gemini.session.display:usage_line}", + "font_family": "Segoe UI", + "font_size": "12", + "weight": "medium", + "rendering": "clear_type", + "contrast": "1", + "align": "left", + "color": { + "color": "#007A6CFF", + "opacity": "antigravity.gemini.opacity" + } + } + }, + { + "id": "antigravity-session-external-value-dark", + "name": "dark Antigravity External session value", + "render": "system.dark && !antigravity.dual_mode && antigravity.external.opacity > 0.01", + "visibility": "100", + "parent": "antigravity-provider", + "x": "ceil(10 / max(1, providers.count)) * 11 - 1 + 4", + "y": "8", + "width": "62", + "height": "13", + "background": { + "type": "none" + }, + "border": null, + "corner_radius": "0", + "layout": "freeform", + "align": "start", + "gap": "0", + "content": { + "type": "text", + "template": "{antigravity.external.session.display:usage_line}", + "font_family": "Segoe UI", + "font_size": "12", + "weight": "medium", + "rendering": "clear_type", + "contrast": "1", + "align": "left", + "color": { + "color": "#98D0E0FF", + "opacity": "antigravity.external.opacity" + } + } + }, + { + "id": "antigravity-session-external-value-light", + "name": "light Antigravity External session value", + "render": "(1 - system.dark && !antigravity.dual_mode) && antigravity.external.opacity > 0.01", + "visibility": "100", + "parent": "antigravity-provider", + "x": "ceil(10 / max(1, providers.count)) * 11 - 1 + 4", + "y": "8", + "width": "62", + "height": "13", + "background": { + "type": "none" + }, + "border": null, + "corner_radius": "0", + "layout": "freeform", + "align": "start", + "gap": "0", + "content": { + "type": "text", + "template": "{antigravity.external.session.display:usage_line}", + "font_family": "Segoe UI", + "font_size": "12", + "weight": "medium", + "rendering": "clear_type", + "contrast": "1", + "align": "left", + "color": { + "color": "#2D6F82FF", + "opacity": "antigravity.external.opacity" + } + } + }, + { + "id": "antigravity-weekly-gemini-solo-dark", + "name": "dark Antigravity Gemini solo weekly segments", + "render": "system.dark && !antigravity.dual_mode && antigravity.gemini.opacity > 0.01", + "visibility": "100 * antigravity.gemini.opacity", + "parent": "antigravity-provider", + "y": "27", + "width": "ceil(10 / max(1, providers.count)) * 11 - 1", + "height": "9", + "background": { + "type": "none" + }, + "border": null, + "corner_radius": "0", + "layout": "freeform", + "align": "start", + "gap": "0", + "content": { + "type": "progress", + "value": "antigravity.gemini.weekly.display", + "direction": "left_to_right", + "fill": { + "color": "#00D2B4FF", + "opacity": "1" + }, + "track": { + "color": "#444444FF", + "opacity": "1" + }, + "corner_radius": "1.5", + "segments": 10, + "segments_expression": "ceil(10 / max(1, providers.count))", + "segment_gap": "1" + } + }, + { + "id": "antigravity-weekly-gemini-solo-dark-pace", + "name": "dark Antigravity Gemini solo weekly segments pace tick", + "render": "system.dark && !antigravity.dual_mode && antigravity.gemini.opacity > 0.01", + "visibility": "(100) * antigravity.gemini.weekly.expected_available * display.show_pace * antigravity.gemini.opacity", + "parent": "antigravity-provider", + "x": "round((ceil(10 / max(1, providers.count)) * 11 - 2) * clamp(antigravity.gemini.weekly.expected_display, 0, 100) / 100)", + "y": "(27) - 1", + "width": "1", + "height": "(9) + 2", + "background": { + "type": "colour", + "colour": { + "color": "#FFFFFFFF", + "opacity": "0.9" + } + }, + "border": null, + "corner_radius": "0", + "layout": "freeform", + "align": "start", + "gap": "0", + "content": { + "type": "none" + } + }, + { + "id": "antigravity-weekly-gemini-solo-light", + "name": "light Antigravity Gemini solo weekly segments", + "render": "(1 - system.dark) && !antigravity.dual_mode && antigravity.gemini.opacity > 0.01", + "visibility": "100 * antigravity.gemini.opacity", + "parent": "antigravity-provider", + "y": "27", + "width": "ceil(10 / max(1, providers.count)) * 11 - 1", + "height": "9", + "background": { + "type": "none" + }, + "border": null, + "corner_radius": "0", + "layout": "freeform", + "align": "start", + "gap": "0", + "content": { + "type": "progress", + "value": "antigravity.gemini.weekly.display", + "direction": "left_to_right", + "fill": { + "color": "#00A896FF", + "opacity": "1" + }, + "track": { + "color": "#AAAAAAFF", + "opacity": "1" + }, + "corner_radius": "1.5", + "segments": 10, + "segments_expression": "ceil(10 / max(1, providers.count))", + "segment_gap": "1" + } + }, + { + "id": "antigravity-weekly-gemini-solo-light-pace", + "name": "light Antigravity Gemini solo weekly segments pace tick", + "render": "(1 - system.dark) && !antigravity.dual_mode && antigravity.gemini.opacity > 0.01", + "visibility": "(100) * antigravity.gemini.weekly.expected_available * display.show_pace * antigravity.gemini.opacity", + "parent": "antigravity-provider", + "x": "round((ceil(10 / max(1, providers.count)) * 11 - 2) * clamp(antigravity.gemini.weekly.expected_display, 0, 100) / 100)", + "y": "(27) - 1", + "width": "1", + "height": "(9) + 2", + "background": { + "type": "colour", + "colour": { + "color": "#1A1A1AFF", + "opacity": "0.9" + } + }, + "border": null, + "corner_radius": "0", + "layout": "freeform", + "align": "start", + "gap": "0", + "content": { + "type": "none" + } + }, + { + "id": "antigravity-weekly-external-solo-dark", + "name": "dark Antigravity External solo weekly segments", + "render": "system.dark && !antigravity.dual_mode && antigravity.external.opacity > 0.01", + "visibility": "100 * antigravity.external.opacity", + "parent": "antigravity-provider", + "y": "27", + "width": "ceil(10 / max(1, providers.count)) * 11 - 1", + "height": "9", + "background": { + "type": "none" + }, + "border": null, + "corner_radius": "0", + "layout": "freeform", + "align": "start", + "gap": "0", + "content": { + "type": "progress", + "value": "antigravity.external.weekly.display", + "direction": "left_to_right", + "fill": { + "color": "#6EB4C8FF", + "opacity": "1" + }, + "track": { + "color": "#444444FF", + "opacity": "1" + }, + "corner_radius": "1.5", + "segments": 10, + "segments_expression": "ceil(10 / max(1, providers.count))", + "segment_gap": "1" + } + }, + { + "id": "antigravity-weekly-external-solo-dark-pace", + "name": "dark Antigravity External solo weekly segments pace tick", + "render": "system.dark && !antigravity.dual_mode && antigravity.external.opacity > 0.01", + "visibility": "(100) * antigravity.external.weekly.expected_available * display.show_pace * antigravity.external.opacity", + "parent": "antigravity-provider", + "x": "round((ceil(10 / max(1, providers.count)) * 11 - 2) * clamp(antigravity.external.weekly.expected_display, 0, 100) / 100)", + "y": "(27) - 1", + "width": "1", + "height": "(9) + 2", + "background": { + "type": "colour", + "colour": { + "color": "#FFFFFFFF", + "opacity": "0.9" + } + }, + "border": null, + "corner_radius": "0", + "layout": "freeform", + "align": "start", + "gap": "0", + "content": { + "type": "none" + } + }, + { + "id": "antigravity-weekly-external-solo-light", + "name": "light Antigravity External solo weekly segments", + "render": "(1 - system.dark) && !antigravity.dual_mode && antigravity.external.opacity > 0.01", + "visibility": "100 * antigravity.external.opacity", + "parent": "antigravity-provider", + "y": "27", + "width": "ceil(10 / max(1, providers.count)) * 11 - 1", + "height": "9", + "background": { + "type": "none" + }, + "border": null, + "corner_radius": "0", + "layout": "freeform", + "align": "start", + "gap": "0", + "content": { + "type": "progress", + "value": "antigravity.external.weekly.display", + "direction": "left_to_right", + "fill": { + "color": "#4A8B9EFF", + "opacity": "1" + }, + "track": { + "color": "#AAAAAAFF", + "opacity": "1" + }, + "corner_radius": "1.5", + "segments": 10, + "segments_expression": "ceil(10 / max(1, providers.count))", + "segment_gap": "1" + } + }, + { + "id": "antigravity-weekly-external-solo-light-pace", + "name": "light Antigravity External solo weekly segments pace tick", + "render": "(1 - system.dark) && !antigravity.dual_mode && antigravity.external.opacity > 0.01", + "visibility": "(100) * antigravity.external.weekly.expected_available * display.show_pace * antigravity.external.opacity", + "parent": "antigravity-provider", + "x": "round((ceil(10 / max(1, providers.count)) * 11 - 2) * clamp(antigravity.external.weekly.expected_display, 0, 100) / 100)", + "y": "(27) - 1", + "width": "1", + "height": "(9) + 2", + "background": { + "type": "colour", + "colour": { + "color": "#1A1A1AFF", + "opacity": "0.9" + } + }, + "border": null, + "corner_radius": "0", + "layout": "freeform", + "align": "start", + "gap": "0", + "content": { + "type": "none" + } + }, + { + "id": "antigravity-weekly-gemini-value-dark", + "name": "dark Antigravity Gemini weekly value", + "render": "system.dark && !antigravity.dual_mode && antigravity.gemini.opacity > 0.01", + "visibility": "100", + "parent": "antigravity-provider", + "x": "ceil(10 / max(1, providers.count)) * 11 - 1 + 4", + "y": "25", + "width": "62", + "height": "13", + "background": { + "type": "none" + }, + "border": null, + "corner_radius": "0", + "layout": "freeform", + "align": "start", + "gap": "0", + "content": { + "type": "text", + "template": "{antigravity.gemini.weekly.display:usage_line}", + "font_family": "Segoe UI", + "font_size": "12", + "weight": "medium", + "rendering": "clear_type", + "contrast": "1", + "align": "left", + "color": { + "color": "#5EEAD4FF", + "opacity": "antigravity.gemini.opacity" + } + } + }, + { + "id": "antigravity-weekly-gemini-value-light", + "name": "light Antigravity Gemini weekly value", + "render": "(1 - system.dark && !antigravity.dual_mode) && antigravity.gemini.opacity > 0.01", + "visibility": "100", + "parent": "antigravity-provider", + "x": "ceil(10 / max(1, providers.count)) * 11 - 1 + 4", + "y": "25", + "width": "62", + "height": "13", + "background": { + "type": "none" + }, + "border": null, + "corner_radius": "0", + "layout": "freeform", + "align": "start", + "gap": "0", + "content": { + "type": "text", + "template": "{antigravity.gemini.weekly.display:usage_line}", + "font_family": "Segoe UI", + "font_size": "12", + "weight": "medium", + "rendering": "clear_type", + "contrast": "1", + "align": "left", + "color": { + "color": "#007A6CFF", + "opacity": "antigravity.gemini.opacity" + } + } + }, + { + "id": "antigravity-weekly-external-value-dark", + "name": "dark Antigravity External weekly value", + "render": "system.dark && !antigravity.dual_mode && antigravity.external.opacity > 0.01", + "visibility": "100", + "parent": "antigravity-provider", + "x": "ceil(10 / max(1, providers.count)) * 11 - 1 + 4", + "y": "25", + "width": "62", + "height": "13", + "background": { + "type": "none" + }, + "border": null, + "corner_radius": "0", + "layout": "freeform", + "align": "start", + "gap": "0", + "content": { + "type": "text", + "template": "{antigravity.external.weekly.display:usage_line}", + "font_family": "Segoe UI", + "font_size": "12", + "weight": "medium", + "rendering": "clear_type", + "contrast": "1", + "align": "left", + "color": { + "color": "#98D0E0FF", + "opacity": "antigravity.external.opacity" + } + } + }, + { + "id": "antigravity-weekly-external-value-light", + "name": "light Antigravity External weekly value", + "render": "(1 - system.dark && !antigravity.dual_mode) && antigravity.external.opacity > 0.01", + "visibility": "100", + "parent": "antigravity-provider", + "x": "ceil(10 / max(1, providers.count)) * 11 - 1 + 4", + "y": "25", + "width": "62", + "height": "13", + "background": { + "type": "none" + }, + "border": null, + "corner_radius": "0", + "layout": "freeform", + "align": "start", + "gap": "0", + "content": { + "type": "text", + "template": "{antigravity.external.weekly.display:usage_line}", + "font_family": "Segoe UI", + "font_size": "12", + "weight": "medium", + "rendering": "clear_type", + "contrast": "1", + "align": "left", + "color": { + "color": "#2D6F82FF", + "opacity": "antigravity.external.opacity" + } + } + }, + { + "id": "opencode-provider", + "name": "OpenCode provider", + "render": "providers.opencode.enabled", + "visibility": "100", + "parent": "provider-row", + "width": "ceil(10 / max(1, providers.count)) * 11 - 1 + 4 + 90", + "height": "46", + "background": { + "type": "none" + }, + "border": null, + "corner_radius": "0", + "layout": "freeform", + "align": "start", + "gap": "0", + "content": { + "type": "none" + } + }, + { + "id": "opencode-session-segments-dark", + "name": "dark OpenCode 5-hour segments", + "render": "system.dark", + "visibility": "100", + "parent": "opencode-provider", + "y": "10", + "width": "ceil(10 / max(1, providers.count)) * 11 - 1", + "height": "9", + "background": { + "type": "none" + }, + "border": null, + "corner_radius": "0", + "layout": "freeform", + "align": "start", + "gap": "0", + "content": { + "type": "progress", + "value": "opencode.session.display", + "direction": "left_to_right", + "fill": { + "color": "#4CAF50FF", + "opacity": "1" + }, + "track": { + "color": "#444444FF", + "opacity": "1" + }, + "corner_radius": "1.5", + "segments": 10, + "segments_expression": "ceil(10 / max(1, providers.count))", + "segment_gap": "1" + } + }, + { + "id": "opencode-session-value-dark", + "name": "dark OpenCode 5-hour value", + "render": "system.dark", + "visibility": "100", + "parent": "opencode-provider", + "x": "ceil(10 / max(1, providers.count)) * 11 - 1 + 4", + "y": "8", + "width": "62", + "height": "13", + "background": { + "type": "none" + }, + "border": null, + "corner_radius": "0", + "layout": "freeform", + "align": "start", + "gap": "0", + "content": { + "type": "text", + "template": "{opencode.session.display:usage_line}", + "font_family": "Segoe UI", + "font_size": "12", + "weight": "medium", + "rendering": "clear_type", + "contrast": "1", + "align": "left", + "color": { + "color": "#81C784FF", + "opacity": "1" + } + } + }, + { + "id": "opencode-session-segments-light", + "name": "light OpenCode 5-hour segments", + "render": "1 - system.dark", + "visibility": "100", + "parent": "opencode-provider", + "y": "10", + "width": "ceil(10 / max(1, providers.count)) * 11 - 1", + "height": "9", + "background": { + "type": "none" + }, + "border": null, + "corner_radius": "0", + "layout": "freeform", + "align": "start", + "gap": "0", + "content": { + "type": "progress", + "value": "opencode.session.display", + "direction": "left_to_right", + "fill": { + "color": "#2E7D32FF", + "opacity": "1" + }, + "track": { + "color": "#AAAAAAFF", + "opacity": "1" + }, + "corner_radius": "1.5", + "segments": 10, + "segments_expression": "ceil(10 / max(1, providers.count))", + "segment_gap": "1" + } + }, + { + "id": "opencode-session-value-light", + "name": "light OpenCode 5-hour value", + "render": "1 - system.dark", + "visibility": "100", + "parent": "opencode-provider", + "x": "ceil(10 / max(1, providers.count)) * 11 - 1 + 4", + "y": "8", + "width": "62", + "height": "13", + "background": { + "type": "none" + }, + "border": null, + "corner_radius": "0", + "layout": "freeform", + "align": "start", + "gap": "0", + "content": { + "type": "text", + "template": "{opencode.session.display:usage_line}", + "font_family": "Segoe UI", + "font_size": "12", + "weight": "medium", + "rendering": "clear_type", + "contrast": "1", + "align": "left", + "color": { + "color": "#1B5E20FF", + "opacity": "1" + } + } + }, + { + "id": "opencode-weekly-segments-dark", + "name": "dark OpenCode long-window segments", + "render": "system.dark", + "visibility": "100", + "parent": "opencode-provider", + "y": "27", + "width": "ceil(10 / max(1, providers.count)) * 11 - 1", + "height": "9", + "background": { + "type": "none" + }, + "border": null, + "corner_radius": "0", + "layout": "freeform", + "align": "start", + "gap": "0", + "content": { + "type": "progress", + "value": "opencode.weekly.display", + "direction": "left_to_right", + "fill": { + "color": "#4CAF50FF", + "opacity": "1" + }, + "track": { + "color": "#444444FF", + "opacity": "1" + }, + "corner_radius": "1.5", + "segments": 10, + "segments_expression": "ceil(10 / max(1, providers.count))", + "segment_gap": "1" + } + }, + { + "id": "opencode-weekly-value-dark", + "name": "dark OpenCode long-window value", + "render": "system.dark", + "visibility": "100", + "parent": "opencode-provider", + "x": "ceil(10 / max(1, providers.count)) * 11 - 1 + 4", + "y": "25", + "width": "90", + "height": "13", + "background": { + "type": "none" + }, + "border": null, + "corner_radius": "0", + "layout": "freeform", + "align": "start", + "gap": "0", + "content": { + "type": "text", + "template": "{opencode.weekly.label} {opencode.weekly.display:usage_line}", + "font_family": "Segoe UI", + "font_size": "12", + "weight": "medium", + "rendering": "clear_type", + "contrast": "1", + "align": "left", + "color": { + "color": "#81C784FF", + "opacity": "1" + } + } + }, + { + "id": "opencode-weekly-segments-light", + "name": "light OpenCode long-window segments", + "render": "1 - system.dark", + "visibility": "100", + "parent": "opencode-provider", + "y": "27", + "width": "ceil(10 / max(1, providers.count)) * 11 - 1", + "height": "9", + "background": { + "type": "none" + }, + "border": null, + "corner_radius": "0", + "layout": "freeform", + "align": "start", + "gap": "0", + "content": { + "type": "progress", + "value": "opencode.weekly.display", + "direction": "left_to_right", + "fill": { + "color": "#2E7D32FF", + "opacity": "1" + }, + "track": { + "color": "#AAAAAAFF", + "opacity": "1" + }, + "corner_radius": "1.5", + "segments": 10, + "segments_expression": "ceil(10 / max(1, providers.count))", + "segment_gap": "1" + } + }, + { + "id": "opencode-weekly-value-light", + "name": "light OpenCode long-window value", + "render": "1 - system.dark", + "visibility": "100", + "parent": "opencode-provider", + "x": "ceil(10 / max(1, providers.count)) * 11 - 1 + 4", + "y": "25", + "width": "90", + "height": "13", + "background": { + "type": "none" + }, + "border": null, + "corner_radius": "0", + "layout": "freeform", + "align": "start", + "gap": "0", + "content": { + "type": "text", + "template": "{opencode.weekly.label} {opencode.weekly.display:usage_line}", + "font_family": "Segoe UI", + "font_size": "12", + "weight": "medium", + "rendering": "clear_type", + "contrast": "1", + "align": "left", + "color": { + "color": "#1B5E20FF", + "opacity": "1" + } + } + }, + { + "id": "claude-credits-segments-dark", + "name": "dark claude credit overlay", + "render": "((system.dark) && claude.credits.available) && (!claude.dual_mode)", + "visibility": "100", + "parent": "claude-provider", + "y": "27", + "width": "ceil(10 / max(1, providers.count)) * 11 - 1", + "height": "9", + "background": { + "type": "none" + }, + "border": null, + "corner_radius": "0", + "layout": "freeform", + "align": "start", + "gap": "0", + "content": { + "type": "progress", + "value": "claude.credits.display", + "direction": "left_to_right", + "fill": { + "color": "#F5A623FF", + "opacity": "1" + }, + "track": { + "color": "#00000000", + "opacity": "0" + }, + "corner_radius": "1.5", + "segments": 10, + "segments_expression": "ceil(10 / max(1, providers.count))", + "segment_gap": "1" + } + }, + { + "id": "claude-credits-value-dark", + "name": "dark claude credit balance", + "render": "((system.dark) && claude.credits.available) && (!claude.dual_mode)", + "visibility": "100", + "parent": "claude-provider", + "x": "ceil(10 / max(1, providers.count)) * 11 - 1 + 4", + "y": "25", + "width": "62", + "height": "13", + "background": { + "type": "none" + }, + "border": null, + "corner_radius": "0", + "layout": "freeform", + "align": "start", + "gap": "0", + "content": { + "type": "text", + "template": "${claude.credits.balance:0.00}", + "font_family": "Segoe UI", + "font_size": "12", + "weight": "medium", + "rendering": "clear_type", + "contrast": "1", + "align": "left", + "color": { + "color": "#F5A623FF", + "opacity": "1" + } + } + }, + { + "id": "claude-credits-segments-light", + "name": "light claude credit overlay", + "render": "((1 - system.dark) && claude.credits.available) && (!claude.dual_mode)", + "visibility": "100", + "parent": "claude-provider", + "y": "27", + "width": "ceil(10 / max(1, providers.count)) * 11 - 1", + "height": "9", + "background": { + "type": "none" + }, + "border": null, + "corner_radius": "0", + "layout": "freeform", + "align": "start", + "gap": "0", + "content": { + "type": "progress", + "value": "claude.credits.display", + "direction": "left_to_right", + "fill": { + "color": "#C77700FF", + "opacity": "1" + }, + "track": { + "color": "#00000000", + "opacity": "0" + }, + "corner_radius": "1.5", + "segments": 10, + "segments_expression": "ceil(10 / max(1, providers.count))", + "segment_gap": "1" + } + }, + { + "id": "claude-credits-value-light", + "name": "light claude credit balance", + "render": "((1 - system.dark) && claude.credits.available) && (!claude.dual_mode)", + "visibility": "100", + "parent": "claude-provider", + "x": "ceil(10 / max(1, providers.count)) * 11 - 1 + 4", + "y": "25", + "width": "62", + "height": "13", + "background": { + "type": "none" + }, + "border": null, + "corner_radius": "0", + "layout": "freeform", + "align": "start", + "gap": "0", + "content": { + "type": "text", + "template": "${claude.credits.balance:0.00}", + "font_family": "Segoe UI", + "font_size": "12", + "weight": "medium", + "rendering": "clear_type", + "contrast": "1", + "align": "left", + "color": { + "color": "#C77700FF", + "opacity": "1" + } + } + }, + { + "id": "claude-main-marker-dark-normal", + "name": "dark Claude Main marker o normal", + "render": "(system.dark) && (claude.dual_mode) && (claude.normal.opacity > 0.01)", + "visibility": "100", + "parent": "claude-provider", + "x": "0", + "y": "7", + "width": "10", + "height": "13", + "background": { + "type": "none" + }, + "border": null, + "corner_radius": "0", + "layout": "freeform", + "align": "start", + "gap": "0", + "content": { + "type": "text", + "template": "o", + "font_family": "Segoe UI", + "font_size": "12", + "weight": "medium", + "rendering": "clear_type", + "contrast": "1", + "align": "left", + "color": { + "color": "#D97757FF", + "opacity": "claude.normal.opacity" + } + } + }, + { + "id": "claude-main-marker-dark-hover", + "name": "dark Claude Main marker o hover", + "render": "(system.dark) && (claude.dual_mode) && (claude.hover.opacity > 0.01)", + "visibility": "100", + "parent": "claude-provider", + "x": "0", + "y": "7", + "width": "10", + "height": "13", + "background": { + "type": "none" + }, + "border": null, + "corner_radius": "0", + "layout": "freeform", + "align": "start", + "gap": "0", + "content": { + "type": "text", + "template": "o", + "font_family": "Segoe UI", + "font_size": "12", + "weight": "medium", + "rendering": "clear_type", + "contrast": "1", + "align": "left", + "color": { + "color": "#C45A38FF", + "opacity": "claude.hover.opacity" + } + } + }, + { + "id": "claude-main-marker-light-normal", + "name": "light Claude Main marker o normal", + "render": "((1 - system.dark)) && (claude.dual_mode) && (claude.normal.opacity > 0.01)", + "visibility": "100", + "parent": "claude-provider", + "x": "0", + "y": "7", + "width": "10", + "height": "13", + "background": { + "type": "none" + }, + "border": null, + "corner_radius": "0", + "layout": "freeform", + "align": "start", + "gap": "0", + "content": { + "type": "text", + "template": "o", + "font_family": "Segoe UI", + "font_size": "12", + "weight": "medium", + "rendering": "clear_type", + "contrast": "1", + "align": "left", + "color": { + "color": "#A94F32FF", + "opacity": "claude.normal.opacity" + } + } + }, + { + "id": "claude-main-marker-light-hover", + "name": "light Claude Main marker o hover", + "render": "((1 - system.dark)) && (claude.dual_mode) && (claude.hover.opacity > 0.01)", + "visibility": "100", + "parent": "claude-provider", + "x": "0", + "y": "7", + "width": "10", + "height": "13", + "background": { + "type": "none" + }, + "border": null, + "corner_radius": "0", + "layout": "freeform", + "align": "start", + "gap": "0", + "content": { + "type": "text", + "template": "o", + "font_family": "Segoe UI", + "font_size": "12", + "weight": "medium", + "rendering": "clear_type", + "contrast": "1", + "align": "left", + "color": { + "color": "#7C2D12FF", + "opacity": "claude.hover.opacity" + } + } + }, + { + "id": "claude-main-5h-dark-normal", + "name": "dark Claude Main 5h normal", + "render": "(system.dark) && (claude.dual_mode) && (claude.normal.opacity > 0.01)", + "visibility": "100 * claude.normal.opacity", + "parent": "claude-provider", + "x": "12", + "y": "8", + "width": "ceil(10 / max(1, providers.count)) * 11 - 1", + "height": "6", + "background": { + "type": "none" + }, + "border": null, + "corner_radius": "0", + "layout": "freeform", + "align": "start", + "gap": "0", + "content": { + "type": "progress", + "value": "accounts.claude.default.session.display", + "direction": "left_to_right", + "fill": { + "color": "#D97757FF", + "opacity": "1" + }, + "track": { + "color": "#444444FF", + "opacity": "1" + }, + "corner_radius": "1.5", + "segments": 10, + "segments_expression": "ceil(10 / max(1, providers.count))", + "segment_gap": "1" + } + }, + { + "id": "claude-main-5h-dark-normal-pace", + "name": "dark Claude Main 5h normal pace tick", + "render": "(system.dark) && (claude.dual_mode) && (claude.normal.opacity > 0.01)", + "visibility": "(100) * accounts.claude.default.session.expected_available * display.show_pace * claude.normal.opacity", + "parent": "claude-provider", + "x": "12 + round((ceil(10 / max(1, providers.count)) * 11 - 2) * clamp(accounts.claude.default.session.expected_display, 0, 100) / 100)", + "y": "7", + "width": "1", + "height": "8", + "background": { + "type": "colour", + "colour": { + "color": "#FFFFFFFF", + "opacity": "0.9" + } + }, + "border": null, + "corner_radius": "0", + "layout": "freeform", + "align": "start", + "gap": "0", + "content": { + "type": "none" + } + }, + { + "id": "claude-main-5h-dark-hover", + "name": "dark Claude Main 5h hover", + "render": "(system.dark) && (claude.dual_mode) && (claude.hover.opacity > 0.01)", + "visibility": "100 * claude.hover.opacity", + "parent": "claude-provider", + "x": "12", + "y": "8", + "width": "ceil(10 / max(1, providers.count)) * 11 - 1", + "height": "3", + "background": { + "type": "none" + }, + "border": null, + "corner_radius": "0", + "layout": "freeform", + "align": "start", + "gap": "0", + "content": { + "type": "progress", + "value": "accounts.claude.default.session.display", + "direction": "left_to_right", + "fill": { + "color": "#D97757FF", + "opacity": "1" + }, + "track": { + "color": "#444444FF", + "opacity": "1" + }, + "corner_radius": "1.5", + "segments": 10, + "segments_expression": "ceil(10 / max(1, providers.count))", + "segment_gap": "1" + } + }, + { + "id": "claude-main-5h-dark-hover-pace", + "name": "dark Claude Main 5h hover pace tick", + "render": "(system.dark) && (claude.dual_mode) && (claude.hover.opacity > 0.01)", + "visibility": "(100) * accounts.claude.default.session.expected_available * display.show_pace * claude.hover.opacity", + "parent": "claude-provider", + "x": "12 + round((ceil(10 / max(1, providers.count)) * 11 - 2) * clamp(accounts.claude.default.session.expected_display, 0, 100) / 100)", + "y": "7", + "width": "1", + "height": "5", + "background": { + "type": "colour", + "colour": { + "color": "#FFFFFFFF", + "opacity": "0.9" + } + }, + "border": null, + "corner_radius": "0", + "layout": "freeform", + "align": "start", + "gap": "0", + "content": { + "type": "none" + } + }, + { + "id": "claude-main-5h-light-normal", + "name": "light Claude Main 5h normal", + "render": "((1 - system.dark)) && (claude.dual_mode) && (claude.normal.opacity > 0.01)", + "visibility": "100 * claude.normal.opacity", + "parent": "claude-provider", + "x": "12", + "y": "8", + "width": "ceil(10 / max(1, providers.count)) * 11 - 1", + "height": "6", + "background": { + "type": "none" + }, + "border": null, + "corner_radius": "0", + "layout": "freeform", + "align": "start", + "gap": "0", + "content": { + "type": "progress", + "value": "accounts.claude.default.session.display", + "direction": "left_to_right", + "fill": { + "color": "#D97757FF", + "opacity": "1" + }, + "track": { + "color": "#AAAAAAFF", + "opacity": "1" + }, + "corner_radius": "1.5", + "segments": 10, + "segments_expression": "ceil(10 / max(1, providers.count))", + "segment_gap": "1" + } + }, + { + "id": "claude-main-5h-light-normal-pace", + "name": "light Claude Main 5h normal pace tick", + "render": "((1 - system.dark)) && (claude.dual_mode) && (claude.normal.opacity > 0.01)", + "visibility": "(100) * accounts.claude.default.session.expected_available * display.show_pace * claude.normal.opacity", + "parent": "claude-provider", + "x": "12 + round((ceil(10 / max(1, providers.count)) * 11 - 2) * clamp(accounts.claude.default.session.expected_display, 0, 100) / 100)", + "y": "7", + "width": "1", + "height": "8", + "background": { + "type": "colour", + "colour": { + "color": "#1A1A1AFF", + "opacity": "0.9" + } + }, + "border": null, + "corner_radius": "0", + "layout": "freeform", + "align": "start", + "gap": "0", + "content": { + "type": "none" + } + }, + { + "id": "claude-main-5h-light-hover", + "name": "light Claude Main 5h hover", + "render": "((1 - system.dark)) && (claude.dual_mode) && (claude.hover.opacity > 0.01)", + "visibility": "100 * claude.hover.opacity", + "parent": "claude-provider", + "x": "12", + "y": "8", + "width": "ceil(10 / max(1, providers.count)) * 11 - 1", + "height": "3", + "background": { + "type": "none" + }, + "border": null, + "corner_radius": "0", + "layout": "freeform", + "align": "start", + "gap": "0", + "content": { + "type": "progress", + "value": "accounts.claude.default.session.display", + "direction": "left_to_right", + "fill": { + "color": "#D97757FF", + "opacity": "1" + }, + "track": { + "color": "#AAAAAAFF", + "opacity": "1" + }, + "corner_radius": "1.5", + "segments": 10, + "segments_expression": "ceil(10 / max(1, providers.count))", + "segment_gap": "1" + } + }, + { + "id": "claude-main-5h-light-hover-pace", + "name": "light Claude Main 5h hover pace tick", + "render": "((1 - system.dark)) && (claude.dual_mode) && (claude.hover.opacity > 0.01)", + "visibility": "(100) * accounts.claude.default.session.expected_available * display.show_pace * claude.hover.opacity", + "parent": "claude-provider", + "x": "12 + round((ceil(10 / max(1, providers.count)) * 11 - 2) * clamp(accounts.claude.default.session.expected_display, 0, 100) / 100)", + "y": "7", + "width": "1", + "height": "5", + "background": { + "type": "colour", + "colour": { + "color": "#1A1A1AFF", + "opacity": "0.9" + } + }, + "border": null, + "corner_radius": "0", + "layout": "freeform", + "align": "start", + "gap": "0", + "content": { + "type": "none" + } + }, + { + "id": "claude-main-7d-dark-normal", + "name": "dark Claude Main 7d normal", + "render": "(system.dark) && (claude.dual_mode) && (claude.normal.opacity > 0.01)", + "visibility": "100 * claude.normal.opacity", + "parent": "claude-provider", + "x": "12", + "y": "16", + "width": "ceil(10 / max(1, providers.count)) * 11 - 1", + "height": "3", + "background": { + "type": "none" + }, + "border": null, + "corner_radius": "0", + "layout": "freeform", + "align": "start", + "gap": "0", + "content": { + "type": "progress", + "value": "accounts.claude.default.weekly.display", + "direction": "left_to_right", + "fill": { + "color": "#A44525FF", + "opacity": "1" + }, + "track": { + "color": "#333333FF", + "opacity": "1" + }, + "corner_radius": "1.5", + "segments": 10, + "segments_expression": "ceil(10 / max(1, providers.count))", + "segment_gap": "1" + } + }, + { + "id": "claude-main-7d-dark-normal-pace", + "name": "dark Claude Main 7d normal pace tick", + "render": "(system.dark) && (claude.dual_mode) && (claude.normal.opacity > 0.01)", + "visibility": "(100) * accounts.claude.default.weekly.expected_available * display.show_pace * claude.normal.opacity", + "parent": "claude-provider", + "x": "12 + round((ceil(10 / max(1, providers.count)) * 11 - 2) * clamp(accounts.claude.default.weekly.expected_display, 0, 100) / 100)", + "y": "15", + "width": "1", + "height": "5", + "background": { + "type": "colour", + "colour": { + "color": "#FFFFFFFF", + "opacity": "0.9" + } + }, + "border": null, + "corner_radius": "0", + "layout": "freeform", + "align": "start", + "gap": "0", + "content": { + "type": "none" + } + }, + { + "id": "claude-main-7d-dark-hover", + "name": "dark Claude Main 7d hover", + "render": "(system.dark) && (claude.dual_mode) && (claude.hover.opacity > 0.01)", + "visibility": "100 * claude.hover.opacity", + "parent": "claude-provider", + "x": "12", + "y": "13", + "width": "ceil(10 / max(1, providers.count)) * 11 - 1", + "height": "6", + "background": { + "type": "none" + }, + "border": null, + "corner_radius": "0", + "layout": "freeform", + "align": "start", + "gap": "0", + "content": { + "type": "progress", + "value": "accounts.claude.default.weekly.display", + "direction": "left_to_right", + "fill": { + "color": "#A44525FF", + "opacity": "1" + }, + "track": { + "color": "#333333FF", + "opacity": "1" + }, + "corner_radius": "1.5", + "segments": 10, + "segments_expression": "ceil(10 / max(1, providers.count))", + "segment_gap": "1" + } + }, + { + "id": "claude-main-7d-dark-hover-pace", + "name": "dark Claude Main 7d hover pace tick", + "render": "(system.dark) && (claude.dual_mode) && (claude.hover.opacity > 0.01)", + "visibility": "(100) * accounts.claude.default.weekly.expected_available * display.show_pace * claude.hover.opacity", + "parent": "claude-provider", + "x": "12 + round((ceil(10 / max(1, providers.count)) * 11 - 2) * clamp(accounts.claude.default.weekly.expected_display, 0, 100) / 100)", + "y": "12", + "width": "1", + "height": "8", + "background": { + "type": "colour", + "colour": { + "color": "#FFFFFFFF", + "opacity": "0.9" + } + }, + "border": null, + "corner_radius": "0", + "layout": "freeform", + "align": "start", + "gap": "0", + "content": { + "type": "none" + } + }, + { + "id": "claude-main-7d-light-normal", + "name": "light Claude Main 7d normal", + "render": "((1 - system.dark)) && (claude.dual_mode) && (claude.normal.opacity > 0.01)", + "visibility": "100 * claude.normal.opacity", + "parent": "claude-provider", + "x": "12", + "y": "16", + "width": "ceil(10 / max(1, providers.count)) * 11 - 1", + "height": "3", + "background": { + "type": "none" + }, + "border": null, + "corner_radius": "0", + "layout": "freeform", + "align": "start", + "gap": "0", + "content": { + "type": "progress", + "value": "accounts.claude.default.weekly.display", + "direction": "left_to_right", + "fill": { + "color": "#7C2D12FF", + "opacity": "1" + }, + "track": { + "color": "#CCCCCCFF", + "opacity": "1" + }, + "corner_radius": "1.5", + "segments": 10, + "segments_expression": "ceil(10 / max(1, providers.count))", + "segment_gap": "1" + } + }, + { + "id": "claude-main-7d-light-normal-pace", + "name": "light Claude Main 7d normal pace tick", + "render": "((1 - system.dark)) && (claude.dual_mode) && (claude.normal.opacity > 0.01)", + "visibility": "(100) * accounts.claude.default.weekly.expected_available * display.show_pace * claude.normal.opacity", + "parent": "claude-provider", + "x": "12 + round((ceil(10 / max(1, providers.count)) * 11 - 2) * clamp(accounts.claude.default.weekly.expected_display, 0, 100) / 100)", + "y": "15", + "width": "1", + "height": "5", + "background": { + "type": "colour", + "colour": { + "color": "#1A1A1AFF", + "opacity": "0.9" + } + }, + "border": null, + "corner_radius": "0", + "layout": "freeform", + "align": "start", + "gap": "0", + "content": { + "type": "none" + } + }, + { + "id": "claude-main-7d-light-hover", + "name": "light Claude Main 7d hover", + "render": "((1 - system.dark)) && (claude.dual_mode) && (claude.hover.opacity > 0.01)", + "visibility": "100 * claude.hover.opacity", + "parent": "claude-provider", + "x": "12", + "y": "13", + "width": "ceil(10 / max(1, providers.count)) * 11 - 1", + "height": "6", + "background": { + "type": "none" + }, + "border": null, + "corner_radius": "0", + "layout": "freeform", + "align": "start", + "gap": "0", + "content": { + "type": "progress", + "value": "accounts.claude.default.weekly.display", + "direction": "left_to_right", + "fill": { + "color": "#7C2D12FF", + "opacity": "1" + }, + "track": { + "color": "#CCCCCCFF", + "opacity": "1" + }, + "corner_radius": "1.5", + "segments": 10, + "segments_expression": "ceil(10 / max(1, providers.count))", + "segment_gap": "1" + } + }, + { + "id": "claude-main-7d-light-hover-pace", + "name": "light Claude Main 7d hover pace tick", + "render": "((1 - system.dark)) && (claude.dual_mode) && (claude.hover.opacity > 0.01)", + "visibility": "(100) * accounts.claude.default.weekly.expected_available * display.show_pace * claude.hover.opacity", + "parent": "claude-provider", + "x": "12 + round((ceil(10 / max(1, providers.count)) * 11 - 2) * clamp(accounts.claude.default.weekly.expected_display, 0, 100) / 100)", + "y": "12", + "width": "1", + "height": "8", + "background": { + "type": "colour", + "colour": { + "color": "#1A1A1AFF", + "opacity": "0.9" + } + }, + "border": null, + "corner_radius": "0", + "layout": "freeform", + "align": "start", + "gap": "0", + "content": { + "type": "none" + } + }, + { + "id": "claude-main-text-dark-normal", + "name": "dark Claude Main text 5h", + "render": "(system.dark) && (claude.dual_mode) && (claude.normal.opacity > 0.01)", + "visibility": "100", + "parent": "claude-provider", + "x": "12 + ceil(10 / max(1, providers.count)) * 11 - 1 + 4", + "y": "7", + "width": "62", + "height": "13", + "background": { + "type": "none" + }, + "border": null, + "corner_radius": "0", + "layout": "freeform", + "align": "start", + "gap": "0", + "content": { + "type": "text", + "template": "{accounts.claude.default.session.display:usage_line}", + "font_family": "Segoe UI", + "font_size": "12", + "weight": "medium", + "rendering": "clear_type", + "contrast": "1", + "align": "left", + "color": { + "color": "#F09A7AFF", + "opacity": "claude.normal.opacity" + } + } + }, + { + "id": "claude-main-text-dark-hover", + "name": "dark Claude Main text 7d", + "render": "(system.dark) && (claude.dual_mode) && (claude.hover.opacity > 0.01)", + "visibility": "100", + "parent": "claude-provider", + "x": "12 + ceil(10 / max(1, providers.count)) * 11 - 1 + 4", + "y": "7", + "width": "62", + "height": "13", + "background": { + "type": "none" + }, + "border": null, + "corner_radius": "0", + "layout": "freeform", + "align": "start", + "gap": "0", + "content": { + "type": "text", + "template": "{accounts.claude.default.weekly.display:usage_line}", + "font_family": "Segoe UI", + "font_size": "12", + "weight": "medium", + "rendering": "clear_type", + "contrast": "1", + "align": "left", + "color": { + "color": "#D97757FF", + "opacity": "claude.hover.opacity" + } + } + }, + { + "id": "claude-main-text-light-normal", + "name": "light Claude Main text 5h", + "render": "((1 - system.dark)) && (claude.dual_mode) && (claude.normal.opacity > 0.01)", + "visibility": "100", + "parent": "claude-provider", + "x": "12 + ceil(10 / max(1, providers.count)) * 11 - 1 + 4", + "y": "7", + "width": "62", + "height": "13", + "background": { + "type": "none" + }, + "border": null, + "corner_radius": "0", + "layout": "freeform", + "align": "start", + "gap": "0", + "content": { + "type": "text", + "template": "{accounts.claude.default.session.display:usage_line}", + "font_family": "Segoe UI", + "font_size": "12", + "weight": "medium", + "rendering": "clear_type", + "contrast": "1", + "align": "left", + "color": { + "color": "#A94F32FF", + "opacity": "claude.normal.opacity" + } + } + }, + { + "id": "claude-main-text-light-hover", + "name": "light Claude Main text 7d", + "render": "((1 - system.dark)) && (claude.dual_mode) && (claude.hover.opacity > 0.01)", + "visibility": "100", + "parent": "claude-provider", + "x": "12 + ceil(10 / max(1, providers.count)) * 11 - 1 + 4", + "y": "7", + "width": "62", + "height": "13", + "background": { + "type": "none" + }, + "border": null, + "corner_radius": "0", + "layout": "freeform", + "align": "start", + "gap": "0", + "content": { + "type": "text", + "template": "{accounts.claude.default.weekly.display:usage_line}", + "font_family": "Segoe UI", + "font_size": "12", + "weight": "medium", + "rendering": "clear_type", + "contrast": "1", + "align": "left", + "color": { + "color": "#7C2D12FF", + "opacity": "claude.hover.opacity" + } + } + }, + { + "id": "claude-x-marker-dark-normal", + "name": "dark Claude X marker x normal", + "render": "(system.dark) && (claude.dual_mode) && (claude.normal.opacity > 0.01)", + "visibility": "100", + "parent": "claude-provider", + "x": "0", + "y": "26", + "width": "10", + "height": "13", + "background": { + "type": "none" + }, + "border": null, + "corner_radius": "0", + "layout": "freeform", + "align": "start", + "gap": "0", + "content": { + "type": "text", + "template": "x", + "font_family": "Segoe UI", + "font_size": "12", + "weight": "medium", + "rendering": "clear_type", + "contrast": "1", + "align": "left", + "color": { + "color": "#D97757FF", + "opacity": "claude.normal.opacity" + } + } + }, + { + "id": "claude-x-marker-dark-hover", + "name": "dark Claude X marker x hover", + "render": "(system.dark) && (claude.dual_mode) && (claude.hover.opacity > 0.01)", + "visibility": "100", + "parent": "claude-provider", + "x": "0", + "y": "26", + "width": "10", + "height": "13", + "background": { + "type": "none" + }, + "border": null, + "corner_radius": "0", + "layout": "freeform", + "align": "start", + "gap": "0", + "content": { + "type": "text", + "template": "x", + "font_family": "Segoe UI", + "font_size": "12", + "weight": "medium", + "rendering": "clear_type", + "contrast": "1", + "align": "left", + "color": { + "color": "#C45A38FF", + "opacity": "claude.hover.opacity" + } + } + }, + { + "id": "claude-x-marker-light-normal", + "name": "light Claude X marker x normal", + "render": "((1 - system.dark)) && (claude.dual_mode) && (claude.normal.opacity > 0.01)", + "visibility": "100", + "parent": "claude-provider", + "x": "0", + "y": "26", + "width": "10", + "height": "13", + "background": { + "type": "none" + }, + "border": null, + "corner_radius": "0", + "layout": "freeform", + "align": "start", + "gap": "0", + "content": { + "type": "text", + "template": "x", + "font_family": "Segoe UI", + "font_size": "12", + "weight": "medium", + "rendering": "clear_type", + "contrast": "1", + "align": "left", + "color": { + "color": "#A94F32FF", + "opacity": "claude.normal.opacity" + } + } + }, + { + "id": "claude-x-marker-light-hover", + "name": "light Claude X marker x hover", + "render": "((1 - system.dark)) && (claude.dual_mode) && (claude.hover.opacity > 0.01)", + "visibility": "100", + "parent": "claude-provider", + "x": "0", + "y": "26", + "width": "10", + "height": "13", + "background": { + "type": "none" + }, + "border": null, + "corner_radius": "0", + "layout": "freeform", + "align": "start", + "gap": "0", + "content": { + "type": "text", + "template": "x", + "font_family": "Segoe UI", + "font_size": "12", + "weight": "medium", + "rendering": "clear_type", + "contrast": "1", + "align": "left", + "color": { + "color": "#7C2D12FF", + "opacity": "claude.hover.opacity" + } + } + }, + { + "id": "claude-x-5h-dark-normal", + "name": "dark Claude X 5h normal", + "render": "(system.dark) && (claude.dual_mode) && (claude.normal.opacity > 0.01)", + "visibility": "100 * claude.normal.opacity", + "parent": "claude-provider", + "x": "12", + "y": "27", + "width": "ceil(10 / max(1, providers.count)) * 11 - 1", + "height": "6", + "background": { + "type": "none" + }, + "border": null, + "corner_radius": "0", + "layout": "freeform", + "align": "start", + "gap": "0", + "content": { + "type": "progress", + "value": "accounts.claude.claude_x.session.display", + "direction": "left_to_right", + "fill": { + "color": "#D97757FF", + "opacity": "1" + }, + "track": { + "color": "#444444FF", + "opacity": "1" + }, + "corner_radius": "1.5", + "segments": 10, + "segments_expression": "ceil(10 / max(1, providers.count))", + "segment_gap": "1" + } + }, + { + "id": "claude-x-5h-dark-normal-pace", + "name": "dark Claude X 5h normal pace tick", + "render": "(system.dark) && (claude.dual_mode) && (claude.normal.opacity > 0.01)", + "visibility": "(100) * accounts.claude.claude_x.session.expected_available * display.show_pace * claude.normal.opacity", + "parent": "claude-provider", + "x": "12 + round((ceil(10 / max(1, providers.count)) * 11 - 2) * clamp(accounts.claude.claude_x.session.expected_display, 0, 100) / 100)", + "y": "26", + "width": "1", + "height": "8", + "background": { + "type": "colour", + "colour": { + "color": "#FFFFFFFF", + "opacity": "0.9" + } + }, + "border": null, + "corner_radius": "0", + "layout": "freeform", + "align": "start", + "gap": "0", + "content": { + "type": "none" + } + }, + { + "id": "claude-x-5h-dark-hover", + "name": "dark Claude X 5h hover", + "render": "(system.dark) && (claude.dual_mode) && (claude.hover.opacity > 0.01)", + "visibility": "100 * claude.hover.opacity", + "parent": "claude-provider", + "x": "12", + "y": "27", + "width": "ceil(10 / max(1, providers.count)) * 11 - 1", + "height": "3", + "background": { + "type": "none" + }, + "border": null, + "corner_radius": "0", + "layout": "freeform", + "align": "start", + "gap": "0", + "content": { + "type": "progress", + "value": "accounts.claude.claude_x.session.display", + "direction": "left_to_right", + "fill": { + "color": "#D97757FF", + "opacity": "1" + }, + "track": { + "color": "#444444FF", + "opacity": "1" + }, + "corner_radius": "1.5", + "segments": 10, + "segments_expression": "ceil(10 / max(1, providers.count))", + "segment_gap": "1" + } + }, + { + "id": "claude-x-5h-dark-hover-pace", + "name": "dark Claude X 5h hover pace tick", + "render": "(system.dark) && (claude.dual_mode) && (claude.hover.opacity > 0.01)", + "visibility": "(100) * accounts.claude.claude_x.session.expected_available * display.show_pace * claude.hover.opacity", + "parent": "claude-provider", + "x": "12 + round((ceil(10 / max(1, providers.count)) * 11 - 2) * clamp(accounts.claude.claude_x.session.expected_display, 0, 100) / 100)", + "y": "26", + "width": "1", + "height": "5", + "background": { + "type": "colour", + "colour": { + "color": "#FFFFFFFF", + "opacity": "0.9" + } + }, + "border": null, + "corner_radius": "0", + "layout": "freeform", + "align": "start", + "gap": "0", + "content": { + "type": "none" + } + }, + { + "id": "claude-x-5h-light-normal", + "name": "light Claude X 5h normal", + "render": "((1 - system.dark)) && (claude.dual_mode) && (claude.normal.opacity > 0.01)", + "visibility": "100 * claude.normal.opacity", + "parent": "claude-provider", + "x": "12", + "y": "27", + "width": "ceil(10 / max(1, providers.count)) * 11 - 1", + "height": "6", + "background": { + "type": "none" + }, + "border": null, + "corner_radius": "0", + "layout": "freeform", + "align": "start", + "gap": "0", + "content": { + "type": "progress", + "value": "accounts.claude.claude_x.session.display", + "direction": "left_to_right", + "fill": { + "color": "#D97757FF", + "opacity": "1" + }, + "track": { + "color": "#AAAAAAFF", + "opacity": "1" + }, + "corner_radius": "1.5", + "segments": 10, + "segments_expression": "ceil(10 / max(1, providers.count))", + "segment_gap": "1" + } + }, + { + "id": "claude-x-5h-light-normal-pace", + "name": "light Claude X 5h normal pace tick", + "render": "((1 - system.dark)) && (claude.dual_mode) && (claude.normal.opacity > 0.01)", + "visibility": "(100) * accounts.claude.claude_x.session.expected_available * display.show_pace * claude.normal.opacity", + "parent": "claude-provider", + "x": "12 + round((ceil(10 / max(1, providers.count)) * 11 - 2) * clamp(accounts.claude.claude_x.session.expected_display, 0, 100) / 100)", + "y": "26", + "width": "1", + "height": "8", + "background": { + "type": "colour", + "colour": { + "color": "#1A1A1AFF", + "opacity": "0.9" + } + }, + "border": null, + "corner_radius": "0", + "layout": "freeform", + "align": "start", + "gap": "0", + "content": { + "type": "none" + } + }, + { + "id": "claude-x-5h-light-hover", + "name": "light Claude X 5h hover", + "render": "((1 - system.dark)) && (claude.dual_mode) && (claude.hover.opacity > 0.01)", + "visibility": "100 * claude.hover.opacity", + "parent": "claude-provider", + "x": "12", + "y": "27", + "width": "ceil(10 / max(1, providers.count)) * 11 - 1", + "height": "3", + "background": { + "type": "none" + }, + "border": null, + "corner_radius": "0", + "layout": "freeform", + "align": "start", + "gap": "0", + "content": { + "type": "progress", + "value": "accounts.claude.claude_x.session.display", + "direction": "left_to_right", + "fill": { + "color": "#D97757FF", + "opacity": "1" + }, + "track": { + "color": "#AAAAAAFF", + "opacity": "1" + }, + "corner_radius": "1.5", + "segments": 10, + "segments_expression": "ceil(10 / max(1, providers.count))", + "segment_gap": "1" + } + }, + { + "id": "claude-x-5h-light-hover-pace", + "name": "light Claude X 5h hover pace tick", + "render": "((1 - system.dark)) && (claude.dual_mode) && (claude.hover.opacity > 0.01)", + "visibility": "(100) * accounts.claude.claude_x.session.expected_available * display.show_pace * claude.hover.opacity", + "parent": "claude-provider", + "x": "12 + round((ceil(10 / max(1, providers.count)) * 11 - 2) * clamp(accounts.claude.claude_x.session.expected_display, 0, 100) / 100)", + "y": "26", + "width": "1", + "height": "5", + "background": { + "type": "colour", + "colour": { + "color": "#1A1A1AFF", + "opacity": "0.9" + } + }, + "border": null, + "corner_radius": "0", + "layout": "freeform", + "align": "start", + "gap": "0", + "content": { + "type": "none" + } + }, + { + "id": "claude-x-7d-dark-normal", + "name": "dark Claude X 7d normal", + "render": "(system.dark) && (claude.dual_mode) && (claude.normal.opacity > 0.01)", + "visibility": "100 * claude.normal.opacity", + "parent": "claude-provider", + "x": "12", + "y": "35", + "width": "ceil(10 / max(1, providers.count)) * 11 - 1", + "height": "3", + "background": { + "type": "none" + }, + "border": null, + "corner_radius": "0", + "layout": "freeform", + "align": "start", + "gap": "0", + "content": { + "type": "progress", + "value": "accounts.claude.claude_x.weekly.display", + "direction": "left_to_right", + "fill": { + "color": "#A44525FF", + "opacity": "1" + }, + "track": { + "color": "#333333FF", + "opacity": "1" + }, + "corner_radius": "1.5", + "segments": 10, + "segments_expression": "ceil(10 / max(1, providers.count))", + "segment_gap": "1" + } + }, + { + "id": "claude-x-7d-dark-normal-pace", + "name": "dark Claude X 7d normal pace tick", + "render": "(system.dark) && (claude.dual_mode) && (claude.normal.opacity > 0.01)", + "visibility": "(100) * accounts.claude.claude_x.weekly.expected_available * display.show_pace * claude.normal.opacity", + "parent": "claude-provider", + "x": "12 + round((ceil(10 / max(1, providers.count)) * 11 - 2) * clamp(accounts.claude.claude_x.weekly.expected_display, 0, 100) / 100)", + "y": "34", + "width": "1", + "height": "5", + "background": { + "type": "colour", + "colour": { + "color": "#FFFFFFFF", + "opacity": "0.9" + } + }, + "border": null, + "corner_radius": "0", + "layout": "freeform", + "align": "start", + "gap": "0", + "content": { + "type": "none" + } + }, + { + "id": "claude-x-7d-dark-hover", + "name": "dark Claude X 7d hover", + "render": "(system.dark) && (claude.dual_mode) && (claude.hover.opacity > 0.01)", + "visibility": "100 * claude.hover.opacity", + "parent": "claude-provider", + "x": "12", + "y": "32", + "width": "ceil(10 / max(1, providers.count)) * 11 - 1", + "height": "6", + "background": { + "type": "none" + }, + "border": null, + "corner_radius": "0", + "layout": "freeform", + "align": "start", + "gap": "0", + "content": { + "type": "progress", + "value": "accounts.claude.claude_x.weekly.display", + "direction": "left_to_right", + "fill": { + "color": "#A44525FF", + "opacity": "1" + }, + "track": { + "color": "#333333FF", + "opacity": "1" + }, + "corner_radius": "1.5", + "segments": 10, + "segments_expression": "ceil(10 / max(1, providers.count))", + "segment_gap": "1" + } + }, + { + "id": "claude-x-7d-dark-hover-pace", + "name": "dark Claude X 7d hover pace tick", + "render": "(system.dark) && (claude.dual_mode) && (claude.hover.opacity > 0.01)", + "visibility": "(100) * accounts.claude.claude_x.weekly.expected_available * display.show_pace * claude.hover.opacity", + "parent": "claude-provider", + "x": "12 + round((ceil(10 / max(1, providers.count)) * 11 - 2) * clamp(accounts.claude.claude_x.weekly.expected_display, 0, 100) / 100)", + "y": "31", + "width": "1", + "height": "8", + "background": { + "type": "colour", + "colour": { + "color": "#FFFFFFFF", + "opacity": "0.9" + } + }, + "border": null, + "corner_radius": "0", + "layout": "freeform", + "align": "start", + "gap": "0", + "content": { + "type": "none" + } + }, + { + "id": "claude-x-7d-light-normal", + "name": "light Claude X 7d normal", + "render": "((1 - system.dark)) && (claude.dual_mode) && (claude.normal.opacity > 0.01)", + "visibility": "100 * claude.normal.opacity", + "parent": "claude-provider", + "x": "12", + "y": "35", + "width": "ceil(10 / max(1, providers.count)) * 11 - 1", + "height": "3", + "background": { + "type": "none" + }, + "border": null, + "corner_radius": "0", + "layout": "freeform", + "align": "start", + "gap": "0", + "content": { + "type": "progress", + "value": "accounts.claude.claude_x.weekly.display", + "direction": "left_to_right", + "fill": { + "color": "#7C2D12FF", + "opacity": "1" + }, + "track": { + "color": "#CCCCCCFF", + "opacity": "1" + }, + "corner_radius": "1.5", + "segments": 10, + "segments_expression": "ceil(10 / max(1, providers.count))", + "segment_gap": "1" + } + }, + { + "id": "claude-x-7d-light-normal-pace", + "name": "light Claude X 7d normal pace tick", + "render": "((1 - system.dark)) && (claude.dual_mode) && (claude.normal.opacity > 0.01)", + "visibility": "(100) * accounts.claude.claude_x.weekly.expected_available * display.show_pace * claude.normal.opacity", + "parent": "claude-provider", + "x": "12 + round((ceil(10 / max(1, providers.count)) * 11 - 2) * clamp(accounts.claude.claude_x.weekly.expected_display, 0, 100) / 100)", + "y": "34", + "width": "1", + "height": "5", + "background": { + "type": "colour", + "colour": { + "color": "#1A1A1AFF", + "opacity": "0.9" + } + }, + "border": null, + "corner_radius": "0", + "layout": "freeform", + "align": "start", + "gap": "0", + "content": { + "type": "none" + } + }, + { + "id": "claude-x-7d-light-hover", + "name": "light Claude X 7d hover", + "render": "((1 - system.dark)) && (claude.dual_mode) && (claude.hover.opacity > 0.01)", + "visibility": "100 * claude.hover.opacity", + "parent": "claude-provider", + "x": "12", + "y": "32", + "width": "ceil(10 / max(1, providers.count)) * 11 - 1", + "height": "6", + "background": { + "type": "none" + }, + "border": null, + "corner_radius": "0", + "layout": "freeform", + "align": "start", + "gap": "0", + "content": { + "type": "progress", + "value": "accounts.claude.claude_x.weekly.display", + "direction": "left_to_right", + "fill": { + "color": "#7C2D12FF", + "opacity": "1" + }, + "track": { + "color": "#CCCCCCFF", + "opacity": "1" + }, + "corner_radius": "1.5", + "segments": 10, + "segments_expression": "ceil(10 / max(1, providers.count))", + "segment_gap": "1" + } + }, + { + "id": "claude-x-7d-light-hover-pace", + "name": "light Claude X 7d hover pace tick", + "render": "((1 - system.dark)) && (claude.dual_mode) && (claude.hover.opacity > 0.01)", + "visibility": "(100) * accounts.claude.claude_x.weekly.expected_available * display.show_pace * claude.hover.opacity", + "parent": "claude-provider", + "x": "12 + round((ceil(10 / max(1, providers.count)) * 11 - 2) * clamp(accounts.claude.claude_x.weekly.expected_display, 0, 100) / 100)", + "y": "31", + "width": "1", + "height": "8", + "background": { + "type": "colour", + "colour": { + "color": "#1A1A1AFF", + "opacity": "0.9" + } + }, + "border": null, + "corner_radius": "0", + "layout": "freeform", + "align": "start", + "gap": "0", + "content": { + "type": "none" + } + }, + { + "id": "claude-x-text-dark-normal", + "name": "dark Claude X text 5h", + "render": "(system.dark) && (claude.dual_mode) && (claude.normal.opacity > 0.01)", + "visibility": "100", + "parent": "claude-provider", + "x": "12 + ceil(10 / max(1, providers.count)) * 11 - 1 + 4", + "y": "26", + "width": "62", + "height": "13", + "background": { + "type": "none" + }, + "border": null, + "corner_radius": "0", + "layout": "freeform", + "align": "start", + "gap": "0", + "content": { + "type": "text", + "template": "{accounts.claude.claude_x.session.display:usage_line}", + "font_family": "Segoe UI", + "font_size": "12", + "weight": "medium", + "rendering": "clear_type", + "contrast": "1", + "align": "left", + "color": { + "color": "#F09A7AFF", + "opacity": "claude.normal.opacity" + } + } + }, + { + "id": "claude-x-text-dark-hover", + "name": "dark Claude X text 7d", + "render": "(system.dark) && (claude.dual_mode) && (claude.hover.opacity > 0.01)", + "visibility": "100", + "parent": "claude-provider", + "x": "12 + ceil(10 / max(1, providers.count)) * 11 - 1 + 4", + "y": "26", + "width": "62", + "height": "13", + "background": { + "type": "none" + }, + "border": null, + "corner_radius": "0", + "layout": "freeform", + "align": "start", + "gap": "0", + "content": { + "type": "text", + "template": "{accounts.claude.claude_x.weekly.display:usage_line}", + "font_family": "Segoe UI", + "font_size": "12", + "weight": "medium", + "rendering": "clear_type", + "contrast": "1", + "align": "left", + "color": { + "color": "#D97757FF", + "opacity": "claude.hover.opacity" + } + } + }, + { + "id": "claude-x-text-light-normal", + "name": "light Claude X text 5h", + "render": "((1 - system.dark)) && (claude.dual_mode) && (claude.normal.opacity > 0.01)", + "visibility": "100", + "parent": "claude-provider", + "x": "12 + ceil(10 / max(1, providers.count)) * 11 - 1 + 4", + "y": "26", + "width": "62", + "height": "13", + "background": { + "type": "none" + }, + "border": null, + "corner_radius": "0", + "layout": "freeform", + "align": "start", + "gap": "0", + "content": { + "type": "text", + "template": "{accounts.claude.claude_x.session.display:usage_line}", + "font_family": "Segoe UI", + "font_size": "12", + "weight": "medium", + "rendering": "clear_type", + "contrast": "1", + "align": "left", + "color": { + "color": "#A94F32FF", + "opacity": "claude.normal.opacity" + } + } + }, + { + "id": "claude-x-text-light-hover", + "name": "light Claude X text 7d", + "render": "((1 - system.dark)) && (claude.dual_mode) && (claude.hover.opacity > 0.01)", + "visibility": "100", + "parent": "claude-provider", + "x": "12 + ceil(10 / max(1, providers.count)) * 11 - 1 + 4", + "y": "26", + "width": "62", + "height": "13", + "background": { + "type": "none" + }, + "border": null, + "corner_radius": "0", + "layout": "freeform", + "align": "start", + "gap": "0", + "content": { + "type": "text", + "template": "{accounts.claude.claude_x.weekly.display:usage_line}", + "font_family": "Segoe UI", + "font_size": "12", + "weight": "medium", + "rendering": "clear_type", + "contrast": "1", + "align": "left", + "color": { + "color": "#7C2D12FF", + "opacity": "claude.hover.opacity" + } + } + }, + { + "id": "codex-credits-segments-dark", + "name": "dark codex credit overlay", + "render": "((system.dark) && codex.credits.available) && (!codex.dual_mode)", + "visibility": "100", + "parent": "codex-provider", + "y": "27", + "width": "ceil(10 / max(1, providers.count)) * 11 - 1", + "height": "9", + "background": { + "type": "none" + }, + "border": null, + "corner_radius": "0", + "layout": "freeform", + "align": "start", + "gap": "0", + "content": { + "type": "progress", + "value": "codex.credits.display", + "direction": "left_to_right", + "fill": { + "color": "#F5A623FF", + "opacity": "1" + }, + "track": { + "color": "#00000000", + "opacity": "0" + }, + "corner_radius": "1.5", + "segments": 10, + "segments_expression": "ceil(10 / max(1, providers.count))", + "segment_gap": "1" + } + }, + { + "id": "codex-credits-value-dark", + "name": "dark codex credit balance", + "render": "((system.dark) && codex.credits.available) && (!codex.dual_mode)", + "visibility": "100", + "parent": "codex-provider", + "x": "ceil(10 / max(1, providers.count)) * 11 - 1 + 4", + "y": "25", + "width": "62", + "height": "13", + "background": { + "type": "none" + }, + "border": null, + "corner_radius": "0", + "layout": "freeform", + "align": "start", + "gap": "0", + "content": { + "type": "text", + "template": "${codex.credits.balance:0.00}", + "font_family": "Segoe UI", + "font_size": "12", + "weight": "medium", + "rendering": "clear_type", + "contrast": "1", + "align": "left", + "color": { + "color": "#F5A623FF", + "opacity": "1" + } + } + }, + { + "id": "codex-credits-segments-light", + "name": "light codex credit overlay", + "render": "((1 - system.dark) && codex.credits.available) && (!codex.dual_mode)", + "visibility": "100", + "parent": "codex-provider", + "y": "27", + "width": "ceil(10 / max(1, providers.count)) * 11 - 1", + "height": "9", + "background": { + "type": "none" + }, + "border": null, + "corner_radius": "0", + "layout": "freeform", + "align": "start", + "gap": "0", + "content": { + "type": "progress", + "value": "codex.credits.display", + "direction": "left_to_right", + "fill": { + "color": "#C77700FF", + "opacity": "1" + }, + "track": { + "color": "#00000000", + "opacity": "0" + }, + "corner_radius": "1.5", + "segments": 10, + "segments_expression": "ceil(10 / max(1, providers.count))", + "segment_gap": "1" + } + }, + { + "id": "codex-credits-value-light", + "name": "light codex credit balance", + "render": "((1 - system.dark) && codex.credits.available) && (!codex.dual_mode)", + "visibility": "100", + "parent": "codex-provider", + "x": "ceil(10 / max(1, providers.count)) * 11 - 1 + 4", + "y": "25", + "width": "62", + "height": "13", + "background": { + "type": "none" + }, + "border": null, + "corner_radius": "0", + "layout": "freeform", + "align": "start", + "gap": "0", + "content": { + "type": "text", + "template": "${codex.credits.balance:0.00}", + "font_family": "Segoe UI", + "font_size": "12", + "weight": "medium", + "rendering": "clear_type", + "contrast": "1", + "align": "left", + "color": { + "color": "#C77700FF", + "opacity": "1" + } + } + }, + { + "id": "codex-main-marker-dark-normal", + "name": "dark Codex Main marker o normal", + "render": "(system.dark) && (codex.dual_mode) && (codex.normal.opacity > 0.01)", + "visibility": "100", + "parent": "codex-provider", + "x": "0", + "y": "7", + "width": "10", + "height": "13", + "background": { + "type": "none" + }, + "border": null, + "corner_radius": "0", + "layout": "freeform", + "align": "start", + "gap": "0", + "content": { + "type": "text", + "template": "o", + "font_family": "Segoe UI", + "font_size": "12", + "weight": "medium", + "rendering": "clear_type", + "contrast": "1", + "align": "left", + "color": { + "color": "#60A5FAFF", + "opacity": "codex.normal.opacity" + } + } + }, + { + "id": "codex-main-marker-dark-hover", + "name": "dark Codex Main marker o hover", + "render": "(system.dark) && (codex.dual_mode) && (codex.hover.opacity > 0.01)", + "visibility": "100", + "parent": "codex-provider", + "x": "0", + "y": "7", + "width": "10", + "height": "13", + "background": { + "type": "none" + }, + "border": null, + "corner_radius": "0", + "layout": "freeform", + "align": "start", + "gap": "0", + "content": { + "type": "text", + "template": "o", + "font_family": "Segoe UI", + "font_size": "12", + "weight": "medium", + "rendering": "clear_type", + "contrast": "1", + "align": "left", + "color": { + "color": "#3B82F6FF", + "opacity": "codex.hover.opacity" + } + } + }, + { + "id": "codex-main-marker-light-normal", + "name": "light Codex Main marker o normal", + "render": "((1 - system.dark)) && (codex.dual_mode) && (codex.normal.opacity > 0.01)", + "visibility": "100", + "parent": "codex-provider", + "x": "0", + "y": "7", + "width": "10", + "height": "13", + "background": { + "type": "none" + }, + "border": null, + "corner_radius": "0", + "layout": "freeform", + "align": "start", + "gap": "0", + "content": { + "type": "text", + "template": "o", + "font_family": "Segoe UI", + "font_size": "12", + "weight": "medium", + "rendering": "clear_type", + "contrast": "1", + "align": "left", + "color": { + "color": "#2563EBFF", + "opacity": "codex.normal.opacity" + } + } + }, + { + "id": "codex-main-marker-light-hover", + "name": "light Codex Main marker o hover", + "render": "((1 - system.dark)) && (codex.dual_mode) && (codex.hover.opacity > 0.01)", + "visibility": "100", + "parent": "codex-provider", + "x": "0", + "y": "7", + "width": "10", + "height": "13", + "background": { + "type": "none" + }, + "border": null, + "corner_radius": "0", + "layout": "freeform", + "align": "start", + "gap": "0", + "content": { + "type": "text", + "template": "o", + "font_family": "Segoe UI", + "font_size": "12", + "weight": "medium", + "rendering": "clear_type", + "contrast": "1", + "align": "left", + "color": { + "color": "#1D4ED8FF", + "opacity": "codex.hover.opacity" + } + } + }, + { + "id": "codex-main-5h-dark-normal", + "name": "dark Codex Main 5h normal", + "render": "(system.dark) && (codex.dual_mode) && (codex.normal.opacity > 0.01)", + "visibility": "100 * codex.normal.opacity", + "parent": "codex-provider", + "x": "12", + "y": "8", + "width": "ceil(10 / max(1, providers.count)) * 11 - 1", + "height": "6", + "background": { + "type": "none" + }, + "border": null, + "corner_radius": "0", + "layout": "freeform", + "align": "start", + "gap": "0", + "content": { + "type": "progress", + "value": "accounts.codex.default.session.display", + "direction": "left_to_right", + "fill": { + "color": "#60A5FAFF", + "opacity": "1" + }, + "track": { + "color": "#444444FF", + "opacity": "1" + }, + "corner_radius": "1.5", + "segments": 10, + "segments_expression": "ceil(10 / max(1, providers.count))", + "segment_gap": "1" + } + }, + { + "id": "codex-main-5h-dark-normal-pace", + "name": "dark Codex Main 5h normal pace tick", + "render": "(system.dark) && (codex.dual_mode) && (codex.normal.opacity > 0.01)", + "visibility": "(100) * accounts.codex.default.session.expected_available * display.show_pace * codex.normal.opacity", + "parent": "codex-provider", + "x": "12 + round((ceil(10 / max(1, providers.count)) * 11 - 2) * clamp(accounts.codex.default.session.expected_display, 0, 100) / 100)", + "y": "7", + "width": "1", + "height": "8", + "background": { + "type": "colour", + "colour": { + "color": "#FFFFFFFF", + "opacity": "0.9" + } + }, + "border": null, + "corner_radius": "0", + "layout": "freeform", + "align": "start", + "gap": "0", + "content": { + "type": "none" + } + }, + { + "id": "codex-main-5h-dark-hover", + "name": "dark Codex Main 5h hover", + "render": "(system.dark) && (codex.dual_mode) && (codex.hover.opacity > 0.01)", + "visibility": "100 * codex.hover.opacity", + "parent": "codex-provider", + "x": "12", + "y": "8", + "width": "ceil(10 / max(1, providers.count)) * 11 - 1", + "height": "3", + "background": { + "type": "none" + }, + "border": null, + "corner_radius": "0", + "layout": "freeform", + "align": "start", + "gap": "0", + "content": { + "type": "progress", + "value": "accounts.codex.default.session.display", + "direction": "left_to_right", + "fill": { + "color": "#60A5FAFF", + "opacity": "1" + }, + "track": { + "color": "#444444FF", + "opacity": "1" + }, + "corner_radius": "1.5", + "segments": 10, + "segments_expression": "ceil(10 / max(1, providers.count))", + "segment_gap": "1" + } + }, + { + "id": "codex-main-5h-dark-hover-pace", + "name": "dark Codex Main 5h hover pace tick", + "render": "(system.dark) && (codex.dual_mode) && (codex.hover.opacity > 0.01)", + "visibility": "(100) * accounts.codex.default.session.expected_available * display.show_pace * codex.hover.opacity", + "parent": "codex-provider", + "x": "12 + round((ceil(10 / max(1, providers.count)) * 11 - 2) * clamp(accounts.codex.default.session.expected_display, 0, 100) / 100)", + "y": "7", + "width": "1", + "height": "5", + "background": { + "type": "colour", + "colour": { + "color": "#FFFFFFFF", + "opacity": "0.9" + } + }, + "border": null, + "corner_radius": "0", + "layout": "freeform", + "align": "start", + "gap": "0", + "content": { + "type": "none" + } + }, + { + "id": "codex-main-5h-light-normal", + "name": "light Codex Main 5h normal", + "render": "((1 - system.dark)) && (codex.dual_mode) && (codex.normal.opacity > 0.01)", + "visibility": "100 * codex.normal.opacity", + "parent": "codex-provider", + "x": "12", + "y": "8", + "width": "ceil(10 / max(1, providers.count)) * 11 - 1", + "height": "6", + "background": { + "type": "none" + }, + "border": null, + "corner_radius": "0", + "layout": "freeform", + "align": "start", + "gap": "0", + "content": { + "type": "progress", + "value": "accounts.codex.default.session.display", + "direction": "left_to_right", + "fill": { + "color": "#2563EBFF", + "opacity": "1" + }, + "track": { + "color": "#AAAAAAFF", + "opacity": "1" + }, + "corner_radius": "1.5", + "segments": 10, + "segments_expression": "ceil(10 / max(1, providers.count))", + "segment_gap": "1" + } + }, + { + "id": "codex-main-5h-light-normal-pace", + "name": "light Codex Main 5h normal pace tick", + "render": "((1 - system.dark)) && (codex.dual_mode) && (codex.normal.opacity > 0.01)", + "visibility": "(100) * accounts.codex.default.session.expected_available * display.show_pace * codex.normal.opacity", + "parent": "codex-provider", + "x": "12 + round((ceil(10 / max(1, providers.count)) * 11 - 2) * clamp(accounts.codex.default.session.expected_display, 0, 100) / 100)", + "y": "7", + "width": "1", + "height": "8", + "background": { + "type": "colour", + "colour": { + "color": "#1A1A1AFF", + "opacity": "0.9" + } + }, + "border": null, + "corner_radius": "0", + "layout": "freeform", + "align": "start", + "gap": "0", + "content": { + "type": "none" + } + }, + { + "id": "codex-main-5h-light-hover", + "name": "light Codex Main 5h hover", + "render": "((1 - system.dark)) && (codex.dual_mode) && (codex.hover.opacity > 0.01)", + "visibility": "100 * codex.hover.opacity", + "parent": "codex-provider", + "x": "12", + "y": "8", + "width": "ceil(10 / max(1, providers.count)) * 11 - 1", + "height": "3", + "background": { + "type": "none" + }, + "border": null, + "corner_radius": "0", + "layout": "freeform", + "align": "start", + "gap": "0", + "content": { + "type": "progress", + "value": "accounts.codex.default.session.display", + "direction": "left_to_right", + "fill": { + "color": "#2563EBFF", + "opacity": "1" + }, + "track": { + "color": "#AAAAAAFF", + "opacity": "1" + }, + "corner_radius": "1.5", + "segments": 10, + "segments_expression": "ceil(10 / max(1, providers.count))", + "segment_gap": "1" + } + }, + { + "id": "codex-main-5h-light-hover-pace", + "name": "light Codex Main 5h hover pace tick", + "render": "((1 - system.dark)) && (codex.dual_mode) && (codex.hover.opacity > 0.01)", + "visibility": "(100) * accounts.codex.default.session.expected_available * display.show_pace * codex.hover.opacity", + "parent": "codex-provider", + "x": "12 + round((ceil(10 / max(1, providers.count)) * 11 - 2) * clamp(accounts.codex.default.session.expected_display, 0, 100) / 100)", + "y": "7", + "width": "1", + "height": "5", + "background": { + "type": "colour", + "colour": { + "color": "#1A1A1AFF", + "opacity": "0.9" + } + }, + "border": null, + "corner_radius": "0", + "layout": "freeform", + "align": "start", + "gap": "0", + "content": { + "type": "none" + } + }, + { + "id": "codex-main-7d-dark-normal", + "name": "dark Codex Main 7d normal", + "render": "(system.dark) && (codex.dual_mode) && (codex.normal.opacity > 0.01)", + "visibility": "100 * codex.normal.opacity", + "parent": "codex-provider", + "x": "12", + "y": "16", + "width": "ceil(10 / max(1, providers.count)) * 11 - 1", + "height": "3", + "background": { + "type": "none" + }, + "border": null, + "corner_radius": "0", + "layout": "freeform", + "align": "start", + "gap": "0", + "content": { + "type": "progress", + "value": "accounts.codex.default.weekly.display", + "direction": "left_to_right", + "fill": { + "color": "#1D4ED8FF", + "opacity": "1" + }, + "track": { + "color": "#333333FF", + "opacity": "1" + }, + "corner_radius": "1.5", + "segments": 10, + "segments_expression": "ceil(10 / max(1, providers.count))", + "segment_gap": "1" + } + }, + { + "id": "codex-main-7d-dark-normal-pace", + "name": "dark Codex Main 7d normal pace tick", + "render": "(system.dark) && (codex.dual_mode) && (codex.normal.opacity > 0.01)", + "visibility": "(100) * accounts.codex.default.weekly.expected_available * display.show_pace * codex.normal.opacity", + "parent": "codex-provider", + "x": "12 + round((ceil(10 / max(1, providers.count)) * 11 - 2) * clamp(accounts.codex.default.weekly.expected_display, 0, 100) / 100)", + "y": "15", + "width": "1", + "height": "5", + "background": { + "type": "colour", + "colour": { + "color": "#FFFFFFFF", + "opacity": "0.9" + } + }, + "border": null, + "corner_radius": "0", + "layout": "freeform", + "align": "start", + "gap": "0", + "content": { + "type": "none" + } + }, + { + "id": "codex-main-7d-dark-hover", + "name": "dark Codex Main 7d hover", + "render": "(system.dark) && (codex.dual_mode) && (codex.hover.opacity > 0.01)", + "visibility": "100 * codex.hover.opacity", + "parent": "codex-provider", + "x": "12", + "y": "13", + "width": "ceil(10 / max(1, providers.count)) * 11 - 1", + "height": "6", + "background": { + "type": "none" + }, + "border": null, + "corner_radius": "0", + "layout": "freeform", + "align": "start", + "gap": "0", + "content": { + "type": "progress", + "value": "accounts.codex.default.weekly.display", + "direction": "left_to_right", + "fill": { + "color": "#1D4ED8FF", + "opacity": "1" + }, + "track": { + "color": "#333333FF", + "opacity": "1" + }, + "corner_radius": "1.5", + "segments": 10, + "segments_expression": "ceil(10 / max(1, providers.count))", + "segment_gap": "1" + } + }, + { + "id": "codex-main-7d-dark-hover-pace", + "name": "dark Codex Main 7d hover pace tick", + "render": "(system.dark) && (codex.dual_mode) && (codex.hover.opacity > 0.01)", + "visibility": "(100) * accounts.codex.default.weekly.expected_available * display.show_pace * codex.hover.opacity", + "parent": "codex-provider", + "x": "12 + round((ceil(10 / max(1, providers.count)) * 11 - 2) * clamp(accounts.codex.default.weekly.expected_display, 0, 100) / 100)", + "y": "12", + "width": "1", + "height": "8", + "background": { + "type": "colour", + "colour": { + "color": "#FFFFFFFF", + "opacity": "0.9" + } + }, + "border": null, + "corner_radius": "0", + "layout": "freeform", + "align": "start", + "gap": "0", + "content": { + "type": "none" + } + }, + { + "id": "codex-main-7d-light-normal", + "name": "light Codex Main 7d normal", + "render": "((1 - system.dark)) && (codex.dual_mode) && (codex.normal.opacity > 0.01)", + "visibility": "100 * codex.normal.opacity", + "parent": "codex-provider", + "x": "12", + "y": "16", + "width": "ceil(10 / max(1, providers.count)) * 11 - 1", + "height": "3", + "background": { + "type": "none" + }, + "border": null, + "corner_radius": "0", + "layout": "freeform", + "align": "start", + "gap": "0", + "content": { + "type": "progress", + "value": "accounts.codex.default.weekly.display", + "direction": "left_to_right", + "fill": { + "color": "#1E40AFFF", + "opacity": "1" + }, + "track": { + "color": "#CCCCCCFF", + "opacity": "1" + }, + "corner_radius": "1.5", + "segments": 10, + "segments_expression": "ceil(10 / max(1, providers.count))", + "segment_gap": "1" + } + }, + { + "id": "codex-main-7d-light-normal-pace", + "name": "light Codex Main 7d normal pace tick", + "render": "((1 - system.dark)) && (codex.dual_mode) && (codex.normal.opacity > 0.01)", + "visibility": "(100) * accounts.codex.default.weekly.expected_available * display.show_pace * codex.normal.opacity", + "parent": "codex-provider", + "x": "12 + round((ceil(10 / max(1, providers.count)) * 11 - 2) * clamp(accounts.codex.default.weekly.expected_display, 0, 100) / 100)", + "y": "15", + "width": "1", + "height": "5", + "background": { + "type": "colour", + "colour": { + "color": "#1A1A1AFF", + "opacity": "0.9" + } + }, + "border": null, + "corner_radius": "0", + "layout": "freeform", + "align": "start", + "gap": "0", + "content": { + "type": "none" + } + }, + { + "id": "codex-main-7d-light-hover", + "name": "light Codex Main 7d hover", + "render": "((1 - system.dark)) && (codex.dual_mode) && (codex.hover.opacity > 0.01)", + "visibility": "100 * codex.hover.opacity", + "parent": "codex-provider", + "x": "12", + "y": "13", + "width": "ceil(10 / max(1, providers.count)) * 11 - 1", + "height": "6", + "background": { + "type": "none" + }, + "border": null, + "corner_radius": "0", + "layout": "freeform", + "align": "start", + "gap": "0", + "content": { + "type": "progress", + "value": "accounts.codex.default.weekly.display", + "direction": "left_to_right", + "fill": { + "color": "#1E40AFFF", + "opacity": "1" + }, + "track": { + "color": "#CCCCCCFF", + "opacity": "1" + }, + "corner_radius": "1.5", + "segments": 10, + "segments_expression": "ceil(10 / max(1, providers.count))", + "segment_gap": "1" + } + }, + { + "id": "codex-main-7d-light-hover-pace", + "name": "light Codex Main 7d hover pace tick", + "render": "((1 - system.dark)) && (codex.dual_mode) && (codex.hover.opacity > 0.01)", + "visibility": "(100) * accounts.codex.default.weekly.expected_available * display.show_pace * codex.hover.opacity", + "parent": "codex-provider", + "x": "12 + round((ceil(10 / max(1, providers.count)) * 11 - 2) * clamp(accounts.codex.default.weekly.expected_display, 0, 100) / 100)", + "y": "12", + "width": "1", + "height": "8", + "background": { + "type": "colour", + "colour": { + "color": "#1A1A1AFF", + "opacity": "0.9" + } + }, + "border": null, + "corner_radius": "0", + "layout": "freeform", + "align": "start", + "gap": "0", + "content": { + "type": "none" + } + }, + { + "id": "codex-main-text-dark-normal", + "name": "dark Codex Main text 5h", + "render": "(system.dark) && (codex.dual_mode) && (codex.normal.opacity > 0.01)", + "visibility": "100", + "parent": "codex-provider", + "x": "12 + ceil(10 / max(1, providers.count)) * 11 - 1 + 4", + "y": "7", + "width": "62", + "height": "13", + "background": { + "type": "none" + }, + "border": null, + "corner_radius": "0", + "layout": "freeform", + "align": "start", + "gap": "0", + "content": { + "type": "text", + "template": "{accounts.codex.default.session.display:usage_line}", + "font_family": "Segoe UI", + "font_size": "12", + "weight": "medium", + "rendering": "clear_type", + "contrast": "1", + "align": "left", + "color": { + "color": "#60A5FAFF", + "opacity": "codex.normal.opacity" + } + } + }, + { + "id": "codex-main-text-dark-hover", + "name": "dark Codex Main text 7d", + "render": "(system.dark) && (codex.dual_mode) && (codex.hover.opacity > 0.01)", + "visibility": "100", + "parent": "codex-provider", + "x": "12 + ceil(10 / max(1, providers.count)) * 11 - 1 + 4", + "y": "7", + "width": "62", + "height": "13", "background": { "type": "none" }, @@ -1713,32 +6024,30 @@ "align": "start", "gap": "0", "content": { - "type": "progress", - "value": "antigravity.gemini.weekly.display", - "direction": "left_to_right", - "fill": { - "color": "#00A896FF", - "opacity": "1" - }, - "track": { - "color": "#AAAAAAFF", - "opacity": "1" - }, - "corner_radius": "1.5", - "segments": 10, - "segments_expression": "ceil(10 / max(1, providers.count))", - "segment_gap": "1" + "type": "text", + "template": "{accounts.codex.default.weekly.display:usage_line}", + "font_family": "Segoe UI", + "font_size": "12", + "weight": "medium", + "rendering": "clear_type", + "contrast": "1", + "align": "left", + "color": { + "color": "#3B82F6FF", + "opacity": "codex.hover.opacity" + } } }, { - "id": "antigravity-weekly-external-dual-dark", - "name": "dark Antigravity External dual weekly segments", - "render": "system.dark && antigravity.dual_mode", + "id": "codex-main-text-light-normal", + "name": "light Codex Main text 5h", + "render": "((1 - system.dark)) && (codex.dual_mode) && (codex.normal.opacity > 0.01)", "visibility": "100", - "parent": "antigravity-provider", - "y": "32", - "width": "ceil(10 / max(1, providers.count)) * 11 - 1", - "height": "4", + "parent": "codex-provider", + "x": "12 + ceil(10 / max(1, providers.count)) * 11 - 1 + 4", + "y": "7", + "width": "62", + "height": "13", "background": { "type": "none" }, @@ -1748,32 +6057,30 @@ "align": "start", "gap": "0", "content": { - "type": "progress", - "value": "antigravity.external.weekly.display", - "direction": "left_to_right", - "fill": { - "color": "#6EB4C8FF", - "opacity": "1" - }, - "track": { - "color": "#444444FF", - "opacity": "1" - }, - "corner_radius": "1.5", - "segments": 10, - "segments_expression": "ceil(10 / max(1, providers.count))", - "segment_gap": "1" + "type": "text", + "template": "{accounts.codex.default.session.display:usage_line}", + "font_family": "Segoe UI", + "font_size": "12", + "weight": "medium", + "rendering": "clear_type", + "contrast": "1", + "align": "left", + "color": { + "color": "#2563EBFF", + "opacity": "codex.normal.opacity" + } } }, { - "id": "antigravity-weekly-external-dual-light", - "name": "light Antigravity External dual weekly segments", - "render": "(1 - system.dark) && antigravity.dual_mode", + "id": "codex-main-text-light-hover", + "name": "light Codex Main text 7d", + "render": "((1 - system.dark)) && (codex.dual_mode) && (codex.hover.opacity > 0.01)", "visibility": "100", - "parent": "antigravity-provider", - "y": "32", - "width": "ceil(10 / max(1, providers.count)) * 11 - 1", - "height": "4", + "parent": "codex-provider", + "x": "12 + ceil(10 / max(1, providers.count)) * 11 - 1 + 4", + "y": "7", + "width": "62", + "height": "13", "background": { "type": "none" }, @@ -1783,32 +6090,29 @@ "align": "start", "gap": "0", "content": { - "type": "progress", - "value": "antigravity.external.weekly.display", - "direction": "left_to_right", - "fill": { - "color": "#4A8B9EFF", - "opacity": "1" - }, - "track": { - "color": "#AAAAAAFF", - "opacity": "1" - }, - "corner_radius": "1.5", - "segments": 10, - "segments_expression": "ceil(10 / max(1, providers.count))", - "segment_gap": "1" + "type": "text", + "template": "{accounts.codex.default.weekly.display:usage_line}", + "font_family": "Segoe UI", + "font_size": "12", + "weight": "medium", + "rendering": "clear_type", + "contrast": "1", + "align": "left", + "color": { + "color": "#1D4ED8FF", + "opacity": "codex.hover.opacity" + } } }, { - "id": "antigravity-weekly-gemini-value-dark", - "name": "dark Antigravity Gemini weekly value", - "render": "system.dark && antigravity.gemini.enabled && (!antigravity.dual_mode || antigravity.crossfade_opacity > 0.01)", + "id": "codex-x-marker-dark-normal", + "name": "dark Codex X marker x normal", + "render": "(system.dark) && (codex.dual_mode) && (codex.normal.opacity > 0.01)", "visibility": "100", - "parent": "antigravity-provider", - "x": "ceil(10 / max(1, providers.count)) * 11 - 1 + 4", - "y": "25", - "width": "62", + "parent": "codex-provider", + "x": "0", + "y": "26", + "width": "10", "height": "13", "background": { "type": "none" @@ -1820,7 +6124,7 @@ "gap": "0", "content": { "type": "text", - "template": "{antigravity.gemini.weekly.display:usage_line}", + "template": "x", "font_family": "Segoe UI", "font_size": "12", "weight": "medium", @@ -1828,20 +6132,20 @@ "contrast": "1", "align": "left", "color": { - "color": "#5EEAD4FF", - "opacity": "if(antigravity.dual_mode, antigravity.crossfade_opacity, 1.0)" + "color": "#60A5FAFF", + "opacity": "codex.normal.opacity" } } }, { - "id": "antigravity-weekly-gemini-value-light", - "name": "light Antigravity Gemini weekly value", - "render": "(1 - system.dark) && antigravity.gemini.enabled && (!antigravity.dual_mode || antigravity.crossfade_opacity > 0.01)", + "id": "codex-x-marker-dark-hover", + "name": "dark Codex X marker x hover", + "render": "(system.dark) && (codex.dual_mode) && (codex.hover.opacity > 0.01)", "visibility": "100", - "parent": "antigravity-provider", - "x": "ceil(10 / max(1, providers.count)) * 11 - 1 + 4", - "y": "25", - "width": "62", + "parent": "codex-provider", + "x": "0", + "y": "26", + "width": "10", "height": "13", "background": { "type": "none" @@ -1853,7 +6157,7 @@ "gap": "0", "content": { "type": "text", - "template": "{antigravity.gemini.weekly.display:usage_line}", + "template": "x", "font_family": "Segoe UI", "font_size": "12", "weight": "medium", @@ -1861,20 +6165,20 @@ "contrast": "1", "align": "left", "color": { - "color": "#007A6CFF", - "opacity": "if(antigravity.dual_mode, antigravity.crossfade_opacity, 1.0)" + "color": "#3B82F6FF", + "opacity": "codex.hover.opacity" } } }, { - "id": "antigravity-weekly-external-value-dark", - "name": "dark Antigravity External weekly value", - "render": "system.dark && antigravity.external.enabled && (!antigravity.dual_mode || (1.0 - antigravity.crossfade_opacity) > 0.01)", + "id": "codex-x-marker-light-normal", + "name": "light Codex X marker x normal", + "render": "((1 - system.dark)) && (codex.dual_mode) && (codex.normal.opacity > 0.01)", "visibility": "100", - "parent": "antigravity-provider", - "x": "ceil(10 / max(1, providers.count)) * 11 - 1 + 4", - "y": "25", - "width": "62", + "parent": "codex-provider", + "x": "0", + "y": "26", + "width": "10", "height": "13", "background": { "type": "none" @@ -1886,7 +6190,7 @@ "gap": "0", "content": { "type": "text", - "template": "{antigravity.external.weekly.display:usage_line}", + "template": "x", "font_family": "Segoe UI", "font_size": "12", "weight": "medium", @@ -1894,20 +6198,20 @@ "contrast": "1", "align": "left", "color": { - "color": "#98D0E0FF", - "opacity": "if(antigravity.dual_mode, 1.0 - antigravity.crossfade_opacity, 1.0)" + "color": "#2563EBFF", + "opacity": "codex.normal.opacity" } } }, { - "id": "antigravity-weekly-external-value-light", - "name": "light Antigravity External weekly value", - "render": "(1 - system.dark) && antigravity.external.enabled && (!antigravity.dual_mode || (1.0 - antigravity.crossfade_opacity) > 0.01)", + "id": "codex-x-marker-light-hover", + "name": "light Codex X marker x hover", + "render": "((1 - system.dark)) && (codex.dual_mode) && (codex.hover.opacity > 0.01)", "visibility": "100", - "parent": "antigravity-provider", - "x": "ceil(10 / max(1, providers.count)) * 11 - 1 + 4", - "y": "25", - "width": "62", + "parent": "codex-provider", + "x": "0", + "y": "26", + "width": "10", "height": "13", "background": { "type": "none" @@ -1919,7 +6223,7 @@ "gap": "0", "content": { "type": "text", - "template": "{antigravity.external.weekly.display:usage_line}", + "template": "x", "font_family": "Segoe UI", "font_size": "12", "weight": "medium", @@ -1927,19 +6231,21 @@ "contrast": "1", "align": "left", "color": { - "color": "#2D6F82FF", - "opacity": "if(antigravity.dual_mode, 1.0 - antigravity.crossfade_opacity, 1.0)" + "color": "#1D4ED8FF", + "opacity": "codex.hover.opacity" } } }, { - "id": "opencode-provider", - "name": "OpenCode provider", - "render": "providers.opencode.enabled", - "visibility": "100", - "parent": "provider-row", - "width": "ceil(10 / max(1, providers.count)) * 11 - 1 + 4 + 90", - "height": "46", + "id": "codex-x-5h-dark-normal", + "name": "dark Codex X 5h normal", + "render": "(system.dark) && (codex.dual_mode) && (codex.normal.opacity > 0.01)", + "visibility": "100 * codex.normal.opacity", + "parent": "codex-provider", + "x": "12", + "y": "27", + "width": "ceil(10 / max(1, providers.count)) * 11 - 1", + "height": "6", "background": { "type": "none" }, @@ -1948,19 +6254,60 @@ "layout": "freeform", "align": "start", "gap": "0", + "content": { + "type": "progress", + "value": "accounts.codex.codex_x.session.display", + "direction": "left_to_right", + "fill": { + "color": "#60A5FAFF", + "opacity": "1" + }, + "track": { + "color": "#444444FF", + "opacity": "1" + }, + "corner_radius": "1.5", + "segments": 10, + "segments_expression": "ceil(10 / max(1, providers.count))", + "segment_gap": "1" + } + }, + { + "id": "codex-x-5h-dark-normal-pace", + "name": "dark Codex X 5h normal pace tick", + "render": "(system.dark) && (codex.dual_mode) && (codex.normal.opacity > 0.01)", + "visibility": "(100) * accounts.codex.codex_x.session.expected_available * display.show_pace * codex.normal.opacity", + "parent": "codex-provider", + "x": "12 + round((ceil(10 / max(1, providers.count)) * 11 - 2) * clamp(accounts.codex.codex_x.session.expected_display, 0, 100) / 100)", + "y": "26", + "width": "1", + "height": "8", + "background": { + "type": "colour", + "colour": { + "color": "#FFFFFFFF", + "opacity": "0.9" + } + }, + "border": null, + "corner_radius": "0", + "layout": "freeform", + "align": "start", + "gap": "0", "content": { "type": "none" } }, { - "id": "opencode-session-segments-dark", - "name": "dark OpenCode 5-hour segments", - "render": "system.dark", - "visibility": "100", - "parent": "opencode-provider", - "y": "11", + "id": "codex-x-5h-dark-hover", + "name": "dark Codex X 5h hover", + "render": "(system.dark) && (codex.dual_mode) && (codex.hover.opacity > 0.01)", + "visibility": "100 * codex.hover.opacity", + "parent": "codex-provider", + "x": "12", + "y": "27", "width": "ceil(10 / max(1, providers.count)) * 11 - 1", - "height": "9", + "height": "3", "background": { "type": "none" }, @@ -1971,10 +6318,10 @@ "gap": "0", "content": { "type": "progress", - "value": "opencode.session.display", + "value": "accounts.codex.codex_x.session.display", "direction": "left_to_right", "fill": { - "color": "#4CAF50FF", + "color": "#60A5FAFF", "opacity": "1" }, "track": { @@ -1988,17 +6335,21 @@ } }, { - "id": "opencode-session-value-dark", - "name": "dark OpenCode 5-hour value", - "render": "system.dark", - "visibility": "100", - "parent": "opencode-provider", - "x": "ceil(10 / max(1, providers.count)) * 11 - 1 + 4", - "y": "9", - "width": "62", - "height": "13", + "id": "codex-x-5h-dark-hover-pace", + "name": "dark Codex X 5h hover pace tick", + "render": "(system.dark) && (codex.dual_mode) && (codex.hover.opacity > 0.01)", + "visibility": "(100) * accounts.codex.codex_x.session.expected_available * display.show_pace * codex.hover.opacity", + "parent": "codex-provider", + "x": "12 + round((ceil(10 / max(1, providers.count)) * 11 - 2) * clamp(accounts.codex.codex_x.session.expected_display, 0, 100) / 100)", + "y": "26", + "width": "1", + "height": "5", "background": { - "type": "none" + "type": "colour", + "colour": { + "color": "#FFFFFFFF", + "opacity": "0.9" + } }, "border": null, "corner_radius": "0", @@ -2006,29 +6357,19 @@ "align": "start", "gap": "0", "content": { - "type": "text", - "template": "{opencode.session.display:usage_line}", - "font_family": "Segoe UI", - "font_size": "12", - "weight": "medium", - "rendering": "clear_type", - "contrast": "1", - "align": "left", - "color": { - "color": "#81C784FF", - "opacity": "1" - } + "type": "none" } }, { - "id": "opencode-session-segments-light", - "name": "light OpenCode 5-hour segments", - "render": "1 - system.dark", - "visibility": "100", - "parent": "opencode-provider", - "y": "11", + "id": "codex-x-5h-light-normal", + "name": "light Codex X 5h normal", + "render": "((1 - system.dark)) && (codex.dual_mode) && (codex.normal.opacity > 0.01)", + "visibility": "100 * codex.normal.opacity", + "parent": "codex-provider", + "x": "12", + "y": "27", "width": "ceil(10 / max(1, providers.count)) * 11 - 1", - "height": "9", + "height": "6", "background": { "type": "none" }, @@ -2039,10 +6380,10 @@ "gap": "0", "content": { "type": "progress", - "value": "opencode.session.display", + "value": "accounts.codex.codex_x.session.display", "direction": "left_to_right", "fill": { - "color": "#2E7D32FF", + "color": "#2563EBFF", "opacity": "1" }, "track": { @@ -2056,17 +6397,21 @@ } }, { - "id": "opencode-session-value-light", - "name": "light OpenCode 5-hour value", - "render": "1 - system.dark", - "visibility": "100", - "parent": "opencode-provider", - "x": "ceil(10 / max(1, providers.count)) * 11 - 1 + 4", - "y": "9", - "width": "62", - "height": "13", + "id": "codex-x-5h-light-normal-pace", + "name": "light Codex X 5h normal pace tick", + "render": "((1 - system.dark)) && (codex.dual_mode) && (codex.normal.opacity > 0.01)", + "visibility": "(100) * accounts.codex.codex_x.session.expected_available * display.show_pace * codex.normal.opacity", + "parent": "codex-provider", + "x": "12 + round((ceil(10 / max(1, providers.count)) * 11 - 2) * clamp(accounts.codex.codex_x.session.expected_display, 0, 100) / 100)", + "y": "26", + "width": "1", + "height": "8", "background": { - "type": "none" + "type": "colour", + "colour": { + "color": "#1A1A1AFF", + "opacity": "0.9" + } }, "border": null, "corner_radius": "0", @@ -2074,29 +6419,19 @@ "align": "start", "gap": "0", "content": { - "type": "text", - "template": "{opencode.session.display:usage_line}", - "font_family": "Segoe UI", - "font_size": "12", - "weight": "medium", - "rendering": "clear_type", - "contrast": "1", - "align": "left", - "color": { - "color": "#1B5E20FF", - "opacity": "1" - } + "type": "none" } }, { - "id": "opencode-weekly-segments-dark", - "name": "dark OpenCode long-window segments", - "render": "system.dark", - "visibility": "100", - "parent": "opencode-provider", + "id": "codex-x-5h-light-hover", + "name": "light Codex X 5h hover", + "render": "((1 - system.dark)) && (codex.dual_mode) && (codex.hover.opacity > 0.01)", + "visibility": "100 * codex.hover.opacity", + "parent": "codex-provider", + "x": "12", "y": "27", "width": "ceil(10 / max(1, providers.count)) * 11 - 1", - "height": "9", + "height": "3", "background": { "type": "none" }, @@ -2107,14 +6442,14 @@ "gap": "0", "content": { "type": "progress", - "value": "opencode.weekly.display", + "value": "accounts.codex.codex_x.session.display", "direction": "left_to_right", "fill": { - "color": "#4CAF50FF", + "color": "#2563EBFF", "opacity": "1" }, "track": { - "color": "#444444FF", + "color": "#AAAAAAFF", "opacity": "1" }, "corner_radius": "1.5", @@ -2124,17 +6459,21 @@ } }, { - "id": "opencode-weekly-value-dark", - "name": "dark OpenCode long-window value", - "render": "system.dark", - "visibility": "100", - "parent": "opencode-provider", - "x": "ceil(10 / max(1, providers.count)) * 11 - 1 + 4", - "y": "25", - "width": "90", - "height": "13", + "id": "codex-x-5h-light-hover-pace", + "name": "light Codex X 5h hover pace tick", + "render": "((1 - system.dark)) && (codex.dual_mode) && (codex.hover.opacity > 0.01)", + "visibility": "(100) * accounts.codex.codex_x.session.expected_available * display.show_pace * codex.hover.opacity", + "parent": "codex-provider", + "x": "12 + round((ceil(10 / max(1, providers.count)) * 11 - 2) * clamp(accounts.codex.codex_x.session.expected_display, 0, 100) / 100)", + "y": "26", + "width": "1", + "height": "5", "background": { - "type": "none" + "type": "colour", + "colour": { + "color": "#1A1A1AFF", + "opacity": "0.9" + } }, "border": null, "corner_radius": "0", @@ -2142,29 +6481,19 @@ "align": "start", "gap": "0", "content": { - "type": "text", - "template": "{opencode.weekly.label} {opencode.weekly.display:usage_line}", - "font_family": "Segoe UI", - "font_size": "12", - "weight": "medium", - "rendering": "clear_type", - "contrast": "1", - "align": "left", - "color": { - "color": "#81C784FF", - "opacity": "1" - } + "type": "none" } }, { - "id": "opencode-weekly-segments-light", - "name": "light OpenCode long-window segments", - "render": "1 - system.dark", - "visibility": "100", - "parent": "opencode-provider", - "y": "27", + "id": "codex-x-7d-dark-normal", + "name": "dark Codex X 7d normal", + "render": "(system.dark) && (codex.dual_mode) && (codex.normal.opacity > 0.01)", + "visibility": "100 * codex.normal.opacity", + "parent": "codex-provider", + "x": "12", + "y": "35", "width": "ceil(10 / max(1, providers.count)) * 11 - 1", - "height": "9", + "height": "3", "background": { "type": "none" }, @@ -2175,14 +6504,14 @@ "gap": "0", "content": { "type": "progress", - "value": "opencode.weekly.display", + "value": "accounts.codex.codex_x.weekly.display", "direction": "left_to_right", "fill": { - "color": "#2E7D32FF", + "color": "#1D4ED8FF", "opacity": "1" }, "track": { - "color": "#AAAAAAFF", + "color": "#333333FF", "opacity": "1" }, "corner_radius": "1.5", @@ -2192,17 +6521,21 @@ } }, { - "id": "opencode-weekly-value-light", - "name": "light OpenCode long-window value", - "render": "1 - system.dark", - "visibility": "100", - "parent": "opencode-provider", - "x": "ceil(10 / max(1, providers.count)) * 11 - 1 + 4", - "y": "25", - "width": "90", - "height": "13", + "id": "codex-x-7d-dark-normal-pace", + "name": "dark Codex X 7d normal pace tick", + "render": "(system.dark) && (codex.dual_mode) && (codex.normal.opacity > 0.01)", + "visibility": "(100) * accounts.codex.codex_x.weekly.expected_available * display.show_pace * codex.normal.opacity", + "parent": "codex-provider", + "x": "12 + round((ceil(10 / max(1, providers.count)) * 11 - 2) * clamp(accounts.codex.codex_x.weekly.expected_display, 0, 100) / 100)", + "y": "34", + "width": "1", + "height": "5", "background": { - "type": "none" + "type": "colour", + "colour": { + "color": "#FFFFFFFF", + "opacity": "0.9" + } }, "border": null, "corner_radius": "0", @@ -2210,29 +6543,19 @@ "align": "start", "gap": "0", "content": { - "type": "text", - "template": "{opencode.weekly.label} {opencode.weekly.display:usage_line}", - "font_family": "Segoe UI", - "font_size": "12", - "weight": "medium", - "rendering": "clear_type", - "contrast": "1", - "align": "left", - "color": { - "color": "#1B5E20FF", - "opacity": "1" - } + "type": "none" } }, { - "id": "claude-credits-segments-dark", - "name": "dark claude credit overlay", - "render": "(system.dark) && claude.credits.available", - "visibility": "100", - "parent": "claude-provider", - "y": "27", + "id": "codex-x-7d-dark-hover", + "name": "dark Codex X 7d hover", + "render": "(system.dark) && (codex.dual_mode) && (codex.hover.opacity > 0.01)", + "visibility": "100 * codex.hover.opacity", + "parent": "codex-provider", + "x": "12", + "y": "32", "width": "ceil(10 / max(1, providers.count)) * 11 - 1", - "height": "9", + "height": "6", "background": { "type": "none" }, @@ -2243,15 +6566,15 @@ "gap": "0", "content": { "type": "progress", - "value": "claude.credits.display", + "value": "accounts.codex.codex_x.weekly.display", "direction": "left_to_right", "fill": { - "color": "#F5A623FF", + "color": "#1D4ED8FF", "opacity": "1" }, "track": { - "color": "#00000000", - "opacity": "0" + "color": "#333333FF", + "opacity": "1" }, "corner_radius": "1.5", "segments": 10, @@ -2260,17 +6583,21 @@ } }, { - "id": "claude-credits-value-dark", - "name": "dark claude credit balance", - "render": "(system.dark) && claude.credits.available", - "visibility": "100", - "parent": "claude-provider", - "x": "ceil(10 / max(1, providers.count)) * 11 - 1 + 4", - "y": "25", - "width": "62", - "height": "13", + "id": "codex-x-7d-dark-hover-pace", + "name": "dark Codex X 7d hover pace tick", + "render": "(system.dark) && (codex.dual_mode) && (codex.hover.opacity > 0.01)", + "visibility": "(100) * accounts.codex.codex_x.weekly.expected_available * display.show_pace * codex.hover.opacity", + "parent": "codex-provider", + "x": "12 + round((ceil(10 / max(1, providers.count)) * 11 - 2) * clamp(accounts.codex.codex_x.weekly.expected_display, 0, 100) / 100)", + "y": "31", + "width": "1", + "height": "8", "background": { - "type": "none" + "type": "colour", + "colour": { + "color": "#FFFFFFFF", + "opacity": "0.9" + } }, "border": null, "corner_radius": "0", @@ -2278,29 +6605,19 @@ "align": "start", "gap": "0", "content": { - "type": "text", - "template": "${claude.credits.balance:0.00}", - "font_family": "Segoe UI", - "font_size": "12", - "weight": "medium", - "rendering": "clear_type", - "contrast": "1", - "align": "left", - "color": { - "color": "#F5A623FF", - "opacity": "1" - } + "type": "none" } }, { - "id": "claude-credits-segments-light", - "name": "light claude credit overlay", - "render": "(1 - system.dark) && claude.credits.available", - "visibility": "100", - "parent": "claude-provider", - "y": "27", + "id": "codex-x-7d-light-normal", + "name": "light Codex X 7d normal", + "render": "((1 - system.dark)) && (codex.dual_mode) && (codex.normal.opacity > 0.01)", + "visibility": "100 * codex.normal.opacity", + "parent": "codex-provider", + "x": "12", + "y": "35", "width": "ceil(10 / max(1, providers.count)) * 11 - 1", - "height": "9", + "height": "3", "background": { "type": "none" }, @@ -2311,15 +6628,15 @@ "gap": "0", "content": { "type": "progress", - "value": "claude.credits.display", + "value": "accounts.codex.codex_x.weekly.display", "direction": "left_to_right", "fill": { - "color": "#C77700FF", + "color": "#1E40AFFF", "opacity": "1" }, "track": { - "color": "#00000000", - "opacity": "0" + "color": "#CCCCCCFF", + "opacity": "1" }, "corner_radius": "1.5", "segments": 10, @@ -2328,17 +6645,21 @@ } }, { - "id": "claude-credits-value-light", - "name": "light claude credit balance", - "render": "(1 - system.dark) && claude.credits.available", - "visibility": "100", - "parent": "claude-provider", - "x": "ceil(10 / max(1, providers.count)) * 11 - 1 + 4", - "y": "25", - "width": "62", - "height": "13", + "id": "codex-x-7d-light-normal-pace", + "name": "light Codex X 7d normal pace tick", + "render": "((1 - system.dark)) && (codex.dual_mode) && (codex.normal.opacity > 0.01)", + "visibility": "(100) * accounts.codex.codex_x.weekly.expected_available * display.show_pace * codex.normal.opacity", + "parent": "codex-provider", + "x": "12 + round((ceil(10 / max(1, providers.count)) * 11 - 2) * clamp(accounts.codex.codex_x.weekly.expected_display, 0, 100) / 100)", + "y": "34", + "width": "1", + "height": "5", "background": { - "type": "none" + "type": "colour", + "colour": { + "color": "#1A1A1AFF", + "opacity": "0.9" + } }, "border": null, "corner_radius": "0", @@ -2346,29 +6667,19 @@ "align": "start", "gap": "0", "content": { - "type": "text", - "template": "${claude.credits.balance:0.00}", - "font_family": "Segoe UI", - "font_size": "12", - "weight": "medium", - "rendering": "clear_type", - "contrast": "1", - "align": "left", - "color": { - "color": "#C77700FF", - "opacity": "1" - } + "type": "none" } }, { - "id": "codex-credits-segments-dark", - "name": "dark codex credit overlay", - "render": "(system.dark) && codex.credits.available", - "visibility": "100", + "id": "codex-x-7d-light-hover", + "name": "light Codex X 7d hover", + "render": "((1 - system.dark)) && (codex.dual_mode) && (codex.hover.opacity > 0.01)", + "visibility": "100 * codex.hover.opacity", "parent": "codex-provider", - "y": "27", + "x": "12", + "y": "32", "width": "ceil(10 / max(1, providers.count)) * 11 - 1", - "height": "9", + "height": "6", "background": { "type": "none" }, @@ -2379,15 +6690,15 @@ "gap": "0", "content": { "type": "progress", - "value": "codex.credits.display", + "value": "accounts.codex.codex_x.weekly.display", "direction": "left_to_right", "fill": { - "color": "#F5A623FF", + "color": "#1E40AFFF", "opacity": "1" }, "track": { - "color": "#00000000", - "opacity": "0" + "color": "#CCCCCCFF", + "opacity": "1" }, "corner_radius": "1.5", "segments": 10, @@ -2396,13 +6707,39 @@ } }, { - "id": "codex-credits-value-dark", - "name": "dark codex credit balance", - "render": "(system.dark) && codex.credits.available", + "id": "codex-x-7d-light-hover-pace", + "name": "light Codex X 7d hover pace tick", + "render": "((1 - system.dark)) && (codex.dual_mode) && (codex.hover.opacity > 0.01)", + "visibility": "(100) * accounts.codex.codex_x.weekly.expected_available * display.show_pace * codex.hover.opacity", + "parent": "codex-provider", + "x": "12 + round((ceil(10 / max(1, providers.count)) * 11 - 2) * clamp(accounts.codex.codex_x.weekly.expected_display, 0, 100) / 100)", + "y": "31", + "width": "1", + "height": "8", + "background": { + "type": "colour", + "colour": { + "color": "#1A1A1AFF", + "opacity": "0.9" + } + }, + "border": null, + "corner_radius": "0", + "layout": "freeform", + "align": "start", + "gap": "0", + "content": { + "type": "none" + } + }, + { + "id": "codex-x-text-dark-normal", + "name": "dark Codex X text 5h", + "render": "(system.dark) && (codex.dual_mode) && (codex.normal.opacity > 0.01)", "visibility": "100", "parent": "codex-provider", - "x": "ceil(10 / max(1, providers.count)) * 11 - 1 + 4", - "y": "25", + "x": "12 + ceil(10 / max(1, providers.count)) * 11 - 1 + 4", + "y": "26", "width": "62", "height": "13", "background": { @@ -2415,7 +6752,7 @@ "gap": "0", "content": { "type": "text", - "template": "${codex.credits.balance:0.00}", + "template": "{accounts.codex.codex_x.session.display:usage_line}", "font_family": "Segoe UI", "font_size": "12", "weight": "medium", @@ -2423,20 +6760,21 @@ "contrast": "1", "align": "left", "color": { - "color": "#F5A623FF", - "opacity": "1" + "color": "#60A5FAFF", + "opacity": "codex.normal.opacity" } } }, { - "id": "codex-credits-segments-light", - "name": "light codex credit overlay", - "render": "(1 - system.dark) && codex.credits.available", + "id": "codex-x-text-dark-hover", + "name": "dark Codex X text 7d", + "render": "(system.dark) && (codex.dual_mode) && (codex.hover.opacity > 0.01)", "visibility": "100", "parent": "codex-provider", - "y": "27", - "width": "ceil(10 / max(1, providers.count)) * 11 - 1", - "height": "9", + "x": "12 + ceil(10 / max(1, providers.count)) * 11 - 1 + 4", + "y": "26", + "width": "62", + "height": "13", "background": { "type": "none" }, @@ -2446,31 +6784,28 @@ "align": "start", "gap": "0", "content": { - "type": "progress", - "value": "codex.credits.display", - "direction": "left_to_right", - "fill": { - "color": "#C77700FF", - "opacity": "1" - }, - "track": { - "color": "#00000000", - "opacity": "0" - }, - "corner_radius": "1.5", - "segments": 10, - "segments_expression": "ceil(10 / max(1, providers.count))", - "segment_gap": "1" + "type": "text", + "template": "{accounts.codex.codex_x.weekly.display:usage_line}", + "font_family": "Segoe UI", + "font_size": "12", + "weight": "medium", + "rendering": "clear_type", + "contrast": "1", + "align": "left", + "color": { + "color": "#3B82F6FF", + "opacity": "codex.hover.opacity" + } } }, { - "id": "codex-credits-value-light", - "name": "light codex credit balance", - "render": "(1 - system.dark) && codex.credits.available", + "id": "codex-x-text-light-normal", + "name": "light Codex X text 5h", + "render": "((1 - system.dark)) && (codex.dual_mode) && (codex.normal.opacity > 0.01)", "visibility": "100", "parent": "codex-provider", - "x": "ceil(10 / max(1, providers.count)) * 11 - 1 + 4", - "y": "25", + "x": "12 + ceil(10 / max(1, providers.count)) * 11 - 1 + 4", + "y": "26", "width": "62", "height": "13", "background": { @@ -2483,7 +6818,7 @@ "gap": "0", "content": { "type": "text", - "template": "${codex.credits.balance:0.00}", + "template": "{accounts.codex.codex_x.session.display:usage_line}", "font_family": "Segoe UI", "font_size": "12", "weight": "medium", @@ -2491,8 +6826,41 @@ "contrast": "1", "align": "left", "color": { - "color": "#C77700FF", - "opacity": "1" + "color": "#2563EBFF", + "opacity": "codex.normal.opacity" + } + } + }, + { + "id": "codex-x-text-light-hover", + "name": "light Codex X text 7d", + "render": "((1 - system.dark)) && (codex.dual_mode) && (codex.hover.opacity > 0.01)", + "visibility": "100", + "parent": "codex-provider", + "x": "12 + ceil(10 / max(1, providers.count)) * 11 - 1 + 4", + "y": "26", + "width": "62", + "height": "13", + "background": { + "type": "none" + }, + "border": null, + "corner_radius": "0", + "layout": "freeform", + "align": "start", + "gap": "0", + "content": { + "type": "text", + "template": "{accounts.codex.codex_x.weekly.display:usage_line}", + "font_family": "Segoe UI", + "font_size": "12", + "weight": "medium", + "rendering": "clear_type", + "contrast": "1", + "align": "left", + "color": { + "color": "#1D4ED8FF", + "opacity": "codex.hover.opacity" } } }, @@ -5252,4 +9620,4 @@ ] } ] -} +} \ No newline at end of file diff --git a/src/window.rs b/src/window.rs index 5bd23d0f..546ceaea 100644 --- a/src/window.rs +++ b/src/window.rs @@ -101,6 +101,17 @@ struct AppState { pub(super) show_antigravity_gemini: bool, pub(super) show_antigravity_external: bool, crossfade_opacity: f64, + antigravity_hovered: bool, + crossfade_animation: Option, + pub(super) antigravity_tile_rect: Option<(f64, f64, f64, f64)>, + pub(super) claude_hovered: bool, + pub(super) claude_crossfade_opacity: f64, + pub(super) claude_crossfade_animation: Option, + pub(super) claude_tile_rect: Option<(f64, f64, f64, f64)>, + pub(super) codex_hovered: bool, + pub(super) codex_crossfade_opacity: f64, + pub(super) codex_crossfade_animation: Option, + pub(super) codex_tile_rect: Option<(f64, f64, f64, f64)>, accounts: crate::accounts::AccountSettings, data: Option, @@ -138,6 +149,7 @@ struct AppState { custom_theme_enabled: bool, usage_countdown: bool, + show_pace: bool, active_theme_path: Option, active_theme: Option, theme_clock_interval: Option, @@ -208,6 +220,7 @@ const IDM_FREQ_15MIN: u16 = 12; const IDM_FREQ_1HOUR: u16 = 13; const IDM_START_WITH_WINDOWS: u16 = 20; const IDM_LOCK_TASKBAR: u16 = 21; +const IDM_SHOW_PACE: u16 = 22; const IDM_VERSION_ACTION: u16 = 31; const IDM_LANG_SYSTEM: u16 = 100; const IDM_LANG_FIRST: u16 = 101; @@ -215,6 +228,10 @@ const IDM_DASHBOARD: u16 = 71; // 62 stays the whole-provider Antigravity toggle used by saved custom menus. pub(super) const IDM_PROVIDER_ANTIGRAVITY_GEMINI: u16 = 68; pub(super) const IDM_PROVIDER_ANTIGRAVITY_EXTERNAL: u16 = 67; +pub(super) const IDM_PROVIDER_CODEX_MAIN: u16 = 69; +pub(super) const IDM_PROVIDER_CODEX_X: u16 = 70; +pub(super) const IDM_PROVIDER_CLAUDE_MAIN: u16 = 72; +pub(super) const IDM_PROVIDER_CLAUDE_X: u16 = 73; const WM_DPICHANGED_MSG: u32 = 0x02E0; const WM_APP_UPDATE_CHECK_COMPLETE: u32 = WM_APP + 2; @@ -793,6 +810,7 @@ fn theme_runtime_from_state(state: &AppState) -> ThemeRuntime { .with_poll_state(poll_ok, has_error) .with_language(state.language) .with_countdown(state.usage_countdown) + .with_show_pace(state.show_pace) .with_nest(nest) .with_floating_card_opacity(opacity) .with_antigravity_pools( @@ -800,6 +818,50 @@ fn theme_runtime_from_state(state: &AppState) -> ThemeRuntime { state.show_antigravity_external, state.crossfade_opacity, ) + .with_claude_state( + state.claude_hovered, + state.providers.contains(ProviderId::Claude) + && state + .accounts + .claude + .profiles + .iter() + .find(|p| p.id == "default") + .map(|p| p.enabled) + .unwrap_or(true), + state.providers.contains(ProviderId::Claude) + && state + .accounts + .claude + .profiles + .iter() + .find(|p| p.id == "claude_x") + .map(|p| p.enabled) + .unwrap_or(false), + state.claude_crossfade_opacity, + ) + .with_codex_state( + state.codex_hovered, + state.providers.contains(ProviderId::Codex) + && state + .accounts + .codex + .profiles + .iter() + .find(|p| p.id == "default") + .map(|p| p.enabled) + .unwrap_or(true), + state.providers.contains(ProviderId::Codex) + && state + .accounts + .codex + .profiles + .iter() + .find(|p| p.id == "codex_x") + .map(|p| p.enabled) + .unwrap_or(false), + state.codex_crossfade_opacity, + ) } /// A transient outage can keep presenting the last real reading while its @@ -1030,6 +1092,7 @@ fn save_state_settings() { persisted.show_antigravity_gemini = Some(antigravity_on && s.show_antigravity_gemini); persisted.show_antigravity_external = Some(antigravity_on && s.show_antigravity_external); persisted.custom_theme_enabled = s.custom_theme_enabled; + persisted.show_pace = s.show_pace; persisted.active_theme_path = s .active_theme_path .as_ref() @@ -1037,6 +1100,7 @@ fn save_state_settings() { persisted.placement_override = s.placement_override.clone(); persisted.floating_card_opacity = s.floating_card_opacity; persisted.lock_taskbar = s.lock_taskbar; + persisted.accounts = s.accounts.clone(); // The dashboard process owns its dimensions, so leave the freshly // loaded values unchanged when monitor actions persist settings. if let Err(error) = save_settings(&persisted) { @@ -1917,6 +1981,9 @@ fn replace_active_theme(state: &mut AppState, loaded: ThemeDocument, path: Optio clear_auto_ejection(state); } state.active_theme = Some(loaded); + state.antigravity_tile_rect = None; + state.claude_tile_rect = None; + state.codex_tile_rect = None; if path.is_some() { state.active_theme_path = path; } @@ -2574,6 +2641,17 @@ pub fn run() { show_antigravity_gemini: settings.antigravity_gemini_enabled(), show_antigravity_external: settings.antigravity_external_enabled(), crossfade_opacity: 1.0, + antigravity_hovered: false, + crossfade_animation: None, + antigravity_tile_rect: None, + claude_hovered: false, + claude_crossfade_opacity: 0.0, + claude_crossfade_animation: None, + claude_tile_rect: None, + codex_hovered: false, + codex_crossfade_opacity: 0.0, + codex_crossfade_animation: None, + codex_tile_rect: None, accounts: settings.accounts.clone(), data: None, poll_interval_ms: settings.poll_interval_ms, @@ -2607,6 +2685,7 @@ pub fn run() { window_state_timer_active: false, custom_theme_enabled, usage_countdown: settings.usage_countdown, + show_pace: settings.show_pace, active_theme_path, active_theme, theme_clock_interval, @@ -2642,17 +2721,6 @@ pub fn run() { // Initial render using the presenter selected by the surface nest. schedule_countdown_timer(); schedule_clock_timer(); - let startup_dual_mode = { - let state = lock_state(); - state.as_ref().is_some_and(|s| { - s.show_antigravity_gemini - && s.show_antigravity_external - && s.providers.contains(ProviderId::Antigravity) - }) - }; - if startup_dual_mode { - arm_crossfade_schedule(hwnd); - } render_layered(); if open_dashboard_on_start { @@ -2744,6 +2812,56 @@ fn render_layered() { }; let surface = &theme.surfaces[surface_index]; let surface_runtime = theme_runtime_for_surface(&theme, surface_index, runtime); + if surface_index == 0 { + let needs_rect = lock_state() + .as_ref() + .map(|s| s.antigravity_tile_rect.is_none()) + .unwrap_or(false); + if needs_rect { + let tile_rect = theme_engine::object_bounds( + &theme, + 0, + usage_data.as_ref(), + surface_runtime, + mouse::ANTIGRAVITY_HOVER_OBJECT, + ); + if let Some(state) = lock_state().as_mut() { + state.antigravity_tile_rect = tile_rect; + } + } + let needs_claude_rect = lock_state() + .as_ref() + .map(|s| s.claude_tile_rect.is_none()) + .unwrap_or(false); + if needs_claude_rect { + let tile_rect = theme_engine::object_bounds( + &theme, + 0, + usage_data.as_ref(), + surface_runtime, + mouse::CLAUDE_HOVER_OBJECT, + ); + if let Some(state) = lock_state().as_mut() { + state.claude_tile_rect = tile_rect; + } + } + let needs_codex_rect = lock_state() + .as_ref() + .map(|s| s.codex_tile_rect.is_none()) + .unwrap_or(false); + if needs_codex_rect { + let tile_rect = theme_engine::object_bounds( + &theme, + 0, + usage_data.as_ref(), + surface_runtime, + mouse::CODEX_HOVER_OBJECT, + ); + if let Some(state) = lock_state().as_mut() { + state.codex_tile_rect = tile_rect; + } + } + } let nest = surface .placement .nest @@ -3358,43 +3476,321 @@ fn check_language_change() { } } -/// All widget surfaces use the same wall-clock phase, including after a -/// settings change or a delayed timer following sleep. -fn antigravity_crossfade_frame(now_ms: u64) -> (f64, u32) { - let phase = now_ms % 20_000; - let smooth = |elapsed: u64| { - let t = elapsed as f64 / 2_000.0; - t * t * (3.0 - 2.0 * t) +const ANTIGRAVITY_CROSSFADE_DURATION_MS: u64 = 300; +const CODEX_CROSSFADE_DURATION_MS: u64 = 300; +const CLAUDE_CROSSFADE_DURATION_MS: u64 = 300; +const ANTIGRAVITY_CROSSFADE_TICK_MS: u32 = 16; + +#[derive(Clone, Copy, Debug)] +pub(super) struct CrossfadeAnimation { + pub(super) start_opacity: f64, + pub(super) target_opacity: f64, + pub(super) start_time: std::time::Instant, + pub(super) duration: std::time::Duration, + pub(super) last_rendered: std::time::Instant, +} + +impl CrossfadeAnimation { + pub(super) fn new( + start_opacity: f64, + target_opacity: f64, + duration: std::time::Duration, + ) -> Self { + let now = std::time::Instant::now(); + Self { + start_opacity, + target_opacity, + start_time: now, + duration, + last_rendered: now, + } + } + + pub(super) fn current_opacity(&self) -> (f64, bool) { + let elapsed = self.start_time.elapsed(); + if elapsed >= self.duration || self.duration.is_zero() { + (self.target_opacity, false) + } else { + let progress = elapsed.as_secs_f64() / self.duration.as_secs_f64(); + let opacity = + self.start_opacity + (self.target_opacity - self.start_opacity) * progress; + (opacity, true) + } + } +} + +pub(super) fn tick_antigravity_crossfade(hwnd: HWND, throttle: bool) { + let (should_render, still_animating) = { + let mut state = lock_state(); + let Some(state) = state.as_mut() else { + return; + }; + let Some(mut anim) = state.crossfade_animation else { + return; + }; + let now = std::time::Instant::now(); + if throttle && now.duration_since(anim.last_rendered) < std::time::Duration::from_millis(15) + { + return; + } + let (opacity, more) = anim.current_opacity(); + state.crossfade_opacity = opacity; + anim.last_rendered = now; + if more { + state.crossfade_animation = Some(anim); + } else { + state.crossfade_opacity = anim.target_opacity; + state.crossfade_animation = None; + } + (true, more) }; - match phase { - 0..8_000 => (1.0, (8_000 - phase) as u32), - 8_000..10_000 => (1.0 - smooth(phase - 8_000), 30), - 10_000..18_000 => (0.0, (18_000 - phase) as u32), - _ => (smooth(phase - 18_000), 30), + if !still_animating { + let any_animating = { + let state = lock_state(); + state.as_ref().is_some_and(|s| { + s.crossfade_animation.is_some() + || s.codex_crossfade_animation.is_some() + || s.claude_crossfade_animation.is_some() + }) + }; + if !any_animating { + unsafe { + let _ = kill_controller_timer(Some(hwnd), TIMER_CROSSFADE_SCHEDULE); + } + } + } + if should_render { + render_layered(); } } -pub(super) fn arm_crossfade_schedule(hwnd: HWND) { - let now_ms = SystemTime::now() - .duration_since(UNIX_EPOCH) - .map(|duration| duration.as_millis() as u64) - .unwrap_or(0); - let (opacity, delay_ms) = antigravity_crossfade_frame(now_ms); - let mut state = lock_state(); - let dual_mode = state.as_ref().is_some_and(|state| { - state.show_antigravity_gemini - && state.show_antigravity_external - && state.providers.contains(ProviderId::Antigravity) - }); - if let Some(state) = state.as_mut() { - state.crossfade_opacity = if dual_mode { opacity } else { 1.0 }; +pub(super) fn tick_claude_crossfade(hwnd: HWND, throttle: bool) { + let (should_render, still_animating) = { + let mut state = lock_state(); + let Some(state) = state.as_mut() else { + return; + }; + let Some(mut anim) = state.claude_crossfade_animation else { + return; + }; + let now = std::time::Instant::now(); + if throttle && now.duration_since(anim.last_rendered) < std::time::Duration::from_millis(15) + { + return; + } + let (opacity, more) = anim.current_opacity(); + state.claude_crossfade_opacity = opacity; + anim.last_rendered = now; + if more { + state.claude_crossfade_animation = Some(anim); + } else { + state.claude_crossfade_opacity = anim.target_opacity; + state.claude_crossfade_animation = None; + } + (true, more) + }; + if !still_animating { + let any_animating = { + let state = lock_state(); + state.as_ref().is_some_and(|s| { + s.crossfade_animation.is_some() + || s.codex_crossfade_animation.is_some() + || s.claude_crossfade_animation.is_some() + }) + }; + if !any_animating { + unsafe { + let _ = kill_controller_timer(Some(hwnd), TIMER_CROSSFADE_SCHEDULE); + } + } } - unsafe { - if dual_mode { - let _ = set_controller_timer(Some(hwnd), TIMER_CROSSFADE_SCHEDULE, delay_ms, None); + if should_render { + render_layered(); + } +} + +pub(super) fn set_claude_hover(hwnd: HWND, hovered: bool) { + let mut should_animate = false; + { + let mut state = lock_state(); + let Some(state) = state.as_mut() else { + return; + }; + let dual_claude = state.providers.contains(ProviderId::Claude) + && state + .accounts + .claude + .profiles + .iter() + .find(|p| p.id == "default") + .map(|p| p.enabled) + .unwrap_or(true) + && state + .accounts + .claude + .profiles + .iter() + .find(|p| p.id == "claude_x") + .map(|p| p.enabled) + .unwrap_or(false); + + if state.claude_hovered != hovered { + state.claude_hovered = hovered; + if dual_claude { + let target = if hovered { 1.0 } else { 0.0 }; + state.claude_crossfade_animation = Some(CrossfadeAnimation::new( + state.claude_crossfade_opacity, + target, + std::time::Duration::from_millis(CLAUDE_CROSSFADE_DURATION_MS), + )); + should_animate = true; + } + } + } + if should_animate { + unsafe { + let _ = set_controller_timer( + Some(hwnd), + TIMER_CROSSFADE_SCHEDULE, + ANTIGRAVITY_CROSSFADE_TICK_MS, + None, + ); + } + render_layered(); + } +} + +pub(super) fn tick_codex_crossfade(hwnd: HWND, throttle: bool) { + let (should_render, still_animating) = { + let mut state = lock_state(); + let Some(state) = state.as_mut() else { + return; + }; + let Some(mut anim) = state.codex_crossfade_animation else { + return; + }; + let now = std::time::Instant::now(); + if throttle && now.duration_since(anim.last_rendered) < std::time::Duration::from_millis(15) + { + return; + } + let (opacity, more) = anim.current_opacity(); + state.codex_crossfade_opacity = opacity; + anim.last_rendered = now; + if more { + state.codex_crossfade_animation = Some(anim); } else { - let _ = kill_controller_timer(Some(hwnd), TIMER_CROSSFADE_SCHEDULE); + state.codex_crossfade_opacity = anim.target_opacity; + state.codex_crossfade_animation = None; + } + (true, more) + }; + if !still_animating { + let any_animating = { + let state = lock_state(); + state.as_ref().is_some_and(|s| { + s.crossfade_animation.is_some() + || s.codex_crossfade_animation.is_some() + || s.claude_crossfade_animation.is_some() + }) + }; + if !any_animating { + unsafe { + let _ = kill_controller_timer(Some(hwnd), TIMER_CROSSFADE_SCHEDULE); + } + } + } + if should_render { + render_layered(); + } +} + +/// Updates the hover state when the cursor enters or leaves the Codex tile with a 300ms crossfade animation. +pub(super) fn set_codex_hover(hwnd: HWND, hovered: bool) { + let mut should_animate = false; + { + let mut state = lock_state(); + let Some(state) = state.as_mut() else { + return; + }; + let dual_codex = state.providers.contains(ProviderId::Codex) + && state + .accounts + .codex + .profiles + .iter() + .find(|p| p.id == "default") + .map(|p| p.enabled) + .unwrap_or(true) + && state + .accounts + .codex + .profiles + .iter() + .find(|p| p.id == "codex_x") + .map(|p| p.enabled) + .unwrap_or(false); + + if state.codex_hovered != hovered { + state.codex_hovered = hovered; + if dual_codex { + let target = if hovered { 1.0 } else { 0.0 }; + state.codex_crossfade_animation = Some(CrossfadeAnimation::new( + state.codex_crossfade_opacity, + target, + std::time::Duration::from_millis(CODEX_CROSSFADE_DURATION_MS), + )); + should_animate = true; + } + } + } + if should_animate { + unsafe { + let _ = set_controller_timer( + Some(hwnd), + TIMER_CROSSFADE_SCHEDULE, + ANTIGRAVITY_CROSSFADE_TICK_MS, + None, + ); } + render_layered(); + } +} + +pub(super) fn set_antigravity_hover(hwnd: HWND, hovered: bool) { + let mut should_animate = false; + { + let mut state = lock_state(); + let Some(state) = state.as_mut() else { + return; + }; + // Dual mode fades Gemini to Claude/GPT; a single pool fades to the + // hidden one. + let any_pool = (state.show_antigravity_gemini || state.show_antigravity_external) + && state.providers.contains(ProviderId::Antigravity); + if state.antigravity_hovered != hovered { + state.antigravity_hovered = hovered; + if any_pool { + let target = if hovered { 0.0 } else { 1.0 }; + state.crossfade_animation = Some(CrossfadeAnimation::new( + state.crossfade_opacity, + target, + std::time::Duration::from_millis(ANTIGRAVITY_CROSSFADE_DURATION_MS), + )); + should_animate = true; + } + } + } + if should_animate { + unsafe { + let _ = set_controller_timer( + Some(hwnd), + TIMER_CROSSFADE_SCHEDULE, + ANTIGRAVITY_CROSSFADE_TICK_MS, + None, + ); + } + render_layered(); } } @@ -3404,8 +3800,6 @@ fn reload_external_settings(hwnd: HWND) { let theme_path = settings.active_theme_path.as_ref().map(PathBuf::from); let providers_changed; let lock_enabled; - let antigravity_changed; - let dual_mode; { let mut state = lock_state(); let Some(state) = state.as_mut() else { @@ -3415,8 +3809,6 @@ fn reload_external_settings(hwnd: HWND) { state.providers != settings.enabled_providers() || state.accounts != settings.accounts; let gemini_enabled = settings.antigravity_gemini_enabled(); let external_enabled = settings.antigravity_external_enabled(); - antigravity_changed = state.show_antigravity_gemini != gemini_enabled - || state.show_antigravity_external != external_enabled; state.show_antigravity_gemini = gemini_enabled; state.show_antigravity_external = external_enabled; state.accounts = settings.accounts.clone(); @@ -3426,15 +3818,37 @@ fn reload_external_settings(hwnd: HWND) { state.poll_interval_ms = settings.poll_interval_ms; state.providers = settings.enabled_providers(); state.usage_countdown = settings.usage_countdown; - dual_mode = state.show_antigravity_gemini - && state.show_antigravity_external + state.show_pace = settings.show_pace; + let any_pool = (state.show_antigravity_gemini || state.show_antigravity_external) && state.providers.contains(ProviderId::Antigravity); - if !dual_mode { + if !any_pool { + state.antigravity_hovered = false; + state.crossfade_opacity = 1.0; + state.crossfade_animation = None; + } + let codex_active = state.providers.contains(ProviderId::Codex); + if !codex_active { + state.codex_hovered = false; + state.codex_crossfade_opacity = 0.0; + state.codex_crossfade_animation = None; + } + let claude_active = state.providers.contains(ProviderId::Claude); + if !claude_active { + state.claude_hovered = false; + state.claude_crossfade_opacity = 0.0; + state.claude_crossfade_animation = None; + } + let any_animating = state.crossfade_animation.is_some() + || state.codex_crossfade_animation.is_some() + || state.claude_crossfade_animation.is_some(); + if !any_animating { unsafe { let _ = kill_controller_timer(Some(hwnd), TIMER_CROSSFADE_SCHEDULE); } - state.crossfade_opacity = 1.0; } + state.antigravity_tile_rect = None; + state.claude_tile_rect = None; + state.codex_tile_rect = None; update_configured_placement( state, settings.placement_override, @@ -3446,9 +3860,6 @@ fn reload_external_settings(hwnd: HWND) { lock_enabled = state.lock_taskbar; apply_language_to_state(state, language_override); } - if dual_mode && (antigravity_changed || providers_changed) { - arm_crossfade_schedule(hwnd); - } unsafe { set_controller_timer(Some(hwnd), TIMER_POLL, settings.poll_interval_ms, None); } @@ -4252,25 +4663,24 @@ mod credential_watch_worker_tests { #[cfg(test)] mod antigravity_crossfade_tests { - use super::antigravity_crossfade_frame; + use super::CrossfadeAnimation; + use std::time::Duration; #[test] - fn pool_crossfade_follows_the_same_phase_after_startup_sleep_and_rearming() { - for cycle in [0, 20_000, 180_000] { - for (phase, opacity, delay) in [ - (0, 1.0, 8_000), - (7_000, 1.0, 1_000), - (8_000, 1.0, 30), - (9_000, 0.5, 30), - (10_000, 0.0, 8_000), - (17_000, 0.0, 1_000), - (18_000, 0.0, 30), - (19_000, 0.5, 30), - ] { - assert_eq!(antigravity_crossfade_frame(cycle + phase), (opacity, delay)); - } - } - let before_wrap = antigravity_crossfade_frame(19_999).0; - assert!((1.0 - before_wrap).abs() < 0.000_001); + fn crossfade_animation_interpolates_and_completes() { + let anim = CrossfadeAnimation::new(1.0, 0.0, Duration::from_millis(0)); + let (opacity, more) = anim.current_opacity(); + assert_eq!(opacity, 0.0); + assert!(!more); + + let anim = CrossfadeAnimation::new(0.0, 1.0, Duration::from_secs(10)); + let (opacity, more) = anim.current_opacity(); + assert!(opacity < 0.1); + assert!(more); + + let anim_return = CrossfadeAnimation::new(0.0, 1.0, Duration::from_millis(0)); + let (opacity, more) = anim_return.current_opacity(); + assert_eq!(opacity, 1.0); + assert!(!more); } } diff --git a/src/window/message_loop.rs b/src/window/message_loop.rs index 4c8cf953..f2ee3272 100644 --- a/src/window/message_loop.rs +++ b/src/window/message_loop.rs @@ -122,8 +122,19 @@ pub(super) unsafe extern "system" fn wnd_proc( lifecycle::reconcile_surfaces(); } TIMER_CROSSFADE_SCHEDULE => { - arm_crossfade_schedule(hwnd); - render_layered(); + tick_antigravity_crossfade(hwnd, false); + tick_claude_crossfade(hwnd, false); + tick_codex_crossfade(hwnd, false); + let any_animating = lock_state().as_ref().is_some_and(|s| { + s.crossfade_animation.is_some() + || s.claude_crossfade_animation.is_some() + || s.codex_crossfade_animation.is_some() + }); + if !any_animating { + unsafe { + let _ = kill_controller_timer(Some(hwnd), TIMER_CROSSFADE_SCHEDULE); + } + } } _ => {} } @@ -135,6 +146,11 @@ pub(super) unsafe extern "system" fn wnd_proc( LRESULT(0) } WM_APP_USAGE_UPDATED => { + if let Some(state) = lock_state().as_mut() { + state.antigravity_tile_rect = None; + state.claude_tile_rect = None; + state.codex_tile_rect = None; + } check_theme_change(); check_language_change(); render_layered(); @@ -773,6 +789,17 @@ pub(super) unsafe extern "system" fn wnd_proc( IDM_LOCK_TASKBAR => { toggle_taskbar_lock(hwnd); } + IDM_SHOW_PACE => { + { + let mut state = lock_state(); + if let Some(s) = state.as_mut() { + s.show_pace = !s.show_pace; + } + } + save_state_settings(); + render_layered(); + sync_tray_icon(hwnd); + } IDM_FREQ_1MIN | IDM_FREQ_5MIN | IDM_FREQ_15MIN | IDM_FREQ_1HOUR => { let new_interval = match id { IDM_FREQ_1MIN => POLL_1_MIN, @@ -793,7 +820,6 @@ pub(super) unsafe extern "system" fn wnd_proc( } IDM_PROVIDER_ANTIGRAVITY_GEMINI | IDM_PROVIDER_ANTIGRAVITY_EXTERNAL => { let mut should_reposition = false; - let mut dual_mode = false; { let mut state = lock_state(); if let Some(s) = state.as_mut() { @@ -829,23 +855,252 @@ pub(super) unsafe extern "system" fn wnd_proc( s.providers.set(ProviderId::Antigravity, true); should_reposition = true; } - dual_mode = s.show_antigravity_gemini - && s.show_antigravity_external + let any_pool = (s.show_antigravity_gemini + || s.show_antigravity_external) && s.providers.contains(ProviderId::Antigravity); - if !dual_mode { - unsafe { - let _ = kill_controller_timer( - Some(hwnd), - TIMER_CROSSFADE_SCHEDULE, - ); - } + s.antigravity_tile_rect = None; + s.claude_tile_rect = None; + s.codex_tile_rect = None; + if !any_pool { + s.antigravity_hovered = false; s.crossfade_opacity = 1.0; + s.crossfade_animation = None; + if s.claude_crossfade_animation.is_none() + && s.codex_crossfade_animation.is_none() + { + unsafe { + let _ = kill_controller_timer( + Some(hwnd), + TIMER_CROSSFADE_SCHEDULE, + ); + } + } } } } } - if dual_mode { - arm_crossfade_schedule(hwnd); + save_state_settings(); + if should_reposition { + position_at_taskbar(); + } + render_layered(); + sync_tray_icon(hwnd); + request_poll(hwnd); + } + IDM_PROVIDER_CLAUDE_MAIN | IDM_PROVIDER_CLAUDE_X => { + let mut should_reposition = false; + { + let mut state = lock_state(); + if let Some(s) = state.as_mut() { + let is_main = id == IDM_PROVIDER_CLAUDE_MAIN; + let target_id = if is_main { "default" } else { "claude_x" }; + if is_main + && !s.accounts.claude.profiles.iter().any(|p| p.id == "default") + { + s.accounts + .claude + .profiles + .push(crate::accounts::AccountProfile { + id: "default".into(), + name: "Default".into(), + config_dir: String::new(), + credentials_path: String::new(), + enabled: true, + }); + s.accounts.claude.used_ids.insert("default".into()); + } else if !is_main + && !s + .accounts + .claude + .profiles + .iter() + .any(|p| p.id == "claude_x") + { + s.accounts + .claude + .profiles + .push(crate::accounts::AccountProfile { + id: "claude_x".into(), + name: "Claude Code X".into(), + config_dir: "~/.claude_x".into(), + credentials_path: String::new(), + enabled: false, + }); + s.accounts.claude.used_ids.insert("claude_x".into()); + } + let mut main_enabled = s.providers.contains(ProviderId::Claude) + && s.accounts + .claude + .profiles + .iter() + .find(|p| p.id == "default") + .map(|p| p.enabled) + .unwrap_or(true); + let mut x_enabled = s.providers.contains(ProviderId::Claude) + && s.accounts + .claude + .profiles + .iter() + .find(|p| p.id == "claude_x") + .map(|p| p.enabled) + .unwrap_or(false); + let current = if is_main { main_enabled } else { x_enabled }; + let other = if is_main { x_enabled } else { main_enabled }; + let target = !current; + if !target + && !other + && s.providers.len() <= 1 + && s.providers.contains(ProviderId::Claude) + { + // Keep at least one provider active + } else { + if let Some(p) = s + .accounts + .claude + .profiles + .iter_mut() + .find(|p| p.id == target_id) + { + p.enabled = target; + } + if is_main { + main_enabled = target; + } else { + x_enabled = target; + } + let any_claude = main_enabled || x_enabled; + if !any_claude { + s.providers.set(ProviderId::Claude, false); + s.claude_hovered = false; + s.claude_crossfade_opacity = 0.0; + s.claude_crossfade_animation = None; + if s.crossfade_animation.is_none() + && s.codex_crossfade_animation.is_none() + { + unsafe { + let _ = kill_controller_timer( + Some(hwnd), + TIMER_CROSSFADE_SCHEDULE, + ); + } + } + should_reposition = true; + } else if !s.providers.contains(ProviderId::Claude) { + s.providers.set(ProviderId::Claude, true); + should_reposition = true; + } + s.claude_tile_rect = None; + } + } + } + save_state_settings(); + if should_reposition { + position_at_taskbar(); + } + render_layered(); + sync_tray_icon(hwnd); + request_poll(hwnd); + } + IDM_PROVIDER_CODEX_MAIN | IDM_PROVIDER_CODEX_X => { + let mut should_reposition = false; + { + let mut state = lock_state(); + if let Some(s) = state.as_mut() { + let is_main = id == IDM_PROVIDER_CODEX_MAIN; + let target_id = if is_main { "default" } else { "codex_x" }; + if is_main + && !s.accounts.codex.profiles.iter().any(|p| p.id == "default") + { + s.accounts + .codex + .profiles + .push(crate::accounts::AccountProfile { + id: "default".into(), + name: "Default".into(), + config_dir: String::new(), + credentials_path: String::new(), + enabled: true, + }); + s.accounts.codex.used_ids.insert("default".into()); + } else if !is_main + && !s.accounts.codex.profiles.iter().any(|p| p.id == "codex_x") + { + s.accounts + .codex + .profiles + .push(crate::accounts::AccountProfile { + id: "codex_x".into(), + name: "Codex X".into(), + config_dir: "~/.codex_x".into(), + credentials_path: String::new(), + enabled: false, + }); + s.accounts.codex.used_ids.insert("codex_x".into()); + } + let mut main_enabled = s.providers.contains(ProviderId::Codex) + && s.accounts + .codex + .profiles + .iter() + .find(|p| p.id == "default") + .map(|p| p.enabled) + .unwrap_or(true); + let mut x_enabled = s.providers.contains(ProviderId::Codex) + && s.accounts + .codex + .profiles + .iter() + .find(|p| p.id == "codex_x") + .map(|p| p.enabled) + .unwrap_or(false); + let current = if is_main { main_enabled } else { x_enabled }; + let other = if is_main { x_enabled } else { main_enabled }; + let target = !current; + if !target + && !other + && s.providers.len() <= 1 + && s.providers.contains(ProviderId::Codex) + { + // Keep at least one provider active + } else { + if let Some(p) = s + .accounts + .codex + .profiles + .iter_mut() + .find(|p| p.id == target_id) + { + p.enabled = target; + } + if is_main { + main_enabled = target; + } else { + x_enabled = target; + } + let any_codex = main_enabled || x_enabled; + if !any_codex { + s.providers.set(ProviderId::Codex, false); + s.codex_hovered = false; + s.codex_crossfade_opacity = 0.0; + s.codex_crossfade_animation = None; + if s.crossfade_animation.is_none() + && s.claude_crossfade_animation.is_none() + { + unsafe { + let _ = kill_controller_timer( + Some(hwnd), + TIMER_CROSSFADE_SCHEDULE, + ); + } + } + should_reposition = true; + } else if !s.providers.contains(ProviderId::Codex) { + s.providers.set(ProviderId::Codex, true); + should_reposition = true; + } + s.codex_tile_rect = None; + } + } } save_state_settings(); if should_reposition { @@ -856,31 +1111,67 @@ pub(super) unsafe extern "system" fn wnd_proc( request_poll(hwnd); } id if ProviderId::from_native_menu_command_id(id).is_some() => { - let mut dual_mode = false; { let mut state = lock_state(); if let Some(s) = state.as_mut() { let provider = ProviderId::from_native_menu_command_id(id) .expect("provider menu command was matched above"); let changed = s.providers.toggle(provider); + // Tile widths depend on the provider count. + s.antigravity_tile_rect = None; + s.claude_tile_rect = None; + s.codex_tile_rect = None; + if !s.providers.contains(ProviderId::Claude) { + s.claude_hovered = false; + s.claude_crossfade_opacity = 0.0; + s.claude_crossfade_animation = None; + if s.crossfade_animation.is_none() + && s.codex_crossfade_animation.is_none() + { + unsafe { + let _ = kill_controller_timer( + Some(hwnd), + TIMER_CROSSFADE_SCHEDULE, + ); + } + } + } + if !s.providers.contains(ProviderId::Codex) { + s.codex_hovered = false; + s.codex_crossfade_opacity = 0.0; + s.codex_crossfade_animation = None; + if s.crossfade_animation.is_none() + && s.claude_crossfade_animation.is_none() + { + unsafe { + let _ = kill_controller_timer( + Some(hwnd), + TIMER_CROSSFADE_SCHEDULE, + ); + } + } + } if provider == ProviderId::Antigravity && changed { let enabled = s.providers.contains(ProviderId::Antigravity); s.show_antigravity_gemini = enabled; s.show_antigravity_external = enabled; if !enabled { - let _ = - kill_controller_timer(Some(hwnd), TIMER_CROSSFADE_SCHEDULE); + s.antigravity_hovered = false; s.crossfade_opacity = 1.0; + s.crossfade_animation = None; + s.antigravity_tile_rect = None; + if s.claude_crossfade_animation.is_none() + && s.codex_crossfade_animation.is_none() + { + let _ = kill_controller_timer( + Some(hwnd), + TIMER_CROSSFADE_SCHEDULE, + ); + } } } - dual_mode = s.show_antigravity_gemini - && s.show_antigravity_external - && s.providers.contains(ProviderId::Antigravity); } } - if dual_mode { - arm_crossfade_schedule(hwnd); - } save_state_settings(); position_at_taskbar(); render_layered(); diff --git a/src/window/mouse.rs b/src/window/mouse.rs index d9c70c03..b60e1aa9 100644 --- a/src/window/mouse.rs +++ b/src/window/mouse.rs @@ -195,10 +195,84 @@ pub(super) fn dispatch_double_click(hwnd: HWND, surface_index: usize, object_id: let _ = hwnd; } +/// Theme object whose hover reveals the Antigravity Claude/GPT pool. +pub(super) const ANTIGRAVITY_HOVER_OBJECT: &str = "antigravity-provider"; +pub(super) const CLAUDE_HOVER_OBJECT: &str = "claude-provider"; +pub(super) const CODEX_HOVER_OBJECT: &str = "codex-provider"; + +fn claude_hover_at(hwnd: HWND, lparam: LPARAM) -> bool { + let state = lock_state(); + let Some(state) = state.as_ref() else { + return false; + }; + if surface_index_for_window(state, hwnd) != Some(0) { + return false; + } + let Some(rect) = state.claude_tile_rect else { + return false; + }; + let Some(theme) = state.active_theme.as_ref() else { + return false; + }; + let scale = theme_surface_scale(theme, 0).max(0.01); + let (x, y) = mouse_client_point(lparam); + let lx = x / scale; + let ly = y / scale; + lx >= rect.0 && lx < rect.0 + rect.2 && ly >= rect.1 && ly < rect.1 + rect.3 +} + +fn codex_hover_at(hwnd: HWND, lparam: LPARAM) -> bool { + let state = lock_state(); + let Some(state) = state.as_ref() else { + return false; + }; + if surface_index_for_window(state, hwnd) != Some(0) { + return false; + } + let Some(rect) = state.codex_tile_rect else { + return false; + }; + let Some(theme) = state.active_theme.as_ref() else { + return false; + }; + let scale = theme_surface_scale(theme, 0).max(0.01); + let (x, y) = mouse_client_point(lparam); + let lx = x / scale; + let ly = y / scale; + lx >= rect.0 && lx < rect.0 + rect.2 && ly >= rect.1 && ly < rect.1 + rect.3 +} + +fn antigravity_hover_at(hwnd: HWND, lparam: LPARAM) -> bool { + let state = lock_state(); + let Some(state) = state.as_ref() else { + return false; + }; + if surface_index_for_window(state, hwnd) != Some(0) { + return false; + } + let Some(rect) = state.antigravity_tile_rect else { + return false; + }; + let Some(theme) = state.active_theme.as_ref() else { + return false; + }; + let scale = theme_surface_scale(theme, 0).max(0.01); + let (x, y) = mouse_client_point(lparam); + let lx = x / scale; + let ly = y / scale; + lx >= rect.0 && lx < rect.0 + rect.2 && ly >= rect.1 && ly < rect.1 + rect.3 +} + pub(super) fn update_mouse_hover(hwnd: HWND, lparam: LPARAM) { track_mouse_hover_with(hwnd, widget_tooltip::visible_for(hwnd), |tracking| unsafe { TrackMouseEvent(tracking) }); + set_antigravity_hover(hwnd, antigravity_hover_at(hwnd, lparam)); + super::set_claude_hover(hwnd, claude_hover_at(hwnd, lparam)); + super::set_codex_hover(hwnd, codex_hover_at(hwnd, lparam)); + super::tick_antigravity_crossfade(hwnd, true); + super::tick_claude_crossfade(hwnd, true); + super::tick_codex_crossfade(hwnd, true); for _ in 0..4 { let target = mouse_target_at(hwnd, lparam); let previous = { @@ -261,6 +335,9 @@ fn track_mouse_hover_with( pub(super) fn clear_mouse_hover(hwnd: HWND) { widget_tooltip::hide_for(hwnd); + set_antigravity_hover(hwnd, false); + super::set_claude_hover(hwnd, false); + super::set_codex_hover(hwnd, false); let previous = { let mut state = lock_state(); let Some(state) = state.as_mut() else { diff --git a/src/window/placement_regression_tests.rs b/src/window/placement_regression_tests.rs index 44b68ed7..90a868f6 100644 --- a/src/window/placement_regression_tests.rs +++ b/src/window/placement_regression_tests.rs @@ -15,6 +15,17 @@ pub(super) fn state_for(theme: ThemeDocument, placement: PlacementOverride) -> A show_antigravity_gemini: true, show_antigravity_external: true, crossfade_opacity: 1.0, + antigravity_hovered: false, + crossfade_animation: None, + antigravity_tile_rect: None, + claude_hovered: false, + claude_crossfade_opacity: 0.0, + claude_crossfade_animation: None, + claude_tile_rect: None, + codex_hovered: false, + codex_crossfade_opacity: 0.0, + codex_crossfade_animation: None, + codex_tile_rect: None, accounts: Default::default(), data: None, poll_interval_ms: POLL_15_MIN, @@ -46,6 +57,7 @@ pub(super) fn state_for(theme: ThemeDocument, placement: PlacementOverride) -> A window_state_timer_active: false, custom_theme_enabled: true, usage_countdown: false, + show_pace: true, active_theme_path: None, active_theme: Some(theme), theme_clock_interval: None, diff --git a/src/window/window_context_menu.rs b/src/window/window_context_menu.rs index f92f1213..06383a26 100644 --- a/src/window/window_context_menu.rs +++ b/src/window/window_context_menu.rs @@ -147,8 +147,53 @@ pub(super) fn context_menu_action_flags( ContextMenuAction::ToggleProvider { provider } => state.providers.contains(*provider), ContextMenuAction::ToggleAntigravityGemini => state.show_antigravity_gemini, ContextMenuAction::ToggleAntigravityExternal => state.show_antigravity_external, + ContextMenuAction::ToggleClaudeMain => { + state.providers.contains(ProviderId::Claude) + && state + .accounts + .claude + .profiles + .iter() + .find(|p| p.id == "default") + .map(|p| p.enabled) + .unwrap_or(true) + } + ContextMenuAction::ToggleClaudeX => { + state.providers.contains(ProviderId::Claude) + && state + .accounts + .claude + .profiles + .iter() + .find(|p| p.id == "claude_x") + .map(|p| p.enabled) + .unwrap_or(false) + } + ContextMenuAction::ToggleCodexMain => { + state.providers.contains(ProviderId::Codex) + && state + .accounts + .codex + .profiles + .iter() + .find(|p| p.id == "default") + .map(|p| p.enabled) + .unwrap_or(true) + } + ContextMenuAction::ToggleCodexX => { + state.providers.contains(ProviderId::Codex) + && state + .accounts + .codex + .profiles + .iter() + .find(|p| p.id == "codex_x") + .map(|p| p.enabled) + .unwrap_or(false) + } ContextMenuAction::ToggleStartup => is_startup_enabled(), ContextMenuAction::ToggleTaskbarLock => state.lock_taskbar, + ContextMenuAction::ToggleShowPace => state.show_pace, ContextMenuAction::ToggleWidget => state .active_theme .as_ref() @@ -271,8 +316,13 @@ pub(super) fn execute_context_menu_action( } ContextMenuAction::ToggleAntigravityGemini => Some(IDM_PROVIDER_ANTIGRAVITY_GEMINI), ContextMenuAction::ToggleAntigravityExternal => Some(IDM_PROVIDER_ANTIGRAVITY_EXTERNAL), + ContextMenuAction::ToggleClaudeMain => Some(IDM_PROVIDER_CLAUDE_MAIN), + ContextMenuAction::ToggleClaudeX => Some(IDM_PROVIDER_CLAUDE_X), + ContextMenuAction::ToggleCodexMain => Some(IDM_PROVIDER_CODEX_MAIN), + ContextMenuAction::ToggleCodexX => Some(IDM_PROVIDER_CODEX_X), ContextMenuAction::ToggleStartup => Some(IDM_START_WITH_WINDOWS), ContextMenuAction::ToggleTaskbarLock => Some(IDM_LOCK_TASKBAR), + ContextMenuAction::ToggleShowPace => Some(IDM_SHOW_PACE), ContextMenuAction::SetLanguage { language } => { if language.eq_ignore_ascii_case("system") { Some(IDM_LANG_SYSTEM)