@m00rl0ck/a11y-widget 0.1.0 → 0.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -40,6 +40,54 @@ npm install @m00rl0ck/a11y-widget
40
40
  ></vision-accessibility-widget>
41
41
  ```
42
42
 
43
+ ### colorblind-adapt
44
+
45
+ Colorblind adaptation panel. Take a quick 3-question test or select your color vision type manually. The website adapts its colors for better readability.
46
+
47
+ ```
48
+ npm install @m00rl0ck/a11y-widget
49
+ ```
50
+
51
+ ```html
52
+ <script type="module">
53
+ import '@m00rl0ck/a11y-widget/colorblind-adapt'
54
+ </script>
55
+
56
+ <colorblind-adapt-widget></colorblind-adapt-widget>
57
+ ```
58
+
59
+ #### Attributes
60
+
61
+ | Attribute | Type | Default | Description |
62
+ |-----------|------|---------|-------------|
63
+ | `lang` | `uk` / `en` / `de` | auto | UI language |
64
+
65
+ #### Test
66
+
67
+ The widget provides a 3-question colorblind test:
68
+ 1. **Red-green vs blue-yellow** color confusion
69
+ 2. **Number detection** (pseudo-ishihara)
70
+ 3. **Brightness comparison**
71
+
72
+ Results suggest your vision type and severity (`mild` / `moderate` / `severe`).
73
+
74
+ You can also skip the test and **select your type manually** with a severity level.
75
+
76
+ #### Example
77
+
78
+ ```html
79
+ <colorblind-adapt-widget lang="en"></colorblind-adapt-widget>
80
+ ```
81
+
82
+ #### Supported vision types
83
+
84
+ | Type | Description |
85
+ |------|-------------|
86
+ | `deuteranopia` | Green-blind (most common) |
87
+ | `protanopia` | Red-blind |
88
+ | `tritanopia` | Blue-yellow blind |
89
+ | `monochromacy` | Complete color blindness |
90
+
43
91
  ## Development
44
92
 
45
93
  ```
