Skip to content

Commit bfc462f

Browse files
committed
feat: polish UX, rewrite README, add project docs
- Popup: pulsing loading animation, styled error messages with retry button, refresh button in header, slide-in animation for incidents - Landing page: prefers-reduced-motion support, MutationObserver for install detection, focus-visible styles for FAQ and inputs - Content CSS: input[type=search] support, focus styles with warm gold ring, accent-color for checkboxes/radios - README: full rewrite with hero section, badges, architecture tree, color palette table, and project backstory - Add CLAUDE.md with project guide, sync rules, and color tokens - Sync all CSS changes to userscript and docs/ copy - Add default_title to manifest.json
1 parent afaa1b7 commit bfc462f

File tree

11 files changed

+334
-80
lines changed

11 files changed

+334
-80
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,3 +8,4 @@ node_modules/
88
*.backup
99
coverage/
1010
*.zip
11+
reddit-post.md

CLAUDE.md

Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
# Claude Status Dark — Project Guide
2+
3+
## Overview
4+
5+
Dark mode for status.claude.com — Chrome/Firefox/Safari extension + userscript + GitHub Pages landing page.
6+
7+
**GitHub:** talkstream/claude-status-dark
8+
**Landing page:** https://talkstream.github.io/claude-status-dark/
9+
10+
## Architecture
11+
12+
Three delivery methods, one codebase:
13+
14+
1. **Browser extension** (`extension/`) — MV3, full features (dark CSS + popup + badge alerts + auto-polling)
15+
2. **Userscript** (`userscript/`) — dark CSS only, works via Tampermonkey/Userscripts
16+
3. **Landing page** (`docs/`) — install wizard with browser detection, hosted on GitHub Pages
17+
18+
## Critical Files
19+
20+
| File | Purpose |
21+
|------|---------|
22+
| `extension/content.css` | Master dark theme — 14 selector groups targeting Atlassian Statuspage classes |
23+
| `extension/content.js` | MutationObserver for dynamic SVG fills, tooltips, modals |
24+
| `extension/background.js` | Service worker: alarm polling (2 min), badge text updates |
25+
| `extension/popup/popup.js` | Fetches /api/v2/summary.json, renders components + incidents |
26+
| `userscript/claude-status-dark.user.js` | Standalone: anti-flash + CSS injection + SVG recoloring |
27+
| `docs/index.html` | Landing page with install wizard, share buttons, FAQ |
28+
29+
## Sync Rules
30+
31+
**content.css is the source of truth for all CSS rules.**
32+
33+
When editing CSS:
34+
1. Edit `extension/content.css`
35+
2. Manually sync changes into `userscript/claude-status-dark.user.js` (CSS is embedded in a template string)
36+
3. Copy userscript to `docs/claude-status-dark.user.js`
37+
38+
## Color Palette
39+
40+
| Token | Hex | Usage |
41+
|-------|-----|-------|
42+
| bg-page | `#1a1816` | Page background |
43+
| bg-card | `#242220` | Cards, modals |
44+
| bg-elevated | `#2a2826` | Headers, footers |
45+
| text-primary | `#e8e4de` | Primary text |
46+
| text-secondary | `#9b9790` | Secondary text |
47+
| text-muted | `#5a5852` | Timestamps, hints |
48+
| border | `#3a3734` | All borders |
49+
| border-hover | `#4a4844` | Hover borders |
50+
| accent | `#c8a97a` | Warm gold — links hover, focus rings |
51+
| green | `#8cc63f` | Operational |
52+
| yellow | `#fbb44c` | Minor / degraded |
53+
| orange | `#f07850` | Major outage |
54+
| red | `#ef5555` | Critical |
55+
| blue | `#4a9ce8` | Maintenance, links |
56+
57+
## Statuspage CSS Classes
58+
59+
Real class names used by Atlassian Statuspage (important — don't guess these):
60+
- `.page-status.status-none` / `.status-minor` / `.status-major` / `.status-critical`
61+
- `.component-inner-container.status-green` / `.status-yellow` / `.status-orange` / `.status-red` / `.status-blue`
62+
- `.unresolved-incident.impact-none` / `.impact-minor` / `.impact-major` / `.impact-critical` / `.impact-maintenance`
63+
- SVG fills are set inline: `#76AD2A`, `#FAA72A`, `#E86235`, `#E04343`, `#2C84DB`, `#B0AEA5`, `#DEDCD1`, `#FAF9F5`
64+
65+
## Testing
66+
67+
1. Chrome: `chrome://extensions` → Developer mode → Load unpacked → `extension/`
68+
2. Open popup → verify loading animation, component list, refresh button
69+
3. Visit status.claude.com → verify dark theme, no white flash, tooltips dark
70+
4. Test subscribe modal → verify dark background, input focus styles
71+
5. Landing page: open `docs/index.html` locally or via GitHub Pages
72+
73+
## Deploy
74+
75+
```bash
76+
git add -A && git commit -m "..." && git push
77+
```
78+
79+
GitHub Pages auto-deploys from `docs/` directory on push to main.
80+
81+
## macOS Notes
82+
83+
- `sed -i ''` (BSD sed)
84+
- Icon generation requires `librsvg` (`brew install librsvg`)
85+
- Safari build requires Xcode

README.md

Lines changed: 89 additions & 74 deletions
Original file line numberDiff line numberDiff line change
@@ -1,77 +1,63 @@
1-
# Claude Status Dark
1+
<p align="center">
2+
<b style="font-size:48px; color:#c8a97a;">✦</b><br>
3+
<strong>Claude Status Dark</strong>
4+
</p>
25

3-
[![Version](https://img.shields.io/github/v/release/talkstream/claude-status-dark)](https://github.com/talkstream/claude-status-dark/releases)
4-
[![License: MIT](https://img.shields.io/badge/license-MIT-blue.svg)](LICENSE)
5-
[![Safari](https://img.shields.io/badge/Safari-compatible-brightgreen)](https://developer.apple.com/safari/extensions/)
6-
[![Chrome](https://img.shields.io/badge/Chrome-compatible-brightgreen)](https://developer.chrome.com/docs/extensions/)
7-
[![Firefox](https://img.shields.io/badge/Firefox-compatible-brightgreen)](https://addons.mozilla.org/en-US/firefox/extensions/)
6+
<p align="center">
7+
<a href="https://github.com/talkstream/claude-status-dark/releases"><img src="https://img.shields.io/github/v/release/talkstream/claude-status-dark?style=flat-square&color=c8a97a" alt="Version"></a>
8+
<a href="LICENSE"><img src="https://img.shields.io/badge/license-MIT-blue?style=flat-square" alt="License: MIT"></a>
9+
<a href="https://talkstream.github.io/claude-status-dark/"><img src="https://img.shields.io/badge/install-two%20clicks-8cc63f?style=flat-square" alt="Install"></a>
10+
</p>
811

9-
Dark mode for [status.claude.com](https://status.claude.com) with a warm palette inspired by Claude's design language.
12+
<p align="center">
13+
Dark mode for <a href="https://status.claude.com">status.claude.com</a> — because checking if Claude is down<br>
14+
shouldn't also burn your retinas.
15+
</p>
1016

11-
## Install — One Click
17+
<p align="center">
18+
<strong><a href="https://talkstream.github.io/claude-status-dark/">Install in two clicks &rarr;</a></strong>
19+
</p>
1220

13-
**[Install from our website](https://talkstream.github.io/claude-status-dark/)** — detects your browser, guides you through setup in 3 steps.
21+
---
1422

15-
> Works with Safari (Userscripts), Chrome, Firefox, Edge (Tampermonkey).
23+
## Before / After
1624

17-
## Features
18-
19-
- Warm dark theme (not cold gray) — 14 CSS override groups covering every page element
20-
- Real-time status popup with component monitoring via Atlassian Statuspage API
21-
- Badge indicator: shows `!`/`!!`/`!!!` on the extension icon when issues are detected
22-
- Automatic polling every 2 minutes
23-
- Works on all pages: main status, `/history`, `/incidents/*`
24-
- Anti-flash: dark background applied before first paint
25-
- MutationObserver handles dynamically injected tooltips, modals, and SVG elements
26-
27-
## Quick Install
28-
29-
### Safari (macOS)
30-
31-
```bash
32-
git clone https://github.com/talkstream/claude-status-dark.git
33-
cd claude-status-dark
34-
make install
35-
```
25+
| Before (ouch) | After (ahh) |
26+
|:-:|:-:|
27+
| Blinding white at 2 AM | Warm dark palette, easy on the eyes |
28+
| `#FAF9F5` background | `#1a1816` background |
29+
| Stock statuspage colors | Hand-tuned warm tones |
3630

37-
This generates icons, converts to a Safari web extension, and opens the Xcode project. Build and enable in Safari preferences.
31+
## Install
3832

39-
**Requirements:** Xcode, `librsvg` (`brew install librsvg`)
33+
**[One-click install from the landing page](https://talkstream.github.io/claude-status-dark/)** — detects your browser, guides you through two steps.
4034

41-
### Chrome / Edge / Brave
35+
> Works with **Safari** (Userscripts), **Chrome**, **Edge**, **Brave** (Tampermonkey), and **Firefox** (Tampermonkey).
4236
43-
1. Download the [latest release](https://github.com/talkstream/claude-status-dark/releases) or clone the repo
44-
2. Open `chrome://extensions`
45-
3. Enable **Developer mode**
46-
4. Click **Load unpacked** → select the `extension/` directory
37+
### Or load the extension directly
4738

48-
### Firefox
39+
**Chrome / Edge / Brave:**
40+
1. Clone or download this repo
41+
2. Open `chrome://extensions` → enable **Developer mode**
42+
3. **Load unpacked** → select the `extension/` directory
4943

44+
**Firefox:**
5045
1. Open `about:debugging#/runtime/this-firefox`
51-
2. Click **Load Temporary Add-on**
52-
3. Select `extension/manifest.json`
53-
54-
### Userscript (Tampermonkey / Userscripts)
55-
56-
Install [claude-status-dark.user.js](https://raw.githubusercontent.com/talkstream/claude-status-dark/main/userscript/claude-status-dark.user.js) directly.
57-
58-
> **Note:** The userscript provides dark mode only (no popup or badge features).
59-
60-
## Build from Source
46+
2. **Load Temporary Add-on** → select `extension/manifest.json`
6147

48+
**Safari (native build):**
6249
```bash
63-
# Generate PNG icons from SVG
64-
make icons
65-
66-
# Build Safari extension (macOS only)
67-
make safari
50+
make install # requires Xcode + librsvg
51+
```
6852

69-
# Build + open in Xcode
70-
make install
53+
## Features
7154

72-
# Clean build artifacts
73-
make clean
74-
```
55+
- **Warm dark theme** — not cold gray, a hand-tuned palette inspired by Claude's design language
56+
- **Status popup** — real-time component monitoring via Atlassian Statuspage API
57+
- **Badge alerts**`!` / `!!` / `!!!` on the extension icon when issues are detected
58+
- **Auto-polling** — checks every 2 minutes, so you don't have to
59+
- **Anti-flash** — dark background injected before first paint, no white blink
60+
- **Full coverage** — main page, `/history`, `/incidents/*`, modals, tooltips, SVG bars
7561

7662
## Color Palette
7763

@@ -82,32 +68,61 @@ make clean
8268
| `#141413` | `#e8e4de` | Primary text |
8369
| `#87867F` | `#9b9790` | Secondary text |
8470
| `#DEDCD1` | `#3a3734` | Borders |
85-
| `#76AD2A` | `#8cc63f` | Operational |
86-
| `#FAA72A` | `#fbb44c` | Minor |
87-
| `#E86235` | `#f07850` | Major |
88-
| `#E04343` | `#ef5555` | Critical |
89-
| `#2C84DB` | `#4a9ce8` | Maintenance |
90-
|| `#c8a97a` | Accent (links, hover) |
71+
| `#76AD2A` | `#8cc63f` | Operational (green) |
72+
| `#FAA72A` | `#fbb44c` | Minor (yellow) |
73+
| `#E86235` | `#f07850` | Major (orange) |
74+
| `#E04343` | `#ef5555` | Critical (red) |
75+
| `#2C84DB` | `#4a9ce8` | Maintenance (blue) |
76+
|| `#c8a97a` | Accent (warm gold) |
9177

92-
## Project Structure
78+
## Architecture
9379

9480
```
95-
extension/
96-
manifest.json Manifest V3 (cross-browser)
97-
content.css Dark theme (14 selector groups)
98-
content.js MutationObserver for dynamic elements
99-
background.js Service worker with alarm polling
100-
popup/ Status monitoring popup (360×480)
101-
icons/ SVG source + generated PNGs
102-
userscript/ Standalone userscript variant
103-
scripts/ Build automation
104-
docs/ GitHub Pages install landing page
81+
claude-status-dark/
82+
extension/
83+
manifest.json MV3 manifest (cross-browser)
84+
content.css Dark theme — 14 selector groups, ~650 lines
85+
content.js MutationObserver for dynamic SVG/tooltips/modals
86+
background.js Service worker — alarm polling, badge updates
87+
popup/ Status popup (360x480, warm dark theme)
88+
popup.html
89+
popup.css
90+
popup.js
91+
icons/ SVG source + generated PNGs (16/32/48/128)
92+
userscript/
93+
claude-status-dark.user.js Standalone userscript (dark mode only)
94+
docs/ GitHub Pages — install landing page
95+
index.html Landing page with install wizard
96+
claude-status-dark.user.js Userscript copy (correct MIME type)
97+
scripts/ Build automation (icon gen, Safari conversion)
98+
Makefile icons / safari / install / clean
10599
```
106100

101+
## Build from Source
102+
103+
```bash
104+
make icons # Generate PNGs from SVG (requires librsvg)
105+
make safari # Convert to Safari Web Extension (macOS only)
106+
make install # Build + open in Xcode
107+
make clean # Remove build artifacts
108+
```
109+
110+
## Why This Exists
111+
112+
Vibe-coded at 2 AM while Claude was down. The irony of staring at a blinding white status page to find out when your AI assistant would come back was too much. So I made it dark.
113+
114+
The warm palette isn't random — it's inspired by Claude's own design language. Gold accents (`#c8a97a`), muted earth tones, and careful contrast ratios make the page pleasant even when the news isn't.
115+
107116
## Contributing
108117

109118
Issues and pull requests are welcome. Please test in at least one browser before submitting.
110119

111120
## License
112121

113122
[MIT](LICENSE)
123+
124+
---
125+
126+
<p align="center">
127+
<sub>Made with ✦ for Claude users who deserve better than a white screen at midnight</sub>
128+
</p>

docs/claude-status-dark.user.js

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -176,10 +176,16 @@ div[id^="subscribe-modal"] .modal-footer, .modal-footer, .modal-footer.incident-
176176
}
177177
.modal-backdrop { background-color: #0a0908 !important; }
178178
input[type="text"], input[type="email"], input[type="tel"], input[type="url"],
179-
textarea, select, .phone-country, .full-width {
179+
input[type="search"], textarea, select, .phone-country, .full-width {
180180
background-color: #1a1816 !important; color: #e8e4de !important; border-color: #3a3734 !important;
181181
}
182+
input:focus, textarea:focus, select:focus {
183+
border-color: #c8a97a !important;
184+
box-shadow: 0 0 0 2px rgba(200, 169, 122, 0.2) !important;
185+
outline: none !important;
186+
}
182187
input::placeholder, textarea::placeholder { color: #5a5852 !important; }
188+
input[type="checkbox"], input[type="radio"] { accent-color: #c8a97a; }
183189
.terms_and_privacy_information, .terms_and_privacy_information a, .help-block { color: #5a5852 !important; }
184190
185191
/* Footer */

docs/index.html

Lines changed: 39 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -560,6 +560,27 @@
560560
footer a { color: #9b9790; text-decoration: none; }
561561
footer a:hover { color: #c8a97a; }
562562

563+
/* ====== ACCESSIBILITY ====== */
564+
@media (prefers-reduced-motion: reduce) {
565+
*, *::before, *::after {
566+
animation-duration: 0.01ms !important;
567+
animation-iteration-count: 1 !important;
568+
transition-duration: 0.01ms !important;
569+
}
570+
}
571+
572+
details summary:focus-visible {
573+
outline: 2px solid #c8a97a;
574+
outline-offset: 2px;
575+
border-radius: 8px;
576+
}
577+
578+
input:focus, textarea:focus, select:focus {
579+
border-color: #c8a97a !important;
580+
outline: none;
581+
box-shadow: 0 0 0 2px rgba(200, 169, 122, 0.2);
582+
}
583+
563584
/* ====== RESPONSIVE ====== */
564585
@media (max-width: 520px) {
565586
.preview { flex-direction: column; align-items: center; }
@@ -788,9 +809,25 @@ <h2>Make the world darker</h2>
788809
if (checkInstalled()) {
789810
document.addEventListener('DOMContentLoaded', showSuccessState);
790811
} else {
812+
// Watch for the userscript setting data-claude-status-dark attribute
813+
var htmlObserver = new MutationObserver(function(mutations) {
814+
for (var i = 0; i < mutations.length; i++) {
815+
if (mutations[i].attributeName === 'data-claude-status-dark' && checkInstalled()) {
816+
showSuccessState();
817+
htmlObserver.disconnect();
818+
return;
819+
}
820+
}
821+
});
822+
htmlObserver.observe(document.documentElement, { attributes: true });
823+
824+
// Fallback timeout for edge cases
791825
setTimeout(function() {
792-
if (checkInstalled()) showSuccessState();
793-
}, 1000);
826+
if (checkInstalled()) {
827+
showSuccessState();
828+
htmlObserver.disconnect();
829+
}
830+
}, 2000);
794831
}
795832

796833
// GitHub Pages URL — correct MIME type (application/javascript)

extension/content.css

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -492,6 +492,7 @@ input[type="text"],
492492
input[type="email"],
493493
input[type="tel"],
494494
input[type="url"],
495+
input[type="search"],
495496
textarea,
496497
select,
497498
.phone-country,
@@ -501,11 +502,25 @@ select,
501502
border-color: #3a3734 !important;
502503
}
503504

505+
input:focus,
506+
textarea:focus,
507+
select:focus {
508+
border-color: #c8a97a !important;
509+
box-shadow: 0 0 0 2px rgba(200, 169, 122, 0.2) !important;
510+
outline: none !important;
511+
}
512+
504513
input::placeholder,
505514
textarea::placeholder {
506515
color: #5a5852 !important;
507516
}
508517

518+
/* Checkbox / radio accent */
519+
input[type="checkbox"],
520+
input[type="radio"] {
521+
accent-color: #c8a97a;
522+
}
523+
509524
.terms_and_privacy_information,
510525
.terms_and_privacy_information a,
511526
.help-block {

0 commit comments

Comments
 (0)