fix: light emphasis colour so plain Bootstrap tables are readable (#36) (#37)

Closes #36.

## What was wrong

`/wiki/manage` showed its table in near-black text on the near-black page: the
header row, the `tid`, `Posts` and `Created` columns were effectively invisible.

## Root cause

The theme repaints Bootstrap's **light** colour mode dark (`$body-color`,
`$body-bg`, `$card-bg`, …) but never overrode `$body-emphasis-color`, which
Bootstrap defaults to `$black` (`#09080b` here). Everything that chains to
`--bs-emphasis-color` inherited that ink:

- `--bs-table-color` / `-striped-` / `-hover-` / `-active-` on any plain `.table`
- `--bs-tooltip-bg` (dark text on a dark tooltip)
- `--bs-nav-tabs-link-active-color`, `--bs-nav-underline-link-active-color`
- `--bs-list-group-action-hover-color` / `-active-color`
- the `.text-emphasis` / `.link-body-emphasis` utilities

`_controls.scss` had already patched this by hand for the two tables anyone had
noticed (`notification/table`, `flags/list`) and for post-content tables. Every
other table in the forum was still broken. Fixing the variable once is a smaller
diff than a third per-table patch, and it covers tables that do not exist yet.

## The change

One variable in `scss/overrides.scss` — the file whose stated job is exactly
this — plus a contract test so the next dark-repaint variable that goes missing
fails a check instead of shipping.

## Verification

Booted the `sow-nodebb` dev stack with this working tree mounted
(`PLUGIN_PATH=../sow-nodebb-theme`), seeded a wiki namespace with topics, and
compared `/wiki/manage` before and after: unreadable → fully legible, gold rules
and buttons unchanged. Also eyeballed `/categories`, `/notifications`,
`/user/admin`, a topic, `/wiki` and `/flags` for regressions — none. The ACP is
unaffected: it builds from `admin/overrides`, not this file.

All `tests/*.test.js` pass; the new test fails when the variable is reverted.

