Repository source: docs/plans/gloss_dark_theme/gloss_dark_theme_direct.md
Gloss Dark theme — direct work
Mode: Direct (no Railspike cycle). Branch feat/gloss_dark_theme from origin/main at 7afe0d6a0.
Status: implemented and verified locally, uncommitted, awaiting the maintainer's review.
Request
2026-11-09, maintainer in a Claude Code session: "Can we please build a theme to mirror Gloss but for dark mode?"
Feedback items: none matched (searched docs/feedback/items/ for Gloss and dark requests; PF-20261030-F46 and PF-20261104-F13 cover Gloss itself).
Outcome
A new explicit theme, Gloss Dark (glossdark, mode dark), in the theme menu and cycle right after Gloss, permitted on ZenMemes. It has Gloss's rounded cards, pill controls, sans-serif face and smooth-line icons on a deep violet page, and the same four colour choices (Violet, Blue, Teal, Rose) in dark colours, with its own saved choice.
Reuse decisions
Stylesheet.
'stylesheet' => 'gloss'on the registry entry, the pattern Engagify uses, instead of a copiedtheme-glossdark.css. Every shared Gloss rule inpublic/assets/theme-gloss.cssnow listsglossdark; the Gloss Dark section sets only variables, the swatch, the palette picker and the icon filter. A future fix to Gloss's shapes reaches Gloss Dark automatically.Palettes. The existing palette mechanism (
'palettes' => self::GLOSS_PALETTES): picker markup, pre-paint restore and storage come fromtemplates/partials/theme_menu.php,templates/layout.phpandtheme_toggle.jsunchanged.Icons. The smooth-line set in
public/assets/theme-nav-icons.csslistsglossdarkalongside Gloss and Engagify; no new SVGs. The glyphs are drawn for a light page (violet stroke, lavender fill), so Gloss Dark appliesfilter: invert(1) hue-rotate(180deg)(light stroke, dark fill, same hue), combined with each palette's hue turn, to the same elements Gloss's palettes already filter.Other theme lists.
public/assets/site.css(app-shell account icon and More label) andpublic/assets/tools.css(Bookmarklets launcher fallback icon) exclude icon themes by name;glossdarkadded.
Checks
./v3 test --smoke ThemeRegistryTest NavIconSetsTest LocalAppSmokeTest: 442 run, 438 passed, 4 failed — the four long-standing failures (AgentPostingApiTest×2,SingleRequestHttpTest,SignedPostBundleValidatorTest, failing 25 runs since 2026-11-07, local PCRE\pproperty issue). Full suite not run.python3 tests/theme_contrast_audit.py:glossdark OK.node tests/browser/gloss_palettes.mjs, extended to Gloss Dark: each palette at 390px and 1280px applies, survives reload and navigation, passes the contrast pairs (it caught--ink-softon teal--active-bgat 3.92, fixed by darkening the three non-violet highlight colours), setscolor-scheme: dark, filters the icons, has no horizontal scroll, and Escape returns focus; Gloss and Engagify behaviour unchanged. PASS.Headless Chrome sweep at 1280px and 390px under Gloss Dark: board, composer, about, users, account key, Tools, open theme menu. No page errors, no horizontal overflow, Gloss's font applied; screenshots inspected. The fixture has no threads, so a thread page was not looked at.
Not checked: headed Chrome (scrollbars; Gloss sets none), production.
Deployment note
Baked thread, profile and tag pages carry the pre-paint theme allow-list. After deploy, run php scripts/build_static_artifacts.php or those routes fall back to the default theme for Gloss Dark readers.