@canvas-digital/blog-sdk 2.0.2 → 2.0.5

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 (61) hide show
  1. package/dist/blog-client.iife.js +1 -1
  2. package/dist/components/admin/AdminPostDetail.js +5 -5
  3. package/dist/components/admin/BrandSettings.js +5 -5
  4. package/dist/components/admin/BrandSwitcher.js +1 -1
  5. package/dist/components/admin/Chips.js +5 -5
  6. package/dist/components/admin/CommentsManager.js +6 -6
  7. package/dist/components/admin/Dashboard.js +1 -1
  8. package/dist/components/admin/MediaLibrary.js +5 -5
  9. package/dist/components/admin/MediaPicker.js +4 -4
  10. package/dist/components/admin/PostList.d.ts.map +1 -1
  11. package/dist/components/admin/PostList.js +13 -4
  12. package/dist/components/admin/PostsTable.d.ts +6 -1
  13. package/dist/components/admin/PostsTable.d.ts.map +1 -1
  14. package/dist/components/admin/PostsTable.js +15 -9
  15. package/dist/components/admin/Shell.js +3 -3
  16. package/dist/components/admin/TermManager.js +4 -4
  17. package/dist/components/admin/UsersManager.js +3 -3
  18. package/dist/components/admin/charts.js +7 -7
  19. package/dist/components/admin/editor/PostEditor.js +16 -16
  20. package/dist/components/admin/editor/RichTextEditor.js +8 -8
  21. package/dist/components/admin/editor/YoastCollapsible.js +2 -2
  22. package/dist/components/admin/editor/YoastInsightsPanel.js +1 -1
  23. package/dist/components/admin/editor/YoastInternalLinksPanel.js +1 -1
  24. package/dist/components/admin/editor/YoastSeoAnalysisPanel.js +6 -6
  25. package/dist/components/admin/editor/YoastSeoMetabox.js +8 -8
  26. package/dist/components/admin/editor/YoastSnippetField.js +2 -2
  27. package/dist/components/admin/internal/States.js +3 -3
  28. package/dist/components/admin/mock/store.d.ts.map +1 -1
  29. package/dist/components/admin/mock/store.js +3 -2
  30. package/dist/components/admin/seo/Ga4Settings.js +6 -6
  31. package/dist/components/admin/seo/RedirectAnalyticsDashboard.js +1 -1
  32. package/dist/components/admin/seo/RedirectDetail.js +6 -6
  33. package/dist/components/admin/seo/RedirectForm.js +1 -1
  34. package/dist/components/admin/seo/RedirectList.js +4 -4
  35. package/dist/components/admin/seo/RobotsEditor.js +1 -1
  36. package/dist/components/admin/seo/shared.js +2 -2
  37. package/dist/components/admin/tools/ToolsHub.js +4 -4
  38. package/dist/components/user/BlogCard.js +3 -3
  39. package/dist/components/user/BlogCategories.js +1 -1
  40. package/dist/components/user/BlogDetail.js +1 -1
  41. package/dist/components/user/BlogList.js +1 -1
  42. package/dist/components/user/BlogSearch.js +2 -2
  43. package/dist/components/user/BlogTags.js +1 -1
  44. package/dist/components/user/FeaturedBlogs.js +1 -1
  45. package/dist/components/user/RelatedBlogs.js +1 -1
  46. package/dist/components/user/SiteMediaHero.js +1 -1
  47. package/dist/components/user/detail/ArticleDetailHero.js +5 -5
  48. package/dist/components/user/detail/ArticleRailDetails.js +2 -2
  49. package/dist/components/user/detail/CommentSection.js +2 -2
  50. package/dist/components/user/detail/HeroFadeSlide.js +1 -1
  51. package/dist/components/user/detail/ReadingProgress.js +1 -1
  52. package/dist/components/user/detail/ShareRow.js +1 -1
  53. package/dist/components/user/internal/States.js +4 -4
  54. package/dist/lib/lexical-doc.js +1 -1
  55. package/dist/pages/admin/BlogAdmin.d.ts.map +1 -1
  56. package/dist/pages/admin/BlogAdmin.js +23 -11
  57. package/dist/services/admin-sdk-client.d.ts +9 -0
  58. package/dist/services/admin-sdk-client.d.ts.map +1 -1
  59. package/dist/services/admin-sdk-client.js +17 -0
  60. package/dist/style.css +1023 -1016
  61. package/package.json +2 -1
@@ -69,7 +69,7 @@ export function RedirectForm({ initial, mode, onDone, onCancel, }) {
69
69
  onDone();
70
70
  });
71
71
  };
72
- return (_jsxs("section", { className: "panel", children: [_jsxs("div", { className: "panel-head", children: [_jsx("h2", { children: mode === "create" ? "Add redirect" : "Edit redirect" }), _jsx("span", { className: "hint", children: brandName })] }), _jsxs("div", { className: "panel-body stack", children: [error ? (_jsx("p", { className: "form-error", role: "alert", children: error })) : null, form.sources.map((src, i) => (_jsxs("div", { className: "btn-row", style: { alignItems: "flex-end" }, children: [_jsxs("label", { className: "fld-row", style: { flex: 1 }, children: [_jsx("span", { className: "fld-lbl", children: "From path" }), _jsx("input", { className: "fld mono", value: src.path, onChange: (e) => setSource(i, { path: e.target.value }), placeholder: "/old-path" })] }), _jsxs("label", { className: "fld-row", children: [_jsx("span", { className: "fld-lbl", children: "Match" }), _jsxs("select", { className: "fld", value: src.match, onChange: (e) => setSource(i, { match: e.target.value }), children: [_jsx("option", { value: "exact", children: "Exact" }), _jsx("option", { value: "contains", children: "Contains" }), _jsx("option", { value: "regex", children: "Regex" })] })] })] }, i))), _jsx("button", { type: "button", className: "btn", onClick: () => setForm((f) => ({ ...f, sources: [...f.sources, emptySource()] })), children: "Add source path" }), _jsxs("label", { className: "fld-row", children: [_jsx("span", { className: "fld-lbl", children: "Type" }), _jsx("select", { className: "fld", value: form.type, onChange: (e) => set("type", e.target.value), children: TYPE_OPTIONS.map((o) => (_jsx("option", { value: o.value, children: o.label }, o.value))) })] }), needsTarget ? (_jsxs("label", { className: "fld-row", children: [_jsx("span", { className: "fld-lbl", children: "Target URL" }), _jsx("input", { className: "fld mono", value: form.to, onChange: (e) => set("to", e.target.value), placeholder: "/new-path" })] })) : null, _jsxs("label", { className: "fld-row", children: [_jsx("span", { className: "fld-lbl", children: "Note" }), _jsx("input", { className: "fld", value: form.note, onChange: (e) => set("note", e.target.value) })] }), _jsxs("div", { className: "chips", children: [_jsxs("label", { className: "pick-row", children: [_jsx("input", { type: "checkbox", checked: form.active, onChange: (e) => set("active", e.target.checked) }), " Active"] }), _jsxs("label", { className: "pick-row", children: [_jsx("input", { type: "checkbox", checked: form.ignoreCase, onChange: (e) => set("ignoreCase", e.target.checked) }), " Ignore case"] }), _jsxs("label", { className: "pick-row", children: [_jsx("input", { type: "checkbox", checked: form.ignoreTrailingSlash, onChange: (e) => set("ignoreTrailingSlash", e.target.checked) }), " ", "Ignore trailing slash"] }), _jsxs("label", { className: "pick-row", children: [_jsx("input", { type: "checkbox", checked: form.forceHttps, onChange: (e) => set("forceHttps", e.target.checked) }), " Force HTTPS"] }), _jsxs("label", { className: "pick-row", children: [_jsx("input", { type: "checkbox", checked: form.preserveQuery, onChange: (e) => set("preserveQuery", e.target.checked) }), " ", "Preserve query"] })] }), _jsxs("div", { className: "btn-row", children: [_jsx("button", { type: "button", className: "btn btn-primary", disabled: pending, onClick: submit, children: pending ? "Saving…" : mode === "create" ? "Create redirect" : "Save redirect" }), _jsx("button", { type: "button", className: "btn", onClick: onCancel, children: "Cancel" })] })] })] }));
72
+ return (_jsxs("section", { className: "blog_panel", children: [_jsxs("div", { className: "blog_panel-head", children: [_jsx("h2", { children: mode === "create" ? "Add redirect" : "Edit redirect" }), _jsx("span", { className: "blog_hint", children: brandName })] }), _jsxs("div", { className: "blog_panel-body blog_stack", children: [error ? (_jsx("p", { className: "blog_form-error", role: "alert", children: error })) : null, form.sources.map((src, i) => (_jsxs("div", { className: "blog_btn-row", style: { alignItems: "flex-end" }, children: [_jsxs("label", { className: "blog_fld-row", style: { flex: 1 }, children: [_jsx("span", { className: "blog_fld-lbl", children: "From path" }), _jsx("input", { className: "blog_fld blog_mono", value: src.path, onChange: (e) => setSource(i, { path: e.target.value }), placeholder: "/old-path" })] }), _jsxs("label", { className: "blog_fld-row", children: [_jsx("span", { className: "blog_fld-lbl", children: "Match" }), _jsxs("select", { className: "blog_fld", value: src.match, onChange: (e) => setSource(i, { match: e.target.value }), children: [_jsx("option", { value: "exact", children: "Exact" }), _jsx("option", { value: "contains", children: "Contains" }), _jsx("option", { value: "regex", children: "Regex" })] })] })] }, i))), _jsx("button", { type: "button", className: "blog_btn", onClick: () => setForm((f) => ({ ...f, sources: [...f.sources, emptySource()] })), children: "Add source path" }), _jsxs("label", { className: "blog_fld-row", children: [_jsx("span", { className: "blog_fld-lbl", children: "Type" }), _jsx("select", { className: "blog_fld", value: form.type, onChange: (e) => set("type", e.target.value), children: TYPE_OPTIONS.map((o) => (_jsx("option", { value: o.value, children: o.label }, o.value))) })] }), needsTarget ? (_jsxs("label", { className: "blog_fld-row", children: [_jsx("span", { className: "blog_fld-lbl", children: "Target URL" }), _jsx("input", { className: "blog_fld blog_mono", value: form.to, onChange: (e) => set("to", e.target.value), placeholder: "/new-path" })] })) : null, _jsxs("label", { className: "blog_fld-row", children: [_jsx("span", { className: "blog_fld-lbl", children: "Note" }), _jsx("input", { className: "blog_fld", value: form.note, onChange: (e) => set("note", e.target.value) })] }), _jsxs("div", { className: "blog_chips", children: [_jsxs("label", { className: "blog_pick-row", children: [_jsx("input", { type: "checkbox", checked: form.active, onChange: (e) => set("active", e.target.checked) }), " Active"] }), _jsxs("label", { className: "blog_pick-row", children: [_jsx("input", { type: "checkbox", checked: form.ignoreCase, onChange: (e) => set("ignoreCase", e.target.checked) }), " Ignore case"] }), _jsxs("label", { className: "blog_pick-row", children: [_jsx("input", { type: "checkbox", checked: form.ignoreTrailingSlash, onChange: (e) => set("ignoreTrailingSlash", e.target.checked) }), " ", "Ignore trailing slash"] }), _jsxs("label", { className: "blog_pick-row", children: [_jsx("input", { type: "checkbox", checked: form.forceHttps, onChange: (e) => set("forceHttps", e.target.checked) }), " Force HTTPS"] }), _jsxs("label", { className: "blog_pick-row", children: [_jsx("input", { type: "checkbox", checked: form.preserveQuery, onChange: (e) => set("preserveQuery", e.target.checked) }), " ", "Preserve query"] })] }), _jsxs("div", { className: "blog_btn-row", children: [_jsx("button", { type: "button", className: "blog_btn blog_btn-primary", disabled: pending, onClick: submit, children: pending ? "Saving…" : mode === "create" ? "Create redirect" : "Save redirect" }), _jsx("button", { type: "button", className: "blog_btn", onClick: onCancel, children: "Cancel" })] })] })] }));
73
73
  }
74
74
  export function redirectToFormValues(row) {
75
75
  return {
@@ -20,9 +20,9 @@ export function RedirectList({ onView, onEdit, onCreate, canEdit = true, }) {
20
20
  alert(res.error);
21
21
  });
22
22
  };
