@north-light/crouter 0.3.197 → 0.3.198

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 (144) hide show
  1. package/dist/api/client.d.ts +2 -2
  2. package/dist/api/dto/inbox.d.ts +46 -0
  3. package/dist/builtin-memory/00-runtime-base.md +3 -3
  4. package/dist/builtin-memory/internal/nodes-and-canvas.md +1 -1
  5. package/dist/builtin-memory/internal/storage-tiers.md +1 -1
  6. package/dist/builtin-memory/wedged-child-on-runaway-bash.md +1 -1
  7. package/dist/clients/attach/render/chat-view.d.ts +3 -8
  8. package/dist/clients/attach/render/chat-view.js +3 -24
  9. package/dist/clients/attach/render/markdown-source.js +0 -6
  10. package/dist/clients/attach/render/tool-calls.js +16 -2
  11. package/dist/clients/attach/viewer.js +613 -602
  12. package/dist/clients/inbox/__tests__/serial/inbox-controller.test.js +2 -2
  13. package/dist/clients/inbox/__tests__/serial/mount-panel.test.js +11 -4
  14. package/dist/clients/inbox/controller.js +4 -4
  15. package/dist/clients/inbox/page-adapter.d.ts +2 -1
  16. package/dist/clients/inbox/tui/render.js +46 -25
  17. package/dist/clients/inbox/tui/slots.d.ts +1 -3
  18. package/dist/clients/inbox/tui/slots.js +8 -37
  19. package/dist/clients/inbox/tui/types.d.ts +4 -3
  20. package/dist/commands/__tests__/human.test.js +160 -23
  21. package/dist/commands/canvas-browse.js +1 -1
  22. package/dist/commands/human/doc.js +21 -74
  23. package/dist/commands/human/html.d.ts +2 -0
  24. package/dist/commands/human/html.js +81 -0
  25. package/dist/commands/human/prompts.d.ts +5 -4
  26. package/dist/commands/human/prompts.js +81 -153
  27. package/dist/commands/human/shared.d.ts +5 -6
  28. package/dist/commands/human/shared.js +13 -61
  29. package/dist/commands/human.js +7 -2
  30. package/dist/core/__tests__/daemon-boot.test.js +7 -4
  31. package/dist/core/__tests__/dead-node-policy-table.test.js +20 -36
  32. package/dist/core/__tests__/human-deliver.test.js +28 -37
  33. package/dist/core/__tests__/seam/broker-crash-teardown.test.js +13 -11
  34. package/dist/core/__tests__/seam/dormancy-release.test.js +63 -4
  35. package/dist/core/__tests__/serial/human-deliver-e2e.test.js +3 -13
  36. package/dist/core/canvas/__tests__/attention.test.js +2 -2
  37. package/dist/core/canvas/__tests__/render-remote.test.js +2 -2
  38. package/dist/core/canvas/browse/app.d.ts +1 -1
  39. package/dist/core/canvas/browse/app.js +21 -3
  40. package/dist/core/canvas/browse/render.d.ts +4 -0
  41. package/dist/core/canvas/browse/render.js +5 -1
  42. package/dist/core/canvas/canvas.d.ts +26 -0
  43. package/dist/core/canvas/canvas.js +55 -0
  44. package/dist/core/command.js +6 -11
  45. package/dist/core/config.js +3 -2
  46. package/dist/core/help.d.ts +3 -0
  47. package/dist/core/human/__tests__/html-markdown.test.d.ts +1 -0
  48. package/dist/core/human/__tests__/html-markdown.test.js +52 -0
  49. package/dist/core/human/__tests__/page-catalog.test.d.ts +1 -0
  50. package/dist/core/human/__tests__/page-catalog.test.js +16 -0
  51. package/dist/core/human/__tests__/page-render.test.js +40 -23
  52. package/dist/core/human/__tests__/page-tickets.test.js +48 -27
  53. package/dist/core/human/__tests__/page.test.js +48 -65
  54. package/dist/core/human/__tests__/serial/inbox-core.test.js +5 -15
  55. package/dist/core/human/answer-text.d.ts +3 -0
  56. package/dist/core/human/answer-text.js +98 -0
  57. package/dist/core/human/answer.d.ts +51 -0
  58. package/dist/core/human/answer.js +125 -0
  59. package/dist/core/human/component-docs.d.ts +14 -0
  60. package/dist/core/human/component-docs.js +161 -0
  61. package/dist/core/human/html-markdown.d.ts +3 -0
  62. package/dist/core/human/html-markdown.js +288 -0
  63. package/dist/core/human/page-catalog.d.ts +19 -3
  64. package/dist/core/human/page-catalog.js +73 -16
  65. package/dist/core/human/page-render.d.ts +3 -2
  66. package/dist/core/human/page-render.js +19 -45
  67. package/dist/core/human/page-schema.d.ts +108 -8
  68. package/dist/core/human/page-schema.js +88 -31
  69. package/dist/core/human/page-synth.d.ts +2 -4
  70. package/dist/core/human/page-synth.js +23 -7
  71. package/dist/core/human/page.d.ts +14 -7
  72. package/dist/core/human/page.js +178 -90
  73. package/dist/core/human/review-schema.d.ts +1 -0
  74. package/dist/core/human/review-schema.js +1 -1
  75. package/dist/core/human/scan.d.ts +3 -2
  76. package/dist/core/human/scan.js +7 -8
  77. package/dist/core/human/summary.d.ts +4 -7
  78. package/dist/core/human/summary.js +4 -60
  79. package/dist/core/human/tickets.d.ts +10 -9
  80. package/dist/core/human/tickets.js +5 -3
  81. package/dist/core/human/types.d.ts +4 -0
  82. package/dist/core/keybindings/catalog.d.ts +2 -2
  83. package/dist/core/keybindings/catalog.js +1 -0
  84. package/dist/core/review/realize.js +9 -1
  85. package/dist/core/runtime/boot-root.js +6 -1
  86. package/dist/core/runtime/broker.js +8 -6
  87. package/dist/core/runtime/busy.d.ts +4 -3
  88. package/dist/core/runtime/busy.js +4 -3
  89. package/dist/core/runtime/spawn.js +4 -4
  90. package/dist/core/user-settings.d.ts +17 -2
  91. package/dist/core/user-settings.js +32 -11
  92. package/dist/daemon/api/handlers/human.js +1 -1
  93. package/dist/daemon/api/handlers/inbox.js +22 -7
  94. package/dist/daemon/cron-run.js +16 -2
  95. package/dist/daemon/crtrd.js +1 -1
  96. package/dist/daemon/fleet.d.ts +22 -10
  97. package/dist/daemon/fleet.js +43 -24
  98. package/dist/daemon/human/finish.d.ts +2 -1
  99. package/dist/daemon/human/finish.js +45 -28
  100. package/dist/daemon/human/sweep.js +4 -2
  101. package/dist/daemon/reconcilers/broker-supervision.js +11 -8
  102. package/dist/daemon/reconcilers/dormant-inbox.js +11 -6
  103. package/dist/daemon/reconcilers/live-obligation.d.ts +21 -1
  104. package/dist/daemon/reconcilers/live-obligation.js +30 -2
  105. package/dist/daemon/reconcilers/storage-maintenance.d.ts +5 -0
  106. package/dist/daemon/reconcilers/storage-maintenance.js +28 -1
  107. package/dist/daemon/review/sweep.js +12 -1
  108. package/dist/pages/bundle.css +1 -1
  109. package/dist/pages/bundle.js +1008 -577
  110. package/dist/pages/comments.d.ts +29 -0
  111. package/dist/pages/comments.js +51 -0
  112. package/dist/pages/controls.d.ts +98 -0
  113. package/dist/pages/controls.js +261 -0
  114. package/dist/pages/elements/cards.d.ts +15 -4
  115. package/dist/pages/elements/cards.js +299 -186
  116. package/dist/pages/elements/chart.d.ts +22 -0
  117. package/dist/pages/elements/chart.js +107 -91
  118. package/dist/pages/elements/options.d.ts +9 -0
  119. package/dist/pages/elements/options.js +268 -155
  120. package/dist/pages/elements/pages.d.ts +6 -0
  121. package/dist/pages/elements/pages.js +60 -38
  122. package/dist/pages/elements/slot.d.ts +5 -0
  123. package/dist/pages/elements/slot.js +17 -10
  124. package/dist/pages/elements/table.d.ts +17 -0
  125. package/dist/pages/elements/table.js +336 -228
  126. package/dist/pages/elements/text.d.ts +9 -3
  127. package/dist/pages/elements/text.js +350 -143
  128. package/dist/pages/host.d.ts +0 -24
  129. package/dist/pages/host.js +0 -17
  130. package/dist/pages/readonly.d.ts +24 -0
  131. package/dist/pages/readonly.js +31 -0
  132. package/dist/pages/responses.d.ts +37 -0
  133. package/dist/pages/responses.js +56 -0
  134. package/dist/pi-extensions/canvas-bash-valve.d.ts +9 -1
  135. package/dist/pi-extensions/canvas-bash-valve.js +12 -8
  136. package/dist/types.d.ts +19 -5
  137. package/dist/types.js +2 -1
  138. package/package.json +1 -1
  139. package/runtime.lock.json +2 -2
  140. package/scripts/install-runtime.mjs +19 -24
  141. package/dist/clients/attach/render/html-markdown.d.ts +0 -13
  142. package/dist/clients/attach/render/html-markdown.js +0 -206
  143. package/dist/core/human/markdown-html.d.ts +0 -8
  144. package/dist/core/human/markdown-html.js +0 -581
