@gemboss/website-ui 0.0.0-stage → 0.2.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.
Files changed (44) hide show
  1. package/AGENTS.md +191 -0
  2. package/CHANGELOG.md +47 -0
  3. package/README.md +118 -2
  4. package/bin/gemboss-website.mjs +78 -0
  5. package/bin/lib/check.mjs +695 -0
  6. package/bin/lib/gap.mjs +189 -0
  7. package/bin/lib/init.mjs +99 -0
  8. package/bin/lib/upgrade.mjs +155 -0
  9. package/bin/lib/util.mjs +147 -0
  10. package/css/base.css +107 -0
  11. package/css/components.css +324 -0
  12. package/css/footer.css +53 -0
  13. package/css/header.css +231 -0
  14. package/css/layout.css +59 -0
  15. package/css/prose.css +119 -0
  16. package/css/sections.css +173 -0
  17. package/css/tokens.css +200 -0
  18. package/demo/index.html +703 -0
  19. package/demo/theme-example.html +133 -0
  20. package/docs/components.md +407 -0
  21. package/docs/markup-contract.md +148 -0
  22. package/docs/philosophy.md +69 -0
  23. package/docs/theming.md +96 -0
  24. package/js/website.js +186 -0
  25. package/package.json +50 -4
  26. package/skill/SKILL.md +49 -0
  27. package/system.json +122 -0
  28. package/templates/footer.html +40 -0
  29. package/templates/header.html +60 -0
  30. package/templates/page.html +134 -0
  31. package/templates/sections/cta.html +15 -0
  32. package/templates/sections/faq.html +24 -0
  33. package/templates/sections/features.html +32 -0
  34. package/templates/sections/hero.html +27 -0
  35. package/templates/sections/logos.html +15 -0
  36. package/templates/sections/pricing.html +51 -0
  37. package/templates/sections/prose.html +36 -0
  38. package/templates/sections/quote.html +13 -0
  39. package/templates/sections/showcase.html +25 -0
  40. package/templates/sections/split.html +27 -0
  41. package/templates/sections/stats.html +26 -0
  42. package/templates/sections/steps.html +17 -0
  43. package/website.css +1274 -0
  44. package/website.min.css +1 -0
