@adia-ai/web-modules 0.6.19 → 0.6.21

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,45 @@
1
1
  # Changelog — @adia-ai/web-modules
2
2
 
3
+ ## [0.6.21] — 2026-05-21
4
+
5
+ ### Changed — `<admin-entity-item>` row insets aligned to shared select / nav-item-ui row convention
6
+
7
+ - **`--entity-item-gap`: `--a-space-2` → `--a-space-1`** (matches `--select-trigger-gap` + `--nav-item-row-gap`) and **NEW `--entity-item-px: --a-ui-px` token** with `padding: 0 var(--entity-item-px)` on the host rule (matches `--select-px` + `--nav-item-row-px`). Identity rows now read as the same shared row vocabulary used inside `<select-ui>` triggers and `<nav-item-ui>` rows — visibly tighter gap between icon / label / badge, plus consistent inline padding. Both tunable: a consumer who finds the inset double-pads inside a particular parent context can set `--entity-item-px: 0` on a per-use basis. Files: `css/admin-shell.entity-item.css`.
8
+
9
+ ### Fixed — `admin-shell` no longer emits a spurious slot-contract `console.warn`
10
+
11
+ - **The one-shot `console.warn` for `<admin-topbar>` / `<admin-statusbar>` missing `slot="header"` / `slot="footer"` (shipped in 0.6.20, FEEDBACK-37) is reverted — it was a false positive.** `<admin-content>` and `<admin-sidebar>` are CSS-only light-DOM elements with no shadow root, so a `slot=` attribute is inert (no projection), and no CSS selector targets `[slot="header"]` / `[slot="footer"]` for them — the topbar/statusbar are positioned purely by tag + DOM order (`admin-content > admin-topbar { … }`). The bars render identically with or without the slot; the warn fired on correct markup with a message that was factually wrong ("renders in the default body slot"). FEEDBACK-37's premise — that the slot is load-bearing — did not hold. Removed: `admin-shell.js` `#checkSlotContracts()` + the `MUST carry slot` `a2ui.rules` in `admin-topbar.yaml` / `admin-statusbar.yaml`.
12
+
13
+ ### Fixed — page-header title row no longer stacks under the `?chunks` dev overlay
14
+
15
+ - **The `<admin-page-header>` title row (`h1` left, actions right) used a `:first-child` selector that broke when the `?chunks=1` dev overlay was active.** `site/dev-chunks.js` prepends a `<span data-chunk-marker>` into every `[data-chunk]` element; on a page-header `<header data-chunk="…">` that span displaced the title `<div>` from `:first-child`, so the flex-row rule (`display: flex; justify-content: space-between`) stopped matching — the title and the action buttons stacked vertically instead of sharing a row. The selector is now `div:first-of-type`, which a prepended non-`<div>` sibling cannot displace. Production (overlay off) was unaffected; this fixes the chunks-on dev view. Files: `css/admin-shell.templates.css`.
16
+
17
+ ## [0.6.20] — 2026-05-21
18
+
19
+ ### Added — `<admin-entity-item>` shell identity-row primitive (FEEDBACK-38)
20
+
21
+ - **New CSS-only shell-tier primitive: a composable icon + label + badge identity row.** A leading `<icon-ui>` (or `<img>` avatar), a truncating `[slot="label"]`, and an optional trailing `[slot="badge"]` travel as one slottable unit — slot it whole into `[slot="heading"]` of an `<admin-topbar>` / `<admin-statusbar>` for workspace or user identity. Geometry mirrors `<select-ui>`'s trigger row (`icon` ≡ `leading`, `label` ≡ `display`, `badge` ≡ `caret`). Inside a collapsible `<admin-sidebar>` the label + badge hide when the rail collapses and the icon survives, so one markup serves both states — closing the gap consumers were filling with ad-hoc `<span>` / `<div>` wrappers. New files: `shell/admin-entity-item/admin-entity-item.{yaml,a2ui.json,html,examples.html}` + `css/admin-shell.entity-item.css`. `admin-topbar.yaml` / `admin-statusbar.yaml` gain `a2ui.rules` pointing at it.
22
+
23
+ ### Added — `admin-shell` warns when `<admin-topbar>` / `<admin-statusbar>` is missing its slot (FEEDBACK-37)
24
+
25
+ - **`<admin-shell>` now logs a one-shot `console.warn` when an `<admin-topbar>` or `<admin-statusbar>` is a direct child of `<admin-sidebar>` / `<admin-content>` without `slot="header"` / `slot="footer"`.** Both are CSS-only elements; omitting the slot lands them in the default body slot — rendering them in the content column instead of the chrome band, previously with zero diagnostics. The check runs once at connect, `WeakSet`-guarded per element. Same silent-misuse-warn discipline `drawer-ui` / `chart-ui` / `segmented-ui` received in 0.6.19. Files: `admin-shell.js`.
26
+
27
+ ### Changed — `<admin-page-header>` background rebased to `--a-canvas-0`
28
+
29
+ - **`--page-content-header-bg` token: `--a-canvas-1` → `--a-canvas-0`.** The sticky page-header band now matches the page-body content surface (`--page-content-bg`), so the header reads as a flush extension of the content area rather than as separate chrome. This is the third iteration of the page-header treatment: v0.6.14 used `--a-canvas-2` (ΔL=0.08, "elevated step over content"); v0.6.16 rebased to `--a-canvas-1` ("shell-chrome continuation"); both still read as not-quite-flush against dense dark-mode layouts. `canvas-0` settles it — fully flush. Consumers who want a raised or contrasting band override `--page-content-header-bg` at `:root`. Files: `admin-shell.tokens.css` (token value + history comment).
30
+
31
+ ### Fixed — `admin-topbar` / `admin-statusbar` inline padding aligns with sibling `<section-ui>`
32
+
33
+ - **The topbar/statusbar inline padding now matches the sibling `<section-ui>`'s, so chrome and content share one gutter.** In the content column the bars took `--page-header-px` (`a-space-3`) while the content `<section-ui>` uses `--page-content-inset` (`a-space-10`) — the topbar title and the body content were misaligned. They now use `--page-content-inset`. The shared rule also covered the sidebar context, where the sidebar's `<section-ui>` uses the tighter `--page-sidebar-px`; a new `admin-sidebar > :is(admin-topbar, admin-statusbar)` rule scopes that case so each context aligns with its own `<section-ui>`. Files: `css/admin-shell.bespoke.css`.
34
+
35
+ ### Fixed — collapsed sidebar `[slot="heading"]` hide no longer wipes composed wrappers (FEEDBACK-38 addendum)
36
+
37
+ - **`collapsed.css`'s `[slot="heading"] { display: none }` rail-cleanup rule is now scoped to leaf text headings.** The unscoped rule hid *any* `slot="heading"` child in a collapsed sidebar — including composed wrappers like `<admin-entity-item slot="heading">`, wiping their icon along with the label text. It now matches `:is(span, p, div, h1–h6)[slot="heading"]` plus `[slot="heading"]:not(:has(> [slot]))` — a heading whose children are themselves slotted (a composed unit) survives collapse and manages its own children. Backward-compatible: bare `<span slot="heading">` text labels still hide. Files: `css/admin-shell.collapsed.css`.
38
+
39
+ ### Fixed — `nav-item-ui` collapsed hit area fills the 48px rail (FEEDBACK-39)
40
+
41
+ - **In a collapsed sidebar, `nav-item-ui` now stretches to the full rail width instead of shrinking to its ~30px icon box.** Previously the centred 30px item left ~9px dead gutters on each side — clicks there hit `section-ui`, not the nav item (~37% of the rail was dead space). `collapsed.css` now sets `width: 100%` on both `nav-item-ui` and `nav-ui` — the latter is required because the collapsed section shrink-wraps its children, so the item's `width: 100%` would otherwise resolve against the 30px content box. `justify-content: center` keeps the glyph centred. Files: `css/admin-shell.collapsed.css`.
42
+
3
43
  ## [0.6.19] — 2026-05-21