23
- return (_jsxs("section", { className: "panel", children: [_jsxs("div", { className: "panel-head", children: [_jsx("h2", { children: "All redirects" }), _jsx("span", { className: "hint", children: rows.length })] }), rows.length === 0 ? (_jsx("div", { className: "panel-body", children: _jsxs("p", { className: "d-empty", style: { margin: 0 }, children: ["No redirects yet.", " ", canEdit ? (_jsx("button", { type: "button", className: "btn btn-ghost btn-sm", onClick: onCreate, children: "Add the first one" })) : null] }) })) : (_jsx("div", { className: "tw", children: _jsxs("table", { className: "tbl", children: [_jsx("thead", { children: _jsxs("tr", { children: [_jsx("th", { children: "From" }), _jsx("th", { children: "To" }), _jsx("th", { children: "Type" }), _jsx("th", { children: "Origin" }), showBrand ? _jsx("th", { children: "Brand" }) : null] }) }), _jsx("tbody", { children: rows.map((r) => (_jsxs("tr", { children: [_jsxs("td", { children: [_jsx("button", { type: "button", className: "row-title mono", onClick: () => onView(r.id), children: r.from }), r.note ? _jsx("span", { className: "cell-sub", children: r.note }) : null, _jsxs("div", { className: "row-actions", children: [_jsx("button", { type: "button", onClick: () => onView(r.id), children: "View" }), canEdit ? (_jsx("button", { type: "button", onClick: () => onEdit(r.id), children: "Edit" })) : null, canEdit ? (_jsx("button", { type: "button", className: "danger", disabled: pending, onClick: () => remove(r), children: "Delete" })) : null] })] }), _jsx("td", { className: "mono muted", children: r.to || "—" }), _jsxs("td", { children: [_jsx("span", { className: `chip ${r.type === "301" || r.type === "308"
24
- ? "chip-approved"
23
+ return (_jsxs("section", { className: "blog_panel", children: [_jsxs("div", { className: "blog_panel-head", children: [_jsx("h2", { children: "All redirects" }), _jsx("span", { className: "blog_hint", children: rows.length })] }), rows.length === 0 ? (_jsx("div", { className: "blog_panel-body", children: _jsxs("p", { className: "blog_d-empty", style: { margin: 0 }, children: ["No redirects yet.", " ", canEdit ? (_jsx("button", { type: "button", className: "blog_btn blog_btn-ghost blog_btn-sm", onClick: onCreate, children: "Add the first one" })) : null] }) })) : (_jsx("div", { className: "blog_tw", children: _jsxs("table", { className: "blog_tbl", children: [_jsx("thead", { children: _jsxs("tr", { children: [_jsx("th", { children: "From" }), _jsx("th", { children: "To" }), _jsx("th", { children: "Type" }), _jsx("th", { children: "Origin" }), showBrand ? _jsx("th", { children: "Brand" }) : null] }) }), _jsx("tbody", { children: rows.map((r) => (_jsxs("tr", { children: [_jsxs("td", { children: [_jsx("button", { type: "button", className: "blog_row-title blog_mono", onClick: () => onView(r.id), children: r.from }), r.note ? _jsx("span", { className: "blog_cell-sub", children: r.note }) : null, _jsxs("div", { className: "blog_row-actions", children: [_jsx("button", { type: "button", onClick: () => onView(r.id), children: "View" }), canEdit ? (_jsx("button", { type: "button", onClick: () => onEdit(r.id), children: "Edit" })) : null, canEdit ? (_jsx("button", { type: "button", className: "blog_danger", disabled: pending, onClick: () => remove(r), children: "Delete" })) : null] })] }), _jsx("td", { className: "blog_mono blog_muted", children: r.to || "—" }), _jsxs("td", { children: [_jsx("span", { className: `blog_chip ${r.type === "301" || r.type === "308"
24
+ ? "blog_chip-approved"
25
25
  : r.type === "404" || r.type === "410" || r.type === "451"
26
- ? "chip-draft"
27
- : "chip-writing"}`, children: r.type }), r.active === false ? _jsx("span", { className: "chip chip-draft", children: "Off" }) : null] }), _jsx("td", { className: "muted", children: SOURCE_LABEL[r.source] ?? r.source }), showBrand ? _jsx("td", { className: "muted", children: r.brandName ?? "—" }) : null] }, r.id))) })] }) }))] }));
26
+ ? "blog_chip-draft"
27
+ : "blog_chip-writing"}`, children: r.type }), r.active === false ? _jsx("span", { className: "blog_chip blog_chip-draft", children: "Off" }) : null] }), _jsx("td", { className: "blog_muted", children: SOURCE_LABEL[r.source] ?? r.source }), showBrand ? _jsx("td", { className: "blog_muted", children: r.brandName ?? "—" }) : null] }, r.id))) })] }) }))] }));
28
28
  }
@@ -46,5 +46,5 @@ export function RobotsEditor({ brandId, canEdit = true, }) {
46
46
  setFlash("Robots.txt saved.");
47
47
  });
48
48
  };
49
- return (_jsxs("fieldset", { className: "seo-module", disabled: !canEdit, children: [!canEdit ? _jsxs("p", { className: "explain", children: ["Only platform admins can change robots.txt for ", brandName, "."] }) : null, error ? (_jsx("p", { className: "form-error", role: "alert", children: error })) : null, flash ? (_jsx("p", { className: "form-ok", role: "status", children: flash })) : null, _jsxs("div", { className: "grid grid-2 seo-grid", children: [_jsxs("section", { className: "panel", children: [_jsx("div", { className: "panel-head", children: _jsxs("h2", { children: ["Rules for ", brandName] }) }), _jsxs("div", { className: "panel-body stack", children: [_jsxs("label", { className: "fld-row", children: [_jsx("span", { className: "fld-lbl", children: "Allow paths (one per line)" }), _jsx("textarea", { className: "fld mono", rows: 4, value: allow, onChange: (e) => setAllow(e.target.value) })] }), _jsxs("label", { className: "fld-row", children: [_jsx("span", { className: "fld-lbl", children: "Disallow paths (one per line)" }), _jsx("textarea", { className: "fld mono", rows: 4, value: disallow, onChange: (e) => setDisallow(e.target.value) })] }), _jsxs("label", { className: "pick-row", children: [_jsx("input", { type: "checkbox", checked: includeSitemap, onChange: (e) => setIncludeSitemap(e.target.checked) }), " ", "Include sitemap URL"] }), _jsxs("label", { className: "fld-row", children: [_jsx("span", { className: "fld-lbl", children: "Extra rules" }), _jsx("textarea", { className: "fld mono", rows: 3, value: extraRules, onChange: (e) => setExtraRules(e.target.value) })] }), canEdit ? (_jsx("button", { type: "button", className: "btn btn-primary", disabled: pending, onClick: save, children: pending ? "Saving…" : "Save robots.txt" })) : null] })] }), _jsxs("section", { className: "panel", children: [_jsx("div", { className: "panel-head", children: _jsx("h2", { children: "Preview" }) }), _jsx("div", { className: "panel-body", children: _jsx("pre", { className: "mono", style: { whiteSpace: "pre-wrap", margin: 0 }, children: preview }) })] })] })] }));
49
+ return (_jsxs("fieldset", { className: "blog_seo-module", disabled: !canEdit, children: [!canEdit ? _jsxs("p", { className: "blog_explain", children: ["Only platform admins can change robots.txt for ", brandName, "."] }) : null, error ? (_jsx("p", { className: "blog_form-error", role: "alert", children: error })) : null, flash ? (_jsx("p", { className: "blog_form-ok", role: "status", children: flash })) : null, _jsxs("div", { className: "blog_grid blog_grid-2 blog_seo-grid", children: [_jsxs("section", { className: "blog_panel", children: [_jsx("div", { className: "blog_panel-head", children: _jsxs("h2", { children: ["Rules for ", brandName] }) }), _jsxs("div", { className: "blog_panel-body blog_stack", children: [_jsxs("label", { className: "blog_fld-row", children: [_jsx("span", { className: "blog_fld-lbl", children: "Allow paths (one per line)" }), _jsx("textarea", { className: "blog_fld blog_mono", rows: 4, value: allow, onChange: (e) => setAllow(e.target.value) })] }), _jsxs("label", { className: "blog_fld-row", children: [_jsx("span", { className: "blog_fld-lbl", children: "Disallow paths (one per line)" }), _jsx("textarea", { className: "blog_fld blog_mono", rows: 4, value: disallow, onChange: (e) => setDisallow(e.target.value) })] }), _jsxs("label", { className: "blog_pick-row", children: [_jsx("input", { type: "checkbox", checked: includeSitemap, onChange: (e) => setIncludeSitemap(e.target.checked) }), " ", "Include sitemap URL"] }), _jsxs("label", { className: "blog_fld-row", children: [_jsx("span", { className: "blog_fld-lbl", children: "Extra rules" }), _jsx("textarea", { className: "blog_fld blog_mono", rows: 3, value: extraRules, onChange: (e) => setExtraRules(e.target.value) })] }), canEdit ? (_jsx("button", { type: "button", className: "blog_btn blog_btn-primary", disabled: pending, onClick: save, children: pending ? "Saving…" : "Save robots.txt" })) : null] })] }), _jsxs("section", { className: "blog_panel", children: [_jsx("div", { className: "blog_panel-head", children: _jsx("h2", { children: "Preview" }) }), _jsx("div", { className: "blog_panel-body", children: _jsx("pre", { className: "blog_mono", style: { whiteSpace: "pre-wrap", margin: 0 }, children: preview }) })] })] })] }));
50
50
  }
@@ -1,7 +1,7 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
2
  import { useAdminMock } from "../mock/store";
3
- export const SeoStatus = ({ ok, label, detail, }) => (_jsxs("div", { className: `seo-status ${ok ? "is-ok" : "is-warn"}`, children: [_jsx("span", { className: "seo-status-dot", "aria-hidden": "true" }), _jsxs("div", { children: [_jsx("strong", { children: label }), _jsx("p", { children: detail })] })] }));
3
+ export const SeoStatus = ({ ok, label, detail, }) => (_jsxs("div", { className: `blog_seo-status ${ok ? "blog_is-ok" : "blog_is-warn"}`, children: [_jsx("span", { className: "blog_seo-status-dot", "aria-hidden": "true" }), _jsxs("div", { children: [_jsx("strong", { children: label }), _jsx("p", { children: detail })] })] }));
4
4
  export function BrandPickPanel({ title, onPick, }) {
5
5
  const store = useAdminMock();
6
- return (_jsxs("section", { className: "panel", children: [_jsx("div", { className: "panel-head", children: _jsx("h2", { children: "Which brand?" }) }), _jsxs("div", { className: "panel-body", children: [_jsxs("p", { className: "explain", style: { marginTop: 0 }, children: [title, " \u2014 these settings are per brand. Pick one to continue."] }), _jsx("div", { className: "chips", children: store.brands.map((t) => (_jsx("button", { type: "button", className: "btn", onClick: () => onPick(t.id), children: t.name }, t.id))) })] })] }));
6
+ return (_jsxs("section", { className: "blog_panel", children: [_jsx("div", { className: "blog_panel-head", children: _jsx("h2", { children: "Which brand?" }) }), _jsxs("div", { className: "blog_panel-body", children: [_jsxs("p", { className: "blog_explain", style: { marginTop: 0 }, children: [title, " \u2014 these settings are per brand. Pick one to continue."] }), _jsx("div", { className: "blog_chips", children: store.brands.map((t) => (_jsx("button", { type: "button", className: "blog_btn", onClick: () => onPick(t.id), children: t.name }, t.id))) })] })] }));
7
7
  }
@@ -50,7 +50,7 @@ export function ExportTool() {
50
50
  setBusy(false);
51
51
  }
52
52
  };
