@gemboss/website-ui 0.10.0 → 0.12.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.
@@ -13,15 +13,16 @@ default `tight` profile, and `soft` makes them 12 / 20 / 24; "ink fill" is the d
13
13
  `data-gw-action="accent"` makes it the accent.
14
14
 
15
15
  Spacing between the children of text blocks is automatic: inside `.gw-section__head`, the hero, a split column,
16
- `.gw-cta`, `.gw-card`, `.gw-feature` and `.gw-plan`, each child is 16px below the previous one, a `.gw-actions` row
17
- 32px, a `.gw-list--check` 24px. Do not add margins to fix rhythm; reorder or remove content instead.
16
+ `.gw-cta`, `.gw-card`, `.gw-feature` and `.gw-plan`, each child is 16px below the previous one, a `.gw-lead` under a
17
+ heading 20px (16px in the hero), a `.gw-actions` row 32px, a `.gw-list--check` 24px. Do not add margins to fix rhythm;
18
+ reorder or remove content instead.
18
19
 
19
20
  ## Page
20
21
 
21
22
  | class | for |
22
23
  |---|---|
23
24
  | `.gw-page` | on `<body>`: the footer stays at the bottom of a short page |
24
- | `.gw-skip` | the first element in `<body>`: "Skip to content", visible only on keyboard focus |
25
+ | `.gw-skip` | the first element in `<body>`: "Skip to content", visible only on keyboard focus (an accent tab from the top left corner) |
25
26
 
26
27
  ```html
27
28
  <body class="gw-page">
@@ -60,11 +61,11 @@ copies of the script and expect both to work (the first owns the page).
60
61
 
61
62
  | class | for |
62
63
  |---|---|
63
- | `h1`, `h2` (and `.gw-h1`, `.gw-h2`) | display sizes: h1 `clamp(40px, 4.6vw, 68px)`, h2 `clamp(32px, 3.4vw, 52px)`, weight 600, tracking −0.03em |
64
- | `h3`, `h4` (and `.gw-h3`, `.gw-h4`) | 24px / 650 and 20px / 600 |
64
+ | `h1`, `h2` (and `.gw-h1`, `.gw-h2`) | display sizes: h1 `clamp(40px, 4.6vw, 68px)` at line height 1.1, h2 `clamp(32px, 3.4vw, 52px)` at 1.06, weight 600, tracking −0.03em |
65
+ | `h3`, `h4` (and `.gw-h3`, `.gw-h4`) | 20px / 600 (tracking −0.02em, line height 1.2, every h3 on gemboss.ai) and 20px / 600 |
65
66
  | `.gw-dim` | the muted first sentence of the house headline shape |
66
- | `.gw-label` | the label above a heading: 13px, muted, led by the 8px accent square |
67
- | `.gw-lead` | the one or two lines under a heading (18px, 20px in the hero, muted, max 60ch) |
67
+ | `.gw-label` | the label above a heading: 13px, muted, led by the 8px square in ink; `--gw-label-mark` paints the square (a product's own colour): `style="--gw-label-mark: var(--gw-accent)"` on the label or around it |
68
+ | `.gw-lead` | the one or two lines under a heading (18px, 20px in the hero, muted, max 58ch) |
68
69
  | `.gw-note` | a short reassurance under actions (14px, muted) |
69
70
  | `.gw-link` | an inline link in the accent, underlined |
70
71
  | `.gw-link--arrow` | a standalone "go there" link with a → that moves 2px on hover |
@@ -92,7 +93,7 @@ Don't: uppercase or letter-spaced labels; a label longer than a few words; the a
92
93
  | `.gw-section` | a section's vertical rhythm (`--gw-space-section`) |
93
94
  | `.gw-section--soft` | on `--gw-bg-soft`, to separate a section without a line |
94
95
  | `.gw-section--tight` | less padding (40px, 64px from 768px), for proof strips and follow-on tables |
95
- | `.gw-section__head` | label + h2 + lead, max 660px; 40–48px above the content |
96
+ | `.gw-section__head` | label + h2 + lead, max 760px; the content after it starts 40px below (48px from 768px), unless it brings its own top margin |
96
97
  | `.gw-section__head--center` | the same, centred |
97
98
  | `.gw-grid`, `.gw-grid--2`, `.gw-grid--3`, `.gw-grid--4` | equal columns: one on phones; 2 and 3 from 768px; 4 is 2 from 480px and 4 from 1080px |
98
99
  | `.gw-actions` | a row of actions that wraps; on phones the hero and CTA buttons go full width |
@@ -118,8 +119,11 @@ Don't: more than three night bands on a page (the closing CTA does not count), o
118
119
  brand's accent with `--gw-on-accent` words under `data-gw-action="accent"` (one colour on the whole site). Variants: `--secondary` (hairline, transparent), `--ghost`
119
120
  (no frame), `--on-night` (light fill for a dark surface that is not a `.gw-band--night`), `--danger` (0.6.0: the
120
121
  danger fill with `--gw-on-danger` words, for the action of a page that destroys something: delete a workspace, erase
121
- my data), `--sm` (36px, with a 44px hit area), `--lg` (48px, 16px type), `--block` (full width). On touch screens every button is at least 44px tall and
122
- its label may wrap. Inside a night band the default button turns light by itself.
122
+ my data), `--sm` (36px, with a 44px hit area), `--lg` (48px, 16px type), `--block` (full width). On hover (0.12.0, as
123
+ gemboss.ai) the filled button rises 1px onto the rest shadow, a framed one darkens its frame; an arrow after the label
124
+ (`<span class="gw-btn__arrow">→</span>`) moves 3px. Up to 768px every button is at least 44px tall; up to 480px a label
125
+ in `<main>` may wrap. The face is `--gw-font-action` (the brand face alone, `system.json` `type.button.family`). Inside a
126
+ night band the default button turns light by itself.
123
127
 
124
128
  ```html
