@bytesbrains/weblocks 0.4.0 → 0.6.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/AGENT.md CHANGED
@@ -46,20 +46,27 @@ its exact config schema:
46
46
  - `catalogPrompt()` — a compact text menu for a system prompt.
47
47
  - `CATALOG.md` — the same, human-readable.
48
48
 
49
- The 40 block types, by group:
49
+ The 45 block types, by group:
50
50
 
51
51
  - **Chrome/app-shell:** `nav`, `app-shell`, `sidebar`, `announcement-bar`, `footer`
52
52
  - **Heroes:** `hero`, `hero-app`
53
+ - **Résumé / profile:** `profile-header` (avatar, name, contacts, Download-PDF/Share buttons), `experience` (dated entries — reuse for Education/Certifications by changing its title), `skills` (tags or level bars)
53
54
  - **Content:** `features`, `about`, `rich-text`, `split`, `steps`, `stats`,
54
55
  `services-catalogue`, `pricing`, `logos`, `team`
55
- - **Media:** `gallery`, `carousel`, `video`, `map`
56
+ - **Media:** `gallery`, `carousel`, `video`, `video-gallery`, `map`
56
57
  - **Location:** `directions` (deep links to open the visitor’s map app)
57
58
  - **Structured:** `timeline`, `tabs`, `accordion`, `testimonials`, `faq`
58
59
  - **Collections:** `blog-list`, `blog-post`, `feed`
59
60
  - **Dynamic (powered):** `contact-form`, `newsletter`, `search`, `auth`
60
- - **Conversion/rhythm:** `cta`, `social-links`, `contact-details`, `divider`, `spacer`
61
+ - **Conversion/rhythm:** `cta`, `social-links`, `contact-details`, `divider`, `spacer`, `copyright`
61
62
  - **Legal:** `legal` (terms/privacy links that open safe-Markdown dialogs; content is Markdown, never raw HTML)
62
63
 
64
+ Interactivity is safe to enable: `gallery` with `lightbox: true`, `carousel` with
65
+ `autoplay: true`, `tabs`/`accordion`, etc. work out of the box — CSS-only where
66
+ possible, and the host serves small shipped islands (`gallery` lightbox,
67
+ `carousel` controls) for the rest. You just set the typed config; you never write
68
+ the JavaScript.
69
+
63
70
  ## Composing a manifest
64
71
 
65
72
  Emit exactly this shape (a block’s `id` is optional — the engine assigns one):
@@ -160,6 +167,15 @@ capability it needs; the **host** wires the endpoint. If no runtime is wired, th
160
167
  block renders inert-but-valid — that is expected, not an error. Never put secrets,
161
168
  endpoints, captcha keys, or backend logic in the config.
162
169
 
170
+ ## Favicon & hero banner
171
+
172
+ - **Favicon:** set `meta.favicon` to an icon **URL** or a single **emoji** (e.g.
173
+ `"🍞"`) — the engine emits the browser-tab `<link rel="icon">`.
174
+ - **Hero image banner:** give the `hero` block an `image` for a full-bleed
175
+ background banner; add `overlay` (`scrim`/`dark`/`light`/`none`) for text
176
+ legibility and `minHeight` (`sm`/`md`/`lg`/`full`). Text colour auto-flips over
177
+ dark overlays.
178
+
163
179
  ## PWA & SEO (optional, additive)
164
180
 
165
181
  Add top-level fields to make the app installable / discoverable:
package/CATALOG.md CHANGED
@@ -1,8 +1,8 @@
1
- # @bytesbrains/weblocks — Block Catalog (v0.4.0)
1
+ # @bytesbrains/weblocks — Block Catalog (v0.6.0)
2
2
 
3
3
  The AI composes a `SiteManifest` (`{ meta, design, blocks[] }`) using **only** the block types below, then the engine validates + renders it to static HTML. This file is generated from the code (`npm run emit:catalog`) — do not edit by hand.
