stack-site-builder 1.20.0 → 1.21.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -11,6 +11,16 @@ content schema, while a consuming site supplies only content, taxonomy data and
11
11
  config. Sites track the theme with `pnpm up stack-site-builder`, so each release
12
12
  here is a plain version bump they pull in.
13
13
 
14
+ ## [1.21.0] - 2026-07-24
15
+
16
+ ### Added
17
+
18
+ - **Header brand options** — `site.header = { logo, logoInvert, name }`:
19
+ `logo` (a public/ path) replaces the hardcoded ⚡ bolt with the site's
20
+ mark, `name: false` drops the wordmark for a logo-only brand (the home
21
+ link keeps `site.name` as its aria-label), and `logoInvert` flips a
22
+ black line-art logo in dark mode. Defaults unchanged: ⚡ + site name.
23
+
14
24
  ## [1.20.0] - 2026-07-24
15
25
 
16
26
  ### Added
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "stack-site-builder",
3
3
  "type": "module",
4
- "version": "1.20.0",
4
+ "version": "1.21.0",
5
5
  "license": "MIT",
6
6
  "description": "The engine behind the awesome-*-stack catalog sites: an Astro theme with the catalog/concepts/articles/slides/samples routes, components, styles and markdown pipeline. Sites provide content, taxonomy data and config.",
7
7
  "repository": {
@@ -53,6 +53,14 @@ const base = import.meta.env.BASE_URL;
53
53
 
54
54
  const baseNoSlash = base.replace(/\/$/, '');
55
55
 
56
+ // Header brand: `site.header = { logo?: '/path.png', logoInvert?: bool,
57
+ // name?: bool }`. A logo replaces the ⚡ bolt; `name: false` drops the
58
+ // wordmark (logo-only brand — the link keeps site.name as its aria-label).
59
+ const header = (site as { header?: { logo?: string; logoInvert?: boolean; name?: boolean } })
60
+ .header;
61
+ const brandLogo = header?.logo;
62
+ const brandName = header?.name !== false;
63
+
56
64
  // Home URL per locale, for the language auto-detect redirect on the root home.
57
65
  const localeHomes = Object.fromEntries(
58
66
  (Object.keys(languages) as Lang[]).map((c) => [c, getRelativeLocaleUrl(c, '')]),
@@ -266,9 +274,19 @@ const navItems = allNavItems.filter((item) => !item.section || sectionEnabled(it
266
274
  aria-label={site.name}
267
275
  class="flex min-w-0 items-center gap-1.5 text-base font-bold tracking-tight whitespace-nowrap no-underline sm:text-lg"
268
276
  >
269
- <span aria-hidden="true">⚡</span>
270
- {/* Below 600px only the bolt remains, so the narrow header never truncates the wordmark. */}
271
- <span class="hidden truncate min-[600px]:inline">{site.name}</span>
277
+ {
278
+ brandLogo ? (
279
+ <img
280
+ src={`${baseNoSlash}${brandLogo}`}
281
+ alt=""
282
+ class:list={['h-7 w-7 shrink-0 object-contain', header?.logoInvert && 'aas-icon-invert']}
283
+ />
284
+ ) : (
285
+ <span aria-hidden="true">⚡</span>
286
+ )
287
+ }
288
+ {/* Below 600px only the mark remains, so the narrow header never truncates the wordmark. */}
289
+ {brandName && <span class="hidden truncate min-[600px]:inline">{site.name}</span>}
272
290
  </a>
273
291
  {/* Section links are icon-only (labels live in aria-label). On phones
274
292
  (<sm) they collapse into the labelled dropdown menu below, so the