125
129
  <div class="gw-actions">
@@ -326,19 +330,24 @@ Don't: hide content a reader needs to decide (prices, terms) only inside a close
326
330
 
327
331
  ## Header
328
332
 
333
+ Since 0.11.0 the header is gemboss.ai's, 1:1: every value and every motion measured against the live site, pixel by
334
+ pixel, at 320 to 1920px, light and dark, every menu open, rows hovered, the keyboard's focus, the phone menu at each
335
+ level. A brand changes what it fills in and the tokens (colours, the Stage, the radius profile), never these values.
336
+
329
337
  | class | for |
330
338
  |---|---|
331
- | `.gw-announce` | optional one-sentence bar above the header, with one link |
339
+ | `.gw-announce` | optional one-sentence bar above the header, with one link, on its own ground in both themes (`color.announce`); `.gw-announce__tag` a small pill before the sentence ("New") |
332
340
  | `.gw-header` (`data-gw-header`) | the sticky, flat 64px bar with one hairline; `.is-scrolled` darkens the hairline |
333
- | `.gw-header--float` | with `.gw-header`, a brand's header profile: from 1080px the same bar as an inset card (panel radius, the surface at 85% over a blur, one hairline, the raised shadow, 16px from the top); the flat bar below 1080px; solid under `prefers-reduced-transparency` |
334
- | `.gw-header__bar` | the row inside (`.gw-wrap gw-header__bar`) |
335
- | `.gw-brand`, `__mark`, `__name` | logo (26px) and name, linking home |
336
- | `.gw-nav`, `__list`, `__item`, `__trigger`, `__link` | the desktop nav (from 1080px); `__trigger` opens a mega panel, `__link` is a plain link; `aria-current="page"` underlines it in the accent |
337
- | `.gw-mega`, `__grid`, `__col`, `__heading`, `__link`, `__icon`, `__feature` | a floating card centred under the bar (the popover radius: 20, 24 in `soft`; raised shadow, as on gemboss.ai): columns of links with an icon and one line each, and at most one feature card |
338
- | `.gw-header__actions` | theme toggle, Sign in, Book a demo, Start free, menu button |
339
- | `.gw-header__signin` | with `.gw-nav__link`: hidden below 1080px (it moves into the mobile menu) |
341
+ | `.gw-header--float` | with `.gw-header`, a brand's header profile: from 1081px the same bar as an inset card (panel radius, the surface at 85% over a blur, one hairline, the raised shadow, 16px from the top); the flat bar up to 1080px; solid under `prefers-reduced-transparency` |
342
+ | `.gw-header__bar` | the row inside: the page's wrap + 12px (1132px on GemBoss), 24px inside (6px up to 640px), 32px between its parts |
343
+ | `.gw-brand`, `__mark`, `__name` | logo (34px, its corners clipped at 8px) and name, linking home; a 44px row up to 768px |
344
+ | `.gw-nav`, `__list`, `__item`, `__trigger`, `__chev`, `__link` | the desktop nav (from 1081px), 14px weight 500, 0.005em tighter; `__trigger` is a section's link that opens its mega panel (its 12px `__chev` turns while open), `__link` a plain link; the current page (`aria-current="page"`) or section (`aria-current` on a trigger) in the accent's strong ink, weight 600 |
345
+ | `.gw-mega` (`--gw-mega-w`, `--gw-mega-pv`, `--gw-mega-cols`), `__body`, `__grid`, `__col`, `__heading`, `__link`, `__aside`, `__card`, `__art`, `__card-text`, `__go`, `__foot`, `__foot-start`, `__foot-end`, `__cta`, `__new` | 0.11.0, gemboss.ai's mega menu: a panel on one surface that morphs between panels (the popover radius, raised shadow), a caret at the open name, a pill under the hovered name, a highlight under the hovered row; columns of rows (a name and one line), the pictures beside them (`__aside`: the panel's own `__card`, a row's preview from its `<template>`), each picture on the Stage (`__art`: the deep iris ground, `--gw-stage-*`); an optional strip under it. The page behind dims and blurs (`.gw-scrim`). Script: `docs/markup-contract.md` |
346
+ | `.gw-header__actions` | Sign in, a second text action, Start free, the menu button (4px apart; the button 8px further) |
347
+ | `.gw-header__signin` | with `.gw-nav__link`: shown from 1081px (it moves into the mobile menu) |
348
+ | `.gw-header__link` | 0.11.0: with `.gw-nav__link`, a second text action (Book a demo), shown from 1181px, the first to go when the bar is tight |
340
349
  | `.gw-theme-toggle` | icon button (`data-gw-theme-toggle`), 40px, 44px on touch |
