Summary
Final pass on the design-tokens cleanup tracked in #33 / #36. Three small categories of literals that the audits missed plus a new namespace for behavior tokens.
Scope
1. Visual literals (DesignTokens)
Three offset literals and five proportional font ratios are still inline:
| File |
Site |
Today |
| `HomeCardSlot.swift:23` |
remove-button offset |
`.offset(x: -8, y: -8)` |
| `LogRowView.swift:51` |
device thumbnail offset |
`.offset(x: 3, y: 3)` |
| `DeviceFirmwareMenu.swift:79` |
update-count badge offset |
`.offset(x: 4, y: -2)` |
| `DocBrowserView.swift:205` |
icon glyph in nav row |
`size * 0.5` |
| `GroupIconView.swift:25` |
member count glyph |
`size * 0.5` |
| `DeviceImageView.swift:73` |
placeholder glyph |
`size * 0.5` |
| `LogRowView.swift:45` |
small device thumb glyph |
`size * 0.38` |
| `FeatureIconTile.swift:17` |
feature glyph |
`prominent ? size * 0.55 : size * 0.5` |
These move to `DesignTokens.Size.` (offsets) and a new `DesignTokens.Typography.iconRatio` family (ratios).
2. Behavior tokens (new `AppConfig` namespace)
Network timeouts and UX-tuning windows are typed constants today, scattered across the files that consume them:
| File |
Constant |
Today |
| `Z2MWebSocketClient.swift` |
connection timeout |
`TimeInterval = 10` |
| `Z2MWebSocketClient.swift` |
first-message timeout |
`TimeInterval = 5` |
| `Z2MDiscoveryService.swift` |
probe timeout |
`TimeInterval = 1.5` |
| `AppStore.swift` |
notification coalesce window |
`TimeInterval = 1.5` |
| `DeviceListViewModel.swift` |
"Recently Added" window |
`TimeInterval = 30 * 60` |
These are not design tokens (no visual role) but they are tokens — single sources of truth for runtime tuning, and obvious candidates for future Settings exposure ("Connection timeout", "Discovery scan duration", etc.).
New file `Shellbee/Core/Config/AppConfig.swift` with two sub-enums:
```swift
enum AppConfig {
enum Networking {
static let websocketConnectionTimeout: TimeInterval = 10
static let websocketFirstMessageTimeout: TimeInterval = 5
static let discoveryProbeTimeout: TimeInterval = 1.5
}
enum UX {
static let notificationCoalesceWindow: TimeInterval = 1.5
static let recentDeviceWindow: TimeInterval = 30 * 60
}
}
```
The existing in-class static lets stay (good for callers' readability) but redirect their values to `AppConfig` — single source of truth.
Acceptance criteria
Notes
This is the residual sweep — after #33, #36, and this, every numeric magic value in Shellbee/ either flows through `DesignTokens` (visual) or `AppConfig` (behavior), or is a domain semantic constant (`spacing: 0`, `opacity(1)`, `lineLimit(2)`, etc.).
Summary
Final pass on the design-tokens cleanup tracked in #33 / #36. Three small categories of literals that the audits missed plus a new namespace for behavior tokens.
Scope
1. Visual literals (DesignTokens)
Three offset literals and five proportional font ratios are still inline:
These move to `DesignTokens.Size.` (offsets) and a new `DesignTokens.Typography.iconRatio` family (ratios).
2. Behavior tokens (new `AppConfig` namespace)
Network timeouts and UX-tuning windows are typed constants today, scattered across the files that consume them:
These are not design tokens (no visual role) but they are tokens — single sources of truth for runtime tuning, and obvious candidates for future Settings exposure ("Connection timeout", "Discovery scan duration", etc.).
New file `Shellbee/Core/Config/AppConfig.swift` with two sub-enums:
```swift
enum AppConfig {
enum Networking {
static let websocketConnectionTimeout: TimeInterval = 10
static let websocketFirstMessageTimeout: TimeInterval = 5
static let discoveryProbeTimeout: TimeInterval = 1.5
}
enum UX {
static let notificationCoalesceWindow: TimeInterval = 1.5
static let recentDeviceWindow: TimeInterval = 30 * 60
}
}
```
The existing in-class static lets stay (good for callers' readability) but redirect their values to `AppConfig` — single source of truth.
Acceptance criteria
Notes
This is the residual sweep — after #33, #36, and this, every numeric magic value in Shellbee/ either flows through `DesignTokens` (visual) or `AppConfig` (behavior), or is a domain semantic constant (`spacing: 0`, `opacity(1)`, `lineLimit(2)`, etc.).