@jirawatpyk/aura-react 5.45.0 → 5.47.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -186,6 +186,26 @@ DataTable with sort and page in the URL (4.17): `onStateChange={({ sort, page })
186
186
  - **Time zone**: `timeZone` on AuraProvider, DatePicker, DateRangePicker and Calendar decides "today" (the marker, `min`/`max="today"`, the first month shown); or pass `today` as an ISO date. `todayIn('Asia/Bangkok')` is exported from the root and `/server`.
187
187
  - **Toasts** queue past three instead of dropping: six in a row all show, in order, three at a time.
188
188
 
189
+ ## 5.47 — Chamber-OS addendum 54 (#152)
190
+
191
+ - **PageHeader `size="compact"`**: 26px below 640px and 32px from 640px, on a 1.2 line — the staff and list boards' title, so a company name such as "Siam Nordic Trading Co., Ltd." takes two lines on a 390px phone instead of three. The **default stays 28px / 36px** (1.15), so DxT Monitor and other apps don't change; pass `size="compact"` (Chamber-OS: in its header wrapper) where the boards draw 26 / 32.
192
+ - **`hero` steps to 36px from 1024px** (30px below), on a 1.2 line, as `hero-lg` does — the portal Main and Edit boards. `hero-lg` is unchanged (26px, then 36px).
193
+ - **`--aura-page-header-hero-space`**: the room above a `hero` or `hero-lg` title, default 16px, on top of the page's own padding (which belongs to the app). For the boards' 24px on a phone and 40px from 1024px inside AppShell's 24px / 32px content padding, set it to `0` below 1024px and `8px` from 1024px — or whatever your page padding needs.
194
+ - Under `lang="th"` titles keep their 1.4 line at every size. Checked at 390 and 1280px in English, Thai and Swedish and at a 32px default font size: nothing scrolls sideways.
195
+
196
+ ## 5.46 — Chamber-OS addendum 53 (#151)
197
+
198
+ What Chamber-OS's own page header did that PageHeader didn't, so it can be rebuilt on PageHeader with its props kept:
199
+
200
+ - **`subtitle`**: a sentence under the title at body size (14px/1.7, the secondary colour) — "Members, plans and renewals for SweCham" — before `meta`, in a `div` (a loading skeleton's blocks are valid inside).
201
+ - **`titleAddon`**: a chip or badge on the title's line (a role, an invoice's status, "Archived"). Title and addon share a wrapping row, 12px apart (8px between lines); on a narrow screen the addon wraps under the title. It sits beside the heading, not in it, so the heading's name stays the title. Where `titleHideBelow` hides the title, the addon goes with it.
202
+ - **A chip eyebrow**: `eyebrow` that is not text (a StatusPill, a member number, badges) renders as a wrapping row in a `div`, 8px apart, 4px above the title as before. Text stays the mono `p`.
203
+ - **`size`**: `default` (28px, 36px from 640px), `hero` (30px on a 36px line) and `hero-lg` (26px, 36px from 1024px), the hero sizes with 16px more room above. Per page, `--aura-page-header-title-size` and `--aura-page-header-title-line-height` override any of them (staff pages at 26/32: set both). Under `lang="th"` the title keeps its 1.4 line, whatever the size or variable. The hero's 16px adds to the padding around it (AppShell's content, a Card), by design.
204
+ - **`focusTitleOnMount`**: the heading takes focus when the header mounts (`tabIndex={-1}`, `preventScroll`, no visible ring) — a page reached by a redirect, so a screen reader starts at its heading (WCAG 2.4.3). The main entry's PageHeader does it once, when it mounts; from `/server` the heading is focusable but not focused. Use it on pages reached by client-side navigation or a redirect, not on every page: on a first load it moves focus past a skip link, and a header that stays mounted while its title changes doesn't refocus — key it by the page (`key={pathname}`) if it must.
205
+ - **`actionsAlign`**: `end` (default) lines the actions up with the bottom of the text, as before; `start` with its top — the title, when there is no breadcrumb or eyebrow.
206
+ - Confirmed, no change: the text column's `flex: 1 1 320px` keeps a long title at least 320px wide; wide actions drop under it (checked at 700px). On a phone `actionsFullWidthBelow="sm"` shares the row between actions.
207
+ - Checked at 390 and 1280px in English, Thai and Swedish, and at a 32px default font size: nothing scrolls sideways.
208
+
189
209
  ## 5.45 — Chamber-OS addendum 52 (#150)
190
210
 
191
211
  - **PageHeader `actionsBarBelow`** (#150): `'sm' | 'md'` — below 640px or 768px the header's `actions` become a bar fixed to the bottom of the screen with ActionBar's look and offset (above a BottomNav, clear of the home indicator), and `actionsStatus` is its status line ("Total 10,700.00 THB incl. VAT · due 22 Oct 2026", a polite live region shown only in the bar).
@@ -7835,7 +7835,23 @@ window.Aura = (() => {
7835
7835
  const level = props.headingLevel || 1;
7836
7836
  const below2 = props.actionsFullWidthBelow;
7837
7837
  const hide2 = props.titleHideBelow;
7838
- const hasMeta = props.meta != null && props.meta !== false;
7838
+ const shown = function(n3) {
7839
+ return n3 != null && n3 !== false && n3 !== "";
7840
+ };
7841
+ const hasMeta = shown(props.meta) || shown(props.subtitle) || shown(props.titleAddon);
7842
+ const size = props.size === "compact" || props.size === "hero" || props.size === "hero-lg" ? props.size : null;
7843
+ const eyebrow = props.eyebrow;
7844
+ const plainEyebrow = typeof eyebrow === "string" || typeof eyebrow === "number";
7845
+ const heading = h8(
7846
+ "h" + level,
7847
+ {
7848
+ className: "aura-page-header__title",
7849
+ id: props.titleId,
7850
+ tabIndex: props.focusTitleOnMount ? -1 : void 0,
7851
+ "data-aura-focus-on-mount": props.focusTitleOnMount ? "" : void 0
7852
+ },
7853
+ props.title
7854
+ );
7839
7855
  const hasActions = props.actions != null && props.actions !== false;
7840
7856
  const bar = hasActions && (props.actionsBarBelow === "sm" || props.actionsBarBelow === "md") ? props.actionsBarBelow : null;
7841
7857
  return h8(
@@ -7848,6 +7864,8 @@ window.Aura = (() => {
7848
7864
  (hide2 === "sm" || hide2 === "md" || hide2 === "lg") && "aura-page-header--title-hide-below-" + hide2,
7849
7865
  (hide2 === "sm" || hide2 === "md" || hide2 === "lg") && !hasMeta && "has-no-meta",
7850
7866
  bar && "aura-page-header--actions-bar-below-" + bar,
7867
+ size && "aura-page-header--" + size,
7868
+ props.actionsAlign === "start" && "aura-page-header--actions-start",
7851
7869
  props.className
7852
7870
  ),
7853
7871
  style: props.style
@@ -7856,8 +7874,14 @@ window.Aura = (() => {
7856
7874
  "div",
7857
7875
  { className: "aura-page-header__text" },
7858
7876
  props.breadcrumb != null && props.breadcrumb !== false ? h8("div", { className: "aura-page-header__breadcrumb" }, props.breadcrumb) : null,
7859
- props.eyebrow != null && props.eyebrow !== false ? h8("p", { className: "aura-page-header__eyebrow" }, props.eyebrow) : null,
7860
- h8("h" + level, { className: "aura-page-header__title", id: props.titleId }, props.title),
7877
+ shown(eyebrow) ? plainEyebrow ? h8("p", { className: "aura-page-header__eyebrow" }, eyebrow) : h8("div", { className: "aura-page-header__eyebrow aura-page-header__eyebrow--rich" }, eyebrow) : null,
7878
+ shown(props.titleAddon) ? h8(
7879
+ "div",
7880
+ { className: "aura-page-header__title-row" },
7881
+ heading,
7882
+ h8("div", { className: "aura-page-header__title-addon" }, props.titleAddon)
7883
+ ) : heading,
7884
+ shown(props.subtitle) ? h8("div", { className: "aura-page-header__subtitle" }, props.subtitle) : null,
7861
7885
  props.meta != null && props.meta !== false ? h8("div", { className: "aura-page-header__meta" }, props.meta) : null
7862
7886
  ),
7863
7887
  props.actions != null && props.actions !== false ? h8(
@@ -7923,6 +7947,12 @@ window.Aura = (() => {
7923
7947
  },
7924
7948
  [bar, hasActions]
7925
7949
  );
7950
+ const focusTitle = !!props.focusTitleOnMount;
7951
+ React44.useEffect(function() {
7952
+ if (!focusTitle || !own.current) return;
7953
+ const t = own.current.querySelector(".aura-page-header__title");
7954
+ if (t) t.focus({ preventScroll: true });
7955
+ }, []);
7926
7956
  return /* @__PURE__ */ React44.createElement(PageHeader, { ...props, ref: merged });
7927
7957
  });
7928
7958
 
@@ -7817,7 +7817,23 @@ var PageHeader = React43.forwardRef(function PageHeader2(props, ref) {
7817
7817
  const level = props.headingLevel || 1;
7818
7818
  const below2 = props.actionsFullWidthBelow;
7819
7819
  const hide2 = props.titleHideBelow;
7820
- const hasMeta = props.meta != null && props.meta !== false;
7820
+ const shown = function(n3) {
7821
+ return n3 != null && n3 !== false && n3 !== "";
7822
+ };
7823
+ const hasMeta = shown(props.meta) || shown(props.subtitle) || shown(props.titleAddon);
7824
+ const size = props.size === "compact" || props.size === "hero" || props.size === "hero-lg" ? props.size : null;
7825
+ const eyebrow = props.eyebrow;
7826
+ const plainEyebrow = typeof eyebrow === "string" || typeof eyebrow === "number";
7827
+ const heading = h8(
7828
+ "h" + level,
7829
+ {
7830
+ className: "aura-page-header__title",
7831
+ id: props.titleId,
7832
+ tabIndex: props.focusTitleOnMount ? -1 : void 0,
7833
+ "data-aura-focus-on-mount": props.focusTitleOnMount ? "" : void 0
7834
+ },
7835
+ props.title
7836
+ );
7821
7837
  const hasActions = props.actions != null && props.actions !== false;
7822
7838
  const bar = hasActions && (props.actionsBarBelow === "sm" || props.actionsBarBelow === "md") ? props.actionsBarBelow : null;
7823
7839
  return h8(
@@ -7830,6 +7846,8 @@ var PageHeader = React43.forwardRef(function PageHeader2(props, ref) {
7830
7846
  (hide2 === "sm" || hide2 === "md" || hide2 === "lg") && "aura-page-header--title-hide-below-" + hide2,
7831
7847
  (hide2 === "sm" || hide2 === "md" || hide2 === "lg") && !hasMeta && "has-no-meta",
7832
7848
  bar && "aura-page-header--actions-bar-below-" + bar,
7849
+ size && "aura-page-header--" + size,
7850
+ props.actionsAlign === "start" && "aura-page-header--actions-start",
7833
7851
  props.className
7834
7852
  ),
7835
7853
  style: props.style
@@ -7838,8 +7856,14 @@ var PageHeader = React43.forwardRef(function PageHeader2(props, ref) {
7838
7856
  "div",
7839
7857
  { className: "aura-page-header__text" },
7840
7858
  props.breadcrumb != null && props.breadcrumb !== false ? h8("div", { className: "aura-page-header__breadcrumb" }, props.breadcrumb) : null,
7841
- props.eyebrow != null && props.eyebrow !== false ? h8("p", { className: "aura-page-header__eyebrow" }, props.eyebrow) : null,
7842
- h8("h" + level, { className: "aura-page-header__title", id: props.titleId }, props.title),
7859
+ shown(eyebrow) ? plainEyebrow ? h8("p", { className: "aura-page-header__eyebrow" }, eyebrow) : h8("div", { className: "aura-page-header__eyebrow aura-page-header__eyebrow--rich" }, eyebrow) : null,
7860
+ shown(props.titleAddon) ? h8(
7861
+ "div",
7862
+ { className: "aura-page-header__title-row" },
7863
+ heading,
7864
+ h8("div", { className: "aura-page-header__title-addon" }, props.titleAddon)
7865
+ ) : heading,
7866
+ shown(props.subtitle) ? h8("div", { className: "aura-page-header__subtitle" }, props.subtitle) : null,
7843
7867
  props.meta != null && props.meta !== false ? h8("div", { className: "aura-page-header__meta" }, props.meta) : null
7844
7868
  ),
7845
7869
  props.actions != null && props.actions !== false ? h8(
@@ -7905,6 +7929,12 @@ var PageHeader3 = React44.forwardRef(function PageHeader4(props, ref) {
7905
7929
  },
7906
7930
  [bar, hasActions]
7907
7931
  );
7932
+ const focusTitle = !!props.focusTitleOnMount;
7933
+ React44.useEffect(function() {
7934
+ if (!focusTitle || !own.current) return;
7935
+ const t = own.current.querySelector(".aura-page-header__title");
7936
+ if (t) t.focus({ preventScroll: true });
7937
+ }, []);
7908
7938
  return /* @__PURE__ */ React44.createElement(PageHeader, { ...props, ref: merged });
7909
7939
  });
7910
7940
 
@@ -11,7 +11,23 @@ const PageHeader = React.forwardRef(function PageHeader2(props, ref) {
11
11
  const level = props.headingLevel || 1;
12
12
  const below = props.actionsFullWidthBelow;
13
13
  const hide = props.titleHideBelow;
14
- const hasMeta = props.meta != null && props.meta !== false;
14
+ const shown = function(n) {
15
+ return n != null && n !== false && n !== "";
16
+ };
17
+ const hasMeta = shown(props.meta) || shown(props.subtitle) || shown(props.titleAddon);
18
+ const size = props.size === "compact" || props.size === "hero" || props.size === "hero-lg" ? props.size : null;
19
+ const eyebrow = props.eyebrow;
20
+ const plainEyebrow = typeof eyebrow === "string" || typeof eyebrow === "number";
21
+ const heading = h(
22
+ "h" + level,
23
+ {
24
+ className: "aura-page-header__title",
25
+ id: props.titleId,
26
+ tabIndex: props.focusTitleOnMount ? -1 : void 0,
27
+ "data-aura-focus-on-mount": props.focusTitleOnMount ? "" : void 0
28
+ },
29
+ props.title
30
+ );
15
31
  const hasActions = props.actions != null && props.actions !== false;
16
32
  const bar = hasActions && (props.actionsBarBelow === "sm" || props.actionsBarBelow === "md") ? props.actionsBarBelow : null;
17
33
  return h(
@@ -24,6 +40,8 @@ const PageHeader = React.forwardRef(function PageHeader2(props, ref) {
24
40
  (hide === "sm" || hide === "md" || hide === "lg") && "aura-page-header--title-hide-below-" + hide,
25
41
  (hide === "sm" || hide === "md" || hide === "lg") && !hasMeta && "has-no-meta",
26
42
  bar && "aura-page-header--actions-bar-below-" + bar,
43
+ size && "aura-page-header--" + size,
44
+ props.actionsAlign === "start" && "aura-page-header--actions-start",
27
45
  props.className
28
46
  ),
29
47
  style: props.style
@@ -32,8 +50,14 @@ const PageHeader = React.forwardRef(function PageHeader2(props, ref) {
32
50
  "div",
33
51
  { className: "aura-page-header__text" },
34
52
  props.breadcrumb != null && props.breadcrumb !== false ? h("div", { className: "aura-page-header__breadcrumb" }, props.breadcrumb) : null,
35
- props.eyebrow != null && props.eyebrow !== false ? h("p", { className: "aura-page-header__eyebrow" }, props.eyebrow) : null,
36
- h("h" + level, { className: "aura-page-header__title", id: props.titleId }, props.title),
53
+ shown(eyebrow) ? plainEyebrow ? h("p", { className: "aura-page-header__eyebrow" }, eyebrow) : h("div", { className: "aura-page-header__eyebrow aura-page-header__eyebrow--rich" }, eyebrow) : null,
54
+ shown(props.titleAddon) ? h(
55
+ "div",
56
+ { className: "aura-page-header__title-row" },
57
+ heading,
58
+ h("div", { className: "aura-page-header__title-addon" }, props.titleAddon)
59
+ ) : heading,
60
+ shown(props.subtitle) ? h("div", { className: "aura-page-header__subtitle" }, props.subtitle) : null,
37
61
  props.meta != null && props.meta !== false ? h("div", { className: "aura-page-header__meta" }, props.meta) : null
38
62
  ),
39
63
  props.actions != null && props.actions !== false ? h(
@@ -55,6 +55,12 @@ const PageHeader = React.forwardRef(function PageHeader2(props, ref) {
55
55
  },
56
56
  [bar, hasActions]
57
57
  );
58
+ const focusTitle = !!props.focusTitleOnMount;
59
+ React.useEffect(function() {
60
+ if (!focusTitle || !own.current) return;
61
+ const t = own.current.querySelector(".aura-page-header__title");
62
+ if (t) t.focus({ preventScroll: true });
63
+ }, []);
58
64
  return /* @__PURE__ */ React.createElement(StaticPageHeader, { ...props, ref: merged });
59
65
  });
60
66
  export {
package/dist/index.d.cts CHANGED
@@ -1932,7 +1932,8 @@ export declare const Container: React$1.ForwardRefExoticComponent<ContainerProps
1932
1932
  * `/server`. It renders a plain `div`: to name a region by its title, put `aria-labelledby={titleId}` on your own
1933
1933
  * `<section>`, or pass `role="region"` with it. */
1934
1934
  export interface PageHeaderProps extends Pick<React$1.HTMLAttributes<HTMLElement>, "id" | "lang" | "dir" | "role">, React$1.AriaAttributes, DataAttributes {
1935
- /** Small mono line above the title — a section or breadcrumb-like context ("Monitor / Sites"). */
1935
+ /** Small mono line above the title — a section or breadcrumb-like context ("Monitor / Sites"). 5.46 (Chamber-OS
1936
+ * 151): anything but text (chips: a status, a member number, badges) is a wrapping row in a `div`, 8px apart. */
1936
1937
  eyebrow?: React$1.ReactNode | undefined;
1937
1938
  /** 5.33 (DxT Monitor #7): a `<Breadcrumb>` above the title, 4px from it like the eyebrow, in its own `div` (a `nav`
1938
1939
  * can't sit in the eyebrow's `p`) and its own 13px sans. Detail pages show a breadcrumb or an eyebrow; with both,
@@ -1940,6 +1941,25 @@ export interface PageHeaderProps extends Pick<React$1.HTMLAttributes<HTMLElement
1940
1941
  breadcrumb?: React$1.ReactNode | undefined;
1941
1942
  /** The page's heading. */
1942
1943
  title: React$1.ReactNode;
1944
+ /** 5.46 (Chamber-OS 151): a sentence under the title at body size (14px/1.7, secondary colour) — "Members, plans
1945
+ * and renewals for SweCham" — before `meta`. A `div`, so a loading skeleton's blocks are valid inside. */
1946
+ subtitle?: React$1.ReactNode | undefined;
1947
+ /** 5.46: a chip or badge on the title's line (a role, an invoice's status, "Archived"). Title and addon share a
1948
+ * wrapping row, 8px apart vertically and 12px across; on a narrow screen the addon wraps under the title. */
1949
+ titleAddon?: React$1.ReactNode | undefined;
1950
+ /** 5.46: the title's size. `default` 28px below 640px, 36px from 640px; `compact` (5.47, Chamber-OS 152) 26px below
1951
+ * 640px, 32px from 640px, on a 1.2 line — staff and list pages; `hero` 30px below 1024px and 36px from 1024px (5.47)
1952
+ * on a 1.2 line, with more room above (`--aura-page-header-hero-space`, default 16px); `hero-lg` 26px below 1024px
1953
+ * and 36px from 1024px, with the same room. Per page, the custom properties `--aura-page-header-title-size` and
1954
+ * `--aura-page-header-title-line-height` override any of them. */
1955
+ size?: "default" | "compact" | "hero" | "hero-lg" | undefined;
1956
+ /** 5.46: focus the heading when the header mounts (`tabIndex={-1}`, `preventScroll`, no visible ring) — a page
1957
+ * reached by a server redirect (renewal done, back from a payment page), so a screen reader starts there (WCAG
1958
+ * 2.4.3). The main entry's PageHeader does it; from `/server` the heading is focusable but not focused. */
1959
+ focusTitleOnMount?: boolean | undefined;
1960
+ /** 5.46: `end` (default) lines the actions up with the bottom of the text; `start` with its top (the title, when
1961
+ * there is no breadcrumb or eyebrow). */
1962
+ actionsAlign?: "end" | "start" | undefined;
1943
1963
  /** A line under the title — counts, last update, owner. */
1944
1964
  meta?: React$1.ReactNode | undefined;
1945
1965
  /** Buttons for the page, bottom-aligned at the end; they wrap below the text on a narrow screen. */
package/dist/index.d.ts CHANGED
@@ -1932,7 +1932,8 @@ export declare const Container: React$1.ForwardRefExoticComponent<ContainerProps
1932
1932
  * `/server`. It renders a plain `div`: to name a region by its title, put `aria-labelledby={titleId}` on your own
1933
1933
  * `<section>`, or pass `role="region"` with it. */
1934
1934
  export interface PageHeaderProps extends Pick<React$1.HTMLAttributes<HTMLElement>, "id" | "lang" | "dir" | "role">, React$1.AriaAttributes, DataAttributes {
1935
- /** Small mono line above the title — a section or breadcrumb-like context ("Monitor / Sites"). */
1935
+ /** Small mono line above the title — a section or breadcrumb-like context ("Monitor / Sites"). 5.46 (Chamber-OS
1936
+ * 151): anything but text (chips: a status, a member number, badges) is a wrapping row in a `div`, 8px apart. */
1936
1937
  eyebrow?: React$1.ReactNode | undefined;
1937
1938
  /** 5.33 (DxT Monitor #7): a `<Breadcrumb>` above the title, 4px from it like the eyebrow, in its own `div` (a `nav`
1938
1939
  * can't sit in the eyebrow's `p`) and its own 13px sans. Detail pages show a breadcrumb or an eyebrow; with both,
@@ -1940,6 +1941,25 @@ export interface PageHeaderProps extends Pick<React$1.HTMLAttributes<HTMLElement
1940
1941
  breadcrumb?: React$1.ReactNode | undefined;
1941
1942
  /** The page's heading. */
1942
1943
  title: React$1.ReactNode;
1944
+ /** 5.46 (Chamber-OS 151): a sentence under the title at body size (14px/1.7, secondary colour) — "Members, plans
1945
+ * and renewals for SweCham" — before `meta`. A `div`, so a loading skeleton's blocks are valid inside. */
1946
+ subtitle?: React$1.ReactNode | undefined;
1947
+ /** 5.46: a chip or badge on the title's line (a role, an invoice's status, "Archived"). Title and addon share a
1948
+ * wrapping row, 8px apart vertically and 12px across; on a narrow screen the addon wraps under the title. */
1949
+ titleAddon?: React$1.ReactNode | undefined;
1950
+ /** 5.46: the title's size. `default` 28px below 640px, 36px from 640px; `compact` (5.47, Chamber-OS 152) 26px below
1951
+ * 640px, 32px from 640px, on a 1.2 line — staff and list pages; `hero` 30px below 1024px and 36px from 1024px (5.47)
1952
+ * on a 1.2 line, with more room above (`--aura-page-header-hero-space`, default 16px); `hero-lg` 26px below 1024px
1953
+ * and 36px from 1024px, with the same room. Per page, the custom properties `--aura-page-header-title-size` and
1954
+ * `--aura-page-header-title-line-height` override any of them. */
1955
+ size?: "default" | "compact" | "hero" | "hero-lg" | undefined;
1956
+ /** 5.46: focus the heading when the header mounts (`tabIndex={-1}`, `preventScroll`, no visible ring) — a page
1957
+ * reached by a server redirect (renewal done, back from a payment page), so a screen reader starts there (WCAG
1958
+ * 2.4.3). The main entry's PageHeader does it; from `/server` the heading is focusable but not focused. */
1959
+ focusTitleOnMount?: boolean | undefined;
1960
+ /** 5.46: `end` (default) lines the actions up with the bottom of the text; `start` with its top (the title, when
1961
+ * there is no breadcrumb or eyebrow). */
1962
+ actionsAlign?: "end" | "start" | undefined;
1943
1963
  /** A line under the title — counts, last update, owner. */
1944
1964
  meta?: React$1.ReactNode | undefined;
1945
1965
  /** Buttons for the page, bottom-aligned at the end; they wrap below the text on a narrow screen. */
@@ -1442,7 +1442,23 @@ var PageHeader = React5.forwardRef(function PageHeader2(props, ref) {
1442
1442
  const level = props.headingLevel || 1;
1443
1443
  const below = props.actionsFullWidthBelow;
1444
1444
  const hide = props.titleHideBelow;
1445
- const hasMeta = props.meta != null && props.meta !== false;
1445
+ const shown = function(n3) {
1446
+ return n3 != null && n3 !== false && n3 !== "";
1447
+ };
1448
+ const hasMeta = shown(props.meta) || shown(props.subtitle) || shown(props.titleAddon);
1449
+ const size = props.size === "compact" || props.size === "hero" || props.size === "hero-lg" ? props.size : null;
1450
+ const eyebrow = props.eyebrow;
1451
+ const plainEyebrow = typeof eyebrow === "string" || typeof eyebrow === "number";
1452
+ const heading = h4(
1453
+ "h" + level,
1454
+ {
1455
+ className: "aura-page-header__title",
1456
+ id: props.titleId,
1457
+ tabIndex: props.focusTitleOnMount ? -1 : void 0,
1458
+ "data-aura-focus-on-mount": props.focusTitleOnMount ? "" : void 0
1459
+ },
1460
+ props.title
1461
+ );
1446
1462
  const hasActions = props.actions != null && props.actions !== false;
1447
1463
  const bar = hasActions && (props.actionsBarBelow === "sm" || props.actionsBarBelow === "md") ? props.actionsBarBelow : null;
1448
1464
  return h4(
@@ -1455,6 +1471,8 @@ var PageHeader = React5.forwardRef(function PageHeader2(props, ref) {
1455
1471
  (hide === "sm" || hide === "md" || hide === "lg") && "aura-page-header--title-hide-below-" + hide,
1456
1472
  (hide === "sm" || hide === "md" || hide === "lg") && !hasMeta && "has-no-meta",
1457
1473
  bar && "aura-page-header--actions-bar-below-" + bar,
1474
+ size && "aura-page-header--" + size,
1475
+ props.actionsAlign === "start" && "aura-page-header--actions-start",
1458
1476
  props.className
1459
1477
  ),
1460
1478
  style: props.style
@@ -1463,8 +1481,14 @@ var PageHeader = React5.forwardRef(function PageHeader2(props, ref) {
1463
1481
  "div",
1464
1482
  { className: "aura-page-header__text" },
1465
1483
  props.breadcrumb != null && props.breadcrumb !== false ? h4("div", { className: "aura-page-header__breadcrumb" }, props.breadcrumb) : null,
1466
- props.eyebrow != null && props.eyebrow !== false ? h4("p", { className: "aura-page-header__eyebrow" }, props.eyebrow) : null,
1467
- h4("h" + level, { className: "aura-page-header__title", id: props.titleId }, props.title),
1484
+ shown(eyebrow) ? plainEyebrow ? h4("p", { className: "aura-page-header__eyebrow" }, eyebrow) : h4("div", { className: "aura-page-header__eyebrow aura-page-header__eyebrow--rich" }, eyebrow) : null,
1485
+ shown(props.titleAddon) ? h4(
1486
+ "div",
1487
+ { className: "aura-page-header__title-row" },
1488
+ heading,
1489
+ h4("div", { className: "aura-page-header__title-addon" }, props.titleAddon)
1490
+ ) : heading,
1491
+ shown(props.subtitle) ? h4("div", { className: "aura-page-header__subtitle" }, props.subtitle) : null,
1468
1492
  props.meta != null && props.meta !== false ? h4("div", { className: "aura-page-header__meta" }, props.meta) : null
1469
1493
  ),
1470
1494
  props.actions != null && props.actions !== false ? h4(
@@ -490,7 +490,8 @@ export declare const Container: React$1.ForwardRefExoticComponent<ContainerProps
490
490
  * `/server`. It renders a plain `div`: to name a region by its title, put `aria-labelledby={titleId}` on your own
491
491
  * `<section>`, or pass `role="region"` with it. */
492
492
  export interface PageHeaderProps extends Pick<React$1.HTMLAttributes<HTMLElement>, "id" | "lang" | "dir" | "role">, React$1.AriaAttributes, DataAttributes {
493
- /** Small mono line above the title — a section or breadcrumb-like context ("Monitor / Sites"). */
493
+ /** Small mono line above the title — a section or breadcrumb-like context ("Monitor / Sites"). 5.46 (Chamber-OS
494
+ * 151): anything but text (chips: a status, a member number, badges) is a wrapping row in a `div`, 8px apart. */
494
495
  eyebrow?: React$1.ReactNode | undefined;
495
496
  /** 5.33 (DxT Monitor #7): a `<Breadcrumb>` above the title, 4px from it like the eyebrow, in its own `div` (a `nav`
496
497
  * can't sit in the eyebrow's `p`) and its own 13px sans. Detail pages show a breadcrumb or an eyebrow; with both,
@@ -498,6 +499,25 @@ export interface PageHeaderProps extends Pick<React$1.HTMLAttributes<HTMLElement
498
499
  breadcrumb?: React$1.ReactNode | undefined;
499
500
  /** The page's heading. */
500
501
  title: React$1.ReactNode;
502
+ /** 5.46 (Chamber-OS 151): a sentence under the title at body size (14px/1.7, secondary colour) — "Members, plans
503
+ * and renewals for SweCham" — before `meta`. A `div`, so a loading skeleton's blocks are valid inside. */
504
+ subtitle?: React$1.ReactNode | undefined;
505
+ /** 5.46: a chip or badge on the title's line (a role, an invoice's status, "Archived"). Title and addon share a
506
+ * wrapping row, 8px apart vertically and 12px across; on a narrow screen the addon wraps under the title. */
507
+ titleAddon?: React$1.ReactNode | undefined;
508
+ /** 5.46: the title's size. `default` 28px below 640px, 36px from 640px; `compact` (5.47, Chamber-OS 152) 26px below
509
+ * 640px, 32px from 640px, on a 1.2 line — staff and list pages; `hero` 30px below 1024px and 36px from 1024px (5.47)
510
+ * on a 1.2 line, with more room above (`--aura-page-header-hero-space`, default 16px); `hero-lg` 26px below 1024px
511
+ * and 36px from 1024px, with the same room. Per page, the custom properties `--aura-page-header-title-size` and
512
+ * `--aura-page-header-title-line-height` override any of them. */
513
+ size?: "default" | "compact" | "hero" | "hero-lg" | undefined;
514
+ /** 5.46: focus the heading when the header mounts (`tabIndex={-1}`, `preventScroll`, no visible ring) — a page
515
+ * reached by a server redirect (renewal done, back from a payment page), so a screen reader starts there (WCAG
516
+ * 2.4.3). The main entry's PageHeader does it; from `/server` the heading is focusable but not focused. */
517
+ focusTitleOnMount?: boolean | undefined;
518
+ /** 5.46: `end` (default) lines the actions up with the bottom of the text; `start` with its top (the title, when
519
+ * there is no breadcrumb or eyebrow). */
520
+ actionsAlign?: "end" | "start" | undefined;
501
521
  /** A line under the title — counts, last update, owner. */
502
522
  meta?: React$1.ReactNode | undefined;
503
523
  /** Buttons for the page, bottom-aligned at the end; they wrap below the text on a narrow screen. */
@@ -490,7 +490,8 @@ export declare const Container: React$1.ForwardRefExoticComponent<ContainerProps
490
490
  * `/server`. It renders a plain `div`: to name a region by its title, put `aria-labelledby={titleId}` on your own
491
491
  * `<section>`, or pass `role="region"` with it. */
492
492
  export interface PageHeaderProps extends Pick<React$1.HTMLAttributes<HTMLElement>, "id" | "lang" | "dir" | "role">, React$1.AriaAttributes, DataAttributes {
493
- /** Small mono line above the title — a section or breadcrumb-like context ("Monitor / Sites"). */
493
+ /** Small mono line above the title — a section or breadcrumb-like context ("Monitor / Sites"). 5.46 (Chamber-OS
494
+ * 151): anything but text (chips: a status, a member number, badges) is a wrapping row in a `div`, 8px apart. */
494
495
  eyebrow?: React$1.ReactNode | undefined;
495
496
  /** 5.33 (DxT Monitor #7): a `<Breadcrumb>` above the title, 4px from it like the eyebrow, in its own `div` (a `nav`
496
497
  * can't sit in the eyebrow's `p`) and its own 13px sans. Detail pages show a breadcrumb or an eyebrow; with both,
@@ -498,6 +499,25 @@ export interface PageHeaderProps extends Pick<React$1.HTMLAttributes<HTMLElement
498
499
  breadcrumb?: React$1.ReactNode | undefined;
499
500
  /** The page's heading. */
500
501
  title: React$1.ReactNode;
502
+ /** 5.46 (Chamber-OS 151): a sentence under the title at body size (14px/1.7, secondary colour) — "Members, plans
503
+ * and renewals for SweCham" — before `meta`. A `div`, so a loading skeleton's blocks are valid inside. */
504
+ subtitle?: React$1.ReactNode | undefined;
505
+ /** 5.46: a chip or badge on the title's line (a role, an invoice's status, "Archived"). Title and addon share a
506
+ * wrapping row, 8px apart vertically and 12px across; on a narrow screen the addon wraps under the title. */
507
+ titleAddon?: React$1.ReactNode | undefined;
508
+ /** 5.46: the title's size. `default` 28px below 640px, 36px from 640px; `compact` (5.47, Chamber-OS 152) 26px below
509
+ * 640px, 32px from 640px, on a 1.2 line — staff and list pages; `hero` 30px below 1024px and 36px from 1024px (5.47)
510
+ * on a 1.2 line, with more room above (`--aura-page-header-hero-space`, default 16px); `hero-lg` 26px below 1024px
511
+ * and 36px from 1024px, with the same room. Per page, the custom properties `--aura-page-header-title-size` and
512
+ * `--aura-page-header-title-line-height` override any of them. */
513
+ size?: "default" | "compact" | "hero" | "hero-lg" | undefined;
514
+ /** 5.46: focus the heading when the header mounts (`tabIndex={-1}`, `preventScroll`, no visible ring) — a page
515
+ * reached by a server redirect (renewal done, back from a payment page), so a screen reader starts there (WCAG
516
+ * 2.4.3). The main entry's PageHeader does it; from `/server` the heading is focusable but not focused. */
517
+ focusTitleOnMount?: boolean | undefined;
518
+ /** 5.46: `end` (default) lines the actions up with the bottom of the text; `start` with its top (the title, when
519
+ * there is no breadcrumb or eyebrow). */
520
+ actionsAlign?: "end" | "start" | undefined;
501
521
  /** A line under the title — counts, last update, owner. */
502
522
  meta?: React$1.ReactNode | undefined;
503
523
  /** Buttons for the page, bottom-aligned at the end; they wrap below the text on a narrow screen. */
@@ -1378,7 +1378,23 @@ var PageHeader = React5.forwardRef(function PageHeader2(props, ref) {
1378
1378
  const level = props.headingLevel || 1;
1379
1379
  const below = props.actionsFullWidthBelow;
1380
1380
  const hide = props.titleHideBelow;
1381
- const hasMeta = props.meta != null && props.meta !== false;
1381
+ const shown = function(n3) {
1382
+ return n3 != null && n3 !== false && n3 !== "";
1383
+ };
1384
+ const hasMeta = shown(props.meta) || shown(props.subtitle) || shown(props.titleAddon);
1385
+ const size = props.size === "compact" || props.size === "hero" || props.size === "hero-lg" ? props.size : null;
1386
+ const eyebrow = props.eyebrow;
1387
+ const plainEyebrow = typeof eyebrow === "string" || typeof eyebrow === "number";
1388
+ const heading = h4(
1389
+ "h" + level,
1390
+ {
1391
+ className: "aura-page-header__title",
1392
+ id: props.titleId,
1393
+ tabIndex: props.focusTitleOnMount ? -1 : void 0,
1394
+ "data-aura-focus-on-mount": props.focusTitleOnMount ? "" : void 0
1395
+ },
1396
+ props.title
1397
+ );
1382
1398
  const hasActions = props.actions != null && props.actions !== false;
1383
1399
  const bar = hasActions && (props.actionsBarBelow === "sm" || props.actionsBarBelow === "md") ? props.actionsBarBelow : null;
1384
1400
  return h4(
@@ -1391,6 +1407,8 @@ var PageHeader = React5.forwardRef(function PageHeader2(props, ref) {
1391
1407
  (hide === "sm" || hide === "md" || hide === "lg") && "aura-page-header--title-hide-below-" + hide,
1392
1408
  (hide === "sm" || hide === "md" || hide === "lg") && !hasMeta && "has-no-meta",
1393
1409
  bar && "aura-page-header--actions-bar-below-" + bar,
1410
+ size && "aura-page-header--" + size,
1411
+ props.actionsAlign === "start" && "aura-page-header--actions-start",
1394
1412
  props.className
1395
1413
  ),
1396
1414
  style: props.style
@@ -1399,8 +1417,14 @@ var PageHeader = React5.forwardRef(function PageHeader2(props, ref) {
1399
1417
  "div",
1400
1418
  { className: "aura-page-header__text" },
1401
1419
  props.breadcrumb != null && props.breadcrumb !== false ? h4("div", { className: "aura-page-header__breadcrumb" }, props.breadcrumb) : null,
1402
- props.eyebrow != null && props.eyebrow !== false ? h4("p", { className: "aura-page-header__eyebrow" }, props.eyebrow) : null,
1403
- h4("h" + level, { className: "aura-page-header__title", id: props.titleId }, props.title),
1420
+ shown(eyebrow) ? plainEyebrow ? h4("p", { className: "aura-page-header__eyebrow" }, eyebrow) : h4("div", { className: "aura-page-header__eyebrow aura-page-header__eyebrow--rich" }, eyebrow) : null,
1421
+ shown(props.titleAddon) ? h4(
1422
+ "div",
1423
+ { className: "aura-page-header__title-row" },
1424
+ heading,
1425
+ h4("div", { className: "aura-page-header__title-addon" }, props.titleAddon)
1426
+ ) : heading,
1427
+ shown(props.subtitle) ? h4("div", { className: "aura-page-header__subtitle" }, props.subtitle) : null,
1404
1428
  props.meta != null && props.meta !== false ? h4("div", { className: "aura-page-header__meta" }, props.meta) : null
1405
1429
  ),
1406
1430
  props.actions != null && props.actions !== false ? h4(
package/dist/styles.css CHANGED
@@ -1152,7 +1152,7 @@ a.aura-tab { text-decoration: none; }
1152
1152
  .aura-page-header { display: flex; flex-wrap: wrap; align-items: flex-end; justify-content: space-between; gap: var(--aura-space-4) var(--aura-space-6); min-width: 0; font-family: var(--font-sans); }
1153
1153
  .aura-page-header__text { display: flex; flex-direction: column; gap: var(--aura-space-1); flex: 1 1 320px; min-width: 0; }
1154
1154
  .aura-page-header__eyebrow { margin: 0; font-family: var(--font-mono); font-size: max(12px, .75rem); line-height: 1.7; color: var(--aura-fg-secondary); overflow-wrap: anywhere; }
1155
- .aura-page-header__title { margin: 0; font-family: var(--font-display); font-size: max(28px, 1.75rem); line-height: 1.15; font-weight: 600; letter-spacing: -0.01em; color: var(--aura-fg-primary); overflow-wrap: anywhere; }
1155
+ .aura-page-header__title { margin: 0; font-family: var(--font-display); font-size: var(--aura-page-header-title-size, max(28px, 1.75rem)); line-height: var(--aura-page-header-title-line-height, 1.15); font-weight: 600; letter-spacing: -0.01em; color: var(--aura-fg-primary); overflow-wrap: anywhere; }
1156
1156
  .aura-page-header__breadcrumb { min-width: 0; } /* 5.33 (DxT Monitor #7): Breadcrumb keeps its own type */
1157
1157
  .aura-page-header__meta { min-width: 0; font-size: max(13px, .8125rem); line-height: 1.5; color: var(--aura-fg-secondary); overflow-wrap: anywhere; }
1158
1158
  .aura-page-header__actions { display: flex; flex-wrap: wrap; align-items: center; gap: var(--aura-space-2); }
@@ -1160,15 +1160,15 @@ a.aura-tab { text-decoration: none; }
1160
1160
  * are gone; with no meta line the text block takes no room, so the actions start the header. */
1161
1161
  @media (max-width: 639.98px) {
1162
1162
  .aura-page-header--title-hide-below-sm .aura-page-header__title, .aura-page-header--title-hide-below-sm.has-no-meta > .aura-page-header__text { position: absolute; width: 1px; height: 1px; margin: -1px; padding: 0; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0; }
1163
- .aura-page-header--title-hide-below-sm :is(.aura-page-header__breadcrumb, .aura-page-header__eyebrow) { display: none; }
1163
+ .aura-page-header--title-hide-below-sm :is(.aura-page-header__breadcrumb, .aura-page-header__eyebrow, .aura-page-header__title-addon) { display: none; }
1164
1164
  }
1165
1165
  @media (max-width: 767.98px) {
1166
1166
  .aura-page-header--title-hide-below-md .aura-page-header__title, .aura-page-header--title-hide-below-md.has-no-meta > .aura-page-header__text { position: absolute; width: 1px; height: 1px; margin: -1px; padding: 0; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0; }
1167
- .aura-page-header--title-hide-below-md :is(.aura-page-header__breadcrumb, .aura-page-header__eyebrow) { display: none; }
1167
+ .aura-page-header--title-hide-below-md :is(.aura-page-header__breadcrumb, .aura-page-header__eyebrow, .aura-page-header__title-addon) { display: none; }
1168
1168
  }
1169
1169
  @media (max-width: 1023.98px) {
1170
1170
  .aura-page-header--title-hide-below-lg .aura-page-header__title, .aura-page-header--title-hide-below-lg.has-no-meta > .aura-page-header__text { position: absolute; width: 1px; height: 1px; margin: -1px; padding: 0; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0; }
1171
- .aura-page-header--title-hide-below-lg :is(.aura-page-header__breadcrumb, .aura-page-header__eyebrow) { display: none; }
1171
+ .aura-page-header--title-hide-below-lg :is(.aura-page-header__breadcrumb, .aura-page-header__eyebrow, .aura-page-header__title-addon) { display: none; }
1172
1172
  }
1173
1173
  /* 5.37 (DxT Monitor #17): actionsFullWidthBelow — the actions take the row under the text; their children share
1174
1174
  * each line equally (wrapping when a label won't fit), a trigger inside a DropdownMenu, Tooltip or Popover wrapper
@@ -1244,7 +1244,23 @@ a.aura-tab { text-decoration: none; }
1244
1244
  :root:has(.aura-page-header--actions-bar-below-md):not(:has(.aura-shell__content)) body { padding-bottom: var(--aura-page-actions-space); }
1245
1245
  }
1246
1246
  @media (prefers-reduced-motion: reduce) { .aura-page-header__actions { transition: none; } }
1247
- @media (min-width: 640px) { .aura-page-header__title { font-size: max(36px, 2.25rem); } }
1247
+ @media (min-width: 640px) { .aura-page-header__title { font-size: var(--aura-page-header-title-size, max(36px, 2.25rem)); } }
1248
+ /* 5.46 (Chamber-OS 151): subtitle, a title addon, a chip eyebrow, hero sizes, a focusable heading, top-aligned actions. */
1249
+ .aura-page-header__subtitle { min-width: 0; font-size: max(14px, .875rem); line-height: 1.7; color: var(--aura-fg-secondary); overflow-wrap: anywhere; }
1250
+ .aura-page-header__title-row { display: flex; flex-wrap: wrap; align-items: center; gap: var(--aura-space-2) var(--aura-space-3); min-width: 0; }
1251
+ .aura-page-header__title-row > .aura-page-header__title { min-width: 0; }
1252
+ .aura-page-header__title-addon { display: flex; flex-wrap: wrap; align-items: center; gap: var(--aura-space-2); min-width: 0; }
1253
+ .aura-page-header__eyebrow--rich { display: flex; flex-wrap: wrap; align-items: center; gap: var(--aura-space-2); font-family: var(--font-sans); line-height: 1.5; }
1254
+ .aura-page-header--hero, .aura-page-header--hero-lg { padding-top: var(--aura-page-header-hero-space, var(--aura-space-4)); }
1255
+ .aura-page-header--hero .aura-page-header__title { font-size: var(--aura-page-header-title-size, max(30px, 1.875rem)); line-height: var(--aura-page-header-title-line-height, 1.2); }
1256
+ /* 5.47 (Chamber-OS 152): compact — the staff boards' 26 / 32; hero steps to 36px from 1024px like hero-lg. */
1257
+ .aura-page-header--compact .aura-page-header__title { font-size: var(--aura-page-header-title-size, max(26px, 1.625rem)); line-height: var(--aura-page-header-title-line-height, 1.2); }
1258
+ @media (min-width: 640px) { .aura-page-header--compact .aura-page-header__title { font-size: var(--aura-page-header-title-size, max(32px, 2rem)); } }
1259
+ @media (min-width: 1024px) { .aura-page-header--hero .aura-page-header__title { font-size: var(--aura-page-header-title-size, max(36px, 2.25rem)); } }
1260
+ .aura-page-header--hero-lg .aura-page-header__title { font-size: var(--aura-page-header-title-size, max(26px, 1.625rem)); line-height: var(--aura-page-header-title-line-height, 1.25); }
1261
+ @media (min-width: 1024px) { .aura-page-header--hero-lg .aura-page-header__title { font-size: var(--aura-page-header-title-size, max(36px, 2.25rem)); line-height: var(--aura-page-header-title-line-height, 1.2); } }
1262
+ .aura-page-header__title[tabindex="-1"]:focus { outline: none; }
1263
+ .aura-page-header--actions-start { align-items: flex-start; }
1248
1264
  /* Thai marks need the room a 1.15 line takes away. */
1249
1265
  .aura-page-header__title:lang(th) { line-height: 1.4; letter-spacing: 0; }
1250
1266
  .aura-page-header__meta:lang(th) { line-height: 1.6; }
@@ -1154,7 +1154,7 @@ a.aura-tab { text-decoration: none; }
1154
1154
  .aura-page-header { display: flex; flex-wrap: wrap; align-items: flex-end; justify-content: space-between; gap: var(--aura-space-4) var(--aura-space-6); min-width: 0; font-family: var(--font-sans); }
1155
1155
  .aura-page-header__text { display: flex; flex-direction: column; gap: var(--aura-space-1); flex: 1 1 320px; min-width: 0; }
1156
1156
  .aura-page-header__eyebrow { margin: 0; font-family: var(--font-mono); font-size: max(12px, .75rem); line-height: 1.7; color: var(--aura-fg-secondary); overflow-wrap: anywhere; }
1157
- .aura-page-header__title { margin: 0; font-family: var(--font-display); font-size: max(28px, 1.75rem); line-height: 1.15; font-weight: 600; letter-spacing: -0.01em; color: var(--aura-fg-primary); overflow-wrap: anywhere; }
1157
+ .aura-page-header__title { margin: 0; font-family: var(--font-display); font-size: var(--aura-page-header-title-size, max(28px, 1.75rem)); line-height: var(--aura-page-header-title-line-height, 1.15); font-weight: 600; letter-spacing: -0.01em; color: var(--aura-fg-primary); overflow-wrap: anywhere; }
1158
1158
  .aura-page-header__breadcrumb { min-width: 0; } /* 5.33 (DxT Monitor #7): Breadcrumb keeps its own type */
1159
1159
  .aura-page-header__meta { min-width: 0; font-size: max(13px, .8125rem); line-height: 1.5; color: var(--aura-fg-secondary); overflow-wrap: anywhere; }
1160
1160
  .aura-page-header__actions { display: flex; flex-wrap: wrap; align-items: center; gap: var(--aura-space-2); }
@@ -1162,15 +1162,15 @@ a.aura-tab { text-decoration: none; }
1162
1162
  * are gone; with no meta line the text block takes no room, so the actions start the header. */
1163
1163
  @media (max-width: 639.98px) {
1164
1164
  .aura-page-header--title-hide-below-sm .aura-page-header__title, .aura-page-header--title-hide-below-sm.has-no-meta > .aura-page-header__text { position: absolute; width: 1px; height: 1px; margin: -1px; padding: 0; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0; }
1165
- .aura-page-header--title-hide-below-sm :is(.aura-page-header__breadcrumb, .aura-page-header__eyebrow) { display: none; }
1165
+ .aura-page-header--title-hide-below-sm :is(.aura-page-header__breadcrumb, .aura-page-header__eyebrow, .aura-page-header__title-addon) { display: none; }
1166
1166
  }
1167
1167
  @media (max-width: 767.98px) {
1168
1168
  .aura-page-header--title-hide-below-md .aura-page-header__title, .aura-page-header--title-hide-below-md.has-no-meta > .aura-page-header__text { position: absolute; width: 1px; height: 1px; margin: -1px; padding: 0; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0; }
1169
- .aura-page-header--title-hide-below-md :is(.aura-page-header__breadcrumb, .aura-page-header__eyebrow) { display: none; }
1169
+ .aura-page-header--title-hide-below-md :is(.aura-page-header__breadcrumb, .aura-page-header__eyebrow, .aura-page-header__title-addon) { display: none; }
1170
1170
  }
1171
1171
  @media (max-width: 1023.98px) {
1172
1172
  .aura-page-header--title-hide-below-lg .aura-page-header__title, .aura-page-header--title-hide-below-lg.has-no-meta > .aura-page-header__text { position: absolute; width: 1px; height: 1px; margin: -1px; padding: 0; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0; }
1173
- .aura-page-header--title-hide-below-lg :is(.aura-page-header__breadcrumb, .aura-page-header__eyebrow) { display: none; }
1173
+ .aura-page-header--title-hide-below-lg :is(.aura-page-header__breadcrumb, .aura-page-header__eyebrow, .aura-page-header__title-addon) { display: none; }
1174
1174
  }
1175
1175
  /* 5.37 (DxT Monitor #17): actionsFullWidthBelow — the actions take the row under the text; their children share
1176
1176
  * each line equally (wrapping when a label won't fit), a trigger inside a DropdownMenu, Tooltip or Popover wrapper
@@ -1246,7 +1246,23 @@ a.aura-tab { text-decoration: none; }
1246
1246
  :root:has(.aura-page-header--actions-bar-below-md):not(:has(.aura-shell__content)) body { padding-bottom: var(--aura-page-actions-space); }
1247
1247
  }
1248
1248
  @media (prefers-reduced-motion: reduce) { .aura-page-header__actions { transition: none; } }
1249
- @media (min-width: 640px) { .aura-page-header__title { font-size: max(36px, 2.25rem); } }
1249
+ @media (min-width: 640px) { .aura-page-header__title { font-size: var(--aura-page-header-title-size, max(36px, 2.25rem)); } }
1250
+ /* 5.46 (Chamber-OS 151): subtitle, a title addon, a chip eyebrow, hero sizes, a focusable heading, top-aligned actions. */
1251
+ .aura-page-header__subtitle { min-width: 0; font-size: max(14px, .875rem); line-height: 1.7; color: var(--aura-fg-secondary); overflow-wrap: anywhere; }
1252
+ .aura-page-header__title-row { display: flex; flex-wrap: wrap; align-items: center; gap: var(--aura-space-2) var(--aura-space-3); min-width: 0; }
1253
+ .aura-page-header__title-row > .aura-page-header__title { min-width: 0; }
1254
+ .aura-page-header__title-addon { display: flex; flex-wrap: wrap; align-items: center; gap: var(--aura-space-2); min-width: 0; }
1255
+ .aura-page-header__eyebrow--rich { display: flex; flex-wrap: wrap; align-items: center; gap: var(--aura-space-2); font-family: var(--font-sans); line-height: 1.5; }
1256
+ .aura-page-header--hero, .aura-page-header--hero-lg { padding-top: var(--aura-page-header-hero-space, var(--aura-space-4)); }
1257
+ .aura-page-header--hero .aura-page-header__title { font-size: var(--aura-page-header-title-size, max(30px, 1.875rem)); line-height: var(--aura-page-header-title-line-height, 1.2); }
1258
+ /* 5.47 (Chamber-OS 152): compact — the staff boards' 26 / 32; hero steps to 36px from 1024px like hero-lg. */
1259
+ .aura-page-header--compact .aura-page-header__title { font-size: var(--aura-page-header-title-size, max(26px, 1.625rem)); line-height: var(--aura-page-header-title-line-height, 1.2); }
1260
+ @media (min-width: 640px) { .aura-page-header--compact .aura-page-header__title { font-size: var(--aura-page-header-title-size, max(32px, 2rem)); } }
1261
+ @media (min-width: 1024px) { .aura-page-header--hero .aura-page-header__title { font-size: var(--aura-page-header-title-size, max(36px, 2.25rem)); } }
1262
+ .aura-page-header--hero-lg .aura-page-header__title { font-size: var(--aura-page-header-title-size, max(26px, 1.625rem)); line-height: var(--aura-page-header-title-line-height, 1.25); }
1263
+ @media (min-width: 1024px) { .aura-page-header--hero-lg .aura-page-header__title { font-size: var(--aura-page-header-title-size, max(36px, 2.25rem)); line-height: var(--aura-page-header-title-line-height, 1.2); } }
1264
+ .aura-page-header__title[tabindex="-1"]:focus { outline: none; }
1265
+ .aura-page-header--actions-start { align-items: flex-start; }
1250
1266
  /* Thai marks need the room a 1.15 line takes away. */
1251
1267
  .aura-page-header__title:lang(th) { line-height: 1.4; letter-spacing: 0; }
1252
1268
  .aura-page-header__meta:lang(th) { line-height: 1.6; }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@jirawatpyk/aura-react",
3
- "version": "5.45.0",
3
+ "version": "5.47.0",
4
4
  "description": "AURA Design System — React components (Enterprise Standard, Human Creative). Thai-first: Buddhist-era dates, Thai collation.",
5
5
  "license": "MIT",
6
6
  "type": "module",