@gemboss/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.
- package/CHANGELOG.md +80 -0
- package/README.md +81 -2
- package/catalog/index.html +19 -6
- package/gemboss-ui.css +109 -65
- package/package.json +1 -1
- package/src/app-shell.css +13 -0
- package/src/editor.css +22 -19
- package/src/gemboss-tokens.css +1 -1
- package/src/kit-plain.css +25 -8
- package/src/theme-dark.css +1 -0
- package/src/ui.css +67 -54
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,86 @@
|
|
|
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.12.0 (05/10/2026)
|
|
6
|
+
|
|
7
|
+
**A change you SEE on every surface, and on the admin's /admin console.** The kit now draws the admin's (Polaris')
|
|
8
|
+
density under a mouse; under a finger or below 768px every control keeps its 44px floor. Measured on admin.gemboss.ai,
|
|
9
|
+
the catalog drew 25 values the admin does not; it now draws 3, all colour (see "Not changed"). README "Admin density
|
|
10
|
+
(0.12.0)".
|
|
11
|
+
|
|
12
|
+
Changed (under a mouse, at 768px and wider)
|
|
13
|
+
- `ui-btn`: 28px tall (was 32), padding 0 12 (was 16), 12px (was 13). New `--ui-btn-h: 28px`; `--ui-control-h` stays 32
|
|
14
|
+
for `gemboss-field` and `ui-select` (Polaris TextField / Select). `ui-btn--icon` is 28 wide. The popup's own 28px rule
|
|
15
|
+
is gone (every button is 28). **A surface that raised `--ui-control-h` to grow its buttons must now set `--ui-btn-h`
|
|
16
|
+
as well** (gemcare `public/assets/inbox.css` sets `--ui-control-h: 44px` for that reason).
|
|
17
|
+
- ui.css (what the admin loads): buttons and segments are 44 at phone width with a mouse too (`max-width: 47.9975em`),
|
|
18
|
+
as they already were under a finger; they were 32 there.
|
|
19
|
+
- `ui-seg`: 28px group, labels 12px/550. `ui-tabs`: 28px (was 44 under every pointer), 12px/550 selected or not, 8px
|
|
20
|
+
apart (was 4); 44px under a finger or at phone width (in ui.css, so the plain export keeps it).
|
|
21
|
+
- `ui-page-head h1`: 20px/24px/700 (was 22/28/650).
|
|
22
|
+
- `ui-card`, `ui-table-wrap`: Polaris' drop under the card, `--ui-card-shadow` (shadow-100, `0 1px 0 rgba(26,26,26,.07)`).
|
|
23
|
+
The edge stays one 1px `--ui-border` line: Polaris paints a bevel inset on a ::before, which a full-bleed child would
|
|
24
|
+
cover in an inset shadow and which would not follow a surface's dark `--ui-border`. The admin console
|
|
25
|
+
(`.gemboss-admin-shell`) and `theme-dark.css` set the shadow to none.
|
|
26
|
+
- `ui-card__title`, `ui-section-head > h2`, `ui-empty__title`: 14px/20px/650 (were 14/18.2/600, 16/650, 16/600).
|
|
27
|
+
- `ui-table`: Polaris DataTable, measured on /app/analytics and Polaris 13.9.5 rendered: cells 8px 6px (a one-line row
|
|
28
|
+
36), header 12px 6px at 13px/450 (45; was 12/600), the first column 12px from the edge (was 8 x 12 everywhere).
|
|
29
|
+
- `ui-select` weight 450 (was 500); `ui-badge` weight 450 (was 550).
|
|
30
|
+
- `ui-tag`: Polaris Tag, 12px/450 on a 20px line, padding 0 6, radius 8 (was 11px/600 uppercase, letter-spaced).
|
|
31
|
+
`ui-tag--chip` keeps its 11px mono and its height (it already sat on the body's 20px line); its corner is 8 (was 6).
|
|
32
|
+
- `ui-metric--lg`: value 24/32 (was 24/1.1), label 13 (was 14). `ui-funnel__val` 20/24.
|
|
33
|
+
- The kit stops reading `--gemboss-fs-body`, `--gemboss-fs-h1/h2/h3` (the admin seller app's prose sizes, 14/24/20/16);
|
|
34
|
+
ui.css reads `--ui-fs-caption` where it read `--gemboss-fs-caption` (same 12px).
|
|
35
|
+
- `app-shell.css`: Polaris' heading reset (`h1…h6, p`: 1em, inherited weight, margin 0) INSIDE `.gemboss-platform-shell`,
|
|
36
|
+
for elements WITHOUT a class, never inside an article: `.ui-prose`, `[data-content]`, and the wrappers the fleet uses
|
|
37
|
+
for rendered HTML today, by name (`.md-body`, `.recap-md`, `.asst-md`, `.article-body`, any class containing
|
|
38
|
+
`prose` or `markdown` in any case). A new wrapper: mark it `ui-prose` or `data-content`. A bare `<h2>` or `<p>` in the shell becomes body text (13/20/450) with no margin, as in the
|
|
39
|
+
admin; `ui-page-head h1` / `p` lose the browser's margins the same way (the admin never had them). A heading with a
|
|
40
|
+
class keeps what it had.
|
|
41
|
+
|
|
42
|
+
Added
|
|
43
|
+
- `ui-chip` (filter chip: Polaris FilterPill's shape at 28px, `aria-pressed` / `aria-current`) and `ui-stack` (cards
|
|
44
|
+
16px apart, `--tight` 8) in kit-plain.css. For a new filter row use `ui-chip`; the older `.ui-chips > .ui-tag--chip`
|
|
45
|
+
(link and toggle) still draws as before and moves to `ui-chip` with each surface's PR.
|
|
46
|
+
- `ui-btn--sm` is the default size under a mouse now (both 28); its own size rule is gone. It still means "compact" in
|
|
47
|
+
one place: under a finger the admin (ui.css only) keeps it 28, as before; every other surface gets 44 from kit-plain.css.
|
|
48
|
+
- `ui-table`: the last column is 12px from the edge too (Polaris DataTable `:last-child`).
|
|
49
|
+
- visual-gate `--density` (scripts/visual-gate): one `density` check per width, `skip` when the page has no kit element
|
|
50
|
+
or was redirected; its selftest has the 28 / 32 control.
|
|
51
|
+
- `polaris-reference.json` + `packages/ui/scripts/density.mjs`: the density gate (README). `packages/ui/src/density.test.ts` runs it in
|
|
52
|
+
Chromium on the catalog and on the admin's own sheets, with negative controls (32px button, 44px under a mouse, bare
|
|
53
|
+
`<h2>`) and positive ones (sr-only, an article's headings, the 44px floor under a finger).
|
|
54
|
+
|
|
55
|
+
Not changed
|
|
56
|
+
- Colour: ink and primary `#1b1c1e` (Polaris `#303030`), the secondary button's fill. A separate change.
|
|
57
|
+
|
|
58
|
+
Surfaces: upgrade, then run `packages/ui/scripts/density.mjs` on your pages; what it still lists is your own CSS (GemFactory
|
|
59
|
+
`server/ui.mjs`, content-radar `v2.css`, taskdesk's segmented buttons are known).
|
|
60
|
+
|
|
61
|
+
## 0.10.1 (05/10/2026)
|
|
62
|
+
|
|
63
|
+
Editor kit step 1b (gemboss #3781): the visible fixes left over from the verbatim move of `editor.css` in 0.9.0. Each one
|
|
64
|
+
changes what the admin's three editors show; nothing else moves (computed style compared on 99 editor states at six
|
|
65
|
+
widths). README "Editor CSS (0.9.x)".
|
|
66
|
+
|
|
67
|
+
Changed
|
|
68
|
+
- `editor.css`, the Configure | Chat tab row: on the space scale. Row padding `var(--ui-space-2) var(--ui-space-3)`
|
|
69
|
+
(was 8px 10px), tab padding `var(--ui-space-2)` (was 7px). The temporary variables `--gemboss-ec-tabs-pad-x` and
|
|
70
|
+
`--gemboss-ec-tab-pad` are gone. Under a mouse a tab is 2px taller and the row 4px narrower inside.
|
|
71
|
+
- No iris for selection: `.gemboss-layer.is-sel` and `.gemboss-pageedit-chip` use `--gemboss-active-bg` /
|
|
72
|
+
`--gemboss-active-fg` / `--gemboss-divider`; `.gemboss-guest-keep` (the try door's Keep) is `--gemboss-primary`, hover
|
|
73
|
+
`--gemboss-primary-dark`, text `--gemboss-on-primary`. Iris (`--gemboss-accent`) stays for focus and links.
|
|
74
|
+
|
|
75
|
+
Added
|
|
76
|
+
- `@keyframes gemboss-flyout-in`, which `.gemboss-editor-menu` has named since before 0.9.0 and no sheet defined: the
|
|
77
|
+
⋯ More and Publish menus fade in with a 4px drop like the page picker, no fill mode, `animation: none` under
|
|
78
|
+
`prefers-reduced-motion`.
|
|
79
|
+
- `editor-css.test.ts`: no literal colour between 228° and 300° hue in `editor.css`.
|
|
80
|
+
|
|
81
|
+
Admin, same PR (not in the package): the theme editor's tabs wear `.gemboss-ec-tab` (36px to 44px under touch, as the
|
|
82
|
+
page and section editors), the Section Library loses its lilac borders, `SectionOutline.tsx` and `.gemboss-ec-panel`
|
|
83
|
+
(unreachable / unused) are deleted.
|
|
84
|
+
|
|
5
85
|
## 0.10.0 (05/10/2026)
|
|
6
86
|
|
|
7
87
|
Navigation pending: a click on a menu item answers on the first frame, and a page is fetched while the pointer rests on
|
package/README.md
CHANGED
|
@@ -246,6 +246,17 @@ resizer. The behaviour (resizing, tabs, menus, the inspector's writes) belongs t
|
|
|
246
246
|
components come in steps 2 to 4 (`EditorFrame` + `EditorTopbar`; `PanelTabs`, `PanelHeader`, `InspectorGroup`, `Field`
|
|
247
247
|
and the controls; `LayerList`, `EditorDrawer`). Step 5 moves GemFactory's Builder onto them.
|
|
248
248
|
|
|
249
|
+
Changes since the verbatim move, in 0.10.1 (05/10/2026, step 1b, the only ones that change what the admin shows; CHANGELOG):
|
|
250
|
+
|
|
251
|
+
- Tab row on the space scale: `padding: var(--ui-space-2) var(--ui-space-3)` on the row, `var(--ui-space-2)` on each
|
|
252
|
+
tab (were 8px 10px and 7px; the temporary `--gemboss-ec-tabs-pad-x` / `--gemboss-ec-tab-pad` are gone). Under a
|
|
253
|
+
mouse a tab is 2px taller; under touch the 44px floor decides.
|
|
254
|
+
- No iris for selection: Layers' selected row and the page editor's "Editing:" chip use `--gemboss-active-bg` /
|
|
255
|
+
`--gemboss-active-fg` / `--gemboss-divider`; the try door's Keep button is `--gemboss-primary` (hover
|
|
256
|
+
`--gemboss-primary-dark`) like Publish. Iris (`--gemboss-accent`) stays for focus and links.
|
|
257
|
+
- `gemboss-flyout-in` is defined (fade + 4px drop, as the page picker), so `.gemboss-editor-menu` animates; `none`
|
|
258
|
+
under `prefers-reduced-motion`.
|
|
259
|
+
|
|
249
260
|
## Plain-HTML behaviour: `kit-plain.js` (0.3.0)
|
|
250
261
|
|
|
251
262
|
Surfaces without React (GemFactory, gemcare, gempress, partner-radar) render the kit's markup on the server and need
|
|
@@ -385,8 +396,8 @@ surfaces on the package, the same gaps were filled six ways. What 0.5.0 settles,
|
|
|
385
396
|
|
|
386
397
|
| | Under a mouse | Under a thumb / ≤ 767px wide |
|
|
387
398
|
|---|---|---|
|
|
388
|
-
| Control height: `gemboss-field`, `ui-select
|
|
389
|
-
| `ui-btn--sm` | 28px | 44px |
|
|
399
|
+
| Control height: `gemboss-field`, `ui-select` | **32px** (Polaris TextField / Select), `--ui-control-h` | **44px** |
|
|
400
|
+
| `ui-btn`, `ui-btn--sm`, `ui-seg`, `ui-tabs` (0.12.0, was 32 / 28 / 32 / 44) | **28px** (Polaris Button), `--ui-btn-h` | **44px**, `ui-btn--sm` included |
|
|
390
401
|
| `ui-btn` inside a popup's head or foot (0.7.3) | 28px, 12px | 44px |
|
|
391
402
|
| Focus ring, every control | 2px iris `--ui-focus` (= `--gemboss-accent`, the admin's `--p-color-border-focus`) | same |
|
|
392
403
|
| Body text (`html`, `body`, at zero specificity) | 13px / 20px, weight 450, `--gemboss-text`, antialiased (Polaris bodyMd) | same |
|
|
@@ -436,6 +447,74 @@ If your surface still sets any of these itself (a `body { font-size }`, a `min-h
|
|
|
436
447
|
cascade over the package's zero-specificity base. `packages/ui/src/kit-look.test.ts` measures the table above in
|
|
437
448
|
Chromium on the built CSS.
|
|
438
449
|
|
|
450
|
+
## Admin density (0.12.0)
|
|
451
|
+
|
|
452
|
+
05/10/2026, Chris: "UI GemFactory hình như mọi thứ to hơn bên gemboss". Measured the same day on admin.gemboss.ai, the
|
|
453
|
+
catalog and nine surfaces (raw data and matrix: `Gems/_local/fleet/ui-density-2026-10/`): about 94% of the gaps came from
|
|
454
|
+
the PACKAGE, not from the surfaces. It drew a 32px button at 13px where Polaris draws 28 at 12, a 22/28/650 page title
|
|
455
|
+
where Polaris draws 20/24/700, table cells padded 8 where Polaris pads 12, a bordered card where Polaris draws a shadow,
|
|
456
|
+
and an uppercase 11px tag. 0.12.0 draws the admin's numbers under a mouse and keeps the 44px floor under a finger or at
|
|
457
|
+
phone width (`(pointer: coarse), (max-width: 47.9975em)`, the topbar search's rule since 0.6.5), which is how a surface
|
|
458
|
+
both looks like the admin and passes Gems/CLAUDE.md §9.1.
|
|
459
|
+
|
|
460
|
+
| | Under a mouse, ≥ 768px | Under a finger / < 768px |
|
|
461
|
+
|---|---|---|
|
|
462
|
+
| `ui-btn` (every variant), `ui-btn--icon` | 28px, padding 0 12, 12px/550 (`--ui-btn-h`) | 44px |
|
|
463
|
+
| `ui-seg` group, `.is-text` label | 28px, 12px/550 | 44px |
|
|
464
|
+
| `ui-tabs` | 28px, padding 0 12, 12px/550 selected or not, 8px apart | 44px |
|
|
465
|
+
| `ui-page-head h1` | 20px / 24px / 700 (Polaris headingLg) | same |
|
|
466
|
+
| `ui-card`, `ui-table-wrap` | Polaris' shadow-100 under it (`--ui-card-shadow`), one 1px `--ui-border` edge, radius 12, padding 16 | same |
|
|
467
|
+
| `ui-card__title`, `ui-section-head > h2`, `ui-empty__title` | 14px / 20px / 650 (headingMd) | same |
|
|
468
|
+
| `ui-table` | Polaris DataTable: cells 8px 6px (row 36), `th` 12px 6px at 13px/450 (45), first and last column 12 from the edge | same |
|
|
469
|
+
| `ui-select` | weight 450 | 44px |
|
|
470
|
+
| `ui-badge` | 12px / 450 (its text span; 550 was the box) | same |
|
|
471
|
+
| `ui-tag` | Polaris Tag: 12px/450 on a 20px line, padding 0 6, radius 8, not uppercase | same |
|
|
472
|
+
| `ui-metric--lg` value / label, `ui-funnel__val` | 24/32/700 · 13px · 20/24/700 | same |
|
|
473
|
+
|
|
474
|
+
New in `kit-plain.css` (surfaces drew both by hand):
|
|
475
|
+
|
|
476
|
+
| Need | Markup |
|
|
477
|
+
|---|---|
|
|
478
|
+
| Filter chip (Polaris FilterPill's shape at the Button's density: dashed until applied) | `<div class="ui-chips"><button type="button" class="ui-chip" aria-pressed="true">Plus</button><a class="ui-chip" href="?c=us" aria-current="page">US</a></div>` |
|
|
479
|
+
| Cards on a page, 16px apart (Polaris BlockStack gap 400) | `<div class="ui-stack">…cards…</div>`, `ui-stack--tight` for 8 |
|
|
480
|
+
|
|
481
|
+
**Headings inside the shell.** In the admin a bare `<h2>` or `<p>` is body text with no margin: Polaris' global sheet
|
|
482
|
+
resets `h1…h6, p` (size 1em, regular weight, margin 0), and every heading that looks like one is a Text variant. `app-shell.css`
|
|
483
|
+
now does the same INSIDE `.gemboss-platform-shell` only, to elements without a class (a surface's `h2.x-title` keeps
|
|
484
|
+
what it had), and never inside an article the surface shows: mark post bodies, rendered markdown and previews with `ui-prose` or `data-content` (the wrappers already in the fleet are recognised by name too: `.md-body`, `.recap-md`, `.asst-md`, `.article-body`, and any class containing `prose` or `markdown`; the gate skips the same list) and they keep the browser's
|
|
485
|
+
heading scale and margins. A page heading is `ui-page-head`, a card or section heading `ui-card__title` /
|
|
486
|
+
`ui-section-head`. The kit no longer reads `--gemboss-fs-body` (14), `--gemboss-fs-h1/h2/h3`: those are the admin seller
|
|
487
|
+
app's own prose sizes; the kit is on Polaris' scale (`--ui-fs-body` 13, `--ui-fs-caption` 12, headings 14 / 20 / 24).
|
|
488
|
+
|
|
489
|
+
Not in 0.12.0 (a separate change): colour. The kit's ink and primary fill are `#1b1c1e`, Polaris' `#303030`; Polaris'
|
|
490
|
+
secondary button is a grey fill, the kit's a white one with a line.
|
|
491
|
+
|
|
492
|
+
### The density gate: `packages/ui/scripts/density.mjs` + `polaris-reference.json`
|
|
493
|
+
|
|
494
|
+
`polaris-reference.json` pins what the admin draws, role by role, with where each number was measured (admin.gemboss.ai
|
|
495
|
+
05/10/2026, Polaris 13.9.5 for Tag and the card bevel). `packages/ui/scripts/density.mjs` opens a page in Chromium, finds every
|
|
496
|
+
visible element of each role (the kit's selectors), reads computed style (text from the element that paints the first
|
|
497
|
+
glyph, as Polaris wraps its labels) and lists every value that is not the admin's. Two modes: `fine` (mouse, ≥ 768px)
|
|
498
|
+
is exact; `touch` (`--touch`, or narrower than 768) keeps typography and asks every control for ≥ 44px. Any `h1`–`h6`
|
|
499
|
+
that is not one of the admin's heading styles (20/24/700, 14/20/650, 13/20/650) is reported: that is a bare heading.
|
|
500
|
+
Not measured: sr-only text (1px), anything inside `.ui-prose` / `[data-content]`, closed `<details>`.
|
|
501
|
+
|
|
502
|
+
```
|
|
503
|
+
node scripts/visual-gate/visual-gate.mjs --url https://factory.gemboss.ai/ --density # in the official gate, every width
|
|
504
|
+
node packages/ui/scripts/density.mjs --catalog # the package's own catalog
|
|
505
|
+
node packages/ui/scripts/density.mjs --url https://factory.gemboss.ai/ --width 1280
|
|
506
|
+
node packages/ui/scripts/density.mjs --url https://factory.gemboss.ai/ --width 390 --touch
|
|
507
|
+
DENSITY_COOKIE='session=…' node packages/ui/scripts/density.mjs --url … --scope main --json
|
|
508
|
+
```
|
|
509
|
+
|
|
510
|
+
Exit 1 when anything differs, 3 when nothing was measured; "not on this page" lists roles the page does not show
|
|
511
|
+
(never read that as a pass). In visual-gate, `--density` adds a `density` check per width (touch mode at <= 768, as the
|
|
512
|
+
gate's own tap checks) that is `skip`, not pass, when the page has no kit element. On a
|
|
513
|
+
surface page, run it after upgrading the package: what it still lists is the surface's own CSS. `packages/ui/src/density.test.ts`
|
|
514
|
+
runs it on the catalog (1280 mouse, 390 finger, 390 mouse) and on the admin's own sheets, with its controls: a
|
|
515
|
+
`.ui-btn{height:32px}` or `min-height:44px` under a mouse and a bare `<h2>` turn it red; sr-only text, an article's
|
|
516
|
+
heading and the 44px floor under a finger do not.
|
|
517
|
+
|
|
439
518
|
## Popup density (0.7.3)
|
|
440
519
|
|
|
441
520
|
The kit popup (`.ui-overlay > .ui-modal`, `<dialog class="ui-modal">`, `openModal`, `Dialog`) is drawn at Polaris
|
package/catalog/index.html
CHANGED
|
@@ -6,7 +6,7 @@ body{margin:0;background:var(--gemboss-app-bg,#f1f1f1);color:var(--gemboss-text)
|
|
|
6
6
|
.cat-nav a{padding:8px 12px;border-radius:var(--gemboss-radius-md);color:var(--gemboss-text);text-decoration:none;min-height:24px}
|
|
7
7
|
.cat-nav a:hover{background:var(--gemboss-hover)}
|
|
8
8
|
.cat-head h1{margin:0 0 4px;font-size:28px}.cat-head p{margin:0 0 24px;color:var(--gemboss-text-muted)}
|
|
9
|
-
.cat section{margin:0 0 48px}.cat h2{margin:0 0 6px;font-size:20px}.cat section>p{margin:0 0 16px;color:var(--gemboss-text-muted)}
|
|
9
|
+
.cat section{margin:0 0 48px}.cat section>h2{margin:0 0 6px;font-size:20px;font-weight:650}.cat section>p{margin:0 0 16px;color:var(--gemboss-text-muted)}
|
|
10
10
|
.cat-demo{margin:0 0 16px;background:var(--gemboss-surface);border:1px solid var(--gemboss-divider);border-radius:12px;overflow:hidden}
|
|
11
11
|
.cat-demo figcaption{padding:10px 16px;font-size:13px;font-weight:600;border-bottom:1px solid var(--gemboss-divider)}
|
|
12
12
|
.cat-demo figcaption span{font-weight:400;color:var(--gemboss-text-muted)}
|
|
@@ -27,9 +27,9 @@ body{margin:0;background:var(--gemboss-app-bg,#f1f1f1);color:var(--gemboss-text)
|
|
|
27
27
|
@media (max-width:760px){.cat{grid-template-columns:1fr;padding:16px}.cat-nav{position:static;flex-direction:row;flex-wrap:wrap}}
|
|
28
28
|
</style></head><body>
|
|
29
29
|
<div class="cat"><nav class="cat-nav" aria-label="Mục"><a href="#tokens">Token</a><a href="#buttons">Nút</a><a href="#fields">Ô nhập</a><a href="#choice">Tab, nhóm nút, thẻ</a><a href="#surfaces">Thẻ, số liệu, bảng, trạng thái trống</a><a href="#report">Báo cáo</a><a href="#resizer">Thanh kéo giữa hai cột</a><a href="#modal">Hộp thoại, toast, menu (JS thuần)</a><a href="#shell">Khung app</a><a href="#nav">Chờ điều hướng</a><a href="#page">Bề rộng nội dung</a><a href="#portal">Cổng công khai: tab trên topbar, tìm kiếm, sáng / tối, người dẫn đầu</a><a href="#auth">Đăng nhập</a><a href="#chat">Thân chat</a><a href="#assistant">Trợ lý: cột phiên</a><a href="#icons">Icon</a></nav>
|
|
30
|
-
<main><header class="cat-head"><h1>@gemboss/ui 0.
|
|
30
|
+
<main><header class="cat-head"><h1>@gemboss/ui 0.12.0</h1><p>Ngôn ngữ thiết kế chung của các công cụ GemBoss. Markup dưới mỗi ví dụ là đúng thứ package render ra; bề mặt không dùng React (HTML tĩnh, Python) chép markup này và nạp <code>gemboss-ui.css</code>. Dựng từ gemboss <code>e4c3bf3203ec</code>.</p></header>
|
|
31
31
|
<section id="tokens"><h2>Token</h2><p>Đổi giao diện một bề mặt bằng cách đặt lại token, không viết đè class. Tên và giá trị đọc thẳng từ gemboss-ui.css.</p><div class="cat-swatches"><div class="cat-swatch"><i style="background:var(--gemboss-primary)"></i><code>--gemboss-primary</code><span>#1b1c1e</span></div><div class="cat-swatch"><i style="background:var(--gemboss-primary-dark)"></i><code>--gemboss-primary-dark</code><span>#000000</span></div><div class="cat-swatch"><i style="background:var(--gemboss-primary-soft)"></i><code>--gemboss-primary-soft</code><span>#f2f3f5</span></div><div class="cat-swatch"><i style="background:var(--gemboss-accent)"></i><code>--gemboss-accent</code><span>#5661f5</span></div><div class="cat-swatch"><i style="background:var(--gemboss-accent-strong)"></i><code>--gemboss-accent-strong</code><span>#3a44de</span></div><div class="cat-swatch"><i style="background:var(--gemboss-accent-soft)"></i><code>--gemboss-accent-soft</code><span>#eef0fe</span></div><div class="cat-swatch"><i style="background:var(--gemboss-text-strong)"></i><code>--gemboss-text-strong</code><span>#1b1c1e</span></div><div class="cat-swatch"><i style="background:var(--gemboss-text)"></i><code>--gemboss-text</code><span>#1b1c1e</span></div><div class="cat-swatch"><i style="background:var(--gemboss-text-muted)"></i><code>--gemboss-text-muted</code><span>#686b71</span></div><div class="cat-swatch"><i style="background:var(--gemboss-surface)"></i><code>--gemboss-surface</code><span>#ffffff</span></div><div class="cat-swatch"><i style="background:var(--gemboss-canvas)"></i><code>--gemboss-canvas</code><span>#ffffff</span></div><div class="cat-swatch"><i style="background:var(--gemboss-preview-canvas)"></i><code>--gemboss-preview-canvas</code><span>#eceef1</span></div><div class="cat-swatch"><i style="background:var(--gemboss-rail-bg)"></i><code>--gemboss-rail-bg</code><span>#ffffff</span></div><div class="cat-swatch"><i style="background:var(--gemboss-panel-bg)"></i><code>--gemboss-panel-bg</code><span>#ffffff</span></div><div class="cat-swatch"><i style="background:var(--gemboss-divider)"></i><code>--gemboss-divider</code><span>#e5e7ea</span></div><div class="cat-swatch"><i style="background:var(--gemboss-divider-soft)"></i><code>--gemboss-divider-soft</code><span>#edeff2</span></div><div class="cat-swatch"><i style="background:var(--gemboss-hover)"></i><code>--gemboss-hover</code><span>#eceef2</span></div><div class="cat-swatch"><i style="background:var(--gemboss-active-bg)"></i><code>--gemboss-active-bg</code><span>#f0f1f4</span></div><div class="cat-swatch"><i style="background:var(--gemboss-active-fg)"></i><code>--gemboss-active-fg</code><span>#1b1c1e</span></div><div class="cat-swatch"><i style="background:var(--gemboss-danger)"></i><code>--gemboss-danger</code><span>#d72c0d</span></div><div class="cat-swatch"><i style="background:var(--gemboss-danger-strong)"></i><code>--gemboss-danger-strong</code><span>#b42318</span></div><div class="cat-swatch"><i style="background:var(--gemboss-danger-soft)"></i><code>--gemboss-danger-soft</code><span>#fff0e9</span></div><div class="cat-swatch"><i style="background:var(--gemboss-danger-border)"></i><code>--gemboss-danger-border</code><span>#f5c9bc</span></div><div class="cat-swatch"><i style="background:var(--gemboss-success)"></i><code>--gemboss-success</code><span>#007f5f</span></div><div class="cat-swatch"><i style="background:var(--gemboss-success-strong)"></i><code>--gemboss-success-strong</code><span>#0a6a4c</span></div><div class="cat-swatch"><i style="background:var(--gemboss-success-soft)"></i><code>--gemboss-success-soft</code><span>#e3f1df</span></div><div class="cat-swatch"><i style="background:var(--gemboss-success-border)"></i><code>--gemboss-success-border</code><span>#b7dfcd</span></div><div class="cat-swatch"><i style="background:var(--gemboss-warning)"></i><code>--gemboss-warning</code><span>#9a6700</span></div><div class="cat-swatch"><i style="background:var(--gemboss-warning-soft)"></i><code>--gemboss-warning-soft</code><span>#fff8e0</span></div><div class="cat-swatch"><i style="background:var(--gemboss-warning-border)"></i><code>--gemboss-warning-border</code><span>#f5d569</span></div><div class="cat-swatch"><i style="background:var(--gemboss-dark-bg)"></i><code>--gemboss-dark-bg</code><span>#0a0a0c</span></div><div class="cat-swatch"><i style="background:var(--gemboss-dark-rail)"></i><code>--gemboss-dark-rail</code><span>#0e0e11</span></div><div class="cat-swatch"><i style="background:var(--gemboss-dark-surface)"></i><code>--gemboss-dark-surface</code><span>#16161a</span></div><div class="cat-swatch"><i style="background:var(--gemboss-dark-surface-2)"></i><code>--gemboss-dark-surface-2</code><span>#1e1e24</span></div><div class="cat-swatch"><i style="background:var(--gemboss-dark-divider)"></i><code>--gemboss-dark-divider</code><span>#2a2a31</span></div><div class="cat-swatch"><i style="background:var(--gemboss-dark-text)"></i><code>--gemboss-dark-text</code><span>#ededf0</span></div><div class="cat-swatch"><i style="background:var(--gemboss-dark-muted)"></i><code>--gemboss-dark-muted</code><span>#9a9aa4</span></div><div class="cat-swatch"><i style="background:var(--gemboss-field-bg)"></i><code>--gemboss-field-bg</code><span>#fdfdfd</span></div><div class="cat-swatch"><i style="background:var(--gemboss-field-bg-hover)"></i><code>--gemboss-field-bg-hover</code><span>#fafafa</span></div><div class="cat-swatch"><i style="background:var(--gemboss-field-ink)"></i><code>--gemboss-field-ink</code><span>#303030</span></div><div class="cat-swatch"><i style="background:var(--gemboss-field-placeholder)"></i><code>--gemboss-field-placeholder</code><span>#616161</span></div><div class="cat-swatch"><i style="background:var(--gemboss-field-line)"></i><code>--gemboss-field-line</code><span>#8a8a8a</span></div><div class="cat-swatch"><i style="background:var(--gemboss-field-line-hover)"></i><code>--gemboss-field-line-hover</code><span>#616161</span></div><div class="cat-swatch"><i style="background:var(--gemboss-field-line-active)"></i><code>--gemboss-field-line-active</code><span>#1a1a1a</span></div><div class="cat-swatch"><i style="background:var(--gemboss-chip-ink)"></i><code>--gemboss-chip-ink</code><span>#303633</span></div><div class="cat-swatch"><i style="background:var(--gemboss-chip-line)"></i><code>--gemboss-chip-line</code><span>#cfd6ce</span></div><div class="cat-swatch"><i style="background:var(--gemboss-chip-line-hover)"></i><code>--gemboss-chip-line-hover</code><span>#aab4ad</span></div><div class="cat-swatch"><i style="background:var(--gemboss-chip-bg-hover)"></i><code>--gemboss-chip-bg-hover</code><span>#f6f7f5</span></div><div class="cat-swatch"><i style="background:var(--gemboss-on-primary)"></i><code>--gemboss-on-primary</code><span>#ffffff</span></div><div class="cat-swatch"><i style="background:var(--gemboss-app-bg)"></i><code>--gemboss-app-bg</code><span>#ffffff</span></div></div><table class="ui-table cat-scale"><thead><tr><th>Token</th><th>Giá trị</th><th>Mẫu</th></tr></thead><tbody><tr><td><code>--gemboss-fs-micro</code></td><td>11px</td><td style="font-size:var(--gemboss-fs-micro)">Ngôn ngữ thiết kế chung</td></tr><tr><td><code>--gemboss-fs-caption</code></td><td>12px</td><td style="font-size:var(--gemboss-fs-caption)">Ngôn ngữ thiết kế chung</td></tr><tr><td><code>--gemboss-fs-body</code></td><td>14px</td><td style="font-size:var(--gemboss-fs-body)">Ngôn ngữ thiết kế chung</td></tr><tr><td><code>--gemboss-fs-body-lg</code></td><td>16px</td><td style="font-size:var(--gemboss-fs-body-lg)">Ngôn ngữ thiết kế chung</td></tr><tr><td><code>--gemboss-fs-h3</code></td><td>16px</td><td style="font-size:var(--gemboss-fs-h3)">Ngôn ngữ thiết kế chung</td></tr><tr><td><code>--gemboss-fs-h2</code></td><td>20px</td><td style="font-size:var(--gemboss-fs-h2)">Ngôn ngữ thiết kế chung</td></tr><tr><td><code>--gemboss-fs-h1</code></td><td>24px</td><td style="font-size:var(--gemboss-fs-h1)">Ngôn ngữ thiết kế chung</td></tr><tr><td><code>--gemboss-fs-display</code></td><td>30px</td><td style="font-size:var(--gemboss-fs-display)">Ngôn ngữ thiết kế chung</td></tr><tr><td><code>--gemboss-radius-xs</code></td><td>4px</td><td><i class="cat-radius" style="border-radius:var(--gemboss-radius-xs)"></i></td></tr><tr><td><code>--gemboss-radius-sm</code></td><td>6px</td><td><i class="cat-radius" style="border-radius:var(--gemboss-radius-sm)"></i></td></tr><tr><td><code>--gemboss-radius-md</code></td><td>8px</td><td><i class="cat-radius" style="border-radius:var(--gemboss-radius-md)"></i></td></tr><tr><td><code>--gemboss-radius-lg</code></td><td>12px</td><td><i class="cat-radius" style="border-radius:var(--gemboss-radius-lg)"></i></td></tr><tr><td><code>--gemboss-radius-xl</code></td><td>16px</td><td><i class="cat-radius" style="border-radius:var(--gemboss-radius-xl)"></i></td></tr><tr><td><code>--gemboss-radius-2xl</code></td><td>20px</td><td><i class="cat-radius" style="border-radius:var(--gemboss-radius-2xl)"></i></td></tr><tr><td><code>--gemboss-radius-full</code></td><td>999px</td><td><i class="cat-radius" style="border-radius:var(--gemboss-radius-full)"></i></td></tr><tr><td><code>--gemboss-shadow-resting</code></td><td class="cat-small">0 1px 2px rgba(31, 30, 29, 0.04), 0 2px 6px rgba(31, 30, 29, 0.06)</td><td><i class="cat-radius" style="box-shadow:var(--gemboss-shadow-resting);border:0"></i></td></tr><tr><td><code>--gemboss-shadow-raised</code></td><td class="cat-small">0 4px 16px rgba(31, 30, 29, 0.10)</td><td><i class="cat-radius" style="box-shadow:var(--gemboss-shadow-raised);border:0"></i></td></tr><tr><td><code>--gemboss-shadow-overlay</code></td><td class="cat-small">0 16px 48px rgba(31, 30, 29, 0.18)</td><td><i class="cat-radius" style="box-shadow:var(--gemboss-shadow-overlay);border:0"></i></td></tr></tbody></table></section>
|
|
32
|
-
<section id="buttons"><h2>Nút</h2><p>Một lớp <code>ui-btn</code>, ba biến thể, tông đỏ, một cỡ nhỏ. Cao
|
|
32
|
+
<section id="buttons"><h2>Nút</h2><p>Một lớp <code>ui-btn</code>, ba biến thể, tông đỏ, một cỡ nhỏ. Cao 28px dưới chuột như Button của Polaris (ô nhập và ô chọn 32, như TextField), 44px dưới ngón tay và ở khổ điện thoại, cỡ nhỏ cũng vậy. Dùng được trên <code><button></code> lẫn <code><a></code> (căn giữa sẵn).</p><figure class="cat-demo"><figcaption>Mặc định · chính · ghost · nhỏ · tắt</figcaption><div class="cat-live"><div class="cat-row"><button type="button" class="ui-btn">Lưu nháp</button><button type="button" class="ui-btn ui-btn--primary">Xuất bản</button><button type="button" class="ui-btn ui-btn--ghost">Huỷ</button><button type="button" class="ui-btn ui-btn--sm">Nhỏ</button><button type="button" class="ui-btn ui-btn--primary" disabled>Đang lưu…</button><a class="ui-btn" href="#buttons">Link dạng nút</a></div></div><details class="cat-code"><summary>Markup</summary><pre><code><div class="cat-row">
|
|
33
33
|
<button type="button" class="ui-btn">Lưu nháp</button>
|
|
34
34
|
<button type="button" class="ui-btn ui-btn--primary">Xuất bản</button>
|
|
35
35
|
<button type="button" class="ui-btn ui-btn--ghost">Huỷ</button>
|
|
@@ -158,6 +158,10 @@ body{margin:0;background:var(--gemboss-app-bg,#f1f1f1);color:var(--gemboss-text)
|
|
|
158
158
|
<a class="ui-tag ui-tag--chip" href="#">Judge.me Product Reviews</a>
|
|
159
159
|
<a class="ui-tag ui-tag--chip" href="#">Klaviyo</a>
|
|
160
160
|
<a class="ui-tag ui-tag--chip" href="#">Instafeed</a>
|
|
161
|
+
</div></code></pre></details></figure><figure class="cat-demo"><figcaption>Chip lọc (<code>ui-chip</code>: hình FilterPill của Polaris, cao như nút 28px, nét đứt khi chưa áp; <code>aria-pressed</code> lọc tại chỗ, <code>aria-current</code> lọc bằng URL)</figcaption><div class="cat-live"><div class="ui-chips"><button type="button" class="ui-chip" aria-pressed="true">Shopify Plus</button><button type="button" class="ui-chip" aria-pressed="false">Có review app</button><a class="ui-chip" href="#">Hoa Kỳ</a></div></div><details class="cat-code"><summary>Markup</summary><pre><code><div class="ui-chips">
|
|
162
|
+
<button type="button" class="ui-chip" aria-pressed="true">Shopify Plus</button>
|
|
163
|
+
<button type="button" class="ui-chip" aria-pressed="false">Có review app</button>
|
|
164
|
+
<a class="ui-chip" href="#">Hoa Kỳ</a>
|
|
161
165
|
</div></code></pre></details></figure></section>
|
|
162
166
|
<section id="surfaces"><h2>Thẻ, số liệu, bảng, trạng thái trống</h2><figure class="cat-demo"><figcaption>Tiêu đề trang (<code>ui-page-head</code>) · chữ phụ (<code>ui-muted</code>)</figcaption><div class="cat-live"><div class="ui-page-head"><h1>Đối thủ</h1><p>Page builder nào đang tích hợp với ai.</p></div><p class="ui-muted">Cập nhật 01/10, 300 trang app đã đọc.</p></div><details class="cat-code"><summary>Markup</summary><pre><code><div class="ui-page-head">
|
|
163
167
|
<h1>Đối thủ</h1>
|
|
@@ -302,7 +306,16 @@ body{margin:0;background:var(--gemboss-app-bg,#f1f1f1);color:var(--gemboss-text)
|
|
|
302
306
|
<span>2 giờ trước</span>
|
|
303
307
|
</div>
|
|
304
308
|
</article>
|
|
305
|
-
</div></code></pre></details></figure><figure class="cat-demo"><figcaption>Card</figcaption><div class="cat-live"><div class="ui-card"
|
|
309
|
+
</div></code></pre></details></figure><figure class="cat-demo"><figcaption>Card</figcaption><div class="cat-live"><div class="ui-card">Một khối nội dung. Nền, một viền 1px <code>--ui-border</code>, bóng shadow-100 của Polaris, bo góc 12 và đệm 16 lấy từ gói.</div></div><details class="cat-code"><summary>Markup</summary><pre><code><div class="ui-card">Một khối nội dung. Nền, một viền 1px <code>--ui-border</code>, bóng shadow-100 của Polaris, bo góc 12 và đệm 16 lấy từ gói.</div></code></pre></details></figure><figure class="cat-demo"><figcaption>Xếp card (<code>ui-stack</code>: khe 16px giữa các khối, như BlockStack gap 400 của Polaris)</figcaption><div class="cat-live"><div class="ui-stack"><div class="ui-card"><h2 class="ui-card__title">Kênh</h2><p class="ui-muted">Lượt đọc theo nguồn.</p></div><div class="ui-card"><h2 class="ui-card__title">Ngôn ngữ</h2><p class="ui-muted">vi · en · zh.</p></div></div></div><details class="cat-code"><summary>Markup</summary><pre><code><div class="ui-stack">
|
|
310
|
+
<div class="ui-card">
|
|
311
|
+
<h2 class="ui-card__title">Kênh</h2>
|
|
312
|
+
<p class="ui-muted">Lượt đọc theo nguồn.</p>
|
|
313
|
+
</div>
|
|
314
|
+
<div class="ui-card">
|
|
315
|
+
<h2 class="ui-card__title">Ngôn ngữ</h2>
|
|
316
|
+
<p class="ui-muted">vi · en · zh.</p>
|
|
317
|
+
</div>
|
|
318
|
+
</div></code></pre></details></figure><figure class="cat-demo"><figcaption>Đầu thẻ có nút (<code>ui-card__head</code>)</figcaption><div class="cat-live"><div class="ui-card"><div class="ui-card__head"><h3 class="ui-card__title">Hạng đối tác</h3><div><button type="button" class="ui-btn ui-btn--primary">Đổi hạng</button><button type="button" class="ui-btn">Kết thúc</button></div></div><p class="ui-muted" style="margin:0">Partner từ 01/08/2026.</p></div></div><details class="cat-code"><summary>Markup</summary><pre><code><div class="ui-card">
|
|
306
319
|
<div class="ui-card__head">
|
|
307
320
|
<h3 class="ui-card__title">Hạng đối tác</h3>
|
|
308
321
|
<div>
|
|
@@ -1577,7 +1590,7 @@ body{margin:0;background:var(--gemboss-app-bg,#f1f1f1);color:var(--gemboss-text)
|
|
|
1577
1590
|
<button type="submit" aria-label="Gửi">↑</button>
|
|
1578
1591
|
</form>
|
|
1579
1592
|
</div></code></pre></details></figure></section>
|
|
1580
|
-
<section id="assistant"><h2>Trợ lý: cột phiên</h2><p><code>SessionRail</code> (React). Khung toàn màn hình / cửa sổ nổi / cột phải cao hết màn (<code>allowSide</code>) / thanh là <code>AssistantHost</code>, cần React vì có trạng thái.</p><figure class="cat-demo"><figcaption>SessionRail</figcaption><div class="cat-live"><div style="height:360px;display:flex"><aside class="gemboss-assistant-rail"><div class="gemboss-assistant-rail-top"><button type="button" class="gemboss-assistant-newchat" title="Phiên mới"><svg viewBox="0 0 20 20" aria-hidden="true" focusable="false"><g fill="none" stroke="currentColor" stroke-width="1.6" stroke-linecap="round" stroke-linejoin="round"><path d="M11 4H5.5A1.5 1.5 0 0 0 4 5.5v9A1.5 1.5 0 0 0 5.5 16h9a1.5 1.5 0 0 0 1.5-1.5V9"></path><path d="M14.5 3.5l2 2L10 12H8v-2z"></path></g></svg><span>Phiên mới</span></button><button type="button" class="gemboss-assistant-collapse" aria-label="Collapse sidebar" title="Collapse"><svg viewBox="0 0 20 20" aria-hidden="true" focusable="false"><g fill="none" stroke="currentColor" stroke-width="1.6" stroke-linecap="round" stroke-linejoin="round"><path d="M12 5l-5 5 5 5"></path></g></svg></button></div><div class="gemboss-assistant-search gemboss-field gemboss-field--group"><svg viewBox="0 0 20 20" aria-hidden="true" focusable="false"><g fill="none" stroke="currentColor" stroke-width="1.6" stroke-linecap="round" stroke-linejoin="round"><circle cx="9" cy="9" r="5"></circle><path d="M13 13l3.5 3.5"></path></g></svg><input class="gemboss-field__bare" placeholder="Tìm phiên…" aria-label="Search history" value=""/><kbd class="gemboss-assistant-kbd">/</kbd></div><div class="gemboss-assistant-threads"><div class="gemboss-assistant-group"><div class="gemboss-assistant-group-label">Đã ghim</div><div class="gemboss-assistant-thread"><button type="button" class="gemboss-assistant-thread-main" title="So sánh advertorial với listicle"><span class="gemboss-assistant-thread-titlerow"><svg viewBox="0 0 20 20" class="gemboss-assistant-pin-dot" aria-hidden="true" focusable="false"><path d="M8 3.5h4l-.5 5 2.5 2.5H6l2.5-2.5z" fill="currentColor"></path><path d="M10 11v5.5" stroke="currentColor" stroke-width="1.6" stroke-linecap="round"></path></svg><span class="gemboss-assistant-thread-title">So sánh advertorial với listicle</span></span><span class="gemboss-assistant-thread-meta">
|
|
1593
|
+
<section id="assistant"><h2>Trợ lý: cột phiên</h2><p><code>SessionRail</code> (React). Khung toàn màn hình / cửa sổ nổi / cột phải cao hết màn (<code>allowSide</code>) / thanh là <code>AssistantHost</code>, cần React vì có trạng thái.</p><figure class="cat-demo"><figcaption>SessionRail</figcaption><div class="cat-live"><div style="height:360px;display:flex"><aside class="gemboss-assistant-rail"><div class="gemboss-assistant-rail-top"><button type="button" class="gemboss-assistant-newchat" title="Phiên mới"><svg viewBox="0 0 20 20" aria-hidden="true" focusable="false"><g fill="none" stroke="currentColor" stroke-width="1.6" stroke-linecap="round" stroke-linejoin="round"><path d="M11 4H5.5A1.5 1.5 0 0 0 4 5.5v9A1.5 1.5 0 0 0 5.5 16h9a1.5 1.5 0 0 0 1.5-1.5V9"></path><path d="M14.5 3.5l2 2L10 12H8v-2z"></path></g></svg><span>Phiên mới</span></button><button type="button" class="gemboss-assistant-collapse" aria-label="Collapse sidebar" title="Collapse"><svg viewBox="0 0 20 20" aria-hidden="true" focusable="false"><g fill="none" stroke="currentColor" stroke-width="1.6" stroke-linecap="round" stroke-linejoin="round"><path d="M12 5l-5 5 5 5"></path></g></svg></button></div><div class="gemboss-assistant-search gemboss-field gemboss-field--group"><svg viewBox="0 0 20 20" aria-hidden="true" focusable="false"><g fill="none" stroke="currentColor" stroke-width="1.6" stroke-linecap="round" stroke-linejoin="round"><circle cx="9" cy="9" r="5"></circle><path d="M13 13l3.5 3.5"></path></g></svg><input class="gemboss-field__bare" placeholder="Tìm phiên…" aria-label="Search history" value=""/><kbd class="gemboss-assistant-kbd">/</kbd></div><div class="gemboss-assistant-threads"><div class="gemboss-assistant-group"><div class="gemboss-assistant-group-label">Đã ghim</div><div class="gemboss-assistant-thread"><button type="button" class="gemboss-assistant-thread-main" title="So sánh advertorial với listicle"><span class="gemboss-assistant-thread-titlerow"><svg viewBox="0 0 20 20" class="gemboss-assistant-pin-dot" aria-hidden="true" focusable="false"><path d="M8 3.5h4l-.5 5 2.5 2.5H6l2.5-2.5z" fill="currentColor"></path><path d="M10 11v5.5" stroke="currentColor" stroke-width="1.6" stroke-linecap="round"></path></svg><span class="gemboss-assistant-thread-title">So sánh advertorial với listicle</span></span><span class="gemboss-assistant-thread-meta">27/8/2026</span></button><div class="gemboss-assistant-thread-actions"><button type="button" class="gemboss-assistant-thread-act" aria-label="Options"><svg viewBox="0 0 20 20" aria-hidden="true" focusable="false"><g fill="none" stroke="currentColor" stroke-width="1.6" stroke-linecap="round" stroke-linejoin="round"><circle cx="5" cy="10" r=".8"></circle><circle cx="10" cy="10" r=".8"></circle><circle cx="15" cy="10" r=".8"></circle></g></svg></button></div></div></div><div class="gemboss-assistant-group"><div class="gemboss-assistant-group-label">Hôm nay</div><div class="gemboss-assistant-thread active"><button type="button" class="gemboss-assistant-thread-main" title="Store nào đang dựng loạt landing?"><span class="gemboss-assistant-thread-titlerow"><span class="gemboss-assistant-thread-title">Store nào đang dựng loạt landing?</span></span><span class="gemboss-assistant-thread-meta">3 giờ trước</span></button><div class="gemboss-assistant-thread-actions"><button type="button" class="gemboss-assistant-thread-act" aria-label="Options"><svg viewBox="0 0 20 20" aria-hidden="true" focusable="false"><g fill="none" stroke="currentColor" stroke-width="1.6" stroke-linecap="round" stroke-linejoin="round"><circle cx="5" cy="10" r=".8"></circle><circle cx="10" cy="10" r=".8"></circle><circle cx="15" cy="10" r=".8"></circle></g></svg></button></div></div></div><div class="gemboss-assistant-group"><div class="gemboss-assistant-group-label">Hôm qua</div><div class="gemboss-assistant-thread"><button type="button" class="gemboss-assistant-thread-main" title="Landing điểm cao nhất của corpus"><span class="gemboss-assistant-thread-titlerow"><span class="gemboss-assistant-thread-title">Landing điểm cao nhất của corpus</span></span><span class="gemboss-assistant-thread-meta">1 ngày trước</span></button><div class="gemboss-assistant-thread-actions"><button type="button" class="gemboss-assistant-thread-act" aria-label="Options"><svg viewBox="0 0 20 20" aria-hidden="true" focusable="false"><g fill="none" stroke="currentColor" stroke-width="1.6" stroke-linecap="round" stroke-linejoin="round"><circle cx="5" cy="10" r=".8"></circle><circle cx="10" cy="10" r=".8"></circle><circle cx="15" cy="10" r=".8"></circle></g></svg></button></div></div></div></div></aside></div></div><details class="cat-code"><summary>Markup</summary><pre><code><div style="height:360px;display:flex">
|
|
1581
1594
|
<aside class="gemboss-assistant-rail">
|
|
1582
1595
|
<div class="gemboss-assistant-rail-top">
|
|
1583
1596
|
<button type="button" class="gemboss-assistant-newchat" title="Phiên mới">
|
|
@@ -1626,7 +1639,7 @@ body{margin:0;background:var(--gemboss-app-bg,#f1f1f1);color:var(--gemboss-text)
|
|
|
1626
1639
|
</svg>
|
|
1627
1640
|
<span class="gemboss-assistant-thread-title">So sánh advertorial với listicle</span>
|
|
1628
1641
|
</span>
|
|
1629
|
-
<span class="gemboss-assistant-thread-meta">
|
|
1642
|
+
<span class="gemboss-assistant-thread-meta">27/8/2026</span>
|
|
1630
1643
|
</button>
|
|
1631
1644
|
<div class="gemboss-assistant-thread-actions">
|
|
1632
1645
|
<button type="button" class="gemboss-assistant-thread-act" aria-label="Options">
|