53
- return (_jsxs("section", { className: "panel", children: [_jsx("div", { className: "panel-head", children: _jsx("h2", { children: "Choose what to export" }) }), _jsxs("div", { className: "panel-body stack", children: [_jsxs("p", { className: "note", style: { marginTop: 0 }, children: ["Download a JSON, XML, or CSV file from the mock store", brandSlug ? ` (currently ${brandName})` : " (all brands)", "."] }), error ? (_jsx("p", { className: "form-error", role: "alert", children: error })) : null, _jsxs("fieldset", { className: "export-fieldset", children: [_jsx("legend", { className: "sr-only", children: "Export type" }), options.map((opt) => (_jsxs("label", { className: `export-option${kind === opt.value ? " is-on" : ""}`, children: [_jsx("input", { type: "radio", name: "export-kind", value: opt.value, checked: kind === opt.value, onChange: () => setKind(opt.value) }), _jsxs("span", { className: "export-option-body", children: [_jsx("span", { className: "export-option-label", children: opt.label }), _jsx("span", { className: "export-option-desc", children: opt.description })] })] }, opt.value)))] }), _jsxs("fieldset", { className: "export-fieldset", children: [_jsx("legend", { className: "export-fieldset-label", children: "File format" }), formats.map((opt) => (_jsxs("label", { className: `export-option${format === opt.value ? " is-on" : ""}`, children: [_jsx("input", { type: "radio", name: "export-format", value: opt.value, checked: format === opt.value, onChange: () => setFormat(opt.value) }), _jsxs("span", { className: "export-option-body", children: [_jsx("span", { className: "export-option-label", children: opt.label }), _jsx("span", { className: "export-option-desc", children: opt.description })] })] }, opt.value)))] }), _jsx("div", { className: "btn-row", children: _jsx("button", { type: "button", className: "btn btn-primary", onClick: download, disabled: busy, children: busy ? "Preparing…" : `Download ${format.toUpperCase()} File` }) })] })] }));
53
+ return (_jsxs("section", { className: "blog_panel", children: [_jsx("div", { className: "blog_panel-head", children: _jsx("h2", { children: "Choose what to export" }) }), _jsxs("div", { className: "blog_panel-body blog_stack", children: [_jsxs("p", { className: "blog_note", style: { marginTop: 0 }, children: ["Download a JSON, XML, or CSV file from the mock store", brandSlug ? ` (currently ${brandName})` : " (all brands)", "."] }), error ? (_jsx("p", { className: "blog_form-error", role: "alert", children: error })) : null, _jsxs("fieldset", { className: "blog_export-fieldset", children: [_jsx("legend", { className: "blog_sr-only", children: "Export type" }), options.map((opt) => (_jsxs("label", { className: `blog_export-option${kind === opt.value ? " blog_is-on" : ""}`, children: [_jsx("input", { type: "radio", name: "export-kind", value: opt.value, checked: kind === opt.value, onChange: () => setKind(opt.value) }), _jsxs("span", { className: "blog_export-option-body", children: [_jsx("span", { className: "blog_export-option-label", children: opt.label }), _jsx("span", { className: "blog_export-option-desc", children: opt.description })] })] }, opt.value)))] }), _jsxs("fieldset", { className: "blog_export-fieldset", children: [_jsx("legend", { className: "blog_export-fieldset-label", children: "File format" }), formats.map((opt) => (_jsxs("label", { className: `blog_export-option${format === opt.value ? " blog_is-on" : ""}`, children: [_jsx("input", { type: "radio", name: "export-format", value: opt.value, checked: format === opt.value, onChange: () => setFormat(opt.value) }), _jsxs("span", { className: "blog_export-option-body", children: [_jsx("span", { className: "blog_export-option-label", children: opt.label }), _jsx("span", { className: "blog_export-option-desc", children: opt.description })] })] }, opt.value)))] }), _jsx("div", { className: "blog_btn-row", children: _jsx("button", { type: "button", className: "blog_btn blog_btn-primary", onClick: download, disabled: busy, children: busy ? "Preparing…" : `Download ${format.toUpperCase()} File` }) })] })] }));
54
54
  }
55
55
  export function ImportTool() {
56
56
  const store = useAdminMock();
@@ -95,12 +95,12 @@ export function ImportTool() {
95
95
  setBusy(false);
96
96
  }
97
97
  };
98
- return (_jsxs("section", { className: "panel", children: [_jsxs("div", { className: "panel-head", children: [_jsx("h2", { children: "Choose what to import" }), _jsx("span", { className: "hint", children: brandName })] }), _jsxs("div", { className: "panel-body stack", children: [_jsxs("p", { className: "note", style: { marginTop: 0 }, children: ["Upload a JSON file from Tools \u2192 Export. Scoped to ", brandSlug || brandName, "."] }), error ? (_jsx("p", { className: "form-error", role: "alert", children: error })) : null, result ? (_jsxs("div", { className: "form-ok", role: "status", children: ["Imported ", result.postsCreated, " post", result.postsCreated === 1 ? "" : "s", result.postsSkipped ? ` (${result.postsSkipped} skipped)` : "", ", ", result.commentsCreated, " comment", result.commentsCreated === 1 ? "" : "s", result.commentsSkipped ? ` (${result.commentsSkipped} skipped)` : "", "."] })) : null, _jsxs("fieldset", { className: "export-fieldset", children: [_jsx("legend", { className: "sr-only", children: "Import type" }), options.map((opt) => (_jsxs("label", { className: `export-option${kind === opt.value ? " is-on" : ""}`, children: [_jsx("input", { type: "radio", name: "import-kind", value: opt.value, checked: kind === opt.value, onChange: () => setKind(opt.value) }), _jsxs("span", { className: "export-option-body", children: [_jsx("span", { className: "export-option-label", children: opt.label }), _jsx("span", { className: "export-option-desc", children: opt.description })] })] }, opt.value)))] }), _jsxs("div", { className: "import-file", children: [_jsx("input", { ref: fileRef, type: "file", accept: ".json,application/json", className: "sr-only", onChange: (e) => {
98
+ return (_jsxs("section", { className: "blog_panel", children: [_jsxs("div", { className: "blog_panel-head", children: [_jsx("h2", { children: "Choose what to import" }), _jsx("span", { className: "blog_hint", children: brandName })] }), _jsxs("div", { className: "blog_panel-body blog_stack", children: [_jsxs("p", { className: "blog_note", style: { marginTop: 0 }, children: ["Upload a JSON file from Tools \u2192 Export. Scoped to ", brandSlug || brandName, "."] }), error ? (_jsx("p", { className: "blog_form-error", role: "alert", children: error })) : null, result ? (_jsxs("div", { className: "blog_form-ok", role: "status", children: ["Imported ", result.postsCreated, " post", result.postsCreated === 1 ? "" : "s", result.postsSkipped ? ` (${result.postsSkipped} skipped)` : "", ", ", result.commentsCreated, " comment", result.commentsCreated === 1 ? "" : "s", result.commentsSkipped ? ` (${result.commentsSkipped} skipped)` : "", "."] })) : null, _jsxs("fieldset", { className: "blog_export-fieldset", children: [_jsx("legend", { className: "blog_sr-only", children: "Import type" }), options.map((opt) => (_jsxs("label", { className: `blog_export-option${kind === opt.value ? " blog_is-on" : ""}`, children: [_jsx("input", { type: "radio", name: "import-kind", value: opt.value, checked: kind === opt.value, onChange: () => setKind(opt.value) }), _jsxs("span", { className: "blog_export-option-body", children: [_jsx("span", { className: "blog_export-option-label", children: opt.label }), _jsx("span", { className: "blog_export-option-desc", children: opt.description })] })] }, opt.value)))] }), _jsxs("div", { className: "blog_import-file", children: [_jsx("input", { ref: fileRef, type: "file", accept: ".json,application/json", className: "blog_sr-only", onChange: (e) => {
99
99
  setFile(e.target.files?.[0] ?? null);
100
100
  setResult(null);
101
101
  setError(null);
102
- } }), _jsx("button", { type: "button", className: "btn", onClick: () => fileRef.current?.click(), disabled: busy, children: file ? "Change file" : "Choose file" }), _jsx("span", { className: "import-file-name mono", children: file ? file.name : "JSON" })] }), _jsx("div", { className: "btn-row", children: _jsx("button", { type: "button", className: "btn btn-primary", onClick: () => void runImport(), disabled: busy || !file, children: busy ? "Importing…" : "Run Import" }) })] })] }));
102
+ } }), _jsx("button", { type: "button", className: "blog_btn", onClick: () => fileRef.current?.click(), disabled: busy, children: file ? "Change file" : "Choose file" }), _jsx("span", { className: "blog_import-file-name blog_mono", children: file ? file.name : "JSON" })] }), _jsx("div", { className: "blog_btn-row", children: _jsx("button", { type: "button", className: "blog_btn blog_btn-primary", onClick: () => void runImport(), disabled: busy || !file, children: busy ? "Importing…" : "Run Import" }) })] })] }));
103
103
  }
104
104
  export function ToolsHub({ onExport, onImport }) {
105
- return (_jsxs(_Fragment, { children: [_jsx("p", { className: "explain", children: "Utilities for moving content in and out of the portal. Import and export are scoped to the brand selected in the top bar." }), _jsxs("section", { className: "panel", children: [_jsx("div", { className: "panel-head", children: _jsx("h2", { children: "Available Tools" }) }), _jsxs("ul", { className: "seo-link-list", children: [_jsx("li", { children: _jsxs("button", { type: "button", onClick: onExport, style: { width: "100%", textAlign: "left" }, children: [_jsxs("span", { children: [_jsx("strong", { children: "Export" }), _jsx("span", { className: "cell-sub", style: { display: "block", marginTop: 4 }, children: "Download posts and media as JSON, XML, or CSV." })] }), _jsx("span", { className: "mono", children: "Open \u2192" })] }) }), _jsx("li", { children: _jsxs("button", { type: "button", onClick: onImport, style: { width: "100%", textAlign: "left" }, children: [_jsxs("span", { children: [_jsx("strong", { children: "Import" }), _jsx("span", { className: "cell-sub", style: { display: "block", marginTop: 4 }, children: "Bulk import blog posts and comments from JSON." })] }), _jsx("span", { className: "mono", children: "Open \u2192" })] }) })] })] })] }));
105
+ return (_jsxs(_Fragment, { children: [_jsx("p", { className: "blog_explain", children: "Utilities for moving content in and out of the portal. Import and export are scoped to the brand selected in the top bar." }), _jsxs("section", { className: "blog_panel", children: [_jsx("div", { className: "blog_panel-head", children: _jsx("h2", { children: "Available Tools" }) }), _jsxs("ul", { className: "blog_seo-link-list", children: [_jsx("li", { children: _jsxs("button", { type: "button", onClick: onExport, style: { width: "100%", textAlign: "left" }, children: [_jsxs("span", { children: [_jsx("strong", { children: "Export" }), _jsx("span", { className: "blog_cell-sub", style: { display: "block", marginTop: 4 }, children: "Download posts and media as JSON, XML, or CSV." })] }), _jsx("span", { className: "blog_mono", children: "Open \u2192" })] }) }), _jsx("li", { children: _jsxs("button", { type: "button", onClick: onImport, style: { width: "100%", textAlign: "left" }, children: [_jsxs("span", { children: [_jsx("strong", { children: "Import" }), _jsx("span", { className: "blog_cell-sub", style: { display: "block", marginTop: 4 }, children: "Bulk import blog posts and comments from JSON." })] }), _jsx("span", { className: "blog_mono", children: "Open \u2192" })] }) })] })] })] }));
106
106
  }
