aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCraig Jennings <c@cjennings.net>2026-06-16 08:37:46 -0500
committerCraig Jennings <c@cjennings.net>2026-06-16 08:37:46 -0500
commitb10a1b7a33772c744abfd11ff1e4aef8b33e519b (patch)
tree219bd11c4d2dacae4160c07ac73f251ce0fca0e1
parentc96c1e9f94f52876b3a8c6ab8e35a00e5f556f3d (diff)
downloaddotemacs-b10a1b7a33772c744abfd11ff1e4aef8b33e519b.tar.gz
dotemacs-b10a1b7a33772c744abfd11ff1e4aef8b33e519b.zip
fix(theme-studio): make the color picker stand out from the page
The picker panel's background (#161412) sat a few shades off the page background (#0d0b0a), so it was hard to tell apart from the page. I gave it the studio's gold accent border (#e8bd30) and lifted the background to #1f1c19, both already used in the toolbar chrome, so the panel reads as a distinct surface. The #pickertest gate asserts the accent border and a per-channel background lift of at least 12 over the page, so the distinction can't quietly regress.
-rw-r--r--scripts/theme-studio/browser-gates.js15
-rw-r--r--scripts/theme-studio/styles.css2
-rw-r--r--scripts/theme-studio/theme-studio.html17
-rw-r--r--todo.org15
4 files changed, 46 insertions, 3 deletions
diff --git a/scripts/theme-studio/browser-gates.js b/scripts/theme-studio/browser-gates.js
index 2748f326e..e474cd4e5 100644
--- a/scripts/theme-studio/browser-gates.js
+++ b/scripts/theme-studio/browser-gates.js
@@ -793,6 +793,21 @@ if(location.hash==='#gnustest'){let ok=true;const notes=[];const A=(c,n)=>{if(!c
A(used.includes(f),'preview includes '+f);
document.title='GNUSTEST '+(ok?'PASS':'FAIL');
const d=document.createElement('div');d.id='gnustest';d.textContent='GNUSTEST '+(ok?'PASS':'FAIL')+(notes.length?' fails='+notes.join(','):'');document.body.appendChild(d);}
+// picker-distinct gate (open with #pickertest): the color picker panel must stand
+// out from the page background. It carries a highlighted gold accent border, and its
+// background is meaningfully lighter than the body so the two are easy to tell apart.
+if(location.hash==='#pickertest'){let ok=true;const notes=[];const A=(c,n)=>{if(!c){ok=false;notes.push(n);}};
+ const pk=document.getElementById('picker');A(!!pk,'picker element exists');
+ if(pk){const cs=getComputedStyle(pk),body=getComputedStyle(document.body);
+ const bc=(cs.borderTopColor.match(/\d+/g)||[]).slice(0,3).map(Number);
+ const pkbg=(cs.backgroundColor.match(/\d+/g)||[]).slice(0,3).map(Number);
+ const bdbg=(body.backgroundColor.match(/\d+/g)||[]).slice(0,3).map(Number);
+ A(bc.join(',')==='232,189,48','picker carries the gold accent border (got '+cs.borderTopColor+')');
+ const lift=pkbg.map((c,i)=>c-bdbg[i]);
+ A(lift.every(d=>d>=12),'picker background is clearly lighter than the page (per-channel lift '+lift.join(',')+')');
+ }
+ document.title='PICKERTEST '+(ok?'PASS':'FAIL');
+ const d=document.createElement('div');d.id='pickertest';d.textContent='PICKERTEST '+(ok?'PASS':'FAIL')+(notes.length?' fails='+notes.join(','):'');document.body.appendChild(d);}
// Box-cluster gate (open with #boxtest): the box control is a 2x2 cluster of
// four radio buttons (none / line / pressed / raised); the color swatch shows
// only while a box style is active.
diff --git a/scripts/theme-studio/styles.css b/scripts/theme-studio/styles.css
index 6a2d08d9d..720539cfd 100644
--- a/scripts/theme-studio/styles.css
+++ b/scripts/theme-studio/styles.css
@@ -96,7 +96,7 @@
.palctl input[type=text]::placeholder{color:#b4b1a2;opacity:1}
.palctl{position:relative}
.swatch{width:128px;height:58px;border:1px solid #555;border-radius:6px;cursor:pointer;background:#888}
- .picker{display:none;position:absolute;top:66px;left:0;z-index:60;background:#161412;border:1px solid #3a3a3a;border-radius:8px;padding:12px;box-shadow:0 10px 30px #000b;width:470px}
+ .picker{display:none;position:absolute;top:66px;left:0;z-index:60;background:#1f1c19;border:1px solid #e8bd30;border-radius:8px;padding:12px;box-shadow:0 10px 30px #000b;width:470px}
.picker .prow{display:flex;gap:10px}
.sv{position:relative;width:400px;height:320px;border-radius:4px;cursor:crosshair}
.svmask{position:absolute;inset:0;pointer-events:none;border-radius:4px}
diff --git a/scripts/theme-studio/theme-studio.html b/scripts/theme-studio/theme-studio.html
index d64316c11..6459960dd 100644
--- a/scripts/theme-studio/theme-studio.html
+++ b/scripts/theme-studio/theme-studio.html
@@ -98,7 +98,7 @@
.palctl input[type=text]::placeholder{color:#b4b1a2;opacity:1}
.palctl{position:relative}
.swatch{width:128px;height:58px;border:1px solid #555;border-radius:6px;cursor:pointer;background:#888}
- .picker{display:none;position:absolute;top:66px;left:0;z-index:60;background:#161412;border:1px solid #3a3a3a;border-radius:8px;padding:12px;box-shadow:0 10px 30px #000b;width:470px}
+ .picker{display:none;position:absolute;top:66px;left:0;z-index:60;background:#1f1c19;border:1px solid #e8bd30;border-radius:8px;padding:12px;box-shadow:0 10px 30px #000b;width:470px}
.picker .prow{display:flex;gap:10px}
.sv{position:relative;width:400px;height:320px;border-radius:4px;cursor:crosshair}
.svmask{position:absolute;inset:0;pointer-events:none;border-radius:4px}
@@ -3549,6 +3549,21 @@ if(location.hash==='#gnustest'){let ok=true;const notes=[];const A=(c,n)=>{if(!c
A(used.includes(f),'preview includes '+f);
document.title='GNUSTEST '+(ok?'PASS':'FAIL');
const d=document.createElement('div');d.id='gnustest';d.textContent='GNUSTEST '+(ok?'PASS':'FAIL')+(notes.length?' fails='+notes.join(','):'');document.body.appendChild(d);}
+// picker-distinct gate (open with #pickertest): the color picker panel must stand
+// out from the page background. It carries a highlighted gold accent border, and its
+// background is meaningfully lighter than the body so the two are easy to tell apart.
+if(location.hash==='#pickertest'){let ok=true;const notes=[];const A=(c,n)=>{if(!c){ok=false;notes.push(n);}};
+ const pk=document.getElementById('picker');A(!!pk,'picker element exists');
+ if(pk){const cs=getComputedStyle(pk),body=getComputedStyle(document.body);
+ const bc=(cs.borderTopColor.match(/\d+/g)||[]).slice(0,3).map(Number);
+ const pkbg=(cs.backgroundColor.match(/\d+/g)||[]).slice(0,3).map(Number);
+ const bdbg=(body.backgroundColor.match(/\d+/g)||[]).slice(0,3).map(Number);
+ A(bc.join(',')==='232,189,48','picker carries the gold accent border (got '+cs.borderTopColor+')');
+ const lift=pkbg.map((c,i)=>c-bdbg[i]);
+ A(lift.every(d=>d>=12),'picker background is clearly lighter than the page (per-channel lift '+lift.join(',')+')');
+ }
+ document.title='PICKERTEST '+(ok?'PASS':'FAIL');
+ const d=document.createElement('div');d.id='pickertest';d.textContent='PICKERTEST '+(ok?'PASS':'FAIL')+(notes.length?' fails='+notes.join(','):'');document.body.appendChild(d);}
// Box-cluster gate (open with #boxtest): the box control is a 2x2 cluster of
// four radio buttons (none / line / pressed / raised); the color swatch shows
// only while a box style is active.
diff --git a/todo.org b/todo.org
index 5b862281b..0a10a738c 100644
--- a/todo.org
+++ b/todo.org
@@ -4240,11 +4240,13 @@ Rule taxonomy captured in [[file:docs/design/theme-studio-face-rules.org][docs/d
Bake into the tool (a lint surfaced in the UI) or run as a build-time check (seeds vs live deffaces via emacsclient).
-** TODO [#C] theme-studio picker panel blends into the page :bug:quick:solo:studio:
+** DONE [#C] theme-studio picker panel blends into the page :bug:quick:solo:studio:
+CLOSED: [2026-06-16 Tue]
:PROPERTIES:
:LAST_REVIEWED: 2026-06-11
:END:
Craig, 2026-06-11 manual-test walk: the color picker's background is hard to distinguish from the page background. Give the picker panel a visibly distinct background or a highlighted border so it stands out. Pin with a gate asserting the picker element carries the distinct style.
+Done 2026-06-16: the picker now carries the gold accent border (#e8bd30) and a lighter background (#1f1c19 vs the page's #0d0b0a). The #pickertest gate asserts the accent border and a per-channel background lift of ≥12 over the page, so the distinction can't silently regress.
** TODO [#C] theme-studio: restrict the cursor row to its background :bug:studio:
The UI table gives the cursor face the full control set (fg, B/I/U/S, box), but Emacs only honors the cursor face's :background. Its shape is cursor-type, not a face attribute, so every other control on that row is a no-op once the theme loads. Restrict the cursor row to just its background swatch so the studio doesn't present controls Emacs drops.
@@ -4579,6 +4581,17 @@ What we're verifying: with the mu4e modes excluded from global font-lock, mu4e's
- Open mu4e, look at the headers list and the main menu
- Open a message and read the body
Expected: headers list shows unread/flagged/date/subject in their theme colors (mu4e-unread-face gold, mu4e-header-face green, etc.); the main menu and the message-view headers (From/To/Subject) are themed; the message body still renders correctly (gnus does the body, so it's unaffected). NOTE: a plain "g" refresh in an already-open *mu4e-headers* won't fix it on its own unless font-lock is off there; a restart is the reliable check.
+*** VERIFY theme-studio gnus view package themes the article headers
+What we're verifying: gnus is now its own view package in theme-studio (it drives the mu4e article view), so the bright-green article headers can be themed and exported. #gnustest confirms the package is registered and its preview emits only real gnus faces; this is the visual read plus the live-green retirement.
+- Reload theme-studio (or make theme-studio-open)
+- Pick "gnus (mu4e article view)" from the view dropdown (sits among the g entries)
+- Confirm the preview shows a header block, an emphasized body, an 11-level quoted reply chain, and a signature
+- Theme a few gnus faces (e.g. gnus-header-name, gnus-header-from, gnus-cite-1) to obvious colors, export to WIP.json, then deploy
+#+begin_src sh :results output
+make -C /home/cjennings/.emacs.d deploy-wip
+#+end_src
+- Restart Emacs (or reload the theme), reopen a mu4e message
+Expected: the studio preview renders each gnus face in its theme color; after export + deploy, the *mu4e-article* From/Subject/To/Date headers show the themed colors instead of the gnus green defaults.
*** VERIFY theme-studio markdown preview reads like a real README
What we're verifying: selecting markdown-mode in the view dropdown shows a realistic README (not the generic face-name list), and the markdown faces render legibly in context. #mdtest already confirms the wiring + that every element's face is real; this is the visual read.
- Reload theme-studio (or make theme-studio-open)