341
- | `.gw-menu-toggle`, `__open`, `__close` | the menu button below 1080px; it shows `__open` or `__close` from `aria-expanded` |
350
+ | `.gw-menu-toggle`, `__open`, `__close` | the menu button up to 1080px: 42px (44px on touch), one strong hairline on the surface, the card radius of the profile, ink while open; it shows `__open` or `__close` from `aria-expanded` |
342
351
  | `.gw-mobile-menu` | the full-height sheet under the bar (`hidden` until opened); `html.is-menu-open` locks the page |
343
352
  | `.gw-mobile-menu__group` | a `<details>` group with a `<summary>` row |
344
353
  | `.gw-mobile-menu__list`, `__link` | the links inside a group, 44px rows |
@@ -349,8 +358,8 @@ Don't: hide content a reader needs to decide (prices, terms) only inside a close
349
358
  | `.gw-mobile-menu__heading`, `__icon`, `__all` | 0.8.0, optional in a level: a muted heading over a run of links; a 32px icon tile before a link's `<b>` name and `<i>` line; the last link, to the section's own page, in the accent with its arrow |
350
359
  | `.gw-lang` (`data-gw-lang`, `hidden`), `__btn`, `__short`, `__menu`, `__link` | 0.8.0, optional: the language switcher (below): a ghost button with the globe and the current language's code, its list of the other languages |
351
360
 
352
- Header buttons: the secondary one shows from 768px, the primary one from 480px; below that they live in the mobile
353
- menu. Full markup: `templates/header.html`. See both 0.8.0 options in `demo/header.html`.
361
+ Header actions: the primary button shows from 561px, the second text action from 1181px, Sign in from 1081px; below
362
+ that they live in the mobile menu. Full markup: `templates/header.html`. See both 0.8.0 options in `demo/header.html`.
354
363
 
355
364
  ### Drill-down mobile menu (0.8.0)
356
365
 
