@emdash-cms/admin 0.5.0 → 0.6.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.
Files changed (67) hide show
  1. package/dist/{LocaleDirectionProvider-DO7M3Tgi.js → LocaleDirectionProvider-BS3RseHk.js} +43 -11
  2. package/dist/LocaleDirectionProvider-BS3RseHk.js.map +1 -0
  3. package/dist/{config-Jgetw4hr.d.ts → config-NP8UHbds.d.ts} +1 -1
  4. package/dist/{config-Jgetw4hr.d.ts.map → config-NP8UHbds.d.ts.map} +1 -1
  5. package/dist/index.d.ts +2 -2
  6. package/dist/index.d.ts.map +1 -1
  7. package/dist/index.js +879 -628
  8. package/dist/index.js.map +1 -1
  9. package/dist/locales/ar/messages.mjs +1 -1
  10. package/dist/locales/de/messages.mjs +1 -1
  11. package/dist/locales/en/messages.mjs +1 -1
  12. package/dist/locales/es-419/messages.mjs +1 -0
  13. package/dist/locales/eu/messages.mjs +1 -1
  14. package/dist/locales/fr/messages.mjs +1 -1
  15. package/dist/locales/index.d.ts +1 -1
  16. package/dist/locales/index.js +1 -1
  17. package/dist/locales/ja/messages.mjs +1 -1
  18. package/dist/locales/ko/messages.mjs +1 -0
  19. package/dist/locales/pseudo/messages.mjs +1 -1
  20. package/dist/locales/pt-BR/messages.mjs +1 -1
  21. package/dist/locales/zh-CN/messages.mjs +1 -1
  22. package/dist/locales/zh-TW/messages.mjs +1 -0
  23. package/dist/messages-57qx1FXa.js +6 -0
  24. package/dist/messages-57qx1FXa.js.map +1 -0
  25. package/dist/messages-8uPA5VDB.js +6 -0
  26. package/dist/messages-8uPA5VDB.js.map +1 -0
  27. package/dist/messages-B60-1lfB.js +6 -0
  28. package/dist/messages-B60-1lfB.js.map +1 -0
  29. package/dist/messages-Bb5acOxw.js +6 -0
  30. package/dist/messages-Bb5acOxw.js.map +1 -0
  31. package/dist/messages-Bc3iE3Xx.js +6 -0
  32. package/dist/messages-Bc3iE3Xx.js.map +1 -0
  33. package/dist/messages-BxPoHitx.js +6 -0
  34. package/dist/messages-BxPoHitx.js.map +1 -0
  35. package/dist/messages-CAhWq719.js +6 -0
  36. package/dist/messages-CAhWq719.js.map +1 -0
  37. package/dist/messages-CLJeZfc0.js +6 -0
  38. package/dist/messages-CLJeZfc0.js.map +1 -0
  39. package/dist/messages-CjWV7b4D.js +6 -0
  40. package/dist/messages-CjWV7b4D.js.map +1 -0
  41. package/dist/messages-DPxhCxJU.js +6 -0
  42. package/dist/messages-DPxhCxJU.js.map +1 -0
  43. package/dist/messages-DYWnQ-qc.js +6 -0
  44. package/dist/messages-DYWnQ-qc.js.map +1 -0
  45. package/dist/messages-J31OZzeY.js +6 -0
  46. package/dist/messages-J31OZzeY.js.map +1 -0
  47. package/dist/styles.css +1 -1
  48. package/package.json +2 -2
  49. package/dist/LocaleDirectionProvider-DO7M3Tgi.js.map +0 -1
  50. package/dist/messages-03AQQSlE.js +0 -6
  51. package/dist/messages-03AQQSlE.js.map +0 -1
  52. package/dist/messages-BMkWfYDe.js +0 -6
  53. package/dist/messages-BMkWfYDe.js.map +0 -1
  54. package/dist/messages-CsGdD1lJ.js +0 -6
  55. package/dist/messages-CsGdD1lJ.js.map +0 -1
  56. package/dist/messages-CwBBghBM.js +0 -6
  57. package/dist/messages-CwBBghBM.js.map +0 -1
  58. package/dist/messages-CxEI1suK.js +0 -6
  59. package/dist/messages-CxEI1suK.js.map +0 -1
  60. package/dist/messages-D70eWqXP.js +0 -6
  61. package/dist/messages-D70eWqXP.js.map +0 -1
  62. package/dist/messages-DKQntaHs.js +0 -6
  63. package/dist/messages-DKQntaHs.js.map +0 -1
  64. package/dist/messages-DgIBjYba.js +0 -6
  65. package/dist/messages-DgIBjYba.js.map +0 -1
  66. package/dist/messages-DhLA1X_1.js +0 -6
  67. package/dist/messages-DhLA1X_1.js.map +0 -1
package/dist/index.js CHANGED
@@ -1,5 +1,5 @@
1
1
  import { c as fetchManifest, i as fetchPlugins, l as parseApiResponse, n as enablePlugin, o as API_BASE, r as fetchPlugin, s as apiFetch, t as disablePlugin, u as throwResponseError } from "./plugins-XhZqfegd.js";
2
- import { a as SUPPORTED_LOCALES, i as DEFAULT_LOCALE, l as resolveLocale, n as useLocale, o as SUPPORTED_LOCALE_CODES, t as LocaleDirectionProvider } from "./LocaleDirectionProvider-DO7M3Tgi.js";
2
+ import { a as SUPPORTED_LOCALES, i as DEFAULT_LOCALE, l as resolveLocale, n as useLocale, o as SUPPORTED_LOCALE_CODES, t as LocaleDirectionProvider } from "./LocaleDirectionProvider-BS3RseHk.js";
3
3
  import "./locales/index.js";
4
4
  import { Badge, Button, Checkbox, CommandPalette, Dialog, Input, InputArea, Label, LinkButton, Loader, Popover, Select, Sidebar as KumoSidebar, Switch, Tabs, Toast, Toasty, Tooltip, buttonVariants, useSidebar } from "@cloudflare/kumo";
5
5
  import { i18n } from "@lingui/core";
