@gemboss/ui 0.1.1 → 0.2.1

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/README.md CHANGED
@@ -109,6 +109,36 @@ Its styles are the `gemboss-assistant-*` rules in `packages/ui/src/shell.css` (t
109
109
  @imports too), and they reach you through `gemboss-ui.css` together with `gemboss-field.css`. The admin passes a second tab ("Talk to a person", gemcare) through `secondTab` and its button
110
110
  through `fullActions`; a surface without those leaves them out.
111
111
 
112
+ ## Resizable panels
113
+
114
+ `ui-resizer` is the seam a person drags between two panels; `ui-resizing` on `<body>` is the drag in
115
+ progress (`dragging` on the seam itself is optional and keeps its grip lit). The admin's four editors
116
+ (chat | preview) use them; they are made for gemcare's inbox columns too, which adopt them at their
117
+ next `ui:sync`. The CSS owns the LOOK: a grip that appears on hover, on
118
+ keyboard focus and while dragging; a 24px finger band on coarse pointers that keeps the visible seam
119
+ thin; and a full-page shield while dragging, so an iframe never swallows the pointer.
120
+
121
+ ```html
122
+ <div class="ui-resizer" role="separator" aria-orientation="vertical" tabindex="0"
123
+ aria-label="Conversation list width" aria-valuenow="340" aria-valuemin="260" aria-valuemax="520"></div>
124
+ ```
125
+
126
+ The surface owns where the seam sits and what it does. Five rules, each paid for once in the admin
127
+ (`apps/admin/src/components/shell/useResizableChatPanel.ts` holds the measurements):
128
+
129
+ 1. **Pointer events, not mouse events.** `mousedown` never fires for a finger.
130
+ 2. **Keyboard.** A focusable separator that ignores keys is a control that does nothing: arrows move
131
+ it, Home / End go to the floor and the ceiling. Leave Alt / Cmd / Ctrl + arrow to the browser
132
+ (Back, Forward), and say the REAL ceiling in `aria-valuemax`, not the constant.
133
+ 3. **Clamp to the box, not to a constant.** A width saved on a 1920px screen follows the person to a
134
+ 1280px one. The ceiling is what the box can spare after the other panel's floor.
135
+ 4. **Release on `pointerup`, `pointercancel` and window `blur`.** A missed release leaves the shield
136
+ over the page and nothing can be clicked.
137
+ 5. **Remember per browser** (localStorage), and recompute the clamp when the box changes size.
138
+
139
+ React surfaces: `useResizableChatPanel` in the admin is the reference. Others write the same markup and
140
+ the five rules by hand; the catalog's "Thanh kéo giữa hai cột" shows the markup.
141
+
112
142
  ## The topbar kit: lockup, account, icons
113
143
 