4
4
 
5
- **Block types:** `app-shell` · `nav` · `announcement-bar` · `sidebar` · `hero` · `hero-app` · `features` · `about` · `rich-text` · `split` · `steps` · `stats` · `services-catalogue` · `pricing` · `logos` · `team` · `gallery` · `carousel` · `video` · `map` · `timeline` · `tabs` · `accordion` · `testimonials` · `faq` · `blog-list` · `blog-post` · `feed` · `contact-form` · `newsletter` · `search` · `auth` · `cta` · `social-links` · `contact-details` · `directions` · `legal` · `divider` · `spacer` · `footer`
5
+ **Block types:** `app-shell` · `nav` · `announcement-bar` · `sidebar` · `hero` · `hero-app` · `profile-header` · `experience` · `skills` · `features` · `about` · `rich-text` · `split` · `steps` · `stats` · `services-catalogue` · `pricing` · `logos` · `team` · `gallery` · `carousel` · `video` · `video-gallery` · `map` · `timeline` · `tabs` · `accordion` · `testimonials` · `faq` · `blog-list` · `blog-post` · `feed` · `contact-form` · `newsletter` · `search` · `auth` · `cta` · `social-links` · `contact-details` · `directions` · `legal` · `divider` · `spacer` · `copyright` · `footer`
6
6
 
7
7
  ## `app-shell`
8
8
 
@@ -47,7 +47,7 @@ A vertical section/drawer navigation for multi-view apps: an optional title over
47
47
 
48
48
  ## `hero`
49
49
 
50
- Top-of-page banner: a big headline with an optional eyebrow, subheading, and one call-to-action button.
50
+ Top-of-page hero: a big headline with optional eyebrow, subheading, and CTA — optionally over a full-bleed background image banner with a legibility overlay.
51
51
 
52
52
  | field | type | required | notes |
53
53
  |---|---|---|---|
@@ -55,6 +55,9 @@ Top-of-page banner: a big headline with an optional eyebrow, subheading, and one
55
55
  | `headline` | string | yes | |
56
56
  | `subhead` | string | | |
57
57
  | `align` | undefined (center\|left) | | |
58
+ | `image` | string | | |
59
+ | `overlay` | undefined (scrim\|dark\|light\|none) | | |
60
+ | `minHeight` | undefined (auto\|sm\|md\|lg\|full) | | |
58
61
  | `cta` | object | | |
59
62
 
60
63
  ## `hero-app`
@@ -69,6 +72,42 @@ An app landing hero: a headline and subhead over a primary install button, with
69
72
  | `installHref` | string | | |
70
73
  | `screenshots` | array | | |
71
74
 
75
+ ## `profile-header`
76
+
77
+ A résumé/CV header: avatar, name, role, location, a contact + social row, and optional Download-PDF and Share buttons.
78
+
79
+ | field | type | required | notes |
80
+ |---|---|---|---|
81
+ | `name` | string | yes | |
82
+ | `headline` | string | | |
83
+ | `location` | string | | |
84
+ | `avatar` | string | | |
85
+ | `summary` | string | | |
86
+ | `contacts` | array | | |
87
+ | `showDownload` | boolean | | |
88
+ | `downloadLabel` | string | | |
89
+ | `showShare` | boolean | | |
90
+ | `shareLabel` | string | | |
91
+
92
+ ## `experience`
93
+
94
+ A résumé section of dated entries (role, org, period, location, bullets). Reuse for Experience, Education, Certifications by changing the title.
95
+
96
+ | field | type | required | notes |
97
+ |---|---|---|---|
98
+ | `title` | string | | |
99
+ | `items` | array | | |
100
+
101
+ ## `skills`
102
+
103
+ Grouped skills shown as tags (with optional proficiency dots) or labelled level bars; also for languages and tools.
104
+
105
+ | field | type | required | notes |
106
+ |---|---|---|---|
107
+ | `title` | string | | |
108
+ | `display` | undefined (tags\|bars) | | |
109
+ | `groups` | array | | |
110
+
72
111
  ## `features`
