Fix widget card compatibility

This commit is contained in:
2026-04-24 13:11:40 +02:00
parent 908fffb091
commit 407528da98
2 changed files with 122 additions and 46 deletions
+83 -40
View File
@@ -94,6 +94,52 @@ Statuses:
Complete the following: Complete the following:
- [-] In the process of testing widgets, I noticed that some are being given the "card" treatment (the glossy purple background element) even if there is no card container. Example here: http://localhost:4567/user/admin
- [x] Widgets without the card containers should display plainly.
- [x] Widgets can be put inside of a card container to make a card.
- [x] Expand this from a single-widget bug into a theme-wide widget compatibility pass. The current issue appears broader: too many generic containers, especially plain `<div>` wrappers emitted by widgets or templates, are inheriting the glossy purple gradient card treatment even when they are only structural wrappers.
- [x] Define a compatibility model for widget rendering before implementation:
- [x] Structural wrappers should remain visually neutral by default. A wrapper existing only for layout, spacing, templating, or plugin/widget output should not automatically become a "Westgate card".
- [x] Card styling should be opt-in and intentional. The gradient/gloss/chrome treatment should apply only to known card surfaces, explicit card utility classes, or template regions that are semantically meant to read as panels.
- [x] Plain-text widgets and lightweight HTML widgets must render cleanly without needing custom markup just to avoid accidental card chrome.
- [x] Nested widget markup should not compound card styling. A widget inside a panel should not create boxes-within-boxes unless the nested card is intentional.
- [x] Footer widgets require special handling. Footer text such as "Powered by NodeBB" should behave like footer chrome, not like a content card or panel.
- [x] Build a proper investigation plan for global compatibility:
- [x] Inventory which selectors currently apply the purple gradient/card treatment too broadly. Pay particular attention to rules targeting generic `div`, broad widget wrappers, `.card`, `.panel`, Bootstrap containers, Harmony wrappers, and footer/sidebar/account-page blocks.
- [x] Trace the rendered wrapper stack for several widget types in the running forum, not just one route. Include at minimum: footer HTML widget, profile-page widget areas, sidebar widgets, category-page widgets, and any ACP-placed plain text/HTML widget.
- [x] Distinguish between three classes of surfaces:
- [x] structural wrappers
- [x] content cards/panels
- [x] utility text blocks / footer chrome / metadata strips
- [x] Decide whether the best long-term model is:
- [ ] tightening overly broad selectors so they only target real card components
- [ ] introducing a small explicit Westgate card utility class for opt-in chrome
- [ ] adding a small set of opt-out compatibility rules for widget regions that must stay plain
- [x] or a hybrid of the above
- 2026-04-24 implementation note: `scss/westgate/_widgets.scss` now limits chrome to known panel surfaces (`.card`, `.alert`, `.forum-stats`, `.search-widget`, `.category`, legacy `.panel`/`.well`/`.jumbotron`) plus explicit opt-in utility classes `.westgate-widget-card` and `.wg-widget-card`. Generic top-level wrappers in widget areas are neutral again, and footer wrappers are forced back to plain chrome.
- [x] Define expected compatibility outcomes before coding:
- [x] A plain HTML widget that outputs only text or a single `<div>` should render plainly.
- [x] A widget wrapped in an intentional card class should receive the full glossy Westgate card treatment.
- [x] Existing topic lists, category lists, and intentional content panels should keep their current Westgate identity.
- [x] Footer widget areas should not automatically gain panel framing unless explicitly requested.
- [x] Account/profile pages such as `/user/admin` should not pick up accidental panel chrome from generic wrappers.
- [x] Widget/plugin markup from outside this theme should degrade gracefully even if it uses simple Bootstrap or generic `<div>` containers.
- [-] Validation plan once implementation starts:
- [ ] Check desktop and mobile for footer widgets, sidebar widgets, profile widgets, and at least one plain HTML widget with no special classes.
- [ ] Confirm that intentionally carded widgets still look like Westgate cards.
- [ ] Confirm that nested wrappers no longer create accidental card-on-card stacking.
- [ ] Verify no regressions to topic cards, category panels, or other intentional glossy surfaces.
- [x] Local investigation covered the rendered wrapper stack on `http://localhost:4567/user/admin`, `http://localhost:4567/categories`, `http://localhost:4567/category/2/announcements`, and the sidebar footer widget HTML from the live local render.
## Future Tasks
Tasks to be considered in the future, not implemented immediately. Keep them in scope when making decisions.
- [ ] Consider a light mode/dark mode toggle while retaining core theme, preferably without adding a Skin
- [ ] Un-bold "topics" and "posts" and make the color lines replace the black line drived from category background color to either use the foreground color of the icon, or an ornate gilding like the icons (image 2)
- [ ] Consider making the category names a bit smoother; it looks like it's not anti-aliased. (image 3)
- [ ] Mobile website doesn't use the correct fonts.
- [-] Implement curated game-icons support for category/subcategory icons: sanitize selected SVGs into mask-friendly theme assets, expose them through `staticDirs`, add reusable `wg-icon-*` CSS mask classes, and include category custom classes in the local category/subcategory templates if Harmony data supports them. - [-] Implement curated game-icons support for category/subcategory icons: sanitize selected SVGs into mask-friendly theme assets, expose them through `staticDirs`, add reusable `wg-icon-*` CSS mask classes, and include category custom classes in the local category/subcategory templates if Harmony data supports them.
- [x] Phase 1: Build our icon stack. - [x] Phase 1: Build our icon stack.
- [x] Recommend icons from the game-icons pack for forum categories and their subcategories. See `GAME_ICONS.md`. - [x] Recommend icons from the game-icons pack for forum categories and their subcategories. See `GAME_ICONS.md`.
@@ -109,38 +155,47 @@ Complete the following:
- [x] Define the exact ACP custom classes to enter for each category/subcategory, based on `GAME_ICONS.md`, so setup can happen without theme code knowing category IDs. - [x] Define the exact ACP custom classes to enter for each category/subcategory, based on `GAME_ICONS.md`, so setup can happen without theme code knowing category IDs.
- [x] Document setup steps for admins: where to enter the custom class, which class names map to which icons, and when to rebuild/restart NodeBB after theme changes. - [x] Document setup steps for admins: where to enter the custom class, which class names map to which icons, and when to rebuild/restart NodeBB after theme changes.
- [x] Validate implementation scaffolding: `./nodebb build` succeeds, compiled templates emit `{./class}`, compiled CSS contains the `wg-icon-*` mask rules, and `/assets/plugins/nodebb-theme-westgate/game-icons/drama-masks.svg` returns HTTP 200. - [x] Validate implementation scaffolding: `./nodebb build` succeeds, compiled templates emit `{./class}`, compiled CSS contains the `wg-icon-*` mask rules, and `/assets/plugins/nodebb-theme-westgate/game-icons/drama-masks.svg` returns HTTP 200.
- [x] Enter the `wg-icon-*` values from `GAME_ICONS.md` into the live ACP category custom class fields. The current live data still contains legacy layout classes like `col-md-3 col-6`; keep them only if they are still intentionally used for layout, and append the `wg-icon-*` class alongside them. - [?] Enter the `wg-icon-*` values from `GAME_ICONS.md` into the live ACP category custom class fields. The current live data still contains legacy layout classes like `col-md-3 col-6`; keep them only if they are still intentionally used for layout, and append the `wg-icon-*` class alongside them.
- [x] Removed `col-md-3 col-6` legacy layout classes. - [?] Removed `col-md-3 col-6` legacy layout classes.
- 2026-04-23 local validation on `http://localhost:4567/categories` found the ACP data was not in the expected final state: root categories still rendered `col-md-3 col-6` and no root `wg-icon-*` classes. Re-enter the preferred classes from `GAME_ICONS.md` in this local NodeBB database before marking this complete.
- [-] Validate actual game-icon visuals on the live website after ACP class entry: desktop and mobile `/categories`, one category page with subcategories, "load more subcategories" if present, and at least one category with no game-icon class to confirm Font Awesome fallback still works. - [-] Validate actual game-icon visuals on the live website after ACP class entry: desktop and mobile `/categories`, one category page with subcategories, "load more subcategories" if present, and at least one category with no game-icon class to confirm Font Awesome fallback still works.
- [ ] Icons don't fit into their containers: either too small or cropped wrong. Especially noticeable when viewing `category` page - [x] Icons don't fit into their containers: either too small or cropped wrong. Especially noticeable when viewing `category` page
- [ ] Missing "signet ring" style ornamentation namely on `category` page (above topic or subcategory list) - Reduced mask inset from 22% to 13%, with category header at 11% and compact child pills at 16%.
- [ ] Subcategory containers no longer tidy; maybe subcategory icon and container should be bigger (1.5x current size) on the `categories` page with text remaining the same size. - [x] Missing "signet ring" style ornamentation namely on `category` page (above topic or subcategory list)
- [ ] Some icons need to be changed. When adding new icons, add new classes for them, and deprecate unused ones: - Category page header icons now share the ornate category icon frame instead of the simpler topic-page shadow.
- [ ] INFORMATION: `scroll-unfurled` - [x] Subcategory containers no longer tidy; maybe subcategory icon and container should be bigger (1.5x current size) on the `categories` page with text remaining the same size.
- [ ] Announcements: `trumpet-flag` - Category child pill icon frames are 27px, with fixed dimensions and unchanged text sizing.
- [ ] Player Guide: `compass` - [x] Some icons need to be changed. When adding new icons, add new classes for them, and deprecate unused ones:
- [ ] COMMUNITY - [x] INFORMATION: `scroll-unfurled`
- [ ] General Discussion:`beer-stein` - [x] Announcements: `trumpet-flag`
- [ ] Screenshots: `wood-frame` - [x] Player Guide: `compass`
- [ ] Creations: `harp` - [x] COMMUNITY
- [ ] ROLEPLAY: `duality-mask` - [x] General Discussion:`beer-stein`
- [ ] Notices: `stabbed-note` - [x] Screenshots: `wood-frame`
- [ ] Rumors & Gossip: `mute` - [x] Creations: `harp`
- [ ] Journals & Biographies: `sword-altar` - [x] ROLEPLAY: `duality-mask`
- [ ] Factions & Guilds: `cowled` - [x] Notices: `stabbed-note`
- [ ] Keep `wax-seal` for "Organization Registry" (subcategory of Factions & Guilds) - [x] Rumors & Gossip: `mute`
- [ ] SUPPORT: `candle-flame` - [x] Journals & Biographies: `sword-altar`
- [ ] Common Issues & Questions: `key-lock` - [x] Factions & Guilds: `cowled`
- [ ] Feedback: `envelope` - [x] Keep `wax-seal` for "Organization Registry" (subcategory of Factions & Guilds)
- [ ] Technical Help:`round-potion` - [x] SUPPORT: `candle-flame`
- [ ] DEVELOPMENT: `anvil` - [x] Common Issues & Questions: `key-lock`
- [ ] Tools & References: `spanner` - [x] Feedback: `envelope`
- [ ] Programming: `gears` - [x] Technical Help:`round-potion`
- [ ] General: `wax-tablet` - [x] DEVELOPMENT: `anvil`
- [ ] Lore: `classical-knowledge` - [x] Tools & References: `spanner`
- [x] Programming: `gears`
- [x] General: `wax-tablet`
- [x] Lore: `classical-knowledge`
- [-] CSS behavior validated with Playwright class injection because local ACP classes were missing: desktop `/categories`, mobile `/categories`, category-page header, category-page subcategory rows, and asset URLs for `scroll-unfurled.svg`, `anvil.svg`, and `candle-flame.svg` returned HTTP 200. Actual ACP-configured visual validation remains incomplete until the local category custom class fields are updated.
- [ ] Decide whether uploaded category background images should be cleared for icon-driven categories after seeing the final ACP-configured visuals. - [ ] Decide whether uploaded category background images should be cleared for icon-driven categories after seeing the final ACP-configured visuals.
- [ ] Explain any operational follow-up after ACP setup, especially asset rebuild, restart/cache behavior, and whether legacy Bootstrap layout classes should remain in category custom class fields. - [ ] Explain any operational follow-up after ACP setup, especially asset rebuild, restart/cache behavior, and whether legacy Bootstrap layout classes should remain in category custom class fields.
Next useful moves:
Re-enter the preferred wg-icon-\* classes from GAME_ICONS.md into this local NodeBB instance, then rerun the rendered checks. Decide whether category background images should be cleared once the real ACP-configured icons are visible. Add the short operational note about rebuild/restart/cache behavior after ACP updates.
### Context for categories ### Context for categories
Categories are fully capitalized. I've also included my own suggestions of what they could look like. If you have better ideas, tell me. Categories are fully capitalized. I've also included my own suggestions of what they could look like. If you have better ideas, tell me.
@@ -180,15 +235,3 @@ DEVELOPMENT -- Behind-the-scenes work, tools, and development discussion. Use a
- Designs - Designs
- Programming - Programming
- Area Building - Area Building
## Future Tasks
Tasks to be considered in the future, not implemented immediately. Keep them in scope when making decisions.
- [ ] Consider a light mode/dark mode toggle while retaining core theme, preferably without adding a Skin
- [ ] Un-bold "topics" and "posts" and make the color lines replace the black line drived from category background color to either use the foreground color of the icon, or an ornate gilding like the icons (image 2)
- [ ] Consider making the category names a bit smoother; it looks like it's not anti-aliased. (image 3)
- [ ] Mobile website doesn't use the correct fonts.
- [ ] In the process of testing widgets, I noticed that some are being given the "card" treatment (the glossy purple background element) even if there is no card container. Example here: http://localhost:4567/user/admin
- [ ] Widgets without the card containers should display plainly.
- [ ] Widgets can be put inside of a card container to make a card.
+39 -6
View File
@@ -23,12 +23,34 @@
gap: 0.85rem; gap: 0.85rem;
} }
[data-widget-area] > :where(.card, .alert, .list-group, .forum-stats, .stats, .well, .jumbotron), [data-widget-area] > :where(
[data-widget-area] > :where(div, section, aside):not(:empty):not(.hidden):not(.row):not([data-widget-area]) { .card,
.alert,
.list-group,
.forum-stats,
.stats-card,
.stats,
.search-widget,
.category,
.well,
.jumbotron,
.panel,
.westgate-widget-card,
.wg-widget-card
) {
color: var(--wg-text-soft); color: var(--wg-text-soft);
} }
[data-widget-area] > :where(div, section, aside):not(:empty):not(.hidden):not(.row):not([data-widget-area]):not(.card):not(.alert):not(.list-group) { [data-widget-area] > :where(
.forum-stats,
.search-widget,
.category,
.well,
.jumbotron,
.panel,
.westgate-widget-card,
.wg-widget-card
) {
padding: 0.85rem; padding: 0.85rem;
background: background:
linear-gradient(to bottom, transparent calc(100% - 1px), rgba(194, 163, 90, 0.045) calc(100% - 1px)), linear-gradient(to bottom, transparent calc(100% - 1px), rgba(194, 163, 90, 0.045) calc(100% - 1px)),
@@ -44,7 +66,10 @@
[data-widget-area] .card.text-bg-light, [data-widget-area] .card.text-bg-light,
[data-widget-area] .card-header.text-bg-light, [data-widget-area] .card-header.text-bg-light,
[data-widget-area] .well, [data-widget-area] .well,
[data-widget-area] .jumbotron { [data-widget-area] .jumbotron,
[data-widget-area] .panel,
[data-widget-area] .westgate-widget-card,
[data-widget-area] .wg-widget-card {
background: background:
linear-gradient(to bottom, rgba(255, 241, 196, 0.024), rgba(8, 7, 10, 0.08)), linear-gradient(to bottom, rgba(255, 241, 196, 0.024), rgba(8, 7, 10, 0.08)),
var(--wg-velvet-panel) !important; var(--wg-velvet-panel) !important;
@@ -192,6 +217,14 @@
font-family: var(--wg-font-ui); font-family: var(--wg-font-ui);
} }
[data-widget-area="footer"] > :where(footer, .footer),
[data-widget-area="sidebar-footer"] > :where(footer, .footer) {
padding: 0;
background: transparent !important;
border: 0 !important;
box-shadow: none !important;
}
[data-widget-area="footer"] > .row:has(> a.btn[href*="/user/"]) { [data-widget-area="footer"] > .row:has(> a.btn[href*="/user/"]) {
--bs-gutter-x: 0.45rem; --bs-gutter-x: 0.45rem;
--bs-gutter-y: 0.45rem; --bs-gutter-y: 0.45rem;
@@ -225,10 +258,10 @@
[data-widget-area="sidebar"] .card, [data-widget-area="sidebar"] .card,
[data-widget-area="sidebar"] .alert, [data-widget-area="sidebar"] .alert,
[data-widget-area="sidebar"] > :where(div, section, aside):not(:empty):not(.hidden):not(.row):not([data-widget-area]):not(.card):not(.alert):not(.list-group), [data-widget-area="sidebar"] > :where(.forum-stats, .search-widget, .category, .well, .jumbotron, .panel, .westgate-widget-card, .wg-widget-card),
[data-widget-area="sidebar-footer"] .card, [data-widget-area="sidebar-footer"] .card,
[data-widget-area="sidebar-footer"] .alert, [data-widget-area="sidebar-footer"] .alert,
[data-widget-area="sidebar-footer"] > :where(div, section, aside):not(:empty):not(.hidden):not(.row):not([data-widget-area]):not(.card):not(.alert):not(.list-group) { [data-widget-area="sidebar-footer"] > :where(.forum-stats, .search-widget, .category, .well, .jumbotron, .panel, .westgate-widget-card, .wg-widget-card) {
box-shadow: box-shadow:
inset 0 1px 0 rgba(255, 255, 255, 0.024), inset 0 1px 0 rgba(255, 255, 255, 0.024),
0 8px 18px rgba(0, 0, 0, 0.18) !important; 0 8px 18px rgba(0, 0, 0, 0.18) !important;