profile-pane 2.0.0-shadowDom-6f51c34b → 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.
@@ -1,168 +1,51 @@
1
- "use strict";
2
-
3
- var _CVCard = _interopRequireDefault(require("./styles/CVCard.css"));
4
- var _litHtml = require("lit-html");
5
- var _global = _interopRequireDefault(require("./styles/global.css"));
6
- function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
7
- class CVCardElement extends HTMLElement {
8
- static sheet = null;
9
- constructor() {
10
- super();
11
- this.shadow = this.attachShadow({
12
- mode: 'open'
13
- });
14
- }
15
- async connectedCallback() {
16
- let globalSheet = null;
17
- let cardSheet = null;
18
- let canUseSheets = typeof CSSStyleSheet !== 'undefined' && typeof _global.default === 'string' && typeof _CVCard.default === 'string';
19
- try {
20
- if (canUseSheets) {
21
- globalSheet = new CSSStyleSheet();
22
- globalSheet.replaceSync(_global.default);
23
- if (!CVCardElement.sheet) {
24
- CVCardElement.sheet = new CSSStyleSheet();
25
- CVCardElement.sheet.replaceSync(_CVCard.default);
26
- }
27
- cardSheet = CVCardElement.sheet;
28
- }
29
- } catch (e) {
30
- globalSheet = null;
31
- cardSheet = null;
32
- }
33
- if ('adoptedStyleSheets' in Document.prototype && globalSheet && cardSheet) {
34
- this.shadow.adoptedStyleSheets = [globalSheet, cardSheet];
35
- } else {
36
- // Fallback for browsers or test environments without adoptedStyleSheets or CSSStyleSheet
37
- if (typeof _global.default === 'string') {
38
- const styleGlobal = document.createElement('style');
39
- styleGlobal.textContent = _global.default;
40
- this.shadow.appendChild(styleGlobal);
41
- }
42
- if (typeof _CVCard.default === 'string') {
43
- const styleCard = document.createElement('style');
44
- styleCard.textContent = _CVCard.default;
45
- this.shadow.appendChild(styleCard);
46
- }
47
- }
48
- this.render();
49
- }
50
- render() {
51
- // .cardFrame wrapper already present from previous patch
52
- // Assume cvData is passed as a property
53
- const cvData = this.cvData;
54
- if (!cvData) return;
55
- const {
56
- rolesByType,
57
- skills,
58
- languages
59
- } = cvData;
60
- const futureRolesArr = rolesByType['FutureRole'] || [];
61
- const currentRolesArr = rolesByType['CurrentRole'] || [];
62
- const pastRolesArr = rolesByType['PastRole'] || [];
63
- const skillsArr = skills || [];
64
- const languagesArr = languages || [];
65
- const hasFutureRole = Array.isArray(futureRolesArr) && futureRolesArr.length > 0;
66
- const hasCurrentRole = Array.isArray(currentRolesArr) && currentRolesArr.length > 0;
67
- const hasPastRole = Array.isArray(pastRolesArr) && pastRolesArr.length > 0;
68
- const hasSkills = Array.isArray(skillsArr) && skillsArr.length > 0;
69
- const hasLanguages = Array.isArray(languagesArr) && languagesArr.length > 0;
70
- if (!(hasFutureRole || hasCurrentRole || hasPastRole || hasSkills || hasLanguages)) {
71
- (0, _litHtml.render)((0, _litHtml.html)``, this.shadow);
72
- return;
73
- }
74
- (0, _litHtml.render)((0, _litHtml.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?$`
75
2
  <div class="cardFrame">
76
3
  <article class="cvCard" aria-label="Professional Experience" data-testid="curriculum-vitae">
77
- ${hasFutureRole ? (0, _litHtml.html)`
4
+ ${d?$`
78
5
  <section class="cvSection" aria-labelledby="cv-future-heading">
79
6
  <h3 id="cv-future-heading">Future Roles</h3>
80
7
  <ul role="list" aria-label="Upcoming professional roles">
81
- ${renderRoles(futureRolesArr, true)}
8
+ ${L(r,!0)}
82
9
  </ul>
83
10
  </section>
84
- ` : ''}
85
- ${hasCurrentRole ? (0, _litHtml.html)`
11
+ `:""}
12
+ ${h?$`
86
13
  <section class="cvSection" aria-labelledby="cv-current-heading">
87
14
  <h3 id="cv-current-heading">Current Roles</h3>
88
15
  <ul role="list" aria-label="Current professional positions">
89
- ${renderRoles(currentRolesArr, true)}
16
+ ${L(o,!0)}
90
17
  </ul>
91
18
  </section>
92
- ` : ''}
93
- ${hasPastRole ? (0, _litHtml.html)`
19
+ `:""}
20
+ ${p?$`
94
21
  <section class="cvSection" aria-labelledby="cv-past-heading">
95
22
  <h3 id="cv-past-heading">Past Roles</h3>
96
23
  <ul role="list" aria-label="Previous work experience">
97
- ${renderRoles(pastRolesArr, true)}
24
+ ${L(a,!0)}
98
25
  </ul>
99
26
  </section>
100
- ` : ''}
101
- ${hasSkills ? (0, _litHtml.html)`
27
+ `:""}
28
+ ${g?$`
102
29
  <section class="cvSection" aria-labelledby="cv-skills-heading">
103
30
  <h3 id="cv-skills-heading">Skills</h3>
104
31
  <ul role="list" aria-label="Professional skills and competencies">
105
- ${renderSkills(skillsArr, true)}
32
+ ${P(s,!0)}
106
33
  </ul>
107
34
  </section>
108
- ` : ''}
109
- ${hasLanguages ? (0, _litHtml.html)`
35
+ `:""}
36
+ ${m?$`
110
37
  <section class="cvSection" aria-labelledby="cv-languages-heading">
111
38
  <h3 id="cv-languages-heading">Languages</h3>
112
39
  <ul role="list" aria-label="Known languages">
113
- ${renderLanguages(languagesArr, true)}
40
+ ${D(l,!0)}
114
41
  </ul>
115
42
  </section>
116
- ` : ''}
43
+ `:""}
117
44
  </article>
118
45
  </div>
119
- `, this.shadow);
120
- }
121
- get cvData() {
122
- return this._cvData;
123
- }
124
- set cvData(val) {
125
- this._cvData = val;
126
- this.render();
127
- }
128
- }
129
- customElements.define('cv-card', CVCardElement);
130
- function renderRoles(roles, asList = false) {
131
- if (!roles || !roles.length || !roles[0]) return (0, _litHtml.html)``;
132
- return (0, _litHtml.html)`${renderRole(roles[0], asList)}${roles.length > 1 ? renderRoles(roles.slice(1), asList) : (0, _litHtml.html)``}`;
133
- }
134
- function renderRole(role, asList = false) {
135
- if (!role) return (0, _litHtml.html)``;
136
- return asList ? (0, _litHtml.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?$`
137
47
  <li class="cvRole" role="listitem">
138
- <strong class="cvOrg" aria-label="Organization">${role.orgName}</strong>
139
- <span aria-label="Role title">${strToUpperCase(role.roleText)}</span>
140
- <time aria-label="Employment period">${role.dates}</time>
141
- </li>` : (0, _litHtml.html)``;
142
- }
143
- function renderSkill(skill, asList = false) {
144
- if (!skill) return (0, _litHtml.html)``;
145
- return asList ? (0, _litHtml.html)`<li class="cvSkill">${strToUpperCase(skill)}</li>` : (0, _litHtml.html)``;
146
- }
147
- function renderSkills(skills, asList = false) {
148
- if (!skills || !skills.length || !skills[0]) return (0, _litHtml.html)``;
149
- return (0, _litHtml.html)`${renderSkill(skills[0], asList)}${skills.length > 1 ? renderSkills(skills.slice(1), asList) : (0, _litHtml.html)``}`;
150
- }
151
- function renderLan(language, asList = false) {
152
- if (!language) return (0, _litHtml.html)``;
153
- return asList ? (0, _litHtml.html)`<li class="cvLanguage">${language}</li>` : (0, _litHtml.html)``;
154
- }
155
- function renderLanguages(languages, asList = false) {
156
- if (!languages || !languages.length || !languages[0]) return (0, _litHtml.html)``;
157
- return (0, _litHtml.html)`${renderLan(languages[0], asList)}${languages.length > 1 ? renderLanguages(languages.slice(1), asList) : (0, _litHtml.html)``}`;
158
- }
159
- function strToUpperCase(str) {
160
- if (str && str[0] > '') {
161
- const strCase = str.split(' ');
162
- for (let i = 0; i < strCase.length; i++) {
163
- strCase[i] = strCase[i].charAt(0).toUpperCase() + strCase[i].substring(1);
164
- }
165
- return strCase.join(' ');
166
- }
167
- return '';
168
- }
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,100 +1 @@
1
- "use strict";
2
-
3
- Object.defineProperty(exports, "__esModule", {
4
- value: true
5
- });
6
- exports.datesAsText = datesAsText;
7
- exports.languageAsText = languageAsText;
8
- exports.presentCV = presentCV;
9
- exports.skillAsText = skillAsText;
10
- exports.typesOfRole = void 0;
11
- var _rdflib = require("rdflib");
12
- var _solidUi = require("solid-ui");
13
- const ORG = (0, _rdflib.Namespace)('http://www.w3.org/ns/org#');
14
- const typesOfRole = exports.typesOfRole = ['PastRole', 'CurrentRole', 'FutureRole'];
15
- function skillAsText(store, sk) {
16
- if (sk.termType === 'Literal') return sk.value; // Not normal but allow this
17
- const publicId = store.anyJS(sk, _solidUi.ns.solid('publicId'));
18
- if (publicId) {
19
- const name = store.anyJS(publicId, _solidUi.ns.schema('name'));
20
- if (name) return name; // @@ check language and get name in diff language if necessary
21
- }
22
- const manual = store.anyJS(sk, _solidUi.ns.vcard('role'));
23
- if (manual && manual[0] > '') return manual;
24
- return '¿¿¿ skill ???';
25
- }
26
- function languageAsText(store, lan) {
27
- if (lan.termType === 'Literal') return lan.value; // Not normal but allow this
28
- const publicId = store.anyJS(lan, _solidUi.ns.solid('publicId'));
29
- if (publicId) return _solidUi.utils.label(publicId, true); // @@ check language and get name in diff language if necessary
30
- return '-';
31
- }
32
- function datesAsText(startDate, endDate) {
33
- return startDate ? '(' + startDate.value.slice(0, 10) + ' to ' + (endDate ? endDate.value.slice(0, 10) : '') + ')' : '';
34
- }
35
- function getRolesByType(store, subject) {
36
- const memberships = store.each(null, ORG('member'), subject, null);
37
- const rolesByType = {
38
- PastRole: [],
39
- CurrentRole: [],
40
- FutureRole: []
41
- };
42
- for (const membership of memberships) {
43
- let orgHomePage, orgNameGiven, publicIdName, roleName, publicId;
44
- // Things should have start dates but we will be very lenient in this view
45
- const startDate = store.any(membership, _solidUi.ns.schema('startDate'));
46
- const endDate = store.any(membership, _solidUi.ns.schema('endDate'));
47
- const dates = datesAsText(startDate, endDate);
48
- const organization = store.any(membership, ORG('organization'));
49
- if (organization) {
50
- orgNameGiven = store.anyJS(organization, _solidUi.ns.schema('name'));
51
- orgHomePage = store.any(organization, _solidUi.ns.schema('uri'));
52
- publicId = store.any(organization, _solidUi.ns.solid('publicId'));
53
- }
54
- if (publicId) {
55
- publicIdName = store.anyJS(publicId, _solidUi.ns.schema('name'));
56
- }
57
- const orgName = publicIdName || orgNameGiven;
58
- const escoRole = store.any(membership, ORG('role'));
59
- if (escoRole) {
60
- roleName = store.anyJS(escoRole, _solidUi.ns.schema('name'));
61
- }
62
- const roleText0 = store.anyJS(membership, _solidUi.ns.vcard('role'));
63
- const roleText = roleText0 && roleName ? roleName + ' - ' + roleText0 : roleText0 || roleName;
64
- const item = {
65
- startDate: startDate,
66
- endDate,
67
- orgName,
68
- roleText,
69
- dates,
70
- orgHomePage
71
- };
72
- for (const t of typesOfRole) {
73
- if (store.holds(membership, _solidUi.ns.rdf('type'), _solidUi.ns.solid(t))) {
74
- rolesByType[t].push(item);
75
- }
76
- }
77
- }
78
- return rolesByType;
79
- }
80
- function presentCV(subject, store) {
81
- const rolesByType = getRolesByType(store, subject);
82
- // Most recent thing most relevant -> sort by end date
83
- for (const t of typesOfRole) {
84
- rolesByType[t].sort(function (x, y) {
85
- if (x.endDate && y.endDate) {
86
- return x.endDate > y.endDate ? -1 : 1;
87
- }
88
- return x.startDate > y.startDate ? -1 : 1;
89
- });
90
- }
91
- const skills = store.each(subject, _solidUi.ns.schema('skills')).map(sk => skillAsText(store, sk));
92
- const languagesInStore = store.anyJS(subject, _solidUi.ns.schema('knowsLanguage'));
93
- let languages = [];
94
- if (languagesInStore) languages = languagesInStore.map(lan => languageAsText(store, lan));
95
- return {
96
- rolesByType,
97
- skills,
98
- languages
99
- };
100
- }
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
- "use strict";
2
-
3
- var _ChatWithMe = _interopRequireDefault(require("./styles/ChatWithMe.css"));
4
- var _litHtml = require("lit-html");
5
- var _solidUi = require("solid-ui");
6
- var _solidLogic = require("solid-logic");
7
- var _texts = require("./texts");
8
- var _buttonsHelper = require("./buttonsHelper");
9
- var _global = _interopRequireDefault(require("./styles/global.css"));
10
- function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
11
- class ChatWithMeElement extends HTMLElement {
12
- static sheet = null;
13
- constructor() {
14
- super();
15
- this.shadow = this.attachShadow({
16
- mode: 'open'
17
- });
18
- }
19
- async connectedCallback() {
20
- let globalSheet = null;
21
- let cardSheet = null;
22
- let canUseSheets = typeof CSSStyleSheet !== 'undefined' && typeof _global.default === 'string' && typeof _ChatWithMe.default === 'string';
23
- try {
24
- if (canUseSheets) {
25
- globalSheet = new CSSStyleSheet();
26
- globalSheet.replaceSync(_global.default);
27
- if (!ChatWithMeElement.sheet) {
28
- ChatWithMeElement.sheet = new CSSStyleSheet();
29
- ChatWithMeElement.sheet.replaceSync(_ChatWithMe.default);
30
- }
31
- cardSheet = ChatWithMeElement.sheet;
32
- }
33
- } catch (e) {
34
- globalSheet = null;
35
- cardSheet = null;
36
- }
37
- if ('adoptedStyleSheets' in Document.prototype && globalSheet && cardSheet) {
38
- this.shadow.adoptedStyleSheets = [globalSheet, cardSheet];
39
- } else {
40
- // Fallback for browsers or test environments without adoptedStyleSheets or CSSStyleSheet
41
- if (typeof _global.default === 'string') {
42
- const styleGlobal = document.createElement('style');
43
- styleGlobal.textContent = _global.default;
44
- this.shadow.appendChild(styleGlobal);
45
- }
46
- if (typeof _ChatWithMe.default === 'string') {
47
- const styleCard = document.createElement('style');
48
- styleCard.textContent = _ChatWithMe.default;
49
- this.shadow.appendChild(styleCard);
50
- }
51
- }
52
- this.render();
53
- }
54
- render() {
55
- const self = this;
56
- const subject = self.subject;
57
- const context = self.context;
58
- if (!subject || !context) {
59
- (0, _litHtml.render)((0, _litHtml.html)``, self.shadow);
60
- return;
61
- }
62
- const logic = context.session.logic;
63
- const longChatPane = context.session.paneRegistry.byName('long chat');
64
- const frame = document.createElement('div');
65
- frame.setAttribute('class', 'cardFrame');
66
- const chatContainer = document.createElement('div');
67
- chatContainer.setAttribute('class', 'chatSection');
68
- chatContainer.setAttribute('aria-labelledby', 'chat-section-title');
69
- chatContainer.setAttribute('role', 'region');
70
- chatContainer.setAttribute('data-testid', 'chat');
71
- const title = document.createElement('h3');
72
- title.id = 'chat-section-title';
73
- title.className = 'sr-only';
74
- title.textContent = 'Communication';
75
- chatContainer.appendChild(title);
76
- let exists;
77
- (async () => {
78
- try {
79
- (0, _litHtml.render)((0, _litHtml.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`
80
2
  <div class="chatLoading" role="status" aria-live="polite">
81
- ${_texts.loadingMessage.toUpperCase()}
3
+ ${D.Eo.toUpperCase()}
82
4
  </div>
83
- `, self.shadow);
84
- exists = await logic.chat.getChat(subject, false);
85
- } catch (e) {
86
- exists = false;
87
- }
88
- if (exists) {
89
- const chatArea = document.createElement('div');
90
- chatArea.setAttribute('role', 'log');
91
- chatArea.setAttribute('aria-label', 'Chat conversation');
92
- chatArea.appendChild(longChatPane.render(exists, context, {}));
93
- chatContainer.appendChild(chatArea);
94
- frame.appendChild(chatContainer);
95
- (0, _litHtml.render)(frame, self.shadow);
96
- } else {
97
- const me = _solidLogic.authn.currentUser();
98
- let label = (0, _buttonsHelper.checkIfAnyUserLoggedIn)(me) ? _texts.chatWithMeButtonText.toUpperCase() : _texts.logInToChatWithMeButtonText.toUpperCase();
99
- const button = _solidUi.widgets.button(document, undefined, label, setButtonHandler, {
100
- needsBorder: true
101
- });
102
- async function setButtonHandler(event) {
103
- event.preventDefault();
104
- try {
105
- const chat = await logic.chat.getChat(subject, true);
106
- chatContainer.innerHTML = '';
107
- chatContainer.appendChild(longChatPane.render(chat, context, {}));
108
- frame.appendChild(chatContainer);
109
- (0, _litHtml.render)(frame, self.shadow);
110
- } catch (error) {
111
- (0, _buttonsHelper.complain)(chatContainer, context, error);
112
- }
113
- }
114
- button.refresh = refreshButton();
115
- function refreshButton() {
116
- const me = _solidLogic.authn.currentUser();
117
- if ((0, _buttonsHelper.checkIfAnyUserLoggedIn)(me)) {
118
- button.innerHTML = _texts.chatWithMeButtonText.toUpperCase();
119
- button.className = 'button';
120
- button.setAttribute('class', 'button');
121
- } else {
122
- button.innerHTML = _texts.logInToChatWithMeButtonText.toUpperCase();
123
- button.className = 'button';
124
- button.setAttribute('class', 'button');
125
- }
126
- }
127
- button.setAttribute('type', 'button');
128
- button.setAttribute('aria-describedby', 'chat-button-description');
129
- const description = document.createElement('span');
130
- description.id = 'chat-button-description';
131
- description.className = 'sr-only';
132
- description.textContent = 'Start a new conversation or sign in to continue existing chat';
133
- chatContainer.appendChild(button);
134
- chatContainer.appendChild(description);
135
- frame.appendChild(chatContainer);
136
- (0, _litHtml.render)(frame, self.shadow);
137
- }
138
- })();
139
- }
140
- get subject() {
141
- return this._subject;
142
- }
143
- set subject(val) {
144
- this._subject = val;
145
- this.render();
146
- }
147
- get context() {
148
- return this._context;
149
- }
150
- set context(val) {
151
- this._context = val;
152
- this.render();
153
- }
154
- }
155
- if (!customElements.get('chat-with-me')) {
156
- customElements.define('chat-with-me', ChatWithMeElement);
157
- }
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)})();