# UI visual redesign — decision record Decided 2026-09-03 from the throwaway prototype at `scratchpad/proto-overview/index.html` (session-local; the screenshots and this record are what survive). This settles the visual language only; the IA, routes and API are `ui-redesign.md`'s and stay as built. ## Direction Pi-hole's structure × NextDNS's visual language, on the light theme. The owner supplied both references directly; four earlier exploration rounds (below) were rejected. ## Chosen values - **Ground and cards.** Near-white ground; white cards with hairline borders; radius **4px**; card padding ~28px; density 1.00; no panel header bars. - **Card head.** Every card: a 1.4rem weight-650 ink title plus a one-line muted description sentence (0.875rem). The title selector must outrank any heading reset (a `.v h2` reset silently ate the title styles in the prototype). - **Stat tiles.** Four tiles: one centered 2.5rem regular-weight numeral over a lowercase muted caption. Semantic color on the numeral itself: ink for totals, red for blocked, muted gray for the percentage, ink for clients. No icons, no borders inside. - **Toolbar.** Two rectangular dropdown selectors (radius token, 44px min-height, hairline border): client scope left, period right. Not pills — the owner rejected the pill shape. - **Queries chart.** Smooth Catmull-Rom area. Total: 2px blue line + 13% blue fill. Blocked: 2px red line + 35% red fill — both series are line-plus-backdrop pairs. Points spread **edge to edge**: the first bucket sits on the left plot edge, the last on the right; the curve never extends past its own data. Hover: NextDNS-style point hover — a 4px dot on each series (white 2px stroke) plus a thin vertical guide line; no bucket-band highlight. Tooltip sits ~16px **beside** the point, flipping to the left near the right edge; it never covers the hovered bucket. SVG note: `hidden` is attribute-only on SVG elements — toggle with `setAttribute`/`removeAttribute`, never the `.hidden` property. - **Client activity chart.** Stacked bars, band-centered, band hover highlight kept. Segments bleed 0.5 viewBox units into the segment below so antialiasing cannot open white seams. Series: the top **eight** named clients (the `/api/overview` contract's own count) plus one aggregated flat "Other" band (gray `oklch(0.80 0.01 260)`) on top. Legend lists the nine names + Other; the tooltip ranks the top four for the bucket, then an Other row, then the total. - **Client palette** (categorical, reserved red at hue 25 excluded): blue `oklch(0.60 0.14 258)`, teal `oklch(0.68 0.12 190)`, violet `oklch(0.62 0.15 300)`, amber `oklch(0.75 0.13 80)`, green `oklch(0.65 0.13 150)`, magenta `oklch(0.66 0.14 340)`, orange `oklch(0.70 0.14 55)`, olive `oklch(0.72 0.11 120)`, sky `oklch(0.78 0.09 230)`. Known-closest pair: amber/orange. - **Red.** `oklch(0.65 0.19 25)` (#ED5350, 3.54:1 vs white). Compliant for non-text UI and large text (3:1 floor); it must never color small text. - **Accent.** Blue, hue 258, for nav, links and the total-queries series. Green (hue 150) stays the cache/success color. Green and red are fixed semantics, never derived from the accent hue. - **Ranked lists.** Full-bleed rows, hairline dividers, name left with a muted sub-line (list/IP), right-aligned tabular count. Blocked list: a 3px red rule flush on each row's left edge. **No hover effect** — the rows are not interactive. - **Progress cards.** Cache hit rate as a full-width rounded bar with a colored percentage figure under it (NextDNS's Encrypted DNS pattern). - **Query types.** Donut + legend list with counts and percentages, single-hue lightness/chroma ramp off the accent. - **Sidebar.** Grouped section labels (MONITORING / SYSTEM), the active item as a soft accent-tinted block, and a compact status block at the foot: Active dot + blocking state, queries/min, uptime. - **Mobile (≤800px).** The sidebar becomes a sticky top bar (brand + status pinned, nav scrolls horizontally); everything stacks single-column; the stat tiles merge into one card — numbers side by side, the percentage on a line under. - **Type.** System font stack. No webfont. ## Rejected along the way - **Round 1** (Quiet / Console / Instrument / Signal): dark themes rejected outright; Console's density liked, its darkness not. - **Round 2** (Ledger / Paper / Grid): a Ledger+Grid mix was "disliked least", never liked. - **Round 3** (convergence with toggles): the settled config (panels frame, system labels, blue accent, 3px radius) read as competent but had no signature — "not an immediate this-is-it". - **Round 4** (signatures: IBM Plex type-led, a blocked-share hero Meter, a chart-first Geist): all three rejected; the direct Pi-hole × NextDNS reference replaced them. - **Chart details rejected in the blend round:** pill-shaped selectors; bucket-band hover on the area chart; tooltip centered above the point (covers the data); a solid 0.9-opacity red band (one-color, inconsistent with the blue pair); the curve overhanging the last bucket. - **Client colors rejected:** 15 hues at 24° spacing (rainbow, neighbors indistinguishable); 6 colors + 9 graduated grays (the gray stripes merge into a dull cap). Codex concurred: nine tiny series cannot be made simultaneously legible through color; aggregate the tail. - **Not adopted from Codex's option list:** hue families with lightness steps (15 still exceed discrimination), small multiples (a different card, not a fix), hover isolation (owner declined), top-N-per-bucket recoloring and streamgraphs (both distort trend reading).