@jirawatpyk/aura-react 5.76.0 → 5.78.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.
@@ -1,6 +1,6 @@
1
1
  'use client';
2
2
  import * as React from "react";
3
- import { cx, omit, tone, devWarnOnce, touchClass } from "./classes.js";
3
+ import { cx, omit, tone, devWarnOnce, isDev, touchClass } from "./classes.js";
4
4
  function useMaybeControlled(value, initial, onChange) {
5
5
  const s = React.useState(initial);
6
6
  const wasSet = React.useState(value !== void 0);
@@ -217,6 +217,48 @@ function useInputModality() {
217
217
  function pointerModality() {
218
218
  setModality("pointer");
219
219
  }
220
+ function useScrollEdges(r, key) {
221
+ React.useEffect(
222
+ function() {
223
+ const el = r.current;
224
+ if (!el || typeof ResizeObserver === "undefined") return;
225
+ let raf = 0;
226
+ const mark = function() {
227
+ raf = 0;
228
+ const max = el.scrollWidth - el.clientWidth;
229
+ const x = Math.abs(el.scrollLeft);
230
+ const v = ((x > 1 ? "start " : "") + (x < max - 1 ? "end" : "")).trim();
231
+ if ((el.getAttribute("data-aura-more") || "") === v) return;
232
+ if (v) el.setAttribute("data-aura-more", v);
233
+ else el.removeAttribute("data-aura-more");
234
+ };
235
+ const on = function() {
236
+ if (!raf) raf = requestAnimationFrame(mark);
237
+ };
238
+ mark();
239
+ el.addEventListener("scroll", on, { passive: true });
240
+ const ro = new ResizeObserver(on);
241
+ ro.observe(el);
242
+ Array.prototype.forEach.call(el.children, function(c) {
243
+ ro.observe(c);
244
+ });
245
+ const mo = new MutationObserver(function() {
246
+ Array.prototype.forEach.call(el.children, function(c) {
247
+ ro.observe(c);
248
+ });
249
+ on();
250
+ });
251
+ mo.observe(el, { childList: true });
252
+ return function() {
253
+ cancelAnimationFrame(raf);
254
+ el.removeEventListener("scroll", on);
255
+ ro.disconnect();
256
+ mo.disconnect();
257
+ };
258
+ },
259
+ [key]
260
+ );
261
+ }
220
262
  export {
221
263
  FOCUSABLE,
222
264
  FilterSheet,
@@ -229,6 +271,7 @@ export {
229
271
  fixedTrapped,
230
272
  focusFirst,
231
273
  inClosedDetails,
274
+ isDev,
232
275
  isTabStop,
233
276
  omit,
234
277
  plainClick,
@@ -241,5 +284,6 @@ export {
241
284
  useIsoLayoutEffect,
242
285
  useMaybeControlled,
243
286
  useMergedRef,
244
- useMounted
287
+ useMounted,
288
+ useScrollEdges
245
289
  };
package/dist/esm/tiles.js CHANGED
@@ -27,6 +27,21 @@ const STATUS_WORD = {
27
27
  ok: "statusOk",
28
28
  unknown: "statusUnknown"
29
29
  };
30
+ function breakAtDots(title) {
31
+ if (typeof title !== "string" || !/[./][A-Za-z]/.test(title)) return title;
32
+ const out = [];
33
+ let run = "";
34
+ for (let i = 0; i < title.length; i++) {
35
+ const c = title.charAt(i);
36
+ run += c;
37
+ if ((c === "." || c === "/") && i + 1 < title.length && /[A-Za-z]/.test(title.charAt(i + 1))) {
38
+ out.push(run, h("wbr", { key: i }));
39
+ run = "";
40
+ }
41
+ }
42
+ if (run) out.push(run);
43
+ return out;
44
+ }
30
45
  function statusWord(status, t) {
31
46
  return String(t[STATUS_WORD[status]] || STATUS_WORD[status]);
32
47
  }
@@ -65,7 +80,7 @@ function statusTileElement(props, ref, Link, t, titleRef) {
65
80
  "span",
66
81
  { className: "aura-status-tile__head" },
67
82
  h(Icon, { name: h(STATUS_ICON[status]), size: 16, className: "aura-status-tile__icon" }),
68
- h("span", { className: "aura-status-tile__title", ref: titleRef }, props.title, comma),
83
+ h("span", { className: "aura-status-tile__title", ref: titleRef }, breakAtDots(props.title), comma),
69
84
  h("span", { className: "aura-sr-only" }, word + (hasValue || hasMeta || markers.length ? "," : "")),
70
85
  hasValue ? h(
71
86
  "span",
@@ -36,6 +36,7 @@ function useModal(open, ref, opts) {
36
36
  prev.current = document.activeElement;
37
37
  const unlock = lockScroll();
38
38
  const el = ref.current;
39
+ let raf = 0;
39
40
  const inPart = function(scope) {
40
41
  if (!scope || !el) return [];
41
42
  const sel = TAB_STOPS.split(",").map(function(s) {
@@ -46,8 +47,20 @@ function useModal(open, ref, opts) {
46
47
  if (el && o.autoFocus !== false) {
47
48
  const auto = el.querySelector("[data-autofocus]");
48
49
  if (!focusFirst(el, auto, [inPart(o.bodySelector), inPart(o.footSelector)])) el.focus();
50
+ const foot = o.footSelector ? el.querySelector(o.footSelector) : null, head = el.firstElementChild, first = document.activeElement, panel = el;
51
+ const toTop = function() {
52
+ if (foot && foot.contains(first) && document.activeElement === first && panel.scrollTop > 0 && /auto|scroll/.test(getComputedStyle(panel).overflowY) && head && head.getBoundingClientRect().top < panel.getBoundingClientRect().top)
53
+ panel.scrollTop = 0;
54
+ };
55
+ toTop();
56
+ if (foot && foot.contains(first))
57
+ raf = requestAnimationFrame(function() {
58
+ toTop();
59
+ raf = requestAnimationFrame(toTop);
60
+ });
49
61
  }
50
62
  return function() {
63
+ cancelAnimationFrame(raf);
51
64
  unlock();
52
65
  const l = latest.current;
53
66
  const ff = l.finalFocus;
@@ -997,15 +997,16 @@ function tone(t) {
997
997
  return TONES.indexOf(t) >= 0 ? t : "neutral";
998
998
  }
999
999
  var warned = {};
1000
- function devWarnOnce(key, message) {
1001
- if (warned[key]) return;
1002
- let dev = false;
1000
+ function isDev() {
1003
1001
  try {
1004
- dev = process.env.NODE_ENV !== "production";
1002
+ return process.env.NODE_ENV !== "production";
1005
1003
  } catch (e) {
1006
- dev = false;
1004
+ return false;
1007
1005
  }
1008
- if (!dev) return;
1006
+ }
1007
+ function devWarnOnce(key, message) {
1008
+ if (warned[key]) return;
1009
+ if (!isDev()) return;
1009
1010
  warned[key] = true;
1010
1011
  console.warn("[AURA] " + message);
1011
1012
  }
@@ -1669,6 +1670,15 @@ function TableSkeleton(props) {
1669
1670
  var React6 = __toESM(require("react"), 1);
1670
1671
  var h5 = React6.createElement;
1671
1672
  var LAZY = Symbol.for("react.lazy");
1673
+ var ID = /([A-Za-z0-9]+(?:-[A-Za-z0-9]+)+)/;
1674
+ function keepIds(title) {
1675
+ if (typeof title !== "string" || title.indexOf("-") < 0) return title;
1676
+ const parts = title.split(ID);
1677
+ if (parts.length < 2) return title;
1678
+ return parts.map(function(p, i) {
1679
+ return i % 2 && /\d/.test(p) && p.length <= 24 ? h5("span", { key: i, className: "aura-nowrap" }, p) : p;
1680
+ });
1681
+ }
1672
1682
  function chipsOnly(node) {
1673
1683
  let el = 0;
1674
1684
  const walk = function(n3) {
@@ -1720,7 +1730,7 @@ var PageHeader = React6.forwardRef(function PageHeader2(props, ref) {
1720
1730
  tabIndex: props.focusTitleOnMount ? -1 : void 0,
1721
1731
  "data-aura-focus-on-mount": props.focusTitleOnMount ? "" : void 0
1722
1732
  },
1723
- props.title
1733
+ keepIds(props.title)
1724
1734
  );
1725
1735
  const hasActions = props.actions != null && props.actions !== false;
1726
1736
  const hasBarActions = props.actionsBar != null && props.actionsBar !== false;
@@ -1791,6 +1801,21 @@ var STATUS_WORD = {
1791
1801
  ok: "statusOk",
1792
1802
  unknown: "statusUnknown"
1793
1803
  };
1804
+ function breakAtDots(title) {
1805
+ if (typeof title !== "string" || !/[./][A-Za-z]/.test(title)) return title;
1806
+ const out = [];
1807
+ let run = "";
1808
+ for (let i = 0; i < title.length; i++) {
1809
+ const c = title.charAt(i);
1810
+ run += c;
1811
+ if ((c === "." || c === "/") && i + 1 < title.length && /[A-Za-z]/.test(title.charAt(i + 1))) {
1812
+ out.push(run, h6("wbr", { key: i }));
1813
+ run = "";
1814
+ }
1815
+ }
1816
+ if (run) out.push(run);
1817
+ return out;
1818
+ }
1794
1819
  function statusWord(status, t) {
1795
1820
  return String(t[STATUS_WORD[status]] || STATUS_WORD[status]);
1796
1821
  }
@@ -1829,7 +1854,7 @@ function statusTileElement(props, ref, Link, t, titleRef) {
1829
1854
  "span",
1830
1855
  { className: "aura-status-tile__head" },
1831
1856
  h6(Icon, { name: h6(STATUS_ICON[status]), size: 16, className: "aura-status-tile__icon" }),
1832
- h6("span", { className: "aura-status-tile__title", ref: titleRef }, props.title, comma),
1857
+ h6("span", { className: "aura-status-tile__title", ref: titleRef }, breakAtDots(props.title), comma),
1833
1858
  h6("span", { className: "aura-sr-only" }, word + (hasValue || hasMeta || markers.length ? "," : "")),
1834
1859
  hasValue ? h6(
1835
1860
  "span",
@@ -930,15 +930,16 @@ function tone(t) {
930
930
  return TONES.indexOf(t) >= 0 ? t : "neutral";
931
931
  }
932
932
  var warned = {};
933
- function devWarnOnce(key, message) {
934
- if (warned[key]) return;
935
- let dev = false;
933
+ function isDev() {
936
934
  try {
937
- dev = process.env.NODE_ENV !== "production";
935
+ return process.env.NODE_ENV !== "production";
938
936
  } catch (e) {
939
- dev = false;
937
+ return false;
940
938
  }
941
- if (!dev) return;
939
+ }
940
+ function devWarnOnce(key, message) {
941
+ if (warned[key]) return;
942
+ if (!isDev()) return;
942
943
  warned[key] = true;
943
944
  console.warn("[AURA] " + message);
944
945
  }
@@ -1602,6 +1603,15 @@ function TableSkeleton(props) {
1602
1603
  import * as React6 from "react";
1603
1604
  var h5 = React6.createElement;
1604
1605
  var LAZY = Symbol.for("react.lazy");
1606
+ var ID = /([A-Za-z0-9]+(?:-[A-Za-z0-9]+)+)/;
1607
+ function keepIds(title) {
1608
+ if (typeof title !== "string" || title.indexOf("-") < 0) return title;
1609
+ const parts = title.split(ID);
1610
+ if (parts.length < 2) return title;
1611
+ return parts.map(function(p, i) {
1612
+ return i % 2 && /\d/.test(p) && p.length <= 24 ? h5("span", { key: i, className: "aura-nowrap" }, p) : p;
1613
+ });
1614
+ }
1605
1615
  function chipsOnly(node) {
1606
1616
  let el = 0;
1607
1617
  const walk = function(n3) {
@@ -1653,7 +1663,7 @@ var PageHeader = React6.forwardRef(function PageHeader2(props, ref) {
1653
1663
  tabIndex: props.focusTitleOnMount ? -1 : void 0,
1654
1664
  "data-aura-focus-on-mount": props.focusTitleOnMount ? "" : void 0
1655
1665
  },
1656
- props.title
1666
+ keepIds(props.title)
1657
1667
  );
1658
1668
  const hasActions = props.actions != null && props.actions !== false;
1659
1669
  const hasBarActions = props.actionsBar != null && props.actionsBar !== false;
@@ -1724,6 +1734,21 @@ var STATUS_WORD = {
1724
1734
  ok: "statusOk",
1725
1735
  unknown: "statusUnknown"
1726
1736
  };
1737
+ function breakAtDots(title) {
1738
+ if (typeof title !== "string" || !/[./][A-Za-z]/.test(title)) return title;
1739
+ const out = [];
1740
+ let run = "";
1741
+ for (let i = 0; i < title.length; i++) {
1742
+ const c = title.charAt(i);
1743
+ run += c;
1744
+ if ((c === "." || c === "/") && i + 1 < title.length && /[A-Za-z]/.test(title.charAt(i + 1))) {
1745
+ out.push(run, h6("wbr", { key: i }));
1746
+ run = "";
1747
+ }
1748
+ }
1749
+ if (run) out.push(run);
1750
+ return out;
1751
+ }
1727
1752
  function statusWord(status, t) {
1728
1753
  return String(t[STATUS_WORD[status]] || STATUS_WORD[status]);
1729
1754
  }
@@ -1762,7 +1787,7 @@ function statusTileElement(props, ref, Link, t, titleRef) {
1762
1787
  "span",
1763
1788
  { className: "aura-status-tile__head" },
1764
1789
  h6(Icon, { name: h6(STATUS_ICON[status]), size: 16, className: "aura-status-tile__icon" }),
1765
- h6("span", { className: "aura-status-tile__title", ref: titleRef }, props.title, comma),
1790
+ h6("span", { className: "aura-status-tile__title", ref: titleRef }, breakAtDots(props.title), comma),
1766
1791
  h6("span", { className: "aura-sr-only" }, word + (hasValue || hasMeta || markers.length ? "," : "")),
1767
1792
  hasValue ? h6(
1768
1793
  "span",
package/dist/styles.css CHANGED
@@ -820,6 +820,20 @@ a.aura-icon-btn { text-decoration: none; }
820
820
  * indicator paints over its bottom row. The list scrolls sideways (overflow-x), and a scroll container clips at its
821
821
  * padding box: an indicator pulled 1px over a border (as up to 5.22) showed only half its height. Same box height. */
822
822
  .aura-tabs__list { display: flex; gap: var(--aura-space-6); box-shadow: inset 0 -1px 0 var(--aura-border-default); overflow-x: auto; scrollbar-width: none; }
823
+ /* 5.78 (visual audit 24): a list wider than its box fades the end (or ends) with more tabs, so a cut tab reads as
824
+ * "scroll for more", not as a broken label. Logical: in RTL the fades swap sides. */
825
+ .aura-tabs__list[data-aura-more] {
826
+ --aura-fade-s: 0px; --aura-fade-e: 0px;
827
+ -webkit-mask-image: linear-gradient(to right, transparent, black var(--aura-fade-s), black calc(100% - var(--aura-fade-e)), transparent);
828
+ mask-image: linear-gradient(to right, transparent, black var(--aura-fade-s), black calc(100% - var(--aura-fade-e)), transparent);
829
+ }
830
+ .aura-tabs__list[data-aura-more] { scroll-padding-inline: var(--aura-space-8); } /* a focused tab scrolls clear of the fade */
831
+ .aura-tabs__list[data-aura-more~='start'] { --aura-fade-s: var(--aura-space-8); }
832
+ .aura-tabs__list[data-aura-more~='end'] { --aura-fade-e: var(--aura-space-8); }
833
+ [dir='rtl'] .aura-tabs__list[data-aura-more], .aura-tabs__list[data-aura-more][dir='rtl'] {
834
+ -webkit-mask-image: linear-gradient(to left, transparent, black var(--aura-fade-s), black calc(100% - var(--aura-fade-e)), transparent);
835
+ mask-image: linear-gradient(to left, transparent, black var(--aura-fade-s), black calc(100% - var(--aura-fade-e)), transparent);
836
+ }
823
837
  .aura-tab {
824
838
  position: relative; display: inline-flex; align-items: center; gap: var(--aura-space-2); flex: none;
825
839
  box-sizing: border-box; /* 5.39: a link tab (<a>) was 2px taller than a button tab — its underline sat outside the height */
@@ -999,6 +1013,9 @@ a.aura-tab { text-decoration: none; }
999
1013
  /* ---------- Combobox ---------- */
1000
1014
  .aura-combo { cursor: text; }
1001
1015
  .aura-combo .aura-input__control { padding-right: calc(var(--aura-space-2) + 2 * var(--aura-control-sm)); }
1016
+ /* 5.78 (visual audit 25): room for the clear button only while there is one — an empty TimePicker in a narrow column
1017
+ * showed "hh:m". (Also on a coarse pointer and with touchHeight, below.) */
1018
+ .aura-combo:not(.is-multi):not(:has(.aura-combo__clear)) .aura-input__control { padding-right: calc(var(--aura-space-2) + var(--aura-control-sm)); }
1002
1019
  .aura-combo__clear, .aura-combo__toggle, .aura-date__toggle {
1003
1020
  position: absolute; display: inline-flex; align-items: center; justify-content: center;
1004
1021
  width: var(--aura-control-sm); height: var(--aura-control-sm); padding: 0; border: 0; border-radius: var(--aura-radius-full);
@@ -1294,6 +1311,9 @@ summary.aura-link::-webkit-details-marker { display: none; }
1294
1311
  .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); }
1295
1312
  .aura-page-header__text { display: flex; flex-direction: column; gap: var(--aura-space-1); flex: 1 1 320px; min-width: 0; }
1296
1313
  .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; }
1314
+ .aura-nowrap { white-space: nowrap; } /* 5.78: a code or document number kept on one line */
1315
+ /* …in a PageHeader title the number moves to the next line whole, and still breaks if it is longer than a line. */
1316
+ .aura-page-header__title .aura-nowrap { display: inline-block; max-width: 100%; white-space: normal; }
1297
1317
  .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; }
1298
1318
  .aura-page-header__breadcrumb { min-width: 0; } /* 5.33 (DxT Monitor #7): Breadcrumb keeps its own type */
1299
1319
  .aura-page-header__meta { min-width: 0; font-size: max(13px, .8125rem); line-height: 1.5; color: var(--aura-fg-secondary); overflow-wrap: anywhere; }
@@ -1323,6 +1343,8 @@ summary.aura-link::-webkit-details-marker { display: none; }
1323
1343
  * span as wide as its text and the page scrolled sideways. :where keeps the selector's weight as before. */
1324
1344
  @media (max-width: 639.98px) {
1325
1345
  .aura-page-header--actions-full-below-sm > .aura-page-header__actions { flex: 1 1 100%; gap: var(--aura-space-3); }
1346
+ .aura-page-header--actions-full-below-sm:not(.aura-page-header--actions-bar-below-sm, .aura-page-header--actions-bar-below-md) > .aura-page-header__actions > :is(.aura-btn, :not(.aura-page-header__bar) > .aura-btn):not(.aura-icon-btn) { border-radius: var(--aura-radius-md); } /* 5.78 (visual audit 11): a label that wraps to two lines is a rounded box, not a lozenge */
1347
+ .aura-page-header--actions-full-below-sm:is(.aura-page-header--actions-bar-below-sm, .aura-page-header--actions-bar-below-md) > .aura-page-header__actions.is-split > :is(.aura-btn, :not(.aura-page-header__bar) > .aura-btn):not(.aura-icon-btn) { border-radius: var(--aura-radius-md); } /* 5.78: actionsBar's split — the header's own actions, not the strip */
1326
1348
  .aura-page-header--actions-full-below-sm > .aura-page-header__actions > :where(:not(.sr-only, .aura-sr-only, .visually-hidden, .screen-reader-text, [hidden], [style*="position: absolute"], [style*="position:absolute"])) { flex: 1 1 0; min-width: max-content; }
1327
1349
  .aura-page-header--actions-full-below-sm > .aura-page-header__actions > :is(.aura-dropdown, .aura-tooltip-anchor, .aura-popover-anchor) > * { flex: 1 1 auto; }
1328
1350
  .aura-page-header--actions-full-below-sm > .aura-page-header__actions > .aura-page-header__bar > :where(:not(.aura-page-header__status, .sr-only, .aura-sr-only, .visually-hidden, .screen-reader-text, [hidden], [style*="position: absolute"], [style*="position:absolute"])) { flex: 1 1 0; min-width: max-content; } /* 5.71: actionsBar in the row, as the actions (5.61) */
@@ -1333,10 +1355,14 @@ summary.aura-link::-webkit-details-marker { display: none; }
1333
1355
  .aura-page-header--actions-full-below-sm > .aura-page-header__actions:has(> .aura-icon-btn, > :not(.aura-page-header__bar) > .aura-icon-btn) { flex-wrap: nowrap; align-items: stretch; }
1334
1356
  .aura-page-header--actions-full-below-sm > .aura-page-header__actions:has(> .aura-icon-btn, > :not(.aura-page-header__bar) > .aura-icon-btn) > * { min-width: 0; }
1335
1357
  .aura-page-header--actions-full-below-sm > .aura-page-header__actions:has(> .aura-icon-btn, > :not(.aura-page-header__bar) > .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); }
1358
+ .aura-page-header--actions-full-below-sm:not(.aura-page-header--actions-bar-below-sm, .aura-page-header--actions-bar-below-md) > .aura-page-header__actions:has(> .aura-icon-btn, > :not(.aura-page-header__bar) > .aura-icon-btn) > :is(.aura-btn, * > .aura-btn):not(.aura-icon-btn) { border-radius: var(--aura-radius-md); } /* 5.78 (visual audit 11) */
1359
+ .aura-page-header--actions-full-below-sm:is(.aura-page-header--actions-bar-below-sm, .aura-page-header--actions-bar-below-md) > .aura-page-header__actions.is-split:has(> .aura-icon-btn, > :not(.aura-page-header__bar) > .aura-icon-btn) > :is(.aura-btn, :not(.aura-page-header__bar) > .aura-btn):not(.aura-icon-btn) { border-radius: var(--aura-radius-md); }
1336
1360
  .aura-page-header--actions-full-below-sm > .aura-page-header__actions:has(> .aura-icon-btn, > :not(.aura-page-header__bar) > .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 */
1337
1361
  }
1338
1362
  @media (max-width: 767.98px) {
1339
1363
  .aura-page-header--actions-full-below-md > .aura-page-header__actions { flex: 1 1 100%; gap: var(--aura-space-3); }
1364
+ .aura-page-header--actions-full-below-md:not(.aura-page-header--actions-bar-below-sm, .aura-page-header--actions-bar-below-md) > .aura-page-header__actions > :is(.aura-btn, :not(.aura-page-header__bar) > .aura-btn):not(.aura-icon-btn) { border-radius: var(--aura-radius-md); } /* 5.78 (visual audit 11): a label that wraps to two lines is a rounded box, not a lozenge */
1365
+ .aura-page-header--actions-full-below-md:is(.aura-page-header--actions-bar-below-sm, .aura-page-header--actions-bar-below-md) > .aura-page-header__actions.is-split > :is(.aura-btn, :not(.aura-page-header__bar) > .aura-btn):not(.aura-icon-btn) { border-radius: var(--aura-radius-md); } /* 5.78: actionsBar's split — the header's own actions, not the strip */
1340
1366
  .aura-page-header--actions-full-below-md > .aura-page-header__actions > :where(:not(.sr-only, .aura-sr-only, .visually-hidden, .screen-reader-text, [hidden], [style*="position: absolute"], [style*="position:absolute"])) { flex: 1 1 0; min-width: max-content; }
1341
1367
  .aura-page-header--actions-full-below-md > .aura-page-header__actions > :is(.aura-dropdown, .aura-tooltip-anchor, .aura-popover-anchor) > * { flex: 1 1 auto; }
1342
1368
  .aura-page-header--actions-full-below-md > .aura-page-header__actions > .aura-page-header__bar > :where(:not(.aura-page-header__status, .sr-only, .aura-sr-only, .visually-hidden, .screen-reader-text, [hidden], [style*="position: absolute"], [style*="position:absolute"])) { flex: 1 1 0; min-width: max-content; } /* 5.71: actionsBar in the row, as the actions (5.61) */
@@ -1346,10 +1372,14 @@ summary.aura-link::-webkit-details-marker { display: none; }
1346
1372
  .aura-page-header--actions-full-below-md > .aura-page-header__actions:has(> .aura-icon-btn, > :not(.aura-page-header__bar) > .aura-icon-btn) { flex-wrap: nowrap; align-items: stretch; }
1347
1373
  .aura-page-header--actions-full-below-md > .aura-page-header__actions:has(> .aura-icon-btn, > :not(.aura-page-header__bar) > .aura-icon-btn) > * { min-width: 0; }
1348
1374
  .aura-page-header--actions-full-below-md > .aura-page-header__actions:has(> .aura-icon-btn, > :not(.aura-page-header__bar) > .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); }
1375
+ .aura-page-header--actions-full-below-md:not(.aura-page-header--actions-bar-below-sm, .aura-page-header--actions-bar-below-md) > .aura-page-header__actions:has(> .aura-icon-btn, > :not(.aura-page-header__bar) > .aura-icon-btn) > :is(.aura-btn, * > .aura-btn):not(.aura-icon-btn) { border-radius: var(--aura-radius-md); } /* 5.78 (visual audit 11) */
1376
+ .aura-page-header--actions-full-below-md:is(.aura-page-header--actions-bar-below-sm, .aura-page-header--actions-bar-below-md) > .aura-page-header__actions.is-split:has(> .aura-icon-btn, > :not(.aura-page-header__bar) > .aura-icon-btn) > :is(.aura-btn, :not(.aura-page-header__bar) > .aura-btn):not(.aura-icon-btn) { border-radius: var(--aura-radius-md); }
1349
1377
  .aura-page-header--actions-full-below-md > .aura-page-header__actions:has(> .aura-icon-btn, > :not(.aura-page-header__bar) > .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 */
1350
1378
  }
1351
1379
  @media (max-width: 1023.98px) {
1352
1380
  .aura-page-header--actions-full-below-lg > .aura-page-header__actions { flex: 1 1 100%; gap: var(--aura-space-3); }
1381
+ .aura-page-header--actions-full-below-lg:not(.aura-page-header--actions-bar-below-sm, .aura-page-header--actions-bar-below-md) > .aura-page-header__actions > :is(.aura-btn, :not(.aura-page-header__bar) > .aura-btn):not(.aura-icon-btn) { border-radius: var(--aura-radius-md); } /* 5.78 (visual audit 11): a label that wraps to two lines is a rounded box, not a lozenge */
1382
+ .aura-page-header--actions-full-below-lg:is(.aura-page-header--actions-bar-below-sm, .aura-page-header--actions-bar-below-md) > .aura-page-header__actions.is-split > :is(.aura-btn, :not(.aura-page-header__bar) > .aura-btn):not(.aura-icon-btn) { border-radius: var(--aura-radius-md); } /* 5.78: actionsBar's split — the header's own actions, not the strip */
1353
1383
  .aura-page-header--actions-full-below-lg > .aura-page-header__actions > :where(:not(.sr-only, .aura-sr-only, .visually-hidden, .screen-reader-text, [hidden], [style*="position: absolute"], [style*="position:absolute"])) { flex: 1 1 0; min-width: max-content; }
1354
1384
  .aura-page-header--actions-full-below-lg > .aura-page-header__actions > :is(.aura-dropdown, .aura-tooltip-anchor, .aura-popover-anchor) > * { flex: 1 1 auto; }
1355
1385
  .aura-page-header--actions-full-below-lg > .aura-page-header__actions > .aura-page-header__bar > :where(:not(.aura-page-header__status, .sr-only, .aura-sr-only, .visually-hidden, .screen-reader-text, [hidden], [style*="position: absolute"], [style*="position:absolute"])) { flex: 1 1 0; min-width: max-content; } /* 5.71: actionsBar in the row, as the actions (5.61) */
@@ -1359,6 +1389,8 @@ summary.aura-link::-webkit-details-marker { display: none; }
1359
1389
  .aura-page-header--actions-full-below-lg > .aura-page-header__actions:has(> .aura-icon-btn, > :not(.aura-page-header__bar) > .aura-icon-btn) { flex-wrap: nowrap; align-items: stretch; }
1360
1390
  .aura-page-header--actions-full-below-lg > .aura-page-header__actions:has(> .aura-icon-btn, > :not(.aura-page-header__bar) > .aura-icon-btn) > * { min-width: 0; }
1361
1391
  .aura-page-header--actions-full-below-lg > .aura-page-header__actions:has(> .aura-icon-btn, > :not(.aura-page-header__bar) > .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); }
1392
+ .aura-page-header--actions-full-below-lg:not(.aura-page-header--actions-bar-below-sm, .aura-page-header--actions-bar-below-md) > .aura-page-header__actions:has(> .aura-icon-btn, > :not(.aura-page-header__bar) > .aura-icon-btn) > :is(.aura-btn, * > .aura-btn):not(.aura-icon-btn) { border-radius: var(--aura-radius-md); } /* 5.78 (visual audit 11) */
1393
+ .aura-page-header--actions-full-below-lg:is(.aura-page-header--actions-bar-below-sm, .aura-page-header--actions-bar-below-md) > .aura-page-header__actions.is-split:has(> .aura-icon-btn, > :not(.aura-page-header__bar) > .aura-icon-btn) > :is(.aura-btn, :not(.aura-page-header__bar) > .aura-btn):not(.aura-icon-btn) { border-radius: var(--aura-radius-md); }
1362
1394
  .aura-page-header--actions-full-below-lg > .aura-page-header__actions:has(> .aura-icon-btn, > :not(.aura-page-header__bar) > .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 */
1363
1395
  }
1364
1396
  /* 5.48 (Chamber-OS 154): only on a screen taller than 30rem (5.49: 480px at the default text size) — on a short one (400% zoom, a phone held sideways) the
@@ -1379,7 +1411,7 @@ summary.aura-link::-webkit-details-marker { display: none; }
1379
1411
  .aura-page-header--actions-bar-below-sm[data-aura-bar="empty"] > .aura-page-header__actions:not(.is-split), .aura-page-header--actions-bar-below-sm[data-aura-bar="empty"] > .aura-page-header__actions > .aura-page-header__bar { display: none; }
1380
1412
  /* …and before hydration, from the markup alone (actionsBar's strip whose element children but the status are all `hidden` or visually hidden): it already goes; the page padding follows once the client has looked. */
1381
1413
  .aura-page-header--actions-bar-below-sm:not([data-aura-bar="shown"]) > .aura-page-header__actions > .aura-page-header__bar:not(:has(> :not(.aura-page-header__status, [hidden], .sr-only, .aura-sr-only, .visually-hidden, .screen-reader-text))):has(> *) { display: none; }
1382
- :is(.aura-page-header--actions-bar-below-sm > .aura-page-header__actions:not(.is-split), .aura-page-header--actions-bar-below-sm > .aura-page-header__actions > .aura-page-header__bar) { position: fixed; z-index: var(--aura-z-bar); left: 0; right: 0; bottom: var(--aura-bottomnav-offset, 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) calc(var(--aura-space-2) + max(0px, env(safe-area-inset-bottom, 0px) - var(--aura-bottomnav-offset, 0px))) var(--aura-space-4); background: var(--aura-bg-surface); color: var(--aura-fg-primary); border: 0; border-top: 1px solid var(--aura-border-default); border-radius: 0; box-shadow: none; transition: bottom var(--aura-duration-base) var(--aura-ease); }
1414
+ :is(.aura-page-header--actions-bar-below-sm > .aura-page-header__actions:not(.is-split), .aura-page-header--actions-bar-below-sm > .aura-page-header__actions > .aura-page-header__bar) { position: fixed; z-index: var(--aura-z-bar); left: 0; right: 0; bottom: var(--aura-bottomnav-offset, 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-4) calc(var(--aura-space-2) + max(0px, env(safe-area-inset-bottom, 0px) - var(--aura-bottomnav-offset, 0px))) var(--aura-space-4); /* 5.78 (audit 9): 16px both sides, the phone gutter */ background: var(--aura-bg-surface); color: var(--aura-fg-primary); border: 0; border-top: 1px solid var(--aura-border-default); border-radius: 0; box-shadow: none; transition: bottom var(--aura-duration-base) var(--aura-ease); }
1383
1415
  /* 5.54 (Chamber-OS 166): the bar's buttons are 44px whatever the density, as ActionBar's on a phone. */
1384
1416
  :is(.aura-page-header--actions-bar-below-sm > .aura-page-header__actions:not(.is-split), .aura-page-header--actions-bar-below-sm > .aura-page-header__actions > .aura-page-header__bar) { --aura-button-height: var(--aura-touch-target); --aura-button-height-sm: var(--aura-touch-target); }
1385
1417
  :is(.aura-page-header--actions-bar-below-sm > .aura-page-header__actions:not(.is-split), .aura-page-header--actions-bar-below-sm > .aura-page-header__actions > .aura-page-header__bar) > .aura-icon-btn, :is(.aura-page-header--actions-bar-below-sm > .aura-page-header__actions:not(.is-split), .aura-page-header--actions-bar-below-sm > .aura-page-header__actions > .aura-page-header__bar) > * > .aura-icon-btn:only-child { width: var(--aura-touch-target); height: var(--aura-touch-target); }
@@ -1405,7 +1437,7 @@ summary.aura-link::-webkit-details-marker { display: none; }
1405
1437
  .aura-page-header--actions-bar-below-md[data-aura-bar="empty"] > .aura-page-header__actions:not(.is-split), .aura-page-header--actions-bar-below-md[data-aura-bar="empty"] > .aura-page-header__actions > .aura-page-header__bar { display: none; }
1406
1438
  /* …and before hydration, from the markup alone (actionsBar's strip whose element children but the status are all `hidden` or visually hidden): it already goes; the page padding follows once the client has looked. */
1407
1439
  .aura-page-header--actions-bar-below-md:not([data-aura-bar="shown"]) > .aura-page-header__actions > .aura-page-header__bar:not(:has(> :not(.aura-page-header__status, [hidden], .sr-only, .aura-sr-only, .visually-hidden, .screen-reader-text))):has(> *) { display: none; }
1408
- :is(.aura-page-header--actions-bar-below-md > .aura-page-header__actions:not(.is-split), .aura-page-header--actions-bar-below-md > .aura-page-header__actions > .aura-page-header__bar) { position: fixed; z-index: var(--aura-z-bar); left: 0; right: 0; bottom: var(--aura-bottomnav-offset, 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) calc(var(--aura-space-2) + max(0px, env(safe-area-inset-bottom, 0px) - var(--aura-bottomnav-offset, 0px))) var(--aura-space-4); background: var(--aura-bg-surface); color: var(--aura-fg-primary); border: 0; border-top: 1px solid var(--aura-border-default); border-radius: 0; box-shadow: none; transition: bottom var(--aura-duration-base) var(--aura-ease); }
1440
+ :is(.aura-page-header--actions-bar-below-md > .aura-page-header__actions:not(.is-split), .aura-page-header--actions-bar-below-md > .aura-page-header__actions > .aura-page-header__bar) { position: fixed; z-index: var(--aura-z-bar); left: 0; right: 0; bottom: var(--aura-bottomnav-offset, 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-4) calc(var(--aura-space-2) + max(0px, env(safe-area-inset-bottom, 0px) - var(--aura-bottomnav-offset, 0px))) var(--aura-space-4); /* 5.78 (audit 9): 16px both sides, the phone gutter */ background: var(--aura-bg-surface); color: var(--aura-fg-primary); border: 0; border-top: 1px solid var(--aura-border-default); border-radius: 0; box-shadow: none; transition: bottom var(--aura-duration-base) var(--aura-ease); }
1409
1441
  /* 5.54 (Chamber-OS 166): the bar's buttons are 44px whatever the density, as ActionBar's on a phone. */
1410
1442
  :is(.aura-page-header--actions-bar-below-md > .aura-page-header__actions:not(.is-split), .aura-page-header--actions-bar-below-md > .aura-page-header__actions > .aura-page-header__bar) { --aura-button-height: var(--aura-touch-target); --aura-button-height-sm: var(--aura-touch-target); }
1411
1443
  :is(.aura-page-header--actions-bar-below-md > .aura-page-header__actions:not(.is-split), .aura-page-header--actions-bar-below-md > .aura-page-header__actions > .aura-page-header__bar) > .aura-icon-btn, :is(.aura-page-header--actions-bar-below-md > .aura-page-header__actions:not(.is-split), .aura-page-header--actions-bar-below-md > .aura-page-header__actions > .aura-page-header__bar) > * > .aura-icon-btn:only-child { width: var(--aura-touch-target); height: var(--aura-touch-target); }
@@ -1913,6 +1945,7 @@ button.aura-stepper__step:hover .aura-stepper__label { text-decoration: underlin
1913
1945
  .aura-combo__toggle, .aura-date__toggle { right: 0; }
1914
1946
  .aura-combo__clear, .aura-date .aura-combo__clear { right: var(--aura-touch-target); }
1915
1947
  .aura-combo .aura-input__control, .aura-date .aura-input__control { padding-right: calc(var(--aura-space-1) + 2 * var(--aura-touch-target)); }
1948
+ .aura-combo:not(.is-multi):not(:has(.aura-combo__clear)) .aura-input__control { padding-right: calc(var(--aura-space-1) + var(--aura-touch-target)); }
1916
1949
  .aura-combo__clear::after, .aura-combo__toggle::after, .aura-date__toggle::after, .aura-tag__remove::after {
1917
1950
  content: ''; position: absolute; top: 50%; left: 50%; width: max(100%, var(--aura-touch-target)); height: max(100%, var(--aura-touch-target)); transform: translate(-50%, -50%);
1918
1951
  }
@@ -1983,6 +2016,7 @@ button.aura-stepper__step:hover .aura-stepper__label { text-decoration: underlin
1983
2016
  :is(.aura-field, .aura-filterbar).is-touch-always :is(.aura-combo__toggle, .aura-date__toggle) { right: 0; }
1984
2017
  :is(.aura-field, .aura-filterbar).is-touch-always .aura-combo__clear { right: var(--aura-touch-target); }
1985
2018
  :is(.aura-field, .aura-filterbar).is-touch-always :is(.aura-combo, .aura-date) .aura-input__control { padding-right: calc(var(--aura-space-1) + 2 * var(--aura-touch-target)); }
2019
+ :is(.aura-field, .aura-filterbar).is-touch-always .aura-combo:not(.is-multi):not(:has(.aura-combo__clear)) .aura-input__control { padding-right: calc(var(--aura-space-1) + var(--aura-touch-target)); }
1986
2020
  :is(.aura-field, .aura-filterbar).is-touch-always .aura-combo.is-multi { padding-right: calc(var(--aura-space-1) + 2 * var(--aura-touch-target)); }
1987
2021
  :is(.aura-field, .aura-filterbar).is-touch-always .aura-combo.is-multi :is(.aura-combo__clear, .aura-combo__toggle) { top: calc((var(--aura-input-height) - 2px - 40px) / 2); }
1988
2022
  :is(.aura-field, .aura-filterbar).is-touch-always .aura-number__step { width: var(--aura-touch-target); }
@@ -1991,6 +2025,7 @@ button.aura-stepper__step:hover .aura-stepper__label { text-decoration: underlin
1991
2025
  :is(.aura-field, .aura-filterbar).is-touch :is(.aura-combo__toggle, .aura-date__toggle) { right: 0; }
1992
2026
  :is(.aura-field, .aura-filterbar).is-touch .aura-combo__clear { right: var(--aura-touch-target); }
1993
2027
  :is(.aura-field, .aura-filterbar).is-touch :is(.aura-combo, .aura-date) .aura-input__control { padding-right: calc(var(--aura-space-1) + 2 * var(--aura-touch-target)); }
2028
+ :is(.aura-field, .aura-filterbar).is-touch .aura-combo:not(.is-multi):not(:has(.aura-combo__clear)) .aura-input__control { padding-right: calc(var(--aura-space-1) + var(--aura-touch-target)); }
1994
2029
  :is(.aura-field, .aura-filterbar).is-touch .aura-combo.is-multi { padding-right: calc(var(--aura-space-1) + 2 * var(--aura-touch-target)); }
1995
2030
  :is(.aura-field, .aura-filterbar).is-touch .aura-combo.is-multi :is(.aura-combo__clear, .aura-combo__toggle) { top: calc((var(--aura-input-height) - 2px - 40px) / 2); }
1996
2031
  :is(.aura-field, .aura-filterbar).is-touch .aura-number__step { width: var(--aura-touch-target); }
@@ -2358,6 +2393,25 @@ button.aura-stepper__step:hover .aura-stepper__label { text-decoration: underlin
2358
2393
  :root:has(.aura-actionbar--edge:not(.is-idle)) .aura-shell__content { padding-bottom: calc(var(--aura-space-6) + var(--aura-actionbar-space)); }
2359
2394
  :root:has(.aura-actionbar--edge:not(.is-idle)):not(:has(.aura-shell__content)) body { padding-bottom: var(--aura-actionbar-space); }
2360
2395
  }
2396
+ /* 5.78 (visual audit 9): one rule for the bottom strips on a phone, as PageHeader's (5.48) — the status on its own row
2397
+ * at the top, the actions sharing the row under it (an IconButton keeps its square; labels too long to share take a row
2398
+ * each), 16px both sides as the page. edgeBelow="md" follows it up to 768px, as PageHeader's md strip. */
2399
+ @media (max-width: 639.98px) {
2400
+ @container aura-actionbar (max-width: 639.98px) {
2401
+ :is(.aura-actionbar--edge, .aura-actionbar--edge-below-sm, .aura-actionbar--edge-below-md):not(.is-idle) > .aura-actionbar__inner { padding-inline: var(--aura-space-4); }
2402
+ :is(.aura-actionbar--edge, .aura-actionbar--edge-below-sm, .aura-actionbar--edge-below-md):not(.is-idle) > .aura-actionbar__inner > .aura-actionbar__status:not(:empty) { flex-basis: 100%; }
2403
+ :is(.aura-actionbar--edge, .aura-actionbar--edge-below-sm, .aura-actionbar--edge-below-md):not(.is-idle) .aura-actionbar__actions { flex: 1 1 auto; min-width: 0; margin-inline-start: 0; }
2404
+ :is(.aura-actionbar--edge, .aura-actionbar--edge-below-sm, .aura-actionbar--edge-below-md):not(.is-idle) .aura-actionbar__actions > :not(.aura-icon-btn, :has(> .aura-icon-btn)) { flex: 1 1 0; min-width: max-content; } /* as PageHeader's strip (5.61): shares, a long label takes its own row */
2405
+ :is(.aura-actionbar--edge, .aura-actionbar--edge-below-sm, .aura-actionbar--edge-below-md):not(.is-idle) .aura-actionbar__actions > :is(.aura-dropdown, .aura-tooltip-anchor, .aura-popover-anchor):not(:has(> .aura-icon-btn)) > .aura-btn { width: 100%; }
2406
+ }
2407
+ }
2408
+ @media (min-width: 640px) and (max-width: 767.98px) {
2409
+ .aura-actionbar--edge-below-md:not(.is-idle) > .aura-actionbar__inner { padding-inline: var(--aura-space-4); }
2410
+ .aura-actionbar--edge-below-md:not(.is-idle) > .aura-actionbar__inner > .aura-actionbar__status:not(:empty) { flex-basis: 100%; }
2411
+ .aura-actionbar--edge-below-md:not(.is-idle) .aura-actionbar__actions { flex: 1 1 auto; min-width: 0; margin-inline-start: 0; }
2412
+ .aura-actionbar--edge-below-md:not(.is-idle) .aura-actionbar__actions > :not(.aura-icon-btn, :has(> .aura-icon-btn)) { flex: 1 1 0; min-width: max-content; } /* as PageHeader's strip (5.61): shares, a long label takes its own row */
2413
+ .aura-actionbar--edge-below-md:not(.is-idle) .aura-actionbar__actions > :is(.aura-dropdown, .aura-tooltip-anchor, .aura-popover-anchor):not(:has(> .aura-icon-btn)) > .aura-btn { width: 100%; }
2414
+ }
2361
2415
  @media (max-width: 639.98px) { .aura-actionbar--edge-below-sm:not(.is-idle) { border: 0; border-top: 1px solid var(--aura-border-default); border-radius: 0; box-shadow: none; } }
2362
2416
  @media (max-width: 639.98px) and (min-height: 30.00125rem) {
2363
2417
  .aura-actionbar--edge-below-sm:not(.is-idle) { position: fixed; left: 0; right: 0; width: auto; bottom: var(--aura-bottomnav-offset, 0px); margin: 0; padding-bottom: max(0px, env(safe-area-inset-bottom, 0px) - var(--aura-bottomnav-offset, 0px)); }
@@ -2581,7 +2635,7 @@ button.aura-stepper__step:hover .aura-stepper__label { text-decoration: underlin
2581
2635
  .aura-table__head:not(.has-select-all) { position: absolute; width: 1px; height: 1px; padding: 0; overflow: hidden; clip: rect(0 0 0 0); }
2582
2636
  .aura-table__head > .aura-table__sel { position: static; width: auto; gap: var(--aura-space-3); padding: 0 var(--aura-space-4); }
2583
2637
  .aura-table__sel-text { display: inline; color: var(--aura-fg-secondary); }
2584
- .aura-table__gutter { display: none; }
2638
+ .aura-table__gutter, .aura-table__gutter--end.has-picker { display: none; } /* 5.78 (audit 20): the column picker's slot too, which squeezed the card's title */
2585
2639
  .aura-table__row, .aura-table__row:last-child {
2586
2640
  height: auto; min-width: 0; flex-wrap: wrap; align-items: center; gap: var(--aura-space-1) var(--aura-space-4);
2587
2641
  margin-bottom: var(--aura-space-2); padding: var(--aura-space-4);