Co-authored-by: vickydotbat <zoelynne.victoria@gmail.com>
Reviewed-on: #37
This commit was merged in pull request #37.
This commit is contained in:
2026-07-20 11:05:46 +00:00
co-authored by vickydotbat
parent 5d37548da0
commit 985ff0755d
3 changed files with 55 additions and 21 deletions
+26 -21
View File
@@ -30,27 +30,32 @@ Fast checks, no forum needed:
tables). There is no `npm test` script; run each file directly. tables). There is no `npm test` script; run each file directly.
- `node scripts/check-emails.js` — when working on email templates. - `node scripts/check-emails.js` — when working on email templates.
Live visual check against a real forum, using the sibling checkout at Live visual check against a real forum**always possible, never skip it**.
`../sow-nodebb`: Every change in this repo can be seen in a browser before it ships; there is no
theme change that can only be checked in production. A unit test cannot tell
you that a colour is unreadable, so look at the page.
1. `cd ../sow-nodebb && cp .env.example .env` (if not done already), then set Use the sibling checkout at `../sow-nodebb`:
`PLUGIN_PATH=../sow-nodebb-theme` and `PLUGIN_ID=nodebb-theme-westgate` so
the compose file mounts this working tree.
2. `docker compose -f docker-compose.dev.yml up`
3. Open `http://localhost:4567` (or `HTTP_PORT` from `.env`). Dev admin login:
`admin` / `Admin12345!` (defaults; dev-only).
4. If Westgate is not the active theme yet, switch to it once in
ACP → Appearance → Themes; the choice persists in the redis volume.
5. NodeBB compiles this theme's SCSS and templates at build time, so a browser
reload alone is not enough after editing them. Rebuild, then reload:
`docker compose -f docker-compose.dev.yml exec nodebb ./nodebb build --config=/opt/config/config.json`
(restart the `nodebb` service if changes still don't show).
6. Full reset (also required after changing `PLUGIN_*` in `.env`):
`docker compose -f docker-compose.dev.yml down -v`
Agents with browser tooling (e.g. Playwright) should point it at 1. `cd ../sow-nodebb && cp .env.example .env`, then uncomment the "Theme
`http://localhost:4567` to load pages, take screenshots, and verify theme development" block so this working tree is the mounted package:
changes on the live forum. `PLUGIN_PATH=../sow-nodebb-theme`, `PLUGIN_ID=nodebb-theme-westgate`,
`EXTRA_PLUGINS=nodebb-plugin-westgate-wiki nodebb-plugin-westgate-pages`.
2. `nix develop --command make dev` — the forum comes up at
`http://localhost:4567` (or `HTTP_PORT`) with this theme already active.
Dev admin login: `admin` / `Admin12345!` (defaults; dev-only).
3. NodeBB compiles this theme's SCSS and templates at build time, so a browser
reload alone is not enough after editing them: `make dev-build`, then
reload. `make dev-restart` if changes still don't show.
4. `make dev-reset` wipes everything; required after changing `PLUGIN_*` or
`EXTRA_PLUGINS` in `.env`.
A fresh database is empty, so pages that render content (wiki, categories,
topics) need seeding first. `../sow-nodebb/AGENTS.md` has the recipes for
seeding over the REST API, for writing plugin settings straight to Redis, and
for driving a headless browser on this NixOS box (the Playwright MCP server
does not work here). Point any browser tooling at `http://localhost:4567` to
load pages, take screenshots, and compare before/after.
## Design Context ## Design Context
@@ -70,8 +75,8 @@ changes on the live forum.
- `templates/`: Harmony template overrides (same relative paths as Harmony). - `templates/`: Harmony template overrides (same relative paths as Harmony).
- `custom_pages/`: source content and mockups for custom-pages surfaces. - `custom_pages/`: source content and mockups for custom-pages surfaces.
- `lib/`, `public/client.js`: server hooks and client behavior. - `lib/`, `public/client.js`: server hooks and client behavior.
- `tests/`: contract tests for topbar, footer, icons, and wiki table - `tests/`: contract tests for topbar, footer, icons, wiki table rendering,
rendering. Plain assert scripts: run each with and the Bootstrap dark-repaint variables. Plain assert scripts: run each with
`node tests/<name>.test.js`; there is no `npm test` script. `node tests/<name>.test.js`; there is no `npm test` script.
## Theme Direction ## Theme Direction
+6
View File
@@ -48,6 +48,12 @@ $dark: $wg-ink !default;
$body-color: $wg-text-soft !default; $body-color: $wg-text-soft !default;
$body-bg: $wg-ink !default; $body-bg: $wg-ink !default;
// We repaint Bootstrap's LIGHT colour mode dark, so emphasis must be light too.
// Bootstrap defaults it to $black; leaving it there paints near-black text on our
// dark surfaces wherever a component chains to --bs-emphasis-color: plain .table
// (e.g. /wiki/manage), tooltips, nav-tabs/nav-underline active links, list-group
// hover states, and the .text-emphasis / .link-body-emphasis utilities.
$body-emphasis-color: $wg-text !default;
$body-tertiary-bg: $wg-panel !default; $body-tertiary-bg: $wg-panel !default;
$text-muted: $wg-text-muted !default; $text-muted: $wg-text-muted !default;
$border-color: rgba($wg-gold, 0.14) !default; $border-color: rgba($wg-gold, 0.14) !default;
+23
View File
@@ -0,0 +1,23 @@
// Westgate repaints Bootstrap's LIGHT colour mode dark, so every Bootstrap
// variable that defaults to a near-black ink must be re-pointed at a light
// token. Missing one is invisible until some component chains to it — that is
// how /wiki/manage ended up with near-black table text on a near-black page.
const assert = require("assert");
const fs = require("fs");
const path = require("path");
const overrides = fs.readFileSync(
path.join(__dirname, "..", "scss", "overrides.scss"),
"utf8"
);
// Bootstrap's defaults for these are $black / $body-color-ish inks.
["$body-color", "$body-bg", "$body-emphasis-color"].forEach(variable => {
const declaration = new RegExp(`\\${variable}:\\s*([^;]+);`).exec(overrides);
assert(declaration, `${variable} must be overridden for the dark repaint`);
assert.match(
declaration[1],
/\$wg-/,
`${variable} must resolve to a Westgate palette token, got: ${declaration[1].trim()}`
);
});