# CodexBar Gauge — Design Spec & Handoff

A redesign of the CodexBar usage gauges for two surfaces that share one visual
system: an **ESP32 1.9″ display** and a **macOS desktop widget**. This file is the
implementation reference — hand it to a coding agent alongside the HTML mock and
the screenshots in `screenshots/`.

The HTML mock (`CodexBar Redesign.html` + `gauge.js` + `app.js` + `tweaks.js`) is the
source of truth for geometry and color. `gauge.js` is the canonical renderer; port
its math, not the screenshots.

---

## 1. Palette — "Ember" (hex)

Warm near-black grounds, cream type, a green→gold→rust heat ramp for *pace*, and a
clear blue reserved for *capacity*. No pure RGB primaries.

| Token | Hex | Use |
|---|---|---|
| `under` | `#54b173` | Pace arc — comfortably under pace (good) |
| `gold` | `#d6a341` | Pace arc — approaching the limit |
| `onpace` | `#dc8b34` | Pace arc — exactly on pace (≈ redline) |
| `over1` | `#c8643a` | Pace arc — over pace |
| `over2` | `#bd4329` | Pace arc — well over pace |
| `redline` | `#f4eede` | Warm-white tick at 12 o'clock |
| `fBase` | `#4f93c9` | Fuel tank — the capacity you actually have |
| `fAhead` | `#55b572` | Fuel tank — bonus capacity above expected line |
| `fDeficit` | `rgba(196,72,44,0.34)` | Fuel tank — translucent deficit ghost (behind pace) |
| `track` | `#332c23` | Faint arc track |
| `tankEmpty` | `#17130f` | Empty tank background |
| `value` | `#f3ecdc` | Center % number |
| `valueDim` | `rgba(243,236,220,0.6)` | The "%" glyph |
| ground (display) | `#0c0a08` | ESP32 screen background |

**Monochrome variant** (macOS widget, foreground state): drop all hue. Arc + fuel
become cream (`monoArc #d2c8b4`, `monoFuel #b7ac95`); the *excess capacity* region
above the expected line is darkened with `rgba(16,12,8,0.32)` so it stays legible;
a behind-pace deficit shows as a faint light band `rgba(255,250,240,0.14)`.

---

## 2. What each gauge encodes

Two independent signals in one dial:

- **Center number** = % of the window's allowance **remaining** (also the fuel level).
- **Pace arc (outer)** = burn rate vs. sustainable rate. *Not* consumption — think
  tachometer. Redline tick at 12 o'clock = "on pace".
- **Fuel tank (inner)** = remaining capacity vs. where it *should* be at this point
  in the window. Dashed line = expected remaining.

### Math (per window)
```
usage      = 100 - remaining            // % consumed
elapsed    = timeElapsed / windowLength  // 0..1
expUsage   = elapsed * 100               // expected % consumed if burning evenly
expRem     = 100 - expUsage              // expected % remaining  (the dashed line)
paceRatio  = expUsage > 0 ? usage / expUsage : 0   // clamp to [0, 2]
behind     = remaining < expRem          // burning faster than sustainable
```
`paceRatio` is identical for every window; only `windowLength` changes
(5h / 7d / 7d-Opus).

---

## 3. Pace arc geometry

- Clock degrees: 0° = top (12 o'clock), increasing **clockwise**.
- Arc spans **213° → 507°** (i.e. start lower-left, sweep 294° clockwise, ending
  lower-right). The 66° gap sits at the bottom, flanking the reset-time label.
- **Redline tick at 360°** (12 o'clock).
- Fill maps pace: `paceRatio 0 → 213°`, `1.0 → 360°`, `2.0 → 507°`.
  Below 12 o'clock-worth = sustainable; past it = over pace.
- Fill **color** = heat ramp by `paceRatio`, stops:
  `0→under, 0.55→under, 0.9→gold, 1.0→onpace, 1.4→over1, 2.0→over2` (linear lerp).
  Solid color (no per-arc gradient — intentional, reduces noise).
- Round line caps; stroke width ≈ 10.5% of gauge size.

## 4. Fuel tank rules

Vertical tank clipped to a circle. Fill from the bottom; height = `remaining%`.
The expected line is a dashed horizontal at `expRem%`.

- **Actual fuel** (always): solid **blue** `fBase`, bottom → `remaining` level.
- **Ahead of pace** (`remaining ≥ expRem`): a **green** `fAhead` "bonus cap" fills
  from the expected line up to the actual level.
- **Behind pace** (`remaining < expRem`): a **translucent red** `fDeficit` ghost
  fills from the actual level up to the expected line — "the fuel you're missing".
- Consistent reading everywhere: **blue = fuel you have, green = bonus, red ghost =
  deficit**, dashed line = where you should be.

## 5. Center value

Number sits dead-center in the fuel circle; the "%" hangs as a ~0.5em superscript to
its right so the number itself stays centered. Number ≈ 28% of gauge size (21.5% when
"100"). Font: a geometric sans with good numerals (mock uses Space Grotesk).

---

## 6. Surface specs

### ESP32 1.9″ display (ST7789, native px)
- **Portrait 170×320** when 2–3 providers: stacked sections (one per provider),
  1px divider. Each section: top bar (repo chip left / provider glyph right) + a
  centered row of a large **5h** gauge (~88px) and a small **7d/Opus** gauge (~54px),
  each with a window label + reset readout below.
- **Landscape 320×170** when 1 provider: single section, large 5h gauge (~110px) +
  small 7d gauge (~72px). Chrome (chip + glyph) is an absolute overlay in the top
  corners so the big gauge keeps full height.
- Background near-black `#0c0a08`. Labels: window label in the number font (~13–15px),
  reset time in monospace (~10.5px, dim).

### macOS widget — two adaptive states
- **Desktop visible** (no foreground app): solid dark cards, full color.
- **App in foreground**: frosted monochrome glass (Claude = warm amber tint, Codex =
  cool slate tint), cream gauges, darkened excess region. Stays out of the way.
- Each card: provider name + glyph header, then a 5h + 7d gauge row with labels.
  Widget label ~16px, reset time ~13.5px for at-a-glance readability.

## 7. Attention indicator (Codex waiting on you)
Subtle, not loud: a soft teal inner glow on the active section + a thin teal edge rail
+ a quiet teal repo chip (`CodexBar-ESP32`). Teal accent `#5ea093`.

## 8. Provider glyphs
Small monochrome marks, top corner of each section/card (widget ~36px, ESP ~28–34px).
**The glyphs in the mock are abstract placeholders** — swap in the official provider
SVGs in your build.

---

## 9. Tweakable options (in the mock)
- **Capacity accent**: Blue (default) or Teal.
- **Provider glyphs**: on/off.
- **Attention indicator**: on/off.
