vanilla-breeze 0.1.0 → 0.1.2

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 (99) hide show
  1. package/dist/cdn/components/adr-record.js +383 -0
  2. package/dist/cdn/components/adr-wc.js +403 -0
  3. package/dist/cdn/components/analytics-panel.js +34 -0
  4. package/dist/cdn/components/author-index.js +3 -0
  5. package/dist/cdn/components/brand-mark.js +2 -0
  6. package/dist/cdn/components/calendar-wc.js +2 -2
  7. package/dist/cdn/components/carousel-wc.js +1 -1
  8. package/dist/cdn/components/chart-wc.js +25 -25
  9. package/dist/cdn/components/color-palette.js +13 -7
  10. package/dist/cdn/components/comment-wc.js +2 -0
  11. package/dist/cdn/components/consent-banner.js +1 -1
  12. package/dist/cdn/components/content-lens.js +2 -0
  13. package/dist/cdn/components/day-view.js +2 -0
  14. package/dist/cdn/components/empathy-map.js +42 -25
  15. package/dist/cdn/components/flow-diagram.js +2 -0
  16. package/dist/cdn/components/font-pairer.js +108 -0
  17. package/dist/cdn/components/gantt-chart.js +2 -0
  18. package/dist/cdn/components/geo-map.js +7 -7
  19. package/dist/cdn/components/glossary-wc.js +2 -0
  20. package/dist/cdn/components/gradient-builder.js +52 -0
  21. package/dist/cdn/components/highlight-wc.js +3 -0
  22. package/dist/cdn/components/manifest.json +134 -26
  23. package/dist/cdn/components/markdown-viewer.js +3 -3
  24. package/dist/cdn/components/motion-specimen.js +21 -0
  25. package/dist/cdn/components/note-wc.js +3 -0
  26. package/dist/cdn/components/notification-wc.js +37 -0
  27. package/dist/cdn/components/page-info.js +55 -24
  28. package/dist/cdn/components/page-toc.js +1 -1
  29. package/dist/cdn/components/popularity-index.js +9 -0
  30. package/dist/cdn/components/print-page.js +1 -1
  31. package/dist/cdn/components/recently-visited.js +3 -0
  32. package/dist/cdn/components/review-surface.js +541 -0
  33. package/dist/cdn/components/selection-menu.js +2 -0
  34. package/dist/cdn/components/semantic-palette.js +30 -0
  35. package/dist/cdn/components/settings-panel.js +55 -51
  36. package/dist/cdn/components/share-wc.js +2 -2
  37. package/dist/cdn/components/site-map-wc.js +2 -0
  38. package/dist/cdn/components/spacing-specimen.js +5 -5
  39. package/dist/cdn/components/split-surface.js +1 -1
  40. package/dist/cdn/components/text-reader.js +2 -2
  41. package/dist/cdn/components/theme-export.js +18 -0
  42. package/dist/cdn/components/theme-picker.js +58 -58
  43. package/dist/cdn/components/token-specimen.js +25 -20
  44. package/dist/cdn/components/topic-map.js +3 -0
  45. package/dist/cdn/components/trust-filter.js +4 -0
  46. package/dist/cdn/components/type-specimen.js +16 -13
  47. package/dist/cdn/components/user-journey.js +48 -30
  48. package/dist/cdn/components/user-persona.js +17 -15
  49. package/dist/cdn/components/user-story.js +55 -22
  50. package/dist/cdn/components/watch-wc.js +3 -0
  51. package/dist/cdn/components/week-view.js +2 -0
  52. package/dist/cdn/components/work-item.js +446 -0
  53. package/dist/cdn/packs/design-system.full.js +124 -47
  54. package/dist/cdn/packs/effects.full.js +1 -1
  55. package/dist/cdn/packs/kawaii.full.css +1 -1
  56. package/dist/cdn/packs/kawaii.full.js +1 -1
  57. package/dist/cdn/packs/kawaii.theme.css +1 -1
  58. package/dist/cdn/packs/manifest.json +10 -40
  59. package/dist/cdn/packs/prototype.full.js +1 -1
  60. package/dist/cdn/packs/ui.full.css +1 -1
  61. package/dist/cdn/packs/ui.full.js +50 -50
  62. package/dist/cdn/packs/ux-planning.full.css +1 -1
  63. package/dist/cdn/packs/ux-planning.full.js +1546 -92
  64. package/dist/cdn/themes/8bit.css +1 -1
  65. package/dist/cdn/themes/alpha1999.css +1 -1
  66. package/dist/cdn/themes/bauhaus.css +1 -1
  67. package/dist/cdn/themes/brutalist.css +1 -1
  68. package/dist/cdn/themes/claymorphism.css +1 -1
  69. package/dist/cdn/themes/cottagecore.css +1 -1
  70. package/dist/cdn/themes/cyber.css +1 -1
  71. package/dist/cdn/themes/genai.css +1 -1
  72. package/dist/cdn/themes/glassmorphism.css +1 -1
  73. package/dist/cdn/themes/kawaii.css +1 -1
  74. package/dist/cdn/themes/magna.css +1 -1
  75. package/dist/cdn/themes/manifest.json +20 -20
  76. package/dist/cdn/themes/nes.css +1 -1
  77. package/dist/cdn/themes/neumorphism.css +1 -1
  78. package/dist/cdn/themes/organic.css +1 -1
  79. package/dist/cdn/themes/rough.css +1 -1
  80. package/dist/cdn/themes/startup.css +1 -1
  81. package/dist/cdn/themes/super2026.css +1 -1
  82. package/dist/cdn/themes/terminal.css +1 -1
  83. package/dist/cdn/themes/vaporwave.css +1 -1
  84. package/dist/cdn/themes/win9x.css +1 -1
  85. package/dist/cdn/vanilla-breeze-charts.js +25 -25
  86. package/dist/cdn/vanilla-breeze-core.css +1 -1
  87. package/dist/cdn/vanilla-breeze-core.js +119 -47
  88. package/dist/cdn/vanilla-breeze-dev.js +1 -1
  89. package/dist/cdn/vanilla-breeze-extras.js +154 -74
  90. package/dist/cdn/vanilla-breeze.css +1 -1
  91. package/dist/cdn/vanilla-breeze.js +1988 -248
  92. package/package.json +8 -6
  93. package/dist/cdn/packs/retro.bundle.js +0 -2
  94. package/dist/cdn/packs/retro.components.js +0 -1
  95. package/dist/cdn/packs/retro.effects.css +0 -2
  96. package/dist/cdn/packs/retro.effects.js +0 -16
  97. package/dist/cdn/packs/retro.full.css +0 -5
  98. package/dist/cdn/packs/retro.full.js +0 -16
  99. package/dist/cdn/packs/retro.theme.css +0 -2
@@ -1,16 +1,19 @@
1
- var b=window.matchMedia("(prefers-reduced-motion: reduce)");var p=new Map;function m(i,t,n={}){let a=n.priority??10,o={impl:t,bundle:n.bundle,contract:n.contract,priority:a},s=p.get(i);if(customElements.get(i)){if(!s||s.priority>=a){s&&s.priority===a&&s.impl!==t&&console.warn(`[VB Bundle] Tag <${i}> already registered by "${s.bundle}" (priority ${s.priority}). Skipping "${n.bundle}".`);return}console.warn(`[VB Bundle] Tag <${i}> defined by "${s.bundle}" cannot be replaced (customElements.define is permanent). "${n.bundle}" has higher priority but arrived late.`);return}if(s&&s.priority>=a){s.priority===a&&console.warn(`[VB Bundle] Tag <${i}> already registered by "${s.bundle}". Skipping "${n.bundle}" (first wins at equal priority).`);return}p.set(i,o),customElements.define(i,t)}var c=class extends HTMLElement{#e=[];connectedCallback(){this.hasAttribute("data-upgraded")||this.setup()!==!1&&this.setAttribute("data-upgraded","")}disconnectedCallback(){for(let t of this.#e)t();this.#e=[],this.removeAttribute("data-upgraded"),this.teardown()}listen(t,n,a,o){t.addEventListener(n,a,o),this.#e.push(()=>t.removeEventListener(n,a,o))}setup(){}teardown(){}};var l=class extends c{static observedAttributes=["font-family","label","sample","show-scale","show-weights","show-characters","weights"];setup(){this.#e()}attributeChangedCallback(){this.isConnected&&this.#e()}#e(){let t=this.getAttribute("font-family")||"system-ui",n=this.getAttribute("label")||t.replace(/['"]/g,"").split(",")[0],a=this.getAttribute("sample")||"The quick brown fox jumps over the lazy dog",o=this.hasAttribute("show-scale"),s=this.hasAttribute("show-weights"),u=this.hasAttribute("show-characters"),h=(this.getAttribute("weights")||"300,400,500,600,700").split(",").map(e=>e.trim()),r="";if(r+=`<div class="specimen-header" style="font-family:${t}">
2
- <span class="specimen-label">${n}</span>
3
- <p class="specimen-sample" contenteditable="plaintext-only" spellcheck="false">${a}</p>
4
- </div>`,u&&(r+=`<div class="specimen-chars" style="font-family:${t}">
5
- <div class="char-row"><span class="char-label">Upper</span>${"ABCDEFGHIJKLMNOPQRSTUVWXYZ".split("").map(e=>`<span>${e}</span>`).join("")}</div>
6
- <div class="char-row"><span class="char-label">Lower</span>${"abcdefghijklmnopqrstuvwxyz".split("").map(e=>`<span>${e}</span>`).join("")}</div>
7
- <div class="char-row"><span class="char-label">Digits</span>${"0123456789".split("").map(e=>`<span>${e}</span>`).join("")}</div>
8
- <div class="char-row"><span class="char-label">Punct</span>${"!@#$%^&*()_+-=[]{}|;:,.<>?".split("").map(e=>`<span>${e==="<"?"&lt;":e===">"?"&gt;":e==="&"?"&amp;":e}</span>`).join("")}</div>
9
- </div>`),s){r+='<div class="specimen-weights">';for(let e of h)r+=`<div class="weight-sample" style="font-family:${t};font-weight:${e}">
10
- <span class="weight-label">${e}</span>
1
+ var w=window.matchMedia("(prefers-reduced-motion: reduce)");var p=new Map;function u(r,e,s={}){let n=s.priority??10,o={impl:e,bundle:s.bundle,contract:s.contract,priority:n},i=p.get(r);if(customElements.get(r)){if(!i||i.priority>=n){i&&i.priority===n&&i.impl!==e&&console.warn(`[VB Bundle] Tag <${r}> already registered by "${i.bundle}" (priority ${i.priority}). Skipping "${s.bundle}".`);return}console.warn(`[VB Bundle] Tag <${r}> defined by "${i.bundle}" cannot be replaced (customElements.define is permanent). "${s.bundle}" has higher priority but arrived late.`);return}if(i&&i.priority>=n){i.priority===n&&console.warn(`[VB Bundle] Tag <${r}> already registered by "${i.bundle}". Skipping "${s.bundle}" (first wins at equal priority).`);return}p.set(r,o),customElements.define(r,e)}var l=class extends HTMLElement{#e=[];connectedCallback(){this.hasAttribute("data-upgraded")||this.setup()!==!1&&this.setAttribute("data-upgraded","")}disconnectedCallback(){for(let e of this.#e)e();this.#e=[],this.removeAttribute("data-upgraded"),this.teardown()}listen(e,s,n,o){e.addEventListener(s,n,o),this.#e.push(()=>e.removeEventListener(s,n,o))}setup(){}teardown(){}};var b=["system-ui","Georgia","Inter, sans-serif",'"JetBrains Mono", monospace',"Verdana","Cambria","ui-serif"],c=class extends l{static observedAttributes=["font-family","label","sample","show-scale","show-weights","show-characters","weights","editable","target","token"];setup(){this.#e(),this.#t()}attributeChangedCallback(){this.isConnected&&(this.#e(),this.#t())}#e(){let e=this.getAttribute("font-family")||"system-ui",s=this.getAttribute("label")||e.replace(/['"]/g,"").split(",")[0],n=this.getAttribute("sample")||"The quick brown fox jumps over the lazy dog",o=this.hasAttribute("show-scale"),i=this.hasAttribute("show-weights"),m=this.hasAttribute("show-characters"),f=(this.getAttribute("weights")||"300,400,500,600,700").split(",").map(t=>t.trim()),a="",h=this.hasAttribute("editable")?`<input type="text" class="specimen-font-input" value="${e.replace(/"/g,"&quot;")}" aria-label="Font family" style="font:inherit;padding:0.25rem 0.5rem;border:1px solid var(--color-border,#ccc);border-radius:var(--radius-s,0.25rem);min-inline-size:18rem;max-inline-size:100%;font-family:${e};font-size:var(--font-size-sm,0.875rem)">
2
+ <span class="specimen-quick" style="display:inline-flex;flex-wrap:wrap;gap:0.25rem;margin-inline-start:0.5rem">
3
+ ${b.map(t=>`<button type="button" class="specimen-quick-btn" data-font="${t.replace(/"/g,"&quot;")}" style="font:inherit;font-size:var(--font-size-xs,0.75rem);padding:0.125rem 0.5rem;border:1px solid var(--color-border,#ccc);border-radius:999px;background:var(--color-surface,#fff);color:var(--color-text,#222);cursor:pointer">${t.split(",")[0].replace(/["']/g,"")}</button>`).join("")}
4
+ </span>`:`<span class="specimen-label">${s}</span>`;if(a+=`<div class="specimen-header" style="font-family:${e}">
5
+ ${h}
6
+ <p class="specimen-sample" contenteditable="plaintext-only" spellcheck="false">${n}</p>
7
+ </div>`,m&&(a+=`<div class="specimen-chars" style="font-family:${e}">
8
+ <div class="char-row"><span class="char-label">Upper</span>${"ABCDEFGHIJKLMNOPQRSTUVWXYZ".split("").map(t=>`<span>${t}</span>`).join("")}</div>
9
+ <div class="char-row"><span class="char-label">Lower</span>${"abcdefghijklmnopqrstuvwxyz".split("").map(t=>`<span>${t}</span>`).join("")}</div>
10
+ <div class="char-row"><span class="char-label">Digits</span>${"0123456789".split("").map(t=>`<span>${t}</span>`).join("")}</div>
11
+ <div class="char-row"><span class="char-label">Punct</span>${"!@#$%^&*()_+-=[]{}|;:,.<>?".split("").map(t=>`<span>${t==="<"?"&lt;":t===">"?"&gt;":t==="&"?"&amp;":t}</span>`).join("")}</div>
12
+ </div>`),i){a+='<div class="specimen-weights">';for(let t of f)a+=`<div class="weight-sample" style="font-family:${e};font-weight:${t}">
13
+ <span class="weight-label">${t}</span>
11
14
  <span class="weight-text">Aa</span>
12
- </div>`;r+="</div>"}if(o){let e=[{name:"xs",rem:.75},{name:"sm",rem:.875},{name:"md",rem:1},{name:"lg",rem:1.125},{name:"xl",rem:1.25},{name:"2xl",rem:1.5},{name:"3xl",rem:1.875},{name:"4xl",rem:2.25},{name:"5xl",rem:3}];r+='<div class="specimen-scale">';for(let d of e)r+=`<div class="scale-step" style="font-family:${t};font-size:${d.rem}rem">
15
+ </div>`;a+="</div>"}if(o){let t=[{name:"xs",rem:.75},{name:"sm",rem:.875},{name:"md",rem:1},{name:"lg",rem:1.125},{name:"xl",rem:1.25},{name:"2xl",rem:1.5},{name:"3xl",rem:1.875},{name:"4xl",rem:2.25},{name:"5xl",rem:3}];a+='<div class="specimen-scale">';for(let d of t)a+=`<div class="scale-step" style="font-family:${e};font-size:${d.rem}rem">
13
16
  <span class="scale-label">${d.name}</span>
14
- <span class="scale-text">${a.substring(0,30)}</span>
15
- </div>`;r+="</div>"}this.innerHTML=r}};m("type-specimen",l);
17
+ <span class="scale-text">${n.substring(0,30)}</span>
18
+ </div>`;a+="</div>"}this.innerHTML=a}#t(){if(!this.hasAttribute("editable"))return;let e=this.querySelector(".specimen-font-input");e&&this.listen(e,"input",()=>this.#s(e.value)),this.querySelectorAll(".specimen-quick-btn").forEach(s=>{this.listen(s,"click",()=>{let n=s.getAttribute("data-font")||"";e&&(e.value=n),this.#s(n)})})}#s(e){let s=this.#n(),n=this.getAttribute("token")||"font-family-base";s&&s.style.setProperty(`--${n}`,e),this.setAttribute("font-family",e),this.dispatchEvent(new CustomEvent("type-specimen:change",{bubbles:!0,detail:{fontFamily:e,token:n,target:this.getAttribute("target")||":root"}}))}#n(){let e=this.getAttribute("target")||":root";try{return e===":root"?document.documentElement:document.querySelector(e)}catch{return document.documentElement}}};u("type-specimen",c);
16
19
  //# sourceMappingURL=type-specimen.js.map