@@ -10,13 +10,13 @@ export function BlogCard({ blog, theme, onSelect, href, lead = false, index = 0,
10
10
  const thumb = blog.featured_image;
11
11
  const showThumb = Boolean(thumb) && !imgFailed;
12
12
  const readingMinutes = estimateReadingMinutes([blog.excerpt, blog.content].filter(Boolean).join(" "));
13
- const body = (_jsxs(_Fragment, { children: [showThumb ? (_jsx("span", { className: "card-img", children: _jsx("img", { src: thumb, alt: blog.title, width: lead ? 1600 : 768, height: lead ? 900 : 512, loading: priority ? "eager" : "lazy", decoding: "async", onError: () => setImgFailed(true) }) })) : (_jsx("span", { className: "card-img card-img-blank", "aria-hidden": "true" })), _jsxs("span", { className: "card-body", children: [categoryName ? _jsx("span", { className: "card-eyebrow", children: categoryName }) : null, _jsx("span", { className: "card-title", children: blog.title }), resolved.showExcerpt && blog.excerpt ? (_jsx("span", { className: "card-excerpt", children: blog.excerpt })) : null, _jsxs("span", { className: "card-meta", children: [resolved.showDate && published ? (_jsx("time", { dateTime: published, children: formatDate(published) })) : null, resolved.showAuthor && blog.author?.name ? (_jsx("span", { children: blog.author.name })) : null, _jsxs("span", { children: [readingMinutes, " min read"] })] })] })] }));
14
- return (_jsx("li", { className: lead ? "card card-lead" : "card", style: { ["--motion-i"]: index }, children: href ? (_jsx("a", { href: href, children: body })) : (_jsx("button", { type: "button", className: "card-link", onClick: () => onSelect?.(blog), children: body })) }));
13
+ const body = (_jsxs(_Fragment, { children: [showThumb ? (_jsx("span", { className: "blog_card-img", children: _jsx("img", { src: thumb, alt: blog.title, width: lead ? 1600 : 768, height: lead ? 900 : 512, loading: priority ? "eager" : "lazy", decoding: "async", onError: () => setImgFailed(true) }) })) : (_jsx("span", { className: "blog_card-img blog_card-img-blank", "aria-hidden": "true" })), _jsxs("span", { className: "blog_card-body", children: [categoryName ? _jsx("span", { className: "blog_card-eyebrow", children: categoryName }) : null, _jsx("span", { className: "blog_card-title", children: blog.title }), resolved.showExcerpt && blog.excerpt ? (_jsx("span", { className: "blog_card-excerpt", children: blog.excerpt })) : null, _jsxs("span", { className: "blog_card-meta", children: [resolved.showDate && published ? (_jsx("time", { dateTime: published, children: formatDate(published) })) : null, resolved.showAuthor && blog.author?.name ? (_jsx("span", { children: blog.author.name })) : null, _jsxs("span", { children: [readingMinutes, " min read"] })] })] })] }));
14
+ return (_jsx("li", { className: lead ? "blog_card blog_card-lead" : "blog_card", style: { ["--motion-i"]: index }, children: href ? (_jsx("a", { href: href, children: body })) : (_jsx("button", { type: "button", className: "blog_card-link", onClick: () => onSelect?.(blog), children: body })) }));
15
15
  }
16
16
  export function BlogGrid({ blogs, theme, onSelect, getHref, className, leadFirst = false, }) {
17
17
  if (blogs.length === 0)
18
18
  return null;
19
19
  const lead = leadFirst ? blogs[0] : null;
20
20
  const rest = leadFirst ? blogs.slice(1) : blogs;
21
- return (_jsxs(_Fragment, { children: [lead ? (_jsx("ul", { className: "post-grid post-grid-lead", children: _jsx(BlogCard, { blog: lead, theme: theme, onSelect: onSelect, href: getHref?.(lead), lead: true, priority: true, index: 0 }) })) : null, rest.length > 0 ? (_jsx("ul", { className: className ? `post-grid ${className}` : "post-grid", children: rest.map((blog, i) => (_jsx(BlogCard, { blog: blog, theme: theme, onSelect: onSelect, href: getHref?.(blog), priority: !lead && i === 0, index: i }, blog.id))) })) : null] }));
21
+ return (_jsxs(_Fragment, { children: [lead ? (_jsx("ul", { className: "blog_post-grid blog_post-grid-lead", children: _jsx(BlogCard, { blog: lead, theme: theme, onSelect: onSelect, href: getHref?.(lead), lead: true, priority: true, index: 0 }) })) : null, rest.length > 0 ? (_jsx("ul", { className: className ? `post-grid ${className}` : "blog_post-grid", children: rest.map((blog, i) => (_jsx(BlogCard, { blog: blog, theme: theme, onSelect: onSelect, href: getHref?.(blog), priority: !lead && i === 0, index: i }, blog.id))) })) : null] }));
22
22
  }
@@ -7,5 +7,5 @@ import { EmptyState, ErrorState, LoadingState, Scope } from "./internal/States";
7
7
  export function BlogCategories({ config, theme, branding, className, onSelect, }) {
8
8
  const client = useMemo(() => new BlogClient(config), [config.apiUrl, config.publicApiKey, config.email, config.domain, config.timeoutMs]);
9
9
  const state = useAsync(() => client.getCategories(), [client], (data) => data.length === 0);
10
- return (_jsxs(Scope, { className: cx("bp-blog-categories", branding?.className, className), style: themeVars(theme, branding), css: branding?.css, children: [state.status === "loading" ? _jsx(LoadingState, { label: "Loading categories..." }) : null, state.status === "error" ? (_jsx(ErrorState, { message: state.error, authError: state.authError })) : null, state.status === "empty" ? _jsx(EmptyState, { label: "No categories yet." }) : null, state.status === "success" ? (_jsx("ul", { className: "bp-blog-categories__list", style: { listStyle: "none", padding: 0, margin: 0 }, children: state.data.map((category) => (_jsx("li", { style: { marginBottom: "0.5rem" }, children: _jsx("button", { type: "button", onClick: () => onSelect?.(category), children: category.name }) }, category.id))) })) : null] }));
10
+ return (_jsxs(Scope, { className: cx("blog_bp-blog-categories", branding?.className, className), style: themeVars(theme, branding), css: branding?.css, children: [state.status === "loading" ? _jsx(LoadingState, { label: "Loading categories..." }) : null, state.status === "error" ? (_jsx(ErrorState, { message: state.error, authError: state.authError })) : null, state.status === "empty" ? _jsx(EmptyState, { label: "No categories yet." }) : null, state.status === "success" ? (_jsx("ul", { className: "blog_bp-blog-categories__list", style: { listStyle: "none", padding: 0, margin: 0 }, children: state.data.map((category) => (_jsx("li", { style: { marginBottom: "0.5rem" }, children: _jsx("button", { type: "button", onClick: () => onSelect?.(category), children: category.name }) }, category.id))) })) : null] }));
11
11
  }
@@ -86,5 +86,5 @@ export function BlogDetail({ config, slug, theme, branding, className, trackView
86
86
  publishedAt: r.published_at,
87
87
  readingMinutes: estimateReadingMinutes(r.content || ""),
88
88
  }));
89
- return (_jsxs(Scope, { className: cx("bp-blog-detail", "bp-site-article", branding?.className, className), style: themeVars(theme, branding), css: branding?.css, children: [state.status === "loading" ? _jsx(LoadingState, { label: "Loading..." }) : null, state.status === "error" ? (_jsx(ErrorState, { message: state.authError ? state.error : "Blog not found.", authError: state.authError })) : null, post ? (_jsxs(_Fragment, { children: [_jsx(ReadingProgress, {}), _jsx(ArticleDetailHero, { homeHref: homeHref, homeLabel: homeLabel, category: post.category ? { slug: post.category.slug, name: post.category.name } : null, categoryHref: post.category ? categoryPath(post.category.slug) : null, title: post.title, excerpt: post.excerpt, publishedAt: post.published_at, readingMinutes: readingMinutes, authors: authors, mediaUrl: mediaUrl, mediaAlt: post.title, onBack: onBack, onHome: onHome, onCategory: onCategory }), _jsxs("main", { className: "wrap article-shell", children: [_jsx(ArticleRailDetails, { className: "rail-details-mobile", owners: authors, related: railRelated, hrefFor: postPath, onSelect: onSelectRelated }), _jsxs("article", { className: "article", children: [_jsx("div", { className: "prose", dangerouslySetInnerHTML: { __html: contentHtml } }), categories.length > 0 || tags.length > 0 ? (_jsxs("div", { className: "tag-row", children: [categories.map((c) => onCategory ? (_jsx("button", { type: "button", className: "tag-pill", onClick: () => onCategory(c.slug), children: c.name }, c.id)) : (_jsx("a", { className: "tag-pill", href: categoryPath(c.slug), children: c.name }, c.id))), tags.map((t) => (_jsxs("span", { className: "tag-pill", children: ["#", t.name] }, t.id)))] })) : null, _jsx("div", { className: "share-foot", children: _jsx(ShareRow, { title: post.title, slug: post.slug, origin: origin || (config.domain ? `https://${config.domain}` : ""), path: postPath(post.slug) }) }), authors.map((a) => (_jsx("div", { className: "author-card", children: _jsxs("div", { children: [_jsxs("p", { className: "author-name", children: [a.name, a.jobTitle ? _jsxs("span", { children: [" \u2014 ", a.jobTitle] }) : null] }), a.bio ? _jsx("p", { className: "author-bio", children: a.bio }) : null] }) }, a.id))), _jsx(CommentSection, { postId: post.id, allowComments: allowComments, initialComments: initialComments, onSubmitComment: onSubmitComment })] }), _jsxs("aside", { className: "rail", children: [_jsx(ArticleRailDetails, { className: "rail-details-desktop", owners: authors, related: railRelated, hrefFor: postPath, onSelect: onSelectRelated }), headings.length > 1 ? (_jsxs("nav", { className: "toc", "aria-label": "On this page", children: [_jsx("p", { className: "rail-title", children: "On this page" }), _jsx("ol", { children: headings.map((h) => (_jsx("li", { className: h.level === 3 ? "sub" : undefined, children: _jsx("a", { href: `#${h.id}`, children: h.text }) }, h.id))) })] })) : null] })] })] })) : state.status === "success" || state.status === "empty" ? (_jsx(EmptyState, { label: "Blog not found." })) : null] }));
89
+ return (_jsxs(Scope, { className: cx("blog_bp-blog-detail", "blog_bp-site-article", branding?.className, className), style: themeVars(theme, branding), css: branding?.css, children: [state.status === "loading" ? _jsx(LoadingState, { label: "Loading..." }) : null, state.status === "error" ? (_jsx(ErrorState, { message: state.authError ? state.error : "Blog not found.", authError: state.authError })) : null, post ? (_jsxs(_Fragment, { children: [_jsx(ReadingProgress, {}), _jsx(ArticleDetailHero, { homeHref: homeHref, homeLabel: homeLabel, category: post.category ? { slug: post.category.slug, name: post.category.name } : null, categoryHref: post.category ? categoryPath(post.category.slug) : null, title: post.title, excerpt: post.excerpt, publishedAt: post.published_at, readingMinutes: readingMinutes, authors: authors, mediaUrl: mediaUrl, mediaAlt: post.title, onBack: onBack, onHome: onHome, onCategory: onCategory }), _jsxs("main", { className: "blog_wrap blog_article-shell", children: [_jsx(ArticleRailDetails, { className: "blog_rail-details-mobile", owners: authors, related: railRelated, hrefFor: postPath, onSelect: onSelectRelated }), _jsxs("article", { className: "blog_article", children: [_jsx("div", { className: "blog_prose", dangerouslySetInnerHTML: { __html: contentHtml } }), categories.length > 0 || tags.length > 0 ? (_jsxs("div", { className: "blog_tag-row", children: [categories.map((c) => onCategory ? (_jsx("button", { type: "button", className: "blog_tag-pill", onClick: () => onCategory(c.slug), children: c.name }, c.id)) : (_jsx("a", { className: "blog_tag-pill", href: categoryPath(c.slug), children: c.name }, c.id))), tags.map((t) => (_jsxs("span", { className: "blog_tag-pill", children: ["#", t.name] }, t.id)))] })) : null, _jsx("div", { className: "blog_share-foot", children: _jsx(ShareRow, { title: post.title, slug: post.slug, origin: origin || (config.domain ? `https://${config.domain}` : ""), path: postPath(post.slug) }) }), authors.map((a) => (_jsx("div", { className: "blog_author-card", children: _jsxs("div", { children: [_jsxs("p", { className: "blog_author-name", children: [a.name, a.jobTitle ? _jsxs("span", { children: [" \u2014 ", a.jobTitle] }) : null] }), a.bio ? _jsx("p", { className: "blog_author-bio", children: a.bio }) : null] }) }, a.id))), _jsx(CommentSection, { postId: post.id, allowComments: allowComments, initialComments: initialComments, onSubmitComment: onSubmitComment })] }), _jsxs("aside", { className: "blog_rail", children: [_jsx(ArticleRailDetails, { className: "blog_rail-details-desktop", owners: authors, related: railRelated, hrefFor: postPath, onSelect: onSelectRelated }), headings.length > 1 ? (_jsxs("nav", { className: "blog_toc", "aria-label": "On this page", children: [_jsx("p", { className: "blog_rail-title", children: "On this page" }), _jsx("ol", { children: headings.map((h) => (_jsx("li", { className: h.level === 3 ? "blog_sub" : undefined, children: _jsx("a", { href: `#${h.id}`, children: h.text }) }, h.id))) })] })) : null] })] })] })) : state.status === "success" || state.status === "empty" ? (_jsx(EmptyState, { label: "Blog not found." })) : null] }));
90
90
  }
