@zitadel/components 0.0.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.
Files changed (115) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +346 -0
  3. package/dist/atoms/index.d.mts +2 -0
  4. package/dist/atoms/index.d.ts +9 -0
  5. package/dist/atoms/index.d.ts.map +1 -0
  6. package/dist/atoms/index.mjs +2 -0
  7. package/dist/atoms/zl-alert.d.ts +56 -0
  8. package/dist/atoms/zl-alert.d.ts.map +1 -0
  9. package/dist/atoms/zl-button.d.ts +83 -0
  10. package/dist/atoms/zl-button.d.ts.map +1 -0
  11. package/dist/atoms/zl-card.d.ts +46 -0
  12. package/dist/atoms/zl-card.d.ts.map +1 -0
  13. package/dist/atoms/zl-field.d.ts +73 -0
  14. package/dist/atoms/zl-field.d.ts.map +1 -0
  15. package/dist/atoms/zl-icon.d.ts +48 -0
  16. package/dist/atoms/zl-icon.d.ts.map +1 -0
  17. package/dist/atoms/zl-page-shell.d.ts +42 -0
  18. package/dist/atoms/zl-page-shell.d.ts.map +1 -0
  19. package/dist/atoms/zl-passkey.d.ts +118 -0
  20. package/dist/atoms/zl-passkey.d.ts.map +1 -0
  21. package/dist/atoms/zl-pill.d.ts +55 -0
  22. package/dist/atoms/zl-pill.d.ts.map +1 -0
  23. package/dist/atoms-CmOTltTH.mjs +1311 -0
  24. package/dist/atoms-CmOTltTH.mjs.map +1 -0
  25. package/dist/index-7FDHEpv5.d.mts +996 -0
  26. package/dist/index-7FDHEpv5.d.mts.map +1 -0
  27. package/dist/index-DIUFZjXw.d.mts +6696 -0
  28. package/dist/index-DIUFZjXw.d.mts.map +1 -0
  29. package/dist/index-DaOSCm0T.d.mts +249 -0
  30. package/dist/index-DaOSCm0T.d.mts.map +1 -0
  31. package/dist/index-bZEvwHtq.d.mts +996 -0
  32. package/dist/index-bZEvwHtq.d.mts.map +1 -0
  33. package/dist/index.d.mts +31 -0
  34. package/dist/index.d.mts.map +1 -0
  35. package/dist/index.d.ts +16 -0
  36. package/dist/index.d.ts.map +1 -0
  37. package/dist/index.mjs +6 -0
  38. package/dist/internal/base64url.d.ts +18 -0
  39. package/dist/internal/base64url.d.ts.map +1 -0
  40. package/dist/internal/unique-id.d.ts +2 -0
  41. package/dist/internal/unique-id.d.ts.map +1 -0
  42. package/dist/manifest-DCC2FxCE.d.mts +39 -0
  43. package/dist/manifest-DCC2FxCE.d.mts.map +1 -0
  44. package/dist/manifest.d.ts +36 -0
  45. package/dist/manifest.d.ts.map +1 -0
  46. package/dist/manifests.d.mts +9 -0
  47. package/dist/manifests.d.mts.map +1 -0
  48. package/dist/manifests.d.ts +6 -0
  49. package/dist/manifests.d.ts.map +1 -0
  50. package/dist/manifests.mjs +30 -0
  51. package/dist/manifests.mjs.map +1 -0
  52. package/dist/orchestrator/api-client.d.ts +33 -0
  53. package/dist/orchestrator/api-client.d.ts.map +1 -0
  54. package/dist/orchestrator/branding-to-tokens.d.ts +28 -0
  55. package/dist/orchestrator/branding-to-tokens.d.ts.map +1 -0
  56. package/dist/orchestrator/branding-validator.d.ts +7 -0
  57. package/dist/orchestrator/branding-validator.d.ts.map +1 -0
  58. package/dist/orchestrator/branding.d.ts +76 -0
  59. package/dist/orchestrator/branding.d.ts.map +1 -0
  60. package/dist/orchestrator/font-loader.d.ts +2 -0
  61. package/dist/orchestrator/font-loader.d.ts.map +1 -0
  62. package/dist/orchestrator/index.d.mts +2 -0
  63. package/dist/orchestrator/index.d.ts +25 -0
  64. package/dist/orchestrator/index.d.ts.map +1 -0
  65. package/dist/orchestrator/index.mjs +2 -0
  66. package/dist/orchestrator/liquid.d.ts +28 -0
  67. package/dist/orchestrator/liquid.d.ts.map +1 -0
  68. package/dist/orchestrator/locales/de.d.ts +9 -0
  69. package/dist/orchestrator/locales/de.d.ts.map +1 -0
  70. package/dist/orchestrator/locales/en.d.ts +13 -0
  71. package/dist/orchestrator/locales/en.d.ts.map +1 -0
  72. package/dist/orchestrator/locales/index.d.ts +12 -0
  73. package/dist/orchestrator/locales/index.d.ts.map +1 -0
  74. package/dist/orchestrator/mandatory-gates.d.ts +26 -0
  75. package/dist/orchestrator/mandatory-gates.d.ts.map +1 -0
  76. package/dist/orchestrator/sanitiser.d.ts +6 -0
  77. package/dist/orchestrator/sanitiser.d.ts.map +1 -0
  78. package/dist/orchestrator/template-context.d.ts +55 -0
  79. package/dist/orchestrator/template-context.d.ts.map +1 -0
  80. package/dist/orchestrator/template-names.d.ts +16 -0
  81. package/dist/orchestrator/template-names.d.ts.map +1 -0
  82. package/dist/orchestrator/templates/auth-form.liquid.d.ts +14 -0
  83. package/dist/orchestrator/templates/auth-form.liquid.d.ts.map +1 -0
  84. package/dist/orchestrator/templates/default.liquid.d.ts +23 -0
  85. package/dist/orchestrator/templates/default.liquid.d.ts.map +1 -0
  86. package/dist/orchestrator/templates/passkey-upsell.liquid.d.ts +15 -0
  87. package/dist/orchestrator/templates/passkey-upsell.liquid.d.ts.map +1 -0
  88. package/dist/orchestrator/templates/signed-in.liquid.d.ts +20 -0
  89. package/dist/orchestrator/templates/signed-in.liquid.d.ts.map +1 -0
  90. package/dist/orchestrator/theme-controller.d.ts +30 -0
  91. package/dist/orchestrator/theme-controller.d.ts.map +1 -0
  92. package/dist/orchestrator/zitadel-login.d.ts +182 -0
  93. package/dist/orchestrator/zitadel-login.d.ts.map +1 -0
  94. package/dist/orchestrator/zitadel-logout.d.ts +86 -0
  95. package/dist/orchestrator/zitadel-logout.d.ts.map +1 -0
  96. package/dist/orchestrator-CNKo2WQG.mjs +3336 -0
  97. package/dist/orchestrator-CNKo2WQG.mjs.map +1 -0
  98. package/dist/styles/base.d.ts +7 -0
  99. package/dist/styles/base.d.ts.map +1 -0
  100. package/dist/styles/focus-ring.d.ts +7 -0
  101. package/dist/styles/focus-ring.d.ts.map +1 -0
  102. package/dist/styles/index.d.ts +5 -0
  103. package/dist/styles/index.d.ts.map +1 -0
  104. package/dist/styles/surface.d.ts +8 -0
  105. package/dist/styles/surface.d.ts.map +1 -0
  106. package/dist/styles/tokens.d.ts +11 -0
  107. package/dist/styles/tokens.d.ts.map +1 -0
  108. package/dist/tokens/index.d.mts +2 -0
  109. package/dist/tokens/index.d.ts +9 -0
  110. package/dist/tokens/index.d.ts.map +1 -0
  111. package/dist/tokens/index.mjs +2 -0
  112. package/dist/tokens-TXmurodq.mjs +244 -0
  113. package/dist/tokens-TXmurodq.mjs.map +1 -0
  114. package/dist/tsconfig.lib.tsbuildinfo +1 -0
  115. package/package.json +94 -0