@@ -114,22 +114,38 @@ var g=`
114
114
  .persona-ref svg { width: 14px; height: 14px; flex-shrink: 0; }
115
115
  a.persona-ref:hover { color: #6366f1; text-decoration: underline; }
116
116
 
117
- /* Title & summary */
117
+ /* Title & summary (slotted content) */
118
+ .journey__title-wrap {
119
+ margin-block-end: var(--_space-2xs);
120
+ }
121
+
118
122
  .journey__title {
119
123
  font-size: var(--_font-xl);
120
124
  font-weight: 700;
121
125
  color: var(--_text);
122
- margin-block-end: var(--_space-2xs);
126
+ margin: 0;
127
+ }
128
+
129
+ ::slotted([slot="title"]) {
130
+ font-size: var(--_font-xl) !important;
131
+ font-weight: 700 !important;
132
+ color: var(--_text) !important;
133
+ margin: 0 !important;
123
134
  }
124
135
 
125
- .journey--compact .journey__title { font-size: var(--_font-md); }
136
+ .journey--compact .journey__title,
137
+ .journey--compact ::slotted([slot="title"]) { font-size: var(--_font-md) !important; }
126
138
 
127
- .journey__summary {
128
- font-size: var(--_font-sm);
129
- color: var(--_muted);
139
+ .journey__summary-wrap {
130
140
  max-width: 72ch;
131
141
  }
132
142
 
143
+ ::slotted([slot="summary"]) {
144
+ font-size: var(--_font-sm) !important;
145
+ color: var(--_muted) !important;
146
+ margin: 0 !important;
147
+ }
148
+
133
149
  /* Emotion curve */
134
150
  .journey__curve {
135
151
  background: var(--_bg);
@@ -287,29 +303,31 @@ var g=`
287
303
  .journey__grid-wrap { overflow: visible; }
288
304
  .row-label, .corner { position: relative; }
289
305
  }
290
- `;var E=window.matchMedia("(prefers-reduced-motion: reduce)");var $=new Map;function j(i,e,r={}){let t=r.priority??10,s={impl:e,bundle:r.bundle,contract:r.contract,priority:t},o=$.get(i);if(customElements.get(i)){if(!o||o.priority>=t){o&&o.priority===t&&o.impl!==e&&console.warn(`[VB Bundle] Tag <${i}> already registered by "${o.bundle}" (priority ${o.priority}). Skipping "${r.bundle}".`);return}console.warn(`[VB Bundle] Tag <${i}> defined by "${o.bundle}" cannot be replaced (customElements.define is permanent). "${r.bundle}" has higher priority but arrived late.`);return}if(o&&o.priority>=t){o.priority===t&&console.warn(`[VB Bundle] Tag <${i}> already registered by "${o.bundle}". Skipping "${r.bundle}" (first wins at equal priority).`);return}$.set(i,s),customElements.define(i,e)}function l(i){return String(i).replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/"/g,"&quot;")}function x(i){return`<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true">${i}</svg>`}var h={user:'<path d="M19 21v-2a4 4 0 0 0-4-4H9a4 4 0 0 0-4 4v2"/><circle cx="12" cy="7" r="4"/>',pencil:'<path d="M21.174 6.812a1 1 0 0 0-3.986-3.987L3.842 16.174a2 2 0 0 0-.5.83l-1.321 4.352a.5.5 0 0 0 .623.622l4.353-1.32a2 2 0 0 0 .83-.497z"/><path d="m15 5 4 4"/>',check:'<path d="M20 6 9 17l-5-5"/>',target:'<circle cx="12" cy="12" r="10"/><circle cx="12" cy="12" r="6"/><circle cx="12" cy="12" r="2"/>',alertTriangle:'<path d="m21.73 18-8-14a2 2 0 0 0-3.48 0l-8 14A2 2 0 0 0 4 21h16a2 2 0 0 0 1.73-3"/><path d="M12 9v4"/><path d="M12 17h.01"/>',messageCircle:'<path d="M2.992 16.342a2 2 0 0 1 .094 1.167l-1.065 3.29a1 1 0 0 0 1.236 1.168l3.413-.998a2 2 0 0 1 1.099.092 10 10 0 1 0-4.777-4.719"/>',lightbulb:'<path d="M15 14c.2-1 .7-1.7 1.5-2.5 1-.9 1.5-2.2 1.5-3.5A6 6 0 0 0 6 8c0 1 .2 2.2 1.5 3.5.7.7 1.3 1.5 1.5 2.5"/><path d="M9 18h6"/><path d="M10 22h4"/>',wrench:'<path d="M14.7 6.3a1 1 0 0 0 0 1.4l1.6 1.6a1 1 0 0 0 1.4 0l3.106-3.105c.32-.322.863-.22.983.218a6 6 0 0 1-8.259 7.057l-7.91 7.91a1 1 0 0 1-2.999-3l7.91-7.91a6 6 0 0 1 7.057-8.259c.438.12.54.662.219.984z"/>',heart:'<path d="M2 9.5a5.5 5.5 0 0 1 9.591-3.676.56.56 0 0 0 .818 0A5.49 5.49 0 0 1 22 9.5c0 2.29-1.5 4-3 5.5l-5.492 5.313a2 2 0 0 1-3 .019L5 15c-1.5-1.5-3-3.2-3-5.5"/>'},S={says:{label:"Says",icon:h.messageCircle,color:"#3b82f6"},thinks:{label:"Thinks",icon:h.lightbulb,color:"#8b5cf6"},does:{label:"Does",icon:h.wrench,color:"#f59e0b"},feels:{label:"Feels",icon:h.heart,color:"#ef4444"}},f={delighted:{emoji:"\u{1F604}",score:.95,color:"#16a34a"},satisfied:{emoji:"\u{1F60A}",score:.8,color:"#22c55e"},hopeful:{emoji:"\u{1F642}",score:.68,color:"#84cc16"},curious:{emoji:"\u{1F914}",score:.55,color:"#eab308"},neutral:{emoji:"\u{1F610}",score:.5,color:"#94a3b8"},uncertain:{emoji:"\u{1F615}",score:.4,color:"#f97316"},confused:{emoji:"\u{1F635}",score:.3,color:"#fb923c"},frustrated:{emoji:"\u{1F624}",score:.18,color:"#ef4444"},angry:{emoji:"\u{1F620}",score:.05,color:"#dc2626"}};var M=[{key:"actions",label:"Actions"},{key:"thoughts",label:"Thoughts"},{key:"touchpoints",label:"Touchpoints"},{key:"painPoints",label:"Pain Points"},{key:"opportunities",label:"Opportunities"}],_=class extends HTMLElement{static get observedAttributes(){return["src","title","persona","persona-id","summary","story-ids","compact"]}#e=new Map;constructor(){super(),this.attachShadow({mode:"open"}),this.__phases=null}get phases(){return this.__phases}set phases(e){this.__phases=e,this.isConnected&&this._render()}#r(){for(let e of this.children){let r=e.getAttribute("slot");r&&this.#e.set(r,e.textContent.trim())}}_resolve(e){return this.getAttribute(e)||this.#e.get(e)||""}connectedCallback(){this.#r(),this.setAttribute("data-upgraded",""),this.hasAttribute("src")?this._loadSrc(this.getAttribute("src")):this._render()}disconnectedCallback(){this.removeAttribute("data-upgraded")}attributeChangedCallback(e){this.isConnected&&(e==="src"?this._loadSrc(this.getAttribute("src")):this._render())}async _loadSrc(e){if(e){this.shadowRoot.innerHTML=`<style>${g}</style><div class="state-msg">Loading\u2026</div>`;try{let r=await fetch(e);if(!r.ok)throw new Error(`HTTP ${r.status}`);let t=await r.json();t.title&&this.setAttribute("title",t.title),t.persona&&this.setAttribute("persona",t.persona),t.personaId&&this.setAttribute("persona-id",t.personaId),t.summary&&this.setAttribute("summary",t.summary),this.__phases=t.phases||[],this._render()}catch(r){this.shadowRoot.innerHTML=`<style>${g}</style><div class="state-msg state-msg--error">Could not load journey: ${l(r.message)}</div>`}}}_render(){let e=this._resolve("title")||"User Journey",r=this._resolve("persona")||"",t=this._resolve("persona-id")||"",s=this._resolve("summary")||"",o=(this._resolve("story-ids")||"").split(",").map(n=>n.trim()).filter(Boolean),p=this.hasAttribute("compact"),c=this.__phases;this.shadowRoot.innerHTML=`<style>${g}</style>
291
- <article class="journey${p?" journey--compact":""}">
306
+ `;var E=window.matchMedia("(prefers-reduced-motion: reduce)");var $=new Map;function j(n,e,r={}){let a=r.priority??10,o={impl:e,bundle:r.bundle,contract:r.contract,priority:a},t=$.get(n);if(customElements.get(n)){if(!t||t.priority>=a){t&&t.priority===a&&t.impl!==e&&console.warn(`[VB Bundle] Tag <${n}> already registered by "${t.bundle}" (priority ${t.priority}). Skipping "${r.bundle}".`);return}console.warn(`[VB Bundle] Tag <${n}> defined by "${t.bundle}" cannot be replaced (customElements.define is permanent). "${r.bundle}" has higher priority but arrived late.`);return}if(t&&t.priority>=a){t.priority===a&&console.warn(`[VB Bundle] Tag <${n}> already registered by "${t.bundle}". Skipping "${r.bundle}" (first wins at equal priority).`);return}$.set(n,o),customElements.define(n,e)}function d(n){return String(n).replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/"/g,"&quot;")}function x(n){return`<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true">${n}</svg>`}var h={user:'<path d="M19 21v-2a4 4 0 0 0-4-4H9a4 4 0 0 0-4 4v2"/><circle cx="12" cy="7" r="4"/>',pencil:'<path d="M21.174 6.812a1 1 0 0 0-3.986-3.987L3.842 16.174a2 2 0 0 0-.5.83l-1.321 4.352a.5.5 0 0 0 .623.622l4.353-1.32a2 2 0 0 0 .83-.497z"/><path d="m15 5 4 4"/>',check:'<path d="M20 6 9 17l-5-5"/>',target:'<circle cx="12" cy="12" r="10"/><circle cx="12" cy="12" r="6"/><circle cx="12" cy="12" r="2"/>',alertTriangle:'<path d="m21.73 18-8-14a2 2 0 0 0-3.48 0l-8 14A2 2 0 0 0 4 21h16a2 2 0 0 0 1.73-3"/><path d="M12 9v4"/><path d="M12 17h.01"/>',messageCircle:'<path d="M2.992 16.342a2 2 0 0 1 .094 1.167l-1.065 3.29a1 1 0 0 0 1.236 1.168l3.413-.998a2 2 0 0 1 1.099.092 10 10 0 1 0-4.777-4.719"/>',lightbulb:'<path d="M15 14c.2-1 .7-1.7 1.5-2.5 1-.9 1.5-2.2 1.5-3.5A6 6 0 0 0 6 8c0 1 .2 2.2 1.5 3.5.7.7 1.3 1.5 1.5 2.5"/><path d="M9 18h6"/><path d="M10 22h4"/>',wrench:'<path d="M14.7 6.3a1 1 0 0 0 0 1.4l1.6 1.6a1 1 0 0 0 1.4 0l3.106-3.105c.32-.322.863-.22.983.218a6 6 0 0 1-8.259 7.057l-7.91 7.91a1 1 0 0 1-2.999-3l7.91-7.91a6 6 0 0 1 7.057-8.259c.438.12.54.662.219.984z"/>',heart:'<path d="M2 9.5a5.5 5.5 0 0 1 9.591-3.676.56.56 0 0 0 .818 0A5.49 5.49 0 0 1 22 9.5c0 2.29-1.5 4-3 5.5l-5.492 5.313a2 2 0 0 1-3 .019L5 15c-1.5-1.5-3-3.2-3-5.5"/>',mapPin:'<path d="M20 10c0 4.993-5.539 10.193-7.399 11.799a1 1 0 0 1-1.202 0C9.539 20.193 4 14.993 4 10a8 8 0 0 1 16 0"/><circle cx="12" cy="10" r="3"/>',checkCircle:'<path d="M22 11.08V12a10 10 0 1 1-5.93-9.14"/><path d="m9 11 3 3L22 4"/>',x:'<path d="M18 6 6 18"/><path d="m6 6 12 12"/>',download:'<path d="M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4"/><polyline points="7 10 12 15 17 10"/><line x1="12" x2="12" y1="15" y2="3"/>',send:'<path d="M14.536 21.686a.5.5 0 0 0 .937-.024l6.5-19a.496.496 0 0 0-.635-.635l-19 6.5a.5.5 0 0 0-.024.937l7.93 3.18a2 2 0 0 1 1.112 1.11z"/><path d="m21.854 2.147-10.94 10.939"/>'},A={says:{label:"Says",icon:h.messageCircle,color:"#3b82f6"},thinks:{label:"Thinks",icon:h.lightbulb,color:"#8b5cf6"},does:{label:"Does",icon:h.wrench,color:"#f59e0b"},feels:{label:"Feels",icon:h.heart,color:"#ef4444"}},f={delighted:{emoji:"\u{1F604}",score:.95,color:"#16a34a"},satisfied:{emoji:"\u{1F60A}",score:.8,color:"#22c55e"},hopeful:{emoji:"\u{1F642}",score:.68,color:"#84cc16"},curious:{emoji:"\u{1F914}",score:.55,color:"#eab308"},neutral:{emoji:"\u{1F610}",score:.5,color:"#94a3b8"},uncertain:{emoji:"\u{1F615}",score:.4,color:"#f97316"},confused:{emoji:"\u{1F635}",score:.3,color:"#fb923c"},frustrated:{emoji:"\u{1F624}",score:.18,color:"#ef4444"},angry:{emoji:"\u{1F620}",score:.05,color:"#dc2626"}};var M=[{key:"actions",label:"Actions"},{key:"thoughts",label:"Thoughts"},{key:"touchpoints",label:"Touchpoints"},{key:"painPoints",label:"Pain Points"},{key:"opportunities",label:"Opportunities"}],_=class extends HTMLElement{static get observedAttributes(){return["src","persona","persona-id","story-ids","compact"]}#e=new Map;constructor(){super(),this.attachShadow({mode:"open"}),this.__phases=null}get phases(){return this.__phases}set phases(e){this.__phases=e,this.isConnected&&this._render()}#t(){for(let e of this.children){let r=e.getAttribute("slot");r&&this.#e.set(r,e.textContent.trim())}}_resolve(e){return this.getAttribute(e)||this.#e.get(e)||""}connectedCallback(){this.#t(),this.setAttribute("data-upgraded",""),this.hasAttribute("src")?this._loadSrc(this.getAttribute("src")):this._render()}disconnectedCallback(){this.removeAttribute("data-upgraded")}attributeChangedCallback(e){this.isConnected&&(e==="src"?this._loadSrc(this.getAttribute("src")):this._render())}async _loadSrc(e){if(e){this.shadowRoot.innerHTML=`<style>${g}</style><div class="state-msg">Loading\u2026</div>`;try{let r=await fetch(e);if(!r.ok)throw new Error(`HTTP ${r.status}`);let a=await r.json();if(a.persona&&this.setAttribute("persona",a.persona),a.personaId&&this.setAttribute("persona-id",a.personaId),a.title&&!this.querySelector('[slot="title"]')){let o=document.createElement("h2");o.slot="title",o.textContent=a.title,this.appendChild(o)}if(a.summary&&!this.querySelector('[slot="summary"]')){let o=document.createElement("p");o.slot="summary",o.textContent=a.summary,this.appendChild(o)}this.__phases=a.phases||[],this._render()}catch(r){this.shadowRoot.innerHTML=`<style>${g}</style><div class="state-msg state-msg--error">Could not load journey: ${d(r.message)}</div>`}}}_render(){let e=this._resolve("persona")||"",r=this._resolve("persona-id")||"",a=(this.getAttribute("story-ids")||"").split(",").map(i=>i.trim()).filter(Boolean),o=this.hasAttribute("compact"),t=this.__phases,p=!!this.querySelector('[slot="summary"]')||this.#e.has("summary");this.shadowRoot.innerHTML=`<style>${g}</style>
307
+ <article class="journey${o?" journey--compact":""}">
292
308
 
