diff --git a/AGENTS.md b/AGENTS.md index f50c4c6..eb8087f 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -94,42 +94,7 @@ Statuses: 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 `
` 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 `
` 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 `
` 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. +- [ ] Experiment with adding a neat new background. Pull it from @/home/vicky/Projects/nwnee-shadowsoverwestgate/media/ae02ec4a-88df-4a53-b780-00b7c3f482f4.png and try to overlay the header with it. Use your best judgment for what "looks good". ## Future Tasks @@ -192,9 +157,44 @@ Tasks to be considered in the future, not implemented immediately. Keep them in - [ ] 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. -Next useful moves: +- [-] 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 `
` 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 `
` 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 `
` 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. -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. +Next useful moves: ### Context for categories diff --git a/plugin.json b/plugin.json index cf8011e..eacb526 100644 --- a/plugin.json +++ b/plugin.json @@ -18,6 +18,7 @@ }, "staticDirs": { "fonts": "public/fonts", - "game-icons": "public/game-icons" + "game-icons": "public/game-icons", + "images": "public/images" } } diff --git a/public/images/mono-header-bg.png b/public/images/mono-header-bg.png new file mode 100644 index 0000000..c278ae9 Binary files /dev/null and b/public/images/mono-header-bg.png differ diff --git a/public/images/plum-header-bg.png b/public/images/plum-header-bg.png new file mode 100644 index 0000000..21d96d5 Binary files /dev/null and b/public/images/plum-header-bg.png differ diff --git a/scss/westgate/_header.scss b/scss/westgate/_header.scss new file mode 100644 index 0000000..66397c8 --- /dev/null +++ b/scss/westgate/_header.scss @@ -0,0 +1,169 @@ +.westgate-brand-hero { + position: relative; + overflow: hidden; + margin-top: 0.25rem; + border: 1px solid rgba(194, 163, 90, 0.22); + border-radius: 10px; + padding: 1.05rem 1.05rem; + filter: saturate(1) contrast(1) brightness(1); + background: url("./plugins/nodebb-theme-westgate/images/plum-header-bg.png") center 50% / cover no-repeat; + box-shadow: + inset 0 1px 0 rgba(255, 242, 204, 0.08), + inset 0 0 0 1px rgba(33, 21, 28, 0.5), + 0 18px 42px rgba(0, 0, 0, 0.3); + + &::before { + content: ""; + position: absolute; + inset: 0; + background: + radial-gradient(circle at 22% 46%, rgba(120, 46, 94, 0.15), transparent 26%), + linear-gradient(90deg, rgba(14, 11, 18, 0.54) 0%, rgba(37, 19, 36, 0.24) 24%, rgba(37, 19, 36, 0.18) 76%, rgba(14, 11, 18, 0.58) 100%); + opacity: 0.82; + pointer-events: none; + } +} + +.westgate-brand-hero__veil, +.westgate-brand-hero__inner { + position: relative; + z-index: 1; +} + +.westgate-brand-hero__veil { + position: absolute; + inset: auto 0 0 0; + height: 54%; + background: linear-gradient(180deg, rgba(11, 8, 15, 0), rgba(34, 15, 30, 0.62)); + z-index: 0; + pointer-events: none; +} + +.westgate-brand-hero__inner { + align-items: center; + justify-content: center; + gap: 0; + min-height: 128px; +} + +.westgate-brand-hero__brand { + width: 100%; + flex-wrap: wrap; + min-height: inherit; + padding: 0 0 0 clamp(1rem, 4vw, 3rem); + + &:hover, + &:focus-within { + background: transparent; + } +} + +.westgate-brand-hero__brand :where([component="brand/anchor"], [component="siteTitle"]) { + color: inherit; + text-decoration: none; + + &:hover, + &:focus { + color: inherit; + text-decoration: none; + background: transparent; + box-shadow: none; + outline: none; + } +} + +.westgate-brand-hero__brand [component="siteTitle"] { + width: 100%; + padding: 0; + justify-content: flex-start; +} + +.westgate-brand-hero__title-block { + display: flex; + flex-direction: column; + align-items: flex-start; + gap: 0.35rem; +} + +.westgate-brand-hero__brand [component="siteTitle"] :where(h1, .fs-6) { + font-family: var(--wg-font-display); + font-size: clamp(1.65rem, 2.8vw, 2.5rem) !important; + line-height: 0.92; + font-weight: 600; + letter-spacing: 0.1em; + text-transform: uppercase; + text-shadow: + 0 1px 0 rgba(255, 222, 142, 0.05), + 0 2px 0 rgba(52, 37, 15, 0.92), + 0 4px 0 rgba(16, 11, 6, 0.96), + 0 8px 14px rgba(0, 0, 0, 0.72), + 0 14px 26px rgba(0, 0, 0, 0.46), + 0 0 16px rgba(48, 10, 26, 0.24); + opacity: 0.82; + mix-blend-mode: screen; +} + +.westgate-brand-hero__subtitle { + color: #c2a35a; + font-family: var(--wg-font-display); + font-size: 0.86rem; + font-weight: 600; + letter-spacing: 0.22em; + line-height: 1; + text-transform: uppercase; + text-shadow: + 0 1px 0 rgba(0, 0, 0, 0.92), + 0 3px 8px rgba(0, 0, 0, 0.34); +} + +.westgate-brand-hero__widgets { + position: relative; + color: var(--wg-text); + text-shadow: 0 1px 0 rgba(0, 0, 0, 0.74); + width: 100%; + padding-left: 0; + border-left: 0; + text-align: center; + margin-top: 0.5rem; + + > :last-child { + margin-bottom: 0; + } +} + +@media (max-width: 991.98px) { + .westgate-brand-hero { + margin-top: 0; + padding: 0.95rem 0.9rem; + background-position: center 46%; + } + + .westgate-brand-hero__inner { + min-height: 108px; + flex-wrap: wrap; + } + + .westgate-brand-hero__brand { + min-height: 0; + padding: 0 0 0 0.4rem; + } + + .westgate-brand-hero__title-block { + gap: 0.28rem; + } + + .westgate-brand-hero__brand [component="siteTitle"] :where(h1, .fs-6) { + font-size: clamp(1.3rem, 5.2vw, 1.8rem) !important; + letter-spacing: 0.07em; + } + + .westgate-brand-hero__subtitle { + font-size: 0.74rem; + letter-spacing: 0.18em; + } + + .westgate-brand-hero__widgets { + border-top: 1px solid rgba(216, 194, 138, 0.12); + padding-top: 0.85rem; + } +} diff --git a/templates/header.tpl b/templates/header.tpl new file mode 100644 index 0000000..c68484b --- /dev/null +++ b/templates/header.tpl @@ -0,0 +1,39 @@ + + + + {browserTitle} + {{{each metaTags}}}{function.buildMetaTag}{{{end}}} + + {{{each linkTags}}}{function.buildLinkTag}{{{end}}} + + + + {{{if useCustomHTML}}} + {{customHTML}} + {{{end}}} + {{{if useCustomCSS}}} + + {{{end}}} + + + + [[global:skip-to-content]] + + {{{ if config.theme.topMobilebar }}} + + {{{ end }}} + +
+ + +
+
+ + + diff --git a/templates/partials/header/brand.tpl b/templates/partials/header/brand.tpl new file mode 100644 index 0000000..e0a7c32 --- /dev/null +++ b/templates/partials/header/brand.tpl @@ -0,0 +1,24 @@ +{{{ if (brand:logo || (config.showSiteTitle || widgets.brand-header.length)) }}} +
+
+
+ {{{ if config.showSiteTitle }}} + + {{{ end }}} + {{{ if widgets.brand-header.length }}} +
+ {{{each widgets.brand-header}}} + {{./html}} + {{{end}}} +
+ {{{ end }}} +
+
+{{{ end }}} diff --git a/theme.scss b/theme.scss index ff52ee6..ed098bb 100644 --- a/theme.scss +++ b/theme.scss @@ -1,5 +1,6 @@ @import "../nodebb-theme-harmony/theme"; @import "./scss/westgate/tokens"; +@import "./scss/westgate/header"; @import "./scss/westgate/surfaces"; @import "./scss/westgate/categories"; @import "./scss/westgate/topics";