@@ -1,88 +1,250 @@
1
- "use strict";(()=>{function K(o){switch(o.kind){case"whole":return"whole";case"option":return`option:${o.optionId}`;case"row":return`row:${o.rowId}`;case"column":return`column:${o.columnId}`;case"card":return`card:${o.cardId}`;case"range":return`range:${o.start}:${o.end}`}}function b(o,t){let e=K(t);return o.find(r=>K(r.anchor)===e)}function R(o,t,e){let r=K(t),n=o.filter(s=>K(s.anchor)!==r),i=e.trim();if(i==="")return n;let a=o.find(s=>K(s.anchor)===r);return[...n,{id:a?.id??Gt(),anchor:t,text:i}]}var Z=0;function Kt(o){if(typeof o!="object"||o===null)return!1;let t=o;switch(t.kind){case"whole":return!0;case"option":return typeof t.optionId=="string";case"row":return typeof t.rowId=="string";case"column":return typeof t.columnId=="string";case"card":return typeof t.cardId=="string";case"range":return typeof t.start=="number"&&typeof t.end=="number"&&typeof t.quote=="string";default:return!1}}function H(o){if(!Array.isArray(o))return[];let t=[];for(let e of o){if(typeof e!="object"||e===null)continue;let{id:r,anchor:n,text:i}=e;if(typeof r!="string"||r===""||typeof i!="string"||i.trim()===""||!Kt(n)||b(t,n)!==void 0)continue;t.push({id:r,anchor:{...n},text:i});let a=/^c(\d+)$/.exec(r);a!==null&&(Z=Math.max(Z,Number(a[1])))}return t}function Gt(){return Z+=1,`c${Z}`}function nt(o){switch(o.kind){case"whole":return"this";case"range":return`\u201C${o.quote}\u201D`;default:return K(o)}}function Q(){return typeof window>"u"?void 0:window.crtr}function vt(o){if(o instanceof Error&&o.message!=="")return o.message;let t=String(o);return t===""?"unknown error":t}function xt(o){return{status:"unavailable",reason:`host bridge does not provide ${o}()`}}function $(o,t){let e=Q();if(typeof e?.respond!="function")return xt("respond");try{return e.respond(o,t),{status:"ok"}}catch(r){return{status:"failed",reason:vt(r)}}}function I(o){let t=Q();if(typeof t?.savedResponse=="function")try{let e=t.savedResponse(o);return typeof e=="object"&&e!==null&&!Array.isArray(e)?e:void 0}catch{return}}function B(o){return Array.isArray(o)?o.filter(t=>typeof t=="string"):[]}async function G(o){let t=Q();if(typeof t?.artifact?.data!="function")return xt("artifact.data");try{return{status:"ok",data:await t.artifact.data(o)}}catch(e){return{status:"failed",reason:vt(e)}}}async function yt(o,t,e){let r=Q();if(typeof r?.mountWorkspaceComponent!="function")return"unavailable";try{return await r.mountWorkspaceComponent(o,t,e)}catch{return"unavailable"}}function v(o,t){customElements.define(o,t)}function k(o){let t=o.querySelector('script[type="application/json"]');if(t===null)return{status:"invalid",reason:"slot has no application/json config"};let e=t.textContent??"";if(e.trim()==="")return{status:"invalid",reason:"slot config is empty"};let r;try{r=JSON.parse(e)}catch(n){return{status:"invalid",reason:`slot config is not valid JSON: ${n instanceof Error&&n.message!==""?n.message:"invalid JSON"}`}}return typeof r!="object"||r===null||Array.isArray(r)?{status:"invalid",reason:"slot config must be a JSON object"}:{status:"ok",config:r}}function N(o){let t=o.getAttribute("slot-id")?.trim();return t===void 0||t===""?void 0:t}var Ft='<svg viewBox="0 0 16 16" aria-hidden="true" focusable="false"><path d="M2.5 3.5h11v7h-6l-3 2.5v-2.5h-2z"/><path d="M8 5.5v3M6.5 7h3"/></svg>',Wt='<svg viewBox="0 0 16 16" aria-hidden="true" focusable="false"><path d="M2.5 3.5h11v7h-6l-3 2.5v-2.5h-2z"/><path d="M5 6.25h6M5 8.25h4"/></svg>',Et=`
1
+ "use strict";(()=>{function L(n){return n!==void 0}function W(n){switch(n.kind){case"whole":return"whole";case"option":return`option:${n.optionId}`;case"row":return`row:${n.rowId}`;case"column":return`column:${n.columnId}`;case"card":return`card:${n.cardId}`;case"range":return`range:${n.start}:${n.end}`}}function y(n,t){let e=W(t);return n.find(r=>W(r.anchor)===e)}function z(n,t,e){let r=W(t),o=n.filter(s=>W(s.anchor)!==r),a=e.trim();if(a==="")return o;let i=n.find(s=>W(s.anchor)===r);return[...o,{id:i?.id??se(),anchor:t,text:a}]}var et=0;function ie(n){if(typeof n!="object"||n===null)return!1;let t=n;switch(t.kind){case"whole":return!0;case"option":return typeof t.optionId=="string";case"row":return typeof t.rowId=="string";case"column":return typeof t.columnId=="string";case"card":return typeof t.cardId=="string";case"range":return typeof t.start=="number"&&typeof t.end=="number"&&typeof t.quote=="string";default:return!1}}function O(n){if(!Array.isArray(n))return[];let t=[];for(let e of n){if(typeof e!="object"||e===null)continue;let{id:r,anchor:o,text:a}=e;if(typeof r!="string"||r===""||typeof a!="string"||a.trim()===""||!ie(o)||y(t,o)!==void 0)continue;t.push({id:r,anchor:{...o},text:a});let i=/^c(\d+)$/.exec(r);i!==null&&(et=Math.max(et,Number(i[1])))}return t}function se(){return et+=1,`c${et}`}var ce=84,le=48,de=30;function he(n){let t=n.lastIndexOf(" ");return(t>0&&t>=n.length-12?n.slice(0,t):n).trimEnd()}function me(n){let t=n.indexOf(" ");return(t!==-1&&t<12?n.slice(t+1):n).trimStart()}function Ht(n){let t=n.replace(/\s+/gu," ").trim();return t.length<=ce?t:`${he(t.slice(0,le))} \u2026 ${me(t.slice(-de))}`}function st(n){switch(n.kind){case"whole":return"this";case"range":return`\u201C${n.quote}\u201D`;default:return W(n)}}var zt=`url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M20 6 9 17l-5-5'/%3E%3C/svg%3E")`,Ot=`url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M5 12h14'/%3E%3C/svg%3E")`;function x(n,t=""){return n.map(e=>`${e}${t}`).join(`,
2
+ `)}function ct(n){let t=n[0];return typeof t=="object"?[t.scope,n.slice(1)]:[null,n]}function I(n,t,e){return(r,o)=>{let a=`var(--crtr-${t}-${r}, ${o})`;return n===null?a:`var(--crtr-${e===""?`${n}-${r}`:`${n}-${e}-${r}`}, ${a})`}}function lt(n){let t=I(n,"control-focus","focus"),e=t("ring-width","0.1875rem"),r=t("ring-color","color-mix(in srgb, var(--crtr-color-focus, CanvasText) 25%, transparent)");return`
3
+ outline: ${t("outline","none")};
4
+ border-color: ${t("border-color","color-mix(in srgb, var(--crtr-color-focus, CanvasText) 60%, transparent)")};
5
+ box-shadow: ${t("ring",`0 0 0 ${e}
6
+ ${r}`)};`}function u(...n){let[t,e]=ct(n);return`
7
+ ${x(e,":focus-visible")} {${lt(t)}
8
+ }
9
+ `}function S(...n){let[t,e]=ct(n),r=I(t,"control-writing",""),a=I(t,"control","")("transition","120ms ease");return`
10
+ ${x(e)} {
11
+ /* Block, not the UA's inline-block: a full-width field on its own line would otherwise sit
12
+ in a line box and carry a descender's worth of dead space under it. */
13
+ display: block;
14
+ box-sizing: border-box;
15
+ width: 100%;
16
+ padding: ${r("padding","var(--crtr-space-2) var(--crtr-space-3)")};
17
+ color: ${r("text-color","var(--crtr-color-text, CanvasText)")};
18
+ font: ${r("font","inherit")};
19
+ line-height: ${r("line-height","var(--crtr-line-height, 1.5)")};
20
+ background: ${r("fill","color-mix(in srgb, var(--crtr-color-text, CanvasText) 2%, var(--crtr-color-background, Canvas))")};
21
+ border: ${r("border-width","1px")} ${r("border-style","solid")} ${r("border-color","var(--crtr-color-border, CanvasText)")};
22
+ border-radius: ${r("radius","var(--crtr-radius-small)")};
23
+ box-shadow: ${r("shadow","var(--crtr-shadow)")};
24
+ transition: border-color ${a}, box-shadow ${a};
25
+ }
26
+
27
+ ${x(e,"::placeholder")} {
28
+ color: ${r("placeholder-color","var(--crtr-color-text-muted, GrayText)")};
29
+ }
30
+
31
+ ${x(e,":focus-visible")} {${lt(t)}
32
+ }
33
+
34
+ /* A page that can no longer take an answer keeps its text selectable and copyable, and drops
35
+ the affordances that say it could still be rewritten. */
36
+ ${x(e,":read-only")} {
37
+ background: ${r("readonly-fill","var(--crtr-color-surface, Canvas)")};
38
+ box-shadow: ${r("readonly-shadow","none")};
39
+ resize: none;
40
+ }
41
+ `}function F(...n){let[t,e]=ct(n),r=I(t,"control-box",""),o=I(t,"control-mark","mark"),a=I(t,"control-radio","radio"),i=I(t,"control-checkbox","checkbox"),s=I(t,"control",""),c=s("transition","120ms ease");return`
42
+ ${x(e)} {
43
+ /* The box tracks the host's font token like every other size in the bundle. The kit's
44
+ control is 16px against 14px text; these ratios are that pair, kept proportional. */
45
+ --control-box: ${r("size","1.125em")};
46
+ appearance: none;
47
+ -webkit-appearance: none;
48
+ box-sizing: border-box;
49
+ display: inline-grid;
50
+ place-content: center;
51
+ flex: none;
52
+ width: var(--control-box);
53
+ height: var(--control-box);
54
+ margin: 0;
55
+ padding: 0;
56
+ vertical-align: middle;
57
+ /* Transparent rather than the background token, so an empty control on a selected row
58
+ carries that row's tint the way the kit's does. */
59
+ background: ${r("fill","transparent")};
60
+ border: ${r("border-width","1px")} ${r("border-style","solid")} ${r("border-color","var(--crtr-color-border, CanvasText)")};
61
+ border-radius: ${r("radius","calc(var(--control-box) * 0.25)")};
62
+ box-shadow: ${r("shadow","var(--crtr-shadow)")};
63
+ cursor: pointer;
64
+ transition: background-color ${c}, border-color ${c}, box-shadow ${c};
65
+ }
66
+
67
+ ${x(e,'[type="radio"]')} {
68
+ border-radius: ${a("radius","50%")};
69
+ }
70
+
71
+ /* The mark. It is always present and always centred; selecting scales it in, which is the
72
+ state change the kit animates too. */
73
+ ${x(e,"::before")} {
74
+ content: "";
75
+ background: ${o("fill","currentColor")};
76
+ transform: scale(0);
77
+ transition: transform ${c};
78
+ }
79
+
80
+ ${x(e,":checked::before")},
81
+ ${x(e,":indeterminate::before")} {
82
+ transform: scale(1);
83
+ }
84
+
85
+ /* A radio keeps its own surface and marks itself with a dot in the accent; a checkbox fills
86
+ with the accent and carries the tick in the accent's contrast colour. */
87
+ ${x(e,'[type="radio"]::before')} {
88
+ width: ${a("mark-size","calc(var(--control-box) * 0.5)")};
89
+ height: ${a("mark-size","calc(var(--control-box) * 0.5)")};
90
+ border-radius: ${a("mark-radius","50%")};
91
+ color: ${a("mark-color","var(--crtr-color-accent, CanvasText)")};
92
+ }
93
+
94
+ ${x(e,'[type="radio"]:checked')} {
95
+ border-color: ${a("checked-border-color","var(--crtr-color-accent, CanvasText)")};
96
+ }
97
+
98
+ ${x(e,'[type="checkbox"]::before')} {
99
+ width: ${i("mark-size","calc(var(--control-box) * 0.875)")};
100
+ height: ${i("mark-size","calc(var(--control-box) * 0.875)")};
101
+ color: ${i("mark-color","var(--crtr-color-accent-contrast, Canvas)")};
102
+ -webkit-mask: ${i("mark-image",zt)} ${i("mark-layout","center / contain no-repeat")};
103
+ mask: ${i("mark-image",zt)} ${i("mark-layout","center / contain no-repeat")};
104
+ }
105
+
106
+ ${x(e,'[type="checkbox"]:indeterminate::before')} {
107
+ -webkit-mask-image: ${i("indeterminate-mark-image",Ot)};
108
+ mask-image: ${i("indeterminate-mark-image",Ot)};
109
+ }
110
+
111
+ ${x(e,'[type="checkbox"]:checked')},
112
+ ${x(e,'[type="checkbox"]:indeterminate')} {
113
+ background: ${i("checked-fill","var(--crtr-color-accent, CanvasText)")};
114
+ border-color: ${i("checked-border-color","var(--crtr-color-accent, CanvasText)")};
115
+ }
116
+
117
+ /* The bundle's one focus treatment. The box scales with the font token, but the ring does
118
+ not: the kit's is a flat three pixels on a checkbox and on the field beside it alike. */
119
+ ${x(e,"[type]:focus-visible")} {${lt(t)}
120
+ }
121
+
122
+ /* A page that can no longer take an answer keeps its selection legible \u2014 the mark stays the
123
+ accent, only dimmed \u2014 and drops every affordance that says it could still be changed. */
124
+ ${x(e,":disabled")} {
125
+ opacity: ${s("disabled-opacity","0.5")};
126
+ box-shadow: ${s("disabled-shadow","none")};
127
+ cursor: default;
128
+ }
129
+ `}function dt(){return typeof window>"u"?void 0:window.crtr}function pe(n){if(n instanceof Error&&n.message!=="")return n.message;let t=String(n);return t===""?"unknown error":t}function ue(n){return{status:"unavailable",reason:`host bridge does not provide ${n}()`}}function M(n,t){let e=dt();if(typeof e?.respond!="function")return ue("respond");try{return e.respond(n,t),{status:"ok"}}catch(r){return{status:"failed",reason:pe(r)}}}function N(n){let t=dt();if(typeof t?.savedResponse=="function")try{let e=t.savedResponse(n);return typeof e=="object"&&e!==null&&!Array.isArray(e)?e:void 0}catch{return}}function q(n){return Array.isArray(n)?n.filter(t=>typeof t=="string"):[]}async function It(n,t,e){let r=dt();if(typeof r?.mountWorkspaceComponent!="function")return"unavailable";try{return await r.mountWorkspaceComponent(n,t,e)}catch{return"unavailable"}}function f(n){return n.closest("[inert], crtr-pages[disabled]")!==null}function j(n,t){for(let e of n.querySelectorAll("input"))e.disabled=t;for(let e of n.querySelectorAll("textarea"))e.readOnly=t}function w(n,t){customElements.define(n,t)}var ht=new Map;function B(n,t,e){ht.set(t,{element:n,read:e})}function Nt(){for(let[n,t]of[...ht]){if(!t.element.isConnected){ht.delete(n);continue}let e;try{e=t.read()}catch{continue}M(n,e)}}function T(n){let t=n.querySelector('script[type="application/json"]');if(t===null)return{status:"invalid",reason:"slot has no application/json config"};let e=t.textContent??"";if(e.trim()==="")return{status:"invalid",reason:"slot config is empty"};let r;try{r=JSON.parse(e)}catch(o){return{status:"invalid",reason:`slot config is not valid JSON: ${o instanceof Error&&o.message!==""?o.message:"invalid JSON"}`}}return typeof r!="object"||r===null||Array.isArray(r)?{status:"invalid",reason:"slot config must be a JSON object"}:{status:"ok",config:r}}function D(n){let t=n.getAttribute("slot-id")?.trim();return t===void 0||t===""?void 0:t}var ve='<svg viewBox="0 0 16 16" aria-hidden="true" focusable="false"><path d="M2.5 3.5h11v7h-6l-3 2.5v-2.5h-2z"/><path d="M8 5.5v3M6.5 7h3"/></svg>',fe='<svg viewBox="0 0 16 16" aria-hidden="true" focusable="false"><path d="M2.5 3.5h11v7h-6l-3 2.5v-2.5h-2z"/><path d="M5 6.25h6M5 8.25h4"/></svg>',jt=`
2
130
  :host {
3
131
  display: block;
4
132
  }
5
133
 
6
134
  [part="container"] {
7
135
  display: grid;
8
- gap: var(--crtr-space-3);
136
+ gap: var(--crtr-options-container-gap, var(--crtr-space-3));
137
+ }
138
+
139
+ /* The question reads as the agent's own prose above its control, matching the table's
140
+ caption rather than shouting over the options it introduces. */
141
+ [part="label"] {
142
+ margin: var(--crtr-options-label-margin, 0);
143
+ color: var(--crtr-options-label-text-color, var(--crtr-color-text-muted));
9
144
  }
10
145
 
11
146
  [part="list"] {
12
147
  display: grid;
13
- gap: var(--crtr-space-2);
148
+ gap: var(--crtr-options-list-gap, var(--crtr-space-2));
14
149
  }
15
150
 
16
151
  [part="option"] {
17
152
  position: relative;
18
153
  display: flex;
19
154
  align-items: flex-start;
20
- gap: var(--crtr-space-3);
21
- padding: var(--crtr-space-2) var(--crtr-space-3);
22
- background: var(--crtr-color-surface);
23
- border: 1px solid var(--crtr-color-border);
24
- border-radius: var(--crtr-radius-medium);
25
- transition: background-color 120ms ease, border-color 120ms ease;
155
+ gap: var(--crtr-options-option-gap, var(--crtr-space-3));
156
+ padding: var(--crtr-options-option-padding, var(--crtr-space-2) var(--crtr-space-3));
157
+ background: var(--crtr-options-option-fill, var(--crtr-color-surface));
158
+ border: var(--crtr-options-option-border-width, 1px)
159
+ var(--crtr-options-option-border-style, solid)
160
+ var(--crtr-options-option-border-color, var(--crtr-color-border));
161
+ border-radius: var(--crtr-options-option-radius, var(--crtr-radius-medium));
162
+ transition: background-color var(--crtr-options-option-transition, 120ms ease),
163
+ border-color var(--crtr-options-option-transition, 120ms ease);
26
164
  }
27
165
 
28
166
  [part="option"]:hover,
29
167
  [part="option"][data-active="true"] {
30
- background: var(--crtr-color-surface-hover);
168
+ background: var(--crtr-options-option-hover-fill, var(--crtr-color-surface-hover));
31
169
  }
32
170
 
33
171
  [part="option"][data-selected="true"] {
34
- border-color: var(--crtr-color-accent);
35
- background: color-mix(in srgb, var(--crtr-color-accent) 10%, var(--crtr-color-surface));
172
+ border-color: var(
173
+ --crtr-options-option-selected-border-color,
174
+ color-mix(in srgb, var(--crtr-color-accent) 45%, transparent)
175
+ );
176
+ background: var(
177
+ --crtr-options-option-selected-fill,
178
+ color-mix(in srgb, var(--crtr-color-accent) 10%, transparent)
179
+ );
180
+ }
181
+
182
+ [part="option"][data-selected="true"]:hover,
183
+ [part="option"][data-selected="true"][data-active="true"] {
184
+ background: var(
185
+ --crtr-options-option-selected-hover-fill,
186
+ color-mix(in srgb, var(--crtr-color-accent) 14%, transparent)
187
+ );
188
+ }
189
+
190
+ /* A page that can no longer take an answer keeps its selection legible and drops every
191
+ affordance that says it could still be changed. */
192
+ [part="option"]:has([part="option-control"]:disabled) [part="option-label"] {
193
+ cursor: default;
36
194
  }
37
195
 
38
196
  [part="option-label"] {
39
197
  display: flex;
40
198
  flex: 1;
41
199
  align-items: flex-start;
42
- gap: var(--crtr-space-3);
200
+ gap: var(--crtr-options-option-label-gap, var(--crtr-space-3));
43
201
  cursor: pointer;
44
202
  }
45
203
 
46
- [part="option-control"] {
47
- margin: 0;
48
- margin-top: 0.15em;
49
- accent-color: var(--crtr-color-accent);
50
- }
204
+ ${F({scope:"options-option-control"},'[part="option-control"]')}
51
205
 
52
- [part="option-control"]:focus-visible {
53
- outline: 2px solid var(--crtr-color-focus);
54
- outline-offset: 2px;
206
+ /* Centred on the first line of the label rather than on its box, so a two-line option keeps
207
+ the control beside the title. Half the difference between a 1.5 line box and the control. */
208
+ [part="option-control"] {
209
+ margin-top: var(--crtr-options-option-control-offset, 0.1875em);
55
210
  }
56
211
 
57
212
  [part="option-text"] {
58
213
  display: grid;
59
- gap: var(--crtr-space-1);
214
+ gap: var(--crtr-options-option-text-gap, var(--crtr-space-1));
60
215
  }
61
216
 
62
217
  [part="option-title"] {
63
- font-weight: 500;
218
+ font-weight: var(--crtr-options-option-title-font-weight, 500);
64
219
  }
65
220
 
66
221
  [part="option-description"] {
67
- color: var(--crtr-color-text-muted);
68
- font-size: 0.9em;
222
+ color: var(--crtr-options-option-description-text-color, var(--crtr-color-text-muted));
223
+ font-size: var(--crtr-options-option-description-font-size, 0.875em);
69
224
  }
70
225
 
226
+ /* The trigger stays in the row's anatomy while quiet, then its state rule below reveals it.
227
+ A host can choose how quiet and how bright those states are independently; the transition
228
+ remains one knob because all three properties are one reveal. */
71
229
  [part="comment"] {
72
230
  display: inline-flex;
73
231
  align-items: center;
74
232
  justify-content: center;
75
233
  flex: none;
76
- width: 1.5rem;
77
- height: 1.5rem;
78
- padding: 0;
79
- color: var(--crtr-color-text-muted);
80
- background: transparent;
81
- border: 1px solid transparent;
82
- border-radius: var(--crtr-radius-small);
83
- opacity: 0;
234
+ width: var(--crtr-options-comment-size, 1.5em);
235
+ height: var(--crtr-options-comment-size, 1.5em);
236
+ padding: var(--crtr-options-comment-padding, 0);
237
+ color: var(--crtr-options-comment-text-color, var(--crtr-color-text-muted));
238
+ background: var(--crtr-options-comment-fill, transparent);
239
+ border: var(--crtr-options-comment-border-width, 1px)
240
+ var(--crtr-options-comment-border-style, solid)
241
+ var(--crtr-options-comment-border-color, transparent);
242
+ border-radius: var(--crtr-options-comment-radius, var(--crtr-radius-small));
243
+ opacity: var(--crtr-options-comment-opacity, 0);
84
244
  cursor: pointer;
85
- transition: opacity 120ms ease, color 120ms ease, background-color 120ms ease;
245
+ transition: opacity var(--crtr-options-comment-transition, var(--crtr-control-transition, 120ms ease)),
246
+ color var(--crtr-options-comment-transition, var(--crtr-control-transition, 120ms ease)),
247
+ background-color var(--crtr-options-comment-transition, var(--crtr-control-transition, 120ms ease));
86
248
  }
87
249
 
88
250
  [part="option"]:hover [part="comment"],
@@ -90,158 +252,164 @@
90
252
  [part="option"]:focus-within [part="comment"],
91
253
  [part="comment"][data-state="commented"],
92
254
  [part="comment"][aria-expanded="true"] {
93
- opacity: 1;
255
+ opacity: var(--crtr-options-comment-visible-opacity, 1);
94
256
  }
95
257
 
96
258
  [part="comment"]:hover {
97
- background: var(--crtr-color-surface-hover);
98
- border-color: var(--crtr-color-border);
99
- }
100
-
101
- [part="comment"]:focus-visible {
102
- outline: 2px solid var(--crtr-color-focus);
103
- outline-offset: 1px;
259
+ background: var(--crtr-options-comment-hover-fill, var(--crtr-color-surface-hover));
260
+ border-color: var(--crtr-options-comment-hover-border-color, var(--crtr-color-border));
104
261
  }
105
262
 
263
+ ${u({scope:"options-comment"},'[part="comment"]')}
106
264
  [part="comment"][data-state="commented"] {
107
- color: var(--crtr-color-accent);
265
+ color: var(--crtr-options-comment-commented-text-color, var(--crtr-color-accent));
108
266
  }
109
267
 
110
268
  [part="comment"] svg {
111
- width: 0.9rem;
112
- height: 0.9rem;
113
- fill: none;
114
- stroke: currentColor;
115
- stroke-width: 1.25;
116
- stroke-linecap: round;
117
- stroke-linejoin: round;
269
+ width: var(--crtr-options-comment-icon-size, 0.875em);
270
+ height: var(--crtr-options-comment-icon-size, 0.875em);
271
+ fill: var(--crtr-options-comment-icon-fill, none);
272
+ stroke: var(--crtr-options-comment-icon-stroke-color, currentColor);
273
+ stroke-width: var(--crtr-options-comment-icon-stroke-width, 1.25);
274
+ stroke-linecap: var(--crtr-options-comment-icon-stroke-cap, round);
275
+ stroke-linejoin: var(--crtr-options-comment-icon-stroke-join, round);
118
276
  }
119
277
 
120
278
  [part="comment-popover"] {
121
279
  position: absolute;
122
- top: calc(100% + var(--crtr-space-1));
280
+ top: calc(100% + var(--crtr-options-comment-popover-offset, var(--crtr-space-1)));
123
281
  right: 0;
124
282
  z-index: 2;
125
283
  display: grid;
126
- gap: var(--crtr-space-2);
127
- width: min(20rem, 100%);
128
- padding: var(--crtr-space-3);
129
- background: var(--crtr-color-background);
130
- border: 1px solid var(--crtr-color-border);
131
- border-radius: var(--crtr-radius-medium);
132
- box-shadow: var(--crtr-shadow);
284
+ gap: var(--crtr-options-comment-popover-gap, var(--crtr-space-2));
285
+ width: var(--crtr-options-comment-popover-width, min(20em, 100%));
286
+ padding: var(--crtr-options-comment-popover-padding, var(--crtr-space-3));
287
+ background: var(--crtr-options-comment-popover-fill, var(--crtr-color-background));
288
+ border: var(--crtr-options-comment-popover-border-width, 1px)
289
+ var(--crtr-options-comment-popover-border-style, solid)
290
+ var(--crtr-options-comment-popover-border-color, var(--crtr-color-border));
291
+ border-radius: var(--crtr-options-comment-popover-radius, var(--crtr-radius-medium));
292
+ box-shadow: var(--crtr-options-comment-popover-shadow, var(--crtr-shadow));
133
293
  }
134
294
 
135
295
  [part="comment-popover"][hidden] {
136
296
  display: none;
137
297
  }
138
298
 
299
+ /* The popover's own prose, in the page's voice \u2014 not a caps-mono field label shouting an
300
+ option id at someone who just clicked that option. */
139
301
  [part="comment-subject"] {
140
- margin: 0;
141
- color: var(--crtr-color-text-muted);
142
- font-family: var(--crtr-font-mono);
143
- font-size: 0.75em;
144
- letter-spacing: 0.06em;
145
- text-transform: uppercase;
146
- }
147
-
148
- [part="comment-input"],
149
- [part="freetext-input"] {
150
- width: 100%;
151
- box-sizing: border-box;
152
- padding: var(--crtr-space-2);
153
- color: var(--crtr-color-text);
154
- font: inherit;
155
- background: var(--crtr-color-surface);
156
- border: 1px solid var(--crtr-color-border);
157
- border-radius: var(--crtr-radius-small);
158
- resize: vertical;
302
+ margin: var(--crtr-options-comment-subject-margin, 0);
303
+ color: var(--crtr-options-comment-subject-text-color, var(--crtr-color-text-muted));
304
+ font-size: var(--crtr-options-comment-subject-font-size, 0.875em);
159
305
  }
160
306
 
307
+ /* Two calls rather than one selector list: a comment box and the freetext box are two things
308
+ a person can point at, so each takes its own scope. They still share the family layer
309
+ underneath, so they cannot drift apart unless a host parts them on purpose. */
310
+ ${S({scope:"options-comment-input"},'[part="comment-input"]')}
311
+ ${S({scope:"options-freetext-input"},'[part="freetext-input"]')}
161
312
  [part="comment-input"] {
162
- min-height: 4.5rem;
313
+ min-height: var(--crtr-options-comment-input-min-height, 4.5em);
314
+ resize: vertical;
163
315
  }
164
316
 
165
317
  [part="freetext-input"] {
166
- min-height: 4rem;
167
- }
168
-
169
- [part="comment-input"]:focus-visible,
170
- [part="freetext-input"]:focus-visible {
171
- outline: 2px solid var(--crtr-color-focus);
172
- outline-offset: -1px;
318
+ min-height: var(--crtr-options-freetext-input-min-height, 4em);
319
+ resize: vertical;
173
320
  }
174
321
 
175
322
  [part="comment-actions"] {
176
323
  display: flex;
177
324
  align-items: center;
178
325
  justify-content: space-between;
179
- gap: var(--crtr-space-2);
326
+ gap: var(--crtr-options-comment-actions-gap, var(--crtr-space-2));
180
327
  }
181
328
 
182
329
  [part="comment-hint"] {
183
- color: var(--crtr-color-text-muted);
184
- font-family: var(--crtr-font-mono);
185
- font-size: 0.75em;
186
- letter-spacing: 0.06em;
187
- text-transform: uppercase;
188
- }
189
-
190
- [part="comment-cancel"],
191
- [part="comment-save"] {
192
- padding: var(--crtr-space-1) var(--crtr-space-2);
193
- font: inherit;
194
- font-size: 0.9em;
195
- border-radius: var(--crtr-radius-small);
196
- cursor: pointer;
330
+ color: var(--crtr-options-comment-hint-text-color, var(--crtr-color-text-muted));
331
+ font-size: var(--crtr-options-comment-hint-font-size, 0.875em);
197
332
  }
198
333
 
334
+ /* The two buttons are one shape drawn twice rather than one rule serving two parts, because
335
+ a scope that named both would make "the cancel button's fill" unsayable. */
199
336
  [part="comment-cancel"] {
200
- color: var(--crtr-color-text-muted);
201
- background: transparent;
202
- border: 1px solid transparent;
337
+ padding: var(--crtr-options-comment-cancel-padding, var(--crtr-space-1) var(--crtr-space-2));
338
+ font: var(--crtr-options-comment-cancel-font, inherit);
339
+ font-size: var(--crtr-options-comment-cancel-font-size, 0.875em);
340
+ color: var(--crtr-options-comment-cancel-text-color, var(--crtr-color-text-muted));
341
+ background: var(--crtr-options-comment-cancel-fill, transparent);
342
+ border: var(--crtr-options-comment-cancel-border-width, 1px)
343
+ var(--crtr-options-comment-cancel-border-style, solid)
344
+ var(--crtr-options-comment-cancel-border-color, transparent);
345
+ border-radius: var(--crtr-options-comment-cancel-radius, var(--crtr-radius-small));
346
+ cursor: pointer;
347
+ transition: color var(--crtr-options-comment-cancel-transition, var(--crtr-control-transition, 120ms ease)),
348
+ background-color var(--crtr-options-comment-cancel-transition, var(--crtr-control-transition, 120ms ease)),
349
+ border-color var(--crtr-options-comment-cancel-transition, var(--crtr-control-transition, 120ms ease));
203
350
  }
204
351
 
205
352
  [part="comment-cancel"]:hover {
206
- color: var(--crtr-color-text);
207
- background: var(--crtr-color-surface-hover);
353
+ color: var(--crtr-options-comment-cancel-hover-text-color, var(--crtr-color-text));
354
+ background: var(--crtr-options-comment-cancel-hover-fill, var(--crtr-color-surface-hover));
208
355
  }
209
356
 
210
357
  [part="comment-save"] {
211
- color: var(--crtr-color-accent-contrast);
212
- background: var(--crtr-color-accent);
213
- border: 1px solid var(--crtr-color-accent);
214
- }
215
-
216
- [part="comment-cancel"]:focus-visible,
217
- [part="comment-save"]:focus-visible {
218
- outline: 2px solid var(--crtr-color-focus);
219
- outline-offset: 1px;
220
- }
221
-
358
+ padding: var(--crtr-options-comment-save-padding, var(--crtr-space-1) var(--crtr-space-2));
359
+ font: var(--crtr-options-comment-save-font, inherit);
360
+ font-size: var(--crtr-options-comment-save-font-size, 0.875em);
361
+ color: var(--crtr-options-comment-save-text-color, var(--crtr-color-accent-contrast));
362
+ background: var(--crtr-options-comment-save-fill, var(--crtr-color-accent));
363
+ border: var(--crtr-options-comment-save-border-width, 1px)
364
+ var(--crtr-options-comment-save-border-style, solid)
365
+ var(--crtr-options-comment-save-border-color, var(--crtr-color-accent));
366
+ border-radius: var(--crtr-options-comment-save-radius, var(--crtr-radius-small));
367
+ cursor: pointer;
368
+ transition: color var(--crtr-options-comment-save-transition, var(--crtr-control-transition, 120ms ease)),
369
+ background-color var(--crtr-options-comment-save-transition, var(--crtr-control-transition, 120ms ease)),
370
+ border-color var(--crtr-options-comment-save-transition, var(--crtr-control-transition, 120ms ease));
371
+ }
372
+
373
+ /* Mixing the accent toward the text colour darkens on a light token set and lightens on a
374
+ dark one \u2014 a brightness filter moves the wrong way on one of them. */
375
+ [part="comment-save"]:hover {
376
+ background: var(
377
+ --crtr-options-comment-save-hover-fill,
378
+ color-mix(in srgb, var(--crtr-color-accent) 88%, var(--crtr-color-text))
379
+ );
380
+ border-color: var(
381
+ --crtr-options-comment-save-hover-border-color,
382
+ color-mix(in srgb, var(--crtr-color-accent) 88%, var(--crtr-color-text))
383
+ );
384
+ }
385
+
386
+ ${u({scope:"options-comment-cancel"},'[part="comment-cancel"]')}
387
+ ${u({scope:"options-comment-save"},'[part="comment-save"]')}
222
388
  [part="freetext"] {
223
389
  display: grid;
224
- gap: var(--crtr-space-1);
390
+ gap: var(--crtr-options-freetext-gap, var(--crtr-space-1));
225
391
  }
226
392
 
227
393
  [part="freetext-label"] {
228
- color: var(--crtr-color-text-muted);
229
- font-size: 0.85em;
394
+ color: var(--crtr-options-freetext-label-text-color, var(--crtr-color-text-muted));
395
+ font-size: var(--crtr-options-freetext-label-font-size, 0.875em);
230
396
  }
231
397
 
232
398
  [part="unavailable"] {
233
- padding: var(--crtr-space-3);
234
- color: var(--crtr-color-text-muted);
235
- background: var(--crtr-color-surface);
236
- border: 1px solid var(--crtr-color-border);
237
- border-radius: var(--crtr-radius-medium);
399
+ padding: var(--crtr-options-unavailable-padding, var(--crtr-space-3));
400
+ color: var(--crtr-options-unavailable-text-color, var(--crtr-color-text-muted));
401
+ background: var(--crtr-options-unavailable-fill, var(--crtr-color-surface));
402
+ border: var(--crtr-options-unavailable-border-width, 1px)
403
+ var(--crtr-options-unavailable-border-style, solid)
404
+ var(--crtr-options-unavailable-border-color, var(--crtr-color-border));
405
+ border-radius: var(--crtr-options-unavailable-radius, var(--crtr-radius-medium));
238
406
  }
239
407
 
240
408
  [part="reason"] {
241
- color: var(--crtr-color-text);
242
- font-family: var(--crtr-font-mono);
409
+ color: var(--crtr-options-reason-text-color, var(--crtr-color-text));
410
+ font-family: var(--crtr-options-reason-font-family, var(--crtr-font-mono));
243
411
  }
244
- `,wt=0;function qt(o){return o instanceof HTMLTextAreaElement||o instanceof HTMLElement&&o.isContentEditable?!0:o instanceof HTMLInputElement?o.type!=="checkbox"&&o.type!=="radio":!1}var it=class extends HTMLElement{#n;#d;#s;#t=new Map;#r=[];#e=[];#o=[];#l;#c;#a;#u=!1;constructor(){super(),this.#n=this.attachShadow({mode:"open"})}connectedCallback(){if(this.#u)return;this.#u=!0,this.#s=N(this);let t=k(this);if(t.status!=="ok"){this.#h(t.reason);return}let e=t.config;if(!Array.isArray(e.options)||e.options.length===0){this.#h("options config lists no options");return}this.#d=e,this.#r=e.options.map(r=>r.id),this.#i(e),this.#x(e),this.#E()}disconnectedCallback(){document.removeEventListener("pointerdown",this.#m,!0)}#i(t){if(this.#s===void 0)return;let e=I(this.#s);if(e===void 0)return;let r=B(e.selectedOptionIds);this.#e=this.#r.filter(n=>r.includes(n)),t.mode==="single"&&(this.#e=this.#e.slice(0,1)),this.#o=H(e.comments).filter(n=>n.anchor.kind!=="option"||this.#r.includes(n.anchor.optionId)),t.allowFreetext===!0&&typeof e.freetext=="string"&&e.freetext!==""&&(this.#l=e.freetext)}#h(t){let e=document.createElement("style");e.textContent=Et;let r=document.createElement("div");r.part.add("unavailable"),r.setAttribute("role","status");let n=document.createElement("span");n.part.add("reason"),n.textContent=t,r.append("Options unavailable: ",n),this.#n.replaceChildren(e,r)}#x(t){let e=document.createElement("style");e.textContent=Et;let r=document.createElement("div");r.part.add("container");let n=document.createElement("div");n.part.add("list"),t.mode==="single"&&n.setAttribute("role","radiogroup"),wt+=1;let i=`crtr-options-${wt}`;for(let a of t.options)n.append(this.#p(t,a,i));r.append(n),t.allowFreetext===!0&&r.append(this.#g(t)),r.addEventListener("keydown",a=>this.#w(a)),this.#n.replaceChildren(e,r)}#p(t,e,r){let n=document.createElement("div");n.part.add("option"),n.dataset.optionId=e.id;let i=document.createElement("label");i.part.add("option-label");let a=document.createElement("input");a.part.add("option-control"),a.type=t.mode==="single"?"radio":"checkbox",a.name=r,a.value=e.id,a.addEventListener("change",()=>this.#k(e.id,a.checked)),a.addEventListener("focus",()=>this.#y(e.id));let s=document.createElement("span");s.part.add("option-text");let c=document.createElement("span");if(c.part.add("option-title"),c.textContent=e.label,s.append(c),e.description!==void 0&&e.description!==""){let y=document.createElement("span");y.part.add("option-description"),y.textContent=e.description,s.append(y)}i.append(a,s);let d=document.createElement("button");d.part.add("comment"),d.type="button",d.setAttribute("aria-haspopup","dialog"),d.addEventListener("click",()=>{this.#a===e.id?this.#f():this.#A(e.id)});let u=document.createElement("div");u.part.add("comment-popover"),u.setAttribute("role","dialog"),u.hidden=!0;let g=document.createElement("p");g.part.add("comment-subject"),g.textContent=`Comment on ${e.label}`,u.setAttribute("aria-label",g.textContent);let m=document.createElement("textarea");m.part.add("comment-input"),m.placeholder="What should the agent know about this?",m.addEventListener("keydown",y=>{if(y.key==="Enter"&&(y.metaKey||y.ctrlKey)){y.preventDefault(),this.#T(e.id);return}y.key==="Escape"&&(y.preventDefault(),this.#f())});let V=document.createElement("div");V.part.add("comment-actions");let P=document.createElement("span");P.part.add("comment-hint");let A=document.createElement("span"),T=document.createElement("button");T.part.add("comment-cancel"),T.type="button",T.textContent="Cancel",T.addEventListener("click",()=>this.#f());let M=document.createElement("button");return M.part.add("comment-save"),M.type="button",M.textContent="Save",M.addEventListener("click",()=>this.#T(e.id)),A.append(T,M),V.append(P,A),u.append(g,m,V),n.append(i,d,u),n.addEventListener("mouseenter",()=>this.#y(e.id)),n.addEventListener("mouseleave",()=>this.#v(e.id)),this.#t.set(e.id,{id:e.id,label:e.label,root:n,control:a,comment:d,popover:u,input:m,hint:P}),n}#g(t){let e=document.createElement("label");e.part.add("freetext");let r=document.createElement("span");r.part.add("freetext-label"),r.textContent=t.freetextLabel??"Something else";let n=document.createElement("textarea");return n.part.add("freetext-input"),n.placeholder=t.freetextPlaceholder??"Answer in your own words\u2026",this.#l!==void 0&&(n.value=this.#l),n.addEventListener("input",()=>{this.#l=n.value===""?void 0:n.value,this.#b()}),e.append(r,n),e}#w(t){if(t.metaKey||t.ctrlKey||t.altKey||qt(t.target))return;let e=t.key.toLowerCase(),r=this.#c??this.#e.at(-1)??this.#r[0];if(r!==void 0){if(e==="j"||e==="k"){t.preventDefault();let n=Math.max(0,this.#r.indexOf(r)),i=e==="j"?1:-1,a=this.#r[(n+i+this.#r.length)%this.#r.length];this.#y(a),this.#t.get(a)?.control.focus();return}if(e==="x"){t.preventDefault();let n=this.#e.includes(r);this.#k(r,this.#d?.mode==="single"?!0:!n);return}e==="c"&&(t.preventDefault(),this.#A(r))}}#y(t){this.#c!==t&&(this.#c=t,this.#E())}#v(t){this.#c===t&&(this.#c=void 0,this.#E())}#k(t,e){if(this.#d!==void 0){if(this.#d.mode==="single")this.#e=[t];else{let r=e?[...this.#e,t]:this.#e.filter(n=>n!==t);this.#e=this.#r.filter(n=>r.includes(n))}this.#y(t),this.#E(),this.#b()}}#m=t=>{if(this.#a===void 0)return;let e=this.#t.get(this.#a);if(e===void 0)return;let r=t.composedPath();r.includes(e.popover)||r.includes(e.comment)||this.#f(!1)};#A(t){let e=this.#t.get(t);e!==void 0&&(this.#a===void 0&&document.addEventListener("pointerdown",this.#m,!0),this.#a=t,this.#c=t,e.input.value=b(this.#o,ot(t))?.text??"",this.#E(),e.input.focus())}#f(t=!0){if(this.#a===void 0)return;let e=this.#t.get(this.#a);this.#a=void 0,document.removeEventListener("pointerdown",this.#m,!0),this.#E(),t&&e?.comment.focus()}#T(t){let e=this.#t.get(t);e!==void 0&&(this.#o=R(this.#o,ot(t),e.input.value),this.#f(),this.#b())}#E(){for(let t of this.#t.values()){let e=this.#e.includes(t.id);t.control.checked=e,t.root.dataset.selected=String(e),t.root.dataset.active=String(this.#c===t.id);let r=b(this.#o,ot(t.id));t.comment.dataset.state=r===void 0?"empty":"commented",t.comment.innerHTML=r===void 0?Ft:Wt,t.comment.setAttribute("aria-label",r===void 0?`Comment on ${t.label}`:`Edit comment on ${t.label}`);let n=this.#a===t.id;t.comment.setAttribute("aria-expanded",String(n)),t.popover.hidden=!n,t.hint.textContent=r===void 0?"\u2318\u21B5 to save":"empty to delete"}}#b(){if(this.#s===void 0)return;let t={selectedOptionIds:[...this.#e],comments:this.#o.map(e=>({...e}))};this.#d?.allowFreetext===!0&&this.#l!==void 0&&(t.freetext=this.#l),$(this.#s,t)}};function ot(o){return{kind:"option",optionId:o}}v("crtr-options",it);var at={kind:"whole"},F="the whole passage",Y="the selected text",Vt=6,St="comment-popover",Ut=`
412
+ `,Bt="prompt-label",Dt=0;function ge(n){return n instanceof HTMLTextAreaElement||n instanceof HTMLElement&&n.isContentEditable?!0:n instanceof HTMLInputElement?n.type!=="checkbox"&&n.type!=="radio":!1}var pt=class extends HTMLElement{static observedAttributes=["inert"];#o;#i;#a;#n=new Map;#e=[];#r=[];#t=[];#h;#c;#s;#l=!1;constructor(){super(),this.#o=this.attachShadow({mode:"open"})}connectedCallback(){if(this.#l)return;this.#l=!0,this.#a=D(this);let t=T(this);if(t.status!=="ok"){this.#m(t.reason);return}let e=t.config;if(!Array.isArray(e.options)||e.options.length===0){this.#m("options config lists no options");return}this.#i=e,this.#e=e.options.map(r=>r.id),this.#u(e),this.#a!==void 0&&B(this,this.#a,()=>this.#x()),this.#E(e),this.#v()}disconnectedCallback(){document.removeEventListener("pointerdown",this.#f,!0)}attributeChangedCallback(){this.isConnected&&this.#d()}#d(){let t=f(this);j(this.#o,t),t&&this.#s!==void 0&&this.#w(!1)}#u(t){if(this.#a===void 0)return;let e=N(this.#a);if(e===void 0)return;let r=q(e.selectedOptionIds);this.#r=this.#e.filter(o=>r.includes(o)),t.mode==="single"&&(this.#r=this.#r.slice(0,1)),this.#t=O(e.comments).filter(o=>o.anchor.kind!=="option"||this.#e.includes(o.anchor.optionId)),t.allowFreetext===!0&&typeof e.freetext=="string"&&e.freetext!==""&&(this.#h=e.freetext)}#m(t){let e=document.createElement("style");e.textContent=jt;let r=document.createElement("div");r.part.add("unavailable"),r.setAttribute("role","status");let o=document.createElement("span");o.part.add("reason"),o.textContent=t,r.append("Options unavailable: ",o),this.#o.replaceChildren(e,r)}#E(t){let e=document.createElement("style");e.textContent=jt;let r=document.createElement("div");r.part.add("container");let o=t.label!==void 0&&t.label!=="";if(o){let s=document.createElement("p");s.part.add("label"),s.id=Bt,s.textContent=t.label??"",r.append(s)}let a=document.createElement("div");a.part.add("list"),t.mode==="single"?a.setAttribute("role","radiogroup"):o&&a.setAttribute("role","group"),o&&a.setAttribute("aria-labelledby",Bt),Dt+=1;let i=`crtr-options-${Dt}`;for(let s of t.options)a.append(this.#L(t,s,i));r.append(a),t.allowFreetext===!0&&r.append(this.#p(t)),r.addEventListener("keydown",s=>this.#T(s)),this.#o.replaceChildren(e,r)}#L(t,e,r){let o=document.createElement("div");o.part.add("option"),o.dataset.optionId=e.id;let a=document.createElement("label");a.part.add("option-label");let i=document.createElement("input");i.part.add("option-control"),i.type=t.mode==="single"?"radio":"checkbox",i.name=r,i.value=e.id,i.addEventListener("change",()=>this.#S(e.id,i.checked)),i.addEventListener("focus",()=>this.#b(e.id));let s=document.createElement("span");s.part.add("option-text");let c=document.createElement("span");if(c.part.add("option-title"),c.textContent=e.label,s.append(c),e.description!==void 0&&e.description!==""){let h=document.createElement("span");h.part.add("option-description"),h.textContent=e.description,s.append(h)}a.append(i,s);let l=L(this.#a)?this.#g(e):void 0;return o.append(a),l!==void 0&&o.append(l.trigger,l.popover),o.addEventListener("mouseenter",()=>this.#b(e.id)),o.addEventListener("mouseleave",()=>this.#y(e.id)),this.#n.set(e.id,{id:e.id,label:e.label,root:o,control:i,...l===void 0?{}:{comment:l}}),o}#g(t){let e=document.createElement("button");e.part.add("comment"),e.type="button",e.setAttribute("aria-haspopup","dialog"),e.addEventListener("click",()=>{this.#s===t.id?this.#w():this.#A(t.id)});let r=document.createElement("div");r.part.add("comment-popover"),r.setAttribute("role","dialog"),r.hidden=!0;let o=document.createElement("p");o.part.add("comment-subject"),o.textContent=`Comment on ${t.label}`,r.setAttribute("aria-label",o.textContent);let a=document.createElement("textarea");a.part.add("comment-input"),a.placeholder="What should the agent know about this?",a.addEventListener("keydown",g=>{if(g.key==="Enter"&&(g.metaKey||g.ctrlKey)){g.preventDefault(),this.#C(t.id);return}g.key==="Escape"&&(g.preventDefault(),this.#w())});let i=document.createElement("div");i.part.add("comment-actions");let s=document.createElement("span");s.part.add("comment-hint");let c=document.createElement("span"),l=document.createElement("button");l.part.add("comment-cancel"),l.type="button",l.textContent="Cancel",l.addEventListener("click",()=>this.#w());let h=document.createElement("button");return h.part.add("comment-save"),h.type="button",h.textContent="Save",h.addEventListener("click",()=>this.#C(t.id)),c.append(l,h),i.append(s,c),r.append(o,a,i),{trigger:e,popover:r,input:a,hint:s}}#p(t){let e=document.createElement("label");e.part.add("freetext");let r=document.createElement("span");r.part.add("freetext-label"),r.textContent=t.freetextLabel??"Something else";let o=document.createElement("textarea");return o.part.add("freetext-input"),o.placeholder=t.freetextPlaceholder??"Answer in your own words\u2026",this.#h!==void 0&&(o.value=this.#h),o.addEventListener("input",()=>{this.#h=o.value===""?void 0:o.value,this.#k()}),e.append(r,o),e}#T(t){if(t.metaKey||t.ctrlKey||t.altKey||ge(t.target))return;let e=t.key.toLowerCase(),r=this.#c??this.#r.at(-1)??this.#e[0];if(r!==void 0){if(e==="j"||e==="k"){t.preventDefault();let o=Math.max(0,this.#e.indexOf(r)),a=e==="j"?1:-1,i=this.#e[(o+a+this.#e.length)%this.#e.length];this.#b(i),this.#n.get(i)?.control.focus();return}if(e==="x"){t.preventDefault();let o=this.#r.includes(r);this.#S(r,this.#i?.mode==="single"?!0:!o);return}e==="c"&&(t.preventDefault(),this.#A(r))}}#b(t){this.#c!==t&&(this.#c=t,this.#v())}#y(t){this.#c===t&&(this.#c=void 0,this.#v())}#S(t,e){if(!(this.#i===void 0||f(this))){if(this.#i.mode==="single")this.#r=[t];else{let r=e?[...this.#r,t]:this.#r.filter(o=>o!==t);this.#r=this.#e.filter(o=>r.includes(o))}this.#b(t),this.#v(),this.#k()}}#f=t=>{if(this.#s===void 0)return;let e=this.#n.get(this.#s)?.comment;if(e===void 0)return;let r=t.composedPath();r.includes(e.popover)||r.includes(e.trigger)||this.#w(!1)};#A(t){let e=this.#n.get(t)?.comment;e===void 0||f(this)||(this.#s===void 0&&document.addEventListener("pointerdown",this.#f,!0),this.#s=t,this.#c=t,e.input.value=y(this.#t,mt(t))?.text??"",this.#v(),e.input.focus())}#w(t=!0){if(this.#s===void 0)return;let e=this.#n.get(this.#s)?.comment;this.#s=void 0,document.removeEventListener("pointerdown",this.#f,!0),this.#v(),t&&e?.trigger.focus()}#C(t){let e=this.#n.get(t)?.comment;e===void 0||f(this)||(this.#t=z(this.#t,mt(t),e.input.value),this.#w(),this.#k())}#v(){for(let t of this.#n.values()){let e=this.#r.includes(t.id);t.control.checked=e,t.root.dataset.selected=String(e),t.root.dataset.active=String(this.#c===t.id);let r=t.comment;if(r===void 0)continue;let o=y(this.#t,mt(t.id));r.trigger.dataset.state=o===void 0?"empty":"commented",r.trigger.innerHTML=o===void 0?ve:fe,r.trigger.setAttribute("aria-label",o===void 0?`Comment on ${t.label}`:`Edit comment on ${t.label}`);let a=this.#s===t.id;r.trigger.setAttribute("aria-expanded",String(a)),r.popover.hidden=!a,r.hint.textContent=o===void 0?"\u2318\u21B5 to save":"empty to delete"}this.#d()}#x(){let t={selectedOptionIds:[...this.#r],comments:this.#t.map(e=>({...e}))};return this.#i?.allowFreetext===!0&&this.#h!==void 0&&(t.freetext=this.#h),t}#k(){this.#a!==void 0&&M(this.#a,this.#x())}};function mt(n){return{kind:"option",optionId:n}}w("crtr-options",pt);var ut={kind:"whole"},U="the whole passage",J="the selected text",rt=6,Ft="comment-popover",Pt="prompt-label",be=`
245
413
  :host {
246
414
  display: block;
247
415
  }
@@ -249,7 +417,14 @@
249
417
  [part="container"] {
250
418
  position: relative;
251
419
  display: grid;
252
- gap: var(--crtr-space-2);
420
+ gap: var(--crtr-text-container-gap, var(--crtr-space-2));
421
+ }
422
+
423
+ /* The prompt reads as the agent's own prose above the passage, matching the table's
424
+ caption rather than shouting over the text it introduces. */
425
+ [part="label"] {
426
+ margin: var(--crtr-text-label-margin, 0);
427
+ color: var(--crtr-text-label-text-color, var(--crtr-color-text-muted));
253
428
  }
254
429
 
255
430
  [part="toolbar"] {
@@ -257,134 +432,178 @@
257
432
  flex-wrap: wrap;
258
433
  align-items: center;
259
434
  justify-content: flex-end;
260
- gap: var(--crtr-space-2);
435
+ gap: var(--crtr-text-toolbar-gap, var(--crtr-space-2));
261
436
  }
262
437
 
263
438
  [part="edited"] {
264
- padding: 0 var(--crtr-space-2);
265
- color: var(--crtr-color-accent);
266
- background: color-mix(in srgb, var(--crtr-color-accent) 14%, transparent);
267
- border-radius: var(--crtr-radius-small);
268
- font-family: var(--crtr-font-mono);
269
- font-size: 0.6875rem;
270
- letter-spacing: 0.06em;
271
- line-height: 1.7;
272
- text-transform: uppercase;
439
+ padding: var(--crtr-text-edited-padding, 0 var(--crtr-space-2));
440
+ color: var(--crtr-text-edited-text-color, var(--crtr-color-accent));
441
+ background: var(--crtr-text-edited-fill, color-mix(in srgb, var(--crtr-color-accent) 14%, transparent));
442
+ border-radius: var(--crtr-text-edited-radius, var(--crtr-radius-small));
443
+ font-family: var(--crtr-text-edited-font-family, var(--crtr-font-mono));
444
+ font-size: var(--crtr-text-edited-font-size, 0.75em);
445
+ letter-spacing: var(--crtr-text-edited-letter-spacing, 0.06em);
446
+ line-height: var(--crtr-text-edited-line-height, 1.7);
447
+ text-transform: var(--crtr-text-edited-text-transform, uppercase);
273
448
  }
274
449
 
275
450
  button {
276
451
  display: inline-flex;
277
452
  align-items: center;
278
- gap: var(--crtr-space-1);
279
- max-width: 100%;
280
- padding: var(--crtr-space-1) var(--crtr-space-2);
281
- color: var(--crtr-color-text-muted);
282
- font: inherit;
283
- background: transparent;
284
- border: 1px solid transparent;
285
- border-radius: var(--crtr-radius-small);
453
+ gap: var(--crtr-text-button-gap, var(--crtr-space-1));
454
+ max-width: var(--crtr-text-button-max-width, 100%);
455
+ padding: var(--crtr-text-button-padding, var(--crtr-space-1) var(--crtr-space-2));
456
+ color: var(--crtr-text-button-text-color, var(--crtr-color-text-muted));
457
+ font: var(--crtr-text-button-font, inherit);
458
+ background: var(--crtr-text-button-fill, transparent);
459
+ border: var(--crtr-text-button-border-width, 1px)
460
+ var(--crtr-text-button-border-style, solid)
461
+ var(--crtr-text-button-border-color, transparent);
462
+ border-radius: var(--crtr-text-button-radius, var(--crtr-radius-small));
286
463
  cursor: pointer;
464
+ /* One motion knob for all three properties, over the family's, because a button that
465
+ settles at a different speed than the field beside it is the drift controls.ts exists
466
+ to remove. */
467
+ transition: color var(--crtr-text-button-transition, var(--crtr-control-transition, 120ms ease)),
468
+ background-color var(--crtr-text-button-transition, var(--crtr-control-transition, 120ms ease)),
469
+ border-color var(--crtr-text-button-transition, var(--crtr-control-transition, 120ms ease));
287
470
  }
288
471
 
289
472
  button:hover {
290
- color: var(--crtr-color-text);
291
- background: var(--crtr-color-surface-hover);
473
+ color: var(--crtr-text-button-hover-text-color, var(--crtr-color-text));
474
+ background: var(--crtr-text-button-hover-fill, var(--crtr-color-surface-hover));
292
475
  }
293
476
 
294
- button:focus-visible {
295
- outline: 2px solid var(--crtr-color-focus);
296
- outline-offset: 2px;
477
+ ${u({scope:"text-whole-comment"},'[part~="whole-comment"]')}
478
+ ${u({scope:"text-edit-toggle"},'[part="edit-toggle"]')}
479
+ ${u({scope:"text-selection-comment"},'[part~="selection-comment"]')}
480
+ ${u({scope:"text-comment-chip"},'[part~="comment-chip"]')}
481
+ ${u({scope:"text-popover-save"},'[part="popover-save"]')}
482
+ ${u({scope:"text-popover-cancel"},'[part="popover-cancel"]')}
483
+ button[data-state="on"] {
484
+ color: var(--crtr-text-button-on-text-color, var(--crtr-color-accent));
297
485
  }
298
486
 
299
- button[data-state="on"] {
300
- color: var(--crtr-color-accent);
487
+ /* Editing a prefilled draft is a primary path, not an icon to discover. Keep the control
488
+ beside the text but give it the bordered, labelled shape that reads as an action. */
489
+ [part="edit-toggle"] {
490
+ color: var(--crtr-text-edit-toggle-text-color, var(--crtr-color-text));
491
+ background: var(--crtr-text-edit-toggle-fill, var(--crtr-color-background));
492
+ border-color: var(--crtr-text-edit-toggle-border-color, var(--crtr-color-border));
301
493
  }
302
494
 
495
+ /* Reached for and engaged are one treatment here, so they are one knob: active. */
496
+ [part="edit-toggle"]:hover,
497
+ [part="edit-toggle"][data-state="on"] {
498
+ color: var(--crtr-text-edit-toggle-active-text-color, var(--crtr-color-accent));
499
+ border-color: var(--crtr-text-edit-toggle-active-border-color,
500
+ color-mix(in srgb, var(--crtr-color-accent) 45%, var(--crtr-color-border)));
501
+ }
502
+
503
+ /* Width and height are one visual knob \u2014 the icon is square. */
303
504
  svg {
304
- width: 0.875rem;
305
- height: 0.875rem;
505
+ width: var(--crtr-text-icon-size, 0.875em);
506
+ height: var(--crtr-text-icon-size, 0.875em);
306
507
  flex: none;
307
508
  }
308
509
 
510
+ /* Both writing boxes in one call, because in the kit they are one control at two heights:
511
+ input.tsx and textarea.tsx carry the same border, radius, padding, fill, elevation and
512
+ focus ring, and differ only in how tall they start. Writing them separately is what let
513
+ them drift into two visibly different fields \u2014 different padding, different radius,
514
+ different fill, and an inset outline on one against the kit's outset ring on the other.
515
+
516
+ Each selector still gets its own scope: the field and editor are distinct anatomy even
517
+ though this recipe keeps their default paint identical. */
518
+ ${S({scope:"text-input"},'[part="input"]')}
519
+ ${S({scope:"text-editor"},'[part="editor"]')}
520
+ /* The one thing the textarea does not share: it starts tall and may be dragged taller. */
309
521
  [part="editor"] {
310
- display: block;
311
- box-sizing: border-box;
312
- width: 100%;
313
- min-height: 10rem;
314
- padding: var(--crtr-space-3) var(--crtr-space-4);
315
- color: var(--crtr-color-text);
316
- font: inherit;
317
- line-height: var(--crtr-line-height);
318
- background: var(--crtr-color-background);
319
- border: 1px solid var(--crtr-color-border);
320
- border-radius: var(--crtr-radius-medium);
522
+ min-height: var(--crtr-text-editor-min-height, 10em);
321
523
  resize: vertical;
322
524
  }
323
525
 
324
- [part="editor"]:focus-visible,
325
- [part="popover-input"]:focus-visible {
326
- outline: 2px solid var(--crtr-color-focus);
327
- outline-offset: -1px;
526
+ /* The kit ring is outset paint, so a writing box needs a three-pixel gutter inside its grid
527
+ track. Without it the box fills the track exactly and the ring is shaved off by a tight
528
+ host frame. Prose is the other face of this surface and keeps its own inset ring, so it
529
+ stays full-bleed. */
530
+ [part="surface"]:has([part="input"]),
531
+ [part="surface"]:has([part="editor"]) {
532
+ padding: var(--crtr-text-surface-padding, 0.1875rem);
328
533
  }
329
534
 
330
535
  [part="body"] {
331
536
  position: relative;
332
- padding: var(--crtr-space-3) var(--crtr-space-4);
333
- background: var(--crtr-color-surface);
334
- border: 1px solid var(--crtr-color-border);
335
- border-radius: var(--crtr-radius-medium);
537
+ padding: var(--crtr-text-body-padding, var(--crtr-space-3) var(--crtr-space-4));
538
+ background: var(--crtr-text-body-fill, var(--crtr-color-surface));
539
+ border: var(--crtr-text-body-border-width, 1px)
540
+ var(--crtr-text-body-border-style, solid)
541
+ var(--crtr-text-body-border-color, var(--crtr-color-border));
542
+ border-radius: var(--crtr-text-body-radius, var(--crtr-radius-medium));
336
543
  }
337
544
 
545
+ /* The ring sits inside the border rather than outside it. The body is full-bleed \u2014 it runs
546
+ the whole width of the frame the host gives the page \u2014 so an outset ring has nowhere to be
547
+ drawn and gets clipped at the frame's edges, showing three sides of a rectangle. */
338
548
  [part="body"]:focus-visible {
339
- outline: 2px solid var(--crtr-color-focus);
340
- outline-offset: 2px;
549
+ outline: var(--crtr-text-body-focus-ring-width, 2px)
550
+ var(--crtr-text-body-focus-ring-style, solid)
551
+ var(--crtr-text-body-focus-ring-color, var(--crtr-color-focus));
552
+ outline-offset: var(--crtr-text-body-focus-ring-offset, -2px);
341
553
  }
342
554
 
343
555
  [part="prose"] {
344
556
  display: grid;
345
- gap: var(--crtr-space-3);
557
+ gap: var(--crtr-text-prose-gap, var(--crtr-space-3));
346
558
  }
347
559
 
348
560
  [part="prose"] p {
349
- margin: 0;
561
+ margin: var(--crtr-text-prose-paragraph-margin, 0);
562
+ /* The agent's own line breaks are the passage; preserving them is behavior. */
350
563
  white-space: pre-wrap;
351
564
  }
352
565
 
353
566
  [part="placeholder"] {
354
- color: var(--crtr-color-text-muted);
567
+ color: var(--crtr-text-placeholder-text-color, var(--crtr-color-text-muted));
355
568
  }
356
569
 
357
570
  [part~="commented"] {
358
571
  position: relative;
359
- border-radius: var(--crtr-radius-small);
360
- background: color-mix(in srgb, var(--crtr-color-accent) 18%, transparent);
361
- text-decoration: underline dotted;
362
- text-decoration-color: var(--crtr-color-accent);
363
- text-underline-offset: 4px;
572
+ border-radius: var(--crtr-text-commented-radius, var(--crtr-radius-small));
573
+ background: var(--crtr-text-commented-fill, color-mix(in srgb, var(--crtr-color-accent) 18%, transparent));
574
+ text-decoration: var(--crtr-text-commented-text-decoration, underline dotted);
575
+ text-decoration-color: var(--crtr-text-commented-text-decoration-color, var(--crtr-color-accent));
576
+ text-underline-offset: var(--crtr-text-commented-text-underline-offset, 0.25em);
364
577
  cursor: help;
365
- outline: none;
578
+ outline: var(--crtr-text-commented-outline, none);
366
579
  }
367
580
 
368
581
  [part~="commented"]:focus-visible {
369
- outline: 2px solid var(--crtr-color-focus);
370
- outline-offset: 2px;
582
+ outline: var(--crtr-text-commented-focus-ring-width, 2px)
583
+ var(--crtr-text-commented-focus-ring-style, solid)
584
+ var(--crtr-text-commented-focus-ring-color, var(--crtr-color-focus));
585
+ outline-offset: var(--crtr-text-commented-focus-ring-offset, 2px);
371
586
  }
372
587
 
588
+ /* The staged delays here and on the hover rule below are the bubble's show/hide
589
+ choreography \u2014 behavior rather than a styling value, so they stay literal. */
373
590
  [part="comment-bubble"] {
374
591
  position: absolute;
375
- bottom: calc(100% + var(--crtr-space-1));
592
+ bottom: calc(100% + var(--crtr-text-comment-bubble-offset, var(--crtr-space-1)));
376
593
  left: 0;
377
594
  z-index: 2;
378
595
  display: grid;
379
- gap: var(--crtr-space-1);
380
- width: max-content;
381
- max-width: 18rem;
382
- padding: var(--crtr-space-2) var(--crtr-space-3);
383
- color: var(--crtr-color-text);
384
- background: var(--crtr-color-background);
385
- border: 1px solid var(--crtr-color-border);
386
- border-radius: var(--crtr-radius-medium);
387
- box-shadow: var(--crtr-shadow);
596
+ gap: var(--crtr-text-comment-bubble-gap, var(--crtr-space-1));
597
+ width: var(--crtr-text-comment-bubble-width, max-content);
598
+ max-width: var(--crtr-text-comment-bubble-max-width, 18em);
599
+ padding: var(--crtr-text-comment-bubble-padding, var(--crtr-space-2) var(--crtr-space-3));
600
+ color: var(--crtr-text-comment-bubble-text-color, var(--crtr-color-text));
601
+ background: var(--crtr-text-comment-bubble-fill, var(--crtr-color-background));
602
+ border: var(--crtr-text-comment-bubble-border-width, 1px)
603
+ var(--crtr-text-comment-bubble-border-style, solid)
604
+ var(--crtr-text-comment-bubble-border-color, var(--crtr-color-border));
605
+ border-radius: var(--crtr-text-comment-bubble-radius, var(--crtr-radius-medium));
606
+ box-shadow: var(--crtr-text-comment-bubble-shadow, var(--crtr-shadow));
388
607
  text-decoration: none;
389
608
  white-space: normal;
390
609
  user-select: none;
@@ -400,45 +619,46 @@
400
619
  transition: opacity 120ms ease 220ms, visibility 0s linear 220ms;
401
620
  }
402
621
 
622
+ /* The comment layer's micro-labels are the page's own prose, one step down and muted \u2014 not
623
+ caps-mono. Mono set in capitals reads as machine output, and what these say ("Comment on
624
+ this passage", "2 comments") is the interface talking to a person. */
403
625
  [part="bubble-label"],
404
626
  [part="comment-count"],
405
627
  [part="popover-subject"],
406
628
  [part="popover-hint"] {
407
- color: var(--crtr-color-text-muted);
408
- font-family: var(--crtr-font-mono);
409
- font-size: 0.6875rem;
410
- letter-spacing: 0.06em;
411
- text-transform: uppercase;
629
+ color: var(--crtr-text-comment-label-text-color, var(--crtr-color-text-muted));
630
+ font-size: var(--crtr-text-comment-label-font-size, 0.875em);
412
631
  }
413
632
 
414
633
  [part="bubble-label"] {
415
- color: var(--crtr-color-accent);
634
+ color: var(--crtr-text-bubble-label-text-color, var(--crtr-color-accent));
416
635
  }
417
636
 
418
637
  [part~="selection-comment"] {
419
638
  position: absolute;
420
639
  z-index: 3;
421
- color: var(--crtr-color-accent);
422
- background: var(--crtr-color-background);
423
- border-color: color-mix(in srgb, var(--crtr-color-accent) 40%, transparent);
424
- box-shadow: var(--crtr-shadow);
640
+ color: var(--crtr-text-selection-comment-text-color, var(--crtr-color-accent));
641
+ background: var(--crtr-text-selection-comment-fill, var(--crtr-color-background));
642
+ border-color: var(--crtr-text-selection-comment-border-color,
643
+ color-mix(in srgb, var(--crtr-color-accent) 40%, transparent));
644
+ box-shadow: var(--crtr-text-selection-comment-shadow, var(--crtr-shadow));
425
645
  }
426
646
 
427
647
  [part="comment-rail"] {
428
648
  display: grid;
429
- gap: var(--crtr-space-1);
649
+ gap: var(--crtr-text-comment-rail-gap, var(--crtr-space-1));
430
650
  }
431
651
 
432
652
  [part="comment-chips"] {
433
653
  display: flex;
434
654
  flex-wrap: wrap;
435
- gap: var(--crtr-space-2);
655
+ gap: var(--crtr-text-comment-chips-gap, var(--crtr-space-2));
436
656
  }
437
657
 
438
658
  [part~="comment-chip"] {
439
- color: var(--crtr-color-text);
440
- border-color: var(--crtr-color-border);
441
- text-align: left;
659
+ color: var(--crtr-text-comment-chip-text-color, var(--crtr-color-text));
660
+ border-color: var(--crtr-text-comment-chip-border-color, var(--crtr-color-border));
661
+ text-align: var(--crtr-text-comment-chip-text-align, left);
442
662
  }
443
663
 
444
664
  [part~="comment-chip"] > span {
@@ -452,17 +672,21 @@
452
672
  z-index: 5;
453
673
  box-sizing: border-box;
454
674
  display: grid;
455
- gap: var(--crtr-space-2);
456
- width: 20rem;
457
- max-width: 100%;
458
- padding: var(--crtr-space-3);
459
- background: var(--crtr-color-background);
460
- border: 1px solid var(--crtr-color-border);
461
- border-radius: var(--crtr-radius-medium);
462
- box-shadow: var(--crtr-shadow);
675
+ gap: var(--crtr-text-popover-gap, var(--crtr-space-2));
676
+ width: var(--crtr-text-popover-width, 20em);
677
+ max-width: var(--crtr-text-popover-max-width, 100%);
678
+ padding: var(--crtr-text-popover-padding, var(--crtr-space-3));
679
+ background: var(--crtr-text-popover-fill, var(--crtr-color-background));
680
+ border: var(--crtr-text-popover-border-width, 1px)
681
+ var(--crtr-text-popover-border-style, solid)
682
+ var(--crtr-text-popover-border-color, var(--crtr-color-border));
683
+ border-radius: var(--crtr-text-popover-radius, var(--crtr-radius-medium));
684
+ box-shadow: var(--crtr-text-popover-shadow, var(--crtr-shadow));
463
685
  }
464
686
 
465
687
  [part="popover"][hidden],
688
+ [part="toolbar"][hidden],
689
+ [part~="whole-comment"][hidden],
466
690
  [part="edited"][hidden],
467
691
  [part="comment-rail"][hidden],
468
692
  [part~="selection-comment"][hidden],
@@ -471,29 +695,30 @@
471
695
  display: none;
472
696
  }
473
697
 
474
- [part="popover-subject"],
475
- [part="popover-quote"] {
476
- margin: 0;
698
+ [part="popover-subject"] {
699
+ margin: var(--crtr-text-popover-subject-margin, 0);
477
700
  }
478
701
 
702
+ /* Smaller than the comment being written, because it is the context and not the subject.
703
+ The text arrives already elided to about two lines by quotePreview, so it wraps normally
704
+ rather than keeping the source's line breaks. */
479
705
  [part="popover-quote"] {
480
- padding: var(--crtr-space-1) var(--crtr-space-2);
481
- color: var(--crtr-color-text-muted);
482
- background: color-mix(in srgb, var(--crtr-color-accent) 8%, transparent);
483
- border-left: 2px solid color-mix(in srgb, var(--crtr-color-accent) 40%, transparent);
484
- white-space: pre-wrap;
485
- }
486
-
706
+ margin: var(--crtr-text-popover-quote-margin, 0);
707
+ padding: var(--crtr-text-popover-quote-padding, var(--crtr-space-1) var(--crtr-space-2));
708
+ color: var(--crtr-text-popover-quote-text-color, var(--crtr-color-text-muted));
709
+ font-size: var(--crtr-text-popover-quote-font-size, 0.8125em);
710
+ background: var(--crtr-text-popover-quote-fill, color-mix(in srgb, var(--crtr-color-accent) 8%, transparent));
711
+ border-left: var(--crtr-text-popover-quote-border-width, 2px)
712
+ var(--crtr-text-popover-quote-border-style, solid)
713
+ var(--crtr-text-popover-quote-border-color, color-mix(in srgb, var(--crtr-color-accent) 40%, transparent));
714
+ overflow-wrap: anywhere;
715
+ }
716
+
717
+ /* The composer is its own scope: it is the one writing box a person can meet beside the
718
+ passage's own, so the two are separately restylable. */
719
+ ${S({scope:"text-popover-input"},'[part="popover-input"]')}
487
720
  [part="popover-input"] {
488
- box-sizing: border-box;
489
- width: 100%;
490
- min-height: 5rem;
491
- padding: var(--crtr-space-2);
492
- color: var(--crtr-color-text);
493
- font: inherit;
494
- background: var(--crtr-color-surface);
495
- border: 1px solid var(--crtr-color-border);
496
- border-radius: var(--crtr-radius-small);
721
+ min-height: var(--crtr-text-popover-input-min-height, 5em);
497
722
  resize: vertical;
498
723
  }
499
724
 
@@ -501,81 +726,110 @@
501
726
  display: flex;
502
727
  align-items: center;
503
728
  justify-content: space-between;
504
- gap: var(--crtr-space-2);
729
+ gap: var(--crtr-text-popover-actions-gap, var(--crtr-space-2));
505
730
  }
506
731
 
507
732
  [part="popover-buttons"] {
508
733
  display: flex;
509
- gap: var(--crtr-space-2);
734
+ gap: var(--crtr-text-popover-buttons-gap, var(--crtr-space-2));
510
735
  }
511
736
 
512
737
  [part="popover-save"] {
513
- color: var(--crtr-color-accent-contrast);
514
- background: var(--crtr-color-accent);
738
+ color: var(--crtr-text-popover-save-text-color, var(--crtr-color-accent-contrast));
739
+ background: var(--crtr-text-popover-save-fill, var(--crtr-color-accent));
515
740
  }
516
741
 
742
+ /* Mixing the accent toward the text colour darkens on a light token set and lightens on a
743
+ dark one \u2014 an opacity or brightness step moves the wrong way on one of them. */
517
744
  [part="popover-save"]:hover {
518
- color: var(--crtr-color-accent-contrast);
519
- background: var(--crtr-color-accent);
520
- opacity: 0.9;
745
+ color: var(--crtr-text-popover-save-hover-text-color, var(--crtr-color-accent-contrast));
746
+ background: var(--crtr-text-popover-save-hover-fill,
747
+ color-mix(in srgb, var(--crtr-color-accent) 88%, var(--crtr-color-text)));
521
748
  }
522
749
 
750
+ /* Cancel is the quiet half of every editor in this bundle: no border until you reach for it. */
523
751
  [part="popover-cancel"] {
524
- border-color: var(--crtr-color-border);
752
+ border-color: var(--crtr-text-popover-cancel-border-color, transparent);
525
753
  }
526
754
 
755
+ /* Flat: this sits in the flow of the page. A shadow in this bundle means floating \u2014 the
756
+ comment bubble, the selection button, the popover, and nothing else. */
527
757
  [part="unavailable"] {
528
- padding: var(--crtr-space-3);
529
- color: var(--crtr-color-text-muted);
530
- background: var(--crtr-color-surface);
531
- border: 1px solid var(--crtr-color-border);
532
- border-radius: var(--crtr-radius-medium);
533
- box-shadow: var(--crtr-shadow);
758
+ padding: var(--crtr-text-unavailable-padding, var(--crtr-space-3));
759
+ color: var(--crtr-text-unavailable-text-color, var(--crtr-color-text-muted));
760
+ background: var(--crtr-text-unavailable-fill, var(--crtr-color-surface));
761
+ border: var(--crtr-text-unavailable-border-width, 1px)
762
+ var(--crtr-text-unavailable-border-style, solid)
763
+ var(--crtr-text-unavailable-border-color, var(--crtr-color-border));
764
+ border-radius: var(--crtr-text-unavailable-radius, var(--crtr-radius-medium));
534
765
  }
535
766
 
536
767
  [part="reason"] {
537
- color: var(--crtr-color-text);
538
- font-family: var(--crtr-font-mono);
768
+ color: var(--crtr-text-reason-text-color, var(--crtr-color-text));
769
+ font-family: var(--crtr-text-reason-font-family, var(--crtr-font-mono));
539
770
  }
540
- `,kt="http://www.w3.org/2000/svg",Lt="M21 15a2 2 0 0 1-2 2H7l-4 4V5a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2z",Ct=[Lt,"M12 7v6","M9 10h6"],Tt=[Lt,"M13 8H7","M17 12H7"],Yt=["M12 20h9","M16.376 3.622a1 1 0 0 1 3.002 3.002L7.368 18.635a2 2 0 0 1-.855.506l-2.872.838a.5.5 0 0 1-.62-.62l.838-2.872a2 2 0 0 1 .506-.854z","m15 5 3 3"],Xt=["M20 6 9 17l-5-5"];function tt(o){let t=document.createElementNS(kt,"svg");t.setAttribute("viewBox","0 0 24 24"),t.setAttribute("fill","none"),t.setAttribute("stroke","currentColor"),t.setAttribute("stroke-width","2"),t.setAttribute("stroke-linecap","round"),t.setAttribute("stroke-linejoin","round"),t.setAttribute("aria-hidden","true");for(let e of o){let r=document.createElementNS(kt,"path");r.setAttribute("d",e),t.append(r)}return t}function Jt(o){let t=[],e=/\n{2,}/g,r=0,n;for(;(n=e.exec(o))!==null;)t.push({start:r,text:o.slice(r,n.index)}),r=n.index+n[0].length;return t.push({start:r,text:o.slice(r)}),t.filter(i=>i.text.trim().length>0)}function Zt(o,t){let e=t.filter(i=>i.anchor.kind==="range").filter(i=>i.anchor.end>o.start&&i.anchor.start<o.start+o.text.length).sort((i,a)=>i.anchor.start-a.anchor.start),r=[],n=0;for(let i of e){let a=Math.max(n,i.anchor.start-o.start),s=Math.min(o.text.length,i.anchor.end-o.start);s<=a||(a>n&&r.push({text:o.text.slice(n,a)}),r.push({text:o.text.slice(a,s),comment:i}),n=s)}return n<o.text.length&&r.push({text:o.text.slice(n)}),r}function Qt(o){return(o.nodeType===Node.ELEMENT_NODE?o:o.parentElement)?.closest("[data-paragraph]")??null}function te(o,t,e){let r=document.createRange();r.selectNodeContents(o),r.setEnd(t,e);let n=r.cloneContents();for(let i of n.querySelectorAll('[part="comment-bubble"]'))i.remove();return n.textContent?.length??0}function At(o){let t=o.cloneNode(!0);for(let e of t.querySelectorAll('[part="comment-bubble"]'))e.remove();return t.textContent?.length??0}function Mt(o,t,e,r){let n=Array.from(o.querySelectorAll("[data-paragraph]")),i=Qt(t);if(i){if(r==="end"&&e===0){let c=n.indexOf(i),d=n[c-1];if(d)return{paragraph:d,offset:At(d)}}return{paragraph:i,offset:te(i,t,e)}}let a=document.createRange();a.setStart(t,e),a.collapse(!0);let s=r==="start"?n:[...n].reverse();for(let c of s){let d=document.createRange();d.selectNodeContents(c);let u=a.compareBoundaryPoints(r==="start"?Range.START_TO_START:Range.START_TO_END,d);if(r==="start"&&u<=0||r==="end"&&u>=0)return{paragraph:c,offset:r==="start"?0:At(c)}}return null}function ee(o,t){let e=o,r=[typeof e.getSelection=="function"?e.getSelection():null,document.getSelection()];for(let n of r){if(!n||n.isCollapsed||n.rangeCount===0)continue;let i=n.getRangeAt(0);if(t.contains(i.startContainer)&&t.contains(i.endContainer))return i}return null}function et(o){o.setAttribute("aria-haspopup","dialog"),o.setAttribute("aria-controls",St),o.setAttribute("aria-expanded","false")}var st=class extends HTMLElement{#n;#d=document.createElement("div");#s=document.createElement("div");#t=document.createElement("span");#r=document.createElement("button");#e=document.createElement("button");#o=document.createElement("span");#l=document.createElement("div");#c=document.createElement("textarea");#a=document.createElement("div");#u=document.createElement("div");#i=document.createElement("button");#h=document.createElement("div");#x=document.createElement("span");#p=document.createElement("div");#g=document.createElement("div");#w=document.createElement("p");#y=document.createElement("blockquote");#v=document.createElement("textarea");#k=document.createElement("span");#m=document.createElement("button");#A=document.createElement("button");#f={initialText:""};#T;#E="";#b=[];#C=!1;#I=!1;#M=null;#S=null;constructor(){super(),this.#n=this.attachShadow({mode:"open"});let t=document.createElement("style");t.textContent=Ut,this.#d.part.add("container"),this.#s.part.add("toolbar"),this.#t.part.add("edited"),this.#t.textContent="edited",this.#t.hidden=!0,this.#r.type="button",this.#r.part.add("comment-trigger"),this.#r.part.add("whole-comment"),et(this.#r),this.#r.addEventListener("click",()=>{this.#R(at,F,this.#r,"end")}),this.#e.type="button",this.#e.part.add("edit-toggle"),this.#e.hidden=!0,this.#e.append(this.#o),this.#e.addEventListener("click",()=>{this.#C=!this.#C,this.#N(),this.#_(),this.#L(),this.#C?this.#c.focus():this.#a.focus()}),this.#s.append(this.#t,this.#r,this.#e),this.#l.part.add("surface"),this.#c.part.add("editor"),this.#c.addEventListener("input",()=>{this.#E=this.#c.value,this.#L(),this.#P()}),this.#a.part.add("body"),this.#a.tabIndex=0,this.#u.part.add("prose"),this.#i.type="button",this.#i.part.add("comment-trigger"),this.#i.part.add("selection-comment"),this.#i.hidden=!0,et(this.#i),this.#i.append(tt(Ct),document.createTextNode("Comment")),this.#i.addEventListener("mousedown",n=>n.preventDefault()),this.#i.addEventListener("click",()=>{let n=this.#M;n!==null&&this.#R(n.anchor,Y,this.#i,"start",n.anchor.quote)}),this.#a.append(this.#u,this.#i),this.#a.addEventListener("mouseup",()=>this.#V()),this.#h.part.add("comment-rail"),this.#h.hidden=!0,this.#x.part.add("comment-count"),this.#p.part.add("comment-chips"),this.#h.append(this.#x,this.#p),this.#g.part.add("popover"),this.#g.hidden=!0,this.#g.id=St,this.#g.setAttribute("role","dialog"),this.#w.part.add("popover-subject"),this.#y.part.add("popover-quote"),this.#y.hidden=!0,this.#v.part.add("popover-input"),this.#v.placeholder="What should the agent know about this?",this.#v.addEventListener("keydown",n=>{n.key==="Enter"&&(n.metaKey||n.ctrlKey)&&(n.preventDefault(),this.#F())}),this.#k.part.add("popover-hint"),this.#A.type="button",this.#A.part.add("popover-cancel"),this.#A.textContent="Cancel",this.#A.addEventListener("click",()=>this.#H()),this.#m.type="button",this.#m.part.add("popover-save"),this.#m.textContent="Save",this.#m.addEventListener("click",()=>this.#F());let e=document.createElement("div");e.part.add("popover-actions");let r=document.createElement("div");r.part.add("popover-buttons"),r.append(this.#A,this.#m),e.append(this.#k,r),this.#g.append(this.#w,this.#y,this.#v,e),this.#d.append(this.#s,this.#l,this.#h,this.#g),this.#n.append(t,this.#d),this.addEventListener("keydown",this.#Y)}connectedCallback(){if(this.#I)return;let t=k(this);if(t.status!=="ok"){this.#z(t.reason);return}if(typeof t.config.initialText!="string"){this.#z("text config has no initialText string");return}this.#I=!0,this.#f=t.config,this.#T=N(this),this.#E=t.config.initialText,this.#W(),this.#C=t.config.editable===!0&&this.#E.length===0,this.#L(),this.#_(),this.#K()}disconnectedCallback(){document.removeEventListener("pointerdown",this.#O,!0)}#W(){if(this.#T===void 0)return;let t=I(this.#T);t!==void 0&&(this.#f.editable===!0&&typeof t.text=="string"&&(this.#E=t.text),this.#b=H(t.comments))}#B(){return{text:this.#E,edited:this.#E!==this.#f.initialText,comments:this.#b}}#P(){this.#T!==void 0&&$(this.#T,this.#B())}#z(t){let e=document.createElement("div");e.part.add("unavailable"),e.setAttribute("role","status");let r=document.createElement("span");r.part.add("reason"),r.textContent=t,e.append("Text unavailable: ",r),this.#d.replaceChildren(e)}#L(){this.#t.hidden=this.#E===this.#f.initialText;let t=b(this.#b,at);this.#r.replaceChildren(tt(t?Tt:Ct)),this.#r.dataset.state=t?"on":"off",this.#r.setAttribute("aria-label",`${t?"Edit comment on":"Comment on"} ${F}`),this.#e.hidden=this.#f.editable!==!0,this.#e.dataset.state=this.#C?"on":"off",this.#o.textContent=this.#C?"Done":"Edit",this.#e.replaceChildren(tt(this.#C?Xt:Yt),this.#o)}#_(){if(this.#C){this.#c.value!==this.#E&&(this.#c.value=this.#E),this.#c.placeholder=this.#f.placeholder??"Write your answer\u2026",this.#l.firstChild!==this.#c&&this.#l.replaceChildren(this.#c);return}this.#l.firstChild!==this.#a&&this.#l.replaceChildren(this.#a),this.#j()}#j(){let t=Jt(this.#E);if(t.length===0){let r=document.createElement("p");r.part.add("placeholder"),r.textContent=this.#f.placeholder??"Nothing yet.",this.#u.replaceChildren(r);return}let e=t.map(r=>{let n=document.createElement("p");n.dataset.paragraph="",n.dataset.start=String(r.start);for(let i of Zt(r,this.#b))n.append(i.comment?this.#q(i.text,i.comment):i.text);return n});this.#u.replaceChildren(...e)}#q(t,e){let r=document.createElement("span");r.part.add("commented"),r.tabIndex=0,r.dataset.commentId=e.id,et(r);let n=document.createElement("span");n.part.add("comment-bubble"),n.setAttribute("role","note");let i=document.createElement("span");i.part.add("bubble-label"),i.textContent="Comment";let a=document.createElement("span");return a.textContent=e.text,n.append(i,a),r.append(t,n),r}#K(){let t=this.#b.length;if(this.#h.hidden=t===0,t===0){this.#p.replaceChildren();return}this.#x.textContent=`${t} comment${t===1?"":"s"}`;let e=this.#b.map(r=>{let n=document.createElement("button");n.type="button",n.part.add("comment-trigger"),n.part.add("comment-chip"),n.dataset.commentId=r.id,et(n);let i=document.createElement("span");i.textContent=r.text,n.append(tt(Tt),i);let a=r.anchor.kind==="range"?r.anchor:void 0;return n.setAttribute("aria-label",`Edit comment on ${a?Y:F}`),n.addEventListener("click",()=>{this.#R(r.anchor,a?Y:F,n,"start",a?.quote)}),n});this.#p.replaceChildren(...e)}#D(){let t=ee(this.#n,this.#a);if(t===null)return null;let e=Mt(this.#a,t.startContainer,t.startOffset,"start"),r=Mt(this.#a,t.endContainer,t.endOffset,"end");if(e===null||r===null||e.paragraph!==r.paragraph)return null;let n=Number(e.paragraph.dataset.start??"0"),i=n+e.offset,a=n+r.offset;if(a<=i)return null;let s=t.getBoundingClientRect(),c=this.#a.getBoundingClientRect();return{anchor:{kind:"range",start:i,end:a,quote:this.#E.slice(i,a)},left:s.left-c.left,top:s.bottom-c.top+4}}#V(){if(this.#C||this.#S!==null)return;let t=this.#D();if(t===null){this.#N();return}this.#M=t,this.#i.hidden=!1,this.#i.style.left=`${t.left}px`,this.#i.style.top=`${t.top}px`}#N(){this.#M=null,this.#i.hidden=!0}#R(t,e,r,n,i){let a=this.#S;if(a!==null){if(a.trigger===r){this.#H();return}a.trigger.setAttribute("aria-expanded","false")}let s=b(this.#b,t);this.#S={anchor:t,trigger:r},r.setAttribute("aria-expanded","true"),this.#w.textContent=`Comment on ${e}`,this.#g.setAttribute("aria-label",`Comment on ${e}`),this.#y.hidden=i===void 0||i==="",this.#y.textContent=i??"",this.#v.value=s?.text??"",this.#k.textContent=s?"empty to delete":"\u2318\u21B5 to save",this.#g.hidden=!1,this.#G(r,n),this.#v.focus(),document.addEventListener("pointerdown",this.#O,!0)}#G(t,e){let r=this.#d.getBoundingClientRect(),n=t.getBoundingClientRect(),i=this.#g.offsetWidth,a=e==="end"?n.right-r.left-i:n.left-r.left,s=Math.min(Math.max(a,0),Math.max(0,r.width-i));this.#g.style.left=`${s}px`,this.#g.style.top=`${n.bottom-r.top+Vt}px`}#H(t=!0){let e=this.#S;this.#S=null,this.#g.hidden=!0,e?.trigger.setAttribute("aria-expanded","false"),document.removeEventListener("pointerdown",this.#O,!0);let r=e!==null&&e.trigger!==this.#i?e.trigger:this.#a;this.#N(),t&&this.#n.contains(r)&&r.focus()}#F(){let t=this.#S;if(t===null)return;let e=this.#u.contains(t.trigger)||this.#p.contains(t.trigger);this.#b=R(this.#b,t.anchor,this.#v.value),this.#H(!e),this.#L(),this.#C||this.#j(),this.#K(),e&&this.#U(t.anchor),this.#P()}#U(t){let e=b(this.#b,t)?.id,r=e===void 0?null:`[data-comment-id="${CSS.escape(e)}"]`,i=(r===null?null:this.#u.querySelector(r)??this.#p.querySelector(r))??this.#a;this.#n.contains(i)&&i.focus()}#O=t=>{if(this.#S===null)return;let e=t.composedPath();e.includes(this.#g)||e.includes(this.#S.trigger)||this.#H()};#Y=t=>{if(t.defaultPrevented)return;if(t.key==="Escape"&&this.#S!==null){t.preventDefault(),this.#H();return}if(this.#S!==null||this.#C)return;let e=t.composedPath()[0];if(!(e instanceof HTMLElement&&(e.tagName==="TEXTAREA"||e.tagName==="INPUT"))&&!(t.metaKey||t.ctrlKey||t.altKey)){if(t.key==="j"||t.key==="k"){t.preventDefault(),this.#X(t.key==="j"?1:-1);return}t.key==="c"&&(t.preventDefault(),this.#J())}};#$(){return Array.from(this.#u.querySelectorAll('[part~="commented"]'))}#X(t){let e=this.#$();if(e.length===0)return;let r=this.#n.activeElement,n=r instanceof HTMLElement?e.indexOf(r):-1,i=n===-1?t>0?0:e.length-1:n+t;e[Math.min(Math.max(i,0),e.length-1)]?.focus()}#J(){let t=this.#M??this.#D();if(t!==null){this.#M=t,this.#i.hidden=!1,this.#i.style.left=`${t.left}px`,this.#i.style.top=`${t.top}px`,this.#R(t.anchor,Y,this.#i,"start",t.anchor.quote);return}let e=this.#n.activeElement;if(e instanceof HTMLElement&&e.dataset.commentId!==void 0){let r=this.#b.find(n=>n.id===e.dataset.commentId);if(r!==void 0){let n=r.anchor.kind==="range"?r.anchor:void 0,i=n===void 0?F:Y;this.#R(r.anchor,i,e,"start",n?.quote);return}}this.#R(at,F,this.#r,"end")}};v("crtr-text",st);var re="M3.25 3.5h9.5A1.75 1.75 0 0 1 14.5 5.25v5A1.75 1.75 0 0 1 12.75 12H7.4l-3.15 2.36A.5.5 0 0 1 3.5 14v-2H3.25A1.75 1.75 0 0 1 1.5 10.25v-5A1.75 1.75 0 0 1 3.25 3.5Z",ne=`
771
+ `,_t="http://www.w3.org/2000/svg",Ut="M21 15a2 2 0 0 1-2 2H7l-4 4V5a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2z",Kt=[Ut,"M12 7v6","M9 10h6"],qt=[Ut,"M13 8H7","M17 12H7"],xe=["M12 20h9","M16.376 3.622a1 1 0 0 1 3.002 3.002L7.368 18.635a2 2 0 0 1-.855.506l-2.872.838a.5.5 0 0 1-.62-.62l.838-2.872a2 2 0 0 1 .506-.854z","m15 5 3 3"],ye=["M20 6 9 17l-5-5"];function ot(n){let t=document.createElementNS(_t,"svg");t.setAttribute("viewBox","0 0 24 24"),t.setAttribute("fill","none"),t.setAttribute("stroke","currentColor"),t.setAttribute("stroke-width","2"),t.setAttribute("stroke-linecap","round"),t.setAttribute("stroke-linejoin","round"),t.setAttribute("aria-hidden","true");for(let e of n){let r=document.createElementNS(_t,"path");r.setAttribute("d",e),t.append(r)}return t}function we(n){let t=[],e=/\n{2,}/g,r=0,o;for(;(o=e.exec(n))!==null;)t.push({start:r,text:n.slice(r,o.index)}),r=o.index+o[0].length;return t.push({start:r,text:n.slice(r)}),t.filter(a=>a.text.trim().length>0)}function ke(n,t){let e=t.filter(a=>a.anchor.kind==="range").filter(a=>a.anchor.end>n.start&&a.anchor.start<n.start+n.text.length).sort((a,i)=>a.anchor.start-i.anchor.start),r=[],o=0;for(let a of e){let i=Math.max(o,a.anchor.start-n.start),s=Math.min(n.text.length,a.anchor.end-n.start);s<=i||(i>o&&r.push({text:n.text.slice(o,i)}),r.push({text:n.text.slice(i,s),comment:a}),o=s)}return o<n.text.length&&r.push({text:n.text.slice(o)}),r}function Ee(n){return(n.nodeType===Node.ELEMENT_NODE?n:n.parentElement)?.closest("[data-paragraph]")??null}function Ce(n,t,e){let r=document.createRange();r.selectNodeContents(n),r.setEnd(t,e);let o=r.cloneContents();for(let a of o.querySelectorAll('[part="comment-bubble"]'))a.remove();return o.textContent?.length??0}function Gt(n){let t=n.cloneNode(!0);for(let e of t.querySelectorAll('[part="comment-bubble"]'))e.remove();return t.textContent?.length??0}function Wt(n,t,e,r){let o=Array.from(n.querySelectorAll("[data-paragraph]")),a=Ee(t);if(a){if(r==="end"&&e===0){let c=o.indexOf(a),l=o[c-1];if(l)return{paragraph:l,offset:Gt(l)}}return{paragraph:a,offset:Ce(a,t,e)}}let i=document.createRange();i.setStart(t,e),i.collapse(!0);let s=r==="start"?o:[...o].reverse();for(let c of s){let l=document.createRange();l.selectNodeContents(c);let h=i.compareBoundaryPoints(r==="start"?Range.START_TO_START:Range.START_TO_END,l);if(r==="start"&&h<=0||r==="end"&&h>=0)return{paragraph:c,offset:r==="start"?0:Gt(c)}}return null}function Te(n,t){let e=n,r=[typeof e.getSelection=="function"?e.getSelection():null,document.getSelection()];for(let o of r){if(!o||o.isCollapsed||o.rangeCount===0)continue;let a=o.getRangeAt(0);if(t.contains(a.startContainer)&&t.contains(a.endContainer))return a}return null}function nt(n){n.setAttribute("aria-haspopup","dialog"),n.setAttribute("aria-controls",Ft),n.setAttribute("aria-expanded","false")}var vt=class extends HTMLElement{static observedAttributes=["inert"];#o;#i=document.createElement("div");#a=document.createElement("p");#n=document.createElement("div");#e=document.createElement("span");#r=document.createElement("button");#t=document.createElement("button");#h=document.createElement("span");#c=document.createElement("div");#s=document.createElement("textarea");#l=document.createElement("input");#d=document.createElement("div");#u=document.createElement("div");#m=document.createElement("button");#E=document.createElement("div");#L=document.createElement("span");#g=document.createElement("div");#p=document.createElement("div");#T=document.createElement("p");#b=document.createElement("blockquote");#y=document.createElement("textarea");#S=document.createElement("span");#f=document.createElement("button");#A=document.createElement("button");#w={initialText:""};#C;#v=!1;#x="";#k=[];#M=!1;#G=!1;#O=null;#$=null;#j=new ResizeObserver(()=>{let t=this.#$;t!==null&&this.#Z(t.trigger,t.align)});constructor(){super(),this.#o=this.attachShadow({mode:"open"});let t=document.createElement("style");t.textContent=be,this.#i.part.add("container"),this.#a.part.add("label"),this.#a.id=Pt,this.#a.hidden=!0,this.#n.part.add("toolbar"),this.#e.part.add("edited"),this.#e.textContent="edited",this.#e.hidden=!0,this.#r.type="button",this.#r.part.add("comment-trigger"),this.#r.part.add("whole-comment"),nt(this.#r),this.#r.addEventListener("click",()=>{this.#P(ut,U,this.#r,"end")}),this.#t.type="button",this.#t.part.add("edit-toggle"),this.#t.hidden=!0,this.#t.append(this.#h),this.#t.addEventListener("click",()=>{this.#M=!this.#M,this.#R(),this.#q(),this.#H(),this.#M?this.#s.focus():this.#d.focus()}),this.#n.append(this.#e,this.#r,this.#t),this.#c.part.add("surface"),this.#s.part.add("editor"),this.#s.addEventListener("input",()=>{this.#x=this.#s.value,this.#H(),this.#K()}),this.#l.type="text",this.#l.part.add("input"),this.#l.addEventListener("input",()=>{this.#x=this.#l.value,this.#H(),this.#K()}),this.#l.addEventListener("keydown",o=>{o.key==="Enter"&&!o.metaKey&&!o.ctrlKey&&!o.altKey&&o.preventDefault()}),this.#d.part.add("body"),this.#d.tabIndex=0,this.#u.part.add("prose"),this.#m.type="button",this.#m.part.add("comment-trigger"),this.#m.part.add("selection-comment"),this.#m.hidden=!0,nt(this.#m),this.#m.append(ot(Kt),document.createTextNode("Comment")),this.#m.addEventListener("mousedown",o=>o.preventDefault()),this.#m.addEventListener("click",()=>{let o=this.#O;o!==null&&this.#P(o.anchor,J,this.#m,"start",o.anchor.quote)}),this.#d.append(this.#u,this.#m),this.#d.addEventListener("mouseup",()=>this.#J()),this.#E.part.add("comment-rail"),this.#E.hidden=!0,this.#L.part.add("comment-count"),this.#g.part.add("comment-chips"),this.#E.append(this.#L,this.#g),this.#p.part.add("popover"),this.#p.hidden=!0,this.#p.id=Ft,this.#p.setAttribute("role","dialog"),this.#T.part.add("popover-subject"),this.#b.part.add("popover-quote"),this.#b.hidden=!0,this.#y.part.add("popover-input"),this.#y.placeholder="What should the agent know about this?",this.#y.addEventListener("keydown",o=>{o.key==="Enter"&&(o.metaKey||o.ctrlKey)&&(o.preventDefault(),this.#tt())}),this.#S.part.add("popover-hint"),this.#A.type="button",this.#A.part.add("popover-cancel"),this.#A.textContent="Cancel",this.#A.addEventListener("click",()=>this.#_()),this.#f.type="button",this.#f.part.add("popover-save"),this.#f.textContent="Save",this.#f.addEventListener("click",()=>this.#tt());let e=document.createElement("div");e.part.add("popover-actions");let r=document.createElement("div");r.part.add("popover-buttons"),r.append(this.#A,this.#f),e.append(this.#S,r),this.#p.append(this.#T,this.#b,this.#y,e),this.#i.append(this.#a,this.#n,this.#c,this.#E,this.#p),this.#o.append(t,this.#i),this.addEventListener("keydown",this.#rt)}connectedCallback(){if(this.#G)return;let t=T(this);if(t.status!=="ok"){this.#U(t.reason);return}if(typeof t.config.initialText!="string"){this.#U("text config has no initialText string");return}this.#G=!0,this.#w=t.config,this.#v=t.config.singleLine===!0,this.#c.toggleAttribute("data-single-line",this.#v),this.#C=D(this),this.#x=t.config.initialText,this.#I(),this.#W(),this.#C!==void 0&&B(this,this.#C,()=>this.#F()),this.#M=this.#N&&this.#x.length===0,this.#H(),this.#q(),this.#Y()}attributeChangedCallback(){this.isConnected&&this.#V()}disconnectedCallback(){document.removeEventListener("pointerdown",this.#Q,!0),this.#j.disconnect()}#W(){if(this.#C===void 0)return;let t=N(this.#C);t!==void 0&&((this.#N||this.#v)&&typeof t.text=="string"&&(this.#x=t.text),this.#k=O(t.comments))}#F(){return{text:this.#x,edited:this.#x!==this.#w.initialText,comments:this.#k}}#K(){this.#C!==void 0&&M(this.#C,this.#F())}#U(t){let e=document.createElement("div");e.part.add("unavailable"),e.setAttribute("role","status");let r=document.createElement("span");r.part.add("reason"),r.textContent=t,e.append("Text unavailable: ",r),this.#i.replaceChildren(e)}#I(){let t=this.#w.label,e=t!==void 0&&t!=="";this.#a.hidden=!e,this.#a.textContent=e?t:"";for(let r of[this.#s,this.#l,this.#d])e?r.setAttribute("aria-labelledby",Pt):r.removeAttribute("aria-labelledby")}#H(){this.#e.hidden=this.#x===this.#w.initialText||this.#v&&this.#w.initialText==="";let t=y(this.#k,ut);this.#r.replaceChildren(ot(t?qt:Kt)),this.#r.dataset.state=t?"on":"off",this.#r.setAttribute("aria-label",`${t?"Edit comment on":"Comment on"} ${U}`),this.#r.hidden=this.#v||!this.#z,this.#t.hidden=!this.#N,this.#n.hidden=this.#v&&this.#e.hidden,this.#t.dataset.state=this.#M?"on":"off",this.#h.textContent=this.#M?"Done editing":"Edit text",this.#t.replaceChildren(ot(this.#M?ye:xe),this.#h),this.#V()}#V(){let t=f(this);j(this.#o,t),this.#s.readOnly=t,this.#l.disabled=!1,this.#l.readOnly=t,this.#t.disabled=t,t&&this.#$!==null&&this.#_(!1)}get#N(){return!this.#v&&this.#w.editable!==!1}get#z(){return L(this.#C)}#q(){if(this.#v){this.#l.value!==this.#x&&(this.#l.value=this.#x),this.#l.placeholder=this.#w.placeholder??"",this.#c.firstChild!==this.#l&&this.#c.replaceChildren(this.#l);return}if(this.#M){this.#s.value!==this.#x&&(this.#s.value=this.#x),this.#s.placeholder=this.#w.placeholder??"Write your answer\u2026",this.#c.firstChild!==this.#s&&this.#c.replaceChildren(this.#s);return}this.#c.firstChild!==this.#d&&this.#c.replaceChildren(this.#d),this.#B()}#B(){let t=we(this.#x);if(t.length===0){let r=document.createElement("p");r.part.add("placeholder"),r.textContent=this.#w.placeholder??"Nothing yet.",this.#u.replaceChildren(r);return}let e=t.map(r=>{let o=document.createElement("p");o.dataset.paragraph="",o.dataset.start=String(r.start);for(let a of ke(r,this.#k))o.append(a.comment?this.#X(a.text,a.comment):a.text);return o});this.#u.replaceChildren(...e)}#X(t,e){let r=document.createElement("span");r.part.add("commented"),r.tabIndex=0,r.dataset.commentId=e.id,nt(r);let o=document.createElement("span");o.part.add("comment-bubble"),o.setAttribute("role","note");let a=document.createElement("span");a.part.add("bubble-label"),a.textContent="Comment";let i=document.createElement("span");return i.textContent=e.text,o.append(a,i),r.append(t,o),r}#Y(){let t=this.#k.length;if(this.#E.hidden=t===0,t===0){this.#g.replaceChildren();return}this.#L.textContent=`${t} comment${t===1?"":"s"}`;let e=this.#k.map(r=>{let o=document.createElement("button");o.type="button",o.part.add("comment-trigger"),o.part.add("comment-chip"),o.dataset.commentId=r.id,nt(o);let a=document.createElement("span");a.textContent=r.text,o.append(ot(qt),a);let i=r.anchor.kind==="range"?r.anchor:void 0;return o.setAttribute("aria-label",`Edit comment on ${i?J:U}`),o.addEventListener("click",()=>{this.#P(r.anchor,i?J:U,o,"start",i?.quote)}),o});this.#g.replaceChildren(...e)}#D(){let t=Te(this.#o,this.#d);if(t===null)return null;let e=Wt(this.#d,t.startContainer,t.startOffset,"start"),r=Wt(this.#d,t.endContainer,t.endOffset,"end");if(e===null||r===null||e.paragraph!==r.paragraph)return null;let o=Number(e.paragraph.dataset.start??"0"),a=o+e.offset,i=o+r.offset;if(i<=a)return null;let s=t.getBoundingClientRect(),c=this.#d.getBoundingClientRect();return{anchor:{kind:"range",start:a,end:i,quote:this.#x.slice(a,i)},left:s.left-c.left,top:s.bottom-c.top+4}}#J(){if(this.#M||this.#$!==null||!this.#z)return;let t=this.#D();if(t===null){this.#R();return}this.#O=t,this.#m.hidden=!1,this.#m.style.left=`${t.left}px`,this.#m.style.top=`${t.top}px`}#R(){this.#O=null,this.#m.hidden=!0}#P(t,e,r,o,a){if(!this.#z||f(this))return;let i=this.#$;if(i!==null){if(i.trigger===r){this.#_();return}i.trigger.setAttribute("aria-expanded","false")}let s=y(this.#k,t);this.#$={anchor:t,trigger:r,align:o},r.setAttribute("aria-expanded","true"),this.#T.textContent=`Comment on ${e}`,this.#p.setAttribute("aria-label",`Comment on ${e}`);let c=Ht(a??"");this.#b.hidden=c==="",this.#b.textContent=c,this.#y.value=s?.text??"",this.#S.textContent=s?"empty to delete":"\u2318\u21B5 to save",this.#p.hidden=!1,this.#Z(r,o),this.#j.observe(this.#p),this.#y.focus(),document.addEventListener("pointerdown",this.#Q,!0)}#Z(t,e){this.#i.style.paddingBottom="";let r=this.#i.getBoundingClientRect(),o=t.getBoundingClientRect(),a=this.#p.offsetWidth,i=this.#p.offsetHeight,s=e==="end"?o.right-r.left-a:o.left-r.left,c=Math.min(Math.max(s,0),Math.max(0,r.width-a)),l=o.bottom+rt+i<=window.innerHeight,h=o.top-rt-i>=0,g=!l&&h?o.top-r.top-rt-i:o.bottom-r.top+rt;this.#p.style.left=`${c}px`,this.#p.style.top=`${g}px`;let p=this.#p.getBoundingClientRect().bottom-document.body.getBoundingClientRect().bottom;p>0&&(this.#i.style.paddingBottom=`${p}px`)}#_(t=!0){let e=this.#$;this.#$=null,this.#p.hidden=!0,this.#j.disconnect(),this.#i.style.paddingBottom="",e?.trigger.setAttribute("aria-expanded","false"),document.removeEventListener("pointerdown",this.#Q,!0);let r=e!==null&&e.trigger!==this.#m?e.trigger:this.#d;this.#R(),t&&this.#o.contains(r)&&r.focus()}#tt(){let t=this.#$;if(t===null||f(this))return;let e=this.#u.contains(t.trigger)||this.#g.contains(t.trigger);this.#k=z(this.#k,t.anchor,this.#y.value),this.#_(!e),this.#H(),!this.#M&&!this.#v&&this.#B(),this.#Y(),e&&this.#et(t.anchor),this.#K()}#et(t){let e=y(this.#k,t)?.id,r=e===void 0?null:`[data-comment-id="${CSS.escape(e)}"]`,a=(r===null?null:this.#u.querySelector(r)??this.#g.querySelector(r))??this.#d;this.#o.contains(a)&&a.focus()}#Q=t=>{if(this.#$===null)return;let e=t.composedPath();e.includes(this.#p)||e.includes(this.#$.trigger)||this.#_()};#rt=t=>{if(t.defaultPrevented)return;if(t.key==="Escape"&&this.#$!==null){t.preventDefault(),this.#_();return}if(this.#$!==null||this.#M)return;let e=t.composedPath()[0];if(!(e instanceof HTMLElement&&(e.tagName==="TEXTAREA"||e.tagName==="INPUT"))&&!(t.metaKey||t.ctrlKey||t.altKey)){if(t.key==="j"||t.key==="k"){t.preventDefault(),this.#nt(t.key==="j"?1:-1);return}t.key==="c"&&(t.preventDefault(),this.#at())}};#ot(){return Array.from(this.#u.querySelectorAll('[part~="commented"]'))}#nt(t){let e=this.#ot();if(e.length===0)return;let r=this.#o.activeElement,o=r instanceof HTMLElement?e.indexOf(r):-1,a=o===-1?t>0?0:e.length-1:o+t;e[Math.min(Math.max(a,0),e.length-1)]?.focus()}#at(){if(this.#v||!this.#z)return;let t=this.#O??this.#D();if(t!==null){this.#O=t,this.#m.hidden=!1,this.#m.style.left=`${t.left}px`,this.#m.style.top=`${t.top}px`,this.#P(t.anchor,J,this.#m,"start",t.anchor.quote);return}let e=this.#o.activeElement;if(e instanceof HTMLElement&&e.dataset.commentId!==void 0){let r=this.#k.find(o=>o.id===e.dataset.commentId);if(r!==void 0){let o=r.anchor.kind==="range"?r.anchor:void 0,a=o===void 0?U:J;this.#P(r.anchor,a,e,"start",o?.quote);return}}this.#P(ut,U,this.#r,"end")}};w("crtr-text",vt);var at=4,ft="var(--crtr-table-column-toggle-transition, var(--crtr-control-transition, 120ms ease))",Se="var(--crtr-table-row-transition, 120ms ease)",gt="var(--crtr-table-comment-trigger-transition, var(--crtr-control-transition, 120ms ease))",bt="var(--crtr-table-comment-button-transition, var(--crtr-control-transition, 120ms ease))",Ae="M3.25 3.5h9.5A1.75 1.75 0 0 1 14.5 5.25v5A1.75 1.75 0 0 1 12.75 12H7.4l-3.15 2.36A.5.5 0 0 1 3.5 14v-2H3.25A1.75 1.75 0 0 1 1.5 10.25v-5A1.75 1.75 0 0 1 3.25 3.5Z",Me=`
541
772
  :host {
542
773
  display: block;
543
774
  }
544
775
 
545
- [part="container"] {
776
+ /* The positioning context for the comment editor, and the ONLY one. The editor cannot live
777
+ inside the container: that box clips to its own rounded corners, so a popover anchored to
778
+ a row was cut off at the table's edge instead of floating over it. The frame has no paint
779
+ and no clipping, so the editor overlays whatever the table sits on. */
780
+ [part="frame"] {
546
781
  position: relative;
547
- background: var(--crtr-color-background);
548
- border: 1px solid var(--crtr-color-border);
549
- border-radius: var(--crtr-radius-medium);
550
- box-shadow: var(--crtr-shadow);
782
+ }
783
+
784
+ /* Flat: the table sits in the flow of the page. A shadow in this bundle means floating \u2014
785
+ the comment editor, and nothing else here. */
786
+ [part="container"] {
787
+ background: var(--crtr-table-container-fill, var(--crtr-color-background));
788
+ border: var(--crtr-table-container-border-width, 1px)
789
+ var(--crtr-table-container-border-style, solid)
790
+ var(--crtr-table-container-border-color, var(--crtr-color-border));
791
+ border-radius: var(--crtr-table-container-radius, var(--crtr-radius-medium));
551
792
  overflow: hidden;
552
793
  }
553
794
 
795
+ /* Inside the border, not outside it: the container is full-bleed, so an outset ring is
796
+ clipped at the edges of the frame the host gives the page and draws only three sides.
797
+ That is why this is NOT the shared control focus family \u2014 it is a focusable region rather
798
+ than a control, and it says so with its own inset outline. */
554
799
  [part="container"]:focus-visible {
555
- outline: 2px solid var(--crtr-color-focus);
556
- outline-offset: 2px;
800
+ outline: var(--crtr-table-container-focus-outline, 2px solid var(--crtr-color-focus));
801
+ outline-offset: var(--crtr-table-container-focus-outline-offset, -2px);
557
802
  }
558
803
 
804
+ /* Typography here is the element's host typography, not a second set of knobs: font stays
805
+ literal inherit so --crtr-table-font-family, --crtr-table-font-size and
806
+ --crtr-table-line-height reach the table, and the colour reads the host's own
807
+ --crtr-table-color, whose fallback is the colour this rule used to hard-code. */
559
808
  [part="table"] {
560
809
  width: 100%;
561
810
  border-collapse: collapse;
562
811
  font: inherit;
563
- color: var(--crtr-color-text);
812
+ color: var(--crtr-table-color, var(--crtr-color-text));
564
813
  }
565
814
 
566
815
  [part="caption"] {
567
816
  caption-side: top;
568
- padding: var(--crtr-space-3) var(--crtr-space-3) var(--crtr-space-2);
817
+ padding: var(--crtr-table-caption-padding, var(--crtr-space-3) var(--crtr-space-3) var(--crtr-space-2));
569
818
  text-align: left;
570
- color: var(--crtr-color-text-muted);
819
+ color: var(--crtr-table-caption-text-color, var(--crtr-color-text-muted));
571
820
  }
572
821
 
573
822
  th {
574
- padding: var(--crtr-space-2) var(--crtr-space-3);
823
+ padding: var(--crtr-table-header-padding, var(--crtr-space-2) var(--crtr-space-3));
575
824
  text-align: left;
576
- font-weight: 600;
577
- color: var(--crtr-color-text-muted);
578
- border-bottom: 1px solid var(--crtr-color-border);
825
+ font-weight: var(--crtr-table-header-font-weight, 600);
826
+ color: var(--crtr-table-header-text-color, var(--crtr-color-text-muted));
827
+ /* A tinted header reads as the table's own chrome; the column-selected tint still wins,
828
+ on specificity (0-1-0 against this 0-0-1). */
829
+ background: var(--crtr-table-header-fill, var(--crtr-color-surface));
830
+ border-bottom: var(--crtr-table-header-border-width, 1px)
831
+ var(--crtr-table-header-border-style, solid)
832
+ var(--crtr-table-header-border-color, var(--crtr-color-border));
579
833
  white-space: nowrap;
580
834
  }
581
835
 
@@ -586,7 +840,7 @@
586
840
  [part="header-cell-inner"] {
587
841
  display: inline-flex;
588
842
  align-items: center;
589
- gap: var(--crtr-space-1);
843
+ gap: var(--crtr-table-header-gap, var(--crtr-space-1));
590
844
  }
591
845
 
592
846
  th[data-align="right"] [part="header-cell-inner"] {
@@ -594,125 +848,170 @@
594
848
  }
595
849
 
596
850
  [part="column-toggle"] {
597
- font: inherit;
598
- font-weight: 600;
599
- color: inherit;
600
- background: transparent;
601
- border: 1px solid transparent;
602
- border-radius: var(--crtr-radius-small);
603
- padding: var(--crtr-space-1) var(--crtr-space-2);
604
- margin: calc(var(--crtr-space-1) * -1) calc(var(--crtr-space-2) * -1);
851
+ font: var(--crtr-table-column-toggle-font, inherit);
852
+ font-weight: var(--crtr-table-column-toggle-font-weight, 600);
853
+ color: var(--crtr-table-column-toggle-text-color, inherit);
854
+ background: var(--crtr-table-column-toggle-fill, transparent);
855
+ border: var(--crtr-table-column-toggle-border-width, 1px)
856
+ var(--crtr-table-column-toggle-border-style, solid)
857
+ var(--crtr-table-column-toggle-border-color, transparent);
858
+ border-radius: var(--crtr-table-column-toggle-radius, var(--crtr-radius-small));
859
+ padding: var(--crtr-table-column-toggle-padding, var(--crtr-space-1) var(--crtr-space-2));
860
+ /* The toggle is pulled back out of its own padding so the header label sits where an
861
+ unselectable one does; a host that repads the toggle repays this too. */
862
+ margin: var(--crtr-table-column-toggle-margin, calc(var(--crtr-space-1) * -1) calc(var(--crtr-space-2) * -1));
605
863
  cursor: pointer;
864
+ transition: color ${ft}, background-color ${ft}, border-color ${ft};
606
865
  }
607
866
 
608
867
  [part="column-toggle"]:hover {
609
- background: var(--crtr-color-surface-hover);
868
+ background: var(--crtr-table-column-toggle-hover-fill, var(--crtr-color-surface-hover));
610
869
  }
611
870
 
612
871
  [part="column-toggle"][aria-pressed="true"] {
613
- color: var(--crtr-color-text);
614
- background: color-mix(in srgb, var(--crtr-color-accent) 12%, transparent);
615
- border-color: color-mix(in srgb, var(--crtr-color-accent) 40%, transparent);
872
+ color: var(--crtr-table-column-toggle-selected-text-color, var(--crtr-color-text));
873
+ background: var(--crtr-table-column-toggle-selected-fill,
874
+ color-mix(in srgb, var(--crtr-color-accent) 10%, transparent));
875
+ border-color: var(--crtr-table-column-toggle-selected-border-color,
876
+ color-mix(in srgb, var(--crtr-color-accent) 45%, transparent));
616
877
  }
617
878
 
618
- [part="column-toggle"]:focus-visible,
619
- [part="comment-trigger"]:focus-visible,
620
- [part="row-control"]:focus-visible,
621
- [part="select-all"]:focus-visible {
622
- outline: 2px solid var(--crtr-color-focus);
623
- outline-offset: 1px;
879
+ [part="column-toggle"][aria-pressed="true"]:hover {
880
+ background: var(--crtr-table-column-toggle-selected-hover-fill,
881
+ color-mix(in srgb, var(--crtr-color-accent) 14%, transparent));
624
882
  }
625
883
 
884
+ ${u({scope:"table-column-toggle"},'[part="column-toggle"]')}
885
+ ${u({scope:"table-comment-trigger"},'[part="comment-trigger"]')}
886
+
626
887
  [part="row"] {
627
- border-bottom: 1px solid color-mix(in srgb, var(--crtr-color-border) 60%, transparent);
888
+ border-bottom: var(--crtr-table-row-border-width, 1px)
889
+ var(--crtr-table-row-border-style, solid)
890
+ var(--crtr-table-row-border-color, color-mix(in srgb, var(--crtr-color-border) 60%, transparent));
891
+ transition: background-color ${Se};
628
892
  }
629
893
 
630
894
  [part="row"]:last-child {
631
- border-bottom: none;
895
+ border-bottom: var(--crtr-table-row-last-border, none);
632
896
  }
633
897
 
634
898
  [part="row"]:hover,
635
899
  [part="row"][data-active="true"] {
636
- background: var(--crtr-color-surface-hover);
900
+ background: var(--crtr-table-row-hover-fill, var(--crtr-color-surface-hover));
901
+ }
902
+
903
+ [part="row"][data-state="selected"] {
904
+ background: var(--crtr-table-row-selected-fill, color-mix(in srgb, var(--crtr-color-accent) 10%, transparent));
637
905
  }
638
906
 
639
- [part="row"][data-state="selected"],
640
- [part="row"][data-state="selected"]:hover {
641
- background: color-mix(in srgb, var(--crtr-color-accent) 8%, transparent);
907
+ [part="row"][data-state="selected"]:hover,
908
+ [part="row"][data-state="selected"][data-active="true"] {
909
+ background: var(--crtr-table-row-selected-hover-fill,
910
+ color-mix(in srgb, var(--crtr-color-accent) 14%, transparent));
642
911
  }
643
912
 
913
+ /* Inset for the same reason the container's is: a row runs the full width of the table. */
644
914
  [part="row"]:focus-visible {
645
- outline: 2px solid var(--crtr-color-focus);
646
- outline-offset: -2px;
915
+ outline: var(--crtr-table-row-focus-outline, 2px solid var(--crtr-color-focus));
916
+ outline-offset: var(--crtr-table-row-focus-outline-offset, -2px);
647
917
  }
648
918
 
649
919
  td {
650
- padding: var(--crtr-space-2) var(--crtr-space-3);
920
+ padding: var(--crtr-table-cell-padding, var(--crtr-space-2) var(--crtr-space-3));
651
921
  vertical-align: middle;
652
922
  }
653
923
 
654
924
  td[data-align="right"] {
655
925
  text-align: right;
656
- font-variant-numeric: tabular-nums;
926
+ font-variant-numeric: var(--crtr-table-cell-numeric-font-variant, tabular-nums);
657
927
  }
658
928
 
659
929
  td[data-mono="true"] {
660
- font-family: var(--crtr-font-mono);
661
- font-size: 0.8125em;
930
+ font-family: var(--crtr-table-cell-mono-font-family, var(--crtr-font-mono));
931
+ font-size: var(--crtr-table-cell-mono-font-size, 0.8125em);
662
932
  }
663
933
 
664
934
  [data-column-selected="true"] {
665
- background: color-mix(in srgb, var(--crtr-color-accent) 6%, transparent);
935
+ background: var(--crtr-table-column-selected-fill, color-mix(in srgb, var(--crtr-color-accent) 6%, transparent));
666
936
  }
667
937
 
668
938
  [part="select-cell"],
669
939
  [part="select-head"] {
670
940
  width: 1px;
671
- padding-right: 0;
941
+ padding-right: var(--crtr-table-select-cell-padding-right, 0);
672
942
  }
673
943
 
674
944
  [part="comment-cell"],
675
945
  [part="comment-head"] {
676
946
  width: 1px;
677
947
  text-align: right;
678
- padding-left: 0;
948
+ padding-left: var(--crtr-table-comment-cell-padding-left, 0);
679
949
  }
680
950
 
681
- [part="row-control"],
682
- [part="select-all"] {
683
- accent-color: var(--crtr-color-accent);
684
- margin: 0;
685
- cursor: pointer;
951
+ /* One scope over both selectors: the header's select-all IS the row control, drawn once in
952
+ the head, and they are meant to be indistinguishable. */
953
+ ${F({scope:"table-selection"},'[part="row-control"]','[part="select-all"]')}
954
+
955
+ /* A page that can no longer take an answer keeps its selection legible and drops every
956
+ affordance that says it could still be changed. */
957
+ [part="column-toggle"]:disabled {
958
+ cursor: default;
959
+ }
960
+
961
+ [part="column-toggle"]:disabled:hover {
962
+ color: var(--crtr-table-column-toggle-disabled-text-color, var(--crtr-color-text-muted));
963
+ background: var(--crtr-table-column-toggle-disabled-fill, none);
686
964
  }
687
965
 
966
+ /* One size knob for a square button, and one for the glyph in it \u2014 width and height are one
967
+ visual decision each. The opacity is the reveal-on-hover mechanic, which is behaviour. */
688
968
  [part="comment-trigger"] {
689
969
  display: inline-flex;
690
970
  align-items: center;
691
971
  justify-content: center;
692
- width: 1.5rem;
693
- height: 1.5rem;
694
- padding: 0;
695
- color: var(--crtr-color-text-muted);
696
- background: transparent;
697
- border: none;
698
- border-radius: var(--crtr-radius-small);
972
+ width: var(--crtr-table-comment-trigger-size, 1.5em);
973
+ height: var(--crtr-table-comment-trigger-size, 1.5em);
974
+ padding: var(--crtr-table-comment-trigger-padding, 0);
975
+ color: var(--crtr-table-comment-trigger-text-color, var(--crtr-color-text-muted));
976
+ background: var(--crtr-table-comment-trigger-fill, transparent);
977
+ border: var(--crtr-table-comment-trigger-border-width, 0)
978
+ var(--crtr-table-comment-trigger-border-style, none)
979
+ var(--crtr-table-comment-trigger-border-color, currentColor);
980
+ border-radius: var(--crtr-table-comment-trigger-radius, var(--crtr-radius-small));
699
981
  cursor: pointer;
700
982
  opacity: 0;
701
- transition: opacity 120ms ease;
983
+ transition: opacity ${gt}, color ${gt}, background-color ${gt};
702
984
  }
703
985
 
704
986
  [part="comment-trigger"] svg {
705
- width: 0.875rem;
706
- height: 0.875rem;
987
+ width: var(--crtr-table-comment-trigger-icon-size, 0.875em);
988
+ height: var(--crtr-table-comment-trigger-icon-size, 0.875em);
989
+ }
990
+
991
+ /* The path geometry stays the icon's anatomy; its paint is component styling. Attribute
992
+ selectors preserve the filled-comment state that syncState writes while allowing both
993
+ appearances to inherit document-root overrides through this shadow root. */
994
+ [part="comment-trigger"] path {
995
+ stroke: var(--crtr-table-comment-trigger-icon-stroke, currentColor);
996
+ stroke-width: var(--crtr-table-comment-trigger-icon-stroke-width, 1.25);
997
+ stroke-linejoin: var(--crtr-table-comment-trigger-icon-stroke-linejoin, round);
998
+ }
999
+
1000
+ [part="comment-trigger"] path[fill="none"] {
1001
+ fill: var(--crtr-table-comment-trigger-icon-fill, none);
1002
+ }
1003
+
1004
+ [part="comment-trigger"] path[fill="currentColor"] {
1005
+ fill: var(--crtr-table-comment-trigger-commented-icon-fill, currentColor);
707
1006
  }
708
1007
 
709
1008
  [part="comment-trigger"][data-has-comment="true"] {
710
- color: var(--crtr-color-accent);
1009
+ color: var(--crtr-table-comment-trigger-commented-text-color, var(--crtr-color-accent));
711
1010
  opacity: 1;
712
1011
  }
713
1012
 
714
1013
  [part="comment-trigger"]:hover {
715
- background: var(--crtr-color-surface-hover);
1014
+ background: var(--crtr-table-comment-trigger-hover-fill, var(--crtr-color-surface-hover));
716
1015
  }
717
1016
 
718
1017
  tr:hover [part="comment-trigger"],
@@ -723,111 +1022,125 @@
723
1022
  opacity: 1;
724
1023
  }
725
1024
 
1025
+ /* A floating panel over the page, not a box in the table's layout: the background token
1026
+ rather than the surface tint, so it reads as lifted off whatever it covers. */
726
1027
  [part="comment-editor"] {
727
1028
  position: absolute;
728
- z-index: 2;
729
- width: min(20rem, calc(100% - var(--crtr-space-4)));
1029
+ z-index: 5;
1030
+ box-sizing: border-box;
1031
+ width: var(--crtr-table-comment-editor-width, min(20em, 100%));
730
1032
  display: grid;
731
- gap: var(--crtr-space-2);
732
- padding: var(--crtr-space-3);
733
- background: var(--crtr-color-surface);
734
- border: 1px solid var(--crtr-color-border);
735
- border-radius: var(--crtr-radius-medium);
736
- box-shadow: var(--crtr-shadow);
1033
+ gap: var(--crtr-table-comment-editor-gap, var(--crtr-space-2));
1034
+ padding: var(--crtr-table-comment-editor-padding, var(--crtr-space-3));
1035
+ background: var(--crtr-table-comment-editor-fill, var(--crtr-color-background));
1036
+ border: var(--crtr-table-comment-editor-border-width, 1px)
1037
+ var(--crtr-table-comment-editor-border-style, solid)
1038
+ var(--crtr-table-comment-editor-border-color, var(--crtr-color-border));
1039
+ border-radius: var(--crtr-table-comment-editor-radius, var(--crtr-radius-medium));
1040
+ box-shadow: var(--crtr-table-comment-editor-shadow, var(--crtr-shadow));
737
1041
  }
738
1042
 
739
1043
  [part="comment-editor"][hidden] {
740
1044
  display: none;
741
1045
  }
742
1046
 
1047
+ /* The editor's own prose, in the page's voice. It was set in caps mono, which shouted a
1048
+ row id at someone who had just clicked that row. */
743
1049
  [part="comment-target"] {
744
- margin: 0;
745
- font-family: var(--crtr-font-mono);
746
- font-size: 0.75em;
747
- text-transform: uppercase;
748
- letter-spacing: 0.06em;
749
- color: var(--crtr-color-text-muted);
1050
+ margin: var(--crtr-table-comment-target-margin, 0);
1051
+ font-size: var(--crtr-table-comment-target-font-size, 0.875em);
1052
+ color: var(--crtr-table-comment-target-text-color, var(--crtr-color-text-muted));
750
1053
  }
751
1054
 
1055
+ ${S({scope:"table-comment-input"},'[part="comment-input"]')}
752
1056
  [part="comment-input"] {
753
- font: inherit;
754
- color: var(--crtr-color-text);
755
- background: var(--crtr-color-background);
756
- border: 1px solid var(--crtr-color-border);
757
- border-radius: var(--crtr-radius-small);
758
- padding: var(--crtr-space-2);
759
- min-height: 4rem;
1057
+ min-height: var(--crtr-table-comment-input-min-height, 4.5em);
760
1058
  resize: vertical;
761
1059
  }
762
1060
 
763
- [part="comment-input"]:focus-visible {
764
- outline: 2px solid var(--crtr-color-focus);
765
- outline-offset: -1px;
766
- }
767
-
768
1061
  [part="comment-actions"] {
769
1062
  display: flex;
770
1063
  align-items: center;
771
1064
  justify-content: space-between;
772
- gap: var(--crtr-space-2);
1065
+ gap: var(--crtr-table-comment-actions-gap, var(--crtr-space-2));
773
1066
  }
774
1067
 
775
1068
  [part="comment-hint"] {
776
- font-family: var(--crtr-font-mono);
777
- font-size: 0.75em;
778
- text-transform: uppercase;
779
- letter-spacing: 0.06em;
780
- color: var(--crtr-color-text-muted);
1069
+ font-size: var(--crtr-table-comment-hint-font-size, 0.875em);
1070
+ color: var(--crtr-table-comment-hint-text-color, var(--crtr-color-text-muted));
781
1071
  }
782
1072
 
1073
+ /* The chrome both editor buttons share reads one scope \u2014 a person sees one pair of buttons \u2014
1074
+ and each button's own paint carries its own. */
783
1075
  [part="comment-cancel"],
784
1076
  [part="comment-save"] {
785
- font: inherit;
786
- font-size: 0.875em;
787
- padding: var(--crtr-space-1) var(--crtr-space-2);
788
- border-radius: var(--crtr-radius-small);
789
- border: 1px solid var(--crtr-color-border);
1077
+ font: var(--crtr-table-comment-button-font, inherit);
1078
+ font-size: var(--crtr-table-comment-button-font-size, 0.875em);
1079
+ padding: var(--crtr-table-comment-button-padding, var(--crtr-space-1) var(--crtr-space-2));
1080
+ border-radius: var(--crtr-table-comment-button-radius, var(--crtr-radius-small));
1081
+ border: var(--crtr-table-comment-button-border-width, 1px)
1082
+ var(--crtr-table-comment-button-border-style, solid)
1083
+ var(--crtr-table-comment-button-border-color, var(--crtr-color-border));
790
1084
  cursor: pointer;
1085
+ transition: color ${bt}, background-color ${bt},
1086
+ border-color ${bt};
791
1087
  }
792
1088
 
793
1089
  [part="comment-cancel"] {
794
- color: var(--crtr-color-text-muted);
795
- background: transparent;
1090
+ color: var(--crtr-table-comment-cancel-text-color, var(--crtr-color-text-muted));
1091
+ background: var(--crtr-table-comment-cancel-fill, transparent);
1092
+ border-color: var(--crtr-table-comment-cancel-border-color,
1093
+ var(--crtr-table-comment-button-border-color, transparent));
1094
+ }
1095
+
1096
+ [part="comment-cancel"]:hover {
1097
+ color: var(--crtr-table-comment-cancel-hover-text-color, var(--crtr-color-text));
1098
+ background: var(--crtr-table-comment-cancel-hover-fill, var(--crtr-color-surface-hover));
796
1099
  }
797
1100
 
798
1101
  [part="comment-save"] {
799
- color: var(--crtr-color-accent-contrast);
800
- background: var(--crtr-color-accent);
801
- border-color: var(--crtr-color-accent);
1102
+ color: var(--crtr-table-comment-save-text-color, var(--crtr-color-accent-contrast));
1103
+ background: var(--crtr-table-comment-save-fill, var(--crtr-color-accent));
1104
+ border-color: var(--crtr-table-comment-save-border-color,
1105
+ var(--crtr-table-comment-button-border-color, var(--crtr-color-accent)));
802
1106
  }
803
1107
 
804
- [part="comment-cancel"]:focus-visible,
805
- [part="comment-save"]:focus-visible {
806
- outline: 2px solid var(--crtr-color-focus);
807
- outline-offset: 1px;
1108
+ /* Mixing toward the text colour darkens on a light token set and lightens on a dark one \u2014
1109
+ a brightness filter moves the wrong way on one of them. */
1110
+ [part="comment-save"]:hover {
1111
+ background: var(--crtr-table-comment-save-hover-fill,
1112
+ color-mix(in srgb, var(--crtr-color-accent) 88%, var(--crtr-color-text)));
1113
+ border-color: var(--crtr-table-comment-save-hover-border-color,
1114
+ color-mix(in srgb, var(--crtr-color-accent) 88%, var(--crtr-color-text)));
808
1115
  }
809
1116
 
1117
+ ${u({scope:"table-comment-cancel"},'[part="comment-cancel"]')}
1118
+ ${u({scope:"table-comment-save"},'[part="comment-save"]')}
1119
+
1120
+ /* One scope over both: a loading line and an unavailable notice are the same box, saying
1121
+ the table has nothing to show yet or ever. */
810
1122
  [part="status"],
811
1123
  [part="unavailable"] {
812
- padding: var(--crtr-space-3);
813
- color: var(--crtr-color-text-muted);
814
- background: var(--crtr-color-surface);
815
- border: 1px solid var(--crtr-color-border);
816
- border-radius: var(--crtr-radius-medium);
817
- box-shadow: var(--crtr-shadow);
1124
+ padding: var(--crtr-table-notice-padding, var(--crtr-space-3));
1125
+ color: var(--crtr-table-notice-text-color, var(--crtr-color-text-muted));
1126
+ background: var(--crtr-table-notice-fill, var(--crtr-color-surface));
1127
+ border: var(--crtr-table-notice-border-width, 1px)
1128
+ var(--crtr-table-notice-border-style, solid)
1129
+ var(--crtr-table-notice-border-color, var(--crtr-color-border));
1130
+ border-radius: var(--crtr-table-notice-radius, var(--crtr-radius-medium));
818
1131
  }
819
1132
 
820
1133
  [part="reason"] {
821
- color: var(--crtr-color-text);
822
- font-family: var(--crtr-font-mono);
1134
+ color: var(--crtr-table-reason-text-color, var(--crtr-color-text));
1135
+ font-family: var(--crtr-table-reason-font-family, var(--crtr-font-mono));
823
1136
  }
824
1137
 
825
1138
  [part="empty"] {
826
- padding: var(--crtr-space-3);
827
- color: var(--crtr-color-text-muted);
1139
+ padding: var(--crtr-table-empty-padding, var(--crtr-space-3));
1140
+ color: var(--crtr-table-empty-text-color, var(--crtr-color-text-muted));
828
1141
  text-align: center;
829
1142
  }
830
- `;function oe(o){return o==null?"":typeof o=="string"?o:String(o)}function ct(o){return typeof o=="object"&&o!==null&&!Array.isArray(o)}function ie(o){let t=Array.isArray(o)?o:ct(o)&&Array.isArray(o.rows)?o.rows:void 0;if(t===void 0)return{status:"invalid",reason:"source data is not a list of rows"};let e=[];for(let r=0;r<t.length;r+=1){let n=t[r];if(!ct(n)||typeof n.id!="string"||n.id===""||!ct(n.cells))return{status:"invalid",reason:`source row #${r} is not { id, cells }`};let i={};for(let[a,s]of Object.entries(n.cells))if(s!==void 0){if(s!==null&&typeof s!="string"&&typeof s!="number"&&typeof s!="boolean")return{status:"invalid",reason:`source row "${n.id}" cell "${a}" is not a string, number, boolean or null`};i[a]=s}e.push({id:n.id,cells:i})}return{status:"ok",rows:e}}function ae(){let o=document.createElementNS("http://www.w3.org/2000/svg","svg");o.setAttribute("viewBox","0 0 16 16"),o.setAttribute("aria-hidden","true"),o.setAttribute("focusable","false");let t=document.createElementNS("http://www.w3.org/2000/svg","path");return t.setAttribute("d",re),t.setAttribute("fill","none"),t.setAttribute("stroke","currentColor"),t.setAttribute("stroke-width","1.25"),t.setAttribute("stroke-linejoin","round"),o.append(t),o}function se(o){return o instanceof HTMLElement?o.closest('input[type="text"], textarea, [contenteditable="true"]')!==null:!1}var dt=class extends HTMLElement{#n;#d;#s;#t=[];#r=[];#e=[];#o=[];#l=null;#c=null;#a;#u=!1;#i;#h;#x;#p;#g;#w;#y=new Map;#v=new Map;#k;constructor(){super(),this.#n=this.attachShadow({mode:"open"})}connectedCallback(){this.#u=!0;let t=k(this);if(t.status!=="ok"){this.#L(t.reason);return}let e=t.config;if(!Array.isArray(e.columns)||e.columns.length===0){this.#L("table config has no columns");return}if(e.rows!==void 0&&e.source!==void 0){this.#L("table rows and source are mutually exclusive");return}if(this.#s=e,this.#d=N(this),e.source!==void 0){this.#_("Loading table data\u2026"),this.#m(e.source);return}if(!Array.isArray(e.rows)){this.#L("table config has neither rows nor source");return}this.#t=e.rows,this.#A(),this.#j()}disconnectedCallback(){this.#u=!1}async#m(t){let e=await G(t);if(!this.#u)return;if(e.status!=="ok"){this.#L(`table source "${t}" is ${e.status}: ${e.reason}`);return}let r=ie(e.data);if(r.status!=="ok"){this.#L(`table source "${t}": ${r.reason}`);return}this.#t=r.rows,this.#A(),this.#j()}#A(){if(this.#d===void 0)return;let t=I(this.#d);if(t===void 0)return;let e=this.#C(B(t.selectedRowIds)),r=this.#I(B(t.selectedColumnIds));this.#r=this.#f==="none"?[]:this.#f==="single"?e.slice(0,1):e,this.#e=this.#T==="none"?[]:this.#T==="single"?r.slice(0,1):r;let n=new Set(this.#t.map(a=>a.id)),i=new Set((this.#s?.columns??[]).map(a=>a.id));this.#o=H(t.comments).filter(a=>a.anchor.kind==="row"?n.has(a.anchor.rowId):a.anchor.kind==="column"?i.has(a.anchor.columnId):!0)}get#f(){return this.#s?.rowSelect??"none"}get#T(){return this.#s?.columnSelect??"none"}#E(){return{selectedRowIds:[...this.#r],selectedColumnIds:[...this.#e],comments:[...this.#o]}}#b(){this.#$(),this.#d!==void 0&&$(this.#d,this.#E())}#C(t){return this.#t.map(e=>e.id).filter(e=>t.includes(e))}#I(t){return(this.#s?.columns??[]).map(e=>e.id).filter(e=>t.includes(e))}#M(t,e){let r=this.#f;r!=="none"&&(r==="single"?this.#r=e?[t]:[]:this.#r=this.#C(e?[...this.#r,t]:this.#r.filter(n=>n!==t)),this.#b())}#S(t){if(this.#f==="single"){this.#M(t,!0);return}this.#M(t,!this.#r.includes(t))}#W(t,e){let r=this.#T;r!=="none"&&(r==="single"?this.#e=e?[t]:[]:this.#e=this.#I(e?[...this.#e,t]:this.#e.filter(n=>n!==t)),this.#b())}#B(t){this.#W(t,!this.#e.includes(t))}#P(t){this.#f==="multi"&&(this.#r=t?this.#t.map(e=>e.id):[],this.#b())}#z(){this.#n.replaceChildren(),this.#y.clear(),this.#v.clear(),this.#i=void 0,this.#h=void 0,this.#a=void 0,this.#c=null,this.#w=void 0,this.#k=void 0;let t=document.createElement("style");t.textContent=ne,this.#n.append(t)}#L(t){this.#z();let e=document.createElement("div");e.part.add("unavailable"),e.setAttribute("role","status");let r=document.createElement("span");r.part.add("reason"),r.textContent=t,e.append("Table unavailable: ",r),this.#n.append(e)}#_(t){this.#z();let e=document.createElement("div");e.part.add("status"),e.setAttribute("role","status"),e.textContent=t,this.#n.append(e)}#j(){let t=this.#s;if(t===void 0)return;this.#z();let e=document.createElement("div");e.part.add("container"),e.tabIndex=0,e.addEventListener("keydown",n=>this.#U(n)),e.addEventListener("focus",()=>{this.#l===null&&this.#t.length>0&&(this.#l=this.#t[0].id,this.#$())}),this.#i=e;let r=document.createElement("table");if(r.part.add("table"),t.caption!==void 0&&t.caption!==""){let n=document.createElement("caption");n.part.add("caption"),n.textContent=t.caption,r.append(n)}if(r.append(this.#q(t),this.#K(t)),e.append(r),this.#t.length===0){let n=document.createElement("div");n.part.add("empty"),n.textContent="No rows.",e.append(n)}e.append(this.#V()),this.#n.append(e),this.#$()}#q(t){let e=document.createElement("thead"),r=document.createElement("tr");if(r.part.add("header-row"),this.#f!=="none"){let i=document.createElement("th");if(i.part.add("select-head"),i.setAttribute("scope","col"),this.#f==="multi"){let a=document.createElement("input");a.type="checkbox",a.part.add("select-all"),a.setAttribute("aria-label","Select every row"),a.addEventListener("change",()=>this.#P(a.checked)),this.#w=a,i.append(a)}r.append(i)}for(let i of t.columns){let a=document.createElement("th");a.part.add("column-header"),a.setAttribute("scope","col"),a.dataset.columnHeader=i.id,i.align==="right"&&(a.dataset.align="right");let s=document.createElement("span");s.part.add("header-cell-inner");let c;if(this.#T==="none"){let u=document.createElement("span");u.textContent=i.label,s.append(u)}else c=document.createElement("button"),c.type="button",c.part.add("column-toggle"),c.dataset.columnToggle=i.id,c.setAttribute("aria-pressed","false"),c.setAttribute("aria-label",`Select the ${i.label} column`),c.textContent=i.label,c.addEventListener("click",()=>this.#B(i.id)),s.append(c);let d=this.#D({kind:"column",columnId:i.id},`the ${i.label} column`);s.append(d),a.append(s),r.append(a),this.#v.set(i.id,{toggle:c,comment:d,cells:[],head:a})}let n=document.createElement("th");return n.part.add("comment-head"),n.setAttribute("scope","col"),this.#k=this.#D({kind:"whole"},"this table"),n.append(this.#k),r.append(n),e.append(r),e}#K(t){let e=document.createElement("tbody");for(let r of this.#t){let n=document.createElement("tr");n.part.add("row"),n.dataset.rowId=r.id,n.tabIndex=-1,n.addEventListener("mouseenter",()=>this.#H(r.id)),n.addEventListener("focusin",()=>this.#H(r.id));let i;if(this.#f!=="none"){let c=document.createElement("td");c.part.add("select-cell");let d=document.createElement("input");d.type=this.#f==="single"?"radio":"checkbox",d.part.add("row-control"),this.#f==="single"&&(d.name=`${this.#d??"crtr-table"}-row`),d.value=r.id,d.setAttribute("aria-label",`Select row ${r.id}`),d.addEventListener("change",()=>this.#M(r.id,d.checked)),i=d,c.append(d),n.append(c)}for(let c of t.columns){let d=document.createElement("td");d.part.add("cell"),d.dataset.columnId=c.id,c.align==="right"&&(d.dataset.align="right"),c.mono===!0&&(d.dataset.mono="true"),d.textContent=oe(r.cells[c.id]),n.append(d),this.#v.get(c.id)?.cells.push(d)}let a=document.createElement("td");a.part.add("comment-cell");let s=this.#D({kind:"row",rowId:r.id},`row ${r.id}`);a.append(s),n.append(a),e.append(n),this.#y.set(r.id,{tr:n,...i===void 0?{}:{control:i},comment:s})}return e}#D(t,e){let r=document.createElement("button");return r.type="button",r.part.add("comment-trigger"),r.setAttribute("aria-label",`Comment on ${e}`),r.dataset.commentTarget=e,r.append(ae()),r.addEventListener("click",()=>this.#N(t,r)),r}#V(){let t=document.createElement("div");t.part.add("comment-editor"),t.hidden=!0,t.setAttribute("role","dialog"),t.setAttribute("aria-label","Comment");let e=document.createElement("p");e.part.add("comment-target"),t.append(e);let r=document.createElement("textarea");r.part.add("comment-input"),r.placeholder="What should the agent know about this?",r.addEventListener("keydown",d=>{d.key==="Enter"&&(d.metaKey||d.ctrlKey)?(d.preventDefault(),this.#G()):d.key==="Escape"&&(d.preventDefault(),this.#R())}),t.append(r);let n=document.createElement("div");n.part.add("comment-actions");let i=document.createElement("span");i.part.add("comment-hint"),n.append(i);let a=document.createElement("span"),s=document.createElement("button");s.type="button",s.part.add("comment-cancel"),s.textContent="Cancel",s.addEventListener("click",()=>this.#R());let c=document.createElement("button");return c.type="button",c.part.add("comment-save"),c.textContent="Save",c.addEventListener("click",()=>this.#G()),a.append(s," ",c),n.append(a),t.append(n),this.#h=t,this.#x=e,this.#p=r,this.#g=i,t}#N(t,e){let r=this.#h,n=this.#i;if(r===void 0||n===void 0)return;this.#c=t,this.#a=e;let i=b(this.#o,t);this.#p!==void 0&&(this.#p.value=i?.text??""),this.#x!==void 0&&(this.#x.textContent=`Comment on ${e.dataset.commentTarget??nt(t)}`),this.#g!==void 0&&(this.#g.textContent=i===void 0?"\u2318\u21B5 to save":"empty to delete");let a=n.getBoundingClientRect(),s=e.getBoundingClientRect();r.hidden=!1,r.style.top=`${Math.max(0,s.bottom-a.top+4)}px`,r.style.right=`${Math.max(0,a.right-s.right)}px`,this.#$(),this.#p?.focus()}#R(){let t=this.#a;this.#c=null,this.#a=void 0,this.#h!==void 0&&(this.#h.hidden=!0),this.#$(),t?.focus()}#G(){let t=this.#c;t!==null&&(this.#o=R(this.#o,t,this.#p?.value??""),this.#R(),this.#b())}#H(t){this.#l!==t&&(this.#l=t,this.#$())}#F(t){let e=this.#y.get(t);(e?.control??e?.tr)?.focus()}#U(t){if(t.metaKey||t.ctrlKey||t.altKey)return;let e=t.composedPath()[0]??t.target;if(se(e))return;let r=t.key.toLowerCase();if(r!=="j"&&r!=="k"&&r!=="x"&&r!=="c")return;let n=e instanceof HTMLElement?e.closest("[data-column-header]")?.dataset.columnHeader:void 0;if(n!==void 0&&(r==="x"||r==="c")){if(t.preventDefault(),r==="x")this.#B(n);else{let c=this.#v.get(n);c!==void 0&&this.#N({kind:"column",columnId:n},c.comment)}return}let i=this.#t.map(c=>c.id);if(i.length===0)return;let a=this.#l??this.#r[this.#r.length-1]??i[0];if(r==="j"||r==="k"){t.preventDefault();let c=Math.max(0,i.indexOf(a)),d=i[(c+(r==="j"?1:-1)+i.length)%i.length];this.#H(d),this.#F(d);return}if(t.preventDefault(),r==="x"){this.#S(a);return}let s=this.#y.get(a);s!==void 0&&this.#N({kind:"row",rowId:a},s.comment)}#O(t,e){let r=b(this.#o,e),n=t.dataset.commentTarget??nt(e);t.dataset.hasComment=r===void 0?"false":"true",t.setAttribute("aria-label",r===void 0?`Comment on ${n}`:`Edit comment on ${n}`),t.title=r?.text??"",t.querySelector("path")?.setAttribute("fill",r===void 0?"none":"currentColor"),t.dataset.open=this.#Y(e)?"true":"false"}#Y(t){let e=this.#c;return e===null||e.kind!==t.kind?!1:e.kind==="row"&&t.kind==="row"?e.rowId===t.rowId:e.kind==="column"&&t.kind==="column"?e.columnId===t.columnId:e.kind==="whole"}#$(){for(let[t,e]of this.#y){let r=this.#r.includes(t);r?e.tr.dataset.state="selected":delete e.tr.dataset.state,e.tr.dataset.active=this.#l===t?"true":"false",e.tr.setAttribute("aria-selected",r?"true":"false"),e.control!==void 0&&(e.control.checked=r),this.#O(e.comment,{kind:"row",rowId:t})}for(let[t,e]of this.#v){let r=this.#e.includes(t);e.toggle?.setAttribute("aria-pressed",r?"true":"false"),e.head.dataset.columnSelected=r?"true":"false";for(let n of e.cells)n.dataset.columnSelected=r?"true":"false";this.#O(e.comment,{kind:"column",columnId:t})}if(this.#k!==void 0&&this.#O(this.#k,{kind:"whole"}),this.#w!==void 0){let t=this.#t.length>0&&this.#r.length===this.#t.length;this.#w.checked=t,this.#w.indeterminate=this.#r.length>0&&!t}}};v("crtr-table",dt);var ce=`
1143
+ `;function Le(n){return n==null?"":typeof n=="string"?n:String(n)}function $e(){let n=document.createElementNS("http://www.w3.org/2000/svg","svg");n.setAttribute("viewBox","0 0 16 16"),n.setAttribute("aria-hidden","true"),n.setAttribute("focusable","false");let t=document.createElementNS("http://www.w3.org/2000/svg","path");return t.setAttribute("d",Ae),t.setAttribute("fill","none"),t.setAttribute("stroke","currentColor"),t.setAttribute("stroke-width","1.25"),t.setAttribute("stroke-linejoin","round"),n.append(t),n}function Re(n){return n instanceof HTMLElement?n.closest('input[type="text"], textarea, [contenteditable="true"]')!==null:!1}var xt=class extends HTMLElement{static observedAttributes=["inert"];#o;#i;#a;#n=[];#e=[];#r=[];#t=[];#h=null;#c=null;#s;#l;#d;#u;#m;#E;#L;#g;#p=new Map;#T=new Map;#b;constructor(){super(),this.#o=this.attachShadow({mode:"open"})}connectedCallback(){let t=T(this);if(t.status!=="ok"){this.#W(t.reason);return}let e=t.config;if(!Array.isArray(e.columns)||e.columns.length===0){this.#W("table config has no columns");return}this.#a=e,this.#i=D(this),this.#i!==void 0&&(this.#f!=="none"||this.#A!=="none")&&B(this,this.#i,()=>this.#w()),this.#n=e.rows??[],this.#S(),this.#F()}attributeChangedCallback(){this.isConnected&&this.#y()}#y(){let t=f(this);j(this.#o,t);for(let e of this.#T.values())e.toggle!==void 0&&(e.toggle.disabled=t);t&&this.#c!==null&&this.#z()}#S(){if(this.#i===void 0)return;let t=N(this.#i);if(t===void 0)return;let e=this.#v(q(t.selectedRowIds)),r=this.#x(q(t.selectedColumnIds));this.#e=this.#f==="none"?[]:this.#f==="single"?e.slice(0,1):e,this.#r=this.#A==="none"?[]:this.#A==="single"?r.slice(0,1):r;let o=new Set(this.#n.map(i=>i.id)),a=new Set((this.#a?.columns??[]).map(i=>i.id));this.#t=O(t.comments).filter(i=>i.anchor.kind==="row"?o.has(i.anchor.rowId):i.anchor.kind==="column"?a.has(i.anchor.columnId):!0)}get#f(){return this.#a?.rowSelect??"none"}get#A(){return this.#a?.columnSelect??"none"}#w(){return{selectedRowIds:[...this.#e],selectedColumnIds:[...this.#r],comments:[...this.#t]}}#C(){this.#R(),this.#i!==void 0&&M(this.#i,this.#w())}#v(t){return this.#n.map(e=>e.id).filter(e=>t.includes(e))}#x(t){return(this.#a?.columns??[]).map(e=>e.id).filter(e=>t.includes(e))}#k(t,e){let r=this.#f;r==="none"||f(this)||(r==="single"?this.#e=e?[t]:[]:this.#e=this.#v(e?[...this.#e,t]:this.#e.filter(o=>o!==t)),this.#C())}#M(t){if(this.#f==="single"){this.#k(t,!0);return}this.#k(t,!this.#e.includes(t))}#G(t,e){let r=this.#A;r==="none"||f(this)||(r==="single"?this.#r=e?[t]:[]:this.#r=this.#x(e?[...this.#r,t]:this.#r.filter(o=>o!==t)),this.#C())}#O(t){this.#G(t,!this.#r.includes(t))}#$(t){this.#f!=="multi"||f(this)||(this.#e=t?this.#n.map(e=>e.id):[],this.#C())}#j(){this.#o.replaceChildren(),this.#p.clear(),this.#T.clear(),this.#l=void 0,this.#d=void 0,this.#u=void 0,this.#s=void 0,this.#c=null,this.#g=void 0,this.#b=void 0;let t=document.createElement("style");t.textContent=Me,this.#o.append(t)}#W(t){this.#j();let e=document.createElement("div");e.part.add("unavailable"),e.setAttribute("role","status");let r=document.createElement("span");r.part.add("reason"),r.textContent=t,e.append("Table unavailable: ",r),this.#o.append(e)}#F(){let t=this.#a;if(t===void 0)return;this.#j();let e=document.createElement("div");e.part.add("container"),e.tabIndex=0,e.addEventListener("keydown",a=>this.#Y(a)),e.addEventListener("focus",()=>{this.#h===null&&this.#n.length>0&&(this.#h=this.#n[0].id,this.#R())}),this.#l=e;let r=document.createElement("table");if(r.part.add("table"),t.label!==void 0&&t.label!==""){let a=document.createElement("caption");a.part.add("caption"),a.textContent=t.label,r.append(a)}if(r.append(this.#K(t),this.#U(t)),e.append(r),this.#n.length===0){let a=document.createElement("div");a.part.add("empty"),a.textContent="No rows.",e.append(a)}let o=document.createElement("div");o.part.add("frame"),o.append(e),this.#I&&o.append(this.#V()),this.#d=o,this.#o.append(o),this.#R()}#K(t){let e=document.createElement("thead"),r=document.createElement("tr");if(r.part.add("header-row"),this.#f!=="none"){let o=document.createElement("th");if(o.part.add("select-head"),o.setAttribute("scope","col"),this.#f==="multi"){let a=document.createElement("input");a.type="checkbox",a.part.add("select-all"),a.setAttribute("aria-label","Select every row"),a.addEventListener("change",()=>this.#$(a.checked)),this.#g=a,o.append(a)}r.append(o)}for(let o of t.columns){let a=document.createElement("th");a.part.add("column-header"),a.setAttribute("scope","col"),a.dataset.columnHeader=o.id,o.align==="right"&&(a.dataset.align="right");let i=document.createElement("span");i.part.add("header-cell-inner");let s;if(this.#A==="none"){let l=document.createElement("span");l.textContent=o.label,i.append(l)}else s=document.createElement("button"),s.type="button",s.part.add("column-toggle"),s.dataset.columnToggle=o.id,s.setAttribute("aria-pressed","false"),s.setAttribute("aria-label",`Select the ${o.label} column`),s.textContent=o.label,s.addEventListener("click",()=>this.#O(o.id)),i.append(s);let c=this.#I?this.#H({kind:"column",columnId:o.id},`the ${o.label} column`):void 0;c!==void 0&&i.append(c),a.append(i),r.append(a),this.#T.set(o.id,{toggle:s,...c===void 0?{}:{comment:c},cells:[],head:a})}if(this.#I){let o=document.createElement("th");o.part.add("comment-head"),o.setAttribute("scope","col"),this.#b=this.#H({kind:"whole"},"this table"),o.append(this.#b),r.append(o)}return e.append(r),e}#U(t){let e=document.createElement("tbody");for(let r of this.#n){let o=document.createElement("tr");o.part.add("row"),o.dataset.rowId=r.id,o.tabIndex=-1,o.addEventListener("mouseenter",()=>this.#B(r.id)),o.addEventListener("focusin",()=>this.#B(r.id));let a;if(this.#f!=="none"){let s=document.createElement("td");s.part.add("select-cell");let c=document.createElement("input");c.type=this.#f==="single"?"radio":"checkbox",c.part.add("row-control"),this.#f==="single"&&(c.name=`${this.#i??"crtr-table"}-row`),c.value=r.id,c.setAttribute("aria-label",`Select row ${r.id}`),c.addEventListener("change",()=>this.#k(r.id,c.checked)),a=c,s.append(c),o.append(s)}for(let s of t.columns){let c=document.createElement("td");c.part.add("cell"),c.dataset.columnId=s.id,s.align==="right"&&(c.dataset.align="right"),s.mono===!0&&(c.dataset.mono="true"),c.textContent=Le(r.cells[s.id]),o.append(c),this.#T.get(s.id)?.cells.push(c)}let i;if(this.#I){let s=document.createElement("td");s.part.add("comment-cell"),i=this.#H({kind:"row",rowId:r.id},`row ${r.id}`),s.append(i),o.append(s)}e.append(o),this.#p.set(r.id,{tr:o,...a===void 0?{}:{control:a},...i===void 0?{}:{comment:i}})}return e}get#I(){return L(this.#i)}#H(t,e){let r=document.createElement("button");return r.type="button",r.part.add("comment-trigger"),r.setAttribute("aria-label",`Comment on ${e}`),r.dataset.commentTarget=e,r.append($e()),r.addEventListener("click",()=>this.#N(t,r)),r}#V(){let t=document.createElement("div");t.part.add("comment-editor"),t.hidden=!0,t.setAttribute("role","dialog"),t.setAttribute("aria-label","Comment");let e=document.createElement("p");e.part.add("comment-target"),t.append(e);let r=document.createElement("textarea");r.part.add("comment-input"),r.placeholder="What should the agent know about this?",r.addEventListener("keydown",l=>{l.key==="Enter"&&(l.metaKey||l.ctrlKey)?(l.preventDefault(),this.#q()):l.key==="Escape"&&(l.preventDefault(),this.#z())}),t.append(r);let o=document.createElement("div");o.part.add("comment-actions");let a=document.createElement("span");a.part.add("comment-hint"),o.append(a);let i=document.createElement("span"),s=document.createElement("button");s.type="button",s.part.add("comment-cancel"),s.textContent="Cancel",s.addEventListener("click",()=>this.#z());let c=document.createElement("button");return c.type="button",c.part.add("comment-save"),c.textContent="Save",c.addEventListener("click",()=>this.#q()),i.append(s," ",c),o.append(i),t.append(o),this.#u=t,this.#m=e,this.#E=r,this.#L=a,t}#N(t,e){let r=this.#u,o=this.#d;if(r===void 0||o===void 0||!this.#I||f(this))return;this.#c=t,this.#s=e;let a=y(this.#t,t);this.#E!==void 0&&(this.#E.value=a?.text??""),this.#m!==void 0&&(this.#m.textContent=`Comment on ${e.dataset.commentTarget??st(t)}`),this.#L!==void 0&&(this.#L.textContent=a===void 0?"\u2318\u21B5 to save":"empty to delete");let i=o.getBoundingClientRect(),s=e.getBoundingClientRect();r.hidden=!1,r.style.right=`${Math.max(0,i.right-s.right)}px`,r.style.top="0px";let c=r.getBoundingClientRect().height,l=s.bottom+at+c<=window.innerHeight,h=s.top-at-c>=0;r.style.top=!l&&h?`${s.top-at-c-i.top}px`:`${s.bottom+at-i.top}px`,this.#R(),this.#E?.focus()}#z(){let t=this.#s;this.#c=null,this.#s=void 0,this.#u!==void 0&&(this.#u.hidden=!0),this.#R(),t?.focus()}#q(){let t=this.#c;t===null||f(this)||(this.#t=z(this.#t,t,this.#E?.value??""),this.#z(),this.#C())}#B(t){this.#h!==t&&(this.#h=t,this.#R())}#X(t){let e=this.#p.get(t);(e?.control??e?.tr)?.focus()}#Y(t){if(t.metaKey||t.ctrlKey||t.altKey)return;let e=t.composedPath()[0]??t.target;if(Re(e))return;let r=t.key.toLowerCase();if(r!=="j"&&r!=="k"&&r!=="x"&&r!=="c")return;let o=e instanceof HTMLElement?e.closest("[data-column-header]")?.dataset.columnHeader:void 0;if(o!==void 0&&(r==="x"||r==="c")){if(t.preventDefault(),r==="x")this.#O(o);else{let c=this.#T.get(o)?.comment;c!==void 0&&this.#N({kind:"column",columnId:o},c)}return}let a=this.#n.map(c=>c.id);if(a.length===0)return;let i=this.#h??this.#e[this.#e.length-1]??a[0];if(r==="j"||r==="k"){t.preventDefault();let c=Math.max(0,a.indexOf(i)),l=a[(c+(r==="j"?1:-1)+a.length)%a.length];this.#B(l),this.#X(l);return}if(t.preventDefault(),r==="x"){this.#M(i);return}let s=this.#p.get(i)?.comment;s!==void 0&&this.#N({kind:"row",rowId:i},s)}#D(t,e){let r=y(this.#t,e),o=t.dataset.commentTarget??st(e);t.dataset.hasComment=r===void 0?"false":"true",t.setAttribute("aria-label",r===void 0?`Comment on ${o}`:`Edit comment on ${o}`),t.title=r?.text??"",t.querySelector("path")?.setAttribute("fill",r===void 0?"none":"currentColor"),t.dataset.open=this.#J(e)?"true":"false"}#J(t){let e=this.#c;return e===null||e.kind!==t.kind?!1:e.kind==="row"&&t.kind==="row"?e.rowId===t.rowId:e.kind==="column"&&t.kind==="column"?e.columnId===t.columnId:e.kind==="whole"}#R(){for(let[t,e]of this.#p){let r=this.#e.includes(t);r?e.tr.dataset.state="selected":delete e.tr.dataset.state,e.tr.dataset.active=this.#h===t?"true":"false",e.tr.setAttribute("aria-selected",r?"true":"false"),e.control!==void 0&&(e.control.checked=r),e.comment!==void 0&&this.#D(e.comment,{kind:"row",rowId:t})}for(let[t,e]of this.#T){let r=this.#r.includes(t);e.toggle?.setAttribute("aria-pressed",r?"true":"false"),e.head.dataset.columnSelected=r?"true":"false";for(let o of e.cells)o.dataset.columnSelected=r?"true":"false";e.comment!==void 0&&this.#D(e.comment,{kind:"column",columnId:t})}if(this.#b!==void 0&&this.#D(this.#b,{kind:"whole"}),this.#g!==void 0){let t=this.#n.length>0&&this.#e.length===this.#n.length;this.#g.checked=t,this.#g.indeterminate=this.#e.length>0&&!t}this.#y()}};w("crtr-table",xt);var He=`
831
1144
  :host {
832
1145
  display: block;
833
1146
  /* Column count answers the element's own width, not the viewport: a slot can sit in
@@ -838,13 +1151,23 @@
838
1151
  [part~="container"] {
839
1152
  display: flex;
840
1153
  flex-direction: column;
841
- gap: var(--crtr-space-1);
1154
+ gap: var(--crtr-cards-container-gap, var(--crtr-space-1));
1155
+ }
1156
+
1157
+ /* The question reads as the agent's own prose above its control, matching the table's
1158
+ caption rather than shouting over the cards it introduces. The container's gap is a
1159
+ hairline, so the breathing room under the prompt is the prompt's own. */
1160
+ [part~="label"] {
1161
+ margin: 0 0 var(--crtr-cards-label-gap, var(--crtr-space-2));
1162
+ color: var(--crtr-cards-label-text-color, var(--crtr-color-text-muted));
842
1163
  }
843
1164
 
1165
+ /* The column count is anatomy rather than paint \u2014 a container query cannot read a custom
1166
+ property, so the breakpoint below stays a literal. */
844
1167
  [part~="grid"] {
845
1168
  display: grid;
846
1169
  grid-template-columns: minmax(0, 1fr);
847
- gap: var(--crtr-space-3);
1170
+ gap: var(--crtr-cards-grid-gap, var(--crtr-space-3));
848
1171
  }
849
1172
 
850
1173
  @container (min-width: 30rem) {
@@ -860,35 +1183,44 @@
860
1183
  [part~="card"] {
861
1184
  display: flex;
862
1185
  flex-direction: column;
863
- gap: var(--crtr-space-2);
864
- padding: var(--crtr-space-3);
865
- color: var(--crtr-color-text);
866
- background: var(--crtr-color-surface);
867
- border: 1px solid color-mix(in srgb, var(--crtr-color-border) 60%, transparent);
868
- border-radius: var(--crtr-radius-medium);
869
- transition: background-color 120ms ease, border-color 120ms ease;
1186
+ gap: var(--crtr-cards-card-gap, var(--crtr-space-2));
1187
+ padding: var(--crtr-cards-card-padding, var(--crtr-space-3));
1188
+ color: var(--crtr-cards-card-text-color, var(--crtr-color-text));
1189
+ background: var(--crtr-cards-card-fill, var(--crtr-color-surface));
1190
+ border: var(--crtr-cards-card-border-width, 1px)
1191
+ var(--crtr-cards-card-border-style, solid)
1192
+ var(--crtr-cards-card-border-color, color-mix(in srgb, var(--crtr-color-border) 60%, transparent));
1193
+ border-radius: var(--crtr-cards-card-radius, var(--crtr-radius-medium));
1194
+ /* The whole card is the target, not just its heading \u2014 see the click handler. */
1195
+ cursor: pointer;
1196
+ transition: background-color var(--crtr-cards-card-transition, 120ms ease),
1197
+ border-color var(--crtr-cards-card-transition, 120ms ease);
1198
+ }
1199
+
1200
+ [part~="card"]:has([part~="control"]:disabled) {
1201
+ cursor: default;
870
1202
  }
871
1203
 
872
1204
  [part~="card"]:hover,
873
1205
  [part~="card"][part~="active"] {
874
- background: var(--crtr-color-surface-hover);
875
- border-color: var(--crtr-color-border);
1206
+ background: var(--crtr-cards-card-hover-fill, var(--crtr-color-surface-hover));
1207
+ border-color: var(--crtr-cards-card-hover-border-color, var(--crtr-color-border));
876
1208
  }
877
1209
 
878
1210
  [part~="card"][part~="selected"] {
879
- background: color-mix(in srgb, var(--crtr-color-accent) 7%, transparent);
880
- border-color: color-mix(in srgb, var(--crtr-color-accent) 40%, transparent);
1211
+ background: var(--crtr-cards-card-selected-fill, color-mix(in srgb, var(--crtr-color-accent) 10%, transparent));
1212
+ border-color: var(--crtr-cards-card-selected-border-color, color-mix(in srgb, var(--crtr-color-accent) 45%, transparent));
881
1213
  }
882
1214
 
883
1215
  [part~="card"][part~="selected"]:hover,
884
1216
  [part~="card"][part~="selected"][part~="active"] {
885
- background: color-mix(in srgb, var(--crtr-color-accent) 12%, transparent);
1217
+ background: var(--crtr-cards-card-selected-hover-fill, color-mix(in srgb, var(--crtr-color-accent) 14%, transparent));
886
1218
  }
887
1219
 
888
1220
  [part~="card-header"] {
889
1221
  display: flex;
890
1222
  align-items: flex-start;
891
- gap: var(--crtr-space-2);
1223
+ gap: var(--crtr-cards-card-header-gap, var(--crtr-space-2));
892
1224
  }
893
1225
 
894
1226
  /* The label carries the click target, so the whole heading toggles the native control
@@ -897,62 +1229,61 @@
897
1229
  display: flex;
898
1230
  flex: 1;
899
1231
  align-items: flex-start;
900
- gap: var(--crtr-space-2);
1232
+ gap: var(--crtr-cards-card-label-gap, var(--crtr-space-2));
901
1233
  min-width: 0;
902
- font: inherit;
1234
+ font: var(--crtr-cards-card-label-font, inherit);
903
1235
  cursor: pointer;
904
1236
  }
905
1237
 
906
- [part~="control"] {
907
- flex: none;
908
- margin: 0;
909
- margin-top: 0.2em;
910
- accent-color: var(--crtr-color-accent);
911
- }
1238
+ ${F({scope:"cards-control"},'[part~="control"]')}
912
1239
 
913
- [part~="control"]:focus-visible {
914
- outline: 2px solid var(--crtr-color-focus);
915
- outline-offset: 2px;
1240
+ /* Centred on the card's title line, which sets its own tighter line-height. The box size
1241
+ is read back through --control-box, the local the recipe above resolves it into, so a
1242
+ host that resizes the control keeps it centred without touching this offset. */
1243
+ [part~="control"] {
1244
+ margin-top: var(--crtr-cards-control-offset, calc((1.35em - var(--control-box)) / 2));
916
1245
  }
917
1246
 
918
1247
  [part~="card-heading"] {
919
1248
  display: grid;
920
1249
  flex: 1;
921
- gap: calc(var(--crtr-space-1) / 2);
1250
+ gap: var(--crtr-cards-card-heading-gap, calc(var(--crtr-space-1) / 2));
922
1251
  min-width: 0;
923
1252
  }
924
1253
 
925
1254
  [part~="card-title"] {
926
- font-weight: 500;
927
- line-height: 1.35;
1255
+ font-weight: var(--crtr-cards-card-title-font-weight, 500);
1256
+ line-height: var(--crtr-cards-card-title-line-height, 1.35);
928
1257
  }
929
1258
 
930
1259
  [part~="card-subtitle"] {
931
- color: var(--crtr-color-text-muted);
932
- font-size: calc(var(--crtr-font-size) * 0.85);
1260
+ color: var(--crtr-cards-card-subtitle-text-color, var(--crtr-color-text-muted));
1261
+ font-size: var(--crtr-cards-card-subtitle-font-size, 0.875em);
933
1262
  }
934
1263
 
935
1264
  [part~="card-body"] {
936
- margin: 0;
937
- color: var(--crtr-color-text-muted);
938
- font-size: calc(var(--crtr-font-size) * 0.85);
939
- line-height: 1.6;
1265
+ margin: var(--crtr-cards-card-body-margin, 0);
1266
+ color: var(--crtr-cards-card-body-text-color, var(--crtr-color-text-muted));
1267
+ font-size: var(--crtr-cards-card-body-font-size, 0.875em);
1268
+ line-height: var(--crtr-cards-card-body-line-height, 1.6);
940
1269
  }
941
1270
 
942
1271
  [part~="tag"] {
943
1272
  align-self: flex-start;
944
- padding: 0 var(--crtr-space-1);
945
- color: var(--crtr-color-text-muted);
946
- font-size: calc(var(--crtr-font-size) * 0.78);
947
- line-height: 1.7;
948
- border: 1px solid var(--crtr-color-border);
949
- border-radius: var(--crtr-radius-small);
1273
+ padding: var(--crtr-cards-tag-padding, 0 var(--crtr-space-1));
1274
+ color: var(--crtr-cards-tag-text-color, var(--crtr-color-text-muted));
1275
+ font-size: var(--crtr-cards-tag-font-size, 0.75em);
1276
+ line-height: var(--crtr-cards-tag-line-height, 1.7);
1277
+ border: var(--crtr-cards-tag-border-width, 1px)
1278
+ var(--crtr-cards-tag-border-style, solid)
1279
+ var(--crtr-cards-tag-border-color, var(--crtr-color-border));
1280
+ border-radius: var(--crtr-cards-tag-radius, var(--crtr-radius-small));
950
1281
  }
951
1282
 
952
1283
  [part~="card"][part~="selected"] [part~="tag"] {
953
- color: var(--crtr-color-accent);
954
- background: color-mix(in srgb, var(--crtr-color-accent) 10%, transparent);
955
- border-color: color-mix(in srgb, var(--crtr-color-accent) 40%, transparent);
1284
+ color: var(--crtr-cards-tag-selected-text-color, var(--crtr-color-accent));
1285
+ background: var(--crtr-cards-tag-selected-fill, color-mix(in srgb, var(--crtr-color-accent) 10%, transparent));
1286
+ border-color: var(--crtr-cards-tag-selected-border-color, color-mix(in srgb, var(--crtr-color-accent) 45%, transparent));
956
1287
  }
957
1288
 
958
1289
  /* The affordance is quiet until you reach for it, and stays visible once a note lives
@@ -962,141 +1293,187 @@
962
1293
  display: flex;
963
1294
  align-items: center;
964
1295
  justify-content: center;
965
- width: calc(var(--crtr-font-size) * 1.6);
966
- height: calc(var(--crtr-font-size) * 1.6);
967
- padding: 0;
968
- color: var(--crtr-color-text-muted);
969
- background: none;
970
- border: none;
971
- border-radius: var(--crtr-radius-small);
1296
+ /* One knob: the affordance is a square, so its width and height are the same value. */
1297
+ width: var(--crtr-cards-comment-button-size, 1.5em);
1298
+ height: var(--crtr-cards-comment-button-size, 1.5em);
1299
+ padding: var(--crtr-cards-comment-button-padding, 0);
1300
+ color: var(--crtr-cards-comment-button-text-color, var(--crtr-color-text-muted));
1301
+ background: var(--crtr-cards-comment-button-fill, none);
1302
+ border: var(--crtr-cards-comment-button-border-width, 1px)
1303
+ var(--crtr-cards-comment-button-border-style, solid)
1304
+ var(--crtr-cards-comment-button-border-color, transparent);
1305
+ border-radius: var(--crtr-cards-comment-button-radius, var(--crtr-radius-small));
972
1306
  cursor: pointer;
973
- opacity: 0;
974
- transition: opacity 120ms ease, color 120ms ease, background-color 120ms ease;
1307
+ opacity: var(--crtr-cards-comment-button-resting-opacity, 0);
1308
+ transition: opacity var(--crtr-cards-comment-button-transition, var(--crtr-control-transition, 120ms ease)),
1309
+ color var(--crtr-cards-comment-button-transition, var(--crtr-control-transition, 120ms ease)),
1310
+ background-color var(--crtr-cards-comment-button-transition, var(--crtr-control-transition, 120ms ease));
975
1311
  }
976
1312
 
977
1313
  [part~="comment-button"] svg {
978
- width: calc(var(--crtr-font-size) * 0.95);
979
- height: calc(var(--crtr-font-size) * 0.95);
1314
+ width: var(--crtr-cards-comment-button-icon-size, 0.875em);
1315
+ height: var(--crtr-cards-comment-button-icon-size, 0.875em);
1316
+ fill: var(--crtr-cards-comment-button-icon-fill, none);
1317
+ stroke: var(--crtr-cards-comment-button-icon-stroke-color, currentColor);
1318
+ stroke-width: var(--crtr-cards-comment-button-icon-stroke-width, 2);
1319
+ stroke-linecap: var(--crtr-cards-comment-button-icon-line-cap, round);
1320
+ stroke-linejoin: var(--crtr-cards-comment-button-icon-line-join, round);
980
1321
  /* The glyph is never the event target: a repaint that swaps it mid-press would
981
1322
  otherwise leave mousedown and mouseup on different nodes and eat the click. */
982
1323
  pointer-events: none;
983
1324
  }
984
1325
 
985
1326
  [part~="comment-button"]:hover {
986
- color: var(--crtr-color-text);
987
- background: var(--crtr-color-surface-hover);
1327
+ color: var(--crtr-cards-comment-button-hover-text-color, var(--crtr-color-text));
1328
+ background: var(--crtr-cards-comment-button-hover-fill, var(--crtr-color-surface-hover));
988
1329
  }
989
1330
 
990
1331
  [part~="comment-button"][part~="has-comment"] {
991
- color: var(--crtr-color-accent);
1332
+ color: var(--crtr-cards-comment-button-noted-text-color, var(--crtr-color-accent));
992
1333
  }
993
1334
 
1335
+ ${u({scope:"cards-comment-button"},'[part~="comment-button"]')}
994
1336
  [part~="card"]:hover [part~="comment-button"],
995
1337
  [part~="card"]:focus-within [part~="comment-button"],
996
1338
  [part~="comment-button"]:focus-visible,
997
1339
  [part~="comment-button"][part~="has-comment"] {
998
- opacity: 1;
1340
+ opacity: var(--crtr-cards-comment-button-revealed-opacity, 1);
999
1341
  }
1000
1342
 
1001
1343
  [part~="comment-editor"] {
1002
1344
  display: grid;
1003
- gap: var(--crtr-space-2);
1345
+ gap: var(--crtr-cards-comment-editor-gap, var(--crtr-space-2));
1004
1346
  width: 100%;
1005
- padding: var(--crtr-space-2);
1006
- text-align: left;
1007
- background: var(--crtr-color-background);
1008
- border: 1px solid var(--crtr-color-border);
1009
- border-radius: var(--crtr-radius-small);
1347
+ padding: var(--crtr-cards-comment-editor-padding, var(--crtr-space-2));
1348
+ text-align: var(--crtr-cards-comment-editor-text-align, left);
1349
+ background: var(--crtr-cards-comment-editor-fill, var(--crtr-color-background));
1350
+ border: var(--crtr-cards-comment-editor-border-width, 1px)
1351
+ var(--crtr-cards-comment-editor-border-style, solid)
1352
+ var(--crtr-cards-comment-editor-border-color, var(--crtr-color-border));
1353
+ border-radius: var(--crtr-cards-comment-editor-radius, var(--crtr-radius-small));
1010
1354
  cursor: auto;
1011
1355
  }
1012
1356
 
1013
- [part~="comment-subject"],
1357
+ /* The editor's own prose, in the page's voice \u2014 not a caps-mono field label shouting a
1358
+ card id at someone who just clicked that card. */
1359
+ [part~="comment-subject"] {
1360
+ color: var(--crtr-cards-comment-subject-text-color, var(--crtr-color-text-muted));
1361
+ font-size: var(--crtr-cards-comment-subject-font-size, 0.875em);
1362
+ }
1363
+
1014
1364
  [part~="comment-hint"] {
1015
- color: var(--crtr-color-text-muted);
1016
- font-family: var(--crtr-font-mono);
1017
- font-size: calc(var(--crtr-font-size) * 0.72);
1018
- letter-spacing: 0.06em;
1019
- text-transform: uppercase;
1365
+ color: var(--crtr-cards-comment-hint-text-color, var(--crtr-color-text-muted));
1366
+ font-size: var(--crtr-cards-comment-hint-font-size, 0.875em);
1020
1367
  }
1021
1368
 
1369
+ ${S({scope:"cards-comment-input"},'[part~="comment-input"]')}
1022
1370
  [part~="comment-input"] {
1023
- box-sizing: border-box;
1024
- width: 100%;
1025
- min-height: 4.5em;
1026
- padding: var(--crtr-space-1) var(--crtr-space-2);
1027
- color: var(--crtr-color-text);
1028
- font: inherit;
1029
- background: var(--crtr-color-background);
1030
- border: 1px solid var(--crtr-color-border);
1031
- border-radius: var(--crtr-radius-small);
1371
+ min-height: var(--crtr-cards-comment-input-min-height, 4.5em);
1032
1372
  resize: vertical;
1033
1373
  }
1034
1374
 
1035
- [part~="comment-input"]:focus-visible {
1036
- outline: 2px solid var(--crtr-color-focus);
1037
- outline-offset: 1px;
1038
- }
1039
-
1040
1375
  [part~="comment-actions"] {
1041
1376
  display: flex;
1042
1377
  align-items: center;
1043
1378
  justify-content: space-between;
1044
- gap: var(--crtr-space-2);
1379
+ gap: var(--crtr-cards-comment-actions-gap, var(--crtr-space-2));
1045
1380
  }
1046
1381
 
1047
1382
  [part~="comment-buttons"] {
1048
1383
  display: flex;
1049
- gap: var(--crtr-space-1);
1050
- }
1051
-
1052
- [part~="comment-cancel"],
1053
- [part~="comment-save"] {
1054
- padding: var(--crtr-space-1) var(--crtr-space-2);
1055
- font: inherit;
1056
- font-size: calc(var(--crtr-font-size) * 0.9);
1057
- border-radius: var(--crtr-radius-small);
1058
- cursor: pointer;
1384
+ gap: var(--crtr-cards-comment-buttons-gap, var(--crtr-space-1));
1059
1385
  }
1060
1386
 
1061
1387
  [part~="comment-cancel"] {
1062
- color: var(--crtr-color-text-muted);
1063
- background: none;
1064
- border: 1px solid transparent;
1388
+ padding: var(--crtr-cards-comment-cancel-padding, var(--crtr-space-1) var(--crtr-space-2));
1389
+ color: var(--crtr-cards-comment-cancel-text-color, var(--crtr-color-text-muted));
1390
+ font: var(--crtr-cards-comment-cancel-font, inherit);
1391
+ font-size: var(--crtr-cards-comment-cancel-font-size, 0.875em);
1392
+ background: var(--crtr-cards-comment-cancel-fill, none);
1393
+ border: var(--crtr-cards-comment-cancel-border-width, 1px)
1394
+ var(--crtr-cards-comment-cancel-border-style, solid)
1395
+ var(--crtr-cards-comment-cancel-border-color, transparent);
1396
+ border-radius: var(--crtr-cards-comment-cancel-radius, var(--crtr-radius-small));
1397
+ cursor: pointer;
1398
+ transition: color var(--crtr-cards-comment-cancel-transition, var(--crtr-control-transition, 120ms ease)),
1399
+ background-color var(--crtr-cards-comment-cancel-transition, var(--crtr-control-transition, 120ms ease)),
1400
+ border-color var(--crtr-cards-comment-cancel-transition, var(--crtr-control-transition, 120ms ease));
1065
1401
  }
1066
1402
 
1067
1403
  [part~="comment-cancel"]:hover {
1068
- color: var(--crtr-color-text);
1069
- background: var(--crtr-color-surface-hover);
1404
+ color: var(--crtr-cards-comment-cancel-hover-text-color, var(--crtr-color-text));
1405
+ background: var(--crtr-cards-comment-cancel-hover-fill, var(--crtr-color-surface-hover));
1070
1406
  }
1071
1407
 
1072
1408
  [part~="comment-save"] {
1073
- color: var(--crtr-color-accent-contrast);
1074
- background: var(--crtr-color-accent);
1075
- border: 1px solid var(--crtr-color-accent);
1409
+ padding: var(--crtr-cards-comment-save-padding, var(--crtr-space-1) var(--crtr-space-2));
1410
+ color: var(--crtr-cards-comment-save-text-color, var(--crtr-color-accent-contrast));
1411
+ font: var(--crtr-cards-comment-save-font, inherit);
1412
+ font-size: var(--crtr-cards-comment-save-font-size, 0.875em);
1413
+ background: var(--crtr-cards-comment-save-fill, var(--crtr-color-accent));
1414
+ border: var(--crtr-cards-comment-save-border-width, 1px)
1415
+ var(--crtr-cards-comment-save-border-style, solid)
1416
+ var(--crtr-cards-comment-save-border-color, var(--crtr-color-accent));
1417
+ border-radius: var(--crtr-cards-comment-save-radius, var(--crtr-radius-small));
1418
+ cursor: pointer;
1419
+ transition: color var(--crtr-cards-comment-save-transition, var(--crtr-control-transition, 120ms ease)),
1420
+ background-color var(--crtr-cards-comment-save-transition, var(--crtr-control-transition, 120ms ease)),
1421
+ border-color var(--crtr-cards-comment-save-transition, var(--crtr-control-transition, 120ms ease));
1422
+ }
1423
+
1424
+ /* Mixing toward the text colour darkens on a light token set and lightens on a dark one \u2014
1425
+ a brightness filter moves the wrong way on one of them. */
1426
+ [part~="comment-save"]:hover {
1427
+ background: var(--crtr-cards-comment-save-hover-fill, color-mix(in srgb, var(--crtr-color-accent) 88%, var(--crtr-color-text)));
1428
+ border-color: var(--crtr-cards-comment-save-hover-border-color, color-mix(in srgb, var(--crtr-color-accent) 88%, var(--crtr-color-text)));
1429
+ }
1430
+
1431
+ ${u({scope:"cards-comment-cancel"},'[part~="comment-cancel"]')}
1432
+ ${u({scope:"cards-comment-save"},'[part~="comment-save"]')}
1433
+ /* These sit in the flow of the page rather than above it, so they carry no elevation \u2014
1434
+ a shadow in this bundle means floating (a popover, an editor). Each state keeps its own
1435
+ scope even though their kit defaults match: one scope never names two different parts. */
1436
+ [part~="unavailable"] {
1437
+ padding: var(--crtr-cards-unavailable-padding, var(--crtr-space-3));
1438
+ color: var(--crtr-cards-unavailable-text-color, var(--crtr-color-text-muted));
1439
+ background: var(--crtr-cards-unavailable-fill, var(--crtr-color-surface));
1440
+ border: var(--crtr-cards-unavailable-border-width, 1px)
1441
+ var(--crtr-cards-unavailable-border-style, solid)
1442
+ var(--crtr-cards-unavailable-border-color, var(--crtr-color-border));
1443
+ border-radius: var(--crtr-cards-unavailable-radius, var(--crtr-radius-medium));
1444
+ }
1445
+
1446
+ [part~="empty"] {
1447
+ padding: var(--crtr-cards-empty-padding, var(--crtr-space-3));
1448
+ color: var(--crtr-cards-empty-text-color, var(--crtr-color-text-muted));
1449
+ background: var(--crtr-cards-empty-fill, var(--crtr-color-surface));
1450
+ border: var(--crtr-cards-empty-border-width, 1px)
1451
+ var(--crtr-cards-empty-border-style, solid)
1452
+ var(--crtr-cards-empty-border-color, var(--crtr-color-border));
1453
+ border-radius: var(--crtr-cards-empty-radius, var(--crtr-radius-medium));
1076
1454
  }
1077
1455
 
1078
- [part~="unavailable"],
1079
- [part~="empty"],
1080
1456
  [part~="loading"] {
1081
- padding: var(--crtr-space-3);
1082
- color: var(--crtr-color-text-muted);
1083
- background: var(--crtr-color-surface);
1084
- border: 1px solid var(--crtr-color-border);
1085
- border-radius: var(--crtr-radius-medium);
1086
- box-shadow: var(--crtr-shadow);
1457
+ padding: var(--crtr-cards-loading-padding, var(--crtr-space-3));
1458
+ color: var(--crtr-cards-loading-text-color, var(--crtr-color-text-muted));
1459
+ background: var(--crtr-cards-loading-fill, var(--crtr-color-surface));
1460
+ border: var(--crtr-cards-loading-border-width, 1px)
1461
+ var(--crtr-cards-loading-border-style, solid)
1462
+ var(--crtr-cards-loading-border-color, var(--crtr-color-border));
1463
+ border-radius: var(--crtr-cards-loading-radius, var(--crtr-radius-medium));
1087
1464
  }
1088
1465
 
1089
1466
  [part~="kind"] {
1090
- color: var(--crtr-color-text);
1091
- font-family: var(--crtr-font-mono);
1467
+ color: var(--crtr-cards-kind-text-color, var(--crtr-color-text));
1468
+ font-family: var(--crtr-cards-kind-font-family, var(--crtr-font-mono));
1092
1469
  }
1093
1470
 
1094
1471
  [part~="reason"] {
1095
1472
  display: block;
1096
- margin-top: var(--crtr-space-1);
1097
- font-size: calc(var(--crtr-font-size) * 0.85);
1473
+ margin-top: var(--crtr-cards-reason-gap, var(--crtr-space-1));
1474
+ font-size: var(--crtr-cards-reason-font-size, 0.875em);
1098
1475
  }
1099
- `,de=new Set(["id","title","subtitle","body","tag"]);function le(o){if(o===null||typeof o!="object"||Array.isArray(o))return null;let t=o;if(typeof t.id!="string"||t.id===""||typeof t.title!="string"||t.title==="")return null;for(let e of["subtitle","body","tag"])if(t[e]!==void 0&&typeof t[e]!="string")return null;for(let e of Object.keys(t))if(!de.has(e))return null;return{id:t.id,title:t.title,subtitle:t.subtitle,body:t.body,tag:t.tag}}function Ht(o){if(!Array.isArray(o))return null;let t=[],e=new Set;for(let r of o){let n=le(r);if(n===null||e.has(n.id))return null;e.add(n.id),t.push(n)}return t}var ue=new Set(["cards","source","mode","columns"]);function pe(o){for(let i of Object.keys(o))if(!ue.has(i))return{status:"invalid",reason:`unknown config property "${i}"`};let t=o.mode;if(t!=="single"&&t!=="multi")return{status:"invalid",reason:'mode must be "single" or "multi"'};let e=o.source;if(e!==void 0&&typeof e!="string")return{status:"invalid",reason:"source must be a string"};let r=o.columns;if(r!==void 0&&r!==2&&r!==3)return{status:"invalid",reason:"columns must be 2 or 3"};let n;if(o.cards!==void 0){if(e!==void 0)return{status:"invalid",reason:"cards and source are mutually exclusive"};let i=Ht(o.cards);if(i===null)return{status:"invalid",reason:"cards must be a list of uniquely identified cards"};n=i}return{status:"ok",config:{cards:n,source:e,mode:t,columns:r}}}function me(o){return o instanceof HTMLTextAreaElement||o instanceof HTMLElement&&o.isContentEditable?!0:o instanceof HTMLInputElement?o.type!=="checkbox"&&o.type!=="radio":!1}var lt="http://www.w3.org/2000/svg";function he(o){let t=document.createElementNS(lt,"svg");t.setAttribute("viewBox","0 0 24 24"),t.setAttribute("fill","none"),t.setAttribute("stroke","currentColor"),t.setAttribute("stroke-width","2"),t.setAttribute("stroke-linecap","round"),t.setAttribute("stroke-linejoin","round"),t.setAttribute("aria-hidden","true");let e=document.createElementNS(lt,"path");e.setAttribute("d","M21 15a2 2 0 0 1-2 2H7l-4 4V5a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2z"),t.append(e);let r=o?[["7","9","17","9"],["7","13","13","13"]]:[["12","7","12","13"],["9","10","15","10"]];for(let[n,i,a,s]of r){let c=document.createElementNS(lt,"line");c.setAttribute("x1",n??"0"),c.setAttribute("y1",i??"0"),c.setAttribute("x2",a??"0"),c.setAttribute("y2",s??"0"),t.append(c)}return t}var Rt=0,ut=class extends HTMLElement{#n=document.createElement("div");#d;#s=null;#t=[];#r;#e=[];#o=[];#l=null;#c=new Map;#a=null;#u=null;#i=0;constructor(){super(),Rt+=1,this.#d=`crtr-cards-${Rt}`;let t=this.attachShadow({mode:"open"}),e=document.createElement("style");e.textContent=ce,this.#n.part.add("container"),this.#n.addEventListener("keydown",r=>this.#f(r)),t.append(e,this.#n)}connectedCallback(){this.#i+=1;let t=this.#i,e=k(this);if(e.status!=="ok"){this.#p(e.reason);return}let r=pe(e.config);if(r.status!=="ok"){this.#p(r.reason);return}this.#s=r.config,this.#r=N(this);let n=r.config.source;if(n===void 0){this.#t=r.config.cards??[],this.#x(),this.#w();return}this.#g("loading","Loading cards\u2026"),this.#h(n,t)}disconnectedCallback(){this.#i+=1}async#h(t,e){let r=await G(t);if(e!==this.#i)return;if(r.status!=="ok"){this.#p(r.reason);return}let n=Ht(r.data);if(n===null){this.#p(`source "${t}" is not a list of cards`);return}this.#t=n,this.#x(),this.#w()}#x(){if(this.#r===void 0)return;let t=I(this.#r);if(t===void 0)return;let e=this.#t.map(r=>r.id).filter(r=>B(t.selectedCardIds).includes(r));this.#e=this.#s?.mode==="single"?e.slice(0,1):e,this.#o=H(t.comments)}#p(t){this.#c.clear(),this.#a=null,this.#u=null;let e=document.createElement("div");e.part.add("unavailable"),e.setAttribute("role","status");let r=document.createElement("span");r.part.add("kind"),r.textContent="cards";let n=document.createElement("span");n.part.add("reason"),n.textContent=t,e.append("Component unavailable: ",r,n),this.#n.replaceChildren(e)}#g(t,e){let r=document.createElement("div");r.part.add(t),r.setAttribute("role","status"),r.textContent=e,this.#n.replaceChildren(r)}#w(){let t=this.#s;if(t===null)return;this.#c.clear(),this.#a=null,this.#u=null;let e=new Set(this.#t.map(n=>n.id));if(this.#e=this.#e.filter(n=>e.has(n)),this.#o=this.#o.filter(n=>n.anchor.kind!=="card"||e.has(n.anchor.cardId)),this.#t.length===0){this.#g("empty","No cards to choose from.");return}let r=document.createElement("div");r.part.add("grid"),t.columns===3&&(r.dataset.columns="3"),r.append(...this.#t.map(n=>this.#y(n,t.mode,this.#d))),this.#n.replaceChildren(r),this.#v()}#y(t,e,r){let n=document.createElement("div");n.part.add("card"),n.dataset.cardId=t.id;let i=document.createElement("div");i.part.add("card-header");let a=document.createElement("label");a.part.add("card-label");let s=document.createElement("input");s.part.add("control"),s.type=e==="single"?"radio":"checkbox",s.name=r,s.value=t.id,s.addEventListener("change",()=>this.#A(t.id,s.checked)),s.addEventListener("focus",()=>this.#m(t.id,!1));let c=document.createElement("span");c.part.add("card-heading");let d=document.createElement("span");if(d.part.add("card-title"),d.textContent=t.title,c.append(d),t.subtitle!==void 0&&t.subtitle!==""){let m=document.createElement("span");m.part.add("card-subtitle"),m.textContent=t.subtitle,c.append(m)}let u=document.createElement("button");if(u.type="button",u.part.add("comment-button"),u.addEventListener("click",m=>{m.stopPropagation(),this.#m(t.id,!1),this.#T({kind:"card",cardId:t.id},t.title,n,null)}),a.append(s,c),i.append(a,u),n.append(i),t.body!==void 0&&t.body!==""){let m=document.createElement("p");m.part.add("card-body"),m.textContent=t.body,n.append(m)}let g=null;return t.tag!==void 0&&t.tag!==""&&(g=document.createElement("span"),g.part.add("tag"),g.textContent=t.tag,n.append(g)),n.addEventListener("mouseenter",()=>this.#m(t.id,!1)),n.addEventListener("mouseleave",()=>{this.#l===t.id&&this.#m(null,!1)}),n.addEventListener("focusin",()=>this.#m(t.id,!1)),this.#c.set(t.id,{root:n,control:s,commentButton:u,tag:g}),n}#v(){let t=this.#s?.mode??"multi",e=t==="single"?this.#e[0]??this.#t[0]?.id:void 0;for(let r of this.#t){let n=this.#c.get(r.id);if(n===void 0)continue;let i=this.#e.includes(r.id);n.root.part.toggle("selected",i),n.root.part.toggle("active",this.#l===r.id),n.control.checked=i,n.control.tabIndex=t==="single"&&r.id!==e?-1:0;let a=b(this.#o,{kind:"card",cardId:r.id});this.#k(n.commentButton,a,r.title)}}#k(t,e,r){let n=e!==void 0,i=t.part.contains("has-comment")!==n;t.part.toggle("has-comment",n),t.setAttribute("aria-label",n?`Edit comment on ${r}`:`Comment on ${r}`),n?t.title=e.text:t.removeAttribute("title"),(i||t.childElementCount===0)&&t.replaceChildren(he(n))}#m(t,e){this.#l===t&&!e||(this.#l=t,this.#v(),e&&t!==null&&this.#c.get(t)?.control.focus())}#A(t,e){if(this.#s!==null){if(this.#s.mode==="single")this.#e=[t];else{let r=e?[...this.#e,t]:this.#e.filter(n=>n!==t);this.#e=this.#t.map(n=>n.id).filter(n=>r.includes(n))}this.#v(),this.#M()}}#f(t){if(t.metaKey||t.ctrlKey||t.altKey||me(t.target))return;let e=this.#t.map(i=>i.id);if(e.length===0)return;let r=t.key.toLowerCase(),n=this.#l??this.#e[this.#e.length-1]??e[0]??"";if(r==="j"||r==="k"){t.preventDefault();let i=Math.max(0,e.indexOf(n)),s=e[(i+(r==="j"?1:-1)+e.length)%e.length];s!==void 0&&this.#m(s,!0);return}if(r==="x"){t.preventDefault(),this.#A(n,this.#s?.mode==="single"?!0:!this.#e.includes(n));return}if(r==="c"){t.preventDefault();let i=this.#t.find(s=>s.id===n),a=this.#c.get(n);if(i===void 0||a===void 0)return;this.#m(n,!1),this.#T({kind:"card",cardId:i.id},i.title,a.root,null)}}#T(t,e,r,n){if(r===null)return;let i=this.#a?.anchor,a=i!==void 0&&i.kind===t.kind&&(t.kind!=="card"||i.kind==="card"&&i.cardId===t.cardId);this.#b(!1),!a&&this.#E({anchor:t,target:e,mount:r,after:n})}#E(t){let e=document.createElement("div");e.part.add("comment-editor"),e.addEventListener("click",u=>u.stopPropagation());let r=document.createElement("p");r.part.add("comment-subject"),r.textContent=`Comment on ${t.target}`;let n=document.createElement("textarea");n.part.add("comment-input"),n.placeholder="What should the agent know about this?",n.value=b(this.#o,t.anchor)?.text??"";let i=document.createElement("div");i.part.add("comment-actions");let a=document.createElement("span");a.part.add("comment-hint"),a.textContent=b(this.#o,t.anchor)!==void 0?"empty to delete":"\u2318\u21B5 to save";let s=document.createElement("div");s.part.add("comment-buttons");let c=document.createElement("button");c.type="button",c.part.add("comment-cancel"),c.textContent="Cancel",c.addEventListener("click",()=>this.#b(!0));let d=document.createElement("button");d.type="button",d.part.add("comment-save"),d.textContent="Save",d.addEventListener("click",()=>this.#C(n.value)),s.append(c,d),i.append(a,s),n.addEventListener("keydown",u=>{if(u.key==="Enter"&&(u.metaKey||u.ctrlKey)){u.preventDefault(),this.#C(n.value);return}u.key==="Escape"&&(u.preventDefault(),this.#b(!0))}),e.append(r,n,i),t.after!==null?t.after.after(e):t.mount.append(e),this.#a=t,this.#u=e,n.focus()}#b(t){let e=this.#a;this.#u?.remove(),this.#u=null,this.#a=null,!(!t||e===null)&&e.anchor.kind==="card"&&this.#c.get(e.anchor.cardId)?.control.focus()}#C(t){let e=this.#a;e!==null&&(this.#o=R(this.#o,e.anchor,t),this.#b(!0),this.#v(),this.#M())}#I(){return{selectedCardIds:[...this.#e],comments:this.#o.map(t=>({...t}))}}#M(){this.#r!==void 0&&$(this.#r,this.#I())}};v("crtr-cards",ut);var W=["var(--crtr-chart-1)","var(--crtr-chart-2)","var(--crtr-chart-3)","var(--crtr-chart-4)","var(--crtr-chart-5)"],fe="http://www.w3.org/2000/svg",q=260,$t=12,ge=12,be=28,ve=5,It=88,xe=5.8,Nt=14,ye=/^\d{4}-\d{2}-\d{2}(?:[T ]|$)/,Ee=/^\d{4}-\d{2}-\d{2}$/,we=`
1476
+ `,ze=new Set(["id","title","subtitle","body","tag"]);function Oe(n){if(n===null||typeof n!="object"||Array.isArray(n))return null;let t=n;if(typeof t.id!="string"||t.id===""||typeof t.title!="string"||t.title==="")return null;for(let e of["subtitle","body","tag"])if(t[e]!==void 0&&typeof t[e]!="string")return null;for(let e of Object.keys(t))if(!ze.has(e))return null;return{id:t.id,title:t.title,subtitle:t.subtitle,body:t.body,tag:t.tag}}function Ie(n){if(!Array.isArray(n))return null;let t=[],e=new Set;for(let r of n){let o=Oe(r);if(o===null||e.has(o.id))return null;e.add(o.id),t.push(o)}return t}var Ne=new Set(["label","cards","mode","columns"]),Yt="prompt-label";function je(n){for(let a of Object.keys(n))if(!Ne.has(a))return{status:"invalid",reason:`unknown config property "${a}"`};let t=n.label;if(t!==void 0&&typeof t!="string")return{status:"invalid",reason:"label must be a string"};let e=n.mode;if(e!=="single"&&e!=="multi")return{status:"invalid",reason:'mode must be "single" or "multi"'};let r=n.columns;if(r!==void 0&&r!==2&&r!==3)return{status:"invalid",reason:"columns must be 2 or 3"};let o;if(n.cards!==void 0){let a=Ie(n.cards);if(a===null)return{status:"invalid",reason:"cards must be a list of uniquely identified cards"};o=a}return{status:"ok",config:{label:t,cards:o,mode:e,columns:r}}}function Be(n){return n instanceof HTMLTextAreaElement||n instanceof HTMLElement&&n.isContentEditable?!0:n instanceof HTMLInputElement?n.type!=="checkbox"&&n.type!=="radio":!1}var yt="http://www.w3.org/2000/svg";function De(n){let t=document.createElementNS(yt,"svg");t.setAttribute("viewBox","0 0 24 24"),t.setAttribute("aria-hidden","true");let e=document.createElementNS(yt,"path");e.setAttribute("d","M21 15a2 2 0 0 1-2 2H7l-4 4V5a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2z"),t.append(e);let r=n?[["7","9","17","9"],["7","13","13","13"]]:[["12","7","12","13"],["9","10","15","10"]];for(let[o,a,i,s]of r){let c=document.createElementNS(yt,"line");c.setAttribute("x1",o??"0"),c.setAttribute("y1",a??"0"),c.setAttribute("x2",i??"0"),c.setAttribute("y2",s??"0"),t.append(c)}return t}function Pe(n){if(n===void 0||n==="")return null;let t=document.createElement("p");return t.part.add("label"),t.id=Yt,t.textContent=n,t}var Vt=0,wt=class extends HTMLElement{static observedAttributes=["inert"];#o=document.createElement("div");#i;#a=null;#n=null;#e=[];#r;#t=[];#h=[];#c=null;#s=new Map;#l=null;#d=null;constructor(){super(),Vt+=1,this.#i=`crtr-cards-${Vt}`;let t=this.attachShadow({mode:"open"}),e=document.createElement("style");e.textContent=He,this.#o.part.add("container"),this.#o.addEventListener("keydown",r=>this.#A(r)),t.append(e,this.#o)}connectedCallback(){let t=T(this);if(t.status!=="ok"){this.#E(t.reason);return}let e=je(t.config);if(e.status!=="ok"){this.#E(e.reason);return}this.#a=e.config,this.#r=D(this),this.#r!==void 0&&B(this,this.#r,()=>this.#k()),this.#n=Pe(e.config.label),this.#e=e.config.cards??[],this.#m(),this.#p()}attributeChangedCallback(){this.isConnected&&this.#u()}#u(){let t=f(this);j(this.#o,t),t&&this.#l!==null&&this.#v(!1)}#m(){if(this.#r===void 0)return;let t=N(this.#r);if(t===void 0)return;let e=this.#e.map(r=>r.id).filter(r=>q(t.selectedCardIds).includes(r));this.#t=this.#a?.mode==="single"?e.slice(0,1):e,this.#h=O(t.comments)}#E(t){this.#s.clear(),this.#l=null,this.#d=null;let e=document.createElement("div");e.part.add("unavailable"),e.setAttribute("role","status");let r=document.createElement("span");r.part.add("kind"),r.textContent="cards";let o=document.createElement("span");o.part.add("reason"),o.textContent=t,e.append("Component unavailable: ",r,o),this.#g(e)}#L(t,e){let r=document.createElement("div");r.part.add(t),r.setAttribute("role","status"),r.textContent=e,this.#g(r)}#g(t){this.#n===null?this.#o.replaceChildren(t):this.#o.replaceChildren(this.#n,t)}#p(){let t=this.#a;if(t===null)return;this.#s.clear(),this.#l=null,this.#d=null;let e=new Set(this.#e.map(o=>o.id));if(this.#t=this.#t.filter(o=>e.has(o)),this.#h=this.#h.filter(o=>o.anchor.kind!=="card"||e.has(o.anchor.cardId)),this.#e.length===0){this.#L("empty","No cards to choose from.");return}let r=document.createElement("div");r.part.add("grid"),t.columns===3&&(r.dataset.columns="3"),this.#n!==null&&(r.setAttribute("role",t.mode==="single"?"radiogroup":"group"),r.setAttribute("aria-labelledby",Yt)),r.append(...this.#e.map(o=>this.#T(o,t.mode,this.#i))),this.#g(r),this.#b()}#T(t,e,r){let o=document.createElement("div");o.part.add("card"),o.dataset.cardId=t.id;let a=document.createElement("div");a.part.add("card-header");let i=document.createElement("label");i.part.add("card-label");let s=document.createElement("input");s.part.add("control"),s.type=e==="single"?"radio":"checkbox",s.name=r,s.value=t.id,s.addEventListener("change",()=>this.#f(t.id,s.checked)),s.addEventListener("focus",()=>this.#S(t.id,!1));let c=document.createElement("span");c.part.add("card-heading");let l=document.createElement("span");if(l.part.add("card-title"),l.textContent=t.title,c.append(l),t.subtitle!==void 0&&t.subtitle!==""){let p=document.createElement("span");p.part.add("card-subtitle"),p.textContent=t.subtitle,c.append(p)}let h;if(L(this.#r)&&(h=document.createElement("button"),h.type="button",h.part.add("comment-button"),h.addEventListener("click",p=>{p.stopPropagation(),this.#S(t.id,!1),this.#w({kind:"card",cardId:t.id},t.title,o,null)})),i.append(s,c),a.append(i),h!==void 0&&a.append(h),o.append(a),t.body!==void 0&&t.body!==""){let p=document.createElement("p");p.part.add("card-body"),p.textContent=t.body,o.append(p)}let g=null;return t.tag!==void 0&&t.tag!==""&&(g=document.createElement("span"),g.part.add("tag"),g.textContent=t.tag,o.append(g)),o.addEventListener("mouseenter",()=>this.#S(t.id,!1)),o.addEventListener("mouseleave",()=>{this.#c===t.id&&this.#S(null,!1)}),o.addEventListener("focusin",()=>this.#S(t.id,!1)),o.addEventListener("click",p=>{s.disabled||p.composedPath().includes(i)||document.getSelection()?.isCollapsed!==!1&&(this.#S(t.id,!1),this.#f(t.id,!this.#t.includes(t.id)))}),this.#s.set(t.id,{root:o,control:s,...h===void 0?{}:{commentButton:h},tag:g}),o}#b(){let t=this.#a?.mode??"multi",e=t==="single"?this.#t[0]??this.#e[0]?.id:void 0;for(let r of this.#e){let o=this.#s.get(r.id);if(o===void 0)continue;let a=this.#t.includes(r.id);o.root.part.toggle("selected",a),o.root.part.toggle("active",this.#c===r.id),o.control.checked=a,o.control.tabIndex=t==="single"&&r.id!==e?-1:0;let i=y(this.#h,{kind:"card",cardId:r.id});o.commentButton!==void 0&&this.#y(o.commentButton,i,r.title)}this.#u()}#y(t,e,r){let o=e!==void 0,a=t.part.contains("has-comment")!==o;t.part.toggle("has-comment",o),t.setAttribute("aria-label",o?`Edit comment on ${r}`:`Comment on ${r}`),o?t.title=e.text:t.removeAttribute("title"),(a||t.childElementCount===0)&&t.replaceChildren(De(o))}#S(t,e){this.#c===t&&!e||(this.#c=t,this.#b(),e&&t!==null&&this.#s.get(t)?.control.focus())}#f(t,e){if(!(this.#a===null||f(this))){if(this.#a.mode==="single")this.#t=[t];else{let r=e?[...this.#t,t]:this.#t.filter(o=>o!==t);this.#t=this.#e.map(o=>o.id).filter(o=>r.includes(o))}this.#b(),this.#M()}}#A(t){if(t.metaKey||t.ctrlKey||t.altKey||Be(t.target))return;let e=this.#e.map(a=>a.id);if(e.length===0)return;let r=t.key.toLowerCase(),o=this.#c??this.#t[this.#t.length-1]??e[0]??"";if(r==="j"||r==="k"){t.preventDefault();let a=Math.max(0,e.indexOf(o)),s=e[(a+(r==="j"?1:-1)+e.length)%e.length];s!==void 0&&this.#S(s,!0);return}if(r==="x"){t.preventDefault(),this.#f(o,this.#a?.mode==="single"?!0:!this.#t.includes(o));return}if(r==="c"){t.preventDefault();let a=this.#e.find(s=>s.id===o),i=this.#s.get(o);if(a===void 0||i?.commentButton===void 0)return;this.#S(o,!1),this.#w({kind:"card",cardId:a.id},a.title,i.root,null)}}#w(t,e,r,o){if(r===null||!L(this.#r)||f(this))return;let a=this.#l?.anchor,i=a!==void 0&&a.kind===t.kind&&(t.kind!=="card"||a.kind==="card"&&a.cardId===t.cardId);this.#v(!1),!i&&this.#C({anchor:t,target:e,mount:r,after:o})}#C(t){let e=document.createElement("div");e.part.add("comment-editor"),e.addEventListener("click",h=>h.stopPropagation());let r=document.createElement("p");r.part.add("comment-subject"),r.textContent=`Comment on ${t.target}`;let o=document.createElement("textarea");o.part.add("comment-input"),o.placeholder="What should the agent know about this?",o.value=y(this.#h,t.anchor)?.text??"";let a=document.createElement("div");a.part.add("comment-actions");let i=document.createElement("span");i.part.add("comment-hint"),i.textContent=y(this.#h,t.anchor)!==void 0?"empty to delete":"\u2318\u21B5 to save";let s=document.createElement("div");s.part.add("comment-buttons");let c=document.createElement("button");c.type="button",c.part.add("comment-cancel"),c.textContent="Cancel",c.addEventListener("click",()=>this.#v(!0));let l=document.createElement("button");l.type="button",l.part.add("comment-save"),l.textContent="Save",l.addEventListener("click",()=>this.#x(o.value)),s.append(c,l),a.append(i,s),o.addEventListener("keydown",h=>{if(h.key==="Enter"&&(h.metaKey||h.ctrlKey)){h.preventDefault(),this.#x(o.value);return}h.key==="Escape"&&(h.preventDefault(),this.#v(!0))}),e.append(r,o,a),t.after!==null?t.after.after(e):t.mount.append(e),this.#l=t,this.#d=e,o.focus()}#v(t){let e=this.#l;this.#d?.remove(),this.#d=null,this.#l=null,!(!t||e===null)&&e.anchor.kind==="card"&&this.#s.get(e.anchor.cardId)?.control.focus()}#x(t){let e=this.#l;e===null||f(this)||(this.#h=z(this.#h,e.anchor,t),this.#v(!0),this.#b(),this.#M())}#k(){return{selectedCardIds:[...this.#t],comments:this.#h.map(t=>({...t}))}}#M(){this.#r!==void 0&&M(this.#r,this.#k())}};w("crtr-cards",wt);var V=["var(--crtr-chart-1)","var(--crtr-chart-2)","var(--crtr-chart-3)","var(--crtr-chart-4)","var(--crtr-chart-5)"],_e="http://www.w3.org/2000/svg",kt=260,Xt=12,Ke=12,qe=28,Ge=5,Jt=88,We=5.8,Qt=14,Fe=/^\d{4}-\d{2}-\d{2}(?:[T ]|$)/,Ue=/^\d{4}-\d{2}-\d{2}$/,Ve=`
1100
1477
  :host {
1101
1478
  display: block;
1102
1479
  }
@@ -1104,36 +1481,38 @@
1104
1481
  [part="container"] {
1105
1482
  display: flex;
1106
1483
  flex-direction: column;
1107
- gap: var(--crtr-space-2);
1484
+ gap: var(--crtr-chart-container-gap, var(--crtr-space-2));
1108
1485
  width: 100%;
1109
1486
  }
1110
1487
 
1111
1488
  [part="title"] {
1112
- color: var(--crtr-color-text);
1113
- font-weight: 500;
1489
+ color: var(--crtr-chart-title-text-color, var(--crtr-color-text));
1490
+ font-weight: var(--crtr-chart-title-font-weight, 500);
1114
1491
  }
1115
1492
 
1116
1493
  [part="legend"] {
1117
1494
  display: flex;
1118
1495
  flex-wrap: wrap;
1119
1496
  align-items: center;
1120
- gap: var(--crtr-space-1) var(--crtr-space-4);
1121
- color: var(--crtr-color-text-muted);
1122
- font-size: calc(var(--crtr-font-size) * 0.85);
1497
+ gap: var(--crtr-chart-legend-gap, var(--crtr-space-1) var(--crtr-space-4));
1498
+ color: var(--crtr-chart-legend-text-color, var(--crtr-color-text-muted));
1499
+ font-size: var(--crtr-chart-legend-font-size, 0.875em);
1123
1500
  }
1124
1501
 
1125
1502
  [part="legend-item"] {
1126
1503
  display: flex;
1127
1504
  align-items: center;
1128
- gap: var(--crtr-space-1);
1505
+ gap: var(--crtr-chart-legend-item-gap, var(--crtr-space-1));
1129
1506
  min-width: 0;
1130
1507
  }
1131
1508
 
1509
+ /* Sized against the legend's own text, not a spacing token doing a sizing job. One knob:
1510
+ the swatch is a square, so its width and height are the same value. */
1132
1511
  [part="legend-swatch"] {
1133
1512
  flex: none;
1134
- width: calc(var(--crtr-space-2) - 1px);
1135
- height: calc(var(--crtr-space-2) - 1px);
1136
- border-radius: 2px;
1513
+ width: var(--crtr-chart-legend-swatch-size, 0.75em);
1514
+ height: var(--crtr-chart-legend-swatch-size, 0.75em);
1515
+ border-radius: var(--crtr-chart-legend-swatch-radius, calc(var(--crtr-radius-small) * 0.5));
1137
1516
  }
1138
1517
 
1139
1518
  [part="legend-label"] {
@@ -1148,53 +1527,93 @@
1148
1527
 
1149
1528
  [part="chart"] {
1150
1529
  display: block;
1530
+ height: var(--crtr-chart-plot-height, 260px);
1151
1531
  overflow: visible;
1152
1532
  }
1153
1533
 
1534
+ /* Waiting for data and having none hold the same space, but each stays in its own scope:
1535
+ one scope never names two different parts. */
1154
1536
  [part="empty"] {
1155
1537
  display: flex;
1156
1538
  align-items: center;
1157
1539
  justify-content: center;
1158
- padding: 0 var(--crtr-space-4);
1159
- color: var(--crtr-color-text-muted);
1160
- border: 1px dashed var(--crtr-color-border);
1161
- border-radius: var(--crtr-radius-medium);
1540
+ padding: var(--crtr-chart-empty-padding, 0 var(--crtr-space-4));
1541
+ color: var(--crtr-chart-empty-text-color, var(--crtr-color-text-muted));
1542
+ font-size: var(--crtr-chart-empty-font-size, 0.875em);
1543
+ border: var(--crtr-chart-empty-border-width, 1px)
1544
+ var(--crtr-chart-empty-border-style, dashed)
1545
+ var(--crtr-chart-empty-border-color, var(--crtr-color-border));
1546
+ border-radius: var(--crtr-chart-empty-radius, var(--crtr-radius-medium));
1162
1547
  }
1163
1548
 
1164
1549
  [part="status"] {
1165
1550
  display: flex;
1166
1551
  align-items: center;
1167
1552
  justify-content: center;
1168
- padding: 0 var(--crtr-space-4);
1169
- color: var(--crtr-color-text-muted);
1170
- border: 1px dashed var(--crtr-color-border);
1171
- border-radius: var(--crtr-radius-medium);
1553
+ padding: var(--crtr-chart-status-padding, 0 var(--crtr-space-4));
1554
+ color: var(--crtr-chart-status-text-color, var(--crtr-color-text-muted));
1555
+ font-size: var(--crtr-chart-status-font-size, 0.875em);
1556
+ border: var(--crtr-chart-status-border-width, 1px)
1557
+ var(--crtr-chart-status-border-style, dashed)
1558
+ var(--crtr-chart-status-border-color, var(--crtr-color-border));
1559
+ border-radius: var(--crtr-chart-status-radius, var(--crtr-radius-medium));
1172
1560
  }
1173
1561
 
1562
+ /* Flat: this sits in the flow of the page. A shadow in this bundle means floating. */
1174
1563
  [part="unavailable"] {
1175
- padding: var(--crtr-space-3);
1176
- color: var(--crtr-color-text-muted);
1177
- background: var(--crtr-color-surface);
1178
- border: 1px solid var(--crtr-color-border);
1179
- border-radius: var(--crtr-radius-medium);
1180
- box-shadow: var(--crtr-shadow);
1564
+ padding: var(--crtr-chart-unavailable-padding, var(--crtr-space-3));
1565
+ color: var(--crtr-chart-unavailable-text-color, var(--crtr-color-text-muted));
1566
+ background: var(--crtr-chart-unavailable-fill, var(--crtr-color-surface));
1567
+ border: var(--crtr-chart-unavailable-border-width, 1px)
1568
+ var(--crtr-chart-unavailable-border-style, solid)
1569
+ var(--crtr-chart-unavailable-border-color, var(--crtr-color-border));
1570
+ border-radius: var(--crtr-chart-unavailable-radius, var(--crtr-radius-medium));
1181
1571
  }
1182
1572
 
1183
1573
  [part="reason"] {
1184
- color: var(--crtr-color-text);
1185
- font-family: var(--crtr-font-mono);
1574
+ color: var(--crtr-chart-reason-text-color, var(--crtr-color-text));
1575
+ font-family: var(--crtr-chart-reason-font-family, var(--crtr-font-mono));
1186
1576
  }
1187
1577
 
1188
1578
  .grid {
1189
- stroke: var(--crtr-color-border);
1190
- stroke-width: 1;
1579
+ stroke: var(--crtr-chart-grid-stroke-color, var(--crtr-color-border));
1580
+ stroke-width: var(--crtr-chart-grid-stroke-width, 1);
1581
+ opacity: var(--crtr-chart-grid-opacity, 0.45);
1582
+ }
1583
+
1584
+ /* The gridline the marks are read against carries more weight than the rest. */
1585
+ .grid.baseline {
1586
+ opacity: var(--crtr-chart-grid-baseline-opacity, 0.9);
1191
1587
  }
1192
1588
 
1193
1589
  .tick {
1194
- fill: var(--crtr-color-text-muted);
1195
- font-size: calc(var(--crtr-font-size) * 0.72);
1590
+ fill: var(--crtr-chart-tick-text-color, var(--crtr-color-text-muted));
1591
+ font-size: var(--crtr-chart-tick-font-size, 0.75em);
1196
1592
  }
1197
- `;function ke(o){let t=o.kind;if(t!=="line"&&t!=="bar"&&t!=="area")return{status:"invalid",reason:"chart kind must be line, bar or area"};let e=o.x;if(typeof e!="string"||e==="")return{status:"invalid",reason:"chart config has no x field"};if(!Array.isArray(o.y)||o.y.length===0)return{status:"invalid",reason:"chart config has no y series"};let r=[];for(let[n,i]of o.y.entries()){if(i===null||typeof i!="object"||Array.isArray(i))return{status:"invalid",reason:`chart series #${n} is not { field, label? }`};let a=i;if(typeof a.field!="string"||a.field==="")return{status:"invalid",reason:`chart series #${n} has no field`};if(a.label!==void 0&&typeof a.label!="string")return{status:"invalid",reason:`chart series "${a.field}" label is not a string`};r.push({field:a.field,label:a.label})}return o.title!==void 0&&typeof o.title!="string"?{status:"invalid",reason:"chart title is not a string"}:o.source!==void 0&&typeof o.source!="string"?{status:"invalid",reason:"chart source is not a string"}:{status:"ok",config:{kind:t,x:e,y:r,title:o.title,data:o.data,source:o.source}}}function Ot(o){return Array.isArray(o)&&o.every(t=>t!==null&&typeof t=="object"&&!Array.isArray(t))}function zt(o,t){return t.split(".").reduce((e,r)=>{if(!(e==null||typeof e!="object"))return e[r]},o)}function pt(o){return o.includes(" ")?o:(o.includes(".")?o.split(".").pop()??o:o).replace(/[_-]+/g," ").replace(/([a-z])([A-Z])/g,"$1 $2").split(/\s+/).filter(Boolean).map(e=>e.charAt(0).toUpperCase()+e.slice(1)).join(" ")}function Ce(o){if(typeof o=="number")return Number.isFinite(o)?o:null;if(typeof o=="boolean")return o?1:0;if(typeof o=="bigint")return Number(o);if(typeof o=="string"){let t=o.replace(/[\s,_]/g,"").replace(/^[$£€¥]/,"").replace(/%$/,"");if(t===""||t==="-")return null;let e=Number(t);return Number.isFinite(e)?e:null}return null}function Te(o){if(o==null)return"";if(o instanceof Date)return Number.isNaN(o.getTime())?"":o.toLocaleDateString(void 0,{month:"short",day:"numeric"});if(typeof o=="string"){let t=o.trim();if(ye.test(t)){let e=new Date(t);if(!Number.isNaN(e.getTime()))return e.toLocaleDateString(void 0,Ee.test(t)?{month:"short",day:"numeric",timeZone:"UTC"}:{month:"short",day:"numeric"})}return o}return typeof o=="object"?"":String(o)}function Ae(o){return o.length>Nt?`${o.slice(0,Nt-1)}\u2026`:o}function Me(o,t,e){let r=t>=1?0:Math.min(4,Math.ceil(-Math.log10(t)));return new Intl.NumberFormat(void 0,{maximumFractionDigits:r,notation:e?"compact":"standard"}).format(o)}function Dt(o){return new Intl.NumberFormat(void 0,{maximumFractionDigits:4}).format(o)}function Se(o,t,e){let r=o,n=t;if((!Number.isFinite(r)||!Number.isFinite(n))&&(r=0,n=1),r===n){let m=Math.abs(r)>0?Math.abs(r)*.1:1;r-=m,n+=m}let i=(n-r)/Math.max(1,e),a=10**Math.floor(Math.log10(i)),s=i/a,c=(s<=1?1:s<=2?2:s<=5?5:10)*a,d=Math.floor(r/c)*c,u=Math.ceil(n/c)*c,g=[];for(let m=d;m<=u+c/2;m+=c)g.push(Number(m.toFixed(10)));return{ticks:g,domainMin:d,domainMax:u,step:c}}function Le(o){let t=[],e=[];for(let r of o){let n=e[e.length-1];if(n===void 0||r.index===n.index+1){e.push(r);continue}t.push(e),e=[r]}return e.length>0&&t.push(e),t}function C(o,t){let e=document.createElementNS(fe,o);return t!==void 0&&e.setAttribute("part",t),e}function O(o,t){for(let[e,r]of Object.entries(t))o.setAttribute(e,String(r))}function jt(o){let t=C("title");return t.textContent=o,t}var mt=class extends HTMLElement{#n=document.createElement("div");#d=document.createElement("div");#s=document.createElement("div");#t=document.createElement("div");#r=null;#e=null;#o=null;#l=0;#c=0;constructor(){super();let t=this.attachShadow({mode:"open"}),e=document.createElement("style");e.textContent=we,this.#n.part.add("container"),this.#d.part.add("title"),this.#s.part.add("legend"),this.#t.part.add("plot"),t.append(e,this.#n)}connectedCallback(){let t=++this.#c;this.#r=null,this.#e=null;let e=k(this);if(e.status!=="ok"){this.#i(e.reason);return}let r=ke(e.config);if(r.status!=="ok"){this.#i(r.reason);return}this.#r=r.config,this.#x(),this.#u();let{data:n,source:i}=r.config;if(n!==void 0){if(!Ot(n)){this.#i("chart data is not a list of rows");return}this.#e=n,this.#p();return}if(i===void 0||i===""){this.#e=[],this.#p();return}this.#h("Loading chart data\u2026"),this.#a(i,t)}disconnectedCallback(){this.#c+=1,this.#o?.disconnect(),this.#o=null}async#a(t,e){let r=await G(t);if(e===this.#c){if(r.status!=="ok"){this.#i(`chart source "${t}" is ${r.status}: ${r.reason}`);return}if(!Ot(r.data)){this.#i(`chart source "${t}" is not a list of rows`);return}this.#e=r.data,this.#p()}}#u(){this.#o?.disconnect(),this.#l=this.#t.getBoundingClientRect().width;let t=new ResizeObserver(e=>{let r=e[0]?.contentRect.width??0;Math.abs(this.#l-r)<.5||(this.#l=r,this.#p())});t.observe(this.#t),this.#o=t}#i(t){this.#o?.disconnect(),this.#o=null;let e=document.createElement("div");e.part.add("unavailable"),e.setAttribute("role","status");let r=document.createElement("span");r.part.add("reason"),r.textContent=t,e.append("Chart unavailable: ",r),this.#n.replaceChildren(e)}#h(t){let e=document.createElement("div");e.part.add("status"),e.setAttribute("role","status"),e.style.height=`${q}px`,e.textContent=t,this.#t.replaceChildren(e)}#x(){let t=this.#r;if(t===null)return;let e=[],r=t.title?.trim();r!==void 0&&r.length>0&&(this.#d.textContent=r,e.push(this.#d)),t.y.length>1&&(this.#s.replaceChildren(...t.y.map((n,i)=>{let a=document.createElement("div");a.part.add("legend-item");let s=document.createElement("span");s.part.add("legend-swatch"),s.setAttribute("aria-hidden","true"),s.style.background=W[i%W.length]??W[0];let c=document.createElement("span");return c.part.add("legend-label"),c.textContent=n.label??pt(n.field),a.append(s,c),a})),e.push(this.#s)),e.push(this.#t),this.#n.replaceChildren(...e)}#p(){let t=this.#r,e=this.#e;if(t===null||e===null)return;let r=e.map(l=>Te(zt(l,t.x))),n=t.y.map((l,p)=>{let h=[];return e.forEach((f,x)=>{let E=Ce(zt(f,l.field));E!==null&&h.push({index:x,value:E})}),{label:l.label??pt(l.field),color:W[p%W.length]??W[0],points:h}}),i=0,a=0,s=0;for(let l of n)for(let p of l.points)i===0?(a=p.value,s=p.value):(p.value<a&&(a=p.value),p.value>s&&(s=p.value)),i+=1;if(t.kind!=="line"&&(a=Math.min(a,0),s=Math.max(s,0)),i===0||e.length===0){let l=document.createElement("div");l.part.add("empty"),l.style.height=`${q}px`,l.textContent="No data to chart",this.#t.replaceChildren(l);return}let c=this.#l;if(c<=0){let l=document.createElement("div");l.style.height=`${q}px`,this.#t.replaceChildren(l);return}let{ticks:d,domainMin:u,domainMax:g,step:m}=Se(a,s,ve),V=Math.max(...d.map(l=>Math.abs(l)))>=1e4,P=d.map(l=>Me(l,m,V)),A=Math.min(88,Math.max(36,Math.max(...P.map(l=>l.length))*6.4+12)),T=Math.max(0,c-A-ge),M=Math.max(0,q-$t-be),y=$t+M,rt=r.length>0?T/r.length:T,_=l=>A+rt*(l+.5),_t=g-u||1,z=l=>y-(l-u)/_t*M,bt=Math.min(Math.max(0,u),g),X=z(bt),D=C("svg","chart");O(D,{role:"img",width:c,height:q,viewBox:`0 0 ${c} ${q}`}),D.setAttribute("aria-label",`${t.kind} chart of ${n.map(l=>l.label).join(", ")} by ${pt(t.x)}`),d.forEach((l,p)=>{let h=C("line");h.setAttribute("class","grid"),O(h,{x1:A,x2:A+T,y1:z(l),y2:z(l),opacity:l===bt?.9:.45});let f=C("text");f.setAttribute("class","tick"),O(f,{x:A-8,y:z(l),"text-anchor":"end","dominant-baseline":"central"}),f.textContent=P[p]??"",D.append(h,f)});let j=[];if(r.length>0){let l=Math.max(2,Math.min(r.length,Math.floor(T/It)||1)),p=Math.max(1,Math.ceil((r.length-1)/(l-1)));for(let f=0;f<r.length;f+=p)j.push(f);let h=j[j.length-1]??0;h!==r.length-1&&((r.length-1-h)*rt>=It?j.push(r.length-1):j[j.length-1]=r.length-1)}for(let l of j){let p=Ae(r[l]??""),h=_(l),f=p.length*xe/2,x=h-f<0?"start":h+f>c?"end":"middle",E=C("text");E.setAttribute("class","tick"),O(E,{x:x==="start"?0:x==="end"?c:h,y:y+16,"text-anchor":x,"dominant-baseline":"hanging"}),E.textContent=p,D.append(E)}if(t.kind==="bar"){let l=rt*.72,p=l/n.length,h=Math.max(1,p-(p>4?1:0));n.forEach((f,x)=>{let E=C("g");for(let S of f.points){let U=z(S.value),L=C("rect","bar");O(L,{x:_(S.index)-l/2+x*p,y:Math.min(U,X),width:h,height:Math.max(1,Math.abs(X-U)),rx:Math.min(2,h/3)}),L.style.fill=f.color,L.append(jt(`${f.label} \xB7 ${r[S.index]??S.index}: ${Dt(S.value)}`)),E.append(L)}D.append(E)})}else{let l=r.length<=40;for(let p of n){let h=C("g"),f=Le(p.points);for(let x of f){let E=x.map(w=>`${_(w.index)},${z(w.value)}`).join(" L "),S=x[0],U=x[x.length-1];if(t.kind==="area"&&S!==void 0&&U!==void 0){let w=C("path","area");O(w,{d:`M ${_(S.index)},${X} L ${E} L ${_(U.index)},${X} Z`,"fill-opacity":.18}),w.style.fill=p.color,h.append(w)}let L=C("path","line");if(O(L,{d:`M ${E}`,fill:"none","stroke-width":2,"stroke-linecap":"round","stroke-linejoin":"round"}),L.style.stroke=p.color,h.append(L),!(!l&&x.length>1))for(let w of x){let J=C("circle","point");O(J,{cx:_(w.index),cy:z(w.value),r:2.5}),J.style.fill=p.color,J.append(jt(`${p.label} \xB7 ${r[w.index]??w.index}: ${Dt(w.value)}`)),h.append(J)}}D.append(h)}}this.#t.replaceChildren(D)}};v("crtr-chart",mt);function Bt(){return window.crtr}var Pt="Submit is unavailable \u2014 this page is not connected to a host.",Re=`
1593
+
1594
+ /* Mark paint. Series colour arrives per node from the theme's chart ramp; everything
1595
+ these marks are drawn WITH is a knob, which is why none of it is an SVG attribute. */
1596
+ [part="line"] {
1597
+ stroke-width: var(--crtr-chart-line-stroke-width, 2);
1598
+ stroke-linecap: var(--crtr-chart-line-line-cap, round);
1599
+ stroke-linejoin: var(--crtr-chart-line-line-join, round);
1600
+ }
1601
+
1602
+ [part="area"] {
1603
+ fill-opacity: var(--crtr-chart-area-fill-opacity, 0.18);
1604
+ }
1605
+
1606
+ [part="point"] {
1607
+ r: var(--crtr-chart-point-radius, 2.5);
1608
+ }
1609
+
1610
+ /* A bar never rounds away more than a third of its own width, and --bar-max-radius is
1611
+ that width \u2014 the one number here the stylesheet cannot know, so the plot writes it onto
1612
+ the SVG and the knob is clamped against it. */
1613
+ [part="bar"] {
1614
+ rx: min(var(--crtr-chart-bar-radius, 2px), var(--bar-max-radius));
1615
+ }
1616
+ `;function Ye(n){let t=n.kind;if(t!=="line"&&t!=="bar"&&t!=="area")return{status:"invalid",reason:"chart kind must be line, bar or area"};let e=n.x;if(typeof e!="string"||e==="")return{status:"invalid",reason:"chart config has no x field"};if(!Array.isArray(n.y)||n.y.length===0)return{status:"invalid",reason:"chart config has no y series"};let r=[];for(let[o,a]of n.y.entries()){if(a===null||typeof a!="object"||Array.isArray(a))return{status:"invalid",reason:`chart series #${o} is not { field, label? }`};let i=a;if(typeof i.field!="string"||i.field==="")return{status:"invalid",reason:`chart series #${o} has no field`};if(i.label!==void 0&&typeof i.label!="string")return{status:"invalid",reason:`chart series "${i.field}" label is not a string`};r.push({field:i.field,label:i.label})}return n.title!==void 0&&typeof n.title!="string"?{status:"invalid",reason:"chart title is not a string"}:{status:"ok",config:{kind:t,x:e,y:r,title:n.title,data:n.data}}}function Xe(n){return Array.isArray(n)&&n.every(t=>t!==null&&typeof t=="object"&&!Array.isArray(t))}function Zt(n,t){return t.split(".").reduce((e,r)=>{if(!(e==null||typeof e!="object"))return e[r]},n)}function Et(n){return n.includes(" ")?n:(n.includes(".")?n.split(".").pop()??n:n).replace(/[_-]+/g," ").replace(/([a-z])([A-Z])/g,"$1 $2").split(/\s+/).filter(Boolean).map(e=>e.charAt(0).toUpperCase()+e.slice(1)).join(" ")}function Je(n){if(typeof n=="number")return Number.isFinite(n)?n:null;if(typeof n=="boolean")return n?1:0;if(typeof n=="bigint")return Number(n);if(typeof n=="string"){let t=n.replace(/[\s,_]/g,"").replace(/^[$£€¥]/,"").replace(/%$/,"");if(t===""||t==="-")return null;let e=Number(t);return Number.isFinite(e)?e:null}return null}function Qe(n){if(n==null)return"";if(n instanceof Date)return Number.isNaN(n.getTime())?"":n.toLocaleDateString(void 0,{month:"short",day:"numeric"});if(typeof n=="string"){let t=n.trim();if(Fe.test(t)){let e=new Date(t);if(!Number.isNaN(e.getTime()))return e.toLocaleDateString(void 0,Ue.test(t)?{month:"short",day:"numeric",timeZone:"UTC"}:{month:"short",day:"numeric"})}return n}return typeof n=="object"?"":String(n)}function Ze(n){return n.length>Qt?`${n.slice(0,Qt-1)}\u2026`:n}function tr(n,t,e){let r=t>=1?0:Math.min(4,Math.ceil(-Math.log10(t)));return new Intl.NumberFormat(void 0,{maximumFractionDigits:r,notation:e?"compact":"standard"}).format(n)}function te(n){return new Intl.NumberFormat(void 0,{maximumFractionDigits:4}).format(n)}function er(n,t,e){let r=n,o=t;if((!Number.isFinite(r)||!Number.isFinite(o))&&(r=0,o=1),r===o){let p=Math.abs(r)>0?Math.abs(r)*.1:1;r-=p,o+=p}let a=(o-r)/Math.max(1,e),i=10**Math.floor(Math.log10(a)),s=a/i,c=(s<=1?1:s<=2?2:s<=5?5:10)*i,l=Math.floor(r/c)*c,h=Math.ceil(o/c)*c,g=[];for(let p=l;p<=h+c/2;p+=c)g.push(Number(p.toFixed(10)));return{ticks:g,domainMin:l,domainMax:h,step:c}}function rr(n){let t=[],e=[];for(let r of n){let o=e[e.length-1];if(o===void 0||r.index===o.index+1){e.push(r);continue}t.push(e),e=[r]}return e.length>0&&t.push(e),t}function A(n,t){let e=document.createElementNS(_e,n);return t!==void 0&&e.setAttribute("part",t),e}function P(n,t){for(let[e,r]of Object.entries(t))n.setAttribute(e,String(r))}function ee(n){let t=A("title");return t.textContent=n,t}var Ct=class extends HTMLElement{#o=document.createElement("div");#i=document.createElement("div");#a=document.createElement("div");#n=document.createElement("div");#e=null;#r=null;#t=null;#h=0;#c=0;constructor(){super();let t=this.attachShadow({mode:"open"}),e=document.createElement("style");e.textContent=Ve,this.#o.part.add("container"),this.#i.part.add("title"),this.#a.part.add("legend"),this.#n.part.add("plot"),t.append(e,this.#o)}connectedCallback(){++this.#c,this.#e=null,this.#r=null;let t=T(this);if(t.status!=="ok"){this.#l(t.reason);return}let e=Ye(t.config);if(e.status!=="ok"){this.#l(e.reason);return}this.#e=e.config,this.#d(),this.#s();let{data:r}=e.config;if(r!==void 0&&!Xe(r)){this.#l("chart data is not a list of rows");return}this.#r=r??[],this.#u()}disconnectedCallback(){this.#c+=1,this.#t?.disconnect(),this.#t=null}#s(){this.#t?.disconnect(),this.#h=this.#n.getBoundingClientRect().width;let t=new ResizeObserver(e=>{let r=e[0]?.contentRect.width??0;Math.abs(this.#h-r)<.5||(this.#h=r,this.#u())});t.observe(this.#n),this.#t=t}#l(t){this.#t?.disconnect(),this.#t=null;let e=document.createElement("div");e.part.add("unavailable"),e.setAttribute("role","status");let r=document.createElement("span");r.part.add("reason"),r.textContent=t,e.append("Chart unavailable: ",r),this.#o.replaceChildren(e)}#d(){let t=this.#e;if(t===null)return;let e=[],r=t.title?.trim();r!==void 0&&r.length>0&&(this.#i.textContent=r,e.push(this.#i)),t.y.length>1&&(this.#a.replaceChildren(...t.y.map((o,a)=>{let i=document.createElement("div");i.part.add("legend-item");let s=document.createElement("span");s.part.add("legend-swatch"),s.setAttribute("aria-hidden","true"),s.style.background=V[a%V.length]??V[0];let c=document.createElement("span");return c.part.add("legend-label"),c.textContent=o.label??Et(o.field),i.append(s,c),i})),e.push(this.#a)),e.push(this.#n),this.#o.replaceChildren(...e)}#u(){let t=this.#e,e=this.#r;if(t===null||e===null)return;let r=e.map(d=>Qe(Zt(d,t.x))),o=t.y.map((d,m)=>{let v=[];return e.forEach((b,k)=>{let E=Je(Zt(b,d.field));E!==null&&v.push({index:k,value:E})}),{label:d.label??Et(d.field),color:V[m%V.length]??V[0],points:v}}),a=0,i=0,s=0;for(let d of o)for(let m of d.points)a===0?(i=m.value,s=m.value):(m.value<i&&(i=m.value),m.value>s&&(s=m.value)),a+=1;if(t.kind!=="line"&&(i=Math.min(i,0),s=Math.max(s,0)),a===0||e.length===0){let d=document.createElement("div");d.part.add("empty"),d.style.height="var(--crtr-chart-plot-height, 260px)",d.textContent="No data to chart",this.#n.replaceChildren(d);return}let c=this.#h;if(c<=0){let d=document.createElement("div");d.style.height="var(--crtr-chart-plot-height, 260px)",this.#n.replaceChildren(d);return}let{ticks:l,domainMin:h,domainMax:g,step:p}=er(i,s,Ge),ne=Math.max(...l.map(d=>Math.abs(d)))>=1e4,Mt=l.map(d=>tr(d,p,ne)),Y=Math.min(88,Math.max(36,Math.max(...Mt.map(d=>d.length))*6.4+12)),Q=Math.max(0,c-Y-Ke),Lt=Math.max(0,kt-Xt-qe),$t=Xt+Lt,it=r.length>0?Q/r.length:Q,G=d=>Y+it*(d+.5),ae=g-h||1,_=d=>$t-(d-h)/ae*Lt,Rt=Math.min(Math.max(0,h),g),Z=_(Rt),$=A("svg","chart");P($,{role:"img",width:c,height:kt,viewBox:`0 0 ${c} ${kt}`}),$.setAttribute("aria-label",`${t.kind} chart of ${o.map(d=>d.label).join(", ")} by ${Et(t.x)}`),l.forEach((d,m)=>{let v=A("line");v.setAttribute("class",d===Rt?"grid baseline":"grid"),P(v,{x1:Y,x2:Y+Q,y1:_(d),y2:_(d)});let b=A("text");b.setAttribute("class","tick"),P(b,{x:Y-8,y:_(d),"text-anchor":"end","dominant-baseline":"central"}),b.textContent=Mt[m]??"",$.append(v,b)});let K=[];if(r.length>0){let d=Math.max(2,Math.min(r.length,Math.floor(Q/Jt)||1)),m=Math.max(1,Math.ceil((r.length-1)/(d-1)));for(let b=0;b<r.length;b+=m)K.push(b);let v=K[K.length-1]??0;v!==r.length-1&&((r.length-1-v)*it>=Jt?K.push(r.length-1):K[K.length-1]=r.length-1)}for(let d of K){let m=Ze(r[d]??""),v=G(d),b=m.length*We/2,k=v-b<0?"start":v+b>c?"end":"middle",E=A("text");E.setAttribute("class","tick"),P(E,{x:k==="start"?0:k==="end"?c:v,y:$t+16,"text-anchor":k,"dominant-baseline":"hanging"}),E.textContent=m,$.append(E)}if(t.kind==="bar"){let d=it*.72,m=d/o.length,v=Math.max(1,m-(m>4?1:0));$.style.setProperty("--bar-max-radius",`${v/3}px`),o.forEach((b,k)=>{let E=A("g");for(let R of b.points){let X=_(R.value),H=A("rect","bar");P(H,{x:G(R.index)-d/2+k*m,y:Math.min(X,Z),width:v,height:Math.max(1,Math.abs(Z-X))}),H.style.fill=b.color,H.append(ee(`${b.label} \xB7 ${r[R.index]??R.index}: ${te(R.value)}`)),E.append(H)}$.append(E)})}else{let d=r.length<=40;for(let m of o){let v=A("g"),b=rr(m.points);for(let k of b){let E=k.map(C=>`${G(C.index)},${_(C.value)}`).join(" L "),R=k[0],X=k[k.length-1];if(t.kind==="area"&&R!==void 0&&X!==void 0){let C=A("path","area");P(C,{d:`M ${G(R.index)},${Z} L ${E} L ${G(X.index)},${Z} Z`}),C.style.fill=m.color,v.append(C)}let H=A("path","line");if(P(H,{d:`M ${E}`,fill:"none"}),H.style.stroke=m.color,v.append(H),!(!d&&k.length>1))for(let C of k){let tt=A("circle","point");P(tt,{cx:G(C.index),cy:_(C.value)}),tt.style.fill=m.color,tt.append(ee(`${m.label} \xB7 ${r[C.index]??C.index}: ${te(C.value)}`)),v.append(tt)}}$.append(v)}}this.#n.replaceChildren($)}};w("crtr-chart",Ct);function re(){return window.crtr}var oe="Submit is unavailable \u2014 this page is not connected to a host.",or=`
1198
1617
  :host {
1199
1618
  display: block;
1200
1619
  }
@@ -1205,20 +1624,24 @@
1205
1624
 
1206
1625
  [part="page"] {
1207
1626
  display: grid;
1208
- gap: var(--crtr-space-3);
1627
+ gap: var(--crtr-page-step-gap, var(--crtr-space-3));
1209
1628
  }
1210
1629
 
1211
- [part="page"]:focus {
1212
- outline: none;
1630
+ /* A step takes focus programmatically when the pager flips to it, so it wears no ring by
1631
+ default \u2014 a host that wants one sets the outline rather than patching around it. The
1632
+ pager focuses the element itself, not the inner div, so the rule has to sit on the host:
1633
+ on [part="page"] it would never match and every step change would paint a UA ring. */
1634
+ :host(:focus) {
1635
+ outline: var(--crtr-page-step-focus-outline, none);
1213
1636
  }
1214
- `,He=`
1637
+ `,nr=`
1215
1638
  :host {
1216
1639
  display: block;
1217
1640
  }
1218
1641
 
1219
1642
  [part="container"] {
1220
1643
  display: grid;
1221
- gap: var(--crtr-space-4);
1644
+ gap: var(--crtr-page-container-gap, var(--crtr-space-4));
1222
1645
  }
1223
1646
 
1224
1647
  [part="chrome"] {
@@ -1226,9 +1649,11 @@
1226
1649
  flex-wrap: wrap;
1227
1650
  align-items: center;
1228
1651
  justify-content: space-between;
1229
- gap: var(--crtr-space-3);
1230
- padding-top: var(--crtr-space-3);
1231
- border-top: 1px solid var(--crtr-color-border);
1652
+ gap: var(--crtr-page-chrome-gap, var(--crtr-space-3));
1653
+ padding-top: var(--crtr-page-chrome-padding-top, var(--crtr-space-3));
1654
+ border-top: var(--crtr-page-chrome-border-width, 1px)
1655
+ var(--crtr-page-chrome-border-style, solid)
1656
+ var(--crtr-page-chrome-border-color, var(--crtr-color-border));
1232
1657
  }
1233
1658
 
1234
1659
  [part="container"][data-steps="1"] [part="chrome"] {
@@ -1238,96 +1663,102 @@
1238
1663
  [part="progress"] {
1239
1664
  display: flex;
1240
1665
  align-items: center;
1241
- gap: var(--crtr-space-2);
1242
- color: var(--crtr-color-text-muted);
1666
+ gap: var(--crtr-page-progress-gap, var(--crtr-space-2));
1667
+ color: var(--crtr-page-progress-text-color, var(--crtr-color-text-muted));
1243
1668
  }
1244
1669
 
1245
1670
  [part="progress-track"] {
1246
1671
  display: flex;
1247
1672
  align-items: center;
1248
- gap: var(--crtr-space-1);
1673
+ gap: var(--crtr-page-progress-track-gap, var(--crtr-space-1));
1249
1674
  }
1250
1675
 
1251
1676
  [part="progress-step"] {
1252
- width: var(--crtr-space-2);
1253
- height: var(--crtr-space-1);
1254
- border-radius: var(--crtr-radius-small);
1255
- background: var(--crtr-color-border);
1677
+ width: var(--crtr-page-progress-step-width, var(--crtr-space-2));
1678
+ height: var(--crtr-page-progress-step-height, var(--crtr-space-1));
1679
+ border-radius: var(--crtr-page-progress-step-radius, var(--crtr-radius-small));
1680
+ background: var(--crtr-page-progress-step-fill, var(--crtr-color-border));
1256
1681
  }
1257
1682
 
1258
1683
  [part="progress-step"][data-state="complete"] {
1259
- background: var(--crtr-color-text-muted);
1684
+ background: var(--crtr-page-progress-step-complete-fill, var(--crtr-color-text-muted));
1260
1685
  }
1261
1686
 
1262
1687
  [part="progress-step"][data-state="current"] {
1263
- width: var(--crtr-space-4);
1264
- background: var(--crtr-color-accent);
1688
+ width: var(--crtr-page-progress-step-current-width, var(--crtr-space-4));
1689
+ background: var(--crtr-page-progress-step-current-fill, var(--crtr-color-accent));
1265
1690
  }
1266
1691
 
1267
1692
  [part="actions"] {
1268
1693
  display: flex;
1269
1694
  align-items: center;
1270
- gap: var(--crtr-space-2);
1695
+ gap: var(--crtr-page-actions-gap, var(--crtr-space-2));
1271
1696
  }
1272
1697
 
1273
1698
  button {
1274
- font: inherit;
1275
- color: var(--crtr-color-text);
1276
- background: var(--crtr-color-surface);
1277
- border: 1px solid var(--crtr-color-border);
1278
- border-radius: var(--crtr-radius-small);
1279
- padding: var(--crtr-space-2) var(--crtr-space-3);
1699
+ font: var(--crtr-page-button-font, inherit);
1700
+ color: var(--crtr-page-button-text-color, var(--crtr-color-text));
1701
+ background: var(--crtr-page-button-fill, var(--crtr-color-surface));
1702
+ border: var(--crtr-page-button-border-width, 1px)
1703
+ var(--crtr-page-button-border-style, solid)
1704
+ var(--crtr-page-button-border-color, var(--crtr-color-border));
1705
+ border-radius: var(--crtr-page-button-radius, var(--crtr-radius-small));
1706
+ padding: var(--crtr-page-button-padding, var(--crtr-space-2) var(--crtr-space-3));
1280
1707
  cursor: pointer;
1708
+ transition: color var(--crtr-page-button-transition, var(--crtr-control-transition, 120ms ease)),
1709
+ background-color var(--crtr-page-button-transition, var(--crtr-control-transition, 120ms ease)),
1710
+ border-color var(--crtr-page-button-transition, var(--crtr-control-transition, 120ms ease));
1281
1711
  }
1282
1712
 
1283
1713
  button:hover:not(:disabled) {
1284
- background: var(--crtr-color-surface-hover);
1285
- }
1286
-
1287
- button:focus-visible {
1288
- outline: 2px solid var(--crtr-color-focus);
1289
- outline-offset: 2px;
1714
+ background: var(--crtr-page-button-hover-fill, var(--crtr-color-surface-hover));
1290
1715
  }
1291
1716
 
1717
+ ${u({scope:"page-button"},"button")}
1292
1718
  button:disabled {
1293
1719
  cursor: not-allowed;
1294
- opacity: 0.5;
1720
+ opacity: var(--crtr-page-button-disabled-opacity, var(--crtr-control-disabled-opacity, 0.5));
1295
1721
  }
1296
1722
 
1297
1723
  [part="submit"] {
1298
- color: var(--crtr-color-accent-contrast);
1299
- background: var(--crtr-color-accent);
1300
- border-color: transparent;
1724
+ color: var(--crtr-page-submit-text-color, var(--crtr-color-accent-contrast));
1725
+ background: var(--crtr-page-submit-fill, var(--crtr-color-accent));
1726
+ border-color: var(--crtr-page-submit-border-color, var(--crtr-color-accent));
1301
1727
  }
1302
1728
 
1729
+ /* Mixing the accent toward the text colour darkens on a light token set and lightens on a
1730
+ dark one \u2014 a brightness filter moves the wrong way on one of them. */
1303
1731
  [part="submit"]:hover:not(:disabled) {
1304
- background: var(--crtr-color-accent);
1305
- filter: brightness(1.08);
1732
+ background: var(--crtr-page-submit-hover-fill, color-mix(in srgb, var(--crtr-color-accent) 88%, var(--crtr-color-text)));
1733
+ border-color: var(--crtr-page-submit-hover-border-color, color-mix(in srgb, var(--crtr-color-accent) 88%, var(--crtr-color-text)));
1306
1734
  }
1307
1735
 
1308
1736
  [part="notice"] {
1309
- color: var(--crtr-color-text-muted);
1737
+ color: var(--crtr-page-notice-text-color, var(--crtr-color-text-muted));
1738
+ font-size: var(--crtr-page-notice-font-size, 0.875em);
1310
1739
  }
1311
1740
 
1312
1741
  [part="notice"][data-state="error"] {
1313
- color: var(--crtr-color-danger);
1742
+ color: var(--crtr-page-notice-error-text-color, var(--crtr-color-danger));
1314
1743
  }
1315
1744
 
1316
1745
  [hidden] {
1317
1746
  display: none !important;
1318
1747
  }
1319
- `,ht=class extends HTMLElement{constructor(){super();let t=this.attachShadow({mode:"open"}),e=document.createElement("style");e.textContent=Re;let r=document.createElement("div");r.part.add("page"),r.append(document.createElement("slot")),t.append(e,r)}},ft=class extends HTMLElement{static observedAttributes=["disabled","submit-label"];#n=[];#d=0;#s="idle";#t=null;#r=document.createElement("div");#e=document.createElement("div");#o=document.createElement("div");#l=document.createElement("span");#c=document.createElement("span");#a=document.createElement("div");#u=document.createElement("span");#i=document.createElement("button");#h=document.createElement("button");#x=document.createElement("button");#p=new MutationObserver(()=>{this.#g(),this.#m()});constructor(){super();let t=this.attachShadow({mode:"open"}),e=document.createElement("style");e.textContent=He;let r=document.createElement("div");r.part.add("steps"),r.append(document.createElement("slot")),this.#r.part.add("container"),this.#e.part.add("chrome"),this.#o.part.add("progress"),this.#o.setAttribute("role","status"),this.#o.setAttribute("aria-live","polite"),this.#l.part.add("progress-label"),this.#c.part.add("progress-track"),this.#c.setAttribute("aria-hidden","true"),this.#o.append(this.#l,this.#c),this.#i.part.add("prev"),this.#i.type="button",this.#i.textContent="Back",this.#i.addEventListener("click",()=>this.#y(-1)),this.#h.part.add("next"),this.#h.type="button",this.#h.textContent="Next",this.#h.addEventListener("click",()=>this.#y(1)),this.#x.part.add("submit"),this.#x.type="button",this.#x.addEventListener("click",()=>{this.#v()}),this.#u.part.add("notice"),this.#a.part.add("actions"),this.#a.append(this.#u,this.#i,this.#h,this.#x),this.#e.append(this.#o,this.#a),this.#r.append(r,this.#e),t.append(e,this.#r)}connectedCallback(){this.#g(),this.#p.observe(this,{childList:!0}),this.ownerDocument.addEventListener("keydown",this.#k),this.#m()}disconnectedCallback(){this.#p.disconnect(),this.ownerDocument.removeEventListener("keydown",this.#k)}attributeChangedCallback(){this.isConnected&&this.#m()}#g(){this.#n=[...this.children].filter(t=>t instanceof HTMLElement&&t.tagName==="CRTR-PAGE");for(let t of this.#n)t.hasAttribute("tabindex")||t.setAttribute("tabindex","-1");this.#d=Math.min(this.#d,Math.max(0,this.#n.length-1))}get#w(){return this.#d>=this.#n.length-1}#y(t,e=!0){let r=this.#d+t;r<0||r>=this.#n.length||r===this.#d||(this.#d=r,this.#t=null,this.#m(),e&&this.#n[this.#d]?.focus())}async#v(){if(this.#s!=="idle"||this.hasAttribute("disabled")||!this.#w)return;let t=Bt();if(typeof t?.submit!="function"){this.#t=Pt,this.#m();return}this.#s="submitting",this.#t=null,this.#m();try{await t.submit(),this.#s="submitted"}catch(e){this.#s="idle",this.#t=e instanceof Error?e.message:"Submit failed."}this.#m()}#k=t=>{if(t.defaultPrevented)return;let e=t.composedPath();if(e.some(n=>n instanceof HTMLElement&&n.tagName==="CRTR-PAGES"&&n!==this))return;if((t.metaKey||t.ctrlKey)&&t.key==="Enter"){if(!this.#w)return;t.preventDefault(),this.#v();return}if(t.metaKey||t.ctrlKey||t.altKey||$e(e))return;let r=t.key.toLowerCase();r!=="n"&&r!=="p"||(t.preventDefault(),this.#y(r==="n"?1:-1))};#m(){let t=this.#n.length,e=t>1,r=Math.min(this.#d,Math.max(0,t-1));for(let[a,s]of this.#n.entries())s.toggleAttribute("hidden",a!==r);if(this.#r.dataset.steps=String(Math.max(1,t)),this.#r.dataset.step=String(r+1),this.#o.hidden=!e,e){let a=this.#n[r]?.getAttribute("label")?.trim();this.#l.textContent=a?`Step ${r+1} of ${t} \xB7 ${a}`:`Step ${r+1} of ${t}`,this.#c.replaceChildren(...this.#n.map((s,c)=>{let d=document.createElement("span");return d.part.add("progress-step"),d.dataset.state=c===r?"current":c<r?"complete":"upcoming",d}))}this.#i.hidden=!e,this.#i.disabled=r===0,this.#h.hidden=!e||this.#w,this.#h.disabled=!1,this.#x.hidden=!this.#w;let n=typeof Bt()?.submit=="function";this.#x.disabled=!n||this.#s!=="idle"||this.hasAttribute("disabled"),this.#x.textContent=this.#s==="submitting"?"Submitting\u2026":this.#s==="submitted"?"Submitted":this.getAttribute("submit-label")?.trim()||"Submit";let i=this.#t??(this.#s==="submitted"?"Your response was submitted.":!n&&this.#w?Pt:null);this.#u.hidden=i===null,this.#u.textContent=i??"",this.#u.dataset.state=this.#t===null?"info":"error"}};function $e(o){return o.some(t=>t instanceof HTMLElement&&(t instanceof HTMLInputElement||t instanceof HTMLTextAreaElement||t.isContentEditable))}v("crtr-page",ht);v("crtr-pages",ft);var Ie=`
1748
+ `,Tt=class extends HTMLElement{constructor(){super();let t=this.attachShadow({mode:"open"}),e=document.createElement("style");e.textContent=or;let r=document.createElement("div");r.part.add("page"),r.append(document.createElement("slot")),t.append(e,r)}},St=class extends HTMLElement{static observedAttributes=["disabled","submit-label"];#o=[];#i=0;#a="idle";#n=null;#e=document.createElement("div");#r=document.createElement("div");#t=document.createElement("div");#h=document.createElement("span");#c=document.createElement("span");#s=document.createElement("div");#l=document.createElement("span");#d=document.createElement("button");#u=document.createElement("button");#m=document.createElement("button");#E=new MutationObserver(()=>{this.#L(),this.#y()});constructor(){super();let t=this.attachShadow({mode:"open"}),e=document.createElement("style");e.textContent=nr;let r=document.createElement("div");r.part.add("steps"),r.append(document.createElement("slot")),this.#e.part.add("container"),this.#r.part.add("chrome"),this.#t.part.add("progress"),this.#t.setAttribute("role","status"),this.#t.setAttribute("aria-live","polite"),this.#h.part.add("progress-label"),this.#c.part.add("progress-track"),this.#c.setAttribute("aria-hidden","true"),this.#t.append(this.#h,this.#c),this.#d.part.add("prev"),this.#d.type="button",this.#d.textContent="Back",this.#d.addEventListener("click",()=>this.#p(-1)),this.#u.part.add("next"),this.#u.type="button",this.#u.textContent="Next",this.#u.addEventListener("click",()=>this.#p(1)),this.#m.part.add("submit"),this.#m.type="button",this.#m.addEventListener("click",()=>{this.#T()}),this.#l.part.add("notice"),this.#s.part.add("actions"),this.#s.append(this.#l,this.#d,this.#u,this.#m),this.#r.append(this.#t,this.#s),this.#e.append(r,this.#r),t.append(e,this.#e)}connectedCallback(){this.#L(),this.#E.observe(this,{childList:!0}),this.ownerDocument.addEventListener("keydown",this.#b),this.#y()}disconnectedCallback(){this.#E.disconnect(),this.ownerDocument.removeEventListener("keydown",this.#b)}attributeChangedCallback(){this.isConnected&&this.#y()}#L(){this.#o=[...this.children].filter(t=>t instanceof HTMLElement&&t.tagName==="CRTR-PAGE");for(let t of this.#o)t.hasAttribute("tabindex")||t.setAttribute("tabindex","-1");this.#i=Math.min(this.#i,Math.max(0,this.#o.length-1))}get#g(){return this.#i>=this.#o.length-1}#p(t,e=!0){let r=this.#i+t;r<0||r>=this.#o.length||r===this.#i||(this.#i=r,this.#n=null,this.#y(),e&&this.#o[this.#i]?.focus())}async#T(){if(this.#a!=="idle"||this.hasAttribute("disabled")||!this.#g)return;let t=re();if(typeof t?.submit!="function"){this.#n=oe,this.#y();return}this.#a="submitting",this.#n=null,this.#y();try{Nt(),await t.submit(),this.#a="submitted"}catch(e){this.#a="idle",this.#n=e instanceof Error?e.message:"Submit failed."}this.#y()}#b=t=>{if(t.defaultPrevented)return;let e=t.composedPath();if(e.some(o=>o instanceof HTMLElement&&o.tagName==="CRTR-PAGES"&&o!==this))return;if((t.metaKey||t.ctrlKey)&&t.key==="Enter"){if(!this.#g)return;t.preventDefault(),this.#T();return}if(t.metaKey||t.ctrlKey||t.altKey||ar(e))return;let r=t.key.toLowerCase();r!=="n"&&r!=="p"||(t.preventDefault(),this.#p(r==="n"?1:-1))};#y(){let t=this.#o.length,e=t>1,r=Math.min(this.#i,Math.max(0,t-1));for(let[i,s]of this.#o.entries())s.toggleAttribute("hidden",i!==r);if(this.#e.dataset.steps=String(Math.max(1,t)),this.#e.dataset.step=String(r+1),this.#t.hidden=!e,e){let i=this.#o[r]?.getAttribute("label")?.trim();this.#h.textContent=i?`Step ${r+1} of ${t} \xB7 ${i}`:`Step ${r+1} of ${t}`,this.#c.replaceChildren(...this.#o.map((s,c)=>{let l=document.createElement("span");return l.part.add("progress-step"),l.dataset.state=c===r?"current":c<r?"complete":"upcoming",l}))}this.#d.hidden=!e,this.#d.disabled=r===0,this.#u.hidden=!e||this.#g,this.#u.disabled=!1,this.#m.hidden=!this.#g;let o=typeof re()?.submit=="function";this.#m.disabled=!o||this.#a!=="idle"||this.hasAttribute("disabled"),this.#m.textContent=this.#a==="submitting"?"Submitting\u2026":this.#a==="submitted"?"Submitted":this.getAttribute("submit-label")?.trim()||"Submit";let a=this.#n??(this.#a==="submitted"?"Your response was submitted.":!o&&this.#g?oe:null);this.#l.hidden=a===null,this.#l.textContent=a??"",this.#l.dataset.state=this.#n===null?"info":"error"}};function ar(n){return n.some(t=>t instanceof HTMLElement&&(t instanceof HTMLInputElement||t instanceof HTMLTextAreaElement||t.isContentEditable))}w("crtr-page",Tt);w("crtr-pages",St);var ir=`
1320
1749
  :host {
1321
1750
  display: block;
1322
1751
  }
1323
1752
 
1753
+ /* Flat: this sits in the flow of the page. A shadow in this bundle means floating. */
1324
1754
  [part="unavailable"] {
1325
- padding: var(--crtr-space-3);
1326
- color: var(--crtr-color-text-muted);
1327
- background: var(--crtr-color-surface);
1328
- border: 1px solid var(--crtr-color-border);
1329
- border-radius: var(--crtr-radius-medium);
1330
- box-shadow: var(--crtr-shadow);
1755
+ padding: var(--crtr-slot-unavailable-padding, var(--crtr-space-3));
1756
+ color: var(--crtr-slot-unavailable-text-color, var(--crtr-color-text-muted));
1757
+ background: var(--crtr-slot-unavailable-fill, var(--crtr-color-surface));
1758
+ border: var(--crtr-slot-unavailable-border-width, 1px)
1759
+ var(--crtr-slot-unavailable-border-style, solid)
1760
+ var(--crtr-slot-unavailable-border-color, var(--crtr-color-border));
1761
+ border-radius: var(--crtr-slot-unavailable-radius, var(--crtr-radius-medium));
1331
1762
  }
1332
1763
 
1333
1764
  [part="unavailable"][hidden] {
@@ -1335,13 +1766,13 @@
1335
1766
  }
1336
1767
 
1337
1768
  [part="kind"] {
1338
- color: var(--crtr-color-text);
1339
- font-family: var(--crtr-font-mono);
1769
+ color: var(--crtr-slot-kind-text-color, var(--crtr-color-text));
1770
+ font-family: var(--crtr-slot-kind-font-family, var(--crtr-font-mono));
1340
1771
  }
1341
1772
 
1342
1773
  [part="reason"] {
1343
1774
  display: block;
1344
- margin-top: var(--crtr-space-1);
1345
- font-size: 0.9em;
1775
+ margin-top: var(--crtr-slot-reason-gap, var(--crtr-space-1));
1776
+ font-size: var(--crtr-slot-reason-font-size, 0.875em);
1346
1777
  }
1347
- `,gt=class extends HTMLElement{#n=document.createElement("div");#d=document.createElement("span");#s=document.createElement("span");#t=document.createElement("div");#r=!1;constructor(){super();let t=this.attachShadow({mode:"open"}),e=document.createElement("style");e.textContent=Ie,this.#n.part.add("unavailable"),this.#n.setAttribute("role","status"),this.#d.part.add("kind"),this.#s.part.add("reason"),this.#n.append("Component unavailable: ",this.#d,this.#s),this.#n.hidden=!0,this.#t.part.add("mount"),t.append(e,document.createElement("slot"),this.#n)}connectedCallback(){if(this.#r)return;this.#r=!0;let t=this.getAttribute("kind")?.trim()??"";if(this.#d.textContent=t===""?"unknown":t,t===""){this.#o("This slot names no component kind.");return}let e=k(this);if(e.status!=="ok"){this.#o(e.reason);return}this.append(this.#t),this.#e(t,e.config)}async#e(t,e){await yt(this.#t,t,e)!=="mounted"&&(this.#t.remove(),this.#o("This page is open somewhere that cannot render it."))}#o(t){this.#s.textContent=t,this.#n.hidden=!1}};v("crtr-slot",gt);})();
1778
+ `,At=class extends HTMLElement{#o=document.createElement("div");#i=document.createElement("span");#a=document.createElement("span");#n=document.createElement("div");#e=!1;constructor(){super();let t=this.attachShadow({mode:"open"}),e=document.createElement("style");e.textContent=ir,this.#o.part.add("unavailable"),this.#o.setAttribute("role","status"),this.#i.part.add("kind"),this.#a.part.add("reason"),this.#o.append("Component unavailable: ",this.#i,this.#a),this.#o.hidden=!0,this.#n.part.add("mount"),t.append(e,document.createElement("slot"),this.#o)}connectedCallback(){if(this.#e)return;this.#e=!0;let t=this.getAttribute("kind")?.trim()??"";if(this.#i.textContent=t===""?"unknown":t,t===""){this.#t("This slot names no component kind.");return}let e=T(this);if(e.status!=="ok"){this.#t(e.reason);return}this.append(this.#n),this.#r(t,e.config)}async#r(t,e){await It(this.#n,t,e)!=="mounted"&&(this.#n.remove(),this.#t("This page is open somewhere that cannot render it."))}#t(t){this.#a.textContent=t,this.#o.hidden=!1}};w("crtr-slot",At);})();