73
112
 
74
113
  A grid of value propositions, each with an optional icon/emoji, a title, and a short line of text.
@@ -203,6 +242,17 @@ A responsive embedded video from YouTube or Vimeo (by id or URL) or a self-hoste
203
242
  | `poster` | string | | |
204
243
  | `caption` | string | | |
205
244
 
245
+ ## `video-gallery`
246
+
247
+ A grid or carousel of click-to-play video cards (YouTube/Vimeo/file); each loads its player inline on click (a lightweight facade — no heavy iframes up front).
248
+
249
+ | field | type | required | notes |
250
+ |---|---|---|---|
251
+ | `title` | string | | |
252
+ | `layout` | undefined (grid\|carousel) | | |
253
+ | `columns` | integer (2\|3\|4) | | |
254
+ | `items` | array | | |
255
+
206
256
  ## `map`
207
257
 
208
258
  An embedded location map for a place or address query, with configurable zoom and height and a link to the full map.
@@ -352,11 +402,14 @@ A full-width call-to-action band: a headline, optional subheading, and one butto
352
402
 
353
403
  ## `social-links`
354
404
 
355
- A centered row of links to social or external profiles, each an optional icon plus a label.
405
+ A row or grid of links to social/contact profiles; each link picks a built-in brand icon by platform (or a custom emoji), shown labeled or icon-only.
356
406
 
357
407
  | field | type | required | notes |
358
408
  |---|---|---|---|
359
409
  | `title` | string | | |
410
+ | `layout` | undefined (row\|grid) | | |
411
+ | `variant` | undefined (labeled\|icon) | | |
412
+ | `align` | undefined (start\|center\|end) | | |
360
413
  | `links` | array | | |
361
414
 
362
415
  ## `contact-details`