package/AGENTS.md ADDED
@@ -0,0 +1,191 @@
1
+ # @gemboss/website-ui: read this before you build or change a page
2
+
3
+ You are building a public website for a GemCommerce brand (GemBoss, GemPages, Gemians…) with this kit. The people
4
+ asking you are often not designers. The kit is how their site ends up looking like it was made by a careful design
5
+ team: **use the kit, follow the rules below, and when the kit is missing something, report it instead of inventing
6
+ it.** Everything here applies to every page, in every language.
7
+
8
+ Files you will use, all inside `node_modules/@gemboss/website-ui/`:
9
+
10
+ | file | what it is |
11
+ |---|---|
12
+ | `website.css` | the whole kit, one file (tokens, base, layout, components, sections) |
13
+ | `js/website.js` | header, mega menu, mobile menu, theme toggle, scroll reveal, segmented control, busy buttons; no dependencies |
14
+ | `system.json` | every value of the system: colours, spacing, type, radii, shadows, widths |
15
+ | `templates/page.html` | the page skeleton: start every new page from it |
16
+ | `templates/sections/*.html` | ready sections: hero, features, split, showcase, logos, stats, steps, pricing, FAQ, CTA, prose… |
17
+ | `demo/index.html` | every component on one page: open it to see what exists before you build anything |
18
+ | `docs/components.md` | every class, what it is for, its variants |
19
+ | `docs/theming.md` | how a brand other than GemBoss sets its accent and logo, and what it must not change |
20
+
21
+ ## 1. The ten rules
22
+
23
+ 1. **Compose, do not invent.** A page is the page skeleton plus kit sections plus your words. Look in `demo/` and
24
+ `docs/components.md` first. A new class is a last resort (section 9).
25
+ 2. **White canvas, ink actions, one accent.** The background is white (`--gw-bg`). The thing you click is near-black
26
+ (`.gw-btn`). The accent colour is for links, focus, the active item, the 8px label square and a chart line. **The
27
+ accent is never a button fill and never body text.**
28
+ 3. **Actions are rectangles, chips are pills.** Buttons: radius 8px, 40px tall, sentence case, 14px/600. Chips,
29
+ toggles, badges: fully rounded. Cards: radius 12px (16px for a large panel). No other radii.
30
+ 4. **A card sits.** A card (`.gw-card`, a plan) is a white box with a 1px `--gw-line` border and the resting shadow
31
+ `--gw-shadow`, the same as the GemBoss dashboard. It never lifts on hover. To separate anything else, use space or a
32
+ hairline before a shadow. The only shadows are `--gw-shadow` (rest), `--gw-shadow-sm` and `--gw-shadow-raised`
33
+ (popovers: the mega menu, menus).
34
+ 5. **Only the scales.** Spacing: 0 2 4 6 8 12 16 20 24 32 40 48 64 80 96 120 (px). Type: 11 12 13 14 16 18 20 22 24 30,
35
+ plus the two display sizes for h1/h2. No half pixels, no "just 15px", no colour outside the tokens.
36
+ 6. **Sentence case everywhere.** Headings, buttons, labels, menu items. No uppercase with letter spacing.
37
+ 7. **One idea per section, one primary action per view.** A section has a short label, a headline, at most two
38
+ lines under it, then the content. One `.gw-btn` per section; the second action is `.gw-btn--secondary` or a link.
39
+ 8. **Real words, real facts.** No lorem ipsum, no invented numbers, customers, logos, reviews or quotes. Missing
40
+ facts become a visible placeholder like `[PRICE]` and a question to the person (section 6). A drawn mock-up may
41
+ show made-up numbers only with the caption `<p class="gw-window__caption">Illustrative data.</p>` in its window.
42
+ 9. **It must work at 320px.** Check every page at 320, 390, 768 and 1366px wide. Nothing scrolls sideways, no text
43
+ is clipped, every tap target is at least 44px.
44
+ 10. **Run the check before you say "done".** `npx gemboss-website check` (section 10).
45
+
46
+ ## 2. Build a page
47
+
48
+ 1. Copy `templates/page.html` into the site. It links `website.css` and `website.js`, has the skip link, the
49
+ header, the `<main>` and the footer. Fill the header and footer once (they are the same on every page).
50
+ 2. Pick sections from `templates/sections/` in the order the page needs. A typical page: hero → proof (logos or
51
+ stats) → 2 to 4 feature sections → one showcase or split → FAQ → final CTA. Not every page needs every section;
52
+ fewer, clearer sections beat more. A page that is read rather than scanned (a blog post, docs, terms, privacy) is
53
+ the prose section: the article's own HTML inside `.gw-prose`, no classes and no site CSS for its type.
54
+ 3. Write the copy (section 6), then delete what you did not use. Do not leave empty slots or sample text.
55
+ 4. Images: real product screens or photos the brand owns. Give every `<img>` a real `alt` (or `alt=""` when it is
56
+ decoration), `width`, `height`, and `loading="lazy"` below the first screen.
57
+ 5. Run the check, open the page at 320px and 1366px, fix, then hand it over.
58
+
59
+ ## 3. The system in short (values: `system.json`)
60
+
61
+ - **Colour roles** (CSS variables, light and dark): `--gw-bg`, `--gw-bg-soft` (the neutral raised fill),
62
+ `--gw-surface`, `--gw-ink`, `--gw-ink-2`, `--gw-muted`, `--gw-line`, `--gw-line-strong`, `--gw-action`,
63
+ `--gw-on-action`, `--gw-accent`, `--gw-accent-strong`, `--gw-accent-soft`, `--gw-success`, `--gw-warning`,
64
+ `--gw-night` (the dark band). Wash hues `--gw-wash-pink|violet|sky|mint` exist for the hero wash and illustrations only.
65
+ - **Dark mode** follows the visitor's system and the theme toggle (`data-theme` on `<html>`). Use the variables and
66
+ it works; a hard-coded colour breaks it.
67
+ - **Accent as text** (links, the active menu item, step numbers) is `--gw-accent-strong`; the plain accent is for
68
+ the label square, the focus ring, check marks and borders. Night bands switch to the dark palette by themselves.
69
+ - **Controls** are 40px tall on desktop and at least 44px on touch screens; `.gw-btn--sm` is 36px with a 46px hit area on desktop and 44px tall on touch screens.
70
+ - **A button that waits** (a form sent, an audit started) gets `aria-busy="true"` from the page's script until the
71
+ answer comes: the kit keeps its label and width, draws the ring and ignores a second press. Nothing else: no
72
+ `disabled`, no loading class, no spinner of your own, no "Loading…" label.
73
+ - **One choice out of two to four** (Monthly / Yearly) is `.gw-segmented`, a radio group; what each option shows
74
+ carries `data-gw-show="group:value"`. Markup: `docs/components.md`, `templates/sections/pricing.html`.
75
+ - **Type**: Inter. Headings weight 650, tracking −0.022em; display h1/h2 weight 600, tracking −0.03em. Body 18px,
76
+ line height 1.6. The house headline shape: a muted first sentence, an ink second one
77
+ (`<h2><span class="gw-dim">Two builders.</span> One engine underneath.</h2>`).
78
+ - **Layout**: content sits in `.gw-wrap` (1120px max, 22px gutters) or `.gw-wrap--narrow` (780px). Sections use
79
+ `.gw-section` and get their vertical rhythm from `--gw-space-section`. Grids: `.gw-grid--2|3|4` collapse to one
80
+ column on phones.
81
+ - **Night bands** (`.gw-band--night`): at most three on a page plus the closing CTA, never two in a row; everything
82
+ else on white or `--gw-bg-soft`.
83
+ - **Motion**: only `transform` and `opacity`, the kit's ease, nothing moves under `prefers-reduced-motion`. Scroll
84
+ reveal is `.gw-reveal` (the JS adds `.is-in`, and a failsafe shows it anyway).
85
+
86
+ ## 4. Don't (each of these has happened, and each one made a page look cheap or broke it)
87
+
88
+ - Don't fill a button with the accent colour, a gradient or a wash hue.
89
+ - Don't use uppercase labels with letter spacing ("FEATURES").
90
+ - Don't add shadows beyond the three tokens, and don't lift cards on hover.
91
+ - Don't round a button into a pill, and don't square a chip.
92
+ - Don't use cream, beige or grey page backgrounds; white or `--gw-bg-soft` only.
93
+ - Don't use colours, sizes, spacings or radii outside the tokens and scales.
94
+ - Don't put a floating, blurred, rounded "pill" header on the page; the header is a flat bar with one hairline.
95
+ - Don't tuck the hero under the header with a negative margin.
96
+ - Don't use emoji as icons; use inline stroke SVG (1.7–2px stroke, `currentColor`, `aria-hidden="true"`).
97
+ - Don't use gradient washes behind body text, glassmorphism on chrome, or neon glows.
98
+ - Don't put two primary buttons side by side.
99
+ - Don't write "Click here", "Learn more" as the only words of a link; say where it goes.
100
+ - Don't use the em dash (—) in visible text. Use a comma, a colon or a full stop.
101
+ - Don't invent numbers, customer names, logos, testimonials, ratings, awards or certifications.
102
+ - Don't write fake numbers on a mock-up without the caption "Illustrative data." under it, and don't reword it.
103
+ - Don't style an article's headings, lists or code in site CSS; wrap the article in `.gw-prose`.
104
+ - Don't animate layout properties (width, height, top, margin), and don't autoplay motion that cannot be stopped.
105
+ - Don't ship a page you have not seen at 320px.
106
+ - Don't write CSS that overrides a `.gw-*` class to change how it looks. If the kit's version is wrong for you,
107
+ that is a gap (section 9).
108
+
109
+ ## 5. Accessibility
110
+
111
+ - Text contrast at least 4.5:1 (3:1 for 24px and above). The tokens pass; a custom colour may not.
112
+ - Every interactive thing is a real `<a href>` or `<button>`. Never a clickable `<div>`.
113
+ - Focus stays visible (the kit draws it with the accent). Do not remove outlines.
114
+ - Tap targets at least 44×44px, with at least 8px between neighbours.
115
+ - One `<h1>` per page, headings in order, landmarks (`header`, `nav`, `main`, `footer`), and the skip link kept.
116
+ - Icon-only buttons get `aria-label`. Decorative SVG gets `aria-hidden="true"`.
117
+ - Loading is `aria-busy="true"` on the button, with its label kept; when the wait ends, say what happened in words
118
+ (a `.gw-note` or a `role="status"` line). Under `prefers-reduced-motion` the kit's ring stands still.
119
+ - A single choice is a radio group (`.gw-segmented`): one Tab stop, the arrows move and choose. Never a row of
120
+ `aria-pressed` buttons for it.
121
+
122
+ ## 6. Words
123
+
124
+ - Write for the reader of the page: what it does for them, in their words, short sentences. Lead with the outcome,
125
+ then how.
126
+ - **Claims**: say only what the product does today. Every number needs a source the person can point to. If you do
127
+ not know a fact (a price, a count, a date, a customer), write a visible placeholder (`[PRICE]`) and ask.
128
+ - Product names, plan names and prices are written exactly as the brand writes them.
129
+ - Domains in the text are the brand's own; never a made-up example brand that looks real.
130
+ - Do not name or quote internal tools or internal data on a public page.
131
+ - Made-up numbers in a drawn mock-up: `.gw-window__caption` says exactly "Illustrative data." (vi: "Dữ liệu minh
132
+ hoạ.", zh: "示意数据。"), plus one sentence only when a demo brand needs naming ("Vital Glow is a GemBoss demo
133
+ brand."). Real numbers in a window: the caption names their source.
134
+ - Image sources: record where each image comes from (the brand's own screen, a licensed photo). No photos of real
135
+ people or other brands' logos without permission.
136
+ - Other languages: rewrite each page for its reader (transcreation), do not translate sentence by sentence. Facts
137
+ (prices, numbers, names, links, claims) stay identical. Labels inside buttons, chips and pills must not grow much
138
+ longer than the English, or they overflow on phones.
139
+
140
+ ## 7. Theming for another brand
141
+
142
+ A brand other than GemBoss changes **only**: the accent family, the wash hues, the logo in the header and footer, and
143
+ the favicon. The accent family is eight variables set in one `:root {}` block after the kit:
144
+ `--gw-accent-light`, `--gw-accent-strong-light`, `--gw-accent-soft-light`, `--gw-on-accent-light` and the same four
145
+ ending in `-dark`. Do not set `--gw-accent` itself: the kit points it at those per theme, and a direct override loses
146
+ as soon as the theme toggle is pressed. Accent text (links, the active menu item) uses `--gw-accent-strong`, so a new
147
+ accent-strong must reach 4.5:1 on both `--gw-bg` and `--gw-bg-soft`. A brand does not change the shapes, the scales,
148
+ the ink action, the white canvas or the type. Recipe and checks: `docs/theming.md`; a working example:
149
+ `demo/theme-example.html`.
150
+
151
+ ## 8. Where things go in a consuming site
152
+
153
+ - Link the kit, then the site's own CSS after it: `website.css` → `site.css`.
154
+ - The site's own CSS is for content the kit cannot know (an illustration, a product mock-up) and uses only the
155
+ tokens. Its classes start with the site's prefix (for example `gp-` on GemPages), never `gw-`.
156
+ - Shared header and footer markup lives in one place in the site (a partial or component), not copied per page.
157
+
158
+ ## 9. When the kit is missing something
159
+
160
+ The kit is young; it will not have everything. When a page needs something it does not have:
161
+
162
+ 1. **Is it really missing?** Look in `demo/index.html` and `docs/components.md`. Can two existing pieces together do
163
+ it (a grid of cards, a split with a list)? Can a variant do it? If yes, use that.
164
+ 2. **Is it a kit thing or a page thing?** A kit thing is reusable by other pages and other brands: a section shape,
165
+ a component, a token, a behaviour. A one-off illustration or a product mock-up is a page thing: build it in the
166
+ site's own CSS with the tokens, and stop here.
167
+ 3. **Build a stopgap in the site, not in the kit.** Put it in one file, `kit-gaps.css` (and `kit-gaps.js` if it needs
168
+ behaviour), with classes prefixed `kitgap-`, using only the kit's tokens and scales, and a comment naming the gap.
169
+ Never edit files inside `node_modules`, and never override `.gw-*` classes.
170
+ 4. **Report it.** Run `npx gemboss-website gap` and answer its questions (or pass `--title`, `--need`, `--page`,
171
+ `--kind`, `--stopgap kit-gaps.css`). It opens an issue in the kit's repository with everything the kit team needs,
172
+ or, when GitHub is not available, writes `kit-gaps/<name>.md` for the person to send. Tell the person you did it.
173
+ 5. **When the kit ships it**, `npx gemboss-website upgrade` lists the gaps that are now in the kit: replace your
174
+ stopgap with the kit's class and delete the `kitgap-` code.
175
+
176
+ ## 10. Check before you hand it over
177
+
178
+ ```sh
179
+ npx gemboss-website check # every .html and .css in the site against the rules above
180
+ npx gemboss-website check --fix-list # the same, as a to-do list
181
+ ```
182
+
183
+ It reports colours, radii, spacing and type outside the system, shadows on chrome, accent-filled buttons, uppercase
184
+ labels, em dashes in visible text, images without `alt`, overrides of `.gw-*` classes, a waiting button not marked
185
+ with `aria-busy`, a segmented control without its radio-group markup, a drawn mock-up with numbers and no caption, and
186
+ patterns that repeat across pages (likely gaps). It does not replace looking at the page at 320px and 1366px.
187
+
188
+ ## 11. Upgrading the kit
189
+
190
+ `npx gemboss-website upgrade` shows what changed since the version the site has (from `CHANGELOG.md`), the gaps that
191
+ were closed, and the exact command to install the new version. Read it, upgrade, run the check, look at the pages.
package/CHANGELOG.md ADDED
@@ -0,0 +1,47 @@
1
+ # Changelog
2
+
3
+ Every release lists what changed for a site that uses the kit. A release that adds what a site reported as missing
4
+ says so with `Closes gap #N` (the GitHub issue number), so `npx gemboss-website upgrade` can tell that site which
5
+ stopgap (`kitgap-*`) it can now delete.
6
+
7
+ ## 0.2.0 (2026-10-25)
8
+
9
+ Four gaps reported while the GemBoss Design System was written. Markup that worked in 0.1.0 still works.
10
+
11
+ - Buttons: a pressed state (`:active`: the ink one step darker, nothing moves) and a loading state
12
+ (`aria-busy="true"` on the `<button>`: the label keeps the width and the accessible name, a 16px ring in the
13
+ button's own ink, a still ellipsis under reduced motion). `website.js` ignores presses on a busy button, so a form
14
+ is not sent twice. Replace a `kitgap-` spinner or loading class with `aria-busy`.
15
+ Closes gap #25 (button pressed and loading states)
16
+ - Segmented control `.gw-segmented` (+ `--block`): one choice out of two to four, a radio group (one Tab stop, the
17
+ arrow keys move and choose) with the dashboard's look, the chosen option on the accent tint. Content for one
18
+ option carries `data-gw-show="group:value"`; `website.js` shows it and fires `gw:segmented`.
19
+ `templates/sections/pricing.html` now has the monthly / yearly control. A `kitgap-segmented` group of
20
+ `aria-pressed` buttons becomes `role="radiogroup"` with `role="radio"` options (docs/components.md).
21
+ Closes gap #27 (segmented control, pricing monthly / yearly)
22
+ - `.gw-window__caption`: what the numbers in a window are, 12px muted at the end of the window. Under a drawn
23
+ mock-up it says "Illustrative data." (vi: "Dữ liệu minh hoạ.", zh: "示意数据。"); under real numbers, their source.
24
+ The hero, split and showcase templates carry it.
25
+ Closes gap #32 (illustrative data caption for mock-ups)
26
+ - `.gw-prose` (+ `--sm` for docs and legal): long-form reading. The article's own HTML needs no classes: headings,
27
+ paragraphs, lists, quotes, inline and block code, tables that scroll inside their own box, images and captions,
28
+ all on the kit's scales. New `templates/sections/prose.html`.
29
+ Closes gap #46 (long-form prose styles)
30
+ - `check`: `busy-button` and `segmented-markup` (errors), `illustrative-caption` (a warning: a drawn window with
31
+ numbers and no caption).
32
+ - Tokens: `--gw-font-mono` and `--gw-spin-ms` (`type.mono` and `motion.spin_ms` in `system.json`).
33
+ - `website.js` 0.2.0, about 9 KB. `AGENTS.md` and the skill say when to use the four new parts.
34
+
35
+ ## 0.1.0 (2026-10-24)
36
+
37
+ The foundation.
38
+
39
+ - `website.css`: tokens (light and dark, from `system.json`), base type, layout, buttons, links, labels, chips,
40
+ badges, cards, window frame, tables, FAQ, header with mega menu and mobile menu, footer, and the sections hero,
41
+ logos, stats, features, split, showcase, steps, quote, pricing and CTA.
42
+ - Cards and plans carry the dashboard's resting shadow; the mega menu is a floating card under the bar (as on
43
+ gemboss.ai); night bands: at most three per page plus the closing CTA.
44
+ - `website.js`: mega menu, mobile menu, theme toggle, scroll reveal, current-page marking.
45
+ - `AGENTS.md`: the rules every page follows (what to use, what never to do, words, accessibility, theming, gaps).
46
+ - `templates/`: the page skeleton and one snippet per section. `demo/`: every component on one page.
47
+ - CLI `gemboss-website`: `init` (CLAUDE.md block + Claude Code skill), `check`, `gap`, `upgrade`.
package/README.md CHANGED
@@ -1,3 +1,119 @@
1
- # Temporary Holding Version
1
+ # @gemboss/website-ui
2
2
 
3
- This version is a temporary placeholder for this package. An operational version to replace this has been submitted for review and is awaiting a staged release.
3
+ **The website kit of GemCommerce.** Tokens, header with mega menu, footer, sections and the design rules that public
4
+ websites built by GemCommerce teams share, plus a CLI that checks a site, reports what the kit is missing and upgrades
5
+ it. Made so that a team working with Claude Code, even without a designer, ships pages that look like one family.
6
+
7
+ > Bộ kit website của GemCommerce: token, header kèm mega menu, footer, các section và luật thiết kế mà mọi website
8
+ > công khai của các team GemCommerce (GemBoss, GemPages, Gemians…) dùng chung, kèm một CLI kiểm site, báo chỗ kit còn
9
+ > thiếu và nâng cấp. Viết để một team làm việc với Claude Code, kể cả không có designer, vẫn ra trang đúng một họ.
10
+
11
+ ## Có gì trong gói
12
+
13
+ | | |
14
+ |---|---|
15
+ | `website.css`, `website.min.css` | toàn bộ kit trong một tệp (khoảng 49 KB, 38 KB bản min): token sáng và tối, chữ, bố cục, nút (cả trạng thái nhấn và đang chờ), link, nhãn, chip, segmented control, badge, card, khung cửa sổ kèm chú thích "Illustrative data.", bảng, FAQ, chữ bài dài (`.gw-prose`), header + mega menu + menu điện thoại, footer, 12 section |
16
+ | `js/website.js` | mega menu, menu điện thoại, đổi giao diện sáng/tối, hiện dần khi cuộn, đánh dấu trang hiện tại, segmented control, chặn bấm lần hai khi nút đang chờ; không phụ thuộc thư viện nào, khoảng 9 KB |
17
+ | `AGENTS.md` | luật mà Claude Code (và người) phải theo: 10 luật, cách dựng trang, điều cấm, chữ, khả năng truy cập, đổi thương hiệu, khi kit thiếu |
18
+ | `templates/` | khung một trang và 12 section (hero, logos, stats, features, split, showcase, steps, quote, pricing, faq, cta, prose) |
19
+ | `demo/` | mọi thành phần trên một trang; `theme-example.html` cho thấy một thương hiệu khác đổi màu nhấn |
20
+ | `docs/` | danh mục class (`components.md`), đổi thương hiệu (`theming.md`), triết lý (`philosophy.md`), hợp đồng markup |
21
+ | `system.json` | mọi giá trị của hệ thống (màu, khoảng cách, chữ, bo góc, bóng, khung): nguồn duy nhất |
22
+ | CLI `gemboss-website` | `init`, `check`, `gap`, `upgrade` |
23
+
24
+ Cần Node 18 trở lên cho CLI. CSS và JS chạy trên mọi trình duyệt hiện đại, không cần bước build.
25
+
26
+ ## Cài đặt
27
+
28
+ ```sh
29
+ npm install @gemboss/website-ui # hoặc: pnpm add @gemboss/website-ui / yarn add @gemboss/website-ui
30
+ npx gemboss-website init # nối luật của kit vào Claude Code của dự án (xem bên dưới)
31
+ ```
32
+
33
+ `init` thêm một khối vào `CLAUDE.md` của dự án (giữa hai dấu `<!-- @gemboss/website-ui:start/end -->`, không đụng chữ
34
+ khác) và cài skill `.claude/skills/gemboss-website-ui/SKILL.md`. Từ đó, mỗi lần bạn nhờ Claude Code làm một trang,
35
+ nó đọc `AGENTS.md` của kit trước, dựng từ mẫu, và chạy `check` trước khi báo xong. Claude Code không tự đọc tệp trong
36
+ `node_modules`, nên bước này là cần thiết.
37
+
38
+ ## Dùng trên trang
39
+
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
+
42
+ ```html
43
+ <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@gemboss/website-ui@0.2.0/website.min.css">
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.2.0/js/website.js" defer></script>
46
+ ```
47
+
48
+ **Next.js (App Router):** nạp CSS trong layout gốc, nạp script bằng `next/script`.
49
+
50
+ ```js
51
+ // app/layout.js
52
+ import "@gemboss/website-ui/website.css";
53
+ import "./site.css";
54
+ import Script from "next/script";
55
+
56
+ export default function RootLayout({ children }) {
57
+ return (
58
+ <html lang="vi">
59
+ <body className="gw-page">
60
+ {children}
61
+ <Script src="/kit/website.js" strategy="afterInteractive" />
62
+ </body>
63
+ </html>
64
+ );
65
+ }
66
+ ```
67
+
68
+ Chép `node_modules/@gemboss/website-ui/js/website.js` vào `public/kit/` (hoặc phục vụ nó bằng một route). Font Inter
69
+ nạp từ Google Fonts như trong `templates/page.html`.
70
+
71
+ **Bắt đầu một trang:** chép `templates/page.html`, điền header và footer một lần (chung cho mọi trang), ghép các
72
+ section trong `templates/sections/` theo thứ tự trang cần, thay mọi chỗ `[trong ngoặc]`, xoá phần không dùng. Mở
73
+ `demo/index.html` để xem kit có gì trước khi tự viết bất cứ thứ gì.
74
+
75
+ ## Thương hiệu khác GemBoss
76
+
77
+ Một thương hiệu chỉ đổi màu nhấn (8 biến cho sáng và tối), màu wash, logo và favicon, trong một khối `:root {}` đặt
78
+ sau kit. Hình dạng, thang, nút màu mực, nền trắng và kiểu chữ giữ nguyên. Công thức và các phép kiểm tương phản:
79
+ `docs/theming.md`; ví dụ chạy được: `demo/theme-example.html`.
80
+
81
+ ## Lệnh
82
+
83
+ | lệnh | làm gì |
84
+ |---|---|
85
+ | `npx gemboss-website init` | nối luật của kit vào Claude Code của dự án (CLAUDE.md + skill) |
86
+ | `npx gemboss-website check` | kiểm mọi `.html` và `.css` của site: màu, khoảng cách, chữ, bo góc ngoài thang, bóng, nút tô màu nhấn, nhãn viết hoa giãn chữ, đè class `gw-`, dấu gạch dài, ảnh thiếu `alt`, link mơ hồ… và gợi ý chỗ kit có thể đang thiếu |
87
+ | `npx gemboss-website gap` | báo một chỗ kit còn thiếu: mở GitHub Issue ở repo của kit (nếu `gh` đã đăng nhập và có quyền), không thì ghi `kit-gaps/<tên>.md` để gửi |
88
+ | `npx gemboss-website upgrade` | so bản đang dùng với bản mới nhất, in thay đổi, gap đã có trong kit, và lệnh nâng cấp |
89
+
90
+ `check` thoát mã 1 khi có lỗi, nên chạy được trong CI của site:
91
+ `npx gemboss-website check --ignore vendor/`.
92
+
93
+ ## Khi kit thiếu thứ bạn cần
94
+
95
+ Đừng đè class `gw-` hay sửa tệp trong `node_modules`. Làm tạm trong site (`kit-gaps.css`, class `kitgap-`, chỉ dùng
96
+ token và thang), rồi `npx gemboss-website gap`. Khi một bản kit mới có thứ đó, CHANGELOG ghi `Closes gap #N` và
97
+ `upgrade` nhắc bạn xoá phần làm tạm. Quy trình đầy đủ: `AGENTS.md` mục 9.
98
+
99
+ ## Phiên bản
100
+
101
+ Semver. Ở 0.x, bản minor có thể đổi markup (đọc CHANGELOG trước khi nâng), bản patch thì an toàn. Ghim đúng phiên bản
102
+ khi dùng CDN.
103
+
104
+ ## Dành cho team GemCommerce
105
+
106
+ Tài liệu GemBoss Design System đầy đủ (triết lý, nền tảng, thành phần, mẫu trang, thương hiệu, quản trị) nằm ở cổng
107
+ tài liệu nội bộ docs.gemboss.ai (đăng nhập bằng GemBoss). Mã nguồn của kit: `packages/website-ui` trong repo
108
+ gemboss-www; mọi thay đổi đi qua PR, giá trị của hệ thống chỉ sửa ở `system.json`.
109
+
110
+ ```sh
111
+ cd packages/website-ui
112
+ node scripts/build.mjs # sinh css/tokens.css từ system.json, ghép website.css và website.min.css
113
+ node test/run.mjs # tự kiểm CLI
114
+ node scripts/gate-demo.mjs # cổng thị giác và khoảng thở của gemboss.ai trên demo (cần .ci của repo)
115
+ ```
116
+
117
+ Phát hành: tăng `version`, thêm mục CHANGELOG (kèm `Closes gap #N`), rồi gắn tag `website-ui-vX.Y.Z`. GitHub Actions
118
+ đưa bản đó lên npm ở dạng CHỜ DUYỆT (`npm stage publish`, Trusted Publishing, không có token nào); bản chỉ ra công
119
+ khai khi một maintainer duyệt bằng passkey trên npmjs.com (hoặc `npm stage approve <id>`).
@@ -0,0 +1,78 @@
1
+ #!/usr/bin/env node
2
+ // gemboss-website: the CLI of @gemboss/website-ui. How a site's Claude Code follows the kit's rules (init, check),
3
+ // reports what the kit is missing (gap) and upgrades (upgrade). Node >= 18, no dependencies.
4
+ import { PKG, UsageError } from "./lib/util.mjs";
5
+
6
+ export const USAGE = `gemboss-website (${PKG.name} ${PKG.version})
7
+
8
+ Usage: npx gemboss-website <command> [options] (run it in the site's root folder)
9
+
10
+ Commands
11
+ init [--force]
12
+ Add or refresh the kit's block in CLAUDE.md (between <!-- ${PKG.name}:start/end --> markers;
13
+ text outside them is never touched) and install the Claude Code skill
14
+ .claude/skills/gemboss-website-ui/SKILL.md (replaced only if init wrote it, or with --force).
15
+
16
+ check [paths...] [--json] [--fix-list] [--ignore <path>]... [--include-kit]
17
+ Check every .html/.htm/.css (and <style>, style="") under the paths (default: here) against
18
+ the kit's rules: colours, radii, type and spacing outside the scales, half pixels, shadows,
19
+ uppercase labels, accent-filled buttons, overrides of .gw-* classes, em dashes, images without
20
+ alt, vague links, h1 count, <html lang>, clickable divs. Notes list likely gaps (a site class on
21
+ 3+ pages) and open kitgap-* stopgaps. Skips node_modules, dist, build, out, coverage, dot-folders
22
+ and the kit's own files. Exit 1 when there is an error, 0 otherwise.
23
+ --json machine-readable findings
24
+ --fix-list the findings as a markdown to-do list
25
+ --ignore skip a file or folder (repeatable), e.g. third-party CSS
26
+ --include-kit also check the kit's own HTML (templates, demo): for the kit's own CI
27
+
28
+ gap [--title ...] [--need ...] [--kind token|component|section|behavior|doc|other]
29
+ [--page <url>] [--site ...] [--why ...] [--shape ...] [--stopgap <file>]
30
+ [--screenshot <path-or-url>] [--dry-run]
31
+ Report something the kit is missing. Asks for missing answers in a terminal; without one,
32
+ --title and --need are required. With gh signed in, opens an issue in ${(PKG.gemboss && PKG.gemboss.gapRepo) || "the kit's repo"};
33
+ otherwise (or with --dry-run, which never touches the network) writes kit-gaps/<slug>.md
34
+ and prints how to send it.
35
+
36
+ upgrade
37
+ Installed vs latest version, the CHANGELOG sections in between, the gaps they close, the
38
+ project's kitgap-* stopgaps that name those gaps, and the install command.
39
+
40
+ help
41
+ This text.
42
+
43
+ Environment (tests and offline use)
44
+ GEMBOSS_WEBSITE_CHANGELOG=<file> upgrade reads this changelog instead of the kit's CHANGELOG.md
45
+ GEMBOSS_WEBSITE_LATEST=<version> upgrade uses this as the latest version instead of asking npm
46
+ GEMBOSS_WEBSITE_OFFLINE=1 upgrade does not ask npm
47
+ GEMBOSS_WEBSITE_GH=<path> gap runs this instead of gh
48
+ NO_COLOR=1 no colours in the output
49
+
50
+ Rules: node_modules/${PKG.name}/AGENTS.md`;
51
+
52
+ async function main(argv) {
53
+ const [cmd, ...rest] = argv;
54
+ switch (cmd) {
55
+ case undefined: case "help": case "--help": case "-h":
56
+ console.log(USAGE);
57
+ return 0;
58
+ case "--version": case "-v": case "version":
59
+ console.log(PKG.version);
60
+ return 0;
61
+ case "init": return (await import("./lib/init.mjs")).cmdInit(rest);
62
+ case "check": return (await import("./lib/check.mjs")).cmdCheck(rest);
63
+ case "gap": return (await import("./lib/gap.mjs")).cmdGap(rest);
64
+ case "upgrade": return (await import("./lib/upgrade.mjs")).cmdUpgrade(rest);
65
+ default:
66
+ throw new UsageError(`unknown command "${cmd}"`);
67
+ }
68
+ }
69
+
70
+ main(process.argv.slice(2)).then((code) => { process.exitCode = code; }, (err) => {
71
+ if (err instanceof UsageError) {
72
+ console.error(`gemboss-website: ${err.message}\nRun "npx gemboss-website help" for usage.`);
73
+ process.exitCode = 2;
74
+ } else {
75
+ console.error(err && err.stack ? err.stack : err);
76
+ process.exitCode = 3;
77
+ }
78
+ });