@@ -52,5 +52,5 @@ export function BlogList({ config, theme, branding, className, params, onSelect,
52
52
  setCategoryId(id);
53
53
  setPage(1);
54
54
  };
55
- return (_jsxs(Scope, { className: cx("bp-site-index", branding?.className, className), style: themeVars(resolvedTheme, branding), css: branding?.css, children: [showMediaHero ? (_jsx(SiteMediaHero, { slides: heroSlides, siteName: siteName, onSelect: onSelect })) : (_jsxs("section", { className: "site-hero site-animate-in", children: [_jsxs("div", { className: "site-hero-inner", children: [_jsx("p", { className: "site-hero-eyebrow site-animate-item", children: siteName }), _jsx("h1", { className: "site-hero-title site-animate-item", children: heroTitle }), _jsx("p", { className: "site-hero-desc site-animate-item", children: heroDesc })] }), _jsx("div", { className: "site-hero-glow", "aria-hidden": "true" })] })), _jsxs("section", { className: "site-index-feed", "aria-label": feedLabel, children: [_jsxs("div", { className: "site-index-bridge", "aria-hidden": "true", children: [_jsx("span", { className: "site-index-bridge-glow" }), _jsx("span", { className: "site-index-bridge-line" })] }), _jsxs("div", { className: "site-index-feed-inner", children: [_jsxs("header", { className: "site-index-feed-head", children: [_jsx("p", { className: "site-index-feed-eyebrow", children: feedLabel }), _jsx("span", { className: "site-index-feed-rule", "aria-hidden": "true" })] }), _jsxs("div", { className: "site-page site-index-feed-body", children: [categories.length > 0 ? (_jsxs("nav", { className: "cat-bar site-animate-in", "aria-label": "Filter by category", children: [_jsx("button", { type: "button", className: "site-animate-item", "aria-current": !categoryId ? "page" : undefined, onClick: () => selectCategory(undefined), children: "All" }), categories.map((c) => (_jsx("button", { type: "button", className: "site-animate-item", "aria-current": categoryId === c.id ? "page" : undefined, onClick: () => selectCategory(c.id), children: c.name }, c.id)))] })) : null, state.status === "loading" ? _jsx(LoadingState, { label: "Loading blogs..." }) : null, state.status === "error" ? (_jsx(ErrorState, { message: state.error, authError: state.authError })) : null, state.status === "empty" ? (_jsx("p", { className: "empty site-animate-in", children: _jsx("span", { className: "site-animate-item", children: "Nothing published yet." }) })) : null, state.status === "success" ? (_jsxs(_Fragment, { children: [_jsx(BlogGrid, { blogs: state.data.items, theme: resolvedTheme, onSelect: onSelect, getHref: getHref, leadFirst: showLeadCard && state.data.items.length > 0 }), totalPages > 1 ? (_jsxs("div", { className: "pagination", children: [_jsx("button", { type: "button", disabled: page <= 1, onClick: () => setPage((value) => Math.max(1, value - 1)), children: "Previous" }), _jsxs("span", { children: ["Page ", page, " of ", totalPages] }), _jsx("button", { type: "button", disabled: page >= totalPages, onClick: () => setPage((value) => value + 1), children: "Next" })] })) : null] })) : null] })] })] })] }));
55
+ return (_jsxs(Scope, { className: cx("blog_bp-site-index", branding?.className, className), style: themeVars(resolvedTheme, branding), css: branding?.css, children: [showMediaHero ? (_jsx(SiteMediaHero, { slides: heroSlides, siteName: siteName, onSelect: onSelect })) : (_jsxs("section", { className: "blog_site-hero blog_site-animate-in", children: [_jsxs("div", { className: "blog_site-hero-inner", children: [_jsx("p", { className: "blog_site-hero-eyebrow blog_site-animate-item", children: siteName }), _jsx("h1", { className: "blog_site-hero-title blog_site-animate-item", children: heroTitle }), _jsx("p", { className: "blog_site-hero-desc blog_site-animate-item", children: heroDesc })] }), _jsx("div", { className: "blog_site-hero-glow", "aria-hidden": "true" })] })), _jsxs("section", { className: "blog_site-index-feed", "aria-label": feedLabel, children: [_jsxs("div", { className: "blog_site-index-bridge", "aria-hidden": "true", children: [_jsx("span", { className: "blog_site-index-bridge-glow" }), _jsx("span", { className: "blog_site-index-bridge-line" })] }), _jsxs("div", { className: "blog_site-index-feed-inner", children: [_jsxs("header", { className: "blog_site-index-feed-head", children: [_jsx("p", { className: "blog_site-index-feed-eyebrow", children: feedLabel }), _jsx("span", { className: "blog_site-index-feed-rule", "aria-hidden": "true" })] }), _jsxs("div", { className: "blog_site-page blog_site-index-feed-body", children: [categories.length > 0 ? (_jsxs("nav", { className: "blog_cat-bar blog_site-animate-in", "aria-label": "Filter by category", children: [_jsx("button", { type: "button", className: "blog_site-animate-item", "aria-current": !categoryId ? "page" : undefined, onClick: () => selectCategory(undefined), children: "All" }), categories.map((c) => (_jsx("button", { type: "button", className: "blog_site-animate-item", "aria-current": categoryId === c.id ? "page" : undefined, onClick: () => selectCategory(c.id), children: c.name }, c.id)))] })) : null, state.status === "loading" ? _jsx(LoadingState, { label: "Loading blogs..." }) : null, state.status === "error" ? (_jsx(ErrorState, { message: state.error, authError: state.authError })) : null, state.status === "empty" ? (_jsx("p", { className: "blog_empty blog_site-animate-in", children: _jsx("span", { className: "blog_site-animate-item", children: "Nothing published yet." }) })) : null, state.status === "success" ? (_jsxs(_Fragment, { children: [_jsx(BlogGrid, { blogs: state.data.items, theme: resolvedTheme, onSelect: onSelect, getHref: getHref, leadFirst: showLeadCard && state.data.items.length > 0 }), totalPages > 1 ? (_jsxs("div", { className: "blog_pagination", children: [_jsx("button", { type: "button", disabled: page <= 1, onClick: () => setPage((value) => Math.max(1, value - 1)), children: "Previous" }), _jsxs("span", { children: ["Page ", page, " of ", totalPages] }), _jsx("button", { type: "button", disabled: page >= totalPages, onClick: () => setPage((value) => value + 1), children: "Next" })] })) : null] })) : null] })] })] })] }));
56
56
  }
