@protobase/ui 0.19.4 → 0.19.6

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.
Files changed (159) hide show
  1. package/dist/account/account-section.js +2 -2
  2. package/dist/account/account-security-page.js +2 -2
  3. package/dist/account/backup-codes.js +3 -10
  4. package/dist/account/passkeys-section.js +2 -2
  5. package/dist/account/password-dialog.js +1 -1
  6. package/dist/account/sign-in-policy-form.js +2 -2
  7. package/dist/account/sign-in-policy-page.js +2 -2
  8. package/dist/account/sign-in-providers-section.js +1 -1
  9. package/dist/account/staff-sign-in-log.js +3 -3
  10. package/dist/account/two-factor-setup.js +6 -6
  11. package/dist/action-card/action-card.js +1 -1
  12. package/dist/activity-chart/activity-chart.js +2 -2
  13. package/dist/app/delete/dialogs.js +3 -3
  14. package/dist/app/displays/display-controls.js +1 -1
  15. package/dist/app/displays/display-frame.js +1 -1
  16. package/dist/app/displays/list-cards.js +1 -1
  17. package/dist/app/displays/list-displays.js +2 -1
  18. package/dist/app/displays/map-display.js +1 -1
  19. package/dist/app/displays/record-card.js +1 -1
  20. package/dist/app/embedded-list/embedded-list.js +2 -2
  21. package/dist/app/error-banner.js +1 -1
  22. package/dist/app/field-editor.js +6 -12
  23. package/dist/app/file-field.js +4 -4
  24. package/dist/app/filled-fields.js +5 -0
  25. package/dist/app/gallery/details-open-storage.js +10 -0
  26. package/dist/app/gallery/gallery-layout.js +3 -1
  27. package/dist/app/gallery/lightbox.js +107 -61
  28. package/dist/app/gallery/photo-details.js +1 -1
  29. package/dist/app/import/convert.js +151 -0
  30. package/dist/app/import/csv-parser.js +119 -0
  31. package/dist/app/import/failed-rows.js +21 -0
  32. package/dist/app/import/import-button.js +31 -0
  33. package/dist/app/import/import-check-step.js +123 -0
  34. package/dist/app/import/import-counts.js +19 -0
  35. package/dist/app/import/import-dialog.js +152 -0
  36. package/dist/app/import/import-file-step.js +65 -0
  37. package/dist/app/import/import-mapping-step.js +195 -0
  38. package/dist/app/import/import-result-step.js +86 -0
  39. package/dist/app/import/import-select.js +35 -0
  40. package/dist/app/import/locale-formats.js +15 -0
  41. package/dist/app/import/lookups.js +48 -0
  42. package/dist/app/import/mapping.js +78 -0
  43. package/dist/app/import/parse-worker.d.ts +1 -0
  44. package/dist/app/import/parse-worker.js +39 -0
  45. package/dist/app/import/prepare-rows.js +129 -0
  46. package/dist/app/import/run-import.js +130 -0
  47. package/dist/app/import/sheet-cell.js +17 -0
  48. package/dist/app/import/sheet-file.js +58 -0
  49. package/dist/app/import/sheet-source.js +72 -0
  50. package/dist/app/import/use-import-flow.js +225 -0
  51. package/dist/app/import/xlsx-reader.js +43 -0
  52. package/dist/app/import/xlsx-xml.js +169 -0
  53. package/dist/app/import/zip-reader.js +72 -0
  54. package/dist/app/list-page.js +8 -1
  55. package/dist/app/meta-gate.js +3 -3
  56. package/dist/app/named-icon.js +9 -1
  57. package/dist/app/pages/blocks/card-frame.js +4 -4
  58. package/dist/app/pages/blocks/field.js +2 -5
  59. package/dist/app/pages/blocks/stat.js +2 -2
  60. package/dist/app/pages/problem.js +1 -1
  61. package/dist/app/pages/render-node.js +1 -1
  62. package/dist/app/record-page.js +13 -4
  63. package/dist/app/record-row/record-row-body.js +3 -3
  64. package/dist/app/record-row/saved-record-row.js +1 -1
  65. package/dist/app/related-section.js +1 -1
  66. package/dist/app/relation-picker.js +1 -1
  67. package/dist/app/runtime/runtime-update.js +3 -3
  68. package/dist/app/saved/saved-list.js +1 -1
  69. package/dist/app/searches/saved-search-rows.js +2 -2
  70. package/dist/app/searches/saved-search-section.js +1 -1
  71. package/dist/app/searches/saved-searches.js +1 -1
  72. package/dist/app/searches/search-controls.js +2 -2
  73. package/dist/app/searches/search-name-dialog.js +1 -1
  74. package/dist/app/searches/update-search-dialog.js +16 -19
  75. package/dist/app/sensitive-field.js +1 -1
  76. package/dist/app/source-notice.js +3 -3
  77. package/dist/app/staff-banner.js +1 -1
  78. package/dist/app-shell/breadcrumb.js +1 -1
  79. package/dist/app-shell/global-search.js +1 -1
  80. package/dist/app-shell/page-header.js +1 -1
  81. package/dist/app-shell/profile-menu.js +3 -3
  82. package/dist/app-shell/sidebar-group.js +1 -1
  83. package/dist/app-shell/sidebar-item.js +1 -1
  84. package/dist/app-shell/sidebar.js +2 -2
  85. package/dist/assistant-dock/part-view.js +1 -4
  86. package/dist/assistant-dock/widget-view.js +1 -4
  87. package/dist/auth/auth-gate.js +2 -2
  88. package/dist/auth/auth-layout.js +1 -1
  89. package/dist/auth/code-form.js +2 -2
  90. package/dist/auth/first-run-page.js +1 -1
  91. package/dist/auth/forgot-password-form.js +2 -2
  92. package/dist/auth/provider-sign-in-page.js +1 -1
  93. package/dist/auth/reset-password-form.js +3 -3
  94. package/dist/auth/setup-required-form.js +2 -2
  95. package/dist/auth/setup-required-page.js +1 -1
  96. package/dist/auth/sign-in-form.js +5 -5
  97. package/dist/auth/sign-in-prompt.js +3 -3
  98. package/dist/auth/sign-up-details-form.js +3 -3
  99. package/dist/auth/sign-up-email-form.js +4 -4
  100. package/dist/auth/staff-sign-in-form.js +3 -3
  101. package/dist/auth/two-factor-form.js +5 -5
  102. package/dist/chat/chat-message.js +1 -1
  103. package/dist/chat/chat-thread.js +1 -1
  104. package/dist/data/api-provider.js +8 -2
  105. package/dist/data-grid/grid-row.js +1 -1
  106. package/dist/data-grid/header-menu.js +1 -1
  107. package/dist/data-grid/row-menu.js +1 -1
  108. package/dist/filter-panel/facet-combobox.js +1 -1
  109. package/dist/filter-panel/filter-menu.js +1 -1
  110. package/dist/filter-panel/filter-panel.js +2 -2
  111. package/dist/inline-child-table/line-menu.js +1 -1
  112. package/dist/inline-child-table/line-row.js +4 -4
  113. package/dist/inline-child-table/number-cell.js +1 -1
  114. package/dist/inline-child-table/totals-footer.js +2 -2
  115. package/dist/lib/save-file.js +12 -0
  116. package/dist/lib/use-focus-trap.js +7 -1
  117. package/dist/organizations/app-roles-picker.js +1 -1
  118. package/dist/organizations/invitation-page.js +3 -3
  119. package/dist/organizations/invitations-page.js +2 -2
  120. package/dist/organizations/members-page.js +2 -2
  121. package/dist/organizations/organization-page.js +1 -1
  122. package/dist/organizations/organizations-page.js +2 -2
  123. package/dist/package.js +1 -1
  124. package/dist/plugins/before-sign-in.js +1 -1
  125. package/dist/plugins/plugin-gate.js +1 -1
  126. package/dist/plugins/plugin-notice.js +1 -1
  127. package/dist/primitives/button.js +1 -1
  128. package/dist/primitives/dialog.js +2 -2
  129. package/dist/primitives/input.js +1 -1
  130. package/dist/primitives/menu-select.js +2 -2
  131. package/dist/primitives/responsive-dialog.js +1 -1
  132. package/dist/primitives/segmented.js +1 -1
  133. package/dist/primitives/sheet-swipe.js +5 -0
  134. package/dist/primitives/sheet.js +40 -12
  135. package/dist/primitives/textarea.js +1 -1
  136. package/dist/record-view/action-rail.js +1 -1
  137. package/dist/record-view/field.js +1 -1
  138. package/dist/record-view/key-facts.js +29 -0
  139. package/dist/record-view/record-sidebar.js +2 -2
  140. package/dist/record-view/section.js +2 -2
  141. package/dist/record-view/spec-table.js +1 -1
  142. package/dist/shell/assets/app-DwKzLvfm.js +67 -0
  143. package/dist/shell/assets/index-CwhnZIJp.css +2 -0
  144. package/dist/shell/assets/{index-CEvfMgFJ.js → index-Dqgcyg7M.js} +1 -1
  145. package/dist/shell/assets/{maplibre-D6zfLfTV.js → maplibre-BWjNhvrH.js} +1 -1
  146. package/dist/shell/assets/parse-worker-BtcY0dQw.js +5 -0
  147. package/dist/shell/assets/{record-map-B6_rbCcG.js → record-map-m5K2uttt.js} +1 -1
  148. package/dist/shell/assets/{records-map-bQbuIc13.js → records-map-CA_JG9RR.js} +1 -1
  149. package/dist/shell/assets/{shared-protobase-ui-8pJgwjfc.js → shared-protobase-ui-BBqKlVLh.js} +1 -1
  150. package/dist/shell/index.html +4 -4
  151. package/dist/shell/protobase.shell.json +1 -1
  152. package/dist/side-panel/side-panel.js +1 -1
  153. package/dist/step-list/step-list.js +1 -1
  154. package/dist/styles.css +1 -1
  155. package/dist/theme.css +2 -0
  156. package/dist/toasts/toast.js +2 -2
  157. package/package.json +4 -4
  158. package/dist/shell/assets/app-BYFiTXK6.js +0 -66
  159. package/dist/shell/assets/index-CiGP6kle.css +0 -2
