@gemboss/ui 0.39.0 → 0.41.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
@@ -2,6 +2,291 @@
2
2
 
3
3
  Versions up to 0.9.0 are described in the README, each in the section that introduced it.
4
4
 
5
+ ## 0.41.0 (20/10/2026)
6
+
7
+ **A document read over its list** (Chris 20/10/2026, after GemMedia's and partner-radar's Docs drew the same popup with
8
+ their own CSS: "làm đi").
9
+
10
+ Added
11
+ - `ReaderDialog`: the kit popup sized for reading, `min(1440px, 94vw)` × `min(92dvh, 1200px)`, the whole screen under
12
+ 768px with the head's actions on their own line. It is `Dialog` with `ui-reader` (same props, less `wide`). The body has
13
+ no padding and is a column the document fills: `ui-reader__frame` (an iframe) or `ui-reader__scroll` (a padded scroller
14
+ of the surface's own). README "ReaderDialog", catalog "Hộp đọc tài liệu".
15
+ - `packages/ui/src/reader-dialog.css` (`@gemboss/ui/reader-dialog.css`): its own entry, imported by the component; every
16
+ selector `dialog.ui-modal.ui-reader…`. Nothing moves into the core or the bundle.
17
+ - `reader-dialog.test.tsx` (markup, every class styled, selectors), `reader-dialog-browser.test.tsx` (Chromium: size,
18
+ fill, scroll, phone head, page lock, Escape; negative control without the entry finds the 460px popup).
19
+
20
+ **The team chat's rows for a plain page, from the package: `gembossUI.teamChat`** (Chris 20/10/2026: the markup in ONE place,
21
+ so GemCare stops writing it by hand and a change to it is made once).
22
+
23
+ Added
24
+ - `packages/ui/src/team-chat-plain.js` (`@gemboss/ui/team-chat-plain.js`, its own entry): builders that RETURN elements with
25
+ the components' markup for the same props: `message` (`Message`, every prop; plus `picking` / `reactionsPicking` /
26
+ `onPickingChange` for a page that redraws its list), `daySeparator`, `newMessagesLine`, `jumpToLatest` + `updateJump`,
27
+ `readReceipt`, `channelSection`, `channelItem`, `peopleSection`, `personRow`, `reactions`, `reactionPicker` (the package's
28
+ picker and its keys, "Frequently used" under the React picker's storage key), `avatar`, `icon`, and `rows` / `dayKey` /
29
+ `dayWord` (`teamChatRows`, `chatDayKey`, `chatDayWord`). Labels are `TEAM_CHAT_LABELS` (`LABELS`), any subset overridable.
30
+ Strings are text; callbacks are click listeners. A classic script, ES5, after `kit-plain.js` when the page has it.
31
+ 8,208 B gzip minified (ceiling 8,714 in `weight-budget.json`; a page that draws no team chat never loads it).
32
+ - `team-chat-plain-browser.test.ts` (Chromium, `test:ui-browser`): every builder, in every state, against
33
+ `renderToStaticMarkup` of its component as one tree (attributes, classes, text, SVG in full); the same clicks and keys on
34
+ the mounted components and on the plain rows leave the same DOM (the pickers, search, Escape and focus); callbacks,
35
+ escaping, toolbar and picker keys, `updateJump`, the load-order warning. `team-chat-plain-data.test.ts` (node): the
36
+ generated block (icons, emoji set; `UPDATE_PLAIN_TEAM_CHAT=1` writes it) and the ES5 copies (labels, initials, tone,
37
+ reaction helpers, row rules) held to the TypeScript.
38
+ - `team-chat.test.fixtures.tsx`: the contract test's data, now shared with the plain parity test (the README is unchanged).
39
+ - The catalog's "Chat đội" section has a live plain-HTML frame built with `gembossUI.teamChat`.
40
+
41
+ **A list whose items come from elsewhere** (item management IM2, 21/10/2026: a list that shows a content type).
42
+
43
+ Changed
44
+ - `RepeaterList` `onMove` and `onRemove` are optional. Without `onMove` the rows keep their order: no grip, no ↑ ↓, no
45
+ Alt+arrows, no drop. Without `onRemove`, no ✕. A row still opens (inline or in the popover) and still says it was picked
46
+ (`onActive`). The admin draws a list read from Content this way: its order and its rows are Content's. No CSS change.
47
+
48
+ ## 0.40.0 (20/10/2026)
49
+
50
+ **A list's item edits in a popover** (item management IM1a, Chris 20/10/2026; GemPages 7.5's "Item management" read in its code).
51
+
52
+ Added
53
+ - `RepeaterList` `editIn="popover"`: the list stays one line per row; the row picked shows its controls in a layer under the list
54
+ (top layer, placed by `menu-layer.ts` `placeFloating`, as wide as the list), one row at a time. ✕, Escape (focus back on the
55
+ row) or the row clicked again close it; a click elsewhere does not (a row's controls open pickers and dialogs of their own).
56
+ A list of one row shows it in place, open (nothing to choose between). Without the popover API the row picked opens in
57
+ place. Default stays `inline`.
58
+ - `thumb(index)`: a 20px picture before the row's name (the admin passes the row's first image field).
59
+ - `onActive(index | null)`: the host hears the row picked, to show that item on the canvas.
60
+ - `packages/ui/src/editor-repeater.css`: the popover's placement and header, the picked row's outline, the picture (+220 B gzip,
61
+ 1,096 of its 1,384 B ceiling). The surface is the fleet's `gemboss-popover-surface`.
62
+
63
+ **An inspector's tabs stand on the fields' edge** (Chris 20/10/2026: "cùng là tabs mà chỗ to chỗ nhỏ").
64
+
65
+ Fixed
66
+ - `packages/ui/src/editor.css`: `.gemboss-ei-tabs` inside a settings body or the column's dock drop their 12px side margin
67
+ (`:is(.gemboss-settings-body,.gemboss-ec-dock-body)`), so the Settings · Advanced track lines up with the fields under it (the
68
+ canvas's element and section panels measured 34–360 and 316px over fields at 22–372). A docked inspector keeps its own, more
69
+ specific rule; a floating inspector keeps 12px. +15 B gzip (8,680 of 8,690).
70
+
71
+ **A phone pays for the topbar once, and the full-screen assistant gets the whole width** (measured on the admin at 390×844,
72
+ 19/10/2026).
73
+
74
+ Fixed
75
+ - `.gemboss-platform-main` at ≤760px: `padding-top` is the 16px gutter (it was 56px). `margin-top: 56px` already clears the fixed
76
+ bar at every width, so a phone had 74px between the bar and a page's title.
77
+ - Full screen at ≤560px: the thread rail (`SessionRail`, one New chat button at that width) sits in the empty left of the
78
+ `.gb-dock-fullchrome` strip, a 44px circle at the strip's 8px/12px inset, instead of a 60px column beside the chat (330 of
79
+ 390px). CSS only: a surface that passes its own New chat through `fullActions` gets no second one. Above 560px nothing moves.
80
+
81
+ **`Switcher`: the nine-dot panel for any list, with illustrated tiles (GemCommunity's groups).**
82
+
83
+ Added
84
+ - `Switcher` (`SwitcherItem`, `SwitcherProps`): the dialog, search, groups, keys and phone sheet of `ServiceSwitcher`, for
85
+ items an app gives (`id`, `name`, `description`, `href`, `group`, `tint`, `badge`). A tile with `media` (`{ src }` an
86
+ image, `{ glyph }` an emoji drawn on its tint) is a card with the picture on top (`gb-svc__tile--media`,
87
+ `gb-svc__media`, 16:9); the groups holding cards lay out in 208px columns, two a row on a phone. `foot` puts the app's
88
+ own actions in the foot. Chris 20/10/2026: GemCommunity's group switcher "kèm hình ảnh minh hoạ, tên và description …
89
+ như các dịch vụ gemboss, gemcapture bấm vào icon lưới 9 chấm".
90
+
91
+ Changed
92
+ - `ServiceSwitcher` is now `Switcher` with the Gem services: the same markup as before (tests pin it).
93
+
94
+ **A competitor page's picture in the chat comes from the GemBoss admin, not from the market archive** (Chris 20/10/2026).
95
+
96
+ Changed
97
+ - `FLEET_IMAGE_HOSTS` (and chat-plain.js's copy) draws `https://admin.gemboss.ai/api/gemboss/market-image/…`, the admin's
98
+ signed picture door, and no longer lists the market archive's own host. GemBoss's tools now hand out admin URLs for
99
+ these pictures; the archive's host in this list put its name in every surface's bundle. A surface that draws the
100
+ archive's own pictures (its own dashboard) passes that host in `imageHosts`. An older answer that still holds an
101
+ archive URL shows the picture as a link, the rule for every host not on the list.
102
+
103
+ **The public site layer: one bar, one lockup size, one set of buttons for every public page** (Chris 20/10/2026: "có gemboss ui
104
+ thì có gemboss website ui"; two lockup sizes, site 18px and app 13.3px). Measured the same day: the logo name 18px on gemboss.ai
105
+ and the docs, 16px on news, 13.3px on the community home; the bar 65 / 57 / 69 / 56px.
106
+
107
+ Added
108
+ - `@gemboss/ui/site.css`, a new entry (1.0 KB gzip): `gb-site-header` (sticky, 64px, the 1132px column), `gb-brand--site` (the
109
+ lockup with an 18px name), `gb-site-nav` / `gb-site-link`, `gb-site-actions`, `gb-site-btn` `--primary` / `--secondary` (40px,
110
+ 36px in the bar, 44px under a finger), and the footer (`gb-site-footer`, `__grid`, `__col`, `__bottom`, `gb-site-wrap`). Values
111
+ are gemboss.ai's own; every colour a token, so the dark palette applies. README "The public site layer".
112
+ It stands alone: with only the tokens and site.css (no core), the site lockup is whole, for plain-HTML pages.
113
+ - `SiteHeader` and `SiteBrand` (`site.tsx`), which bring it. `SiteBrand` draws the same gem as `BrandLockup` and does not import
114
+ brand.tsx, so a public page never carries the ServiceSwitcher.
115
+ - Catalog section "Trang công khai"; `site.test.tsx` (markup, same gem, no rule on :root/html/body, no colour literal) and
116
+ `site-browser.test.tsx` (64px bar, 18px vs 13.3px, 44px controls at 390, no sideways scroll at 1280/390/320).
117
+
118
+ Changed
119
+ - The lockup's gem moved to `brand-gem.tsx` (`BrandGem`), shared by `BrandLockup` and `SiteBrand`. `BrandLockup` renders the
120
+ same markup as before.
121
+
122
+ **A colour not set is not black** (control standard §13b U7, Chris 20/10/2026). An empty colour drew a black swatch beside "Not set",
123
+ so a seller read a colour nobody chose.
124
+
125
+ Changed
126
+ - `ColorControl`: an empty value marks its swatch `data-empty` and opens it on white; `editor.css` draws the slash a picker draws for
127
+ "none" over it (`.gemboss-ei-swatch[data-empty]::-webkit-color-swatch`). A value the swatch cannot show is unchanged (black, off,
128
+ with the reason under it).
129
+ - `packages/ui/weight-budget.json`: `packages/ui/src/editor.css` 8,615 → 8,690 B gzip, Chris's OK on 20/10/2026. This rule is +45 B (8,665 measured); main
130
+ was already at 8,620, over the old ceiling, after two PRs that each passed it alone (#4701, #4648).
131
+
132
+ **The ? beside a label stays a 16px circle inside the page editor.**
133
+
134
+ Fixed
135
+ - `.gemboss-pageedit .gemboss-ec-dock-body`, `.gemboss-page-section-content` and `.gemboss-bundle-look .gemboss-ei-body` set every
136
+ button to 44px; the ? (`.gemboss-ei-help`) is now left out, as the inspector field's own 44px rule already left it out. It drew
137
+ 16x44, an oval beside every label in the page editor's Settings (measured 19/10/2026). Its target is its ring (::after).
138
+
139
+ **The team chat layer: GemCare's channel chat for every surface** (Chris 20/10/2026: bring GemCare's Slack-like channel chat to
140
+ GemCommunity, and make the two inherit the same UI so the next upgrade happens once). GemCare's look and behaviour (origin/main
141
+ 20/10/2026: public/assets/inbox.{html,css,js}) moved into the package; GemCare (plain HTML) and GemCommunity (React) draw the same thing.
142
+
143
+ Added
144
+ - `@gemboss/ui/team-chat.css`, a new entry (3.6 KB gzip, ceiling 4174): the screen (`gb-tc`, rail | conversation | right panel), the
145
+ rail (`gb-tc-rail`, `gb-tc-channel` with a kind glyph, `gb-tc-badge` and `--mention`), the head (`gb-tc-head`, back button, members
146
+ toggle), the list (`gb-tc-log` role=log, `gb-tc-day` sticky, `gb-tc-new`, `gb-tc-jump`), the message (`gb-tc-msg`, `--grouped`,
147
+ `--mention`, `--highlight`, `--sending`, `--failed`, `--active`, `--editing`; `gb-tc-quote`, `gb-tc-threadprev`, `gb-tc-receipt`, the action
148
+ bar `gb-tc-acts`), the composer (`gb-tc-composer`, one box: paperclip, a field that grows, send; "Replying to", files and mention
149
+ picker slots, "Also send to"), the thread panel (`gb-tc-thread`) and the people panel (`gb-tc-people`, sections "Online — n", rows
150
+ with a presence dot and a role chip, a 56px collapsed strip; usable on its own in an app shell's right column). Every colour a
151
+ `--gemboss-*` token (dark applies unchanged); no rule on :root/html/body. Reused, not redrawn: `Avatar` (portal.css), `Reactions`
152
+ (reactions.css), the kit's `ui-btn` / `ui-check`.
153
+ - The screen decides by its OWN width (container queries, not the viewport): > 1100px the right panel is a column (thread 380, people
154
+ 260 / 56); ≤ 1100px a drawer over the conversation with a scrim (the conversation keeps its width); ≤ 760px the channel list OR the
155
+ conversation (`data-view`), a back button, the panel a sheet over the chat. Under a finger every control is 44px; under a mouse the
156
+ rail and the action bar are 32px. The action bar is one tap away under a finger (the row takes focus) instead of a row of 44px
157
+ buttons under every message as in GemCare; the message list's own container query drops the quick reactions where it is narrow.
158
+ - React, props only (`team-chat.tsx`): `TeamChat`, `ChannelRail`, `ChannelSection`, `ChannelItem`, `ChatHeader`, `MessageList`,
159
+ `DaySeparator`, `NewMessagesLine`, `JumpToLatest`, `Message`, `ReadReceipt`, `Composer`, `ThreadPanel`, `PeoplePanel`, `PeopleSection`,
160
+ `PersonRow`; `TEAM_CHAT_LABELS` (every word, `labels` to translate). `TeamChat` holds focus in a drawer (focus in, the rest `inert`,
161
+ Escape / the scrim close it, focus back to the opener). `Composer`: Enter sends, Shift+Enter a new line, an IME composition is never cut.
162
+ - `teamChatRows`, `chatDayKey`, `chatDayWord` (`team-chat-data.ts`, plain TS): GemCare's rules for turns (same author, same day, < 5 min,
163
+ not a reply), day separators and the "New messages" line.
164
+ - Icons `hash`, `lock`, `reply`, `thread`, `paperclip`, `send`, `chevronLeft`, `chevronsDown`, `panelRight`.
165
+ - README "The team chat layer": the plain-HTML markup of every part, held to the React components by `team-chat-contract.test.tsx`.
166
+ Catalog section "Chat đội" (desktop with a thread, dark with people, the 1024 drawer, phone conversation and list, the people
167
+ panel alone). `team-chat.test.tsx` (markup, ARIA, states, the row rules, the stylesheet's rules) and `team-chat-browser.test.tsx`
168
+ (Chromium at 1366 / 1024 / 390 / 320: columns vs drawer, the screen's own width, list or conversation, no sideways scroll, 44px under
169
+ a finger, a tap shows the bar, Enter sends, contrast in light and dark; negative controls without the drawer and the finger blocks).
170
+
171
+ **A colour swatch that cannot show its value says why, under it** (Claude Design: a disabled control says why).
172
+
173
+ Added
174
+ - `swatchWhy(value)` (`@gemboss/ui/editor/swatch`): the reason, or null when the swatch shows the value. A theme token says which
175
+ one ("Theme color: Accent. Type a hex to use your own."), any other value that is not a 6-digit hex says it is kept as written.
176
+
177
+ Changed
178
+ - `ColorControl` draws that reason as a line under the swatch and its box (`.gemboss-ei-color-why`, 12/16 muted) and points the
179
+ swatch at it (`aria-describedby`); the swatch's title is the same sentence. It was a tooltip only, which a finger and the keys
180
+ never reach, and every colour the editors' toolbar picks is a token, so the swatch was grey after each one.
181
+
182
+ **Room between the settings, and one inset for the column** (Chris 20/10/2026: "khoảng cách giữa các dòng settings … dính tịt vào nhau",
183
+ "section settings padding 2 bên lại không đồng bộ với element settings", "chia cụm và các khoảng nghỉ"). Measured on the Canvas at 1280:
184
+ neighbouring fields of the element panel 0px apart (1,831 of 1,831 on the 71 kinds: the panel wraps each setting in a `<div>`, so each
185
+ field was a `:last-child` and lost its 12px); a section's settings 36px in from the column's edges where the element panel's are 16.
186
+
187
+ Changed
188
+ - Inside a collapsible group (`.gemboss-ei-grp`) the gap is the group's, between its items, whatever wraps a field: 12px, 8px under
189
+ the header, none above a hint. A `.gemboss-ei-group` holds its fields bare, and their own 12px applies.
190
+ - `.gemboss-ei-grp`, `.gemboss-ei-group`: 16px above and below (12): a pause between clusters, larger than the one between fields.
191
+ - `.gemboss-settings-body`: fields 12px apart (20), the label 6px above the box (4), as in a group. Docked in the Canvas's column it
192
+ drops its own 16px 20px, so the column's inset is the one: that rule is the Canvas's (admin `funnel-canvas.css`), as this file
193
+ is at its weight ceiling.
194
+
195
+ Removed
196
+ - `.gemboss-ei-group > .gemboss-ei-fld:last-child`: the same as `.gemboss-ei-fld:last-child`.
197
+
198
+ **The editor's frame at the kit's size under a mouse** (Chris 19/10/2026: "những cái button vẫn bị to hơn chuẩn của gemboss ui"). Every
199
+ control of the element panel was already on the standard (measured on all 71 kinds); the frame around it was not. Measured on the Canvas
200
+ at 1280: Publish 33px, 14 / 600, 20px in; Undo, Redo and ⋯ 32 × 36; ← and the panel toggle 30 × 30; the Settings · Chat tabs 38px, 12 / 600.
201
+
202
+ Changed
203
+ - `.gemboss-editor-tb-publish`: 28px (`--ui-btn-h`), 12 / 550 / 16, 12px in, as the kit's button; its caret 8px in. A narrow bar and a
204
+ finger keep their own rules.
205
+ - `.gemboss-pv-device` (the bar's icon buttons), `.gemboss-editor-back`, `.gemboss-editor-chat-toggle`: 28 × 28.
206
+ - `.gemboss-ec-tabs > [role="tab"]`: 28px, 12 / 550 / 16, 12px in (Polaris Tabs); 44px at 767 and below as before.
207
+
208
+ Removed
209
+ - The 36 × 32 box and 44px overlay the theme and page editors' icon buttons wore above 1000px: on 28px boxes 8px apart the overlays
210
+ would cross, and under a mouse the kit asks 28.
211
+
212
+ **A popup opened from a link draws no ring around itself.**
213
+
214
+ Fixed
215
+ - `.ui-modal:focus` has no outline. The panel takes focus on open and is never a Tab stop; Chrome drew its own ring
216
+ around the whole dialog when that focus came from a script with no click before it (every admin settings door, 19/10).
217
+
218
+ **Tabs, row buttons and the trail at Polaris sizes** (control standard U3b).
219
+
220
+ Changed
221
+ - `.gemboss-ei-tab` (an inspector's Settings / Advanced): 12px / 550 on a 16px line, 28px tall (it was 27px / 600).
222
+ - `RepeaterList`: a row's ↑ ↓ duplicate ✕ and its toggle at radius 8 (6); "+ Add item" is the kit's `.ui-btn` at full width (it
223
+ was a dashed box, 13px / 450).
224
+
225
+ **A field's buttons are Polaris buttons, and one touch rule** (control standard U3, research pickers-2026-10-16 §13b).
226
+
227
+ Changed
228
+ - `ChipButton` (Choose, Remove, Select image, Library, Clear, + Add…) is the kit's `.ui-btn`, a Polaris secondary button: 28px,
229
+ 12px / 550, radius 8, 44px under a finger. It was `.gemboss-ei-addchip`, a dashed pill (27px, 11px / 600, radius 999).
230
+ - The inspector's tabs, group heads, swatches and field controls grow to 44px on the kit's rule, `(pointer: coarse), (max-width:
231
+ 47.9975em)`, not on `(pointer: coarse)` alone: at 390px with a mouse the fields were 44px and the heads 20px.
232
+ - The "?" keeps its 16px circle under a finger and is pressed in a 44px ring (it grew into a 44px circle that pushed its label).
233
+
234
+ Removed
235
+ - `.gemboss-ei-addchip`: use `ChipButton` (or `.ui-btn`).
236
+
237
+ **A number box with its unit stays one line inside a field** (fix of U1). The admin's FieldRenderer puts `UnitField` straight
238
+ inside `.gemboss-ei-fld`, and its box is a `<label>`: the field's label rule (`.gemboss-ei-fld>label`, 0,1,1) beat the group's
239
+ `display:flex` (0,1,0), so the box was a block, 42px high with the unit under the value, a 6px label margin and the label's type
240
+ on the value. Measured on the section panel at 1280: 7 of 7 such boxes.
241
+
242
+ Fixed
243
+ - The label rules leave a field group out: `.gemboss-ei-fld>label:where(:not(.gemboss-field))`, same weight as before, in the
244
+ plain rule and the quiet one inside a group.
245
+
246
+ Changed
247
+ - `editor.css` 8.580 → 8.571 B gzip: two rules that repeated a selector (`.gemboss-pagepicker-list`, `.gemboss-platform-main:has(.gemboss-editor)`)
248
+ are one each, and `.gemboss-ei-gh:hover` is gone (it set the colour the header already has).
249
+
250
+ **Type at Polaris sizes in the panel** (control standard U2, research pickers-2026-10-16 §13b). Measured on the element panel at 1280:
251
+ 130 hints at 11px, and 215 "?" buttons drawn in the browser's 13.33px / 400.
252
+
253
+ Changed
254
+ - `.gemboss-ei-hint` 11px → Polaris bodySm **12px / 16px**, 4px under its control (Polaris help text's gap; it was 8).
255
+ - `.gemboss-ei-help` (the "?"): its `font` shorthand ended in `inherit`, which is not valid there, so the whole declaration was
256
+ dropped; now `650 10px/16px var(--gemboss-font-sans)`.
257
+ - `.gemboss-ei-gh-note` (a group header's aside) 10px / 500 → 12px / 450.
258
+ - `.gemboss-settings-field > span` (the section panel's and the page-settings sheet's field labels) 13px / 700, full colour → the
259
+ inspector's quiet label, 13px / 450 in `--gemboss-text-muted`, 4px above its control (it was 6).
260
+
261
+ **The panel's edges line up** (control standard U1, research pickers-2026-10-16 §13b; Chris 19/10/2026: "giờ méo, kích thước chưa
262
+ chuẩn polaris"). Measured on the element panel at 1280 before: 71 rows whose number box stopped short of the panel's right edge
263
+ because the unit sat outside it, swatches 34px beside 32px boxes, group titles 16px right of the labels under them.
264
+
265
+ Added
266
+ - **`UnitField`** (`editor/controls.tsx`): a number box with its unit INSIDE, as Polaris TextField's `suffix`. A
267
+ `label.gemboss-field.gemboss-field--group` around `.gemboss-field__bare` and `.gemboss-field__suffix`, so a click anywhere in the
268
+ box, the unit included, focuses it. Props: every `<input>` prop, plus `unit`, `className` and `style` for the box.
269
+ - `.gemboss-field__suffix` (`gemboss-field.css`): the unit's place in a field group, Polaris secondary text, 6px after the value.
270
+
271
+ Changed
272
+ - `ValueControl`'s box is a `UnitField` (`.gemboss-ei-value-box`, 7em: 91px at 13px, 112px at the phone's 16px), the unit inside.
273
+ - `.gemboss-ei-swatch` 34 → 32px, the height of the box beside it.
274
+ - `InspectorGroup`'s header: the disclosure mark sits at the END of the line, drawn as a chevron (two borders; down open, right
275
+ closed), so the title starts on the labels' edge. The ▾ / ▸ glyph stays in the markup for `editor-plain.js`, hidden.
276
+ - A field group whose text field is disabled is drawn disabled (50%, not-allowed) and does not react to hover; a disabled colour
277
+ swatch beside an editable box does not dim the box.
278
+
279
+ Removed
280
+ - `.gemboss-ei-suffix` (the unit beside the box): use `UnitField`.
281
+
282
+ **The section panel's groups are the inspector's** (control standard §13b U5). The band panel listed each element's options and
283
+ lists in native `<details>` (the browser's triangle, no divider); they are `InspectorGroup`s now.
284
+
285
+ Added
286
+ - `InspectorGroup`'s `attrs`: `data-*` attributes on the group itself (`.gemboss-ei-grp` / the static `section`), so a page that
287
+ finds a group by an attribute needs no wrapper. A wrapper made each group the `:last-child` of its own parent, and the divider
288
+ between groups (`.gemboss-ei-grp:last-child{border-bottom:none}`) never drew.
289
+
5
290
  ## 0.39.0 (19/10/2026)
6
291
 
7
292
  **A field of real pages for the sign-in panel, and an entrance for the screen.** Chris, on admin.gemboss.ai/login: