@jirawatpyk/aura-react 5.43.0 → 5.45.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.
@@ -4,7 +4,7 @@ import { cx, omit } from "./internal.js";
4
4
  import { Icon } from "./Icon.js";
5
5
  import { useAutoTip } from "./autoTip.js";
6
6
  const IconButton = React.forwardRef(function IconButton2(props, ref) {
7
- const rest = omit(props, ["icon", "label", "className", "size", "tone", "touchHeight"]);
7
+ const rest = omit(props, ["icon", "label", "className", "size", "tone", "touchHeight", "variant"]);
8
8
  useAutoTip();
9
9
  const own = props.title !== void 0;
10
10
  return /* @__PURE__ */ React.createElement(
@@ -18,6 +18,7 @@ const IconButton = React.forwardRef(function IconButton2(props, ref) {
18
18
  className: cx(
19
19
  "aura-icon-btn",
20
20
  props.tone === "danger" && "aura-icon-btn--danger",
21
+ props.variant === "outline" && "aura-icon-btn--outline",
21
22
  props.touchHeight && "aura-icon-btn--touch",
22
23
  props.className
23
24
  )
@@ -12,6 +12,8 @@ const PageHeader = React.forwardRef(function PageHeader2(props, ref) {
12
12
  const below = props.actionsFullWidthBelow;
13
13
  const hide = props.titleHideBelow;
14
14
  const hasMeta = props.meta != null && props.meta !== false;
15
+ const hasActions = props.actions != null && props.actions !== false;
16
+ const bar = hasActions && (props.actionsBarBelow === "sm" || props.actionsBarBelow === "md") ? props.actionsBarBelow : null;
15
17
  return h(
16
18
  "div",
17
19
  Object.assign(attrs, {
@@ -21,6 +23,7 @@ const PageHeader = React.forwardRef(function PageHeader2(props, ref) {
21
23
  (below === "sm" || below === "md" || below === "lg") && "aura-page-header--actions-full-below-" + below,
22
24
  (hide === "sm" || hide === "md" || hide === "lg") && "aura-page-header--title-hide-below-" + hide,
23
25
  (hide === "sm" || hide === "md" || hide === "lg") && !hasMeta && "has-no-meta",
26
+ bar && "aura-page-header--actions-bar-below-" + bar,
24
27
  props.className
25
28
  ),
26
29
  style: props.style
@@ -33,7 +36,12 @@ const PageHeader = React.forwardRef(function PageHeader2(props, ref) {
33
36
  h("h" + level, { className: "aura-page-header__title", id: props.titleId }, props.title),
34
37
  props.meta != null && props.meta !== false ? h("div", { className: "aura-page-header__meta" }, props.meta) : null
35
38
  ),
36
- props.actions != null && props.actions !== false ? h("div", { className: "aura-page-header__actions" }, props.actions) : null
39
+ props.actions != null && props.actions !== false ? h(
40
+ "div",
41
+ { className: "aura-page-header__actions" },
42
+ bar && props.actionsStatus != null && props.actionsStatus !== false ? h("div", { className: "aura-page-header__status", role: "status" }, props.actionsStatus) : null,
43
+ props.actions
44
+ ) : null
37
45
  );
38
46
  });
39
47
  export {
@@ -0,0 +1,62 @@
1
+ 'use client';
2
+ import * as React from "react";
3
+ import { PageHeader as StaticPageHeader } from "./PageHeader.js";
4
+ import { devWarnOnce, useMergedRef } from "./internal.js";
5
+ const NAME = "--aura-page-actions-height";
6
+ const bars = [];
7
+ function trapped(el) {
8
+ for (let p = el.parentElement; p && p !== document.documentElement; p = p.parentElement) {
9
+ const s = getComputedStyle(p);
10
+ if (s.transform !== "none" || s.filter !== "none" || (s.backdropFilter || "none") !== "none" || s.contentVisibility === "auto" || s.perspective !== "none" || /transform|filter|perspective/.test(s.willChange) || /paint|layout|strict|content/.test(s.contain))
11
+ return true;
12
+ }
13
+ return false;
14
+ }
15
+ const PageHeader = React.forwardRef(function PageHeader2(props, ref) {
16
+ const own = React.useRef(null);
17
+ const merged = useMergedRef(ref, own);
18
+ const bar = props.actionsBarBelow;
19
+ const hasActions = props.actions != null && props.actions !== false;
20
+ React.useEffect(
21
+ function() {
22
+ if (bar !== "sm" && bar !== "md" || !hasActions || !own.current) return;
23
+ const el = own.current.querySelector(":scope > .aura-page-header__actions");
24
+ if (!el) return;
25
+ const root = document.documentElement;
26
+ let checked = false;
27
+ function sync() {
28
+ if (bars[bars.length - 1] !== sync) return;
29
+ if (getComputedStyle(el).position === "fixed") {
30
+ root.style.setProperty(NAME, el.offsetHeight + "px");
31
+ if (!checked && (checked = true, trapped(el)))
32
+ devWarnOnce(
33
+ "pageheader-bar-trapped",
34
+ "PageHeader actionsBarBelow: an ancestor has a transform, filter, will-change or paint containment, so the fixed bar is placed against it instead of the screen. Remove it from the page header's ancestors."
35
+ );
36
+ } else root.style.removeProperty(NAME);
37
+ }
38
+ if (bars.length)
39
+ devWarnOnce(
40
+ "pageheader-bar-twice",
41
+ "PageHeader actionsBarBelow: two bars on one page overlap at the bottom of the screen. Give it to one PageHeader per page."
42
+ );
43
+ bars.push(sync);
44
+ const ro = typeof ResizeObserver === "undefined" ? null : new ResizeObserver(sync);
45
+ if (ro) ro.observe(el);
46
+ window.addEventListener("resize", sync);
47
+ sync();
48
+ return function() {
49
+ if (ro) ro.disconnect();
50
+ window.removeEventListener("resize", sync);
51
+ bars.splice(bars.indexOf(sync), 1);
52
+ if (bars.length) bars[bars.length - 1]();
53
+ else root.style.removeProperty(NAME);
54
+ };
55
+ },
56
+ [bar, hasActions]
57
+ );
58
+ return /* @__PURE__ */ React.createElement(StaticPageHeader, { ...props, ref: merged });
59
+ });
60
+ export {
61
+ PageHeader
62
+ };
package/dist/esm/index.js CHANGED
@@ -35,7 +35,7 @@ import { Avatar } from "./Avatar.js";
35
35
  import { Stack } from "./Stack.js";
36
36
  import { Grid } from "./Grid.js";
37
37
  import { Container } from "./Container.js";
38
- import { PageHeader } from "./PageHeader.js";
38
+ import { PageHeader } from "./PageHeaderClient.js";
39
39
  import { StatusTile } from "./StatusTile.js";
40
40
  import { TileGrid, Sparkline } from "./tiles.js";
41
41
  import { AppShell } from "./AppShell.js";
package/dist/index.d.cts CHANGED
@@ -353,6 +353,9 @@ export interface IconButtonProps extends React$1.ButtonHTMLAttributes<HTMLButton
353
353
  label: string;
354
354
  /** Icon size. Default `sm` (16). */
355
355
  size?: "sm" | "md" | undefined;
356
+ /** 5.44 (Chamber-OS 149): `outline` adds a secondary Button's 1px border, so a lone ⋯ reads as a button beside
357
+ * outlined actions. Default `ghost`: no border. */
358
+ variant?: "ghost" | "outline" | undefined;
356
359
  /** 44×44 instead of 32×32 below 640px (the viewport's) or wherever the primary pointer is coarse (a tablet, 5.24) —
357
360
  * a phone sheet's close button, a card's ⋯ trigger (5.15, Chamber-OS 100). */
358
361
  touchHeight?: boolean | undefined;
@@ -1950,6 +1953,19 @@ export interface PageHeaderProps extends Pick<React$1.HTMLAttributes<HTMLElement
1950
1953
  * readers — and the breadcrumb and eyebrow are hidden, for phone layouts that show the title in the top bar. The
1951
1954
  * meta line and actions stay; with no meta, the actions start the header. */
1952
1955
  titleHideBelow?: "sm" | "md" | "lg" | undefined;
1956
+ /** 5.45 (Chamber-OS 150): below this breakpoint (`sm` 640px, `md` 768px) the same `actions` — rendered once, so a
1957
+ * dialog trigger or test id is never doubled — become a bar fixed to the bottom of the screen with ActionBar's look:
1958
+ * above a BottomNav, clear of the home indicator, `actionsStatus` as its status line. The page's end and a focused
1959
+ * field scroll clear of it (AppShell's content, or the body, gains the bar's height). With an IconButton among them
1960
+ * the actions share one row, labels wrapping inside the buttons (as `actionsFullWidthBelow`, Chamber-OS 149); with only icon
1961
+ * buttons the status and the icons share one row. From the breakpoint up nothing changes. Use it for a detail page's
1962
+ * own actions (Issue credit note…, ⋯) — one per page. The bar is `position: fixed`: no ancestor of the header may
1963
+ * have a transform, filter, backdrop-filter, will-change, paint/layout containment or `content-visibility: auto`, or it is placed
1964
+ * against that ancestor instead of the screen — the main entry warns in development. */
1965
+ actionsBarBelow?: "sm" | "md" | undefined;
1966
+ /** 5.45: the bar's status line ("Total 10,700.00 THB incl. VAT · due 22 Oct 2026"), shown only while the actions are
1967
+ * a bar, in a polite live region. */
1968
+ actionsStatus?: React$1.ReactNode | undefined;
1953
1969
  /** Default 1. Use 2 when the page already has an h1 (e.g. in the AppShell bar). */
1954
1970
  headingLevel?: 1 | 2 | 3 | undefined;
1955
1971
  /** The heading's id, for `aria-labelledby` on the page's region. */
package/dist/index.d.ts CHANGED
@@ -353,6 +353,9 @@ export interface IconButtonProps extends React$1.ButtonHTMLAttributes<HTMLButton
353
353
  label: string;
354
354
  /** Icon size. Default `sm` (16). */
355
355
  size?: "sm" | "md" | undefined;
356
+ /** 5.44 (Chamber-OS 149): `outline` adds a secondary Button's 1px border, so a lone ⋯ reads as a button beside
357
+ * outlined actions. Default `ghost`: no border. */
358
+ variant?: "ghost" | "outline" | undefined;
356
359
  /** 44×44 instead of 32×32 below 640px (the viewport's) or wherever the primary pointer is coarse (a tablet, 5.24) —
357
360
  * a phone sheet's close button, a card's ⋯ trigger (5.15, Chamber-OS 100). */
358
361
  touchHeight?: boolean | undefined;
@@ -1950,6 +1953,19 @@ export interface PageHeaderProps extends Pick<React$1.HTMLAttributes<HTMLElement
1950
1953
  * readers — and the breadcrumb and eyebrow are hidden, for phone layouts that show the title in the top bar. The
1951
1954
  * meta line and actions stay; with no meta, the actions start the header. */
1952
1955
  titleHideBelow?: "sm" | "md" | "lg" | undefined;
1956
+ /** 5.45 (Chamber-OS 150): below this breakpoint (`sm` 640px, `md` 768px) the same `actions` — rendered once, so a
1957
+ * dialog trigger or test id is never doubled — become a bar fixed to the bottom of the screen with ActionBar's look:
1958
+ * above a BottomNav, clear of the home indicator, `actionsStatus` as its status line. The page's end and a focused
1959
+ * field scroll clear of it (AppShell's content, or the body, gains the bar's height). With an IconButton among them
1960
+ * the actions share one row, labels wrapping inside the buttons (as `actionsFullWidthBelow`, Chamber-OS 149); with only icon
1961
+ * buttons the status and the icons share one row. From the breakpoint up nothing changes. Use it for a detail page's
1962
+ * own actions (Issue credit note…, ⋯) — one per page. The bar is `position: fixed`: no ancestor of the header may
1963
+ * have a transform, filter, backdrop-filter, will-change, paint/layout containment or `content-visibility: auto`, or it is placed
1964
+ * against that ancestor instead of the screen — the main entry warns in development. */
1965
+ actionsBarBelow?: "sm" | "md" | undefined;
1966
+ /** 5.45: the bar's status line ("Total 10,700.00 THB incl. VAT · due 22 Oct 2026"), shown only while the actions are
1967
+ * a bar, in a polite live region. */
1968
+ actionsStatus?: React$1.ReactNode | undefined;
1953
1969
  /** Default 1. Use 2 when the page already has an h1 (e.g. in the AppShell bar). */
1954
1970
  headingLevel?: 1 | 2 | 3 | undefined;
1955
1971
  /** The heading's id, for `aria-labelledby` on the page's region. */
@@ -1443,6 +1443,8 @@ var PageHeader = React5.forwardRef(function PageHeader2(props, ref) {
1443
1443
  const below = props.actionsFullWidthBelow;
1444
1444
  const hide = props.titleHideBelow;
1445
1445
  const hasMeta = props.meta != null && props.meta !== false;
1446
+ const hasActions = props.actions != null && props.actions !== false;
1447
+ const bar = hasActions && (props.actionsBarBelow === "sm" || props.actionsBarBelow === "md") ? props.actionsBarBelow : null;
1446
1448
  return h4(
1447
1449
  "div",
1448
1450
  Object.assign(attrs2, {
@@ -1452,6 +1454,7 @@ var PageHeader = React5.forwardRef(function PageHeader2(props, ref) {
1452
1454
  (below === "sm" || below === "md" || below === "lg") && "aura-page-header--actions-full-below-" + below,
1453
1455
  (hide === "sm" || hide === "md" || hide === "lg") && "aura-page-header--title-hide-below-" + hide,
1454
1456
  (hide === "sm" || hide === "md" || hide === "lg") && !hasMeta && "has-no-meta",
1457
+ bar && "aura-page-header--actions-bar-below-" + bar,
1455
1458
  props.className
1456
1459
  ),
1457
1460
  style: props.style
@@ -1464,7 +1467,12 @@ var PageHeader = React5.forwardRef(function PageHeader2(props, ref) {
1464
1467
  h4("h" + level, { className: "aura-page-header__title", id: props.titleId }, props.title),
1465
1468
  props.meta != null && props.meta !== false ? h4("div", { className: "aura-page-header__meta" }, props.meta) : null
1466
1469
  ),
1467
- props.actions != null && props.actions !== false ? h4("div", { className: "aura-page-header__actions" }, props.actions) : null
1470
+ props.actions != null && props.actions !== false ? h4(
1471
+ "div",
1472
+ { className: "aura-page-header__actions" },
1473
+ bar && props.actionsStatus != null && props.actionsStatus !== false ? h4("div", { className: "aura-page-header__status", role: "status" }, props.actionsStatus) : null,
1474
+ props.actions
1475
+ ) : null
1468
1476
  );
1469
1477
  });
1470
1478
 
@@ -511,6 +511,19 @@ export interface PageHeaderProps extends Pick<React$1.HTMLAttributes<HTMLElement
511
511
  * readers — and the breadcrumb and eyebrow are hidden, for phone layouts that show the title in the top bar. The
512
512
  * meta line and actions stay; with no meta, the actions start the header. */
513
513
  titleHideBelow?: "sm" | "md" | "lg" | undefined;
514
+ /** 5.45 (Chamber-OS 150): below this breakpoint (`sm` 640px, `md` 768px) the same `actions` — rendered once, so a
515
+ * dialog trigger or test id is never doubled — become a bar fixed to the bottom of the screen with ActionBar's look:
516
+ * above a BottomNav, clear of the home indicator, `actionsStatus` as its status line. The page's end and a focused
517
+ * field scroll clear of it (AppShell's content, or the body, gains the bar's height). With an IconButton among them
518
+ * the actions share one row, labels wrapping inside the buttons (as `actionsFullWidthBelow`, Chamber-OS 149); with only icon
519
+ * buttons the status and the icons share one row. From the breakpoint up nothing changes. Use it for a detail page's
520
+ * own actions (Issue credit note…, ⋯) — one per page. The bar is `position: fixed`: no ancestor of the header may
521
+ * have a transform, filter, backdrop-filter, will-change, paint/layout containment or `content-visibility: auto`, or it is placed
522
+ * against that ancestor instead of the screen — the main entry warns in development. */
523
+ actionsBarBelow?: "sm" | "md" | undefined;
524
+ /** 5.45: the bar's status line ("Total 10,700.00 THB incl. VAT · due 22 Oct 2026"), shown only while the actions are
525
+ * a bar, in a polite live region. */
526
+ actionsStatus?: React$1.ReactNode | undefined;
514
527
  /** Default 1. Use 2 when the page already has an h1 (e.g. in the AppShell bar). */
515
528
  headingLevel?: 1 | 2 | 3 | undefined;
516
529
  /** The heading's id, for `aria-labelledby` on the page's region. */
@@ -511,6 +511,19 @@ export interface PageHeaderProps extends Pick<React$1.HTMLAttributes<HTMLElement
511
511
  * readers — and the breadcrumb and eyebrow are hidden, for phone layouts that show the title in the top bar. The
512
512
  * meta line and actions stay; with no meta, the actions start the header. */
513
513
  titleHideBelow?: "sm" | "md" | "lg" | undefined;
514
+ /** 5.45 (Chamber-OS 150): below this breakpoint (`sm` 640px, `md` 768px) the same `actions` — rendered once, so a
515
+ * dialog trigger or test id is never doubled — become a bar fixed to the bottom of the screen with ActionBar's look:
516
+ * above a BottomNav, clear of the home indicator, `actionsStatus` as its status line. The page's end and a focused
517
+ * field scroll clear of it (AppShell's content, or the body, gains the bar's height). With an IconButton among them
518
+ * the actions share one row, labels wrapping inside the buttons (as `actionsFullWidthBelow`, Chamber-OS 149); with only icon
519
+ * buttons the status and the icons share one row. From the breakpoint up nothing changes. Use it for a detail page's
520
+ * own actions (Issue credit note…, ⋯) — one per page. The bar is `position: fixed`: no ancestor of the header may
521
+ * have a transform, filter, backdrop-filter, will-change, paint/layout containment or `content-visibility: auto`, or it is placed
522
+ * against that ancestor instead of the screen — the main entry warns in development. */
523
+ actionsBarBelow?: "sm" | "md" | undefined;
524
+ /** 5.45: the bar's status line ("Total 10,700.00 THB incl. VAT · due 22 Oct 2026"), shown only while the actions are
525
+ * a bar, in a polite live region. */
526
+ actionsStatus?: React$1.ReactNode | undefined;
514
527
  /** Default 1. Use 2 when the page already has an h1 (e.g. in the AppShell bar). */
515
528
  headingLevel?: 1 | 2 | 3 | undefined;
516
529
  /** The heading's id, for `aria-labelledby` on the page's region. */
@@ -1379,6 +1379,8 @@ var PageHeader = React5.forwardRef(function PageHeader2(props, ref) {
1379
1379
  const below = props.actionsFullWidthBelow;
1380
1380
  const hide = props.titleHideBelow;
1381
1381
  const hasMeta = props.meta != null && props.meta !== false;
1382
+ const hasActions = props.actions != null && props.actions !== false;
1383
+ const bar = hasActions && (props.actionsBarBelow === "sm" || props.actionsBarBelow === "md") ? props.actionsBarBelow : null;
1382
1384
  return h4(
1383
1385
  "div",
1384
1386
  Object.assign(attrs2, {
@@ -1388,6 +1390,7 @@ var PageHeader = React5.forwardRef(function PageHeader2(props, ref) {
1388
1390
  (below === "sm" || below === "md" || below === "lg") && "aura-page-header--actions-full-below-" + below,
1389
1391
  (hide === "sm" || hide === "md" || hide === "lg") && "aura-page-header--title-hide-below-" + hide,
1390
1392
  (hide === "sm" || hide === "md" || hide === "lg") && !hasMeta && "has-no-meta",
1393
+ bar && "aura-page-header--actions-bar-below-" + bar,
1391
1394
  props.className
1392
1395
  ),
1393
1396
  style: props.style
@@ -1400,7 +1403,12 @@ var PageHeader = React5.forwardRef(function PageHeader2(props, ref) {
1400
1403
  h4("h" + level, { className: "aura-page-header__title", id: props.titleId }, props.title),
1401
1404
  props.meta != null && props.meta !== false ? h4("div", { className: "aura-page-header__meta" }, props.meta) : null
1402
1405
  ),
1403
- props.actions != null && props.actions !== false ? h4("div", { className: "aura-page-header__actions" }, props.actions) : null
1406
+ props.actions != null && props.actions !== false ? h4(
1407
+ "div",
1408
+ { className: "aura-page-header__actions" },
1409
+ bar && props.actionsStatus != null && props.actionsStatus !== false ? h4("div", { className: "aura-page-header__status", role: "status" }, props.actionsStatus) : null,
1410
+ props.actions
1411
+ ) : null
1404
1412
  );
1405
1413
  });
1406
1414
 
package/dist/styles.css CHANGED
@@ -346,6 +346,7 @@ a.aura-icon-btn { text-decoration: none; }
346
346
  }
347
347
  .aura-icon-btn:hover, .aura-icon-btn[aria-haspopup][aria-expanded="true"] { background: var(--aura-hover, var(--aura-bg-surface-hover)); } /* 5.41 (DxT #22): looks open while its menu shows */
348
348
  .aura-icon-btn--danger { color: var(--aura-fg-danger); }
349
+ .aura-icon-btn--outline { box-sizing: border-box; border: 1px solid var(--aura-button-secondary-border); } /* 5.44 (Chamber-OS 149): reads as a button beside outlined ones */
349
350
  .aura-icon-btn--danger:hover { background: var(--aura-alert-danger-bg); }
350
351
  .aura-icon-btn:disabled { opacity: var(--aura-disabled-opacity); pointer-events: none; }
351
352
  .aura-icon-btn:focus-visible { outline: var(--aura-focus-ring-width) solid var(--aura-focus-ring); outline-offset: var(--aura-focus-ring-offset); }
@@ -359,6 +360,9 @@ a.aura-icon-btn { text-decoration: none; }
359
360
  .aura-tag.aura-tag--touch { min-height: var(--aura-touch-target); }
360
361
  .aura-filterbar__clear { min-height: var(--aura-touch-target); } /* 5.28 (Chamber-OS 133) */
361
362
  }
363
+ @media (max-width: 639.98px), (pointer: coarse) {
364
+ .aura-page-header__actions:has(> .aura-icon-btn, > * > .aura-icon-btn) > :is(.aura-btn, * > .aura-btn).aura-btn--touch { min-height: var(--aura-touch-target); } /* 5.44: a wrapped label keeps 44px */
365
+ }
362
366
  /* Touch: same 32px look, a 44px hit area around it (WCAG 2.5.5). */
363
367
  @media (pointer: coarse) {
364
368
  .aura-icon-btn { position: relative; }
@@ -1168,13 +1172,19 @@ a.aura-tab { text-decoration: none; }
1168
1172
  }
1169
1173
  /* 5.37 (DxT Monitor #17): actionsFullWidthBelow — the actions take the row under the text; their children share
1170
1174
  * each line equally (wrapping when a label won't fit), a trigger inside a DropdownMenu, Tooltip or Popover wrapper
1171
- * fills it, and icon buttons keep their size. The :has rule is alone so older browsers drop only it. */
1175
+ * fills it, and icon buttons keep their size. The :has rule is alone so older browsers drop only it.
1176
+ * 5.44 (Chamber-OS 149): with an icon button among them (a ⋯ menu) the actions are one bar: the row never wraps,
1177
+ * the buttons share what the icon leaves and wrap their labels inside (never an ellipsis). */
1172
1178
  @media (max-width: 639.98px) {
1173
1179
  .aura-page-header--actions-full-below-sm > .aura-page-header__actions { flex: 1 1 100%; gap: var(--aura-space-3); }
1174
1180
  .aura-page-header--actions-full-below-sm > .aura-page-header__actions > * { flex: 1 1 0; min-width: max-content; }
1175
1181
  .aura-page-header--actions-full-below-sm > .aura-page-header__actions > :is(.aura-dropdown, .aura-tooltip-anchor, .aura-popover-anchor) > * { flex: 1 1 auto; }
1176
1182
  .aura-page-header--actions-full-below-sm > .aura-page-header__actions > .aura-icon-btn { flex: none; }
1177
1183
  .aura-page-header--actions-full-below-sm > .aura-page-header__actions > :has(> .aura-icon-btn) { flex: none; }
1184
+ .aura-page-header--actions-full-below-sm > .aura-page-header__actions:has(> .aura-icon-btn, > * > .aura-icon-btn) { flex-wrap: nowrap; align-items: stretch; }
1185
+ .aura-page-header--actions-full-below-sm > .aura-page-header__actions:has(> .aura-icon-btn, > * > .aura-icon-btn) > * { min-width: 0; }
1186
+ .aura-page-header--actions-full-below-sm > .aura-page-header__actions:has(> .aura-icon-btn, > * > .aura-icon-btn) > :is(.aura-btn, * > .aura-btn):not(.aura-icon-btn) { height: auto; min-height: var(--aura-button-height); white-space: normal; padding: var(--aura-space-2) var(--aura-space-3); line-height: 1.35; text-align: center; overflow-wrap: anywhere; hyphens: auto; border-radius: min(var(--aura-button-radius), 22px); }
1187
+ .aura-page-header--actions-full-below-sm > .aura-page-header__actions:has(> .aura-icon-btn, > * > .aura-icon-btn) > :is(.aura-icon-btn, :has(> .aura-icon-btn)) { align-self: center; } /* 5.45 (Chamber-OS addendum 52): centred on a taller button */
1178
1188
  }
1179
1189
  @media (max-width: 767.98px) {
1180
1190
  .aura-page-header--actions-full-below-md > .aura-page-header__actions { flex: 1 1 100%; gap: var(--aura-space-3); }
@@ -1182,6 +1192,10 @@ a.aura-tab { text-decoration: none; }
1182
1192
  .aura-page-header--actions-full-below-md > .aura-page-header__actions > :is(.aura-dropdown, .aura-tooltip-anchor, .aura-popover-anchor) > * { flex: 1 1 auto; }
1183
1193
  .aura-page-header--actions-full-below-md > .aura-page-header__actions > .aura-icon-btn { flex: none; }
1184
1194
  .aura-page-header--actions-full-below-md > .aura-page-header__actions > :has(> .aura-icon-btn) { flex: none; }
1195
+ .aura-page-header--actions-full-below-md > .aura-page-header__actions:has(> .aura-icon-btn, > * > .aura-icon-btn) { flex-wrap: nowrap; align-items: stretch; }
1196
+ .aura-page-header--actions-full-below-md > .aura-page-header__actions:has(> .aura-icon-btn, > * > .aura-icon-btn) > * { min-width: 0; }
1197
+ .aura-page-header--actions-full-below-md > .aura-page-header__actions:has(> .aura-icon-btn, > * > .aura-icon-btn) > :is(.aura-btn, * > .aura-btn):not(.aura-icon-btn) { height: auto; min-height: var(--aura-button-height); white-space: normal; padding: var(--aura-space-2) var(--aura-space-3); line-height: 1.35; text-align: center; overflow-wrap: anywhere; hyphens: auto; border-radius: min(var(--aura-button-radius), 22px); }
1198
+ .aura-page-header--actions-full-below-md > .aura-page-header__actions:has(> .aura-icon-btn, > * > .aura-icon-btn) > :is(.aura-icon-btn, :has(> .aura-icon-btn)) { align-self: center; } /* 5.45 (Chamber-OS addendum 52): centred on a taller button */
1185
1199
  }
1186
1200
  @media (max-width: 1023.98px) {
1187
1201
  .aura-page-header--actions-full-below-lg > .aura-page-header__actions { flex: 1 1 100%; gap: var(--aura-space-3); }
@@ -1189,7 +1203,47 @@ a.aura-tab { text-decoration: none; }
1189
1203
  .aura-page-header--actions-full-below-lg > .aura-page-header__actions > :is(.aura-dropdown, .aura-tooltip-anchor, .aura-popover-anchor) > * { flex: 1 1 auto; }
1190
1204
  .aura-page-header--actions-full-below-lg > .aura-page-header__actions > .aura-icon-btn { flex: none; }
1191
1205
  .aura-page-header--actions-full-below-lg > .aura-page-header__actions > :has(> .aura-icon-btn) { flex: none; }
1206
+ .aura-page-header--actions-full-below-lg > .aura-page-header__actions:has(> .aura-icon-btn, > * > .aura-icon-btn) { flex-wrap: nowrap; align-items: stretch; }
1207
+ .aura-page-header--actions-full-below-lg > .aura-page-header__actions:has(> .aura-icon-btn, > * > .aura-icon-btn) > * { min-width: 0; }
1208
+ .aura-page-header--actions-full-below-lg > .aura-page-header__actions:has(> .aura-icon-btn, > * > .aura-icon-btn) > :is(.aura-btn, * > .aura-btn):not(.aura-icon-btn) { height: auto; min-height: var(--aura-button-height); white-space: normal; padding: var(--aura-space-2) var(--aura-space-3); line-height: 1.35; text-align: center; overflow-wrap: anywhere; hyphens: auto; border-radius: min(var(--aura-button-radius), 22px); }
1209
+ .aura-page-header--actions-full-below-lg > .aura-page-header__actions:has(> .aura-icon-btn, > * > .aura-icon-btn) > :is(.aura-icon-btn, :has(> .aura-icon-btn)) { align-self: center; } /* 5.45 (Chamber-OS addendum 52): centred on a taller button */
1210
+ }
1211
+ /* 5.45 (Chamber-OS 150): actionsBarBelow — the same actions become a fixed bar with a status line; the page gains its
1212
+ * height (--aura-page-actions-height, measured on the client) so its end and a focused field scroll clear. */
1213
+ .aura-page-header__status { display: none; }
1214
+ @media (max-width: 639.98px) {
1215
+ .aura-page-header--actions-bar-below-sm > .aura-page-header__actions { position: fixed; z-index: var(--aura-z-bar); left: var(--aura-space-4); right: var(--aura-space-4); bottom: calc(var(--aura-bottomnav-offset, 0px) + max(var(--aura-space-3), env(safe-area-inset-bottom, 0px))); box-sizing: border-box; min-height: 60px; flex-wrap: wrap; align-items: center; justify-content: flex-end; gap: var(--aura-space-2); margin: 0; padding: var(--aura-space-2) var(--aura-space-3) var(--aura-space-2) var(--aura-space-4); background: var(--aura-bg-surface); color: var(--aura-fg-primary); border: 1px solid var(--aura-border-default); border-radius: var(--aura-radius-lg); box-shadow: var(--aura-shadow-overlay); transition: bottom var(--aura-duration-base) var(--aura-ease); }
1216
+ .aura-page-header--actions-bar-below-sm > .aura-page-header__actions > .aura-page-header__status { display: block; flex: 1 1 100%; min-width: 0; font-size: max(14px, .875rem); line-height: 1.5; color: var(--aura-fg-secondary); font-variant-numeric: tabular-nums; overflow-wrap: anywhere; }
1217
+ .aura-page-header--actions-bar-below-sm > .aura-page-header__actions > :not(.aura-page-header__status) { flex: 1 1 0; min-width: max-content; }
1218
+ .aura-page-header--actions-bar-below-sm > .aura-page-header__actions > :is(.aura-dropdown, .aura-tooltip-anchor, .aura-popover-anchor) > * { flex: 1 1 auto; }
1219
+ .aura-page-header--actions-bar-below-sm > .aura-page-header__actions > .aura-icon-btn { flex: none; }
1220
+ .aura-page-header--actions-bar-below-sm > .aura-page-header__actions > :has(> .aura-icon-btn) { flex: none; }
1221
+ .aura-page-header--actions-bar-below-sm > .aura-page-header__actions:has(> .aura-icon-btn, > * > .aura-icon-btn) { flex-wrap: wrap; align-items: stretch; }
1222
+ .aura-page-header--actions-bar-below-sm > .aura-page-header__actions:has(> .aura-icon-btn, > * > .aura-icon-btn) > :not(.aura-page-header__status) { min-width: 0; }
1223
+ .aura-page-header--actions-bar-below-sm > .aura-page-header__actions:has(> .aura-icon-btn, > * > .aura-icon-btn) > :is(.aura-icon-btn, :has(> .aura-icon-btn)) { align-self: center; }
1224
+ .aura-page-header--actions-bar-below-sm > .aura-page-header__actions:has(> .aura-icon-btn, > * > .aura-icon-btn) > :is(.aura-btn, * > .aura-btn):not(.aura-icon-btn) { height: auto; min-height: var(--aura-button-height); white-space: normal; padding: var(--aura-space-2) var(--aura-space-3); line-height: 1.35; text-align: center; overflow-wrap: anywhere; hyphens: auto; border-radius: min(var(--aura-button-radius), 22px); }
1225
+ .aura-page-header--actions-bar-below-sm > .aura-page-header__actions:not(:has(> .aura-btn, > * > .aura-btn)) > .aura-page-header__status { flex: 1 1 0; align-self: center; }
1226
+ :root:has(.aura-page-header--actions-bar-below-sm) { --aura-page-actions-space: calc(var(--aura-page-actions-height, 7rem) + var(--aura-bottomnav-offset, 0px) + max(var(--aura-space-3), env(safe-area-inset-bottom, 0px)) + var(--aura-space-3)); scroll-padding-bottom: var(--aura-page-actions-space); }
1227
+ :root:has(.aura-page-header--actions-bar-below-sm) .aura-shell__content { padding-bottom: calc(var(--aura-space-6) + var(--aura-page-actions-space)); }
1228
+ :root:has(.aura-page-header--actions-bar-below-sm):not(:has(.aura-shell__content)) body { padding-bottom: var(--aura-page-actions-space); }
1192
1229
  }
1230
+ @media (max-width: 767.98px) {
1231
+ .aura-page-header--actions-bar-below-md > .aura-page-header__actions { position: fixed; z-index: var(--aura-z-bar); left: var(--aura-space-4); right: var(--aura-space-4); bottom: calc(var(--aura-bottomnav-offset, 0px) + max(var(--aura-space-3), env(safe-area-inset-bottom, 0px))); box-sizing: border-box; min-height: 60px; flex-wrap: wrap; align-items: center; justify-content: flex-end; gap: var(--aura-space-2); margin: 0; padding: var(--aura-space-2) var(--aura-space-3) var(--aura-space-2) var(--aura-space-4); background: var(--aura-bg-surface); color: var(--aura-fg-primary); border: 1px solid var(--aura-border-default); border-radius: var(--aura-radius-lg); box-shadow: var(--aura-shadow-overlay); transition: bottom var(--aura-duration-base) var(--aura-ease); }
1232
+ .aura-page-header--actions-bar-below-md > .aura-page-header__actions > .aura-page-header__status { display: block; flex: 1 1 100%; min-width: 0; font-size: max(14px, .875rem); line-height: 1.5; color: var(--aura-fg-secondary); font-variant-numeric: tabular-nums; overflow-wrap: anywhere; }
1233
+ .aura-page-header--actions-bar-below-md > .aura-page-header__actions > :not(.aura-page-header__status) { flex: 1 1 0; min-width: max-content; }
1234
+ .aura-page-header--actions-bar-below-md > .aura-page-header__actions > :is(.aura-dropdown, .aura-tooltip-anchor, .aura-popover-anchor) > * { flex: 1 1 auto; }
1235
+ .aura-page-header--actions-bar-below-md > .aura-page-header__actions > .aura-icon-btn { flex: none; }
1236
+ .aura-page-header--actions-bar-below-md > .aura-page-header__actions > :has(> .aura-icon-btn) { flex: none; }
1237
+ .aura-page-header--actions-bar-below-md > .aura-page-header__actions:has(> .aura-icon-btn, > * > .aura-icon-btn) { flex-wrap: wrap; align-items: stretch; }
1238
+ .aura-page-header--actions-bar-below-md > .aura-page-header__actions:has(> .aura-icon-btn, > * > .aura-icon-btn) > :not(.aura-page-header__status) { min-width: 0; }
1239
+ .aura-page-header--actions-bar-below-md > .aura-page-header__actions:has(> .aura-icon-btn, > * > .aura-icon-btn) > :is(.aura-icon-btn, :has(> .aura-icon-btn)) { align-self: center; }
1240
+ .aura-page-header--actions-bar-below-md > .aura-page-header__actions:has(> .aura-icon-btn, > * > .aura-icon-btn) > :is(.aura-btn, * > .aura-btn):not(.aura-icon-btn) { height: auto; min-height: var(--aura-button-height); white-space: normal; padding: var(--aura-space-2) var(--aura-space-3); line-height: 1.35; text-align: center; overflow-wrap: anywhere; hyphens: auto; border-radius: min(var(--aura-button-radius), 22px); }
1241
+ .aura-page-header--actions-bar-below-md > .aura-page-header__actions:not(:has(> .aura-btn, > * > .aura-btn)) > .aura-page-header__status { flex: 1 1 0; align-self: center; }
1242
+ :root:has(.aura-page-header--actions-bar-below-md) { --aura-page-actions-space: calc(var(--aura-page-actions-height, 7rem) + var(--aura-bottomnav-offset, 0px) + max(var(--aura-space-3), env(safe-area-inset-bottom, 0px)) + var(--aura-space-3)); scroll-padding-bottom: var(--aura-page-actions-space); }
1243
+ :root:has(.aura-page-header--actions-bar-below-md) .aura-shell__content { padding-bottom: calc(var(--aura-space-6) + var(--aura-page-actions-space)); }
1244
+ :root:has(.aura-page-header--actions-bar-below-md):not(:has(.aura-shell__content)) body { padding-bottom: var(--aura-page-actions-space); }
1245
+ }
1246
+ @media (prefers-reduced-motion: reduce) { .aura-page-header__actions { transition: none; } }
1193
1247
  @media (min-width: 640px) { .aura-page-header__title { font-size: max(36px, 2.25rem); } }
1194
1248
  /* Thai marks need the room a 1.15 line takes away. */
1195
1249
  .aura-page-header__title:lang(th) { line-height: 1.4; letter-spacing: 0; }
@@ -348,6 +348,7 @@ a.aura-icon-btn { text-decoration: none; }
348
348
  }
349
349
  .aura-icon-btn:hover, .aura-icon-btn[aria-haspopup][aria-expanded="true"] { background: var(--aura-hover, var(--aura-bg-surface-hover)); } /* 5.41 (DxT #22): looks open while its menu shows */
350
350
  .aura-icon-btn--danger { color: var(--aura-fg-danger); }
351
+ .aura-icon-btn--outline { box-sizing: border-box; border: 1px solid var(--aura-button-secondary-border); } /* 5.44 (Chamber-OS 149): reads as a button beside outlined ones */
351
352
  .aura-icon-btn--danger:hover { background: var(--aura-alert-danger-bg); }
352
353
  .aura-icon-btn:disabled { opacity: var(--aura-disabled-opacity); pointer-events: none; }
353
354
  .aura-icon-btn:focus-visible { outline: var(--aura-focus-ring-width) solid var(--aura-focus-ring); outline-offset: var(--aura-focus-ring-offset); }
@@ -361,6 +362,9 @@ a.aura-icon-btn { text-decoration: none; }
361
362
  .aura-tag.aura-tag--touch { min-height: var(--aura-touch-target); }
362
363
  .aura-filterbar__clear { min-height: var(--aura-touch-target); } /* 5.28 (Chamber-OS 133) */
363
364
  }
365
+ @media (max-width: 639.98px), (pointer: coarse) {
366
+ .aura-page-header__actions:has(> .aura-icon-btn, > * > .aura-icon-btn) > :is(.aura-btn, * > .aura-btn).aura-btn--touch { min-height: var(--aura-touch-target); } /* 5.44: a wrapped label keeps 44px */
367
+ }
364
368
  /* Touch: same 32px look, a 44px hit area around it (WCAG 2.5.5). */
365
369
  @media (pointer: coarse) {
366
370
  .aura-icon-btn { position: relative; }
@@ -1170,13 +1174,19 @@ a.aura-tab { text-decoration: none; }
1170
1174
  }
1171
1175
  /* 5.37 (DxT Monitor #17): actionsFullWidthBelow — the actions take the row under the text; their children share
1172
1176
  * each line equally (wrapping when a label won't fit), a trigger inside a DropdownMenu, Tooltip or Popover wrapper
1173
- * fills it, and icon buttons keep their size. The :has rule is alone so older browsers drop only it. */
1177
+ * fills it, and icon buttons keep their size. The :has rule is alone so older browsers drop only it.
1178
+ * 5.44 (Chamber-OS 149): with an icon button among them (a ⋯ menu) the actions are one bar: the row never wraps,
1179
+ * the buttons share what the icon leaves and wrap their labels inside (never an ellipsis). */
1174
1180
  @media (max-width: 639.98px) {
1175
1181
  .aura-page-header--actions-full-below-sm > .aura-page-header__actions { flex: 1 1 100%; gap: var(--aura-space-3); }
1176
1182
  .aura-page-header--actions-full-below-sm > .aura-page-header__actions > * { flex: 1 1 0; min-width: max-content; }
1177
1183
  .aura-page-header--actions-full-below-sm > .aura-page-header__actions > :is(.aura-dropdown, .aura-tooltip-anchor, .aura-popover-anchor) > * { flex: 1 1 auto; }
1178
1184
  .aura-page-header--actions-full-below-sm > .aura-page-header__actions > .aura-icon-btn { flex: none; }
1179
1185
  .aura-page-header--actions-full-below-sm > .aura-page-header__actions > :has(> .aura-icon-btn) { flex: none; }
1186
+ .aura-page-header--actions-full-below-sm > .aura-page-header__actions:has(> .aura-icon-btn, > * > .aura-icon-btn) { flex-wrap: nowrap; align-items: stretch; }
1187
+ .aura-page-header--actions-full-below-sm > .aura-page-header__actions:has(> .aura-icon-btn, > * > .aura-icon-btn) > * { min-width: 0; }
1188
+ .aura-page-header--actions-full-below-sm > .aura-page-header__actions:has(> .aura-icon-btn, > * > .aura-icon-btn) > :is(.aura-btn, * > .aura-btn):not(.aura-icon-btn) { height: auto; min-height: var(--aura-button-height); white-space: normal; padding: var(--aura-space-2) var(--aura-space-3); line-height: 1.35; text-align: center; overflow-wrap: anywhere; hyphens: auto; border-radius: min(var(--aura-button-radius), 22px); }
1189
+ .aura-page-header--actions-full-below-sm > .aura-page-header__actions:has(> .aura-icon-btn, > * > .aura-icon-btn) > :is(.aura-icon-btn, :has(> .aura-icon-btn)) { align-self: center; } /* 5.45 (Chamber-OS addendum 52): centred on a taller button */
1180
1190
  }
1181
1191
  @media (max-width: 767.98px) {
1182
1192
  .aura-page-header--actions-full-below-md > .aura-page-header__actions { flex: 1 1 100%; gap: var(--aura-space-3); }
@@ -1184,6 +1194,10 @@ a.aura-tab { text-decoration: none; }
1184
1194
  .aura-page-header--actions-full-below-md > .aura-page-header__actions > :is(.aura-dropdown, .aura-tooltip-anchor, .aura-popover-anchor) > * { flex: 1 1 auto; }
1185
1195
  .aura-page-header--actions-full-below-md > .aura-page-header__actions > .aura-icon-btn { flex: none; }
1186
1196
  .aura-page-header--actions-full-below-md > .aura-page-header__actions > :has(> .aura-icon-btn) { flex: none; }
1197
+ .aura-page-header--actions-full-below-md > .aura-page-header__actions:has(> .aura-icon-btn, > * > .aura-icon-btn) { flex-wrap: nowrap; align-items: stretch; }
1198
+ .aura-page-header--actions-full-below-md > .aura-page-header__actions:has(> .aura-icon-btn, > * > .aura-icon-btn) > * { min-width: 0; }
1199
+ .aura-page-header--actions-full-below-md > .aura-page-header__actions:has(> .aura-icon-btn, > * > .aura-icon-btn) > :is(.aura-btn, * > .aura-btn):not(.aura-icon-btn) { height: auto; min-height: var(--aura-button-height); white-space: normal; padding: var(--aura-space-2) var(--aura-space-3); line-height: 1.35; text-align: center; overflow-wrap: anywhere; hyphens: auto; border-radius: min(var(--aura-button-radius), 22px); }
1200
+ .aura-page-header--actions-full-below-md > .aura-page-header__actions:has(> .aura-icon-btn, > * > .aura-icon-btn) > :is(.aura-icon-btn, :has(> .aura-icon-btn)) { align-self: center; } /* 5.45 (Chamber-OS addendum 52): centred on a taller button */
1187
1201
  }
1188
1202
  @media (max-width: 1023.98px) {
1189
1203
  .aura-page-header--actions-full-below-lg > .aura-page-header__actions { flex: 1 1 100%; gap: var(--aura-space-3); }
@@ -1191,7 +1205,47 @@ a.aura-tab { text-decoration: none; }
1191
1205
  .aura-page-header--actions-full-below-lg > .aura-page-header__actions > :is(.aura-dropdown, .aura-tooltip-anchor, .aura-popover-anchor) > * { flex: 1 1 auto; }
1192
1206
  .aura-page-header--actions-full-below-lg > .aura-page-header__actions > .aura-icon-btn { flex: none; }
1193
1207
  .aura-page-header--actions-full-below-lg > .aura-page-header__actions > :has(> .aura-icon-btn) { flex: none; }
1208
+ .aura-page-header--actions-full-below-lg > .aura-page-header__actions:has(> .aura-icon-btn, > * > .aura-icon-btn) { flex-wrap: nowrap; align-items: stretch; }
1209
+ .aura-page-header--actions-full-below-lg > .aura-page-header__actions:has(> .aura-icon-btn, > * > .aura-icon-btn) > * { min-width: 0; }
1210
+ .aura-page-header--actions-full-below-lg > .aura-page-header__actions:has(> .aura-icon-btn, > * > .aura-icon-btn) > :is(.aura-btn, * > .aura-btn):not(.aura-icon-btn) { height: auto; min-height: var(--aura-button-height); white-space: normal; padding: var(--aura-space-2) var(--aura-space-3); line-height: 1.35; text-align: center; overflow-wrap: anywhere; hyphens: auto; border-radius: min(var(--aura-button-radius), 22px); }
1211
+ .aura-page-header--actions-full-below-lg > .aura-page-header__actions:has(> .aura-icon-btn, > * > .aura-icon-btn) > :is(.aura-icon-btn, :has(> .aura-icon-btn)) { align-self: center; } /* 5.45 (Chamber-OS addendum 52): centred on a taller button */
1212
+ }
1213
+ /* 5.45 (Chamber-OS 150): actionsBarBelow — the same actions become a fixed bar with a status line; the page gains its
1214
+ * height (--aura-page-actions-height, measured on the client) so its end and a focused field scroll clear. */
1215
+ .aura-page-header__status { display: none; }
1216
+ @media (max-width: 639.98px) {
1217
+ .aura-page-header--actions-bar-below-sm > .aura-page-header__actions { position: fixed; z-index: var(--aura-z-bar); left: var(--aura-space-4); right: var(--aura-space-4); bottom: calc(var(--aura-bottomnav-offset, 0px) + max(var(--aura-space-3), env(safe-area-inset-bottom, 0px))); box-sizing: border-box; min-height: 60px; flex-wrap: wrap; align-items: center; justify-content: flex-end; gap: var(--aura-space-2); margin: 0; padding: var(--aura-space-2) var(--aura-space-3) var(--aura-space-2) var(--aura-space-4); background: var(--aura-bg-surface); color: var(--aura-fg-primary); border: 1px solid var(--aura-border-default); border-radius: var(--aura-radius-lg); box-shadow: var(--aura-shadow-overlay); transition: bottom var(--aura-duration-base) var(--aura-ease); }
1218
+ .aura-page-header--actions-bar-below-sm > .aura-page-header__actions > .aura-page-header__status { display: block; flex: 1 1 100%; min-width: 0; font-size: max(14px, .875rem); line-height: 1.5; color: var(--aura-fg-secondary); font-variant-numeric: tabular-nums; overflow-wrap: anywhere; }
1219
+ .aura-page-header--actions-bar-below-sm > .aura-page-header__actions > :not(.aura-page-header__status) { flex: 1 1 0; min-width: max-content; }
1220
+ .aura-page-header--actions-bar-below-sm > .aura-page-header__actions > :is(.aura-dropdown, .aura-tooltip-anchor, .aura-popover-anchor) > * { flex: 1 1 auto; }
1221
+ .aura-page-header--actions-bar-below-sm > .aura-page-header__actions > .aura-icon-btn { flex: none; }
1222
+ .aura-page-header--actions-bar-below-sm > .aura-page-header__actions > :has(> .aura-icon-btn) { flex: none; }
1223
+ .aura-page-header--actions-bar-below-sm > .aura-page-header__actions:has(> .aura-icon-btn, > * > .aura-icon-btn) { flex-wrap: wrap; align-items: stretch; }
1224
+ .aura-page-header--actions-bar-below-sm > .aura-page-header__actions:has(> .aura-icon-btn, > * > .aura-icon-btn) > :not(.aura-page-header__status) { min-width: 0; }
1225
+ .aura-page-header--actions-bar-below-sm > .aura-page-header__actions:has(> .aura-icon-btn, > * > .aura-icon-btn) > :is(.aura-icon-btn, :has(> .aura-icon-btn)) { align-self: center; }
1226
+ .aura-page-header--actions-bar-below-sm > .aura-page-header__actions:has(> .aura-icon-btn, > * > .aura-icon-btn) > :is(.aura-btn, * > .aura-btn):not(.aura-icon-btn) { height: auto; min-height: var(--aura-button-height); white-space: normal; padding: var(--aura-space-2) var(--aura-space-3); line-height: 1.35; text-align: center; overflow-wrap: anywhere; hyphens: auto; border-radius: min(var(--aura-button-radius), 22px); }
1227
+ .aura-page-header--actions-bar-below-sm > .aura-page-header__actions:not(:has(> .aura-btn, > * > .aura-btn)) > .aura-page-header__status { flex: 1 1 0; align-self: center; }
1228
+ :root:has(.aura-page-header--actions-bar-below-sm) { --aura-page-actions-space: calc(var(--aura-page-actions-height, 7rem) + var(--aura-bottomnav-offset, 0px) + max(var(--aura-space-3), env(safe-area-inset-bottom, 0px)) + var(--aura-space-3)); scroll-padding-bottom: var(--aura-page-actions-space); }
1229
+ :root:has(.aura-page-header--actions-bar-below-sm) .aura-shell__content { padding-bottom: calc(var(--aura-space-6) + var(--aura-page-actions-space)); }
1230
+ :root:has(.aura-page-header--actions-bar-below-sm):not(:has(.aura-shell__content)) body { padding-bottom: var(--aura-page-actions-space); }
1194
1231
  }
1232
+ @media (max-width: 767.98px) {
1233
+ .aura-page-header--actions-bar-below-md > .aura-page-header__actions { position: fixed; z-index: var(--aura-z-bar); left: var(--aura-space-4); right: var(--aura-space-4); bottom: calc(var(--aura-bottomnav-offset, 0px) + max(var(--aura-space-3), env(safe-area-inset-bottom, 0px))); box-sizing: border-box; min-height: 60px; flex-wrap: wrap; align-items: center; justify-content: flex-end; gap: var(--aura-space-2); margin: 0; padding: var(--aura-space-2) var(--aura-space-3) var(--aura-space-2) var(--aura-space-4); background: var(--aura-bg-surface); color: var(--aura-fg-primary); border: 1px solid var(--aura-border-default); border-radius: var(--aura-radius-lg); box-shadow: var(--aura-shadow-overlay); transition: bottom var(--aura-duration-base) var(--aura-ease); }
1234
+ .aura-page-header--actions-bar-below-md > .aura-page-header__actions > .aura-page-header__status { display: block; flex: 1 1 100%; min-width: 0; font-size: max(14px, .875rem); line-height: 1.5; color: var(--aura-fg-secondary); font-variant-numeric: tabular-nums; overflow-wrap: anywhere; }
1235
+ .aura-page-header--actions-bar-below-md > .aura-page-header__actions > :not(.aura-page-header__status) { flex: 1 1 0; min-width: max-content; }
1236
+ .aura-page-header--actions-bar-below-md > .aura-page-header__actions > :is(.aura-dropdown, .aura-tooltip-anchor, .aura-popover-anchor) > * { flex: 1 1 auto; }
1237
+ .aura-page-header--actions-bar-below-md > .aura-page-header__actions > .aura-icon-btn { flex: none; }
1238
+ .aura-page-header--actions-bar-below-md > .aura-page-header__actions > :has(> .aura-icon-btn) { flex: none; }
1239
+ .aura-page-header--actions-bar-below-md > .aura-page-header__actions:has(> .aura-icon-btn, > * > .aura-icon-btn) { flex-wrap: wrap; align-items: stretch; }
1240
+ .aura-page-header--actions-bar-below-md > .aura-page-header__actions:has(> .aura-icon-btn, > * > .aura-icon-btn) > :not(.aura-page-header__status) { min-width: 0; }
1241
+ .aura-page-header--actions-bar-below-md > .aura-page-header__actions:has(> .aura-icon-btn, > * > .aura-icon-btn) > :is(.aura-icon-btn, :has(> .aura-icon-btn)) { align-self: center; }
1242
+ .aura-page-header--actions-bar-below-md > .aura-page-header__actions:has(> .aura-icon-btn, > * > .aura-icon-btn) > :is(.aura-btn, * > .aura-btn):not(.aura-icon-btn) { height: auto; min-height: var(--aura-button-height); white-space: normal; padding: var(--aura-space-2) var(--aura-space-3); line-height: 1.35; text-align: center; overflow-wrap: anywhere; hyphens: auto; border-radius: min(var(--aura-button-radius), 22px); }
1243
+ .aura-page-header--actions-bar-below-md > .aura-page-header__actions:not(:has(> .aura-btn, > * > .aura-btn)) > .aura-page-header__status { flex: 1 1 0; align-self: center; }
1244
+ :root:has(.aura-page-header--actions-bar-below-md) { --aura-page-actions-space: calc(var(--aura-page-actions-height, 7rem) + var(--aura-bottomnav-offset, 0px) + max(var(--aura-space-3), env(safe-area-inset-bottom, 0px)) + var(--aura-space-3)); scroll-padding-bottom: var(--aura-page-actions-space); }
1245
+ :root:has(.aura-page-header--actions-bar-below-md) .aura-shell__content { padding-bottom: calc(var(--aura-space-6) + var(--aura-page-actions-space)); }
1246
+ :root:has(.aura-page-header--actions-bar-below-md):not(:has(.aura-shell__content)) body { padding-bottom: var(--aura-page-actions-space); }
1247
+ }
1248
+ @media (prefers-reduced-motion: reduce) { .aura-page-header__actions { transition: none; } }
1195
1249
  @media (min-width: 640px) { .aura-page-header__title { font-size: max(36px, 2.25rem); } }
1196
1250
  /* Thai marks need the room a 1.15 line takes away. */
1197
1251
  .aura-page-header__title:lang(th) { line-height: 1.4; letter-spacing: 0; }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@jirawatpyk/aura-react",
3
- "version": "5.43.0",
3
+ "version": "5.45.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",