@@ -395,7 +404,7 @@ it shows only where the page has another language and stays hidden everywhere el
395
404
  </div>
396
405
  ```
397
406
 
398
- - Two copies: one in `.gw-header__actions` (drawn from 1080px), one in the mobile menu's actions (its list opens
407
+ - Two copies: one in `.gw-header__actions` (drawn from 1081px), one in the mobile menu's actions (its list opens
399
408
  upward), each with its own list `id`. Keep `hidden` on both and the list empty: the script fills them.
400
409
  - The head is the source: one `<link rel="alternate" hreflang="…" href="…">` per language the page has (its own
401
410
  included), and `x-default` if you like (it is not listed). A `title` on a link names that language in the list.
@@ -833,10 +842,12 @@ not make public with the review; masonry or a carousel that moves by itself.
833
842
 
834
843
  | class | for |
835
844
  |---|---|
836
- | `.gw-reveal` | fades and rises 24px into place when 15% visible (the script adds `.is-in`); shown anyway after 2.5s, and still under `prefers-reduced-motion` |
845
+ | `.gw-reveal` | fades and rises 20px into place once 12% of it is in view (the script adds `.is-in`); each one after the first among its siblings waits 70ms more (at most 380ms); shown anyway after 1.6s, and still under `prefers-reduced-motion` |
846
+ | `[data-gw-count]` | inside a `.gw-reveal`: its number counts up from 0 when the reveal shows (`<span data-gw-count>$1,200+</span>`) |
837
847
 
838
- Put it on a block (a grid, a list, a window), not on each card in a grid. Don't use it on the hero or anything in
839
- the first screen, and don't animate anything but `transform` and `opacity`.
848
+ Put it on a block (a grid, a list, a window), or on each card of one grid to cascade them. Don't use it on the hero
849
+ or anything in the first screen, and don't animate anything but `transform` and `opacity`. A count is for a number
850
+ that is a measure (a total, a percentage), never for a step's ordinal ("01").
840
851
 
841
852
  ### Spotlight `data-gw-spot` (0.9.0)
842
853
 
@@ -848,7 +859,7 @@ else:
848
859
  |---|---|
849
860
  | a plan card (its one `.gw-btn` is the action) | `<div class="gw-plan" data-gw-spot>…<a class="gw-btn" href="/signup">…</a>…</div>` |
850
861
  | a link card | `<a class="gw-card gw-card--link" href="/mcp" data-gw-spot>…</a>` |
851
- | the mega menu's feature card (the Stage) | `<a class="gw-mega__feature" href="/engine" data-gw-spot>…</a>` |
862
+ | a mega menu's card (its Stage lights) | `<a class="gw-mega__card" href="/engine" data-gw-spot=".gw-mega__art">…</a>` |
852
863
  | the primary button of a night band | `<a class="gw-btn" href="/signup" data-gw-spot>Start free</a>` inside `.gw-band--night` |
853
864
  | an inner element only (the art of a card) | `<a class="gw-card gw-card--link" href="/engine" data-gw-spot=".gp-card-art"><span class="gp-card-art" aria-hidden="true"></span>…</a>` |
854
865
 
@@ -44,8 +44,8 @@ the spotlight (0.9.0). It comes in two entries built from one source
44
44
  to the page (Escape, the outside click, the busy-button guard, the system theme, the scroll) are installed once.
45
45
  - **`destroy(root = document)`** takes back what `init` wired under `root`: its listeners and its marks. An open
46
46
  mega menu or mobile menu is closed first, so an unmounted menu cannot leave the page locked.
47
- - **`version`**: `'0.10.0'`. The classic script exposes the three as `window.gwWebsite`.
48
- - **`data-gw-ready`**: on each wired element, the parts wired on it (`mega`, `menu`, `lang`, `theme`, `reveal`,
47
+ - **`version`**: `'0.12.0'`. The classic script exposes the three as `window.gwWebsite`.
48
+ - **`data-gw-ready`**: on each wired element, the parts wired on it (`mega`, on the `.gw-header` since 0.11.0, `menu`, `lang`, `theme`, `reveal`,
49
49
  `header`, `segmented`, `toc`, `table`, `fold`, `spot`). A drill-down menu is wired with its toggle (`menu`). It is a mark for people and tests, not a switch: markup copied from a live page, attribute and all,
50
50
  is still wired.
51
51
  - **One copy per page.** The first copy that runs owns the page (`window.gwWebsite`); another one (the classic
@@ -92,7 +92,7 @@ The script tells the page's own code what changed. Every event is a `CustomEvent
92
92
 
