profile-pane 2.0.0-shadowDom-bb2bef56 → 2.0.0-shadowDom-be6a9934

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 (51) hide show
  1. package/lib/CVCardElement.js +21 -146
  2. package/lib/CVPresenter.js +1 -87
  3. package/lib/ChatWithMeElement.js +3 -155
  4. package/lib/FriendListElement.js +4 -71
  5. package/lib/FriendListElement.js.LICENSE.txt +5 -0
  6. package/lib/FriendsPresenter.js +1 -55
  7. package/lib/ProfileCardElement.js +23 -112
  8. package/lib/ProfileCardElement.js.LICENSE.txt +5 -0
  9. package/lib/ProfileViewElement.js +20 -100
  10. package/lib/ProfileViewElement.js.LICENSE.txt +5 -0
  11. package/lib/QRCodeCardElement.js +10 -113
  12. package/lib/QRCodeCardElement.js.LICENSE.txt +5 -0
  13. package/lib/SocialCardElement.js +9 -79
  14. package/lib/SocialPresenter.js +1 -74
  15. package/lib/StuffCardElement.js +5 -80
  16. package/lib/StuffCardElement.js.LICENSE.txt +5 -0
  17. package/lib/StuffPresenter.js +1 -30
  18. package/lib/addMeToYourFriends.js +2 -108
  19. package/lib/addMeToYourFriends.js.LICENSE.txt +5 -0
  20. package/lib/buttonsHelper.js +1 -38
  21. package/lib/editProfilePane/editProfile.view.js +1 -130
  22. package/lib/editProfilePane/profile.dom.js +1 -28
  23. package/lib/index.js +1 -38
  24. package/lib/presenter.js +1 -62
  25. package/lib/texts.js +0 -17
  26. package/package.json +5 -6
  27. package/lib/CVCardElement.js.map +0 -1
  28. package/lib/CVPresenter.js.map +0 -1
  29. package/lib/ChatWithMeElement.js.map +0 -1
  30. package/lib/FriendListElement.js.map +0 -1
  31. package/lib/FriendsPresenter.js.map +0 -1
  32. package/lib/ProfileCardElement.js.map +0 -1
  33. package/lib/ProfileViewElement.js.map +0 -1
  34. package/lib/QRCodeCardElement.js.map +0 -1
  35. package/lib/SocialCardElement.js.map +0 -1
  36. package/lib/SocialPresenter.js.map +0 -1
  37. package/lib/StuffCardElement.js.map +0 -1
  38. package/lib/StuffPresenter.js.map +0 -1
  39. package/lib/addMeToYourFriends.js.map +0 -1
  40. package/lib/buttonsHelper.js.map +0 -1
  41. package/lib/editProfilePane/editProfile.view.js.map +0 -1
  42. package/lib/editProfilePane/profile.dom.js.map +0 -1
  43. package/lib/index.js.map +0 -1
  44. package/lib/presenter.js.map +0 -1
  45. package/lib/styles/CVCard.css +0 -39
  46. package/lib/styles/ChatWithMe.css +0 -50
  47. package/lib/styles/ProfileCard.css +0 -118
  48. package/lib/styles/QRCodeCard.css +0 -18
  49. package/lib/styles/SocialCard.css +0 -58
  50. package/lib/styles/global.css +0 -640
  51. package/lib/texts.js.map +0 -1