@@ -12,8 +12,8 @@ export function BlogSearch({ config, theme, branding, className, onSelect, getHr
12
12
  const state = useAsync(() => submitted
13
13
  ? client.searchBlogs(submitted, { page: 1, page_size: 12 })
14
14
  : Promise.resolve({ items: [], page: 1, pageSize: 12, total: 0 }), [client, submitted], (data) => submitted !== "" && data.items.length === 0);
15
- return (_jsxs(Scope, { className: cx("bp-site-index", "bp-blog-search", branding?.className, className), style: themeVars(theme, branding), css: branding?.css, children: [_jsxs("form", { className: "bp-blog-search__form", onSubmit: (event) => {
15
+ return (_jsxs(Scope, { className: cx("blog_bp-site-index", "blog_bp-blog-search", branding?.className, className), style: themeVars(theme, branding), css: branding?.css, children: [_jsxs("form", { className: "blog_bp-blog-search__form", onSubmit: (event) => {
16
16
  event.preventDefault();
17
17
  setSubmitted(query.trim());
18
- }, style: { display: "flex", gap: "0.5rem", marginBottom: "1rem" }, children: [_jsx("input", { value: query, onChange: (event) => setQuery(event.target.value), placeholder: placeholder, "aria-label": "Search blogs", style: { flex: 1, padding: "0.6rem 0.75rem", borderRadius: "var(--bp-radius)" } }), _jsx("button", { type: "submit", children: "Search" })] }), !submitted ? _jsx("p", { className: "bp-state", children: "Enter a search term to find posts." }) : null, submitted && state.status === "loading" ? _jsx(LoadingState, { label: "Searching..." }) : null, state.status === "error" ? (_jsx(ErrorState, { message: state.error, authError: state.authError })) : null, state.status === "empty" ? _jsx(EmptyState, { label: "No matching posts." }) : null, state.status === "success" ? (_jsx(BlogGrid, { blogs: state.data.items, theme: theme, onSelect: onSelect, getHref: getHref })) : null] }));
18
+ }, style: { display: "flex", gap: "0.5rem", marginBottom: "1rem" }, children: [_jsx("input", { value: query, onChange: (event) => setQuery(event.target.value), placeholder: placeholder, "aria-label": "Search blogs", style: { flex: 1, padding: "0.6rem 0.75rem", borderRadius: "var(--bp-radius)" } }), _jsx("button", { type: "submit", children: "Search" })] }), !submitted ? _jsx("p", { className: "blog_bp-state", children: "Enter a search term to find posts." }) : null, submitted && state.status === "loading" ? _jsx(LoadingState, { label: "Searching..." }) : null, state.status === "error" ? (_jsx(ErrorState, { message: state.error, authError: state.authError })) : null, state.status === "empty" ? _jsx(EmptyState, { label: "No matching posts." }) : null, state.status === "success" ? (_jsx(BlogGrid, { blogs: state.data.items, theme: theme, onSelect: onSelect, getHref: getHref })) : null] }));
19
19
  }
@@ -7,5 +7,5 @@ import { EmptyState, ErrorState, LoadingState, Scope } from "./internal/States";
7
7
  export function BlogTags({ config, theme, branding, className, onSelect, }) {
8
8
  const client = useMemo(() => new BlogClient(config), [config.apiUrl, config.publicApiKey, config.email, config.domain, config.timeoutMs]);
9
9
  const state = useAsync(() => client.getTags(), [client], (data) => data.length === 0);
10
- return (_jsxs(Scope, { className: cx("bp-blog-tags", branding?.className, className), style: themeVars(theme, branding), css: branding?.css, children: [state.status === "loading" ? _jsx(LoadingState, { label: "Loading tags..." }) : null, state.status === "error" ? (_jsx(ErrorState, { message: state.error, authError: state.authError })) : null, state.status === "empty" ? _jsx(EmptyState, { label: "No tags yet." }) : null, state.status === "success" ? (_jsx("div", { className: "bp-blog-tags__list", style: { display: "flex", flexWrap: "wrap", gap: "0.5rem" }, children: state.data.map((tag) => (_jsx("button", { type: "button", onClick: () => onSelect?.(tag), children: tag.name }, tag.id))) })) : null] }));
10
+ return (_jsxs(Scope, { className: cx("blog_bp-blog-tags", branding?.className, className), style: themeVars(theme, branding), css: branding?.css, children: [state.status === "loading" ? _jsx(LoadingState, { label: "Loading tags..." }) : null, state.status === "error" ? (_jsx(ErrorState, { message: state.error, authError: state.authError })) : null, state.status === "empty" ? _jsx(EmptyState, { label: "No tags yet." }) : null, state.status === "success" ? (_jsx("div", { className: "blog_bp-blog-tags__list", style: { display: "flex", flexWrap: "wrap", gap: "0.5rem" }, children: state.data.map((tag) => (_jsx("button", { type: "button", onClick: () => onSelect?.(tag), children: tag.name }, tag.id))) })) : null] }));
11
11
  }
@@ -8,5 +8,5 @@ import { EmptyState, ErrorState, LoadingState, Scope } from "./internal/States";
8
8
  export function FeaturedBlogs({ config, theme, branding, className, limit = 3, onSelect, getHref, }) {
9
9
  const client = useMemo(() => new BlogClient(config), [config.apiUrl, config.publicApiKey, config.email, config.domain, config.timeoutMs]);
10
10
  const state = useAsync(() => client.getFeaturedBlogs(limit), [client, limit], (data) => data.length === 0);
11
- return (_jsxs(Scope, { className: cx("bp-site-index", "bp-featured-blogs", branding?.className, className), style: themeVars(theme, branding), css: branding?.css, children: [state.status === "loading" ? _jsx(LoadingState, {}) : null, state.status === "error" ? (_jsx(ErrorState, { message: state.error, authError: state.authError })) : null, state.status === "empty" ? _jsx(EmptyState, {}) : null, state.status === "success" ? (_jsx(BlogGrid, { blogs: state.data, theme: theme, onSelect: onSelect, getHref: getHref })) : null] }));
11
+ return (_jsxs(Scope, { className: cx("blog_bp-site-index", "blog_bp-featured-blogs", branding?.className, className), style: themeVars(theme, branding), css: branding?.css, children: [state.status === "loading" ? _jsx(LoadingState, {}) : null, state.status === "error" ? (_jsx(ErrorState, { message: state.error, authError: state.authError })) : null, state.status === "empty" ? _jsx(EmptyState, {}) : null, state.status === "success" ? (_jsx(BlogGrid, { blogs: state.data, theme: theme, onSelect: onSelect, getHref: getHref })) : null] }));
12
12
  }
@@ -8,5 +8,5 @@ import { EmptyState, ErrorState, LoadingState, Scope } from "./internal/States";
8
8
  export function RelatedBlogs({ config, blog, theme, branding, className, limit = 3, onSelect, getHref, }) {
9
9
  const client = useMemo(() => new BlogClient(config), [config.apiUrl, config.publicApiKey, config.email, config.domain, config.timeoutMs]);
10
10
  const state = useAsync(() => client.getRelatedBlogs(blog, limit), [client, blog.id, blog.category_id, limit], (data) => data.length === 0);
11
- return (_jsxs(Scope, { className: cx("bp-site-index", "bp-related-blogs", branding?.className, className), style: themeVars(theme, branding), css: branding?.css, children: [state.status === "loading" ? _jsx(LoadingState, {}) : null, state.status === "error" ? (_jsx(ErrorState, { message: state.error, authError: state.authError })) : null, state.status === "empty" ? _jsx(EmptyState, { label: "No related posts." }) : null, state.status === "success" ? (_jsx(BlogGrid, { blogs: state.data, theme: theme, onSelect: onSelect, getHref: getHref })) : null] }));
11
+ return (_jsxs(Scope, { className: cx("blog_bp-site-index", "blog_bp-related-blogs", branding?.className, className), style: themeVars(theme, branding), css: branding?.css, children: [state.status === "loading" ? _jsx(LoadingState, {}) : null, state.status === "error" ? (_jsx(ErrorState, { message: state.error, authError: state.authError })) : null, state.status === "empty" ? _jsx(EmptyState, { label: "No related posts." }) : null, state.status === "success" ? (_jsx(BlogGrid, { blogs: state.data, theme: theme, onSelect: onSelect, getHref: getHref })) : null] }));
12
12
  }
@@ -39,5 +39,5 @@ export function SiteMediaHero({ slides: rawSlides, siteName, onSelect }) {
39
39
  const published = blog.published_at || blog.created_at;
40
40
  const readingMinutes = estimateReadingMinutes([blog.excerpt, blog.content].filter(Boolean).join(" "));
41
41
  const multi = slides.length > 1;
42
- return (_jsxs("section", { className: "site-hero-media", "aria-labelledby": "site-hero-media-title", "aria-roledescription": multi ? "carousel" : undefined, children: [_jsxs("div", { className: "site-hero-media-bg", children: [slides.map(({ blog: slideBlog }, i) => (_jsx("div", { className: `site-hero-media-slide${i === safeIndex ? " is-active" : ""}`, "aria-hidden": i !== safeIndex, children: _jsx("img", { className: "site-hero-media-visual", src: slideBlog.featured_image, alt: "" }) }, slideBlog.id))), _jsx("div", { className: "site-hero-media-scrim", "aria-hidden": "true" }), _jsx("div", { className: "site-hero-media-grain", "aria-hidden": "true" })] }), _jsxs("div", { className: "site-hero-media-content", children: [_jsxs("div", { className: "site-hero-media-copy", children: [_jsx(HeroFadeSlide, { from: "left", delayMs: 100, children: _jsx("p", { className: "site-hero-media-eyebrow", children: eyebrow }) }), _jsx(HeroFadeSlide, { from: "left", delayMs: 260, children: _jsx("h1", { id: "site-hero-media-title", className: "site-hero-media-title", children: blog.title }) }), excerpt ? (_jsx(HeroFadeSlide, { from: "right", delayMs: 420, children: _jsx("p", { className: "site-hero-media-desc", children: excerpt }) })) : null, _jsx(HeroFadeSlide, { from: "left", delayMs: excerpt ? 580 : 420, className: "site-hero-media-meta-wrap", children: _jsxs("div", { className: "site-hero-media-meta", children: [published ? _jsx("time", { dateTime: published, children: formatDate(published) }) : null, readingMinutes ? (_jsxs("span", { className: "site-hero-media-reading", children: [readingMinutes, " min read"] })) : null] }) }), _jsx(HeroFadeSlide, { from: "left", delayMs: excerpt ? 700 : 540, children: href ? (_jsxs("a", { href: href, className: "site-hero-media-cta", children: [_jsx("span", { className: "site-hero-media-cta-label", children: "Read story" }), _jsx("span", { className: "site-hero-media-cta-arrow", "aria-hidden": "true", children: "\u2192" })] })) : (_jsxs("button", { type: "button", className: "site-hero-media-cta", onClick: () => onSelect?.(blog), children: [_jsx("span", { className: "site-hero-media-cta-label", children: "Read story" }), _jsx("span", { className: "site-hero-media-cta-arrow", "aria-hidden": "true", children: "\u2192" })] })) })] }, blog.id), multi ? (_jsx("div", { className: "site-hero-media-dots", role: "tablist", "aria-label": "Featured posts", children: slides.map(({ blog: slideBlog }, i) => (_jsx("button", { type: "button", role: "tab", className: `site-hero-media-dot${i === safeIndex ? " is-active" : ""}`, "aria-selected": i === safeIndex, "aria-label": `Show ${slideBlog.title}`, onClick: () => setIndex(i) }, slideBlog.id))) })) : null] }), _jsx("div", { className: "site-hero-media-edge", "aria-hidden": "true" })] }));
42
+ return (_jsxs("section", { className: "blog_site-hero-media", "aria-labelledby": "site-hero-media-title", "aria-roledescription": multi ? "carousel" : undefined, children: [_jsxs("div", { className: "blog_site-hero-media-bg", children: [slides.map(({ blog: slideBlog }, i) => (_jsx("div", { className: `blog_site-hero-media-slide${i === safeIndex ? " blog_is-active" : ""}`, "aria-hidden": i !== safeIndex, children: _jsx("img", { className: "blog_site-hero-media-visual", src: slideBlog.featured_image, alt: "" }) }, slideBlog.id))), _jsx("div", { className: "blog_site-hero-media-scrim", "aria-hidden": "true" }), _jsx("div", { className: "blog_site-hero-media-grain", "aria-hidden": "true" })] }), _jsxs("div", { className: "blog_site-hero-media-content", children: [_jsxs("div", { className: "blog_site-hero-media-copy", children: [_jsx(HeroFadeSlide, { from: "left", delayMs: 100, children: _jsx("p", { className: "blog_site-hero-media-eyebrow", children: eyebrow }) }), _jsx(HeroFadeSlide, { from: "left", delayMs: 260, children: _jsx("h1", { id: "site-hero-media-title", className: "blog_site-hero-media-title", children: blog.title }) }), excerpt ? (_jsx(HeroFadeSlide, { from: "right", delayMs: 420, children: _jsx("p", { className: "blog_site-hero-media-desc", children: excerpt }) })) : null, _jsx(HeroFadeSlide, { from: "left", delayMs: excerpt ? 580 : 420, className: "blog_site-hero-media-meta-wrap", children: _jsxs("div", { className: "blog_site-hero-media-meta", children: [published ? _jsx("time", { dateTime: published, children: formatDate(published) }) : null, readingMinutes ? (_jsxs("span", { className: "blog_site-hero-media-reading", children: [readingMinutes, " min read"] })) : null] }) }), _jsx(HeroFadeSlide, { from: "left", delayMs: excerpt ? 700 : 540, children: href ? (_jsxs("a", { href: href, className: "blog_site-hero-media-cta", children: [_jsx("span", { className: "blog_site-hero-media-cta-label", children: "Read story" }), _jsx("span", { className: "blog_site-hero-media-cta-arrow", "aria-hidden": "true", children: "\u2192" })] })) : (_jsxs("button", { type: "button", className: "blog_site-hero-media-cta", onClick: () => onSelect?.(blog), children: [_jsx("span", { className: "blog_site-hero-media-cta-label", children: "Read story" }), _jsx("span", { className: "blog_site-hero-media-cta-arrow", "aria-hidden": "true", children: "\u2192" })] })) })] }, blog.id), multi ? (_jsx("div", { className: "blog_site-hero-media-dots", role: "tablist", "aria-label": "Featured posts", children: slides.map(({ blog: slideBlog }, i) => (_jsx("button", { type: "button", role: "tab", className: `blog_site-hero-media-dot${i === safeIndex ? " blog_is-active" : ""}`, "aria-selected": i === safeIndex, "aria-label": `Show ${slideBlog.title}`, onClick: () => setIndex(i) }, slideBlog.id))) })) : null] }), _jsx("div", { className: "blog_site-hero-media-edge", "aria-hidden": "true" })] }));
43
43
  }
@@ -4,11 +4,11 @@ import { BackButton } from "./BackButton";
4
4
  import { articleFormatDate } from "./toc";
5
5
  export function ArticleDetailHero({ homeHref, homeLabel, category, categoryHref, title, excerpt, publishedAt, readingMinutes, authors, mediaUrl, mediaAlt, mediaCaption, formatHero, onBack, onHome, onCategory, }) {
6
6
  const isBlogDetails = !mediaUrl && !formatHero;
7
- const homeEl = onHome ? (_jsx("button", { type: "button", className: "bp-linkish", onClick: onHome, style: { color: "inherit", background: "none", border: 0, padding: 0, cursor: "pointer", font: "inherit" }, children: homeLabel })) : (_jsx("a", { href: homeHref, style: { color: "inherit", textDecoration: "none" }, children: homeLabel }));
7
+ const homeEl = onHome ? (_jsx("button", { type: "button", className: "blog_bp-linkish", onClick: onHome, style: { color: "inherit", background: "none", border: 0, padding: 0, cursor: "pointer", font: "inherit" }, children: homeLabel })) : (_jsx("a", { href: homeHref, style: { color: "inherit", textDecoration: "none" }, children: homeLabel }));
8
8
  const catEl = category ? (categoryHref || onCategory ? (onCategory ? (_jsx("button", { type: "button", onClick: () => onCategory(category.slug), style: { color: "inherit", background: "none", border: 0, padding: 0, cursor: "pointer", font: "inherit", textDecoration: "none" }, children: category.name })) : (_jsx("a", { href: categoryHref, style: { color: "inherit", textDecoration: "none" }, children: category.name }))) : (_jsx("span", { children: category.name }))) : null;
9
- return (_jsxs("section", { className: `article-detail-hero${isBlogDetails ? " blog-details-hero" : ""}`, "aria-labelledby": "article-hero-title", style: isBlogDetails
9
+ return (_jsxs("section", { className: `blog_article-detail-hero${isBlogDetails ? " blog_blog-details-hero" : ""}`, "aria-labelledby": "article-hero-title", style: isBlogDetails
10
10
  ? { backgroundColor: "#0B4A75", color: "#fff", paddingTop: 40, paddingBottom: 60 }
11
- : undefined, children: [mediaUrl ? (_jsxs("figure", { className: "article-hero-media", children: [_jsx("img", { className: "article-hero-visual", src: mediaUrl, alt: mediaAlt || title }), mediaCaption ? _jsx("figcaption", { className: "article-hero-caption", children: mediaCaption }) : null] })) : formatHero ? (_jsx("div", { className: "article-hero-media article-hero-format", children: formatHero })) : null, _jsx("header", { className: "article-hero-copy", children: _jsxs("div", { className: "article-hero-copy-inner", style: { maxWidth: 1200, margin: "0 auto", width: "100%" }, children: [_jsx(HeroFadeSlide, { from: "left", delayMs: 80, children: _jsxs("ul", { className: "breadcrumb", style: {
11
+ : undefined, children: [mediaUrl ? (_jsxs("figure", { className: "blog_article-hero-media", children: [_jsx("img", { className: "blog_article-hero-visual", src: mediaUrl, alt: mediaAlt || title }), mediaCaption ? _jsx("figcaption", { className: "blog_article-hero-caption", children: mediaCaption }) : null] })) : formatHero ? (_jsx("div", { className: "blog_article-hero-media blog_article-hero-format", children: formatHero })) : null, _jsx("header", { className: "blog_article-hero-copy", children: _jsxs("div", { className: "blog_article-hero-copy-inner", style: { maxWidth: 1200, margin: "0 auto", width: "100%" }, children: [_jsx(HeroFadeSlide, { from: "left", delayMs: 80, children: _jsxs("ul", { className: "blog_breadcrumb", style: {
12
12
  display: "flex",
13
13
  alignItems: "center",
14
14
  flexWrap: "wrap",
@@ -18,12 +18,12 @@ export function ArticleDetailHero({ homeHref, homeLabel, category, categoryHref,
18
18
  margin: "0 0 40px 0",
19
19
  color: isBlogDetails ? "#fff" : "inherit",
20
20
  fontSize: "0.9rem",
21
- }, children: [_jsx("li", { children: homeEl }), category ? (_jsxs(_Fragment, { children: [_jsx("li", { "aria-hidden": "true", style: { opacity: 0.6, fontSize: "0.8em" }, children: "\u2794" }), _jsx("li", { children: catEl })] })) : null, _jsx("li", { "aria-hidden": "true", style: { opacity: 0.6, fontSize: "0.8em" }, children: "\u2794" }), _jsx("li", { style: { opacity: 0.9 }, children: title })] }) }), category && !isBlogDetails ? (_jsx(HeroFadeSlide, { from: "left", delayMs: 180, children: _jsx("p", { className: "eyebrow", children: category.name }) })) : null, _jsx(HeroFadeSlide, { from: "left", delayMs: category ? 300 : 220, children: _jsxs("div", { style: {
21
+ }, children: [_jsx("li", { children: homeEl }), category ? (_jsxs(_Fragment, { children: [_jsx("li", { "aria-hidden": "true", style: { opacity: 0.6, fontSize: "0.8em" }, children: "\u2794" }), _jsx("li", { children: catEl })] })) : null, _jsx("li", { "aria-hidden": "true", style: { opacity: 0.6, fontSize: "0.8em" }, children: "\u2794" }), _jsx("li", { style: { opacity: 0.9 }, children: title })] }) }), category && !isBlogDetails ? (_jsx(HeroFadeSlide, { from: "left", delayMs: 180, children: _jsx("p", { className: "blog_eyebrow", children: category.name }) })) : null, _jsx(HeroFadeSlide, { from: "left", delayMs: category ? 300 : 220, children: _jsxs("div", { style: {
22
22
  display: "flex",
23
23
  alignItems: "center",
24
24
  justifyContent: isBlogDetails ? "center" : "flex-start",
25
25
  gap: 16,
26
26
  marginBottom: 24,
27
27
  textAlign: isBlogDetails ? "center" : "left",
28
- }, children: [!isBlogDetails ? _jsx(BackButton, { onBack: onBack }) : null, _jsx("h1", { id: "article-hero-title", className: "article-hero-title", style: { margin: 0, color: isBlogDetails ? "#fff" : "inherit" }, children: title })] }) }), excerpt ? (_jsx(HeroFadeSlide, { from: "right", delayMs: category ? 460 : 380, children: _jsx("p", { className: "standfirst article-hero-standfirst", children: excerpt }) })) : null, _jsx(HeroFadeSlide, { from: "left", delayMs: excerpt ? 620 : 500, children: _jsxs("div", { className: "byline-row", children: [authors.length ? (_jsx("div", { className: "byline-faces", children: authors.map((a) => a.avatarUrl ? (_jsx("img", { src: a.avatarUrl, alt: "", width: 34, height: 34 }, a.id)) : (_jsx("span", { className: "face-fallback", "aria-hidden": "true", children: a.name.slice(0, 1) }, a.id))) })) : null, _jsxs("div", { className: "byline-text", children: [authors.length ? (_jsx("span", { className: "by", children: authors.map((a) => a.name).join(" and ") })) : null, _jsxs("span", { className: "meta", children: [publishedAt ? (_jsx("time", { dateTime: publishedAt, children: articleFormatDate(publishedAt) })) : null, readingMinutes ? _jsxs("span", { children: [readingMinutes, " min read"] }) : null] })] })] }) })] }) })] }));
28
+ }, children: [!isBlogDetails ? _jsx(BackButton, { onBack: onBack }) : null, _jsx("h1", { id: "article-hero-title", className: "blog_article-hero-title", style: { margin: 0, color: isBlogDetails ? "#fff" : "inherit" }, children: title })] }) }), excerpt ? (_jsx(HeroFadeSlide, { from: "right", delayMs: category ? 460 : 380, children: _jsx("p", { className: "blog_standfirst blog_article-hero-standfirst", children: excerpt }) })) : null, _jsx(HeroFadeSlide, { from: "left", delayMs: excerpt ? 620 : 500, children: _jsxs("div", { className: "blog_byline-row", children: [authors.length ? (_jsx("div", { className: "blog_byline-faces", children: authors.map((a) => a.avatarUrl ? (_jsx("img", { src: a.avatarUrl, alt: "", width: 34, height: 34 }, a.id)) : (_jsx("span", { className: "blog_face-fallback", "aria-hidden": "true", children: a.name.slice(0, 1) }, a.id))) })) : null, _jsxs("div", { className: "blog_byline-text", children: [authors.length ? (_jsx("span", { className: "blog_by", children: authors.map((a) => a.name).join(" and ") })) : null, _jsxs("span", { className: "blog_meta", children: [publishedAt ? (_jsx("time", { dateTime: publishedAt, children: articleFormatDate(publishedAt) })) : null, readingMinutes ? _jsxs("span", { children: [readingMinutes, " min read"] }) : null] })] })] }) })] }) })] }));
29
29
  }
@@ -3,10 +3,10 @@ import { relativeTime } from "./toc";
3
3
  export function ArticleRailDetails({ owners, related, hrefFor, onSelect, className }) {
4
4
  if (!owners.length && !related.length)
5
5
  return null;
6
- return (_jsxs("div", { className: `article-rail-details${className ? ` ${className}` : ""}`, children: [owners.length ? (_jsxs("section", { className: "rail-owner-panel", "aria-label": "Post owner", children: [_jsx("div", { className: "rail-related-head", children: _jsx("h3", { children: owners.length > 1 ? "Authors" : "Owner" }) }), _jsx("ul", { className: "rail-owner-list", children: owners.map((owner) => (_jsxs("li", { className: "rail-owner", children: [owner.avatarUrl ? (_jsx("img", { src: owner.avatarUrl, alt: "", width: 40, height: 40 })) : (_jsx("span", { className: "rail-owner-fallback", "aria-hidden": "true", children: owner.name
6
+ return (_jsxs("div", { className: `blog_article-rail-details${className ? ` ${className}` : ""}`, children: [owners.length ? (_jsxs("section", { className: "blog_rail-owner-panel", "aria-label": "Post owner", children: [_jsx("div", { className: "blog_rail-related-head", children: _jsx("h3", { children: owners.length > 1 ? "Authors" : "Owner" }) }), _jsx("ul", { className: "blog_rail-owner-list", children: owners.map((owner) => (_jsxs("li", { className: "blog_rail-owner", children: [owner.avatarUrl ? (_jsx("img", { src: owner.avatarUrl, alt: "", width: 40, height: 40 })) : (_jsx("span", { className: "blog_rail-owner-fallback", "aria-hidden": "true", children: owner.name
7
7
  .split(/\s+/)
8
8
  .filter(Boolean)
9
9
  .slice(0, 2)
10
10
  .map((p) => p[0]?.toUpperCase() ?? "")
11
- .join("") || "?" })), _jsxs("div", { className: "rail-owner-body", children: [_jsx("p", { className: "rail-owner-name", children: owner.name }), owner.jobTitle ? _jsx("p", { className: "rail-owner-role", children: owner.jobTitle }) : null, owner.bio ? _jsx("p", { className: "rail-owner-bio", children: owner.bio }) : null] })] }, owner.id))) })] })) : null, related.length ? (_jsxs("section", { className: "rail-related-panel", "aria-label": "Related posts", children: [_jsx("div", { className: "rail-related-head", children: _jsx("h3", { children: "Related posts" }) }), _jsx("div", { className: "rail-related-rows", children: related.map((item) => (_jsx("div", { className: "rail-related-row", children: _jsxs("div", { className: "rail-related-row-main", children: [onSelect ? (_jsx("button", { type: "button", className: "rail-related-t", onClick: () => onSelect(item.slug), children: item.title })) : (_jsx("a", { className: "rail-related-t", href: hrefFor(item.slug), children: item.title })), _jsxs("div", { className: "rail-related-sub", children: [_jsx("span", { children: relativeTime(item.publishedAt) }), item.readingMinutes ? _jsxs("span", { children: [item.readingMinutes, " min"] }) : null, onSelect ? (_jsx("button", { type: "button", className: "bp-linkish", onClick: () => onSelect(item.slug), children: "View \u2197" })) : (_jsx("a", { href: hrefFor(item.slug), children: "View \u2197" }))] })] }) }, item.id))) })] })) : null] }));
11
+ .join("") || "?" })), _jsxs("div", { className: "blog_rail-owner-body", children: [_jsx("p", { className: "blog_rail-owner-name", children: owner.name }), owner.jobTitle ? _jsx("p", { className: "blog_rail-owner-role", children: owner.jobTitle }) : null, owner.bio ? _jsx("p", { className: "blog_rail-owner-bio", children: owner.bio }) : null] })] }, owner.id))) })] })) : null, related.length ? (_jsxs("section", { className: "blog_rail-related-panel", "aria-label": "Related posts", children: [_jsx("div", { className: "blog_rail-related-head", children: _jsx("h3", { children: "Related posts" }) }), _jsx("div", { className: "blog_rail-related-rows", children: related.map((item) => (_jsx("div", { className: "blog_rail-related-row", children: _jsxs("div", { className: "blog_rail-related-row-main", children: [onSelect ? (_jsx("button", { type: "button", className: "blog_rail-related-t", onClick: () => onSelect(item.slug), children: item.title })) : (_jsx("a", { className: "blog_rail-related-t", href: hrefFor(item.slug), children: item.title })), _jsxs("div", { className: "blog_rail-related-sub", children: [_jsx("span", { children: relativeTime(item.publishedAt) }), item.readingMinutes ? _jsxs("span", { children: [item.readingMinutes, " min"] }) : null, onSelect ? (_jsx("button", { type: "button", className: "blog_bp-linkish", onClick: () => onSelect(item.slug), children: "View \u2197" })) : (_jsx("a", { href: hrefFor(item.slug), children: "View \u2197" }))] })] }) }, item.id))) })] })) : null] }));
12
12
  }
@@ -22,7 +22,7 @@ export function CommentSection({ postId, allowComments, initialComments = [], on
22
22
  setComments(initialComments);
23
23
  }, [initialComments]);
24
24
  if (!allowComments) {
25
- return (_jsxs("section", { className: "comments", id: "comments", "aria-labelledby": "comments-heading", children: [_jsx("h2", { id: "comments-heading", children: "Comments" }), _jsx("p", { className: "comments-closed", children: "Comments are closed for this post." })] }));
25
+ return (_jsxs("section", { className: "blog_comments", id: "comments", "aria-labelledby": "comments-heading", children: [_jsx("h2", { id: "comments-heading", children: "Comments" }), _jsx("p", { className: "blog_comments-closed", children: "Comments are closed for this post." })] }));
26
26
  }
27
27
  const submit = () => {
28
28
  setError(null);
@@ -64,5 +64,5 @@ export function CommentSection({ postId, allowComments, initialComments = [], on
64
64
  }
65
65
  })();
66
66
  };
67
- return (_jsxs("section", { className: "comments", id: "comments", "aria-labelledby": "comments-heading", children: [_jsxs("h2", { id: "comments-heading", children: ["Comments", comments.length ? _jsxs("span", { className: "comments-count", children: [" (", comments.length, ")"] }) : null] }), comments.length === 0 ? (_jsx("p", { className: "comments-empty", children: "No comments yet. Be the first to share your thoughts." })) : (_jsx("ul", { className: "comments-list", children: comments.map((c) => (_jsx("li", { className: "comment-item", children: _jsxs("div", { className: "comment-profile", children: [_jsx("span", { className: "comment-avatar", "aria-hidden": "true", children: initialsFor(c.authorName) }), _jsxs("div", { className: "comment-profile-body", children: [_jsxs("div", { className: "comment-meta", children: [_jsx("strong", { className: "comment-author", children: c.authorName }), _jsx("time", { dateTime: c.createdAt, children: articleFormatDate(c.createdAt) })] }), _jsx("p", { className: "comment-body", children: c.body })] })] }) }, c.id))) })), _jsxs("div", { className: "comment-form", children: [_jsx("h3", { className: "comment-form-title", children: "Leave a comment" }), error ? (_jsx("p", { className: "comment-error", role: "alert", children: error })) : null, flash ? (_jsx("p", { className: "comment-ok", role: "status", children: flash })) : null, _jsxs("label", { className: "comment-hp", "aria-hidden": "true", children: ["Website", _jsx("input", { tabIndex: -1, autoComplete: "off", value: website, onChange: (e) => setWebsite(e.target.value) })] }), _jsxs("div", { className: "comment-form-grid", children: [_jsxs("label", { children: [_jsx("span", { children: "Name" }), _jsx("input", { value: name, onChange: (e) => setName(e.target.value), maxLength: 80, required: true, autoComplete: "name" })] }), _jsxs("label", { children: [_jsxs("span", { children: ["Email ", _jsx("em", { children: "(optional, never shown)" })] }), _jsx("input", { type: "email", value: email, onChange: (e) => setEmail(e.target.value), autoComplete: "email" })] })] }), _jsxs("label", { className: "comment-body-field", children: [_jsx("span", { children: "Comment" }), _jsx("textarea", { rows: 5, value: body, onChange: (e) => setBody(e.target.value), maxLength: 4000, required: true })] }), _jsx("button", { type: "button", className: "comment-submit", disabled: pending, onClick: submit, children: pending ? "Posting…" : "Post comment" }), _jsx("p", { className: "comment-moderation-note", children: "Comments are reviewed before they appear on this post." })] })] }));
67
+ return (_jsxs("section", { className: "blog_comments", id: "comments", "aria-labelledby": "comments-heading", children: [_jsxs("h2", { id: "comments-heading", children: ["Comments", comments.length ? _jsxs("span", { className: "blog_comments-count", children: [" (", comments.length, ")"] }) : null] }), comments.length === 0 ? (_jsx("p", { className: "blog_comments-empty", children: "No comments yet. Be the first to share your thoughts." })) : (_jsx("ul", { className: "blog_comments-list", children: comments.map((c) => (_jsx("li", { className: "blog_comment-item", children: _jsxs("div", { className: "blog_comment-profile", children: [_jsx("span", { className: "blog_comment-avatar", "aria-hidden": "true", children: initialsFor(c.authorName) }), _jsxs("div", { className: "blog_comment-profile-body", children: [_jsxs("div", { className: "blog_comment-meta", children: [_jsx("strong", { className: "blog_comment-author", children: c.authorName }), _jsx("time", { dateTime: c.createdAt, children: articleFormatDate(c.createdAt) })] }), _jsx("p", { className: "blog_comment-body", children: c.body })] })] }) }, c.id))) })), _jsxs("div", { className: "blog_comment-form", children: [_jsx("h3", { className: "blog_comment-form-title", children: "Leave a comment" }), error ? (_jsx("p", { className: "blog_comment-error", role: "alert", children: error })) : null, flash ? (_jsx("p", { className: "blog_comment-ok", role: "status", children: flash })) : null, _jsxs("label", { className: "blog_comment-hp", "aria-hidden": "true", children: ["Website", _jsx("input", { tabIndex: -1, autoComplete: "off", value: website, onChange: (e) => setWebsite(e.target.value) })] }), _jsxs("div", { className: "blog_comment-form-grid", children: [_jsxs("label", { children: [_jsx("span", { children: "Name" }), _jsx("input", { value: name, onChange: (e) => setName(e.target.value), maxLength: 80, required: true, autoComplete: "name" })] }), _jsxs("label", { children: [_jsxs("span", { children: ["Email ", _jsx("em", { children: "(optional, never shown)" })] }), _jsx("input", { type: "email", value: email, onChange: (e) => setEmail(e.target.value), autoComplete: "email" })] })] }), _jsxs("label", { className: "blog_comment-body-field", children: [_jsx("span", { children: "Comment" }), _jsx("textarea", { rows: 5, value: body, onChange: (e) => setBody(e.target.value), maxLength: 4000, required: true })] }), _jsx("button", { type: "button", className: "blog_comment-submit", disabled: pending, onClick: submit, children: pending ? "Posting…" : "Post comment" }), _jsx("p", { className: "blog_comment-moderation-note", children: "Comments are reviewed before they appear on this post." })] })] }));
68
68
  }
@@ -1,5 +1,5 @@
1
1
  import { jsx as _jsx } from "react/jsx-runtime";
2
2
  /** BlogUploader looping fade/slide wrapper used on list media hero + article detail. */
3
3
  export function HeroFadeSlide({ children, delayMs = 0, from = "left", className }) {
4
- return (_jsx("div", { className: `hero-fade-slide hero-fade-slide-${from}${className ? ` ${className}` : ""}`.trim(), style: { ["--slide-delay"]: `${delayMs}ms` }, children: children }));
4
+ return (_jsx("div", { className: `blog_hero-fade-slide blog_hero-fade-slide-${from}${className ? ` ${className}` : ""}`.trim(), style: { ["--slide-delay"]: `${delayMs}ms` }, children: children }));
5
5
  }
@@ -16,5 +16,5 @@ export function ReadingProgress() {
16
16
  window.removeEventListener("resize", update);
17
17
  };
18
18
  }, []);