93
93
  | event | target | `detail` | fires when |
94
94
  |---|---|---|---|
95
- | `gw:mega` | the trigger (`[data-gw-mega]`) | `{ id, open }`: the panel's `id`, `true` when it opened | a panel opens or closes: click, hover, Escape, a click outside, focus leaving, a link inside, `destroy` of an open one. Moving to another menu fires a close, then an open |
95
+ | `gw:mega` | the panel's name (`.gw-nav__trigger`, or the `[data-gw-mega]` of a 0.10.0 header) | `{ id, open }`: the panel's `id`, `true` when it opened | a panel opens or closes: the pointer resting on a name or leaving it, the keyboard's focus, ArrowDown, Escape, a click on a `<button>` name, a link inside, a click outside, another panel opening (in this header or another), `destroy` of an open one. Moving to another menu fires a close, then an open |
96
96
  | `gw:theme` | `<html>` | `{ theme: 'light' \| 'dark' }`: the theme the page now shows | a press on a theme toggle; also a change of the system's scheme while the page follows it (no `data-theme`) |
97
97
  | `gw:segmented` | the group (`[data-gw-segmented]`) | `{ name, value }`: the group's name, the chosen option's `value` | the reader chooses an option (click, arrows, Home, End) |
98
98
  | `gw:menu` | the mobile menu (`.gw-mobile-menu`) | `{ open, level }`: `true` while it is open; `level` is the title of the drill-down level in view, `''` for the top level (and for a 0.7.0 menu) | the menu opens or closes (the toggle, Escape, a link inside, resizing past 1080px, `destroy` of an open one), and a drill-down menu moves to a level or back to the top. Closing from a level fires only the close (0.8.0) |