@@ -9,6 +9,7 @@ import { Link, Link as Link$1, Outlet, RouterProvider, createRootRouteWithContex
9
9
  import * as React from "react";
10
10
  import { createContext, useCallback, useContext, useEffect, useState } from "react";
11
11
  import { Fragment, jsx, jsxs } from "react/jsx-runtime";
12
+ import { Dialog as Dialog$1 } from "@cloudflare/kumo/primitives";
12
13
  import { ArrowCounterClockwise, ArrowLeft, ArrowRight, ArrowSquareOut, ArrowUUpLeft, ArrowUUpRight, ArrowsClockwise, ArrowsInSimple, ArrowsLeftRight, ArrowsOutSimple, BracketsCurly, Calendar, CalendarBlank, CaretDown, CaretLeft, CaretRight, CaretUp, ChatCircle, Check, CheckCircle, CircleDashed, CircleNotch, ClockCounterClockwise, Cloud, Code, CodeBlock, Copy, Cube, Database, DeviceMobile, DotsSixVertical, DownloadSimple, Envelope, EnvelopeSimple, Eye, EyeSlash, File, FileArrowDown, FileText, FloppyDisk, FolderOpen, Gear, GithubLogo, Globe, GlobeSimple, GridFour, HardDrive, Hash, Image as Image$1, ImageSquare, Info, Key, Link as Link$2, LinkBreak, LinkSimple, List, ListBullets, ListChecks, ListNumbers, MagnifyingGlass, Minus, Monitor, Moon, Palette, PaperPlaneTilt, Paragraph, Pencil, PencilSimple, PlugsConnected, Plus, Prohibit, PuzzlePiece, Quotes, Rows, Ruler, ShareNetwork, Shield, ShieldCheck, ShieldWarning, SignOut, SlidersHorizontal, Sparkle, SquaresFour, Stack, Storefront, Sun, TextAlignCenter, TextAlignLeft, TextAlignRight, TextB, TextHOne, TextHThree, TextHTwo, TextItalic, TextStrikethrough, TextT, TextUnderline, ToggleLeft, Trash, Upload, User, UserCircle, UserPlus, Users, Warning, WarningCircle, WebhooksLogo, X, YoutubeLogo } from "@phosphor-icons/react";
13
14
  import { clsx } from "clsx";
14
15
  import { twMerge } from "tailwind-merge";
@@ -290,7 +291,7 @@ function CommentDetail({ comment, onClose, onStatusChange, onDelete, isAdmin, is
290
291
  onClick: onClose,
291
292
  "aria-hidden": "true"
292
293
  }), /* @__PURE__ */ jsxs("div", {
293
- className: "fixed inset-y-0 right-0 z-50 w-full max-w-lg overflow-y-auto bg-kumo-base border-l shadow-lg",
294
+ className: "fixed inset-y-0 end-0 z-50 w-full max-w-lg overflow-y-auto bg-kumo-base border-s shadow-lg",
294
295
  children: [
295
296
  /* @__PURE__ */ jsxs("div", {
296
297
  className: "flex items-center justify-between border-b px-6 py-4",
@@ -614,7 +615,7 @@ function CommentInbox({ comments, counts, isLoading, nextCursor, collections, ac
614
615
  className: "flex items-center gap-3 flex-wrap",
615
616
  children: [/* @__PURE__ */ jsxs("div", {
616
617
  className: "relative max-w-xs flex-1 min-w-[200px]",
617
- children: [/* @__PURE__ */ jsx(MagnifyingGlass, { className: "absolute left-3 top-1/2 -translate-y-1/2 h-4 w-4 text-kumo-subtle" }), /* @__PURE__ */ jsx(Input, {
618
+ children: [/* @__PURE__ */ jsx(MagnifyingGlass, { className: "absolute start-3 top-1/2 -translate-y-1/2 h-4 w-4 text-kumo-subtle" }), /* @__PURE__ */ jsx(Input, {
618
619
  type: "search",
619
620
  placeholder: _t({
620
621
  id: "egS4fF",
@@ -626,7 +627,7 @@ function CommentInbox({ comments, counts, isLoading, nextCursor, collections, ac
626
627
  }),
627
628
  value: searchQuery,
628
629
  onChange: (e) => onSearchChange(e.target.value),
629
- className: "pl-9"
630
+ className: "ps-9"
630
631
  })]
631
632
  }), Object.keys(collections).length > 1 && /* @__PURE__ */ jsx("div", {
632
633
  className: "w-48",
@@ -706,7 +707,7 @@ function CommentInbox({ comments, counts, isLoading, nextCursor, collections, ac
706
707
  values: { 0: selected.size }
707
708
  })
708
709
  }), /* @__PURE__ */ jsxs("div", {
709
- className: "flex gap-2 ml-auto",
710
+ className: "flex gap-2 ms-auto",
710
711
  children: [
711
712
  activeStatus !== "approved" && /* @__PURE__ */ jsx(Button, {
712
713
  size: "sm",
@@ -771,7 +772,7 @@ function CommentInbox({ comments, counts, isLoading, nextCursor, collections, ac
771
772
  }),
772
773
  /* @__PURE__ */ jsx("th", {
773
774
  scope: "col",
774
- className: "px-4 py-3 text-left text-sm font-medium",
775
+ className: "px-4 py-3 text-start text-sm font-medium",
775
776
  children: _t({
776
777
  id: "VbeIOx",
777
778
  message: "Author"
@@ -779,7 +780,7 @@ function CommentInbox({ comments, counts, isLoading, nextCursor, collections, ac
779
780
  }),
780
781
  /* @__PURE__ */ jsx("th", {
781
782
  scope: "col",
782
- className: "px-4 py-3 text-left text-sm font-medium",
783
+ className: "px-4 py-3 text-start text-sm font-medium",
783
784
  children: _t({
784
785
  id: "NBdIgR",
785
786
  message: "Comment"
@@ -787,7 +788,7 @@ function CommentInbox({ comments, counts, isLoading, nextCursor, collections, ac
787
788
  }),
788
789
  /* @__PURE__ */ jsx("th", {
789
790
  scope: "col",
790
- className: "px-4 py-3 text-left text-sm font-medium",
791
+ className: "px-4 py-3 text-start text-sm font-medium",
791
792
  children: _t({
792
793
  id: "4b3oEV",
793
794
  message: "Content"
@@ -795,7 +796,7 @@ function CommentInbox({ comments, counts, isLoading, nextCursor, collections, ac
795
796
  }),
796
797
  /* @__PURE__ */ jsx("th", {
797
798
  scope: "col",
798
- className: "px-4 py-3 text-left text-sm font-medium",
799
+ className: "px-4 py-3 text-start text-sm font-medium",
799
800
  children: _t({
800
801
  id: "mYGY3B",
801
802
  message: "Date"
@@ -803,7 +804,7 @@ function CommentInbox({ comments, counts, isLoading, nextCursor, collections, ac
803
804
  }),
804
805
  /* @__PURE__ */ jsx("th", {
805
806
  scope: "col",
806
- className: "px-4 py-3 text-right text-sm font-medium",
807
+ className: "px-4 py-3 text-end text-sm font-medium",
807
808
  children: _t({
808
809
  id: "7L01XJ",
809
810
  message: "Actions"
@@ -961,7 +962,7 @@ function CommentRow({ comment, isSelected, onToggle, onRowClick, onStatusChange,
961
962
  children: /* @__PURE__ */ jsxs("button", {
962
963
  type: "button",
963
964
  onClick: onRowClick,
964
- className: "text-left",
965
+ className: "text-start",
965
966
  children: [/* @__PURE__ */ jsx("div", {
966
967
  className: "font-medium text-sm",
967
968
  children: comment.authorName
@@ -976,7 +977,7 @@ function CommentRow({ comment, isSelected, onToggle, onRowClick, onStatusChange,
976
977
  children: /* @__PURE__ */ jsx("button", {
977
978
  type: "button",
978
979
  onClick: onRowClick,
979
- className: "text-left text-sm text-kumo-subtle hover:text-kumo-default line-clamp-2",
980
+ className: "text-start text-sm text-kumo-subtle hover:text-kumo-default line-clamp-2",
980
981
  children: excerpt
981
982
  })
982
983
  }),
@@ -995,7 +996,7 @@ function CommentRow({ comment, isSelected, onToggle, onRowClick, onStatusChange,
995
996
  children: date.toLocaleDateString()
996
997
  }),
997
998
  /* @__PURE__ */ jsx("td", {
998
- className: "px-4 py-3 text-right",
999
+ className: "px-4 py-3 text-end",
999
1000
  children: /* @__PURE__ */ jsxs("div", {
1000
1001
  className: "flex items-center justify-end gap-1",
1001
1002
  children: [
@@ -2746,10 +2747,10 @@ function BlockKitFieldElement({ element, value, onChange }) {
2746
2747
  */
2747
2748
  function getIndentClass(level) {
2748
2749
  switch (level) {
2749
- case 1: return "pl-0";
2750
- case 2: return "pl-4";
2751
- case 3: return "pl-8";
2752
- default: return "pl-0";
2750
+ case 1: return "ps-0";
2751
+ case 2: return "ps-4";
2752
+ case 3: return "ps-8";
2753
+ default: return "ps-0";
2753
2754
  }
2754
2755
  }
2755
2756
  function getTextClass(level) {
@@ -2859,7 +2860,7 @@ function DocumentOutline({ editor, className }) {
2859
2860
  return /* @__PURE__ */ jsx("button", {
2860
2861
  type: "button",
2861
2862
  onClick: () => handleHeadingClick(heading),
2862
- className: cn("w-full text-left px-2 py-1 text-sm rounded transition-colors", "hover:bg-kumo-tint/50 cursor-pointer", "truncate", getIndentClass(heading.level), getTextClass(heading.level), isCurrent && "bg-kumo-tint text-kumo-default"),
2863
+ className: cn("w-full text-start px-2 py-1 text-sm rounded transition-colors", "hover:bg-kumo-tint/50 cursor-pointer", "truncate", getIndentClass(heading.level), getTextClass(heading.level), isCurrent && "bg-kumo-tint text-kumo-default"),
2863
2864
  title: heading.text,
2864
2865
  children: heading.text
2865
2866
  }, heading.key);
@@ -2986,7 +2987,7 @@ function RepeaterField({ label, id, value, onChange, subFields, minItems = 0, ma
2986
2987
  htmlFor: id,
2987
2988
  className: "text-sm font-medium",
2988
2989
  children: [label, items.length > 0 && /* @__PURE__ */ jsx("span", {
2989
- className: "ml-2 text-kumo-subtle font-normal",
2990
+ className: "ms-2 text-kumo-subtle font-normal",
2990
2991
  children: i18n._({
2991
2992
  id: "JcH6Wc",
2992
2993
  message: "{0, plural, one {(# item)} other {(# items)}}",
@@ -3537,7 +3538,7 @@ function MediaPickerModal({ open, onOpenChange, onSelect, mimeTypeFilter = "imag
3537
3538
  id: "yz7wBu",
3538
3539
  message: "Close"
3539
3540
  }),
3540
- className: "absolute right-4 top-4",
3541
+ className: "absolute end-4 top-4",
3541
3542
  children: [/* @__PURE__ */ jsx(X, { className: "h-4 w-4" }), /* @__PURE__ */ jsx("span", {
3542
3543
  className: "sr-only",
3543
3544
  children: _t({
@@ -3559,7 +3560,7 @@ function MediaPickerModal({ open, onOpenChange, onSelect, mimeTypeFilter = "imag
3559
3560
  className: "flex gap-2 mt-1.5",
3560
3561
  children: [/* @__PURE__ */ jsxs("div", {
3561
3562
  className: "flex-1 relative",
3562
- children: [/* @__PURE__ */ jsx(Globe, { className: "absolute left-3 top-1/2 -translate-y-1/2 h-4 w-4 text-kumo-subtle" }), /* @__PURE__ */ jsx(Input, {
3563
+ children: [/* @__PURE__ */ jsx(Globe, { className: "absolute start-3 top-1/2 -translate-y-1/2 h-4 w-4 text-kumo-subtle" }), /* @__PURE__ */ jsx(Input, {
3563
3564
  type: "url",
3564
3565
  placeholder: "https://example.com/image.jpg",
3565
3566
  "aria-label": _t({
@@ -3572,7 +3573,7 @@ function MediaPickerModal({ open, onOpenChange, onSelect, mimeTypeFilter = "imag
3572
3573
  setUrlError(null);
3573
3574
  },
3574
3575
  onKeyDown: handleUrlKeyDown,
3575
- className: "pl-9"
3576
+ className: "ps-9"
3576
3577
  })]
3577
3578
  }), /* @__PURE__ */ jsx(Button, {
3578
3579
  onClick: handleUrlSubmit,
@@ -3630,7 +3631,7 @@ function MediaPickerModal({ open, onOpenChange, onSelect, mimeTypeFilter = "imag
3630
3631
  className: "flex items-center justify-between pb-3 gap-4",
3631
3632
  children: [canSearch ? /* @__PURE__ */ jsxs("div", {
3632
3633
  className: "relative flex-1 max-w-xs",
3633
- children: [/* @__PURE__ */ jsx(MagnifyingGlass, { className: "absolute left-3 top-1/2 -translate-y-1/2 h-4 w-4 text-kumo-subtle" }), /* @__PURE__ */ jsx(Input, {
3634
+ children: [/* @__PURE__ */ jsx(MagnifyingGlass, { className: "absolute start-3 top-1/2 -translate-y-1/2 h-4 w-4 text-kumo-subtle" }), /* @__PURE__ */ jsx(Input, {
3634
3635
  type: "search",
3635
3636
  placeholder: _t({
3636
3637
  id: "YIix5Y",
@@ -3642,7 +3643,7 @@ function MediaPickerModal({ open, onOpenChange, onSelect, mimeTypeFilter = "imag
3642
3643
  }),
3643
3644
  value: searchQuery,
3644
3645
  onChange: (e) => setSearchQuery(e.target.value),
3645
- className: "pl-9"
3646
+ className: "ps-9"
3646
3647
  })]
3647
3648
  }) : /* @__PURE__ */ jsx("p", {
3648
3649
  className: "text-sm text-kumo-subtle",
@@ -3782,7 +3783,7 @@ function MediaPickerModal({ open, onOpenChange, onSelect, mimeTypeFilter = "imag
3782
3783
  " ",
3783
3784
  /* @__PURE__ */ jsx("strong", { children: selectedItem.item.filename }),
3784
3785
  selectedItem.providerId !== "local" && /* @__PURE__ */ jsx("span", {
3785
- className: "ml-2 text-xs",
3786
+ className: "ms-2 text-xs",
3786
3787
  children: _t({
3787
3788
  id: "qjriNt",
3788
3789
  message: "(from {0})",
@@ -3869,7 +3870,7 @@ function MediaPickerItem({ item, selected, onClick, onDoubleClick, onDimensionsD
3869
3870
  })
3870
3871
  }),
3871
3872
  /* @__PURE__ */ jsx("div", {
3872
- className: "absolute bottom-0 left-0 right-0 bg-gradient-to-t from-black/60 to-transparent p-2",
3873
+ className: "absolute bottom-0 start-0 end-0 bg-gradient-to-t from-black/60 to-transparent p-2",
3873
3874
  "aria-hidden": "true",
3874
3875
  children: /* @__PURE__ */ jsx("p", {
3875
3876
  className: "text-xs text-white truncate",
@@ -3932,7 +3933,7 @@ function ProviderMediaItem({ item, selected, onClick, onDoubleClick, onDimension
3932
3933
  })
3933
3934
  }),
3934
3935
  /* @__PURE__ */ jsx("div", {
3935
- className: "absolute bottom-0 left-0 right-0 bg-gradient-to-t from-black/60 to-transparent p-2",
3936
+ className: "absolute bottom-0 start-0 end-0 bg-gradient-to-t from-black/60 to-transparent p-2",
3936
3937
  "aria-hidden": "true",
3937
3938
  children: /* @__PURE__ */ jsx("p", {
3938
3939
  className: "text-xs text-white truncate",
@@ -4069,7 +4070,7 @@ function ImageDetailPanel({ attributes, onUpdate, onReplace, onDelete, onClose,
4069
4070
  })
4070
4071
  })] });
4071
4072
  if (inline) return /* @__PURE__ */ jsxs("div", {
4072
- className: "rounded-lg border bg-kumo-base flex flex-col animate-in fade-in duration-200",
4073
+ className: "rounded-lg border bg-kumo-base flex flex-col",
4073
4074
  children: [
4074
4075
  /* @__PURE__ */ jsxs("div", {
4075
4076
  className: "flex items-center justify-between p-4 border-b",
@@ -4320,7 +4321,7 @@ function ImageDetailPanel({ attributes, onUpdate, onReplace, onDelete, onClose,
4320
4321
  ]
4321
4322
  });
4322
4323
  return /* @__PURE__ */ jsxs("div", {
4323
- className: "fixed inset-y-0 right-0 w-96 bg-kumo-base border-l shadow-xl z-50 flex flex-col animate-in slide-in-from-right duration-200",
4324
+ className: "fixed inset-y-0 end-0 w-96 bg-kumo-base border-s shadow-xl z-50 flex flex-col",
4324
4325
  children: [
4325
4326
  /* @__PURE__ */ jsxs("div", {
4326
4327
  className: "flex items-center justify-between border-b p-4",
@@ -5051,14 +5052,14 @@ function BlockMenu({ editor, anchorElement, isOpen, onClose }) {
5051
5052
  children: [
5052
5053
  /* @__PURE__ */ jsxs("button", {
5053
5054
  type: "button",
5054
- className: "flex items-center gap-2 w-full px-3 py-2 text-sm hover:bg-kumo-tint text-left",
5055
+ className: "flex items-center gap-2 w-full px-3 py-2 text-sm hover:bg-kumo-tint text-start",
5055
5056
  onClick: () => setShowTransforms(false),
5056
5057
  children: [/* @__PURE__ */ jsx(CaretRight, { className: "h-4 w-4 rotate-180" }), /* @__PURE__ */ jsx("span", { children: "Back" })]
5057
5058
  }),
5058
5059
  /* @__PURE__ */ jsx("div", { className: "h-px bg-kumo-line my-1" }),
5059
5060
  blockTransforms.map((transform) => /* @__PURE__ */ jsxs("button", {
5060
5061
  type: "button",
5061
- className: "flex items-center gap-2 w-full px-3 py-2 text-sm hover:bg-kumo-tint text-left",
5062
+ className: "flex items-center gap-2 w-full px-3 py-2 text-sm hover:bg-kumo-tint text-start",
5062
5063
  onClick: () => handleTransform(transform),
5063
5064
  children: [/* @__PURE__ */ jsx(transform.icon, { className: "h-4 w-4 text-kumo-subtle" }), /* @__PURE__ */ jsx("span", { children: _t(transform.label) })]
5064
5065
  }, transform.id))
@@ -5068,7 +5069,7 @@ function BlockMenu({ editor, anchorElement, isOpen, onClose }) {
5068
5069
  children: [
5069
5070
  /* @__PURE__ */ jsxs("button", {
5070
5071
  type: "button",
5071
- className: "flex items-center justify-between w-full px-3 py-2 text-sm hover:bg-kumo-tint text-left",
5072
+ className: "flex items-center justify-between w-full px-3 py-2 text-sm hover:bg-kumo-tint text-start",
5072
5073
  onClick: () => setShowTransforms(true),
5073
5074
  children: [/* @__PURE__ */ jsxs("span", {
5074
5075
  className: "flex items-center gap-2",
@@ -5077,14 +5078,14 @@ function BlockMenu({ editor, anchorElement, isOpen, onClose }) {
5077
5078
  }),
5078
5079
  /* @__PURE__ */ jsxs("button", {
5079
5080
  type: "button",
5080
- className: "flex items-center gap-2 w-full px-3 py-2 text-sm hover:bg-kumo-tint text-left",
5081
+ className: "flex items-center gap-2 w-full px-3 py-2 text-sm hover:bg-kumo-tint text-start",
5081
5082
  onClick: handleDuplicate,
5082
5083
  children: [/* @__PURE__ */ jsx(Copy, { className: "h-4 w-4 text-kumo-subtle" }), /* @__PURE__ */ jsx("span", { children: "Duplicate" })]
5083
5084
  }),
5084
5085
  /* @__PURE__ */ jsx("div", { className: "h-px bg-kumo-line my-1" }),
5085
5086
  /* @__PURE__ */ jsxs("button", {
5086
5087
  type: "button",
5087
- className: "flex items-center gap-2 w-full px-3 py-2 text-sm hover:bg-kumo-tint text-left text-kumo-danger",
5088
+ className: "flex items-center gap-2 w-full px-3 py-2 text-sm hover:bg-kumo-tint text-start text-kumo-danger",
5088
5089
  onClick: handleDelete,
5089
5090
  children: [/* @__PURE__ */ jsx(Trash, { className: "h-4 w-4" }), /* @__PURE__ */ jsx("span", { children: "Delete" })]
5090
5091
  })
@@ -5248,7 +5249,7 @@ function ImageNodeView({ node, updateAttributes, selected, deleteNode, editor })
5248
5249
  draggable: false
5249
5250
  }),
5250
5251
  selected && /* @__PURE__ */ jsxs("div", {
5251
- className: "absolute top-2 right-2 flex gap-1 opacity-0 group-hover:opacity-100 transition-opacity",
5252
+ className: "absolute top-2 end-2 flex gap-1 opacity-0 group-hover:opacity-100 transition-opacity",
5252
5253
  children: [
5253
5254
  /* @__PURE__ */ jsx(Button, {
5254
5255
  type: "button",
@@ -5286,7 +5287,7 @@ function ImageNodeView({ node, updateAttributes, selected, deleteNode, editor })
5286
5287
  ]
5287
5288
  }),
5288
5289
  isEditingAlt && /* @__PURE__ */ jsxs("div", {
5289
- className: "absolute bottom-0 left-0 right-0 bg-kumo-base/95 backdrop-blur p-3 rounded-b-lg border-t",
5290
+ className: "absolute bottom-0 start-0 end-0 bg-kumo-base/95 backdrop-blur p-3 rounded-b-lg border-t",
5290
5291
  children: [/* @__PURE__ */ jsx("label", {
5291
5292
  className: "text-xs font-medium text-kumo-subtle mb-1 block",
5292
5293
  children: "Alt text"
@@ -5589,7 +5590,7 @@ function PluginBlockNodeView({ node, updateAttributes, selected, deleteNode, edi
5589
5590
  children: /* @__PURE__ */ jsxs("div", {
5590
5591
  className: "relative group",
5591
5592
  children: [/* @__PURE__ */ jsx("div", {
5592
- className: cn("absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-opacity cursor-grab active:cursor-grabbing", selected && "opacity-100"),
5593
+ className: cn("absolute -start-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-opacity cursor-grab active:cursor-grabbing", selected && "opacity-100"),
5593
5594
  "data-drag-handle": true,
5594
5595
  children: /* @__PURE__ */ jsx(DotsSixVertical, { className: "h-5 w-5 text-kumo-subtle/50" })
5595
5596
  }), /* @__PURE__ */ jsxs("div", {
@@ -5816,7 +5817,7 @@ function SectionPickerModal({ open, onOpenChange, onSelect }) {
5816
5817
  id: "yz7wBu",
5817
5818
  message: "Close"
5818
5819
  }),
5819
- className: "absolute right-4 top-4",
5820
+ className: "absolute end-4 top-4",
5820
5821
  children: [/* @__PURE__ */ jsx(X, { className: "h-4 w-4" }), /* @__PURE__ */ jsx("span", {
5821
5822
  className: "sr-only",
5822
5823
  children: _t({
@@ -5831,14 +5832,14 @@ function SectionPickerModal({ open, onOpenChange, onSelect }) {
5831
5832
  className: "flex items-center gap-4 py-4 border-b",
5832
5833
  children: /* @__PURE__ */ jsxs("div", {
5833
5834
  className: "relative flex-1",
5834
- children: [/* @__PURE__ */ jsx(MagnifyingGlass, { className: "absolute left-3 top-1/2 -translate-y-1/2 h-4 w-4 text-kumo-subtle" }), /* @__PURE__ */ jsx(Input, {
5835
+ children: [/* @__PURE__ */ jsx(MagnifyingGlass, { className: "absolute start-3 top-1/2 -translate-y-1/2 h-4 w-4 text-kumo-subtle" }), /* @__PURE__ */ jsx(Input, {
5835
5836
  placeholder: _t({
5836
5837
  id: "qPx4oA",
5837
5838
  message: "Search sections..."
5838
5839
  }),
5839
5840
  value: searchQuery,
5840
5841
  onChange: (e) => setSearchQuery(e.target.value),
5841
- className: "pl-10",
5842
+ className: "ps-10",
5842
5843
  autoFocus: true
5843
5844
  })]
5844
5845
  })
@@ -5916,7 +5917,7 @@ function SectionCard$1({ section, onSelect }) {
5916
5917
  return /* @__PURE__ */ jsxs("button", {
5917
5918
  type: "button",
5918
5919
  onClick: onSelect,
5919
- className: cn("text-left rounded-lg border bg-kumo-base overflow-hidden transition-colors", "hover:border-kumo-brand hover:bg-kumo-tint/50", "focus:outline-none focus:ring-2 focus:ring-kumo-ring focus:ring-offset-2"),
5920
+ className: cn("text-start rounded-lg border bg-kumo-base overflow-hidden transition-colors", "hover:border-kumo-brand hover:bg-kumo-tint/50", "focus:outline-none focus:ring-2 focus:ring-kumo-ring focus:ring-offset-2"),
5920
5921
  children: [/* @__PURE__ */ jsx("div", {
5921
5922
  className: "aspect-video bg-kumo-tint flex items-center justify-center",
5922
5923
  children: section.previewUrl ? /* @__PURE__ */ jsx("img", {
@@ -6613,7 +6614,7 @@ function SlashCommandMenu({ state, onCommand, onClose: _onClose, setSelectedInde
6613
6614
  }) : state.items.map((item, index) => /* @__PURE__ */ jsxs("button", {
6614
6615
  type: "button",
6615
6616
  "data-index": index,
6616
- className: cn("flex items-center gap-3 w-full px-3 py-2 text-sm rounded text-left", index === state.selectedIndex ? "bg-kumo-tint text-kumo-default" : "hover:bg-kumo-tint/50"),
6617
+ className: cn("flex items-center gap-3 w-full px-3 py-2 text-sm rounded text-start", index === state.selectedIndex ? "bg-kumo-tint text-kumo-default" : "hover:bg-kumo-tint/50"),
6617
6618
  onClick: () => onCommand(item),
6618
6619
  onMouseEnter: () => setSelectedIndex(index),
6619
6620
  children: [/* @__PURE__ */ jsx(item.icon, { className: "h-4 w-4 text-kumo-subtle flex-shrink-0" }), /* @__PURE__ */ jsxs("div", {
@@ -6683,7 +6684,7 @@ function PluginBlockModal({ block, initialValues, onClose, onInsert }) {
6683
6684
  variant: "ghost",
6684
6685
  shape: "square",
6685
6686
  "aria-label": "Close",
6686
- className: "absolute right-4 top-4",
6687
+ className: "absolute end-4 top-4",
6687
6688
  children: [/* @__PURE__ */ jsx(X, { className: "h-4 w-4" }), /* @__PURE__ */ jsx("span", {
6688
6689
  className: "sr-only",
6689
6690
  children: "Close"
@@ -7605,7 +7606,7 @@ function EditorToolbar({ editor, focusMode, onFocusModeChange }) {
7605
7606
  "aria-hidden": "true"
7606
7607
  })
7607
7608
  }), showLinkPopover && /* @__PURE__ */ jsx("div", {
7608
- className: "absolute top-full left-0 mt-1 z-50 rounded-md border bg-kumo-overlay p-3 shadow-lg",
7609
+ className: "absolute top-full start-0 mt-1 z-50 rounded-md border bg-kumo-overlay p-3 shadow-lg",
7609
7610
  children: /* @__PURE__ */ jsxs("div", {
7610
7611
  className: "flex flex-col gap-2",
7611
7612
  children: [
@@ -7870,7 +7871,7 @@ function RevisionHistory({ collection, entryId, onRestored }) {
7870
7871
  children: [/* @__PURE__ */ jsxs("button", {
7871
7872
  type: "button",
7872
7873
  onClick: () => setIsExpanded(!isExpanded),
7873
- className: "flex w-full items-center justify-between p-4 text-left hover:bg-kumo-tint/50 transition-colors",
7874
+ className: "flex w-full items-center justify-between p-4 text-start hover:bg-kumo-tint/50 transition-colors",
7874
7875
  children: [/* @__PURE__ */ jsxs("div", {
7875
7876
  className: "flex items-center gap-2",
7876
7877
  children: [
@@ -7962,7 +7963,7 @@ function RevisionItem({ revision, compareRevision, isLatest, isRestoring, isSele
7962
7963
  children: [/* @__PURE__ */ jsxs("button", {
7963
7964
  type: "button",
7964
7965
  onClick: onSelect,
7965
- className: "flex-1 text-left",
7966
+ className: "flex-1 text-start",
7966
7967
  children: [/* @__PURE__ */ jsxs("div", {
7967
7968
  className: "flex items-center gap-2",
7968
7969
  children: [/* @__PURE__ */ jsx("span", {
@@ -8210,7 +8211,7 @@ function SeoImageField({ seo, onChange }) {
8210
8211
  alt: "",
8211
8212
  className: "max-h-48 rounded-lg border object-cover"
8212
8213
  }), /* @__PURE__ */ jsxs("div", {
8213
- className: "absolute top-2 right-2 opacity-0 group-hover:opacity-100 transition-opacity flex gap-1",
8214
+ className: "absolute top-2 end-2 opacity-0 group-hover:opacity-100 transition-opacity flex gap-1",
8214
8215
  children: [/* @__PURE__ */ jsx(Button, {
8215
8216
  type: "button",
8216
8217
  size: "sm",
@@ -8504,7 +8505,7 @@ function CategoryCheckboxTree({ term, level = 0, selectedIds, onToggle }) {
8504
8505
  type: "checkbox",
8505
8506
  checked: isChecked,
8506
8507
  onChange: () => onToggle(term.id),
8507
- className: "mr-2"
8508
+ className: "me-2"
8508
8509
  }), /* @__PURE__ */ jsx("span", {
8509
8510
  className: "text-sm",
8510
8511
  children: term.label
@@ -8519,22 +8520,40 @@ function CategoryCheckboxTree({ term, level = 0, selectedIds, onToggle }) {
8519
8520
  /**
8520
8521
  * Tag input for flat taxonomies
8521
8522
  */
8522
- function TagInput({ terms, selectedIds, onAdd, onRemove, label }) {
8523
+ function TagInput({ terms, selectedIds, onAdd, onRemove, onCreate, isCreating, label }) {
8523
8524
  const { _: _t } = useLingui();
8524
8525
  const [input, setInput] = React.useState("");
8525
8526
  const selectedTerms = terms.filter((term) => selectedIds.has(term.id));
8527
+ const trimmedInput = input.trim();
8526
8528
  const suggestions = React.useMemo(() => {
8527
- if (!input) return [];
8528
- return terms.filter((term) => term.label.toLowerCase().includes(input.toLowerCase()) && !selectedIds.has(term.id)).slice(0, 5);
8529
+ if (!trimmedInput) return [];
8530
+ return terms.filter((term) => term.label.toLowerCase().includes(trimmedInput.toLowerCase()) && !selectedIds.has(term.id)).slice(0, 5);
8529
8531
  }, [
8530
- input,
8532
+ trimmedInput,
8531
8533
  terms,
8532
8534
  selectedIds
8533
8535
  ]);
8536
+ const hasExactMatch = React.useMemo(() => {
8537
+ if (!trimmedInput) return false;
8538
+ return terms.some((term) => term.label.toLowerCase() === trimmedInput.toLowerCase());
8539
+ }, [trimmedInput, terms]);
8540
+ const showCreateOption = trimmedInput.length > 0 && !hasExactMatch;
8534
8541
  const handleSelect = (term) => {
8535
8542
  onAdd(term.id);
8536
8543
  setInput("");
8537
8544
  };
8545
+ const handleCreate = () => {
8546
+ if (!trimmedInput || isCreating) return;
8547
+ onCreate(trimmedInput);
8548
+ setInput("");
8549
+ };
8550
+ const handleKeyDown = (e) => {
8551
+ if (e.key === "Enter") {
8552
+ e.preventDefault();
8553
+ if (suggestions.length === 1 && !showCreateOption) handleSelect(suggestions[0]);
8554
+ else if (showCreateOption && suggestions.length === 0) handleCreate();
8555
+ }
8556
+ };
8538
8557
  return /* @__PURE__ */ jsxs("div", {
8539
8558
  className: "space-y-2",
8540
8559
  children: [selectedTerms.length > 0 && /* @__PURE__ */ jsx("div", {
@@ -8558,6 +8577,7 @@ function TagInput({ terms, selectedIds, onAdd, onRemove, label }) {
8558
8577
  children: [/* @__PURE__ */ jsx(Input, {
8559
8578
  value: input,
8560
8579
  onChange: (e) => setInput(e.target.value),
8580
+ onKeyDown: handleKeyDown,
8561
8581
  placeholder: _t({
8562
8582
  id: "SnJVrE",
8563
8583
  message: "Add tags..."
@@ -8568,14 +8588,20 @@ function TagInput({ terms, selectedIds, onAdd, onRemove, label }) {
8568
8588
  values: { label }
8569
8589
  }),
8570
8590
  className: "text-sm"
8571
- }), suggestions.length > 0 && /* @__PURE__ */ jsx("div", {
8572
- className: "absolute top-full left-0 right-0 mt-1 bg-kumo-overlay border rounded-md shadow-lg z-10",
8573
- children: suggestions.map((term) => /* @__PURE__ */ jsx("button", {
8591
+ }), (suggestions.length > 0 || showCreateOption) && /* @__PURE__ */ jsxs("div", {
8592
+ className: "absolute top-full start-0 end-0 mt-1 bg-kumo-overlay border rounded-md shadow-lg z-10",
8593
+ children: [suggestions.map((term) => /* @__PURE__ */ jsx("button", {
8574
8594
  type: "button",
8575
8595
  onClick: () => handleSelect(term),
8576
- className: "w-full text-left px-3 py-2 text-sm hover:bg-kumo-tint",
8596
+ className: "w-full text-start px-3 py-2 text-sm hover:bg-kumo-tint",
8577
8597
  children: term.label
8578
- }, term.id))
8598
+ }, term.id)), showCreateOption && /* @__PURE__ */ jsxs("button", {
8599
+ type: "button",
8600
+ onClick: handleCreate,
8601
+ disabled: isCreating,
8602
+ className: "w-full text-left px-3 py-2 text-sm hover:bg-kumo-tint text-kumo-accent flex items-center gap-1 border-t",
8603
+ children: [/* @__PURE__ */ jsx(Plus, { className: "w-3 h-3" }), isCreating ? "Creating..." : `Create "${trimmedInput}"`]
8604
+ })]
8579
8605
  })]
8580
8606
  })]
8581
8607
  });
@@ -8586,6 +8612,9 @@ function TagInput({ terms, selectedIds, onAdd, onRemove, label }) {
8586
8612
  function TaxonomySection({ taxonomy, collection, entryId, onChange }) {
8587
8613
  const { _: _t2 } = useLingui();
8588
8614
  const queryClient = useQueryClient();
8615
+ const toastManager = Toast.useToastManager();
8616
+ const [newCategoryLabel, setNewCategoryLabel] = React.useState("");
8617
+ const [showCategoryInput, setShowCategoryInput] = React.useState(false);
8589
8618
  const { data: terms = [] } = useQuery({
8590
8619
  queryKey: ["taxonomy-terms", taxonomy.name],
8591
8620
  queryFn: () => fetchTerms$1(taxonomy.name)
@@ -8615,6 +8644,42 @@ function TaxonomySection({ taxonomy, collection, entryId, onChange }) {
8615
8644
  entryId,
8616
8645
  taxonomy.name
8617
8646
  ] });
8647
+ toastManager.add({ title: _t2({
8648
+ id: "KDffey",
8649
+ message: "{0} updated",
8650
+ values: { 0: taxonomy.label }
8651
+ }) });
8652
+ },
8653
+ onError: (error) => {
8654
+ toastManager.add({
8655
+ title: _t2({
8656
+ id: "J1Hhct",
8657
+ message: "Failed to update {0}",
8658
+ values: { 0: taxonomy.label.toLowerCase() }
8659
+ }),
8660
+ description: error instanceof Error ? error.message : _t2({
8661
+ id: "Vw8l6h",
8662
+ message: "An error occurred"
8663
+ }),
8664
+ type: "error"
8665
+ });
8666
+ }
8667
+ });
8668
+ const createTermMutation = useMutation({
8669
+ mutationFn: (label) => createTerm(taxonomy.name, {
8670
+ slug: slugify(label),
8671
+ label
8672
+ }),
8673
+ onSuccess: (newTerm) => {
8674
+ queryClient.invalidateQueries({ queryKey: ["taxonomy-terms", taxonomy.name] });
8675
+ const newSelected = new Set(selectedIds);
8676
+ newSelected.add(newTerm.id);
8677
+ setSelectedIds(newSelected);
8678
+ const termIdsArray = [...newSelected];
8679
+ onChange?.(termIdsArray);
8680
+ if (entryId) saveMutation.mutate(termIdsArray);
8681
+ setNewCategoryLabel("");
8682
+ setShowCategoryInput(false);
8618
8683
  }
8619
8684
  });
8620
8685
  const [selectedIds, setSelectedIds] = React.useState(/* @__PURE__ */ new Set());
@@ -8636,30 +8701,89 @@ function TaxonomySection({ taxonomy, collection, entryId, onChange }) {
8636
8701
  const handleRemove = (termId) => {
8637
8702
  handleToggle(termId);
8638
8703
  };
8704
+ const handleCreateCategory = () => {
8705
+ const label = newCategoryLabel.trim();
8706
+ if (!label || createTermMutation.isPending) return;
8707
+ createTermMutation.mutate(label);
8708
+ };
8639
8709
  return /* @__PURE__ */ jsxs("div", {
8640
8710
  className: "space-y-2",
8641
8711
  children: [/* @__PURE__ */ jsx(Label, {
8642
8712
  className: "text-sm font-medium",
8643
8713
  children: taxonomy.label
8644
- }), terms.length === 0 ? /* @__PURE__ */ jsx("p", {
8645
- className: "text-sm text-kumo-subtle",
8646
- children: _t2({
8647
- id: "eRblWH",
8648
- message: "No {0} available.",
8649
- values: { 0: taxonomy.label.toLowerCase() }
8714
+ }), taxonomy.hierarchical ? /* @__PURE__ */ jsxs(Fragment, { children: [
8715
+ terms.length === 0 ? /* @__PURE__ */ jsx("p", {
8716
+ className: "text-sm text-kumo-subtle",
8717
+ children: _t2({
8718
+ id: "eRblWH",
8719
+ message: "No {0} available.",
8720
+ values: { 0: taxonomy.label.toLowerCase() }
8721
+ })
8722
+ }) : /* @__PURE__ */ jsx("div", {
8723
+ className: "border rounded-md p-2 max-h-64 overflow-y-auto",
8724
+ children: terms.map((term) => /* @__PURE__ */ jsx(CategoryCheckboxTree, {
8725
+ term,
8726
+ selectedIds,
8727
+ onToggle: handleToggle
8728
+ }, term.id))
8729
+ }),
8730
+ showCategoryInput ? /* @__PURE__ */ jsxs("div", {
8731
+ className: "flex gap-1",
8732
+ children: [/* @__PURE__ */ jsx(Input, {
8733
+ value: newCategoryLabel,
8734
+ onChange: (e) => setNewCategoryLabel(e.target.value),
8735
+ onKeyDown: (e) => {
8736
+ if (e.key === "Enter") {
8737
+ e.preventDefault();
8738
+ handleCreateCategory();
8739
+ } else if (e.key === "Escape") {
8740
+ setShowCategoryInput(false);
8741
+ setNewCategoryLabel("");
8742
+ }
8743
+ },
8744
+ placeholder: _t2({
8745
+ id: "6WSYbN",
8746
+ message: "New {0}",
8747
+ values: { 0: (taxonomy.labelSingular || taxonomy.label).toLowerCase() }
8748
+ }),
8749
+ className: "text-sm flex-1",
8750
+ autoFocus: true,
8751
+ disabled: createTermMutation.isPending
8752
+ }), /* @__PURE__ */ jsx(Button, {
8753
+ type: "button",
8754
+ onClick: handleCreateCategory,
8755
+ disabled: !newCategoryLabel.trim(),
8756
+ loading: createTermMutation.isPending,
8757
+ variant: "primary",
8758
+ children: _t2({
8759
+ id: "m16xKo",
8760
+ message: "Add"
8761
+ })
8762
+ })]
8763
+ }) : /* @__PURE__ */ jsxs("button", {
8764
+ type: "button",
8765
+ onClick: () => setShowCategoryInput(true),
8766
+ className: "text-sm text-kumo-accent hover:underline flex items-center gap-1",
8767
+ children: [/* @__PURE__ */ jsx(Plus, { className: "w-3 h-3" }), _t2({
8768
+ id: "eABj3Y",
8769
+ message: "Add new {0}",
8770
+ values: { 0: (taxonomy.labelSingular || taxonomy.label).toLowerCase() }
8771
+ })]
8772
+ }),
8773
+ createTermMutation.error && /* @__PURE__ */ jsx("p", {
8774
+ className: "text-sm text-kumo-danger",
8775
+ children: createTermMutation.error instanceof Error ? createTermMutation.error.message : _t2({
8776
+ id: "CyQAPp",
8777
+ message: "Failed to create term"
8778
+ })
8650
8779
  })
8651
- }) : taxonomy.hierarchical ? /* @__PURE__ */ jsx("div", {
8652
- className: "border rounded-md p-2 max-h-64 overflow-y-auto",
8653
- children: terms.map((term) => /* @__PURE__ */ jsx(CategoryCheckboxTree, {
8654
- term,
8655
- selectedIds,
8656
- onToggle: handleToggle
8657
- }, term.id))
8658
- }) : /* @__PURE__ */ jsx(TagInput, {
8780
+ ] }) : /* @__PURE__ */ jsx(TagInput, {
8659
8781
  terms,
8660
8782
  selectedIds,
8661
8783
  onAdd: handleAdd,
8662
8784
  onRemove: handleRemove,
8785
+ onCreate: (label) => createTermMutation.mutate(label),
8786
+ isCreating: createTermMutation.isPending,
8663
8787
  label: taxonomy.label
8664
8788
  })]
8665
8789
  });
@@ -8726,6 +8850,13 @@ function ContentEditor({ collection, collectionLabel, item, fields, isNew, isSav
8726
8850
  roleLabel: entry.roleLabel
8727
8851
  })) ?? []);
8728
8852
  const [portableTextEditor, setPortableTextEditor] = React.useState(null);
8853
+ const ptEditorClaimedRef = React.useRef(false);
8854
+ React.useCallback((editor) => {
8855
+ if (!ptEditorClaimedRef.current) {
8856
+ ptEditorClaimedRef.current = true;
8857
+ setPortableTextEditor(editor);
8858
+ }
8859
+ }, []);
8729
8860
  const [blockSidebarPanel, setBlockSidebarPanel] = React.useState(null);
8730
8861
  const handleBlockSidebarOpen = React.useCallback((panel) => {
8731
8862
  setBlockSidebarPanel(panel);
@@ -8804,11 +8935,19 @@ function ContentEditor({ collection, collectionLabel, item, fields, isNew, isSav
8804
8935
  setLastSavedData(pendingAutosaveStateRef.current);
8805
8936
  pendingAutosaveStateRef.current = null;
8806
8937
  }, [lastAutosaveAt]);
8938
+ const hasInvalidUrls = React.useCallback((data) => {
8939
+ for (const [name, field] of Object.entries(fields)) if (field.kind === "url") {
8940
+ const val = typeof data[name] === "string" ? data[name].trim() : "";
8941
+ if (val && !isValidUrl(val)) return true;
8942
+ }
8943
+ return false;
8944
+ }, [fields]);
8807
8945
  React.useEffect(() => {
8808
8946
  if (isNew || !onAutosave || !item?.id) return;
8809
8947
  if (!isDirty || isSaving || isAutosaving) return;
8810
8948
  if (autosaveTimeoutRef.current) clearTimeout(autosaveTimeoutRef.current);
8811
8949
  autosaveTimeoutRef.current = setTimeout(() => {
8950
+ if (hasInvalidUrls(formDataRef.current)) return;
8812
8951
  const payload = {
8813
8952
  data: formDataRef.current,
8814
8953
  slug: slugRef.current || void 0,
@@ -8832,10 +8971,12 @@ function ContentEditor({ collection, collectionLabel, item, fields, isNew, isSav
8832
8971
  isDirty,
8833
8972
  isSaving,
8834
8973
  isAutosaving,
8835
- activeBylines
8974
+ activeBylines,
8975
+ hasInvalidUrls
8836
8976
  ]);
8837
8977
  const handleSubmit = (e) => {
8838
8978
  e.preventDefault();
8979
+ if (hasInvalidUrls(formData)) return;
8839
8980
  if (autosaveTimeoutRef.current) {
8840
8981
  clearTimeout(autosaveTimeoutRef.current);
8841
8982
  autosaveTimeoutRef.current = null;
@@ -8904,7 +9045,7 @@ function ContentEditor({ collection, collectionLabel, item, fields, isNew, isSav
8904
9045
  onSubmit: handleSubmit,
8905
9046
  className: cn("space-y-6 transition-all duration-300", isDistractionFree && "fixed inset-0 z-50 bg-kumo-base p-8 overflow-auto"),
8906
9047
  children: [/* @__PURE__ */ jsxs("div", {
8907
- className: cn("flex flex-wrap items-center justify-between gap-y-2", isDistractionFree && "opacity-0 hover:opacity-100 transition-opacity duration-200 fixed top-0 left-0 right-0 bg-kumo-base/95 backdrop-blur p-4 z-10"),
9048
+ className: cn("flex flex-wrap items-center justify-between gap-y-2", isDistractionFree && "opacity-0 hover:opacity-100 transition-opacity duration-200 fixed top-0 start-0 end-0 bg-kumo-base/95 backdrop-blur p-4 z-10"),
8908
9049
  children: [/* @__PURE__ */ jsxs("div", {
8909
9050
  className: "flex items-center space-x-4",
8910
9051
  children: [
@@ -8966,13 +9107,13 @@ function ContentEditor({ collection, collectionLabel, item, fields, isNew, isSav
8966
9107
  "aria-label": "Autosave status",
8967
9108
  "aria-live": "polite",
8968
9109
  children: isAutosaving ? /* @__PURE__ */ jsxs(Fragment, { children: [/* @__PURE__ */ jsx(Loader, { size: "sm" }), /* @__PURE__ */ jsx("span", {
8969
- className: "ml-1",
9110
+ className: "ms-1",
8970
9111
  children: _t({
8971
9112
  id: "XvjC4F",
8972
9113
  message: "Saving..."
8973
9114
  })
8974
9115
  })] }) : lastAutosaveAt ? /* @__PURE__ */ jsxs(Fragment, { children: [/* @__PURE__ */ jsx(Check, {
8975
- className: "mr-1 h-3 w-3 text-green-600",
9116
+ className: "me-1 h-3 w-3 text-green-600",
8976
9117
  "aria-hidden": "true"
8977
9118
  }), /* @__PURE__ */ jsx("span", { children: _t({
8978
9119
  id: "idD8Ev",
@@ -9097,7 +9238,7 @@ function ContentEditor({ collection, collectionLabel, item, fields, isNew, isSav
9097
9238
  rel: "noopener noreferrer",
9098
9239
  className: buttonVariants({ variant: "outline" }),
9099
9240
  children: [/* @__PURE__ */ jsx(ArrowSquareOut, {
9100
- className: "mr-2 h-4 w-4",
9241
+ className: "me-2 h-4 w-4",
9101
9242
  "aria-hidden": "true"
9102
9243
  }), _t({
9103
9244
  id: "I1UtWg",
@@ -9121,7 +9262,7 @@ function ContentEditor({ collection, collectionLabel, item, fields, isNew, isSav
9121
9262
  field,
9122
9263
  value: formData[name],
9123
9264
  onChange: handleFieldChange,
9124
- onEditorReady: field.kind === "portableText" ? setPortableTextEditor : void 0,
9265
+ onEditorReady: field.kind === "portableText" && name === "content" ? setPortableTextEditor : void 0,
9125
9266
  minimal: isDistractionFree,
9126
9267
  pluginBlocks,
9127
9268
  onBlockSidebarOpen: field.kind === "portableText" ? handleBlockSidebarOpen : void 0,
@@ -9559,7 +9700,7 @@ function FieldRenderer({ name, field, value, onChange, onEditorReady, minimal, p
9559
9700
  case "boolean": return /* @__PURE__ */ jsx(Switch, {
9560
9701
  id,
9561
9702
  label,
9562
- checked: typeof value === "boolean" ? value : false,
9703
+ checked: Boolean(value),
9563
9704
  onCheckedChange: handleChange
9564
9705
  });
9565
9706
  case "portableText": {
@@ -9675,6 +9816,15 @@ function FieldRenderer({ name, field, value, onChange, onEditorReady, minimal, p
9675
9816
  onChange: handleChange,
9676
9817
  required: field.required
9677
9818
  });
9819
+ case "url": return /* @__PURE__ */ jsx(UrlFieldEditor, {
9820
+ label,
9821
+ labelClass,
9822
+ id,
9823
+ value: typeof value === "string" ? value : "",
9824
+ onChange: handleChange,
9825
+ required: field.required,
9826
+ placeholder: "https://"
9827
+ });
9678
9828
  default: return /* @__PURE__ */ jsx(Input, {
9679
9829
  label,
9680
9830
  id,
@@ -9684,11 +9834,61 @@ function FieldRenderer({ name, field, value, onChange, onEditorReady, minimal, p
9684
9834
  });
9685
9835
  }
9686
9836
  }
9837
+ const URL_PROTOCOL_PATTERN = /^https?:\/\//;
9838
+ function isValidUrl(val) {
9839
+ if (!URL_PROTOCOL_PATTERN.test(val)) return false;
9840
+ try {
9841
+ const url = new URL(val);
9842
+ if (url.protocol !== "http:" && url.protocol !== "https:") return false;
9843
+ if (url.hostname.includes("..")) return false;
9844
+ return url.hostname.includes(".") || url.hostname === "localhost";
9845
+ } catch {
9846
+ return false;
9847
+ }
9848
+ }
9849
+ /**
9850
+ * URL field editor with validation on blur
9851
+ */
9852
+ function UrlFieldEditor({ label, labelClass, id, value, onChange, required, placeholder }) {
9853
+ const { _: _t3 } = useLingui();
9854
+ const [error, setError] = React.useState(null);
9855
+ const handleBlur = (e) => {
9856
+ const val = e.target.value.trim();
9857
+ if (!val) {
9858
+ setError(null);
9859
+ return;
9860
+ }
9861
+ if (!isValidUrl(val)) setError(_t3({
9862
+ id: "KPnpQW",
9863
+ message: "Enter a valid URL (e.g. https://example.com)"
9864
+ }));
9865
+ else setError(null);
9866
+ };
9867
+ return /* @__PURE__ */ jsxs("div", { children: [/* @__PURE__ */ jsx(Input, {
9868
+ label: /* @__PURE__ */ jsx("span", {
9869
+ className: labelClass,
9870
+ children: label
9871
+ }),
9872
+ id,
9873
+ type: "url",
9874
+ value,
9875
+ onChange: (e) => {
9876
+ if (error) setError(null);
9877
+ onChange(e.target.value);
9878
+ },
9879
+ onBlur: handleBlur,
9880
+ required,
9881
+ placeholder
9882
+ }), error && /* @__PURE__ */ jsx("p", {
9883
+ className: "text-sm text-kumo-danger mt-1",
9884
+ children: error
9885
+ })] });
9886
+ }
9687
9887
  /**
9688
9888
  * JSON field editor with syntax validation
9689
9889
  */
9690
9890
  function JsonFieldEditor({ label, id, value, onChange, required }) {
9691
- const { _: _t3 } = useLingui();
9891
+ const { _: _t4 } = useLingui();
9692
9892
  const [text, setText] = React.useState(value);
9693
9893
  const [error, setError] = React.useState(null);
9694
9894
  React.useEffect(() => {
@@ -9711,7 +9911,7 @@ function JsonFieldEditor({ label, id, value, onChange, required }) {
9711
9911
  setError(null);
9712
9912
  onChange(parsed);
9713
9913
  } catch {
9714
- setError(_t3({
9914
+ setError(_t4({
9715
9915
  id: "Deej3j",
9716
9916
  message: "Invalid JSON"
9717
9917
  }));
@@ -9733,7 +9933,7 @@ function JsonFieldEditor({ label, id, value, onChange, required }) {
9733
9933
  })] });
9734
9934
  }
9735
9935
  function ImageFieldRenderer({ id, label, description, value, onChange, required }) {
9736
- const { _: _t4 } = useLingui();
9936
+ const { _: _t5 } = useLingui();
9737
9937
  const [pickerOpen, setPickerOpen] = React.useState(false);
9738
9938
  const displayUrl = typeof value === "string" ? value : value?.previewUrl || value?.src || (value && (!value.provider || value.provider === "local") ? `/_emdash/api/media/file/${typeof value.meta?.storageKey === "string" ? value.meta.storageKey : value.id}` : void 0);
9739
9939
  const handleSelect = (item) => {
@@ -9765,13 +9965,13 @@ function ImageFieldRenderer({ id, label, description, value, onChange, required
9765
9965
  alt: "",
9766
9966
  className: "max-h-48 rounded-lg border object-cover"
9767
9967
  }), /* @__PURE__ */ jsxs("div", {
9768
- className: "absolute top-2 right-2 opacity-0 group-hover:opacity-100 transition-opacity flex gap-1",
9968
+ className: "absolute top-2 end-2 opacity-0 group-hover:opacity-100 transition-opacity flex gap-1",
9769
9969
  children: [/* @__PURE__ */ jsx(Button, {
9770
9970
  type: "button",
9771
9971
  size: "sm",
9772
9972
  variant: "secondary",
9773
9973
  onClick: () => setPickerOpen(true),
9774
- children: _t4({
9974
+ children: _t5({
9775
9975
  id: "o+XJ9D",
9776
9976
  message: "Change"
9777
9977
  })
@@ -9781,7 +9981,7 @@ function ImageFieldRenderer({ id, label, description, value, onChange, required
9781
9981
  variant: "destructive",
9782
9982
  className: "h-8 w-8",
9783
9983
  onClick: handleRemove,
9784
- "aria-label": _t4({
9984
+ "aria-label": _t5({
9785
9985
  id: "5ywtDz",
9786
9986
  message: "Remove image"
9787
9987
  }),
@@ -9795,7 +9995,7 @@ function ImageFieldRenderer({ id, label, description, value, onChange, required
9795
9995
  onClick: () => setPickerOpen(true),
9796
9996
  children: /* @__PURE__ */ jsxs("div", {
9797
9997
  className: "flex flex-col items-center gap-2 text-kumo-subtle",
9798
- children: [/* @__PURE__ */ jsx(Image$1, { className: "h-8 w-8" }), /* @__PURE__ */ jsx("span", { children: _t4({
9998
+ children: [/* @__PURE__ */ jsx(Image$1, { className: "h-8 w-8" }), /* @__PURE__ */ jsx("span", { children: _t5({
9799
9999
  id: "oDodff",
9800
10000
  message: "Select image"
9801
10001
  }) })]
@@ -9806,7 +10006,7 @@ function ImageFieldRenderer({ id, label, description, value, onChange, required
9806
10006
  onOpenChange: setPickerOpen,
9807
10007
  onSelect: handleSelect,
9808
10008
  mimeTypeFilter: "image/",
9809
- title: _t4({
10009
+ title: _t5({
9810
10010
  id: "pov/PW",
9811
10011
  message: "Select {label}",
9812
10012
  values: { label }
@@ -9818,7 +10018,7 @@ function ImageFieldRenderer({ id, label, description, value, onChange, required
9818
10018
  }),
9819
10019
  required && !displayUrl && /* @__PURE__ */ jsx("p", {
9820
10020
  className: "text-sm text-kumo-danger mt-1",
9821
- children: _t4({
10021
+ children: _t5({
9822
10022
  id: "B8AaMI",
9823
10023
  message: "This field is required"
9824
10024
  })
@@ -9827,7 +10027,7 @@ function ImageFieldRenderer({ id, label, description, value, onChange, required
9827
10027
  });
9828
10028
  }
9829
10029
  function BylineCreditsEditor({ credits, bylines, onChange, onQuickCreate, onQuickEdit }) {
9830
- const { _: _t5 } = useLingui();
10030
+ const { _: _t6 } = useLingui();
9831
10031
  const [selectedBylineId, setSelectedBylineId] = React.useState("");
9832
10032
  const [quickName, setQuickName] = React.useState("");
9833
10033
  const [quickSlug, setQuickSlug] = React.useState("");
@@ -9877,7 +10077,7 @@ function BylineCreditsEditor({ credits, bylines, onChange, onQuickCreate, onQuic
9877
10077
  className: "w-full rounded border bg-kumo-base px-3 py-2 text-sm",
9878
10078
  children: [/* @__PURE__ */ jsx("option", {
9879
10079
  value: "",
9880
- children: _t5({
10080
+ children: _t6({
9881
10081
  id: "r5zcIE",
9882
10082
  message: "Select byline..."
9883
10083
  })
@@ -9897,7 +10097,7 @@ function BylineCreditsEditor({ credits, bylines, onChange, onQuickCreate, onQuic
9897
10097
  setSelectedBylineId("");
9898
10098
  },
9899
10099
  disabled: !selectedBylineId,
9900
- children: _t5({
10100
+ children: _t6({
9901
10101
  id: "m16xKo",
9902
10102
  message: "Add"
9903
10103
  })
@@ -9926,7 +10126,7 @@ function BylineCreditsEditor({ credits, bylines, onChange, onQuickCreate, onQuic
9926
10126
  variant: "ghost",
9927
10127
  size: "sm",
9928
10128
  onClick: () => move(index, -1),
9929
- children: _t5({
10129
+ children: _t6({
9930
10130
  id: "n+PHuv",
9931
10131
  message: "Up"
9932
10132
  })
@@ -9936,7 +10136,7 @@ function BylineCreditsEditor({ credits, bylines, onChange, onQuickCreate, onQuic
9936
10136
  variant: "ghost",
9937
10137
  size: "sm",
9938
10138
  onClick: () => move(index, 1),
9939
- children: _t5({
10139
+ children: _t6({
9940
10140
  id: "gUjkl/",
9941
10141
  message: "Down"
9942
10142
  })
@@ -9946,7 +10146,7 @@ function BylineCreditsEditor({ credits, bylines, onChange, onQuickCreate, onQuic
9946
10146
  variant: "ghost",
9947
10147
  size: "sm",
9948
10148
  onClick: () => openEditByline(byline),
9949
- children: _t5({
10149
+ children: _t6({
9950
10150
  id: "ePK91l",
9951
10151
  message: "Edit"
9952
10152
  })
@@ -9956,7 +10156,7 @@ function BylineCreditsEditor({ credits, bylines, onChange, onQuickCreate, onQuic
9956
10156
  variant: "destructive",
9957
10157
  size: "sm",
9958
10158
  onClick: () => onChange(credits.filter((_, i) => i !== index)),
9959
- children: _t5({
10159
+ children: _t6({
9960
10160
  id: "t/YqKh",
9961
10161
  message: "Remove"
9962
10162
  })
@@ -9964,7 +10164,7 @@ function BylineCreditsEditor({ credits, bylines, onChange, onQuickCreate, onQuic
9964
10164
  ]
9965
10165
  })]
9966
10166
  }), /* @__PURE__ */ jsx(Input, {
9967
- label: _t5({
10167
+ label: _t6({
9968
10168
  id: "QeScoL",
9969
10169
  message: "Role label"
9970
10170
  }),
@@ -9984,7 +10184,7 @@ function BylineCreditsEditor({ credits, bylines, onChange, onQuickCreate, onQuic
9984
10184
  })
9985
10185
  }) : /* @__PURE__ */ jsx("p", {
9986
10186
  className: "text-sm text-kumo-subtle",
9987
- children: _t5({
10187
+ children: _t6({
9988
10188
  id: "dyZY24",
9989
10189
  message: "No bylines selected."
9990
10190
  })
@@ -9993,7 +10193,7 @@ function BylineCreditsEditor({ credits, bylines, onChange, onQuickCreate, onQuic
9993
10193
  ...p,
9994
10194
  type: "button",
9995
10195
  variant: "secondary",
9996
- children: _t5({
10196
+ children: _t6({
9997
10197
  id: "gqa8eq",
9998
10198
  message: "Quick create byline"
9999
10199
  })
@@ -10003,7 +10203,7 @@ function BylineCreditsEditor({ credits, bylines, onChange, onQuickCreate, onQuic
10003
10203
  children: [
10004
10204
  /* @__PURE__ */ jsx(Dialog.Title, {
10005
10205
  className: "text-lg font-semibold",
10006
- children: _t5({
10206
+ children: _t6({
10007
10207
  id: "d6HWlw",
10008
10208
  message: "Create byline"
10009
10209
  })
@@ -10012,7 +10212,7 @@ function BylineCreditsEditor({ credits, bylines, onChange, onQuickCreate, onQuic
10012
10212
  className: "mt-4 space-y-3",
10013
10213
  children: [
10014
10214
  /* @__PURE__ */ jsx(Input, {
10015
- label: _t5({
10215
+ label: _t6({
10016
10216
  id: "pfa8F0",
10017
10217
  message: "Display name"
10018
10218
  }),
@@ -10023,7 +10223,7 @@ function BylineCreditsEditor({ credits, bylines, onChange, onQuickCreate, onQuic
10023
10223
  }
10024
10224
  }),
10025
10225
  /* @__PURE__ */ jsx(Input, {
10026
- label: _t5({
10226
+ label: _t6({
10027
10227
  id: "L85WcV",
10028
10228
  message: "Slug"
10029
10229
  }),
@@ -10045,7 +10245,7 @@ function BylineCreditsEditor({ credits, bylines, onChange, onQuickCreate, onQuic
10045
10245
  resetQuickCreate();
10046
10246
  p.onClick?.(e);
10047
10247
  },
10048
- children: _t5({
10248
+ children: _t6({
10049
10249
  id: "dEgA5A",
10050
10250
  message: "Cancel"
10051
10251
  })
@@ -10066,7 +10266,7 @@ function BylineCreditsEditor({ credits, bylines, onChange, onQuickCreate, onQuic
10066
10266
  }]);
10067
10267
  resetQuickCreate();
10068
10268
  } catch (err) {
10069
- setQuickError(err instanceof Error ? err.message : _t5({
10269
+ setQuickError(err instanceof Error ? err.message : _t6({
10070
10270
  id: "Kd9Ewv",
10071
10271
  message: "Failed to create byline"
10072
10272
  }));
@@ -10074,10 +10274,10 @@ function BylineCreditsEditor({ credits, bylines, onChange, onQuickCreate, onQuic
10074
10274
  setIsCreating(false);
10075
10275
  }
10076
10276
  },
10077
- children: isCreating ? _t5({
10277
+ children: isCreating ? _t6({
10078
10278
  id: "HM56Bx",
10079
10279
  message: "Creating..."
10080
- }) : _t5({
10280
+ }) : _t6({
10081
10281
  id: "hYgDIe",
10082
10282
  message: "Create"
10083
10283
  })
@@ -10094,7 +10294,7 @@ function BylineCreditsEditor({ credits, bylines, onChange, onQuickCreate, onQuic
10094
10294
  children: [
10095
10295
  /* @__PURE__ */ jsx(Dialog.Title, {
10096
10296
  className: "text-lg font-semibold",
10097
- children: _t5({
10297
+ children: _t6({
10098
10298
  id: "d9lVyw",
10099
10299
  message: "Edit byline"
10100
10300
  })
@@ -10103,7 +10303,7 @@ function BylineCreditsEditor({ credits, bylines, onChange, onQuickCreate, onQuic
10103
10303
  className: "mt-4 space-y-3",
10104
10304
  children: [
10105
10305
  /* @__PURE__ */ jsx(Input, {
10106
- label: _t5({
10306
+ label: _t6({
10107
10307
  id: "pfa8F0",
10108
10308
  message: "Display name"
10109
10309
  }),
@@ -10114,7 +10314,7 @@ function BylineCreditsEditor({ credits, bylines, onChange, onQuickCreate, onQuic
10114
10314
  }
10115
10315
  }),
10116
10316
  /* @__PURE__ */ jsx(Input, {
10117
- label: _t5({
10317
+ label: _t6({
10118
10318
  id: "L85WcV",
10119
10319
  message: "Slug"
10120
10320
  }),
@@ -10133,7 +10333,7 @@ function BylineCreditsEditor({ credits, bylines, onChange, onQuickCreate, onQuic
10133
10333
  type: "button",
10134
10334
  variant: "secondary",
10135
10335
  onClick: resetQuickEdit,
10136
- children: _t5({
10336
+ children: _t6({
10137
10337
  id: "dEgA5A",
10138
10338
  message: "Cancel"
10139
10339
  })
@@ -10150,7 +10350,7 @@ function BylineCreditsEditor({ credits, bylines, onChange, onQuickCreate, onQuic
10150
10350
  });
10151
10351
  resetQuickEdit();
10152
10352
  } catch (err) {
10153
- setEditError(err instanceof Error ? err.message : _t5({
10353
+ setEditError(err instanceof Error ? err.message : _t6({
10154
10354
  id: "fd6o+d",
10155
10355
  message: "Failed to update byline"
10156
10356
  }));
@@ -10158,10 +10358,10 @@ function BylineCreditsEditor({ credits, bylines, onChange, onQuickCreate, onQuic
10158
10358
  setIsEditing(false);
10159
10359
  }
10160
10360
  },
10161
- children: isEditing ? _t5({
10361
+ children: isEditing ? _t6({
10162
10362
  id: "XvjC4F",
10163
10363
  message: "Saving..."
10164
- }) : _t5({
10364
+ }) : _t6({
10165
10365
  id: "tfDRzk",
10166
10366
  message: "Save"
10167
10367
  })
@@ -10174,9 +10374,9 @@ function BylineCreditsEditor({ credits, bylines, onChange, onQuickCreate, onQuic
10174
10374
  });
10175
10375
  }
10176
10376
  function AuthorSelector({ authorId, users, onChange }) {
10177
- const { _: _t6 } = useLingui();
10377
+ const { _: _t7 } = useLingui();
10178
10378
  const currentAuthor = users.find((u) => u.id === authorId);
10179
- const authorItems = { unassigned: _t6({
10379
+ const authorItems = { unassigned: _t7({
10180
10380
  id: "EbMPZJ",
10181
10381
  message: "Unassigned"
10182
10382
  }) };
@@ -10191,7 +10391,7 @@ function AuthorSelector({ authorId, users, onChange }) {
10191
10391
  value: "unassigned",
10192
10392
  children: /* @__PURE__ */ jsx("span", {
10193
10393
  className: "text-kumo-subtle",
10194
- children: _t6({
10394
+ children: _t7({
10195
10395
  id: "EbMPZJ",
10196
10396
  message: "Unassigned"
10197
10397
  })
@@ -10318,7 +10518,7 @@ function ContentList({ collection, collectionLabel, items, trashedItems = [], is
10318
10518
  search: { locale: activeLocale },
10319
10519
  className: buttonVariants(),
10320
10520
  children: [/* @__PURE__ */ jsx(Plus, {
10321
- className: "mr-2 h-4 w-4",
10521
+ className: "me-2 h-4 w-4",
10322
10522
  "aria-hidden": "true"
10323
10523
  }), _t({
10324
10524
  id: "ApsD9J",
@@ -10328,7 +10528,7 @@ function ContentList({ collection, collectionLabel, items, trashedItems = [], is
10328
10528
  }),
10329
10529
  items.length > 0 && /* @__PURE__ */ jsxs("div", {
10330
10530
  className: "relative max-w-sm",
10331
- children: [/* @__PURE__ */ jsx(MagnifyingGlass, { className: "absolute left-3 top-1/2 -translate-y-1/2 h-4 w-4 text-kumo-subtle" }), /* @__PURE__ */ jsx(Input, {
10531
+ children: [/* @__PURE__ */ jsx(MagnifyingGlass, { className: "absolute start-3 top-1/2 -translate-y-1/2 h-4 w-4 text-kumo-subtle" }), /* @__PURE__ */ jsx(Input, {
10332
10532
  type: "search",
10333
10533
  placeholder: _t({
10334
10534
  id: "FpEIAP",
@@ -10342,7 +10542,7 @@ function ContentList({ collection, collectionLabel, items, trashedItems = [], is
10342
10542
  }),
10343
10543
  value: searchQuery,
10344
10544
  onChange: handleSearchChange,
10345
- className: "pl-9"
10545
+ className: "ps-9"
10346
10546
  })]
10347
10547
  }),
10348
10548
  /* @__PURE__ */ jsx(Tabs, {
@@ -10388,7 +10588,7 @@ function ContentList({ collection, collectionLabel, items, trashedItems = [], is
10388
10588
  children: [
10389
10589
  /* @__PURE__ */ jsx("th", {
10390
10590
  scope: "col",
10391
- className: "px-4 py-3 text-left text-sm font-medium",
10591
+ className: "px-4 py-3 text-start text-sm font-medium",
10392
10592
  children: _t({
10393
10593
  id: "MHrjPM",
10394
10594
  message: "Title"
@@ -10396,7 +10596,7 @@ function ContentList({ collection, collectionLabel, items, trashedItems = [], is
10396
10596
  }),
10397
10597
  /* @__PURE__ */ jsx("th", {
10398
10598
  scope: "col",
10399
- className: "px-4 py-3 text-left text-sm font-medium",
10599
+ className: "px-4 py-3 text-start text-sm font-medium",
10400
10600
  children: _t({
10401
10601
  id: "uAQUqI",
10402
10602
  message: "Status"
@@ -10404,7 +10604,7 @@ function ContentList({ collection, collectionLabel, items, trashedItems = [], is
10404
10604
  }),
10405
10605
  i18n$1 && /* @__PURE__ */ jsx("th", {
10406
10606
  scope: "col",
10407
- className: "px-4 py-3 text-left text-sm font-medium",
10607
+ className: "px-4 py-3 text-start text-sm font-medium",
10408
10608
  children: _t({
10409
10609
  id: "8NbHF7",
10410
10610
  message: "Locale"
@@ -10412,7 +10612,7 @@ function ContentList({ collection, collectionLabel, items, trashedItems = [], is
10412
10612
  }),
10413
10613
  /* @__PURE__ */ jsx("th", {
10414
10614
  scope: "col",
10415
- className: "px-4 py-3 text-left text-sm font-medium",
10615
+ className: "px-4 py-3 text-start text-sm font-medium",
10416
10616
  children: _t({
10417
10617
  id: "mYGY3B",
10418
10618
  message: "Date"
@@ -10420,7 +10620,7 @@ function ContentList({ collection, collectionLabel, items, trashedItems = [], is
10420
10620
  }),
10421
10621
  /* @__PURE__ */ jsx("th", {
10422
10622
  scope: "col",
10423
- className: "px-4 py-3 text-right text-sm font-medium",
10623
+ className: "px-4 py-3 text-end text-sm font-medium",
10424
10624
  children: _t({
10425
10625
  id: "7L01XJ",
10426
10626
  message: "Actions"
@@ -10552,7 +10752,7 @@ function ContentList({ collection, collectionLabel, items, trashedItems = [], is
10552
10752
  children: [
10553
10753
  /* @__PURE__ */ jsx("th", {
10554
10754
  scope: "col",
10555
- className: "px-4 py-3 text-left text-sm font-medium",
10755
+ className: "px-4 py-3 text-start text-sm font-medium",
10556
10756
  children: _t({
10557
10757
  id: "MHrjPM",
10558
10758
  message: "Title"
@@ -10560,7 +10760,7 @@ function ContentList({ collection, collectionLabel, items, trashedItems = [], is
10560
10760
  }),
10561
10761
  /* @__PURE__ */ jsx("th", {
10562
10762
  scope: "col",
10563
- className: "px-4 py-3 text-left text-sm font-medium",
10763
+ className: "px-4 py-3 text-start text-sm font-medium",
10564
10764
  children: _t({
10565
10765
  id: "vGjmyl",
10566
10766
  message: "Deleted"
@@ -10568,7 +10768,7 @@ function ContentList({ collection, collectionLabel, items, trashedItems = [], is
10568
10768
  }),
10569
10769
  /* @__PURE__ */ jsx("th", {
10570
10770
  scope: "col",
10571
- className: "px-4 py-3 text-right text-sm font-medium",
10771
+ className: "px-4 py-3 text-end text-sm font-medium",
10572
10772
  children: _t({
10573
10773
  id: "7L01XJ",
10574
10774
  message: "Actions"
@@ -10644,7 +10844,7 @@ function ContentListItem({ item, collection, onDelete, onDuplicate, showLocale,
10644
10844
  children: date.toLocaleDateString()
10645
10845
  }),
10646
10846
  /* @__PURE__ */ jsx("td", {
10647
- className: "px-4 py-3 text-right",
10847
+ className: "px-4 py-3 text-end",
10648
10848
  children: /* @__PURE__ */ jsxs("div", {
10649
10849
  className: "flex items-center justify-end space-x-1",
10650
10850
  children: [
@@ -10781,7 +10981,7 @@ function TrashedListItem({ item, onRestore, onPermanentDelete }) {
10781
10981
  children: deletedDate.toLocaleDateString()
10782
10982
  }),
10783
10983
  /* @__PURE__ */ jsx("td", {
10784
- className: "px-4 py-3 text-right",
10984
+ className: "px-4 py-3 text-end",
10785
10985
  children: /* @__PURE__ */ jsxs("div", {
10786
10986
  className: "flex items-center justify-end space-x-1",
10787
10987
  children: [/* @__PURE__ */ jsx(Button, {
@@ -11114,6 +11314,18 @@ function FieldEditor({ open, onOpenChange, field, onSave, isSaving }) {
11114
11314
  }),
11115
11315
  icon: Link$2
11116
11316
  },
11317
+ {
11318
+ type: "url",
11319
+ label: _t({
11320
+ id: "IagCbF",
11321
+ message: "URL"
11322
+ }),
11323
+ description: _t({
11324
+ id: "55l21g",
11325
+ message: "Web address"
11326
+ }),
11327
+ icon: GlobeSimple
11328
+ },
11117
11329
  {
11118
11330
  type: "repeater",
11119
11331
  label: _t({
@@ -11170,7 +11382,7 @@ function FieldEditor({ open, onOpenChange, field, onSave, isSaving }) {
11170
11382
  type: selectedType,
11171
11383
  required,
11172
11384
  unique,
11173
- searchable: selectedType === "string" || selectedType === "text" || selectedType === "portableText" || selectedType === "slug" ? searchable : void 0,
11385
+ searchable: selectedType === "string" || selectedType === "text" || selectedType === "portableText" || selectedType === "slug" || selectedType === "url" ? searchable : void 0,
11174
11386
  validation: Object.keys(validation).length > 0 ? validation : void 0
11175
11387
  });
11176
11388
  };
@@ -11209,7 +11421,7 @@ function FieldEditor({ open, onOpenChange, field, onSave, isSaving }) {
11209
11421
  id: "yz7wBu",
11210
11422
  message: "Close"
11211
11423
  }),
11212
- className: "absolute right-4 top-4",
11424
+ className: "absolute end-4 top-4",
11213
11425
  children: [/* @__PURE__ */ jsx(X, { className: "h-4 w-4" }), /* @__PURE__ */ jsx("span", {
11214
11426
  className: "sr-only",
11215
11427
  children: _t({
@@ -11227,7 +11439,7 @@ function FieldEditor({ open, onOpenChange, field, onSave, isSaving }) {
11227
11439
  return /* @__PURE__ */ jsxs("button", {
11228
11440
  type: "button",
11229
11441
  onClick: () => handleTypeSelect(ft.type),
11230
- className: cn("flex items-start space-x-3 p-4 rounded-lg border text-left transition-colors hover:border-kumo-brand hover:bg-kumo-tint/50"),
11442
+ className: cn("flex items-start space-x-3 p-4 rounded-lg border text-start transition-colors hover:border-kumo-brand hover:bg-kumo-tint/50"),
11231
11443
  children: [/* @__PURE__ */ jsx("div", {
11232
11444
  className: "flex h-10 w-10 shrink-0 items-center justify-center rounded-lg bg-kumo-tint",
11233
11445
  children: /* @__PURE__ */ jsx(Icon, { className: "h-5 w-5" })
@@ -11257,7 +11469,7 @@ function FieldEditor({ open, onOpenChange, field, onSave, isSaving }) {
11257
11469
  !field && /* @__PURE__ */ jsx(Button, {
11258
11470
  variant: "ghost",
11259
11471
  size: "sm",
11260
- className: "ml-auto",
11472
+ className: "ms-auto",
11261
11473
  onClick: () => setField("step", "type"),
11262
11474
  children: _t({
11263
11475
  id: "o+XJ9D",
@@ -11329,7 +11541,7 @@ function FieldEditor({ open, onOpenChange, field, onSave, isSaving }) {
11329
11541
  })
11330
11542
  })]
11331
11543
  }),
11332
- (selectedType === "string" || selectedType === "text" || selectedType === "portableText" || selectedType === "slug") && /* @__PURE__ */ jsxs("label", {
11544
+ (selectedType === "string" || selectedType === "text" || selectedType === "portableText" || selectedType === "slug" || selectedType === "url") && /* @__PURE__ */ jsxs("label", {
11333
11545
  className: "flex items-center space-x-2",
11334
11546
  children: [/* @__PURE__ */ jsx("input", {
11335
11547
  type: "checkbox",
@@ -11576,6 +11788,13 @@ function FieldEditor({ open, onOpenChange, field, onSave, isSaving }) {
11576
11788
  id: "rG3WVm",
11577
11789
  message: "Select"
11578
11790
  })
11791
+ }),
11792
+ /* @__PURE__ */ jsx("option", {
11793
+ value: "url",
11794
+ children: _t({
11795
+ id: "IagCbF",
11796
+ message: "URL"
11797
+ })
11579
11798
  })
11580
11799
  ]
11581
11800
  })] })]
@@ -11808,7 +12027,7 @@ function ContentTypeEditor({ collection, isNew, isSaving, onSave, onAddField, on
11808
12027
  const [labelSingular, setLabelSingular] = React.useState(collection?.labelSingular ?? "");
11809
12028
  const [description, setDescription] = React.useState(collection?.description ?? "");
11810
12029
  const [urlPattern, setUrlPattern] = React.useState(collection?.urlPattern ?? "");
11811
- const [supports, setSupports] = React.useState(collection?.supports ?? ["drafts"]);
12030
+ const [supports, setSupports] = React.useState((collection?.supports ?? ["drafts"]).filter((s) => s !== "seo"));
11812
12031
  const [hasSeo, setHasSeo] = React.useState(collection?.hasSeo ?? false);
11813
12032
  const [commentsEnabled, setCommentsEnabled] = React.useState(collection?.commentsEnabled ?? false);
11814
12033
  const [commentsModeration, setCommentsModeration] = React.useState(collection?.commentsModeration ?? "first_time");
@@ -11822,7 +12041,7 @@ function ContentTypeEditor({ collection, isNew, isSaving, onSave, onAddField, on
11822
12041
  const hasChanges = React.useMemo(() => {
11823
12042
  if (isNew) return slug && label;
11824
12043
  if (!collection) return false;
11825
- return label !== collection.label || labelSingular !== (collection.labelSingular ?? "") || description !== (collection.description ?? "") || urlPattern !== (collection.urlPattern ?? "") || JSON.stringify([...supports].toSorted()) !== JSON.stringify([...collection.supports].toSorted()) || hasSeo !== collection.hasSeo || commentsEnabled !== collection.commentsEnabled || commentsModeration !== collection.commentsModeration || commentsClosedAfterDays !== collection.commentsClosedAfterDays || commentsAutoApproveUsers !== collection.commentsAutoApproveUsers;
12044
+ return label !== collection.label || labelSingular !== (collection.labelSingular ?? "") || description !== (collection.description ?? "") || urlPattern !== (collection.urlPattern ?? "") || JSON.stringify([...supports].toSorted()) !== JSON.stringify(collection.supports.filter((s) => s !== "seo").toSorted()) || hasSeo !== collection.hasSeo || commentsEnabled !== collection.commentsEnabled || commentsModeration !== collection.commentsModeration || commentsClosedAfterDays !== collection.commentsClosedAfterDays || commentsAutoApproveUsers !== collection.commentsAutoApproveUsers;
11826
12045
  }, [
11827
12046
  isNew,
11828
12047
  collection,
@@ -11928,7 +12147,7 @@ function ContentTypeEditor({ collection, isNew, isSaving, onSave, onAddField, on
11928
12147
  className: "bg-kumo-tint px-1.5 py-0.5 rounded",
11929
12148
  children: collection?.slug
11930
12149
  }), isFromCode && /* @__PURE__ */ jsx("span", {
11931
- className: "ml-2 text-purple-600 dark:text-purple-400",
12150
+ className: "ms-2 text-purple-600 dark:text-purple-400",
11932
12151
  children: "Defined in code"
11933
12152
  })]
11934
12153
  })]
@@ -12250,7 +12469,7 @@ function FieldRow({ field, isFromCode, onEdit, onDelete }) {
12250
12469
  !isFromCode && /* @__PURE__ */ jsx("button", {
12251
12470
  ...attributes,
12252
12471
  ...listeners,
12253
- className: "cursor-grab active:cursor-grabbing mr-3",
12472
+ className: "cursor-grab active:cursor-grabbing me-3",
12254
12473
  "aria-label": `Drag to reorder ${field.label}`,
12255
12474
  children: /* @__PURE__ */ jsx(DotsSixVertical, { className: "h-5 w-5 text-kumo-subtle" })
12256
12475
  }),
@@ -12370,7 +12589,7 @@ function ContentTypeList({ collections, orphanedTables, isLoading, onDelete, onR
12370
12589
  to: "/content-types/new",
12371
12590
  className: buttonVariants(),
12372
12591
  children: [/* @__PURE__ */ jsx(Plus, {
12373
- className: "mr-2 h-4 w-4",
12592
+ className: "me-2 h-4 w-4",
12374
12593
  "aria-hidden": "true"
12375
12594
  }), _t({
12376
12595
  id: "NFFxa9",
@@ -12407,7 +12626,7 @@ function ContentTypeList({ collections, orphanedTables, isLoading, onDelete, onR
12407
12626
  className: "text-sm font-medium",
12408
12627
  children: orphan.slug
12409
12628
  }), /* @__PURE__ */ jsx("span", {
12410
- className: "text-xs text-kumo-subtle ml-2",
12629
+ className: "text-xs text-kumo-subtle ms-2",
12411
12630
  children: i18n._({
12412
12631
  id: "JcH6Wc",
12413
12632
  message: "{0, plural, one {(# item)} other {(# items)}}",
@@ -12438,7 +12657,7 @@ function ContentTypeList({ collections, orphanedTables, isLoading, onDelete, onR
12438
12657
  children: [
12439
12658
  /* @__PURE__ */ jsx("th", {
12440
12659
  scope: "col",
12441
- className: "px-4 py-3 text-left text-sm font-medium",
12660
+ className: "px-4 py-3 text-start text-sm font-medium",
12442
12661
  children: _t({
12443
12662
  id: "6YtxFj",
12444
12663
  message: "Name"
@@ -12446,7 +12665,7 @@ function ContentTypeList({ collections, orphanedTables, isLoading, onDelete, onR
12446
12665
  }),
12447
12666
  /* @__PURE__ */ jsx("th", {
12448
12667
  scope: "col",
12449
- className: "px-4 py-3 text-left text-sm font-medium",
12668
+ className: "px-4 py-3 text-start text-sm font-medium",
12450
12669
  children: _t({
12451
12670
  id: "L85WcV",
12452
12671
  message: "Slug"
@@ -12454,7 +12673,7 @@ function ContentTypeList({ collections, orphanedTables, isLoading, onDelete, onR
12454
12673
  }),
12455
12674
  /* @__PURE__ */ jsx("th", {
12456
12675
  scope: "col",
12457
- className: "px-4 py-3 text-left text-sm font-medium",
12676
+ className: "px-4 py-3 text-start text-sm font-medium",
12458
12677
  children: _t({
12459
12678
  id: "wdxz7K",
12460
12679
  message: "Source"
@@ -12462,7 +12681,7 @@ function ContentTypeList({ collections, orphanedTables, isLoading, onDelete, onR
12462
12681
  }),
12463
12682
  /* @__PURE__ */ jsx("th", {
12464
12683
  scope: "col",
12465
- className: "px-4 py-3 text-left text-sm font-medium",
12684
+ className: "px-4 py-3 text-start text-sm font-medium",
12466
12685
  children: _t({
12467
12686
  id: "PpZkda",
12468
12687
  message: "Features"
@@ -12470,7 +12689,7 @@ function ContentTypeList({ collections, orphanedTables, isLoading, onDelete, onR
12470
12689
  }),
12471
12690
  /* @__PURE__ */ jsx("th", {
12472
12691
  scope: "col",
12473
- className: "px-4 py-3 text-right text-sm font-medium",
12692
+ className: "px-4 py-3 text-end text-sm font-medium",
12474
12693
  children: _t({
12475
12694
  id: "7L01XJ",
12476
12695
  message: "Actions"
@@ -12586,7 +12805,7 @@ function ContentTypeRow({ collection, onRequestDelete }) {
12586
12805
  })
12587
12806
  }),
12588
12807
  /* @__PURE__ */ jsx("td", {
12589
- className: "px-4 py-3 text-right",
12808
+ className: "px-4 py-3 text-end",
12590
12809
  children: /* @__PURE__ */ jsxs("div", {
12591
12810
  className: "flex items-center justify-end space-x-1",
12592
12811
  children: [/* @__PURE__ */ jsx(Link$1, {
@@ -14661,8 +14880,8 @@ function LoginPage({ redirectUrl = "/_emdash/admin" }) {
14661
14880
  if (manifestLoading || manifest?.authMode && manifest.authMode !== "passkey") return /* @__PURE__ */ jsx("div", {
14662
14881
  className: "min-h-screen flex items-center justify-center bg-kumo-base p-4",
14663
14882
  children: /* @__PURE__ */ jsxs("div", {
14664
- className: "text-center",
14665
- children: [/* @__PURE__ */ jsx(LogoLockup, { className: "h-10 mx-auto mb-4" }), /* @__PURE__ */ jsx(Loader, {})]
14883
+ className: "flex flex-col items-center",
14884
+ children: [/* @__PURE__ */ jsx(LogoLockup, { className: "h-10 mb-4" }), /* @__PURE__ */ jsx(Loader, {})]
14666
14885
  })
14667
14886
  });
14668
14887
  return /* @__PURE__ */ jsx("div", {
@@ -14725,7 +14944,7 @@ function LoginPage({ redirectUrl = "/_emdash/admin" }) {
14725
14944
  onClick: () => handleOAuthClick(provider.id),
14726
14945
  className: "w-full justify-center",
14727
14946
  children: [provider.icon, /* @__PURE__ */ jsx("span", {
14728
- className: "ml-2",
14947
+ className: "ms-2",
14729
14948
  children: provider.name
14730
14949
  })]
14731
14950
  }, provider.id))
@@ -14765,12 +14984,17 @@ function LoginPage({ redirectUrl = "/_emdash/admin" }) {
14765
14984
  })
14766
14985
  }),
14767
14986
  SUPPORTED_LOCALES.length > 1 && /* @__PURE__ */ jsx("div", {
14768
- className: "mt-6 flex justify-center gap-2 text-xs text-kumo-subtle",
14769
- children: SUPPORTED_LOCALES.map((l, i) => /* @__PURE__ */ jsxs(React.Fragment, { children: [i > 0 && /* @__PURE__ */ jsx("span", { children: "·" }), /* @__PURE__ */ jsx("button", {
14770
- onClick: () => setLocale(l.code),
14771
- className: l.code === locale ? "font-medium text-kumo-default" : "hover:text-kumo-default transition-colors",
14772
- children: l.label
14773
- })] }, l.code))
14987
+ className: "mt-6 flex justify-center",
14988
+ children: /* @__PURE__ */ jsx(Select, {
14989
+ "aria-label": _t2({
14990
+ id: "vXIe7J",
14991
+ message: "Language"
14992
+ }),
14993
+ className: "w-48",
14994
+ value: locale,
14995
+ onValueChange: (v) => v && setLocale(v),
14996
+ items: Object.fromEntries(SUPPORTED_LOCALES.map((l) => [l.code, l.label]))
14997
+ })
14774
14998
  })
14775
14999
  ]
14776
15000
  })
@@ -14851,7 +15075,7 @@ function MarketplaceBrowse({ installedPluginIds = /* @__PURE__ */ new Set() }) {
14851
15075
  children: [
14852
15076
  /* @__PURE__ */ jsxs("div", {
14853
15077
  className: "relative flex-1",
14854
- children: [/* @__PURE__ */ jsx(MagnifyingGlass, { className: "absolute left-3 top-1/2 h-4 w-4 -translate-y-1/2 text-kumo-subtle" }), /* @__PURE__ */ jsx("input", {
15078
+ children: [/* @__PURE__ */ jsx(MagnifyingGlass, { className: "absolute start-3 top-1/2 h-4 w-4 -translate-y-1/2 text-kumo-subtle" }), /* @__PURE__ */ jsx("input", {
14855
15079
  type: "search",
14856
15080
  placeholder: _t({
14857
15081
  id: "slq1pb",
@@ -14859,7 +15083,7 @@ function MarketplaceBrowse({ installedPluginIds = /* @__PURE__ */ new Set() }) {
14859
15083
  }),
14860
15084
  value: searchQuery,
14861
15085
  onChange: (e) => setSearchQuery(e.target.value),
14862
- className: "w-full rounded-md border bg-kumo-base px-3 py-2 pl-9 text-sm placeholder:text-kumo-subtle focus:outline-none focus:ring-2 focus:ring-kumo-ring"
15086
+ className: "w-full rounded-md border bg-kumo-base px-3 py-2 ps-9 text-sm placeholder:text-kumo-subtle focus:outline-none focus:ring-2 focus:ring-kumo-ring"
14863
15087
  })]
14864
15088
  }),
14865
15089
  /* @__PURE__ */ jsxs("select", {
@@ -14921,7 +15145,7 @@ function MarketplaceBrowse({ installedPluginIds = /* @__PURE__ */ new Set() }) {
14921
15145
  variant: "ghost",
14922
15146
  className: "mt-4",
14923
15147
  onClick: () => void refetch(),
14924
- children: [/* @__PURE__ */ jsx(ArrowsClockwise, { className: "mr-2 h-4 w-4" }), _t({
15148
+ children: [/* @__PURE__ */ jsx(ArrowsClockwise, { className: "me-2 h-4 w-4" }), _t({
14925
15149
  id: "6gRgw8",
14926
15150
  message: "Retry"
14927
15151
  })]
@@ -15179,7 +15403,7 @@ function CapabilityConsentDialog({ mode, pluginName, capabilities, allowedHosts,
15179
15403
  className: cn(isNew && "font-medium"),
15180
15404
  children: describeCapability(cap, allowedHosts)
15181
15405
  }), isNew && /* @__PURE__ */ jsx("span", {
15182
- className: "ml-2 text-xs text-warning font-medium",
15406
+ className: "ms-2 text-xs text-warning font-medium",
15183
15407
  children: _t({
15184
15408
  id: "p6NueD",
15185
15409
  message: "NEW"
@@ -15375,7 +15599,7 @@ function PluginManager({ manifest }) {
15375
15599
  variant: "ghost",
15376
15600
  onClick: () => void refetchUpdates(),
15377
15601
  disabled: isCheckingUpdates,
15378
- children: [/* @__PURE__ */ jsx(ArrowsClockwise, { className: cn("mr-2 h-4 w-4", isCheckingUpdates && "animate-spin") }), _t({
15602
+ children: [/* @__PURE__ */ jsx(ArrowsClockwise, { className: cn("me-2 h-4 w-4", isCheckingUpdates && "animate-spin") }), _t({
15379
15603
  id: "WMCwmR",
15380
15604
  message: "Check for updates"
15381
15605
  })]
@@ -15384,7 +15608,7 @@ function PluginManager({ manifest }) {
15384
15608
  to: "/plugins/marketplace",
15385
15609
  children: /* @__PURE__ */ jsxs(Button, {
15386
15610
  variant: "ghost",
15387
- children: [/* @__PURE__ */ jsx(Storefront, { className: "mr-2 h-4 w-4" }), _t({
15611
+ children: [/* @__PURE__ */ jsx(Storefront, { className: "me-2 h-4 w-4" }), _t({
15388
15612
  id: "Zt5PUS",
15389
15613
  message: "Marketplace"
15390
15614
  })]
@@ -15637,7 +15861,7 @@ function PluginCard({ plugin, updateInfo, onEnable, onDisable, isToggling, hasMa
15637
15861
  children: /* @__PURE__ */ jsxs(Button, {
15638
15862
  variant: "ghost",
15639
15863
  size: "sm",
15640
- children: [/* @__PURE__ */ jsx(Storefront, { className: "mr-1.5 h-3.5 w-3.5" }), _t2({
15864
+ children: [/* @__PURE__ */ jsx(Storefront, { className: "me-1.5 h-3.5 w-3.5" }), _t2({
15641
15865
  id: "w1kDNj",
15642
15866
  message: "View in Marketplace"
15643
15867
  })]
@@ -15796,7 +16020,7 @@ function PluginCard({ plugin, updateInfo, onEnable, onDisable, isToggling, hasMa
15796
16020
  className: "text-kumo-danger hover:text-kumo-danger",
15797
16021
  onClick: () => setShowUninstallConfirm(true),
15798
16022
  disabled: uninstallMutation.isPending,
15799
- children: [/* @__PURE__ */ jsx(Trash, { className: "mr-2 h-4 w-4" }), _t2({
16023
+ children: [/* @__PURE__ */ jsx(Trash, { className: "me-2 h-4 w-4" }), _t2({
15800
16024
  id: "fo0VXg",
15801
16025
  message: "Uninstall"
15802
16026
  })]
@@ -16081,7 +16305,7 @@ function MarketplacePluginDetail({ pluginId, installedPluginIds = /* @__PURE__ *
16081
16305
  })]
16082
16306
  }) : /* @__PURE__ */ jsxs(Button, {
16083
16307
  onClick: () => setShowConsent(true),
16084
- children: [/* @__PURE__ */ jsx(DownloadSimple, { className: "mr-2 h-4 w-4" }), _t({
16308
+ children: [/* @__PURE__ */ jsx(DownloadSimple, { className: "me-2 h-4 w-4" }), _t({
16085
16309
  id: "TKQ7K+",
16086
16310
  message: "Install"
16087
16311
  })]
@@ -16325,7 +16549,7 @@ function ScreenshotLightbox({ screenshots, index, isBlurred = false, onClose, on
16325
16549
  children: [
16326
16550
  /* @__PURE__ */ jsx("button", {
16327
16551
  onClick: onClose,
16328
- className: "absolute right-4 top-4 rounded-full bg-black/50 p-2 text-white hover:bg-black/70",
16552
+ className: "absolute end-4 top-4 rounded-full bg-black/50 p-2 text-white hover:bg-black/70",
16329
16553
  "aria-label": _t3({
16330
16554
  id: "yz7wBu",
16331
16555
  message: "Close"
@@ -16334,7 +16558,7 @@ function ScreenshotLightbox({ screenshots, index, isBlurred = false, onClose, on
16334
16558
  }),
16335
16559
  index > 0 && /* @__PURE__ */ jsx("button", {
16336
16560
  onClick: () => onNavigate(index - 1),
16337
- className: "absolute left-4 rounded-full bg-black/50 p-2 text-white hover:bg-black/70",
16561
+ className: "absolute start-4 rounded-full bg-black/50 p-2 text-white hover:bg-black/70",
16338
16562
  "aria-label": _t3({
16339
16563
  id: "k7xxm/",
16340
16564
  message: "Previous screenshot"
@@ -16355,7 +16579,7 @@ function ScreenshotLightbox({ screenshots, index, isBlurred = false, onClose, on
16355
16579
  }),
16356
16580
  index < screenshots.length - 1 && /* @__PURE__ */ jsx("button", {
16357
16581
  onClick: () => onNavigate(index + 1),
16358
- className: "absolute right-4 rounded-full bg-black/50 p-2 text-white hover:bg-black/70",
16582
+ className: "absolute end-4 rounded-full bg-black/50 p-2 text-white hover:bg-black/70",
16359
16583
  "aria-label": _t3({
16360
16584
  id: "tgnDjk",
16361
16585
  message: "Next screenshot"
@@ -16363,7 +16587,7 @@ function ScreenshotLightbox({ screenshots, index, isBlurred = false, onClose, on
16363
16587
  children: /* @__PURE__ */ jsx(CaretRight, { className: "h-5 w-5" })
16364
16588
  }),
16365
16589
  /* @__PURE__ */ jsxs("div", {
16366
- className: "absolute bottom-4 left-1/2 -translate-x-1/2 rounded-full bg-black/50 px-3 py-1 text-sm text-white",
16590
+ className: "absolute bottom-4 start-1/2 -translate-x-1/2 rounded-full bg-black/50 px-3 py-1 text-sm text-white",
16367
16591
  children: [
16368
16592
  index + 1,
16369
16593
  " / ",
@@ -16528,12 +16752,12 @@ function MediaDetailPanel({ item, onClose, onDeleted }) {
16528
16752
  const isVideo = item.mimeType.startsWith("video/");
16529
16753
  const isAudio = item.mimeType.startsWith("audio/");
16530
16754
  return /* @__PURE__ */ jsxs(Fragment, { children: [/* @__PURE__ */ jsxs("div", {
16531
- className: cn("fixed inset-y-0 right-0 w-96 bg-kumo-base border-l shadow-xl z-50", "flex flex-col", "animate-in slide-in-from-right duration-200"),
16755
+ className: cn("fixed inset-y-0 end-0 w-96 bg-kumo-base border-s shadow-xl z-50", "flex flex-col"),
16532
16756
  children: [
16533
16757
  /* @__PURE__ */ jsxs("div", {
16534
16758
  className: "flex items-center justify-between p-4 border-b",
16535
16759
  children: [/* @__PURE__ */ jsx("h2", {
16536
- className: "font-semibold truncate pr-2",
16760
+ className: "font-semibold truncate pe-2",
16537
16761
  children: _t({
16538
16762
  id: "T9un00",
16539
16763
  message: "Media Details"
@@ -17084,7 +17308,7 @@ function MediaLibrary({ items = [], isLoading, onUpload, onDelete, onItemUpdated
17084
17308
  }),
17085
17309
  canSearch && /* @__PURE__ */ jsxs("div", {
17086
17310
  className: "relative max-w-sm",
17087
- children: [/* @__PURE__ */ jsx(MagnifyingGlass, { className: "absolute left-3 top-1/2 -translate-y-1/2 h-4 w-4 text-kumo-subtle" }), /* @__PURE__ */ jsx(Input, {
17311
+ children: [/* @__PURE__ */ jsx(MagnifyingGlass, { className: "absolute start-3 top-1/2 -translate-y-1/2 h-4 w-4 text-kumo-subtle" }), /* @__PURE__ */ jsx(Input, {
17088
17312
  type: "search",
17089
17313
  placeholder: _t({
17090
17314
  id: "YIix5Y",
@@ -17092,7 +17316,7 @@ function MediaLibrary({ items = [], isLoading, onUpload, onDelete, onItemUpdated
17092
17316
  }),
17093
17317
  value: searchQuery,
17094
17318
  onChange: (e) => setSearchQuery(e.target.value),
17095
- className: "pl-9"
17319
+ className: "ps-9"
17096
17320
  })]
17097
17321
  }),
17098
17322
  currentLoading ? /* @__PURE__ */ jsx("div", {
@@ -17193,35 +17417,35 @@ function MediaLibrary({ items = [], isLoading, onUpload, onDelete, onItemUpdated
17193
17417
  className: "border-b bg-kumo-tint/50",
17194
17418
  children: [
17195
17419
  /* @__PURE__ */ jsx("th", {
17196
- className: "px-4 py-3 text-left text-sm font-medium",
17420
+ className: "px-4 py-3 text-start text-sm font-medium",
17197
17421
  children: _t({
17198
17422
  id: "rdUucN",
17199
17423
  message: "Preview"
17200
17424
  })
17201
17425
  }),
17202
17426
  /* @__PURE__ */ jsx("th", {
17203
- className: "px-4 py-3 text-left text-sm font-medium",
17427
+ className: "px-4 py-3 text-start text-sm font-medium",
17204
17428
  children: _t({
17205
17429
  id: "GN6L5F",
17206
17430
  message: "Filename"
17207
17431
  })
17208
17432
  }),
17209
17433
  /* @__PURE__ */ jsx("th", {
17210
- className: "px-4 py-3 text-left text-sm font-medium",
17434
+ className: "px-4 py-3 text-start text-sm font-medium",
17211
17435
  children: _t({
17212
17436
  id: "+zy2Nq",
17213
17437
  message: "Type"
17214
17438
  })
17215
17439
  }),
17216
17440
  /* @__PURE__ */ jsx("th", {
17217
- className: "px-4 py-3 text-left text-sm font-medium",
17441
+ className: "px-4 py-3 text-start text-sm font-medium",
17218
17442
  children: _t({
17219
17443
  id: "Cj2Gtd",
17220
17444
  message: "Size"
17221
17445
  })
17222
17446
  }),
17223
17447
  /* @__PURE__ */ jsx("th", {
17224
- className: "px-4 py-3 text-right text-sm font-medium",
17448
+ className: "px-4 py-3 text-end text-sm font-medium",
17225
17449
  children: _t({
17226
17450
  id: "7L01XJ",
17227
17451
  message: "Actions"
@@ -17274,7 +17498,7 @@ function MediaGridItem({ item, selected, onClick }) {
17274
17498
  return /* @__PURE__ */ jsxs("button", {
17275
17499
  type: "button",
17276
17500
  onClick,
17277
- className: cn("group relative overflow-hidden rounded-lg border bg-kumo-base text-left transition-all max-w-[200px]", selected ? "ring-2 ring-kumo-brand border-kumo-brand" : "hover:border-kumo-brand/50"),
17501
+ className: cn("group relative overflow-hidden rounded-lg border bg-kumo-base text-start transition-all max-w-[200px]", selected ? "ring-2 ring-kumo-brand border-kumo-brand" : "hover:border-kumo-brand/50"),
17278
17502
  children: [/* @__PURE__ */ jsx("div", {
17279
17503
  className: "aspect-square",
17280
17504
  children: isImage ? /* @__PURE__ */ jsx("img", {
@@ -17309,7 +17533,7 @@ function ProviderGridItem({ item, selected, onClick, onDimensionsLoaded }) {
17309
17533
  return /* @__PURE__ */ jsxs("button", {
17310
17534
  type: "button",
17311
17535
  onClick,
17312
- className: cn("group relative overflow-hidden rounded-lg border bg-kumo-base text-left transition-all max-w-[200px]", selected ? "ring-2 ring-kumo-brand border-kumo-brand" : "hover:border-kumo-brand/50"),
17536
+ className: cn("group relative overflow-hidden rounded-lg border bg-kumo-base text-start transition-all max-w-[200px]", selected ? "ring-2 ring-kumo-brand border-kumo-brand" : "hover:border-kumo-brand/50"),
17313
17537
  children: [/* @__PURE__ */ jsx("div", {
17314
17538
  className: "aspect-square",
17315
17539
  children: isImage && item.previewUrl ? /* @__PURE__ */ jsx("img", {
@@ -17370,7 +17594,7 @@ function MediaListItem({ item, selected, onClick }) {
17370
17594
  children: formatFileSize(item.size)
17371
17595
  }),
17372
17596
  /* @__PURE__ */ jsx("td", {
17373
- className: "px-4 py-3 text-right",
17597
+ className: "px-4 py-3 text-end",
17374
17598
  children: /* @__PURE__ */ jsx("span", {
17375
17599
  className: "text-sm text-kumo-subtle",
17376
17600
  children: item.alt ? _t2({
@@ -17424,7 +17648,7 @@ function ProviderListItem({ item, selected, onClick, onDimensionsLoaded }) {
17424
17648
  children: item.size ? formatFileSize(item.size) : "—"
17425
17649
  }),
17426
17650
  /* @__PURE__ */ jsx("td", {
17427
- className: "px-4 py-3 text-right",
17651
+ className: "px-4 py-3 text-end",
17428
17652
  children: /* @__PURE__ */ jsx("span", {
17429
17653
  className: "text-sm text-kumo-subtle",
17430
17654
  children: item.alt ? _t3({
@@ -17547,7 +17771,7 @@ function ContentPickerModal({ open, onOpenChange, onSelect }) {
17547
17771
  id: "yz7wBu",
17548
17772
  message: "Close"
17549
17773
  }),
17550
- className: "absolute right-4 top-4",
17774
+ className: "absolute end-4 top-4",
17551
17775
  children: [/* @__PURE__ */ jsx(X, { className: "h-4 w-4" }), /* @__PURE__ */ jsx("span", {
17552
17776
  className: "sr-only",
17553
17777
  children: _t({
@@ -17562,14 +17786,14 @@ function ContentPickerModal({ open, onOpenChange, onSelect }) {
17562
17786
  className: "flex items-center gap-4 py-4 border-b",
17563
17787
  children: [/* @__PURE__ */ jsxs("div", {
17564
17788
  className: "relative flex-1",
17565
- children: [/* @__PURE__ */ jsx(MagnifyingGlass, { className: "absolute left-3 top-1/2 -translate-y-1/2 h-4 w-4 text-kumo-subtle" }), /* @__PURE__ */ jsx(Input, {
17789
+ children: [/* @__PURE__ */ jsx(MagnifyingGlass, { className: "absolute start-3 top-1/2 -translate-y-1/2 h-4 w-4 text-kumo-subtle" }), /* @__PURE__ */ jsx(Input, {
17566
17790
  placeholder: _t({
17567
17791
  id: "uqgkuX",
17568
17792
  message: "Search content..."
17569
17793
  }),
17570
17794
  value: searchQuery,
17571
17795
  onChange: (e) => setSearchQuery(e.target.value),
17572
- className: "pl-10",
17796
+ className: "ps-10",
17573
17797
  autoFocus: true
17574
17798
  })]
17575
17799
  }), /* @__PURE__ */ jsx("select", {
@@ -17629,7 +17853,7 @@ function ContentPickerModal({ open, onOpenChange, onSelect }) {
17629
17853
  return /* @__PURE__ */ jsxs("button", {
17630
17854
  type: "button",
17631
17855
  onClick: () => handleSelect(item),
17632
- className: cn("w-full text-left rounded-md px-3 py-2 transition-colors", "hover:bg-kumo-tint/50", "focus:outline-none focus:ring-2 focus:ring-kumo-ring focus:ring-offset-2"),
17856
+ className: cn("w-full text-start rounded-md px-3 py-2 transition-colors", "hover:bg-kumo-tint/50", "focus:outline-none focus:ring-2 focus:ring-kumo-ring focus:ring-offset-2"),
17633
17857
  children: [/* @__PURE__ */ jsx("div", {
17634
17858
  className: "font-medium",
17635
17859
  children: getItemTitle(item)
@@ -17960,7 +18184,7 @@ function MenuEditor() {
17960
18184
  id: "yz7wBu",
17961
18185
  message: "Close"
17962
18186
  }),
17963
- className: "absolute right-4 top-4",
18187
+ className: "absolute end-4 top-4",
17964
18188
  children: [/* @__PURE__ */ jsx(X, { className: "h-4 w-4" }), /* @__PURE__ */ jsx("span", {
17965
18189
  className: "sr-only",
17966
18190
  children: _t({
@@ -18206,7 +18430,7 @@ function MenuEditor() {
18206
18430
  id: "yz7wBu",
18207
18431
  message: "Close"
18208
18432
  }),
18209
- className: "absolute right-4 top-4",
18433
+ className: "absolute end-4 top-4",
18210
18434
  children: [/* @__PURE__ */ jsx(X, { className: "h-4 w-4" }), /* @__PURE__ */ jsx("span", {
18211
18435
  className: "sr-only",
18212
18436
  children: _t({
@@ -18444,7 +18668,7 @@ function MenuList() {
18444
18668
  id: "yz7wBu",
18445
18669
  message: "Close"
18446
18670
  }),
18447
- className: "absolute right-4 top-4",
18671
+ className: "absolute end-4 top-4",
18448
18672
  children: [/* @__PURE__ */ jsx(X, { className: "h-4 w-4" }), /* @__PURE__ */ jsx("span", {
18449
18673
  className: "sr-only",
18450
18674
  children: _t({
@@ -18580,7 +18804,7 @@ function MenuList() {
18580
18804
  variant: "outline",
18581
18805
  size: "sm"
18582
18806
  }),
18583
- children: [/* @__PURE__ */ jsx(Pencil, { className: "h-4 w-4 mr-2" }), _t({
18807
+ children: [/* @__PURE__ */ jsx(Pencil, { className: "h-4 w-4 me-2" }), _t({
18584
18808
  id: "ePK91l",
18585
18809
  message: "Edit"
18586
18810
  })]
@@ -18705,7 +18929,7 @@ function RedirectFormDialog({ open, onClose, redirect, defaultSource }) {
18705
18929
  id: "yz7wBu",
18706
18930
  message: "Close"
18707
18931
  }),
18708
- className: "absolute right-4 top-4",
18932
+ className: "absolute end-4 top-4",
18709
18933
  children: /* @__PURE__ */ jsx(X, { className: "h-4 w-4" })
18710
18934
  })
18711
18935
  })]
@@ -18856,7 +19080,7 @@ function NotFoundPanel({ items, onCreateRedirect }) {
18856
19080
  })
18857
19081
  }),
18858
19082
  /* @__PURE__ */ jsx("div", {
18859
- className: "w-16 text-right",
19083
+ className: "w-16 text-end",
18860
19084
  children: _t2({
18861
19085
  id: "m8rC/C",
18862
19086
  message: "Hits"
@@ -18879,7 +19103,7 @@ function NotFoundPanel({ items, onCreateRedirect }) {
18879
19103
  children: item.path
18880
19104
  }),
18881
19105
  /* @__PURE__ */ jsx("div", {
18882
- className: "w-16 text-right tabular-nums",
19106
+ className: "w-16 text-end tabular-nums",
18883
19107
  children: item.count
18884
19108
  }),
18885
19109
  /* @__PURE__ */ jsx("div", {
@@ -19006,7 +19230,7 @@ function Redirects() {
19006
19230
  message: "Redirects"
19007
19231
  }), redirectsQuery.data && /* @__PURE__ */ jsxs(Badge, {
19008
19232
  variant: "secondary",
19009
- className: "ml-2",
19233
+ className: "ms-2",
19010
19234
  children: [redirectsQuery.data.items.length, redirectsQuery.data.nextCursor ? "+" : ""]
19011
19235
  })]
19012
19236
  }), /* @__PURE__ */ jsx("button", {
@@ -19025,14 +19249,14 @@ function Redirects() {
19025
19249
  /* @__PURE__ */ jsxs("div", {
19026
19250
  className: "relative flex-1 max-w-md",
19027
19251
  children: [/* @__PURE__ */ jsx(MagnifyingGlass, {
19028
- className: "absolute left-3 top-1/2 -translate-y-1/2 text-kumo-subtle",
19252
+ className: "absolute start-3 top-1/2 -translate-y-1/2 text-kumo-subtle",
19029
19253
  size: 16
19030
19254
  }), /* @__PURE__ */ jsx(Input, {
19031
19255
  placeholder: _t3({
19032
19256
  id: "coyvwq",
19033
19257
  message: "Search source or destination..."
19034
19258
  }),
19035
- className: "pl-10",
19259
+ className: "ps-10",
19036
19260
  value: search,
19037
19261
  onChange: (e) => setSearch(e.target.value)
19038
19262
  })]
@@ -19181,7 +19405,7 @@ function Redirects() {
19181
19405
  })
19182
19406
  }),
19183
19407
  /* @__PURE__ */ jsx("div", {
19184
- className: "w-16 text-right",
19408
+ className: "w-16 text-end",
19185
19409
  children: _t3({
19186
19410
  id: "m8rC/C",
19187
19411
  message: "Hits"
@@ -19221,7 +19445,7 @@ function Redirects() {
19221
19445
  })
19222
19446
  }),
19223
19447
  /* @__PURE__ */ jsx("div", {
19224
- className: "w-16 text-right tabular-nums text-kumo-subtle",
19448
+ className: "w-16 text-end tabular-nums text-kumo-subtle",
19225
19449
  children: r.hits
19226
19450
  }),
19227
19451
  /* @__PURE__ */ jsx("div", {
@@ -19249,7 +19473,7 @@ function Redirects() {
19249
19473
  id: "Ny5fJL",
19250
19474
  message: "Part of a redirect loop"
19251
19475
  }),
19252
- className: "mr-1 inline-flex",
19476
+ className: "me-1 inline-flex",
19253
19477
  children: /* @__PURE__ */ jsx(WarningCircle, {
19254
19478
  size: 14,
19255
19479
  weight: "fill",
@@ -19263,7 +19487,7 @@ function Redirects() {
19263
19487
  }),
19264
19488
  r.auto && /* @__PURE__ */ jsx(Badge, {
19265
19489
  variant: "outline",
19266
- className: "mr-1 text-xs",
19490
+ className: "me-1 text-xs",
19267
19491
  children: _t3({
19268
19492
  id: "VS9ghV",
19269
19493
  message: "auto"
@@ -19417,7 +19641,7 @@ function SandboxedPluginPage({ pluginId, page }) {
19417
19641
  return /* @__PURE__ */ jsxs("div", {
19418
19642
  className: "relative",
19419
19643
  children: [toast && /* @__PURE__ */ jsx("div", {
19420
- className: `fixed right-4 top-4 z-50 rounded-lg border px-4 py-3 text-sm shadow-lg ${toast.type === "success" ? "border-green-200 bg-green-50 text-green-800" : toast.type === "error" ? "border-red-200 bg-red-50 text-red-800" : "border-blue-200 bg-blue-50 text-blue-800"}`,
19644
+ className: `fixed end-4 top-4 z-50 rounded-lg border px-4 py-3 text-sm shadow-lg ${toast.type === "success" ? "border-green-200 bg-green-50 text-green-800" : toast.type === "error" ? "border-red-200 bg-red-50 text-red-800" : "border-blue-200 bg-blue-50 text-blue-800"}`,
19421
19645
  children: toast.message
19422
19646
  }), /* @__PURE__ */ jsx(BlockRenderer, {
19423
19647
  blocks,
@@ -19878,7 +20102,7 @@ function Sections() {
19878
20102
  id: "yz7wBu",
19879
20103
  message: "Close"
19880
20104
  }),
19881
- className: "absolute right-4 top-4",
20105
+ className: "absolute end-4 top-4",
19882
20106
  children: [/* @__PURE__ */ jsx(X, { className: "h-4 w-4" }), /* @__PURE__ */ jsx("span", {
19883
20107
  className: "sr-only",
19884
20108
  children: _t({
@@ -19972,14 +20196,14 @@ function Sections() {
19972
20196
  className: "flex items-center gap-4",
19973
20197
  children: [/* @__PURE__ */ jsxs("div", {
19974
20198
  className: "relative flex-1 max-w-md",
19975
- children: [/* @__PURE__ */ jsx(MagnifyingGlass, { className: "absolute left-3 top-1/2 -translate-y-1/2 h-4 w-4 text-kumo-subtle" }), /* @__PURE__ */ jsx(Input, {
20199
+ children: [/* @__PURE__ */ jsx(MagnifyingGlass, { className: "absolute start-3 top-1/2 -translate-y-1/2 h-4 w-4 text-kumo-subtle" }), /* @__PURE__ */ jsx(Input, {
19976
20200
  placeholder: _t({
19977
20201
  id: "qPx4oA",
19978
20202
  message: "Search sections..."
19979
20203
  }),
19980
20204
  value: searchQuery,
19981
20205
  onChange: (e) => setSearchQuery(e.target.value),
19982
- className: "pl-10"
20206
+ className: "ps-10"
19983
20207
  })]
19984
20208
  }), /* @__PURE__ */ jsxs("select", {
19985
20209
  value: selectedSource || "",
@@ -20943,7 +21167,7 @@ function AllowedDomainsSettings() {
20943
21167
  id: "yz7wBu",
20944
21168
  message: "Close"
20945
21169
  }),
20946
- className: "absolute right-4 top-4",
21170
+ className: "absolute end-4 top-4",
20947
21171
  children: [/* @__PURE__ */ jsx(X, { className: "h-4 w-4" }), /* @__PURE__ */ jsx("span", {
20948
21172
  className: "sr-only",
20949
21173
  children: _t({
@@ -23553,7 +23777,7 @@ function StepIndicator$1({ currentStep, useAccessAuth }) {
23553
23777
  })
23554
23778
  }) : index + 1
23555
23779
  }), /* @__PURE__ */ jsx("span", {
23556
- className: `ml-2 text-sm ${index <= currentIndex ? "text-kumo-default" : "text-kumo-subtle"}`,
23780
+ className: `ms-2 text-sm ${index <= currentIndex ? "text-kumo-default" : "text-kumo-subtle"}`,
23557
23781
  children: step.label
23558
23782
  })]
23559
23783
  }), index < steps.length - 1 && /* @__PURE__ */ jsx("div", { className: `w-12 h-0.5 mx-2 ${index < currentIndex ? "bg-kumo-brand" : "bg-kumo-tint"}` })] }, step.key))
@@ -24103,7 +24327,7 @@ function NavMenuLink({ item, isActive }) {
24103
24327
  className: cn("emdash-nav-icon size-[18px] shrink-0 transition-colors duration-200", isActive ? "text-white" : "text-white/60 group-hover/menu-button:text-white/90"),
24104
24328
  "aria-hidden": "true"
24105
24329
  }), /* @__PURE__ */ jsxs("span", {
24106
- className: "emdash-nav-label flex flex-1 items-center min-w-0 text-left overflow-hidden",
24330
+ className: "emdash-nav-label flex flex-1 items-center min-w-0 text-start overflow-hidden",
24107
24331
  children: [item.label, item.badge != null && item.badge > 0 && /* @__PURE__ */ jsx(KumoSidebar.MenuBadge, { children: item.badge })]
24108
24332
  })]
24109
24333
  });
@@ -24455,36 +24679,48 @@ function SidebarNav({ manifest }) {
24455
24679
  visibleContent.length > 1 && /* @__PURE__ */ jsxs(KumoSidebar.Group, {
24456
24680
  collapsible: true,
24457
24681
  defaultOpen: true,
24458
- children: [/* @__PURE__ */ jsx(KumoSidebar.GroupLabel, { children: _t({
24459
- id: "4b3oEV",
24460
- message: "Content"
24461
- }) }), /* @__PURE__ */ jsx(KumoSidebar.GroupContent, { children: /* @__PURE__ */ jsx(KumoSidebar.Menu, { children: renderNavItems(visibleContent.filter((i) => i.to !== "/")) }) })]
24682
+ children: [/* @__PURE__ */ jsx(KumoSidebar.GroupLabel, {
24683
+ className: "[&>span]:text-start",
24684
+ children: _t({
24685
+ id: "4b3oEV",
24686
+ message: "Content"
24687
+ })
24688
+ }), /* @__PURE__ */ jsx(KumoSidebar.GroupContent, { children: /* @__PURE__ */ jsx(KumoSidebar.Menu, { children: renderNavItems(visibleContent.filter((i) => i.to !== "/")) }) })]
24462
24689
  }),
24463
24690
  /* @__PURE__ */ jsx(KumoSidebar.Separator, {}),
24464
24691
  visibleManage.length > 0 && /* @__PURE__ */ jsxs(KumoSidebar.Group, {
24465
24692
  collapsible: true,
24466
24693
  defaultOpen: true,
24467
- children: [/* @__PURE__ */ jsx(KumoSidebar.GroupLabel, { children: _t({
24468
- id: "wckWOP",
24469
- message: "Manage"
24470
- }) }), /* @__PURE__ */ jsx(KumoSidebar.GroupContent, { children: /* @__PURE__ */ jsx(KumoSidebar.Menu, { children: renderNavItems(visibleManage) }) })]
24694
+ children: [/* @__PURE__ */ jsx(KumoSidebar.GroupLabel, {
24695
+ className: "[&>span]:text-start",
24696
+ children: _t({
24697
+ id: "wckWOP",
24698
+ message: "Manage"
24699
+ })
24700
+ }), /* @__PURE__ */ jsx(KumoSidebar.GroupContent, { children: /* @__PURE__ */ jsx(KumoSidebar.Menu, { children: renderNavItems(visibleManage) }) })]
24471
24701
  }),
24472
24702
  /* @__PURE__ */ jsx(KumoSidebar.Separator, {}),
24473
24703
  visibleAdmin.length > 0 && /* @__PURE__ */ jsxs(KumoSidebar.Group, {
24474
24704
  collapsible: true,
24475
24705
  defaultOpen: true,
24476
- children: [/* @__PURE__ */ jsx(KumoSidebar.GroupLabel, { children: _t({
24477
- id: "U3pytU",
24478
- message: "Admin"
24479
- }) }), /* @__PURE__ */ jsx(KumoSidebar.GroupContent, { children: /* @__PURE__ */ jsx(KumoSidebar.Menu, { children: renderNavItems(visibleAdmin) }) })]
24706
+ children: [/* @__PURE__ */ jsx(KumoSidebar.GroupLabel, {
24707
+ className: "[&>span]:text-start",
24708
+ children: _t({
24709
+ id: "U3pytU",
24710
+ message: "Admin"
24711
+ })
24712
+ }), /* @__PURE__ */ jsx(KumoSidebar.GroupContent, { children: /* @__PURE__ */ jsx(KumoSidebar.Menu, { children: renderNavItems(visibleAdmin) }) })]
24480
24713
  }),
24481
24714
  visiblePlugins.length > 0 && /* @__PURE__ */ jsxs(Fragment, { children: [/* @__PURE__ */ jsx(KumoSidebar.Separator, {}), /* @__PURE__ */ jsxs(KumoSidebar.Group, {
24482
24715
  collapsible: true,
24483
24716
  defaultOpen: true,
24484
- children: [/* @__PURE__ */ jsx(KumoSidebar.GroupLabel, { children: _t({
24485
- id: "ohUJJM",
24486
- message: "Plugins"
24487
- }) }), /* @__PURE__ */ jsx(KumoSidebar.GroupContent, { children: /* @__PURE__ */ jsx(KumoSidebar.Menu, { children: renderNavItems(visiblePlugins) }) })]
24717
+ children: [/* @__PURE__ */ jsx(KumoSidebar.GroupLabel, {
24718
+ className: "[&>span]:text-start",
24719
+ children: _t({
24720
+ id: "ohUJJM",
24721
+ message: "Plugins"
24722
+ })
24723
+ }), /* @__PURE__ */ jsx(KumoSidebar.GroupContent, { children: /* @__PURE__ */ jsx(KumoSidebar.Menu, { children: renderNavItems(visiblePlugins) }) })]
24488
24724
  })] })
24489
24725
  ] }),
24490
24726
  /* @__PURE__ */ jsx(KumoSidebar.Footer, { children: /* @__PURE__ */ jsxs("p", {
@@ -24583,7 +24819,7 @@ function Header() {
24583
24819
  const initials = ((user?.name || user?.email || "U")[0] ?? "U").toUpperCase();
24584
24820
  return /* @__PURE__ */ jsxs("header", {
24585
24821
  className: "sticky top-0 z-10 flex h-16 items-center justify-between border-b bg-kumo-base px-4",
24586
- children: [/* @__PURE__ */ jsx(KumoSidebar.Trigger, { className: "cursor-pointer" }), /* @__PURE__ */ jsxs("div", {
24822
+ children: [/* @__PURE__ */ jsx(KumoSidebar.Trigger, { className: "cursor-pointer rtl:rotate-180" }), /* @__PURE__ */ jsxs("div", {
24587
24823
  className: "flex items-center gap-2",
24588
24824
  children: [
24589
24825
  /* @__PURE__ */ jsxs(LinkButton, {
@@ -24591,7 +24827,7 @@ function Header() {
24591
24827
  size: "sm",
24592
24828
  href: "/",
24593
24829
  external: true,
24594
- children: [/* @__PURE__ */ jsx(ArrowSquareOut, { className: "h-4 w-4 mr-1" }), _t({
24830
+ children: [/* @__PURE__ */ jsx(ArrowSquareOut, { className: "h-4 w-4 me-1" }), _t({
24595
24831
  id: "4/SFQS",
24596
24832
  message: "View Site"
24597
24833
  })]
@@ -24657,7 +24893,7 @@ function Header() {
24657
24893
  /* @__PURE__ */ jsx("hr", { className: "my-1" }),
24658
24894
  /* @__PURE__ */ jsxs("button", {
24659
24895
  onClick: handleLogout,
24660
- className: "flex items-center gap-2 rounded-md px-3 py-2 text-sm text-kumo-danger hover:bg-kumo-danger/10 w-full text-left",
24896
+ className: "flex items-center gap-2 rounded-md px-3 py-2 text-sm text-kumo-danger hover:bg-kumo-danger/10 w-full text-start",
24661
24897
  children: [/* @__PURE__ */ jsx(SignOut, { className: "h-4 w-4" }), _t({
24662
24898
  id: "FgAxTj",
24663
24899
  message: "Log out"
@@ -24800,7 +25036,7 @@ function WelcomeModal({ open, onClose, userName, userRole }) {
24800
25036
  variant: "ghost",
24801
25037
  shape: "square",
24802
25038
  "aria-label": _t(MSG_CLOSE),
24803
- className: "absolute right-4 top-4",
25039
+ className: "absolute end-4 top-4",
24804
25040
  children: [/* @__PURE__ */ jsx(X, { className: "h-4 w-4" }), /* @__PURE__ */ jsx("span", {
24805
25041
  className: "sr-only",
24806
25042
  children: _t(MSG_CLOSE)
@@ -25454,7 +25690,7 @@ function TermRow({ term, level = 0, onEdit, onDelete }) {
25454
25690
  className: "font-medium",
25455
25691
  children: term.label
25456
25692
  }), /* @__PURE__ */ jsxs("span", {
25457
- className: "text-sm text-kumo-subtle ml-2",
25693
+ className: "text-sm text-kumo-subtle ms-2",
25458
25694
  children: [
25459
25695
  "(",
25460
25696
  term.slug,
@@ -25621,7 +25857,7 @@ function TermFormDialog({ open, onClose, taxonomyName, taxonomyDef, term, allTer
25621
25857
  id: "yz7wBu",
25622
25858
  message: "Close"
25623
25859
  }),
25624
- className: "absolute right-4 top-4",
25860
+ className: "absolute end-4 top-4",
25625
25861
  children: [/* @__PURE__ */ jsx(X, { className: "h-4 w-4" }), /* @__PURE__ */ jsx("span", {
25626
25862
  className: "sr-only",
25627
25863
  children: _t2({
@@ -25847,7 +26083,7 @@ function CreateTaxonomyDialog({ open, onClose, onCreated }) {
25847
26083
  id: "yz7wBu",
25848
26084
  message: "Close"
25849
26085
  }),
25850
- className: "absolute right-4 top-4",
26086
+ className: "absolute end-4 top-4",
25851
26087
  children: [/* @__PURE__ */ jsx(X, { className: "h-4 w-4" }), /* @__PURE__ */ jsx("span", {
25852
26088
  className: "sr-only",
25853
26089
  children: _t3({
@@ -26232,7 +26468,7 @@ function ThemeMarketplaceBrowse() {
26232
26468
  className: "flex flex-col gap-3 sm:flex-row sm:items-center",
26233
26469
  children: [/* @__PURE__ */ jsxs("div", {
26234
26470
  className: "relative flex-1",
26235
- children: [/* @__PURE__ */ jsx(MagnifyingGlass, { className: "absolute left-3 top-1/2 h-4 w-4 -translate-y-1/2 text-kumo-subtle" }), /* @__PURE__ */ jsx("input", {
26471
+ children: [/* @__PURE__ */ jsx(MagnifyingGlass, { className: "absolute start-3 top-1/2 h-4 w-4 -translate-y-1/2 text-kumo-subtle" }), /* @__PURE__ */ jsx("input", {
26236
26472
  type: "search",
26237
26473
  placeholder: _t({
26238
26474
  id: "uD5EVk",
@@ -26240,7 +26476,7 @@ function ThemeMarketplaceBrowse() {
26240
26476
  }),
26241
26477
  value: searchQuery,
26242
26478
  onChange: (e) => setSearchQuery(e.target.value),
26243
- className: "w-full rounded-md border bg-kumo-base px-3 py-2 pl-9 text-sm placeholder:text-kumo-subtle focus:outline-none focus:ring-2 focus:ring-kumo-ring"
26479
+ className: "w-full rounded-md border bg-kumo-base px-3 py-2 ps-9 text-sm placeholder:text-kumo-subtle focus:outline-none focus:ring-2 focus:ring-kumo-ring"
26244
26480
  })]
26245
26481
  }), /* @__PURE__ */ jsx("select", {
26246
26482
  value: sort,
@@ -26281,7 +26517,7 @@ function ThemeMarketplaceBrowse() {
26281
26517
  variant: "ghost",
26282
26518
  className: "mt-4",
26283
26519
  onClick: () => void refetch(),
26284
- children: [/* @__PURE__ */ jsx(ArrowsClockwise, { className: "mr-2 h-4 w-4" }), _t({
26520
+ children: [/* @__PURE__ */ jsx(ArrowsClockwise, { className: "me-2 h-4 w-4" }), _t({
26285
26521
  id: "6gRgw8",
26286
26522
  message: "Retry"
26287
26523
  })]
@@ -26404,7 +26640,7 @@ function ThemeCard({ theme }) {
26404
26640
  previewMutation.mutate();
26405
26641
  },
26406
26642
  disabled: previewMutation.isPending,
26407
- children: [/* @__PURE__ */ jsx(Eye, { className: "mr-1.5 h-3.5 w-3.5" }), previewMutation.isPending ? _t2({
26643
+ children: [/* @__PURE__ */ jsx(Eye, { className: "me-1.5 h-3.5 w-3.5" }), previewMutation.isPending ? _t2({
26408
26644
  id: "Z3FXyt",
26409
26645
  message: "Loading..."
26410
26646
  }) : _t2({
@@ -26415,7 +26651,7 @@ function ThemeCard({ theme }) {
26415
26651
  variant: "ghost",
26416
26652
  size: "sm",
26417
26653
  onClick: () => window.open(theme.demoUrl, "_blank", "noopener"),
26418
- children: [/* @__PURE__ */ jsx(ArrowSquareOut, { className: "mr-1.5 h-3.5 w-3.5" }), _t2({
26654
+ children: [/* @__PURE__ */ jsx(ArrowSquareOut, { className: "me-1.5 h-3.5 w-3.5" }), _t2({
26419
26655
  id: "kc+zZA",
26420
26656
  message: "Demo"
26421
26657
  })]
@@ -26550,7 +26786,7 @@ function ThemeMarketplaceDetail({ themeId }) {
26550
26786
  variant: "primary",
26551
26787
  onClick: () => previewMutation.mutate(),
26552
26788
  disabled: previewMutation.isPending,
26553
- children: [/* @__PURE__ */ jsx(Eye, { className: "mr-2 h-4 w-4" }), previewMutation.isPending ? _t({
26789
+ children: [/* @__PURE__ */ jsx(Eye, { className: "me-2 h-4 w-4" }), previewMutation.isPending ? _t({
26554
26790
  id: "Z3FXyt",
26555
26791
  message: "Loading..."
26556
26792
  }) : _t({
@@ -26560,7 +26796,7 @@ function ThemeMarketplaceDetail({ themeId }) {
26560
26796
  }), theme.demoUrl && isSafeUrl(theme.demoUrl) && /* @__PURE__ */ jsxs(Button, {
26561
26797
  variant: "outline",
26562
26798
  onClick: () => window.open(theme.demoUrl, "_blank", "noopener"),
26563
- children: [/* @__PURE__ */ jsx(ArrowSquareOut, { className: "mr-2 h-4 w-4" }), _t({
26799
+ children: [/* @__PURE__ */ jsx(ArrowSquareOut, { className: "me-2 h-4 w-4" }), _t({
26564
26800
  id: "kc+zZA",
26565
26801
  message: "Demo"
26566
26802
  })]
@@ -26698,7 +26934,7 @@ function Lightbox({ urls, index, onClose, onPrev, onNext }) {
26698
26934
  }),
26699
26935
  /* @__PURE__ */ jsx("button", {
26700
26936
  onClick: onClose,
26701
- className: "absolute -top-3 -right-3 rounded-full bg-kumo-base p-1.5 shadow-lg hover:bg-kumo-tint",
26937
+ className: "absolute -top-3 -end-3 rounded-full bg-kumo-base p-1.5 shadow-lg hover:bg-kumo-tint",
26702
26938
  "aria-label": _t2({
26703
26939
  id: "yz7wBu",
26704
26940
  message: "Close"
@@ -26707,7 +26943,7 @@ function Lightbox({ urls, index, onClose, onPrev, onNext }) {
26707
26943
  }),
26708
26944
  urls.length > 1 && /* @__PURE__ */ jsxs(Fragment, { children: [/* @__PURE__ */ jsx("button", {
26709
26945
  onClick: onPrev,
26710
- className: "absolute left-2 top-1/2 -translate-y-1/2 rounded-full bg-kumo-base/80 p-2 shadow hover:bg-kumo-base",
26946
+ className: "absolute start-2 top-1/2 -translate-y-1/2 rounded-full bg-kumo-base/80 p-2 shadow hover:bg-kumo-base",
26711
26947
  "aria-label": _t2({
26712
26948
  id: "DHhJ7s",
26713
26949
  message: "Previous"
@@ -26715,7 +26951,7 @@ function Lightbox({ urls, index, onClose, onPrev, onNext }) {
26715
26951
  children: /* @__PURE__ */ jsx(CaretLeft, { className: "h-5 w-5" })
26716
26952
  }), /* @__PURE__ */ jsx("button", {
26717
26953
  onClick: onNext,
26718
- className: "absolute right-2 top-1/2 -translate-y-1/2 rounded-full bg-kumo-base/80 p-2 shadow hover:bg-kumo-base",
26954
+ className: "absolute end-2 top-1/2 -translate-y-1/2 rounded-full bg-kumo-base/80 p-2 shadow hover:bg-kumo-base",
26719
26955
  "aria-label": _t2({
26720
26956
  id: "hXzOVo",
26721
26957
  message: "Next"
@@ -26723,7 +26959,7 @@ function Lightbox({ urls, index, onClose, onPrev, onNext }) {
26723
26959
  children: /* @__PURE__ */ jsx(CaretRight, { className: "h-5 w-5" })
26724
26960
  })] }),
26725
26961
  /* @__PURE__ */ jsxs("div", {
26726
- className: "absolute bottom-2 left-1/2 -translate-x-1/2 rounded-full bg-kumo-base/80 px-3 py-1 text-xs",
26962
+ className: "absolute bottom-2 start-1/2 -translate-x-1/2 rounded-full bg-kumo-base/80 px-3 py-1 text-xs",
26727
26963
  children: [
26728
26964
  index + 1,
26729
26965
  " / ",
@@ -26735,6 +26971,18 @@ function Lightbox({ urls, index, onClose, onPrev, onNext }) {
26735
26971
  });
26736
26972
  }
26737
26973
 
26974
+ //#endregion
26975
+ //#region src/lib/pluginBlocks.ts
26976
+ /** Extract plugin block definitions from the manifest for the Portable Text editor. */
26977
+ function getPluginBlocks(manifest) {
26978
+ const blocks = [];
26979
+ for (const [pluginId, plugin] of Object.entries(manifest.plugins)) if (plugin.portableTextBlocks) for (const block of plugin.portableTextBlocks) blocks.push({
26980
+ ...block,
26981
+ pluginId
26982
+ });
26983
+ return blocks;
26984
+ }
26985
+
26738
26986
  //#endregion
26739
26987
  //#region src/components/Widgets.tsx
26740
26988
  /**
@@ -26789,6 +27037,11 @@ function Widgets() {
26789
27037
  queryKey: ["widget-components"],
26790
27038
  queryFn: fetchWidgetComponents
26791
27039
  });
27040
+ const { data: manifest } = useQuery({
27041
+ queryKey: ["manifest"],
27042
+ queryFn: fetchManifest
27043
+ });
27044
+ const pluginBlocks = React.useMemo(() => manifest ? getPluginBlocks(manifest) : [], [manifest]);
26792
27045
  const createAreaMutation = useMutation({
26793
27046
  mutationFn: createWidgetArea,
26794
27047
  onSuccess: () => {
@@ -26948,7 +27201,7 @@ function Widgets() {
26948
27201
  variant: "ghost",
26949
27202
  shape: "square",
26950
27203
  "aria-label": "Close",
26951
- className: "absolute right-4 top-4",
27204
+ className: "absolute end-4 top-4",
26952
27205
  children: [/* @__PURE__ */ jsx(X, { className: "h-4 w-4" }), /* @__PURE__ */ jsx("span", {
26953
27206
  className: "sr-only",
26954
27207
  children: "Close"
@@ -27046,7 +27299,8 @@ function Widgets() {
27046
27299
  expandedWidgets,
27047
27300
  onToggleWidget: toggleWidget,
27048
27301
  isDraggingPalette: activeDragData !== null && isPaletteItem(activeDragData),
27049
- components
27302
+ components,
27303
+ pluginBlocks
27050
27304
  }, area.id))
27051
27305
  })]
27052
27306
  })]
@@ -27106,7 +27360,7 @@ function DraggablePaletteItem({ id, label, description, widgetInput }) {
27106
27360
  })]
27107
27361
  });
27108
27362
  }
27109
- function WidgetAreaPanel({ area, expandedWidgets, onToggleWidget, isDraggingPalette, components }) {
27363
+ function WidgetAreaPanel({ area, expandedWidgets, onToggleWidget, isDraggingPalette, components, pluginBlocks }) {
27110
27364
  const queryClient = useQueryClient();
27111
27365
  const toastManager = Toast.useToastManager();
27112
27366
  const [deleteAreaName, setDeleteAreaName] = React.useState(null);
@@ -27151,7 +27405,8 @@ function WidgetAreaPanel({ area, expandedWidgets, onToggleWidget, isDraggingPale
27151
27405
  areaName: area.name,
27152
27406
  isExpanded: expandedWidgets.has(widget.id),
27153
27407
  onToggle: () => onToggleWidget(widget.id),
27154
- components
27408
+ components,
27409
+ pluginBlocks
27155
27410
  }, widget.id))
27156
27411
  }) : null,
27157
27412
  isDraggingPalette && /* @__PURE__ */ jsx("div", {
@@ -27181,7 +27436,7 @@ function WidgetAreaPanel({ area, expandedWidgets, onToggleWidget, isDraggingPale
27181
27436
  ]
27182
27437
  });
27183
27438
  }
27184
- function WidgetItem({ widget, areaName, isExpanded, onToggle, components }) {
27439
+ function WidgetItem({ widget, areaName, isExpanded, onToggle, components, pluginBlocks }) {
27185
27440
  const queryClient = useQueryClient();
27186
27441
  const toastManager = Toast.useToastManager();
27187
27442
  const { attributes, listeners, setNodeRef, transform, transition, isDragging } = useSortable({
@@ -27239,7 +27494,7 @@ function WidgetItem({ widget, areaName, isExpanded, onToggle, components }) {
27239
27494
  }),
27240
27495
  /* @__PURE__ */ jsx("button", {
27241
27496
  onClick: onToggle,
27242
- className: "flex-1 text-left",
27497
+ className: "flex-1 text-start",
27243
27498
  "aria-expanded": isExpanded,
27244
27499
  children: /* @__PURE__ */ jsxs("div", {
27245
27500
  className: "flex items-center gap-2",
@@ -27271,13 +27526,14 @@ function WidgetItem({ widget, areaName, isExpanded, onToggle, components }) {
27271
27526
  }), isExpanded && /* @__PURE__ */ jsx(WidgetEditor, {
27272
27527
  widget,
27273
27528
  components,
27529
+ pluginBlocks,
27274
27530
  onSave: (input) => updateMutation.mutate(input),
27275
27531
  isSaving: updateMutation.isPending
27276
27532
  })]
27277
27533
  });
27278
27534
  }
27279
27535
  /** Inline editor form for a widget, rendered when the widget is expanded */
27280
- function WidgetEditor({ widget, components, onSave, isSaving }) {
27536
+ function WidgetEditor({ widget, components, pluginBlocks, onSave, isSaving }) {
27281
27537
  const [title, setTitle] = React.useState(widget.title ?? "");
27282
27538
  const [content, setContent] = React.useState(Array.isArray(widget.content) ? widget.content : []);
27283
27539
  const [menuName, setMenuName] = React.useState(widget.menuName ?? "");
@@ -27315,7 +27571,8 @@ function WidgetEditor({ widget, components, onSave, isSaving }) {
27315
27571
  value: content,
27316
27572
  onChange: (value) => setContent(value),
27317
27573
  minimal: true,
27318
- placeholder: "Write widget content..."
27574
+ placeholder: "Write widget content...",
27575
+ pluginBlocks
27319
27576
  })] }),
27320
27577
  widget.type === "menu" && /* @__PURE__ */ jsxs(Select, {
27321
27578
  label: "Menu",
@@ -27389,7 +27646,7 @@ function ComponentPropField({ def, value, onChange }) {
27389
27646
  });
27390
27647
  case "boolean": return /* @__PURE__ */ jsx(Switch, {
27391
27648
  label: def.label,
27392
- checked: typeof value === "boolean" ? value : false,
27649
+ checked: Boolean(value),
27393
27650
  onCheckedChange: onChange
27394
27651
  });
27395
27652
  case "select": {
@@ -28219,7 +28476,7 @@ function FeatureComparison() {
28219
28476
  className: "border-b bg-kumo-tint/20",
28220
28477
  children: [
28221
28478
  /* @__PURE__ */ jsx("th", {
28222
- className: "text-left p-3 font-medium",
28479
+ className: "text-start p-3 font-medium",
28223
28480
  children: _t3({
28224
28481
  id: "en3oy5",
28225
28482
  message: "Feature"
@@ -28320,7 +28577,7 @@ function ProbeResultStep({ result, onUploadFile, onPluginConnect, onPluginManual
28320
28577
  if (!result.isWordPress) return /* @__PURE__ */ jsxs("div", {
28321
28578
  className: "space-y-6",
28322
28579
  children: [/* @__PURE__ */ jsx("div", {
28323
- className: "rounded-lg border-l-4 border-l-orange-500 border border-kumo-line bg-kumo-base p-6",
28580
+ className: "rounded-lg border-s-4 border-s-orange-500 border border-kumo-line bg-kumo-base p-6",
28324
28581
  children: /* @__PURE__ */ jsxs("div", {
28325
28582
  className: "flex items-start gap-4",
28326
28583
  children: [/* @__PURE__ */ jsx(Warning, { className: "h-6 w-6 text-orange-500 flex-shrink-0" }), /* @__PURE__ */ jsxs("div", { children: [/* @__PURE__ */ jsx("h3", {
@@ -28404,7 +28661,7 @@ function ProbeResultStep({ result, onUploadFile, onPluginConnect, onPluginManual
28404
28661
  className: "space-y-6",
28405
28662
  children: [
28406
28663
  /* @__PURE__ */ jsx("div", {
28407
- className: "rounded-lg border-l-4 border-l-green-500 border border-kumo-line bg-kumo-base p-6",
28664
+ className: "rounded-lg border-s-4 border-s-green-500 border border-kumo-line bg-kumo-base p-6",
28408
28665
  children: /* @__PURE__ */ jsxs("div", {
28409
28666
  className: "flex items-start gap-4",
28410
28667
  children: [/* @__PURE__ */ jsx(Check, { className: "h-6 w-6 text-green-500 flex-shrink-0" }), /* @__PURE__ */ jsxs("div", { children: [/* @__PURE__ */ jsx("h3", {
@@ -28472,7 +28729,7 @@ function ProbeResultStep({ result, onUploadFile, onPluginConnect, onPluginManual
28472
28729
  }),
28473
28730
  !hasPlugin && /* @__PURE__ */ jsx(FeatureComparison, {}),
28474
28731
  hasPlugin && /* @__PURE__ */ jsx("div", {
28475
- className: "rounded-lg border-l-4 border-l-green-500 border border-kumo-line bg-kumo-base p-6",
28732
+ className: "rounded-lg border-s-4 border-s-green-500 border border-kumo-line bg-kumo-base p-6",
28476
28733
  children: /* @__PURE__ */ jsxs("div", {
28477
28734
  className: "flex items-start gap-4",
28478
28735
  children: [/* @__PURE__ */ jsx("div", {
@@ -28714,7 +28971,7 @@ function PluginAuthStep({ siteTitle, siteUrl, username, password, onUsernameChan
28714
28971
  })
28715
28972
  ]
28716
28973
  }), /* @__PURE__ */ jsx("div", {
28717
- className: "rounded-lg border-l-4 border-l-blue-500 border border-kumo-line bg-kumo-base p-4",
28974
+ className: "rounded-lg border-s-4 border-s-blue-500 border border-kumo-line bg-kumo-base p-4",
28718
28975
  children: /* @__PURE__ */ jsxs("div", {
28719
28976
  className: "flex gap-3",
28720
28977
  children: [/* @__PURE__ */ jsx(ArrowSquareOut, { className: "h-5 w-5 text-blue-500 flex-shrink-0" }), /* @__PURE__ */ jsxs("div", {
@@ -29153,7 +29410,7 @@ function ReviewStep({ analysis, selections, expandedTypes, prepareError, importE
29153
29410
  })
29154
29411
  }),
29155
29412
  selectedCount > 0 && /* @__PURE__ */ jsx("div", {
29156
- className: "rounded-lg border-l-4 border-l-blue-500 border border-kumo-line bg-kumo-base p-4",
29413
+ className: "rounded-lg border-s-4 border-s-blue-500 border border-kumo-line bg-kumo-base p-4",
29157
29414
  children: /* @__PURE__ */ jsxs("div", {
29158
29415
  className: "flex gap-3",
29159
29416
  children: [/* @__PURE__ */ jsx(Database, { className: "h-5 w-5 text-blue-500 flex-shrink-0" }), /* @__PURE__ */ jsxs("div", {
@@ -29253,7 +29510,7 @@ function PostTypeRow({ postType, selection, expanded, onToggleExpand, onToggleEn
29253
29510
  })
29254
29511
  }), /* @__PURE__ */ jsxs("button", {
29255
29512
  onClick: onToggleExpand,
29256
- className: "flex items-center gap-1 text-left",
29513
+ className: "flex items-center gap-1 text-start",
29257
29514
  "aria-expanded": expanded,
29258
29515
  children: [expanded ? /* @__PURE__ */ jsx(CaretDown, { className: "h-4 w-4 text-kumo-subtle" }) : /* @__PURE__ */ jsx(CaretRight, { className: "h-4 w-4 text-kumo-subtle" }), /* @__PURE__ */ jsxs("div", { children: [/* @__PURE__ */ jsx("p", {
29259
29516
  className: "font-medium",
@@ -29296,11 +29553,11 @@ function PostTypeRow({ postType, selection, expanded, onToggleExpand, onToggleEn
29296
29553
  }) })
29297
29554
  })]
29298
29555
  }), expanded && /* @__PURE__ */ jsxs("div", {
29299
- className: "mt-4 ml-8 p-3 rounded-lg bg-kumo-tint/50 text-sm",
29556
+ className: "mt-4 ms-8 p-3 rounded-lg bg-kumo-tint/50 text-sm",
29300
29557
  children: [
29301
29558
  !canImport && schemaStatus.reason && /* @__PURE__ */ jsxs("div", {
29302
29559
  className: "mb-3 p-2 rounded bg-red-100 dark:bg-red-900/30 text-red-800 dark:text-red-300",
29303
- children: [/* @__PURE__ */ jsx(WarningCircle, { className: "inline h-4 w-4 mr-1" }), schemaStatus.reason]
29560
+ children: [/* @__PURE__ */ jsx(WarningCircle, { className: "inline h-4 w-4 me-1" }), schemaStatus.reason]
29304
29561
  }),
29305
29562
  /* @__PURE__ */ jsx("p", {
29306
29563
  className: "font-medium mb-2",
@@ -29428,7 +29685,7 @@ function MediaStep({ attachments, error, onImport, onSkip }) {
29428
29685
  })
29429
29686
  }),
29430
29687
  /* @__PURE__ */ jsx("div", {
29431
- className: "mt-4 p-4 rounded-lg border-l-4 border-l-blue-500 border border-kumo-line bg-kumo-base",
29688
+ className: "mt-4 p-4 rounded-lg border-s-4 border-s-blue-500 border border-kumo-line bg-kumo-base",
29432
29689
  children: /* @__PURE__ */ jsxs("div", {
29433
29690
  className: "flex gap-3",
29434
29691
  children: [/* @__PURE__ */ jsx(DownloadSimple, { className: "h-5 w-5 text-blue-500 flex-shrink-0" }), /* @__PURE__ */ jsxs("div", {
@@ -29848,7 +30105,7 @@ function AuthorMappingStep({ authorMappings, emdashUsers, onMappingChange, onCon
29848
30105
  }),
29849
30106
  matchedCount > 0 && /* @__PURE__ */ jsxs("p", {
29850
30107
  className: "text-sm text-green-600 dark:text-green-400 mt-2",
29851
- children: [/* @__PURE__ */ jsx(Check, { className: "inline h-4 w-4 mr-1" }), _t10({
30108
+ children: [/* @__PURE__ */ jsx(Check, { className: "inline h-4 w-4 me-1" }), _t10({
29852
30109
  id: "gIZkFQ",
29853
30110
  message: "{matchedCount} of {totalCount} authors matched by email",
29854
30111
  values: {
@@ -29896,7 +30153,7 @@ function AuthorMappingStep({ authorMappings, emdashUsers, onMappingChange, onCon
29896
30153
  }), /* @__PURE__ */ jsxs("p", {
29897
30154
  className: "text-sm text-kumo-subtle",
29898
30155
  children: [mapping.wpEmail || mapping.wpLogin, mapping.postCount > 0 && /* @__PURE__ */ jsxs("span", {
29899
- className: "ml-2",
30156
+ className: "ms-2",
29900
30157
  children: ["• ", i18n._({
29901
30158
  id: "S6XZwv",
29902
30159
  message: "{0, plural, one {# post} other {# posts}}",
@@ -29929,7 +30186,7 @@ function AuthorMappingStep({ authorMappings, emdashUsers, onMappingChange, onCon
29929
30186
  })]
29930
30187
  }),
29931
30188
  emdashUsers.length === 0 && /* @__PURE__ */ jsx("div", {
29932
- className: "rounded-lg border-l-4 border-l-yellow-500 border border-kumo-line bg-kumo-base p-4",
30189
+ className: "rounded-lg border-s-4 border-s-yellow-500 border border-kumo-line bg-kumo-base p-4",
29933
30190
  children: /* @__PURE__ */ jsxs("div", {
29934
30191
  className: "flex gap-3",
29935
30192
  children: [/* @__PURE__ */ jsx(Warning, { className: "h-5 w-5 text-yellow-500 flex-shrink-0" }), /* @__PURE__ */ jsxs("div", { children: [/* @__PURE__ */ jsx("p", {
@@ -30145,7 +30402,7 @@ function BylinesPage() {
30145
30402
  return /* @__PURE__ */ jsxs("button", {
30146
30403
  type: "button",
30147
30404
  onClick: () => setSelectedId(item.id),
30148
- className: `w-full rounded border p-3 text-left ${item.id === selectedId ? "border-kumo-brand bg-kumo-brand/10" : "border-kumo-line"}`,
30405
+ className: `w-full rounded border p-3 text-start ${item.id === selectedId ? "border-kumo-brand bg-kumo-brand/10" : "border-kumo-line"}`,
30149
30406
  children: [/* @__PURE__ */ jsx("p", {
30150
30407
  className: "font-medium",
30151
30408
  children: item.displayName
@@ -30297,7 +30554,7 @@ function RoleBadge({ role, size = "sm", showDescription = false, className }) {
30297
30554
  }[config.color], className),
30298
30555
  title: showDescription ? void 0 : _t(config.description),
30299
30556
  children: [_t(config.label), showDescription && /* @__PURE__ */ jsxs("span", {
30300
- className: "ml-1 opacity-75",
30557
+ className: "ms-1 opacity-75",
30301
30558
  children: ["- ", _t(config.description)]
30302
30559
  })]
30303
30560
  });
@@ -30344,12 +30601,12 @@ function UserList({ users, isLoading, hasMore, searchQuery, roleFilter, onSearch
30344
30601
  children: [/* @__PURE__ */ jsxs("div", {
30345
30602
  className: "relative flex-1 max-w-sm",
30346
30603
  children: [/* @__PURE__ */ jsx(MagnifyingGlass, {
30347
- className: "absolute left-3 top-1/2 h-4 w-4 -translate-y-1/2 text-kumo-subtle",
30604
+ className: "absolute start-3 top-1/2 h-4 w-4 -translate-y-1/2 text-kumo-subtle",
30348
30605
  "aria-hidden": "true"
30349
30606
  }), /* @__PURE__ */ jsx(Input, {
30350
30607
  type: "search",
30351
30608
  placeholder: "Search by name or email...",
30352
- className: "pl-10",
30609
+ className: "ps-10",
30353
30610
  value: searchQuery,
30354
30611
  onChange: (e) => onSearchChange(e.target.value),
30355
30612
  "aria-label": "Search users"
@@ -30374,27 +30631,27 @@ function UserList({ users, isLoading, hasMore, searchQuery, roleFilter, onSearch
30374
30631
  children: [
30375
30632
  /* @__PURE__ */ jsx("th", {
30376
30633
  scope: "col",
30377
- className: "px-4 py-3 text-left text-sm font-medium",
30634
+ className: "px-4 py-3 text-start text-sm font-medium",
30378
30635
  children: "User"
30379
30636
  }),
30380
30637
  /* @__PURE__ */ jsx("th", {
30381
30638
  scope: "col",
30382
- className: "px-4 py-3 text-left text-sm font-medium",
30639
+ className: "px-4 py-3 text-start text-sm font-medium",
30383
30640
  children: "Role"
30384
30641
  }),
30385
30642
  /* @__PURE__ */ jsx("th", {
30386
30643
  scope: "col",
30387
- className: "px-4 py-3 text-left text-sm font-medium",
30644
+ className: "px-4 py-3 text-start text-sm font-medium",
30388
30645
  children: "Status"
30389
30646
  }),
30390
30647
  /* @__PURE__ */ jsx("th", {
30391
30648
  scope: "col",
30392
- className: "px-4 py-3 text-left text-sm font-medium",
30649
+ className: "px-4 py-3 text-start text-sm font-medium",
30393
30650
  children: "Last Login"
30394
30651
  }),
30395
30652
  /* @__PURE__ */ jsx("th", {
30396
30653
  scope: "col",
30397
- className: "px-4 py-3 text-left text-sm font-medium",
30654
+ className: "px-4 py-3 text-start text-sm font-medium",
30398
30655
  children: "Passkeys"
30399
30656
  })
30400
30657
  ]
@@ -30554,14 +30811,6 @@ function UserDetail({ user, isLoading, isOpen, isSaving, isSendingRecovery, reco
30554
30811
  }
30555
30812
  }
30556
30813
  const stableOnClose = useStableCallback(onClose);
30557
- React.useEffect(() => {
30558
- const handleKeyDown = (e) => {
30559
- if (e.key === "Escape") stableOnClose();
30560
- };
30561
- document.addEventListener("keydown", handleKeyDown);
30562
- return () => document.removeEventListener("keydown", handleKeyDown);
30563
- }, [stableOnClose]);
30564
- if (!isOpen) return null;
30565
30814
  const isSelf = user && currentUserId && user.id === currentUserId;
30566
30815
  const isDirty = user && (name !== (user.name ?? "") || email !== user.email || role !== user.role);
30567
30816
  const handleSubmit = (e) => {
@@ -30573,366 +30822,362 @@ function UserDetail({ user, isLoading, isOpen, isSaving, isSendingRecovery, reco
30573
30822
  if (role !== user.role && !isSelf) data.role = role;
30574
30823
  onSave(data);
30575
30824
  };
30576
- return /* @__PURE__ */ jsxs(Fragment, { children: [/* @__PURE__ */ jsx("div", {
30577
- className: "fixed inset-0 z-40 bg-black/50",
30578
- onClick: onClose,
30579
- "aria-hidden": "true"
30580
- }), /* @__PURE__ */ jsxs("div", {
30581
- className: cn("fixed right-0 top-0 z-50 flex h-full w-full max-w-md flex-col bg-kumo-base shadow-xl", "transform transition-transform duration-200", isOpen ? "translate-x-0" : "translate-x-full"),
30582
- role: "dialog",
30583
- "aria-modal": "true",
30584
- "aria-labelledby": "user-detail-title",
30585
- children: [
30586
- /* @__PURE__ */ jsxs("div", {
30587
- className: "flex items-center justify-between border-b px-6 py-4",
30588
- children: [/* @__PURE__ */ jsx("h2", {
30589
- id: "user-detail-title",
30590
- className: "text-lg font-semibold",
30591
- children: _t({
30592
- id: "anfIXl",
30593
- message: "User Details"
30594
- })
30595
- }), /* @__PURE__ */ jsx(Button, {
30596
- variant: "ghost",
30597
- shape: "square",
30598
- onClick: onClose,
30599
- "aria-label": _t({
30600
- id: "mO95sp",
30601
- message: "Close panel"
30602
- }),
30603
- children: /* @__PURE__ */ jsx(X, {
30604
- className: "h-5 w-5",
30605
- "aria-hidden": "true"
30606
- })
30607
- })]
30608
- }),
30609
- /* @__PURE__ */ jsx("div", {
30610
- className: "flex-1 overflow-y-auto p-6",
30611
- children: isLoading ? /* @__PURE__ */ jsx(UserDetailSkeleton, {}) : user ? /* @__PURE__ */ jsxs("form", {
30612
- id: "user-edit-form",
30613
- onSubmit: handleSubmit,
30614
- className: "space-y-6",
30615
- children: [
30616
- /* @__PURE__ */ jsxs("div", {
30617
- className: "flex items-start gap-4",
30618
- children: [user.avatarUrl ? /* @__PURE__ */ jsx("img", {
30619
- src: user.avatarUrl,
30620
- alt: "",
30621
- className: "h-16 w-16 shrink-0 rounded-full object-cover"
30622
- }) : /* @__PURE__ */ jsx("div", {
30623
- className: "h-16 w-16 shrink-0 rounded-full bg-kumo-tint flex items-center justify-center text-2xl font-medium",
30624
- children: (name || email)?.[0]?.toUpperCase() ?? "?"
30625
- }), /* @__PURE__ */ jsxs("div", {
30626
- className: "flex-1 min-w-0 space-y-3",
30627
- children: [/* @__PURE__ */ jsx(Input, {
30628
- label: _t({
30629
- id: "6YtxFj",
30630
- message: "Name"
30631
- }),
30632
- value: name,
30633
- onChange: (e) => setName(e.target.value),
30634
- placeholder: _t({
30635
- id: "RI7NuK",
30636
- message: "Enter name"
30637
- })
30638
- }), /* @__PURE__ */ jsx(Input, {
30639
- label: _t({
30640
- id: "O3oNi5",
30641
- message: "Email"
30642
- }),
30643
- type: "email",
30644
- value: email,
30645
- onChange: (e) => setEmail(e.target.value),
30646
- placeholder: _t({
30647
- id: "6KnyG0",
30648
- message: "Enter email"
30649
- }),
30650
- required: true
30651
- })]
30652
- })]
30825
+ return /* @__PURE__ */ jsx(Dialog$1.Root, {
30826
+ open: isOpen,
30827
+ onOpenChange: (open) => !open && stableOnClose(),
30828
+ children: /* @__PURE__ */ jsxs(Dialog$1.Portal, { children: [/* @__PURE__ */ jsx(Dialog$1.Backdrop, { className: cn("fixed inset-0 z-40 bg-black/50 transition-opacity duration-200", "data-starting-style:opacity-0 data-ending-style:opacity-0") }), /* @__PURE__ */ jsxs(Dialog$1.Popup, {
30829
+ className: cn("fixed top-0 end-0 z-50 flex h-full w-full max-w-md flex-col bg-kumo-base shadow-xl outline-none", "transform transition-transform duration-200 ease-out", "data-starting-style:ltr:translate-x-full data-starting-style:rtl:-translate-x-full", "data-ending-style:ltr:translate-x-full data-ending-style:rtl:-translate-x-full"),
30830
+ children: [
30831
+ /* @__PURE__ */ jsxs("div", {
30832
+ className: "flex items-center justify-between border-b px-6 py-4",
30833
+ children: [/* @__PURE__ */ jsx(Dialog$1.Title, {
30834
+ className: "text-lg font-semibold",
30835
+ children: _t({
30836
+ id: "anfIXl",
30837
+ message: "User Details"
30838
+ })
30839
+ }), /* @__PURE__ */ jsx(Button, {
30840
+ variant: "ghost",
30841
+ shape: "square",
30842
+ onClick: stableOnClose,
30843
+ "aria-label": _t({
30844
+ id: "mO95sp",
30845
+ message: "Close panel"
30653
30846
  }),
30654
- /* @__PURE__ */ jsxs("div", {
30655
- className: "flex items-end gap-3",
30656
- children: [isSelf ? /* @__PURE__ */ jsxs("div", {
30657
- className: "flex-1",
30658
- children: [/* @__PURE__ */ jsx(Input, {
30659
- label: _t({
30660
- id: "GDvlUT",
30661
- message: "Role"
30662
- }),
30663
- value: getRoleLabel(role),
30664
- disabled: true,
30665
- className: "cursor-not-allowed"
30666
- }), /* @__PURE__ */ jsx("p", {
30667
- className: "text-xs text-kumo-subtle mt-1",
30668
- children: _t({
30669
- id: "e+3JRc",
30670
- message: "You cannot change your own role"
30671
- })
30672
- })]
30673
- }) : /* @__PURE__ */ jsx("div", {
30674
- className: "flex-1",
30675
- children: /* @__PURE__ */ jsx(Select, {
30676
- label: _t({
30677
- id: "GDvlUT",
30678
- message: "Role"
30679
- }),
30680
- value: role.toString(),
30681
- onValueChange: (v) => v !== null && setRole(parseInt(v, 10)),
30682
- items: roleLabels,
30683
- children: roles.map((r) => /* @__PURE__ */ jsx(Select.Option, {
30684
- value: r.value.toString(),
30685
- children: /* @__PURE__ */ jsxs("div", { children: [/* @__PURE__ */ jsx("div", { children: r.label }), /* @__PURE__ */ jsx("div", {
30686
- className: "text-xs text-kumo-subtle",
30687
- children: r.description
30688
- })] })
30689
- }, r.value))
30690
- })
30691
- }), /* @__PURE__ */ jsx("div", {
30692
- className: "pb-1",
30693
- children: user.disabled ? /* @__PURE__ */ jsxs("span", {
30694
- className: "inline-flex items-center gap-1 text-sm text-kumo-danger",
30695
- children: [/* @__PURE__ */ jsx(Prohibit, {
30696
- className: "h-3.5 w-3.5",
30697
- "aria-hidden": "true"
30698
- }), _t({
30699
- id: "E/QGRL",
30700
- message: "Disabled"
30701
- })]
30702
- }) : /* @__PURE__ */ jsxs("span", {
30703
- className: "inline-flex items-center gap-1 text-sm text-green-600 dark:text-green-400",
30704
- children: [/* @__PURE__ */ jsx(CheckCircle, {
30705
- className: "h-3.5 w-3.5",
30706
- "aria-hidden": "true"
30707
- }), _t({
30708
- id: "F6pfE9",
30709
- message: "Active"
30847
+ children: /* @__PURE__ */ jsx(X, {
30848
+ className: "h-5 w-5",
30849
+ "aria-hidden": "true"
30850
+ })
30851
+ })]
30852
+ }),
30853
+ /* @__PURE__ */ jsx("div", {
30854
+ className: "flex-1 overflow-y-auto p-6",
30855
+ children: isLoading ? /* @__PURE__ */ jsx(UserDetailSkeleton, {}) : user ? /* @__PURE__ */ jsxs("form", {
30856
+ id: "user-edit-form",
30857
+ onSubmit: handleSubmit,
30858
+ className: "space-y-6",
30859
+ children: [
30860
+ /* @__PURE__ */ jsxs("div", {
30861
+ className: "flex items-start gap-4",
30862
+ children: [user.avatarUrl ? /* @__PURE__ */ jsx("img", {
30863
+ src: user.avatarUrl,
30864
+ alt: "",
30865
+ className: "h-16 w-16 shrink-0 rounded-full object-cover"
30866
+ }) : /* @__PURE__ */ jsx("div", {
30867
+ className: "h-16 w-16 shrink-0 rounded-full bg-kumo-tint flex items-center justify-center text-2xl font-medium",
30868
+ children: (name || email)?.[0]?.toUpperCase() ?? "?"
30869
+ }), /* @__PURE__ */ jsxs("div", {
30870
+ className: "flex-1 min-w-0 space-y-3",
30871
+ children: [/* @__PURE__ */ jsx(Input, {
30872
+ label: _t({
30873
+ id: "6YtxFj",
30874
+ message: "Name"
30875
+ }),
30876
+ value: name,
30877
+ onChange: (e) => setName(e.target.value),
30878
+ placeholder: _t({
30879
+ id: "RI7NuK",
30880
+ message: "Enter name"
30881
+ })
30882
+ }), /* @__PURE__ */ jsx(Input, {
30883
+ label: _t({
30884
+ id: "O3oNi5",
30885
+ message: "Email"
30886
+ }),
30887
+ type: "email",
30888
+ value: email,
30889
+ onChange: (e) => setEmail(e.target.value),
30890
+ placeholder: _t({
30891
+ id: "6KnyG0",
30892
+ message: "Enter email"
30893
+ }),
30894
+ required: true
30710
30895
  })]
30711
- })
30712
- })]
30713
- }),
30714
- /* @__PURE__ */ jsxs("div", {
30715
- className: "grid gap-4",
30716
- children: [
30717
- /* @__PURE__ */ jsxs("div", {
30718
- className: "rounded-lg border p-4",
30719
- children: [/* @__PURE__ */ jsx("h4", {
30720
- className: "text-sm font-medium text-kumo-subtle mb-3",
30896
+ })]
30897
+ }),
30898
+ /* @__PURE__ */ jsxs("div", {
30899
+ className: "flex items-end gap-3",
30900
+ children: [isSelf ? /* @__PURE__ */ jsxs("div", {
30901
+ className: "flex-1",
30902
+ children: [/* @__PURE__ */ jsx(Input, {
30903
+ label: _t({
30904
+ id: "GDvlUT",
30905
+ message: "Role"
30906
+ }),
30907
+ value: getRoleLabel(role),
30908
+ disabled: true,
30909
+ className: "cursor-not-allowed"
30910
+ }), /* @__PURE__ */ jsx("p", {
30911
+ className: "text-xs text-kumo-subtle mt-1",
30721
30912
  children: _t({
30722
- id: "NPGiDn",
30723
- message: "Account Info"
30913
+ id: "e+3JRc",
30914
+ message: "You cannot change your own role"
30724
30915
  })
30725
- }), /* @__PURE__ */ jsxs("div", {
30726
- className: "space-y-2 text-sm",
30727
- children: [
30728
- /* @__PURE__ */ jsxs("div", {
30729
- className: "flex justify-between",
30730
- children: [/* @__PURE__ */ jsx("span", {
30731
- className: "text-kumo-subtle",
30732
- children: _t({
30733
- id: "d+F6q9",
30734
- message: "Created"
30735
- })
30736
- }), /* @__PURE__ */ jsx("span", { children: new Date(user.createdAt).toLocaleDateString() })]
30737
- }),
30738
- /* @__PURE__ */ jsxs("div", {
30739
- className: "flex justify-between",
30740
- children: [/* @__PURE__ */ jsx("span", {
30741
- className: "text-kumo-subtle",
30742
- children: _t({
30743
- id: "C3yOz3",
30744
- message: "Last updated"
30745
- })
30746
- }), /* @__PURE__ */ jsx("span", { children: new Date(user.updatedAt).toLocaleDateString() })]
30747
- }),
30748
- /* @__PURE__ */ jsxs("div", {
30749
- className: "flex justify-between",
30750
- children: [/* @__PURE__ */ jsx("span", {
30751
- className: "text-kumo-subtle",
30752
- children: _t({
30753
- id: "I3yitW",
30754
- message: "Last login"
30755
- })
30756
- }), /* @__PURE__ */ jsx("span", { children: user.lastLogin ? new Date(user.lastLogin).toLocaleDateString() : _t({
30757
- id: "qqeAJM",
30758
- message: "Never"
30759
- }) })]
30760
- }),
30761
- /* @__PURE__ */ jsxs("div", {
30762
- className: "flex justify-between",
30763
- children: [/* @__PURE__ */ jsx("span", {
30764
- className: "text-kumo-subtle",
30765
- children: _t({
30766
- id: "PLEl94",
30767
- message: "Email verified"
30768
- })
30769
- }), /* @__PURE__ */ jsx("span", { children: user.emailVerified ? _t({
30770
- id: "l75CjT",
30771
- message: "Yes"
30772
- }) : _t({
30773
- id: "1UzENP",
30774
- message: "No"
30775
- }) })]
30776
- })
30777
- ]
30778
30916
  })]
30779
- }),
30780
- /* @__PURE__ */ jsxs("div", {
30781
- className: "rounded-lg border p-4",
30782
- children: [/* @__PURE__ */ jsxs("h4", {
30783
- className: "text-sm font-medium text-kumo-subtle mb-3 flex items-center gap-2",
30784
- children: [/* @__PURE__ */ jsx(Key, {
30785
- className: "h-4 w-4",
30917
+ }) : /* @__PURE__ */ jsx("div", {
30918
+ className: "flex-1",
30919
+ children: /* @__PURE__ */ jsx(Select, {
30920
+ label: _t({
30921
+ id: "GDvlUT",
30922
+ message: "Role"
30923
+ }),
30924
+ value: role.toString(),
30925
+ onValueChange: (v) => v !== null && setRole(parseInt(v, 10)),
30926
+ items: roleLabels,
30927
+ children: roles.map((r) => /* @__PURE__ */ jsx(Select.Option, {
30928
+ value: r.value.toString(),
30929
+ children: /* @__PURE__ */ jsxs("div", { children: [/* @__PURE__ */ jsx("div", { children: r.label }), /* @__PURE__ */ jsx("div", {
30930
+ className: "text-xs text-kumo-subtle",
30931
+ children: r.description
30932
+ })] })
30933
+ }, r.value))
30934
+ })
30935
+ }), /* @__PURE__ */ jsx("div", {
30936
+ className: "pb-1",
30937
+ children: user.disabled ? /* @__PURE__ */ jsxs("span", {
30938
+ className: "inline-flex items-center gap-1 text-sm text-kumo-danger",
30939
+ children: [/* @__PURE__ */ jsx(Prohibit, {
30940
+ className: "h-3.5 w-3.5",
30786
30941
  "aria-hidden": "true"
30787
30942
  }), _t({
30788
- id: "ChKSdm",
30789
- message: "Passkeys ({0})",
30790
- values: { 0: user.credentials.length }
30943
+ id: "E/QGRL",
30944
+ message: "Disabled"
30791
30945
  })]
30792
- }), user.credentials.length === 0 ? /* @__PURE__ */ jsx("p", {
30793
- className: "text-sm text-kumo-subtle",
30794
- children: _t({
30795
- id: "foMWA+",
30796
- message: "No passkeys registered"
30797
- })
30798
- }) : /* @__PURE__ */ jsx("div", {
30799
- className: "space-y-2",
30800
- children: user.credentials.map((cred) => /* @__PURE__ */ jsxs("div", {
30801
- className: "flex justify-between text-sm",
30802
- children: [/* @__PURE__ */ jsxs("div", { children: [/* @__PURE__ */ jsx("div", { children: cred.name || _t({
30803
- id: "xowKks",
30804
- message: "Unnamed passkey"
30805
- }) }), /* @__PURE__ */ jsx("div", {
30806
- className: "text-xs text-kumo-subtle",
30807
- children: cred.deviceType === "multiDevice" ? _t({
30808
- id: "N2FcBE",
30809
- message: "Synced"
30810
- }) : _t({
30811
- id: "tuIPad",
30812
- message: "Device-bound"
30946
+ }) : /* @__PURE__ */ jsxs("span", {
30947
+ className: "inline-flex items-center gap-1 text-sm text-green-600 dark:text-green-400",
30948
+ children: [/* @__PURE__ */ jsx(CheckCircle, {
30949
+ className: "h-3.5 w-3.5",
30950
+ "aria-hidden": "true"
30951
+ }), _t({
30952
+ id: "F6pfE9",
30953
+ message: "Active"
30954
+ })]
30955
+ })
30956
+ })]
30957
+ }),
30958
+ /* @__PURE__ */ jsxs("div", {
30959
+ className: "grid gap-4",
30960
+ children: [
30961
+ /* @__PURE__ */ jsxs("div", {
30962
+ className: "rounded-lg border p-4",
30963
+ children: [/* @__PURE__ */ jsx("h4", {
30964
+ className: "text-sm font-medium text-kumo-subtle mb-3",
30965
+ children: _t({
30966
+ id: "NPGiDn",
30967
+ message: "Account Info"
30968
+ })
30969
+ }), /* @__PURE__ */ jsxs("div", {
30970
+ className: "space-y-2 text-sm",
30971
+ children: [
30972
+ /* @__PURE__ */ jsxs("div", {
30973
+ className: "flex justify-between",
30974
+ children: [/* @__PURE__ */ jsx("span", {
30975
+ className: "text-kumo-subtle",
30976
+ children: _t({
30977
+ id: "d+F6q9",
30978
+ message: "Created"
30979
+ })
30980
+ }), /* @__PURE__ */ jsx("span", { children: new Date(user.createdAt).toLocaleDateString() })]
30981
+ }),
30982
+ /* @__PURE__ */ jsxs("div", {
30983
+ className: "flex justify-between",
30984
+ children: [/* @__PURE__ */ jsx("span", {
30985
+ className: "text-kumo-subtle",
30986
+ children: _t({
30987
+ id: "C3yOz3",
30988
+ message: "Last updated"
30989
+ })
30990
+ }), /* @__PURE__ */ jsx("span", { children: new Date(user.updatedAt).toLocaleDateString() })]
30991
+ }),
30992
+ /* @__PURE__ */ jsxs("div", {
30993
+ className: "flex justify-between",
30994
+ children: [/* @__PURE__ */ jsx("span", {
30995
+ className: "text-kumo-subtle",
30996
+ children: _t({
30997
+ id: "I3yitW",
30998
+ message: "Last login"
30999
+ })
31000
+ }), /* @__PURE__ */ jsx("span", { children: user.lastLogin ? new Date(user.lastLogin).toLocaleDateString() : _t({
31001
+ id: "qqeAJM",
31002
+ message: "Never"
31003
+ }) })]
31004
+ }),
31005
+ /* @__PURE__ */ jsxs("div", {
31006
+ className: "flex justify-between",
31007
+ children: [/* @__PURE__ */ jsx("span", {
31008
+ className: "text-kumo-subtle",
31009
+ children: _t({
31010
+ id: "PLEl94",
31011
+ message: "Email verified"
31012
+ })
31013
+ }), /* @__PURE__ */ jsx("span", { children: user.emailVerified ? _t({
31014
+ id: "l75CjT",
31015
+ message: "Yes"
31016
+ }) : _t({
31017
+ id: "1UzENP",
31018
+ message: "No"
31019
+ }) })]
30813
31020
  })
30814
- })] }), /* @__PURE__ */ jsxs("div", {
30815
- className: "text-right text-kumo-subtle",
30816
- children: [/* @__PURE__ */ jsx("div", { children: _t({
30817
- id: "MXSt4t",
30818
- message: "Created {0}",
30819
- values: { 0: new Date(cred.createdAt).toLocaleDateString() }
31021
+ ]
31022
+ })]
31023
+ }),
31024
+ /* @__PURE__ */ jsxs("div", {
31025
+ className: "rounded-lg border p-4",
31026
+ children: [/* @__PURE__ */ jsxs("h4", {
31027
+ className: "text-sm font-medium text-kumo-subtle mb-3 flex items-center gap-2",
31028
+ children: [/* @__PURE__ */ jsx(Key, {
31029
+ className: "h-4 w-4",
31030
+ "aria-hidden": "true"
31031
+ }), _t({
31032
+ id: "ChKSdm",
31033
+ message: "Passkeys ({0})",
31034
+ values: { 0: user.credentials.length }
31035
+ })]
31036
+ }), user.credentials.length === 0 ? /* @__PURE__ */ jsx("p", {
31037
+ className: "text-sm text-kumo-subtle",
31038
+ children: _t({
31039
+ id: "foMWA+",
31040
+ message: "No passkeys registered"
31041
+ })
31042
+ }) : /* @__PURE__ */ jsx("div", {
31043
+ className: "space-y-2",
31044
+ children: user.credentials.map((cred) => /* @__PURE__ */ jsxs("div", {
31045
+ className: "flex justify-between text-sm",
31046
+ children: [/* @__PURE__ */ jsxs("div", { children: [/* @__PURE__ */ jsx("div", { children: cred.name || _t({
31047
+ id: "xowKks",
31048
+ message: "Unnamed passkey"
30820
31049
  }) }), /* @__PURE__ */ jsx("div", {
30821
- className: "text-xs",
30822
- children: _t({
30823
- id: "ylo1I0",
30824
- message: "Last used {0}",
30825
- values: { 0: new Date(cred.lastUsedAt).toLocaleDateString() }
31050
+ className: "text-xs text-kumo-subtle",
31051
+ children: cred.deviceType === "multiDevice" ? _t({
31052
+ id: "N2FcBE",
31053
+ message: "Synced"
31054
+ }) : _t({
31055
+ id: "tuIPad",
31056
+ message: "Device-bound"
30826
31057
  })
31058
+ })] }), /* @__PURE__ */ jsxs("div", {
31059
+ className: "text-end text-kumo-subtle",
31060
+ children: [/* @__PURE__ */ jsx("div", { children: _t({
31061
+ id: "MXSt4t",
31062
+ message: "Created {0}",
31063
+ values: { 0: new Date(cred.createdAt).toLocaleDateString() }
31064
+ }) }), /* @__PURE__ */ jsx("div", {
31065
+ className: "text-xs",
31066
+ children: _t({
31067
+ id: "ylo1I0",
31068
+ message: "Last used {0}",
31069
+ values: { 0: new Date(cred.lastUsedAt).toLocaleDateString() }
31070
+ })
31071
+ })]
30827
31072
  })]
30828
- })]
30829
- }, cred.id))
30830
- })]
30831
- }),
30832
- user.oauthAccounts.length > 0 && /* @__PURE__ */ jsxs("div", {
30833
- className: "rounded-lg border p-4",
30834
- children: [/* @__PURE__ */ jsxs("h4", {
30835
- className: "text-sm font-medium text-kumo-subtle mb-3 flex items-center gap-2",
30836
- children: [/* @__PURE__ */ jsx(ArrowSquareOut, {
30837
- className: "h-4 w-4",
30838
- "aria-hidden": "true"
30839
- }), _t({
30840
- id: "V89WqR",
30841
- message: "Linked Accounts ({0})",
30842
- values: { 0: user.oauthAccounts.length }
31073
+ }, cred.id))
30843
31074
  })]
30844
- }), /* @__PURE__ */ jsx("div", {
30845
- className: "space-y-2",
30846
- children: user.oauthAccounts.map((account, i) => /* @__PURE__ */ jsxs("div", {
30847
- className: "flex justify-between text-sm",
30848
- children: [/* @__PURE__ */ jsx("span", {
30849
- className: "capitalize",
30850
- children: account.provider
30851
- }), /* @__PURE__ */ jsx("span", {
30852
- className: "text-kumo-subtle",
30853
- children: _t({
30854
- id: "sk/Z5E",
30855
- message: "Connected {0}",
30856
- values: { 0: new Date(account.createdAt).toLocaleDateString() }
30857
- })
31075
+ }),
31076
+ user.oauthAccounts.length > 0 && /* @__PURE__ */ jsxs("div", {
31077
+ className: "rounded-lg border p-4",
31078
+ children: [/* @__PURE__ */ jsxs("h4", {
31079
+ className: "text-sm font-medium text-kumo-subtle mb-3 flex items-center gap-2",
31080
+ children: [/* @__PURE__ */ jsx(ArrowSquareOut, {
31081
+ className: "h-4 w-4",
31082
+ "aria-hidden": "true"
31083
+ }), _t({
31084
+ id: "V89WqR",
31085
+ message: "Linked Accounts ({0})",
31086
+ values: { 0: user.oauthAccounts.length }
30858
31087
  })]
30859
- }, `${account.provider}-${i}`))
30860
- })]
30861
- })
30862
- ]
31088
+ }), /* @__PURE__ */ jsx("div", {
31089
+ className: "space-y-2",
31090
+ children: user.oauthAccounts.map((account, i) => /* @__PURE__ */ jsxs("div", {
31091
+ className: "flex justify-between text-sm",
31092
+ children: [/* @__PURE__ */ jsx("span", {
31093
+ className: "capitalize",
31094
+ children: account.provider
31095
+ }), /* @__PURE__ */ jsx("span", {
31096
+ className: "text-kumo-subtle",
31097
+ children: _t({
31098
+ id: "sk/Z5E",
31099
+ message: "Connected {0}",
31100
+ values: { 0: new Date(account.createdAt).toLocaleDateString() }
31101
+ })
31102
+ })]
31103
+ }, `${account.provider}-${i}`))
31104
+ })]
31105
+ })
31106
+ ]
31107
+ })
31108
+ ]
31109
+ }) : /* @__PURE__ */ jsx("div", {
31110
+ className: "text-center text-kumo-subtle py-8",
31111
+ children: _t({
31112
+ id: "eW9fDd",
31113
+ message: "User not found"
30863
31114
  })
30864
- ]
30865
- }) : /* @__PURE__ */ jsx("div", {
30866
- className: "text-center text-kumo-subtle py-8",
30867
- children: _t({
30868
- id: "eW9fDd",
30869
- message: "User not found"
30870
31115
  })
30871
- })
30872
- }),
30873
- user && /* @__PURE__ */ jsxs("div", {
30874
- className: "border-t px-6 py-4 space-y-2",
30875
- children: [/* @__PURE__ */ jsxs("div", {
30876
- className: "flex gap-2",
30877
- children: [/* @__PURE__ */ jsx(Button, {
30878
- type: "submit",
30879
- form: "user-edit-form",
30880
- className: "flex-1",
30881
- disabled: !isDirty || isSaving,
30882
- icon: /* @__PURE__ */ jsx(FloppyDisk, {}),
30883
- children: isSaving ? _t({
30884
- id: "XvjC4F",
30885
- message: "Saving..."
30886
- }) : _t({
30887
- id: "IUwGEM",
30888
- message: "Save Changes"
30889
- })
30890
- }), !isSelf && /* @__PURE__ */ jsx(Button, {
30891
- variant: user.disabled ? "outline" : "destructive",
30892
- onClick: user.disabled ? onEnable : onDisable,
30893
- icon: user.disabled ? /* @__PURE__ */ jsx(CheckCircle, {}) : /* @__PURE__ */ jsx(Prohibit, {}),
30894
- children: user.disabled ? _t({
30895
- id: "PaQ3df",
30896
- message: "Enable"
30897
- }) : _t({
30898
- id: "cO9+2L",
30899
- message: "Disable"
30900
- })
30901
- })]
30902
- }), !isSelf && onSendRecovery && /* @__PURE__ */ jsxs("div", {
30903
- className: "space-y-1",
30904
- children: [
30905
- /* @__PURE__ */ jsx(Button, {
30906
- variant: "outline",
30907
- className: "w-full",
30908
- onClick: onSendRecovery,
30909
- disabled: isSendingRecovery,
30910
- icon: /* @__PURE__ */ jsx(Envelope, {}),
30911
- children: isSendingRecovery ? _t({
30912
- id: "IoAuJG",
30913
- message: "Sending..."
31116
+ }),
31117
+ user && /* @__PURE__ */ jsxs("div", {
31118
+ className: "border-t px-6 py-4 space-y-2",
31119
+ children: [/* @__PURE__ */ jsxs("div", {
31120
+ className: "flex gap-2",
31121
+ children: [/* @__PURE__ */ jsx(Button, {
31122
+ type: "submit",
31123
+ form: "user-edit-form",
31124
+ className: "flex-1",
31125
+ disabled: !isDirty || isSaving,
31126
+ icon: /* @__PURE__ */ jsx(FloppyDisk, {}),
31127
+ children: isSaving ? _t({
31128
+ id: "XvjC4F",
31129
+ message: "Saving..."
30914
31130
  }) : _t({
30915
- id: "HHspu6",
30916
- message: "Send Recovery Link"
31131
+ id: "IUwGEM",
31132
+ message: "Save Changes"
30917
31133
  })
30918
- }),
30919
- recoverySent && /* @__PURE__ */ jsx("p", {
30920
- className: "text-xs text-green-600 dark:text-green-400 text-center",
30921
- children: _t({
30922
- id: "SLJUHb",
30923
- message: "Recovery link sent to {0}",
30924
- values: { 0: user.email }
31134
+ }), !isSelf && /* @__PURE__ */ jsx(Button, {
31135
+ variant: user.disabled ? "outline" : "destructive",
31136
+ onClick: user.disabled ? onEnable : onDisable,
31137
+ icon: user.disabled ? /* @__PURE__ */ jsx(CheckCircle, {}) : /* @__PURE__ */ jsx(Prohibit, {}),
31138
+ children: user.disabled ? _t({
31139
+ id: "PaQ3df",
31140
+ message: "Enable"
31141
+ }) : _t({
31142
+ id: "cO9+2L",
31143
+ message: "Disable"
30925
31144
  })
30926
- }),
30927
- recoveryError && /* @__PURE__ */ jsx("p", {
30928
- className: "text-xs text-kumo-danger text-center",
30929
- children: recoveryError
30930
- })
30931
- ]
30932
- })]
30933
- })
30934
- ]
30935
- })] });
31145
+ })]
31146
+ }), !isSelf && onSendRecovery && /* @__PURE__ */ jsxs("div", {
31147
+ className: "space-y-1",
31148
+ children: [
31149
+ /* @__PURE__ */ jsx(Button, {
31150
+ variant: "outline",
31151
+ className: "w-full",
31152
+ onClick: onSendRecovery,
31153
+ disabled: isSendingRecovery,
31154
+ icon: /* @__PURE__ */ jsx(Envelope, {}),
31155
+ children: isSendingRecovery ? _t({
31156
+ id: "IoAuJG",
31157
+ message: "Sending..."
31158
+ }) : _t({
31159
+ id: "HHspu6",
31160
+ message: "Send Recovery Link"
31161
+ })
31162
+ }),
31163
+ recoverySent && /* @__PURE__ */ jsx("p", {
31164
+ className: "text-xs text-green-600 dark:text-green-400 text-center",
31165
+ children: _t({
31166
+ id: "SLJUHb",
31167
+ message: "Recovery link sent to {0}",
31168
+ values: { 0: user.email }
31169
+ })
31170
+ }),
31171
+ recoveryError && /* @__PURE__ */ jsx("p", {
31172
+ className: "text-xs text-kumo-danger text-center",
31173
+ children: recoveryError
31174
+ })
31175
+ ]
31176
+ })]
31177
+ })
31178
+ ]
31179
+ })] })
31180
+ });
30936
31181
  }
30937
31182
  /** Loading skeleton for user detail */
30938
31183
  function UserDetailSkeleton() {
@@ -31045,7 +31290,7 @@ function InviteUserModal({ open, isSending, error, inviteUrl, onOpenChange, onIn
31045
31290
  id: "yz7wBu",
31046
31291
  message: "Close"
31047
31292
  }),
31048
- className: "absolute right-4 top-4",
31293
+ className: "absolute end-4 top-4",
31049
31294
  children: [/* @__PURE__ */ jsx(X, { className: "h-4 w-4" }), /* @__PURE__ */ jsx("span", {
31050
31295
  className: "sr-only",
31051
31296
  children: _t({
@@ -31668,15 +31913,6 @@ function ContentListPage() {
31668
31913
  urlPattern: collectionConfig.urlPattern
31669
31914
  });
31670
31915
  }
31671
- /** Extract plugin block definitions from the manifest for Portable Text editor */
31672
- function getPluginBlocks(manifest) {
31673
- const blocks = [];
31674
- for (const [pluginId, plugin] of Object.entries(manifest.plugins)) if (plugin.portableTextBlocks) for (const block of plugin.portableTextBlocks) blocks.push({
31675
- ...block,
31676
- pluginId
31677
- });
31678
- return blocks;
31679
- }
31680
31916
  const contentNewRoute = createRoute({
31681
31917
  getParentRoute: () => adminLayoutRoute,
31682
31918
  path: "/content/$collection/new",
@@ -32568,6 +32804,8 @@ const contentTypesEditRoute = createRoute({
32568
32804
  function ContentTypesEditPage() {
32569
32805
  const { slug } = useParams({ from: "/_admin/content-types/$slug" });
32570
32806
  const queryClient = useQueryClient();
32807
+ const toastManager = Toast.useToastManager();
32808
+ const { _: _t } = useLingui();
32571
32809
  const { data: collection, isLoading, error } = useQuery({
32572
32810
  queryKey: [
32573
32811
  "schema",
@@ -32598,6 +32836,19 @@ function ContentTypesEditPage() {
32598
32836
  ] });
32599
32837
  queryClient.invalidateQueries({ queryKey: ["schema", "collections"] });
32600
32838
  queryClient.invalidateQueries({ queryKey: ["manifest"] });
32839
+ },
32840
+ onError: (mutationError) => {
32841
+ toastManager.add({
32842
+ title: _t({
32843
+ id: "+Ya+b9",
32844
+ message: "Failed to save"
32845
+ }),
32846
+ description: mutationError instanceof Error ? mutationError.message : _t({
32847
+ id: "Vw8l6h",
32848
+ message: "An error occurred"
32849
+ }),
32850
+ type: "error"
32851
+ });
32601
32852
  }
32602
32853
  });
32603
32854
  const addFieldMutation = useMutation({