@gemboss/website-ui 0.10.0 → 0.11.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
@@ -4,6 +4,65 @@ Every release lists what changed for a site that uses the kit. A release that ad
4
4
  says so with `Closes gap #N` (the GitHub issue number), so `npx gemboss-website upgrade` can tell that site which
5
5
  stopgap (`kitgap-*`) it can now delete.
6
6
 
7
+ ## 0.11.0 (2026-10-26)
8
+
9
+ The header, 1:1 with gemboss.ai. Since the footer (0.10.0), the header was the last part of gemboss.ai not drawn by
10
+ the kit, and the kit's header was a simpler one: a narrower panel with icons, a button for each section, no pictures,
11
+ nothing behind. Chris asked for it identical, with nothing missed, and for every value to live in the kit so that
12
+ GemPages, Gemians and GemX inherit it (26/10/2026). 0.11.0 takes every value and every motion from gemboss.ai's own
13
+ header and was measured against it in Chromium, pixel by pixel: the bar at 320 to 1920px, every menu open at 1081,
14
+ 1366, 1440 and 1920px, rows hovered (their previews), the pill under a hovered name, the keyboard's focus, the phone
15
+ menu's top level, each level and each level's end at 390, 768 and 1080px, light and dark, on pages in each section.
16
+ All of it is identical but one thing, on purpose: on the phone, gemboss.ai's own menu gives "Start free" a light
17
+ bottom hairline and takes "Book a demo"'s away (a rule meant for its menu's rows reaches them); the kit draws the two
18
+ buttons whole.
19
+
20
+ A minor version: a 0.10.0 header changes to these values, and its mega menu's markup changes (below).
21
+
22
+ - The bar: the page's wrap + 12px (1132px on GemBoss), 24px inside (6px up to 640px), its own width whatever order the
23
+ stylesheets load in (`.gw-header > .gw-header__bar`; drop `.gw-wrap` from it). The logo 34px with 8px corners (was
24
+ 26px), a 44px row up to 768px. The menu's words 0.005em tighter, 38px tall (8px x 12px, 1.6 lines); the current page
25
+ or section in the accent's strong ink, weight 600 (was ink with an underline; a section's name carries
26
+ `aria-current`). Actions 4px apart: Sign in from 1081px, a second text action `.gw-header__link` (Book a demo) from
27
+ 1181px, the button from 561px, 8px further out. The menu button 42px (44px on touch) with one strong hairline on
28
+ the surface, the card radius, ink while open; its icons gemboss.ai's. The phone menu runs to 1080px, the desktop
29
+ starts at 1081px (was 1080px), in the CSS and in `website.js`.
30
+ - The mega menu, gemboss.ai's own (its v5): a section's name is a link to its page (`a.gw-nav__trigger` with a 12px
31
+ `.gw-nav__chev`) that opens its panel after the pointer rests 200ms (90ms to switch, 350ms to close; the keyboard's
32
+ focus at once; ArrowDown steps into the first row). One surface morphs to the open panel's size and place, the
33
+ panels crossfade on it, a caret points at the name, a pill glides under the hovered name, a highlight under the
34
+ hovered row, the page behind dims and blurs (`.gw-scrim`, `--gw-scrim`). A panel: `.gw-mega__body` (columns of
35
+ rows, then `.gw-mega__aside`, the pictures) and an optional `.gw-mega__foot` strip; its widths and columns are its
36
+ markup's (`--gw-mega-w`, `--gw-mega-pv`, `--gw-mega-cols`). Pictures sit on the Stage (`.gw-mega__art`, new tokens
37
+ `--gw-stage-*`): the panel's own `.gw-mega__card`, and a row's preview, the `<template>` its `data-gw-preview` names
38
+ (`"feature"`: the panel's card). A card's pictures load the first time it shows (`data-gw-bg`,
39
+ `template[data-gw-hydrate]`, `.is-hydrated`). A picture straight on the Stage (an `<img>`) fills it.
40
+ - Moving a 0.10.0 header: the panel's `.gw-wrap.gw-mega__grid` becomes `.gw-mega__body > .gw-mega__grid`, the
41
+ `.gw-mega__feature` card becomes a `.gw-mega__card` in a `.gw-mega__aside` (its words in `.gw-mega__card-text`, a
42
+ picture in `.gw-mega__art`), the rows' `.gw-mega__icon` is not drawn on desktop. A `<button>` name still works: a
43
+ click opens its panel and keeps it open, a second click closes it. `templates/header.html` has the new markup.
44
+ - The script: the mega menu is wired per header (the `mega` mark is on the `.gw-header` now, not on each name);
45
+ `gw:mega` fires on the name. One panel open on the page, across headers. `destroy` takes the surface, caret, pill,
46
+ scrim and previews away and hides the panels again.
47
+ - The phone menu (the drill-down): 24px in from the edges, its links set at 18px, weight 500, 0.005em tighter, its
48
+ heads and headings on 1.6 lines; a row under the pointer or the keyboard takes the soft ground, 2px to the right, its
49
+ icon tile in the accent; a row may carry a 48x32 picture; a level may end with its panel's card and "All of … →"
50
+ (the arrow after a space); the action bar's buttons 8px apart, 16px words; `.gw-mobile-menu__link--muted`, a
51
+ quieter link before Sign in (What's new). The current page is not marked on the phone.
52
+ - Tokens, gemboss.ai's: the dark theme's shadows (`shadow.dark`: a 1px ledge, a deeper raised shadow; the kit kept
53
+ the light ones in dark before), `--gw-shadow-lift` (an object on the Stage), `--gw-stage-*` (glow, glow-2, top,
54
+ bottom, dot, ink), `--gw-scrim` light and dark, `--gw-radius-2` (the caret's corner), the dark theme's primary
55
+ button `#e3e4e8` (gemboss.ai's ink, was `#f2f3f5`). The focus ring 3px out with 4px corners (was 2px out).
56
+ - `check`: a mega panel's `--gw-mega-w`, `--gw-mega-pv`, `--gw-mega-cols` are inputs set in the markup, not tokens;
57
+ every kit shadow (dark ones and the lift included) is a token shadow.
58
+ - Budget: `js/website.js` is 34 KB, 9.9 KB gzipped (0.10.0: 23.1 KB, 7.1 KB); the test's budget is now 36 KB and
59
+ 10 KB.
60
+ - Tests: `test/run.mjs` holds the header's base rules byte for byte again from this version (their hash renewed once),
61
+ the mega menu in its fake DOM (the marks, the drawn parts, hover 200/90/350ms, touch, focus, ArrowDown, the pinned
62
+ button, one open across headers, destroy); `test/browser.mjs` drives the desktop mega menu at 1366px (its timing,
63
+ the surface and caret placement, a row's preview, ArrowDown, Escape, destroy). Demos and templates carry the new
64
+ markup.
65
+
7
66
  ## 0.10.0 (2026-10-26)
8
67
 
9
68
  The footer, 1:1 with gemboss.ai. 0.7.0 drew the footer "as gemboss.ai has it", but not to the pixel: when gemboss.ai
package/README.md CHANGED
@@ -40,9 +40,9 @@ nó đọc `AGENTS.md` của kit trước, dựng từ mẫu, và chạy `check`
40
40
  **Site HTML tĩnh hoặc không có bước build:** dùng CDN của npm, ghim đúng phiên bản.
41
41
 
42
42
  ```html
43
- <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@gemboss/website-ui@0.10.0/website.min.css">
43
+ <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@gemboss/website-ui@0.11.0/website.min.css">
44
44
  <link rel="stylesheet" href="/site.css"> <!-- CSS riêng của site, luôn SAU kit -->
45
- <script src="https://cdn.jsdelivr.net/npm/@gemboss/website-ui@0.10.0/js/website.js" defer></script>
45
+ <script src="https://cdn.jsdelivr.net/npm/@gemboss/website-ui@0.11.0/js/website.js" defer></script>
46
46
  ```
47
47
 
48
48
  Chèn markup của kit sau khi trang đã tải (block của builder, bản xem trước CMS): gọi `gwWebsite.init(phầnMới)` ngay
package/bin/lib/check.mjs CHANGED
@@ -335,7 +335,9 @@ export function subjectOf(sel) {
335
335
  const ATTR_THEME = String.raw`\[\s*data-theme(?:\s*[~|^$*]?=\s*(?:"[^"]*"|'[^']*'|[\w-]+))?\s*\]`;
336
336
  const ROOTISH = new RegExp(`^(?::root|html)?(?:${ATTR_THEME}|:not\\(\\s*${ATTR_THEME}\\s*\\))*$`, "i");
337
337
  const isRootish = (sel) => splitTop(sel).every((s) => s && ROOTISH.test(s));
338
- const INPUTS = new Set(["--gw-stars"]); // set on one element in the markup (style="--gw-stars: 4.9"), read by the kit's CSS
338
+ // set on one element in the markup, read by the kit's CSS: the stars' value (style="--gw-stars: 4.9"); a mega panel's width,
339
+ // its pictures' width and its columns (0.11.0: style="--gw-mega-w: 1120px; --gw-mega-pv: 380px; --gw-mega-cols: 2")
340
+ const INPUTS = new Set(["--gw-stars", "--gw-mega-w", "--gw-mega-pv", "--gw-mega-cols"]);
339
341
  const THEMABLE = /^--gw-(?:accent(?:-[\w-]+)?|on-accent(?:-(?:light|dark))?|wash(?:-[\w-]+)?)$/; // docs/theming.md: the eight accent variables (-light/-dark) + wash
340
342
 
341
343
  const COLOR_PROPS = /^(?:color|background(?:-color|-image)?|border(?:-(?:top|right|bottom|left|block|inline)(?:-(?:start|end))?)?(?:-color)?|outline(?:-color)?|fill|stroke|text-decoration(?:-color)?|caret-color|accent-color|column-rule(?:-color)?|text-emphasis(?:-color)?|-webkit-text-fill-color|-webkit-text-stroke(?:-color)?|scrollbar-color|stop-color|flood-color|lighting-color)$/;
@@ -361,7 +363,9 @@ const BUTTONISH = /btn|button/i;
361
363
  const pxNumbers = (v) => [...v.matchAll(/(-?\d*\.?\d+)(px|rem)\b/gi)].map((m) => ({ raw: m[0], px: Math.abs(parseFloat(m[1])) * (m[2].toLowerCase() === "rem" ? 16 : 1), unit: m[2].toLowerCase() }));
362
364
  const isFraction = (n) => Math.abs(n - Math.round(n)) > 1e-6;
363
365
  const normShadow = (s) => s.toLowerCase().replace(/\b0\./g, ".").replace(/\s*([,()])\s*/g, "$1").replace(/\s+/g, " ").trim();
364
- const TOKEN_SHADOWS = new Set(Object.entries(SYSTEM.shadow).filter(([k]) => !k.startsWith("$")).map(([, v]) => normShadow(v)));
366
+ // every shadow the kit draws: rest, sm, raised, the Stage's lift and (0.11.0) the dark theme's own
367
+ const TOKEN_SHADOWS = new Set(Object.entries(SYSTEM.shadow).filter(([k]) => !k.startsWith("$"))
368
+ .flatMap(([, v]) => (typeof v === "string" ? [v] : Object.values(v))).map(normShadow));
365
369
 
366
370
  function okShadowPart(p) {
367
371
  const v = p.trim();
package/css/base.css CHANGED
@@ -74,7 +74,8 @@ h5, h6 { font-size: 16px; font-weight: 600; letter-spacing: 0; }
74
74
  :where(p, dd, td, figcaption, .gw-list--check li, .gw-prose) a:not([class]):hover,
75
75
  .gw-link:hover { text-decoration-color: currentColor; }
76
76
 
77
- :focus-visible { outline: 2px solid var(--gw-accent); outline-offset: 2px; }
77
+ /* the focus ring, as gemboss.ai draws it (0.11.0): 2px of accent, 3px out, 4px corners */
78
+ :focus-visible { border-radius: var(--gw-radius-4); outline: 2px solid var(--gw-accent); outline-offset: 3px; }
78
79
  [id] { scroll-margin-top: calc(var(--gw-header-height) + 16px); }
79
80
 
80
81
  .gw-skip {
package/css/effects.css CHANGED
@@ -50,7 +50,7 @@
50
50
  the build checks the words on. */
51
51
  .gw-btn.gw-spot:not([aria-busy="true"])::before { --gw-spot-mix: var(--gw-spot-strength-action); }
52
52
  /* the mega menu's feature card is the Stage, a night ground: a stronger light, or it would not show */
53
- .gw-mega__feature.gw-spot:not([aria-busy="true"])::before { --gw-spot-mix: var(--gw-spot-strength-stage); }
53
+ .gw-mega__art.gw-spot:not([aria-busy="true"])::before { --gw-spot-mix: var(--gw-spot-strength-stage); }
54
54
 
55
55
  /* words under the light: lit, muted words are ink-2 at once (rules above); back to muted only once the light has gone
56
56
  out (a colour that waits the light's time, no movement). :where(), so a part's own transition wins. */