@@ -108,43 +108,59 @@ document.addEventListener('gw:menu', function (e) { if (e.detail.level) analytic
108
108
 
109
109
  ```html
110
110
  <header class="gw-header gw-header--float?" data-gw-header> <!-- --float: a brand's header profile (0.3.0) -->
111
- <div class="gw-wrap gw-header__bar">
112
- <a class="gw-brand" href="/"><img class="gw-brand__mark" src="…" alt="" width="26" height="26"><span class="gw-brand__name">GemBoss</span></a>
111
+ <div class="gw-header__bar"> <!-- 0.11.0: no .gw-wrap; the bar is wrap + 12px -->
112
+ <a class="gw-brand" href="/"><img class="gw-brand__mark" src="…" alt="" width="34" height="34"><span class="gw-brand__name">GemBoss</span></a>
113
113
  <nav class="gw-nav" aria-label="Main">
114
114
  <ul class="gw-nav__list">
115
115
  <li class="gw-nav__item">
116
- <button class="gw-nav__trigger" type="button" aria-expanded="false" aria-controls="gw-mega-product" data-gw-mega="gw-mega-product">Product</button>
117
- <div class="gw-mega" id="gw-mega-product" hidden>
118
- <div class="gw-wrap gw-mega__grid">
119
- <div class="gw-mega__col"><p class="gw-mega__heading">Build</p>
120
- <a class="gw-mega__link" href="…"><span class="gw-mega__icon" aria-hidden="true">svg</span><span><b>Title</b><i>One line</i></span></a>
116
+ <a class="gw-nav__trigger" href="/product" aria-current?="true" aria-expanded="false" aria-controls="gw-mega-product">Product <svg class="gw-nav__chev" aria-hidden="true" width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.6"><path d="M6 9l6 6 6-6"/></svg></a>
117
+ <div class="gw-mega" id="gw-mega-product" style="--gw-mega-w: 1120px; --gw-mega-pv: 380px; --gw-mega-cols?: 2" hidden>
118
+ <div class="gw-mega__body">
119
+ <div class="gw-mega__grid">
120
+ <div class="gw-mega__col"><p class="gw-mega__heading">Build</p>
121
+ <a class="gw-mega__link" href="…" data-gw-preview?="pv-funnel"><span><b>Title</b><i>One line</i></span></a>
122
+ </div>
123
+ </div>
124
+ <div class="gw-mega__aside"> <!-- optional: the pictures -->
125
+ <a class="gw-mega__card" href="…"><span class="gw-mega__art">…on the Stage…</span><span class="gw-mega__card-text"><b>Title</b><i>One line</i><span class="gw-mega__go">See it →</span></span></a>
121
126
  </div>
122
- <a class="gw-mega__feature" href="…">…</a> <!-- optional card on the right -->
123
127
  </div>
128
+ <div class="gw-mega__foot">…</div> <!-- optional strip: __foot-start, __foot-end, a.gw-mega__cta, .gw-mega__new -->
124
129
  </div>
125
130
  </li>
126
131
  <li class="gw-nav__item"><a class="gw-nav__link" href="/pricing" aria-current?="page">Pricing</a></li>
127
132
  </ul>
128
133
  </nav>
129
134
  <div class="gw-header__actions">
130
- <button class="gw-theme-toggle" type="button" data-gw-theme-toggle aria-label="Switch to dark theme">svg</button>
131
135
  <div class="gw-lang" data-gw-lang hidden> … </div> <!-- optional: the language switcher (0.8.0, below) -->
132
136
  <a class="gw-nav__link gw-header__signin" href="…">Sign in</a>
133
- <a class="gw-btn gw-btn--secondary gw-btn--sm" href="…">Book a demo</a>
137
+ <a class="gw-nav__link gw-header__link" href="…">Book a demo</a> <!-- 0.11.0: a second text action, from 1181px -->
134
138
  <a class="gw-btn gw-btn--sm" href="…">Start free</a>
135
139
  <button class="gw-menu-toggle" type="button" aria-expanded="false" aria-controls="gw-mobile-menu" data-gw-menu-toggle aria-label="Open menu">svg</button>
136
140
  </div>
137
141
  </div>
138
142
  <div class="gw-mobile-menu" id="gw-mobile-menu" data-gw-menu?="drill" hidden> …the same links as lists, and the actions… </div>
143
+ <template id="pv-funnel">…the row's preview, for the Stage…</template>
139
144
  </header>
140
145
  ```
141
146
 
142
147
  Script behaviour:
143
- - **Mega menu**: click on a trigger toggles its panel (`hidden` removed, `aria-expanded="true"`, `.is-open` on the
144
- `.gw-nav__item`). Hover opens on fine pointers after 80ms and closes 160ms after leaving item and panel. Only one
145
- open at a time on the page, across every header `init` wired. `Escape` closes and returns focus to the trigger. A
146
- click outside closes. Arrow keys are not required. Each change fires `gw:mega`.
147
- - **Mobile menu** (below 1080px the `.gw-nav` and sign-in hide, `.gw-menu-toggle` shows): the toggle flips `hidden`
148
+ - **Mega menu** (0.11.0, gemboss.ai's own, from 1081px; one record per header, the `mega` mark on the `.gw-header`):
149
+ the script marks the header `.has-mega`, takes `hidden` off the panels and keeps a closed one `inert`, and draws
150
+ `.gw-mega-surface`, `.gw-mega-caret` and `.gw-nav__pill` in the header and `.gw-scrim` in the body (all
151
+ `aria-hidden`). A section's name is a link to its page: the pointer resting on it 200ms opens its panel (90ms to
152
+ switch once one is open; a touch is ignored), the keyboard's focus opens it at once, ArrowDown opens it and puts the
153
+ focus on its first row; 350ms after the pointer leaves it closes. Open: `aria-expanded="true"`, `.is-open` on the
154
+ `.gw-nav__item`, `.is-mega-open` on the header, the scrim on; the surface takes the panel's size and place (centred
155
+ under the name, 8px inside the bar's edges) and the panels crossfade on it. A row under the pointer or the focus is
156
+ lit (`.gw-mega__hl`) and shows its preview: the `<template>` its `data-gw-preview` names, cloned once into a
157
+ `.gw-mega__card` (its title the row's, `aria-hidden`, out of the Tab order); `data-gw-preview="feature"`, the
158
+ panel's own card. A card's pictures load the first time it shows: `data-gw-bg="url"` becomes its background,
159
+ `<template data-gw-hydrate>` is added to its parent (`.is-hydrated` on both). `Escape` closes and gives the focus
160
+ back to the name; a link inside or a click outside closes. One panel open on the page, across every header. A
161
+ `<button>` name (0.10.0 markup) also opens its panel with a click and keeps it open when the pointer leaves; a click
162
+ on it again closes it. Each change fires `gw:mega`. `destroy` takes all of it back.
163
+ - **Mobile menu** (up to 1080px the `.gw-nav` and sign-in hide, `.gw-menu-toggle` shows): the toggle flips `hidden`
148
164
  on the menu its `aria-controls` names (`#gw-mobile-menu`), `aria-expanded`, `.is-menu-open` on `<html>` (the CSS
149
165
  locks scroll), and its `aria-label` (Open menu / Close menu). `Escape` closes. Resizing above 1080px closes it.
150
166
  - **Labels in other languages**: the script never writes English over a translated page. Give the toggles their
@@ -154,12 +170,18 @@ Script behaviour:
154
170
  (`gw-theme`, every access in try/catch), updates `aria-label` on every toggle, fires `gw:theme`. On load, a stored
155
171
  choice is applied before paint by a one-line inline script in `<head>` that the template carries
156
172
  (`templates/page.html`).
157
- - **Reveal**: elements with `.gw-reveal` get `.is-in` when 15% visible (IntersectionObserver, once). Failsafe: 2.5s
158
- after the `init` that found them, or at once if IntersectionObserver is missing, they get `.is-in`. Under
159
- `prefers-reduced-motion` the CSS shows them without motion.
173
+ - **Reveal** (0.12.0, as gemboss.ai): elements with `.gw-reveal` get `.is-in` once 12% of them is in view, the bottom
174
+ 6% of the view not counting (IntersectionObserver, once). Each `.gw-reveal` after the first among its `.gw-reveal`
175
+ siblings waits 70ms more (at most 380ms), so a grid of them cascades. A number in a `[data-gw-count]` element inside
176
+ counts up from 0 to itself over 1.1s when its reveal shows (its first words: `$1,200+` keeps the sign, the grouping
177
+ and the decimals). Failsafe: 1.6s after the `init` that found them, or at once if IntersectionObserver is missing,
178
+ they get `.is-in`. Under `prefers-reduced-motion` the CSS shows them without motion, at once, and nothing counts.
179
+ The values are `system.json` `motion.reveal`.
160
180
  - **Header**: `.is-scrolled` on `[data-gw-header]` once the page scrolled more than 8px (the CSS may use it for the
161
181
  hairline only; the bar does not change height or colour). The floating header needs nothing more from the script:
162
182
  it is the same element with one more class.
183
+ - **Current section** (0.11.0): a section's name with `aria-current` in the markup (`"true"`: the page is in that
184
+ section) is drawn like the current page's link, in the accent's strong ink at weight 600.
163
185
  - **Current page**: the script marks `aria-current="page"` on `.gw-nav__link` / `.gw-mega__link` and the mobile
164
186
  menu's links whose `href` pathname equals `location.pathname` (when the markup did not already). Each `init` takes
165
187
  its own marks back first, so after a client-side navigation they follow the new path; a mark in the markup stays.
@@ -217,6 +239,14 @@ top-level links and the actions are children of the sheet's `<nav>`.
217
239
  - `check` reports a group of a drill menu that is not a `<details>`, has no `<summary>`, no back button, no title or a
218
240
  title without `tabindex="-1"`, and `data-gw-menu` with another value (`menu-markup`).
219
241
 
242
+ **0.11.0, as gemboss.ai's phone menu:** the sheet is 24px in from both edges and its links are set at 18px, weight
243
+ 500, 0.005em tighter. A level may end with its panel's card (the same `.gw-mega__card` markup as in the panel: its
244
+ pictures load the first time the level shows) and `.gw-mobile-menu__all`, the link to the section's own page ("All of
245
+ Product →", the arrow drawn after a space). A row may carry a 48x32 picture (`<img>`) instead of its icon. A row under
246
+ the pointer or the keyboard takes the soft ground, moves 2px right, its icon tile in the accent. In the action bar,
247
+ `.gw-mobile-menu__link--muted` is a quieter link before Sign in (What's new); the buttons are 8px apart. The current
248
+ page is not marked on the phone.
249
+
220
250
  ### Language switcher (0.8.0)
221
251
 
222
252
  ```html
@@ -232,7 +262,7 @@ top-level links and the actions are children of the sheet's `<nav>`.
232
262
  </div>
233
263
  ```
234
264
 
235
- - **Where**: in `.gw-header__actions`, before Sign in (drawn from 1080px), and a second one, with its own list `id`, in
265
+ - **Where**: in `.gw-header__actions`, before Sign in (drawn from 1081px), and a second one, with its own list `id`, in
236
266
  the mobile menu's `.gw-mobile-menu__actions` (its list opens upward there). Both are filled the same way.
237
267
  - **The languages are the head's** `<link rel="alternate" hreflang href>`, not `x-default`, the first link of each
238
268
  `hreflang`: the links search engines read. The current language is the one whose `hreflang` is `<html lang>`, else the
@@ -495,7 +525,7 @@ CSS only: the script does not touch a form. The page (or its server) owns valida
495
525
  |---|---|
496
526
  | `.gw-btn` (+ `--secondary`, `--ghost`, `--on-night`, `--danger` (0.6.0), `--sm`, `--lg`, `--block`) | actions; a rectangle with the action radius, the action colour as fill (ink, or the accent under `data-gw-action="accent"`); `:active` pressed, `[aria-busy="true"]` loading (script above) |
497
527
  | `.gw-link` (+ `--arrow`) | inline text link in the accent; `--arrow` adds → that moves 2px on hover |
498
- | `.gw-label` | the label above a heading: 13px muted, 8px accent square before it |
528
+ | `.gw-label` | the label above a heading: 13px muted, the 8px square before it in ink; `--gw-label-mark` (on it or around it) paints the square |
499
529
  | `.gw-dim` | the muted first sentence inside a headline |
500
530
  | `.gw-chip` (+ `.is-active`) | selectable token, pill |
501
531
  | `.gw-segmented` (+ `--block`) | one choice out of two to four (script above) |
@@ -527,7 +557,7 @@ CSS only: the script does not touch a form. The page (or its server) owns valida
527
557
  |---|---|
528
558
  | `.gw-section` (+ `--soft`, `--tight`) | vertical rhythm; `--soft` on `--gw-bg-soft` |
529
559
  | `.gw-band--night` | a dark band (max three per page plus the closing CTA, never adjacent) |
530
- | `.gw-section__head` (+ `--center`) | label + h2 + one or two lines, max 660px |
560
+ | `.gw-section__head` (+ `--center`) | label + h2 + one or two lines, max 760px |
531
561
  | `.gw-hero` (+ `__wash`, `--center`, `--compact`) | first screen; `__wash` is the soft colour wash behind it |
532
562
  | `.gw-logos` | proof strip of customer or partner logos (real ones only) |
533
563
  | `.gw-stats` (`__item`, `__value`, `__label`) | 3–4 facts in a row, each with its source |
package/docs/theming.md CHANGED
@@ -98,7 +98,7 @@ the panels; in `tight` that is the 16px the header was designed with.
98
98
  - **Gradient or accent-coloured words in a heading.** A heading is ink, with a muted first sentence (`.gw-dim`).
99
99
  - **Accent-coloured section bands.** A section is white, `--gw-bg-soft` or a night band; the accent only lights a
100
100
  night band's top edge.
101
- - **All-caps labels.** Labels are sentence case, muted, led by the 8px accent square.
101
+ - **All-caps labels.** Labels are sentence case, muted, led by the 8px square (ink, or the colour `--gw-label-mark` gives it).
102
102
  - **A light on a heading, or in more than one colour.** The spotlight lights things you click, in the accent only.
103
103
 
104
104
  These make a page louder without making it clearer, and `check` reports the last one (`uppercase-label`) and any