19
- return (_jsx("div", { className: "progress", "aria-hidden": "true", children: _jsx("span", { style: { width: `${pct}%` } }) }));
19
+ return (_jsx("div", { className: "blog_progress", "aria-hidden": "true", children: _jsx("span", { style: { width: `${pct}%` } }) }));
20
20
  }
@@ -3,5 +3,5 @@ export function ShareRow({ title, slug, origin, path, }) {
3
3
  const url = `${origin}${path ?? `/blogs/${slug}`}`;
4
4
  const encoded = encodeURIComponent(url);
5
5
  const text = encodeURIComponent(title);
6
- return (_jsxs("div", { className: "share", children: [_jsx("span", { className: "share-label", children: "Share" }), _jsx("a", { href: `https://www.linkedin.com/sharing/share-offsite/?url=${encoded}`, target: "_blank", rel: "noreferrer noopener", children: "LinkedIn" }), _jsx("a", { href: `https://x.com/intent/tweet?url=${encoded}&text=${text}`, target: "_blank", rel: "noreferrer noopener", children: "X" }), _jsx("a", { href: `https://api.whatsapp.com/send?text=${text}%20${encoded}`, target: "_blank", rel: "noreferrer noopener", children: "WhatsApp" }), _jsx("a", { href: `mailto:?subject=${text}&body=${encoded}`, children: "Email" }), _jsxs("details", { className: "share-copy", children: [_jsx("summary", { children: "Copy link" }), _jsx("input", { readOnly: true, value: url, "aria-label": "Article URL" })] })] }));
6
+ return (_jsxs("div", { className: "blog_share", children: [_jsx("span", { className: "blog_share-label", children: "Share" }), _jsx("a", { href: `https://www.linkedin.com/sharing/share-offsite/?url=${encoded}`, target: "_blank", rel: "noreferrer noopener", children: "LinkedIn" }), _jsx("a", { href: `https://x.com/intent/tweet?url=${encoded}&text=${text}`, target: "_blank", rel: "noreferrer noopener", children: "X" }), _jsx("a", { href: `https://api.whatsapp.com/send?text=${text}%20${encoded}`, target: "_blank", rel: "noreferrer noopener", children: "WhatsApp" }), _jsx("a", { href: `mailto:?subject=${text}&body=${encoded}`, children: "Email" }), _jsxs("details", { className: "blog_share-copy", children: [_jsx("summary", { children: "Copy link" }), _jsx("input", { readOnly: true, value: url, "aria-label": "Article URL" })] })] }));
7
7
  }