@@ -10,6 +10,7 @@ import { recordTitle } from "../live/model-helpers.js";
10
10
  import { humanize } from "../live/naming.js";
11
11
  import { useProjectUi } from "./pages/project-ui.js";
12
12
  import { displayValue } from "../live/display-value.js";
13
+ import { filledFields } from "./filled-fields.js";
13
14
  import { Notice, useAdminMeta, usePermissions } from "./meta-gate.js";
14
15
  import { AppLink, useAppAddress } from "./use-app-address.js";
15
16
  import { ErrorBanner } from "./error-banner.js";
@@ -22,9 +23,11 @@ import { Section } from "../record-view/section.js";
22
23
  import { MetadataCard, RelatedRecords, SidebarCard } from "../record-view/record-sidebar.js";
23
24
  import { RecordHeader } from "../record-view/record-header.js";
24
25
  import { SpecTable } from "../record-view/spec-table.js";
26
+ import { KeyFacts } from "../record-view/key-facts.js";
25
27
  import { toneFor } from "../live/columns-from-model.js";
26
28
  import { useDeleteFlow } from "./delete/use-delete-flow.js";
27
29
  import { useRestore } from "./delete/use-restore.js";
30
+ import { namedIcon } from "./named-icon.js";
28
31
  import { ValueBadge } from "./value-badge.js";
29
32
  import { FieldValue } from "./pages/field-value.js";
30
33
  import { auditField } from "../live/audit-fields.js";