4
44
 
5
45
  ### Added — `./shell/with-css` opt-in export (FEEDBACK-25)
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@adia-ai/web-modules",
3
- "version": "0.6.19",
3
+ "version": "0.6.21",
4
4
  "description": "AdiaUI composite custom elements \u2014 shell, chat, editor, runtime clusters built from @adia-ai/web-components primitives. Subpath exports per cluster.",
5
5
  "type": "module",
6
6
  "exports": {
@@ -0,0 +1,79 @@
1
+ {
2
+ "$schema": "https://json-schema.org/draft/2020-12/schema",
3
+ "$id": "https://adiaui.dev/a2ui/v0_9/components/AdminEntityItem.json",
4
+ "title": "AdminEntityItem",
5
+ "description": "Module-tier shell identity row. CSS-only — no behavior, no JS.\nA composable icon + label + badge unit: a leading icon (or avatar),\na truncating label, and an optional trailing badge that travel\ntogether as one slottable element.\n\nUse it wherever a shell surface shows an entity identity — workspace\nidentity in an <admin-topbar slot=\"header\">, user identity in an\n<admin-statusbar>, the leading item of a breadcrumb, a flyout header,\nor a user row. Inside a collapsible <admin-sidebar> the label and\nbadge hide when the rail collapses; the icon survives — so the same\nmarkup works expanded and collapsed without authoring two shapes.\n\nGeometry mirrors <select-ui>'s trigger row: [slot=\"icon\"] is fixed\n(like [slot=\"leading\"]), [slot=\"label\"] flexes + truncates (like\n[slot=\"display\"]), [slot=\"badge\"] is fixed trailing (like\n[slot=\"caret\"]).\n",
6
+ "type": "object",
7
+ "allOf": [
8
+ {
9
+ "$ref": "common_types.json#/$defs/ComponentCommon"
10
+ },
11
+ {
12
+ "$ref": "common_types.json#/$defs/CatalogComponentCommon"
13
+ }
14
+ ],
15
+ "properties": {
16
+ "component": {
17
+ "const": "AdminEntityItem"
18
+ }
19
+ },
20
+ "required": [
21
+ "component"
22
+ ],
23
+ "unevaluatedProperties": false,
24
+ "x-adiaui": {
25
+ "anti_patterns": [],
26
+ "category": "layout",
27
+ "composes": [],
28
+ "events": {},
29
+ "examples": [],
30
+ "keywords": [
31
+ "admin-entity-item",
32
+ "entity-item",
33
+ "identity-row",
34
+ "workspace-identity",
35
+ "user-identity",
36
+ "icon-label-badge"
37
+ ],
38
+ "name": "AdminEntityItem",
39
+ "related": [
40
+ "AdminTopbar",
41
+ "AdminStatusbar",
42
+ "AdminSidebar",
43
+ "Select",
44
+ "Badge",
45
+ "Icon"
46
+ ],
47
+ "slots": {
48
+ "default": {
49
+ "description": "Default content — unslotted children flow inline. Prefer the named slots for the canonical icon + label + badge composition."
50
+ },
51
+ "badge": {
52
+ "description": "Optional trailing chip — environment (staging / beta) or role badge. Fixed width. Hidden when a collapsible sidebar collapses."
53
+ },
54
+ "icon": {
55
+ "description": "Leading visual — an <icon-ui> glyph or an <img> avatar (img is given a circular crop). Fixed width; survives sidebar collapse."
56
+ },
57
+ "label": {
58
+ "description": "Primary text. Flexes to fill the remaining width and truncates with an ellipsis. Hidden when a collapsible sidebar collapses."
59
+ }
60
+ },
61
+ "states": [
62
+ {
63
+ "description": "Default, the only state.",
64
+ "name": "idle"
65
+ }
66
+ ],
67
+ "synonyms": {
68
+ "entity-item": [
69
+ "identity-row",
70
+ "entity-row",
71
+ "identity-item"
72
+ ]
73
+ },
74
+ "tag": "admin-entity-item",
75
+ "tokens": {},
76
+ "traits": [],
77
+ "version": 1
78
+ }
79
+ }
@@ -0,0 +1,84 @@
1
+ # Edit this file; run `npm run build:components` to regenerate a2ui.json.
2
+ $schema: ../../../../scripts/schemas/component.yaml.schema.json
3
+ name: AdminEntityItem
4
+ tag: admin-entity-item
5
+ component: AdminEntityItem
6
+ category: layout
7
+ version: 1
8
+ description: |
9
+ Module-tier shell identity row. CSS-only — no behavior, no JS.
10
+ A composable icon + label + badge unit: a leading icon (or avatar),
11
+ a truncating label, and an optional trailing badge that travel
12
+ together as one slottable element.
13
+
14
+ Use it wherever a shell surface shows an entity identity — workspace
15
+ identity in an <admin-topbar slot="header">, user identity in an
16
+ <admin-statusbar>, the leading item of a breadcrumb, a flyout header,
17
+ or a user row. Inside a collapsible <admin-sidebar> the label and
18
+ badge hide when the rail collapses; the icon survives — so the same
19
+ markup works expanded and collapsed without authoring two shapes.
20
+
21
+ Geometry mirrors <select-ui>'s trigger row: [slot="icon"] is fixed
22
+ (like [slot="leading"]), [slot="label"] flexes + truncates (like
23
+ [slot="display"]), [slot="badge"] is fixed trailing (like
24
+ [slot="caret"]).
25
+
26
+ props: {}
27
+
28
+ events: {}
29
+
30
+ slots:
31
+ default:
32
+ description: >-
33
+ Default content — unslotted children flow inline. Prefer the
34
+ named slots for the canonical icon + label + badge composition.
35
+ icon:
36
+ description: >-
37
+ Leading visual — an <icon-ui> glyph or an <img> avatar (img is
38
+ given a circular crop). Fixed width; survives sidebar collapse.
39
+ label:
40
+ description: >-
41
+ Primary text. Flexes to fill the remaining width and truncates
42
+ with an ellipsis. Hidden when a collapsible sidebar collapses.
43
+ badge:
44
+ description: >-
45
+ Optional trailing chip — environment (staging / beta) or role
46
+ badge. Fixed width. Hidden when a collapsible sidebar collapses.
47
+
48
+ states:
49
+ - name: idle
50
+ description: Default, the only state.
51
+
52
+ traits: []
53
+
54
+ a2ui:
55
+ rules:
56
+ - >-
57
+ admin-entity-item is the canonical icon + label + badge identity
58
+ row for shell surfaces. Slot it whole into [slot="heading"] of an
59
+ <admin-topbar> / <admin-statusbar> so the icon + label + badge
60
+ collapse together inside a collapsible <admin-sidebar>. Do NOT
61
+ re-implement it with a bare <span> or an ad-hoc flex <div> — those
62
+ have no shared collapse boundary.
63
+ - >-
64
+ For an INTERACTIVE workspace switcher use <select-ui variant="ghost">
65
+ instead — admin-entity-item is read-only identity display.
66
+
67
+ keywords:
68
+ - admin-entity-item
69
+ - entity-item
70
+ - identity-row
71
+ - workspace-identity
72
+ - user-identity
73
+ - icon-label-badge
74
+
75
+ synonyms:
76
+ entity-item: [identity-row, entity-row, identity-item]
77
+
78
+ related:
79
+ - AdminTopbar
80
+ - AdminStatusbar
81
+ - AdminSidebar
82
+ - Select
83
+ - Badge
84
+ - Icon
@@ -13,3 +13,4 @@
13
13
  @import "./css/admin-shell.templates.css";
14
14
  @import "./css/admin-shell.helpers.css";
15
15
  @import "./css/admin-shell.bespoke.css";
16
+ @import "./css/admin-shell.entity-item.css";
@@ -87,7 +87,12 @@ describe('admin-shell.collapsed.css — vanilla HTML fallback (v0.6.17)', () =>
87
87
  // text labels don't overflow the 48px rail when the consumer doesn't
88
88
  // use AdiaUI <nav-item-ui> primitives.
89
89
  expect(collapsedCSS).toMatch(/Vanilla-HTML fallback/);
90
- expect(collapsedCSS).toMatch(/\[slot="heading"\]\s*\{[\s\S]*?display:\s*none/);
90
+ // v0.6.20 (FEEDBACK-38 addendum): the heading-hide rule narrowed from a
91
+ // blanket `[slot="heading"]` to plain-text headings + headings without
92
+ // slotted children, so composed wrappers (<admin-entity-item slot="heading">)
93
+ // survive collapse. The rule still resolves to `display: none`.
94
+ expect(collapsedCSS).toMatch(/\[slot="heading"\][^{]*\{\s*display:\s*none/);
95
+ expect(collapsedCSS).toMatch(/\[slot="heading"\]:not\(:has\(>\s*\[slot\]\)\)/);
91
96
  expect(collapsedCSS).toMatch(/button\.nav-item/);
92
97
  expect(collapsedCSS).toMatch(/text-indent:\s*-9999px/);
93
98
  });
@@ -34,7 +34,7 @@ admin-sidebar > admin-topbar {
34
34
  display: flex;
35
35
  align-items: center;
36
36
  gap: var(--page-header-gap);
37
- padding: 0 var(--page-header-px);
37
+ padding: 0 var(--page-content-inset);
38
38
  height: var(--page-header-height);
39
39
  font-size: var(--page-header-font);
40
40
  border-bottom: var(--page-border);
@@ -48,7 +48,7 @@ admin-sidebar > admin-statusbar {
48
48
  display: flex;
49
49
  align-items: center;
50
50
  gap: var(--page-header-gap);
51
- padding: 0 var(--page-header-px);
51
+ padding: 0 var(--page-content-inset);
52
52
  height: var(--page-header-height);
53
53
  font-size: var(--page-header-font);
54
54
  color: var(--page-header-fg-muted);
@@ -56,6 +56,13 @@ admin-sidebar > admin-statusbar {
56
56
  flex-shrink: 0;
57
57
  }
58
58
 
59
+ /* Sidebar header/footer chrome takes the sidebar's tighter inline inset
60
+ (--page-sidebar-px) so it aligns with the sidebar's own <section-ui>
61
+ body — not the content column's wider --page-content-inset. */
62
+ admin-sidebar > :is(admin-topbar, admin-statusbar) {
63
+ padding-inline: var(--page-sidebar-px);
64
+ }
65
+
59
66
  /* ── admin-scroll ≡ <section> child of <main> ── */
60
67
  admin-content > admin-scroll {
61
68
  flex: 1;
@@ -71,6 +71,19 @@
71
71
  padding: 0;
72
72
  min-height: var(--nav-item-row-height);
73
73
  min-width: var(--nav-item-row-height);
74
+ /* FEEDBACK-39: fill the rail width so the whole 48px column is the hit
75
+ area — without this the item shrinks to its ~30px icon box, leaving
76
+ ~9px dead gutters on each side. justify-content keeps the glyph
77
+ centred within the now-full-width item. */
78
+ width: 100%;
79
+ }
80
+
81
+ /* FEEDBACK-39: nav-ui itself must fill the rail — the collapsed section
82
+ centres + shrink-wraps its children, so without an explicit width
83
+ nav-ui collapses to its ~30px content box and `width: 100%` on the
84
+ items would resolve against 30px, not the 48px rail. */
85
+ nav-ui {
86
+ width: 100%;
74
87
  }
75
88
 
76
89
  /* Button: icon-only mode */
@@ -111,7 +124,13 @@
111
124
  <admin-topbar slot="header">) — keeps the rail clean in collapsed mode.
112
125
  Authors who want a brand mark visible when collapsed should put an
113
126
  <icon-ui> or logo image in [slot="leading"] instead. */
114
- [slot="heading"] {
127
+ /* FEEDBACK-38 (addendum): scope the hide to leaf text headings — a bare
128
+ <span slot="heading">Brand</span> — not composed wrappers (e.g. an
129
+ <admin-entity-item slot="heading">) that carry their own internal slot
130
+ contract. `:not(:has(> [slot]))` preserves any heading element whose
131
+ children are themselves slotted, so its icon survives collapse. */
132
+ :is(span, p, div, h1, h2, h3, h4, h5, h6)[slot="heading"],
133
+ [slot="heading"]:not(:has(> [slot])) {
115
134
  display: none;
116
135
  }
117
136
 
@@ -0,0 +1,88 @@
1
+ /* ═══════════════════════════════════════════════════════════════
2
+ admin-shell — <admin-entity-item> (FEEDBACK-38)
3
+
4
+ CSS-only shell-tier primitive: a composable icon + label + badge
5
+ identity row. The leading icon, a truncating label, and an
6
+ optional trailing badge travel as one unit, so they can be
7
+ slotted whole into <admin-topbar>, <admin-statusbar>, breadcrumb
8
+ leading items, flyout headers, and user-identity rows.
9
+
10
+ Geometry mirrors <select-ui>'s trigger row:
11
+ [slot="icon"] ≡ select-ui [slot="leading"] — fixed, flex-shrink:0
12
+ [slot="label"] ≡ select-ui [slot="display"] — flexible, truncates
13
+ [slot="badge"] ≡ select-ui [slot="caret"] — fixed trailing
14
+
15
+ Collapse: inside a collapsed <admin-sidebar> (@container sidebar,
16
+ ≤96px) the label + badge hide and the icon survives. This is why
17
+ the element is a wrapper: collapsed.css's [slot="heading"] hide
18
+ rule is scoped to preserve any heading that carries slotted
19
+ children (`:not(:has(> [slot]))`, see FEEDBACK-38 addendum), so a
20
+ <admin-entity-item slot="heading"> survives collapse and manages
21
+ its own label/badge here — a bare <span slot="heading"> cannot.
22
+ ═══════════════════════════════════════════════════════════════ */
23
+
24
+ admin-entity-item {
25
+ /* ── tunable tokens ──
26
+ Gap + horizontal padding match <select-ui>'s trigger row and
27
+ <nav-item-ui>'s row (shared convention: --a-space-1 between
28
+ slots, --a-ui-px on each inline edge). Consumers can opt out
29
+ by setting --entity-item-px: 0 on a per-use basis. */
30
+ --entity-item-gap: var(--a-space-1);
31
+ --entity-item-px: var(--a-ui-px);
32
+ --entity-item-icon-size: 1rem;
33
+ --entity-item-icon-color: var(--a-fg-muted);
34
+ --entity-item-avatar-size: 1.5rem;
35
+
36
+ display: inline-flex;
37
+ align-items: center;
38
+ gap: var(--entity-item-gap);
39
+ padding: 0 var(--entity-item-px);
40
+ min-width: 0;
41
+ overflow: hidden;
42
+ }
43
+
44
+ /* Leading visual — <icon-ui> glyph or <img> avatar. Never shrinks. */
45
+ admin-entity-item > [slot="icon"] {
46
+ flex-shrink: 0;
47
+ display: inline-flex;
48
+ align-items: center;
49
+ line-height: 1;
50
+ color: var(--entity-item-icon-color);
51
+ --a-icon-size: var(--entity-item-icon-size);
52
+ }
53
+
54
+ /* <img slot="icon"> → circular avatar treatment. */
55
+ admin-entity-item > img[slot="icon"] {
56
+ width: var(--entity-item-avatar-size);
57
+ height: var(--entity-item-avatar-size);
58
+ border-radius: var(--a-radius-full);
59
+ object-fit: cover;
60
+ }
61
+
62
+ /* Truncating label — takes the remaining width, ellipsises overflow. */
63
+ admin-entity-item > [slot="label"] {
64
+ flex: 1;
65
+ min-width: 0;
66
+ overflow: hidden;
67
+ text-overflow: ellipsis;
68
+ white-space: nowrap;
69
+ font-size: var(--a-ui-sm);
70
+ font-weight: var(--a-weight-medium, 500);
71
+ color: var(--a-fg);
72
+ }
73
+
74
+ /* Optional trailing badge — environment / role chip. Never shrinks. */
75
+ admin-entity-item > [slot="badge"] {
76
+ flex-shrink: 0;
77
+ }
78
+
79
+ /* ── Collapsed sidebar (icon-only rail) ──
80
+ Hide the label + badge; the icon survives. The enclosing
81
+ <admin-topbar>/<admin-statusbar> collapsed rule (justify-content:
82
+ center, in collapsed.css) centres the now-icon-only item. */
83
+ @container sidebar (max-width: 96px) {
84
+ admin-entity-item > [slot="label"],
85
+ admin-entity-item > [slot="badge"] {
86
+ display: none;
87
+ }
88
+ }
@@ -83,8 +83,14 @@ admin-page-header > :is(header, header-ui)[data-compact] {
83
83
  padding-block: var(--page-header-px);
84
84
  }
85
85
 
86
- /* Title row: h1 left, actions right */
87
- admin-page-header > :is(header, header-ui) > div:first-child {
86
+ /* Title row: h1 left, actions right.
87
+ `:first-of-type` (not `:first-child`) so the row still matches when a
88
+ non-<div> element is prepended ahead of it — e.g. the
89
+ `<span data-chunk-marker>` the `?chunks` dev overlay (site/dev-chunks.js)
90
+ injects as the first child of every `[data-chunk]` element. With
91
+ `:first-child` the prepended span won the match and the title + actions
92
+ stacked instead of sitting on one row. */
93
+ admin-page-header > :is(header, header-ui) > div:first-of-type {
88
94
  display: flex;
89
95
  align-items: center;
90
96
  justify-content: space-between;
@@ -38,7 +38,7 @@
38
38
 
39
39
  /* Content area — scroll region inside main */
40
40
  --page-content-bg: var(--a-canvas-0); /* content surface (lighter than chrome) */
41
- --page-content-header-bg: var(--a-canvas-1); /* sticky page-header band — matches sidebar/topbar canvas so the shell reads as a continuous L-shape of chrome wrapping the page-body. ΔL=0.04 above body canvas-0. History: v0.6.14 used canvas-2 (ΔL=0.08) under the "elevated step over content" intent, but vision-tests against dense layouts showed the band still read as flush with body. v0.6.15 reframes the page-header as shell-chrome continuation (canvas-1 matches sidebar) rather than as an elevated step — visual cohesion over contrast. Consumers who want a stronger raised band can override this token at :root. */
41
+ --page-content-header-bg: var(--a-canvas-0); /* sticky page-header band — canvas-0, matching the page-body content surface (--page-content-bg) so the header reads as a flush extension of the content area, not as separate chrome. History: v0.6.14 used canvas-2 (ΔL=0.08, "elevated step over content"); v0.6.16 rebased to canvas-1 ("shell-chrome continuation"); both still read as not-quite-flush against dense dark-mode layouts, so the band is now canvas-0 fully flush with the body content surface. Consumers who want a raised/contrasting band override this token at :root. */
42
42
  --page-content-radius: var(--a-radius-lg); /* used by "rounded" mode */
43
43
  --page-content-inset: var(--a-space-10); /* padding for header/body/footer */
44
44
  --page-content-max-width: 1540px; /* max-width for content children */
@@ -39,6 +39,7 @@
39
39
  "AdminShell",
40
40
  "AdminContent",
41
41
  "AdminTopbar",
42
+ "AdminEntityItem",
42
43
  "Footer"
43
44
  ],
44
45
  "slots": {
@@ -50,6 +50,11 @@ a2ui:
50
50
  admin-statusbar replaces <footer-ui> at shell-tier. Same slot
51
51
  vocabulary as <admin-topbar>; visual treatment differs (the
52
52
  shell css applies a top-border instead of bottom).
53
+ - >-
54
+ For a user-identity row (avatar + name + role badge), slot a single
55
+ <admin-entity-item slot="heading"> rather than separate slot="icon" +
56
+ slot="heading" children — the wrapper collapses the name + badge
57
+ together inside a collapsible <admin-sidebar>, keeping the avatar.
53
58
 
54
59
  keywords:
55
60
  - admin-statusbar
@@ -65,4 +70,5 @@ related:
65
70
  - AdminShell
66
71
  - AdminContent
67
72
  - AdminTopbar
73
+ - AdminEntityItem
68
74
  - Footer
@@ -40,6 +40,7 @@
40
40
  "AdminContent",
41
41
  "AdminSidebar",
42
42
  "AdminStatusbar",
43
+ "AdminEntityItem",
43
44
  "Header"
44
45
  ],
45
46
  "slots": {
@@ -56,6 +56,12 @@ a2ui:
56
56
  admin-topbar replaces <header-ui> at shell-tier — use it for
57
57
  chrome bars inside admin-shell, admin-content, admin-sidebar.
58
58
  Use <header-ui> for primitive containers (Card / Drawer / Modal).
59
+ - >-
60
+ For an icon + label (+ optional badge) identity row — workspace or
61
+ product identity — slot a single <admin-entity-item slot="heading">
62
+ rather than separate slot="icon" + slot="heading" children. The
63
+ wrapper keeps the icon and label as one unit so they truncate and
64
+ collapse together inside a collapsible <admin-sidebar>.
59
65
 
60
66
  keywords:
61
67
  - admin-topbar
@@ -72,4 +78,5 @@ related:
72
78
  - AdminContent
73
79
  - AdminSidebar
74
80
  - AdminStatusbar
81
+ - AdminEntityItem
75
82
  - Header