@@ -1,18 +1,18 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
2
  import { cx } from "../../../styles/userTheme";
3
3
  export function LoadingState({ label = "Loading..." }) {
4
- return (_jsx("div", { className: "bp-state bp-state--loading", role: "status", children: label }));
4
+ return (_jsx("div", { className: "blog_bp-state blog_bp-state--loading", role: "status", children: label }));
5
5
  }
6
6
  export function ErrorState({ message, authError, }) {
7
- return (_jsx("div", { className: "bp-state bp-state--error", role: "alert", children: authError
7
+ return (_jsx("div", { className: "blog_bp-state blog_bp-state--error", role: "alert", children: authError
8
8
  ? "Authentication failed. Check the public API key."
9
9
  : message || "Something went wrong." }));
10
10
  }
11
11
  export function EmptyState({ label = "No posts found." }) {
12
- return (_jsx("div", { className: "bp-state bp-state--empty", children: label }));
12
+ return (_jsx("div", { className: "blog_bp-state blog_bp-state--empty", children: label }));
13
13
  }
14
14
  export function Scope({ className, style, css, children, }) {
15
- return (_jsxs("div", { className: cx("bp-root", className), style: {
15
+ return (_jsxs("div", { className: cx("blog_bp-root", className), style: {
16
16
  width: "100%",
17
17
  maxWidth: "100%",
18
18
  boxSizing: "border-box",
@@ -363,7 +363,7 @@ const nodeToHtml = (node) => {
363
363
  const media = mediaFromNode(node.value);
364
364
  if (!media)
365
365
  return '';
366
- return (`<figure class="ed-figure" contenteditable="false" data-media-id="${escapeHtml(media.id)}"` +
366
+ return (`<figure class="blog_ed-figure" contenteditable="false" data-media-id="${escapeHtml(media.id)}"` +
367
367
  ` data-node-id="${escapeHtml(str(node.id))}">` +
368
368
  `<img src="${escapeHtml(media.url)}" alt="${escapeHtml(media.alt)}">` +
369
369
  `<figcaption>${escapeHtml(media.alt || 'Image')}</figcaption>` +
@@ -1 +1 @@
1
- {"version":3,"file":"BlogAdmin.d.ts","sourceRoot":"","sources":["../../../app/pages/admin/BlogAdmin.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,cAAc,EAAE,UAAU,EAAE,QAAQ,EAAE,MAAM,mBAAmB,CAAC;AAuB9E,MAAM,MAAM,cAAc,GAAG;IAC3B,MAAM,EAAE,cAAc,CAAC;IACvB,KAAK,CAAC,EAAE,UAAU,CAAC;IACnB,QAAQ,CAAC,EAAE,QAAQ,CAAC;IACpB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB,CAAC;AA8WF,wBAAgB,SAAS,CAAC,EAAE,MAAM,EAAE,KAAK,EAAE,QAAQ,EAAE,SAAS,EAAE,EAAE,cAAc,+BAM/E"}
1
+ {"version":3,"file":"BlogAdmin.d.ts","sourceRoot":"","sources":["../../../app/pages/admin/BlogAdmin.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,cAAc,EAAE,UAAU,EAAE,QAAQ,EAAE,MAAM,mBAAmB,CAAC;AAuB9E,MAAM,MAAM,cAAc,GAAG;IAC3B,MAAM,EAAE,cAAc,CAAC;IACvB,KAAK,CAAC,EAAE,UAAU,CAAC;IACnB,QAAQ,CAAC,EAAE,QAAQ,CAAC;IACpB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB,CAAC;AA6XF,wBAAgB,SAAS,CAAC,EAAE,MAAM,EAAE,KAAK,EAAE,QAAQ,EAAE,SAAS,EAAE,EAAE,cAAc,+BAM/E"}