@nuasite/notes 0.22.2 → 0.23.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.
package/dist/overlay.js CHANGED
@@ -523,21 +523,23 @@ function formatTime(iso) {
523
523
  return iso;
524
524
  }
525
525
  }
526
- function SidebarItem({ item, active, stale, applying, onFocus, onResolve, onReopen, onDelete, onApply }) {
526
+ function SidebarItem({ item, active, stale, applying, isAgency, onFocus, onResolve, onReopen, onDelete, onPurge, onApply }) {
527
527
  const isResolved = item.status === "resolved" || item.status === "applied";
528
528
  const isApplied = item.status === "applied";
529
+ const isDeleted = item.status === "deleted";
529
530
  const isSuggestion = item.type === "suggestion" && item.range;
530
- const canApply = isSuggestion && !isApplied && !stale;
531
+ const canApply = isAgency && isSuggestion && !isApplied && !isDeleted && !stale;
531
532
  return /* @__PURE__ */ u$1(
532
533
  "div",
533
534
  {
534
- class: `notes-item ${active ? "notes-item--active" : ""} ${isResolved ? "notes-item--resolved" : ""}`,
535
+ class: `notes-item ${active ? "notes-item--active" : ""} ${isResolved ? "notes-item--resolved" : ""} ${isDeleted ? "notes-item--deleted" : ""}`,
535
536
  onMouseEnter: onFocus,
536
537
  children: [
537
538
  /* @__PURE__ */ u$1("div", { class: "notes-item__head", children: [
538
539
  /* @__PURE__ */ u$1("div", { children: [
539
540
  /* @__PURE__ */ u$1("span", { class: `notes-item__badge notes-item__badge--${item.type}`, children: item.type }),
540
541
  isResolved ? /* @__PURE__ */ u$1("span", { class: "notes-item__badge notes-item__badge--resolved", children: item.status }) : null,
542
+ isDeleted ? /* @__PURE__ */ u$1("span", { class: "notes-item__badge notes-item__badge--deleted", children: "deleted" }) : null,
541
543
  /* @__PURE__ */ u$1("span", { class: "notes-item__author", children: item.author })
542
544
  ] }),
543
545
  /* @__PURE__ */ u$1("span", { class: "notes-item__time", children: formatTime(item.createdAt) })
@@ -555,18 +557,51 @@ function SidebarItem({ item, active, stale, applying, onFocus, onResolve, onReop
555
557
  item.targetSnippet ? /* @__PURE__ */ u$1("div", { class: "notes-item__snippet", children: item.targetSnippet }) : null,
556
558
  /* @__PURE__ */ u$1("div", { class: "notes-item__body", children: item.body })
557
559
  ] }),
558
- /* @__PURE__ */ u$1("div", { class: "notes-item__actions", children: [
560
+ isAgency && item.history.length > 1 ? /* @__PURE__ */ u$1("details", { class: "notes-item__history", children: [
561
+ /* @__PURE__ */ u$1("summary", { children: [
562
+ "History (",
563
+ item.history.length,
564
+ ")"
565
+ ] }),
566
+ /* @__PURE__ */ u$1("ul", { children: item.history.map((h2, i2) => /* @__PURE__ */ u$1("li", { children: [
567
+ /* @__PURE__ */ u$1("span", { class: "notes-item__history-action", children: h2.action }),
568
+ /* @__PURE__ */ u$1("span", { class: "notes-item__history-meta", children: [
569
+ h2.role ? ` · ${h2.role}` : "",
570
+ " · ",
571
+ formatTime(h2.at)
572
+ ] }),
573
+ h2.note ? /* @__PURE__ */ u$1("div", { class: "notes-item__history-note", children: h2.note }) : null
574
+ ] }, i2)) })
575
+ ] }) : null,
576
+ isAgency ? /* @__PURE__ */ u$1("div", { class: "notes-item__actions", children: [
559
577
  canApply ? /* @__PURE__ */ u$1("button", { class: "notes-btn notes-btn--primary", onClick: onApply, disabled: applying, children: applying ? "Applying..." : "Apply" }) : null,
560
- isResolved ? /* @__PURE__ */ u$1("button", { class: "notes-btn notes-btn--ghost", onClick: onReopen, children: "Reopen" }) : /* @__PURE__ */ u$1("button", { class: "notes-btn", onClick: onResolve, children: "Resolve" }),
561
- /* @__PURE__ */ u$1("button", { class: "notes-btn notes-btn--ghost notes-btn--danger", onClick: onDelete, children: "Delete" })
562
- ] })
578
+ isDeleted ? /* @__PURE__ */ u$1("button", { class: "notes-btn notes-btn--ghost notes-btn--danger", onClick: onPurge, children: "Purge" }) : isResolved ? /* @__PURE__ */ u$1("button", { class: "notes-btn notes-btn--ghost", onClick: onReopen, children: "Reopen" }) : /* @__PURE__ */ u$1("button", { class: "notes-btn", onClick: onResolve, children: "Resolve" }),
579
+ !isDeleted ? /* @__PURE__ */ u$1("button", { class: "notes-btn notes-btn--ghost notes-btn--danger", onClick: onDelete, children: "Delete" }) : null
580
+ ] }) : null
563
581
  ]
564
582
  }
565
583
  );
566
584
  }
567
- function Sidebar({ page, items, activeId, picking, error, staleIds, applyingId, onFocus, onResolve, onReopen, onDelete, onApply }) {
568
- const open = items.filter((i2) => i2.status !== "resolved" && i2.status !== "applied");
569
- const closed = items.filter((i2) => i2.status === "resolved" || i2.status === "applied");
585
+ function Sidebar({
586
+ page,
587
+ items,
588
+ activeId,
589
+ picking,
590
+ error,
591
+ staleIds,
592
+ applyingId,
593
+ isAgency,
594
+ onFocus,
595
+ onResolve,
596
+ onReopen,
597
+ onDelete,
598
+ onPurge,
599
+ onApply
600
+ }) {
601
+ const open = items.filter((i2) => i2.status === "open" || i2.status === "stale" || i2.status === "rejected");
602
+ const resolved = items.filter((i2) => i2.status === "resolved" || i2.status === "applied");
603
+ const deleted = isAgency ? items.filter((i2) => i2.status === "deleted") : [];
604
+ const visible = [...open, ...resolved, ...deleted];
570
605
  const renderItem = (item) => /* @__PURE__ */ u$1(
571
606
  SidebarItem,
572
607
  {
@@ -574,10 +609,12 @@ function Sidebar({ page, items, activeId, picking, error, staleIds, applyingId,
574
609
  active: item.id === activeId,
575
610
  stale: staleIds.has(item.id),
576
611
  applying: applyingId === item.id,
612
+ isAgency,
577
613
  onFocus: () => onFocus(item.id),
578
614
  onResolve: () => onResolve(item.id),
579
615
  onReopen: () => onReopen(item.id),
580
616
  onDelete: () => onDelete(item.id),
617
+ onPurge: () => onPurge(item.id),
581
618
  onApply: () => onApply(item.id)
582
619
  },
583
620
  item.id
@@ -588,18 +625,28 @@ function Sidebar({ page, items, activeId, picking, error, staleIds, applyingId,
588
625
  /* @__PURE__ */ u$1("div", { class: "notes-sidebar__meta", children: [
589
626
  open.length,
590
627
  " open · ",
591
- closed.length,
592
- " resolved · ",
628
+ resolved.length,
629
+ " resolved",
630
+ isAgency && deleted.length > 0 ? ` · ${deleted.length} deleted` : "",
631
+ " · ",
593
632
  /* @__PURE__ */ u$1("code", { children: page })
594
633
  ] })
595
634
  ] }),
596
635
  /* @__PURE__ */ u$1("div", { class: "notes-sidebar__list", children: [
597
636
  error ? /* @__PURE__ */ u$1("div", { class: "notes-banner", children: error }) : null,
598
- items.length === 0 ? /* @__PURE__ */ u$1("div", { class: "notes-sidebar__empty", children: picking ? "Click any text or element on the page to add a comment." : 'Select text on the page to suggest an edit, or click "Pick element" to comment.' }) : null,
637
+ visible.length === 0 ? /* @__PURE__ */ u$1("div", { class: "notes-sidebar__empty", children: picking ? "Click any text or element on the page to add a comment." : 'Select text on the page to suggest an edit, or click "Pick element" to comment.' }) : null,
599
638
  open.map(renderItem),
600
- closed.length > 0 ? /* @__PURE__ */ u$1(S, { children: [
601
- /* @__PURE__ */ u$1("div", { class: "notes-sidebar__meta", style: { marginTop: "4px" }, children: "Resolved" }),
602
- closed.map(renderItem)
639
+ resolved.length > 0 ? /* @__PURE__ */ u$1(S, { children: [
640
+ /* @__PURE__ */ u$1("div", { class: "notes-sidebar__section", children: "Resolved" }),
641
+ resolved.map(renderItem)
642
+ ] }) : null,
643
+ isAgency && deleted.length > 0 ? /* @__PURE__ */ u$1("details", { class: "notes-sidebar__deleted", children: [
644
+ /* @__PURE__ */ u$1("summary", { children: [
645
+ "Deleted (",
646
+ deleted.length,
647
+ ")"
648
+ ] }),
649
+ deleted.map(renderItem)
603
650
  ] }) : null
604
651
  ] })
605
652
  ] });
@@ -732,11 +779,12 @@ function SuggestPopover({ rect, originalText, defaultAuthor, onCancel, onSubmit
732
779
  }
733
780
  );
734
781
  }
735
- function Toolbar({ page, count, picking, onTogglePick, onExit }) {
782
+ function Toolbar({ page, count, picking, role, collapsed, onTogglePick, onToggleCollapse, onExit }) {
736
783
  return /* @__PURE__ */ u$1("div", { class: "notes-toolbar", children: [
737
784
  /* @__PURE__ */ u$1("div", { class: "notes-toolbar__brand", children: [
738
785
  /* @__PURE__ */ u$1("span", { class: "notes-toolbar__dot" }),
739
786
  /* @__PURE__ */ u$1("span", { children: "Notes" }),
787
+ /* @__PURE__ */ u$1("span", { class: `notes-toolbar__role notes-toolbar__role--${role}`, children: role }),
740
788
  /* @__PURE__ */ u$1("span", { class: "notes-toolbar__page", children: [
741
789
  page,
742
790
  " · ",
@@ -755,10 +803,65 @@ function Toolbar({ page, count, picking, onTogglePick, onExit }) {
755
803
  children: picking ? "Cancel pick" : "Pick element"
756
804
  }
757
805
  ),
806
+ /* @__PURE__ */ u$1(
807
+ "button",
808
+ {
809
+ class: "notes-btn notes-btn--ghost",
810
+ onClick: onToggleCollapse,
811
+ title: collapsed ? "Show notes sidebar" : "Hide notes sidebar to see the full page",
812
+ children: collapsed ? "Show sidebar" : "Hide sidebar"
813
+ }
814
+ ),
758
815
  /* @__PURE__ */ u$1("button", { class: "notes-btn notes-btn--ghost", onClick: onExit, title: "Leave review mode", children: "Exit" })
759
816
  ] })
760
817
  ] });
761
818
  }
819
+ const STYLE_ID = "nua-notes-cms-bridge";
820
+ const COLLAPSE_ATTR = "data-nua-notes-collapsed";
821
+ const STYLES = `
822
+ #cms-app-host { display: none !important; }
823
+ [data-nuasite-cms] { display: none !important; }
824
+
825
+ /* Reserve space for the notes toolbar + sidebar so they don't sit on top
826
+ * of host page content. Padding the body lets the page reflow into the
827
+ * visible area instead of being clipped under fixed-position chrome. */
828
+ html:not([${COLLAPSE_ATTR}]) body {
829
+ box-sizing: border-box;
830
+ padding-top: 40px !important;
831
+ padding-right: 340px !important;
832
+ }
833
+
834
+ /* When the sidebar is collapsed, only reserve the toolbar height. */
835
+ html[${COLLAPSE_ATTR}] body {
836
+ box-sizing: border-box;
837
+ padding-top: 40px !important;
838
+ }
839
+
840
+ /* Page-fixed elements (sticky headers, fixed nav) don't get pushed by
841
+ * body padding because they're positioned against the viewport. Offset
842
+ * them via top/right so they slot into the same chrome-free area. We
843
+ * scope this to elements the host page declared as fixed/sticky to
844
+ * avoid touching the notes UI itself (which lives in a shadow DOM). */
845
+ html:not([${COLLAPSE_ATTR}]) body > header[class*="fixed"],
846
+ html:not([${COLLAPSE_ATTR}]) body > nav[class*="fixed"],
847
+ html:not([${COLLAPSE_ATTR}]) body > [class*="sticky"] {
848
+ right: 340px !important;
849
+ }
850
+ `;
851
+ function enableCmsBridge() {
852
+ if (document.getElementById(STYLE_ID)) return;
853
+ const style = document.createElement("style");
854
+ style.id = STYLE_ID;
855
+ style.textContent = STYLES;
856
+ document.head.appendChild(style);
857
+ }
858
+ function setSidebarCollapsed(collapsed) {
859
+ if (collapsed) {
860
+ document.documentElement.setAttribute(COLLAPSE_ATTR, "");
861
+ } else {
862
+ document.documentElement.removeAttribute(COLLAPSE_ATTR);
863
+ }
864
+ }
762
865
  function manifestUrlForPage(page) {
763
866
  if (page === "" || page === "/") return "/index.json";
764
867
  const trimmed = page.replace(/^\/+|\/+$/g, "");
@@ -776,12 +879,64 @@ async function fetchPageManifest(page) {
776
879
  return null;
777
880
  }
778
881
  }
882
+ const MODE_COOKIE = "nua-notes-mode";
883
+ const ROLE_COOKIE = "nua-notes-role";
884
+ function readCookie(name) {
885
+ if (typeof document === "undefined") return null;
886
+ for (const part of document.cookie.split("; ")) {
887
+ const eq = part.indexOf("=");
888
+ if (eq < 0) continue;
889
+ if (part.slice(0, eq) === name) return decodeURIComponent(part.slice(eq + 1));
890
+ }
891
+ return null;
892
+ }
893
+ function isReviewMode(urlFlag) {
894
+ if (typeof window === "undefined") return false;
895
+ const url = new URL(window.location.href);
896
+ if (url.searchParams.has(urlFlag)) return true;
897
+ return readCookie(MODE_COOKIE) === "1";
898
+ }
899
+ function setReviewModeCookie() {
900
+ document.cookie = `${MODE_COOKIE}=1; path=/; SameSite=Lax`;
901
+ }
902
+ function clearReviewModeCookie() {
903
+ document.cookie = `${MODE_COOKIE}=; path=/; expires=Thu, 01 Jan 1970 00:00:00 GMT; SameSite=Lax`;
904
+ }
905
+ function resolveRole(agencyFlag) {
906
+ if (typeof window === "undefined") return "client";
907
+ const url = new URL(window.location.href);
908
+ if (url.searchParams.has(agencyFlag)) {
909
+ document.cookie = `${ROLE_COOKIE}=agency; path=/; SameSite=Lax`;
910
+ return "agency";
911
+ }
912
+ return readCookie(ROLE_COOKIE) === "agency" ? "agency" : "client";
913
+ }
914
+ function clearRoleCookie() {
915
+ document.cookie = `${ROLE_COOKIE}=; path=/; expires=Thu, 01 Jan 1970 00:00:00 GMT; SameSite=Lax`;
916
+ }
917
+ function exitReviewMode(urlFlag, agencyFlag) {
918
+ clearReviewModeCookie();
919
+ clearRoleCookie();
920
+ const url = new URL(window.location.href);
921
+ url.searchParams.delete(urlFlag);
922
+ url.searchParams.delete(agencyFlag);
923
+ window.location.href = url.pathname + (url.search || "") + url.hash;
924
+ }
925
+ function getCurrentPagePath() {
926
+ if (typeof window === "undefined") return "/";
927
+ const p2 = window.location.pathname;
928
+ if (p2 === "" || p2 === "/") return "/";
929
+ return p2.endsWith("/") ? p2.slice(0, -1) : p2;
930
+ }
779
931
  const BASE = "/_nua/notes";
780
932
  const TIMEOUT_MS = 1e4;
933
+ function authHeaders() {
934
+ return { "x-nua-role": resolveRole("nua-agency") };
935
+ }
781
936
  async function postJson(path, body) {
782
937
  const res = await fetch(`${BASE}${path}`, {
783
938
  method: "POST",
784
- headers: { "Content-Type": "application/json" },
939
+ headers: { "Content-Type": "application/json", ...authHeaders() },
785
940
  body: JSON.stringify(body),
786
941
  signal: AbortSignal.timeout(TIMEOUT_MS)
787
942
  });
@@ -799,7 +954,7 @@ async function postJson(path, body) {
799
954
  }
800
955
  async function listNotes(page) {
801
956
  const res = await fetch(`${BASE}/list?page=${encodeURIComponent(page)}`, {
802
- headers: { Accept: "application/json" },
957
+ headers: { Accept: "application/json", ...authHeaders() },
803
958
  signal: AbortSignal.timeout(TIMEOUT_MS)
804
959
  });
805
960
  if (!res.ok) throw new Error(`notes: list failed (${res.status})`);
@@ -825,12 +980,16 @@ async function setNoteStatus(page, id, status) {
825
980
  return updateNote(page, id, { status });
826
981
  }
827
982
  async function deleteNote(page, id) {
828
- await postJson("/delete", { page, id });
983
+ const res = await postJson("/delete", { page, id });
984
+ return res.item;
985
+ }
986
+ async function purgeNote(page, id) {
987
+ await postJson("/purge", { page, id });
829
988
  }
830
989
  async function applyNote(page, id) {
831
990
  const res = await fetch(`${BASE}/apply`, {
832
991
  method: "POST",
833
- headers: { "Content-Type": "application/json" },
992
+ headers: { "Content-Type": "application/json", ...authHeaders() },
834
993
  body: JSON.stringify({ page, id }),
835
994
  signal: AbortSignal.timeout(TIMEOUT_MS)
836
995
  });
@@ -932,30 +1091,19 @@ function selectionInsideElement(el, selection) {
932
1091
  if (!text.trim()) return null;
933
1092
  return { text, rect: range.getBoundingClientRect() };
934
1093
  }
935
- const COOKIE = "nua-notes-mode";
936
- function isReviewMode(urlFlag) {
937
- if (typeof window === "undefined") return false;
938
- const url = new URL(window.location.href);
939
- if (url.searchParams.has(urlFlag)) return true;
940
- return document.cookie.split("; ").some((c2) => c2.startsWith(`${COOKIE}=1`));
941
- }
942
- function setReviewModeCookie() {
943
- document.cookie = `${COOKIE}=1; path=/; SameSite=Lax`;
944
- }
945
- function clearReviewModeCookie() {
946
- document.cookie = `${COOKIE}=; path=/; expires=Thu, 01 Jan 1970 00:00:00 GMT; SameSite=Lax`;
947
- }
948
- function exitReviewMode(urlFlag) {
949
- clearReviewModeCookie();
950
- const url = new URL(window.location.href);
951
- url.searchParams.delete(urlFlag);
952
- window.location.href = url.pathname + (url.search || "") + url.hash;
1094
+ const COLLAPSED_KEY = "nua-notes-sidebar-collapsed";
1095
+ function loadCollapsed() {
1096
+ try {
1097
+ return localStorage.getItem(COLLAPSED_KEY) === "1";
1098
+ } catch {
1099
+ return false;
1100
+ }
953
1101
  }
954
- function getCurrentPagePath() {
955
- if (typeof window === "undefined") return "/";
956
- const p2 = window.location.pathname;
957
- if (p2 === "" || p2 === "/") return "/";
958
- return p2.endsWith("/") ? p2.slice(0, -1) : p2;
1102
+ function saveCollapsed(value) {
1103
+ try {
1104
+ localStorage.setItem(COLLAPSED_KEY, value ? "1" : "0");
1105
+ } catch {
1106
+ }
959
1107
  }
960
1108
  const AUTHOR_KEY = "nua-notes-author";
961
1109
  function loadAuthor() {
@@ -986,8 +1134,10 @@ function findCmsAncestor(target) {
986
1134
  }
987
1135
  return null;
988
1136
  }
989
- function App({ urlFlag }) {
1137
+ function App({ urlFlag, agencyFlag }) {
990
1138
  const page = T(() => getCurrentPagePath(), []);
1139
+ const role = T(() => resolveRole(agencyFlag), [agencyFlag]);
1140
+ const isAgency = role === "agency";
991
1141
  const [items, setItems] = d([]);
992
1142
  const [manifest, setManifest] = d(null);
993
1143
  const [picking, setPicking] = d(false);
@@ -1001,6 +1151,17 @@ function App({ urlFlag }) {
1001
1151
  const [author, setAuthor] = d(() => loadAuthor());
1002
1152
  const [staleIds, setStaleIds] = d(/* @__PURE__ */ new Set());
1003
1153
  const [applyingId, setApplyingId] = d(null);
1154
+ const [collapsed, setCollapsedState] = d(() => loadCollapsed());
1155
+ y(() => {
1156
+ setSidebarCollapsed(collapsed);
1157
+ saveCollapsed(collapsed);
1158
+ }, [collapsed]);
1159
+ y(() => {
1160
+ setSidebarCollapsed(loadCollapsed());
1161
+ }, []);
1162
+ const toggleCollapsed = q(() => {
1163
+ setCollapsedState((c2) => !c2);
1164
+ }, []);
1004
1165
  y(() => {
1005
1166
  let alive = true;
1006
1167
  Promise.all([listNotes(page), fetchPageManifest(page)]).then(([file, mf]) => {
@@ -1214,7 +1375,16 @@ function App({ urlFlag }) {
1214
1375
  }, [page]);
1215
1376
  const handleDelete = q(async (id) => {
1216
1377
  try {
1217
- await deleteNote(page, id);
1378
+ const item = await deleteNote(page, id);
1379
+ setItems((prev) => prev.map((i2) => i2.id === id ? item : i2));
1380
+ if (activeId === id) setActiveId(null);
1381
+ } catch (err) {
1382
+ setError(err instanceof Error ? err.message : String(err));
1383
+ }
1384
+ }, [page, activeId]);
1385
+ const handlePurge = q(async (id) => {
1386
+ try {
1387
+ await purgeNote(page, id);
1218
1388
  setItems((prev) => prev.filter((i2) => i2.id !== id));
1219
1389
  if (activeId === id) setActiveId(null);
1220
1390
  } catch (err) {
@@ -1256,17 +1426,20 @@ function App({ urlFlag }) {
1256
1426
  Toolbar,
1257
1427
  {
1258
1428
  page,
1259
- count: items.length,
1429
+ count: items.filter((i2) => i2.status !== "deleted").length,
1260
1430
  picking,
1431
+ role,
1432
+ collapsed,
1261
1433
  onTogglePick: () => {
1262
1434
  setPicking((p2) => !p2);
1263
1435
  setPendingPick(null);
1264
1436
  setPendingSuggest(null);
1265
1437
  },
1266
- onExit: () => exitReviewMode(urlFlag)
1438
+ onToggleCollapse: toggleCollapsed,
1439
+ onExit: () => exitReviewMode(urlFlag, agencyFlag)
1267
1440
  }
1268
1441
  ),
1269
- /* @__PURE__ */ u$1(
1442
+ collapsed ? null : /* @__PURE__ */ u$1(
1270
1443
  Sidebar,
1271
1444
  {
1272
1445
  page,
@@ -1276,10 +1449,12 @@ function App({ urlFlag }) {
1276
1449
  error,
1277
1450
  staleIds,
1278
1451
  applyingId,
1452
+ isAgency,
1279
1453
  onFocus: setActiveId,
1280
1454
  onResolve: handleResolve,
1281
1455
  onReopen: handleReopen,
1282
1456
  onDelete: handleDelete,
1457
+ onPurge: handlePurge,
1283
1458
  onApply: handleApply
1284
1459
  }
1285
1460
  ),
@@ -1321,25 +1496,12 @@ function App({ urlFlag }) {
1321
1496
  ) : null
1322
1497
  ] });
1323
1498
  }
1324
- const STYLE_ID = "nua-notes-cms-bridge";
1325
- const HIDE_CMS_CSS = `
1326
- #cms-app-host { display: none !important; }
1327
- [data-nuasite-cms] { display: none !important; }
1328
- /* Allow notes to handle clicks on annotated elements without CMS interfering */
1329
- [data-cms-id] { cursor: default !important; }
1330
- `;
1331
- function enableCmsBridge() {
1332
- if (document.getElementById(STYLE_ID)) return;
1333
- const style = document.createElement("style");
1334
- style.id = STYLE_ID;
1335
- style.textContent = HIDE_CMS_CSS;
1336
- document.head.appendChild(style);
1337
- }
1338
- const OVERLAY_STYLES = "/**\n * @nuasite/notes overlay styles.\n *\n * Imported via Vite's `?inline` query and injected into a shadow root, so\n * these styles never leak into the host page (and the host page can't\n * accidentally style notes UI). Variables on `:host` are the only knobs.\n */\n\n:host {\n --notes-bg: #ffffff;\n --notes-fg: #0f172a;\n --notes-muted: #64748b;\n --notes-border: #e2e8f0;\n --notes-accent: #f59e0b;\n --notes-accent-fg: #1f2937;\n --notes-danger: #dc2626;\n --notes-success: #16a34a;\n --notes-shadow: 0 10px 30px rgba(15, 23, 42, 0.18);\n --notes-radius: 10px;\n --notes-sidebar-w: 360px;\n --notes-z: 2147483600;\n\n font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;\n font-size: 14px;\n line-height: 1.45;\n color: var(--notes-fg);\n -webkit-font-smoothing: antialiased;\n}\n\n* {\n box-sizing: border-box;\n}\n\nbutton {\n font: inherit;\n cursor: pointer;\n border: none;\n background: none;\n color: inherit;\n padding: 0;\n}\n\ninput,\ntextarea {\n font: inherit;\n color: inherit;\n}\n\n.notes-root {\n position: fixed;\n inset: 0;\n pointer-events: none;\n z-index: var(--notes-z);\n}\n\n/* Toolbar (top, full width) */\n.notes-toolbar {\n position: fixed;\n top: 0;\n left: 0;\n right: 0;\n height: 44px;\n background: var(--notes-bg);\n border-bottom: 1px solid var(--notes-border);\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: 0 16px;\n box-shadow: var(--notes-shadow);\n pointer-events: auto;\n}\n\n.notes-toolbar__brand {\n display: flex;\n align-items: center;\n gap: 8px;\n font-weight: 600;\n}\n\n.notes-toolbar__dot {\n width: 8px;\n height: 8px;\n border-radius: 50%;\n background: var(--notes-accent);\n box-shadow: 0 0 0 2px rgba(245, 158, 11, 0.2);\n}\n\n.notes-toolbar__page {\n color: var(--notes-muted);\n font-weight: 400;\n margin-left: 12px;\n font-size: 13px;\n}\n\n.notes-toolbar__actions {\n display: flex;\n align-items: center;\n gap: 8px;\n}\n\n.notes-btn {\n padding: 6px 12px;\n border-radius: 6px;\n background: #f1f5f9;\n color: var(--notes-fg);\n font-size: 13px;\n font-weight: 500;\n transition: background 0.15s;\n}\n\n.notes-btn:hover {\n background: #e2e8f0;\n}\n\n.notes-btn--primary {\n background: var(--notes-accent);\n color: var(--notes-accent-fg);\n}\n\n.notes-btn--primary:hover {\n background: #d97706;\n color: #ffffff;\n}\n\n.notes-btn--ghost {\n background: transparent;\n color: var(--notes-muted);\n}\n\n.notes-btn--ghost:hover {\n color: var(--notes-fg);\n background: #f1f5f9;\n}\n\n.notes-btn--danger {\n color: var(--notes-danger);\n}\n\n/* Sidebar (right side) */\n.notes-sidebar {\n position: fixed;\n top: 44px;\n right: 0;\n bottom: 0;\n width: var(--notes-sidebar-w);\n background: var(--notes-bg);\n border-left: 1px solid var(--notes-border);\n box-shadow: var(--notes-shadow);\n display: flex;\n flex-direction: column;\n pointer-events: auto;\n}\n\n.notes-sidebar__header {\n padding: 16px 16px 12px;\n border-bottom: 1px solid var(--notes-border);\n}\n\n.notes-sidebar__title {\n font-size: 16px;\n font-weight: 600;\n margin: 0 0 4px;\n}\n\n.notes-sidebar__meta {\n font-size: 12px;\n color: var(--notes-muted);\n}\n\n.notes-sidebar__list {\n flex: 1;\n overflow-y: auto;\n padding: 12px;\n display: flex;\n flex-direction: column;\n gap: 10px;\n}\n\n.notes-sidebar__empty {\n padding: 24px 16px;\n text-align: center;\n color: var(--notes-muted);\n font-size: 13px;\n line-height: 1.5;\n}\n\n.notes-sidebar__hint {\n font-size: 12px;\n color: var(--notes-muted);\n margin-top: 6px;\n}\n\n/* Item card */\n.notes-item {\n border: 1px solid var(--notes-border);\n border-radius: var(--notes-radius);\n padding: 12px;\n background: #ffffff;\n transition: border-color 0.15s, box-shadow 0.15s;\n}\n\n.notes-item:hover {\n border-color: #cbd5e1;\n}\n\n.notes-item--active {\n border-color: var(--notes-accent);\n box-shadow: 0 0 0 3px rgba(245, 158, 11, 0.12);\n}\n\n.notes-item--resolved {\n opacity: 0.55;\n}\n\n.notes-item__head {\n display: flex;\n align-items: center;\n justify-content: space-between;\n margin-bottom: 6px;\n}\n\n.notes-item__author {\n font-weight: 600;\n font-size: 13px;\n}\n\n.notes-item__time {\n font-size: 11px;\n color: var(--notes-muted);\n}\n\n.notes-item__snippet {\n font-size: 12px;\n color: var(--notes-muted);\n background: #f8fafc;\n border-left: 3px solid var(--notes-border);\n padding: 6px 8px;\n margin-bottom: 6px;\n border-radius: 0 4px 4px 0;\n white-space: pre-wrap;\n word-break: break-word;\n}\n\n.notes-item__body {\n font-size: 13px;\n white-space: pre-wrap;\n word-break: break-word;\n}\n\n.notes-item__actions {\n display: flex;\n gap: 6px;\n margin-top: 10px;\n padding-top: 10px;\n border-top: 1px solid #f1f5f9;\n}\n\n.notes-item__badge {\n display: inline-block;\n font-size: 10px;\n font-weight: 600;\n text-transform: uppercase;\n letter-spacing: 0.04em;\n padding: 2px 6px;\n border-radius: 4px;\n margin-right: 6px;\n}\n\n.notes-item__badge--comment {\n background: #dbeafe;\n color: #1e40af;\n}\n\n.notes-item__badge--suggestion {\n background: #fef3c7;\n color: #92400e;\n}\n\n.notes-item__badge--resolved {\n background: #dcfce7;\n color: #166534;\n}\n\n/* Element highlight ring */\n.notes-highlight {\n position: fixed;\n pointer-events: none;\n border: 2px solid var(--notes-accent);\n border-radius: 4px;\n box-shadow: 0 0 0 4px rgba(245, 158, 11, 0.18);\n transition: all 0.08s ease-out;\n}\n\n.notes-highlight--persistent {\n border-color: rgba(245, 158, 11, 0.6);\n box-shadow: 0 0 0 3px rgba(245, 158, 11, 0.12);\n}\n\n/* Comment popover */\n.notes-popover {\n position: fixed;\n width: 320px;\n background: var(--notes-bg);\n border: 1px solid var(--notes-border);\n border-radius: var(--notes-radius);\n box-shadow: var(--notes-shadow);\n padding: 14px;\n pointer-events: auto;\n display: flex;\n flex-direction: column;\n gap: 10px;\n}\n\n.notes-popover__title {\n font-size: 13px;\n font-weight: 600;\n margin: 0;\n}\n\n.notes-popover__snippet {\n font-size: 12px;\n color: var(--notes-muted);\n background: #f8fafc;\n border-left: 3px solid var(--notes-border);\n padding: 6px 8px;\n border-radius: 0 4px 4px 0;\n max-height: 60px;\n overflow: hidden;\n}\n\n.notes-popover textarea {\n width: 100%;\n min-height: 80px;\n resize: vertical;\n border: 1px solid var(--notes-border);\n border-radius: 6px;\n padding: 8px 10px;\n background: #ffffff;\n outline: none;\n}\n\n.notes-popover textarea:focus {\n border-color: var(--notes-accent);\n box-shadow: 0 0 0 3px rgba(245, 158, 11, 0.15);\n}\n\n.notes-popover input[type='text'] {\n border: 1px solid var(--notes-border);\n border-radius: 6px;\n padding: 6px 10px;\n background: #ffffff;\n outline: none;\n}\n\n.notes-popover input[type='text']:focus {\n border-color: var(--notes-accent);\n box-shadow: 0 0 0 3px rgba(245, 158, 11, 0.15);\n}\n\n.notes-popover__row {\n display: flex;\n justify-content: space-between;\n align-items: center;\n gap: 8px;\n}\n\n/* Selection tooltip */\n.notes-selection-tooltip {\n position: fixed;\n display: flex;\n align-items: center;\n gap: 6px;\n padding: 4px 6px;\n background: #0f172a;\n color: #ffffff;\n border-radius: 8px;\n box-shadow: var(--notes-shadow);\n pointer-events: auto;\n z-index: calc(var(--notes-z) + 5);\n}\n\n.notes-selection-tooltip .notes-btn {\n background: rgba(255, 255, 255, 0.08);\n color: #ffffff;\n font-size: 12px;\n padding: 4px 8px;\n}\n\n.notes-selection-tooltip .notes-btn--primary {\n background: var(--notes-accent);\n color: var(--notes-accent-fg);\n}\n\n.notes-selection-tooltip .notes-btn--ghost {\n color: #e2e8f0;\n}\n\n.notes-selection-tooltip .notes-btn--ghost:hover {\n background: rgba(255, 255, 255, 0.16);\n color: #ffffff;\n}\n\n/* Suggest popover variations */\n.notes-popover--suggest {\n width: 360px;\n}\n\n.notes-popover__label {\n display: block;\n font-size: 11px;\n font-weight: 600;\n text-transform: uppercase;\n letter-spacing: 0.04em;\n color: var(--notes-muted);\n margin-bottom: 4px;\n}\n\n.notes-popover__original {\n background: #fef3c7;\n border: 1px solid #fde68a;\n border-radius: 6px;\n padding: 8px 10px;\n font-size: 13px;\n color: #78350f;\n max-height: 80px;\n overflow-y: auto;\n white-space: pre-wrap;\n word-break: break-word;\n}\n\n.notes-strikethrough {\n text-decoration: line-through;\n text-decoration-color: rgba(220, 38, 38, 0.6);\n text-decoration-thickness: 2px;\n}\n\n/* Diff preview in sidebar */\n.notes-diff {\n font-size: 13px;\n border-radius: 6px;\n background: #f8fafc;\n border: 1px solid var(--notes-border);\n overflow: hidden;\n margin-bottom: 8px;\n}\n\n.notes-diff__row {\n padding: 6px 10px;\n display: flex;\n gap: 6px;\n white-space: pre-wrap;\n word-break: break-word;\n}\n\n.notes-diff__row--del {\n background: #fef2f2;\n color: #7f1d1d;\n border-bottom: 1px solid #fee2e2;\n}\n\n.notes-diff__row--ins {\n background: #f0fdf4;\n color: #14532d;\n}\n\n.notes-diff__marker {\n font-weight: 700;\n font-family: ui-monospace, SFMono-Regular, monospace;\n width: 12px;\n flex-shrink: 0;\n text-align: center;\n}\n\n.notes-item__rationale {\n font-size: 12px;\n color: var(--notes-muted);\n margin-bottom: 6px;\n font-style: italic;\n}\n\n.notes-item__rationale-label {\n font-style: normal;\n font-weight: 600;\n color: var(--notes-fg);\n margin-right: 4px;\n}\n\n/* Stale warning */\n.notes-stale {\n display: flex;\n align-items: center;\n gap: 6px;\n background: #fef3c7;\n border: 1px solid #fde68a;\n color: #92400e;\n font-size: 12px;\n padding: 6px 8px;\n border-radius: 6px;\n margin-bottom: 8px;\n}\n\n.notes-stale__icon {\n font-size: 14px;\n}\n\n/* Persistent highlight variant for suggestion ranges */\n.notes-highlight--suggestion {\n border-color: rgba(250, 204, 21, 0.9);\n box-shadow: 0 0 0 3px rgba(250, 204, 21, 0.18);\n background: rgba(254, 243, 199, 0.25);\n}\n\n/* Banner shown when notes API fails to load */\n.notes-banner {\n position: fixed;\n top: 56px;\n left: 16px;\n right: calc(var(--notes-sidebar-w) + 16px);\n padding: 10px 14px;\n background: #fef2f2;\n border: 1px solid #fecaca;\n color: #991b1b;\n border-radius: var(--notes-radius);\n font-size: 13px;\n pointer-events: auto;\n}\n";
1499
+ const OVERLAY_STYLES = "/**\n * @nuasite/notes overlay styles.\n *\n * Imported via Vite's `?inline` query and injected into a shadow root, so\n * these styles never leak into the host page (and the host page can't\n * accidentally style notes UI). Variables on `:host` are the only knobs.\n *\n * Design language: cool neutrals (slate / zinc) with a single muted blue\n * accent. No bright primaries, no rounded-blob corners. Typography sticks\n * to the system stack. The goal is to feel like a real product, not a\n * Pastel-style demo.\n */\n\n:host {\n /* Surfaces */\n --notes-bg: #ffffff;\n --notes-bg-soft: #f8fafc;\n --notes-bg-sunken: #f1f5f9;\n\n /* Text */\n --notes-fg: #0f172a;\n --notes-fg-muted: #64748b;\n --notes-fg-subtle: #94a3b8;\n\n /* Lines */\n --notes-border: #e2e8f0;\n --notes-border-strong: #cbd5e1;\n\n /* Accent — single muted blue used for primary actions and active state */\n --notes-accent: #2563eb;\n --notes-accent-hover: #1d4ed8;\n --notes-accent-fg: #ffffff;\n --notes-accent-soft: rgba(37, 99, 235, 0.08);\n --notes-accent-ring: rgba(37, 99, 235, 0.2);\n\n /* Status colors — used sparingly */\n --notes-danger: #dc2626;\n --notes-danger-soft: #fef2f2;\n --notes-success: #16a34a;\n --notes-warn: #d97706;\n --notes-warn-soft: #fffbeb;\n --notes-warn-border: #fde68a;\n\n /* Geometry */\n --notes-shadow-sm: 0 1px 2px rgba(15, 23, 42, 0.06);\n --notes-shadow: 0 8px 24px -8px rgba(15, 23, 42, 0.16), 0 2px 4px -2px rgba(15, 23, 42, 0.06);\n --notes-shadow-lg: 0 24px 48px -16px rgba(15, 23, 42, 0.22);\n --notes-radius: 8px;\n --notes-radius-sm: 5px;\n --notes-sidebar-w: 340px;\n --notes-z: 2147483600;\n\n font-family: -apple-system, BlinkMacSystemFont, 'Inter', 'Segoe UI', Roboto, sans-serif;\n font-size: 13px;\n line-height: 1.5;\n color: var(--notes-fg);\n -webkit-font-smoothing: antialiased;\n font-feature-settings: 'cv11', 'ss01';\n}\n\n* {\n box-sizing: border-box;\n}\n\nbutton {\n font: inherit;\n cursor: pointer;\n border: none;\n background: none;\n color: inherit;\n padding: 0;\n}\n\ninput,\ntextarea {\n font: inherit;\n color: inherit;\n}\n\ncode {\n font-family: ui-monospace, 'SF Mono', Menlo, Consolas, monospace;\n font-size: 0.92em;\n background: var(--notes-bg-sunken);\n padding: 1px 5px;\n border-radius: 3px;\n color: var(--notes-fg);\n}\n\n.notes-root {\n position: fixed;\n inset: 0;\n pointer-events: none;\n z-index: var(--notes-z);\n}\n\n/* ──────────────────────────────────────────────────────────────────\n * Toolbar\n * ────────────────────────────────────────────────────────────────── */\n.notes-toolbar {\n position: fixed;\n top: 0;\n left: 0;\n right: 0;\n height: 40px;\n background: var(--notes-bg);\n border-bottom: 1px solid var(--notes-border);\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: 0 14px;\n pointer-events: auto;\n}\n\n.notes-toolbar__brand {\n display: flex;\n align-items: center;\n gap: 8px;\n font-weight: 600;\n font-size: 13px;\n letter-spacing: -0.01em;\n}\n\n.notes-toolbar__dot {\n width: 7px;\n height: 7px;\n border-radius: 50%;\n background: var(--notes-accent);\n box-shadow: 0 0 0 3px var(--notes-accent-soft);\n}\n\n.notes-toolbar__role {\n font-size: 10px;\n font-weight: 600;\n text-transform: uppercase;\n letter-spacing: 0.06em;\n padding: 2px 6px;\n border-radius: 3px;\n background: var(--notes-bg-sunken);\n color: var(--notes-fg-muted);\n}\n\n.notes-toolbar__role--agency {\n background: var(--notes-accent-soft);\n color: var(--notes-accent);\n}\n\n.notes-toolbar__page {\n color: var(--notes-fg-subtle);\n font-weight: 400;\n margin-left: 4px;\n font-size: 12px;\n}\n\n.notes-toolbar__actions {\n display: flex;\n align-items: center;\n gap: 6px;\n}\n\n/* ──────────────────────────────────────────────────────────────────\n * Buttons\n * ────────────────────────────────────────────────────────────────── */\n.notes-btn {\n padding: 5px 11px;\n border-radius: var(--notes-radius-sm);\n background: var(--notes-bg-sunken);\n color: var(--notes-fg);\n font-size: 12px;\n font-weight: 500;\n border: 1px solid transparent;\n transition: background 0.12s ease, border-color 0.12s ease, color 0.12s ease;\n white-space: nowrap;\n}\n\n.notes-btn:hover {\n background: var(--notes-border);\n}\n\n.notes-btn:disabled {\n opacity: 0.5;\n cursor: not-allowed;\n}\n\n.notes-btn--primary {\n background: var(--notes-accent);\n color: var(--notes-accent-fg);\n}\n\n.notes-btn--primary:hover {\n background: var(--notes-accent-hover);\n}\n\n.notes-btn--primary:disabled:hover {\n background: var(--notes-accent);\n}\n\n.notes-btn--ghost {\n background: transparent;\n color: var(--notes-fg-muted);\n}\n\n.notes-btn--ghost:hover {\n color: var(--notes-fg);\n background: var(--notes-bg-sunken);\n}\n\n.notes-btn--danger {\n color: var(--notes-danger);\n}\n\n.notes-btn--danger:hover {\n background: var(--notes-danger-soft);\n color: var(--notes-danger);\n}\n\n/* ──────────────────────────────────────────────────────────────────\n * Sidebar\n * ────────────────────────────────────────────────────────────────── */\n.notes-sidebar {\n position: fixed;\n top: 40px;\n right: 0;\n bottom: 0;\n width: var(--notes-sidebar-w);\n background: var(--notes-bg);\n border-left: 1px solid var(--notes-border);\n display: flex;\n flex-direction: column;\n pointer-events: auto;\n}\n\n.notes-sidebar__header {\n padding: 14px 16px 12px;\n border-bottom: 1px solid var(--notes-border);\n background: var(--notes-bg);\n}\n\n.notes-sidebar__title {\n font-size: 13px;\n font-weight: 600;\n margin: 0 0 3px;\n color: var(--notes-fg);\n letter-spacing: -0.01em;\n}\n\n.notes-sidebar__meta {\n font-size: 11px;\n color: var(--notes-fg-subtle);\n display: flex;\n align-items: center;\n gap: 4px;\n flex-wrap: wrap;\n}\n\n.notes-sidebar__list {\n flex: 1;\n overflow-y: auto;\n padding: 10px;\n display: flex;\n flex-direction: column;\n gap: 8px;\n}\n\n.notes-sidebar__list::-webkit-scrollbar {\n width: 8px;\n}\n\n.notes-sidebar__list::-webkit-scrollbar-thumb {\n background: var(--notes-border);\n border-radius: 4px;\n}\n\n.notes-sidebar__list::-webkit-scrollbar-thumb:hover {\n background: var(--notes-border-strong);\n}\n\n.notes-sidebar__empty {\n padding: 32px 16px;\n text-align: center;\n color: var(--notes-fg-subtle);\n font-size: 12px;\n line-height: 1.6;\n}\n\n.notes-sidebar__hint {\n font-size: 11px;\n color: var(--notes-fg-subtle);\n}\n\n.notes-sidebar__section {\n font-size: 10px;\n font-weight: 600;\n text-transform: uppercase;\n letter-spacing: 0.06em;\n color: var(--notes-fg-subtle);\n margin: 6px 4px 2px;\n}\n\n.notes-sidebar__deleted {\n margin-top: 4px;\n border-top: 1px solid var(--notes-border);\n padding-top: 8px;\n}\n\n.notes-sidebar__deleted summary {\n font-size: 11px;\n font-weight: 500;\n color: var(--notes-fg-muted);\n cursor: pointer;\n padding: 4px 4px;\n user-select: none;\n list-style: none;\n}\n\n.notes-sidebar__deleted summary::-webkit-details-marker {\n display: none;\n}\n\n.notes-sidebar__deleted summary::before {\n content: '▸';\n display: inline-block;\n margin-right: 6px;\n transition: transform 0.15s;\n font-size: 9px;\n}\n\n.notes-sidebar__deleted[open] summary::before {\n transform: rotate(90deg);\n}\n\n.notes-sidebar__deleted summary:hover {\n color: var(--notes-fg);\n}\n\n.notes-sidebar__deleted[open] {\n display: flex;\n flex-direction: column;\n gap: 8px;\n}\n\n/* ──────────────────────────────────────────────────────────────────\n * Item card\n * ────────────────────────────────────────────────────────────────── */\n.notes-item {\n border: 1px solid var(--notes-border);\n border-radius: var(--notes-radius);\n padding: 11px 12px;\n background: var(--notes-bg);\n transition: border-color 0.12s, box-shadow 0.12s;\n}\n\n.notes-item:hover {\n border-color: var(--notes-border-strong);\n}\n\n.notes-item--active {\n border-color: var(--notes-accent);\n box-shadow: 0 0 0 3px var(--notes-accent-ring);\n}\n\n.notes-item--resolved {\n opacity: 0.6;\n}\n\n.notes-item--deleted {\n opacity: 0.45;\n background: var(--notes-bg-soft);\n}\n\n.notes-item__head {\n display: flex;\n align-items: center;\n justify-content: space-between;\n margin-bottom: 7px;\n gap: 8px;\n}\n\n.notes-item__author {\n font-weight: 600;\n font-size: 12px;\n color: var(--notes-fg);\n}\n\n.notes-item__time {\n font-size: 10px;\n color: var(--notes-fg-subtle);\n white-space: nowrap;\n}\n\n.notes-item__snippet {\n font-size: 11px;\n color: var(--notes-fg-muted);\n background: var(--notes-bg-soft);\n border-left: 2px solid var(--notes-border);\n padding: 5px 8px;\n margin-bottom: 7px;\n border-radius: 0 3px 3px 0;\n white-space: pre-wrap;\n word-break: break-word;\n max-height: 48px;\n overflow: hidden;\n}\n\n.notes-item__body {\n font-size: 12.5px;\n white-space: pre-wrap;\n word-break: break-word;\n color: var(--notes-fg);\n}\n\n.notes-item__actions {\n display: flex;\n gap: 5px;\n margin-top: 10px;\n padding-top: 9px;\n border-top: 1px solid var(--notes-border);\n}\n\n.notes-item__badge {\n display: inline-block;\n font-size: 9px;\n font-weight: 600;\n text-transform: uppercase;\n letter-spacing: 0.06em;\n padding: 2px 6px;\n border-radius: 3px;\n margin-right: 6px;\n vertical-align: 1px;\n}\n\n.notes-item__badge--comment {\n background: var(--notes-accent-soft);\n color: var(--notes-accent);\n}\n\n.notes-item__badge--suggestion {\n background: rgba(217, 119, 6, 0.1);\n color: var(--notes-warn);\n}\n\n.notes-item__badge--resolved {\n background: rgba(22, 163, 74, 0.1);\n color: var(--notes-success);\n}\n\n.notes-item__badge--deleted {\n background: var(--notes-bg-sunken);\n color: var(--notes-fg-subtle);\n}\n\n.notes-item__history {\n margin-top: 8px;\n font-size: 11px;\n}\n\n.notes-item__history summary {\n cursor: pointer;\n color: var(--notes-fg-subtle);\n user-select: none;\n font-weight: 500;\n list-style: none;\n}\n\n.notes-item__history summary::-webkit-details-marker {\n display: none;\n}\n\n.notes-item__history summary::before {\n content: '▸';\n display: inline-block;\n margin-right: 5px;\n transition: transform 0.15s;\n font-size: 8px;\n}\n\n.notes-item__history[open] summary::before {\n transform: rotate(90deg);\n}\n\n.notes-item__history summary:hover {\n color: var(--notes-fg-muted);\n}\n\n.notes-item__history ul {\n list-style: none;\n padding: 6px 0 0 14px;\n margin: 0;\n}\n\n.notes-item__history li {\n padding: 3px 0;\n color: var(--notes-fg-muted);\n}\n\n.notes-item__history-action {\n font-weight: 600;\n color: var(--notes-fg);\n text-transform: capitalize;\n}\n\n.notes-item__history-meta {\n color: var(--notes-fg-subtle);\n}\n\n.notes-item__history-note {\n color: var(--notes-fg-subtle);\n font-style: italic;\n padding-left: 8px;\n margin-top: 1px;\n font-size: 10px;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n\n/* ──────────────────────────────────────────────────────────────────\n * Element highlight ring\n * ────────────────────────────────────────────────────────────────── */\n.notes-highlight {\n position: fixed;\n pointer-events: none;\n border: 2px solid var(--notes-accent);\n border-radius: 3px;\n box-shadow: 0 0 0 3px var(--notes-accent-ring);\n transition: all 0.08s ease-out;\n}\n\n.notes-highlight--persistent {\n border-color: rgba(37, 99, 235, 0.55);\n box-shadow: 0 0 0 3px var(--notes-accent-soft);\n}\n\n/* ──────────────────────────────────────────────────────────────────\n * Popover (comment + suggest)\n * ────────────────────────────────────────────────────────────────── */\n.notes-popover {\n position: fixed;\n width: 320px;\n background: var(--notes-bg);\n border: 1px solid var(--notes-border);\n border-radius: var(--notes-radius);\n box-shadow: var(--notes-shadow-lg);\n padding: 14px;\n pointer-events: auto;\n display: flex;\n flex-direction: column;\n gap: 10px;\n}\n\n.notes-popover__title {\n font-size: 12px;\n font-weight: 600;\n margin: 0;\n color: var(--notes-fg);\n letter-spacing: -0.01em;\n}\n\n.notes-popover__snippet {\n font-size: 11px;\n color: var(--notes-fg-muted);\n background: var(--notes-bg-soft);\n border-left: 2px solid var(--notes-border);\n padding: 6px 8px;\n border-radius: 0 3px 3px 0;\n max-height: 60px;\n overflow: hidden;\n}\n\n.notes-popover textarea {\n width: 100%;\n min-height: 78px;\n resize: vertical;\n border: 1px solid var(--notes-border);\n border-radius: var(--notes-radius-sm);\n padding: 8px 10px;\n background: var(--notes-bg);\n outline: none;\n font-size: 12.5px;\n line-height: 1.5;\n}\n\n.notes-popover textarea:focus {\n border-color: var(--notes-accent);\n box-shadow: 0 0 0 3px var(--notes-accent-ring);\n}\n\n.notes-popover input[type='text'] {\n border: 1px solid var(--notes-border);\n border-radius: var(--notes-radius-sm);\n padding: 6px 10px;\n background: var(--notes-bg);\n outline: none;\n font-size: 12px;\n width: 100%;\n}\n\n.notes-popover input[type='text']:focus {\n border-color: var(--notes-accent);\n box-shadow: 0 0 0 3px var(--notes-accent-ring);\n}\n\n.notes-popover__row {\n display: flex;\n justify-content: space-between;\n align-items: center;\n gap: 8px;\n}\n\n/* Selection tooltip */\n.notes-selection-tooltip {\n position: fixed;\n display: flex;\n align-items: center;\n gap: 4px;\n padding: 4px 5px;\n background: #0f172a;\n color: #ffffff;\n border-radius: 6px;\n box-shadow: var(--notes-shadow);\n pointer-events: auto;\n z-index: calc(var(--notes-z) + 5);\n}\n\n.notes-selection-tooltip .notes-btn {\n background: rgba(255, 255, 255, 0.06);\n color: #ffffff;\n font-size: 11px;\n padding: 4px 9px;\n}\n\n.notes-selection-tooltip .notes-btn:hover {\n background: rgba(255, 255, 255, 0.14);\n}\n\n.notes-selection-tooltip .notes-btn--primary {\n background: var(--notes-accent);\n color: var(--notes-accent-fg);\n}\n\n.notes-selection-tooltip .notes-btn--primary:hover {\n background: var(--notes-accent-hover);\n}\n\n.notes-selection-tooltip .notes-btn--ghost {\n color: #e2e8f0;\n}\n\n.notes-selection-tooltip .notes-btn--ghost:hover {\n background: rgba(255, 255, 255, 0.14);\n color: #ffffff;\n}\n\n/* Suggest popover variations */\n.notes-popover--suggest {\n width: 360px;\n}\n\n.notes-popover__label {\n display: block;\n font-size: 10px;\n font-weight: 600;\n text-transform: uppercase;\n letter-spacing: 0.06em;\n color: var(--notes-fg-subtle);\n margin-bottom: 4px;\n}\n\n.notes-popover__original {\n background: var(--notes-warn-soft);\n border: 1px solid var(--notes-warn-border);\n border-radius: var(--notes-radius-sm);\n padding: 8px 10px;\n font-size: 12px;\n color: #78350f;\n max-height: 80px;\n overflow-y: auto;\n white-space: pre-wrap;\n word-break: break-word;\n}\n\n.notes-strikethrough {\n text-decoration: line-through;\n text-decoration-color: rgba(220, 38, 38, 0.55);\n text-decoration-thickness: 1.5px;\n}\n\n/* ──────────────────────────────────────────────────────────────────\n * Diff preview\n * ────────────────────────────────────────────────────────────────── */\n.notes-diff {\n font-size: 12px;\n border-radius: var(--notes-radius-sm);\n background: var(--notes-bg-soft);\n border: 1px solid var(--notes-border);\n overflow: hidden;\n margin-bottom: 8px;\n}\n\n.notes-diff__row {\n padding: 6px 10px;\n display: flex;\n gap: 6px;\n white-space: pre-wrap;\n word-break: break-word;\n line-height: 1.5;\n}\n\n.notes-diff__row--del {\n background: #fef2f2;\n color: #7f1d1d;\n border-bottom: 1px solid #fee2e2;\n}\n\n.notes-diff__row--ins {\n background: #f0fdf4;\n color: #14532d;\n}\n\n.notes-diff__marker {\n font-weight: 700;\n font-family: ui-monospace, 'SF Mono', Menlo, Consolas, monospace;\n width: 11px;\n flex-shrink: 0;\n text-align: center;\n font-size: 11px;\n}\n\n.notes-item__rationale {\n font-size: 11px;\n color: var(--notes-fg-muted);\n margin-bottom: 6px;\n font-style: italic;\n}\n\n.notes-item__rationale-label {\n font-style: normal;\n font-weight: 600;\n color: var(--notes-fg);\n margin-right: 4px;\n}\n\n/* Stale warning */\n.notes-stale {\n display: flex;\n align-items: center;\n gap: 6px;\n background: var(--notes-warn-soft);\n border: 1px solid var(--notes-warn-border);\n color: #92400e;\n font-size: 11px;\n padding: 5px 8px;\n border-radius: var(--notes-radius-sm);\n margin-bottom: 8px;\n}\n\n.notes-stale__icon {\n font-size: 12px;\n}\n\n/* Persistent highlight variant for suggestion ranges */\n.notes-highlight--suggestion {\n border-color: rgba(217, 119, 6, 0.85);\n box-shadow: 0 0 0 3px rgba(217, 119, 6, 0.18);\n background: rgba(254, 243, 199, 0.25);\n}\n\n/* Banner shown when notes API fails to load */\n.notes-banner {\n padding: 9px 12px;\n background: var(--notes-danger-soft);\n border: 1px solid #fecaca;\n color: #991b1b;\n border-radius: var(--notes-radius-sm);\n font-size: 12px;\n pointer-events: auto;\n}\n";
1339
1500
  function init() {
1340
1501
  if (window.__nuasiteNotesMounted) return;
1341
1502
  const config = window.__NuaNotesConfig ?? {};
1342
1503
  const urlFlag = config.urlFlag ?? "nua-notes";
1504
+ const agencyFlag = config.agencyFlag ?? "nua-agency";
1343
1505
  if (!isReviewMode(urlFlag)) return;
1344
1506
  window.__nuasiteNotesMounted = true;
1345
1507
  setReviewModeCookie();
@@ -1356,7 +1518,7 @@ function init() {
1356
1518
  const root = document.createElement("div");
1357
1519
  root.id = "nua-notes-root";
1358
1520
  shadow.appendChild(root);
1359
- R(/* @__PURE__ */ u$1(App, { urlFlag }), root);
1521
+ R(/* @__PURE__ */ u$1(App, { urlFlag, agencyFlag }), root);
1360
1522
  }
1361
1523
  if (typeof window !== "undefined") {
1362
1524
  if (document.readyState === "loading") {
package/package.json CHANGED
@@ -14,7 +14,7 @@
14
14
  "directory": "packages/notes"
15
15
  },
16
16
  "license": "Apache-2.0",
17
- "version": "0.22.2",
17
+ "version": "0.23.0",
18
18
  "module": "src/index.ts",
19
19
  "types": "src/index.ts",
20
20
  "type": "module",