From a94768f8d5fa36931617ed00be095e111d3998bd Mon Sep 17 00:00:00 2001 From: akashsokik Date: Fri, 10 Jul 2026 12:56:17 +0100 Subject: [PATCH] dim terminal coral palette --- .../plans/2026-07-10-dimmer-terminal-coral.md | 80 +++++++++++++++++++ ...2026-07-10-dimmer-terminal-coral-design.md | 34 ++++++++ src/ui/theme.ts | 12 +-- test/banner.test.ts | 3 +- test/commands/platform.test.ts | 4 +- test/ui/theme.test.ts | 11 ++- 6 files changed, 134 insertions(+), 10 deletions(-) create mode 100644 docs/superpowers/plans/2026-07-10-dimmer-terminal-coral.md create mode 100644 docs/superpowers/specs/2026-07-10-dimmer-terminal-coral-design.md diff --git a/docs/superpowers/plans/2026-07-10-dimmer-terminal-coral.md b/docs/superpowers/plans/2026-07-10-dimmer-terminal-coral.md new file mode 100644 index 0000000..941d445 --- /dev/null +++ b/docs/superpowers/plans/2026-07-10-dimmer-terminal-coral.md @@ -0,0 +1,80 @@ +# Dimmer Terminal Coral Implementation Plan + +> **For agentic workers:** REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (`- [ ]`) syntax for tracking. + +**Goal:** Replace the bright terminal coral family with substantially dimmer tones while keeping Ink and raw ANSI output consistent. + +**Architecture:** The palette remains centralized in `src/ui/theme.ts`. Change the primary accent in its hex and ANSI forms and add a focused consistency test; all consumers continue using the existing tokens. + +**Tech Stack:** TypeScript, Ink, Vitest, tsup + +## Global Constraints + +- Use `#B85C4A` and RGB `184,92,74` for the primary accent. +- Use `#9E4938` and RGB `158,73,56` for the strong accent. +- Leave all other palette tokens and color-gating behavior unchanged. +- Do not add dependencies or start a server. + +--- + +### Task 1: Dim the primary accent token + +**Files:** +- Modify: `src/ui/theme.ts` +- Test: `test/ui/theme.test.ts` + +**Interfaces:** +- Consumes: the exported `theme.accent` and `ansi.accent` tokens. +- Produces: matching hex and ANSI values for the dimmed primary and strong coral tokens. + +- [ ] **Step 1: Write the failing test** + +Add this test to `test/ui/theme.test.ts`: + +```ts +it('keeps the muted coral hex and ANSI accent values aligned', () => { + expect(theme.accent).toBe('#B85C4A') + expect(ansi.accent).toBe('\x1b[38;2;184;92;74m') + expect(theme.accentStrong).toBe('#9E4938') + expect(ansi.accentStrong).toBe('\x1b[38;2;158;73;56m') +}) +``` + +Import `ansi` and `theme` from `../../src/ui/theme.js`. + +- [ ] **Step 2: Run the focused test to verify it fails** + +Run: `npx vitest run test/ui/theme.test.ts` + +Expected: FAIL because the current coral tokens still use the brighter values. + +- [ ] **Step 3: Update the centralized tokens** + +In `src/ui/theme.ts`, set: + +```ts +accent: '#B85C4A', +accentStrong: '#9E4938', +``` + +and: + +```ts +accent: '\x1b[38;2;184;92;74m', +accentStrong: '\x1b[38;2;158;73;56m', +``` + +Update the adjacent comments to describe the muted terminal coral accurately. + +- [ ] **Step 4: Run focused and full verification** + +Run: + +```bash +npx vitest run test/ui/theme.test.ts +npm test +npm run typecheck +npm run build +``` + +Expected: every command exits successfully. diff --git a/docs/superpowers/specs/2026-07-10-dimmer-terminal-coral-design.md b/docs/superpowers/specs/2026-07-10-dimmer-terminal-coral-design.md new file mode 100644 index 0000000..e1dfdac --- /dev/null +++ b/docs/superpowers/specs/2026-07-10-dimmer-terminal-coral-design.md @@ -0,0 +1,34 @@ +# Dimmer Terminal Coral Design + +## Goal + +Make Orca's primary coral accent more comfortable for sustained use on dark +terminal backgrounds without changing the CLI's visual hierarchy or color +semantics. + +## Design + +Replace the primary accent `#FE785D` (RGB `254,120,93`) with the substantially +dimmer coral `#B85C4A` (RGB `184,92,74`). Replace the strong accent `#F0543C` +(RGB `240,84,60`) with `#9E4938` (RGB `158,73,56`). The new colors keep the +existing warm coral hue while reducing brightness and saturation enough to +avoid glare. + +Update both representations in `src/ui/theme.ts`: + +- `theme.accent`, used by Ink components, becomes `#B85C4A`. +- `ansi.accent`, used by direct terminal output, becomes the matching 24-bit + escape sequence `\x1b[38;2;184;92;74m`. +- `theme.accentStrong` and `ansi.accentStrong` become `#9E4938` and + `\x1b[38;2;158;73;56m` respectively, keeping inline code from retaining the + brighter coral. + +Leave status colors, muted text, subtle text, borders, and `NO_COLOR` behavior +unchanged. This is a token-only change; every existing accent consumer inherits +it automatically. + +## Verification + +Add a focused theme test that locks the Ink and ANSI representations to the +same RGB value. Run the theme test, the full test suite, typecheck, and package +build. Do not start a development server. diff --git a/src/ui/theme.ts b/src/ui/theme.ts index 22b9be6..f56e9a4 100644 --- a/src/ui/theme.ts +++ b/src/ui/theme.ts @@ -21,10 +21,10 @@ import type { RunStatus } from '../lib/types.js' export const theme = { - // Brand coral, --accent hsl(10 100% 68%) = #FE785D. - accent: '#FE785D', - // --accent-strong hsl(10 90% 58%). - accentStrong: '#F0543C', + // Dim terminal coral: warm enough for the brand, muted for sustained use. + accent: '#B85C4A', + // Strong coral stays darker than the primary accent for inline emphasis. + accentStrong: '#9E4938', // --text-muted (66%): secondary text, table body. muted: '#A8A8A8', // --text-subtle (46%): hints, timestamps, dividers. @@ -38,8 +38,8 @@ export const theme = { // The coral wordmark and subtle grays as raw 24-bit ANSI, for the banner and // any output that renders outside Ink. Mirrors the hex tokens above. export const ansi = { - accent: '\x1b[38;2;254;120;93m', - accentStrong: '\x1b[38;2;240;84;60m', + accent: '\x1b[38;2;184;92;74m', + accentStrong: '\x1b[38;2;158;73;56m', muted: '\x1b[38;2;168;168;168m', subtle: '\x1b[38;2;117;117;117m', destructive: '\x1b[38;2;220;60;60m', diff --git a/test/banner.test.ts b/test/banner.test.ts index b8aba79..acf52aa 100644 --- a/test/banner.test.ts +++ b/test/banner.test.ts @@ -1,6 +1,7 @@ import { afterEach, describe, expect, it, vi } from 'vitest' import { bannerString } from '../src/ui/banner.js' +import { ansi } from '../src/ui/theme.js' import { VERSION } from '../src/version.js' const realIsTTY = process.stdout.isTTY @@ -45,7 +46,7 @@ describe('bannerString', () => { process.stdout.isTTY = true vi.stubEnv('NO_COLOR', '') const s = bannerString() - expect(s).toContain('38;2;254;120;93') // coral + expect(s).toContain(ansi.accent) expect(s).toContain('\x1b[1m') // bold ORCA }) }) diff --git a/test/commands/platform.test.ts b/test/commands/platform.test.ts index 0406e9b..3c93109 100644 --- a/test/commands/platform.test.ts +++ b/test/commands/platform.test.ts @@ -4,7 +4,7 @@ import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest' import { registerPlatform, renderTopologyTree } from '../../src/commands/platform.js' import { saveConfig } from '../../src/lib/config.js' import { ExitCode } from '../../src/lib/errors.js' -import { glyphs } from '../../src/ui/theme.js' +import { ansi, glyphs } from '../../src/ui/theme.js' import { jsonResponse, stubFetch } from '../helpers/fetch-mock.js' import { useTmpConfigDir } from '../helpers/tmp-config.js' @@ -104,7 +104,7 @@ describe('renderTopologyTree', () => { }) it('emits coral ANSI on the conductor node when color is enabled', () => { - expect(renderTopologyTree(TOPOLOGY, { color: true })).toContain('38;2;254;120;93') + expect(renderTopologyTree(TOPOLOGY, { color: true })).toContain(ansi.accent) }) it('handles an empty pool without throwing', () => { diff --git a/test/ui/theme.test.ts b/test/ui/theme.test.ts index d768060..acf943c 100644 --- a/test/ui/theme.test.ts +++ b/test/ui/theme.test.ts @@ -1,11 +1,20 @@ import { afterEach, describe, expect, it, vi } from 'vitest' -import { glyphs, POINTER, unicodeEnabled } from '../../src/ui/theme.js' +import { ansi, glyphs, POINTER, theme, unicodeEnabled } from '../../src/ui/theme.js' afterEach(() => { vi.unstubAllEnvs() }) +describe('coral palette', () => { + it('keeps the dim coral hex and ANSI values aligned', () => { + expect(theme.accent).toBe('#B85C4A') + expect(ansi.accent).toBe('\x1b[38;2;184;92;74m') + expect(theme.accentStrong).toBe('#9E4938') + expect(ansi.accentStrong).toBe('\x1b[38;2;158;73;56m') + }) +}) + // unicodeEnabled reads env live, so we exercise the tier selection through it. // glyphs/POINTER are resolved once at module load and are asserted for shape. describe('unicodeEnabled', () => {