114
144
  What goes INTO the frame, so a surface does not draw its own (28/09/2026: GemFactory's rail icons came
@@ -139,6 +169,11 @@ import { AppShell, BrandLockup, AccountMenu, AccountMenuItem, Icon, RailItem } f
139
169
  applications that integrate with Shopify. Draw a missing one HERE, not in the surface: every rail
140
170
  icon must keep `fill="none"` on its inner `<g>`, because `.gnav-ico svg { fill: currentColor }`
141
171
  outranks an attribute on the `<svg>` itself and paints an outline icon solid.
172
+ - `Menu` / `MenuItem` / `MenuSeparator` (0.2.1): the "⋯" action menu. Same `<details>` rule as the account
173
+ menu (works as plain markup; with React it closes on an outside click, on Escape with focus back on the
174
+ trigger, and after a button row's handler). Rows share the account menu's row style. `MenuItem` is a link
175
+ (`href`) or a button; `disabled` on a link drops the href and sets `aria-disabled`; `className` is added
176
+ to the row's class.
142
177
 
143
178
  ## The catalog: every token, class and component, with its markup
144
179
 
@@ -185,6 +220,7 @@ something the base cannot express, add a token or a prop here, and every surface
185
220
  |---|---|
186
221
  | `gemboss-ui.css` | built at pack time: `apps/admin/scripts/export-ui-css.mjs` (tokens + kit + field + `packages/ui/src/shell.css`, with Polaris `--p-*` resolved to their fallbacks) + `packages/ui/src/app-shell.css` + `packages/ui/src/auth.css` + `packages/ui/src/assistant.css` |
187
222
  | `packages/ui/src/shell.css` | the SHARED SHELL (rail, topbar, main, mobile drawer, the assistant's thread rail, popover surface, account chip). The admin's `gemboss-shell.css` @imports it on line 2; the export refuses a shared-shell rule in the admin's sheet or an admin-only rule here (one owner). |
223
+ | `packages/ui/src/kit-plain.css` | primitives for surfaces that render plain HTML, not React (0.2.1): menu, key/value list, icon button. Shipped inside `gemboss-ui.css`; the admin does not import it (its first-load CSS budget has ~0.1 KB headroom). |
188
224
  | `packages/ui/src/**/*.tsx` | the components, as TypeScript source. Next: add `@gemboss/ui` to `transpilePackages`. Vite compiles it as is. |
189
225
 
190
226
  `gemboss-ui.css` is never committed and never edited. To change a colour or a radius, change
@@ -205,4 +241,22 @@ Publish from a worktree at the MERGED commit on `main`, not from a branch, so th
205
241
  to publish (403) from an account without two-factor auth; the account needs 2FA set to
206
242
  "Authorization and publishing".
207
243
 
244
+ The account's second factor is a passkey, so run the publish in a real terminal as
245
+ `npm publish --auth-type=web` and approve the page it opens (each approval page lives 5 minutes).
246
+ Without a terminal npm answers `EOTP` instead of offering the page. After `+ @gemboss/ui@x.y.z`
247
+ npm says the package "is being processed": `npm view` returns 404 for a few more minutes (0.1.1,
248
+ 30/09/2026). Publishing from CI with npm trusted publishing needs a GitHub-hosted runner, and this
249
+ repo's are blocked by the Actions budget since 12/09/2026 (see `admin-freshness.yml`).
250
+
208
251
  Consumers pin a version; a bump is a PR in their repo, not a surprise.
252
+
253
+ ## Who is on which version
254
+
255
+ ```bash
256
+ npm run fleet --prefix packages/ui # every surface vs the npm release (reads their repos with `gh`)
257
+ node packages/ui/scripts/fleet.mjs --release-only # main vs npm only; CI runs this as a warning
258
+ ```
259
+
260
+ Compared by content: sha256 of `gemboss-ui.css` minus its `gemboss commit:` line, so a gemboss commit
261
+ that leaves the design system alone does not make everyone look stale. Add a row to `CONSUMERS` in
262
+ `packages/ui/scripts/fleet.mjs` when a surface starts using the package.
@@ -26,8 +26,8 @@ body{margin:0;background:var(--gemboss-app-bg,#f1f1f1);color:var(--gemboss-text)
26
26
 
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
- <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="#modal">Hộp thoại</a><a href="#shell">Khung app</a><a href="#auth">Đăng nhập</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.1.1</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>c41e1cabde7b</code>.</p></header>
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="#resizer">Thanh kéo giữa hai cột</a><a href="#modal">Hộp thoại</a><a href="#shell">Khung app</a><a href="#auth">Đăng nhập</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.2.1</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>be1da9b1254e</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
32
  <section id="buttons"><h2>Nút</h2><p>Một lớp <code>ui-btn</code>, ba biến thể, một cỡ nhỏ. Dùng được trên <code>&lt;button&gt;</code> lẫn <code>&lt;a&gt;</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>&lt;div class=&quot;cat-row&quot;&gt;
33
33
  &lt;button type=&quot;button&quot; class=&quot;ui-btn&quot;&gt;Lưu nháp&lt;/button&gt;
@@ -37,8 +37,9 @@ body{margin:0;background:var(--gemboss-app-bg,#f1f1f1);color:var(--gemboss-text)
37
37
  &lt;button type=&quot;button&quot; class=&quot;ui-btn ui-btn--primary&quot; disabled&gt;Đang lưu…&lt;/button&gt;
38
38
  &lt;a class=&quot;ui-btn&quot; href=&quot;#buttons&quot;&gt;Link dạng nút&lt;/a&gt;
39
39
  &lt;/div&gt;</code></pre></details></figure></section>
40
- <section id="fields"><h2>Ô nhập</h2><p>Mọi ô chữ dùng <code>gemboss-field</code>: cùng viền, cùng focus, 44px trên màn chạm.</p><figure class="cat-demo"><figcaption>Ô chữ · ô có biểu tượng · chọn · vùng chữ</figcaption><div class="cat-live"><div class="cat-stack"><input class="gemboss-field" placeholder="Tên chiến dịch"><label class="gemboss-field gemboss-field--group"><svg viewBox="0 0 20 20" width="20" height="20" aria-hidden="true" focusable="false"><g fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"><circle cx="8.8" cy="8.8" r="5.3"></circle><path d="M12.8 12.8 17 17"></path></g></svg><input class="gemboss-field__bare" placeholder="Tìm store theo domain…"></label><select class="ui-select"><option>Mọi ngành</option><option>Mỹ phẩm</option></select><textarea class="gemboss-field" rows="4" placeholder="Ghi chú"></textarea></div></div><details class="cat-code"><summary>Markup</summary><pre><code>&lt;div class=&quot;cat-stack&quot;&gt;
41
- &lt;input class=&quot;gemboss-field&quot; placeholder=&quot;Tên chiến dịch&quot;&gt;
40
+ <section id="fields"><h2>Ô nhập</h2><p>Mọi ô chữ dùng <code>gemboss-field</code>: cùng viền, cùng focus, 44px trên màn chạm.</p><figure class="cat-demo"><figcaption>Ô chữ · ô có biểu tượng · chọn · vùng chữ</figcaption><div class="cat-live"><div class="cat-stack"><label class="ui-label" for="cat-f1">Tên chiến dịch</label><input id="cat-f1" class="gemboss-field" placeholder="Tên chiến dịch"><label class="gemboss-field gemboss-field--group"><svg viewBox="0 0 20 20" width="20" height="20" aria-hidden="true" focusable="false"><g fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"><circle cx="8.8" cy="8.8" r="5.3"></circle><path d="M12.8 12.8 17 17"></path></g></svg><input class="gemboss-field__bare" placeholder="Tìm store theo domain…"></label><select class="ui-select"><option>Mọi ngành</option><option>Mỹ phẩm</option></select><textarea class="gemboss-field" rows="4" placeholder="Ghi chú"></textarea><textarea class="ui-textarea" placeholder="ui-textarea: cùng họ, cao sẵn 96px"></textarea><label class="ui-check"><input type="checkbox" checked> Chỉ thứ đã duyệt</label><label class="ui-check"><input type="checkbox"> Khoá preset</label></div></div><details class="cat-code"><summary>Markup</summary><pre><code>&lt;div class=&quot;cat-stack&quot;&gt;
41
+ &lt;label class=&quot;ui-label&quot; for=&quot;cat-f1&quot;&gt;Tên chiến dịch&lt;/label&gt;
42
+ &lt;input id=&quot;cat-f1&quot; class=&quot;gemboss-field&quot; placeholder=&quot;Tên chiến dịch&quot;&gt;
42
43
  &lt;label class=&quot;gemboss-field gemboss-field--group&quot;&gt;
43
44
  &lt;svg viewBox=&quot;0 0 20 20&quot; width=&quot;20&quot; height=&quot;20&quot; aria-hidden=&quot;true&quot; focusable=&quot;false&quot;&gt;
44
45
  &lt;g fill=&quot;none&quot; stroke=&quot;currentColor&quot; stroke-width=&quot;1.5&quot; stroke-linecap=&quot;round&quot; stroke-linejoin=&quot;round&quot;&gt;
@@ -56,6 +57,12 @@ body{margin:0;background:var(--gemboss-app-bg,#f1f1f1);color:var(--gemboss-text)
56
57
  &lt;/select&gt;
57
58
  &lt;textarea class=&quot;gemboss-field&quot; rows=&quot;4&quot; placeholder=&quot;Ghi chú&quot;&gt;
58
59
  &lt;/textarea&gt;
60
+ &lt;textarea class=&quot;ui-textarea&quot; placeholder=&quot;ui-textarea: cùng họ, cao sẵn 96px&quot;&gt;
61
+ &lt;/textarea&gt;
62
+ &lt;label class=&quot;ui-check&quot;&gt;
63
+ &lt;input type=&quot;checkbox&quot; checked&gt; Chỉ thứ đã duyệt&lt;/label&gt;
64
+ &lt;label class=&quot;ui-check&quot;&gt;
65
+ &lt;input type=&quot;checkbox&quot;&gt; Khoá preset&lt;/label&gt;
59
66
  &lt;/div&gt;</code></pre></details></figure></section>
60
67
  <section id="choice"><h2>Tab, nhóm nút, thẻ</h2><figure class="cat-demo"><figcaption>Tab (<code>aria-selected</code> quyết định tab đang chọn)</figcaption><div class="cat-live"><div class="ui-tabs" role="tablist"><button type="button" role="tab" aria-selected="true">Tổng quan</button><button type="button" role="tab" aria-selected="false">Chi tiết</button><button type="button" role="tab" aria-selected="false" disabled>Sắp có</button></div></div><details class="cat-code"><summary>Markup</summary><pre><code>&lt;div class=&quot;ui-tabs&quot; role=&quot;tablist&quot;&gt;
61
68
  &lt;button type=&quot;button&quot; role=&quot;tab&quot; aria-selected=&quot;true&quot;&gt;Tổng quan&lt;/button&gt;
@@ -65,20 +72,136 @@ body{margin:0;background:var(--gemboss-app-bg,#f1f1f1);color:var(--gemboss-text)
65
72
  &lt;button type=&quot;button&quot; aria-pressed=&quot;true&quot; class=&quot;is-text active&quot;&gt;Kanban&lt;/button&gt;
66
73
  &lt;button type=&quot;button&quot; aria-pressed=&quot;false&quot; class=&quot;is-text&quot;&gt;Nhóm&lt;/button&gt;
67
74
  &lt;button type=&quot;button&quot; aria-pressed=&quot;false&quot; class=&quot;is-text&quot;&gt;Danh sách&lt;/button&gt;
75
+ &lt;/div&gt;</code></pre></details></figure><figure class="cat-demo"><figcaption>Nút icon · menu (<code>details.ui-menu</code>, mở không cần script) · danh sách nhãn-giá trị</figcaption><div class="cat-live"><div class="cat-row" style="align-items:flex-start;min-height:260px"><button type="button" class="ui-btn ui-btn--icon" aria-label="Đóng"><svg viewBox="0 0 20 20" width="20" height="20" aria-hidden="true" focusable="false"><g fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"><path d="M5 5l10 10M15 5 5 15"></path></g></svg></button><details class="ui-menu" open><summary class="ui-btn ui-btn--icon" aria-label="Thêm thao tác" title="Thêm thao tác"><svg viewBox="0 0 20 20" width="20" height="20" aria-hidden="true" focusable="false"><g fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"><circle cx="4.5" cy="10" r="1"></circle><circle cx="10" cy="10" r="1"></circle><circle cx="15.5" cy="10" r="1"></circle></g></svg></summary><div class="ui-menu__list gemboss-popover-surface"><button type="button" class="ui-menu__item">Chép #12<span class="ui-menu__hint">dán vào Claude Code</span></button><a class="ui-menu__item" href="#choice">Mở trang riêng</a><hr class="ui-menu__sep"/><button type="button" class="ui-menu__item ui-menu__item--danger">Xoá…</button></div></details><dl class="ui-kv" style="flex-basis:100%"><dt>Người dựng</dt><dd>Lily</dd><dt>Người duyệt</dt><dd>chưa</dd><dt>Báo cáo</dt><dd>research/kho-section-can-build-2026-09-28.md</dd></dl></div></div><details class="cat-code"><summary>Markup</summary><pre><code>&lt;div class=&quot;cat-row&quot; style=&quot;align-items:flex-start;min-height:260px&quot;&gt;
76
+ &lt;button type=&quot;button&quot; class=&quot;ui-btn ui-btn--icon&quot; aria-label=&quot;Đóng&quot;&gt;
77
+ &lt;svg viewBox=&quot;0 0 20 20&quot; width=&quot;20&quot; height=&quot;20&quot; aria-hidden=&quot;true&quot; focusable=&quot;false&quot;&gt;
78
+ &lt;g fill=&quot;none&quot; stroke=&quot;currentColor&quot; stroke-width=&quot;1.5&quot; stroke-linecap=&quot;round&quot; stroke-linejoin=&quot;round&quot;&gt;
79
+ &lt;path d=&quot;M5 5l10 10M15 5 5 15&quot;&gt;
80
+ &lt;/path&gt;
81
+ &lt;/g&gt;
82
+ &lt;/svg&gt;
83
+ &lt;/button&gt;
84
+ &lt;details class=&quot;ui-menu&quot; open&gt;
85
+ &lt;summary class=&quot;ui-btn ui-btn--icon&quot; aria-label=&quot;Thêm thao tác&quot; title=&quot;Thêm thao tác&quot;&gt;
86
+ &lt;svg viewBox=&quot;0 0 20 20&quot; width=&quot;20&quot; height=&quot;20&quot; aria-hidden=&quot;true&quot; focusable=&quot;false&quot;&gt;
87
+ &lt;g fill=&quot;none&quot; stroke=&quot;currentColor&quot; stroke-width=&quot;1.5&quot; stroke-linecap=&quot;round&quot; stroke-linejoin=&quot;round&quot;&gt;
88
+ &lt;circle cx=&quot;4.5&quot; cy=&quot;10&quot; r=&quot;1&quot;&gt;
89
+ &lt;/circle&gt;
90
+ &lt;circle cx=&quot;10&quot; cy=&quot;10&quot; r=&quot;1&quot;&gt;
91
+ &lt;/circle&gt;
92
+ &lt;circle cx=&quot;15.5&quot; cy=&quot;10&quot; r=&quot;1&quot;&gt;
93
+ &lt;/circle&gt;
94
+ &lt;/g&gt;
95
+ &lt;/svg&gt;
96
+ &lt;/summary&gt;
97
+ &lt;div class=&quot;ui-menu__list gemboss-popover-surface&quot;&gt;
98
+ &lt;button type=&quot;button&quot; class=&quot;ui-menu__item&quot;&gt;Chép #12&lt;span class=&quot;ui-menu__hint&quot;&gt;dán vào Claude Code&lt;/span&gt;
99
+ &lt;/button&gt;
100
+ &lt;a class=&quot;ui-menu__item&quot; href=&quot;#choice&quot;&gt;Mở trang riêng&lt;/a&gt;
101
+ &lt;hr class=&quot;ui-menu__sep&quot;/&gt;
102
+ &lt;button type=&quot;button&quot; class=&quot;ui-menu__item ui-menu__item--danger&quot;&gt;Xoá…&lt;/button&gt;
103
+ &lt;/div&gt;
104
+ &lt;/details&gt;
105
+ &lt;dl class=&quot;ui-kv&quot; style=&quot;flex-basis:100%&quot;&gt;
106
+ &lt;dt&gt;Người dựng&lt;/dt&gt;
107
+ &lt;dd&gt;Lily&lt;/dd&gt;
108
+ &lt;dt&gt;Người duyệt&lt;/dt&gt;
109
+ &lt;dd&gt;chưa&lt;/dd&gt;
110
+ &lt;dt&gt;Báo cáo&lt;/dt&gt;
111
+ &lt;dd&gt;research/kho-section-can-build-2026-09-28.md&lt;/dd&gt;
112
+ &lt;/dl&gt;
68
113
  &lt;/div&gt;</code></pre></details></figure><figure class="cat-demo"><figcaption>Thẻ · nhãn đếm</figcaption><div class="cat-live"><div class="cat-row"><span class="ui-tag">Nháp</span><span class="ui-tag ui-tag--accent">Đã duyệt</span><span class="ui-tag ui-tag--chip">SECTION</span><span class="ui-badge">12</span></div></div><details class="cat-code"><summary>Markup</summary><pre><code>&lt;div class=&quot;cat-row&quot;&gt;
69
114
  &lt;span class=&quot;ui-tag&quot;&gt;Nháp&lt;/span&gt;
70
115
  &lt;span class=&quot;ui-tag ui-tag--accent&quot;&gt;Đã duyệt&lt;/span&gt;
71
116
  &lt;span class=&quot;ui-tag ui-tag--chip&quot;&gt;SECTION&lt;/span&gt;
72
117
  &lt;span class=&quot;ui-badge&quot;&gt;12&lt;/span&gt;
118
+ &lt;/div&gt;</code></pre></details></figure><figure class="cat-demo"><figcaption>Tab bằng link (<code>&lt;nav class=ui-tabs&gt;</code>, <code>aria-current=page</code> là tab đang chọn)</figcaption><div class="cat-live"><nav class="ui-tabs" aria-label="Chế độ xem"><a href="#" aria-current="page">Tăng trưởng</a><a href="#">Mới lên</a><a href="#">Quảng cáo</a></nav></div><details class="cat-code"><summary>Markup</summary><pre><code>&lt;nav class=&quot;ui-tabs&quot; aria-label=&quot;Chế độ xem&quot;&gt;
119
+ &lt;a href=&quot;#&quot; aria-current=&quot;page&quot;&gt;Tăng trưởng&lt;/a&gt;
120
+ &lt;a href=&quot;#&quot;&gt;Mới lên&lt;/a&gt;
121
+ &lt;a href=&quot;#&quot;&gt;Quảng cáo&lt;/a&gt;
122
+ &lt;/nav&gt;</code></pre></details></figure><figure class="cat-demo"><figcaption>Lọc bằng link (<code>ui-seg</code> với <code>&lt;a&gt;</code>; danh sách dài dùng <code>ui-chips</code>)</figcaption><div class="cat-live"><div class="ui-seg" role="group" aria-label="Hạng"><a class="is-text" href="#" aria-current="page">Tất cả</a><a class="is-text" href="#">Plus</a><a class="is-text" href="#">Premier</a></div><div class="ui-chips" style="margin-top:12px"><a class="ui-tag ui-tag--chip" href="#" aria-current="page">CRO</a><a class="ui-tag ui-tag--chip" href="#">Klaviyo</a><a class="ui-tag ui-tag--chip" href="#">Meta Ads</a></div></div><details class="cat-code"><summary>Markup</summary><pre><code>&lt;div class=&quot;ui-seg&quot; role=&quot;group&quot; aria-label=&quot;Hạng&quot;&gt;
123
+ &lt;a class=&quot;is-text&quot; href=&quot;#&quot; aria-current=&quot;page&quot;&gt;Tất cả&lt;/a&gt;
124
+ &lt;a class=&quot;is-text&quot; href=&quot;#&quot;&gt;Plus&lt;/a&gt;
125
+ &lt;a class=&quot;is-text&quot; href=&quot;#&quot;&gt;Premier&lt;/a&gt;
126
+ &lt;/div&gt;
127
+ &lt;div class=&quot;ui-chips&quot; style=&quot;margin-top:12px&quot;&gt;
128
+ &lt;a class=&quot;ui-tag ui-tag--chip&quot; href=&quot;#&quot; aria-current=&quot;page&quot;&gt;CRO&lt;/a&gt;
129
+ &lt;a class=&quot;ui-tag ui-tag--chip&quot; href=&quot;#&quot;&gt;Klaviyo&lt;/a&gt;
130
+ &lt;a class=&quot;ui-tag ui-tag--chip&quot; href=&quot;#&quot;&gt;Meta Ads&lt;/a&gt;
131
+ &lt;/div&gt;</code></pre></details></figure><figure class="cat-demo"><figcaption>Tông màu cho tag (<code>--success</code> / <code>--warning</code> / <code>--danger</code>)</figcaption><div class="cat-live"><div class="cat-row"><span class="ui-tag ui-tag--success">Đã tích hợp</span><span class="ui-tag ui-tag--warning">Chờ duyệt</span><span class="ui-tag ui-tag--danger">Lỗi tải</span></div></div><details class="cat-code"><summary>Markup</summary><pre><code>&lt;div class=&quot;cat-row&quot;&gt;
132
+ &lt;span class=&quot;ui-tag ui-tag--success&quot;&gt;Đã tích hợp&lt;/span&gt;
133
+ &lt;span class=&quot;ui-tag ui-tag--warning&quot;&gt;Chờ duyệt&lt;/span&gt;
134
+ &lt;span class=&quot;ui-tag ui-tag--danger&quot;&gt;Lỗi tải&lt;/span&gt;
135
+ &lt;/div&gt;</code></pre></details></figure><figure class="cat-demo"><figcaption>Danh sách link dạng chip (<code>ui-chips</code>: cao ≥ 28px, 44px dưới ngón tay, khe 8px)</figcaption><div class="cat-live"><div class="ui-chips"><a class="ui-tag ui-tag--chip" href="#">Judge.me Product Reviews</a><a class="ui-tag ui-tag--chip" href="#">Klaviyo</a><a class="ui-tag ui-tag--chip" href="#">Instafeed</a></div></div><details class="cat-code"><summary>Markup</summary><pre><code>&lt;div class=&quot;ui-chips&quot;&gt;
136
+ &lt;a class=&quot;ui-tag ui-tag--chip&quot; href=&quot;#&quot;&gt;Judge.me Product Reviews&lt;/a&gt;
137
+ &lt;a class=&quot;ui-tag ui-tag--chip&quot; href=&quot;#&quot;&gt;Klaviyo&lt;/a&gt;
138
+ &lt;a class=&quot;ui-tag ui-tag--chip&quot; href=&quot;#&quot;&gt;Instafeed&lt;/a&gt;
73
139
  &lt;/div&gt;</code></pre></details></figure></section>
74
- <section id="surfaces"><h2>Thẻ, số liệu, bảng, trạng thái trống</h2><figure class="cat-demo"><figcaption>Card</figcaption><div class="cat-live"><div class="ui-card" style="padding:16px">Một khối nội dung. Nền, viền, bo góc và bóng lấy từ token.</div></div><details class="cat-code"><summary>Markup</summary><pre><code>&lt;div class=&quot;ui-card&quot; style=&quot;padding:16px&quot;&gt;Một khối nội dung. Nền, viền, bo góc và bóng lấy từ token.&lt;/div&gt;</code></pre></details></figure><figure class="cat-demo"><figcaption>Số liệu (<code>ui-stats</code> / <code>ui-stat</code>)</figcaption><div class="cat-live"><div class="ui-stats"><div class="ui-stat"><b>17</b> Nháp</div><div class="ui-stat is-clickable active"><b>4</b> Đang duyệt</div><div class="ui-stat is-clickable"><b>0</b> Loại</div></div></div><details class="cat-code"><summary>Markup</summary><pre><code>&lt;div class=&quot;ui-stats&quot;&gt;
140
+ <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>&lt;div class=&quot;ui-page-head&quot;&gt;
141
+ &lt;h1&gt;Đối thủ&lt;/h1&gt;
142
+ &lt;p&gt;Page builder nào đang tích hợp với ai.&lt;/p&gt;
143
+ &lt;/div&gt;
144
+ &lt;p class=&quot;ui-muted&quot;&gt;Cập nhật 01/10, 300 trang app đã đọc.&lt;/p&gt;</code></pre></details></figure><figure class="cat-demo"><figcaption>Thanh công cụ (<code>ui-toolbar</code>)</figcaption><div class="cat-live"><div class="ui-toolbar"><div class="gemboss-field gemboss-field--group" style="flex:1 1 260px"><input class="gemboss-field__bare" placeholder="Tìm app…" aria-label="Tìm app"></div><select class="ui-select" aria-label="Xếp theo"><option>Store cài</option></select><button type="button" class="ui-btn">Xuất CSV</button></div></div><details class="cat-code"><summary>Markup</summary><pre><code>&lt;div class=&quot;ui-toolbar&quot;&gt;
145
+ &lt;div class=&quot;gemboss-field gemboss-field--group&quot; style=&quot;flex:1 1 260px&quot;&gt;
146
+ &lt;input class=&quot;gemboss-field__bare&quot; placeholder=&quot;Tìm app…&quot; aria-label=&quot;Tìm app&quot;&gt;
147
+ &lt;/div&gt;
148
+ &lt;select class=&quot;ui-select&quot; aria-label=&quot;Xếp theo&quot;&gt;
149
+ &lt;option&gt;Store cài&lt;/option&gt;
150
+ &lt;/select&gt;
151
+ &lt;button type=&quot;button&quot; class=&quot;ui-btn&quot;&gt;Xuất CSV&lt;/button&gt;
152
+ &lt;/div&gt;</code></pre></details></figure><figure class="cat-demo"><figcaption>Ô số liệu (<code>ui-metrics</code> / <code>ui-metric</code>, tông <code>--success|--warning|--danger</code>)</figcaption><div class="cat-live"><div class="ui-metrics"><div class="ui-metric"><span class="ui-metric__val">31.503</span><span class="ui-metric__lbl">App</span></div><div class="ui-metric ui-metric--success"><span class="ui-metric__val">157</span><span class="ui-metric__lbl">Khớp</span></div><div class="ui-metric ui-metric--danger"><span class="ui-metric__val">3</span><span class="ui-metric__lbl">Lỗi</span></div><a class="ui-metric" href="#"><span class="ui-metric__val">$41</span><span class="ui-metric__lbl">Chi phí tháng này</span></a></div></div><details class="cat-code"><summary>Markup</summary><pre><code>&lt;div class=&quot;ui-metrics&quot;&gt;
153
+ &lt;div class=&quot;ui-metric&quot;&gt;
154
+ &lt;span class=&quot;ui-metric__val&quot;&gt;31.503&lt;/span&gt;
155
+ &lt;span class=&quot;ui-metric__lbl&quot;&gt;App&lt;/span&gt;
156
+ &lt;/div&gt;
157
+ &lt;div class=&quot;ui-metric ui-metric--success&quot;&gt;
158
+ &lt;span class=&quot;ui-metric__val&quot;&gt;157&lt;/span&gt;
159
+ &lt;span class=&quot;ui-metric__lbl&quot;&gt;Khớp&lt;/span&gt;
160
+ &lt;/div&gt;
161
+ &lt;div class=&quot;ui-metric ui-metric--danger&quot;&gt;
162
+ &lt;span class=&quot;ui-metric__val&quot;&gt;3&lt;/span&gt;
163
+ &lt;span class=&quot;ui-metric__lbl&quot;&gt;Lỗi&lt;/span&gt;
164
+ &lt;/div&gt;
165
+ &lt;a class=&quot;ui-metric&quot; href=&quot;#&quot;&gt;
166
+ &lt;span class=&quot;ui-metric__val&quot;&gt;$41&lt;/span&gt;
167
+ &lt;span class=&quot;ui-metric__lbl&quot;&gt;Chi phí tháng này&lt;/span&gt;
168
+ &lt;/a&gt;
169
+ &lt;/div&gt;</code></pre></details></figure><figure class="cat-demo"><figcaption>Cặp nhãn – giá trị (<code>ui-dl</code>)</figcaption><div class="cat-live"><dl class="ui-dl"><div><dt>Quốc gia</dt><dd>IL</dd></div><div><dt>Store cài</dt><dd>133.340</dd></div><div><dt>Điểm tiềm năng</dt><dd>71</dd></div></dl></div><details class="cat-code"><summary>Markup</summary><pre><code>&lt;dl class=&quot;ui-dl&quot;&gt;
170
+ &lt;div&gt;
171
+ &lt;dt&gt;Quốc gia&lt;/dt&gt;
172
+ &lt;dd&gt;IL&lt;/dd&gt;
173
+ &lt;/div&gt;
174
+ &lt;div&gt;
175
+ &lt;dt&gt;Store cài&lt;/dt&gt;
176
+ &lt;dd&gt;133.340&lt;/dd&gt;
177
+ &lt;/div&gt;
178
+ &lt;div&gt;
179
+ &lt;dt&gt;Điểm tiềm năng&lt;/dt&gt;
180
+ &lt;dd&gt;71&lt;/dd&gt;
181
+ &lt;/div&gt;
182
+ &lt;/dl&gt;</code></pre></details></figure><figure class="cat-demo"><figcaption>Thông báo (<code>ui-notice</code>, tông <code>--warning|--danger|--success</code>)</figcaption><div class="cat-live"><div class="ui-notice ui-notice--warning">Token Slack đã hết hạn: bản tin thứ Hai sẽ không gửi được.</div></div><details class="cat-code"><summary>Markup</summary><pre><code>&lt;div class=&quot;ui-notice ui-notice--warning&quot;&gt;Token Slack đã hết hạn: bản tin thứ Hai sẽ không gửi được.&lt;/div&gt;</code></pre></details></figure><figure class="cat-demo"><figcaption>Phân trang (<code>ui-pager</code>)</figcaption><div class="cat-live"><nav class="ui-pager" aria-label="Trang"><a href="#" rel="prev"><span aria-hidden="true">‹</span> Trước</a><span aria-current="page">2 / 9</span><a href="#" rel="next">Sau <span aria-hidden="true">›</span></a></nav></div><details class="cat-code"><summary>Markup</summary><pre><code>&lt;nav class=&quot;ui-pager&quot; aria-label=&quot;Trang&quot;&gt;
183
+ &lt;a href=&quot;#&quot; rel=&quot;prev&quot;&gt;
184
+ &lt;span aria-hidden=&quot;true&quot;&gt;‹&lt;/span&gt; Trước&lt;/a&gt;
185
+ &lt;span aria-current=&quot;page&quot;&gt;2 / 9&lt;/span&gt;
186
+ &lt;a href=&quot;#&quot; rel=&quot;next&quot;&gt;Sau &lt;span aria-hidden=&quot;true&quot;&gt;›&lt;/span&gt;
187
+ &lt;/a&gt;
188
+ &lt;/nav&gt;</code></pre></details></figure><figure class="cat-demo"><figcaption>Card</figcaption><div class="cat-live"><div class="ui-card" style="padding:16px">Một khối nội dung. Nền, viền, bo góc và bóng lấy từ token.</div></div><details class="cat-code"><summary>Markup</summary><pre><code>&lt;div class=&quot;ui-card&quot; style=&quot;padding:16px&quot;&gt;Một khối nội dung. Nền, viền, bo góc và bóng lấy từ token.&lt;/div&gt;</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>&lt;div class=&quot;ui-card&quot;&gt;
189
+ &lt;div class=&quot;ui-card__head&quot;&gt;
190
+ &lt;h3 class=&quot;ui-card__title&quot;&gt;Hạng đối tác&lt;/h3&gt;
191
+ &lt;div&gt;
192
+ &lt;button type=&quot;button&quot; class=&quot;ui-btn ui-btn--primary&quot;&gt;Đổi hạng&lt;/button&gt;
193
+ &lt;button type=&quot;button&quot; class=&quot;ui-btn&quot;&gt;Kết thúc&lt;/button&gt;
194
+ &lt;/div&gt;
195
+ &lt;/div&gt;
196
+ &lt;p class=&quot;ui-muted&quot; style=&quot;margin:0&quot;&gt;Partner từ 01/08/2026.&lt;/p&gt;
197
+ &lt;/div&gt;</code></pre></details></figure><figure class="cat-demo"><figcaption>Số liệu (<code>ui-stats</code> / <code>ui-stat</code>)</figcaption><div class="cat-live"><div class="ui-stats"><div class="ui-stat"><b>17</b> Nháp</div><div class="ui-stat is-clickable active"><b>4</b> Đang duyệt</div><div class="ui-stat is-clickable"><b>0</b> Loại</div></div></div><details class="cat-code"><summary>Markup</summary><pre><code>&lt;div class=&quot;ui-stats&quot;&gt;
75
198
  &lt;div class=&quot;ui-stat&quot;&gt;
76
199
  &lt;b&gt;17&lt;/b&gt; Nháp&lt;/div&gt;
77
200
  &lt;div class=&quot;ui-stat is-clickable active&quot;&gt;
78
201
  &lt;b&gt;4&lt;/b&gt; Đang duyệt&lt;/div&gt;
79
202
  &lt;div class=&quot;ui-stat is-clickable&quot;&gt;
80
203
  &lt;b&gt;0&lt;/b&gt; Loại&lt;/div&gt;
81
- &lt;/div&gt;</code></pre></details></figure><figure class="cat-demo"><figcaption>Bảng (<code>is-num</code> căn phải, số đều cột)</figcaption><div class="cat-live"><div class="ui-table-wrap"><table class="ui-table"><thead><tr><th>Store</th><th>Ngành</th><th class="is-num">Trang</th></tr></thead><tbody><tr><td>fluke.com</td><td>Audio</td><td class="is-num">1.284</td></tr><tr><td>glowrecipe.com</td><td>Mỹ phẩm</td><td class="is-num">312</td></tr></tbody></table></div></div><details class="cat-code"><summary>Markup</summary><pre><code>&lt;div class=&quot;ui-table-wrap&quot;&gt;
204
+ &lt;/div&gt;</code></pre></details></figure><figure class="cat-demo"><figcaption>Bảng (<code>is-num</code> căn phải, số đều cột; <code>ui-sub</code> dòng phụ trong ô)</figcaption><div class="cat-live"><div class="ui-table-wrap"><table class="ui-table"><thead><tr><th>Store</th><th>Ngành</th><th class="is-num">Trang</th></tr></thead><tbody><tr><td>fluke.com<span class="ui-sub">Shopify Plus</span></td><td>Audio</td><td class="is-num">1.284</td></tr><tr><td>glowrecipe.com<span class="ui-sub">Shopify</span></td><td>Mỹ phẩm</td><td class="is-num">312</td></tr></tbody></table></div></div><details class="cat-code"><summary>Markup</summary><pre><code>&lt;div class=&quot;ui-table-wrap&quot;&gt;
82
205
  &lt;table class=&quot;ui-table&quot;&gt;
83
206
  &lt;thead&gt;
84
207
  &lt;tr&gt;
@@ -89,12 +212,14 @@ body{margin:0;background:var(--gemboss-app-bg,#f1f1f1);color:var(--gemboss-text)
89
212
  &lt;/thead&gt;
90
213
  &lt;tbody&gt;
91
214
  &lt;tr&gt;
92
- &lt;td&gt;fluke.com&lt;/td&gt;
215
+ &lt;td&gt;fluke.com&lt;span class=&quot;ui-sub&quot;&gt;Shopify Plus&lt;/span&gt;
216
+ &lt;/td&gt;
93
217
  &lt;td&gt;Audio&lt;/td&gt;
94
218
  &lt;td class=&quot;is-num&quot;&gt;1.284&lt;/td&gt;
95
219
  &lt;/tr&gt;
96
220
  &lt;tr&gt;
97
- &lt;td&gt;glowrecipe.com&lt;/td&gt;
221
+ &lt;td&gt;glowrecipe.com&lt;span class=&quot;ui-sub&quot;&gt;Shopify&lt;/span&gt;
222
+ &lt;/td&gt;
98
223
  &lt;td&gt;Mỹ phẩm&lt;/td&gt;
99
224
  &lt;td class=&quot;is-num&quot;&gt;312&lt;/td&gt;
100
225
  &lt;/tr&gt;
@@ -102,6 +227,12 @@ body{margin:0;background:var(--gemboss-app-bg,#f1f1f1);color:var(--gemboss-text)
102
227
  &lt;/table&gt;
103
228
  &lt;/div&gt;</code></pre></details></figure><figure class="cat-demo"><figcaption>Trống</figcaption><div class="cat-live"><div class="ui-empty">Chưa có gì ở đây.<button type="button" class="ui-btn ui-btn--primary">Tạo mục đầu tiên</button></div></div><details class="cat-code"><summary>Markup</summary><pre><code>&lt;div class=&quot;ui-empty&quot;&gt;Chưa có gì ở đây.&lt;button type=&quot;button&quot; class=&quot;ui-btn ui-btn--primary&quot;&gt;Tạo mục đầu tiên&lt;/button&gt;
104
229
  &lt;/div&gt;</code></pre></details></figure></section>
230
+ <section id="resizer"><h2>Thanh kéo giữa hai cột</h2><p>Thanh <code>ui-resizer</code> đứng giữa hai cột, người dùng kéo để đổi độ rộng. Phần NHÌN (vạch nắm hiện khi rê chuột hoặc focus bàn phím, vùng chạm 24px cho ngón tay, lớp che khi đang kéo) là của gemboss-ui.css; vị trí và hành vi là của bề mặt: dùng <b>pointer event</b> (chạm là một pointer), gắn <code>ui-resizing</code> lên <code>&lt;body&gt;</code> trong lúc kéo, phím mũi tên / Home / End di chuyển nó, kẹp theo bề rộng THẬT của khung (không theo một con số), và nhớ độ rộng theo trình duyệt. Admin: <code>useResizableChatPanel</code>; gemcare: viết tay theo đúng markup này.</p><figure class="cat-demo"><figcaption>Rê chuột hoặc Tab vào khe giữa để thấy vạch nắm</figcaption><div class="cat-live"><div style="display:grid;grid-template-columns:200px 5px minmax(0,1fr);height:140px;border:1px solid var(--gemboss-divider);border-radius:var(--gemboss-radius-md);overflow:hidden"><div style="padding:12px;background:var(--gemboss-surface)">Danh sách</div><div class="ui-resizer" role="separator" aria-orientation="vertical" aria-label="Độ rộng danh sách" tabindex="0" aria-valuenow="200" aria-valuemin="160" aria-valuemax="420"></div><div style="padding:12px;background:var(--gemboss-surface)">Nội dung</div></div></div><details class="cat-code"><summary>Markup</summary><pre><code>&lt;div style=&quot;display:grid;grid-template-columns:200px 5px minmax(0,1fr);height:140px;border:1px solid var(--gemboss-divider);border-radius:var(--gemboss-radius-md);overflow:hidden&quot;&gt;
231
+ &lt;div style=&quot;padding:12px;background:var(--gemboss-surface)&quot;&gt;Danh sách&lt;/div&gt;
232
+ &lt;div class=&quot;ui-resizer&quot; role=&quot;separator&quot; aria-orientation=&quot;vertical&quot; aria-label=&quot;Độ rộng danh sách&quot; tabindex=&quot;0&quot; aria-valuenow=&quot;200&quot; aria-valuemin=&quot;160&quot; aria-valuemax=&quot;420&quot;&gt;
233
+ &lt;/div&gt;
234
+ &lt;div style=&quot;padding:12px;background:var(--gemboss-surface)&quot;&gt;Nội dung&lt;/div&gt;
235
+ &lt;/div&gt;</code></pre></details></figure></section>
105
236
  <section id="modal"><h2>Hộp thoại</h2><p>Lớp phủ <code>ui-overlay</code> + hộp <code>ui-modal</code> (ở đây vẽ không có lớp phủ để xem được trong trang). Thân hộp thoại tự đệm: <code>ui-modal__body</code> / <code>__foot</code> chưa có CSS nào, kể cả trong admin.</p><figure class="cat-demo"><figcaption>Hộp thoại (<code>ui-modal__head</code> có nút đóng 44px)</figcaption><div class="cat-live"><div class="ui-modal" role="dialog" aria-modal="true" aria-labelledby="cat-m"><div class="ui-modal__head"><div class="ui-modal__title" id="cat-m">Xoá phiên này?</div><button type="button" class="ui-modal__close" aria-label="Đóng"><svg viewBox="0 0 20 20" width="20" height="20" aria-hidden="true" focusable="false"><g fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"><path d="M5 5l10 10M15 5 5 15"></path></g></svg></button></div><div style="padding:16px 20px">Lịch sử vẫn còn trong sổ; phiên chỉ ẩn khỏi danh sách.<div class="cat-row" style="justify-content:flex-end;margin-top:16px"><button type="button" class="ui-btn ui-btn--ghost">Huỷ</button><button type="button" class="ui-btn ui-btn--primary">Xoá</button></div></div></div></div><details class="cat-code"><summary>Markup</summary><pre><code>&lt;div class=&quot;ui-modal&quot; role=&quot;dialog&quot; aria-modal=&quot;true&quot; aria-labelledby=&quot;cat-m&quot;&gt;
106
237
  &lt;div class=&quot;ui-modal__head&quot;&gt;
107
238
  &lt;div class=&quot;ui-modal__title&quot; id=&quot;cat-m&quot;&gt;Xoá phiên này?&lt;/div&gt;
@@ -290,7 +421,7 @@ body{margin:0;background:var(--gemboss-app-bg,#f1f1f1);color:var(--gemboss-text)
290
421
  &lt;/aside&gt;
291
422
  &lt;/div&gt;
292
423
  &lt;/main&gt;</code></pre></details></figure></section>
293
- <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 / 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">20/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>&lt;div style=&quot;height:360px;display:flex&quot;&gt;
424
+ <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 / 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">23/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>&lt;div style=&quot;height:360px;display:flex&quot;&gt;
294
425
  &lt;aside class=&quot;gemboss-assistant-rail&quot;&gt;
295
426
  &lt;div class=&quot;gemboss-assistant-rail-top&quot;&gt;
296
427
  &lt;button type=&quot;button&quot; class=&quot;gemboss-assistant-newchat&quot; title=&quot;Phiên mới&quot;&gt;
@@ -339,7 +470,7 @@ body{margin:0;background:var(--gemboss-app-bg,#f1f1f1);color:var(--gemboss-text)
339
470
  &lt;/svg&gt;
340
471
  &lt;span class=&quot;gemboss-assistant-thread-title&quot;&gt;So sánh advertorial với listicle&lt;/span&gt;
341
472
  &lt;/span&gt;
342
- &lt;span class=&quot;gemboss-assistant-thread-meta&quot;&gt;20/8/2026&lt;/span&gt;
473
+ &lt;span class=&quot;gemboss-assistant-thread-meta&quot;&gt;23/8/2026&lt;/span&gt;
343
474
  &lt;/button&gt;
344
475
  &lt;div class=&quot;gemboss-assistant-thread-actions&quot;&gt;
345
476
  &lt;button type=&quot;button&quot; class=&quot;gemboss-assistant-thread-act&quot; aria-label=&quot;Options&quot;&gt;
@@ -410,7 +541,7 @@ body{margin:0;background:var(--gemboss-app-bg,#f1f1f1);color:var(--gemboss-text)
410
541
  &lt;/div&gt;
411
542
  &lt;/aside&gt;
412
543
  &lt;/div&gt;</code></pre></details></figure></section>
413
- <section id="icons"><h2>Icon</h2><p>Bộ icon GemBoss: 39 icon, lưới 20px, nét 1.5. <code>fill="none"</code> nằm trên <code>&lt;g&gt;</code>, không trên <code>&lt;svg&gt;</code>.</p><div class="cat-icons"><div class="gnav-ico cat-icon" title="home"><svg viewBox="0 0 20 20" width="20" height="20" aria-hidden="true" focusable="false"><g fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"><path d="M3.5 9 10 3.5 16.5 9"></path><path d="M5 7.8v8.7h10V7.8"></path><path d="M8.5 16.5v-4h3v4"></path></g></svg><code>home</code></div><div class="gnav-ico cat-icon" title="dashboard"><svg viewBox="0 0 20 20" width="20" height="20" aria-hidden="true" focusable="false"><g fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"><rect x="3" y="3" width="6" height="6" rx="1.3"></rect><rect x="11" y="3" width="6" height="6" rx="1.3"></rect><rect x="3" y="11" width="6" height="6" rx="1.3"></rect><rect x="11" y="11" width="6" height="6" rx="1.3"></rect></g></svg><code>dashboard</code></div><div class="gnav-ico cat-icon" title="board"><svg viewBox="0 0 20 20" width="20" height="20" aria-hidden="true" focusable="false"><g fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"><rect x="3" y="3.5" width="4" height="13" rx="1.2"></rect><rect x="8" y="3.5" width="4" height="9" rx="1.2"></rect><rect x="13" y="3.5" width="4" height="6" rx="1.2"></rect></g></svg><code>board</code></div><div class="gnav-ico cat-icon" title="layout"><svg viewBox="0 0 20 20" width="20" height="20" aria-hidden="true" focusable="false"><g fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"><rect x="3.5" y="3" width="13" height="3.5" rx="1"></rect><rect x="3.5" y="8.25" width="13" height="3.5" rx="1"></rect><rect x="3.5" y="13.5" width="13" height="3.5" rx="1"></rect></g></svg><code>layout</code></div><div class="gnav-ico cat-icon" title="layers"><svg viewBox="0 0 20 20" width="20" height="20" aria-hidden="true" focusable="false"><g fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"><path d="M10 3 17 6.8 10 10.6 3 6.8z"></path><path d="M3 10.1l7 3.8 7-3.8"></path><path d="M3 13.4l7 3.8 7-3.8"></path></g></svg><code>layers</code></div><div class="gnav-ico cat-icon" title="document"><svg viewBox="0 0 20 20" width="20" height="20" aria-hidden="true" focusable="false"><g fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"><path d="M5 2.8h6.8l3.2 3.2v11.2H5z"></path><path d="M11.8 2.8V6H15M7.5 10h5M7.5 13h5"></path></g></svg><code>document</code></div><div class="gnav-ico cat-icon" title="article"><svg viewBox="0 0 20 20" width="20" height="20" aria-hidden="true" focusable="false"><g fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"><rect x="3" y="3.5" width="14" height="13" rx="1.5"></rect><path d="M6 7h8M6 10h8M6 13h5"></path></g></svg><code>article</code></div><div class="gnav-ico cat-icon" title="page"><svg viewBox="0 0 20 20" width="20" height="20" aria-hidden="true" focusable="false"><g fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"><rect x="2.5" y="3.5" width="15" height="13" rx="2"></rect><path d="M2.5 7.5h15M6 11h8M6 13.5h5"></path></g></svg><code>page</code></div><div class="gnav-ico cat-icon" title="image"><svg viewBox="0 0 20 20" width="20" height="20" aria-hidden="true" focusable="false"><g fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"><rect x="3" y="3.5" width="14" height="13" rx="1.8"></rect><circle cx="7.3" cy="7.8" r="1.3"></circle><path d="M3.5 15l4.2-4.2 3 3 2.2-2.2 3.6 3.6"></path></g></svg><code>image</code></div><div class="gnav-ico cat-icon" title="folder"><svg viewBox="0 0 20 20" width="20" height="20" aria-hidden="true" focusable="false"><g fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"><path d="M2.8 5.3c0-.8.6-1.3 1.3-1.3h3.4l1.8 2h6.6c.8 0 1.3.6 1.3 1.3v7.7c0 .8-.6 1.3-1.3 1.3H4.1c-.8 0-1.3-.6-1.3-1.3z"></path></g></svg><code>folder</code></div><div class="gnav-ico cat-icon" title="list"><svg viewBox="0 0 20 20" width="20" height="20" aria-hidden="true" focusable="false"><g fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"><path d="M8 5h9M8 10h9M8 15h9"></path><circle cx="4" cy="5" r=".9"></circle><circle cx="4" cy="10" r=".9"></circle><circle cx="4" cy="15" r=".9"></circle></g></svg><code>list</code></div><div class="gnav-ico cat-icon" title="activity"><svg viewBox="0 0 20 20" width="20" height="20" aria-hidden="true" focusable="false"><g fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"><path d="M2.5 10h3l2-5 3 10 2-5h5"></path></g></svg><code>activity</code></div><div class="gnav-ico cat-icon" title="chart"><svg viewBox="0 0 20 20" width="20" height="20" aria-hidden="true" focusable="false"><g fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"><path d="M3 16.5h14"></path><rect x="4.5" y="9" width="2.8" height="5.5" rx=".7"></rect><rect x="8.6" y="5" width="2.8" height="9.5" rx=".7"></rect><rect x="12.7" y="11" width="2.8" height="3.5" rx=".7"></rect></g></svg><code>chart</code></div><div class="gnav-ico cat-icon" title="radar"><svg viewBox="0 0 20 20" width="20" height="20" aria-hidden="true" focusable="false"><g fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"><circle cx="10" cy="10" r="7"></circle><circle cx="10" cy="10" r="3.5"></circle><path d="M10 10l5-5"></path></g></svg><code>radar</code></div><div class="gnav-ico cat-icon" title="map"><svg viewBox="0 0 20 20" width="20" height="20" aria-hidden="true" focusable="false"><g fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"><rect x="3" y="3" width="14" height="14" rx="2"></rect><path d="M3 7.7h14M3 12.3h14M7.7 3v14M12.3 3v14"></path></g></svg><code>map</code></div><div class="gnav-ico cat-icon" title="globe"><svg viewBox="0 0 20 20" width="20" height="20" aria-hidden="true" focusable="false"><g fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"><circle cx="10" cy="10" r="7"></circle><path d="M3 10h14M10 3c2 2 2.8 4.3 2.8 7s-.8 5-2.8 7c-2-2-2.8-4.3-2.8-7s.8-5 2.8-7z"></path></g></svg><code>globe</code></div><div class="gnav-ico cat-icon" title="megaphone"><svg viewBox="0 0 20 20" width="20" height="20" aria-hidden="true" focusable="false"><g fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"><path d="M3 8v4h3l6 4V4L6 8H3z"></path><path d="M15 7.5a3.5 3.5 0 0 1 0 5"></path></g></svg><code>megaphone</code></div><div class="gnav-ico cat-icon" title="star"><svg viewBox="0 0 20 20" width="20" height="20" aria-hidden="true" focusable="false"><g fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"><path d="M10 2.8l2.2 4.5 5 .7-3.6 3.5.9 5-4.5-2.4-4.5 2.4.9-5L2.8 8l5-.7z"></path></g></svg><code>star</code></div><div class="gnav-ico cat-icon" title="eye"><svg viewBox="0 0 20 20" width="20" height="20" aria-hidden="true" focusable="false"><g fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"><path d="M1.8 10S4.7 4.8 10 4.8 18.2 10 18.2 10 15.3 15.2 10 15.2 1.8 10 1.8 10z"></path><circle cx="10" cy="10" r="2.5"></circle></g></svg><code>eye</code></div><div class="gnav-ico cat-icon" title="inbox"><svg viewBox="0 0 20 20" width="20" height="20" aria-hidden="true" focusable="false"><g fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"><path d="M3 11l2-7h10l2 7v5H3z"></path><path d="M3 11h4l1 2h4l1-2h4"></path></g></svg><code>inbox</code></div><div class="gnav-ico cat-icon" title="bell"><svg viewBox="0 0 20 20" width="20" height="20" aria-hidden="true" focusable="false"><g fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"><path d="M5 13.5V9a5 5 0 0 1 10 0v4.5l1.3 1.5H3.7z"></path><path d="M8.3 17.2a1.9 1.9 0 0 0 3.4 0"></path></g></svg><code>bell</code></div><div class="gnav-ico cat-icon" title="chat"><svg viewBox="0 0 20 20" width="20" height="20" aria-hidden="true" focusable="false"><g fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"><path d="M3 4.5h14v9H8.5L5 16.5v-3H3z"></path></g></svg><code>chat</code></div><div class="gnav-ico cat-icon" title="money"><svg viewBox="0 0 20 20" width="20" height="20" aria-hidden="true" focusable="false"><g fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"><circle cx="10" cy="10" r="7"></circle><path d="M12 7.6c-.5-.7-1.2-1-2-1-1.1 0-2 .7-2 1.6 0 2.1 4 1.2 4 3.4 0 .9-.9 1.6-2 1.6-.8 0-1.6-.3-2.1-1M10 5v1.6M10 13.2V15"></path></g></svg><code>money</code></div><div class="gnav-ico cat-icon" title="store"><svg viewBox="0 0 20 20" width="20" height="20" aria-hidden="true" focusable="false"><g fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"><path d="M3.2 7.5 4.5 3.5h11l1.3 4"></path><path d="M3.2 7.5c0 1.3 1 2.2 2.3 2.2s2.2-1 2.2-2.2c0 1.3 1 2.2 2.3 2.2s2.3-1 2.3-2.2c0 1.3.9 2.2 2.2 2.2s2.3-.9 2.3-2.2"></path><path d="M4.5 9.5v7h11v-7M8.5 16.5v-3.5h3v3.5"></path></g></svg><code>store</code></div><div class="gnav-ico cat-icon" title="user"><svg viewBox="0 0 20 20" width="20" height="20" aria-hidden="true" focusable="false"><g fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"><circle cx="10" cy="7" r="3.2"></circle><path d="M3.8 16.5c.8-2.8 3.3-4.5 6.2-4.5s5.4 1.7 6.2 4.5"></path></g></svg><code>user</code></div><div class="gnav-ico cat-icon" title="users"><svg viewBox="0 0 20 20" width="20" height="20" aria-hidden="true" focusable="false"><g fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"><circle cx="7.5" cy="7.3" r="2.8"></circle><path d="M2.5 16.3c.6-2.5 2.5-4 5-4s4.4 1.5 5 4"></path><path d="M12.3 4.8a2.8 2.8 0 0 1 0 5.2M14.3 12.5c1.6.4 2.7 1.7 3.2 3.8"></path></g></svg><code>users</code></div><div class="gnav-ico cat-icon" title="calendar"><svg viewBox="0 0 20 20" width="20" height="20" aria-hidden="true" focusable="false"><g fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"><rect x="3" y="4.5" width="14" height="12.5" rx="1.8"></rect><path d="M3 8.5h14M7 3v3M13 3v3"></path></g></svg><code>calendar</code></div><div class="gnav-ico cat-icon" title="clock"><svg viewBox="0 0 20 20" width="20" height="20" aria-hidden="true" focusable="false"><g fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"><circle cx="10" cy="10" r="7"></circle><path d="M10 6v4l2.8 1.8"></path></g></svg><code>clock</code></div><div class="gnav-ico cat-icon" title="search"><svg viewBox="0 0 20 20" width="20" height="20" aria-hidden="true" focusable="false"><g fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"><circle cx="8.8" cy="8.8" r="5.3"></circle><path d="M12.8 12.8 17 17"></path></g></svg><code>search</code></div><div class="gnav-ico cat-icon" title="link"><svg viewBox="0 0 20 20" width="20" height="20" aria-hidden="true" focusable="false"><g fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"><path d="M8.6 11.4a3 3 0 0 0 4.2 0l2.6-2.6a3 3 0 0 0-4.2-4.2l-1 1"></path><path d="M11.4 8.6a3 3 0 0 0-4.2 0l-2.6 2.6a3 3 0 0 0 4.2 4.2l1-1"></path></g></svg><code>link</code></div><div class="gnav-ico cat-icon" title="sliders"><svg viewBox="0 0 20 20" width="20" height="20" aria-hidden="true" focusable="false"><g fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"><path d="M3 5h14M3 10h14M3 15h14"></path><circle cx="7" cy="5" r="1.6"></circle><circle cx="13" cy="10" r="1.6"></circle><circle cx="9" cy="15" r="1.6"></circle></g></svg><code>sliders</code></div><div class="gnav-ico cat-icon" title="settings"><svg viewBox="0 0 20 20" width="20" height="20" aria-hidden="true" focusable="false"><g fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"><path d="M15.52 9.08 17.15 9.15 17.15 10.85 15.52 10.92 14.56 13.26 15.66 14.45 14.45 15.66 13.26 14.56 10.92 15.52 10.85 17.15 9.15 17.15 9.08 15.52 6.74 14.56 5.55 15.66 4.34 14.45 5.44 13.26 4.48 10.92 2.85 10.85 2.85 9.15 4.48 9.08 5.44 6.74 4.34 5.55 5.55 4.34 6.74 5.44 9.08 4.48 9.15 2.85 10.85 2.85 10.92 4.48 13.26 5.44 14.45 4.34 15.66 5.55 14.56 6.74Z"></path><circle cx="10" cy="10" r="2.4"></circle></g></svg><code>settings</code></div><div class="gnav-ico cat-icon" title="alert"><svg viewBox="0 0 20 20" width="20" height="20" aria-hidden="true" focusable="false"><g fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"><path d="M10 3.2 17.3 16H2.7z"></path><path d="M10 8.2v3.6M10 13.9v.1"></path></g></svg><code>alert</code></div><div class="gnav-ico cat-icon" title="info"><svg viewBox="0 0 20 20" width="20" height="20" aria-hidden="true" focusable="false"><g fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"><circle cx="10" cy="10" r="7"></circle><path d="M10 9v4.5M10 6.4v.1"></path></g></svg><code>info</code></div><div class="gnav-ico cat-icon" title="check"><svg viewBox="0 0 20 20" width="20" height="20" aria-hidden="true" focusable="false"><g fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"><path d="M4 10.5 8 14.5 16 5.5"></path></g></svg><code>check</code></div><div class="gnav-ico cat-icon" title="plus"><svg viewBox="0 0 20 20" width="20" height="20" aria-hidden="true" focusable="false"><g fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"><path d="M10 4v12M4 10h12"></path></g></svg><code>plus</code></div><div class="gnav-ico cat-icon" title="close"><svg viewBox="0 0 20 20" width="20" height="20" aria-hidden="true" focusable="false"><g fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"><path d="M5 5l10 10M15 5 5 15"></path></g></svg><code>close</code></div><div class="gnav-ico cat-icon" title="utensils"><svg viewBox="0 0 20 20" width="20" height="20" aria-hidden="true" focusable="false"><g fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"><path d="M6 3v5a2 2 0 0 0 4 0V3M8 3v14"></path><path d="M15 3c-1.6 1.4-2.5 3.6-2.5 6.5H15V17"></path></g></svg><code>utensils</code></div><div class="gnav-ico cat-icon" title="signOut"><svg viewBox="0 0 20 20" width="20" height="20" aria-hidden="true" focusable="false"><g fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"><path d="M8 3.5H4v13h4M12.5 6.5 16 10l-3.5 3.5M16 10H8"></path></g></svg><code>signOut</code></div></div><figure class="cat-demo"><figcaption>Một icon (markup)</figcaption><div class="cat-live"><svg viewBox="0 0 20 20" width="20" height="20" aria-hidden="true" focusable="false"><g fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"><rect x="3" y="3.5" width="4" height="13" rx="1.2"></rect><rect x="8" y="3.5" width="4" height="9" rx="1.2"></rect><rect x="13" y="3.5" width="4" height="6" rx="1.2"></rect></g></svg></div><details class="cat-code"><summary>Markup</summary><pre><code>&lt;svg viewBox=&quot;0 0 20 20&quot; width=&quot;20&quot; height=&quot;20&quot; aria-hidden=&quot;true&quot; focusable=&quot;false&quot;&gt;
544
+ <section id="icons"><h2>Icon</h2><p>Bộ icon GemBoss: 40 icon, lưới 20px, nét 1.5. <code>fill="none"</code> nằm trên <code>&lt;g&gt;</code>, không trên <code>&lt;svg&gt;</code>.</p><div class="cat-icons"><div class="gnav-ico cat-icon" title="home"><svg viewBox="0 0 20 20" width="20" height="20" aria-hidden="true" focusable="false"><g fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"><path d="M3.5 9 10 3.5 16.5 9"></path><path d="M5 7.8v8.7h10V7.8"></path><path d="M8.5 16.5v-4h3v4"></path></g></svg><code>home</code></div><div class="gnav-ico cat-icon" title="dashboard"><svg viewBox="0 0 20 20" width="20" height="20" aria-hidden="true" focusable="false"><g fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"><rect x="3" y="3" width="6" height="6" rx="1.3"></rect><rect x="11" y="3" width="6" height="6" rx="1.3"></rect><rect x="3" y="11" width="6" height="6" rx="1.3"></rect><rect x="11" y="11" width="6" height="6" rx="1.3"></rect></g></svg><code>dashboard</code></div><div class="gnav-ico cat-icon" title="board"><svg viewBox="0 0 20 20" width="20" height="20" aria-hidden="true" focusable="false"><g fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"><rect x="3" y="3.5" width="4" height="13" rx="1.2"></rect><rect x="8" y="3.5" width="4" height="9" rx="1.2"></rect><rect x="13" y="3.5" width="4" height="6" rx="1.2"></rect></g></svg><code>board</code></div><div class="gnav-ico cat-icon" title="layout"><svg viewBox="0 0 20 20" width="20" height="20" aria-hidden="true" focusable="false"><g fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"><rect x="3.5" y="3" width="13" height="3.5" rx="1"></rect><rect x="3.5" y="8.25" width="13" height="3.5" rx="1"></rect><rect x="3.5" y="13.5" width="13" height="3.5" rx="1"></rect></g></svg><code>layout</code></div><div class="gnav-ico cat-icon" title="layers"><svg viewBox="0 0 20 20" width="20" height="20" aria-hidden="true" focusable="false"><g fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"><path d="M10 3 17 6.8 10 10.6 3 6.8z"></path><path d="M3 10.1l7 3.8 7-3.8"></path><path d="M3 13.4l7 3.8 7-3.8"></path></g></svg><code>layers</code></div><div class="gnav-ico cat-icon" title="document"><svg viewBox="0 0 20 20" width="20" height="20" aria-hidden="true" focusable="false"><g fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"><path d="M5 2.8h6.8l3.2 3.2v11.2H5z"></path><path d="M11.8 2.8V6H15M7.5 10h5M7.5 13h5"></path></g></svg><code>document</code></div><div class="gnav-ico cat-icon" title="article"><svg viewBox="0 0 20 20" width="20" height="20" aria-hidden="true" focusable="false"><g fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"><rect x="3" y="3.5" width="14" height="13" rx="1.5"></rect><path d="M6 7h8M6 10h8M6 13h5"></path></g></svg><code>article</code></div><div class="gnav-ico cat-icon" title="page"><svg viewBox="0 0 20 20" width="20" height="20" aria-hidden="true" focusable="false"><g fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"><rect x="2.5" y="3.5" width="15" height="13" rx="2"></rect><path d="M2.5 7.5h15M6 11h8M6 13.5h5"></path></g></svg><code>page</code></div><div class="gnav-ico cat-icon" title="image"><svg viewBox="0 0 20 20" width="20" height="20" aria-hidden="true" focusable="false"><g fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"><rect x="3" y="3.5" width="14" height="13" rx="1.8"></rect><circle cx="7.3" cy="7.8" r="1.3"></circle><path d="M3.5 15l4.2-4.2 3 3 2.2-2.2 3.6 3.6"></path></g></svg><code>image</code></div><div class="gnav-ico cat-icon" title="folder"><svg viewBox="0 0 20 20" width="20" height="20" aria-hidden="true" focusable="false"><g fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"><path d="M2.8 5.3c0-.8.6-1.3 1.3-1.3h3.4l1.8 2h6.6c.8 0 1.3.6 1.3 1.3v7.7c0 .8-.6 1.3-1.3 1.3H4.1c-.8 0-1.3-.6-1.3-1.3z"></path></g></svg><code>folder</code></div><div class="gnav-ico cat-icon" title="list"><svg viewBox="0 0 20 20" width="20" height="20" aria-hidden="true" focusable="false"><g fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"><path d="M8 5h9M8 10h9M8 15h9"></path><circle cx="4" cy="5" r=".9"></circle><circle cx="4" cy="10" r=".9"></circle><circle cx="4" cy="15" r=".9"></circle></g></svg><code>list</code></div><div class="gnav-ico cat-icon" title="activity"><svg viewBox="0 0 20 20" width="20" height="20" aria-hidden="true" focusable="false"><g fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"><path d="M2.5 10h3l2-5 3 10 2-5h5"></path></g></svg><code>activity</code></div><div class="gnav-ico cat-icon" title="chart"><svg viewBox="0 0 20 20" width="20" height="20" aria-hidden="true" focusable="false"><g fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"><path d="M3 16.5h14"></path><rect x="4.5" y="9" width="2.8" height="5.5" rx=".7"></rect><rect x="8.6" y="5" width="2.8" height="9.5" rx=".7"></rect><rect x="12.7" y="11" width="2.8" height="3.5" rx=".7"></rect></g></svg><code>chart</code></div><div class="gnav-ico cat-icon" title="radar"><svg viewBox="0 0 20 20" width="20" height="20" aria-hidden="true" focusable="false"><g fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"><circle cx="10" cy="10" r="7"></circle><circle cx="10" cy="10" r="3.5"></circle><path d="M10 10l5-5"></path></g></svg><code>radar</code></div><div class="gnav-ico cat-icon" title="map"><svg viewBox="0 0 20 20" width="20" height="20" aria-hidden="true" focusable="false"><g fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"><rect x="3" y="3" width="14" height="14" rx="2"></rect><path d="M3 7.7h14M3 12.3h14M7.7 3v14M12.3 3v14"></path></g></svg><code>map</code></div><div class="gnav-ico cat-icon" title="globe"><svg viewBox="0 0 20 20" width="20" height="20" aria-hidden="true" focusable="false"><g fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"><circle cx="10" cy="10" r="7"></circle><path d="M3 10h14M10 3c2 2 2.8 4.3 2.8 7s-.8 5-2.8 7c-2-2-2.8-4.3-2.8-7s.8-5 2.8-7z"></path></g></svg><code>globe</code></div><div class="gnav-ico cat-icon" title="megaphone"><svg viewBox="0 0 20 20" width="20" height="20" aria-hidden="true" focusable="false"><g fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"><path d="M3 8v4h3l6 4V4L6 8H3z"></path><path d="M15 7.5a3.5 3.5 0 0 1 0 5"></path></g></svg><code>megaphone</code></div><div class="gnav-ico cat-icon" title="star"><svg viewBox="0 0 20 20" width="20" height="20" aria-hidden="true" focusable="false"><g fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"><path d="M10 2.8l2.2 4.5 5 .7-3.6 3.5.9 5-4.5-2.4-4.5 2.4.9-5L2.8 8l5-.7z"></path></g></svg><code>star</code></div><div class="gnav-ico cat-icon" title="eye"><svg viewBox="0 0 20 20" width="20" height="20" aria-hidden="true" focusable="false"><g fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"><path d="M1.8 10S4.7 4.8 10 4.8 18.2 10 18.2 10 15.3 15.2 10 15.2 1.8 10 1.8 10z"></path><circle cx="10" cy="10" r="2.5"></circle></g></svg><code>eye</code></div><div class="gnav-ico cat-icon" title="inbox"><svg viewBox="0 0 20 20" width="20" height="20" aria-hidden="true" focusable="false"><g fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"><path d="M3 11l2-7h10l2 7v5H3z"></path><path d="M3 11h4l1 2h4l1-2h4"></path></g></svg><code>inbox</code></div><div class="gnav-ico cat-icon" title="bell"><svg viewBox="0 0 20 20" width="20" height="20" aria-hidden="true" focusable="false"><g fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"><path d="M5 13.5V9a5 5 0 0 1 10 0v4.5l1.3 1.5H3.7z"></path><path d="M8.3 17.2a1.9 1.9 0 0 0 3.4 0"></path></g></svg><code>bell</code></div><div class="gnav-ico cat-icon" title="chat"><svg viewBox="0 0 20 20" width="20" height="20" aria-hidden="true" focusable="false"><g fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"><path d="M3 4.5h14v9H8.5L5 16.5v-3H3z"></path></g></svg><code>chat</code></div><div class="gnav-ico cat-icon" title="money"><svg viewBox="0 0 20 20" width="20" height="20" aria-hidden="true" focusable="false"><g fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"><circle cx="10" cy="10" r="7"></circle><path d="M12 7.6c-.5-.7-1.2-1-2-1-1.1 0-2 .7-2 1.6 0 2.1 4 1.2 4 3.4 0 .9-.9 1.6-2 1.6-.8 0-1.6-.3-2.1-1M10 5v1.6M10 13.2V15"></path></g></svg><code>money</code></div><div class="gnav-ico cat-icon" title="store"><svg viewBox="0 0 20 20" width="20" height="20" aria-hidden="true" focusable="false"><g fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"><path d="M3.2 7.5 4.5 3.5h11l1.3 4"></path><path d="M3.2 7.5c0 1.3 1 2.2 2.3 2.2s2.2-1 2.2-2.2c0 1.3 1 2.2 2.3 2.2s2.3-1 2.3-2.2c0 1.3.9 2.2 2.2 2.2s2.3-.9 2.3-2.2"></path><path d="M4.5 9.5v7h11v-7M8.5 16.5v-3.5h3v3.5"></path></g></svg><code>store</code></div><div class="gnav-ico cat-icon" title="user"><svg viewBox="0 0 20 20" width="20" height="20" aria-hidden="true" focusable="false"><g fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"><circle cx="10" cy="7" r="3.2"></circle><path d="M3.8 16.5c.8-2.8 3.3-4.5 6.2-4.5s5.4 1.7 6.2 4.5"></path></g></svg><code>user</code></div><div class="gnav-ico cat-icon" title="users"><svg viewBox="0 0 20 20" width="20" height="20" aria-hidden="true" focusable="false"><g fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"><circle cx="7.5" cy="7.3" r="2.8"></circle><path d="M2.5 16.3c.6-2.5 2.5-4 5-4s4.4 1.5 5 4"></path><path d="M12.3 4.8a2.8 2.8 0 0 1 0 5.2M14.3 12.5c1.6.4 2.7 1.7 3.2 3.8"></path></g></svg><code>users</code></div><div class="gnav-ico cat-icon" title="calendar"><svg viewBox="0 0 20 20" width="20" height="20" aria-hidden="true" focusable="false"><g fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"><rect x="3" y="4.5" width="14" height="12.5" rx="1.8"></rect><path d="M3 8.5h14M7 3v3M13 3v3"></path></g></svg><code>calendar</code></div><div class="gnav-ico cat-icon" title="clock"><svg viewBox="0 0 20 20" width="20" height="20" aria-hidden="true" focusable="false"><g fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"><circle cx="10" cy="10" r="7"></circle><path d="M10 6v4l2.8 1.8"></path></g></svg><code>clock</code></div><div class="gnav-ico cat-icon" title="search"><svg viewBox="0 0 20 20" width="20" height="20" aria-hidden="true" focusable="false"><g fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"><circle cx="8.8" cy="8.8" r="5.3"></circle><path d="M12.8 12.8 17 17"></path></g></svg><code>search</code></div><div class="gnav-ico cat-icon" title="link"><svg viewBox="0 0 20 20" width="20" height="20" aria-hidden="true" focusable="false"><g fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"><path d="M8.6 11.4a3 3 0 0 0 4.2 0l2.6-2.6a3 3 0 0 0-4.2-4.2l-1 1"></path><path d="M11.4 8.6a3 3 0 0 0-4.2 0l-2.6 2.6a3 3 0 0 0 4.2 4.2l1-1"></path></g></svg><code>link</code></div><div class="gnav-ico cat-icon" title="sliders"><svg viewBox="0 0 20 20" width="20" height="20" aria-hidden="true" focusable="false"><g fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"><path d="M3 5h14M3 10h14M3 15h14"></path><circle cx="7" cy="5" r="1.6"></circle><circle cx="13" cy="10" r="1.6"></circle><circle cx="9" cy="15" r="1.6"></circle></g></svg><code>sliders</code></div><div class="gnav-ico cat-icon" title="settings"><svg viewBox="0 0 20 20" width="20" height="20" aria-hidden="true" focusable="false"><g fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"><path d="M15.52 9.08 17.15 9.15 17.15 10.85 15.52 10.92 14.56 13.26 15.66 14.45 14.45 15.66 13.26 14.56 10.92 15.52 10.85 17.15 9.15 17.15 9.08 15.52 6.74 14.56 5.55 15.66 4.34 14.45 5.44 13.26 4.48 10.92 2.85 10.85 2.85 9.15 4.48 9.08 5.44 6.74 4.34 5.55 5.55 4.34 6.74 5.44 9.08 4.48 9.15 2.85 10.85 2.85 10.92 4.48 13.26 5.44 14.45 4.34 15.66 5.55 14.56 6.74Z"></path><circle cx="10" cy="10" r="2.4"></circle></g></svg><code>settings</code></div><div class="gnav-ico cat-icon" title="alert"><svg viewBox="0 0 20 20" width="20" height="20" aria-hidden="true" focusable="false"><g fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"><path d="M10 3.2 17.3 16H2.7z"></path><path d="M10 8.2v3.6M10 13.9v.1"></path></g></svg><code>alert</code></div><div class="gnav-ico cat-icon" title="info"><svg viewBox="0 0 20 20" width="20" height="20" aria-hidden="true" focusable="false"><g fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"><circle cx="10" cy="10" r="7"></circle><path d="M10 9v4.5M10 6.4v.1"></path></g></svg><code>info</code></div><div class="gnav-ico cat-icon" title="check"><svg viewBox="0 0 20 20" width="20" height="20" aria-hidden="true" focusable="false"><g fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"><path d="M4 10.5 8 14.5 16 5.5"></path></g></svg><code>check</code></div><div class="gnav-ico cat-icon" title="plus"><svg viewBox="0 0 20 20" width="20" height="20" aria-hidden="true" focusable="false"><g fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"><path d="M10 4v12M4 10h12"></path></g></svg><code>plus</code></div><div class="gnav-ico cat-icon" title="close"><svg viewBox="0 0 20 20" width="20" height="20" aria-hidden="true" focusable="false"><g fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"><path d="M5 5l10 10M15 5 5 15"></path></g></svg><code>close</code></div><div class="gnav-ico cat-icon" title="more"><svg viewBox="0 0 20 20" width="20" height="20" aria-hidden="true" focusable="false"><g fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"><circle cx="4.5" cy="10" r="1"></circle><circle cx="10" cy="10" r="1"></circle><circle cx="15.5" cy="10" r="1"></circle></g></svg><code>more</code></div><div class="gnav-ico cat-icon" title="utensils"><svg viewBox="0 0 20 20" width="20" height="20" aria-hidden="true" focusable="false"><g fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"><path d="M6 3v5a2 2 0 0 0 4 0V3M8 3v14"></path><path d="M15 3c-1.6 1.4-2.5 3.6-2.5 6.5H15V17"></path></g></svg><code>utensils</code></div><div class="gnav-ico cat-icon" title="signOut"><svg viewBox="0 0 20 20" width="20" height="20" aria-hidden="true" focusable="false"><g fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"><path d="M8 3.5H4v13h4M12.5 6.5 16 10l-3.5 3.5M16 10H8"></path></g></svg><code>signOut</code></div></div><figure class="cat-demo"><figcaption>Một icon (markup)</figcaption><div class="cat-live"><svg viewBox="0 0 20 20" width="20" height="20" aria-hidden="true" focusable="false"><g fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"><rect x="3" y="3.5" width="4" height="13" rx="1.2"></rect><rect x="8" y="3.5" width="4" height="9" rx="1.2"></rect><rect x="13" y="3.5" width="4" height="6" rx="1.2"></rect></g></svg></div><details class="cat-code"><summary>Markup</summary><pre><code>&lt;svg viewBox=&quot;0 0 20 20&quot; width=&quot;20&quot; height=&quot;20&quot; aria-hidden=&quot;true&quot; focusable=&quot;false&quot;&gt;
414
545
  &lt;g fill=&quot;none&quot; stroke=&quot;currentColor&quot; stroke-width=&quot;1.5&quot; stroke-linecap=&quot;round&quot; stroke-linejoin=&quot;round&quot;&gt;
415
546
  &lt;rect x=&quot;3&quot; y=&quot;3.5&quot; width=&quot;4&quot; height=&quot;13&quot; rx=&quot;1.2&quot;&gt;
416
547
  &lt;/rect&gt;