Skip to content

Commit fa73475

Browse files
retlehsclaude
andauthored
Add adaptive color palette for light terminal themes (#18)
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
1 parent be4d41b commit fa73475

7 files changed

Lines changed: 56 additions & 24 deletions

File tree

README.md

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,16 @@ The CrUX API is free. Not all domains have field data — a site needs enough Ch
8383

8484
</details>
8585

86+
## Theme
87+
88+
quien automatically detects your terminal background and picks light or dark colors. If detection gets it wrong (common in tmux, screen, or remote shells), override it:
89+
90+
```sh
91+
export QUIEN_THEME=light # force light palette
92+
export QUIEN_THEME=dark # force dark palette
93+
export QUIEN_THEME=auto # auto-detect (default)
94+
```
95+
8696
> [!TIP]
8797
> If you want `quien` to replace your default WHOIS tool, you can add an alias to your shell config:
8898
> ```sh

internal/display/display.go

Lines changed: 34 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ package display
33
import (
44
"encoding/json"
55
"fmt"
6+
"os"
67
"strings"
78
"time"
89

@@ -38,15 +39,37 @@ func SetWidth(w int) {
3839
displayWidth = w
3940
}
4041

42+
func init() {
43+
switch strings.ToLower(os.Getenv("QUIEN_THEME")) {
44+
case "light":
45+
lipgloss.SetHasDarkBackground(false)
46+
case "dark":
47+
lipgloss.SetHasDarkBackground(true)
48+
}
49+
// "auto" or unset: lipgloss detects automatically.
50+
}
51+
52+
// ac returns an AdaptiveColor that picks light on light backgrounds and dark
53+
// on dark backgrounds. lipgloss detects the terminal background automatically.
54+
func ac(light, dark string) lipgloss.AdaptiveColor {
55+
return lipgloss.AdaptiveColor{Light: light, Dark: dark}
56+
}
57+
4158
var (
42-
// Colors
43-
cyan = lipgloss.Color("#00D7FF")
44-
green = lipgloss.Color("#00FF87")
45-
red = lipgloss.Color("#FF5F87")
46-
yellow = lipgloss.Color("#FFD700")
47-
dim = lipgloss.Color("#6C6C6C")
48-
white = lipgloss.Color("#FFFFFF")
49-
faint = lipgloss.Color("#4E4E4E")
59+
// Colors — dark values are unchanged; light values target white/light backgrounds.
60+
cyan = ac("#0969DA", "#00D7FF")
61+
green = ac("#1A7F37", "#00FF87")
62+
red = ac("#CF222E", "#FF5F87")
63+
yellow = ac("#9A6700", "#FFD700")
64+
dim = ac("#57606A", "#6C6C6C")
65+
white = ac("#1F2328", "#FFFFFF") // main body text
66+
faint = ac("#8C959F", "#4E4E4E")
67+
68+
// Secondary palette tokens used across multiple files.
69+
accent = ac("#2E59A1", "#87AFFF") // nameservers, headers, DNS records
70+
muted = ac("#57606A", "#A8A8A8") // TXT records, redirect URLs, mail records
71+
border = ac("#D0D7DE", "#3A3A3A") // box and panel borders
72+
tabGray = ac("#57606A", "#A0A0A0") // inactive tab text
5073

5174
// Styles
5275
domainStyle = lipgloss.NewStyle().
@@ -73,10 +96,10 @@ var (
7396
Italic(true)
7497

7598
nsStyle = lipgloss.NewStyle().
76-
Foreground(lipgloss.Color("#87AFFF"))
99+
Foreground(accent)
77100

78101
txtStyle = lipgloss.NewStyle().
79-
Foreground(lipgloss.Color("#A8A8A8"))
102+
Foreground(muted)
80103

81104
dimStyle = lipgloss.NewStyle().
82105
Foreground(dim)
@@ -88,7 +111,7 @@ var (
88111
func box() lipgloss.Style {
89112
return lipgloss.NewStyle().
90113
Border(lipgloss.RoundedBorder()).
91-
BorderForeground(lipgloss.Color("#3A3A3A")).
114+
BorderForeground(border).
92115
Padding(1, boxPadH).
93116
Width(displayWidth)
94117
}

internal/display/http.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ import (
1010

1111
var (
1212
headerNameStyle = lipgloss.NewStyle().
13-
Foreground(lipgloss.Color("#87AFFF"))
13+
Foreground(accent)
1414

1515
headerValStyle = lipgloss.NewStyle().
1616
Foreground(white)
@@ -19,7 +19,7 @@ var (
1919
Foreground(dim)
2020

2121
redirectURLStyle = lipgloss.NewStyle().
22-
Foreground(lipgloss.Color("#A8A8A8"))
22+
Foreground(muted)
2323

2424
statusOKStyle = lipgloss.NewStyle().
2525
Foreground(green).

internal/display/interactive.go

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ var (
4141
PaddingLeft(2)
4242

4343
tabStyle = lipgloss.NewStyle().
44-
Foreground(lipgloss.Color("#A0A0A0")).
44+
Foreground(tabGray).
4545
PaddingRight(2)
4646

4747
tabKeyStyle = lipgloss.NewStyle().
@@ -63,8 +63,7 @@ var (
6363
Foreground(dim).
6464
PaddingLeft(2)
6565

66-
borderColor = lipgloss.Color("#3A3A3A")
67-
borderFg = lipgloss.NewStyle().Foreground(borderColor)
66+
borderFg = lipgloss.NewStyle().Foreground(border)
6867
)
6968

7069
// chrome = tab bar (1) + top border (1) + bottom border (1) + footer (1)

internal/display/mail.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ import (
1111
var (
1212
foundStyle = lipgloss.NewStyle().Foreground(green)
1313
notFoundStyle = lipgloss.NewStyle().Foreground(red)
14-
recordStyle = lipgloss.NewStyle().Foreground(lipgloss.Color("#A8A8A8"))
14+
recordStyle = lipgloss.NewStyle().Foreground(muted)
1515
)
1616

1717
// RenderMail returns a lipgloss-styled string for email-related DNS records.

internal/display/prompt.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -79,7 +79,7 @@ func (m PromptModel) View() string {
7979
return ""
8080
}
8181

82-
underline := lipgloss.NewStyle().Foreground(lipgloss.Color("#555555"))
82+
underline := lipgloss.NewStyle().Foreground(ac("#AAAAAA", "#555555"))
8383

8484
var content strings.Builder
8585
content.WriteString(promptTitleStyle.Render("quien"))
@@ -92,7 +92,7 @@ func (m PromptModel) View() string {
9292

9393
outerBox := lipgloss.NewStyle().
9494
Border(lipgloss.RoundedBorder()).
95-
BorderForeground(lipgloss.Color("#3A3A3A")).
95+
BorderForeground(border).
9696
Padding(1, 3).
9797
Width(50)
9898

internal/display/stack.go

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -9,18 +9,18 @@ import (
99

1010
var (
1111
tagStyle = lipgloss.NewStyle().
12-
Foreground(lipgloss.Color("#000000")).
13-
Background(lipgloss.Color("#87AFFF")).
12+
Foreground(ac("#FFFFFF", "#000000")).
13+
Background(accent).
1414
Padding(0, 1)
1515

1616
tagGreenStyle = lipgloss.NewStyle().
17-
Foreground(lipgloss.Color("#000000")).
17+
Foreground(ac("#FFFFFF", "#000000")).
1818
Background(green).
1919
Padding(0, 1)
2020

2121
tagDimStyle = lipgloss.NewStyle().
22-
Foreground(lipgloss.Color("#000000")).
23-
Background(lipgloss.Color("#6C6C6C")).
22+
Foreground(ac("#FFFFFF", "#000000")).
23+
Background(dim).
2424
Padding(0, 1)
2525
)
2626

0 commit comments

Comments
 (0)