@@ -0,0 +1,474 @@
1
+ var _=Object.defineProperty;var S=(t,e,a)=>e in t?_(t,e,{enumerable:!0,configurable:!0,writable:!0,value:a}):t[e]=a;var b=(t,e,a)=>S(t,typeof e!="symbol"?e+"":e,a);var c={uk:{toggleText:"\u0414\u0430\u043B\u044C\u0442\u043E\u043D\u0456\u0437\u043C",toggleLabel:"\u041D\u0430\u043B\u0430\u0448\u0442\u0443\u0432\u0430\u0442\u0438 \u0441\u0430\u0439\u0442 \u0434\u043B\u044F \u043B\u044E\u0434\u0435\u0439 \u0456\u0437 \u0434\u0430\u043B\u044C\u0442\u043E\u043D\u0456\u0437\u043C\u043E\u043C",closeLabel:"\u0417\u0430\u043A\u0440\u0438\u0442\u0438 \u043F\u0430\u043D\u0435\u043B\u044C",panelTitle:"\u041D\u0430\u043B\u0430\u0448\u0442\u0443\u0432\u0430\u043D\u043D\u044F \u0434\u043B\u044F \u0434\u0430\u043B\u044C\u0442\u043E\u043D\u0456\u0437\u043C\u0443",panelSubtitle:"\u041F\u0440\u043E\u0439\u0434\u0456\u0442\u044C \u0448\u0432\u0438\u0434\u043A\u0438\u0439 \u0442\u0435\u0441\u0442 \u0430\u0431\u043E \u043E\u0431\u0435\u0440\u0456\u0442\u044C \u0441\u0432\u0456\u0439 \u0442\u0438\u043F \u0437\u043E\u0440\u0443.",testTab:"\u0422\u0435\u0441\u0442",manualTab:"\u0412\u0440\u0443\u0447\u043D\u0443",startTest:"\u0420\u043E\u0437\u043F\u043E\u0447\u0430\u0442\u0438 \u0442\u0435\u0441\u0442",nextQuestion:"\u0414\u0430\u043B\u0456",question1:"\u042F\u043A\u0438\u0439 \u043A\u043E\u043B\u0456\u0440 \u0432\u0438 \u0431\u0430\u0447\u0438\u0442\u0435 \u0432 \u0446\u0435\u043D\u0442\u0440\u0456?",question2:"\u042F\u043A\u0435 \u0447\u0438\u0441\u043B\u043E \u0431\u0430\u0447\u0438\u0442\u0435?",question3:"\u042F\u043A\u0438\u0439 \u043A\u0432\u0430\u0434\u0440\u0430\u0442 \u044F\u0441\u043A\u0440\u0430\u0432\u0456\u0448\u0438\u0439?",optRedGreen:"\u0427\u0435\u0440\u0432\u043E\u043D\u0438\u0439 / \u0417\u0435\u043B\u0435\u043D\u0438\u0439",optBlueYellow:"\u0421\u0438\u043D\u0456\u0439 / \u0416\u043E\u0432\u0442\u0438\u0439",optNone:"\u041D\u0435 \u0431\u0430\u0447\u0443 \u0440\u0456\u0437\u043D\u0438\u0446\u0456",optNumber74:"74",optNumber21:"21",optNoNumber:"\u041D\u0435 \u0431\u0430\u0447\u0443 \u0447\u0438\u0441\u043B\u0430",optLeft:"\u041B\u0456\u0432\u0438\u0439",optRight:"\u041F\u0440\u0430\u0432\u0438\u0439",optSame:"\u041E\u0434\u043D\u0430\u043A\u043E\u0432\u0456",resultTitle:"\u0420\u0435\u0437\u0443\u043B\u044C\u0442\u0430\u0442 \u0442\u0435\u0441\u0442\u0443",resultDesc:"\u0421\u0445\u043E\u0436\u0435, \u0443 \u0432\u0430\u0441 {type}. \u0421\u0430\u0439\u0442 \u043F\u0456\u0434\u043B\u0430\u0448\u0442\u043E\u0432\u0430\u043D\u043E.",typeNormal:"\u043D\u043E\u0440\u043C\u0430\u043B\u044C\u043D\u0438\u0439 \u0437\u0456\u0440",typeDeuteranopia:"\u0434\u0430\u043B\u044C\u0442\u043E\u043D\u0456\u0437\u043C \u043D\u0430 \u0437\u0435\u043B\u0435\u043D\u0438\u0439 (deuteranopia)",typeProtanopia:"\u0434\u0430\u043B\u044C\u0442\u043E\u043D\u0456\u0437\u043C \u043D\u0430 \u0447\u0435\u0440\u0432\u043E\u043D\u0438\u0439 (protanopia)",typeTritanopia:"\u0434\u0430\u043B\u044C\u0442\u043E\u043D\u0456\u0437\u043C \u043D\u0430 \u0441\u0438\u043D\u0456\u0439 (tritanopia)",typeMonochromacy:"\u043F\u043E\u0432\u043D\u0430 \u0432\u0456\u0434\u0441\u0443\u0442\u043D\u0456\u0441\u0442\u044C \u043A\u043E\u043B\u044C\u043E\u0440\u043E\u0432\u043E\u0433\u043E \u0437\u043E\u0440\u0443 (monochromacy)",selectType:"\u041E\u0431\u0435\u0440\u0456\u0442\u044C \u0432\u0430\u0448 \u0442\u0438\u043F \u0437\u043E\u0440\u0443:",deuteranopia:"\u041D\u0435 \u0440\u043E\u0437\u0440\u0456\u0437\u043D\u044F\u044E \u0437\u0435\u043B\u0435\u043D\u0438\u0439",protanopia:"\u041D\u0435 \u0440\u043E\u0437\u0440\u0456\u0437\u043D\u044F\u044E \u0447\u0435\u0440\u0432\u043E\u043D\u0438\u0439",tritanopia:"\u041D\u0435 \u0440\u043E\u0437\u0440\u0456\u0437\u043D\u044F\u044E \u0441\u0438\u043D\u0456\u0439",monochromacy:"\u0427\u043E\u0440\u043D\u043E-\u0431\u0456\u043B\u0438\u0439 \u0437\u0456\u0440",apply:"\u0417\u0430\u0441\u0442\u043E\u0441\u0443\u0432\u0430\u0442\u0438",reset:"\u0421\u043A\u0438\u043D\u0443\u0442\u0438 \u043D\u0430\u043B\u0430\u0448\u0442\u0443\u0432\u0430\u043D\u043D\u044F",severity:"\u0421\u0442\u0443\u043F\u0456\u043D\u044C:",mild:"\u041B\u0435\u0433\u043A\u0430",moderate:"\u041F\u043E\u043C\u0456\u0440\u043D\u0430",severe:"\u0421\u0438\u043B\u044C\u043D\u0430"},en:{toggleText:"Colorblind",toggleLabel:"Adapt website for colorblind users",closeLabel:"Close panel",panelTitle:"Colorblind Settings",panelSubtitle:"Take a quick test or select your vision type.",testTab:"Test",manualTab:"Manual",startTest:"Start test",nextQuestion:"Next",question1:"What color do you see in the center?",question2:"What number do you see?",question3:"Which square is brighter?",optRedGreen:"Red / Green",optBlueYellow:"Blue / Yellow",optNone:"No difference",optNumber74:"74",optNumber21:"21",optNoNumber:"No number",optLeft:"Left",optRight:"Right",optSame:"Same",resultTitle:"Test result",resultDesc:"It appears you have {type}. The site has been adapted.",typeNormal:"normal vision",typeDeuteranopia:"green-blindness (deuteranopia)",typeProtanopia:"red-blindness (protanopia)",typeTritanopia:"blue-blindness (tritanopia)",typeMonochromacy:"complete color blindness (monochromacy)",selectType:"Select your vision type:",deuteranopia:"Cannot distinguish green",protanopia:"Cannot distinguish red",tritanopia:"Cannot distinguish blue",monochromacy:"Black and white vision",apply:"Apply",reset:"Reset settings",severity:"Severity:",mild:"Mild",moderate:"Moderate",severe:"Severe"},de:{toggleText:"Farbenblindheit",toggleLabel:"Website f\xFCr Farbenblinde anpassen",closeLabel:"Schlie\xDFen",panelTitle:"Farbenblind-Einstellungen",panelSubtitle:"Machen Sie einen schnellen Test oder w\xE4hlen Sie Ihren Sehtyp.",testTab:"Test",manualTab:"Manuell",startTest:"Test starten",nextQuestion:"Weiter",question1:"Welche Farbe sehen Sie in der Mitte?",question2:"Welche Zahl sehen Sie?",question3:"Welches Quadrat ist heller?",optRedGreen:"Rot / Gr\xFCn",optBlueYellow:"Blau / Gelb",optNone:"Kein Unterschied",optNumber74:"74",optNumber21:"21",optNoNumber:"Keine Zahl",optLeft:"Links",optRight:"Rechts",optSame:"Gleich",resultTitle:"Testergebnis",resultDesc:"Sie haben wahrscheinlich {type}. Die Website wurde angepasst.",typeNormal:"normales Sehen",typeDeuteranopia:"Gr\xFCnblindheit (Deuteranopie)",typeProtanopia:"Rotblindheit (Protanopie)",typeTritanopia:"Blaublindheit (Tritanopie)",typeMonochromacy:"vollst\xE4ndige Farbenblindheit (Monochromasie)",selectType:"W\xE4hlen Sie Ihren Sehtyp:",deuteranopia:"Kann Gr\xFCn nicht unterscheiden",protanopia:"Kann Rot nicht unterscheiden",tritanopia:"Kann Blau nicht unterscheiden",monochromacy:"Schwarz-Wei\xDF-Sehen",apply:"Anwenden",reset:"Zur\xFCcksetzen",severity:"St\xE4rke:",mild:"Leicht",moderate:"M\xE4\xDFig",severe:"Stark"}};function m(){let e=(document.documentElement.lang||navigator.language||"en").slice(0,2).toLowerCase();return e in c?e:"en"}var n=[{id:"q1",promptKey:"question1",options:[{labelKey:"optRedGreen",value:"red-green"},{labelKey:"optBlueYellow",value:"blue-yellow"},{labelKey:"optNone",value:"none"}]},{id:"q2",promptKey:"question2",options:[{labelKey:"optNumber74",value:"number"},{labelKey:"optNumber21",value:"number"},{labelKey:"optNoNumber",value:"none"}]},{id:"q3",promptKey:"question3",options:[{labelKey:"optLeft",value:"left"},{labelKey:"optRight",value:"right"},{labelKey:"optSame",value:"same"}]}];function v(t){let e=0,a=0,i=0,o=0;t.q1==="red-green"?(a+=3,e+=3):t.q1==="none"&&(o+=2),t.q2==="none"&&(e+=3,a+=2,o+=2),t.q3==="same"&&(o+=3,e+=1,a+=1);let s=[{type:"monochromacy",score:o},{type:"deuteranopia",score:e},{type:"protanopia",score:a},{type:"tritanopia",score:i}];if(s.sort((f,x)=>x.score-f.score),s[0].score===0)return{type:"normal",severity:"none"};let r=s[0].score,h=s[1].score,R=h>0?r/h:99,u="mild";return r>=7?u="severe":r>=4&&(u="moderate"),{type:s[0].type,severity:u}}var y="colorblind-adapt-styles";function g(t,e){if(p(),t==="normal"||!t)return;let a=document.createElement("style");a.id=y,a.textContent=T(t,e||"moderate"),document.head.appendChild(a)}function p(){document.getElementById(y)?.remove()}function T(t,e){return[w(t,e==="severe"?1:e==="moderate"?.6:.3)].join(`
2
+ `)}function w(t,e){switch(t){case"deuteranopia":return q(e);case"protanopia":return $(e);case"tritanopia":return z(e);case"monochromacy":return k(e);default:return""}}function q(t){return`
3
+ html[data-cba-active] * {
4
+ --cba-green: hsl(140, ${30*t}%, 50%);
5
+ --cba-red: hsl(0, 100%, 40%);
6
+ --cba-bg: hsl(220, ${5*t}%, 97%);
7
+ }
8
+ html[data-cba-active] a,
9
+ html[data-cba-active] a:visited {
10
+ text-decoration: underline;
11
+ text-decoration-thickness: 2px;
12
+ }
13
+ html[data-cba-active] .success,
14
+ html[data-cba-active] [class*="success"],
15
+ html[data-cba-active] [class*="valid"],
16
+ html[data-cba-active] [class*="positive"] {
17
+ color: #0055aa !important;
18
+ border-color: #0055aa !important;
19
+ }
20
+ html[data-cba-active] .error,
21
+ html[data-cba-active] [class*="error"],
22
+ html[data-cba-active] [class*="invalid"],
23
+ html[data-cba-active] [class*="danger"],
24
+ html[data-cba-active] [class*="negative"] {
25
+ color: #cc4400 !important;
26
+ border-color: #cc4400 !important;
27
+ }
28
+ html[data-cba-active] button:not([class*="active"]):not([class*="selected"]):not([class*="primary"]) {
29
+ border: 2px solid currentColor;
30
+ }
31
+ `}function $(t){return`
32
+ html[data-cba-active] * {
33
+ --cba-red: hsl(10, ${80*t}%, 40%);
34
+ --cba-green: hsl(140, ${60*t}%, 40%);
35
+ --cba-bg: hsl(220, ${5*t}%, 97%);
36
+ }
37
+ html[data-cba-active] a,
38
+ html[data-cba-active] a:visited {
39
+ text-decoration: underline;
40
+ text-decoration-thickness: 2px;
41
+ }
42
+ html[data-cba-active] .success,
43
+ html[data-cba-active] [class*="success"],
44
+ html[data-cba-active] [class*="valid"],
45
+ html[data-cba-active] [class*="positive"] {
46
+ color: #007744 !important;
47
+ border-color: #007744 !important;
48
+ }
49
+ html[data-cba-active] .error,
50
+ html[data-cba-active] [class*="error"],
51
+ html[data-cba-active] [class*="invalid"],
52
+ html[data-cba-active] [class*="danger"],
53
+ html[data-cba-active] [class*="negative"] {
54
+ color: #cc0033 !important;
55
+ border-color: #cc0033 !important;
56
+ }
57
+ html[data-cba-active] button:not([class*="active"]):not([class*="selected"]):not([class*="primary"]) {
58
+ border: 2px solid currentColor;
59
+ }
60
+ `}function z(t){return`
61
+ html[data-cba-active] * {
62
+ --cba-blue: hsl(200, ${80*t}%, 45%);
63
+ --cba-yellow: hsl(40, ${80*t}%, 50%);
64
+ --cba-bg: hsl(220, ${5*t}%, 97%);
65
+ }
66
+ html[data-cba-active] a,
67
+ html[data-cba-active] a:visited {
68
+ text-decoration: underline;
69
+ text-decoration-style: dotted;
70
+ text-decoration-thickness: 2px;
71
+ }
72
+ html[data-cba-active] [class*="blue"],
73
+ html[data-cba-active] [class*="info"],
74
+ html[data-cba-active] [class*="primary"] {
75
+ color: #0066aa !important;
76
+ border-color: #0066aa !important;
77
+ }
78
+ html[data-cba-active] [class*="yellow"],
79
+ html[data-cba-active] [class*="warning"] {
80
+ color: #885500 !important;
81
+ border-color: #885500 !important;
82
+ }
83
+ html[data-cba-active] button:not([class*="active"]):not([class*="selected"]):not([class*="primary"]) {
84
+ border: 2px solid currentColor;
85
+ }
86
+ `}function k(t){return`
87
+ html[data-cba-active] {
88
+ filter: grayscale(${t});
89
+ }
90
+ html[data-cba-active] img,
91
+ html[data-cba-active] video,
92
+ html[data-cba-active] canvas {
93
+ filter: grayscale(${t});
94
+ }
95
+ html[data-cba-active] a {
96
+ text-decoration: underline;
97
+ text-decoration-thickness: 2px;
98
+ font-weight: 700;
99
+ }
100
+ html[data-cba-active] [class*="error"],
101
+ html[data-cba-active] [class*="danger"],
102
+ html[data-cba-active] [class*="negative"],
103
+ html[data-cba-active] [class*="invalid"] {
104
+ border-left: 4px solid #666 !important;
105
+ padding-left: 8px !important;
106
+ }
107
+ html[data-cba-active] [class*="success"],
108
+ html[data-cba-active] [class*="valid"],
109
+ html[data-cba-active] [class*="positive"] {
110
+ border-left: 4px solid #999 !important;
111
+ padding-left: 8px !important;
112
+ }
113
+ html[data-cba-active] button,
114
+ html[data-cba-active] .btn,
115
+ html[data-cba-active] [role="button"] {
116
+ border: 2px solid currentColor;
117
+ }
118
+ html[data-cba-active] button:hover,
119
+ html[data-cba-active] .btn:hover {
120
+ outline: 3px solid #ffcc00;
121
+ outline-offset: 2px;
122
+ }
123
+ `}var d="colorblind-adapt-settings",l=class extends HTMLElement{constructor(){super(),this.attachShadow({mode:"open"}),this._open=!1,this._tab="test",this._quizAnswers={},this._quizStep=0,this._quizDone=!1,this._quizResult=null,this._activeType=null,this._activeSeverity="moderate"}get lang(){return this.getAttribute("lang")||m()}t(e){return(c[this.lang]||c.en)[e]||e}connectedCallback(){this._loadState(),this._render(),this._applyAdaptation()}attributeChangedCallback(){this.shadowRoot.innerHTML&&this._render()}_loadState(){try{let e=JSON.parse(localStorage.getItem(d));e&&e.type&&(this._activeType=e.type,this._activeSeverity=e.severity||"moderate")}catch{}}_saveState(){this._activeType?localStorage.setItem(d,JSON.stringify({type:this._activeType,severity:this._activeSeverity})):localStorage.removeItem(d)}_setOpen(e){this._open=e,this._render()}_switchTab(e){this._tab=e,e==="test"&&(this._quizAnswers={},this._quizStep=0,this._quizDone=!1,this._quizResult=null),this._render()}_answerQuestion(e){let a=n[this._quizStep];a&&(this._quizAnswers[a.id]=e,this._quizStep<n.length-1?(this._quizStep++,this._render()):(this._quizResult=v(this._quizAnswers),this._quizDone=!0,this._activeType=this._quizResult.type,this._activeSeverity=this._quizResult.severity,this._saveState(),this._applyAdaptation(),this._render()))}_selectType(e){this._activeType=e,this._saveState(),this._applyAdaptation(),this._render()}_setSeverity(e){this._activeSeverity=e,this._activeType&&(this._saveState(),this._applyAdaptation()),this._render()}_reset(){this._activeType=null,this._activeSeverity="moderate",this._quizAnswers={},this._quizStep=0,this._quizDone=!1,this._quizResult=null,this._tab="test",localStorage.removeItem(d),p(),document.documentElement.removeAttribute("data-cba-active"),this._render()}_applyAdaptation(){document.documentElement.removeAttribute("data-cba-active"),p(),this._activeType&&this._activeType!=="normal"&&(document.documentElement.setAttribute("data-cba-active",this._activeType),g(this._activeType,this._activeSeverity))}_render(){let e=i=>this.t(i);this.shadowRoot.innerHTML=`
124
+ <style>
125
+ :host {
126
+ position: fixed;
127
+ right: 20px;
128
+ bottom: 80px;
129
+ z-index: 99999;
130
+ font-family: Arial, Helvetica, sans-serif;
131
+ }
132
+ * { box-sizing: border-box; }
133
+ .widget {
134
+ display: flex;
135
+ flex-direction: column;
136
+ align-items: flex-end;
137
+ gap: 10px;
138
+ }
139
+ .toggle {
140
+ display: inline-flex;
141
+ align-items: center;
142
+ gap: 8px;
143
+ border: 2px solid #111;
144
+ border-radius: 999px;
145
+ padding: 12px 16px;
146
+ background: #fff;
147
+ color: #111;
148
+ font-size: 15px;
149
+ font-weight: 700;
150
+ cursor: pointer;
151
+ box-shadow: 0 10px 30px rgba(0,0,0,.18);
152
+ transition: transform 160ms ease, box-shadow 160ms ease;
153
+ }
154
+ .toggle:hover {
155
+ transform: translateY(-1px);
156
+ box-shadow: 0 14px 34px rgba(0,0,0,.22);
157
+ }
158
+ .toggle:focus-visible,
159
+ .control:focus-visible,
160
+ .tab:focus-visible {
161
+ outline: 3px solid #ffcc00;
162
+ outline-offset: 3px;
163
+ }
164
+ .panel {
165
+ width: min(360px, calc(100vw - 32px));
166
+ padding: 18px;
167
+ border: 2px solid #111;
168
+ border-radius: 18px;
169
+ background: #fff;
170
+ color: #111;
171
+ box-shadow: 0 18px 50px rgba(0,0,0,.25);
172
+ }
173
+ .panel[hidden] { display: none; }
174
+ .header {
175
+ display: flex;
176
+ align-items: flex-start;
177
+ justify-content: space-between;
178
+ gap: 12px;
179
+ margin-bottom: 14px;
180
+ }
181
+ .title {
182
+ margin: 0;
183
+ font-size: 18px;
184
+ line-height: 1.25;
185
+ font-weight: 800;
186
+ }
187
+ .subtitle {
188
+ margin: 4px 0 0;
189
+ font-size: 13px;
190
+ line-height: 1.4;
191
+ color: #555;
192
+ }
193
+ .close {
194
+ width: 32px; height: 32px;
195
+ border: 1px solid #ddd;
196
+ border-radius: 50%;
197
+ background: #f7f7f7;
198
+ cursor: pointer;
199
+ font-size: 20px;
200
+ line-height: 1;
201
+ }
202
+ .tabs {
203
+ display: flex;
204
+ gap: 4px;
205
+ margin-bottom: 14px;
206
+ background: #f0f0f0;
207
+ border-radius: 10px;
208
+ padding: 3px;
209
+ }
210
+ .tab {
211
+ flex: 1;
212
+ padding: 8px;
213
+ border: none;
214
+ border-radius: 8px;
215
+ background: transparent;
216
+ color: #555;
217
+ font-size: 13px;
218
+ font-weight: 700;
219
+ cursor: pointer;
220
+ transition: background 140ms, color 140ms;
221
+ }
222
+ .tab.active {
223
+ background: #fff;
224
+ color: #111;
225
+ box-shadow: 0 1px 3px rgba(0,0,0,.1);
226
+ }
227
+ .option-grid {
228
+ display: flex;
229
+ flex-direction: column;
230
+ gap: 8px;
231
+ }
232
+ .option {
233
+ display: block;
234
+ width: 100%;
235
+ padding: 12px 14px;
236
+ border: 2px solid #d6d6d6;
237
+ border-radius: 12px;
238
+ background: #fafafa;
239
+ color: #111;
240
+ font-size: 14px;
241
+ font-weight: 700;
242
+ cursor: pointer;
243
+ text-align: left;
244
+ transition: border-color 140ms ease, background 140ms ease;
245
+ }
246
+ .option:hover {
247
+ border-color: #111;
248
+ background: #f0f0f0;
249
+ }
250
+ .option.active {
251
+ border-color: #111;
252
+ background: #111;
253
+ color: #fff;
254
+ }
255
+ .step-indicator {
256
+ font-size: 12px;
257
+ color: #888;
258
+ margin-bottom: 12px;
259
+ }
260
+ .result-card {
261
+ padding: 16px;
262
+ border: 2px solid #111;
263
+ border-radius: 12px;
264
+ background: #fafafa;
265
+ margin-bottom: 12px;
266
+ }
267
+ .result-title {
268
+ font-weight: 800;
269
+ font-size: 16px;
270
+ margin-bottom: 6px;
271
+ }
272
+ .result-desc {
273
+ font-size: 13px;
274
+ line-height: 1.5;
275
+ color: #333;
276
+ }
277
+ .result-type {
278
+ display: inline-block;
279
+ padding: 3px 10px;
280
+ border-radius: 999px;
281
+ background: #111;
282
+ color: #fff;
283
+ font-size: 12px;
284
+ font-weight: 700;
285
+ margin-top: 8px;
286
+ }
287
+ .select-group {
288
+ margin-bottom: 12px;
289
+ }
290
+ .select-label {
291
+ display: block;
292
+ font-weight: 700;
293
+ font-size: 13px;
294
+ margin-bottom: 6px;
295
+ color: #333;
296
+ }
297
+ .select-input {
298
+ width: 100%;
299
+ padding: 10px 12px;
300
+ border: 2px solid #d6d6d6;
301
+ border-radius: 10px;
302
+ font-size: 14px;
303
+ font-weight: 600;
304
+ background: #fafafa;
305
+ color: #111;
306
+ cursor: pointer;
307
+ }
308
+ .select-input:focus {
309
+ border-color: #111;
310
+ outline: none;
311
+ }
312
+ .severity-group {
313
+ display: flex;
314
+ gap: 6px;
315
+ margin-top: 8px;
316
+ }
317
+ .severity-btn {
318
+ flex: 1;
319
+ padding: 8px;
320
+ border: 2px solid #d6d6d6;
321
+ border-radius: 8px;
322
+ background: #fafafa;
323
+ color: #555;
324
+ font-size: 12px;
325
+ font-weight: 700;
326
+ cursor: pointer;
327
+ text-align: center;
328
+ transition: all 140ms;
329
+ }
330
+ .severity-btn.active {
331
+ border-color: #111;
332
+ background: #111;
333
+ color: #fff;
334
+ }
335
+ .action-row {
336
+ display: flex;
337
+ gap: 8px;
338
+ margin-top: 14px;
339
+ }
340
+ .btn-primary {
341
+ flex: 1;
342
+ padding: 10px;
343
+ border: 2px solid #111;
344
+ border-radius: 10px;
345
+ background: #111;
346
+ color: #fff;
347
+ font-weight: 700;
348
+ font-size: 13px;
349
+ cursor: pointer;
350
+ }
351
+ .btn-reset {
352
+ flex: 1;
353
+ padding: 10px;
354
+ border: 2px solid #f0b4b4;
355
+ border-radius: 10px;
356
+ background: #fff4f4;
357
+ color: #8a0000;
358
+ font-weight: 700;
359
+ font-size: 13px;
360
+ cursor: pointer;
361
+ }
362
+ .btn-reset:hover {
363
+ background: #ffe0e0;
364
+ }
365
+ .tag {
366
+ display: inline-block;
367
+ padding: 2px 8px;
368
+ border-radius: 6px;
369
+ font-size: 11px;
370
+ font-weight: 700;
371
+ margin-left: 8px;
372
+ }
373
+ .tag-active {
374
+ background: #111;
375
+ color: #fff;
376
+ }
377
+ @media (max-width: 520px) {
378
+ :host {
379
+ right: 12px !important;
380
+ bottom: 70px !important;
381
+ }
382
+ .toggle { padding: 11px 14px; font-size: 14px; }
383
+ }
384
+ </style>
385
+
386
+ <div class="widget">
387
+ <section class="panel" ${this._open?"":"hidden"} aria-label="${e("panelTitle")}">
388
+ <div class="header">
389
+ <div>
390
+ <h2 class="title">
391
+ ${e("panelTitle")}
392
+ ${this._activeType&&this._activeType!=="normal"?`<span class="tag tag-active">${this._activeType}</span>`:""}
393
+ </h2>
394
+ <p class="subtitle">${e("panelSubtitle")}</p>
395
+ </div>
396
+ <button class="close" type="button" aria-label="${e("closeLabel")}">\xD7</button>
397
+ </div>
398
+
399
+ ${this._renderBody()}
400
+
401
+ ${this._activeType&&this._activeType!=="normal"?`
402
+ <div class="action-row">
403
+ <button class="btn-reset" type="button">${e("reset")}</button>
404
+ </div>
405
+ `:""}
406
+ </section>
407
+
408
+ <button
409
+ class="toggle"
410
+ type="button"
411
+ aria-expanded="${this._open?"true":"false"}"
412
+ aria-label="${e("toggleLabel")}"
413
+ >
414
+ <span class="icon" aria-hidden="true">\u{1F535}</span>
415
+ <span>${e("toggleText")}</span>
416
+ ${this._activeType&&this._activeType!=="normal"?" \u2713":""}
417
+ </button>
418
+ </div>
419
+ `,this.shadowRoot.querySelector(".toggle").addEventListener("click",()=>this._setOpen(!this._open)),this.shadowRoot.querySelector(".close").addEventListener("click",()=>this._setOpen(!1));let a=this.shadowRoot.querySelector(".panel");if(a&&a.querySelectorAll("button[data-answer]").forEach(i=>{i.addEventListener("click",()=>this._answerQuestion(i.dataset.answer))}),this._open&&this._tab==="test"&&!this._quizDone&&this.shadowRoot.querySelectorAll(".tab").forEach(i=>{i.addEventListener("click",()=>this._switchTab(i.dataset.tab))}),this._open&&this._tab==="manual"){let i=this.shadowRoot.querySelector("#cba-type-select");i&&(i.addEventListener("change",()=>this._selectType(i.value)),this.shadowRoot.querySelectorAll("[data-severity]").forEach(r=>{r.addEventListener("click",()=>this._setSeverity(r.dataset.severity))}));let o=this.shadowRoot.querySelector(".btn-reset");o&&o.addEventListener("click",()=>this._reset())}if(this._open&&this._quizDone){let i=this.shadowRoot.querySelector(".btn-reset");i&&i.addEventListener("click",()=>this._reset())}}_renderBody(){let e=a=>this.t(a);return this._activeType&&this._activeType!=="normal"?this._renderActiveState(e):this._quizDone?this._renderResult(e):`
420
+ <div class="tabs">
421
+ <button class="tab ${this._tab==="test"?"active":""}" data-tab="test" type="button">${e("testTab")}</button>
422
+ <button class="tab ${this._tab==="manual"?"active":""}" data-tab="manual" type="button">${e("manualTab")}</button>
423
+ </div>
424
+ ${this._tab==="test"?this._renderQuiz(e):this._renderManual(e)}
425
+ `}_renderQuiz(e){let a=n[this._quizStep];return a?`
426
+ <div class="step-indicator">${e("question"+(this._quizStep+1))} (${this._quizStep+1}/${n.length})</div>
427
+ <p style="font-weight:700;font-size:15px;margin:0 0 12px">${e(a.promptKey)}</p>
428
+ <div class="option-grid">
429
+ ${a.options.map((i,o)=>`
430
+ <button class="option" data-answer="${i.value}" type="button">
431
+ ${e(i.labelKey)}
432
+ </button>
433
+ `).join("")}
434
+ </div>
435
+ `:""}_renderManual(e){let a=["deuteranopia","protanopia","tritanopia","monochromacy"],i=["mild","moderate","severe"];return`
436
+ <div class="select-group">
437
+ <label class="select-label" for="cba-type-select">${e("selectType")}</label>
438
+ <select class="select-input" id="cba-type-select">
439
+ <option value="">\u2014 ${e("selectType")} \u2014</option>
440
+ ${a.map(o=>`
441
+ <option value="${o}" ${this._activeType===o?"selected":""}>
442
+ ${e(o)}
443
+ </option>
444
+ `).join("")}
445
+ </select>
446
+ </div>
447
+ ${this._activeType?`
448
+ <div class="select-group">
449
+ <label class="select-label">${e("severity")}</label>
450
+ <div class="severity-group">
451
+ ${i.map(o=>`
452
+ <button class="severity-btn ${this._activeSeverity===o?"active":""}" data-severity="${o}" type="button">
453
+ ${e(o)}
454
+ </button>
455
+ `).join("")}
456
+ </div>
457
+ </div>
458
+ `:""}
459
+ `}_renderResult(e){let a=this._quizResult;if(!a)return"";let i="type"+a.type.charAt(0).toUpperCase()+a.type.slice(1);return`
460
+ <div class="result-card">
461
+ <div class="result-title">${e("resultTitle")}</div>
462
+ <div class="result-desc">
463
+ ${e("resultDesc").replace("{type}",e(i))}
464
+ </div>
465
+ <span class="result-type">${e(a.severity)} \xB7 ${e(i)}</span>
466
+ </div>
467
+ <button class="btn-reset" type="button">${e("reset")}</button>
468
+ `}_renderActiveState(e){let a=this._quizResult;return`
469
+ <div class="result-card">
470
+ <div class="result-title">${e("resultTitle")}</div>
471
+ <span class="result-type">${this._activeType} \xB7 ${e(this._activeSeverity)}</span>
472
+ </div>
473
+ `}};b(l,"observedAttributes",["lang"]);var D=l;customElements.get("colorblind-adapt-widget")||customElements.define("colorblind-adapt-widget",l);export{l as ColorblindAdaptWidget,D as default};
474
+ //# sourceMappingURL=colorblind-adapt.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../src/colorblind-adapt/locales.js", "../src/colorblind-adapt/quiz.js", "../src/colorblind-adapt/styles.js", "../src/colorblind-adapt/index.js"],
4
+ "sourcesContent": ["export const locales = {\n uk: {\n toggleText: '\u0414\u0430\u043B\u044C\u0442\u043E\u043D\u0456\u0437\u043C',\n toggleLabel: '\u041D\u0430\u043B\u0430\u0448\u0442\u0443\u0432\u0430\u0442\u0438 \u0441\u0430\u0439\u0442 \u0434\u043B\u044F \u043B\u044E\u0434\u0435\u0439 \u0456\u0437 \u0434\u0430\u043B\u044C\u0442\u043E\u043D\u0456\u0437\u043C\u043E\u043C',\n closeLabel: '\u0417\u0430\u043A\u0440\u0438\u0442\u0438 \u043F\u0430\u043D\u0435\u043B\u044C',\n panelTitle: '\u041D\u0430\u043B\u0430\u0448\u0442\u0443\u0432\u0430\u043D\u043D\u044F \u0434\u043B\u044F \u0434\u0430\u043B\u044C\u0442\u043E\u043D\u0456\u0437\u043C\u0443',\n panelSubtitle: '\u041F\u0440\u043E\u0439\u0434\u0456\u0442\u044C \u0448\u0432\u0438\u0434\u043A\u0438\u0439 \u0442\u0435\u0441\u0442 \u0430\u0431\u043E \u043E\u0431\u0435\u0440\u0456\u0442\u044C \u0441\u0432\u0456\u0439 \u0442\u0438\u043F \u0437\u043E\u0440\u0443.',\n testTab: '\u0422\u0435\u0441\u0442',\n manualTab: '\u0412\u0440\u0443\u0447\u043D\u0443',\n startTest: '\u0420\u043E\u0437\u043F\u043E\u0447\u0430\u0442\u0438 \u0442\u0435\u0441\u0442',\n nextQuestion: '\u0414\u0430\u043B\u0456',\n question1: '\u042F\u043A\u0438\u0439 \u043A\u043E\u043B\u0456\u0440 \u0432\u0438 \u0431\u0430\u0447\u0438\u0442\u0435 \u0432 \u0446\u0435\u043D\u0442\u0440\u0456?',\n question2: '\u042F\u043A\u0435 \u0447\u0438\u0441\u043B\u043E \u0431\u0430\u0447\u0438\u0442\u0435?',\n question3: '\u042F\u043A\u0438\u0439 \u043A\u0432\u0430\u0434\u0440\u0430\u0442 \u044F\u0441\u043A\u0440\u0430\u0432\u0456\u0448\u0438\u0439?',\n optRedGreen: '\u0427\u0435\u0440\u0432\u043E\u043D\u0438\u0439 / \u0417\u0435\u043B\u0435\u043D\u0438\u0439',\n optBlueYellow: '\u0421\u0438\u043D\u0456\u0439 / \u0416\u043E\u0432\u0442\u0438\u0439',\n optNone: '\u041D\u0435 \u0431\u0430\u0447\u0443 \u0440\u0456\u0437\u043D\u0438\u0446\u0456',\n optNumber74: '74',\n optNumber21: '21',\n optNoNumber: '\u041D\u0435 \u0431\u0430\u0447\u0443 \u0447\u0438\u0441\u043B\u0430',\n optLeft: '\u041B\u0456\u0432\u0438\u0439',\n optRight: '\u041F\u0440\u0430\u0432\u0438\u0439',\n optSame: '\u041E\u0434\u043D\u0430\u043A\u043E\u0432\u0456',\n resultTitle: '\u0420\u0435\u0437\u0443\u043B\u044C\u0442\u0430\u0442 \u0442\u0435\u0441\u0442\u0443',\n resultDesc: '\u0421\u0445\u043E\u0436\u0435, \u0443 \u0432\u0430\u0441 {type}. \u0421\u0430\u0439\u0442 \u043F\u0456\u0434\u043B\u0430\u0448\u0442\u043E\u0432\u0430\u043D\u043E.',\n typeNormal: '\u043D\u043E\u0440\u043C\u0430\u043B\u044C\u043D\u0438\u0439 \u0437\u0456\u0440',\n typeDeuteranopia: '\u0434\u0430\u043B\u044C\u0442\u043E\u043D\u0456\u0437\u043C \u043D\u0430 \u0437\u0435\u043B\u0435\u043D\u0438\u0439 (deuteranopia)',\n typeProtanopia: '\u0434\u0430\u043B\u044C\u0442\u043E\u043D\u0456\u0437\u043C \u043D\u0430 \u0447\u0435\u0440\u0432\u043E\u043D\u0438\u0439 (protanopia)',\n typeTritanopia: '\u0434\u0430\u043B\u044C\u0442\u043E\u043D\u0456\u0437\u043C \u043D\u0430 \u0441\u0438\u043D\u0456\u0439 (tritanopia)',\n typeMonochromacy: '\u043F\u043E\u0432\u043D\u0430 \u0432\u0456\u0434\u0441\u0443\u0442\u043D\u0456\u0441\u0442\u044C \u043A\u043E\u043B\u044C\u043E\u0440\u043E\u0432\u043E\u0433\u043E \u0437\u043E\u0440\u0443 (monochromacy)',\n selectType: '\u041E\u0431\u0435\u0440\u0456\u0442\u044C \u0432\u0430\u0448 \u0442\u0438\u043F \u0437\u043E\u0440\u0443:',\n deuteranopia: '\u041D\u0435 \u0440\u043E\u0437\u0440\u0456\u0437\u043D\u044F\u044E \u0437\u0435\u043B\u0435\u043D\u0438\u0439',\n protanopia: '\u041D\u0435 \u0440\u043E\u0437\u0440\u0456\u0437\u043D\u044F\u044E \u0447\u0435\u0440\u0432\u043E\u043D\u0438\u0439',\n tritanopia: '\u041D\u0435 \u0440\u043E\u0437\u0440\u0456\u0437\u043D\u044F\u044E \u0441\u0438\u043D\u0456\u0439',\n monochromacy: '\u0427\u043E\u0440\u043D\u043E-\u0431\u0456\u043B\u0438\u0439 \u0437\u0456\u0440',\n apply: '\u0417\u0430\u0441\u0442\u043E\u0441\u0443\u0432\u0430\u0442\u0438',\n reset: '\u0421\u043A\u0438\u043D\u0443\u0442\u0438 \u043D\u0430\u043B\u0430\u0448\u0442\u0443\u0432\u0430\u043D\u043D\u044F',\n severity: '\u0421\u0442\u0443\u043F\u0456\u043D\u044C:',\n mild: '\u041B\u0435\u0433\u043A\u0430',\n moderate: '\u041F\u043E\u043C\u0456\u0440\u043D\u0430',\n severe: '\u0421\u0438\u043B\u044C\u043D\u0430',\n },\n en: {\n toggleText: 'Colorblind',\n toggleLabel: 'Adapt website for colorblind users',\n closeLabel: 'Close panel',\n panelTitle: 'Colorblind Settings',\n panelSubtitle: 'Take a quick test or select your vision type.',\n testTab: 'Test',\n manualTab: 'Manual',\n startTest: 'Start test',\n nextQuestion: 'Next',\n question1: 'What color do you see in the center?',\n question2: 'What number do you see?',\n question3: 'Which square is brighter?',\n optRedGreen: 'Red / Green',\n optBlueYellow: 'Blue / Yellow',\n optNone: 'No difference',\n optNumber74: '74',\n optNumber21: '21',\n optNoNumber: 'No number',\n optLeft: 'Left',\n optRight: 'Right',\n optSame: 'Same',\n resultTitle: 'Test result',\n resultDesc: 'It appears you have {type}. The site has been adapted.',\n typeNormal: 'normal vision',\n typeDeuteranopia: 'green-blindness (deuteranopia)',\n typeProtanopia: 'red-blindness (protanopia)',\n typeTritanopia: 'blue-blindness (tritanopia)',\n typeMonochromacy: 'complete color blindness (monochromacy)',\n selectType: 'Select your vision type:',\n deuteranopia: 'Cannot distinguish green',\n protanopia: 'Cannot distinguish red',\n tritanopia: 'Cannot distinguish blue',\n monochromacy: 'Black and white vision',\n apply: 'Apply',\n reset: 'Reset settings',\n severity: 'Severity:',\n mild: 'Mild',\n moderate: 'Moderate',\n severe: 'Severe',\n },\n de: {\n toggleText: 'Farbenblindheit',\n toggleLabel: 'Website f\u00FCr Farbenblinde anpassen',\n closeLabel: 'Schlie\u00DFen',\n panelTitle: 'Farbenblind-Einstellungen',\n panelSubtitle: 'Machen Sie einen schnellen Test oder w\u00E4hlen Sie Ihren Sehtyp.',\n testTab: 'Test',\n manualTab: 'Manuell',\n startTest: 'Test starten',\n nextQuestion: 'Weiter',\n question1: 'Welche Farbe sehen Sie in der Mitte?',\n question2: 'Welche Zahl sehen Sie?',\n question3: 'Welches Quadrat ist heller?',\n optRedGreen: 'Rot / Gr\u00FCn',\n optBlueYellow: 'Blau / Gelb',\n optNone: 'Kein Unterschied',\n optNumber74: '74',\n optNumber21: '21',\n optNoNumber: 'Keine Zahl',\n optLeft: 'Links',\n optRight: 'Rechts',\n optSame: 'Gleich',\n resultTitle: 'Testergebnis',\n resultDesc: 'Sie haben wahrscheinlich {type}. Die Website wurde angepasst.',\n typeNormal: 'normales Sehen',\n typeDeuteranopia: 'Gr\u00FCnblindheit (Deuteranopie)',\n typeProtanopia: 'Rotblindheit (Protanopie)',\n typeTritanopia: 'Blaublindheit (Tritanopie)',\n typeMonochromacy: 'vollst\u00E4ndige Farbenblindheit (Monochromasie)',\n selectType: 'W\u00E4hlen Sie Ihren Sehtyp:',\n deuteranopia: 'Kann Gr\u00FCn nicht unterscheiden',\n protanopia: 'Kann Rot nicht unterscheiden',\n tritanopia: 'Kann Blau nicht unterscheiden',\n monochromacy: 'Schwarz-Wei\u00DF-Sehen',\n apply: 'Anwenden',\n reset: 'Zur\u00FCcksetzen',\n severity: 'St\u00E4rke:',\n mild: 'Leicht',\n moderate: 'M\u00E4\u00DFig',\n severe: 'Stark',\n },\n}\n\nexport function detectLang() {\n const html = document.documentElement\n const htmlLang = (html.lang || navigator.language || 'en').slice(0, 2).toLowerCase()\n return htmlLang in locales ? htmlLang : 'en'\n}\n", "export const questions = [\n {\n id: 'q1',\n promptKey: 'question1',\n options: [\n { labelKey: 'optRedGreen', value: 'red-green' },\n { labelKey: 'optBlueYellow', value: 'blue-yellow' },\n { labelKey: 'optNone', value: 'none' },\n ],\n },\n {\n id: 'q2',\n promptKey: 'question2',\n options: [\n { labelKey: 'optNumber74', value: 'number' },\n { labelKey: 'optNumber21', value: 'number' },\n { labelKey: 'optNoNumber', value: 'none' },\n ],\n },\n {\n id: 'q3',\n promptKey: 'question3',\n options: [\n { labelKey: 'optLeft', value: 'left' },\n { labelKey: 'optRight', value: 'right' },\n { labelKey: 'optSame', value: 'same' },\n ],\n },\n]\n\nexport function suggestType(answers) {\n let deutScore = 0\n let protScore = 0\n let tritScore = 0\n let monoScore = 0\n\n if (answers.q1 === 'red-green') {\n protScore += 3\n deutScore += 3\n } else if (answers.q1 === 'none') {\n monoScore += 2\n }\n\n if (answers.q2 === 'none') {\n deutScore += 3\n protScore += 2\n monoScore += 2\n }\n\n if (answers.q3 === 'same') {\n monoScore += 3\n deutScore += 1\n protScore += 1\n }\n\n const scores = [\n { type: 'monochromacy', score: monoScore },\n { type: 'deuteranopia', score: deutScore },\n { type: 'protanopia', score: protScore },\n { type: 'tritanopia', score: tritScore },\n ]\n\n scores.sort((a, b) => b.score - a.score)\n\n if (scores[0].score === 0) {\n return { type: 'normal', severity: 'none' }\n }\n\n const maxScore = scores[0].score\n const secondScore = scores[1].score\n const ratio = secondScore > 0 ? maxScore / secondScore : 99\n\n let severity = 'mild'\n if (maxScore >= 7) severity = 'severe'\n else if (maxScore >= 4) severity = 'moderate'\n\n return { type: scores[0].type, severity }\n}\n", "const styleId = 'colorblind-adapt-styles'\n\nexport function injectStyles(type, severity) {\n removeStyles()\n\n if (type === 'normal' || !type) return\n\n const sheet = document.createElement('style')\n sheet.id = styleId\n sheet.textContent = buildCSS(type, severity || 'moderate')\n document.head.appendChild(sheet)\n}\n\nexport function removeStyles() {\n document.getElementById(styleId)?.remove()\n}\n\nfunction buildCSS(type, severity) {\n const intensity = severity === 'severe' ? 1 : severity === 'moderate' ? 0.6 : 0.3\n\n const blocks = [baseOverrides(type, intensity)]\n return blocks.join('\\n')\n}\n\nfunction baseOverrides(type, intensity) {\n switch (type) {\n case 'deuteranopia':\n return deuteranopiaCSS(intensity)\n case 'protanopia':\n return protanopiaCSS(intensity)\n case 'tritanopia':\n return tritanopiaCSS(intensity)\n case 'monochromacy':\n return monochromacyCSS(intensity)\n default:\n return ''\n }\n}\n\nfunction deuteranopiaCSS(i) {\n return `\n html[data-cba-active] * {\n --cba-green: hsl(140, ${30 * i}%, 50%);\n --cba-red: hsl(0, 100%, 40%);\n --cba-bg: hsl(220, ${5 * i}%, 97%);\n }\n html[data-cba-active] a,\n html[data-cba-active] a:visited {\n text-decoration: underline;\n text-decoration-thickness: 2px;\n }\n html[data-cba-active] .success,\n html[data-cba-active] [class*=\"success\"],\n html[data-cba-active] [class*=\"valid\"],\n html[data-cba-active] [class*=\"positive\"] {\n color: #0055aa !important;\n border-color: #0055aa !important;\n }\n html[data-cba-active] .error,\n html[data-cba-active] [class*=\"error\"],\n html[data-cba-active] [class*=\"invalid\"],\n html[data-cba-active] [class*=\"danger\"],\n html[data-cba-active] [class*=\"negative\"] {\n color: #cc4400 !important;\n border-color: #cc4400 !important;\n }\n html[data-cba-active] button:not([class*=\"active\"]):not([class*=\"selected\"]):not([class*=\"primary\"]) {\n border: 2px solid currentColor;\n }\n `\n}\n\nfunction protanopiaCSS(i) {\n return `\n html[data-cba-active] * {\n --cba-red: hsl(10, ${80 * i}%, 40%);\n --cba-green: hsl(140, ${60 * i}%, 40%);\n --cba-bg: hsl(220, ${5 * i}%, 97%);\n }\n html[data-cba-active] a,\n html[data-cba-active] a:visited {\n text-decoration: underline;\n text-decoration-thickness: 2px;\n }\n html[data-cba-active] .success,\n html[data-cba-active] [class*=\"success\"],\n html[data-cba-active] [class*=\"valid\"],\n html[data-cba-active] [class*=\"positive\"] {\n color: #007744 !important;\n border-color: #007744 !important;\n }\n html[data-cba-active] .error,\n html[data-cba-active] [class*=\"error\"],\n html[data-cba-active] [class*=\"invalid\"],\n html[data-cba-active] [class*=\"danger\"],\n html[data-cba-active] [class*=\"negative\"] {\n color: #cc0033 !important;\n border-color: #cc0033 !important;\n }\n html[data-cba-active] button:not([class*=\"active\"]):not([class*=\"selected\"]):not([class*=\"primary\"]) {\n border: 2px solid currentColor;\n }\n `\n}\n\nfunction tritanopiaCSS(i) {\n return `\n html[data-cba-active] * {\n --cba-blue: hsl(200, ${80 * i}%, 45%);\n --cba-yellow: hsl(40, ${80 * i}%, 50%);\n --cba-bg: hsl(220, ${5 * i}%, 97%);\n }\n html[data-cba-active] a,\n html[data-cba-active] a:visited {\n text-decoration: underline;\n text-decoration-style: dotted;\n text-decoration-thickness: 2px;\n }\n html[data-cba-active] [class*=\"blue\"],\n html[data-cba-active] [class*=\"info\"],\n html[data-cba-active] [class*=\"primary\"] {\n color: #0066aa !important;\n border-color: #0066aa !important;\n }\n html[data-cba-active] [class*=\"yellow\"],\n html[data-cba-active] [class*=\"warning\"] {\n color: #885500 !important;\n border-color: #885500 !important;\n }\n html[data-cba-active] button:not([class*=\"active\"]):not([class*=\"selected\"]):not([class*=\"primary\"]) {\n border: 2px solid currentColor;\n }\n `\n}\n\nfunction monochromacyCSS(i) {\n return `\n html[data-cba-active] {\n filter: grayscale(${i});\n }\n html[data-cba-active] img,\n html[data-cba-active] video,\n html[data-cba-active] canvas {\n filter: grayscale(${i});\n }\n html[data-cba-active] a {\n text-decoration: underline;\n text-decoration-thickness: 2px;\n font-weight: 700;\n }\n html[data-cba-active] [class*=\"error\"],\n html[data-cba-active] [class*=\"danger\"],\n html[data-cba-active] [class*=\"negative\"],\n html[data-cba-active] [class*=\"invalid\"] {\n border-left: 4px solid #666 !important;\n padding-left: 8px !important;\n }\n html[data-cba-active] [class*=\"success\"],\n html[data-cba-active] [class*=\"valid\"],\n html[data-cba-active] [class*=\"positive\"] {\n border-left: 4px solid #999 !important;\n padding-left: 8px !important;\n }\n html[data-cba-active] button,\n html[data-cba-active] .btn,\n html[data-cba-active] [role=\"button\"] {\n border: 2px solid currentColor;\n }\n html[data-cba-active] button:hover,\n html[data-cba-active] .btn:hover {\n outline: 3px solid #ffcc00;\n outline-offset: 2px;\n }\n `\n}\n", "import { locales, detectLang } from './locales.js'\nimport { questions, suggestType } from './quiz.js'\nimport { injectStyles, removeStyles } from './styles.js'\n\nconst storageKey = 'colorblind-adapt-settings'\n\nclass ColorblindAdaptWidget extends HTMLElement {\n static observedAttributes = ['lang']\n\n constructor() {\n super()\n this.attachShadow({ mode: 'open' })\n this._open = false\n this._tab = 'test'\n this._quizAnswers = {}\n this._quizStep = 0\n this._quizDone = false\n this._quizResult = null\n this._activeType = null\n this._activeSeverity = 'moderate'\n }\n\n get lang() {\n return this.getAttribute('lang') || detectLang()\n }\n\n t(key) {\n return (locales[this.lang] || locales.en)[key] || key\n }\n\n connectedCallback() {\n this._loadState()\n this._render()\n this._applyAdaptation()\n }\n\n attributeChangedCallback() {\n if (this.shadowRoot.innerHTML) this._render()\n }\n\n _loadState() {\n try {\n const saved = JSON.parse(localStorage.getItem(storageKey))\n if (saved && saved.type) {\n this._activeType = saved.type\n this._activeSeverity = saved.severity || 'moderate'\n }\n } catch {}\n }\n\n _saveState() {\n if (this._activeType) {\n localStorage.setItem(storageKey, JSON.stringify({\n type: this._activeType,\n severity: this._activeSeverity,\n }))\n } else {\n localStorage.removeItem(storageKey)\n }\n }\n\n _setOpen(val) {\n this._open = val\n this._render()\n }\n\n _switchTab(tab) {\n this._tab = tab\n if (tab === 'test') {\n this._quizAnswers = {}\n this._quizStep = 0\n this._quizDone = false\n this._quizResult = null\n }\n this._render()\n }\n\n _answerQuestion(value) {\n const q = questions[this._quizStep]\n if (!q) return\n this._quizAnswers[q.id] = value\n if (this._quizStep < questions.length - 1) {\n this._quizStep++\n this._render()\n } else {\n this._quizResult = suggestType(this._quizAnswers)\n this._quizDone = true\n this._activeType = this._quizResult.type\n this._activeSeverity = this._quizResult.severity\n this._saveState()\n this._applyAdaptation()\n this._render()\n }\n }\n\n _selectType(type) {\n this._activeType = type\n this._saveState()\n this._applyAdaptation()\n this._render()\n }\n\n _setSeverity(sev) {\n this._activeSeverity = sev\n if (this._activeType) {\n this._saveState()\n this._applyAdaptation()\n }\n this._render()\n }\n\n _reset() {\n this._activeType = null\n this._activeSeverity = 'moderate'\n this._quizAnswers = {}\n this._quizStep = 0\n this._quizDone = false\n this._quizResult = null\n this._tab = 'test'\n localStorage.removeItem(storageKey)\n removeStyles()\n document.documentElement.removeAttribute('data-cba-active')\n this._render()\n }\n\n _applyAdaptation() {\n document.documentElement.removeAttribute('data-cba-active')\n removeStyles()\n if (this._activeType && this._activeType !== 'normal') {\n document.documentElement.setAttribute('data-cba-active', this._activeType)\n injectStyles(this._activeType, this._activeSeverity)\n }\n }\n\n _render() {\n const t = (k) => this.t(k)\n\n this.shadowRoot.innerHTML = `\n <style>\n :host {\n position: fixed;\n right: 20px;\n bottom: 80px;\n z-index: 99999;\n font-family: Arial, Helvetica, sans-serif;\n }\n * { box-sizing: border-box; }\n .widget {\n display: flex;\n flex-direction: column;\n align-items: flex-end;\n gap: 10px;\n }\n .toggle {\n display: inline-flex;\n align-items: center;\n gap: 8px;\n border: 2px solid #111;\n border-radius: 999px;\n padding: 12px 16px;\n background: #fff;\n color: #111;\n font-size: 15px;\n font-weight: 700;\n cursor: pointer;\n box-shadow: 0 10px 30px rgba(0,0,0,.18);\n transition: transform 160ms ease, box-shadow 160ms ease;\n }\n .toggle:hover {\n transform: translateY(-1px);\n box-shadow: 0 14px 34px rgba(0,0,0,.22);\n }\n .toggle:focus-visible,\n .control:focus-visible,\n .tab:focus-visible {\n outline: 3px solid #ffcc00;\n outline-offset: 3px;\n }\n .panel {\n width: min(360px, calc(100vw - 32px));\n padding: 18px;\n border: 2px solid #111;\n border-radius: 18px;\n background: #fff;\n color: #111;\n box-shadow: 0 18px 50px rgba(0,0,0,.25);\n }\n .panel[hidden] { display: none; }\n .header {\n display: flex;\n align-items: flex-start;\n justify-content: space-between;\n gap: 12px;\n margin-bottom: 14px;\n }\n .title {\n margin: 0;\n font-size: 18px;\n line-height: 1.25;\n font-weight: 800;\n }\n .subtitle {\n margin: 4px 0 0;\n font-size: 13px;\n line-height: 1.4;\n color: #555;\n }\n .close {\n width: 32px; height: 32px;\n border: 1px solid #ddd;\n border-radius: 50%;\n background: #f7f7f7;\n cursor: pointer;\n font-size: 20px;\n line-height: 1;\n }\n .tabs {\n display: flex;\n gap: 4px;\n margin-bottom: 14px;\n background: #f0f0f0;\n border-radius: 10px;\n padding: 3px;\n }\n .tab {\n flex: 1;\n padding: 8px;\n border: none;\n border-radius: 8px;\n background: transparent;\n color: #555;\n font-size: 13px;\n font-weight: 700;\n cursor: pointer;\n transition: background 140ms, color 140ms;\n }\n .tab.active {\n background: #fff;\n color: #111;\n box-shadow: 0 1px 3px rgba(0,0,0,.1);\n }\n .option-grid {\n display: flex;\n flex-direction: column;\n gap: 8px;\n }\n .option {\n display: block;\n width: 100%;\n padding: 12px 14px;\n border: 2px solid #d6d6d6;\n border-radius: 12px;\n background: #fafafa;\n color: #111;\n font-size: 14px;\n font-weight: 700;\n cursor: pointer;\n text-align: left;\n transition: border-color 140ms ease, background 140ms ease;\n }\n .option:hover {\n border-color: #111;\n background: #f0f0f0;\n }\n .option.active {\n border-color: #111;\n background: #111;\n color: #fff;\n }\n .step-indicator {\n font-size: 12px;\n color: #888;\n margin-bottom: 12px;\n }\n .result-card {\n padding: 16px;\n border: 2px solid #111;\n border-radius: 12px;\n background: #fafafa;\n margin-bottom: 12px;\n }\n .result-title {\n font-weight: 800;\n font-size: 16px;\n margin-bottom: 6px;\n }\n .result-desc {\n font-size: 13px;\n line-height: 1.5;\n color: #333;\n }\n .result-type {\n display: inline-block;\n padding: 3px 10px;\n border-radius: 999px;\n background: #111;\n color: #fff;\n font-size: 12px;\n font-weight: 700;\n margin-top: 8px;\n }\n .select-group {\n margin-bottom: 12px;\n }\n .select-label {\n display: block;\n font-weight: 700;\n font-size: 13px;\n margin-bottom: 6px;\n color: #333;\n }\n .select-input {\n width: 100%;\n padding: 10px 12px;\n border: 2px solid #d6d6d6;\n border-radius: 10px;\n font-size: 14px;\n font-weight: 600;\n background: #fafafa;\n color: #111;\n cursor: pointer;\n }\n .select-input:focus {\n border-color: #111;\n outline: none;\n }\n .severity-group {\n display: flex;\n gap: 6px;\n margin-top: 8px;\n }\n .severity-btn {\n flex: 1;\n padding: 8px;\n border: 2px solid #d6d6d6;\n border-radius: 8px;\n background: #fafafa;\n color: #555;\n font-size: 12px;\n font-weight: 700;\n cursor: pointer;\n text-align: center;\n transition: all 140ms;\n }\n .severity-btn.active {\n border-color: #111;\n background: #111;\n color: #fff;\n }\n .action-row {\n display: flex;\n gap: 8px;\n margin-top: 14px;\n }\n .btn-primary {\n flex: 1;\n padding: 10px;\n border: 2px solid #111;\n border-radius: 10px;\n background: #111;\n color: #fff;\n font-weight: 700;\n font-size: 13px;\n cursor: pointer;\n }\n .btn-reset {\n flex: 1;\n padding: 10px;\n border: 2px solid #f0b4b4;\n border-radius: 10px;\n background: #fff4f4;\n color: #8a0000;\n font-weight: 700;\n font-size: 13px;\n cursor: pointer;\n }\n .btn-reset:hover {\n background: #ffe0e0;\n }\n .tag {\n display: inline-block;\n padding: 2px 8px;\n border-radius: 6px;\n font-size: 11px;\n font-weight: 700;\n margin-left: 8px;\n }\n .tag-active {\n background: #111;\n color: #fff;\n }\n @media (max-width: 520px) {\n :host {\n right: 12px !important;\n bottom: 70px !important;\n }\n .toggle { padding: 11px 14px; font-size: 14px; }\n }\n </style>\n\n <div class=\"widget\">\n <section class=\"panel\" ${this._open ? '' : 'hidden'} aria-label=\"${t('panelTitle')}\">\n <div class=\"header\">\n <div>\n <h2 class=\"title\">\n ${t('panelTitle')}\n ${this._activeType && this._activeType !== 'normal' ? `<span class=\"tag tag-active\">${this._activeType}</span>` : ''}\n </h2>\n <p class=\"subtitle\">${t('panelSubtitle')}</p>\n </div>\n <button class=\"close\" type=\"button\" aria-label=\"${t('closeLabel')}\">\u00D7</button>\n </div>\n\n ${this._renderBody()}\n\n ${this._activeType && this._activeType !== 'normal' ? `\n <div class=\"action-row\">\n <button class=\"btn-reset\" type=\"button\">${t('reset')}</button>\n </div>\n ` : ''}\n </section>\n\n <button\n class=\"toggle\"\n type=\"button\"\n aria-expanded=\"${this._open ? 'true' : 'false'}\"\n aria-label=\"${t('toggleLabel')}\"\n >\n <span class=\"icon\" aria-hidden=\"true\">\uD83D\uDD35</span>\n <span>${t('toggleText')}</span>\n ${this._activeType && this._activeType !== 'normal' ? ` \u2713` : ''}\n </button>\n </div>\n `\n\n this.shadowRoot.querySelector('.toggle').addEventListener('click', () => this._setOpen(!this._open))\n this.shadowRoot.querySelector('.close').addEventListener('click', () => this._setOpen(false))\n\n const panel = this.shadowRoot.querySelector('.panel')\n if (panel) {\n panel.querySelectorAll('button[data-answer]').forEach((btn) => {\n btn.addEventListener('click', () => this._answerQuestion(btn.dataset.answer))\n })\n }\n\n if (this._open && this._tab === 'test' && !this._quizDone) {\n this.shadowRoot.querySelectorAll('.tab').forEach((el) => {\n el.addEventListener('click', () => this._switchTab(el.dataset.tab))\n })\n }\n\n if (this._open && this._tab === 'manual') {\n const select = this.shadowRoot.querySelector('#cba-type-select')\n if (select) {\n select.addEventListener('change', () => this._selectType(select.value))\n\n const severityBtns = this.shadowRoot.querySelectorAll('[data-severity]')\n severityBtns.forEach((btn) => {\n btn.addEventListener('click', () => this._setSeverity(btn.dataset.severity))\n })\n }\n\n const resetBtn = this.shadowRoot.querySelector('.btn-reset')\n if (resetBtn) resetBtn.addEventListener('click', () => this._reset())\n }\n\n if (this._open && this._quizDone) {\n const retakeBtn = this.shadowRoot.querySelector('.btn-reset')\n if (retakeBtn) retakeBtn.addEventListener('click', () => this._reset())\n }\n }\n\n _renderBody() {\n const t = (k) => this.t(k)\n\n if (this._activeType && this._activeType !== 'normal') {\n return this._renderActiveState(t)\n }\n\n if (this._quizDone) {\n return this._renderResult(t)\n }\n\n return `\n <div class=\"tabs\">\n <button class=\"tab ${this._tab === 'test' ? 'active' : ''}\" data-tab=\"test\" type=\"button\">${t('testTab')}</button>\n <button class=\"tab ${this._tab === 'manual' ? 'active' : ''}\" data-tab=\"manual\" type=\"button\">${t('manualTab')}</button>\n </div>\n ${this._tab === 'test' ? this._renderQuiz(t) : this._renderManual(t)}\n `\n }\n\n _renderQuiz(t) {\n const q = questions[this._quizStep]\n if (!q) return ''\n\n return `\n <div class=\"step-indicator\">${t('question' + (this._quizStep + 1))} (${this._quizStep + 1}/${questions.length})</div>\n <p style=\"font-weight:700;font-size:15px;margin:0 0 12px\">${t(q.promptKey)}</p>\n <div class=\"option-grid\">\n ${q.options.map((opt, i) => `\n <button class=\"option\" data-answer=\"${opt.value}\" type=\"button\">\n ${t(opt.labelKey)}\n </button>\n `).join('')}\n </div>\n `\n }\n\n _renderManual(t) {\n const types = ['deuteranopia', 'protanopia', 'tritanopia', 'monochromacy']\n const severities = ['mild', 'moderate', 'severe']\n\n return `\n <div class=\"select-group\">\n <label class=\"select-label\" for=\"cba-type-select\">${t('selectType')}</label>\n <select class=\"select-input\" id=\"cba-type-select\">\n <option value=\"\">\u2014 ${t('selectType')} \u2014</option>\n ${types.map((type) => `\n <option value=\"${type}\" ${this._activeType === type ? 'selected' : ''}>\n ${t(type)}\n </option>\n `).join('')}\n </select>\n </div>\n ${this._activeType ? `\n <div class=\"select-group\">\n <label class=\"select-label\">${t('severity')}</label>\n <div class=\"severity-group\">\n ${severities.map((sev) => `\n <button class=\"severity-btn ${this._activeSeverity === sev ? 'active' : ''}\" data-severity=\"${sev}\" type=\"button\">\n ${t(sev)}\n </button>\n `).join('')}\n </div>\n </div>\n ` : ''}\n `\n }\n\n _renderResult(t) {\n const r = this._quizResult\n if (!r) return ''\n\n const typeKey = 'type' + r.type.charAt(0).toUpperCase() + r.type.slice(1)\n\n return `\n <div class=\"result-card\">\n <div class=\"result-title\">${t('resultTitle')}</div>\n <div class=\"result-desc\">\n ${t('resultDesc').replace('{type}', t(typeKey))}\n </div>\n <span class=\"result-type\">${t(r.severity)} \u00B7 ${t(typeKey)}</span>\n </div>\n <button class=\"btn-reset\" type=\"button\">${t('reset')}</button>\n `\n }\n\n _renderActiveState(t) {\n const r = this._quizResult\n return `\n <div class=\"result-card\">\n <div class=\"result-title\">${t('resultTitle')}</div>\n <span class=\"result-type\">${this._activeType} \u00B7 ${t(this._activeSeverity)}</span>\n </div>\n `\n }\n}\n\nexport { ColorblindAdaptWidget }\nexport default ColorblindAdaptWidget\n\nif (!customElements.get('colorblind-adapt-widget')) {\n customElements.define('colorblind-adapt-widget', ColorblindAdaptWidget)\n}\n"],
5
+ "mappings": "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AAM,KAAK,EAAEA,CAAC,EAEzB,KAAK,WAAW,UAAY;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA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",
6
+ "names": ["locales", "detectLang", "htmlLang", "questions", "suggestType", "answers", "deutScore", "protScore", "tritScore", "monoScore", "scores", "a", "b", "maxScore", "secondScore", "ratio", "severity", "styleId", "injectStyles", "type", "severity", "removeStyles", "sheet", "buildCSS", "baseOverrides", "intensity", "deuteranopiaCSS", "protanopiaCSS", "tritanopiaCSS", "monochromacyCSS", "i", "storageKey", "ColorblindAdaptWidget", "detectLang", "key", "locales", "saved", "val", "tab", "value", "q", "questions", "suggestType", "type", "sev", "removeStyles", "injectStyles", "t", "k", "panel", "btn", "el", "select", "resetBtn", "retakeBtn", "opt", "i", "types", "severities", "r", "typeKey", "__publicField", "colorblind_adapt_default", "ColorblindAdaptWidget"]
7
+ }