codeburn/mac/Sources/CodeBurnMenubar/Theme/Theme.swift
Resham Joshi f7f64a01ab
Add new providers, fix menubar tabs, accent color picker (#167)
* Add Kiro provider and transparent auto-model naming

- Add Kiro IDE provider: parses .chat JSON files, estimates tokens,
  normalizes dot-versioned model IDs for cost lookup
- Show "Cursor (auto)", "Copilot (auto)", "Kiro (auto)" in CLI
  dashboard instead of pretending to know which model was used
- Route auto model names through BUILTIN_ALIASES for cost estimation

* Fix menubar tabs: add missing providers, show period-scoped costs

- Add Kiro, OMP to ProviderFilter enum so installed providers appear as tabs
- Merge Cursor + Cursor Agent into single Cursor tab
- Tab costs now reflect the selected period (7d/30d/month/all) instead
  of always showing today
- Tab visibility still uses today's provider list so tabs don't
  disappear when switching to periods with no data

* Add accent color picker to menubar with Apple system presets

- 9 presets using Apple's exact macOS dark-mode accent colors
  (Ember, Blue, Purple, Pink, Red, Orange, Yellow, Green, Graphite)
- Color picker in header, persisted via UserDefaults
- "Burn" text stays fixed ember regardless of accent
- ThemeState is MainActor-isolated for thread safety
- Picker state lifted to AppStore so it survives .id() tree rebuild
- Accessibility labels on all color swatches
- Renamed brandAccentDark/brandEmberDeep/brandEmberGlow to match
  their actual light/deep/glow semantics

* Fix review findings: case-sensitive cost lookup, Kiro timestamp guard, cache versioning

- Normalize provider dictionary keys to lowercase in tab cost lookup
  so "Cursor Agent" (title-case from CLI) matches providerKeys
- Guard against missing/invalid/epoch startTime in Kiro parser to
  prevent RangeError crash or 1970-01-01 ghost entries
- Bump DAILY_CACHE_VERSION to 4 so upgraded users get a clean
  recompute with the new auto-model naming (cursor-auto vs default)
- Add version field to cursor-results.json cache to invalidate stale
  entries that still use the old 'default' model name
2026-04-27 19:46:30 -07:00

35 lines
1.9 KiB
Swift

import SwiftUI
/// Design tokens. Accent colors are driven by ThemeState so the user can switch palettes.
@MainActor
enum Theme {
static let brandEmber = Color(red: 0xC9/255.0, green: 0x52/255.0, blue: 0x1D/255.0)
static var brandAccent: Color { ThemeState.shared.preset.base }
static var brandAccentLight: Color { ThemeState.shared.preset.light }
static var brandAccentDeep: Color { ThemeState.shared.preset.deep }
static var brandAccentGlow: Color { ThemeState.shared.preset.glow }
static let warmSurface = Color(red: 0xFA/255.0, green: 0xF7/255.0, blue: 0xF3/255.0)
static let warmSurfaceDark = Color(red: 0x1C/255.0, green: 0x18/255.0, blue: 0x16/255.0)
static let categoricalClaude = Color(red: 0xC9/255.0, green: 0x52/255.0, blue: 0x1D/255.0)
static let categoricalCursor = Color(red: 0x3F/255.0, green: 0x6B/255.0, blue: 0x8C/255.0)
static let categoricalCodex = Color(red: 0x4A/255.0, green: 0x7D/255.0, blue: 0x5C/255.0)
static let oneShotGood = Color(red: 0x30/255.0, green: 0xD1/255.0, blue: 0x58/255.0)
static let oneShotMid = Color(red: 0xFF/255.0, green: 0x9F/255.0, blue: 0x0A/255.0)
static let oneShotLow = Color(red: 0xFF/255.0, green: 0x45/255.0, blue: 0x3A/255.0)
// Semantic colors -- tuned to sit alongside the terracotta accent without clashing.
static let semanticDanger = Color(red: 0xC8/255.0, green: 0x3F/255.0, blue: 0x2C/255.0) // brick-red, terracotta-leaning
static let semanticWarning = Color(red: 0xD9/255.0, green: 0x8F/255.0, blue: 0x29/255.0) // amber, warmer than vanilla
static let semanticSuccess = Color(red: 0x4E/255.0, green: 0xA8/255.0, blue: 0x65/255.0) // muted green that holds against terracotta
}
extension Font {
/// SF Mono for currency values -- developer-tool identity.
static func codeMono(size: CGFloat, weight: Font.Weight = .regular) -> Font {
.system(size: size, weight: weight, design: .monospaced)
}
}