@@ -413,6 +466,18 @@ Deliberate vertical whitespace between sections, in one of four sizes (sm, md, l
413
466
  |---|---|---|---|
414
467
  | `size` | undefined (sm\|md\|lg\|xl) | | |
415
468
 
469
+ ## `copyright`
470
+
471
+ A small copyright bar (© year holder + rights text) for the bottom of a page; the year auto-fills to the current year when left blank.
472
+
473
+ | field | type | required | notes |
474
+ |---|---|---|---|
475
+ | `holder` | string | | |
476
+ | `year` | string | | |
477
+ | `text` | string | | |
478
+ | `showSymbol` | boolean | | |
479
+ | `align` | undefined (start\|center\|end) | | |
480
+
416
481
  ## `footer`
417
482
 
418
483
  Page footer: brand, tagline, a row of links, and a copyright line. Place last.
package/CHANGELOG.md CHANGED
@@ -5,6 +5,68 @@ follows [semantic versioning](https://semver.org): the **block catalog** and the
5
5
  **`SiteManifest` shape** are the public contract — additive block/field changes
6
6
  are minor, breaking changes to either are major.
7
7
 
8
+ ## 0.6.0 — 2026-07-16
9
+
10
+ A résumé/CV builder, hero image banners, and favicons. Additive and
11
+ **non-breaking** — every `0.5.0` manifest still validates and renders identically.
12
+ Catalog 42 → 45.
13
+
14
+ ### Added
15
+ - **Résumé / CV pack** — turn the engine into a live-resume builder:
16
+ - **`profile-header`** — avatar (or initials), name, role, location, a contact +
17
+ social row (brand icons), and optional **Download-PDF** and **Share** buttons.
18
+ - **`experience`** — dated, structured entries (role, org, period, location,
19
+ summary, achievement bullets). Reuse for Experience / Education /
20
+ Certifications by changing its title.
21
+ - **`skills`** — grouped skills as tags (with proficiency dots) or level bars.
22
+ - **Print styles** — `renderSite` now emits an `@media print` stylesheet so any
23
+ page (especially a résumé) exports cleanly to PDF; the **`resume.js` island**
24
+ wires the header's Download (`window.print()`) and Share (Web Share API +
25
+ copy-link) buttons. `data-wl-noprint` elements are hidden from the printout.
26
+ - **`hero` image banner** — the `hero` block gains optional `image`, `overlay`
27
+ (scrim / dark / light / none), and `minHeight` (sm / md / lg / full). With an
28
+ image, the photo sits behind the content (an `<img>` + scrim) with a legibility
29
+ overlay and the text flips to a readable colour; with no image it renders
30
+ exactly as before.
31
+ - **`meta.favicon`** — a browser-tab favicon: a URL (svg/png/ico) **or a single
32
+ emoji** (rendered as an inline SVG data URI). `renderSite` emits a scheme-
33
+ sanitized `<link rel="icon">` in `<head>` when set.
34
+
35
+ ## 0.5.0 — 2026-07-16
36
+
37
+ More media & footer blocks, brand icons, and shipped interactivity. Additive and
38
+ **non-breaking** — every `0.4.0` manifest still validates and renders identically.
39
+ Catalog 40 → 42.
40
+
41
+ ### Added
42
+ - **`video-gallery` block** — a grid or carousel of **click-to-play video cards**
43
+ (YouTube / Vimeo / self-hosted). Each card is a lightweight *facade* (thumbnail
44
+ + play button); the new **`video.js` island** loads the real player inline on
45
+ click, so no heavy iframes load up front. YouTube thumbnails auto-derive from
46
+ the id; no-JS clicks open the platform.
47
+ - **`copyright` block** — a small "© year holder · rights" bar for the bottom of
48
+ a page (a standalone alternative to the `footer` copyright line). The year
49
+ auto-fills to the current year when blank; configurable holder, note, symbol,
50
+ and alignment.
51
+ - **`social-links` — built-in brand icons & layouts.** Each link takes a typed
52
+ `platform` (x/twitter, instagram, facebook, linkedin, youtube, github, tiktok,
53
+ whatsapp, telegram, discord, mastodon, rss, email, website, phone) that supplies
54
+ a monochrome brand icon (simple-icons, CC0; themed via `currentColor`) and a
55
+ default label — `custom` still takes your own emoji/glyph. New `layout`
56
+ (row/grid), `variant` (labeled/icon-only), and `align` options. Non-breaking.
57
+ - **Shipped interactive islands** — the engine now ships the client scripts for
58
+ its interactive blocks (previously host-provided), as zero-dependency browser
59
+ modules under the `./islands/*.js` subpath export:
60
+ - `lightbox.js` — `gallery` click-to-zoom: prev/next, keyboard, swipe, Esc,
61
+ caption, scroll-lock, focus restore.
62
+ - `carousel.js` — `carousel` arrows, dot indicators, keyboard nav, and optional
63
+ autoplay (honours `prefers-reduced-motion`, pauses on hover/focus).
64
+ - `renderSite(manifest, { islandBase })` to configure where island scripts are
65
+ served (default `/_island`).
66
+ - Islands are built by a separate `tsconfig.islands.json` (DOM lib); the engine's
67
+ Node code stays DOM-free. `gallery` now marks `data-wl-lightbox` when its
68
+ lightbox is enabled.
69
+
8
70
  ## 0.4.0 — 2026-07-16
9
71
 
10
72
  Additive and non-breaking — every `0.3.0` manifest still validates and renders
package/README.md CHANGED
@@ -101,7 +101,7 @@ is never raw HTML:
101
101
 
102
102
  ```ts
103
103
  type SiteManifest = {
104
- meta: { title: string; description: string; lang: string };
104
+ meta: { title: string; description: string; lang: string; favicon?: string };
105
105
  design: DesignTokens; // the shared baseplate (CSS custom properties)
106
106
  blocks: Block[]; // ordered, typed page sections
107
107
  version: number; // bumped per accepted edit → undo / history / diff
@@ -139,19 +139,20 @@ import catalogJson from '@bytesbrains/weblocks/catalog.json' with { type: 'json'
139
139
 
140
140
  ## Block catalog
141
141
 
142
- **40 typed blocks.** Full field reference in [`CATALOG.md`](./CATALOG.md).
142
+ **45 typed blocks.** Full field reference in [`CATALOG.md`](./CATALOG.md).
143
143
 
144
144
  | Group | Blocks |
145
145
  |---|---|
146
146
  | Chrome / app-shell | `nav` · `app-shell` · `sidebar` · `announcement-bar` · `footer` |
147
147
  | Heroes | `hero` · `hero-app` |
148
+ | Résumé / profile | `profile-header` · `experience` · `skills` (live CV — avatar, dated entries, skills, Download-PDF/Share) |
148
149
  | Content | `features` · `about` · `rich-text` · `split` · `steps` · `stats` · `services-catalogue` · `pricing` · `logos` · `team` |
149
- | Media | `gallery` · `carousel` · `video` · `map` |
150
+ | Media | `gallery` · `carousel` · `video` · `video-gallery` · `map` |
150
151
  | Location | `directions` (deep links to the visitor’s map app) |
151
152
  | Structured | `timeline` · `tabs` · `accordion` · `testimonials` · `faq` |
152
153
  | Collections | `blog-list` · `blog-post` · `feed` |
153
154
  | Dynamic (powered) | `contact-form` · `newsletter` · `search` · `auth` |
154
- | Conversion / rhythm | `cta` · `social-links` · `contact-details` · `divider` · `spacer` |
155
+ | Conversion / rhythm | `cta` · `social-links` · `contact-details` · `divider` · `spacer` · `copyright` |
155
156
  | Legal | `legal` (terms/privacy links → safe-Markdown dialogs) |
156
157
 
157
158
  `rich-text` and `blog-post` carry **typed** content nodes (headings, paragraphs,
@@ -234,6 +235,31 @@ for (const [file, body] of Object.entries(emitPwa(manifest) ?? {})) writeFileSyn
234
235
  // → manifest.webmanifest + sw.js
235
236
  ```
236
237
 
238
+ ## Interactivity (islands)
239
+
240
+ Pages are static-first: JavaScript ships only for the interactive blocks that need
241
+ it, and only when their behaviour is on. `renderSite` emits a marker for each —
242
+ `<script type="module" src="/_island/<name>.js">` — and the engine **ships the
243
+ island scripts** (zero-dependency, ~6 KB each) under a subpath:
244
+
245
+ | Block | Island | Behaviour |
246
+ |---|---|---|
247
+ | `gallery` (`lightbox: true`) | `lightbox.js` | click-to-zoom, prev/next, keyboard, swipe, Esc |
248
+ | `carousel` | `carousel.js` | arrows, dots, keyboard, optional autoplay |
249
+ | `video-gallery` | `video.js` | click-to-play cards (load the real player inline on press) |
250
+ | `profile-header` (Download/Share on) | `resume.js` | print-to-PDF (`window.print()`) + Web Share / copy-link |
251
+
252
+ Serve them at the island URL. Copy from the package's `./islands/*.js` export, e.g.:
253
+
254
+ ```ts
255
+ import lightbox from '@bytesbrains/weblocks/islands/lightbox.js?url'; // bundler
256
+ // or, for a static host, copy node_modules/@bytesbrains/weblocks/lib/islands/*.js
257
+ // to /_island/ (change the base with renderSite(m, { islandBase: '/assets/js' }))
258
+ ```
259
+
260
+ Blocks whose behaviour is off (e.g. `tabs`, `accordion` — CSS-only) ship no JS at
261
+ all.
262
+
237
263
  ## API reference
238
264
 
239
265
  All exports are named; types are shipped (`lib/index.d.ts`).