@@ -1,176 +1,51 @@
1
- import cvCardCss from './styles/CVCard.css';
2
- import { html, render } from 'lit-html';
3
- import globalCssText from './styles/global.css';
4
- class CVCardElement extends HTMLElement {
5
- constructor() {
6
- super();
7
- this.shadow = this.attachShadow({ mode: 'open' });
8
- }
9
- async connectedCallback() {
10
- let globalSheet = null;
11
- let cardSheet = null;
12
- let canUseSheets = typeof CSSStyleSheet !== 'undefined' && typeof globalCssText === 'string' && typeof cvCardCss === 'string';
13
- try {
14
- if (canUseSheets) {
15
- globalSheet = new CSSStyleSheet();
16
- globalSheet.replaceSync(globalCssText);
17
- if (!CVCardElement.sheet) {
18
- CVCardElement.sheet = new CSSStyleSheet();
19
- CVCardElement.sheet.replaceSync(cvCardCss);
20
- }
21
- cardSheet = CVCardElement.sheet;
22
- }
23
- }
24
- catch (e) {
25
- globalSheet = null;
26
- cardSheet = null;
27
- }
28
- if ('adoptedStyleSheets' in Document.prototype && globalSheet && cardSheet) {
29
- this.shadow.adoptedStyleSheets = [globalSheet, cardSheet];
30
- }
31
- else {
32
- // Fallback for browsers or test environments without adoptedStyleSheets or CSSStyleSheet
33
- if (typeof globalCssText === 'string') {
34
- const styleGlobal = document.createElement('style');
35
- styleGlobal.textContent = globalCssText;
36
- this.shadow.appendChild(styleGlobal);
37
- }
38
- if (typeof cvCardCss === 'string') {
39
- const styleCard = document.createElement('style');
40
- styleCard.textContent = cvCardCss;
41
- this.shadow.appendChild(styleCard);
42
- }
43
- }
44
- this.render();
45
- }
46
- render() {
47
- // .cardFrame wrapper already present from previous patch
48
- // Assume cvData is passed as a property
49
- const cvData = this.cvData;
50
- if (!cvData)
51
- return;
52
- const { rolesByType, skills, languages } = cvData;
53
- const futureRolesArr = rolesByType['FutureRole'] || [];
54
- const currentRolesArr = rolesByType['CurrentRole'] || [];
55
- const pastRolesArr = rolesByType['PastRole'] || [];
56
- const skillsArr = skills || [];
57
- const languagesArr = languages || [];
58
- const hasFutureRole = Array.isArray(futureRolesArr) && futureRolesArr.length > 0;
59
- const hasCurrentRole = Array.isArray(currentRolesArr) && currentRolesArr.length > 0;
60
- const hasPastRole = Array.isArray(pastRolesArr) && pastRolesArr.length > 0;
61
- const hasSkills = Array.isArray(skillsArr) && skillsArr.length > 0;
62
- const hasLanguages = Array.isArray(languagesArr) && languagesArr.length > 0;
63
- if (!(hasFutureRole || hasCurrentRole || hasPastRole || hasSkills || hasLanguages)) {
64
- render(html ``, this.shadow);
65
- return;
66
- }
67
- render(html `
1
+ (()=>{"use strict";const n="/* Card frame for secondary background/border */\n\n\n.cvSection {\n margin-bottom: 1.25em;\n}\n\n.cvRole {\n margin: var(--spacing-xs) 0;\n font-size: var(--font-size-base);\n line-height: var(--line-height-base);\n display: flex;\n flex-direction: column;\n gap: 0.2em;\n}\n\n.cvOrg {\n font-weight: 600;\n color: var(--primary-color);\n}\n\n.cvSkill, .cvLanguage {\n text-align: left;\n margin: var(--spacing-xs) 0;\n font-size: var(--font-size-base);\n line-height: var(--line-height-base);\n}\n\n.cvSection h3 {\n color: var(--text-color);\n font-size: var(--font-size-lg);\n font-weight: 600;\n line-height: var(--line-height-tight);\n margin-bottom: var(--spacing-xs);\n border-bottom: 1px solid var(--border-light);\n padding-bottom: var(--spacing-xs);\n}\n",e=globalThis,t=e.trustedTypes,i=t?t.createPolicy("lit-html",{createHTML:n=>n}):void 0,r="$lit$",o=`lit$${Math.random().toFixed(9).slice(2)}$`,a="?"+o,s=`<${a}>`,l=document,c=()=>l.createComment(""),d=n=>null===n||"object"!=typeof n&&"function"!=typeof n,h=Array.isArray,p="[ \t\n\f\r]",g=/<(?:(!--|\/[^a-zA-Z])|(\/?[a-zA-Z][^>\s]*)|(\/?$))/g,m=/-->/g,u=/>/g,b=RegExp(`>|${p}(?:([^\\s"'>=/]+)(${p}*=${p}*(?:[^ \t\n\f\r"'\`<>=]|("|')|))|$)`,"g"),f=/'/g,v=/"/g,x=/^(?:script|style|textarea|title)$/i,y=n=>(e,...t)=>({_$litType$:n,strings:e,values:t}),$=y(1),A=(y(2),y(3),Symbol.for("lit-noChange")),_=Symbol.for("lit-nothing"),w=new WeakMap,k=l.createTreeWalker(l,129);function S(n,e){if(!h(n)||!n.hasOwnProperty("raw"))throw Error("invalid template strings array");return void 0!==i?i.createHTML(e):e}const C=(n,e)=>{const t=n.length-1,i=[];let a,l=2===e?"<svg>":3===e?"<math>":"",c=g;for(let e=0;e<t;e++){const t=n[e];let d,h,p=-1,y=0;for(;y<t.length&&(c.lastIndex=y,h=c.exec(t),null!==h);)y=c.lastIndex,c===g?"!--"===h[1]?c=m:void 0!==h[1]?c=u:void 0!==h[2]?(x.test(h[2])&&(a=RegExp("</"+h[2],"g")),c=b):void 0!==h[3]&&(c=b):c===b?">"===h[0]?(c=a??g,p=-1):void 0===h[1]?p=-2:(p=c.lastIndex-h[2].length,d=h[1],c=void 0===h[3]?b:'"'===h[3]?v:f):c===v||c===f?c=b:c===m||c===u?c=g:(c=b,a=void 0);const $=c===b&&n[e+1].startsWith("/>")?" ":"";l+=c===g?t+s:p>=0?(i.push(d),t.slice(0,p)+r+t.slice(p)+o+$):t+o+(-2===p?e:$)}return[S(n,l+(n[t]||"<?>")+(2===e?"</svg>":3===e?"</math>":"")),i]};class z{constructor({strings:n,_$litType$:e},i){let s;this.parts=[];let l=0,d=0;const h=n.length-1,p=this.parts,[g,m]=C(n,e);if(this.el=z.createElement(g,i),k.currentNode=this.el.content,2===e||3===e){const n=this.el.content.firstChild;n.replaceWith(...n.childNodes)}for(;null!==(s=k.nextNode())&&p.length<h;){if(1===s.nodeType){if(s.hasAttributes())for(const n of s.getAttributeNames())if(n.endsWith(r)){const e=m[d++],t=s.getAttribute(n).split(o),i=/([.?@])?(.*)/.exec(e);p.push({type:1,index:l,name:i[2],strings:t,ctor:"."===i[1]?F:"?"===i[1]?B:"@"===i[1]?E:M}),s.removeAttribute(n)}else n.startsWith(o)&&(p.push({type:6,index:l}),s.removeAttribute(n));if(x.test(s.tagName)){const n=s.textContent.split(o),e=n.length-1;if(e>0){s.textContent=t?t.emptyScript:"";for(let t=0;t<e;t++)s.append(n[t],c()),k.nextNode(),p.push({type:2,index:++l});s.append(n[e],c())}}}else if(8===s.nodeType)if(s.data===a)p.push({type:2,index:l});else{let n=-1;for(;-1!==(n=s.data.indexOf(o,n+1));)p.push({type:7,index:l}),n+=o.length-1}l++}}static createElement(n,e){const t=l.createElement("template");return t.innerHTML=n,t}}function H(n,e,t=n,i){if(e===A)return e;let r=void 0!==i?t._$Co?.[i]:t._$Cl;const o=d(e)?void 0:e._$litDirective$;return r?.constructor!==o&&(r?._$AO?.(!1),void 0===o?r=void 0:(r=new o(n),r._$AT(n,t,i)),void 0!==i?(t._$Co??=[])[i]=r:t._$Cl=r),void 0!==r&&(e=H(n,r._$AS(n,e.values),r,i)),e}class T{constructor(n,e){this._$AV=[],this._$AN=void 0,this._$AD=n,this._$AM=e}get parentNode(){return this._$AM.parentNode}get _$AU(){return this._$AM._$AU}u(n){const{el:{content:e},parts:t}=this._$AD,i=(n?.creationScope??l).importNode(e,!0);k.currentNode=i;let r=k.nextNode(),o=0,a=0,s=t[0];for(;void 0!==s;){if(o===s.index){let e;2===s.type?e=new N(r,r.nextSibling,this,n):1===s.type?e=new s.ctor(r,s.name,s.strings,this,n):6===s.type&&(e=new R(r,this,n)),this._$AV.push(e),s=t[++a]}o!==s?.index&&(r=k.nextNode(),o++)}return k.currentNode=l,i}p(n){let e=0;for(const t of this._$AV)void 0!==t&&(void 0!==t.strings?(t._$AI(n,t,e),e+=t.strings.length-2):t._$AI(n[e])),e++}}class N{get _$AU(){return this._$AM?._$AU??this._$Cv}constructor(n,e,t,i){this.type=2,this._$AH=_,this._$AN=void 0,this._$AA=n,this._$AB=e,this._$AM=t,this.options=i,this._$Cv=i?.isConnected??!0}get parentNode(){let n=this._$AA.parentNode;const e=this._$AM;return void 0!==e&&11===n?.nodeType&&(n=e.parentNode),n}get startNode(){return this._$AA}get endNode(){return this._$AB}_$AI(n,e=this){n=H(this,n,e),d(n)?n===_||null==n||""===n?(this._$AH!==_&&this._$AR(),this._$AH=_):n!==this._$AH&&n!==A&&this._(n):void 0!==n._$litType$?this.$(n):void 0!==n.nodeType?this.T(n):(n=>h(n)||"function"==typeof n?.[Symbol.iterator])(n)?this.k(n):this._(n)}O(n){return this._$AA.parentNode.insertBefore(n,this._$AB)}T(n){this._$AH!==n&&(this._$AR(),this._$AH=this.O(n))}_(n){this._$AH!==_&&d(this._$AH)?this._$AA.nextSibling.data=n:this.T(l.createTextNode(n)),this._$AH=n}$(n){const{values:e,_$litType$:t}=n,i="number"==typeof t?this._$AC(n):(void 0===t.el&&(t.el=z.createElement(S(t.h,t.h[0]),this.options)),t);if(this._$AH?._$AD===i)this._$AH.p(e);else{const n=new T(i,this),t=n.u(this.options);n.p(e),this.T(t),this._$AH=n}}_$AC(n){let e=w.get(n.strings);return void 0===e&&w.set(n.strings,e=new z(n)),e}k(n){h(this._$AH)||(this._$AH=[],this._$AR());const e=this._$AH;let t,i=0;for(const r of n)i===e.length?e.push(t=new N(this.O(c()),this.O(c()),this,this.options)):t=e[i],t._$AI(r),i++;i<e.length&&(this._$AR(t&&t._$AB.nextSibling,i),e.length=i)}_$AR(n=this._$AA.nextSibling,e){for(this._$AP?.(!1,!0,e);n!==this._$AB;){const e=n.nextSibling;n.remove(),n=e}}setConnected(n){void 0===this._$AM&&(this._$Cv=n,this._$AP?.(n))}}class M{get tagName(){return this.element.tagName}get _$AU(){return this._$AM._$AU}constructor(n,e,t,i,r){this.type=1,this._$AH=_,this._$AN=void 0,this.element=n,this.name=e,this._$AM=i,this.options=r,t.length>2||""!==t[0]||""!==t[1]?(this._$AH=Array(t.length-1).fill(new String),this.strings=t):this._$AH=_}_$AI(n,e=this,t,i){const r=this.strings;let o=!1;if(void 0===r)n=H(this,n,e,0),o=!d(n)||n!==this._$AH&&n!==A,o&&(this._$AH=n);else{const i=n;let a,s;for(n=r[0],a=0;a<r.length-1;a++)s=H(this,i[t+a],e,a),s===A&&(s=this._$AH[a]),o||=!d(s)||s!==this._$AH[a],s===_?n=_:n!==_&&(n+=(s??"")+r[a+1]),this._$AH[a]=s}o&&!i&&this.j(n)}j(n){n===_?this.element.removeAttribute(this.name):this.element.setAttribute(this.name,n??"")}}class F extends M{constructor(){super(...arguments),this.type=3}j(n){this.element[this.name]=n===_?void 0:n}}class B extends M{constructor(){super(...arguments),this.type=4}j(n){this.element.toggleAttribute(this.name,!!n&&n!==_)}}class E extends M{constructor(n,e,t,i,r){super(n,e,t,i,r),this.type=5}_$AI(n,e=this){if((n=H(this,n,e,0)??_)===A)return;const t=this._$AH,i=n===_&&t!==_||n.capture!==t.capture||n.once!==t.once||n.passive!==t.passive,r=n!==_&&(t===_||i);i&&this.element.removeEventListener(this.name,this,t),r&&this.element.addEventListener(this.name,this,n),this._$AH=n}handleEvent(n){"function"==typeof this._$AH?this._$AH.call(this.options?.host??this.element,n):this._$AH.handleEvent(n)}}class R{constructor(n,e,t){this.element=n,this.type=6,this._$AN=void 0,this._$AM=e,this.options=t}get _$AU(){return this._$AM._$AU}_$AI(n){H(this,n)}}const I=e.litHtmlPolyfillSupport;I?.(z,N),(e.litHtmlVersions??=[]).push("3.3.1");const O='/* Generic profile table styles */\n.profileTable {\n width: 100%;\n border-collapse: collapse;\n margin-bottom: var(--spacing-md);\n}\n.profileTable caption {\n padding: var(--spacing-sm);\n text-align: left;\n color: var(--text-color);\n}\n.profileTable th,\n.profileTable td {\n padding: var(--spacing-sm) var(--spacing-md);\n text-align: left;\n line-height: 1.4;\n}\n.profileTable td {\n background: var(--card-internal-bg);\n}\n.profileTable tbody tr:nth-child(even) {\n background-color: rgba(0, 0, 0, 0.02);\n}\n/* Card frame for secondary background/border */\n.cardFrame {\n background: var(--card-frame-bg, #f8f9fa);\n border: 2px solid var(--card-frame-border, #e0e0e0);\n border-radius: 18px;\n box-shadow: 0 4px 16px rgba(0,0,0,0.08);\n padding: 18px;\n margin: 12px 0;\n}\n/* Global CSS: base styles, variables, and resets */\n\n.center {\n display: flex;\n justify-content: center;\n align-items: center;\n}\n\n/* Accessible color palette */\n\n:host, :root {\n\n --primary-color: #7C4DFF; /* Vivid Purple */\n --secondary-color: #0077B6; /* Accessible Blue */\n --background-color: #FFFFFF; /* White */\n --card-bg: #FFFFFF; /* White for inner cards */\n --section-bg: #F5F5F5; /* Light grey for outer sections */\n --card-internal-bg: transparent; /* Transparent for internal components */\n --text-color: #1A1A1A; /* Near-black */\n --text-secondary: #666; /* Added for repeated usage */\n --text-muted: #444; /* Added for repeated usage */\n --border-light: #eee; /* Added for repeated borders */\n --accent-color: #FFD600; /* Bright Yellow */\n --error-color: #B00020; /* Accessible Red */\n --success-color: #00C853; /* Accessible Green */\n --border-radius: 1rem; /* Matches module usage */\n --border-radius-sm: 0.5rem;\n --box-shadow: 0 2px 8px rgba(124,77,255,0.08); /* Matches module usage */\n --box-shadow-sm: 0 1px 4px rgba(124,77,255,0.12);\n --spacing-xs: 0.5rem;\n --spacing-sm: 0.75rem;\n --spacing-md: 1rem;\n --spacing-lg: 1.5rem;\n --spacing-xl: 2rem;\n --font-family: \'Inter\', -apple-system, BlinkMacSystemFont, \'Segoe UI\', Roboto, Oxygen, Ubuntu, Cantarell, sans-serif;\n --font-size-base: 1rem; /* 16px default */\n --font-size-sm: 0.875rem; /* 14px */\n --font-size-lg: 1.125rem; /* 18px */\n --font-size-xl: 1.25rem; /* 20px */\n --line-height-base: 1.5; /* WCAG recommended */\n --line-height-tight: 1.4;\n --line-height-loose: 1.6;\n --letter-spacing-wide: 0.025em;\n\n /* Minimum font sizes for accessibility */\n --min-font-size: 14px;\n --min-line-height: 1.4;\n\n /* Accessibility improvements */\n --min-touch-target: 44px; /* WCAG minimum touch target */\n --focus-ring-width: 2px;\n --animation-duration: 0.2s; /* Reduced motion friendly */\n\n /* Additional accessibility variables */\n --focus-indicator-width: 3px;\n --animation-duration-slow: 0.3s;\n --high-contrast-ratio: 7:1; /* WCAG AAA standard */\n}\n\n/* Improve text rendering */\nhtml, body {\n margin: 0;\n padding: 0;\n font-family: var(--font-family);\n font-size: var(--font-size-base);\n line-height: var(--line-height-base);\n background: var(--background-color);\n color: var(--text-color);\n -webkit-font-smoothing: antialiased;\n -moz-osx-font-smoothing: grayscale;\n text-rendering: optimizeLegibility;\n}\n\n/* Improved heading hierarchy */\nh1, h2, h3, h4, h5, h6 {\n color: var(--primary-color);\n font-weight: 600;\n line-height: var(--line-height-tight);\n margin-top: 0;\n margin-bottom: var(--spacing-sm);\n}\n\nh2 {\n text-align: center;\n}\n\nh1 { font-size: 2rem; } /* 32px */\nh2 { font-size: 1.5rem; } /* 24px */\nh3 { font-size: 1.25rem; } /* 20px */\nh4 { font-size: 1.125rem; }/* 18px */\nh5, h6 { font-size: 1rem; }/* 16px */\n\n/* Better paragraph spacing */\np {\n margin-bottom: var(--spacing-md);\n line-height: var(--line-height-base);\n max-width: 65ch; /* Optimal reading width */\n}\n\n/* Improved link accessibility */\na {\n color: var(--primary-color);\n text-decoration: underline;\n text-underline-offset: 0.125em;\n text-decoration-thickness: 0.0625em;\n}\n\na:hover, a:focus {\n text-decoration-thickness: 0.125em;\n}\n\n/* Ensure minimum font sizes are respected */\n@media screen and (max-width: 768px) {\n html {\n font-size: max(16px, 1rem); /* Never smaller than 16px on mobile */\n }\n}\n\n/* Support for larger text preferences */\n@media (prefers-reduced-motion: no-preference) {\n html {\n scroll-behavior: smooth;\n }\n}\n\n/* Accessibility: focus styles */\n:focus {\n outline: 2px solid var(--primary-color);\n outline-offset: 1px;\n box-shadow: 0 0 0 1px var(--background-color);\n}\n\n/* Accessibility: Respect user motion preferences */\n@media (prefers-reduced-motion: reduce) {\n *, *::before, *::after {\n animation-duration: 0.01ms !important;\n animation-iteration-count: 1 !important;\n transition-duration: 0.01ms !important;\n scroll-behavior: auto !important;\n }\n}\n\n/* Accessibility: High contrast mode support */\n@media (prefers-contrast: high) {\n :root {\n --border-light: #000;\n --box-shadow: 0 2px 4px rgba(0,0,0,0.5);\n --box-shadow-sm: 0 1px 2px rgba(0,0,0,0.3);\n }\n}\n\n/* Accessibility: Improved focus management */\n:focus-visible {\n outline: var(--focus-ring-width) solid var(--primary-color);\n outline-offset: 2px;\n box-shadow: 0 0 0 1px var(--background-color);\n}\n\n:focus:not(:focus-visible) {\n outline: none;\n}\n\n/* Skip link for screen readers */\n.skip-link {\n position: absolute;\n top: -40px;\n left: 6px;\n background: var(--primary-color);\n color: white;\n padding: var(--spacing-sm) var(--spacing-md);\n text-decoration: none;\n border-radius: var(--border-radius-sm);\n z-index: 1000;\n font-weight: 600;\n font-size: var(--font-size-base);\n line-height: 1;\n}\n\n.skip-link:focus {\n top: 6px;\n outline: 2px solid white;\n outline-offset: 2px;\n}\n\n/* Semantic HTML5 improvements */\narticle, aside, section {\n display: block;\n}\n\nheader {\n margin-bottom: var(--spacing-md);\n}\n\nnav {\n display: block;\n}\n\nnav ul {\n list-style: none;\n padding: 0;\n margin: 0;\n}\n\n/* Enhanced keyboard navigation */\n*:focus-visible {\n outline: var(--focus-indicator-width) solid var(--primary-color);\n outline-offset: 2px;\n box-shadow: 0 0 0 1px var(--background-color), 0 0 0 4px rgba(124, 77, 255, 0.2);\n border-radius: 2px;\n transition: none; /* Remove transitions on focus for immediate feedback */\n}\n\n/* Improve focus management for interactive elements */\n[role="button"]:focus,\n[role="link"]:focus,\nbutton:focus,\na:focus {\n outline: 2px solid var(--primary-color);\n outline-offset: 2px;\n box-shadow: 0 0 0 1px var(--background-color);\n}\n\n/* Enhanced error message accessibility */\n[role="alert"] {\n padding: var(--spacing-md);\n border: 2px solid var(--error-color);\n border-radius: var(--border-radius-sm);\n background-color: rgba(176, 0, 32, 0.1);\n margin: var(--spacing-md) 0;\n}\n\n/* Success message styling */\n[role="status"] {\n padding: var(--spacing-md);\n border: 2px solid var(--success-color);\n border-radius: var(--border-radius-sm);\n background-color: rgba(0, 200, 83, 0.1);\n margin: var(--spacing-md) 0;\n}\n\n/* Enhanced table accessibility */\ntable {\n border-collapse: collapse;\n width: 100%;\n}\n\nth {\n font-weight: 600;\n text-align: left;\n padding: var(--spacing-sm);\n}\n\ntd {\n padding: var(--spacing-sm);\n}\n\n/* Focus trap for modals */\n.focus-trap {\n position: fixed;\n top: 0;\n left: 0;\n width: 100%;\n height: 100%;\n z-index: 9999;\n background: rgba(0, 0, 0, 0.5);\n display: flex;\n justify-content: center;\n align-items: center;\n}\n\n/* Enhanced button accessibility */\nbutton, [role="button"] {\n cursor: pointer;\n border: none;\n border-radius: var(--border-radius-sm);\n padding: var(--spacing-sm) var(--spacing-md);\n min-height: var(--min-touch-target);\n min-width: var(--min-touch-target);\n font-size: var(--font-size-base);\n font-weight: 600;\n transition: all var(--animation-duration) ease;\n position: relative;\n}\n\nbutton:disabled, [role="button"][aria-disabled="true"] {\n opacity: 0.6;\n cursor: not-allowed;\n pointer-events: none;\n}\n\n/* Loading indicator accessibility */\n.loading-spinner {\n width: 40px;\n height: 40px;\n border: 3px solid var(--border-light);\n border-top: 3px solid var(--primary-color);\n border-radius: 50%;\n animation: spin 1s linear infinite;\n}\n\n@keyframes spin {\n 0% { transform: rotate(0deg); }\n 100% { transform: rotate(360deg); }\n}\n\n@media (prefers-reduced-motion: reduce) {\n .loading-spinner {\n animation: none;\n border-top-color: var(--primary-color);\n }\n}\n\n/* Utility classes */\n.u-flex {\n display: flex;\n}\n.u-grid {\n display: grid;\n}\n.u-center {\n justify-content: center;\n align-items: center;\n}\n.u-gap {\n gap: 1em;\n}\n\n/* Common card component - used across all modules */\n.module-card {\n background: var(--card-bg);\n border-radius: var(--border-radius);\n box-shadow: var(--box-shadow);\n padding: var(--spacing-lg);\n margin-bottom: var(--spacing-lg);\n width: 100%;\n max-width: 100%;\n box-sizing: border-box;\n}\n\n/* Common header styles */\n.module-header {\n text-align: center;\n margin-bottom: var(--spacing-md);\n}\n\n/* Common flex patterns */\n.flex-center {\n display: flex;\n justify-content: center;\n align-items: center;\n}\n\n.flex-column {\n display: flex;\n flex-direction: column;\n}\n\n.flex-column-center {\n display: flex;\n flex-direction: column;\n align-items: center;\n}\n\n/* Text utilities */\n.text-center {\n text-align: center;\n}\n\n.text-secondary {\n color: var(--text-secondary);\n}\n\n.text-muted {\n color: var(--text-muted);\n}\n\n/* Responsive grid for profile */\n.profile-grid {\n display: grid;\n grid-template-columns: repeat(auto-fit, minmax(400px, 1fr));\n gap: 1.5em;\n background: var(--profile-grid-bg, var(--background-color));\n}\n.profile-header, .profile-footer {\n grid-column: 1 / -1;\n}\n\n.profileSection {\n background: var(--section-bg);\n border-radius: var(--border-radius);\n box-shadow: var(--box-shadow);\n padding: var(--spacing-md);\n margin-bottom: var(--spacing-md);\n width: 100%;\n max-width: 100%;\n box-sizing: border-box;\n}\n\n.profileHeader {\n text-align: center;\n margin-bottom: var(--spacing-md);\n}\n\n@media (min-width: 900px) {\n .profileSection {\n margin-bottom: 0;\n }\n}\n\n\n/* Override solid-ui error message close button styling */\n.errorMessageBlock .close,\n.errorMessageBlock button[type="button"],\n.errorMessageBlock .button {\n background: var(--border-light) !important;\n color: var(--text-color) !important;\n border: 1px solid var(--border-light) !important;\n}\n\n.errorMessageBlock .close:hover,\n.errorMessageBlock button[type="button"]:hover,\n.errorMessageBlock .button:hover {\n background: var(--text-secondary) !important;\n color: var(--background-color) !important;\n}\n\n/* --- Utility-first CSS classes (migrated from utilities.css) --- */\n.flex {\n display: flex;\n}\n.grid {\n display: grid;\n}\n\n/* Spacing utilities using CSS variables */\n.gap-xs { gap: var(--spacing-xs); }\n.gap-sm { gap: var(--spacing-sm); }\n.gap-md { gap: var(--spacing-md); }\n.gap-lg { gap: var(--spacing-lg); }\n.gap-xl { gap: var(--spacing-xl); }\n\n.mt-xs { margin-top: var(--spacing-xs); }\n.mt-sm { margin-top: var(--spacing-sm); }\n.mt-md { margin-top: var(--spacing-md); }\n.mt-lg { margin-top: var(--spacing-lg); }\n\n.mb-xs { margin-bottom: var(--spacing-xs); }\n.mb-sm { margin-bottom: var(--spacing-sm); }\n.mb-md { margin-bottom: var(--spacing-md); }\n.mb-lg { margin-bottom: var(--spacing-lg); }\n\n.p-xs { padding: var(--spacing-xs); }\n.p-sm { padding: var(--spacing-sm); }\n.p-md { padding: var(--spacing-md); }\n.p-lg { padding: var(--spacing-lg); }\n\n.rounded { border-radius: var(--border-radius); }\n.rounded-sm { border-radius: var(--border-radius-sm); }\n\n.shadow { box-shadow: var(--box-shadow); }\n.shadow-sm { box-shadow: var(--box-shadow-sm); }\n\n.bg-primary {\n background: var(--primary-color);\n color: #fff;\n}\n.bg-card {\n background: var(--card-bg);\n}\n\n/* Accessibility utilities */\n.sr-only {\n position: absolute;\n width: 1px;\n height: 1px;\n padding: 0;\n margin: -1px;\n overflow: hidden;\n clip: rect(0, 0, 0, 0);\n white-space: nowrap;\n border: 0;\n}\n\n.min-touch-target {\n min-height: var(--min-touch-target);\n min-width: var(--min-touch-target);\n}\n\n/* Enhanced accessibility utilities */\n.visually-hidden {\n position: absolute !important;\n width: 1px !important;\n height: 1px !important;\n padding: 0 !important;\n margin: -1px !important;\n overflow: hidden !important;\n clip: rect(0, 0, 0, 0) !important;\n white-space: nowrap !important;\n border: 0 !important;\n}\n\n.visually-hidden.focusable:focus,\n.visually-hidden.focusable:active {\n position: static !important;\n width: auto !important;\n height: auto !important;\n padding: inherit !important;\n margin: inherit !important;\n overflow: visible !important;\n clip: auto !important;\n white-space: inherit !important;\n}\n\n/* Skip links utility */\n.skip-links {\n position: absolute;\n top: -100px;\n left: 0;\n z-index: 1000;\n}\n\n.skip-links a {\n position: absolute;\n left: 6px;\n top: 6px;\n padding: var(--spacing-sm);\n background: var(--primary-color);\n color: white;\n text-decoration: none;\n border-radius: var(--border-radius-sm);\n}\n\n.skip-links a:focus {\n top: 6px;\n}\n\n/* Color contrast utilities */\n.high-contrast {\n background: white;\n color: black;\n border: 2px solid black;\n}\n\n.reduced-motion {\n animation: none !important;\n transition: none !important;\n}\n\n/* Focus management */\n.focus-ring {\n outline: 2px solid var(--primary-color);\n outline-offset: 2px;\n}\n\n.no-focus-ring {\n outline: none;\n}\n\n/* ARIA live regions */\n.live-region {\n position: absolute;\n left: -10000px;\n width: 1px;\n height: 1px;\n overflow: hidden;\n}\n\n/* Text scaling utilities */\n.text-scale-friendly {\n line-height: 1.5;\n max-width: 70ch; /* Optimal reading length */\n}\n\n/* Text accessibility utilities */\n.text-readable {\n line-height: var(--line-height-base);\n max-width: 65ch;\n}\n\n.text-large {\n font-size: var(--font-size-lg);\n line-height: var(--line-height-base);\n}\n\n.text-small {\n font-size: max(var(--font-size-sm), var(--min-font-size));\n line-height: var(--min-line-height);\n}\n\n.text-contrast-high {\n color: var(--text-color);\n font-weight: 600;\n}\n\n/* Better focus for text elements */\n.focusable-text:focus {\n background-color: rgba(124, 77, 255, 0.1);\n outline: 2px solid var(--primary-color);\n outline-offset: 2px;\n border-radius: 2px;\n}\n\n/* High contrast text */\n.high-contrast {\n color: var(--text-color);\n background: var(--background-color);\n border: 1px solid var(--border-light);\n}';class U extends HTMLElement{constructor(){super(),this.shadow=this.attachShadow({mode:"open"})}async connectedCallback(){let e=null,t=null,i="undefined"!=typeof CSSStyleSheet&&!0;try{i&&(e=new CSSStyleSheet,e.replaceSync(O),U.sheet||(U.sheet=new CSSStyleSheet,U.sheet.replaceSync(n)),t=U.sheet)}catch(n){e=null,t=null}if("adoptedStyleSheets"in Document.prototype&&e&&t)this.shadow.adoptedStyleSheets=[e,t];else{{const n=document.createElement("style");n.textContent=O,this.shadow.appendChild(n)}{const e=document.createElement("style");e.textContent=n,this.shadow.appendChild(e)}}this.render()}render(){const n=this.cvData;if(!n)return;const{rolesByType:e,skills:t,languages:i}=n,r=e.FutureRole||[],o=e.CurrentRole||[],a=e.PastRole||[],s=t||[],l=i||[],d=Array.isArray(r)&&r.length>0,h=Array.isArray(o)&&o.length>0,p=Array.isArray(a)&&a.length>0,g=Array.isArray(s)&&s.length>0,m=Array.isArray(l)&&l.length>0;((n,e,t)=>{const i=t?.renderBefore??e;let r=i._$litPart$;if(void 0===r){const n=t?.renderBefore??null;i._$litPart$=r=new N(e.insertBefore(c(),n),n,void 0,t??{})}r._$AI(n)})(d||h||p||g||m?$`
68
2
  <div class="cardFrame">
69
3
  <article class="cvCard" aria-label="Professional Experience" data-testid="curriculum-vitae">
70
- ${hasFutureRole ? html `
4
+ ${d?$`
71
5
  <section class="cvSection" aria-labelledby="cv-future-heading">
72
6
  <h3 id="cv-future-heading">Future Roles</h3>
73
7
  <ul role="list" aria-label="Upcoming professional roles">
74
- ${renderRoles(futureRolesArr, true)}
8
+ ${L(r,!0)}
75
9
  </ul>
76
10
  </section>
77
- ` : ''}
78
- ${hasCurrentRole ? html `
11
+ `:""}
12
+ ${h?$`
79
13
  <section class="cvSection" aria-labelledby="cv-current-heading">
80
14
  <h3 id="cv-current-heading">Current Roles</h3>
81
15
  <ul role="list" aria-label="Current professional positions">
82
- ${renderRoles(currentRolesArr, true)}
16
+ ${L(o,!0)}
83
17
  </ul>
84
18
  </section>
85
- ` : ''}
86
- ${hasPastRole ? html `
19
+ `:""}
20
+ ${p?$`
87
21
  <section class="cvSection" aria-labelledby="cv-past-heading">
88
22
  <h3 id="cv-past-heading">Past Roles</h3>
89
23
  <ul role="list" aria-label="Previous work experience">
90
- ${renderRoles(pastRolesArr, true)}
24
+ ${L(a,!0)}
91
25
  </ul>
92
26
  </section>
93
- ` : ''}
94
- ${hasSkills ? html `
27
+ `:""}
28
+ ${g?$`
95
29
  <section class="cvSection" aria-labelledby="cv-skills-heading">
96
30
  <h3 id="cv-skills-heading">Skills</h3>
97
31
  <ul role="list" aria-label="Professional skills and competencies">
98
- ${renderSkills(skillsArr, true)}
32
+ ${P(s,!0)}
99
33
  </ul>
100
34
  </section>
101
- ` : ''}
102
- ${hasLanguages ? html `
35
+ `:""}
36
+ ${m?$`
103
37
  <section class="cvSection" aria-labelledby="cv-languages-heading">
104
38
  <h3 id="cv-languages-heading">Languages</h3>
105
39
  <ul role="list" aria-label="Known languages">
106
- ${renderLanguages(languagesArr, true)}
40
+ ${D(l,!0)}
107
41
  </ul>
108
42
  </section>
109
- ` : ''}
43
+ `:""}
110
44
  </article>
111
45
  </div>
112
- `, this.shadow);
113
- }
114
- get cvData() {
115
- return this._cvData;
116
- }
117
- set cvData(val) {
118
- this._cvData = val;
119
- this.render();
120
- }
121
- }
122
- CVCardElement.sheet = null;
123
- customElements.define('cv-card', CVCardElement);
124
- function renderRoles(roles, asList = false) {
125
- if (!roles || !roles.length || !roles[0])
126
- return html ``;
127
- return html `${renderRole(roles[0], asList)}${roles.length > 1 ? renderRoles(roles.slice(1), asList) : html ``}`;
128
- }
129
- function renderRole(role, asList = false) {
130
- if (!role)
131
- return html ``;
132
- return asList
133
- ? html `
46
+ `:$``,this.shadow)}get cvData(){return this._cvData}set cvData(n){this._cvData=n,this.render()}}function L(n,e=!1){return n&&n.length&&n[0]?$`${function(n,e=!1){return n&&e?$`
134
47
  <li class="cvRole" role="listitem">
135
- <strong class="cvOrg" aria-label="Organization">${role.orgName}</strong>
136
- <span aria-label="Role title">${strToUpperCase(role.roleText)}</span>
137
- <time aria-label="Employment period">${role.dates}</time>
138
- </li>`
139
- : html ``;
140
- }
141
- function renderSkill(skill, asList = false) {
142
- if (!skill)
143
- return html ``;
144
- return asList
145
- ? html `<li class="cvSkill">${strToUpperCase(skill)}</li>`
146
- : html ``;
147
- }
148
- function renderSkills(skills, asList = false) {
149
- if (!skills || !skills.length || !skills[0])
150
- return html ``;
151
- return html `${renderSkill(skills[0], asList)}${skills.length > 1 ? renderSkills(skills.slice(1), asList) : html ``}`;
152
- }
153
- function renderLan(language, asList = false) {
154
- if (!language)
155
- return html ``;
156
- return asList
157
- ? html `<li class="cvLanguage">${language}</li>`
158
- : html ``;
159
- }
160
- function renderLanguages(languages, asList = false) {
161
- if (!languages || !languages.length || !languages[0])
162
- return html ``;
163
- return html `${renderLan(languages[0], asList)}${languages.length > 1 ? renderLanguages(languages.slice(1), asList) : html ``}`;
164
- }
165
- function strToUpperCase(str) {
166
- if (str && str[0] > '') {
167
- const strCase = str.split(' ');
168
- for (let i = 0; i < strCase.length; i++) {
169
- strCase[i] = strCase[i].charAt(0).toUpperCase() +
170
- strCase[i].substring(1);
171
- }
172
- return strCase.join(' ');
173
- }
174
- return '';
175
- }
176
- //# sourceMappingURL=CVCardElement.js.map
48
+ <strong class="cvOrg" aria-label="Organization">${n.orgName}</strong>
49
+ <span aria-label="Role title">${W(n.roleText)}</span>
50
+ <time aria-label="Employment period">${n.dates}</time>
51
+ </li>`:$``}(n[0],e)}${n.length>1?L(n.slice(1),e):$``}`:$``}function P(n,e=!1){return n&&n.length&&n[0]?$`${function(n,e=!1){return n&&e?$`<li class="cvSkill">${W(n)}</li>`:$``}(n[0],e)}${n.length>1?P(n.slice(1),e):$``}`:$``}function D(n,e=!1){return n&&n.length&&n[0]?$`${function(n,e=!1){return n&&e?$`<li class="cvLanguage">${n}</li>`:$``}(n[0],e)}${n.length>1?D(n.slice(1),e):$``}`:$``}function W(n){if(n&&n[0]>""){const e=n.split(" ");for(let n=0;n<e.length;n++)e[n]=e[n].charAt(0).toUpperCase()+e[n].substring(1);return e.join(" ")}return""}U.sheet=null,customElements.define("cv-card",U)})();
@@ -1,87 +1 @@
1
- import { Namespace } from 'rdflib';
2
- import { ns, utils } from 'solid-ui';
3
- const ORG = Namespace('http://www.w3.org/ns/org#');
4
- export const typesOfRole = ['PastRole', 'CurrentRole', 'FutureRole'];
5
- export function skillAsText(store, sk) {
6
- if (sk.termType === 'Literal')
7
- return sk.value; // Not normal but allow this
8
- const publicId = store.anyJS(sk, ns.solid('publicId'));
9
- if (publicId) {
10
- const name = store.anyJS(publicId, ns.schema('name'));
11
- if (name)
12
- return name; // @@ check language and get name in diff language if necessary
13
- }
14
- const manual = store.anyJS(sk, ns.vcard('role'));
15
- if (manual && manual[0] > '')
16
- return manual;
17
- return '¿¿¿ skill ???';
18
- }
19
- export function languageAsText(store, lan) {
20
- if (lan.termType === 'Literal')
21
- return lan.value; // Not normal but allow this
22
- const publicId = store.anyJS(lan, ns.solid('publicId'));
23
- if (publicId)
24
- return utils.label(publicId, true); // @@ check language and get name in diff language if necessary
25
- return '-';
26
- }
27
- export function datesAsText(startDate, endDate) {
28
- return startDate ? '(' + startDate.value.slice(0, 10) + ' to ' +
29
- (endDate ? endDate.value.slice(0, 10) : '') + ')'
30
- : '';
31
- }
32
- function getRolesByType(store, subject) {
33
- const memberships = store.each(null, ORG('member'), subject, null);
34
- const rolesByType = { PastRole: [], CurrentRole: [], FutureRole: [] };
35
- for (const membership of memberships) {
36
- let orgHomePage, orgNameGiven, publicIdName, roleName, publicId;
37
- // Things should have start dates but we will be very lenient in this view
38
- const startDate = store.any(membership, ns.schema('startDate'));
39
- const endDate = store.any(membership, ns.schema('endDate'));
40
- const dates = datesAsText(startDate, endDate);
41
- const organization = store.any(membership, ORG('organization'));
42
- if (organization) {
43
- orgNameGiven = store.anyJS(organization, ns.schema('name'));
44
- orgHomePage = store.any(organization, ns.schema('uri'));
45
- publicId = store.any(organization, ns.solid('publicId'));
46
- }
47
- if (publicId) {
48
- publicIdName = store.anyJS(publicId, ns.schema('name'));
49
- }
50
- const orgName = publicIdName || orgNameGiven;
51
- const escoRole = store.any(membership, ORG('role'));
52
- if (escoRole) {
53
- roleName = store.anyJS(escoRole, ns.schema('name'));
54
- }
55
- const roleText0 = store.anyJS(membership, ns.vcard('role'));
56
- const roleText = (roleText0 && roleName) ? roleName + ' - ' + roleText0
57
- : roleText0 || roleName;
58
- const item = {
59
- startDate: startDate, endDate, orgName, roleText, dates, orgHomePage
60
- };
61
- for (const t of typesOfRole) {
62
- if (store.holds(membership, ns.rdf('type'), ns.solid(t))) {
63
- rolesByType[t].push(item);
64
- }
65
- }
66
- }
67
- return rolesByType;
68
- }
69
- export function presentCV(subject, store) {
70
- const rolesByType = getRolesByType(store, subject);
71
- // Most recent thing most relevant -> sort by end date
72
- for (const t of typesOfRole) {
73
- rolesByType[t].sort(function (x, y) {
74
- if (x.endDate && y.endDate) {
75
- return x.endDate > y.endDate ? -1 : 1;
76
- }
77
- return x.startDate > y.startDate ? -1 : 1;
78
- });
79
- }
80
- const skills = store.each(subject, ns.schema('skills')).map(sk => skillAsText(store, sk));
81
- const languagesInStore = store.anyJS(subject, ns.schema('knowsLanguage'));
82
- let languages = [];
83
- if (languagesInStore)
84
- languages = languagesInStore.map(lan => languageAsText(store, lan));
85
- return { rolesByType, skills, languages };
86
- }
87
- //# sourceMappingURL=CVPresenter.js.map
1
+ (()=>{"use strict";var r={2511:r=>{r.exports=$rdf},8077:r=>{r.exports=UI}},e={};function t(o){var a=e[o];if(void 0!==a)return a.exports;var p=e[o]={exports:{}};return r[o](p,p.exports,t),p.exports}t.n=r=>{var e=r&&r.__esModule?()=>r.default:()=>r;return t.d(e,{a:e}),e},t.d=(r,e)=>{for(var o in e)t.o(e,o)&&!t.o(r,o)&&Object.defineProperty(r,o,{enumerable:!0,get:e[o]})},t.o=(r,e)=>Object.prototype.hasOwnProperty.call(r,e);var o=t(2511);t(8077),(0,o.Namespace)("http://www.w3.org/ns/org#")})();
@@ -1,157 +1,5 @@
1
- import chatWithMeCss from './styles/ChatWithMe.css';
2
- import { html, render } from 'lit-html';
3
- import { widgets } from 'solid-ui';
4
- import { authn } from 'solid-logic';
5
- import { chatWithMeButtonText, logInToChatWithMeButtonText, loadingMessage } from './texts';
6
- import { checkIfAnyUserLoggedIn, complain } from './buttonsHelper';
7
- import globalCssText from './styles/global.css';
8
- class ChatWithMeElement extends HTMLElement {
9
- constructor() {
10
- super();
11
- this.shadow = this.attachShadow({ mode: 'open' });
12
- }
13
- async connectedCallback() {
14
- let globalSheet = null;
15
- let cardSheet = null;
16
- let canUseSheets = typeof CSSStyleSheet !== 'undefined' && typeof globalCssText === 'string' && typeof chatWithMeCss === 'string';
17
- try {
18
- if (canUseSheets) {
19
- globalSheet = new CSSStyleSheet();
20
- globalSheet.replaceSync(globalCssText);
21
- if (!ChatWithMeElement.sheet) {
22
- ChatWithMeElement.sheet = new CSSStyleSheet();
23
- ChatWithMeElement.sheet.replaceSync(chatWithMeCss);
24
- }
25
- cardSheet = ChatWithMeElement.sheet;
26
- }
27
- }
28
- catch (e) {
29
- globalSheet = null;
30
- cardSheet = null;
31
- }
32
- if ('adoptedStyleSheets' in Document.prototype && globalSheet && cardSheet) {
33
- this.shadow.adoptedStyleSheets = [globalSheet, cardSheet];
34
- }
35
- else {
36
- // Fallback for browsers or test environments without adoptedStyleSheets or CSSStyleSheet
37
- if (typeof globalCssText === 'string') {
38
- const styleGlobal = document.createElement('style');
39
- styleGlobal.textContent = globalCssText;
40
- this.shadow.appendChild(styleGlobal);
41
- }
42
- if (typeof chatWithMeCss === 'string') {
43
- const styleCard = document.createElement('style');
44
- styleCard.textContent = chatWithMeCss;
45
- this.shadow.appendChild(styleCard);
46
- }
47
- }
48
- this.render();
49
- }
50
- render() {
51
- const self = this;
52
- const subject = self.subject;
53
- const context = self.context;
54
- if (!subject || !context) {
55
- render(html ``, self.shadow);
56
- return;
57
- }
58
- const logic = context.session.logic;
59
- const longChatPane = context.session.paneRegistry.byName('long chat');
60
- const frame = document.createElement('div');
61
- frame.setAttribute('class', 'cardFrame');
62
- const chatContainer = document.createElement('div');
63
- chatContainer.setAttribute('class', 'chatSection');
64
- chatContainer.setAttribute('aria-labelledby', 'chat-section-title');
65
- chatContainer.setAttribute('role', 'region');
66
- chatContainer.setAttribute('data-testid', 'chat');
67
- const title = document.createElement('h3');
68
- title.id = 'chat-section-title';
69
- title.className = 'sr-only';
70
- title.textContent = 'Communication';
71
- chatContainer.appendChild(title);
72
- let exists;
73
- (async () => {
74
- try {
75
- render(html `
1
+ (()=>{"use strict";var n={728:(n,t,e)=>{e.d(t,{Eo:()=>i,e_:()=>r,m7:()=>o});const i="Loading...",r="Login to chat with me",o="Chat with me"},7037:(n,t,e)=>{e.d(t,{S:()=>o,cc:()=>r});var i=e(8077);function r(n,t,e){const r=i.widgets.errorMessageBlock(t.dom,e);r.setAttribute("role","alert"),r.setAttribute("aria-live","assertive"),r.setAttribute("tabindex","0"),setTimeout(()=>{r.focus()},100),n.appendChild(r)}function o(n){return!!n}},8077:n=>{n.exports=UI}},t={};function e(i){var r=t[i];if(void 0!==r)return r.exports;var o=t[i]={exports:{}};return n[i](o,o.exports,e),o.exports}e.n=n=>{var t=n&&n.__esModule?()=>n.default:()=>n;return e.d(t,{a:t}),t},e.d=(n,t)=>{for(var i in t)e.o(t,i)&&!e.o(n,i)&&Object.defineProperty(n,i,{enumerable:!0,get:t[i]})},e.o=(n,t)=>Object.prototype.hasOwnProperty.call(n,t);const i="/* Card frame for secondary background/border */\n\n.chatSection {\n display: flex;\n flex-direction: column;\n align-items: center;\n overflow-x: auto;\n}\n\n.chatSection div button {\n background-color: transparent;\n}\n\n.chatSection div button:hover {\n background-color: transparent;\n}\n\n.chatLoading {\n color: var(--primary-color);\n text-align: center;\n margin: var(--spacing-md) 0;\n}\n\n.chatSection button {\n min-height: var(--min-touch-target);\n padding: var(--spacing-sm) var(--spacing-md);\n border: 1px solid var(--primary-color);\n border-radius: var(--border-radius-sm);\n background: var(--primary-color);\n color: white;\n font-weight: 600;\n cursor: pointer;\n transition: all var(--animation-duration) ease;\n}\n\n.chatSection button:hover {\n background: color-mix(in srgb, var(--primary-color) 90%, black);\n box-shadow: 0 2px 4px rgba(124, 77, 255, 0.2);\n}\n\n.chatSection button:active {\n transform: translateY(0);\n box-shadow: 0 1px 2px rgba(124, 77, 255, 0.2);\n}\n\n.chatSection button:disabled {\n opacity: 0.6;\n cursor: not-allowed;\n transform: none;\n}\n",r=globalThis,o=r.trustedTypes,a=o?o.createPolicy("lit-html",{createHTML:n=>n}):void 0,s="$lit$",l=`lit$${Math.random().toFixed(9).slice(2)}$`,c="?"+l,d=`<${c}>`,p=document,h=()=>p.createComment(""),m=n=>null===n||"object"!=typeof n&&"function"!=typeof n,g=Array.isArray,u="[ \t\n\f\r]",b=/<(?:(!--|\/[^a-zA-Z])|(\/?[a-zA-Z][^>\s]*)|(\/?$))/g,f=/-->/g,v=/>/g,x=RegExp(`>|${u}(?:([^\\s"'>=/]+)(${u}*=${u}*(?:[^ \t\n\f\r"'\`<>=]|("|')|))|$)`,"g"),y=/'/g,A=/"/g,$=/^(?:script|style|textarea|title)$/i,_=n=>(t,...e)=>({_$litType$:n,strings:t,values:e}),w=_(1),k=(_(2),_(3),Symbol.for("lit-noChange")),C=Symbol.for("lit-nothing"),S=new WeakMap,H=p.createTreeWalker(p,129);function T(n,t){if(!g(n)||!n.hasOwnProperty("raw"))throw Error("invalid template strings array");return void 0!==a?a.createHTML(t):t}const z=(n,t)=>{const e=n.length-1,i=[];let r,o=2===t?"<svg>":3===t?"<math>":"",a=b;for(let t=0;t<e;t++){const e=n[t];let c,p,h=-1,m=0;for(;m<e.length&&(a.lastIndex=m,p=a.exec(e),null!==p);)m=a.lastIndex,a===b?"!--"===p[1]?a=f:void 0!==p[1]?a=v:void 0!==p[2]?($.test(p[2])&&(r=RegExp("</"+p[2],"g")),a=x):void 0!==p[3]&&(a=x):a===x?">"===p[0]?(a=r??b,h=-1):void 0===p[1]?h=-2:(h=a.lastIndex-p[2].length,c=p[1],a=void 0===p[3]?x:'"'===p[3]?A:y):a===A||a===y?a=x:a===f||a===v?a=b:(a=x,r=void 0);const g=a===x&&n[t+1].startsWith("/>")?" ":"";o+=a===b?e+d:h>=0?(i.push(c),e.slice(0,h)+s+e.slice(h)+l+g):e+l+(-2===h?t:g)}return[T(n,o+(n[e]||"<?>")+(2===t?"</svg>":3===t?"</math>":"")),i]};class M{constructor({strings:n,_$litType$:t},e){let i;this.parts=[];let r=0,a=0;const d=n.length-1,p=this.parts,[m,g]=z(n,t);if(this.el=M.createElement(m,e),H.currentNode=this.el.content,2===t||3===t){const n=this.el.content.firstChild;n.replaceWith(...n.childNodes)}for(;null!==(i=H.nextNode())&&p.length<d;){if(1===i.nodeType){if(i.hasAttributes())for(const n of i.getAttributeNames())if(n.endsWith(s)){const t=g[a++],e=i.getAttribute(n).split(l),o=/([.?@])?(.*)/.exec(t);p.push({type:1,index:r,name:o[2],strings:e,ctor:"."===o[1]?I:"?"===o[1]?U:"@"===o[1]?L:B}),i.removeAttribute(n)}else n.startsWith(l)&&(p.push({type:6,index:r}),i.removeAttribute(n));if($.test(i.tagName)){const n=i.textContent.split(l),t=n.length-1;if(t>0){i.textContent=o?o.emptyScript:"";for(let e=0;e<t;e++)i.append(n[e],h()),H.nextNode(),p.push({type:2,index:++r});i.append(n[t],h())}}}else if(8===i.nodeType)if(i.data===c)p.push({type:2,index:r});else{let n=-1;for(;-1!==(n=i.data.indexOf(l,n+1));)p.push({type:7,index:r}),n+=l.length-1}r++}}static createElement(n,t){const e=p.createElement("template");return e.innerHTML=n,e}}function N(n,t,e=n,i){if(t===k)return t;let r=void 0!==i?e._$Co?.[i]:e._$Cl;const o=m(t)?void 0:t._$litDirective$;return r?.constructor!==o&&(r?._$AO?.(!1),void 0===o?r=void 0:(r=new o(n),r._$AT(n,e,i)),void 0!==i?(e._$Co??=[])[i]=r:e._$Cl=r),void 0!==r&&(t=N(n,r._$AS(n,t.values),r,i)),t}class E{constructor(n,t){this._$AV=[],this._$AN=void 0,this._$AD=n,this._$AM=t}get parentNode(){return this._$AM.parentNode}get _$AU(){return this._$AM._$AU}u(n){const{el:{content:t},parts:e}=this._$AD,i=(n?.creationScope??p).importNode(t,!0);H.currentNode=i;let r=H.nextNode(),o=0,a=0,s=e[0];for(;void 0!==s;){if(o===s.index){let t;2===s.type?t=new F(r,r.nextSibling,this,n):1===s.type?t=new s.ctor(r,s.name,s.strings,this,n):6===s.type&&(t=new j(r,this,n)),this._$AV.push(t),s=e[++a]}o!==s?.index&&(r=H.nextNode(),o++)}return H.currentNode=p,i}p(n){let t=0;for(const e of this._$AV)void 0!==e&&(void 0!==e.strings?(e._$AI(n,e,t),t+=e.strings.length-2):e._$AI(n[t])),t++}}class F{get _$AU(){return this._$AM?._$AU??this._$Cv}constructor(n,t,e,i){this.type=2,this._$AH=C,this._$AN=void 0,this._$AA=n,this._$AB=t,this._$AM=e,this.options=i,this._$Cv=i?.isConnected??!0}get parentNode(){let n=this._$AA.parentNode;const t=this._$AM;return void 0!==t&&11===n?.nodeType&&(n=t.parentNode),n}get startNode(){return this._$AA}get endNode(){return this._$AB}_$AI(n,t=this){n=N(this,n,t),m(n)?n===C||null==n||""===n?(this._$AH!==C&&this._$AR(),this._$AH=C):n!==this._$AH&&n!==k&&this._(n):void 0!==n._$litType$?this.$(n):void 0!==n.nodeType?this.T(n):(n=>g(n)||"function"==typeof n?.[Symbol.iterator])(n)?this.k(n):this._(n)}O(n){return this._$AA.parentNode.insertBefore(n,this._$AB)}T(n){this._$AH!==n&&(this._$AR(),this._$AH=this.O(n))}_(n){this._$AH!==C&&m(this._$AH)?this._$AA.nextSibling.data=n:this.T(p.createTextNode(n)),this._$AH=n}$(n){const{values:t,_$litType$:e}=n,i="number"==typeof e?this._$AC(n):(void 0===e.el&&(e.el=M.createElement(T(e.h,e.h[0]),this.options)),e);if(this._$AH?._$AD===i)this._$AH.p(t);else{const n=new E(i,this),e=n.u(this.options);n.p(t),this.T(e),this._$AH=n}}_$AC(n){let t=S.get(n.strings);return void 0===t&&S.set(n.strings,t=new M(n)),t}k(n){g(this._$AH)||(this._$AH=[],this._$AR());const t=this._$AH;let e,i=0;for(const r of n)i===t.length?t.push(e=new F(this.O(h()),this.O(h()),this,this.options)):e=t[i],e._$AI(r),i++;i<t.length&&(this._$AR(e&&e._$AB.nextSibling,i),t.length=i)}_$AR(n=this._$AA.nextSibling,t){for(this._$AP?.(!1,!0,t);n!==this._$AB;){const t=n.nextSibling;n.remove(),n=t}}setConnected(n){void 0===this._$AM&&(this._$Cv=n,this._$AP?.(n))}}class B{get tagName(){return this.element.tagName}get _$AU(){return this._$AM._$AU}constructor(n,t,e,i,r){this.type=1,this._$AH=C,this._$AN=void 0,this.element=n,this.name=t,this._$AM=i,this.options=r,e.length>2||""!==e[0]||""!==e[1]?(this._$AH=Array(e.length-1).fill(new String),this.strings=e):this._$AH=C}_$AI(n,t=this,e,i){const r=this.strings;let o=!1;if(void 0===r)n=N(this,n,t,0),o=!m(n)||n!==this._$AH&&n!==k,o&&(this._$AH=n);else{const i=n;let a,s;for(n=r[0],a=0;a<r.length-1;a++)s=N(this,i[e+a],t,a),s===k&&(s=this._$AH[a]),o||=!m(s)||s!==this._$AH[a],s===C?n=C:n!==C&&(n+=(s??"")+r[a+1]),this._$AH[a]=s}o&&!i&&this.j(n)}j(n){n===C?this.element.removeAttribute(this.name):this.element.setAttribute(this.name,n??"")}}class I extends B{constructor(){super(...arguments),this.type=3}j(n){this.element[this.name]=n===C?void 0:n}}class U extends B{constructor(){super(...arguments),this.type=4}j(n){this.element.toggleAttribute(this.name,!!n&&n!==C)}}class L extends B{constructor(n,t,e,i,r){super(n,t,e,i,r),this.type=5}_$AI(n,t=this){if((n=N(this,n,t,0)??C)===k)return;const e=this._$AH,i=n===C&&e!==C||n.capture!==e.capture||n.once!==e.once||n.passive!==e.passive,r=n!==C&&(e===C||i);i&&this.element.removeEventListener(this.name,this,e),r&&this.element.addEventListener(this.name,this,n),this._$AH=n}handleEvent(n){"function"==typeof this._$AH?this._$AH.call(this.options?.host??this.element,n):this._$AH.handleEvent(n)}}class j{constructor(n,t,e){this.element=n,this.type=6,this._$AN=void 0,this._$AM=t,this.options=e}get _$AU(){return this._$AM._$AU}_$AI(n){N(this,n)}}const R=r.litHtmlPolyfillSupport;R?.(M,F),(r.litHtmlVersions??=[]).push("3.3.1");const O=(n,t,e)=>{const i=e?.renderBefore??t;let r=i._$litPart$;if(void 0===r){const n=e?.renderBefore??null;i._$litPart$=r=new F(t.insertBefore(h(),n),n,void 0,e??{})}return r._$AI(n),r};var W=e(8077);const P=SolidLogic;var D=e(728),G=e(7037);const V='/* Generic profile table styles */\n.profileTable {\n width: 100%;\n border-collapse: collapse;\n margin-bottom: var(--spacing-md);\n}\n.profileTable caption {\n padding: var(--spacing-sm);\n text-align: left;\n color: var(--text-color);\n}\n.profileTable th,\n.profileTable td {\n padding: var(--spacing-sm) var(--spacing-md);\n text-align: left;\n line-height: 1.4;\n}\n.profileTable td {\n background: var(--card-internal-bg);\n}\n.profileTable tbody tr:nth-child(even) {\n background-color: rgba(0, 0, 0, 0.02);\n}\n/* Card frame for secondary background/border */\n.cardFrame {\n background: var(--card-frame-bg, #f8f9fa);\n border: 2px solid var(--card-frame-border, #e0e0e0);\n border-radius: 18px;\n box-shadow: 0 4px 16px rgba(0,0,0,0.08);\n padding: 18px;\n margin: 12px 0;\n}\n/* Global CSS: base styles, variables, and resets */\n\n.center {\n display: flex;\n justify-content: center;\n align-items: center;\n}\n\n/* Accessible color palette */\n\n:host, :root {\n\n --primary-color: #7C4DFF; /* Vivid Purple */\n --secondary-color: #0077B6; /* Accessible Blue */\n --background-color: #FFFFFF; /* White */\n --card-bg: #FFFFFF; /* White for inner cards */\n --section-bg: #F5F5F5; /* Light grey for outer sections */\n --card-internal-bg: transparent; /* Transparent for internal components */\n --text-color: #1A1A1A; /* Near-black */\n --text-secondary: #666; /* Added for repeated usage */\n --text-muted: #444; /* Added for repeated usage */\n --border-light: #eee; /* Added for repeated borders */\n --accent-color: #FFD600; /* Bright Yellow */\n --error-color: #B00020; /* Accessible Red */\n --success-color: #00C853; /* Accessible Green */\n --border-radius: 1rem; /* Matches module usage */\n --border-radius-sm: 0.5rem;\n --box-shadow: 0 2px 8px rgba(124,77,255,0.08); /* Matches module usage */\n --box-shadow-sm: 0 1px 4px rgba(124,77,255,0.12);\n --spacing-xs: 0.5rem;\n --spacing-sm: 0.75rem;\n --spacing-md: 1rem;\n --spacing-lg: 1.5rem;\n --spacing-xl: 2rem;\n --font-family: \'Inter\', -apple-system, BlinkMacSystemFont, \'Segoe UI\', Roboto, Oxygen, Ubuntu, Cantarell, sans-serif;\n --font-size-base: 1rem; /* 16px default */\n --font-size-sm: 0.875rem; /* 14px */\n --font-size-lg: 1.125rem; /* 18px */\n --font-size-xl: 1.25rem; /* 20px */\n --line-height-base: 1.5; /* WCAG recommended */\n --line-height-tight: 1.4;\n --line-height-loose: 1.6;\n --letter-spacing-wide: 0.025em;\n\n /* Minimum font sizes for accessibility */\n --min-font-size: 14px;\n --min-line-height: 1.4;\n\n /* Accessibility improvements */\n --min-touch-target: 44px; /* WCAG minimum touch target */\n --focus-ring-width: 2px;\n --animation-duration: 0.2s; /* Reduced motion friendly */\n\n /* Additional accessibility variables */\n --focus-indicator-width: 3px;\n --animation-duration-slow: 0.3s;\n --high-contrast-ratio: 7:1; /* WCAG AAA standard */\n}\n\n/* Improve text rendering */\nhtml, body {\n margin: 0;\n padding: 0;\n font-family: var(--font-family);\n font-size: var(--font-size-base);\n line-height: var(--line-height-base);\n background: var(--background-color);\n color: var(--text-color);\n -webkit-font-smoothing: antialiased;\n -moz-osx-font-smoothing: grayscale;\n text-rendering: optimizeLegibility;\n}\n\n/* Improved heading hierarchy */\nh1, h2, h3, h4, h5, h6 {\n color: var(--primary-color);\n font-weight: 600;\n line-height: var(--line-height-tight);\n margin-top: 0;\n margin-bottom: var(--spacing-sm);\n}\n\nh2 {\n text-align: center;\n}\n\nh1 { font-size: 2rem; } /* 32px */\nh2 { font-size: 1.5rem; } /* 24px */\nh3 { font-size: 1.25rem; } /* 20px */\nh4 { font-size: 1.125rem; }/* 18px */\nh5, h6 { font-size: 1rem; }/* 16px */\n\n/* Better paragraph spacing */\np {\n margin-bottom: var(--spacing-md);\n line-height: var(--line-height-base);\n max-width: 65ch; /* Optimal reading width */\n}\n\n/* Improved link accessibility */\na {\n color: var(--primary-color);\n text-decoration: underline;\n text-underline-offset: 0.125em;\n text-decoration-thickness: 0.0625em;\n}\n\na:hover, a:focus {\n text-decoration-thickness: 0.125em;\n}\n\n/* Ensure minimum font sizes are respected */\n@media screen and (max-width: 768px) {\n html {\n font-size: max(16px, 1rem); /* Never smaller than 16px on mobile */\n }\n}\n\n/* Support for larger text preferences */\n@media (prefers-reduced-motion: no-preference) {\n html {\n scroll-behavior: smooth;\n }\n}\n\n/* Accessibility: focus styles */\n:focus {\n outline: 2px solid var(--primary-color);\n outline-offset: 1px;\n box-shadow: 0 0 0 1px var(--background-color);\n}\n\n/* Accessibility: Respect user motion preferences */\n@media (prefers-reduced-motion: reduce) {\n *, *::before, *::after {\n animation-duration: 0.01ms !important;\n animation-iteration-count: 1 !important;\n transition-duration: 0.01ms !important;\n scroll-behavior: auto !important;\n }\n}\n\n/* Accessibility: High contrast mode support */\n@media (prefers-contrast: high) {\n :root {\n --border-light: #000;\n --box-shadow: 0 2px 4px rgba(0,0,0,0.5);\n --box-shadow-sm: 0 1px 2px rgba(0,0,0,0.3);\n }\n}\n\n/* Accessibility: Improved focus management */\n:focus-visible {\n outline: var(--focus-ring-width) solid var(--primary-color);\n outline-offset: 2px;\n box-shadow: 0 0 0 1px var(--background-color);\n}\n\n:focus:not(:focus-visible) {\n outline: none;\n}\n\n/* Skip link for screen readers */\n.skip-link {\n position: absolute;\n top: -40px;\n left: 6px;\n background: var(--primary-color);\n color: white;\n padding: var(--spacing-sm) var(--spacing-md);\n text-decoration: none;\n border-radius: var(--border-radius-sm);\n z-index: 1000;\n font-weight: 600;\n font-size: var(--font-size-base);\n line-height: 1;\n}\n\n.skip-link:focus {\n top: 6px;\n outline: 2px solid white;\n outline-offset: 2px;\n}\n\n/* Semantic HTML5 improvements */\narticle, aside, section {\n display: block;\n}\n\nheader {\n margin-bottom: var(--spacing-md);\n}\n\nnav {\n display: block;\n}\n\nnav ul {\n list-style: none;\n padding: 0;\n margin: 0;\n}\n\n/* Enhanced keyboard navigation */\n*:focus-visible {\n outline: var(--focus-indicator-width) solid var(--primary-color);\n outline-offset: 2px;\n box-shadow: 0 0 0 1px var(--background-color), 0 0 0 4px rgba(124, 77, 255, 0.2);\n border-radius: 2px;\n transition: none; /* Remove transitions on focus for immediate feedback */\n}\n\n/* Improve focus management for interactive elements */\n[role="button"]:focus,\n[role="link"]:focus,\nbutton:focus,\na:focus {\n outline: 2px solid var(--primary-color);\n outline-offset: 2px;\n box-shadow: 0 0 0 1px var(--background-color);\n}\n\n/* Enhanced error message accessibility */\n[role="alert"] {\n padding: var(--spacing-md);\n border: 2px solid var(--error-color);\n border-radius: var(--border-radius-sm);\n background-color: rgba(176, 0, 32, 0.1);\n margin: var(--spacing-md) 0;\n}\n\n/* Success message styling */\n[role="status"] {\n padding: var(--spacing-md);\n border: 2px solid var(--success-color);\n border-radius: var(--border-radius-sm);\n background-color: rgba(0, 200, 83, 0.1);\n margin: var(--spacing-md) 0;\n}\n\n/* Enhanced table accessibility */\ntable {\n border-collapse: collapse;\n width: 100%;\n}\n\nth {\n font-weight: 600;\n text-align: left;\n padding: var(--spacing-sm);\n}\n\ntd {\n padding: var(--spacing-sm);\n}\n\n/* Focus trap for modals */\n.focus-trap {\n position: fixed;\n top: 0;\n left: 0;\n width: 100%;\n height: 100%;\n z-index: 9999;\n background: rgba(0, 0, 0, 0.5);\n display: flex;\n justify-content: center;\n align-items: center;\n}\n\n/* Enhanced button accessibility */\nbutton, [role="button"] {\n cursor: pointer;\n border: none;\n border-radius: var(--border-radius-sm);\n padding: var(--spacing-sm) var(--spacing-md);\n min-height: var(--min-touch-target);\n min-width: var(--min-touch-target);\n font-size: var(--font-size-base);\n font-weight: 600;\n transition: all var(--animation-duration) ease;\n position: relative;\n}\n\nbutton:disabled, [role="button"][aria-disabled="true"] {\n opacity: 0.6;\n cursor: not-allowed;\n pointer-events: none;\n}\n\n/* Loading indicator accessibility */\n.loading-spinner {\n width: 40px;\n height: 40px;\n border: 3px solid var(--border-light);\n border-top: 3px solid var(--primary-color);\n border-radius: 50%;\n animation: spin 1s linear infinite;\n}\n\n@keyframes spin {\n 0% { transform: rotate(0deg); }\n 100% { transform: rotate(360deg); }\n}\n\n@media (prefers-reduced-motion: reduce) {\n .loading-spinner {\n animation: none;\n border-top-color: var(--primary-color);\n }\n}\n\n/* Utility classes */\n.u-flex {\n display: flex;\n}\n.u-grid {\n display: grid;\n}\n.u-center {\n justify-content: center;\n align-items: center;\n}\n.u-gap {\n gap: 1em;\n}\n\n/* Common card component - used across all modules */\n.module-card {\n background: var(--card-bg);\n border-radius: var(--border-radius);\n box-shadow: var(--box-shadow);\n padding: var(--spacing-lg);\n margin-bottom: var(--spacing-lg);\n width: 100%;\n max-width: 100%;\n box-sizing: border-box;\n}\n\n/* Common header styles */\n.module-header {\n text-align: center;\n margin-bottom: var(--spacing-md);\n}\n\n/* Common flex patterns */\n.flex-center {\n display: flex;\n justify-content: center;\n align-items: center;\n}\n\n.flex-column {\n display: flex;\n flex-direction: column;\n}\n\n.flex-column-center {\n display: flex;\n flex-direction: column;\n align-items: center;\n}\n\n/* Text utilities */\n.text-center {\n text-align: center;\n}\n\n.text-secondary {\n color: var(--text-secondary);\n}\n\n.text-muted {\n color: var(--text-muted);\n}\n\n/* Responsive grid for profile */\n.profile-grid {\n display: grid;\n grid-template-columns: repeat(auto-fit, minmax(400px, 1fr));\n gap: 1.5em;\n background: var(--profile-grid-bg, var(--background-color));\n}\n.profile-header, .profile-footer {\n grid-column: 1 / -1;\n}\n\n.profileSection {\n background: var(--section-bg);\n border-radius: var(--border-radius);\n box-shadow: var(--box-shadow);\n padding: var(--spacing-md);\n margin-bottom: var(--spacing-md);\n width: 100%;\n max-width: 100%;\n box-sizing: border-box;\n}\n\n.profileHeader {\n text-align: center;\n margin-bottom: var(--spacing-md);\n}\n\n@media (min-width: 900px) {\n .profileSection {\n margin-bottom: 0;\n }\n}\n\n\n/* Override solid-ui error message close button styling */\n.errorMessageBlock .close,\n.errorMessageBlock button[type="button"],\n.errorMessageBlock .button {\n background: var(--border-light) !important;\n color: var(--text-color) !important;\n border: 1px solid var(--border-light) !important;\n}\n\n.errorMessageBlock .close:hover,\n.errorMessageBlock button[type="button"]:hover,\n.errorMessageBlock .button:hover {\n background: var(--text-secondary) !important;\n color: var(--background-color) !important;\n}\n\n/* --- Utility-first CSS classes (migrated from utilities.css) --- */\n.flex {\n display: flex;\n}\n.grid {\n display: grid;\n}\n\n/* Spacing utilities using CSS variables */\n.gap-xs { gap: var(--spacing-xs); }\n.gap-sm { gap: var(--spacing-sm); }\n.gap-md { gap: var(--spacing-md); }\n.gap-lg { gap: var(--spacing-lg); }\n.gap-xl { gap: var(--spacing-xl); }\n\n.mt-xs { margin-top: var(--spacing-xs); }\n.mt-sm { margin-top: var(--spacing-sm); }\n.mt-md { margin-top: var(--spacing-md); }\n.mt-lg { margin-top: var(--spacing-lg); }\n\n.mb-xs { margin-bottom: var(--spacing-xs); }\n.mb-sm { margin-bottom: var(--spacing-sm); }\n.mb-md { margin-bottom: var(--spacing-md); }\n.mb-lg { margin-bottom: var(--spacing-lg); }\n\n.p-xs { padding: var(--spacing-xs); }\n.p-sm { padding: var(--spacing-sm); }\n.p-md { padding: var(--spacing-md); }\n.p-lg { padding: var(--spacing-lg); }\n\n.rounded { border-radius: var(--border-radius); }\n.rounded-sm { border-radius: var(--border-radius-sm); }\n\n.shadow { box-shadow: var(--box-shadow); }\n.shadow-sm { box-shadow: var(--box-shadow-sm); }\n\n.bg-primary {\n background: var(--primary-color);\n color: #fff;\n}\n.bg-card {\n background: var(--card-bg);\n}\n\n/* Accessibility utilities */\n.sr-only {\n position: absolute;\n width: 1px;\n height: 1px;\n padding: 0;\n margin: -1px;\n overflow: hidden;\n clip: rect(0, 0, 0, 0);\n white-space: nowrap;\n border: 0;\n}\n\n.min-touch-target {\n min-height: var(--min-touch-target);\n min-width: var(--min-touch-target);\n}\n\n/* Enhanced accessibility utilities */\n.visually-hidden {\n position: absolute !important;\n width: 1px !important;\n height: 1px !important;\n padding: 0 !important;\n margin: -1px !important;\n overflow: hidden !important;\n clip: rect(0, 0, 0, 0) !important;\n white-space: nowrap !important;\n border: 0 !important;\n}\n\n.visually-hidden.focusable:focus,\n.visually-hidden.focusable:active {\n position: static !important;\n width: auto !important;\n height: auto !important;\n padding: inherit !important;\n margin: inherit !important;\n overflow: visible !important;\n clip: auto !important;\n white-space: inherit !important;\n}\n\n/* Skip links utility */\n.skip-links {\n position: absolute;\n top: -100px;\n left: 0;\n z-index: 1000;\n}\n\n.skip-links a {\n position: absolute;\n left: 6px;\n top: 6px;\n padding: var(--spacing-sm);\n background: var(--primary-color);\n color: white;\n text-decoration: none;\n border-radius: var(--border-radius-sm);\n}\n\n.skip-links a:focus {\n top: 6px;\n}\n\n/* Color contrast utilities */\n.high-contrast {\n background: white;\n color: black;\n border: 2px solid black;\n}\n\n.reduced-motion {\n animation: none !important;\n transition: none !important;\n}\n\n/* Focus management */\n.focus-ring {\n outline: 2px solid var(--primary-color);\n outline-offset: 2px;\n}\n\n.no-focus-ring {\n outline: none;\n}\n\n/* ARIA live regions */\n.live-region {\n position: absolute;\n left: -10000px;\n width: 1px;\n height: 1px;\n overflow: hidden;\n}\n\n/* Text scaling utilities */\n.text-scale-friendly {\n line-height: 1.5;\n max-width: 70ch; /* Optimal reading length */\n}\n\n/* Text accessibility utilities */\n.text-readable {\n line-height: var(--line-height-base);\n max-width: 65ch;\n}\n\n.text-large {\n font-size: var(--font-size-lg);\n line-height: var(--line-height-base);\n}\n\n.text-small {\n font-size: max(var(--font-size-sm), var(--min-font-size));\n line-height: var(--min-line-height);\n}\n\n.text-contrast-high {\n color: var(--text-color);\n font-weight: 600;\n}\n\n/* Better focus for text elements */\n.focusable-text:focus {\n background-color: rgba(124, 77, 255, 0.1);\n outline: 2px solid var(--primary-color);\n outline-offset: 2px;\n border-radius: 2px;\n}\n\n/* High contrast text */\n.high-contrast {\n color: var(--text-color);\n background: var(--background-color);\n border: 1px solid var(--border-light);\n}';class Y extends HTMLElement{constructor(){super(),this.shadow=this.attachShadow({mode:"open"})}async connectedCallback(){let n=null,t=null,e="undefined"!=typeof CSSStyleSheet&&!0;try{e&&(n=new CSSStyleSheet,n.replaceSync(V),Y.sheet||(Y.sheet=new CSSStyleSheet,Y.sheet.replaceSync(i)),t=Y.sheet)}catch(e){n=null,t=null}if("adoptedStyleSheets"in Document.prototype&&n&&t)this.shadow.adoptedStyleSheets=[n,t];else{{const n=document.createElement("style");n.textContent=V,this.shadow.appendChild(n)}{const n=document.createElement("style");n.textContent=i,this.shadow.appendChild(n)}}this.render()}render(){const n=this,t=n.subject,e=n.context;if(!t||!e)return void O(w``,n.shadow);const i=e.session.logic,r=e.session.paneRegistry.byName("long chat"),o=document.createElement("div");o.setAttribute("class","cardFrame");const a=document.createElement("div");a.setAttribute("class","chatSection"),a.setAttribute("aria-labelledby","chat-section-title"),a.setAttribute("role","region"),a.setAttribute("data-testid","chat");const s=document.createElement("h3");let l;s.id="chat-section-title",s.className="sr-only",s.textContent="Communication",a.appendChild(s),(async()=>{try{O(w`
76
2
  <div class="chatLoading" role="status" aria-live="polite">
77
- ${loadingMessage.toUpperCase()}
3
+ ${D.Eo.toUpperCase()}
78
4
  </div>
79
- `, self.shadow);
80
- exists = await logic.chat.getChat(subject, false);
81
- }
82
- catch (e) {
83
- exists = false;
84
- }
85
- if (exists) {
86
- const chatArea = document.createElement('div');
87
- chatArea.setAttribute('role', 'log');
88
- chatArea.setAttribute('aria-label', 'Chat conversation');
89
- chatArea.appendChild(longChatPane.render(exists, context, {}));
90
- chatContainer.appendChild(chatArea);
91
- frame.appendChild(chatContainer);
92
- render(frame, self.shadow);
93
- }
94
- else {
95
- const me = authn.currentUser();
96
- let label = checkIfAnyUserLoggedIn(me) ? chatWithMeButtonText.toUpperCase() : logInToChatWithMeButtonText.toUpperCase();
97
- const button = widgets.button(document, undefined, label, setButtonHandler, { needsBorder: true });
98
- async function setButtonHandler(event) {
99
- event.preventDefault();
100
- try {
101
- const chat = await logic.chat.getChat(subject, true);
102
- chatContainer.innerHTML = '';
103
- chatContainer.appendChild(longChatPane.render(chat, context, {}));
104
- frame.appendChild(chatContainer);
105
- render(frame, self.shadow);
106
- }
107
- catch (error) {
108
- complain(chatContainer, context, error);
109
- }
110
- }
111
- button.refresh = refreshButton();
112
- function refreshButton() {
113
- const me = authn.currentUser();
114
- if (checkIfAnyUserLoggedIn(me)) {
115
- button.innerHTML = chatWithMeButtonText.toUpperCase();
116
- button.className = 'button';
117
- button.setAttribute('class', 'button');
118
- }
119
- else {
120
- button.innerHTML = logInToChatWithMeButtonText.toUpperCase();
121
- button.className = 'button';
122
- button.setAttribute('class', 'button');
123
- }
124
- }
125
- button.setAttribute('type', 'button');
126
- button.setAttribute('aria-describedby', 'chat-button-description');
127
- const description = document.createElement('span');
128
- description.id = 'chat-button-description';
129
- description.className = 'sr-only';
130
- description.textContent = 'Start a new conversation or sign in to continue existing chat';
131
- chatContainer.appendChild(button);
132
- chatContainer.appendChild(description);
133
- frame.appendChild(chatContainer);
134
- render(frame, self.shadow);
135
- }
136
- })();
137
- }
138
- get subject() {
139
- return this._subject;
140
- }
141
- set subject(val) {
142
- this._subject = val;
143
- this.render();
144
- }
145
- get context() {
146
- return this._context;
147
- }
148
- set context(val) {
149
- this._context = val;
150
- this.render();
151
- }
152
- }
153
- ChatWithMeElement.sheet = null;
154
- if (!customElements.get('chat-with-me')) {
155
- customElements.define('chat-with-me', ChatWithMeElement);
156
- }
157
- //# sourceMappingURL=ChatWithMeElement.js.map
5
+ `,n.shadow),l=await i.chat.getChat(t,!1)}catch(s){l=!1}if(l){const c=document.createElement("div");c.setAttribute("role","log"),c.setAttribute("aria-label","Chat conversation"),c.appendChild(r.render(l,e,{})),a.appendChild(c),o.appendChild(a),O(o,n.shadow)}else{const d=P.authn.currentUser();let p=(0,G.S)(d)?D.m7.toUpperCase():D.e_.toUpperCase();const h=W.widgets.button(document,void 0,p,m,{needsBorder:!0});async function m(s){s.preventDefault();try{const s=await i.chat.getChat(t,!0);a.innerHTML="",a.appendChild(r.render(s,e,{})),o.appendChild(a),O(o,n.shadow)}catch(n){(0,G.cc)(a,e,n)}}function g(){const n=P.authn.currentUser();(0,G.S)(n)?(h.innerHTML=D.m7.toUpperCase(),h.className="button",h.setAttribute("class","button")):(h.innerHTML=D.e_.toUpperCase(),h.className="button",h.setAttribute("class","button"))}h.refresh=g(),h.setAttribute("type","button"),h.setAttribute("aria-describedby","chat-button-description");const u=document.createElement("span");u.id="chat-button-description",u.className="sr-only",u.textContent="Start a new conversation or sign in to continue existing chat",a.appendChild(h),a.appendChild(u),o.appendChild(a),O(o,n.shadow)}})()}get subject(){return this._subject}set subject(n){this._subject=n,this.render()}get context(){return this._context}set context(n){this._context=n,this.render()}}Y.sheet=null,customElements.get("chat-with-me")||customElements.define("chat-with-me",Y)})();