@@ -320,7 +323,7 @@ const LoadedRecord = ({ model, recordKey, stored }) => {
320
323
  })
321
324
  }),
322
325
  shown !== "form" && offersEdit && editor.dirty && /* @__PURE__ */ jsxs("div", {
323
- className: "mt-4 flex items-center justify-between gap-3 rounded-lg border bg-surface px-3 py-2 text-[13px]",
326
+ className: "mt-4 flex items-center justify-between gap-3 rounded-lg border bg-surface px-3 py-2",
324
327
  role: "status",
325
328
  children: [/* @__PURE__ */ jsx("span", { children: "You have unsaved changes to this record." }), /* @__PURE__ */ jsxs("span", {
326
329
  className: "flex gap-2",
@@ -336,7 +339,7 @@ const LoadedRecord = ({ model, recordKey, stored }) => {
336
339
  })]
337
340
  }),
338
341
  shown === "form" && editor.restored && /* @__PURE__ */ jsxs("div", {
339
- className: "mt-4 flex items-center justify-between gap-3 rounded-lg border bg-surface px-3 py-2 text-[13px]",
342
+ className: "mt-4 flex items-center justify-between gap-3 rounded-lg border bg-surface px-3 py-2",
340
343
  role: "status",
341
344
  children: [/* @__PURE__ */ jsx("span", { children: "Your unsaved changes were restored." }), /* @__PURE__ */ jsxs("span", {
342
345
  className: "flex gap-2",
@@ -375,12 +378,18 @@ const LoadedRecord = ({ model, recordKey, stored }) => {
375
378
  recordKey
376
379
  }, `gallery:${index}`)];
377
380
  if (item.kind !== "section") return [];
378
- const fields = item.fields.filter((name) => model.fields[name] && visible(name));
381
+ const visibleFields = item.fields.filter((name) => model.fields[name] && visible(name));
382
+ const facts = shown === "read" && item.presentation === "facts";
383
+ const fields = facts ? filledFields(stored.record, visibleFields) : visibleFields;
379
384
  if (fields.length === 0) return [];
380
385
  return [/* @__PURE__ */ jsx(Section, {
381
386
  title: item.title,
382
387
  help: helpShown(item.helpWhen, view, editing) ? item.help : void 0,
383
- children: shown === "read" ? /* @__PURE__ */ jsx(SpecTable, { rows: fields.map(readRow) }) : /* @__PURE__ */ jsx("div", {
388
+ children: facts ? /* @__PURE__ */ jsx(KeyFacts, { facts: fields.map((name) => ({
389
+ label: readRow(name).label,
390
+ value: readRow(name).value,
391
+ icon: namedIcon(hint(name)?.icon)
392
+ })) }) : shown === "read" ? /* @__PURE__ */ jsx(SpecTable, { rows: fields.map(readRow) }) : /* @__PURE__ */ jsx("div", {
384
393
  className: "grid grid-cols-1 gap-x-6 gap-y-5 sm:grid-cols-2",
385
394
  children: fields.map(fieldView)
386
395
  })
@@ -68,7 +68,7 @@ const RecordRowBody = ({ model, view, filter, sort = "", display: named, limit,
68
68
  showChips && chips.length > 0 || total !== void 0 || note ? /* @__PURE__ */ jsxs("div", {
69
69
  className: "flex flex-wrap items-center justify-between gap-2",
70
70
  children: [showChips && chips.length > 0 ? /* @__PURE__ */ jsx(FilterChipList, { chips }) : /* @__PURE__ */ jsx("span", {}), /* @__PURE__ */ jsxs("p", {
71
- className: "flex flex-wrap gap-x-3 text-[13px] text-muted-foreground",
71
+ className: "flex flex-wrap gap-x-3 text-muted-foreground",
72
72
  children: [note && /* @__PURE__ */ jsx("span", { children: note }), total !== void 0 && /* @__PURE__ */ jsx("span", {
73
73
  className: "tabular-nums",
74
74
  children: `${total.toLocaleString("en-GB")} ${total === 1 ? singular : plural.toLowerCase()}`
@@ -79,7 +79,7 @@ const RecordRowBody = ({ model, view, filter, sort = "", display: named, limit,
79
79
  title: "Could not load",
80
80
  error: rows.error
81
81
  }) : !source || source.total === 0 ? /* @__PURE__ */ jsx("p", {
82
- className: "text-[13px] text-muted-foreground",
82
+ className: "text-muted-foreground",
83
83
  children: empty ?? `No ${plural.toLowerCase()} match.`
84
84
  }) : /* @__PURE__ */ jsx(RecordRow, {
85
85
  model,
@@ -98,7 +98,7 @@ const RecordRowBody = ({ model, view, filter, sort = "", display: named, limit,
98
98
  resource: list
99
99
  }),
100
100
  onClick: viewAll?.onOpen,
101
- className: "flex items-center gap-1 self-end text-[13px] font-medium text-primary-text hover:underline",
101
+ className: "flex items-center gap-1 self-end font-medium text-primary-text hover:underline",
102
102
  children: [viewAll?.label ?? /* @__PURE__ */ jsxs(Fragment$1, { children: ["View all ", /* @__PURE__ */ jsx("span", {
103
103
  className: "sr-only",
104
104
  children: plural.toLowerCase()
@@ -25,7 +25,7 @@ const SavedRecordRow = ({ model, view, empty, ...props }) => {
25
25
  if (!saved.data) return /* @__PURE__ */ jsx(Skeleton, { className: "h-24" });
26
26
  const scope = savedScope(listed.model, saved.data);
27
27
  if (!scope) return /* @__PURE__ */ jsx("p", {
28
- className: "text-[13px] text-muted-foreground",
28
+ className: "text-muted-foreground",
29
29
  children: empty ?? `No ${plural} yet.`
30
30
  });
31
31
  return /* @__PURE__ */ jsx(RecordRowBody, {
@@ -62,7 +62,7 @@ const Loading = () => /* @__PURE__ */ jsx("div", {
62
62
  children: Array.from({ length: 3 }, (_, index) => /* @__PURE__ */ jsx(Skeleton, { className: "h-4 w-full" }, index))
63
63
  });
64
64
  const Empty = ({ text }) => /* @__PURE__ */ jsx("p", {
65
- className: "text-[13px] text-muted-foreground",
65
+ className: "text-muted-foreground",
66
66
  children: text ?? "Nothing here yet."
67
67
  });
68
68
  /**
@@ -38,7 +38,7 @@ const RelationPicker = ({ target, view, value, label, invalid, onChange }) => {
38
38
  onChange: (event) => setText(event.target.value)
39
39
  }), open && /* @__PURE__ */ jsxs("ul", {
40
40
  role: "listbox",
41
- className: "absolute z-30 mt-1 max-h-60 w-full overflow-y-auto rounded-md border bg-background py-1 text-[13px] shadow-pop",
41
+ className: "absolute z-30 mt-1 max-h-60 w-full overflow-y-auto rounded-md border bg-background py-1 shadow-pop",
42
42
  children: [
43
43
  options.data?.items.map((item) => /* @__PURE__ */ jsx("li", { children: /* @__PURE__ */ jsx("button", {
44
44
  type: "button",
@@ -7,7 +7,7 @@ import { ArrowUpCircle } from "lucide-react";
7
7
  import { Fragment as Fragment$1, jsx, jsxs } from "react/jsx-runtime";
8
8
  //#region src/app/runtime/runtime-update.tsx
9
9
  const Row = ({ label, value }) => /* @__PURE__ */ jsxs("div", {
10
- className: "flex justify-between gap-4 py-1 text-[13px]",
10
+ className: "flex justify-between gap-4 py-1",
11
11
  children: [/* @__PURE__ */ jsx("span", {
12
12
  className: "text-muted-foreground",
13
13
  children: label
@@ -60,11 +60,11 @@ const RuntimeUpdate = ({ client }) => {
60
60
  }),
61
61
  error !== void 0 && /* @__PURE__ */ jsx("p", {
62
62
  role: "alert",
63
- className: "mt-3 text-[13px] text-danger-text",
63
+ className: "mt-3 text-danger-text",
64
64
  children: updateErrorText(error)
65
65
  }),
66
66
  checkError !== void 0 && /* @__PURE__ */ jsx("p", {
67
- className: "mt-3 text-[13px] text-muted-foreground",
67
+ className: "mt-3 text-muted-foreground",
68
68
  children: "The status could not be checked again; this is the last one read."
69
69
  })
70
70
  ]
@@ -30,7 +30,7 @@ const SavedList = ({ model, view, target, children }) => {
30
30
  }));
31
31
  const scope = savedScope(target, saved.data);
32
32
  if (!scope) return frame(/* @__PURE__ */ jsxs("p", {
33
- className: "py-8 text-center text-[13px] text-muted-foreground",
33
+ className: "py-8 text-center text-muted-foreground",
34
34
  children: [
35
35
  "No ",
36
36
  plural.toLowerCase(),
@@ -25,7 +25,7 @@ const SearchRowItem = ({ model, view, target, targetView, row }) => {
25
25
  "aria-label": title,
26
26
  className: "flex flex-col gap-3 py-4 first:pt-0 last:pb-0",
27
27
  children: [/* @__PURE__ */ jsx("h3", {
28
- className: "text-[14px] font-semibold",
28
+ className: "text-[15px] font-semibold",
29
29
  children: /* @__PURE__ */ jsx(AppLink, {
30
30
  to: {
31
31
  kind: "record",
@@ -55,7 +55,7 @@ const SavedSearchRows = ({ model, view, empty }) => {
55
55
  });
56
56
  if (!saved.data) return /* @__PURE__ */ jsx(Skeleton, { className: "h-40" });
57
57
  if (saved.data.length === 0) return /* @__PURE__ */ jsx("p", {
58
- className: "text-[13px] text-muted-foreground",
58
+ className: "text-muted-foreground",
59
59
  children: empty ?? `No ${plural} yet.`
60
60
  });
61
61
  return /* @__PURE__ */ jsx("div", {
@@ -53,7 +53,7 @@ const SavedSearchSection = ({ model, view, of, target, targetView, row, recordKe
53
53
  children: [/* @__PURE__ */ jsx("div", {
54
54
  className: "flex min-w-0 flex-col gap-2",
55
55
  children: /* @__PURE__ */ jsx("h2", {
56
- className: "text-[15px] font-semibold",
56
+ className: "text-[16px] font-semibold",
57
57
  children: /* @__PURE__ */ jsx(AppLink, {
58
58
  to: {
59
59
  kind: "record",
@@ -58,7 +58,7 @@ const SavedSearches = ({ model, view }) => {
58
58
  if (saved.data.length === 0) {
59
59
  const searched = (targetView?.names?.plural ?? humanize(target.name)).toLowerCase();
60
60
  return frame(/* @__PURE__ */ jsxs("p", {
61
- className: "py-8 text-center text-[13px] text-muted-foreground",
61
+ className: "py-8 text-center text-muted-foreground",
62
62
  children: [
63
63
  "No ",
64
64
  plural.toLowerCase(),
@@ -22,12 +22,12 @@ const Control = ({ model, view, name, value, onChange }) => {
22
22
  if (field?.type !== "enum") throw new Error(`Not implemented: "${name}" is ${field?.type ?? "unknown"}, and a saved search's controls are enums or booleans`);
23
23
  return /* @__PURE__ */ jsxs("label", {
24
24
  htmlFor: id,
25
- className: "flex items-center gap-2 text-[13px] text-muted-foreground",
25
+ className: "flex items-center gap-2 text-muted-foreground",
26
26
  children: [label, /* @__PURE__ */ jsx("select", {
27
27
  id,
28
28
  value: String(value ?? ""),
29
29
  onChange: (event) => onChange(event.target.value),
30
- className: "h-8 rounded-md border border-border-strong bg-background px-2 text-[13px] text-foreground shadow-sm focus:border-primary focus:outline-none focus:ring-2 focus:ring-primary/20",
30
+ className: "h-8 rounded-md border border-border-strong bg-background px-2 text-foreground shadow-sm focus:border-primary focus:outline-none focus:ring-2 focus:ring-primary/20",
31
31
  children: (field.enumValues ?? []).map((option) => /* @__PURE__ */ jsx("option", {
32
32
  value: option,
33
33
  children: enumLabel(option, hints?.valueLabels)
@@ -34,7 +34,7 @@ const SearchNameDialog = ({ title, chips, label, required, initial = "", busy, o
34
34
  children: [chips.length > 0 && /* @__PURE__ */ jsx(FilterChipList, { chips }), /* @__PURE__ */ jsxs("div", {
35
35
  className: "flex flex-col gap-1.5",
36
36
  children: [/* @__PURE__ */ jsxs("div", {
37
- className: "flex items-baseline justify-between gap-2 text-[13px]",
37
+ className: "flex items-baseline justify-between gap-2",
38
38
  children: [/* @__PURE__ */ jsx("label", {
39
39
  htmlFor: id,
40
40
  className: "font-medium",
@@ -31,7 +31,7 @@ const changeStyle = {
31
31
  };
32
32
  const FilterChanges = ({ changes }) => /* @__PURE__ */ jsx("ul", {
33
33
  "aria-label": "Filter changes",
34
- className: "divide-y rounded-md border text-[13px]",
34
+ className: "divide-y rounded-md border",
35
35
  children: changes.map((change) => /* @__PURE__ */ jsxs("li", {
36
36
  className: "grid grid-cols-[72px_1fr] gap-3 px-3 py-2",
37
37
  children: [/* @__PURE__ */ jsx("span", {
@@ -70,7 +70,7 @@ const RecordsSide = ({ model, view, title, filter, total, plural }) => {
70
70
  className: "flex flex-col gap-2",
71
71
  children: [
72
72
  /* @__PURE__ */ jsxs("h3", {
73
- className: "text-[13px] font-semibold",
73
+ className: "font-semibold",
74
74
  children: [
75
75
  title,
76
76
  " ",
@@ -95,7 +95,7 @@ const RecordsSide = ({ model, view, title, filter, total, plural }) => {
95
95
  ]
96
96
  }),
97
97
  filter === null || total === 0 ? /* @__PURE__ */ jsxs("p", {
98
- className: "text-[13px] text-muted-foreground",
98
+ className: "text-muted-foreground",
99
99
  children: [
100
100
  "No ",
101
101
  plural,
@@ -156,22 +156,19 @@ const UpdateSearchDialog = ({ model, view, title, before, after, saveNewLabel, u
156
156
  className: "flex flex-col gap-4",
157
157
  children: [
158
158
  changes.length > 0 && /* @__PURE__ */ jsx(FilterChanges, { changes }),
159
- counted ? /* @__PURE__ */ jsxs("p", {
160
- className: "text-[13px]",
161
- children: [/* @__PURE__ */ jsx("span", {
162
- className: "font-semibold",
163
- children: netChange(addedCount, removedCount, singular, plural)
164
- }), /* @__PURE__ */ jsxs("span", {
165
- className: "text-muted-foreground",
166
- children: [
167
- ": ",
168
- count(addedCount, singular, plural),
169
- " added, ",
170
- removedCount,
171
- " removed"
172
- ]
173
- })]
174
- }) : /* @__PURE__ */ jsx(Skeleton, { className: "h-4 w-48" }),
159
+ counted ? /* @__PURE__ */ jsxs("p", { children: [/* @__PURE__ */ jsx("span", {
160
+ className: "font-semibold",
161
+ children: netChange(addedCount, removedCount, singular, plural)
162
+ }), /* @__PURE__ */ jsxs("span", {
163
+ className: "text-muted-foreground",
164
+ children: [
165
+ ": ",
166
+ count(addedCount, singular, plural),
167
+ " added, ",
168
+ removedCount,
169
+ " removed"
170
+ ]
171
+ })] }) : /* @__PURE__ */ jsx(Skeleton, { className: "h-4 w-48" }),
175
172
  /* @__PURE__ */ jsx(RecordsSide, {
176
173
  model,
177
174
  view,
@@ -42,7 +42,7 @@ const SensitiveField = ({ field, hints, value, reveal, locked, invalid, placehol
42
42
  })
43
43
  });
44
44
  if (locked) return /* @__PURE__ */ jsxs("div", { children: [/* @__PURE__ */ jsxs("div", {
45
- className: "flex items-center gap-2 py-1 text-[13px]",
45
+ className: "flex items-center gap-2 py-1",
46
46
  children: [/* @__PURE__ */ jsx("span", {
47
47
  className: cn(shown ? hints?.format === "code" ? "font-mono text-xs" : "" : "tracking-widest text-muted-foreground"),
48
48
  children: shown ? displayValue(field, stored.data, hints) : mask
@@ -14,7 +14,7 @@ const reason = (error) => {
14
14
  const SourceNotice = ({ status }) => {
15
15
  const queryClient = useQueryClient();
16
16
  if (status.state !== "error") return /* @__PURE__ */ jsxs("div", {
17
- className: "flex h-full min-h-48 flex-1 items-center justify-center gap-2 text-[13px] text-muted-foreground",
17
+ className: "flex h-full min-h-48 flex-1 items-center justify-center gap-2 text-muted-foreground",
18
18
  children: [
19
19
  /* @__PURE__ */ jsx(Spinner, {}),
20
20
  " Loading from ",
@@ -27,11 +27,11 @@ const SourceNotice = ({ status }) => {
27
27
  className: "max-w-md text-center",
28
28
  children: [
29
29
  /* @__PURE__ */ jsxs("h1", {
30
- className: "text-[15px] font-semibold",
30
+ className: "text-[16px] font-semibold",
31
31
  children: ["Cannot reach ", status.source.label]
32
32
  }),
33
33
  /* @__PURE__ */ jsxs("p", {
34
- className: "mt-1 text-[13px] text-muted-foreground",
34
+ className: "mt-1 text-muted-foreground",
35
35
  children: [reason(status.error), " The rest of the app works as before."]
36
36
  }),
37
37
  /* @__PURE__ */ jsx(Button, {
@@ -24,7 +24,7 @@ const StaffBanner = ({ signIn, onStop }) => {
24
24
  return /* @__PURE__ */ jsxs("div", {
25
25
  role: "region",
26
26
  "aria-label": "Staff session",
27
- className: "flex flex-wrap items-center gap-x-3 gap-y-2 border-b border-warning/40 bg-warning-soft px-4 py-2 text-[13px] text-warning-text",
27
+ className: "flex flex-wrap items-center gap-x-3 gap-y-2 border-b border-warning/40 bg-warning-soft px-4 py-2 text-warning-text",
28
28
  children: [
29
29
  /* @__PURE__ */ jsx(UserRoundCog, {
30
30
  "aria-hidden": true,
@@ -8,7 +8,7 @@ const inApp = (event) => event.button === 0 && !event.metaKey && !event.ctrlKey
8
8
  /** The trail of where you are; the last crumb, the current page, shows on phones too. */
9
9
  const Breadcrumb = ({ parts, onNavigate }) => /* @__PURE__ */ jsx("nav", {
10
10
  "aria-label": "Breadcrumb",
11
- className: "flex min-w-0 items-center gap-1.5 text-[13px]",
11
+ className: "flex min-w-0 items-center gap-1.5",
12
12
  children: parts.map((part, index) => {
13
13
  const last = index === parts.length - 1;
14
14
  const { label, href, loading } = typeof part === "string" ? {
@@ -94,7 +94,7 @@ const GlobalSearch = ({ search, className = "w-96", autoFocus, showShortcut = tr
94
94
  id: listId,
95
95
  role: "listbox",
96
96
  "aria-label": "Search results",
97
- className: "absolute right-0 top-full z-40 mt-1 max-h-96 w-full min-w-72 overflow-y-auto rounded-lg border bg-background py-1 text-[13px] shadow-pop",
97
+ className: "absolute right-0 top-full z-40 mt-1 max-h-96 w-full min-w-72 overflow-y-auto rounded-lg border bg-background py-1 shadow-pop",
98
98
  children: [search.groups.length === 0 && /* @__PURE__ */ jsx("p", {
99
99
  className: "px-3 py-2 text-muted-foreground",
100
100
  children: search.loading ? "Searching" : `No matches for “${search.query}”`
@@ -5,7 +5,7 @@ const PageHeader = ({ title, subtitle, aside, actions }) => {
5
5
  className: "text-xl font-semibold tracking-tight",
6
6
  children: title
7
7
  }), subtitle && /* @__PURE__ */ jsx("p", {
8
- className: "text-[13px] text-muted-foreground",
8
+ className: "text-muted-foreground",
9
9
  children: subtitle
10
10
  })] });
11
11
  return /* @__PURE__ */ jsxs("div", {
@@ -7,7 +7,7 @@ import { useEffect, useRef, useState } from "react";
7
7
  import { ChevronsUpDown, LogOut } from "lucide-react";
8
8
  import { Fragment as Fragment$1, jsx, jsxs } from "react/jsx-runtime";
9
9
  //#region src/app-shell/profile-menu.tsx
10
- const menuRow = "flex min-h-11 w-full items-center gap-2.5 px-3 py-1.5 text-left text-[13px] text-muted-foreground hover:bg-muted md:min-h-0";
10
+ const menuRow = "flex min-h-11 w-full items-center gap-2.5 px-3 py-1.5 text-left text-muted-foreground hover:bg-muted md:min-h-0";
11
11
  /** The person at the bottom of the sidebar; the menu is fixed to the viewport so a narrow sidebar cannot clip it. */
12
12
  const ProfileMenu = ({ user, compact, open: controlled, items = [], onNavigate, onSignOut, organizations, roles, theme }) => {
13
13
  const activeRole = roles?.roles.find((role) => role.name === roles.active);
@@ -53,7 +53,7 @@ const ProfileMenu = ({ user, compact, open: controlled, items = [], onNavigate,
53
53
  }), !compact && /* @__PURE__ */ jsxs(Fragment$1, { children: [/* @__PURE__ */ jsxs("span", {
54
54
  className: "min-w-0 flex-1 leading-tight",
55
55
  children: [/* @__PURE__ */ jsx("span", {
56
- className: "block truncate text-[13px] font-medium",
56
+ className: "block truncate font-medium",
57
57
  children: user.name
58
58
  }), /* @__PURE__ */ jsx(Badge, {
59
59
  tone: user.roleTone,
@@ -73,7 +73,7 @@ const ProfileMenu = ({ user, compact, open: controlled, items = [], onNavigate,
73
73
  /* @__PURE__ */ jsxs("div", {
74
74
  className: "border-b px-3 pb-2 pt-1.5",
75
75
  children: [/* @__PURE__ */ jsx("div", {
76
- className: "text-[13px] font-medium",
76
+ className: "font-medium",
77
77
  children: user.name
78
78
  }), /* @__PURE__ */ jsx("div", {
79
79
  className: "truncate text-xs text-muted-foreground",
@@ -7,7 +7,7 @@ import { ChevronRight } from "lucide-react";
7
7
  import { jsx, jsxs } from "react/jsx-runtime";
8
8
  //#region src/app-shell/sidebar-group.tsx
9
9
  const row = {
10
- "text-large": "h-8 gap-2.5 px-2.5 text-[13px]",
10
+ "text-large": "h-8 gap-2.5 px-2.5",
11
11
  "text-small": "h-7 gap-2 px-2 text-xs"
12
12
  };
13
13
  /** Lines the records up under the entry's icon. */
@@ -10,7 +10,7 @@ const layout = {
10
10
  icon: "size-9 justify-center",
11
11
  "icon-label": "w-full flex-col gap-0.5 py-1.5 text-[10px]",
12
12
  "icon-tooltip": "size-9 justify-center",
13
- "icon-expand": "h-8 gap-3 px-3 text-[13px]"
13
+ "icon-expand": "h-8 gap-3 px-3"
14
14
  };
15
15
  const SidebarItem = ({ item, mode, active, onNavigate, className }) => {
16
16
  const Icon = item.icon;
@@ -62,11 +62,11 @@ const Sidebar = ({ mode, activeItem, user, workspace, forceExpanded, profileMenu
62
62
  theme
63
63
  }) : /* @__PURE__ */ jsxs(Fragment, { children: [theme && inline && /* @__PURE__ */ jsx(ThemeSwitch, {
64
64
  theme,
65
- className: "flex min-h-11 w-full items-center gap-2.5 whitespace-nowrap p-1.5 text-[13px] text-muted-foreground md:min-h-0"
65
+ className: "flex min-h-11 w-full items-center gap-2.5 whitespace-nowrap p-1.5 text-muted-foreground md:min-h-0"
66
66
  }), signIn && /* @__PURE__ */ jsxs(RouteLink, {
67
67
  to: signIn,
68
68
  "aria-label": "Sign in",
69
- className: "flex min-h-11 w-full items-center gap-2.5 rounded-md p-1.5 text-left text-[13px] font-medium text-muted-foreground hover:bg-muted hover:text-foreground md:min-h-0",
69
+ className: "flex min-h-11 w-full items-center gap-2.5 rounded-md p-1.5 text-left font-medium text-muted-foreground hover:bg-muted hover:text-foreground md:min-h-0",
70
70
  children: [/* @__PURE__ */ jsx(LogIn, { className: "size-4 shrink-0" }), inline && /* @__PURE__ */ jsx("span", {
71
71
  className: "whitespace-nowrap",
72
72
  children: "Sign in"
@@ -24,10 +24,7 @@ const PartView = ({ part, onAction }) => {
24
24
  actions: part.actions,
25
25
  onAction: (actionId) => onAction?.(part.id, actionId),
26
26
  children: [
27
- part.body && /* @__PURE__ */ jsx("p", {
28
- className: "text-[13px]",
29
- children: part.body
30
- }),
27
+ part.body && /* @__PURE__ */ jsx("p", { children: part.body }),
31
28
  part.code && /* @__PURE__ */ jsx("pre", {
32
29
  className: "overflow-x-auto rounded-md bg-surface px-2.5 py-2 font-mono text-[11px] whitespace-pre-wrap break-words",
33
30
  children: part.code
@@ -8,10 +8,7 @@ import { jsx } from "react/jsx-runtime";
8
8
  const Fallback = ({ part, note }) => part.fallback ? /* @__PURE__ */ jsx(ActionCard, {
9
9
  title: part.fallback.title,
10
10
  note,
11
- children: part.fallback.body && /* @__PURE__ */ jsx("p", {
12
- className: "text-[13px]",
13
- children: part.fallback.body
14
- })
11
+ children: part.fallback.body && /* @__PURE__ */ jsx("p", { children: part.fallback.body })
15
12
  }) : /* @__PURE__ */ jsx("p", {
16
13
  className: "text-xs text-muted-foreground",
17
14
  children: `${part.name}: ${note}`
@@ -130,13 +130,13 @@ const useAuthPage = (workspace, children) => {
130
130
  };
131
131
  switch (state.kind) {
132
132
  case "loading": return /* @__PURE__ */ jsxs("div", {
133
- className: "flex h-full min-h-48 items-center justify-center gap-2 text-[13px] text-muted-foreground",
133
+ className: "flex h-full min-h-48 items-center justify-center gap-2 text-muted-foreground",
134
134
  children: [/* @__PURE__ */ jsx(Spinner, {}), " Loading"]
135
135
  });
136
136
  case "error": return /* @__PURE__ */ jsxs("div", {
137
137
  className: "flex h-full min-h-48 flex-col items-center justify-center gap-3 p-8 text-center",
138
138
  children: [/* @__PURE__ */ jsxs("p", {
139
- className: "text-[13px] text-muted-foreground",
139
+ className: "text-muted-foreground",
140
140
  children: ["Cannot reach the server: ", state.message]
141
141
  }), /* @__PURE__ */ jsx(Button, {
142
142
  onClick: recheck,
@@ -15,7 +15,7 @@ const AuthLayout = ({ title, description, children }) => /* @__PURE__ */ jsx("di
15
15
  children: title
16
16
  }),
17
17
  description && /* @__PURE__ */ jsx("p", {
18
- className: "mt-1 text-[13px] text-muted-foreground",
18
+ className: "mt-1 text-muted-foreground",
19
19
  children: description
20
20
  })
21
21
  ]
@@ -16,7 +16,7 @@ const CodeForm = ({ title, description, explanation, submitLabel, onSubmit, onRe
16
16
  description,
17
17
  children: [
18
18
  /* @__PURE__ */ jsx("p", {
19
- className: "mb-4 text-[13px] text-muted-foreground",
19
+ className: "mb-4 text-muted-foreground",
20
20
  children: explanation
21
21
  }),
22
22
  notice && /* @__PURE__ */ jsx("p", {
@@ -32,7 +32,7 @@ const CodeForm = ({ title, description, explanation, submitLabel, onSubmit, onRe
32
32
  },
33
33
  children: [
34
34
  /* @__PURE__ */ jsxs("label", {
35
- className: "flex flex-col gap-1.5 text-[13px] font-medium",
35
+ className: "flex flex-col gap-1.5 font-medium",
36
36
  children: ["Code", /* @__PURE__ */ jsx(OtpInput, {
37
37
  name: "code",
38
38
  required: true,
@@ -16,7 +16,7 @@ const FirstRunPage = ({ command = createAdminCommand, onCheckAgain, busy }) => {
16
16
  description: "This Protobase has no users to sign in with.",
17
17
  children: [
18
18
  /* @__PURE__ */ jsx("p", {
19
- className: "text-[13px] text-muted-foreground",
19
+ className: "text-muted-foreground",
20
20
  children: "Run this in the terminal where Protobase runs, then reload. The first admin is created on the server, not in the browser, so nobody else can claim a fresh URL."
21
21
  }),
22
22
  /* @__PURE__ */ jsxs("div", {
@@ -11,7 +11,7 @@ const ForgotPasswordForm = ({ onSubmit, back, busy, error, sentTo }) => {
11
11
  if (sentTo) return /* @__PURE__ */ jsxs(AuthLayout, {
12
12
  title: "Check your email",
13
13
  children: [/* @__PURE__ */ jsxs("p", {
14
- className: "text-[13px] text-muted-foreground",
14
+ className: "text-muted-foreground",
15
15
  children: [
16
16
  "If ",
17
17
  /* @__PURE__ */ jsx("span", {
@@ -37,7 +37,7 @@ const ForgotPasswordForm = ({ onSubmit, back, busy, error, sentTo }) => {
37
37
  },
38
38
  children: [
39
39
  /* @__PURE__ */ jsxs("label", {
40
- className: "flex flex-col gap-1.5 text-[13px] font-medium",
40
+ className: "flex flex-col gap-1.5 font-medium",
41
41
  children: ["Email", /* @__PURE__ */ jsx(Input, {
42
42
  type: "email",
43
43
  name: "email",
@@ -13,7 +13,7 @@ const ProviderRedirect = ({ name, workspace }) => /* @__PURE__ */ jsx(AuthLayout
13
13
  description: workspace,
14
14
  children: /* @__PURE__ */ jsxs("p", {
15
15
  role: "status",
16
- className: "flex items-center justify-center gap-2 text-[13px] text-muted-foreground",
16
+ className: "flex items-center justify-center gap-2 text-muted-foreground",
17
17
  children: [
18
18
  /* @__PURE__ */ jsx(Spinner, {}),
19
19
  " Taking you to ",
@@ -10,7 +10,7 @@ const ResetPasswordForm = ({ onSubmit, invalidLink, onRequestNewLink, onBack, bu
10
10
  if (invalidLink) return /* @__PURE__ */ jsxs(AuthLayout, {
11
11
  title: "This link no longer works",
12
12
  children: [/* @__PURE__ */ jsx("p", {
13
- className: "text-[13px] text-muted-foreground",
13
+ className: "text-muted-foreground",
14
14
  children: "A reset link works once, for a limited time. Ask for a new one to choose your password."
15
15
  }), /* @__PURE__ */ jsxs("div", {
16
16
  className: "mt-4 flex flex-col gap-2",
@@ -40,7 +40,7 @@ const ResetPasswordForm = ({ onSubmit, invalidLink, onRequestNewLink, onBack, bu
40
40
  },
41
41
  children: [
42
42
  /* @__PURE__ */ jsxs("label", {
43
- className: "flex flex-col gap-1.5 text-[13px] font-medium",
43
+ className: "flex flex-col gap-1.5 font-medium",
44
44
  children: ["New password", /* @__PURE__ */ jsx(Input, {
45
45
  type: "password",
46
46
  name: "new-password",
@@ -55,7 +55,7 @@ const ResetPasswordForm = ({ onSubmit, invalidLink, onRequestNewLink, onBack, bu
55
55
  })]
56
56
  }),
57
57
  /* @__PURE__ */ jsxs("label", {
58
- className: "flex flex-col gap-1.5 text-[13px] font-medium",
58
+ className: "flex flex-col gap-1.5 font-medium",
59
59
  children: ["Repeat new password", /* @__PURE__ */ jsx(Input, {
60
60
  type: "password",
61
61
  name: "repeat-password",
@@ -16,7 +16,7 @@ const SetupRequiredForm = ({ step, twoFactor, onAddPasskey, busy, error, onSignO
16
16
  className: "flex flex-col gap-4",
17
17
  children: [
18
18
  /* @__PURE__ */ jsx("p", {
19
- className: "text-[13px] text-muted-foreground",
19
+ className: "text-muted-foreground",
20
20
  children: "A passkey signs you in with Face ID, Touch ID, Windows Hello, your phone or a security key. Your browser asks which one to use."
21
21
  }),
22
22
  error && /* @__PURE__ */ jsx("p", {
@@ -35,7 +35,7 @@ const SetupRequiredForm = ({ step, twoFactor, onAddPasskey, busy, error, onSignO
35
35
  }), /* @__PURE__ */ jsx("button", {
36
36
  type: "button",
37
37
  onClick: onSignOut,
38
- className: "mt-4 w-full text-center text-[13px] font-medium text-muted-foreground hover:underline",
38
+ className: "mt-4 w-full text-center font-medium text-muted-foreground hover:underline",
39
39
  children: "Sign out"
40
40
  })]
41
41
  });
@@ -28,7 +28,7 @@ const SetupRequiredPage = ({ missing }) => {
28
28
  }
29
29
  };
30
30
  if (!methods && !error) return /* @__PURE__ */ jsxs("div", {
31
- className: "flex h-full min-h-48 items-center justify-center gap-2 text-[13px] text-muted-foreground",
31
+ className: "flex h-full min-h-48 items-center justify-center gap-2 text-muted-foreground",
32
32
  children: [/* @__PURE__ */ jsx(Spinner, {}), " Loading"]
33
33
  });
34
34
  return /* @__PURE__ */ jsx(SetupRequiredForm, {