@thessor/widget 0.1.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.
@@ -0,0 +1,578 @@
1
+ // src/styles.ts
2
+ var styles = `
3
+ @import url('https://fonts.googleapis.com/css2?family=IBM+Plex+Sans:wght@400;500;600&family=IBM+Plex+Mono:wght@400;500&display=swap');
4
+
5
+ :host {
6
+ all: initial;
7
+ display: inline-block;
8
+ font-family: 'IBM Plex Sans', -apple-system, BlinkMacSystemFont, sans-serif;
9
+ -webkit-font-smoothing: antialiased;
10
+ }
11
+
12
+ * {
13
+ box-sizing: border-box;
14
+ }
15
+
16
+ .root {
17
+ position: relative;
18
+ display: inline-block;
19
+ }
20
+
21
+ .badge {
22
+ display: inline-flex;
23
+ align-items: center;
24
+ gap: 11px;
25
+ padding: 10px 14px;
26
+ border-radius: 10px;
27
+ border: 1px solid var(--tw-border, rgba(0, 0, 0, 0.12));
28
+ background: var(--tw-bg, #ffffff);
29
+ color: var(--tw-fg, #16171a);
30
+ cursor: pointer;
31
+ font-size: 13px;
32
+ font-weight: 500;
33
+ line-height: 1.2;
34
+ user-select: none;
35
+ transition: border-color 150ms ease, background 150ms ease;
36
+ }
37
+
38
+ .badge:hover {
39
+ border-color: var(--tw-border-hover, rgba(0, 0, 0, 0.22));
40
+ }
41
+
42
+ .badge:focus-visible {
43
+ outline: 2px solid #6c8cf5;
44
+ outline-offset: 2px;
45
+ }
46
+
47
+ :host([data-theme='dark']) .badge,
48
+ .root.theme-dark .badge {
49
+ --tw-bg: #17181c;
50
+ --tw-fg: #f3f3f5;
51
+ --tw-border: rgba(255, 255, 255, 0.14);
52
+ --tw-border-hover: rgba(255, 255, 255, 0.26);
53
+ }
54
+
55
+ .dot {
56
+ width: 8px;
57
+ height: 8px;
58
+ border-radius: 50%;
59
+ background: #2fbf6c;
60
+ flex-shrink: 0;
61
+ }
62
+
63
+ .dot.dot-muted {
64
+ background: #9a9aa2;
65
+ }
66
+
67
+ .dot.dot-loading {
68
+ animation: pulse 1.4s ease-in-out infinite;
69
+ }
70
+
71
+ .logo {
72
+ display: inline-flex;
73
+ align-items: center;
74
+ flex-shrink: 0;
75
+ height: 16px;
76
+ }
77
+
78
+ .logo-img {
79
+ display: block;
80
+ height: 100%;
81
+ width: auto;
82
+ }
83
+
84
+ .logo-dark {
85
+ display: none;
86
+ }
87
+
88
+ :host([data-theme='dark']) .logo-light,
89
+ .root.theme-dark .logo-light {
90
+ display: none;
91
+ }
92
+
93
+ :host([data-theme='dark']) .logo-dark,
94
+ .root.theme-dark .logo-dark {
95
+ display: block;
96
+ }
97
+
98
+ .label {
99
+ white-space: nowrap;
100
+ }
101
+
102
+ .label .muted-text {
103
+ color: var(--tw-fg);
104
+ opacity: 0.6;
105
+ }
106
+
107
+ /* --- Proof panel --- */
108
+
109
+ .panel-wrapper {
110
+ display: grid;
111
+ grid-template-rows: 0fr;
112
+ transition: grid-template-rows 220ms cubic-bezier(0.4, 0, 0.2, 1);
113
+ position: absolute;
114
+ top: calc(100% + 8px);
115
+ left: 0;
116
+ width: max-content;
117
+ min-width: 320px;
118
+ max-width: min(380px, 92vw);
119
+ z-index: 2147483000;
120
+ }
121
+
122
+ .panel-wrapper.open {
123
+ grid-template-rows: 1fr;
124
+ }
125
+
126
+ .panel-inner {
127
+ overflow: hidden;
128
+ min-height: 0;
129
+ }
130
+
131
+ .panel {
132
+ background: #0b0b0e;
133
+ color: #f3f3f5;
134
+ border-radius: 14px;
135
+ border: 1px solid rgba(255, 255, 255, 0.08);
136
+ padding: 16px;
137
+ opacity: 0;
138
+ transform: scale(0.96);
139
+ transform-origin: top left;
140
+ transition: opacity 220ms cubic-bezier(0.4, 0, 0.2, 1),
141
+ transform 220ms cubic-bezier(0.4, 0, 0.2, 1);
142
+ box-shadow: 0 12px 32px rgba(0, 0, 0, 0.35);
143
+ }
144
+
145
+ .panel-wrapper.open .panel {
146
+ opacity: 1;
147
+ transform: scale(1);
148
+ }
149
+
150
+ @media (prefers-reduced-motion: reduce) {
151
+ .panel-wrapper,
152
+ .panel {
153
+ transition: none !important;
154
+ }
155
+ }
156
+
157
+ .panel-header {
158
+ display: flex;
159
+ align-items: center;
160
+ justify-content: space-between;
161
+ margin-bottom: 14px;
162
+ }
163
+
164
+ .panel-title {
165
+ font-size: 13px;
166
+ font-weight: 600;
167
+ letter-spacing: 0.01em;
168
+ }
169
+
170
+ .live-indicator {
171
+ display: inline-flex;
172
+ align-items: center;
173
+ gap: 6px;
174
+ font-size: 11px;
175
+ color: #6adf9a;
176
+ font-weight: 500;
177
+ }
178
+
179
+ .live-dot {
180
+ width: 6px;
181
+ height: 6px;
182
+ border-radius: 50%;
183
+ background: #2fbf6c;
184
+ box-shadow: 0 0 0 0 rgba(47, 191, 108, 0.5);
185
+ animation: live-pulse 2s ease-out infinite;
186
+ }
187
+
188
+ @keyframes live-pulse {
189
+ 0% {
190
+ box-shadow: 0 0 0 0 rgba(47, 191, 108, 0.45);
191
+ }
192
+ 70% {
193
+ box-shadow: 0 0 0 6px rgba(47, 191, 108, 0);
194
+ }
195
+ 100% {
196
+ box-shadow: 0 0 0 0 rgba(47, 191, 108, 0);
197
+ }
198
+ }
199
+
200
+ @media (prefers-reduced-motion: reduce) {
201
+ .live-dot {
202
+ animation: none;
203
+ }
204
+ }
205
+
206
+ /* stage chain */
207
+
208
+ .stage-chain {
209
+ display: grid;
210
+ grid-template-columns: auto 1fr auto 1fr auto 1fr auto;
211
+ row-gap: 8px;
212
+ margin-bottom: 16px;
213
+ }
214
+
215
+ .stage-dot {
216
+ grid-row: 1;
217
+ align-self: center;
218
+ width: 10px;
219
+ height: 10px;
220
+ border-radius: 50%;
221
+ flex-shrink: 0;
222
+ }
223
+
224
+ .stage-track {
225
+ grid-row: 1;
226
+ align-self: center;
227
+ height: 2px;
228
+ min-width: 14px;
229
+ }
230
+
231
+ .stage-label {
232
+ grid-row: 2;
233
+ font-size: 10px;
234
+ text-align: center;
235
+ color: rgba(255, 255, 255, 0.6);
236
+ line-height: 1.3;
237
+ padding: 0 2px;
238
+ }
239
+
240
+ /* data rows */
241
+
242
+ .rows {
243
+ display: flex;
244
+ flex-direction: column;
245
+ gap: 9px;
246
+ padding: 12px 0;
247
+ border-top: 1px solid rgba(255, 255, 255, 0.08);
248
+ border-bottom: 1px solid rgba(255, 255, 255, 0.08);
249
+ }
250
+
251
+ .row {
252
+ display: flex;
253
+ align-items: baseline;
254
+ justify-content: space-between;
255
+ gap: 12px;
256
+ }
257
+
258
+ .row-label {
259
+ font-size: 11px;
260
+ color: rgba(255, 255, 255, 0.5);
261
+ flex-shrink: 0;
262
+ }
263
+
264
+ .row-value {
265
+ font-family: 'IBM Plex Mono', ui-monospace, monospace;
266
+ font-size: 11px;
267
+ color: #f3f3f5;
268
+ text-align: right;
269
+ overflow-wrap: anywhere;
270
+ }
271
+
272
+ /* footer */
273
+
274
+ .panel-footer {
275
+ display: flex;
276
+ align-items: center;
277
+ justify-content: space-between;
278
+ margin-top: 12px;
279
+ }
280
+
281
+ .view-link {
282
+ font-size: 12px;
283
+ color: #a3b4f7;
284
+ text-decoration: none;
285
+ font-weight: 500;
286
+ }
287
+
288
+ .view-link:hover {
289
+ text-decoration: underline;
290
+ }
291
+
292
+ .watermark {
293
+ font-size: 10px;
294
+ color: rgba(255, 255, 255, 0.28);
295
+ }
296
+
297
+ /* skeleton */
298
+
299
+ .skeleton-line {
300
+ height: 10px;
301
+ border-radius: 4px;
302
+ background: linear-gradient(
303
+ 90deg,
304
+ rgba(255, 255, 255, 0.06) 25%,
305
+ rgba(255, 255, 255, 0.14) 37%,
306
+ rgba(255, 255, 255, 0.06) 63%
307
+ );
308
+ background-size: 400% 100%;
309
+ animation: shimmer 1.4s ease infinite;
310
+ }
311
+
312
+ @keyframes shimmer {
313
+ 0% {
314
+ background-position: 100% 50%;
315
+ }
316
+ 100% {
317
+ background-position: 0 50%;
318
+ }
319
+ }
320
+
321
+ @keyframes pulse {
322
+ 0%, 100% {
323
+ opacity: 1;
324
+ }
325
+ 50% {
326
+ opacity: 0.4;
327
+ }
328
+ }
329
+
330
+ @media (prefers-reduced-motion: reduce) {
331
+ .skeleton-line,
332
+ .dot-loading {
333
+ animation: none;
334
+ }
335
+ }
336
+
337
+ .error-message {
338
+ font-size: 12px;
339
+ color: rgba(255, 255, 255, 0.65);
340
+ padding: 8px 0 4px;
341
+ line-height: 1.5;
342
+ }
343
+ `;
344
+
345
+ // src/assets/thessor-logo-black.png
346
+ var thessor_logo_black_default = "data:image/png;base64,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";
347
+
348
+ // src/assets/thessor-logo-white.png
349
+ var thessor_logo_white_default = "data:image/png;base64,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";
350
+
351
+ // src/logo.ts
352
+ var THESSOR_LOGO_LIGHT = thessor_logo_black_default;
353
+ var THESSOR_LOGO_DARK = thessor_logo_white_default;
354
+
355
+ // src/theme.ts
356
+ function parseRgbLightness(color) {
357
+ const match = color.match(/rgba?\(([^)]+)\)/);
358
+ if (!match || !match[1]) return null;
359
+ const parts = match[1].split(",").map((p) => parseFloat(p.trim()));
360
+ const [r, g, b, a] = parts;
361
+ if (r === void 0 || g === void 0 || b === void 0) return null;
362
+ if ([r, g, b].some((n) => Number.isNaN(n))) return null;
363
+ if (a === 0) return null;
364
+ return (0.2126 * r + 0.7152 * g + 0.0722 * b) / 255;
365
+ }
366
+ function detectHostTheme(el) {
367
+ const override = el.getAttribute("data-theme");
368
+ if (override === "light" || override === "dark") return override;
369
+ let node = el.parentElement;
370
+ while (node) {
371
+ const lightness = parseRgbLightness(getComputedStyle(node).backgroundColor);
372
+ if (lightness !== null) return lightness < 0.5 ? "dark" : "light";
373
+ node = node.parentElement;
374
+ }
375
+ return "light";
376
+ }
377
+
378
+ // src/index.ts
379
+ var STAGES = [
380
+ { label: "Hashed", color: "#6C8CF5" },
381
+ { label: "Signed (ML-DSA-65)", color: "#8E84F2" },
382
+ { label: "Merkle checkpoint", color: "#A186EF" },
383
+ { label: "Bitcoin", color: "#B189EC" }
384
+ ];
385
+ var API_BASE = "https://api.thessor.com/verify";
386
+ var PROOF_BASE = "https://thessor.com/verify";
387
+ function escapeHtml(value) {
388
+ const div = document.createElement("div");
389
+ div.textContent = value;
390
+ return div.innerHTML;
391
+ }
392
+ function formatTimestamp(iso) {
393
+ const date = new Date(iso);
394
+ if (Number.isNaN(date.getTime())) return iso;
395
+ return date.toLocaleString(void 0, { dateStyle: "medium", timeStyle: "short" });
396
+ }
397
+ function renderStageChainMarkup() {
398
+ let row = "";
399
+ STAGES.forEach((stage, i) => {
400
+ row += `<span class="stage-dot" style="background:${stage.color}"></span>`;
401
+ const next = STAGES[i + 1];
402
+ if (next) {
403
+ row += `<span class="stage-track" style="background:linear-gradient(to right, ${stage.color}, ${next.color})"></span>`;
404
+ }
405
+ });
406
+ const labels = STAGES.map(
407
+ (stage, i) => `<span class="stage-label" style="grid-column:${i * 2 + 1}">${escapeHtml(stage.label)}</span>`
408
+ ).join("");
409
+ return row + labels;
410
+ }
411
+ var ThessorBadge = class extends HTMLElement {
412
+ constructor() {
413
+ super();
414
+ this.state = "loading";
415
+ this.proof = null;
416
+ this.isOpen = false;
417
+ this.abortController = null;
418
+ this.hasRendered = false;
419
+ this.shadow = this.attachShadow({ mode: "open" });
420
+ }
421
+ connectedCallback() {
422
+ this.render();
423
+ this.applyTheme();
424
+ void this.fetchProof();
425
+ }
426
+ disconnectedCallback() {
427
+ this.abortController?.abort();
428
+ }
429
+ attributeChangedCallback(name) {
430
+ if (!this.hasRendered) return;
431
+ if (name === "data-theme") this.applyTheme();
432
+ if (name === "decision-id") void this.fetchProof();
433
+ }
434
+ applyTheme() {
435
+ const theme = detectHostTheme(this);
436
+ const root = this.shadow.querySelector(".root");
437
+ root?.classList.toggle("theme-dark", theme === "dark");
438
+ root?.classList.toggle("theme-light", theme === "light");
439
+ }
440
+ async fetchProof() {
441
+ const id = this.getAttribute("decision-id");
442
+ this.abortController?.abort();
443
+ if (!id) {
444
+ this.setState("error");
445
+ return;
446
+ }
447
+ this.setState("loading");
448
+ const controller = new AbortController();
449
+ this.abortController = controller;
450
+ try {
451
+ const res = await fetch(`${API_BASE}/${encodeURIComponent(id)}`, { signal: controller.signal });
452
+ if (!res.ok) throw new Error(`Request failed with status ${res.status}`);
453
+ const data = await res.json();
454
+ this.proof = data;
455
+ this.setState("success");
456
+ } catch (err) {
457
+ if (err instanceof DOMException && err.name === "AbortError") return;
458
+ this.proof = null;
459
+ this.setState("error");
460
+ }
461
+ }
462
+ setState(state) {
463
+ this.state = state;
464
+ this.renderBadgeContent();
465
+ this.renderPanelContent();
466
+ }
467
+ togglePanel() {
468
+ this.isOpen = !this.isOpen;
469
+ this.shadow.querySelector(".panel-wrapper")?.classList.toggle("open", this.isOpen);
470
+ this.shadow.querySelector(".badge")?.setAttribute("aria-expanded", String(this.isOpen));
471
+ }
472
+ render() {
473
+ this.shadow.innerHTML = `
474
+ <style>${styles}</style>
475
+ <div class="root">
476
+ <button type="button" class="badge" part="badge" aria-expanded="false" aria-haspopup="true">
477
+ <span class="dot dot-loading"></span>
478
+ <span class="label">Verified \xB7 Sealed by Thessor</span>
479
+ <span class="logo">
480
+ <img class="logo-img logo-light" src="${THESSOR_LOGO_LIGHT}" alt="Thessor" />
481
+ <img class="logo-img logo-dark" src="${THESSOR_LOGO_DARK}" alt="Thessor" />
482
+ </span>
483
+ </button>
484
+ <div class="panel-wrapper">
485
+ <div class="panel-inner">
486
+ <div class="panel" role="region" aria-label="Thessor verification proof">
487
+ <div class="panel-content"></div>
488
+ </div>
489
+ </div>
490
+ </div>
491
+ </div>
492
+ `;
493
+ this.shadow.querySelector(".badge")?.addEventListener("click", () => this.togglePanel());
494
+ this.hasRendered = true;
495
+ this.renderBadgeContent();
496
+ this.renderPanelContent();
497
+ }
498
+ renderBadgeContent() {
499
+ const dot = this.shadow.querySelector(".dot");
500
+ const label = this.shadow.querySelector(".label");
501
+ if (!dot || !label) return;
502
+ dot.className = "dot";
503
+ if (this.state === "error") {
504
+ dot.classList.add("dot-muted");
505
+ label.innerHTML = `<span class="muted-text">Unable to verify</span>`;
506
+ } else {
507
+ if (this.state === "loading") dot.classList.add("dot-loading");
508
+ label.textContent = "Verified \xB7 Sealed by Thessor";
509
+ }
510
+ }
511
+ renderPanelContent() {
512
+ const content = this.shadow.querySelector(".panel-content");
513
+ if (!content) return;
514
+ const id = escapeHtml(this.getAttribute("decision-id") ?? "");
515
+ const header = `
516
+ <div class="panel-header">
517
+ <span class="panel-title">Verification Proof</span>
518
+ <span class="live-indicator"><span class="live-dot"></span>Verified</span>
519
+ </div>
520
+ `;
521
+ const footer = (linkable) => `
522
+ <div class="panel-footer">
523
+ ${linkable ? `<a class="view-link" href="${PROOF_BASE}/${id}" target="_blank" rel="noopener noreferrer">View full proof \u2192</a>` : "<span></span>"}
524
+ <span class="watermark">thessor.com</span>
525
+ </div>
526
+ `;
527
+ if (this.state === "loading") {
528
+ content.innerHTML = `
529
+ ${header}
530
+ <div class="stage-chain">${renderStageChainMarkup()}</div>
531
+ <div class="rows">
532
+ <div class="skeleton-line" style="width: 90%"></div>
533
+ <div class="skeleton-line" style="width: 70%"></div>
534
+ <div class="skeleton-line" style="width: 55%"></div>
535
+ </div>
536
+ ${footer(false)}
537
+ `;
538
+ return;
539
+ }
540
+ if (this.state === "error") {
541
+ content.innerHTML = `
542
+ ${header}
543
+ <p class="error-message">We couldn't reach Thessor to verify this credential right now. This doesn't necessarily mean it's invalid \u2014 please try again shortly.</p>
544
+ ${footer(Boolean(this.getAttribute("decision-id")))}
545
+ `;
546
+ return;
547
+ }
548
+ const proof = this.proof;
549
+ if (!proof) return;
550
+ content.innerHTML = `
551
+ ${header}
552
+ <div class="stage-chain">${renderStageChainMarkup()}</div>
553
+ <div class="rows">
554
+ <div class="row">
555
+ <span class="row-label">Envelope ID</span>
556
+ <span class="row-value">${escapeHtml(proof.envelope_id)}</span>
557
+ </div>
558
+ <div class="row">
559
+ <span class="row-label">Sealed</span>
560
+ <span class="row-value">${escapeHtml(formatTimestamp(proof.created_at))}</span>
561
+ </div>
562
+ <div class="row">
563
+ <span class="row-label">Signature suite</span>
564
+ <span class="row-value">${escapeHtml(proof.signature_suite)}</span>
565
+ </div>
566
+ </div>
567
+ ${footer(true)}
568
+ `;
569
+ }
570
+ };
571
+ ThessorBadge.observedAttributes = ["decision-id", "data-theme"];
572
+ if (!customElements.get("thessor-badge")) {
573
+ customElements.define("thessor-badge", ThessorBadge);
574
+ }
575
+ export {
576
+ ThessorBadge
577
+ };
578
+ //# sourceMappingURL=thessor-widget.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../src/styles.ts", "../src/logo.ts", "../src/theme.ts", "../src/index.ts"],
4
+ "sourcesContent": ["export const styles = `\n@import url('https://fonts.googleapis.com/css2?family=IBM+Plex+Sans:wght@400;500;600&family=IBM+Plex+Mono:wght@400;500&display=swap');\n\n:host {\n all: initial;\n display: inline-block;\n font-family: 'IBM Plex Sans', -apple-system, BlinkMacSystemFont, sans-serif;\n -webkit-font-smoothing: antialiased;\n}\n\n* {\n box-sizing: border-box;\n}\n\n.root {\n position: relative;\n display: inline-block;\n}\n\n.badge {\n display: inline-flex;\n align-items: center;\n gap: 11px;\n padding: 10px 14px;\n border-radius: 10px;\n border: 1px solid var(--tw-border, rgba(0, 0, 0, 0.12));\n background: var(--tw-bg, #ffffff);\n color: var(--tw-fg, #16171a);\n cursor: pointer;\n font-size: 13px;\n font-weight: 500;\n line-height: 1.2;\n user-select: none;\n transition: border-color 150ms ease, background 150ms ease;\n}\n\n.badge:hover {\n border-color: var(--tw-border-hover, rgba(0, 0, 0, 0.22));\n}\n\n.badge:focus-visible {\n outline: 2px solid #6c8cf5;\n outline-offset: 2px;\n}\n\n:host([data-theme='dark']) .badge,\n.root.theme-dark .badge {\n --tw-bg: #17181c;\n --tw-fg: #f3f3f5;\n --tw-border: rgba(255, 255, 255, 0.14);\n --tw-border-hover: rgba(255, 255, 255, 0.26);\n}\n\n.dot {\n width: 8px;\n height: 8px;\n border-radius: 50%;\n background: #2fbf6c;\n flex-shrink: 0;\n}\n\n.dot.dot-muted {\n background: #9a9aa2;\n}\n\n.dot.dot-loading {\n animation: pulse 1.4s ease-in-out infinite;\n}\n\n.logo {\n display: inline-flex;\n align-items: center;\n flex-shrink: 0;\n height: 16px;\n}\n\n.logo-img {\n display: block;\n height: 100%;\n width: auto;\n}\n\n.logo-dark {\n display: none;\n}\n\n:host([data-theme='dark']) .logo-light,\n.root.theme-dark .logo-light {\n display: none;\n}\n\n:host([data-theme='dark']) .logo-dark,\n.root.theme-dark .logo-dark {\n display: block;\n}\n\n.label {\n white-space: nowrap;\n}\n\n.label .muted-text {\n color: var(--tw-fg);\n opacity: 0.6;\n}\n\n/* --- Proof panel --- */\n\n.panel-wrapper {\n display: grid;\n grid-template-rows: 0fr;\n transition: grid-template-rows 220ms cubic-bezier(0.4, 0, 0.2, 1);\n position: absolute;\n top: calc(100% + 8px);\n left: 0;\n width: max-content;\n min-width: 320px;\n max-width: min(380px, 92vw);\n z-index: 2147483000;\n}\n\n.panel-wrapper.open {\n grid-template-rows: 1fr;\n}\n\n.panel-inner {\n overflow: hidden;\n min-height: 0;\n}\n\n.panel {\n background: #0b0b0e;\n color: #f3f3f5;\n border-radius: 14px;\n border: 1px solid rgba(255, 255, 255, 0.08);\n padding: 16px;\n opacity: 0;\n transform: scale(0.96);\n transform-origin: top left;\n transition: opacity 220ms cubic-bezier(0.4, 0, 0.2, 1),\n transform 220ms cubic-bezier(0.4, 0, 0.2, 1);\n box-shadow: 0 12px 32px rgba(0, 0, 0, 0.35);\n}\n\n.panel-wrapper.open .panel {\n opacity: 1;\n transform: scale(1);\n}\n\n@media (prefers-reduced-motion: reduce) {\n .panel-wrapper,\n .panel {\n transition: none !important;\n }\n}\n\n.panel-header {\n display: flex;\n align-items: center;\n justify-content: space-between;\n margin-bottom: 14px;\n}\n\n.panel-title {\n font-size: 13px;\n font-weight: 600;\n letter-spacing: 0.01em;\n}\n\n.live-indicator {\n display: inline-flex;\n align-items: center;\n gap: 6px;\n font-size: 11px;\n color: #6adf9a;\n font-weight: 500;\n}\n\n.live-dot {\n width: 6px;\n height: 6px;\n border-radius: 50%;\n background: #2fbf6c;\n box-shadow: 0 0 0 0 rgba(47, 191, 108, 0.5);\n animation: live-pulse 2s ease-out infinite;\n}\n\n@keyframes live-pulse {\n 0% {\n box-shadow: 0 0 0 0 rgba(47, 191, 108, 0.45);\n }\n 70% {\n box-shadow: 0 0 0 6px rgba(47, 191, 108, 0);\n }\n 100% {\n box-shadow: 0 0 0 0 rgba(47, 191, 108, 0);\n }\n}\n\n@media (prefers-reduced-motion: reduce) {\n .live-dot {\n animation: none;\n }\n}\n\n/* stage chain */\n\n.stage-chain {\n display: grid;\n grid-template-columns: auto 1fr auto 1fr auto 1fr auto;\n row-gap: 8px;\n margin-bottom: 16px;\n}\n\n.stage-dot {\n grid-row: 1;\n align-self: center;\n width: 10px;\n height: 10px;\n border-radius: 50%;\n flex-shrink: 0;\n}\n\n.stage-track {\n grid-row: 1;\n align-self: center;\n height: 2px;\n min-width: 14px;\n}\n\n.stage-label {\n grid-row: 2;\n font-size: 10px;\n text-align: center;\n color: rgba(255, 255, 255, 0.6);\n line-height: 1.3;\n padding: 0 2px;\n}\n\n/* data rows */\n\n.rows {\n display: flex;\n flex-direction: column;\n gap: 9px;\n padding: 12px 0;\n border-top: 1px solid rgba(255, 255, 255, 0.08);\n border-bottom: 1px solid rgba(255, 255, 255, 0.08);\n}\n\n.row {\n display: flex;\n align-items: baseline;\n justify-content: space-between;\n gap: 12px;\n}\n\n.row-label {\n font-size: 11px;\n color: rgba(255, 255, 255, 0.5);\n flex-shrink: 0;\n}\n\n.row-value {\n font-family: 'IBM Plex Mono', ui-monospace, monospace;\n font-size: 11px;\n color: #f3f3f5;\n text-align: right;\n overflow-wrap: anywhere;\n}\n\n/* footer */\n\n.panel-footer {\n display: flex;\n align-items: center;\n justify-content: space-between;\n margin-top: 12px;\n}\n\n.view-link {\n font-size: 12px;\n color: #a3b4f7;\n text-decoration: none;\n font-weight: 500;\n}\n\n.view-link:hover {\n text-decoration: underline;\n}\n\n.watermark {\n font-size: 10px;\n color: rgba(255, 255, 255, 0.28);\n}\n\n/* skeleton */\n\n.skeleton-line {\n height: 10px;\n border-radius: 4px;\n background: linear-gradient(\n 90deg,\n rgba(255, 255, 255, 0.06) 25%,\n rgba(255, 255, 255, 0.14) 37%,\n rgba(255, 255, 255, 0.06) 63%\n );\n background-size: 400% 100%;\n animation: shimmer 1.4s ease infinite;\n}\n\n@keyframes shimmer {\n 0% {\n background-position: 100% 50%;\n }\n 100% {\n background-position: 0 50%;\n }\n}\n\n@keyframes pulse {\n 0%, 100% {\n opacity: 1;\n }\n 50% {\n opacity: 0.4;\n }\n}\n\n@media (prefers-reduced-motion: reduce) {\n .skeleton-line,\n .dot-loading {\n animation: none;\n }\n}\n\n.error-message {\n font-size: 12px;\n color: rgba(255, 255, 255, 0.65);\n padding: 8px 0 4px;\n line-height: 1.5;\n}\n`;\n", "import logoBlack from './assets/thessor-logo-black.png';\nimport logoWhite from './assets/thessor-logo-white.png';\n\n// Real Thessor cube-grid mark, bundled as inlined data URIs so the widget\n// stays a single file (no separate asset requests when loaded via CDN).\nexport const THESSOR_LOGO_LIGHT = logoBlack; // black mark, for light-background hosts\nexport const THESSOR_LOGO_DARK = logoWhite; // white mark, for dark-background hosts\n", "import type { ThemeMode } from './types';\n\n/**\n * Coarse perceptual lightness from an rgb()/rgba() computed-style string.\n * Not the sRGB-linearized WCAG formula \u2014 we only need a light/dark call,\n * not an accessibility contrast ratio.\n */\nfunction parseRgbLightness(color: string): number | null {\n const match = color.match(/rgba?\\(([^)]+)\\)/);\n if (!match || !match[1]) return null;\n const parts = match[1].split(',').map((p) => parseFloat(p.trim()));\n const [r, g, b, a] = parts;\n if (r === undefined || g === undefined || b === undefined) return null;\n if ([r, g, b].some((n) => Number.isNaN(n))) return null;\n if (a === 0) return null;\n return (0.2126 * r + 0.7152 * g + 0.0722 * b) / 255;\n}\n\n/**\n * Walks up from the host element looking for the nearest ancestor with a\n * non-transparent background-color to decide light vs. dark. A\n * `data-theme` attribute on the badge itself always wins.\n */\nexport function detectHostTheme(el: HTMLElement): ThemeMode {\n const override = el.getAttribute('data-theme');\n if (override === 'light' || override === 'dark') return override;\n\n let node: Element | null = el.parentElement;\n while (node) {\n const lightness = parseRgbLightness(getComputedStyle(node).backgroundColor);\n if (lightness !== null) return lightness < 0.5 ? 'dark' : 'light';\n node = node.parentElement;\n }\n return 'light';\n}\n", "import { styles } from './styles';\nimport { THESSOR_LOGO_LIGHT, THESSOR_LOGO_DARK } from './logo';\nimport { detectHostTheme } from './theme';\nimport type { BadgeState, ProofData } from './types';\n\nconst STAGES: Array<{ label: string; color: string }> = [\n { label: 'Hashed', color: '#6C8CF5' },\n { label: 'Signed (ML-DSA-65)', color: '#8E84F2' },\n { label: 'Merkle checkpoint', color: '#A186EF' },\n { label: 'Bitcoin', color: '#B189EC' },\n];\n\nconst API_BASE = 'https://api.thessor.com/verify';\nconst PROOF_BASE = 'https://thessor.com/verify';\n\nfunction escapeHtml(value: string): string {\n const div = document.createElement('div');\n div.textContent = value;\n return div.innerHTML;\n}\n\nfunction formatTimestamp(iso: string): string {\n const date = new Date(iso);\n if (Number.isNaN(date.getTime())) return iso;\n return date.toLocaleString(undefined, { dateStyle: 'medium', timeStyle: 'short' });\n}\n\nfunction renderStageChainMarkup(): string {\n let row = '';\n STAGES.forEach((stage, i) => {\n row += `<span class=\"stage-dot\" style=\"background:${stage.color}\"></span>`;\n const next = STAGES[i + 1];\n if (next) {\n row += `<span class=\"stage-track\" style=\"background:linear-gradient(to right, ${stage.color}, ${next.color})\"></span>`;\n }\n });\n const labels = STAGES.map(\n (stage, i) => `<span class=\"stage-label\" style=\"grid-column:${i * 2 + 1}\">${escapeHtml(stage.label)}</span>`\n ).join('');\n return row + labels;\n}\n\n/**\n * Framework-agnostic verification badge. Renders a pill showing Thessor's\n * verification status; clicking it expands an inline proof panel populated\n * from `GET /verify/{decision-id}`.\n *\n * Usage: <thessor-badge decision-id=\"env_...\"></thessor-badge>\n * Theme override: <thessor-badge decision-id=\"...\" data-theme=\"dark\">\n */\nexport class ThessorBadge extends HTMLElement {\n static observedAttributes = ['decision-id', 'data-theme'];\n\n private shadow: ShadowRoot;\n private state: BadgeState = 'loading';\n private proof: ProofData | null = null;\n private isOpen = false;\n private abortController: AbortController | null = null;\n private hasRendered = false;\n\n constructor() {\n super();\n this.shadow = this.attachShadow({ mode: 'open' });\n }\n\n connectedCallback(): void {\n this.render();\n this.applyTheme();\n void this.fetchProof();\n }\n\n disconnectedCallback(): void {\n this.abortController?.abort();\n }\n\n attributeChangedCallback(name: string): void {\n if (!this.hasRendered) return;\n if (name === 'data-theme') this.applyTheme();\n if (name === 'decision-id') void this.fetchProof();\n }\n\n private applyTheme(): void {\n const theme = detectHostTheme(this);\n const root = this.shadow.querySelector('.root');\n root?.classList.toggle('theme-dark', theme === 'dark');\n root?.classList.toggle('theme-light', theme === 'light');\n }\n\n private async fetchProof(): Promise<void> {\n const id = this.getAttribute('decision-id');\n this.abortController?.abort();\n\n if (!id) {\n this.setState('error');\n return;\n }\n\n this.setState('loading');\n const controller = new AbortController();\n this.abortController = controller;\n\n try {\n const res = await fetch(`${API_BASE}/${encodeURIComponent(id)}`, { signal: controller.signal });\n if (!res.ok) throw new Error(`Request failed with status ${res.status}`);\n const data = (await res.json()) as ProofData;\n this.proof = data;\n this.setState('success');\n } catch (err) {\n if (err instanceof DOMException && err.name === 'AbortError') return;\n this.proof = null;\n this.setState('error');\n }\n }\n\n private setState(state: BadgeState): void {\n this.state = state;\n this.renderBadgeContent();\n this.renderPanelContent();\n }\n\n private togglePanel(): void {\n this.isOpen = !this.isOpen;\n this.shadow.querySelector('.panel-wrapper')?.classList.toggle('open', this.isOpen);\n this.shadow.querySelector('.badge')?.setAttribute('aria-expanded', String(this.isOpen));\n }\n\n private render(): void {\n this.shadow.innerHTML = `\n <style>${styles}</style>\n <div class=\"root\">\n <button type=\"button\" class=\"badge\" part=\"badge\" aria-expanded=\"false\" aria-haspopup=\"true\">\n <span class=\"dot dot-loading\"></span>\n <span class=\"label\">Verified \u00B7 Sealed by Thessor</span>\n <span class=\"logo\">\n <img class=\"logo-img logo-light\" src=\"${THESSOR_LOGO_LIGHT}\" alt=\"Thessor\" />\n <img class=\"logo-img logo-dark\" src=\"${THESSOR_LOGO_DARK}\" alt=\"Thessor\" />\n </span>\n </button>\n <div class=\"panel-wrapper\">\n <div class=\"panel-inner\">\n <div class=\"panel\" role=\"region\" aria-label=\"Thessor verification proof\">\n <div class=\"panel-content\"></div>\n </div>\n </div>\n </div>\n </div>\n `;\n this.shadow.querySelector('.badge')?.addEventListener('click', () => this.togglePanel());\n this.hasRendered = true;\n this.renderBadgeContent();\n this.renderPanelContent();\n }\n\n private renderBadgeContent(): void {\n const dot = this.shadow.querySelector('.dot');\n const label = this.shadow.querySelector('.label');\n if (!dot || !label) return;\n\n dot.className = 'dot';\n if (this.state === 'error') {\n dot.classList.add('dot-muted');\n label.innerHTML = `<span class=\"muted-text\">Unable to verify</span>`;\n } else {\n if (this.state === 'loading') dot.classList.add('dot-loading');\n label.textContent = 'Verified \u00B7 Sealed by Thessor';\n }\n }\n\n private renderPanelContent(): void {\n const content = this.shadow.querySelector('.panel-content');\n if (!content) return;\n\n const id = escapeHtml(this.getAttribute('decision-id') ?? '');\n const header = `\n <div class=\"panel-header\">\n <span class=\"panel-title\">Verification Proof</span>\n <span class=\"live-indicator\"><span class=\"live-dot\"></span>Verified</span>\n </div>\n `;\n const footer = (linkable: boolean) => `\n <div class=\"panel-footer\">\n ${\n linkable\n ? `<a class=\"view-link\" href=\"${PROOF_BASE}/${id}\" target=\"_blank\" rel=\"noopener noreferrer\">View full proof \u2192</a>`\n : '<span></span>'\n }\n <span class=\"watermark\">thessor.com</span>\n </div>\n `;\n\n if (this.state === 'loading') {\n content.innerHTML = `\n ${header}\n <div class=\"stage-chain\">${renderStageChainMarkup()}</div>\n <div class=\"rows\">\n <div class=\"skeleton-line\" style=\"width: 90%\"></div>\n <div class=\"skeleton-line\" style=\"width: 70%\"></div>\n <div class=\"skeleton-line\" style=\"width: 55%\"></div>\n </div>\n ${footer(false)}\n `;\n return;\n }\n\n if (this.state === 'error') {\n content.innerHTML = `\n ${header}\n <p class=\"error-message\">We couldn't reach Thessor to verify this credential right now. This doesn't necessarily mean it's invalid \u2014 please try again shortly.</p>\n ${footer(Boolean(this.getAttribute('decision-id')))}\n `;\n return;\n }\n\n const proof = this.proof;\n if (!proof) return;\n\n content.innerHTML = `\n ${header}\n <div class=\"stage-chain\">${renderStageChainMarkup()}</div>\n <div class=\"rows\">\n <div class=\"row\">\n <span class=\"row-label\">Envelope ID</span>\n <span class=\"row-value\">${escapeHtml(proof.envelope_id)}</span>\n </div>\n <div class=\"row\">\n <span class=\"row-label\">Sealed</span>\n <span class=\"row-value\">${escapeHtml(formatTimestamp(proof.created_at))}</span>\n </div>\n <div class=\"row\">\n <span class=\"row-label\">Signature suite</span>\n <span class=\"row-value\">${escapeHtml(proof.signature_suite)}</span>\n </div>\n </div>\n ${footer(true)}\n `;\n }\n}\n\nif (!customElements.get('thessor-badge')) {\n customElements.define('thessor-badge', ThessorBadge);\n}\n"],
5
+ "mappings": ";AAAO,IAAM,SAAS;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;AAAA;AAAA;AAAA;AAAA;AAAA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",
6
+ "names": []
7
+ }