293
309
  <header class="journey__header">
294
310
  <div class="journey__header-top">
295
311
  <div class="journey__chips">
296
312
  <span class="chip chip--type">Journey Map</span>
297
- ${o.map(n=>`<a class="chip chip--story" href="#${n}">${this._label(n)}</a>`).join("")}
313
+ ${a.map(i=>`<a class="chip chip--story" href="#${i}">${this._label(i)}</a>`).join("")}
298
314
  </div>
299
- ${r?`
315
+ ${e?`
300
316
  <div class="journey__persona">
301
- ${t?`<a class="persona-ref" href="#${t}">${x(h.user)} ${l(r)}</a>`:`<span class="persona-ref">${x(h.user)} ${l(r)}</span>`}
317
+ ${r?`<a class="persona-ref" href="#${r}">${x(h.user)} ${d(e)}</a>`:`<span class="persona-ref">${x(h.user)} ${d(e)}</span>`}
302
318
  </div>`:""}
303
319
  </div>
304
- <h2 class="journey__title">${l(e)}</h2>
305
- ${s?`<p class="journey__summary">${l(s)}</p>`:""}
320
+ <div class="journey__title-wrap">
321
+ <slot name="title"><h2 class="journey__title">User Journey</h2></slot>
322
+ </div>
323
+ ${p?'<div class="journey__summary-wrap"><slot name="summary"></slot></div>':""}
306
324
  </header>
307
325
 
308
- ${c&&c.length?this._curve(c)+this._grid(c):`<div class="journey__placeholder">
326
+ ${t&&t.length?this._curve(t)+this._grid(t):`<div class="journey__placeholder">
309
327
  <p>Add phase data via <code>src</code> (JSON) or set <code>.phases</code> programmatically.</p>
310
328
  </div>`}
311
329
 
312
- </article>`,this.dispatchEvent(new CustomEvent("journey-ready",{bubbles:!0,composed:!0,detail:{title:e,persona:r,phaseCount:c?c.length:0}}))}_curve(e){let n=e.length,b=a=>28+(n<2?944/2:a/(n-1)*944),k=a=>14+(1-(f[a.emotion]||f.neutral).score)*72,d=e.map((a,u)=>({x:b(u),y:k(a),ph:a})),v=`M ${d[0].x},${d[0].y}`;for(let a=1;a<d.length;a++){let u=d[a-1],m=d[a],y=(u.x+m.x)/2;v+=` C ${y},${u.y} ${y},${m.y} ${m.x},${m.y}`}let w=`uj-${Math.random().toString(36).slice(2,8)}`,z=d.at(-1);return`
330
+ </article>`,this.dispatchEvent(new CustomEvent("journey-ready",{bubbles:!0,composed:!0,detail:{title,persona:e,phaseCount:t?t.length:0}}))}_curve(e){let l=e.length,b=s=>28+(l<2?944/2:s/(l-1)*944),k=s=>14+(1-(f[s.emotion]||f.neutral).score)*72,c=e.map((s,u)=>({x:b(u),y:k(s),ph:s})),v=`M ${c[0].x},${c[0].y}`;for(let s=1;s<c.length;s++){let u=c[s-1],m=c[s],y=(u.x+m.x)/2;v+=` C ${y},${u.y} ${y},${m.y} ${m.x},${m.y}`}let w=`uj-${Math.random().toString(36).slice(2,8)}`,z=c.at(-1);return`
313
331
  <div class="journey__curve" aria-hidden="true">
314
332
  <svg viewBox="0 0 1000 100" preserveAspectRatio="none" class="curve-svg">
315
333
  <defs>
@@ -321,35 +339,35 @@ var g=`
321
339
  <rect x="0" y="0" width="1000" height="${100*.4}" class="zone zone--pos"/>
322
340
  <rect x="0" y="${100*.4}" width="1000" height="${100*.2}" class="zone zone--neu"/>
323
341
  <rect x="0" y="${100*.6}" width="1000" height="${100*.4}" class="zone zone--neg"/>
324
- ${d.map(({x:a})=>`<line x1="${a}" y1="0" x2="${a}" y2="100" class="vline"/>`).join("")}
325
- <path d="${v} L ${z.x},100 L ${d[0].x},100 Z" fill="url(#${w})"/>
342
+ ${c.map(({x:s})=>`<line x1="${s}" y1="0" x2="${s}" y2="100" class="vline"/>`).join("")}
343
+ <path d="${v} L ${z.x},100 L ${c[0].x},100 Z" fill="url(#${w})"/>
326
344
  <path d="${v}" fill="none" class="curve-line"/>
327
- ${d.map(({x:a,y:u,ph:m})=>{let y=f[m.emotion]||f.neutral;return`<circle cx="${a}" cy="${u}" r="5" class="dot" style="fill:${y.color}"/>`}).join("")}
345
+ ${c.map(({x:s,y:u,ph:m})=>{let y=f[m.emotion]||f.neutral;return`<circle cx="${s}" cy="${u}" r="5" class="dot" style="fill:${y.color}"/>`}).join("")}
328
346
  </svg>
329
- </div>`}_grid(e){let r=e.map((s,o)=>{let p=f[s.emotion]||f.neutral,c=s.storyIds||[];return`
330
- <th class="phase-head" data-emotion="${s.emotion||"neutral"}"
347
+ </div>`}_grid(e){let r=e.map((o,t)=>{let p=f[o.emotion]||f.neutral,i=o.storyIds||[];return`
348
+ <th class="phase-head" data-emotion="${o.emotion||"neutral"}"
331
349
  style="--ec:${p.color}">
332
- <span class="ph-num">${o+1}</span>
333
- <span class="ph-name">${l(s.name||"")}</span>
334
- <span class="ph-emoji" title="${s.emotion||"neutral"}"><span role="img" aria-label="${l(s.emotion||"neutral")}">${p.emoji}</span></span>
335
- ${c.length?`<div class="ph-stories">${c.map(n=>`<a class="chip chip--story" href="#${n}">${this._label(n)}</a>`).join("")}</div>`:""}
336
- </th>`}).join(""),t=M.map(({key:s,label:o})=>{let p=e.map(c=>{let n=c[s]||[];return n.length?`<td class="data-cell data-cell--${s.toLowerCase()}">
337
- ${n.map(b=>`<p>${l(b)}</p>`).join("")}
350
+ <span class="ph-num">${t+1}</span>
351
+ <span class="ph-name">${d(o.name||"")}</span>
352
+ <span class="ph-emoji" title="${o.emotion||"neutral"}"><span role="img" aria-label="${d(o.emotion||"neutral")}">${p.emoji}</span></span>
353
+ ${i.length?`<div class="ph-stories">${i.map(l=>`<a class="chip chip--story" href="#${l}">${this._label(l)}</a>`).join("")}</div>`:""}
354
+ </th>`}).join(""),a=M.map(({key:o,label:t})=>{let p=e.map(i=>{let l=i[o]||[];return l.length?`<td class="data-cell data-cell--${o.toLowerCase()}">
355
+ ${l.map(b=>`<p>${d(b)}</p>`).join("")}
338
356
  </td>`:'<td class="data-cell data-cell--empty">\u2014</td>'}).join("");return`
339
- <tr class="grid-row grid-row--${s.toLowerCase()}">
340
- <th class="row-label">${o}</th>
357
+ <tr class="grid-row grid-row--${o.toLowerCase()}">
358
+ <th class="row-label">${t}</th>
341
359
  ${p}
342
360
  </tr>`}).join("");return`
343
361
  <div class="journey__grid-wrap">
344
362
  <table class="journey__grid"
345
- aria-label="${l(this.getAttribute("title")||"User Journey")} \u2014 phase breakdown">
363
+ aria-label="${d(this.getAttribute("title")||"User Journey")} \u2014 phase breakdown">
346
364
  <thead>
347
365
  <tr>
348
366
  <th class="corner">Stage</th>
349
367
  ${r}
350
368
  </tr>
351
369
  </thead>
352
- <tbody>${t}</tbody>
370
+ <tbody>${a}</tbody>
353
371
  </table>
354
372
  </div>`}_label(e){return e.replace(/^(activity|persona|journey|story|user)-/,"").replace(/-/g," ").replace(/\b\w/g,r=>r.toUpperCase())}};j("user-journey",_);export{_ as UserJourney};
355
373
  //# sourceMappingURL=user-journey.js.map
@@ -1,4 +1,4 @@
1
- var d=`
1
+ var v=`
2
2
  :host {
3
3
  display: block;
4
4
  font-family: var(--user-persona-font, var(--font-sans, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif));
@@ -246,41 +246,43 @@ var d=`
246
246
  transition: none !important;
247
247
  }
248
248
  }
249
- `;var b=window.matchMedia("(prefers-reduced-motion: reduce)");var p=new Map;function v(o,e,t={}){let r=t.priority??10,s={impl:e,bundle:t.bundle,contract:t.contract,priority:r},a=p.get(o);if(customElements.get(o)){if(!a||a.priority>=r){a&&a.priority===r&&a.impl!==e&&console.warn(`[VB Bundle] Tag <${o}> already registered by "${a.bundle}" (priority ${a.priority}). Skipping "${t.bundle}".`);return}console.warn(`[VB Bundle] Tag <${o}> defined by "${a.bundle}" cannot be replaced (customElements.define is permanent). "${t.bundle}" has higher priority but arrived late.`);return}if(a&&a.priority>=r){a.priority===r&&console.warn(`[VB Bundle] Tag <${o}> already registered by "${a.bundle}". Skipping "${t.bundle}" (first wins at equal priority).`);return}p.set(o,s),customElements.define(o,e)}function i(o){return String(o).replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/"/g,"&quot;")}function u(o){return o.split(" ").map(e=>e[0]).join("").toUpperCase().slice(0,2)}function h(o){let e=0;for(let r=0;r<o.length;r++)e=o.charCodeAt(r)+((e<<5)-e);return`hsl(${(e%360+360)%360}, 65%, 55%)`}var n={user:'<path d="M19 21v-2a4 4 0 0 0-4-4H9a4 4 0 0 0-4 4v2"/><circle cx="12" cy="7" r="4"/>',pencil:'<path d="M21.174 6.812a1 1 0 0 0-3.986-3.987L3.842 16.174a2 2 0 0 0-.5.83l-1.321 4.352a.5.5 0 0 0 .623.622l4.353-1.32a2 2 0 0 0 .83-.497z"/><path d="m15 5 4 4"/>',check:'<path d="M20 6 9 17l-5-5"/>',target:'<circle cx="12" cy="12" r="10"/><circle cx="12" cy="12" r="6"/><circle cx="12" cy="12" r="2"/>',alertTriangle:'<path d="m21.73 18-8-14a2 2 0 0 0-3.48 0l-8 14A2 2 0 0 0 4 21h16a2 2 0 0 0 1.73-3"/><path d="M12 9v4"/><path d="M12 17h.01"/>',messageCircle:'<path d="M2.992 16.342a2 2 0 0 1 .094 1.167l-1.065 3.29a1 1 0 0 0 1.236 1.168l3.413-.998a2 2 0 0 1 1.099.092 10 10 0 1 0-4.777-4.719"/>',lightbulb:'<path d="M15 14c.2-1 .7-1.7 1.5-2.5 1-.9 1.5-2.2 1.5-3.5A6 6 0 0 0 6 8c0 1 .2 2.2 1.5 3.5.7.7 1.3 1.5 1.5 2.5"/><path d="M9 18h6"/><path d="M10 22h4"/>',wrench:'<path d="M14.7 6.3a1 1 0 0 0 0 1.4l1.6 1.6a1 1 0 0 0 1.4 0l3.106-3.105c.32-.322.863-.22.983.218a6 6 0 0 1-8.259 7.057l-7.91 7.91a1 1 0 0 1-2.999-3l7.91-7.91a6 6 0 0 1 7.057-8.259c.438.12.54.662.219.984z"/>',heart:'<path d="M2 9.5a5.5 5.5 0 0 1 9.591-3.676.56.56 0 0 0 .818 0A5.49 5.49 0 0 1 22 9.5c0 2.29-1.5 4-3 5.5l-5.492 5.313a2 2 0 0 1-3 .019L5 15c-1.5-1.5-3-3.2-3-5.5"/>'},_={says:{label:"Says",icon:n.messageCircle,color:"#3b82f6"},thinks:{label:"Thinks",icon:n.lightbulb,color:"#8b5cf6"},does:{label:"Does",icon:n.wrench,color:"#f59e0b"},feels:{label:"Feels",icon:n.heart,color:"#ef4444"}};var c=class extends HTMLElement{static get observedAttributes(){return["name","role","age","location","avatar","quote","compact","src"]}#e=new Map;constructor(){super(),this.attachShadow({mode:"open"})}#r(){for(let e of[...this.children]){let t=e.getAttribute("slot");t&&!this.getAttribute(t)&&this.#e.set(t,e.textContent.trim())}}_resolve(e){return this.getAttribute(e)||this.#e.get(e)||""}async _loadSrc(e){if(e)try{let t=await fetch(e);if(!t.ok)throw new Error(`HTTP ${t.status}`);let r=await t.json();for(let s of["name","role","age","location","avatar","quote"])r[s]&&this.setAttribute(s,r[s]);for(let s of["bio","goals","frustrations","behaviors"])r[s]&&(Array.isArray(r[s])?this.#e.set(s,r[s]):this.#e.set(s,r[s]));this.#t()}catch(t){console.warn(`[user-persona] Failed to load src="${e}":`,t)}}connectedCallback(){this.#r(),this.hasAttribute("src")&&this._loadSrc(this.getAttribute("src")),this.#t(),this.setAttribute("data-upgraded",""),this.dispatchEvent(new CustomEvent("persona-ready",{bubbles:!0,composed:!0,detail:{name:this.personaName,role:this.personaRole}}))}disconnectedCallback(){this.removeAttribute("data-upgraded")}attributeChangedCallback(e,t,r){t!==r&&this.shadowRoot&&(e==="src"&&this.isConnected?this._loadSrc(r):this.#t())}get personaName(){return this._resolve("name")||"Unnamed Persona"}get personaRole(){return this._resolve("role")||""}get age(){return this._resolve("age")||""}get location(){return this._resolve("location")||""}get avatar(){return this._resolve("avatar")||""}get quote(){return this._resolve("quote")||""}get compact(){return this.hasAttribute("compact")}#t(){let e=this.personaName,t=this.personaRole,r=this.age,s=this.location,a=this.avatar,l=this.quote,m=h(e),f=a?`background:url(${i(a)}) center/cover`:`background:${m}`;this.shadowRoot.innerHTML=`
250
- <style>${d}</style>
249
+ `;var T=window.matchMedia("(prefers-reduced-motion: reduce)");var f=new Map;function g(r,e,a={}){let o=a.priority??10,s={impl:e,bundle:a.bundle,contract:a.contract,priority:o},t=f.get(r);if(customElements.get(r)){if(!t||t.priority>=o){t&&t.priority===o&&t.impl!==e&&console.warn(`[VB Bundle] Tag <${r}> already registered by "${t.bundle}" (priority ${t.priority}). Skipping "${a.bundle}".`);return}console.warn(`[VB Bundle] Tag <${r}> defined by "${t.bundle}" cannot be replaced (customElements.define is permanent). "${a.bundle}" has higher priority but arrived late.`);return}if(t&&t.priority>=o){t.priority===o&&console.warn(`[VB Bundle] Tag <${r}> already registered by "${t.bundle}". Skipping "${a.bundle}" (first wins at equal priority).`);return}f.set(r,s),customElements.define(r,e)}function n(r){return String(r).replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/"/g,"&quot;")}function b(r){return r.split(" ").map(e=>e[0]).join("").toUpperCase().slice(0,2)}function x(r){let e=0;for(let o=0;o<r.length;o++)e=r.charCodeAt(o)+((e<<5)-e);return`hsl(${(e%360+360)%360}, 65%, 55%)`}var d={user:'<path d="M19 21v-2a4 4 0 0 0-4-4H9a4 4 0 0 0-4 4v2"/><circle cx="12" cy="7" r="4"/>',pencil:'<path d="M21.174 6.812a1 1 0 0 0-3.986-3.987L3.842 16.174a2 2 0 0 0-.5.83l-1.321 4.352a.5.5 0 0 0 .623.622l4.353-1.32a2 2 0 0 0 .83-.497z"/><path d="m15 5 4 4"/>',check:'<path d="M20 6 9 17l-5-5"/>',target:'<circle cx="12" cy="12" r="10"/><circle cx="12" cy="12" r="6"/><circle cx="12" cy="12" r="2"/>',alertTriangle:'<path d="m21.73 18-8-14a2 2 0 0 0-3.48 0l-8 14A2 2 0 0 0 4 21h16a2 2 0 0 0 1.73-3"/><path d="M12 9v4"/><path d="M12 17h.01"/>',messageCircle:'<path d="M2.992 16.342a2 2 0 0 1 .094 1.167l-1.065 3.29a1 1 0 0 0 1.236 1.168l3.413-.998a2 2 0 0 1 1.099.092 10 10 0 1 0-4.777-4.719"/>',lightbulb:'<path d="M15 14c.2-1 .7-1.7 1.5-2.5 1-.9 1.5-2.2 1.5-3.5A6 6 0 0 0 6 8c0 1 .2 2.2 1.5 3.5.7.7 1.3 1.5 1.5 2.5"/><path d="M9 18h6"/><path d="M10 22h4"/>',wrench:'<path d="M14.7 6.3a1 1 0 0 0 0 1.4l1.6 1.6a1 1 0 0 0 1.4 0l3.106-3.105c.32-.322.863-.22.983.218a6 6 0 0 1-8.259 7.057l-7.91 7.91a1 1 0 0 1-2.999-3l7.91-7.91a6 6 0 0 1 7.057-8.259c.438.12.54.662.219.984z"/>',heart:'<path d="M2 9.5a5.5 5.5 0 0 1 9.591-3.676.56.56 0 0 0 .818 0A5.49 5.49 0 0 1 22 9.5c0 2.29-1.5 4-3 5.5l-5.492 5.313a2 2 0 0 1-3 .019L5 15c-1.5-1.5-3-3.2-3-5.5"/>',mapPin:'<path d="M20 10c0 4.993-5.539 10.193-7.399 11.799a1 1 0 0 1-1.202 0C9.539 20.193 4 14.993 4 10a8 8 0 0 1 16 0"/><circle cx="12" cy="10" r="3"/>',checkCircle:'<path d="M22 11.08V12a10 10 0 1 1-5.93-9.14"/><path d="m9 11 3 3L22 4"/>',x:'<path d="M18 6 6 18"/><path d="m6 6 12 12"/>',download:'<path d="M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4"/><polyline points="7 10 12 15 17 10"/><line x1="12" x2="12" y1="15" y2="3"/>',send:'<path d="M14.536 21.686a.5.5 0 0 0 .937-.024l6.5-19a.496.496 0 0 0-.635-.635l-19 6.5a.5.5 0 0 0-.024.937l7.93 3.18a2 2 0 0 1 1.112 1.11z"/><path d="m21.854 2.147-10.94 10.939"/>'},N={says:{label:"Says",icon:d.messageCircle,color:"#3b82f6"},thinks:{label:"Thinks",icon:d.lightbulb,color:"#8b5cf6"},does:{label:"Does",icon:d.wrench,color:"#f59e0b"},feels:{label:"Feels",icon:d.heart,color:"#ef4444"}};var _="https://cdn.jsdelivr.net/gh/faker-js/assets-person-portrait",p=[32,64,128,256,512];function w(r){let e=0;for(let a=0;a<r.length;a++)e=r.charCodeAt(a)+((e<<5)-e);return e}function k(r){let e=p[0],a=Math.abs(r-e);for(let o=1;o<p.length;o++){let s=Math.abs(r-p[o]);s<a&&(e=p[o],a=s)}return e}function y(r,e=128){let a=w(String(r)),o=(a%100+100)%100,s=(a>>>16&1)===0?"female":"male",t=k(e);return`${_}/${s}/${t}/${o}.jpg`}function h(r){let e=0;for(let a=0;a<r.length;a++)e=r.charCodeAt(a)+((e<<5)-e);return e}var S=["Sarah Chen","Marcus Johnson","Aisha Patel","James O'Brien","Yuki Tanaka","Elena Rodriguez","David Kim","Fatima Al-Hassan","Lucas Silva","Priya Sharma","Noah Williams","Mei Lin","Carlos Mendez","Amara Osei","Henrik Larsson","Zara Ahmed"],C=["Product Manager","UX Designer","Frontend Developer","Data Analyst","Marketing Lead","QA Engineer","DevOps Lead","Content Strategist","Startup Founder","IT Director","Customer Success Lead","Research Scientist"],A=["San Francisco, CA","Austin, TX","London, UK","Toronto, CA","Berlin, DE","Tokyo, JP","Sydney, AU","S\xE3o Paulo, BR"],M=["I need tools that help me stay organized without slowing me down.","The dashboard is where I live \u2014 it has to be fast and reliable.","I want to understand the data, not fight the interface.","If it takes more than two clicks, I\u2019ll find another way.","Collaboration shouldn\u2019t mean endless notification noise.","I just want it to work the way I expect it to.","Give me the big picture first, then let me drill into details.","Accessibility isn\u2019t a nice-to-have \u2014 it\u2019s how I use the web."],z=["Streamline daily workflows","Reduce context-switching","Stay aligned with the team","Make data-driven decisions quickly","Ship features on a predictable cadence","Automate repetitive tasks","Improve onboarding experience","Keep documentation up to date"],$=["Too many disconnected tools","Slow page loads break focus","Unclear ownership of tasks","Settings that reset unexpectedly","Notifications that bury important updates","Poor mobile experience","Inconsistent design across features","No offline support"],q=["Checks dashboards every morning","Prefers keyboard shortcuts over mouse","Skims docs, reads deeply only when stuck","Shares screenshots in Slack","Batches email to twice a day","Tests features in incognito first","Bookmarks frequently used reports","Uses dark mode exclusively"],u=class extends HTMLElement{static get observedAttributes(){return["role","age","location","avatar","compact","src"]}#e=new Map;constructor(){super(),this.attachShadow({mode:"open"})}#a(){for(let e of[...this.children]){let a=e.getAttribute("slot");a&&!this.getAttribute(a)&&this.#e.set(a,e.textContent.trim())}}_resolve(e){return this.getAttribute(e)||this.#e.get(e)||""}async _loadSrc(e){if(e)try{let a=await fetch(e);if(!a.ok)throw new Error(`HTTP ${a.status}`);let o=await a.json();for(let s of["role","age","location","avatar"])o[s]&&this.setAttribute(s,o[s]);if(o.name&&!this.querySelector('[slot="name"]')){let s=document.createElement("h2");s.slot="name",s.textContent=o.name,this.appendChild(s)}if(o.quote&&!this.querySelector('[slot="quote"]')){let s=document.createElement("p");s.slot="quote",s.textContent=o.quote,this.appendChild(s)}for(let s of["bio","goals","frustrations","behaviors"])o[s]&&(Array.isArray(o[s])?this.#e.set(s,o[s]):this.#e.set(s,o[s]));this.#t()}catch(a){console.warn(`[user-persona] Failed to load src="${e}":`,a)}}connectedCallback(){this.#a(),this.hasAttribute("data-mock")?this.#o():this.hasAttribute("src")&&this._loadSrc(this.getAttribute("src")),this.#t(),this.setAttribute("data-upgraded",""),this.dispatchEvent(new CustomEvent("persona-ready",{bubbles:!0,composed:!0,detail:{name:this.personaName,role:this.personaRole}}))}disconnectedCallback(){this.removeAttribute("data-upgraded")}attributeChangedCallback(e,a,o){a!==o&&this.shadowRoot&&(e==="src"&&this.isConnected?this._loadSrc(o):this.#t())}get personaName(){return this.querySelector('[slot="name"]')?.textContent?.trim()||this.#e.get("name")||"Unnamed Persona"}get personaRole(){return this.getAttribute("role")||""}get age(){return this.getAttribute("age")||""}get location(){return this.getAttribute("location")||""}get avatar(){return this.getAttribute("avatar")||""}get quote(){return this.querySelector('[slot="quote"]')?.textContent?.trim()||this.#e.get("quote")||""}get compact(){return this.hasAttribute("compact")}#o(){let e=this.dataset.seed||this.dataset.mock||String(Date.now()),a=t=>t[(h(e+t.length)%t.length+t.length)%t.length],o=(t,l)=>{let i=[];for(let c=0;c<l;c++)i.push(t[(h(e+c+t.length)%t.length+t.length)%t.length]);return[...new Set(i)]};if(!this.querySelector('[slot="name"]')){let t=document.createElement("h2");t.slot="name",t.textContent=a(S),this.appendChild(t)}if(this.getAttribute("role")||this.setAttribute("role",a(C)),this.getAttribute("age")||this.setAttribute("age",String(25+(h(e)%30+30)%30)),this.getAttribute("location")||this.setAttribute("location",a(A)),!this.getAttribute("avatar")){let t=this.querySelector('[slot="name"]')?.textContent?.trim()||"Persona";this.setAttribute("avatar",y(t,256))}if(!this.querySelector('[slot="quote"]')){let t=document.createElement("p");t.slot="quote",t.textContent=a(M),this.appendChild(t)}let s=(t,l)=>{if(this.querySelector(`[slot="${t}"]`))return;let i=document.createElement("ul");i.setAttribute("slot",t);for(let c of l){let m=document.createElement("li");m.textContent=c,i.appendChild(m)}this.appendChild(i)};s("goals",o(z,3)),s("frustrations",o($,3)),s("behaviors",o(q,3))}#t(){let e=this.personaName,a=this.personaRole,o=this.age,s=this.location,t=this.avatar,l=this.quote,i=x(e),c=t?`background:url(${n(t)}) center/cover`:`background:${i}`;this.shadowRoot.innerHTML=`
250
+ <style>${v}</style>
251
251
 
252
252
  <article class="persona-card" part="card" role="article"
253
- aria-label="User persona: ${i(e)}">
253
+ aria-label="User persona: ${n(e)}">
254
254
 
255
255
  <header class="persona-header" part="header">
256
- <div class="avatar" part="avatar" style="${f}"
257
- role="img" aria-label="Avatar for ${i(e)}">
258
- ${a?"":i(u(e))}
256
+ <div class="avatar" part="avatar" style="${c}"
257
+ role="img" aria-label="Avatar for ${n(e)}">
258
+ ${t?"":n(b(e))}
259
259
  </div>
260
260
  <div class="header-info">
261
- <h2 class="persona-name" part="name">${i(e)}</h2>
262
- ${t?`<p class="persona-role" part="role">${i(t)}</p>`:""}
261
+ <div class="persona-name-wrap" part="name">
262
+ <slot name="name"><h2 class="persona-name-fallback">${n(e)}</h2></slot>
263
+ </div>
264
+ ${a?`<p class="persona-role" part="role">${n(a)}</p>`:""}
263
265
  <div class="persona-meta" part="meta">
264
- ${r?`
266
+ ${o?`
265
267
  <span class="meta-item">
266
268
  <svg viewBox="0 0 24 24" aria-hidden="true"><path d="M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm0 3c1.66 0 3 1.34 3 3s-1.34 3-3 3-3-1.34-3-3 1.34-3 3-3zm0 14.2c-2.5 0-4.71-1.28-6-3.22.03-1.99 4-3.08 6-3.08 1.99 0 5.97 1.09 6 3.08-1.29 1.94-3.5 3.22-6 3.22z"/></svg>
267
- ${i(r)} years old
269
+ ${n(o)} years old
268
270
  </span>
269
271
  `:""}
270
272
  ${s?`
271
273
  <span class="meta-item">
272
274
  <svg viewBox="0 0 24 24" aria-hidden="true"><path d="M12 2C8.13 2 5 5.13 5 9c0 5.25 7 13 7 13s7-7.75 7-13c0-3.87-3.13-7-7-7zm0 9.5c-1.38 0-2.5-1.12-2.5-2.5s1.12-2.5 2.5-2.5 2.5 1.12 2.5 2.5-1.12 2.5-2.5 2.5z"/></svg>
273
- ${i(s)}
275
+ ${n(s)}
274
276
  </span>
275
277
  `:""}
276
278
  </div>
277
279
  </div>
278
280
  </header>
279
281
 
280
- ${l?`
282
+ ${l||this.querySelector('[slot="quote"]')?`
281
283
  <div class="persona-quote" part="quote">
282
284
  <span class="quote-mark" aria-hidden="true">&ldquo;</span>
283
- <p class="quote-text">${i(l)}</p>
285
+ <div class="quote-text-wrap"><slot name="quote"><p class="quote-text">${n(l)}</p></slot></div>
284
286
  </div>
285
287
  `:""}
286
288
 
@@ -334,5 +336,5 @@ var d=`
334
336
  </div>
335
337
  </div>
336
338
  </article>
337
- `}};v("user-persona",c);export{c as UserPersona};
339
+ `}};g("user-persona",u);export{u as UserPersona};
338
340
  //# sourceMappingURL=user-persona.js.map
@@ -134,6 +134,24 @@ var h=`
134
134
  font-weight: 500;
135
135
  }
136
136
 
137
+ .persona-text--link {
138
+ display: inline-flex;
139
+ align-items: center;
140
+ gap: 3px;
141
+ color: var(--_accent);
142
+ text-decoration: none;
143
+ }
144
+
145
+ .persona-text--link svg {
146
+ width: 13px;
147
+ height: 13px;
148
+ flex-shrink: 0;
149
+ }
150
+
151
+ .persona-text--link:hover {
152
+ text-decoration: underline;
153
+ }
154
+
137
155
  .action-text {
138
156
  font-weight: 500;
139
157
  }
@@ -237,6 +255,24 @@ var h=`
237
255
  }
238
256
  }
239
257
 
258
+ /* \u2500\u2500 Slotted title (minimal mode heading) \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */
259
+ .story-title-wrap {
260
+ margin: 0;
261
+ }
262
+
263
+ ::slotted([slot="title"]) {
264
+ font-size: var(--_font-sm) !important;
265
+ font-weight: 600 !important;
266
+ color: var(--_text) !important;
267
+ margin: 0 !important;
268
+ }
269
+
270
+ .story-title-fallback {
271
+ font-size: var(--_font-sm);
272
+ font-weight: 600;
273
+ color: var(--_text);
274
+ }
275
+
240
276
  /* Minimal detail level */
241
277
  :host([detail="minimal"]) .story-card {
242
278
  padding: var(--_space-xs);
@@ -267,11 +303,6 @@ var h=`
267
303
  outline-offset: 2px;
268
304
  }
269
305
 
270
- :host([detail="minimal"]) .story-statement {
271
- font-size: var(--_font-sm);
272
- margin: 0;
273
- }
274
-
275
306
  :host([detail="minimal"]) .story-id {
276
307
  display: block;
277
308
  margin-bottom: var(--_space-2xs);
@@ -289,43 +320,45 @@ var h=`
289
320
  :host([detail="compact"]) .slot-fallback {
290
321
  display: none;
291
322
  }
292
- `;var v=window.matchMedia("(prefers-reduced-motion: reduce)");var m=new Map;function f(r,t,e={}){let s=e.priority??10,a={impl:t,bundle:e.bundle,contract:e.contract,priority:s},o=m.get(r);if(customElements.get(r)){if(!o||o.priority>=s){o&&o.priority===s&&o.impl!==t&&console.warn(`[VB Bundle] Tag <${r}> already registered by "${o.bundle}" (priority ${o.priority}). Skipping "${e.bundle}".`);return}console.warn(`[VB Bundle] Tag <${r}> defined by "${o.bundle}" cannot be replaced (customElements.define is permanent). "${e.bundle}" has higher priority but arrived late.`);return}if(o&&o.priority>=s){o.priority===s&&console.warn(`[VB Bundle] Tag <${r}> already registered by "${o.bundle}". Skipping "${e.bundle}" (first wins at equal priority).`);return}m.set(r,a),customElements.define(r,t)}function n(r){return String(r).replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/"/g,"&quot;")}var p={user:'<path d="M19 21v-2a4 4 0 0 0-4-4H9a4 4 0 0 0-4 4v2"/><circle cx="12" cy="7" r="4"/>',pencil:'<path d="M21.174 6.812a1 1 0 0 0-3.986-3.987L3.842 16.174a2 2 0 0 0-.5.83l-1.321 4.352a.5.5 0 0 0 .623.622l4.353-1.32a2 2 0 0 0 .83-.497z"/><path d="m15 5 4 4"/>',check:'<path d="M20 6 9 17l-5-5"/>',target:'<circle cx="12" cy="12" r="10"/><circle cx="12" cy="12" r="6"/><circle cx="12" cy="12" r="2"/>',alertTriangle:'<path d="m21.73 18-8-14a2 2 0 0 0-3.48 0l-8 14A2 2 0 0 0 4 21h16a2 2 0 0 0 1.73-3"/><path d="M12 9v4"/><path d="M12 17h.01"/>',messageCircle:'<path d="M2.992 16.342a2 2 0 0 1 .094 1.167l-1.065 3.29a1 1 0 0 0 1.236 1.168l3.413-.998a2 2 0 0 1 1.099.092 10 10 0 1 0-4.777-4.719"/>',lightbulb:'<path d="M15 14c.2-1 .7-1.7 1.5-2.5 1-.9 1.5-2.2 1.5-3.5A6 6 0 0 0 6 8c0 1 .2 2.2 1.5 3.5.7.7 1.3 1.5 1.5 2.5"/><path d="M9 18h6"/><path d="M10 22h4"/>',wrench:'<path d="M14.7 6.3a1 1 0 0 0 0 1.4l1.6 1.6a1 1 0 0 0 1.4 0l3.106-3.105c.32-.322.863-.22.983.218a6 6 0 0 1-8.259 7.057l-7.91 7.91a1 1 0 0 1-2.999-3l7.91-7.91a6 6 0 0 1 7.057-8.259c.438.12.54.662.219.984z"/>',heart:'<path d="M2 9.5a5.5 5.5 0 0 1 9.591-3.676.56.56 0 0 0 .818 0A5.49 5.49 0 0 1 22 9.5c0 2.29-1.5 4-3 5.5l-5.492 5.313a2 2 0 0 1-3 .019L5 15c-1.5-1.5-3-3.2-3-5.5"/>'},x={says:{label:"Says",icon:p.messageCircle,color:"#3b82f6"},thinks:{label:"Thinks",icon:p.lightbulb,color:"#8b5cf6"},does:{label:"Does",icon:p.wrench,color:"#f59e0b"},feels:{label:"Feels",icon:p.heart,color:"#ef4444"}};var u=class r extends HTMLElement{static get observedAttributes(){return["persona","action","benefit","priority","points","status","epic","story-id","title","compact","detail","src"]}static PRIORITIES={critical:{label:"Critical",color:"#dc2626",bg:"rgba(220, 38, 38, 0.1)"},high:{label:"High",color:"#ea580c",bg:"rgba(234, 88, 12, 0.1)"},medium:{label:"Medium",color:"#ca8a04",bg:"rgba(202, 138, 4, 0.1)"},low:{label:"Low",color:"#16a34a",bg:"rgba(22, 163, 74, 0.1)"}};static STATUSES={backlog:{label:"Backlog",color:"#6b7280",bg:"rgba(107, 114, 128, 0.1)"},"to-do":{label:"To Do",color:"#3b82f6",bg:"rgba(59, 130, 246, 0.1)"},"in-progress":{label:"In Progress",color:"#8b5cf6",bg:"rgba(139, 92, 246, 0.1)"},review:{label:"Review",color:"#f59e0b",bg:"rgba(245, 158, 11, 0.1)"},done:{label:"Done",color:"#22c55e",bg:"rgba(34, 197, 94, 0.1)"}};#t=new Map;constructor(){super(),this.attachShadow({mode:"open"})}#s(){for(let t of[...this.children]){let e=t.getAttribute("slot");e&&!this.getAttribute(e)&&this.#t.set(e,t.textContent.trim())}}_resolve(t){return this.getAttribute(t)||this.#t.get(t)||""}async _loadSrc(t){if(t)try{let e=await fetch(t);if(!e.ok)throw new Error(`HTTP ${e.status}`);let s=await e.json();for(let[a,o]of[["storyId","story-id"],["persona","persona"],["action","action"],["benefit","benefit"],["priority","priority"],["status","status"],["points","points"],["epic","epic"],["title","title"],["detail","detail"]])s[a]!=null&&this.setAttribute(o,String(s[a]));for(let a of["acceptanceCriteria","tasks","notes"])s[a]&&this.#t.set(a==="acceptanceCriteria"?"acceptance-criteria":a,s[a]);this.#e()}catch(e){console.warn(`[user-story] Failed to load src="${t}":`,e)}}connectedCallback(){this.#s(),this.storyId&&!this.id&&(this.id=this.storyId),this.hasAttribute("src")&&this._loadSrc(this.getAttribute("src")),this.#e(),this.setAttribute("data-upgraded","")}disconnectedCallback(){this.removeAttribute("data-upgraded")}attributeChangedCallback(t,e,s){e!==s&&this.shadowRoot&&(t==="src"&&this.isConnected?this._loadSrc(s):this.#e())}get persona(){return this._resolve("persona")||"user"}get action(){return this._resolve("action")||""}get benefit(){return this._resolve("benefit")||""}get priority(){return this.getAttribute("priority")||"medium"}get points(){return this.getAttribute("points")||""}get status(){return this.getAttribute("status")||"backlog"}get epic(){return this._resolve("epic")||""}get storyId(){return this._resolve("story-id")||""}get storyTitle(){return this._resolve("title")||""}get _minimalLabel(){if(this.storyTitle)return this.storyTitle;let t=this.action;return t.length>40?t.slice(0,40)+"\u2026":t}get compact(){return this.hasAttribute("compact")}get _detailLevel(){return this.getAttribute("detail")?this.getAttribute("detail"):this.hasAttribute("compact")?"compact":"full"}updateStatus(t){r.STATUSES[t]&&(this.setAttribute("status",t),this.dispatchEvent(new CustomEvent("status-changed",{detail:{status:t,storyId:this.storyId},bubbles:!0,composed:!0})))}updatePriority(t){r.PRIORITIES[t]&&(this.setAttribute("priority",t),this.dispatchEvent(new CustomEvent("priority-changed",{detail:{priority:t,storyId:this.storyId},bubbles:!0,composed:!0})))}showDetail(){let t=`story-dialog-${this.storyId||this.id||"detail"}`,e=document.getElementById(t);e||(e=document.createElement("dialog"),e.id=t,e.setAttribute("data-size","l"),document.body.appendChild(e));let s=document.createElement("form");s.method="dialog";let a=document.createElement("header"),o=document.createElement("h3");o.textContent=this.storyTitle||this.storyId||"Story Detail";let c=document.createElement("button");c.type="submit",c.setAttribute("aria-label","Close"),c.textContent="\xD7",a.appendChild(o),a.appendChild(c);let l=document.createElement("section"),d=document.createElement("user-story");for(let i of this.getAttributeNames())i==="detail"||i==="compact"||i==="data-upgraded"||i==="draggable"||i==="data-id"||i==="data-quadrant"||d.setAttribute(i,this.getAttribute(i));let b=[...this.children].some(i=>i.getAttribute("slot")&&i.tagName!=="DIALOG");d.setAttribute("detail",b?"full":"compact"),d.removeAttribute("id");for(let i of[...this.children])i.tagName!=="DIALOG"&&d.appendChild(i.cloneNode(!0));l.appendChild(d),s.appendChild(a),s.appendChild(l),e.innerHTML="",e.appendChild(s),e.addEventListener("close",()=>{e.innerHTML=""},{once:!0}),e.showModal()}#e(){let t=r.PRIORITIES[this.priority]||r.PRIORITIES.medium,e=r.STATUSES[this.status]||r.STATUSES.backlog,s=this._detailLevel,a=this.storyId?`User story: ${n(this.storyId)}`:"User story";if(s==="minimal"){this.shadowRoot.innerHTML=`
323
+ `;var v=window.matchMedia("(prefers-reduced-motion: reduce)");var m=new Map;function f(i,t,s={}){let o=s.priority??10,e={impl:t,bundle:s.bundle,contract:s.contract,priority:o},r=m.get(i);if(customElements.get(i)){if(!r||r.priority>=o){r&&r.priority===o&&r.impl!==t&&console.warn(`[VB Bundle] Tag <${i}> already registered by "${r.bundle}" (priority ${r.priority}). Skipping "${s.bundle}".`);return}console.warn(`[VB Bundle] Tag <${i}> defined by "${r.bundle}" cannot be replaced (customElements.define is permanent). "${s.bundle}" has higher priority but arrived late.`);return}if(r&&r.priority>=o){r.priority===o&&console.warn(`[VB Bundle] Tag <${i}> already registered by "${r.bundle}". Skipping "${s.bundle}" (first wins at equal priority).`);return}m.set(i,e),customElements.define(i,t)}function c(i){return String(i).replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/"/g,"&quot;")}function b(i){return`<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true">${i}</svg>`}var p={user:'<path d="M19 21v-2a4 4 0 0 0-4-4H9a4 4 0 0 0-4 4v2"/><circle cx="12" cy="7" r="4"/>',pencil:'<path d="M21.174 6.812a1 1 0 0 0-3.986-3.987L3.842 16.174a2 2 0 0 0-.5.83l-1.321 4.352a.5.5 0 0 0 .623.622l4.353-1.32a2 2 0 0 0 .83-.497z"/><path d="m15 5 4 4"/>',check:'<path d="M20 6 9 17l-5-5"/>',target:'<circle cx="12" cy="12" r="10"/><circle cx="12" cy="12" r="6"/><circle cx="12" cy="12" r="2"/>',alertTriangle:'<path d="m21.73 18-8-14a2 2 0 0 0-3.48 0l-8 14A2 2 0 0 0 4 21h16a2 2 0 0 0 1.73-3"/><path d="M12 9v4"/><path d="M12 17h.01"/>',messageCircle:'<path d="M2.992 16.342a2 2 0 0 1 .094 1.167l-1.065 3.29a1 1 0 0 0 1.236 1.168l3.413-.998a2 2 0 0 1 1.099.092 10 10 0 1 0-4.777-4.719"/>',lightbulb:'<path d="M15 14c.2-1 .7-1.7 1.5-2.5 1-.9 1.5-2.2 1.5-3.5A6 6 0 0 0 6 8c0 1 .2 2.2 1.5 3.5.7.7 1.3 1.5 1.5 2.5"/><path d="M9 18h6"/><path d="M10 22h4"/>',wrench:'<path d="M14.7 6.3a1 1 0 0 0 0 1.4l1.6 1.6a1 1 0 0 0 1.4 0l3.106-3.105c.32-.322.863-.22.983.218a6 6 0 0 1-8.259 7.057l-7.91 7.91a1 1 0 0 1-2.999-3l7.91-7.91a6 6 0 0 1 7.057-8.259c.438.12.54.662.219.984z"/>',heart:'<path d="M2 9.5a5.5 5.5 0 0 1 9.591-3.676.56.56 0 0 0 .818 0A5.49 5.49 0 0 1 22 9.5c0 2.29-1.5 4-3 5.5l-5.492 5.313a2 2 0 0 1-3 .019L5 15c-1.5-1.5-3-3.2-3-5.5"/>',mapPin:'<path d="M20 10c0 4.993-5.539 10.193-7.399 11.799a1 1 0 0 1-1.202 0C9.539 20.193 4 14.993 4 10a8 8 0 0 1 16 0"/><circle cx="12" cy="10" r="3"/>',checkCircle:'<path d="M22 11.08V12a10 10 0 1 1-5.93-9.14"/><path d="m9 11 3 3L22 4"/>',x:'<path d="M18 6 6 18"/><path d="m6 6 12 12"/>',download:'<path d="M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4"/><polyline points="7 10 12 15 17 10"/><line x1="12" x2="12" y1="15" y2="3"/>',send:'<path d="M14.536 21.686a.5.5 0 0 0 .937-.024l6.5-19a.496.496 0 0 0-.635-.635l-19 6.5a.5.5 0 0 0-.024.937l7.93 3.18a2 2 0 0 1 1.112 1.11z"/><path d="m21.854 2.147-10.94 10.939"/>'},_={says:{label:"Says",icon:p.messageCircle,color:"#3b82f6"},thinks:{label:"Thinks",icon:p.lightbulb,color:"#8b5cf6"},does:{label:"Does",icon:p.wrench,color:"#f59e0b"},feels:{label:"Feels",icon:p.heart,color:"#ef4444"}};var u=class i extends HTMLElement{static get observedAttributes(){return["persona-id","priority","points","status","epic","story-id","compact","detail","src"]}static PRIORITIES={critical:{label:"Critical",color:"#dc2626",bg:"rgba(220, 38, 38, 0.1)"},high:{label:"High",color:"#ea580c",bg:"rgba(234, 88, 12, 0.1)"},medium:{label:"Medium",color:"#ca8a04",bg:"rgba(202, 138, 4, 0.1)"},low:{label:"Low",color:"#16a34a",bg:"rgba(22, 163, 74, 0.1)"}};static STATUSES={backlog:{label:"Backlog",color:"#6b7280",bg:"rgba(107, 114, 128, 0.1)"},"to-do":{label:"To Do",color:"#3b82f6",bg:"rgba(59, 130, 246, 0.1)"},"in-progress":{label:"In Progress",color:"#8b5cf6",bg:"rgba(139, 92, 246, 0.1)"},review:{label:"Review",color:"#f59e0b",bg:"rgba(245, 158, 11, 0.1)"},done:{label:"Done",color:"#22c55e",bg:"rgba(34, 197, 94, 0.1)"}};#t=new Map;constructor(){super(),this.attachShadow({mode:"open"})}#s(){for(let t of[...this.children]){let s=t.getAttribute("slot");s&&this.#t.set(s,t.textContent.trim())}}_resolve(t){return this.getAttribute(t)||this.#t.get(t)||""}async _loadSrc(t){if(t)try{let s=await fetch(t);if(!s.ok)throw new Error(`HTTP ${s.status}`);let o=await s.json();for(let[e,r]of[["storyId","story-id"],["personaId","persona-id"],["priority","priority"],["status","status"],["points","points"],["epic","epic"],["detail","detail"]])o[e]!=null&&this.setAttribute(r,String(o[e]));if(o.persona&&!this.querySelector('[slot="persona"]')){let e=document.createElement("span");e.slot="persona",e.textContent=o.persona,this.appendChild(e)}if(o.action&&!this.querySelector('[slot="action"]')){let e=document.createElement("span");e.slot="action",e.textContent=o.action,this.appendChild(e)}if(o.benefit&&!this.querySelector('[slot="benefit"]')){let e=document.createElement("span");e.slot="benefit",e.textContent=o.benefit,this.appendChild(e)}if(o.title&&!this.querySelector('[slot="title"]')){let e=document.createElement("h3");e.slot="title",e.textContent=o.title,this.appendChild(e)}for(let e of["acceptance-criteria","tasks","notes"]){let r=e==="acceptance-criteria"?"acceptanceCriteria":e;if(o[r]&&!this.querySelector(`[slot="${e}"]`))if(Array.isArray(o[r])){let a=document.createElement("ul");a.slot=e;for(let d of o[r]){let l=document.createElement("li");l.textContent=d,a.appendChild(l)}this.appendChild(a)}else{let a=document.createElement("p");a.slot=e,a.textContent=o[r],this.appendChild(a)}}this.#s(),this.#e()}catch(s){console.warn(`[user-story] Failed to load src="${t}":`,s)}}connectedCallback(){this.#s(),this.storyId&&!this.id&&(this.id=this.storyId),this.hasAttribute("src")&&this._loadSrc(this.getAttribute("src")),this.#e(),this.setAttribute("data-upgraded","")}disconnectedCallback(){this.removeAttribute("data-upgraded")}attributeChangedCallback(t,s,o){s!==o&&this.shadowRoot&&(t==="src"&&this.isConnected?this._loadSrc(o):this.#e())}get persona(){return this.querySelector('[slot="persona"]')?.textContent?.trim()||this.#t.get("persona")||"user"}get personaId(){return this.getAttribute("persona-id")||""}get action(){return this.querySelector('[slot="action"]')?.textContent?.trim()||this.#t.get("action")||""}get benefit(){return this.querySelector('[slot="benefit"]')?.textContent?.trim()||this.#t.get("benefit")||""}get priority(){return this.getAttribute("priority")||"medium"}get points(){return this.getAttribute("points")||""}get status(){return this.getAttribute("status")||"backlog"}get epic(){return this.getAttribute("epic")||""}get storyId(){return this.getAttribute("story-id")||""}get storyTitle(){return this.querySelector('[slot="title"]')?.textContent?.trim()||this.#t.get("title")||""}get _minimalLabel(){if(this.storyTitle)return this.storyTitle;let t=this.action;return t.length>40?t.slice(0,40)+"\u2026":t}get compact(){return this.hasAttribute("compact")}get _detailLevel(){return this.getAttribute("detail")?this.getAttribute("detail"):this.hasAttribute("compact")?"compact":"full"}updateStatus(t){i.STATUSES[t]&&(this.setAttribute("status",t),this.dispatchEvent(new CustomEvent("status-changed",{detail:{status:t,storyId:this.storyId},bubbles:!0,composed:!0})))}updatePriority(t){i.PRIORITIES[t]&&(this.setAttribute("priority",t),this.dispatchEvent(new CustomEvent("priority-changed",{detail:{priority:t,storyId:this.storyId},bubbles:!0,composed:!0})))}showDetail(){let t=`story-dialog-${this.storyId||this.id||"detail"}`,s=document.getElementById(t);s||(s=document.createElement("dialog"),s.id=t,s.setAttribute("data-size","l"),document.body.appendChild(s));let o=document.createElement("form");o.method="dialog";let e=document.createElement("header"),r=document.createElement("h3");r.textContent=this.storyTitle||this.storyId||"Story Detail";let a=document.createElement("button");a.type="submit",a.setAttribute("aria-label","Close"),a.textContent="\xD7",e.appendChild(r),e.appendChild(a);let d=document.createElement("section"),l=document.createElement("user-story");for(let n of this.getAttributeNames())n==="detail"||n==="compact"||n==="data-upgraded"||n==="draggable"||n==="data-id"||n==="data-quadrant"||l.setAttribute(n,this.getAttribute(n));let y=[...this.children].some(n=>n.getAttribute("slot")&&n.tagName!=="DIALOG");l.setAttribute("detail",y?"full":"compact"),l.removeAttribute("id");for(let n of[...this.children])n.tagName!=="DIALOG"&&l.appendChild(n.cloneNode(!0));d.appendChild(l),o.appendChild(e),o.appendChild(d),s.innerHTML="",s.appendChild(o),s.addEventListener("close",()=>{s.innerHTML=""},{once:!0}),s.showModal()}#e(){let t=i.PRIORITIES[this.priority]||i.PRIORITIES.medium,s=i.STATUSES[this.status]||i.STATUSES.backlog,o=this._detailLevel,e=this.storyId?`User story: ${c(this.storyId)}`:"User story";if(o==="minimal"){this.shadowRoot.innerHTML=`
293
324
  <style>${h}</style>
294
- <article class="story-card story-card--minimal" role="article" aria-label="${a}"
295
- tabindex="0" title="Click to view full story">
325
+ <article class="story-card story-card--minimal" role="article" aria-label="${e}"
326
+ tabindex="0">
296
327
  <div class="story-body">
297
- ${this.storyId?`<span class="story-id">${n(this.storyId)}</span>`:""}
298
- <p class="story-statement story-statement--minimal">${n(this._minimalLabel||"[describe the action]")}</p>
328
+ ${this.storyId?`<span class="story-id">${c(this.storyId)}</span>`:""}
329
+ <div class="story-title-wrap">
330
+ <slot name="title"><span class="story-title-fallback">${c(this._minimalLabel||"[describe the action]")}</span></slot>
331
+ </div>
299
332
  </div>
300
333
  </article>
301
- `;let o=this.shadowRoot.querySelector(".story-card--minimal");o.addEventListener("click",()=>this.showDetail()),o.addEventListener("keydown",c=>{(c.key==="Enter"||c.key===" ")&&(c.preventDefault(),this.showDetail())})}else this.shadowRoot.innerHTML=`
334
+ `;let r=this.shadowRoot.querySelector(".story-card--minimal");r.addEventListener("click",()=>this.showDetail()),r.addEventListener("keydown",a=>{(a.key==="Enter"||a.key===" ")&&(a.preventDefault(),this.showDetail())})}else this.shadowRoot.innerHTML=`
302
335
  <style>${h}</style>
303
336
 
304
- <article class="story-card story-card--${s}" part="card" role="article" aria-label="${a}">
337
+ <article class="story-card story-card--${o}" part="card" role="article" aria-label="${e}">
305
338
  <header class="story-header" part="header">
306
339
  <div class="story-meta">
307
- ${this.storyId?`<span class="story-id" part="id">${n(this.storyId)}</span>`:""}
308
- ${this.epic?`<span class="epic-badge" part="epic">${n(this.epic)}</span>`:""}
340
+ ${this.storyId?`<span class="story-id" part="id">${c(this.storyId)}</span>`:""}
341
+ ${this.epic?`<span class="epic-badge" part="epic">${c(this.epic)}</span>`:""}
309
342
  </div>
310
343
  <div class="story-badges">
311
344
  <span class="priority-badge" part="priority"
312
345
  style="color: ${t.color}; background: ${t.bg};"
313
- >${n(t.label)}</span>
346
+ >${c(t.label)}</span>
314
347
  <span class="status-badge" part="status"
315
- style="color: ${e.color}; background: ${e.bg};"
316
- >${n(e.label)}</span>
317
- ${this.points?`<span class="points-badge" part="points" title="Story points">${n(this.points)}</span>`:""}
348
+ style="color: ${s.color}; background: ${s.bg};"
349
+ >${c(s.label)}</span>
350
+ ${this.points?`<span class="points-badge" part="points">${c(this.points)}</span>`:""}
318
351
  </div>
319
352
  </header>
320
353
 
321
354
  <div class="story-body" part="body">
322
355
  <p class="story-statement" part="statement">
323
356
  <span class="keyword">As a</span>
324
- <span class="persona-text">${n(this.persona)}</span>,
357
+ ${this.personaId?`<a class="persona-text persona-text--link" href="#${c(this.personaId)}">${b(p.user)} <slot name="persona"><span>user</span></slot></a>`:'<span class="persona-text"><slot name="persona"><span>user</span></slot></span>'},
325
358
  <span class="keyword">I want</span>
326
- <span class="action-text">${n(this.action||"[describe the action]")}</span>${this.benefit?`
359
+ <span class="action-text"><slot name="action"><span>[describe the action]</span></slot></span>${this.benefit||this.querySelector('[slot="benefit"]')?`
327
360
  <span class="keyword">so that</span>
328
- <span class="benefit-text">${n(this.benefit)}</span>`:""}
361
+ <span class="benefit-text"><slot name="benefit"></slot></span>`:""}
329
362
  </p>
330
363
  </div>
331
364
 
@@ -373,5 +406,5 @@ var h=`
373
406
  </div>
374
407
  </div>
375
408
  </article>
376
- `,s==="compact"&&this.shadowRoot.querySelectorAll(".section").forEach(c=>{let l=c.querySelector("slot");l&&l.assignedNodes().length===0&&c.setAttribute("data-empty","")});this.dispatchEvent(new CustomEvent("story-ready",{detail:{id:this.storyId,persona:this.persona,action:this.action,benefit:this.benefit,priority:this.priority,status:this.status,points:this.points},bubbles:!0,composed:!0}))}};f("user-story",u);export{u as UserStory};
409
+ `,o==="compact"&&this.shadowRoot.querySelectorAll(".section").forEach(a=>{let d=a.querySelector("slot");d&&d.assignedNodes().length===0&&a.setAttribute("data-empty","")});this.dispatchEvent(new CustomEvent("story-ready",{detail:{id:this.storyId,persona:this.persona,action:this.action,benefit:this.benefit,priority:this.priority,status:this.status,points:this.points},bubbles:!0,composed:!0}))}};f("user-story",u);export{u as UserStory};
377
410
  //# sourceMappingURL=user-story.js.map
@@ -0,0 +1,3 @@
1
+ var mt=Object.defineProperty;var O=(n,t)=>()=>(n&&(t=n(n=0)),t);var gt=(n,t)=>{for(var e in t)mt(n,e,{get:t[e],enumerable:!0})};function yt(){let n=globalThis.localStorage;if(!n)throw new Error("VBStore: localStorage is not available in this environment");return{async getRaw(t){return n.getItem(t)},async setRaw(t,e){n.setItem(t,e)},async removeRaw(t){n.removeItem(t)},async keys(t){let e=[];for(let i=0;i<n.length;i++){let o=n.key(i);o&&o.startsWith(t)&&e.push(o)}return e}}}function m(){return L||(L=yt()),L}function M(n,t){if(typeof n!="string"||!n)throw new TypeError("VBStore: namespace must be a non-empty string");if(typeof t!="string"||!t)throw new TypeError("VBStore: key must be a non-empty string");return`vb:${n}:${t}`}function Q(n){if(typeof n!="string"||!n)throw new TypeError("VBStore: namespace must be a non-empty string");return`vb:${n}:`}function Z(n){try{let t=JSON.parse(n);if(t&&typeof t=="object"&&typeof t.timestamp=="number")return t}catch{}return null}var L,y,H=O(()=>{L=null;y={configure(n={}){L=n.backend??null},async set(n,t,e){let i={data:e,timestamp:Date.now()};await m().setRaw(M(n,t),JSON.stringify(i))},async get(n,t,e){let i=await m().getRaw(M(n,t));if(i==null)return null;let o=Z(i);return!o||e?.maxAge!=null&&Date.now()-o.timestamp>e.maxAge?null:o.data},async remove(n,t){await m().removeRaw(M(n,t))},async list(n){let t=Q(n),e=await m().keys(t),i=[];for(let o of e){let s=await m().getRaw(o);if(s==null)continue;let r=Z(s);r&&i.push({key:o.slice(t.length),data:r.data,timestamp:r.timestamp})}return i},async clear(n){let t=Q(n),e=await m().keys(t);for(let i of e)await m().removeRaw(i)},async clearAll(){let n=await m().keys("vb:");for(let t of n)await m().removeRaw(t)},async setMany(n,t){for(let[e,i]of t)await y.set(n,e,i)}}});function bt(n,t){if(!t)return n;let e=n??new URLSearchParams;for(let[i,o]of Object.entries(t))o!=null&&e.set(i,String(o));return e}async function wt(n){if((n.headers.get("content-type")??"").includes("application/json"))try{return await n.json()}catch{return null}try{return await n.text()}catch{return null}}function tt(n){return n.endsWith("/")?n.slice(0,-1):n}var p,S,C,et=O(()=>{p={baseUrl:"/go",headers:{},services:{}},S=class extends Error{constructor(t,e,i,o){super(`VBService(${i}): ${t} ${o}`),this.name="VBServiceError",this.status=t,this.body=e,this.role=i,this.path=o}};C=class n{static configure(t={}){p={baseUrl:t.baseUrl??p.baseUrl,headers:{...p.headers,...t.headers??{}},services:{...p.services,...t.services??{}}}}static resolve(t){if(!t||typeof t!="string")throw new TypeError("VBService: role must be a non-empty string");return p.services[t]?tt(p.services[t]):p.baseUrl?`${tt(p.baseUrl)}/${t}`:`/go/${t}`}static _reset(){p={baseUrl:"/go",headers:{},services:{}}}constructor(t){if(!t||typeof t!="string")throw new TypeError("VBService: role must be a non-empty string");this.role=t}async get(t,e){return this.#t("GET",t,{params:e})}async post(t,e){return this.#t("POST",t,{body:e})}async patch(t,e){return this.#t("PATCH",t,{body:e})}async delete(t){return this.#t("DELETE",t,{})}async#t(t,e,i){let o=n.resolve(this.role),s=e?e.startsWith("/")?e:`/${e}`:"",r=new URL(`${o}${s}`,globalThis.location?.origin??"http://localhost"),d=bt(r.searchParams,i.params);d&&(r.search=d.toString());let a={method:t,headers:{...p.headers}};i.body!==void 0&&(a.body=JSON.stringify(i.body),a.headers["content-type"]="application/json");let c=r.toString(),l=await fetch(c,a),f=await wt(l);if(!l.ok)throw new S(l.status,f,this.role,`${s||"/"}`);return f}}});function $(n){let t=2166136261;for(let e=0;e<n.length;e++)t^=n.charCodeAt(e),t=Math.imul(t,16777619);return(t>>>0).toString(36)}function St(){return"hn-"+crypto.randomUUID().slice(0,8)}function rt(n,t){return getComputedStyle(n).getPropertyValue(`--highlight-${t}`).trim()}function Ct(n){if(E){k++;return}E=new CSSStyleSheet;let t=n.map(e=>`::highlight(hn-${e}) { background-color: var(--highlight-${e}); text-decoration-line: underline; text-decoration-color: var(--highlight-${e}); text-underline-offset: 2px; }`).join(`
2
+ `);E.replaceSync(t),document.adoptedStyleSheets=[...document.adoptedStyleSheets,E],k=1}function At(){k--,k<=0&&E&&(document.adoptedStyleSheets=document.adoptedStyleSheets.filter(n=>n!==E),E=null,k=0)}function kt(){return h||(h=document.createElement("div"),h.className="hn-toolbar",h.setAttribute("role","toolbar"),h.setAttribute("aria-label","Highlight tools"),h.setAttribute("popover","auto"),h.hidden=!0,document.body.appendChild(h),h.addEventListener("toggle",n=>{n.newState==="closed"&&(h.hidden=!0,R=null)}),h)}function I(n,t,e){let i=kt();i.innerHTML="",R=t;let o=t.colors,s=t.element,r=e?.color,d=document.createElement("div");if(d.className="hn-swatches",d.setAttribute("role","group"),d.setAttribute("aria-label","Highlight colors"),o.forEach((a,c)=>{let l=document.createElement("button");l.type="button",l.className="hn-swatch",l.dataset.color=a,l.setAttribute("aria-label",`Highlight ${a}${r===a?" (current)":""}`),l.setAttribute("tabindex",c===0?"0":"-1");let f=rt(s,a);f&&(l.style.backgroundColor=f),r===a&&l.setAttribute("aria-pressed","true"),l.addEventListener("click",()=>{e?t._changeColor(e.id,a):t._createFromSelection(a),A()}),d.appendChild(l)}),i.appendChild(d),e){let a=document.createElement("span");a.className="hn-separator",a.setAttribute("aria-hidden","true"),i.appendChild(a);let c=document.createElement("button");c.type="button",c.className="hn-action",c.textContent=e.note?"Edit Note":"Add Note",c.addEventListener("click",()=>{at(t,e),A()}),i.appendChild(c);let l=document.createElement("button");l.type="button",l.className="hn-action hn-action-remove",l.textContent="Remove",l.addEventListener("click",()=>{t.removeHighlight(e.id),A()}),i.appendChild(l)}d.addEventListener("keydown",a=>{let c=[...d.querySelectorAll("button")],l=c.indexOf(document.activeElement);if(l<0)return;let f=-1;if(a.key==="ArrowRight"||a.key==="ArrowDown")a.preventDefault(),f=(l+1)%c.length;else if(a.key==="ArrowLeft"||a.key==="ArrowUp")a.preventDefault(),f=(l-1+c.length)%c.length;else if(a.key==="Escape"){A();return}f>=0&&(c[l].setAttribute("tabindex","-1"),c[f].setAttribute("tabindex","0"),c[f].focus())}),i.hidden=!1;try{i.showPopover()}catch{}xt(n),requestAnimationFrame(()=>{let a=i.querySelector(".hn-swatch");a&&a.focus()})}function at(n,t){v();let e=n.element,i=w(e,t.startOffset,t.endOffset);if(!i)return;u=document.createElement("div"),u.className="hn-note-panel",u.setAttribute("role","dialog"),u.setAttribute("aria-label","Private note");let o=document.createElement("header");o.className="hn-note-header",o.innerHTML="<small>PRIVATE NOTE</small>",u.appendChild(o);let s=document.createElement("blockquote");s.className="hn-note-quote",s.textContent=t.text.length>80?t.text.slice(0,80)+"\u2026":t.text,u.appendChild(s);let r=document.createElement("textarea");r.className="hn-note-textarea",r.placeholder="Add a note\u2026",r.value=t.note||"",r.rows=3,r.setAttribute("aria-label","Note for highlighted text"),u.appendChild(r);let d=document.createElement("footer");d.className="hn-note-actions";let a=document.createElement("button");a.type="button",a.className="hn-action hn-action-save",a.textContent="Save",a.addEventListener("click",()=>{n._updateNote(t.id,r.value.trim()),v()});let c=document.createElement("button");c.type="button",c.className="hn-action",c.textContent="Cancel",c.addEventListener("click",()=>v()),d.append(a,c),u.appendChild(d),r.addEventListener("keydown",g=>{g.key==="Escape"&&(g.preventDefault(),v()),g.key==="Enter"&&(g.metaKey||g.ctrlKey)&&(g.preventDefault(),n._updateNote(t.id,r.value.trim()),v())}),e.style.position="relative",e.appendChild(u);let l=i.getClientRects()[0],f=e.getBoundingClientRect();if(l){let g=l.top-f.top;u.style.top=`${g}px`}requestAnimationFrame(()=>{r.focus(),document.addEventListener("pointerdown",ct)})}function ct(n){u&&!u.contains(n.target)&&v()}function v(){u&&(document.removeEventListener("pointerdown",ct),u.remove(),u=null)}function xt(n){h&&requestAnimationFrame(()=>{let t=h.getBoundingClientRect(),e=t.width||200,i=t.height||40,o=n.top-i-it,s=n.left+n.width/2-e/2;o<P&&(o=n.bottom+it);let r=window.innerWidth-e-P;s=Math.max(P,Math.min(s,r)),h.style.top=`${o}px`,h.style.left=`${s}px`})}function A(){if(h){try{h.hidePopover()}catch{}h.hidden=!0,R=null}}function q(n){b||(b=document.createElement("div"),b.setAttribute("aria-live","polite"),b.setAttribute("aria-atomic","true"),b.className="hn-sr-only",document.body.appendChild(b)),b.textContent="",requestAnimationFrame(()=>{b.textContent=n})}function ot(n,t,e){let i=document.createTreeWalker(n,NodeFilter.SHOW_TEXT),o=0;for(;i.nextNode();){if(i.currentNode===t)return o+e;o+=(i.currentNode.textContent??"").length}return-1}function w(n,t,e){let i=document.createTreeWalker(n,NodeFilter.SHOW_TEXT),o=0,s=null,r=0,d=null,a=0;for(;i.nextNode();){let c=i.currentNode,l=(c.textContent??"").length;if(!s&&o+l>t&&(s=c,r=t-o),o+l>=e){d=c,a=e-o;break}o+=l}if(!s||!d)return null;try{let c=document.createRange();return c.setStart(s,Math.min(r,(s.textContent??"").length)),c.setEnd(d,Math.min(a,(d.textContent??"").length)),c}catch{return null}}function _(n){if(D.has(n))return D.get(n);let t=new F(n);return D.set(n,t),t}function st(n=document){n.querySelectorAll(W).forEach(t=>{t.hasAttribute("data-highlights-init")||_(t)})}var W,nt,vt,it,P,Et,E,k,h,R,u,b,F,D,Nt,lt=O(()=>{H();W="[data-highlights]",nt="highlights",vt=["yellow","green","blue","pink"],it=8,P=8,Et=typeof CSS<"u"&&"highlights"in CSS;E=null,k=0;h=null,R=null;u=null;b=null;F=class{#t;#s;#n;#r;#e=[];#c=!Et;#l;#d;#h=!1;#u=[];constructor(t){this.#t=t,this.#r=t.hasAttribute("data-highlights-readonly");let e=t.dataset.highlights;this.#s=e&&e!==""?e:location.pathname;let i=t.dataset.highlightsColors;this.#n=i?i.split(",").map(o=>o.trim()).filter(Boolean):[...vt],this.#c||Ct(this.#n),this.#o(),this.#r||(this.#l=this.#m.bind(this),this.#d=this.#g.bind(this),t.addEventListener("pointerup",this.#l),t.addEventListener("click",this.#d)),t.setAttribute("data-highlights-init",""),this.#b().then(()=>{this.#h||this.#o()})}get colors(){return[...this.#n]}get element(){return this.#t}getHighlights(){return this.#e.map(t=>({...t}))}removeHighlight(t){let e=this.#e.findIndex(i=>i.id===t);e<0||(this.#e.splice(e,1),this.#i(),this.#o(),this.#a("highlights:removed",{id:t}),q("Highlight removed"))}clearAll(){this.#e=[],this.#i(),this.#o()}exportHighlights(){return JSON.stringify({version:1,highlights:this.#e})}importHighlights(t){try{let e=typeof t=="string"?JSON.parse(t):t;if(!e.highlights||!Array.isArray(e.highlights))return;this.#e=e.highlights,this.#i(),this.#o()}catch{}}destroy(){if(!this.#h){if(this.#h=!0,this.#l&&this.#t.removeEventListener("pointerup",this.#l),this.#d&&this.#t.removeEventListener("click",this.#d),this.#c)this.#t.querySelectorAll("mark[data-hn-id]").forEach(t=>{let e=t.parentNode;for(;t.firstChild;)e.insertBefore(t.firstChild,t);e.removeChild(t),e.normalize()});else{for(let t of this.#n)CSS.highlights.delete(`hn-${t}`);At()}this.#f(),this.#t.removeAttribute("data-highlights-init"),R===this&&A(),v()}}#m(){requestAnimationFrame(()=>{if(this.#h||this.#t.hasAttribute("data-selection-menu"))return;let t=window.getSelection();if(!t||t.isCollapsed||!t.toString().trim())return;let e=t.getRangeAt(0);if(!this.#t.contains(e.commonAncestorContainer))return;let i=e.getBoundingClientRect();I(i,this,null)})}#g(t){if(this.#t.hasAttribute("data-selection-menu"))return;let e=t.target.closest?.(".hn-margin-annotation");if(e){let o=e.dataset.hnId,s=this.#e.find(r=>r.id===o);if(s){at(this,s);return}}let i=t.target.closest?.("mark[data-hn-id]");if(i){let o=i.dataset.hnId,s=this.#e.find(r=>r.id===o);if(s){this.#a("highlights:clicked",{id:o});let r=i.getBoundingClientRect();I(r,this,s);return}}if(!this.#c){let o=this.#y(t.clientX,t.clientY);if(o){this.#a("highlights:clicked",{id:o.id});let s=w(this.#t,o.startOffset,o.endOffset);s&&I(s.getBoundingClientRect(),this,o)}}}#y(t,e){for(let i of this.#e){let o=w(this.#t,i.startOffset,i.endOffset);if(!o)continue;let s=o.getClientRects();for(let r of s)if(t>=r.left&&t<=r.right&&e>=r.top&&e<=r.bottom)return i}return null}_createFromSelection(t){let e=window.getSelection();if(!e||e.isCollapsed)return;let i=e.getRangeAt(0);if(!this.#t.contains(i.commonAncestorContainer))return;let o=ot(this.#t,i.startContainer,i.startOffset),s=ot(this.#t,i.endContainer,i.endOffset);if(o<0||s<0||o>=s)return;let r=e.toString().trim(),d={id:St(),startOffset:o,endOffset:s,text:r,color:t,note:"",created:Date.now()};this.#e.push(d),this.#i(),this.#o(),e.removeAllRanges(),this.#a("highlights:added",{id:d.id,text:r,color:t,note:""}),q("Highlight added")}_changeColor(t,e){let i=this.#e.find(o=>o.id===t);i&&(i.color=e,this.#i(),this.#o())}_updateNote(t,e){let i=this.#e.find(o=>o.id===t);i&&(i.note=e,this.#i(),this.#p(),this.#a("highlights:note-changed",{id:t,note:e}),q("Note saved"))}async#b(){let t=await y.get(nt,this.#s);if(!t||!Array.isArray(t.highlights))return;let e=$(this.#t.textContent);t.contentHash&&t.contentHash!==e?(this.#e=t.highlights.filter(i=>{let o=w(this.#t,i.startOffset,i.endOffset);return o?o.toString().trim()===i.text:!1}),this.#i()):this.#e=t.highlights}#i(){let t={version:1,contentHash:$(this.#t.textContent),highlights:this.#e};y.set(nt,this.#s,t).catch(()=>{})}#o(){this.#c?this.#v():this.#w(),this.#p()}#w(){let t=new Map;for(let e of this.#n)t.set(e,[]);for(let e of this.#e){let i=w(this.#t,e.startOffset,e.endOffset);i&&t.has(e.color)&&t.get(e.color).push(i)}for(let[e,i]of t){let o=`hn-${e}`;i.length===0?CSS.highlights.delete(o):CSS.highlights.set(o,new Highlight(...i))}}#v(){this.#t.querySelectorAll("mark[data-hn-id]").forEach(e=>{let i=e.parentNode;for(;e.firstChild;)i.insertBefore(e.firstChild,e);i.removeChild(e)}),this.#t.normalize();let t=[...this.#e].sort((e,i)=>i.startOffset-e.startOffset);for(let e of t){let i=w(this.#t,e.startOffset,e.endOffset);if(!i)continue;let o=rt(this.#t,e.color),s=document.createElement("mark");s.dataset.hnId=e.id,s.dataset.hnColor=e.color,o&&(s.style.backgroundColor=o,s.style.textDecorationColor=o);try{i.surroundContents(s)}catch{let r=i.extractContents();s.appendChild(r),i.insertNode(s)}}}#f(){for(let t of this.#u)t.remove();this.#u=[]}#p(){if(this.#f(),this.#e.length===0)return;getComputedStyle(this.#t).position==="static"&&(this.#t.style.position="relative");for(let e of this.#e){let i=w(this.#t,e.startOffset,e.endOffset);if(!i)continue;let o=i.getClientRects();if(o.length===0)continue;let s=o[0],r=this.#t.getBoundingClientRect(),d=s.top-r.top,a=document.createElement("span");a.className="hn-margin-annotation",a.dataset.hnId=e.id,a.setAttribute("aria-hidden","true"),a.style.top=`${d}px`,e.note?(a.innerHTML='<span class="hn-note-indicator">*</span> You highlighted',a.classList.add("hn-has-note")):a.textContent="You highlighted",this.#t.appendChild(a),this.#u.push(a)}}#a(t,e={}){this.#t.dispatchEvent(new CustomEvent(t,{detail:e,bubbles:!0}))}},D=new WeakMap;document.readyState==="loading"?document.addEventListener("DOMContentLoaded",()=>st()):st();Nt=new MutationObserver(n=>{for(let t of n)for(let e of t.addedNodes){if(e.nodeType!==Node.ELEMENT_NODE)continue;let i=e;i.matches(W)&&_(i),i.querySelectorAll(W).forEach(o=>{o.hasAttribute("data-highlights-init")||_(o)})}});Nt.observe(document.documentElement,{childList:!0,subtree:!0})});var ut={};gt(ut,{currentHash:()=>z,initPageWatch:()=>X,readWatch:()=>B,removeWatch:()=>ht,writeWatch:()=>x});function dt(){return typeof window<"u"&&window.vbPageWatch?.serverSync===!0?!0:document.querySelector('meta[name="vb-page-watch-server"]')?.getAttribute("content")==="true"}async function Ot(n){if(!dt())return null;try{let t=new C("notify"),e={url:n.url,type:"page-watch",notify:["panel"]},i=await t.post("/subscribe",e);return typeof i?.id=="string"?i.id:null}catch(t){let e=t instanceof S?`${t.status}`:String(t);return console.warn("[page-watch] server subscribe failed; client-only watch in effect.",e),null}}async function Tt(n){if(!(!n||!dt()))try{await new C("notify").delete(`/subscribe/${encodeURIComponent(n)}`)}catch(t){let e=t instanceof S?`${t.status}`:String(t);console.warn("[page-watch] server unsubscribe failed; local state already cleared.",e)}}function Lt(){return document.querySelector("main")||document.querySelector("article")||document.body}function N(){return location.pathname||"/"}function z(){let n=Lt();return n?$(n.textContent||""):""}function $t(){return document.title||N()}async function B(){return await y.get(G,N())}async function x(n){await y.set(G,N(),n)}async function ht(){await y.remove(G,N())}function U(n,t){n.setAttribute("aria-pressed",t?"true":"false"),n.dataset.watching="",t||delete n.dataset.watching;let e=n.querySelector("icon-wc");e&&e.setAttribute("name",t?"bookmark-check":"bookmark");let i=[...n.childNodes].find(o=>o.nodeType===Node.TEXT_NODE&&(o.textContent||"").trim());i&&!n.hasAttribute("data-watch-label-locked")&&(i.textContent=t?"Watching":"Watch for updates"),n.setAttribute("title",t?"Stop watching this page":"Watch this page for content updates")}async function j(n){if(n.hasAttribute("data-watch-page-init"))return;n.setAttribute("data-watch-page-init",""),n.setAttribute("type",n.getAttribute("type")||"button");let t=await B();U(n,!!t),n.addEventListener("click",async e=>{e.preventDefault();let i=await B();if(i)await ht(),U(n,!1),n.dispatchEvent(new CustomEvent("page-watch:remove",{bubbles:!0,composed:!0,detail:{url:i.url,subscriptionId:i.subscriptionId}})),Tt(i.subscriptionId);else{let o={url:N(),title:$t(),contentHash:z(),watchedAt:new Date().toISOString(),lastChecked:new Date().toISOString(),lastChanged:null,subscriptionId:null};await x(o),U(n,!0),n.dispatchEvent(new CustomEvent("page-watch:add",{bubbles:!0,composed:!0,detail:{entry:o}}));let s=await Ot(o);s&&await x({...o,subscriptionId:s})}})}async function Rt(){let n=await B();if(!n)return;let t=z(),e=new Date().toISOString(),i=n.contentHash,o={...n,lastChecked:e};if(t&&t!==i){o.contentHash=t,o.lastChanged=e,await x(o);let s={id:`page-watch:${n.url}:${t}`,type:"watch",title:`Updated: ${n.title}`,body:"Content changed since your last visit.",url:n.url,date:e,read:!1,dismissed:!1,priority:"normal"};document.dispatchEvent(new CustomEvent("notification-wc:new",{bubbles:!0,composed:!0,detail:{notification:s}}))}else await x(o)}function X(n=document){for(let t of n.querySelectorAll(V))j(t);Rt()}var V,G,Bt,ft=O(()=>{H();et();lt();V="[data-watch-page]",G="watches";document.readyState==="loading"?document.addEventListener("DOMContentLoaded",()=>X()):X();Bt=new MutationObserver(n=>{for(let t of n)for(let e of t.addedNodes){if(e.nodeType!==Node.ELEMENT_NODE)continue;let i=e;i.matches?.(V)&&j(i),i.querySelectorAll?.(V).forEach(o=>j(o))}});Bt.observe(document.documentElement,{childList:!0,subtree:!0})});var Pt=window.matchMedia("(prefers-reduced-motion: reduce)");var K=new Map;function Y(n,t,e={}){let i=e.priority??10,o={impl:t,bundle:e.bundle,contract:e.contract,priority:i},s=K.get(n);if(customElements.get(n)){if(!s||s.priority>=i){s&&s.priority===i&&s.impl!==t&&console.warn(`[VB Bundle] Tag <${n}> already registered by "${s.bundle}" (priority ${s.priority}). Skipping "${e.bundle}".`);return}console.warn(`[VB Bundle] Tag <${n}> defined by "${s.bundle}" cannot be replaced (customElements.define is permanent). "${e.bundle}" has higher priority but arrived late.`);return}if(s&&s.priority>=i){s.priority===i&&console.warn(`[VB Bundle] Tag <${n}> already registered by "${s.bundle}". Skipping "${e.bundle}" (first wins at equal priority).`);return}K.set(n,o),customElements.define(n,t)}var T=class extends HTMLElement{#t=[];connectedCallback(){this.hasAttribute("data-upgraded")||this.setup()!==!1&&this.setAttribute("data-upgraded","")}disconnectedCallback(){for(let t of this.#t)t();this.#t=[],this.removeAttribute("data-upgraded"),this.teardown()}listen(t,e,i,o){t.addEventListener(e,i,o),this.#t.push(()=>t.removeEventListener(e,i,o))}setup(){}teardown(){}};var pt="Watch for updates",Mt="Watching",J=class extends T{#t=null;setup(){if(this.hasAttribute("server-sync")){let e=window;e.vbPageWatch={...e.vbPageWatch??{},serverSync:!0}}let t=this.#s();this.dataset.variant=t;for(let e of Array.from(this.children))e.hasAttribute?.("data-watch-page")&&e.remove();this.#t=this.#n(t),this.appendChild(this.#t),this.listen(document,"page-watch:add",this.#r),this.listen(document,"page-watch:remove",this.#r)}teardown(){this.#t&&(this.#t.remove(),this.#t=null)}#s(){let t=this.getAttribute("variant");return t==="compact"||t==="button"?t:"icon"}#n(t){let e=document.createElement("button");e.type="button",e.setAttribute("data-watch-page",""),e.className="ghost",e.setAttribute("aria-label","Watch this page for updates");let i=t==="icon"?"sm":"xs",o=this.getAttribute("label")??pt;return t==="icon"?e.innerHTML=`<icon-wc name="bookmark" size="${i}"></icon-wc>`:(e.innerHTML=`<icon-wc name="bookmark" size="${i}"></icon-wc><span>${this.#e(o)}</span>`,e.setAttribute("data-watch-label-locked","")),e}#r=async()=>{if(this.#t)try{let{readWatch:t}=await Promise.resolve().then(()=>(ft(),ut)),i=!!await t();this.#t.setAttribute("aria-pressed",i?"true":"false");let o=this.#t.querySelector("icon-wc");o&&o.setAttribute("name",i?"bookmark-check":"bookmark");let s=this.#t.querySelector("span");if(s&&this.#s()!=="icon"){let r=this.getAttribute("label");s.textContent=r||(i?Mt:pt)}this.#t.setAttribute("title",i?"Stop watching this page":"Watch this page for content updates")}catch{}};#e(t){let e=document.createElement("div");return e.textContent=t,e.innerHTML}};Y("watch-wc",J);export{J as WatchWc};
3
+ //# sourceMappingURL=watch-wc.js.map