@@ -0,0 +1,1311 @@
1
+ import { t as cssVars } from "./tokens-TXmurodq.mjs";
2
+ import { LitElement, css, html, nothing, unsafeCSS } from "lit";
3
+ import { customElement, property, state } from "lit/decorators.js";
4
+ import { unsafeSVG } from "lit/directives/unsafe-svg.js";
5
+ import { ArrowLeft, ArrowRight, Check, CircleAlert, Eye, EyeOff, Info, KeyRound, LoaderCircle, Plus, TriangleAlert, User, X } from "lucide";
6
+ //#region ../shared-component-styles/src/lit/alert-host.css?inline
7
+ var alert_host_default = ":host {\n display: block;\n}\n";
8
+ //#endregion
9
+ //#region ../shared-component-styles/src/alert.css?inline
10
+ var alert_default = ".zr-alert {\n align-items: flex-start;\n gap: var(--zl-spacing-03, 1rem);\n padding: var(--zl-spacing-03, 1rem);\n border-radius: var(--zl-radius-m, .75rem);\n background: var(--zl-color-surface-default-primary-gray, #252528);\n color: var(--zl-color-text-button-invert, #f4f4f6);\n font-family: var(--zl-font-family-sans, system-ui, sans-serif);\n font-size: .875rem;\n font-weight: 400;\n line-height: 1.25rem;\n display: flex;\n box-shadow: 0 1px 2px #1018280d;\n}\n\n.zr-alert__icon {\n color: var(--zl-color-text-error, #ea4f70);\n flex-shrink: 0;\n}\n\n.zr-alert--warning .zr-alert__icon {\n color: var(--zl-color-text-subtitle-orange, #f25543);\n}\n\n.zr-alert--success .zr-alert__icon {\n color: var(--zl-color-text-success, #33a779);\n}\n\n.zr-alert--info .zr-alert__icon {\n color: var(--zl-color-text-subtitle-gray, #bfbfcf);\n}\n\n.zr-alert__body {\n gap: var(--zl-spacing-01, .25rem);\n flex-direction: column;\n flex: auto;\n min-width: 0;\n display: flex;\n}\n\n.zr-alert__title {\n color: var(--zl-color-text-button-invert, #f4f4f6);\n font-weight: 600;\n}\n\n.zr-alert__message {\n color: var(--zl-color-border-default-white, #f4f4f6);\n margin: 0;\n}\n\n.zr-alert:not(:has(.zr-alert__title)) .zr-alert__message {\n color: var(--zl-color-text-button-invert, #f4f4f6);\n}\n\n.zr-alert__close {\n all: unset;\n width: 2.25rem;\n height: 2.25rem;\n padding: var(--zl-spacing-02, .5rem);\n border-radius: var(--zl-radius-s, .5rem);\n color: var(--zl-color-text-secondary-gray, #bfbfcf);\n cursor: pointer;\n transition: background-color var(--zl-duration-fast, .12s) var(--zl-easing-standard, cubic-bezier(.2, 0, 0, 1));\n flex-shrink: 0;\n justify-content: center;\n align-items: center;\n display: inline-flex;\n}\n\n.zr-alert__close .zr-icon {\n --zl-icon-size: 1.25rem;\n width: 1.25rem;\n height: 1.25rem;\n}\n\n.zr-alert__close:hover {\n background: var(--zl-color-gray-200, #484a57);\n}\n\n.zr-alert__close:focus-visible {\n outline: var(--zl-focus-width, 2px) solid var(--zl-focus-color, #f4f4f6);\n outline-offset: var(--zl-focus-offset, 2px);\n}\n";
11
+ //#endregion
12
+ //#region src/styles/tokens.ts
13
+ function wrap(node) {
14
+ if (typeof node === "string") return unsafeCSS(node);
15
+ const out = {};
16
+ for (const [key, value] of Object.entries(node)) out[key] = wrap(value);
17
+ return out;
18
+ }
19
+ const t = wrap(cssVars);
20
+ //#endregion
21
+ //#region src/styles/base.ts
22
+ /**
23
+ * Shared shadow-root base styles. Each atom prepends this fragment to its own
24
+ * `static styles` so font/colour inheritance, box-sizing, and resets stay
25
+ * consistent without forcing a global stylesheet on the host page.
26
+ */
27
+ const baseHostStyles = css`
28
+ :host {
29
+ box-sizing: border-box;
30
+ font-family: ${t.font.family.sans};
31
+ color: ${t.color.text.primaryWhite};
32
+ line-height: 1.5;
33
+ -webkit-font-smoothing: antialiased;
34
+ }
35
+ *,
36
+ *::before,
37
+ *::after {
38
+ box-sizing: inherit;
39
+ }
40
+ `;
41
+ //#endregion
42
+ //#region src/styles/focus-ring.ts
43
+ /**
44
+ * Visible focus indicator shared across interactive atoms. Mirrors the
45
+ * Figma button "Focused" state — a 2px white outline offset by 2px from
46
+ * the element edge. Atoms apply via `&:focus-visible { ${focusVisibleStyles} }`.
47
+ */
48
+ const focusVisibleStyles = css`
49
+ outline: ${t.focus.width} solid ${t.focus.color};
50
+ outline-offset: ${t.focus.offset};
51
+ `;
52
+ //#endregion
53
+ //#region src/styles/surface.ts
54
+ /**
55
+ * Wrap shared surface CSS (from `@zitadel/shared-component-styles`)
56
+ * for Lit `static styles`. Import `.css?inline` in atoms; `@tsdown/css` inlines
57
+ * the strings when `components` is built.
58
+ */
59
+ function surfaceStyles(...cssChunks) {
60
+ return cssChunks.map((chunk) => unsafeCSS(chunk));
61
+ }
62
+ //#endregion
63
+ //#region ../shared-component-styles/src/lit/icon-host.css?inline
64
+ var icon_host_default = ":host {\n color: inherit;\n display: contents;\n}\n";
65
+ //#endregion
66
+ //#region ../shared-component-styles/src/icon.css?inline
67
+ var icon_default = ".zr-icon {\n color: inherit;\n width: var(--zl-icon-size, 1.5rem);\n height: var(--zl-icon-size, 1.5rem);\n justify-content: center;\n align-items: center;\n display: inline-flex;\n}\n\n.zr-icon--16 {\n --zl-icon-size: 1rem;\n}\n\n.zr-icon--24 {\n --zl-icon-size: 1.5rem;\n}\n\n.zr-icon--tone-error {\n color: var(--zl-color-icon-error);\n}\n\n.zr-icon--tone-success {\n color: var(--zl-color-icon-success);\n}\n\n.zr-icon--tone-disabled {\n color: var(--zl-color-icon-disabled);\n}\n\n.zr-icon svg {\n width: 100%;\n height: 100%;\n display: block;\n}\n\n.zr-icon--spin svg {\n animation: .8s linear infinite zr-icon-spin;\n}\n\n@keyframes zr-icon-spin {\n to {\n transform: rotate(360deg);\n }\n}\n";
68
+ //#endregion
69
+ //#region \0@oxc-project+runtime@0.127.0/helpers/decorate.js
70
+ function __decorate(decorators, target, key, desc) {
71
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
72
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
73
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
74
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
75
+ }
76
+ //#endregion
77
+ //#region src/atoms/zl-icon.ts
78
+ let ZlIcon = class ZlIcon extends LitElement {
79
+ static styles = surfaceStyles(icon_host_default, icon_default);
80
+ #_name_accessor_storage = "plus";
81
+ get name() {
82
+ return this.#_name_accessor_storage;
83
+ }
84
+ set name(value) {
85
+ this.#_name_accessor_storage = value;
86
+ }
87
+ #_size_accessor_storage = "24";
88
+ get size() {
89
+ return this.#_size_accessor_storage;
90
+ }
91
+ set size(value) {
92
+ this.#_size_accessor_storage = value;
93
+ }
94
+ #_tone_accessor_storage = "default";
95
+ get tone() {
96
+ return this.#_tone_accessor_storage;
97
+ }
98
+ set tone(value) {
99
+ this.#_tone_accessor_storage = value;
100
+ }
101
+ #_spin_accessor_storage = false;
102
+ get spin() {
103
+ return this.#_spin_accessor_storage;
104
+ }
105
+ set spin(value) {
106
+ this.#_spin_accessor_storage = value;
107
+ }
108
+ #_decorative_accessor_storage = false;
109
+ get decorative() {
110
+ return this.#_decorative_accessor_storage;
111
+ }
112
+ set decorative(value) {
113
+ this.#_decorative_accessor_storage = value;
114
+ }
115
+ #_label_accessor_storage = void 0;
116
+ get label() {
117
+ return this.#_label_accessor_storage;
118
+ }
119
+ set label(value) {
120
+ this.#_label_accessor_storage = value;
121
+ }
122
+ render() {
123
+ const ariaLabel = this.label ?? DEFAULT_LABELS[this.name];
124
+ const hidden = this.decorative || !ariaLabel;
125
+ return html`
126
+ <span class=${[
127
+ "zr-icon",
128
+ `zr-icon--${this.size}`,
129
+ this.tone !== "default" ? `zr-icon--tone-${this.tone}` : "",
130
+ this.spin ? "zr-icon--spin" : ""
131
+ ].filter(Boolean).join(" ")}>
132
+ <svg
133
+ viewBox="0 0 24 24"
134
+ fill="none"
135
+ stroke="currentColor"
136
+ stroke-width="2"
137
+ stroke-linecap="round"
138
+ stroke-linejoin="round"
139
+ role=${hidden ? "presentation" : "img"}
140
+ aria-hidden=${hidden ? "true" : "false"}
141
+ aria-label=${hidden ? nothing : ariaLabel}
142
+ >${unsafeSVG(ICON_MARKUP[this.name])}</svg>
143
+ </span>
144
+ `;
145
+ }
146
+ };
147
+ __decorate([property()], ZlIcon.prototype, "name", null);
148
+ __decorate([property({ reflect: true })], ZlIcon.prototype, "size", null);
149
+ __decorate([property({ reflect: true })], ZlIcon.prototype, "tone", null);
150
+ __decorate([property({
151
+ type: Boolean,
152
+ reflect: true
153
+ })], ZlIcon.prototype, "spin", null);
154
+ __decorate([property({
155
+ type: Boolean,
156
+ reflect: true
157
+ })], ZlIcon.prototype, "decorative", null);
158
+ __decorate([property()], ZlIcon.prototype, "label", null);
159
+ ZlIcon = __decorate([customElement("zl-icon")], ZlIcon);
160
+ /** Curated mapping from our public name to a Lucide canonical icon. */
161
+ const ICON_NODES = {
162
+ plus: Plus,
163
+ "arrow-right": ArrowRight,
164
+ "arrow-left": ArrowLeft,
165
+ spinner: LoaderCircle,
166
+ check: Check,
167
+ cross: X,
168
+ warning: TriangleAlert,
169
+ "alert-circle": CircleAlert,
170
+ info: Info,
171
+ passkey: KeyRound,
172
+ user: User,
173
+ eye: Eye,
174
+ "eye-off": EyeOff
175
+ };
176
+ const DEFAULT_LABELS = {
177
+ spinner: "Loading",
178
+ warning: "Warning",
179
+ "alert-circle": "Alert",
180
+ info: "Information",
181
+ passkey: "Passkey",
182
+ user: "User",
183
+ eye: "Show",
184
+ "eye-off": "Hide"
185
+ };
186
+ const ICON_MARKUP = Object.fromEntries(Object.entries(ICON_NODES).map(([name, node]) => [name, nodeToSvgMarkup(node)]));
187
+ function nodeToSvgMarkup(node) {
188
+ return node.map(([tag, attrs]) => {
189
+ return `<${tag} ${Object.entries(attrs).filter(([, value]) => value !== void 0).map(([key, value]) => `${key}="${String(value)}"`).join(" ")}/>`;
190
+ }).join("");
191
+ }
192
+ const zlIconManifest = {
193
+ tag: "zl-icon",
194
+ attrs: [
195
+ "name",
196
+ "size",
197
+ "tone",
198
+ "spin",
199
+ "decorative",
200
+ "label"
201
+ ],
202
+ parts: [],
203
+ slots: [],
204
+ events: []
205
+ };
206
+ //#endregion
207
+ //#region src/atoms/zl-alert.ts
208
+ let ZlAlert = class ZlAlert extends LitElement {
209
+ static styles = [baseHostStyles, ...surfaceStyles(alert_host_default, alert_default)];
210
+ #_severity_accessor_storage = "error";
211
+ get severity() {
212
+ return this.#_severity_accessor_storage;
213
+ }
214
+ set severity(value) {
215
+ this.#_severity_accessor_storage = value;
216
+ }
217
+ #_heading_accessor_storage = void 0;
218
+ get heading() {
219
+ return this.#_heading_accessor_storage;
220
+ }
221
+ set heading(value) {
222
+ this.#_heading_accessor_storage = value;
223
+ }
224
+ #_dismissible_accessor_storage = false;
225
+ get dismissible() {
226
+ return this.#_dismissible_accessor_storage;
227
+ }
228
+ set dismissible(value) {
229
+ this.#_dismissible_accessor_storage = value;
230
+ }
231
+ render() {
232
+ const iconName = ICON_FOR_SEVERITY[this.severity];
233
+ return html`
234
+ <div
235
+ class="zr-alert zr-alert--${this.severity}"
236
+ part="alert"
237
+ role=${this.severity === "error" ? "alert" : "status"}
238
+ aria-live=${this.severity === "error" ? "assertive" : "polite"}
239
+ >
240
+ <zl-icon class="zr-alert__icon" part="icon" name=${iconName} size="16" decorative></zl-icon>
241
+ <div class="zr-alert__body" part="body">
242
+ ${this.heading ? html`<span class="zr-alert__title" part="title">${this.heading}</span>` : null}
243
+ <div class="zr-alert__message" part="message">
244
+ <slot></slot>
245
+ </div>
246
+ </div>
247
+ ${this.dismissible ? html`<button
248
+ type="button"
249
+ class="zr-alert__close"
250
+ part="close"
251
+ aria-label="Dismiss"
252
+ @click=${this.handleDismiss}
253
+ >
254
+ <zl-icon name="cross" size="16" label="Dismiss" decorative></zl-icon>
255
+ </button>` : null}
256
+ </div>
257
+ `;
258
+ }
259
+ handleDismiss = () => {
260
+ this.dispatchEvent(new CustomEvent("zl-dismiss", {
261
+ bubbles: true,
262
+ composed: true
263
+ }));
264
+ this.remove();
265
+ };
266
+ };
267
+ __decorate([property({ reflect: true })], ZlAlert.prototype, "severity", null);
268
+ __decorate([property()], ZlAlert.prototype, "heading", null);
269
+ __decorate([property({
270
+ type: Boolean,
271
+ reflect: true
272
+ })], ZlAlert.prototype, "dismissible", null);
273
+ ZlAlert = __decorate([customElement("zl-alert")], ZlAlert);
274
+ const ICON_FOR_SEVERITY = {
275
+ error: "alert-circle",
276
+ warning: "alert-circle",
277
+ success: "check",
278
+ info: "info"
279
+ };
280
+ const zlAlertManifest = {
281
+ tag: "zl-alert",
282
+ attrs: [
283
+ "severity",
284
+ "heading",
285
+ "dismissible"
286
+ ],
287
+ parts: [
288
+ "alert",
289
+ "icon",
290
+ "body",
291
+ "title",
292
+ "message",
293
+ "close"
294
+ ],
295
+ slots: [],
296
+ events: ["zl-dismiss"]
297
+ };
298
+ //#endregion
299
+ //#region ../shared-component-styles/src/lit/button-host.css?inline
300
+ var button_host_default = ":host {\n display: inline-flex;\n}\n\n:host([block]) {\n width: 100%;\n display: flex;\n}\n\n:host([hierarchy=\"primary\"]) {\n color: var(--zl-color-text-button-default, #0f0f11);\n}\n\n:host([hierarchy=\"secondary\"]), :host([hierarchy=\"text\"]) {\n color: var(--zl-color-text-button-invert, #f4f4f6);\n}\n\n:host([disabled]) {\n color: var(--zl-color-text-disabled, #686883);\n}\n\n::slotted([slot=\"leading\"]), ::slotted([slot=\"trailing\"]) {\n align-items: center;\n display: inline-flex;\n}\n\n.zr-btn .spinner {\n display: inline-flex;\n}\n";
301
+ //#endregion
302
+ //#region ../shared-component-styles/src/button.css?inline
303
+ var button_default = ":where(.zr-btn) {\n all: unset;\n box-sizing: border-box;\n cursor: pointer;\n font-family: var(--zl-font-family-sans, system-ui, sans-serif);\n justify-content: center;\n align-items: center;\n gap: var(--zl-spacing-02, .5rem);\n width: max-content;\n padding-inline: var(--zl-spacing-03, 1rem);\n border-radius: var(--zl-radius-s, .5rem);\n text-align: center;\n white-space: nowrap;\n transition: background-color var(--zl-duration-fast, .12s) var(--zl-easing-standard, cubic-bezier(.2, 0, 0, 1)),\n color var(--zl-duration-fast, .12s) var(--zl-easing-standard, cubic-bezier(.2, 0, 0, 1)),\n border-color var(--zl-duration-fast, .12s) var(--zl-easing-standard, cubic-bezier(.2, 0, 0, 1)),\n background-image var(--zl-duration-fast, .12s) var(--zl-easing-standard, cubic-bezier(.2, 0, 0, 1));\n border: 1px solid #0000;\n padding-block: .625rem;\n font-weight: 600;\n display: inline-flex;\n}\n\n.zr-btn:focus-visible, .zr-btn[data-state=\"focused\"] {\n outline: var(--zl-focus-width, 2px) solid var(--zl-focus-color, #f4f4f6);\n outline-offset: var(--zl-focus-offset, 2px);\n}\n\n.zr-btn--block {\n width: 100%;\n display: flex;\n}\n\n.zr-btn--medium {\n height: 3rem;\n font-size: 1rem;\n line-height: 1.5rem;\n}\n\n.zr-btn--small {\n height: 2.5rem;\n font-size: .875rem;\n line-height: 1.25rem;\n}\n\n.zr-btn--primary {\n background: var(--zl-color-surface-default-white, #f4f4f6);\n color: var(--zl-color-text-button-default, #0f0f11);\n}\n\n.zr-btn--primary:hover:not(:disabled), .zr-btn--primary:active:not(:disabled), .zr-btn--primary:focus-visible:not(:disabled), .zr-btn--primary[data-state=\"hovered\"]:not(:disabled), .zr-btn--primary[data-state=\"pressed\"]:not(:disabled), .zr-btn--primary[data-state=\"focused\"]:not(:disabled) {\n background: var(--zl-color-gray-600, #cfcfde);\n border-color: var(--zl-color-border-default-black, #252528);\n}\n\n.zr-btn--primary:disabled {\n color: var(--zl-color-text-disabled, #686883);\n cursor: not-allowed;\n}\n\n.zr-btn--secondary {\n background: var(--zl-color-border-default-black, #252528);\n color: var(--zl-color-text-button-invert, #f4f4f6);\n}\n\n.zr-btn--secondary:hover:not(:disabled), .zr-btn--secondary:active:not(:disabled), .zr-btn--secondary[data-state=\"hovered\"]:not(:disabled), .zr-btn--secondary[data-state=\"pressed\"]:not(:disabled) {\n background: var(--zl-color-gray-200, #484a57);\n}\n\n.zr-btn--secondary:disabled {\n color: var(--zl-color-text-disabled, #686883);\n cursor: not-allowed;\n}\n\n.zr-btn--text {\n color: var(--zl-color-text-button-invert, #f4f4f6);\n background: none;\n}\n\n.zr-btn--text:hover:not(:disabled), .zr-btn--text:active:not(:disabled), .zr-btn--text[data-state=\"hovered\"]:not(:disabled), .zr-btn--text[data-state=\"pressed\"]:not(:disabled) {\n background: var(--zl-color-gray-200, #484a57);\n}\n\n.zr-btn--text:focus-visible:not(:disabled), .zr-btn--text[data-state=\"focused\"]:not(:disabled) {\n background: var(--zl-color-border-default-black, #252528);\n}\n\n.zr-btn--text:disabled {\n color: var(--zl-color-text-disabled, #686883);\n cursor: not-allowed;\n}\n";
304
+ //#endregion
305
+ //#region src/atoms/zl-button.ts
306
+ let ZlButton = class ZlButton extends LitElement {
307
+ static formAssociated = true;
308
+ static shadowRootOptions = {
309
+ ...LitElement.shadowRootOptions,
310
+ delegatesFocus: true
311
+ };
312
+ static styles = [baseHostStyles, ...surfaceStyles(button_host_default, button_default)];
313
+ #_hierarchy_accessor_storage = "primary";
314
+ get hierarchy() {
315
+ return this.#_hierarchy_accessor_storage;
316
+ }
317
+ set hierarchy(value) {
318
+ this.#_hierarchy_accessor_storage = value;
319
+ }
320
+ #_size_accessor_storage = "medium";
321
+ get size() {
322
+ return this.#_size_accessor_storage;
323
+ }
324
+ set size(value) {
325
+ this.#_size_accessor_storage = value;
326
+ }
327
+ #_type_accessor_storage = "button";
328
+ get type() {
329
+ return this.#_type_accessor_storage;
330
+ }
331
+ set type(value) {
332
+ this.#_type_accessor_storage = value;
333
+ }
334
+ #_action_accessor_storage = void 0;
335
+ get action() {
336
+ return this.#_action_accessor_storage;
337
+ }
338
+ set action(value) {
339
+ this.#_action_accessor_storage = value;
340
+ }
341
+ #_loading_accessor_storage = false;
342
+ get loading() {
343
+ return this.#_loading_accessor_storage;
344
+ }
345
+ set loading(value) {
346
+ this.#_loading_accessor_storage = value;
347
+ }
348
+ #_disabled_accessor_storage = false;
349
+ get disabled() {
350
+ return this.#_disabled_accessor_storage;
351
+ }
352
+ set disabled(value) {
353
+ this.#_disabled_accessor_storage = value;
354
+ }
355
+ #_block_accessor_storage = false;
356
+ get block() {
357
+ return this.#_block_accessor_storage;
358
+ }
359
+ set block(value) {
360
+ this.#_block_accessor_storage = value;
361
+ }
362
+ #_label_accessor_storage = void 0;
363
+ get label() {
364
+ return this.#_label_accessor_storage;
365
+ }
366
+ set label(value) {
367
+ this.#_label_accessor_storage = value;
368
+ }
369
+ internals;
370
+ constructor() {
371
+ super();
372
+ this.internals = this.attachInternals();
373
+ }
374
+ focus(options) {
375
+ this.shadowRoot?.querySelector("button")?.focus(options);
376
+ }
377
+ surfaceClasses() {
378
+ return [
379
+ "root",
380
+ "zr-btn",
381
+ `zr-btn--${this.hierarchy}`,
382
+ `zr-btn--${this.size}`,
383
+ this.block ? "zr-btn--block" : ""
384
+ ].filter(Boolean).join(" ");
385
+ }
386
+ render() {
387
+ const blocked = this.disabled || this.loading;
388
+ const forcedState = this.getAttribute("data-state");
389
+ const body = this.label !== void 0 ? html`<span>${this.label}</span>` : html`<slot></slot>`;
390
+ return html`
391
+ <button
392
+ class=${this.surfaceClasses()}
393
+ part="root"
394
+ type=${this.type}
395
+ ?disabled=${blocked}
396
+ aria-busy=${this.loading ? "true" : "false"}
397
+ data-state=${forcedState ?? nothing}
398
+ @click=${this.handleClick}
399
+ >
400
+ <slot name="leading"></slot>
401
+ ${body}
402
+ ${this.loading ? html`<span class="spinner" part="spinner"><zl-icon name="spinner" size=${this.size === "small" ? "16" : "24"} spin decorative></zl-icon></span>` : html`<slot name="trailing"></slot>`}
403
+ </button>
404
+ `;
405
+ }
406
+ handleClick = (event) => {
407
+ if (this.disabled || this.loading) {
408
+ event.preventDefault();
409
+ event.stopImmediatePropagation();
410
+ return;
411
+ }
412
+ const form = this.internals.form;
413
+ if (this.type === "submit" && form) {
414
+ event.preventDefault();
415
+ form.requestSubmit();
416
+ } else if (this.type === "reset" && form) {
417
+ event.preventDefault();
418
+ form.reset();
419
+ }
420
+ this.dispatchEvent(new CustomEvent("zl-submit", {
421
+ bubbles: true,
422
+ composed: true,
423
+ detail: { action: this.action ?? null }
424
+ }));
425
+ };
426
+ };
427
+ __decorate([property({ reflect: true })], ZlButton.prototype, "hierarchy", null);
428
+ __decorate([property({ reflect: true })], ZlButton.prototype, "size", null);
429
+ __decorate([property()], ZlButton.prototype, "type", null);
430
+ __decorate([property()], ZlButton.prototype, "action", null);
431
+ __decorate([property({ type: Boolean })], ZlButton.prototype, "loading", null);
432
+ __decorate([property({
433
+ type: Boolean,
434
+ reflect: true
435
+ })], ZlButton.prototype, "disabled", null);
436
+ __decorate([property({
437
+ type: Boolean,
438
+ reflect: true
439
+ })], ZlButton.prototype, "block", null);
440
+ __decorate([property()], ZlButton.prototype, "label", null);
441
+ ZlButton = __decorate([customElement("zl-button")], ZlButton);
442
+ const zlButtonManifest = {
443
+ tag: "zl-button",
444
+ consumes: { action: {
445
+ kind: "submit",
446
+ required: false
447
+ } },
448
+ attrs: [
449
+ "hierarchy",
450
+ "size",
451
+ "type",
452
+ "action",
453
+ "loading",
454
+ "disabled",
455
+ "block",
456
+ "label"
457
+ ],
458
+ parts: ["root", "spinner"],
459
+ slots: [
460
+ "",
461
+ "leading",
462
+ "trailing"
463
+ ],
464
+ events: ["zl-submit"]
465
+ };
466
+ //#endregion
467
+ //#region ../shared-component-styles/src/lit/card-host.css?inline
468
+ var card_host_default = ":host {\n width: 100%;\n max-width: var(--zl-container-auth-card, 24rem);\n margin-inline: auto;\n display: block;\n}\n\n.zr-card ::slotted([slot=\"header\"]), .zr-card ::slotted([slot=\"footer\"]) {\n margin: 0;\n}\n";
469
+ //#endregion
470
+ //#region ../shared-component-styles/src/card.css?inline
471
+ var card_default = ".zr-card {\n width: 100%;\n max-width: var(--zl-container-auth-card, 24rem);\n border: 1px solid var(--zl-color-surface-default-primary-gray, #252528);\n border-radius: var(--zl-radius-l, 1rem);\n padding: var(--zl-spacing-05, 2rem);\n gap: var(--zl-spacing-05, 2rem);\n font-family: var(--zl-font-family-sans, system-ui, sans-serif);\n color: var(--zl-color-text-primary-white, #f4f4f6);\n box-sizing: border-box;\n background: none;\n flex-direction: column;\n margin-inline: auto;\n display: flex;\n}\n\n.zr-card--compact {\n gap: var(--zl-spacing-04, 1.5rem);\n}\n\n.zr-card__header, .zr-card__footer {\n gap: var(--zl-spacing-02, .5rem);\n flex-direction: column;\n display: flex;\n}\n\n.zr-card__region--empty {\n display: none;\n}\n\n.zr-card__body {\n gap: var(--zl-spacing-03, 1rem);\n flex-direction: column;\n display: flex;\n}\n";
472
+ //#endregion
473
+ //#region src/atoms/zl-card.ts
474
+ let ZlCard = class ZlCard extends LitElement {
475
+ static styles = [baseHostStyles, ...surfaceStyles(card_host_default, card_default)];
476
+ #_compact_accessor_storage = false;
477
+ get compact() {
478
+ return this.#_compact_accessor_storage;
479
+ }
480
+ set compact(value) {
481
+ this.#_compact_accessor_storage = value;
482
+ }
483
+ render() {
484
+ const hasHeader = this.lightDomSlotFilled("header");
485
+ const hasFooter = this.lightDomSlotFilled("footer");
486
+ return html`
487
+ <section class=${this.compact ? "zr-card zr-card--compact" : "zr-card"} part="card">
488
+ <header class=${hasHeader ? "zr-card__header" : "zr-card__header zr-card__region--empty"} part="header">
489
+ <slot name="header"></slot>
490
+ </header>
491
+ <div class="zr-card__body" part="body">
492
+ <slot></slot>
493
+ </div>
494
+ <footer class=${hasFooter ? "zr-card__footer" : "zr-card__footer zr-card__region--empty"} part="footer">
495
+ <slot name="footer"></slot>
496
+ </footer>
497
+ </section>
498
+ `;
499
+ }
500
+ /** Slotted nodes are always light-DOM children of the host in our templates. */
501
+ lightDomSlotFilled(slot) {
502
+ for (const child of this.children) if (child.getAttribute("slot") === slot) return true;
503
+ return false;
504
+ }
505
+ };
506
+ __decorate([property({
507
+ type: Boolean,
508
+ reflect: true
509
+ })], ZlCard.prototype, "compact", null);
510
+ ZlCard = __decorate([customElement("zl-card")], ZlCard);
511
+ const zlCardManifest = {
512
+ tag: "zl-card",
513
+ attrs: ["compact"],
514
+ parts: [
515
+ "card",
516
+ "header",
517
+ "body",
518
+ "footer"
519
+ ],
520
+ slots: [
521
+ "",
522
+ "header",
523
+ "footer"
524
+ ],
525
+ events: []
526
+ };
527
+ //#endregion
528
+ //#region ../shared-component-styles/src/lit/text-field-host.css?inline
529
+ var text_field_host_default = ":host {\n display: block;\n}\n\n::slotted([slot=\"prefix\"]), ::slotted([slot=\"suffix\"]) {\n color: var(--zl-color-text-secondary-gray, #bfbfcf);\n display: inline-flex;\n}\n\n.zr-field__help[hidden], .zr-field__error[hidden] {\n display: none;\n}\n\n:host([data-state=\"hovered\"]:not([disabled])) .zr-field:not(.zr-field--invalid):not(.zr-field--success) .zr-field__wrap:not(:focus-within) {\n border-color: var(--zl-color-gray-500, #9e9eb2);\n background-color: color-mix(in srgb, var(--zl-color-text-primary-white, #f4f4f6) 10%, transparent);\n}\n\n:host([data-state=\"focused\"]:not([disabled])) .zr-field:not(.zr-field--invalid):not(.zr-field--success) .zr-field__wrap {\n border-color: var(--zl-color-border-default-white, #f4f4f6);\n}\n\n:host([data-state=\"focused\"]:not([disabled])) .zr-field--invalid .zr-field__wrap {\n border-color: var(--zl-color-border-error, #ea4f70);\n}\n\n:host([data-state=\"focused\"]:not([disabled])) .zr-field--success .zr-field__wrap {\n border-color: var(--zl-color-border-success, #33a779);\n}\n";
530
+ //#endregion
531
+ //#region ../shared-component-styles/src/text-field.css?inline
532
+ var text_field_default = ".zr-field {\n align-items: stretch;\n gap: var(--zl-spacing-02, .5rem);\n font-family: var(--zl-font-family-sans, system-ui, sans-serif);\n flex-direction: column;\n display: flex;\n}\n\n.zr-field__label-row {\n justify-content: space-between;\n align-items: flex-start;\n gap: var(--zl-spacing-02, .5rem);\n width: 100%;\n display: flex;\n}\n\n.zr-field__label {\n align-items: center;\n gap: var(--zl-spacing-01, .25rem);\n color: var(--zl-color-text-primary-white, #f4f4f6);\n font-size: 1rem;\n font-weight: 600;\n line-height: 1.5rem;\n display: inline-flex;\n}\n\n.zr-field__link {\n color: var(--zl-color-icon-default-purple, #bba5e4);\n flex-shrink: 0;\n font-size: .875rem;\n font-weight: 400;\n line-height: 1.25rem;\n text-decoration: none;\n}\n\n.zr-field__link:hover {\n text-decoration: underline;\n}\n\n.zr-field__link:focus-visible {\n outline: var(--zl-focus-width, 2px) solid var(--zl-focus-color, #f4f4f6);\n outline-offset: var(--zl-focus-offset, 2px);\n border-radius: 2px;\n}\n\n.zr-field__required {\n color: var(--zl-color-text-error, #ea4f70);\n}\n\n.zr-field--disabled .zr-field__label {\n color: var(--zl-color-text-disabled, #686883);\n}\n\n.zr-field__wrap {\n align-items: center;\n gap: var(--zl-spacing-02, .5rem);\n padding-block: var(--zl-spacing-02, .5rem);\n padding-inline: var(--zl-spacing-03, 1rem);\n border-radius: var(--zl-radius-xs, .25rem);\n border: 1px solid var(--zl-color-border-default-gray-300, #686883);\n height: 2.5rem;\n transition: border-color var(--zl-duration-fast, .12s) var(--zl-easing-standard, cubic-bezier(.2, 0, 0, 1)),\n background-color var(--zl-duration-fast, .12s) var(--zl-easing-standard, cubic-bezier(.2, 0, 0, 1));\n box-sizing: border-box;\n background: none;\n display: flex;\n position: relative;\n overflow: visible;\n}\n\n.zr-field__wrap--trailing {\n padding-inline-end: 2.5rem;\n}\n\n.zr-field:not(.zr-field--disabled) .zr-field__wrap:hover:not(:focus-within) {\n border-color: var(--zl-color-gray-500, #9e9eb2);\n background-color: color-mix(in srgb, var(--zl-color-text-primary-white, #f4f4f6) 10%, transparent);\n}\n\n.zr-field:not(.zr-field--invalid):not(.zr-field--disabled):not(.zr-field--success) .zr-field__wrap:has(.zr-field__input:not(:placeholder-shown)):not(:focus-within) {\n border-color: var(--zl-color-border-default-gray-400, #82829c);\n}\n\n.zr-field:not(.zr-field--invalid):not(.zr-field--disabled):not(.zr-field--success) .zr-field__wrap:focus-within {\n border-color: var(--zl-color-border-default-white, #f4f4f6);\n outline: none;\n}\n\n.zr-field--invalid .zr-field__wrap {\n border-color: var(--zl-color-border-error, #ea4f70);\n}\n\n.zr-field--invalid .zr-field__wrap:focus-within {\n border-color: var(--zl-color-border-error, #ea4f70);\n outline: none;\n}\n\n.zr-field--success .zr-field__wrap {\n border-color: var(--zl-color-border-success, #33a779);\n}\n\n.zr-field--success .zr-field__wrap:focus-within {\n border-color: var(--zl-color-border-success, #33a779);\n outline: none;\n}\n\n.zr-field--disabled .zr-field__wrap {\n border-color: var(--zl-color-border-default-gray-200, #484a57);\n}\n\n.zr-field__input {\n min-width: 0;\n height: 100%;\n color: var(--zl-color-text-primary-white, #f4f4f6);\n background: none;\n border: 0;\n outline: none;\n flex: auto;\n padding: 0;\n font-family: inherit;\n font-size: .875rem;\n font-weight: 400;\n line-height: 1.25rem;\n}\n\n.zr-field__input[type=\"password\"] {\n letter-spacing: .125rem;\n}\n\n.zr-field__input::placeholder {\n color: var(--zl-color-text-secondary-gray, #bfbfcf);\n}\n\n.zr-field__input:focus, .zr-field__input:focus-visible {\n outline: none;\n}\n\n.zr-field__input:disabled {\n cursor: not-allowed;\n color: var(--zl-color-text-disabled, #686883);\n}\n\n.zr-field--disabled .zr-field__wrap:hover {\n border-color: var(--zl-color-border-default-gray-200, #484a57);\n background-color: #0000;\n}\n\n.zr-field__trailing {\n width: 1rem;\n height: 1rem;\n color: var(--zl-color-text-secondary-gray, #bfbfcf);\n justify-content: center;\n align-items: center;\n display: inline-flex;\n position: absolute;\n top: 50%;\n right: .9375rem;\n transform: translateY(-50%);\n}\n\n.zr-field__trailing-action {\n color: inherit;\n cursor: pointer;\n background: none;\n border: 0;\n justify-content: center;\n align-items: center;\n margin: 0;\n padding: 0;\n line-height: 0;\n display: inline-flex;\n}\n\n.zr-field__trailing-action:focus-visible {\n outline: var(--zl-focus-width, 2px) solid var(--zl-focus-color, #f4f4f6);\n outline-offset: var(--zl-focus-offset, 2px);\n border-radius: 2px;\n}\n\n.zr-field__trailing-action:disabled {\n cursor: not-allowed;\n}\n\n.zr-field--invalid .zr-field__trailing {\n color: var(--zl-color-text-error, #ea4f70);\n}\n\n.zr-field--success .zr-field__trailing {\n color: var(--zl-color-text-success, #33a779);\n}\n\n.zr-field__help {\n color: var(--zl-color-text-primary-white, #f4f4f6);\n font-size: .75rem;\n line-height: 1rem;\n}\n\n.zr-field__success {\n color: var(--zl-color-text-success, #33a779);\n font-size: .75rem;\n line-height: 1rem;\n}\n\n.zr-field__error {\n color: var(--zl-color-text-error, #ea4f70);\n font-size: .75rem;\n line-height: 1rem;\n}\n";
533
+ //#endregion
534
+ //#region src/internal/unique-id.ts
535
+ /**
536
+ * Monotonic counter for DOM IDs that need to be unique within a document but
537
+ * stable across renders. Used by atoms that wire `<label for>` ↔ `<input id>`
538
+ * inside their Shadow DOM.
539
+ *
540
+ * A counter beats `Math.random()` and `crypto.randomUUID()` here:
541
+ *
542
+ * - Tests get deterministic IDs.
543
+ * - There's zero collision risk within a page.
544
+ * - It's an order of magnitude faster on each component instantiation.
545
+ */
546
+ let counter = 0;
547
+ function nextUid(prefix) {
548
+ counter += 1;
549
+ return `${prefix}-${counter}`;
550
+ }
551
+ //#endregion
552
+ //#region src/atoms/zl-field.ts
553
+ let ZlField = class ZlField extends LitElement {
554
+ static formAssociated = true;
555
+ static shadowRootOptions = {
556
+ ...LitElement.shadowRootOptions,
557
+ delegatesFocus: true
558
+ };
559
+ static styles = [baseHostStyles, ...surfaceStyles(text_field_host_default, text_field_default)];
560
+ #_name_accessor_storage = "";
561
+ get name() {
562
+ return this.#_name_accessor_storage;
563
+ }
564
+ set name(value) {
565
+ this.#_name_accessor_storage = value;
566
+ }
567
+ #_label_accessor_storage = "";
568
+ get label() {
569
+ return this.#_label_accessor_storage;
570
+ }
571
+ set label(value) {
572
+ this.#_label_accessor_storage = value;
573
+ }
574
+ #_type_accessor_storage = "text";
575
+ get type() {
576
+ return this.#_type_accessor_storage;
577
+ }
578
+ set type(value) {
579
+ this.#_type_accessor_storage = value;
580
+ }
581
+ #_value_accessor_storage = "";
582
+ get value() {
583
+ return this.#_value_accessor_storage;
584
+ }
585
+ set value(value) {
586
+ this.#_value_accessor_storage = value;
587
+ }
588
+ #_placeholder_accessor_storage = "";
589
+ get placeholder() {
590
+ return this.#_placeholder_accessor_storage;
591
+ }
592
+ set placeholder(value) {
593
+ this.#_placeholder_accessor_storage = value;
594
+ }
595
+ #_autocomplete_accessor_storage = void 0;
596
+ get autocomplete() {
597
+ return this.#_autocomplete_accessor_storage;
598
+ }
599
+ set autocomplete(value) {
600
+ this.#_autocomplete_accessor_storage = value;
601
+ }
602
+ #_pattern_accessor_storage = void 0;
603
+ get pattern() {
604
+ return this.#_pattern_accessor_storage;
605
+ }
606
+ set pattern(value) {
607
+ this.#_pattern_accessor_storage = value;
608
+ }
609
+ #_error_accessor_storage = "";
610
+ get error() {
611
+ return this.#_error_accessor_storage;
612
+ }
613
+ set error(value) {
614
+ this.#_error_accessor_storage = value;
615
+ }
616
+ #_success_accessor_storage = "";
617
+ get success() {
618
+ return this.#_success_accessor_storage;
619
+ }
620
+ set success(value) {
621
+ this.#_success_accessor_storage = value;
622
+ }
623
+ #_forgotPasswordHref_accessor_storage = void 0;
624
+ get forgotPasswordHref() {
625
+ return this.#_forgotPasswordHref_accessor_storage;
626
+ }
627
+ set forgotPasswordHref(value) {
628
+ this.#_forgotPasswordHref_accessor_storage = value;
629
+ }
630
+ #_forgotPasswordLabel_accessor_storage = "Forgot password?";
631
+ get forgotPasswordLabel() {
632
+ return this.#_forgotPasswordLabel_accessor_storage;
633
+ }
634
+ set forgotPasswordLabel(value) {
635
+ this.#_forgotPasswordLabel_accessor_storage = value;
636
+ }
637
+ #_trailingIcon_accessor_storage = true;
638
+ get trailingIcon() {
639
+ return this.#_trailingIcon_accessor_storage;
640
+ }
641
+ set trailingIcon(value) {
642
+ this.#_trailingIcon_accessor_storage = value;
643
+ }
644
+ #_required_accessor_storage = false;
645
+ get required() {
646
+ return this.#_required_accessor_storage;
647
+ }
648
+ set required(value) {
649
+ this.#_required_accessor_storage = value;
650
+ }
651
+ #_disabled_accessor_storage = false;
652
+ get disabled() {
653
+ return this.#_disabled_accessor_storage;
654
+ }
655
+ set disabled(value) {
656
+ this.#_disabled_accessor_storage = value;
657
+ }
658
+ #_invalid_accessor_storage = false;
659
+ get invalid() {
660
+ return this.#_invalid_accessor_storage;
661
+ }
662
+ set invalid(value) {
663
+ this.#_invalid_accessor_storage = value;
664
+ }
665
+ #_hasHelp_accessor_storage = false;
666
+ get hasHelp() {
667
+ return this.#_hasHelp_accessor_storage;
668
+ }
669
+ set hasHelp(value) {
670
+ this.#_hasHelp_accessor_storage = value;
671
+ }
672
+ #_hasSuffixSlot_accessor_storage = false;
673
+ get hasSuffixSlot() {
674
+ return this.#_hasSuffixSlot_accessor_storage;
675
+ }
676
+ set hasSuffixSlot(value) {
677
+ this.#_hasSuffixSlot_accessor_storage = value;
678
+ }
679
+ inputId = nextUid("zl-field");
680
+ internals;
681
+ constructor() {
682
+ super();
683
+ this.internals = this.attachInternals();
684
+ }
685
+ connectedCallback() {
686
+ super.connectedCallback();
687
+ this.syncFormState();
688
+ }
689
+ willUpdate(changed) {
690
+ if (changed.has("value") || changed.has("required") || changed.has("error")) this.syncFormState();
691
+ }
692
+ formResetCallback() {
693
+ this.value = "";
694
+ }
695
+ formStateRestoreCallback(state) {
696
+ this.value = state ?? "";
697
+ }
698
+ focus(options) {
699
+ this.shadowRoot?.querySelector("input")?.focus(options);
700
+ }
701
+ render() {
702
+ const labelId = `${this.inputId}-label`;
703
+ const errorId = `${this.inputId}-error`;
704
+ const successId = `${this.inputId}-success`;
705
+ const helpId = `${this.inputId}-help`;
706
+ const showError = Boolean(this.error);
707
+ const showSuccess = Boolean(this.success) && !showError && !this.invalid;
708
+ const describedBy = [
709
+ showError ? errorId : null,
710
+ showSuccess ? successId : null,
711
+ this.hasHelp ? helpId : null
712
+ ].filter(Boolean).join(" ");
713
+ const rootClass = [
714
+ "zr-field",
715
+ this.invalid || showError ? "zr-field--invalid" : "",
716
+ showSuccess ? "zr-field--success" : "",
717
+ this.disabled ? "zr-field--disabled" : ""
718
+ ].filter(Boolean).join(" ");
719
+ const showDefaultTrailing = this.trailingIcon && !this.hasSuffixSlot && !this.disabled;
720
+ const trailing = showDefaultTrailing ? this.renderTrailingIcon() : null;
721
+ const wrapClass = ["zr-field__wrap", showDefaultTrailing ? "zr-field__wrap--trailing" : ""].filter(Boolean).join(" ");
722
+ return html`
723
+ <div class=${rootClass} part="root">
724
+ ${this.renderLabelRow(labelId)}
725
+ <div class=${wrapClass} part="input-wrap">
726
+ <slot name="prefix"></slot>
727
+ <input
728
+ class="zr-field__input"
729
+ part="input"
730
+ id=${this.inputId}
731
+ name=${this.name}
732
+ type=${this.type}
733
+ .value=${this.value}
734
+ placeholder=${this.placeholder}
735
+ autocomplete=${this.autocomplete ?? ""}
736
+ pattern=${this.pattern ?? ""}
737
+ ?required=${this.required}
738
+ ?disabled=${this.disabled}
739
+ aria-invalid=${this.invalid || showError ? "true" : "false"}
740
+ aria-describedby=${describedBy || nothing}
741
+ @input=${this.handleInput}
742
+ @change=${this.handleChange}
743
+ @keydown=${this.handleKeyDown}
744
+ />
745
+ <slot name="suffix" @slotchange=${this.handleSuffixSlotChange}></slot>
746
+ ${trailing}
747
+ </div>
748
+ <div class="zr-field__help" part="help" id=${helpId} ?hidden=${!this.hasHelp}>
749
+ <slot name="help" @slotchange=${this.handleHelpSlotChange}></slot>
750
+ </div>
751
+ <div
752
+ class="zr-field__success"
753
+ part="success"
754
+ id=${successId}
755
+ role="status"
756
+ ?hidden=${!showSuccess}
757
+ >
758
+ ${this.success}
759
+ </div>
760
+ <div class="zr-field__error" part="error" id=${errorId} role="alert" ?hidden=${!showError}>
761
+ ${this.error}
762
+ </div>
763
+ </div>
764
+ `;
765
+ }
766
+ renderLabelRow(labelId) {
767
+ if (!this.label) return null;
768
+ if (this.forgotPasswordHref) return html`
769
+ <div class="zr-field__label-row" part="label-row">
770
+ <label class="zr-field__label" part="label" id=${labelId} for=${this.inputId}>
771
+ <span>${this.label}</span>
772
+ ${this.required ? html`<span class="zr-field__required" aria-hidden="true">*</span>` : null}
773
+ </label>
774
+ <a class="zr-field__link" part="forgot-link" href=${this.forgotPasswordHref}
775
+ >${this.forgotPasswordLabel}</a
776
+ >
777
+ </div>
778
+ `;
779
+ return html`
780
+ <label class="zr-field__label" part="label" id=${labelId} for=${this.inputId}>
781
+ <span>${this.label}</span>
782
+ ${this.required ? html`<span class="zr-field__required" aria-hidden="true">*</span>` : null}
783
+ </label>
784
+ `;
785
+ }
786
+ renderTrailingIcon() {
787
+ let iconName = "cross";
788
+ let tone = "default";
789
+ let clearable = true;
790
+ if (this.invalid || this.error) {
791
+ iconName = "alert-circle";
792
+ tone = "error";
793
+ clearable = false;
794
+ } else if (this.success) {
795
+ iconName = "check";
796
+ tone = "success";
797
+ clearable = false;
798
+ }
799
+ const icon = html`<zl-icon name=${iconName} size="16" tone=${tone} decorative></zl-icon>`;
800
+ if (!clearable) return html`<span class="zr-field__trailing" part="trailing-icon">${icon}</span>`;
801
+ return html`
802
+ <span class="zr-field__trailing" part="trailing-icon">
803
+ <button
804
+ type="button"
805
+ class="zr-field__trailing-action"
806
+ part="trailing-action"
807
+ aria-label="Clear"
808
+ ?disabled=${this.disabled}
809
+ @click=${this.handleClear}
810
+ >
811
+ ${icon}
812
+ </button>
813
+ </span>
814
+ `;
815
+ }
816
+ syncFormState() {
817
+ this.internals.setFormValue?.(this.value);
818
+ if (this.required && !this.value) this.internals.setValidity?.({ valueMissing: true }, "Please fill out this field.");
819
+ else if (this.error) this.internals.setValidity?.({ customError: true }, this.error);
820
+ else this.internals.setValidity?.({});
821
+ }
822
+ handleHelpSlotChange = (event) => {
823
+ const slot = event.target;
824
+ this.hasHelp = slot.assignedNodes({ flatten: true }).length > 0;
825
+ };
826
+ handleSuffixSlotChange = (event) => {
827
+ const slot = event.target;
828
+ this.hasSuffixSlot = slot.assignedNodes({ flatten: true }).length > 0;
829
+ };
830
+ handleClear = () => {
831
+ this.value = "";
832
+ this.dispatchEvent(new CustomEvent("zl-input", {
833
+ bubbles: true,
834
+ composed: true,
835
+ detail: {
836
+ name: this.name,
837
+ value: this.value
838
+ }
839
+ }));
840
+ this.syncFormState();
841
+ this.shadowRoot?.querySelector(".zr-field__input")?.focus();
842
+ };
843
+ handleInput = (event) => {
844
+ const input = event.target;
845
+ this.value = input.value;
846
+ this.dispatchEvent(new CustomEvent("zl-input", {
847
+ bubbles: true,
848
+ composed: true,
849
+ detail: {
850
+ name: this.name,
851
+ value: this.value
852
+ }
853
+ }));
854
+ };
855
+ handleChange = (event) => {
856
+ const input = event.target;
857
+ this.value = input.value;
858
+ this.dispatchEvent(new Event("change", {
859
+ bubbles: true,
860
+ composed: true
861
+ }));
862
+ };
863
+ handleKeyDown = (event) => {
864
+ if (event.key === "Enter" && !event.isComposing && !event.shiftKey && !event.altKey && !event.metaKey && !event.ctrlKey) {
865
+ const form = this.internals.form;
866
+ if (form) {
867
+ event.preventDefault();
868
+ form.requestSubmit();
869
+ }
870
+ }
871
+ };
872
+ };
873
+ __decorate([property()], ZlField.prototype, "name", null);
874
+ __decorate([property()], ZlField.prototype, "label", null);
875
+ __decorate([property()], ZlField.prototype, "type", null);
876
+ __decorate([property()], ZlField.prototype, "value", null);
877
+ __decorate([property()], ZlField.prototype, "placeholder", null);
878
+ __decorate([property()], ZlField.prototype, "autocomplete", null);
879
+ __decorate([property()], ZlField.prototype, "pattern", null);
880
+ __decorate([property()], ZlField.prototype, "error", null);
881
+ __decorate([property()], ZlField.prototype, "success", null);
882
+ __decorate([property({ attribute: "forgot-password-href" })], ZlField.prototype, "forgotPasswordHref", null);
883
+ __decorate([property({ attribute: "forgot-password-label" })], ZlField.prototype, "forgotPasswordLabel", null);
884
+ __decorate([property({
885
+ type: Boolean,
886
+ attribute: "trailing-icon"
887
+ })], ZlField.prototype, "trailingIcon", null);
888
+ __decorate([property({ type: Boolean })], ZlField.prototype, "required", null);
889
+ __decorate([property({
890
+ type: Boolean,
891
+ reflect: true
892
+ })], ZlField.prototype, "disabled", null);
893
+ __decorate([property({
894
+ type: Boolean,
895
+ reflect: true
896
+ })], ZlField.prototype, "invalid", null);
897
+ __decorate([state()], ZlField.prototype, "hasHelp", null);
898
+ __decorate([state()], ZlField.prototype, "hasSuffixSlot", null);
899
+ ZlField = __decorate([customElement("zl-field")], ZlField);
900
+ const zlFieldManifest = {
901
+ tag: "zl-field",
902
+ consumes: { field: { required: true } },
903
+ attrs: [
904
+ "name",
905
+ "label",
906
+ "type",
907
+ "value",
908
+ "placeholder",
909
+ "autocomplete",
910
+ "pattern",
911
+ "required",
912
+ "disabled",
913
+ "invalid",
914
+ "error",
915
+ "success",
916
+ "forgot-password-href",
917
+ "forgot-password-label",
918
+ "trailing-icon"
919
+ ],
920
+ parts: [
921
+ "root",
922
+ "label",
923
+ "label-row",
924
+ "forgot-link",
925
+ "input-wrap",
926
+ "input",
927
+ "trailing-icon",
928
+ "trailing-action",
929
+ "help",
930
+ "success",
931
+ "error"
932
+ ],
933
+ slots: [
934
+ "prefix",
935
+ "suffix",
936
+ "help"
937
+ ],
938
+ events: ["zl-input"]
939
+ };
940
+ //#endregion
941
+ //#region ../shared-component-styles/src/lit/page-shell-host.css?inline
942
+ var page_shell_host_default = ":host {\n background: var(--zl-color-surface-default-black, #0f0f11);\n min-height: 100vh;\n color: var(--zl-color-text-primary-white, #f4f4f6);\n display: block;\n}\n\n:host([data-embedded]) {\n height: 100%;\n min-height: 100%;\n}\n\n:host([data-embedded]) .zr-page-shell {\n min-height: 100%;\n}\n\n.zr-page-shell ::slotted([slot=\"header\"]), .zr-page-shell ::slotted([slot=\"footer\"]) {\n margin: 0;\n}\n";
943
+ //#endregion
944
+ //#region ../shared-component-styles/src/page-shell.css?inline
945
+ var page_shell_default = ".zr-page-shell {\n background: var(--zl-color-surface-default-black, #0f0f11);\n min-height: 100vh;\n color: var(--zl-color-text-primary-white, #f4f4f6);\n font-family: var(--zl-font-family-sans, system-ui, sans-serif);\n justify-content: center;\n align-items: center;\n gap: var(--zl-spacing-04, 1.5rem);\n padding-block: var(--zl-spacing-05, 2rem);\n padding-inline: var(--zl-spacing-03, 1rem);\n box-sizing: border-box;\n flex-direction: column;\n display: flex;\n}\n\n@media (width >= 48rem) {\n .zr-page-shell {\n padding-block: 3.25rem;\n padding-inline: var(--zl-spacing-03, 1rem);\n }\n}\n\n.zr-page-shell__header, .zr-page-shell__main, .zr-page-shell__footer {\n justify-content: center;\n align-items: center;\n width: 100%;\n display: flex;\n}\n\n.zr-page-shell__main {\n flex: none;\n}\n\n.zr-page-shell__footer {\n min-height: 1.5rem;\n}\n\n.zr-page-shell__region--empty {\n display: none;\n}\n\n.zr-page-shell[data-embedded] {\n height: 100%;\n min-height: 100%;\n}\n";
946
+ //#endregion
947
+ //#region src/atoms/zl-page-shell.ts
948
+ let ZlPageShell = class ZlPageShell extends LitElement {
949
+ static styles = [baseHostStyles, ...surfaceStyles(page_shell_host_default, page_shell_default)];
950
+ render() {
951
+ const hasHeader = this.lightDomSlotFilled("header");
952
+ const hasFooter = this.lightDomSlotFilled("footer");
953
+ return html`
954
+ <div class="zr-page-shell" part="shell">
955
+ <header class=${hasHeader ? "zr-page-shell__header" : "zr-page-shell__header zr-page-shell__region--empty"} part="header">
956
+ <slot name="header"></slot>
957
+ </header>
958
+ <main class="zr-page-shell__main" part="main">
959
+ <slot></slot>
960
+ </main>
961
+ <footer class=${hasFooter ? "zr-page-shell__footer" : "zr-page-shell__footer zr-page-shell__region--empty"} part="footer">
962
+ <slot name="footer"></slot>
963
+ </footer>
964
+ </div>
965
+ `;
966
+ }
967
+ lightDomSlotFilled(slot) {
968
+ for (const child of this.children) if (child.getAttribute("slot") === slot) return true;
969
+ return false;
970
+ }
971
+ };
972
+ ZlPageShell = __decorate([customElement("zl-page-shell")], ZlPageShell);
973
+ const zlPageShellManifest = {
974
+ tag: "zl-page-shell",
975
+ attrs: [],
976
+ parts: [
977
+ "shell",
978
+ "header",
979
+ "main",
980
+ "footer"
981
+ ],
982
+ slots: [
983
+ "",
984
+ "header",
985
+ "footer"
986
+ ],
987
+ events: []
988
+ };
989
+ //#endregion
990
+ //#region src/internal/base64url.ts
991
+ /**
992
+ * Base64URL encoding/decoding for WebAuthn binary fields.
993
+ *
994
+ * WebAuthn's `ArrayBuffer` values (`rawId`, `clientDataJSON`,
995
+ * `authenticatorData`, `signature`, `attestationObject`, `userHandle`)
996
+ * must be base64url-encoded before sending as JSON. The WebAuthn JSON
997
+ * serialization spec (https://www.w3.org/TR/webauthn-3/) requires
998
+ * Base64URL (RFC 4648 §5) — no padding, URL-safe alphabet.
999
+ */
1000
+ /**
1001
+ * Encode an `ArrayBuffer` to a Base64URL string (no padding).
1002
+ */
1003
+ function bufferToBase64Url(buffer) {
1004
+ const bytes = new Uint8Array(buffer);
1005
+ let binary = "";
1006
+ for (const byte of bytes) binary += String.fromCharCode(byte);
1007
+ return btoa(binary).replace(/\+/g, "-").replace(/\//g, "_").replace(/=/g, "");
1008
+ }
1009
+ /**
1010
+ * Decode a Base64URL string to an `ArrayBuffer`.
1011
+ */
1012
+ function base64UrlToBuffer(base64url) {
1013
+ const base64 = base64url.replace(/-/g, "+").replace(/_/g, "/");
1014
+ const padded = base64.padEnd(base64.length + (4 - base64.length % 4) % 4, "=");
1015
+ const binary = atob(padded);
1016
+ const bytes = new Uint8Array(binary.length);
1017
+ for (let i = 0; i < binary.length; i++) bytes[i] = binary.charCodeAt(i);
1018
+ return bytes.buffer;
1019
+ }
1020
+ //#endregion
1021
+ //#region src/atoms/zl-passkey.ts
1022
+ let ZlPasskey = class ZlPasskey extends LitElement {
1023
+ #_ceremony_accessor_storage = "authenticate";
1024
+ get ceremony() {
1025
+ return this.#_ceremony_accessor_storage;
1026
+ }
1027
+ set ceremony(value) {
1028
+ this.#_ceremony_accessor_storage = value;
1029
+ }
1030
+ #_challengeId_accessor_storage = "";
1031
+ get challengeId() {
1032
+ return this.#_challengeId_accessor_storage;
1033
+ }
1034
+ set challengeId(value) {
1035
+ this.#_challengeId_accessor_storage = value;
1036
+ }
1037
+ #_options_accessor_storage = null;
1038
+ get options() {
1039
+ return this.#_options_accessor_storage;
1040
+ }
1041
+ set options(value) {
1042
+ this.#_options_accessor_storage = value;
1043
+ }
1044
+ #_manual_accessor_storage = false;
1045
+ get manual() {
1046
+ return this.#_manual_accessor_storage;
1047
+ }
1048
+ set manual(value) {
1049
+ this.#_manual_accessor_storage = value;
1050
+ }
1051
+ abortController = null;
1052
+ connectedCallback() {
1053
+ super.connectedCallback();
1054
+ if (!this.manual && this.options) this.startCeremony();
1055
+ }
1056
+ disconnectedCallback() {
1057
+ this.abort();
1058
+ super.disconnectedCallback();
1059
+ }
1060
+ /**
1061
+ * Abort any in-flight WebAuthn ceremony. Called automatically when the
1062
+ * component disconnects (step change, page navigation).
1063
+ */
1064
+ abort() {
1065
+ this.abortController?.abort();
1066
+ this.abortController = null;
1067
+ }
1068
+ /**
1069
+ * Trigger the WebAuthn ceremony. Resolves when the ceremony completes
1070
+ * or rejects on error/abort.
1071
+ */
1072
+ async startCeremony() {
1073
+ if (!this.options) {
1074
+ this.emitError("No WebAuthn options provided.", false);
1075
+ return;
1076
+ }
1077
+ if (!window.PublicKeyCredential) {
1078
+ this.emitError("WebAuthn is not supported in this browser.", false);
1079
+ return;
1080
+ }
1081
+ this.abort();
1082
+ this.abortController = new AbortController();
1083
+ try {
1084
+ const credential = this.ceremony === "register" ? await this.createCredential() : await this.getCredential();
1085
+ if (!credential) {
1086
+ this.emitError("No credential returned by the browser.", false);
1087
+ return;
1088
+ }
1089
+ const proof = this.serializeCredential(credential);
1090
+ this.emitResult(proof);
1091
+ } catch (error) {
1092
+ const aborted = error instanceof DOMException && (error.name === "AbortError" || error.name === "NotAllowedError");
1093
+ this.emitError(error instanceof Error ? error.message : "WebAuthn ceremony failed.", aborted);
1094
+ }
1095
+ }
1096
+ /**
1097
+ * `navigator.credentials.get()` — authentication ceremony.
1098
+ */
1099
+ async getCredential() {
1100
+ const opts = this.options;
1101
+ if (!opts) throw new Error("getCredential called without options");
1102
+ const publicKeyOptions = {
1103
+ challenge: base64UrlToBuffer(opts.challenge),
1104
+ rpId: opts.rpId,
1105
+ timeout: opts.timeout,
1106
+ userVerification: opts.userVerification,
1107
+ allowCredentials: this.decodeCredentialDescriptors(opts.allowCredentials)
1108
+ };
1109
+ return await navigator.credentials.get({
1110
+ publicKey: publicKeyOptions,
1111
+ signal: this.abortController?.signal
1112
+ });
1113
+ }
1114
+ /**
1115
+ * `navigator.credentials.create()` — registration ceremony.
1116
+ */
1117
+ async createCredential() {
1118
+ const opts = this.options;
1119
+ if (!opts) throw new Error("createCredential called without options");
1120
+ const rp = opts.rp;
1121
+ const user = opts.user;
1122
+ const pubKeyCredParams = opts.pubKeyCredParams;
1123
+ const publicKeyOptions = {
1124
+ challenge: base64UrlToBuffer(opts.challenge),
1125
+ rp: {
1126
+ name: rp.name,
1127
+ ...rp.id ? { id: rp.id } : {}
1128
+ },
1129
+ user: {
1130
+ id: base64UrlToBuffer(user.id),
1131
+ name: user.name,
1132
+ displayName: user.displayName
1133
+ },
1134
+ pubKeyCredParams: pubKeyCredParams.map((p) => ({
1135
+ type: p.type,
1136
+ alg: p.alg
1137
+ })),
1138
+ timeout: opts.timeout,
1139
+ attestation: opts.attestation ?? "none",
1140
+ authenticatorSelection: opts.authenticatorSelection,
1141
+ excludeCredentials: this.decodeCredentialDescriptors(opts.excludeCredentials)
1142
+ };
1143
+ return await navigator.credentials.create({
1144
+ publicKey: publicKeyOptions,
1145
+ signal: this.abortController?.signal
1146
+ });
1147
+ }
1148
+ /**
1149
+ * Decode a list of credential descriptors from the server's base64url
1150
+ * format to the browser's ArrayBuffer format.
1151
+ */
1152
+ decodeCredentialDescriptors(descriptors) {
1153
+ if (!descriptors) return [];
1154
+ return descriptors.map((d) => ({
1155
+ type: d.type,
1156
+ id: base64UrlToBuffer(d.id),
1157
+ transports: d.transports
1158
+ }));
1159
+ }
1160
+ /**
1161
+ * Serialize a `PublicKeyCredential` to the JSON shape defined in
1162
+ * `passkey-proof.yaml`. All `ArrayBuffer` fields are base64url-encoded.
1163
+ */
1164
+ serializeCredential(credential) {
1165
+ const response = credential.response;
1166
+ const serialized = {
1167
+ id: credential.id,
1168
+ rawId: bufferToBase64Url(credential.rawId),
1169
+ type: "public-key",
1170
+ response: { clientDataJSON: bufferToBase64Url(response.clientDataJSON) }
1171
+ };
1172
+ if ("attestationObject" in response) {
1173
+ const attestation = response;
1174
+ serialized.response.attestationObject = bufferToBase64Url(attestation.attestationObject);
1175
+ }
1176
+ if ("authenticatorData" in response) {
1177
+ const assertion = response;
1178
+ serialized.response.authenticatorData = bufferToBase64Url(assertion.authenticatorData);
1179
+ serialized.response.signature = bufferToBase64Url(assertion.signature);
1180
+ if (assertion.userHandle) serialized.response.userHandle = bufferToBase64Url(assertion.userHandle);
1181
+ }
1182
+ if (credential.authenticatorAttachment) serialized.authenticatorAttachment = credential.authenticatorAttachment;
1183
+ return serialized;
1184
+ }
1185
+ emitResult(proof) {
1186
+ const detail = {
1187
+ challenge_id: this.challengeId,
1188
+ method: "passkey",
1189
+ proof
1190
+ };
1191
+ this.dispatchEvent(new CustomEvent("zl-passkey-result", {
1192
+ bubbles: true,
1193
+ composed: true,
1194
+ detail
1195
+ }));
1196
+ }
1197
+ emitError(message, aborted) {
1198
+ const detail = {
1199
+ challenge_id: this.challengeId,
1200
+ error: message,
1201
+ aborted
1202
+ };
1203
+ this.dispatchEvent(new CustomEvent("zl-passkey-error", {
1204
+ bubbles: true,
1205
+ composed: true,
1206
+ detail
1207
+ }));
1208
+ }
1209
+ /** Invisible component — no shadow DOM rendering needed. */
1210
+ createRenderRoot() {
1211
+ return this;
1212
+ }
1213
+ };
1214
+ __decorate([property()], ZlPasskey.prototype, "ceremony", null);
1215
+ __decorate([property({ attribute: "challenge-id" })], ZlPasskey.prototype, "challengeId", null);
1216
+ __decorate([property({
1217
+ attribute: "options",
1218
+ converter: {
1219
+ fromAttribute(value) {
1220
+ if (!value) return null;
1221
+ try {
1222
+ return JSON.parse(value);
1223
+ } catch {
1224
+ return null;
1225
+ }
1226
+ },
1227
+ toAttribute(value) {
1228
+ return value ? JSON.stringify(value) : null;
1229
+ }
1230
+ }
1231
+ })], ZlPasskey.prototype, "options", null);
1232
+ __decorate([property({ type: Boolean })], ZlPasskey.prototype, "manual", null);
1233
+ ZlPasskey = __decorate([customElement("zl-passkey")], ZlPasskey);
1234
+ const zlPasskeyManifest = {
1235
+ tag: "zl-passkey",
1236
+ consumes: {},
1237
+ attrs: [
1238
+ "ceremony",
1239
+ "challenge-id",
1240
+ "options",
1241
+ "manual"
1242
+ ],
1243
+ parts: [],
1244
+ slots: [],
1245
+ events: ["zl-passkey-result", "zl-passkey-error"]
1246
+ };
1247
+ //#endregion
1248
+ //#region ../shared-component-styles/src/lit/pill-host.css?inline
1249
+ var pill_host_default = ":host {\n display: inline-flex;\n}\n\n::slotted(.zr-pill__logotype) {\n flex-shrink: 0;\n width: 65px;\n height: 16px;\n margin-top: 2px;\n line-height: 0;\n display: block;\n}\n\n::slotted(.zr-pill__logotype-svg) {\n width: 100%;\n height: 100%;\n display: block;\n}\n";
1250
+ //#endregion
1251
+ //#region ../shared-component-styles/src/pill.css?inline
1252
+ var pill_default = ".zr-pill {\n box-sizing: border-box;\n justify-content: center;\n align-items: flex-start;\n gap: var(--zl-spacing-02, .5rem);\n height: 2.5rem;\n padding-inline: var(--zl-spacing-03, 1rem);\n font-family: var(--zl-font-family-sans, system-ui, sans-serif);\n letter-spacing: 0;\n text-transform: none;\n background: linear-gradient(182deg, #484a5799 28.65%, #0f0f1199 81.82%),\n var(--zl-color-surface-default-primary-gray, #252528);\n color: var(--zl-color-text-primary-white, #f4f4f6);\n border: 1px solid var(--zl-color-border-default-gray-200, #484a57);\n white-space: nowrap;\n border-radius: 100px;\n padding-block: calc(.625rem - 1px);\n font-size: .875rem;\n font-weight: 400;\n line-height: 1.25rem;\n text-decoration: none;\n display: inline-flex;\n}\n\n.zr-pill__logotype {\n flex-shrink: 0;\n width: 65px;\n height: 16px;\n margin-top: 2px;\n line-height: 0;\n display: block;\n}\n\n.zr-pill__logotype-svg {\n width: 100%;\n height: 100%;\n display: block;\n}\n\n.zr-pill--pink {\n color: var(--zl-color-text-subtitle-pink);\n border-color: var(--zl-color-text-subtitle-pink);\n background: color-mix(in srgb, var(--zl-color-text-subtitle-pink) 10%, var(--zl-color-surface-default-primary-gray));\n}\n\n.zr-pill--purple {\n color: var(--zl-color-text-subtitle-purple);\n border-color: var(--zl-color-text-subtitle-purple);\n background: color-mix(in srgb, var(--zl-color-text-subtitle-purple) 10%, var(--zl-color-surface-default-primary-gray));\n}\n\n.zr-pill--orange {\n color: var(--zl-color-text-subtitle-orange);\n border-color: var(--zl-color-text-subtitle-orange);\n background: color-mix(in srgb, var(--zl-color-text-subtitle-orange) 10%, var(--zl-color-surface-default-primary-gray));\n}\n\n.zr-pill--success {\n color: var(--zl-color-text-success);\n border-color: var(--zl-color-text-success);\n background: color-mix(in srgb, var(--zl-color-text-success) 10%, var(--zl-color-surface-default-primary-gray));\n}\n\na.zr-pill:focus-visible {\n outline: var(--zl-focus-width, 2px) solid var(--zl-focus-color, #f4f4f6);\n outline-offset: var(--zl-focus-offset, 2px);\n}\n";
1253
+ //#endregion
1254
+ //#region src/atoms/zl-pill.ts
1255
+ let ZlPill = class ZlPill extends LitElement {
1256
+ static styles = [baseHostStyles, ...surfaceStyles(pill_host_default, pill_default)];
1257
+ #_tone_accessor_storage = "neutral";
1258
+ get tone() {
1259
+ return this.#_tone_accessor_storage;
1260
+ }
1261
+ set tone(value) {
1262
+ this.#_tone_accessor_storage = value;
1263
+ }
1264
+ #_href_accessor_storage = void 0;
1265
+ get href() {
1266
+ return this.#_href_accessor_storage;
1267
+ }
1268
+ set href(value) {
1269
+ this.#_href_accessor_storage = value;
1270
+ }
1271
+ #_ariaLabel_accessor_storage = null;
1272
+ get ariaLabel() {
1273
+ return this.#_ariaLabel_accessor_storage;
1274
+ }
1275
+ set ariaLabel(value) {
1276
+ this.#_ariaLabel_accessor_storage = value;
1277
+ }
1278
+ surfaceClasses() {
1279
+ return ["zr-pill", this.tone !== "neutral" ? `zr-pill--${this.tone}` : ""].filter(Boolean).join(" ");
1280
+ }
1281
+ render() {
1282
+ const classes = this.surfaceClasses();
1283
+ if (this.href) return html`<a
1284
+ class=${classes}
1285
+ part="pill"
1286
+ href=${this.href}
1287
+ rel="noopener"
1288
+ aria-label=${this.ariaLabel ?? nothing}
1289
+ ><slot></slot></a>`;
1290
+ return html`<span class=${classes} part="pill"><slot></slot></span>`;
1291
+ }
1292
+ };
1293
+ __decorate([property()], ZlPill.prototype, "tone", null);
1294
+ __decorate([property()], ZlPill.prototype, "href", null);
1295
+ __decorate([property({ attribute: "aria-label" })], ZlPill.prototype, "ariaLabel", null);
1296
+ ZlPill = __decorate([customElement("zl-pill")], ZlPill);
1297
+ const zlPillManifest = {
1298
+ tag: "zl-pill",
1299
+ attrs: [
1300
+ "tone",
1301
+ "href",
1302
+ "aria-label"
1303
+ ],
1304
+ parts: ["pill"],
1305
+ slots: [],
1306
+ events: []
1307
+ };
1308
+ //#endregion
1309
+ export { __decorate as _, ZlPageShell as a, t as b, zlFieldManifest as c, ZlButton as d, zlButtonManifest as f, zlIconManifest as g, ZlIcon as h, zlPasskeyManifest as i, ZlCard as l, zlAlertManifest as m, zlPillManifest as n, zlPageShellManifest as o, ZlAlert as p, ZlPasskey as r, ZlField as s, ZlPill as t, zlCardManifest as u, focusVisibleStyles as v, baseHostStyles as y };
1310
+
1311
+ //# sourceMappingURL=atoms-CmOTltTH.mjs.map