@zitadel/components 0.1.0-alpha.0 → 0.1.0-alpha.2

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 (46) hide show
  1. package/README.md +41 -36
  2. package/dist/atoms/index.d.mts +1 -1
  3. package/dist/atoms/index.mjs +1 -1
  4. package/dist/atoms/zl-alert.d.ts.map +1 -1
  5. package/dist/atoms/zl-button.d.ts +7 -1
  6. package/dist/atoms/zl-button.d.ts.map +1 -1
  7. package/dist/atoms/zl-card.d.ts +7 -0
  8. package/dist/atoms/zl-card.d.ts.map +1 -1
  9. package/dist/atoms/zl-field.d.ts +6 -0
  10. package/dist/atoms/zl-field.d.ts.map +1 -1
  11. package/dist/atoms/zl-icon.d.ts.map +1 -1
  12. package/dist/atoms/zl-page-shell.d.ts +6 -0
  13. package/dist/atoms/zl-page-shell.d.ts.map +1 -1
  14. package/dist/atoms/zl-pill.d.ts +0 -1
  15. package/dist/atoms/zl-pill.d.ts.map +1 -1
  16. package/dist/{atoms-B9yd0c-i.mjs → atoms-eOxuoGDq.mjs} +118 -73
  17. package/dist/atoms-eOxuoGDq.mjs.map +1 -0
  18. package/dist/{index-B74_igDN.d.mts → index-DjBsBWdg.d.mts} +82 -18
  19. package/dist/index-DjBsBWdg.d.mts.map +1 -0
  20. package/dist/{index-Dd8hfOWt.d.mts → index-DmtnqUIY.d.mts} +1223 -572
  21. package/dist/index-DmtnqUIY.d.mts.map +1 -0
  22. package/dist/index.d.mts +2 -2
  23. package/dist/index.mjs +2 -2
  24. package/dist/internal/emit.d.ts +12 -0
  25. package/dist/internal/emit.d.ts.map +1 -0
  26. package/dist/internal/escape-html.d.ts +10 -0
  27. package/dist/internal/escape-html.d.ts.map +1 -0
  28. package/dist/manifests.mjs +1 -1
  29. package/dist/orchestrator/index.d.mts +1 -1
  30. package/dist/orchestrator/index.mjs +1 -1
  31. package/dist/orchestrator/locales/en.d.ts.map +1 -1
  32. package/dist/orchestrator/resolve-api.d.ts +37 -0
  33. package/dist/orchestrator/resolve-api.d.ts.map +1 -0
  34. package/dist/orchestrator/zitadel-login.d.ts +27 -2
  35. package/dist/orchestrator/zitadel-login.d.ts.map +1 -1
  36. package/dist/orchestrator/zitadel-logout.d.ts +33 -5
  37. package/dist/orchestrator/zitadel-logout.d.ts.map +1 -1
  38. package/dist/{orchestrator-B8eXcPRi.mjs → orchestrator-Dds72XrU.mjs} +349 -125
  39. package/dist/orchestrator-Dds72XrU.mjs.map +1 -0
  40. package/dist/standalone.mjs +12002 -0
  41. package/dist/tsconfig.lib.tsbuildinfo +1 -1
  42. package/package.json +8 -2
  43. package/dist/atoms-B9yd0c-i.mjs.map +0 -1
  44. package/dist/index-B74_igDN.d.mts.map +0 -1
  45. package/dist/index-Dd8hfOWt.d.mts.map +0 -1
  46. package/dist/orchestrator-B8eXcPRi.mjs.map +0 -1
@@ -1,14 +1,36 @@
1
1
  import { t as cssVars } from "./tokens-TXmurodq.mjs";
2
2
  import { LitElement, css, html, nothing, unsafeCSS } from "lit";
3
- import { customElement, property, state } from "lit/decorators.js";
3
+ import { customElement, property, query, state } from "lit/decorators.js";
4
+ import { classMap } from "lit/directives/class-map.js";
4
5
  import { unsafeSVG } from "lit/directives/unsafe-svg.js";
5
6
  import { ArrowLeft, ArrowRight, Check, CircleAlert, Eye, EyeOff, Info, KeyRound, LoaderCircle, Plus, TriangleAlert, User, X } from "lucide";
7
+ import { ifDefined } from "lit/directives/if-defined.js";
8
+ import { live } from "lit/directives/live.js";
6
9
  //#region ../shared-component-styles/src/lit/alert-host.css?inline
7
10
  var alert_host_default = ":host {\n display: block;\n}\n";
8
11
  //#endregion
9
12
  //#region ../shared-component-styles/src/alert.css?inline
10
13
  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
14
  //#endregion
15
+ //#region src/internal/emit.ts
16
+ /**
17
+ * Dispatch a custom event with the project-wide defaults (`bubbles` +
18
+ * `composed`) so it crosses the shadow boundary and reaches delegated
19
+ * listeners — whether it's an atom's `zl-*` event or the orchestrator's
20
+ * public `zitadel-*` event.
21
+ *
22
+ * Centralising the dispatch shape keeps every event contract identical and
23
+ * removes the repeated `new CustomEvent(..., { bubbles: true, composed: true,
24
+ * detail })` boilerplate.
25
+ */
26
+ function emit(host, type, detail) {
27
+ return host.dispatchEvent(new CustomEvent(type, {
28
+ bubbles: true,
29
+ composed: true,
30
+ detail
31
+ }));
32
+ }
33
+ //#endregion
12
34
  //#region src/styles/tokens.ts
13
35
  function wrap(node) {
14
36
  if (typeof node === "string") return unsafeCSS(node);
@@ -123,12 +145,12 @@ let ZlIcon = class ZlIcon extends LitElement {
123
145
  const ariaLabel = this.label ?? DEFAULT_LABELS[this.name];
124
146
  const hidden = this.decorative || !ariaLabel;
125
147
  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(" ")}>
148
+ <span class=${classMap({
149
+ "zr-icon": true,
150
+ [`zr-icon--${this.size}`]: true,
151
+ [`zr-icon--tone-${this.tone}`]: this.tone !== "default",
152
+ "zr-icon--spin": this.spin
153
+ })}>
132
154
  <svg
133
155
  viewBox="0 0 24 24"
134
156
  fill="none"
@@ -257,10 +279,7 @@ let ZlAlert = class ZlAlert extends LitElement {
257
279
  `;
258
280
  }
259
281
  handleDismiss = () => {
260
- this.dispatchEvent(new CustomEvent("zl-dismiss", {
261
- bubbles: true,
262
- composed: true
263
- }));
282
+ emit(this, "zl-dismiss");
264
283
  this.remove();
265
284
  };
266
285
  };
@@ -292,7 +311,7 @@ const zlAlertManifest = {
292
311
  "message",
293
312
  "close"
294
313
  ],
295
- slots: [],
314
+ slots: [""],
296
315
  events: ["zl-dismiss"]
297
316
  };
298
317
  //#endregion
@@ -366,6 +385,13 @@ let ZlButton = class ZlButton extends LitElement {
366
385
  set label(value) {
367
386
  this.#_label_accessor_storage = value;
368
387
  }
388
+ #_forcedState_accessor_storage = null;
389
+ get forcedState() {
390
+ return this.#_forcedState_accessor_storage;
391
+ }
392
+ set forcedState(value) {
393
+ this.#_forcedState_accessor_storage = value;
394
+ }
369
395
  internals;
370
396
  constructor() {
371
397
  super();
@@ -374,27 +400,23 @@ let ZlButton = class ZlButton extends LitElement {
374
400
  focus(options) {
375
401
  this.shadowRoot?.querySelector("button")?.focus(options);
376
402
  }
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
403
  render() {
387
404
  const blocked = this.disabled || this.loading;
388
- const forcedState = this.getAttribute("data-state");
389
405
  const body = this.label !== void 0 ? html`<span>${this.label}</span>` : html`<slot></slot>`;
390
406
  return html`
391
407
  <button
392
- class=${this.surfaceClasses()}
408
+ class=${classMap({
409
+ root: true,
410
+ "zr-btn": true,
411
+ [`zr-btn--${this.hierarchy}`]: true,
412
+ [`zr-btn--${this.size}`]: true,
413
+ "zr-btn--block": this.block
414
+ })}
393
415
  part="root"
394
416
  type=${this.type}
395
417
  ?disabled=${blocked}
396
418
  aria-busy=${this.loading ? "true" : "false"}
397
- data-state=${forcedState ?? nothing}
419
+ data-state=${this.forcedState ?? nothing}
398
420
  @click=${this.handleClick}
399
421
  >
400
422
  <slot name="leading"></slot>
@@ -417,11 +439,7 @@ let ZlButton = class ZlButton extends LitElement {
417
439
  event.preventDefault();
418
440
  form.reset();
419
441
  }
420
- this.dispatchEvent(new CustomEvent("zl-submit", {
421
- bubbles: true,
422
- composed: true,
423
- detail: { action: this.action ?? null }
424
- }));
442
+ emit(this, "zl-submit", { action: this.action ?? null });
425
443
  };
426
444
  };
427
445
  __decorate([property({ reflect: true })], ZlButton.prototype, "hierarchy", null);
@@ -438,6 +456,7 @@ __decorate([property({
438
456
  reflect: true
439
457
  })], ZlButton.prototype, "block", null);
440
458
  __decorate([property()], ZlButton.prototype, "label", null);
459
+ __decorate([property({ attribute: "data-state" })], ZlButton.prototype, "forcedState", null);
441
460
  ZlButton = __decorate([customElement("zl-button")], ZlButton);
442
461
  const zlButtonManifest = {
443
462
  tag: "zl-button",
@@ -483,20 +502,32 @@ let ZlCard = class ZlCard extends LitElement {
483
502
  render() {
484
503
  const hasHeader = this.lightDomSlotFilled("header");
485
504
  const hasFooter = this.lightDomSlotFilled("footer");
505
+ const cardClass = this.compact ? "zr-card zr-card--compact" : "zr-card";
506
+ const headerClass = hasHeader ? "zr-card__header" : "zr-card__header zr-card__region--empty";
507
+ const footerClass = hasFooter ? "zr-card__footer" : "zr-card__footer zr-card__region--empty";
486
508
  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>
509
+ <section class=${cardClass} part="card">
510
+ <header class=${headerClass} part="header">
511
+ <slot name="header" @slotchange=${this.onSlotChange}></slot>
490
512
  </header>
491
513
  <div class="zr-card__body" part="body">
492
514
  <slot></slot>
493
515
  </div>
494
- <footer class=${hasFooter ? "zr-card__footer" : "zr-card__footer zr-card__region--empty"} part="footer">
495
- <slot name="footer"></slot>
516
+ <footer class=${footerClass} part="footer">
517
+ <slot name="footer" @slotchange=${this.onSlotChange}></slot>
496
518
  </footer>
497
519
  </section>
498
520
  `;
499
521
  }
522
+ /**
523
+ * `lightDomSlotFilled` is a render-time snapshot, so re-run render whenever a
524
+ * named slot's assignment changes (e.g. a header added after first paint).
525
+ * The initial render still reads children synchronously, avoiding the
526
+ * empty-then-filled flash a slotchange-only approach would introduce.
527
+ */
528
+ onSlotChange = () => {
529
+ this.requestUpdate();
530
+ };
500
531
  /** Slotted nodes are always light-DOM children of the host in our templates. */
501
532
  lightDomSlotFilled(slot) {
502
533
  for (const child of this.children) if (child.getAttribute("slot") === slot) return true;
@@ -681,6 +712,13 @@ let ZlField = class ZlField extends LitElement {
681
712
  set hasSuffixSlot(value) {
682
713
  this.#_hasSuffixSlot_accessor_storage = value;
683
714
  }
715
+ #_inputEl_accessor_storage = null;
716
+ get inputEl() {
717
+ return this.#_inputEl_accessor_storage;
718
+ }
719
+ set inputEl(value) {
720
+ this.#_inputEl_accessor_storage = value;
721
+ }
684
722
  inputId = nextUid("zl-field");
685
723
  internals;
686
724
  constructor() {
@@ -701,7 +739,7 @@ let ZlField = class ZlField extends LitElement {
701
739
  this.value = state ?? "";
702
740
  }
703
741
  focus(options) {
704
- this.shadowRoot?.querySelector("input")?.focus(options);
742
+ this.inputEl?.focus(options);
705
743
  }
706
744
  render() {
707
745
  const labelId = `${this.inputId}-label`;
@@ -715,15 +753,18 @@ let ZlField = class ZlField extends LitElement {
715
753
  showSuccess ? successId : null,
716
754
  this.hasHelp ? helpId : null
717
755
  ].filter(Boolean).join(" ");
718
- const rootClass = [
719
- "zr-field",
720
- this.invalid || showError ? "zr-field--invalid" : "",
721
- showSuccess ? "zr-field--success" : "",
722
- this.disabled ? "zr-field--disabled" : ""
723
- ].filter(Boolean).join(" ");
756
+ const rootClass = classMap({
757
+ "zr-field": true,
758
+ "zr-field--invalid": this.invalid || showError,
759
+ "zr-field--success": showSuccess,
760
+ "zr-field--disabled": this.disabled
761
+ });
724
762
  const showDefaultTrailing = this.trailingIcon && !this.hasSuffixSlot && !this.disabled;
725
763
  const trailing = showDefaultTrailing ? this.renderTrailingIcon() : null;
726
- const wrapClass = ["zr-field__wrap", showDefaultTrailing ? "zr-field__wrap--trailing" : ""].filter(Boolean).join(" ");
764
+ const wrapClass = classMap({
765
+ "zr-field__wrap": true,
766
+ "zr-field__wrap--trailing": showDefaultTrailing
767
+ });
727
768
  return html`
728
769
  <div class=${rootClass} part="root">
729
770
  ${this.renderLabelRow(labelId)}
@@ -735,10 +776,10 @@ let ZlField = class ZlField extends LitElement {
735
776
  id=${this.inputId}
736
777
  name=${this.name}
737
778
  type=${this.type}
738
- .value=${this.value}
779
+ .value=${live(this.value)}
739
780
  placeholder=${this.placeholder}
740
- autocomplete=${this.autocomplete ?? ""}
741
- pattern=${this.pattern ?? ""}
781
+ autocomplete=${ifDefined(this.autocomplete)}
782
+ pattern=${ifDefined(this.pattern)}
742
783
  ?required=${this.required}
743
784
  ?disabled=${this.disabled}
744
785
  aria-invalid=${this.invalid || showError ? "true" : "false"}
@@ -834,28 +875,20 @@ let ZlField = class ZlField extends LitElement {
834
875
  };
835
876
  handleClear = () => {
836
877
  this.value = "";
837
- this.dispatchEvent(new CustomEvent("zl-input", {
838
- bubbles: true,
839
- composed: true,
840
- detail: {
841
- name: this.name,
842
- value: this.value
843
- }
844
- }));
878
+ emit(this, "zl-input", {
879
+ name: this.name,
880
+ value: this.value
881
+ });
845
882
  this.syncFormState();
846
- this.shadowRoot?.querySelector(".zr-field__input")?.focus();
883
+ this.inputEl?.focus();
847
884
  };
848
885
  handleInput = (event) => {
849
886
  const input = event.target;
850
887
  this.value = input.value;
851
- this.dispatchEvent(new CustomEvent("zl-input", {
852
- bubbles: true,
853
- composed: true,
854
- detail: {
855
- name: this.name,
856
- value: this.value
857
- }
858
- }));
888
+ emit(this, "zl-input", {
889
+ name: this.name,
890
+ value: this.value
891
+ });
859
892
  };
860
893
  handleChange = (event) => {
861
894
  const input = event.target;
@@ -900,6 +933,7 @@ __decorate([property({
900
933
  })], ZlField.prototype, "invalid", null);
901
934
  __decorate([state()], ZlField.prototype, "hasHelp", null);
902
935
  __decorate([state()], ZlField.prototype, "hasSuffixSlot", null);
936
+ __decorate([query(".zr-field__input")], ZlField.prototype, "inputEl", null);
903
937
  ZlField = __decorate([customElement("zl-field")], ZlField);
904
938
  const zlFieldManifest = {
905
939
  tag: "zl-field",
@@ -954,20 +988,30 @@ let ZlPageShell = class ZlPageShell extends LitElement {
954
988
  render() {
955
989
  const hasHeader = this.lightDomSlotFilled("header");
956
990
  const hasFooter = this.lightDomSlotFilled("footer");
991
+ const headerClass = hasHeader ? "zr-page-shell__header" : "zr-page-shell__header zr-page-shell__region--empty";
992
+ const footerClass = hasFooter ? "zr-page-shell__footer" : "zr-page-shell__footer zr-page-shell__region--empty";
957
993
  return html`
958
994
  <div class="zr-page-shell" part="shell">
959
- <header class=${hasHeader ? "zr-page-shell__header" : "zr-page-shell__header zr-page-shell__region--empty"} part="header">
960
- <slot name="header"></slot>
995
+ <header class=${headerClass} part="header">
996
+ <slot name="header" @slotchange=${this.onSlotChange}></slot>
961
997
  </header>
962
998
  <main class="zr-page-shell__main" part="main">
963
999
  <slot></slot>
964
1000
  </main>
965
- <footer class=${hasFooter ? "zr-page-shell__footer" : "zr-page-shell__footer zr-page-shell__region--empty"} part="footer">
966
- <slot name="footer"></slot>
1001
+ <footer class=${footerClass} part="footer">
1002
+ <slot name="footer" @slotchange=${this.onSlotChange}></slot>
967
1003
  </footer>
968
1004
  </div>
969
1005
  `;
970
1006
  }
1007
+ /**
1008
+ * Re-render when a named slot's assignment changes so a footer/header added
1009
+ * after first paint updates the empty-region class. The initial render reads
1010
+ * children synchronously (no empty-then-filled flash).
1011
+ */
1012
+ onSlotChange = () => {
1013
+ this.requestUpdate();
1014
+ };
971
1015
  lightDomSlotFilled(slot) {
972
1016
  for (const child of this.children) if (child.getAttribute("slot") === slot) return true;
973
1017
  return false;
@@ -1248,6 +1292,7 @@ const zlPasskeyManifest = {
1248
1292
  consumes: {},
1249
1293
  attrs: [
1250
1294
  "ceremony",
1295
+ "method",
1251
1296
  "challenge-id",
1252
1297
  "options",
1253
1298
  "manual"
@@ -1287,11 +1332,11 @@ let ZlPill = class ZlPill extends LitElement {
1287
1332
  set ariaLabel(value) {
1288
1333
  this.#_ariaLabel_accessor_storage = value;
1289
1334
  }
1290
- surfaceClasses() {
1291
- return ["zr-pill", this.tone !== "neutral" ? `zr-pill--${this.tone}` : ""].filter(Boolean).join(" ");
1292
- }
1293
1335
  render() {
1294
- const classes = this.surfaceClasses();
1336
+ const classes = classMap({
1337
+ "zr-pill": true,
1338
+ [`zr-pill--${this.tone}`]: this.tone !== "neutral"
1339
+ });
1295
1340
  if (this.href) return html`<a
1296
1341
  class=${classes}
1297
1342
  part="pill"
@@ -1314,10 +1359,10 @@ const zlPillManifest = {
1314
1359
  "aria-label"
1315
1360
  ],
1316
1361
  parts: ["pill"],
1317
- slots: [],
1362
+ slots: [""],
1318
1363
  events: []
1319
1364
  };
1320
1365
  //#endregion
1321
- 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 };
1366
+ 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, emit as x, baseHostStyles as y };
1322
1367
 
1323
- //# sourceMappingURL=atoms-B9yd0c-i.mjs.map
1368
+ //# sourceMappingURL=atoms-eOxuoGDq.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"atoms-eOxuoGDq.mjs","names":["raw","iconHost","iconSurface","alertHost","alertSurface","buttonHost","buttonSurface","cardHost","cardSurface","fieldHost","fieldSurface","pageShellHost","pageShellSurface","pillHost","pillSurface"],"sources":["../../shared-component-styles/src/lit/alert-host.css?inline","../../shared-component-styles/src/alert.css?inline","../src/internal/emit.ts","../src/styles/tokens.ts","../src/styles/base.ts","../src/styles/focus-ring.ts","../src/styles/surface.ts","../../shared-component-styles/src/lit/icon-host.css?inline","../../shared-component-styles/src/icon.css?inline","../src/atoms/zl-icon.ts","../src/atoms/zl-alert.ts","../../shared-component-styles/src/lit/button-host.css?inline","../../shared-component-styles/src/button.css?inline","../src/atoms/zl-button.ts","../../shared-component-styles/src/lit/card-host.css?inline","../../shared-component-styles/src/card.css?inline","../src/atoms/zl-card.ts","../../shared-component-styles/src/lit/text-field-host.css?inline","../../shared-component-styles/src/text-field.css?inline","../src/internal/unique-id.ts","../src/atoms/zl-field.ts","../../shared-component-styles/src/lit/page-shell-host.css?inline","../../shared-component-styles/src/page-shell.css?inline","../src/atoms/zl-page-shell.ts","../src/internal/base64url.ts","../src/atoms/zl-passkey.ts","../../shared-component-styles/src/lit/pill-host.css?inline","../../shared-component-styles/src/pill.css?inline","../src/atoms/zl-pill.ts"],"sourcesContent":["/* Lit-only: <zl-alert> host + slot reset. */\n:host {\n display: block;\n}\n","/* Shared surface for `<zl-alert>` / `<Alert>`. Lit-only rules: lit/alert-host.css */\n/* Figma master: 8UjCXw8yemgljmbkWGrSfE / Alert/Error `6593:2640` */\n.zr-alert {\n display: flex;\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, 0.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: 0.875rem;\n font-weight: 400;\n line-height: 1.25rem;\n box-shadow: 0 1px 2px rgb(16 24 40 / 0.05);\n}\n.zr-alert__icon {\n flex-shrink: 0;\n color: var(--zl-color-text-error, #ea4f70);\n}\n.zr-alert--warning .zr-alert__icon {\n color: var(--zl-color-text-subtitle-orange, #f25543);\n}\n.zr-alert--success .zr-alert__icon {\n color: var(--zl-color-text-success, #33a779);\n}\n.zr-alert--info .zr-alert__icon {\n color: var(--zl-color-text-subtitle-gray, #bfbfcf);\n}\n.zr-alert__body {\n flex: 1 1 auto;\n min-width: 0;\n display: flex;\n flex-direction: column;\n gap: var(--zl-spacing-01, 0.25rem);\n}\n.zr-alert__title {\n font-weight: 600;\n color: var(--zl-color-text-button-invert, #f4f4f6);\n}\n.zr-alert__message {\n margin: 0;\n color: var(--zl-color-border-default-white, #f4f4f6);\n}\n.zr-alert:not(:has(.zr-alert__title)) .zr-alert__message {\n color: var(--zl-color-text-button-invert, #f4f4f6);\n}\n.zr-alert__close {\n all: unset;\n flex-shrink: 0;\n display: inline-flex;\n align-items: center;\n justify-content: center;\n width: 2.25rem;\n height: 2.25rem;\n padding: var(--zl-spacing-02, 0.5rem);\n border-radius: var(--zl-radius-s, 0.5rem);\n color: var(--zl-color-text-secondary-gray, #bfbfcf);\n cursor: pointer;\n transition: background-color var(--zl-duration-fast, 120ms) var(--zl-easing-standard, cubic-bezier(0.2, 0, 0, 1));\n}\n.zr-alert__close .zr-icon {\n --zl-icon-size: 1.25rem;\n width: 1.25rem;\n height: 1.25rem;\n}\n.zr-alert__close:hover {\n background: var(--zl-color-gray-200, #484a57);\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","/**\n * Dispatch a custom event with the project-wide defaults (`bubbles` +\n * `composed`) so it crosses the shadow boundary and reaches delegated\n * listeners — whether it's an atom's `zl-*` event or the orchestrator's\n * public `zitadel-*` event.\n *\n * Centralising the dispatch shape keeps every event contract identical and\n * removes the repeated `new CustomEvent(..., { bubbles: true, composed: true,\n * detail })` boilerplate.\n */\nexport function emit<T = undefined>(host: HTMLElement, type: string, detail?: T): boolean {\n return host.dispatchEvent(\n new CustomEvent<T>(type, { bubbles: true, composed: true, detail: detail as T }),\n );\n}\n","import { cssVars as raw } from \"@zitadel/design-tokens\";\nimport { unsafeCSS, type CSSResult } from \"lit\";\n\n/**\n * Lit-friendly token bridge.\n *\n * `@zitadel/design-tokens` exports two parallel trees:\n * - `tokens.color.text.primaryWhite === \"#f4f4f6\"` (resolved values)\n * - `cssVars.color.text.primaryWhite === \"var(--zl-color-text-primary-white)\"`\n *\n * Atom CSS authored with Lit's `css` tagged template needs `CSSResult`\n * fragments, not raw strings. This module wraps the cssVars tree in\n * `unsafeCSS` once so every atom can write:\n *\n * css`background: ${t.color.surface.defaultBlack};`\n *\n * The cssVars tree itself never changes shape outside of a design-tokens\n * rebuild, so the `unsafeCSS` calls are constant and safe.\n */\ntype CssNode = CSSResult | { readonly [k: string]: CssNode };\ntype CssTree = {\n [K in keyof typeof raw]: WrapTree<(typeof raw)[K]>;\n};\ntype WrapTree<T> = T extends string\n ? CSSResult\n : T extends Record<string, unknown>\n ? { [K in keyof T]: WrapTree<T[K]> }\n : never;\n\nfunction wrap(node: unknown): CssNode {\n if (typeof node === \"string\") return unsafeCSS(node);\n const out: Record<string, CssNode> = {};\n for (const [key, value] of Object.entries(node as Record<string, unknown>)) {\n out[key] = wrap(value);\n }\n return out;\n}\n\nexport const t = wrap(raw) as unknown as CssTree;\n","import { css } from \"lit\";\n\nimport { t } from \"./tokens.js\";\n\n/**\n * Shared shadow-root base styles. Each atom prepends this fragment to its own\n * `static styles` so font/colour inheritance, box-sizing, and resets stay\n * consistent without forcing a global stylesheet on the host page.\n */\nexport const baseHostStyles = css`\n :host {\n box-sizing: border-box;\n font-family: ${t.font.family.sans};\n color: ${t.color.text.primaryWhite};\n line-height: 1.5;\n -webkit-font-smoothing: antialiased;\n }\n *,\n *::before,\n *::after {\n box-sizing: inherit;\n }\n`;\n","import { css } from \"lit\";\n\nimport { t } from \"./tokens.js\";\n\n/**\n * Visible focus indicator shared across interactive atoms. Mirrors the\n * Figma button \"Focused\" state — a 2px white outline offset by 2px from\n * the element edge. Atoms apply via `&:focus-visible { ${focusVisibleStyles} }`.\n */\nexport const focusVisibleStyles = css`\n outline: ${t.focus.width} solid ${t.focus.color};\n outline-offset: ${t.focus.offset};\n`;\n","import { unsafeCSS, type CSSResult } from \"lit\";\n\n/**\n * Wrap shared surface CSS (from `@zitadel/shared-component-styles`)\n * for Lit `static styles`. Import `.css?inline` in atoms; `@tsdown/css` inlines\n * the strings when `components` is built.\n */\nexport function surfaceStyles(...cssChunks: string[]): CSSResult[] {\n return cssChunks.map((chunk) => unsafeCSS(chunk));\n}\n","/* Lit-only: <zl-icon> defers box metrics to inner .zr-icon. */\n:host {\n display: contents;\n color: inherit;\n}\n","/* Shared surface for `<zl-icon>` / `<Icon>`. Lit-only rules: lit/icon-host.css */\n.zr-icon {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n color: inherit;\n width: var(--zl-icon-size, 1.5rem);\n height: var(--zl-icon-size, 1.5rem);\n}\n.zr-icon--16 {\n --zl-icon-size: 1rem;\n}\n.zr-icon--24 {\n --zl-icon-size: 1.5rem;\n}\n.zr-icon--tone-error {\n color: var(--zl-color-icon-error);\n}\n.zr-icon--tone-success {\n color: var(--zl-color-icon-success);\n}\n.zr-icon--tone-disabled {\n color: var(--zl-color-icon-disabled);\n}\n.zr-icon svg {\n width: 100%;\n height: 100%;\n display: block;\n}\n.zr-icon--spin svg {\n animation: zr-icon-spin 800ms linear infinite;\n}\n@keyframes zr-icon-spin {\n to { transform: rotate(360deg); }\n}\n","import { LitElement, html, nothing } from \"lit\";\nimport { customElement, property } from \"lit/decorators.js\";\nimport { classMap } from \"lit/directives/class-map.js\";\nimport { unsafeSVG } from \"lit/directives/unsafe-svg.js\";\n\nimport iconHost from \"@zitadel/shared-component-styles/lit/icon-host.css?inline\";\nimport iconSurface from \"@zitadel/shared-component-styles/icon.css?inline\";\nimport {\n ArrowLeft,\n ArrowRight,\n Check,\n CircleAlert,\n Eye,\n EyeOff,\n type IconNode,\n Info,\n KeyRound,\n LoaderCircle,\n Plus,\n TriangleAlert,\n User,\n X,\n} from \"lucide\";\n\nimport type { AtomManifest } from \"../manifest.js\";\nimport { surfaceStyles } from \"../styles/index.js\";\n\n/**\n * Atom: `<zl-icon>` — renders a curated glyph from the Lucide icon library.\n *\n * The Figma design system (file `8UjCXw8yemgljmbkWGrSfE`, Icons set\n * `4103:10466`, sizes `16 | 24`) is explicitly built on Lucide. Rather than redrawing every glyph as an\n * inline `<path>` (which inevitably drifts), we curate the auth surface's\n * subset by importing each canonical Lucide node and exposing a stable\n * kebab-case `name` API. To add a glyph: import it from `lucide`, add an\n * entry to {@link ICON_NODES}, and extend the {@link IconName} union.\n *\n * Colour: by default the icon inherits `currentColor`. Set `tone` to one\n * of the semantic states to pick up `--zl-color-icon-{error|success|disabled}`\n * directly. The \"palette\" colour tokens (`--zl-color-icon-default-*`) are\n * not exposed as `tone` values; consumers wanting those set `color:` on\n * the host.\n *\n * Accessibility: glyphs with an entry in {@link DEFAULT_LABELS} expose an\n * `aria-label` so they're meaningful when used standalone. When the icon\n * is purely decorative (e.g. sitting next to a visible button label),\n * pass `decorative` to force `aria-hidden=\"true\"` and `role=\"presentation\"`,\n * which prevents the icon's name from leaking into the parent's\n * accessible name (e.g. avoids \"Loading Loading\" on a loading button).\n */\n@customElement(\"zl-icon\")\nexport class ZlIcon extends LitElement {\n /* No baseHostStyles — would force white on :host; icons inherit context color. */\n static override styles = surfaceStyles(iconHost, iconSurface);\n\n @property() accessor name: IconName = \"plus\";\n\n @property({ reflect: true }) accessor size: IconSize = \"24\";\n\n @property({ reflect: true }) accessor tone: IconTone = \"default\";\n\n @property({ type: Boolean, reflect: true }) accessor spin = false;\n\n @property({ type: Boolean, reflect: true }) accessor decorative = false;\n\n @property() accessor label: string | undefined = undefined;\n\n override render() {\n const ariaLabel = this.label ?? DEFAULT_LABELS[this.name];\n const hidden = this.decorative || !ariaLabel;\n const classes = classMap({\n \"zr-icon\": true,\n [`zr-icon--${this.size}`]: true,\n [`zr-icon--tone-${this.tone}`]: this.tone !== \"default\",\n \"zr-icon--spin\": this.spin,\n });\n return html`\n <span class=${classes}>\n <svg\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n stroke-width=\"2\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n role=${hidden ? \"presentation\" : \"img\"}\n aria-hidden=${hidden ? \"true\" : \"false\"}\n aria-label=${hidden ? nothing : ariaLabel}\n >${unsafeSVG(ICON_MARKUP[this.name])}</svg>\n </span>\n `;\n }\n}\n\n/** Public, kebab-case glyph IDs. Add a new one by extending both this union and {@link ICON_NODES}. */\nexport type IconName =\n | \"plus\"\n | \"arrow-right\"\n | \"arrow-left\"\n | \"spinner\"\n | \"check\"\n | \"cross\"\n | \"warning\"\n | \"alert-circle\"\n | \"info\"\n | \"passkey\"\n | \"user\"\n | \"eye\"\n | \"eye-off\";\n\n/** Auth-surface glyph list — keep playgrounds and parity tests in sync. */\nexport const SHIPPED_ICON_NAMES = [\n \"plus\",\n \"arrow-right\",\n \"arrow-left\",\n \"spinner\",\n \"check\",\n \"cross\",\n \"warning\",\n \"alert-circle\",\n \"info\",\n \"passkey\",\n \"user\",\n \"eye\",\n \"eye-off\",\n] as const satisfies readonly IconName[];\n\nexport type IconSize = \"16\" | \"24\";\n\nexport type IconTone = \"default\" | \"error\" | \"success\" | \"disabled\";\n\n/** Curated mapping from our public name to a Lucide canonical icon. */\nconst ICON_NODES: Record<IconName, IconNode> = {\n plus: Plus,\n \"arrow-right\": ArrowRight,\n \"arrow-left\": ArrowLeft,\n spinner: LoaderCircle,\n check: Check,\n cross: X,\n warning: TriangleAlert,\n \"alert-circle\": CircleAlert,\n info: Info,\n passkey: KeyRound,\n user: User,\n eye: Eye,\n \"eye-off\": EyeOff,\n};\n\nconst DEFAULT_LABELS: Partial<Record<IconName, string>> = {\n spinner: \"Loading\",\n warning: \"Warning\",\n \"alert-circle\": \"Alert\",\n info: \"Information\",\n passkey: \"Passkey\",\n user: \"User\",\n eye: \"Show\",\n \"eye-off\": \"Hide\",\n};\n\n// Pre-serialise the inner SVG markup once at module load so `render()` is\n// cheap. Lucide's `IconNode` payloads are static module data, so caching\n// the stringified output is safe and equivalent to inlining the source.\nconst ICON_MARKUP: Record<IconName, string> = Object.fromEntries(\n (Object.entries(ICON_NODES) as Array<[IconName, IconNode]>).map(([name, node]) => [\n name,\n nodeToSvgMarkup(node),\n ]),\n) as Record<IconName, string>;\n\nfunction nodeToSvgMarkup(node: IconNode): string {\n return node\n .map(([tag, attrs]) => {\n const attrStr = Object.entries(attrs)\n .filter(([, value]) => value !== undefined)\n .map(([key, value]) => `${key}=\"${String(value)}\"`)\n .join(\" \");\n return `<${tag} ${attrStr}/>`;\n })\n .join(\"\");\n}\n\nexport const zlIconManifest: AtomManifest = {\n tag: \"zl-icon\",\n attrs: [\"name\", \"size\", \"tone\", \"spin\", \"decorative\", \"label\"],\n parts: [],\n slots: [],\n events: [],\n} as const;\n\ndeclare global {\n interface HTMLElementTagNameMap {\n \"zl-icon\": ZlIcon;\n }\n}\n","import { LitElement, html } from \"lit\";\nimport { customElement, property } from \"lit/decorators.js\";\n\nimport alertHost from \"@zitadel/shared-component-styles/lit/alert-host.css?inline\";\nimport alertSurface from \"@zitadel/shared-component-styles/alert.css?inline\";\n\nimport { emit } from \"../internal/emit.js\";\nimport type { AtomManifest } from \"../manifest.js\";\nimport { baseHostStyles, surfaceStyles } from \"../styles/index.js\";\n\nimport \"./zl-icon.js\";\nimport type { IconName } from \"./zl-icon.js\";\n\n/**\n * Atom: `<zl-alert>` — inline status message replacing the legacy\n * `<zl-error>`.\n *\n * Spec lineage (file `8UjCXw8yemgljmbkWGrSfE`):\n * - design-system master: node `6593:2640` (Alert/Error). Screen instance\n * `6596:132779` matches the same chrome. Severity is conveyed by icon\n * shape and colour, not by tinting the background.\n *\n * Per-state Figma values:\n *\n * Layout\n * surface bg surface.default-primary-gray (#252528), no border\n * padding 16px (spacing-03)\n * gap 16px between icon and content\n * radius 12px (radius.m)\n * shadow 0 1px 2px rgba(16,24,40,0.05) (shadow-xs)\n *\n * Icon (16px)\n * error alert-circle, color text.error (#ea4f70)\n * warning alert-circle, color text.subtitle-orange (#f25543)\n * success check, color text.success (#33a779)\n * info info, color text.subtitle-gray (#bfbfcf)\n *\n * Text\n * heading Arimo SemiBold 14/20, color text.button-invert (#f4f4f6)\n * body Arimo Regular 14/20, color text.button-invert\n * gap (heading→body) 4px (spacing-01)\n *\n * Close button (when dismissible)\n * 36 × 36 hit target, padding 8px, radius 8px (radius.s)\n * icon `cross` at 20px, color text.secondary-gray\n * placed at the end of the flex row (icon · content · close)\n *\n * Templates render one per step when the flow returns errors; the\n * orchestrator surfaces flow-level errors through `errors` in the Liquid\n * context.\n */\n@customElement(\"zl-alert\")\nexport class ZlAlert extends LitElement {\n static override styles = [\n baseHostStyles,\n ...surfaceStyles(alertHost, alertSurface),\n ];\n\n @property({ reflect: true }) accessor severity: \"error\" | \"success\" | \"warning\" | \"info\" = \"error\";\n\n @property() accessor heading: string | undefined = undefined;\n\n @property({ type: Boolean, reflect: true }) accessor dismissible = false;\n\n override render() {\n const iconName = ICON_FOR_SEVERITY[this.severity];\n return html`\n <div\n class=\"zr-alert zr-alert--${this.severity}\"\n part=\"alert\"\n role=${this.severity === \"error\" ? \"alert\" : \"status\"}\n aria-live=${this.severity === \"error\" ? \"assertive\" : \"polite\"}\n >\n <zl-icon class=\"zr-alert__icon\" part=\"icon\" name=${iconName} size=\"16\" decorative></zl-icon>\n <div class=\"zr-alert__body\" part=\"body\">\n ${this.heading ? html`<span class=\"zr-alert__title\" part=\"title\">${this.heading}</span>` : null}\n <div class=\"zr-alert__message\" part=\"message\">\n <slot></slot>\n </div>\n </div>\n ${this.dismissible\n ? html`<button\n type=\"button\"\n class=\"zr-alert__close\"\n part=\"close\"\n aria-label=\"Dismiss\"\n @click=${this.handleDismiss}\n >\n <zl-icon name=\"cross\" size=\"16\" label=\"Dismiss\" decorative></zl-icon>\n </button>`\n : null}\n </div>\n `;\n }\n\n private handleDismiss = (): void => {\n emit(this, \"zl-dismiss\");\n this.remove();\n };\n}\n\nconst ICON_FOR_SEVERITY: Record<NonNullable<ZlAlert[\"severity\"]>, IconName> = {\n error: \"alert-circle\",\n warning: \"alert-circle\",\n success: \"check\",\n info: \"info\",\n};\n\nexport const zlAlertManifest: AtomManifest = {\n tag: \"zl-alert\",\n attrs: [\"severity\", \"heading\", \"dismissible\"],\n parts: [\"alert\", \"icon\", \"body\", \"title\", \"message\", \"close\"],\n slots: [\"\"],\n events: [\"zl-dismiss\"],\n} as const;\n\ndeclare global {\n interface HTMLElementTagNameMap {\n \"zl-alert\": ZlAlert;\n }\n}\n","/* Lit-only: <zl-button> host and slots (surface rules live in ../button.css). */\n:host {\n display: inline-flex;\n}\n:host([block]) {\n display: flex;\n width: 100%;\n}\n/* Slotted <zl-icon> is a light-DOM child of the host, not of .zr-btn — match the\n inner button foreground so icons inherit the same color as the label. */\n:host([hierarchy=\"primary\"]) {\n color: var(--zl-color-text-button-default, #0f0f11);\n}\n:host([hierarchy=\"secondary\"]),\n:host([hierarchy=\"text\"]) {\n color: var(--zl-color-text-button-invert, #f4f4f6);\n}\n:host([disabled]) {\n color: var(--zl-color-text-disabled, #686883);\n}\n::slotted([slot=\"leading\"]),\n::slotted([slot=\"trailing\"]) {\n display: inline-flex;\n align-items: center;\n}\n.zr-btn .spinner {\n display: inline-flex;\n}\n","/* Shared surface for `<zl-button>` / `<Button>`. Lit-only rules: lit/button-host.css */\n: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 font-weight: 600;\n display: inline-flex;\n width: max-content;\n align-items: center;\n justify-content: center;\n gap: var(--zl-spacing-02, 0.5rem);\n padding-inline: var(--zl-spacing-03, 1rem);\n padding-block: 0.625rem;\n border-radius: var(--zl-radius-s, 0.5rem);\n border: 1px solid transparent;\n text-align: center;\n white-space: nowrap;\n transition:\n background-color var(--zl-duration-fast, 120ms) var(--zl-easing-standard, cubic-bezier(0.2, 0, 0, 1)),\n color var(--zl-duration-fast, 120ms) var(--zl-easing-standard, cubic-bezier(0.2, 0, 0, 1)),\n border-color var(--zl-duration-fast, 120ms) var(--zl-easing-standard, cubic-bezier(0.2, 0, 0, 1)),\n background-image var(--zl-duration-fast, 120ms) var(--zl-easing-standard, cubic-bezier(0.2, 0, 0, 1));\n}\n.zr-btn:focus-visible,\n.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.zr-btn--block {\n display: flex;\n width: 100%;\n}\n.zr-btn--medium {\n height: 3rem;\n font-size: 1rem;\n line-height: 1.5rem;\n}\n.zr-btn--small {\n height: 2.5rem;\n font-size: 0.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.zr-btn--primary:hover:not(:disabled),\n.zr-btn--primary:active:not(:disabled),\n.zr-btn--primary:focus-visible:not(:disabled),\n.zr-btn--primary[data-state=\"hovered\"]:not(:disabled),\n.zr-btn--primary[data-state=\"pressed\"]:not(:disabled),\n.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.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.zr-btn--secondary:hover:not(:disabled),\n.zr-btn--secondary:active:not(:disabled),\n.zr-btn--secondary[data-state=\"hovered\"]:not(:disabled),\n.zr-btn--secondary[data-state=\"pressed\"]:not(:disabled) {\n background: var(--zl-color-gray-200, #484a57);\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 background: transparent;\n color: var(--zl-color-text-button-invert, #f4f4f6);\n}\n.zr-btn--text:hover:not(:disabled),\n.zr-btn--text:active:not(:disabled),\n.zr-btn--text[data-state=\"hovered\"]:not(:disabled),\n.zr-btn--text[data-state=\"pressed\"]:not(:disabled) {\n background: var(--zl-color-gray-200, #484a57);\n}\n.zr-btn--text:focus-visible:not(:disabled),\n.zr-btn--text[data-state=\"focused\"]:not(:disabled) {\n background: var(--zl-color-border-default-black, #252528);\n}\n.zr-btn--text:disabled {\n color: var(--zl-color-text-disabled, #686883);\n cursor: not-allowed;\n}\n","import { LitElement, html, nothing } from \"lit\";\nimport { customElement, property } from \"lit/decorators.js\";\nimport { classMap } from \"lit/directives/class-map.js\";\n\nimport buttonHost from \"@zitadel/shared-component-styles/lit/button-host.css?inline\";\nimport buttonSurface from \"@zitadel/shared-component-styles/button.css?inline\";\n\nimport { emit } from \"../internal/emit.js\";\nimport type { AtomManifest } from \"../manifest.js\";\nimport { baseHostStyles, surfaceStyles } from \"../styles/index.js\";\n\nimport \"./zl-icon.js\";\n\n/**\n * Atom: `<zl-button>` — the entire Figma button matrix in a single atom.\n *\n * Spec lineage (file `8UjCXw8yemgljmbkWGrSfE`, \"Zitadel - Design System - External\"):\n * - master variant set: node `6598:292`\n * - icon-leading instance reference: node `6598:143281` (passkey upsell)\n *\n * Variant axes (matches Figma directly):\n * - hierarchy: primary | secondary | text\n * - size: medium (48 × auto) | small (40 × auto)\n * - state: enabled / hovered / focused / pressed / disabled\n * (derived from interaction, not props)\n * - slots: `leading` icon, `trailing` icon, default for the label.\n * When `loading` is set the trailing slot is replaced with a\n * spinning ring (Figma shows the spinner trailing).\n *\n * Per-state Figma values (resolved from `figma.tokens.json` primitives):\n *\n * Primary\n * enabled bg=#f4f4f6 (surface.default-white) fg=#0f0f11 border=transparent\n * hover/pressed bg=#cfcfde (gray.600) fg=#0f0f11 border=1px #252528\n * focus-visible bg=#cfcfde + native outline ring\n * disabled bg=#f4f4f6 fg=#686883 (text.disabled)\n *\n * Secondary\n * enabled bg=#252528 (border.default-black) fg=#f4f4f6 (text.button-invert)\n * hover/pressed bg=#484a57 (gray.200) fg=#f4f4f6\n * focus-visible bg=#252528 + native outline ring fg=#f4f4f6\n * disabled bg=#252528 fg=#686883\n *\n * Text\n * enabled bg=transparent fg=#f4f4f6\n * hover/pressed bg=#484a57 fg=#f4f4f6\n * focus-visible bg=#252528 + native outline ring fg=#f4f4f6\n * disabled bg=transparent fg=#686883\n *\n * Common\n * padding 10px (block) / 16px (inline) radius=8px\n * gap 8px between icon/label/icon\n * font Arimo SemiBold (600)\n * medium: 16/24 small: 14/20\n * icon 24px medium, 16px small\n * focus ring 2px solid #f4f4f6, 2px offset\n * transition background-color / color / border-color, fast standard\n *\n * Form-associated so it can participate in the orchestrator's `<form>`\n * exactly like a native `<button>`. Setting `type=\"submit\"` triggers\n * `form.requestSubmit()` on click; setting `type=\"reset\"` calls\n * `form.reset()`. Otherwise the click event bubbles for SPA listeners.\n *\n * The atom always renders a real `<button>` inside the shadow root —\n * `delegatesFocus` ensures Tab lands on it and `<zl-field>`'s\n * Enter-to-submit pipe still fires the host form.\n */\n@customElement(\"zl-button\")\nexport class ZlButton extends LitElement {\n static formAssociated = true;\n\n static override shadowRootOptions: ShadowRootInit = {\n ...LitElement.shadowRootOptions,\n delegatesFocus: true,\n };\n\n static override styles = [\n baseHostStyles,\n ...surfaceStyles(buttonHost, buttonSurface),\n ];\n\n @property({ reflect: true }) accessor hierarchy: \"primary\" | \"secondary\" | \"text\" = \"primary\";\n\n @property({ reflect: true }) accessor size: \"medium\" | \"small\" = \"medium\";\n\n @property() accessor type: \"button\" | \"submit\" | \"reset\" = \"button\";\n\n @property() accessor action: string | undefined = undefined;\n\n @property({ type: Boolean }) accessor loading = false;\n\n @property({ type: Boolean, reflect: true }) accessor disabled = false;\n\n @property({ type: Boolean, reflect: true }) accessor block = false;\n\n @property() accessor label: string | undefined = undefined;\n\n /**\n * Forces a visual interaction state on the inner button, projected to its\n * `data-state` attribute. Used by the design playground to capture\n * hover/pressed/focus states; reactive so toggling the host attribute\n * re-renders.\n */\n @property({ attribute: \"data-state\" }) accessor forcedState: string | null = null;\n\n private readonly internals: ElementInternals;\n\n constructor() {\n super();\n this.internals = this.attachInternals();\n }\n\n override focus(options?: FocusOptions): void {\n this.shadowRoot?.querySelector<HTMLButtonElement>(\"button\")?.focus(options);\n }\n\n override render() {\n const blocked = this.disabled || this.loading;\n // If `label` is provided, render the text directly and treat the default\n // slot as a fallback (avoids the whitespace-only slot bug where indentation\n // between `<zl-icon slot=\"leading\">` tags marks the default slot as\n // \"assigned\" with text nodes, suppressing slot fallback content).\n const body = this.label !== undefined ? html`<span>${this.label}</span>` : html`<slot></slot>`;\n return html`\n <button\n class=${classMap({\n root: true,\n \"zr-btn\": true,\n [`zr-btn--${this.hierarchy}`]: true,\n [`zr-btn--${this.size}`]: true,\n \"zr-btn--block\": this.block,\n })}\n part=\"root\"\n type=${this.type}\n ?disabled=${blocked}\n aria-busy=${this.loading ? \"true\" : \"false\"}\n data-state=${this.forcedState ?? nothing}\n @click=${this.handleClick}\n >\n <slot name=\"leading\"></slot>\n ${body}\n ${this.loading\n ? html`<span class=\"spinner\" part=\"spinner\"><zl-icon name=\"spinner\" size=${this.size === \"small\" ? \"16\" : \"24\"} spin decorative></zl-icon></span>`\n : html`<slot name=\"trailing\"></slot>`}\n </button>\n `;\n }\n\n private handleClick = (event: MouseEvent): void => {\n if (this.disabled || this.loading) {\n event.preventDefault();\n event.stopImmediatePropagation();\n return;\n }\n const form = this.internals.form;\n if (this.type === \"submit\" && form) {\n // Mirror native <button type=\"submit\"> behaviour through the\n // shadow boundary so the host <form>'s validation runs.\n event.preventDefault();\n form.requestSubmit();\n } else if (this.type === \"reset\" && form) {\n event.preventDefault();\n form.reset();\n }\n emit<{ action: string | null }>(this, \"zl-submit\", { action: this.action ?? null });\n };\n}\n\nexport const zlButtonManifest: AtomManifest = {\n tag: \"zl-button\",\n consumes: { action: { kind: \"submit\", required: false } },\n attrs: [\"hierarchy\", \"size\", \"type\", \"action\", \"loading\", \"disabled\", \"block\", \"label\"],\n parts: [\"root\", \"spinner\"],\n slots: [\"\", \"leading\", \"trailing\"],\n events: [\"zl-submit\"],\n} as const;\n\ndeclare global {\n interface HTMLElementTagNameMap {\n \"zl-button\": ZlButton;\n }\n}\n","/* Lit-only: <zl-card> width constraint and slotted margin reset. */\n:host {\n display: block;\n width: 100%;\n max-width: var(--zl-container-auth-card, 24rem);\n margin-inline: auto;\n}\n.zr-card ::slotted([slot=\"header\"]),\n.zr-card ::slotted([slot=\"footer\"]) {\n margin: 0;\n}\n","/* Shared surface for `<zl-card>` / `<Card>`. Lit-only rules: lit/card-host.css */\n.zr-card {\n width: 100%;\n max-width: var(--zl-container-auth-card, 24rem);\n margin-inline: auto;\n background: transparent;\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 display: flex;\n flex-direction: column;\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}\n.zr-card--compact {\n gap: var(--zl-spacing-04, 1.5rem);\n}\n.zr-card__header,\n.zr-card__footer {\n display: flex;\n flex-direction: column;\n gap: var(--zl-spacing-02, 0.5rem);\n}\n/* Lit keeps slots mounted; hide empty regions so flex gap matches React Card. */\n.zr-card__region--empty {\n display: none;\n}\n.zr-card__body {\n display: flex;\n flex-direction: column;\n gap: var(--zl-spacing-03, 1rem);\n}\n","import { LitElement, html } from \"lit\";\nimport { customElement, property } from \"lit/decorators.js\";\n\nimport cardHost from \"@zitadel/shared-component-styles/lit/card-host.css?inline\";\nimport cardSurface from \"@zitadel/shared-component-styles/card.css?inline\";\n\nimport type { AtomManifest } from \"../manifest.js\";\nimport { baseHostStyles, surfaceStyles } from \"../styles/index.js\";\n\n/**\n * Atom: `<zl-card>` — the auth-card surface used by every flow screen.\n *\n * Spec lineage (file `xkvBjkOJ8ENuHdTGZHXezK`):\n * - sign-in: node `6593:141985` (combined sign-in card, 32px gap)\n * - sign-up: node `6593:141743` / frame `6593:141741` (title only, 32px gap)\n * - passkey-upsell: node `6594:632` (288h, heading+subtitle, 24px gap)\n * - signed-in: node `6596:132846` (272h, heading+subtitle, 24px gap)\n *\n * Per-state Figma values (constant across all four screens unless noted):\n *\n * width 384px fixed (container.auth-card token; xs collapses\n * to full-width via the surrounding page-shell)\n * background transparent — the page (surface.default-black) shows\n * through; the card is *not* an elevated surface, only\n * outlined\n * border 1px solid surface.default-primary-gray (#252528)\n * radius 16px (radius.l)\n * padding 32px all sides (spacing-05)\n * gap 32px between header / body / footer slots (sign-in,\n * sign-up). Passkey-upsell + signed-in tighten to 24px\n * (spacing-04) via `compact` because their heading group\n * carries a subtitle.\n *\n * Internal slot gaps:\n * header 8px (spacing-02) — heading → subtitle stack\n * body 16px (spacing-03) — fields/buttons stack (matches\n * Figma \"Field+CTAs\" gap)\n * footer 8px (spacing-02) — auxiliary links\n */\n@customElement(\"zl-card\")\nexport class ZlCard extends LitElement {\n static override styles = [baseHostStyles, ...surfaceStyles(cardHost, cardSurface)];\n\n @property({ type: Boolean, reflect: true }) accessor compact = false;\n\n override render() {\n const hasHeader = this.lightDomSlotFilled(\"header\");\n const hasFooter = this.lightDomSlotFilled(\"footer\");\n const cardClass = this.compact ? \"zr-card zr-card--compact\" : \"zr-card\";\n const headerClass = hasHeader ? \"zr-card__header\" : \"zr-card__header zr-card__region--empty\";\n const footerClass = hasFooter ? \"zr-card__footer\" : \"zr-card__footer zr-card__region--empty\";\n return html`\n <section class=${cardClass} part=\"card\">\n <header class=${headerClass} part=\"header\">\n <slot name=\"header\" @slotchange=${this.onSlotChange}></slot>\n </header>\n <div class=\"zr-card__body\" part=\"body\">\n <slot></slot>\n </div>\n <footer class=${footerClass} part=\"footer\">\n <slot name=\"footer\" @slotchange=${this.onSlotChange}></slot>\n </footer>\n </section>\n `;\n }\n\n /**\n * `lightDomSlotFilled` is a render-time snapshot, so re-run render whenever a\n * named slot's assignment changes (e.g. a header added after first paint).\n * The initial render still reads children synchronously, avoiding the\n * empty-then-filled flash a slotchange-only approach would introduce.\n */\n private onSlotChange = (): void => {\n this.requestUpdate();\n };\n\n /** Slotted nodes are always light-DOM children of the host in our templates. */\n private lightDomSlotFilled(slot: string): boolean {\n for (const child of this.children) {\n if (child.getAttribute(\"slot\") === slot) return true;\n }\n return false;\n }\n}\n\nexport const zlCardManifest: AtomManifest = {\n tag: \"zl-card\",\n attrs: [\"compact\"],\n parts: [\"card\", \"header\", \"body\", \"footer\"],\n slots: [\"\", \"header\", \"footer\"],\n events: [],\n} as const;\n\ndeclare global {\n interface HTMLElementTagNameMap {\n \"zl-card\": ZlCard;\n }\n}\n","/* Lit-only: <zl-field> slots, hidden helpers, dev-matrix preview states. */\n:host {\n display: block;\n}\n::slotted([slot=\"prefix\"]),\n::slotted([slot=\"suffix\"]) {\n color: var(--zl-color-text-secondary-gray, #bfbfcf);\n display: inline-flex;\n}\n.zr-field__help[hidden],\n.zr-field__error[hidden] {\n display: none;\n}\n\n/* Atom playground only — `data-state` on `<zl-field>` documents Figma columns; not product API. */\n:host([data-state=\"hovered\"]:not([disabled])) .zr-field:not(.zr-field--invalid):not(.zr-field--success)\n .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:host([data-state=\"focused\"]:not([disabled])) .zr-field:not(.zr-field--invalid):not(.zr-field--success)\n .zr-field__wrap {\n border-color: var(--zl-color-border-default-white, #f4f4f6);\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:host([data-state=\"focused\"]:not([disabled])) .zr-field--success .zr-field__wrap {\n border-color: var(--zl-color-border-success, #33a779);\n}\n","/* Shared surface for `<zl-field>` / `<TextField>`. Lit-only rules: lit/text-field-host.css */\n/* Figma master: 8UjCXw8yemgljmbkWGrSfE / Text Field 4390:1404 */\n.zr-field {\n display: flex;\n flex-direction: column;\n align-items: stretch;\n gap: var(--zl-spacing-02, 0.5rem);\n font-family: var(--zl-font-family-sans, system-ui, sans-serif);\n}\n.zr-field__label-row {\n display: flex;\n align-items: flex-start;\n justify-content: space-between;\n gap: var(--zl-spacing-02, 0.5rem);\n width: 100%;\n}\n.zr-field__label {\n display: inline-flex;\n align-items: center;\n gap: var(--zl-spacing-01, 0.25rem);\n font-size: 1rem;\n font-weight: 600;\n line-height: 1.5rem;\n color: var(--zl-color-text-primary-white, #f4f4f6);\n}\n.zr-field__link {\n flex-shrink: 0;\n font-size: 0.875rem;\n font-weight: 400;\n line-height: 1.25rem;\n color: var(--zl-color-icon-default-purple, #bba5e4);\n text-decoration: none;\n}\n.zr-field__link:hover {\n text-decoration: underline;\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.zr-field__required {\n color: var(--zl-color-text-error, #ea4f70);\n}\n.zr-field--disabled .zr-field__label {\n color: var(--zl-color-text-disabled, #686883);\n}\n.zr-field__wrap {\n position: relative;\n display: flex;\n align-items: center;\n gap: var(--zl-spacing-02, 0.5rem);\n padding-block: var(--zl-spacing-02, 0.5rem);\n padding-inline: var(--zl-spacing-03, 1rem);\n height: 2.5rem;\n border-radius: var(--zl-radius-xs, 0.25rem);\n border: 1px solid var(--zl-color-border-default-gray-300, #686883);\n background: transparent;\n overflow: visible;\n transition:\n border-color var(--zl-duration-fast, 120ms) var(--zl-easing-standard, cubic-bezier(0.2, 0, 0, 1)),\n background-color var(--zl-duration-fast, 120ms) var(--zl-easing-standard, cubic-bezier(0.2, 0, 0, 1));\n box-sizing: border-box;\n}\n.zr-field__wrap--trailing {\n padding-inline-end: 2.5rem;\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.zr-field:not(.zr-field--invalid):not(.zr-field--disabled):not(.zr-field--success)\n .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/* Figma State=Focused (`4390:2180`): single 1px border on the field — no outer focus ring. */\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.zr-field--invalid .zr-field__wrap {\n border-color: var(--zl-color-border-error, #ea4f70);\n}\n.zr-field--invalid .zr-field__wrap:focus-within {\n border-color: var(--zl-color-border-error, #ea4f70);\n outline: none;\n}\n.zr-field--success .zr-field__wrap {\n border-color: var(--zl-color-border-success, #33a779);\n}\n.zr-field--success .zr-field__wrap:focus-within {\n border-color: var(--zl-color-border-success, #33a779);\n outline: none;\n}\n.zr-field--disabled .zr-field__wrap {\n border-color: var(--zl-color-border-default-gray-200, #484a57);\n}\n.zr-field__input {\n flex: 1 1 auto;\n min-width: 0;\n height: 100%;\n padding: 0;\n border: 0;\n outline: none;\n background: transparent;\n color: var(--zl-color-text-primary-white, #f4f4f6);\n font-family: inherit;\n font-size: 0.875rem;\n line-height: 1.25rem;\n font-weight: 400;\n}\n.zr-field__input[type=\"password\"] {\n letter-spacing: 0.125rem;\n}\n.zr-field__input::placeholder {\n color: var(--zl-color-text-secondary-gray, #bfbfcf);\n}\n.zr-field__input:focus,\n.zr-field__input:focus-visible {\n outline: none;\n}\n.zr-field__input:disabled {\n cursor: not-allowed;\n color: var(--zl-color-text-disabled, #686883);\n}\n.zr-field--disabled .zr-field__wrap:hover {\n border-color: var(--zl-color-border-default-gray-200, #484a57);\n background-color: transparent;\n}\n.zr-field__trailing {\n position: absolute;\n right: 0.9375rem;\n top: 50%;\n transform: translateY(-50%);\n display: inline-flex;\n align-items: center;\n justify-content: center;\n width: 1rem;\n height: 1rem;\n color: var(--zl-color-text-secondary-gray, #bfbfcf);\n}\n.zr-field__trailing-action {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n padding: 0;\n margin: 0;\n border: 0;\n background: transparent;\n color: inherit;\n cursor: pointer;\n line-height: 0;\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.zr-field__trailing-action:disabled {\n cursor: not-allowed;\n}\n.zr-field--invalid .zr-field__trailing {\n color: var(--zl-color-text-error, #ea4f70);\n}\n.zr-field--success .zr-field__trailing {\n color: var(--zl-color-text-success, #33a779);\n}\n.zr-field__help {\n font-size: 0.75rem;\n line-height: 1rem;\n color: var(--zl-color-text-primary-white, #f4f4f6);\n}\n.zr-field__success {\n font-size: 0.75rem;\n line-height: 1rem;\n color: var(--zl-color-text-success, #33a779);\n}\n.zr-field__error {\n font-size: 0.75rem;\n line-height: 1rem;\n color: var(--zl-color-text-error, #ea4f70);\n}\n","/**\n * Monotonic counter for DOM IDs that need to be unique within a document but\n * stable across renders. Used by atoms that wire `<label for>` ↔ `<input id>`\n * inside their Shadow DOM.\n *\n * A counter beats `Math.random()` and `crypto.randomUUID()` here:\n *\n * - Tests get deterministic IDs.\n * - There's zero collision risk within a page.\n * - It's an order of magnitude faster on each component instantiation.\n */\nlet counter = 0;\n\nexport function nextUid(prefix: string): string {\n counter += 1;\n return `${prefix}-${counter}`;\n}\n","import type { CreateFlow201StepFieldsType } from \"@zitadel/api/generated/model\";\nimport { LitElement, html, nothing, type PropertyValues } from \"lit\";\nimport { customElement, property, query, state } from \"lit/decorators.js\";\nimport { classMap } from \"lit/directives/class-map.js\";\nimport { ifDefined } from \"lit/directives/if-defined.js\";\nimport { live } from \"lit/directives/live.js\";\n\nimport fieldHost from \"@zitadel/shared-component-styles/lit/text-field-host.css?inline\";\nimport fieldSurface from \"@zitadel/shared-component-styles/text-field.css?inline\";\n\nimport { emit } from \"../internal/emit.js\";\nimport { nextUid } from \"../internal/unique-id.js\";\nimport type { AtomManifest } from \"../manifest.js\";\nimport { baseHostStyles, surfaceStyles } from \"../styles/index.js\";\n\nimport \"./zl-icon.js\";\nimport type { IconName } from \"./zl-icon.js\";\n\n/**\n * Alias of the orval-generated wire enum for field types so the atom's\n * accepted `type` values track the API contract exactly.\n */\nexport type ZlFieldType = CreateFlow201StepFieldsType;\n\n/** Detail shape emitted by the `zl-input` event (input + clear). */\nexport type ZlFieldInputDetail = { name: string; value: string };\n\n/**\n * Atom: `<zl-field>` — labelled input bound to a step `field`. Visual\n * spec lineage:\n * - design-system master variant set: node `4390:1404` (file\n * `8UjCXw8yemgljmbkWGrSfE`) — Enabled / Hovered / Focused / Filled /\n * Disabled / Error / Success / Password forgot\n *\n * Per-state Figma values (master `4390:1404`):\n *\n * Layout\n * root flex-column, gap=8px (spacing-02)\n * label row optional \"Forgot password?\" link (#bba5e4, 14/20)\n * input-wrap 40px, padding 8/16, trailing icon at right 15px\n * trailing cross (clear) | alert-circle (error) | check (success)\n *\n * Form participation: `<zl-field>` is a form-associated custom element.\n */\n@customElement(\"zl-field\")\nexport class ZlField extends LitElement {\n static formAssociated = true;\n\n static override shadowRootOptions: ShadowRootInit = {\n ...LitElement.shadowRootOptions,\n delegatesFocus: true,\n };\n\n static override styles = [\n baseHostStyles,\n ...surfaceStyles(fieldHost, fieldSurface),\n ];\n\n /**\n * Field name — used as the key in form submission and in `zl-input` event\n * detail. For form-associated custom elements the browser owns a native\n * `name` property; using `@property()` would create a conflicting accessor\n * that loses sync with the DOM attribute. We therefore manage it manually.\n */\n get name(): string {\n return this.getAttribute(\"name\") ?? \"\";\n }\n\n set name(value: string) {\n this.setAttribute(\"name\", value);\n }\n @property() accessor label = \"\";\n @property() accessor type: ZlFieldType = \"text\";\n @property() accessor value = \"\";\n @property() accessor placeholder = \"\";\n @property() accessor autocomplete: string | undefined = undefined;\n @property() accessor pattern: string | undefined = undefined;\n @property() accessor error = \"\";\n @property() accessor success = \"\";\n @property({ attribute: \"forgot-password-href\" }) accessor forgotPasswordHref: string | undefined =\n undefined;\n @property({ attribute: \"forgot-password-label\" }) accessor forgotPasswordLabel =\n \"Forgot password?\";\n @property({ type: Boolean, attribute: \"trailing-icon\" }) accessor trailingIcon = true;\n @property({ type: Boolean }) accessor required = false;\n @property({ type: Boolean, reflect: true }) accessor disabled = false;\n @property({ type: Boolean, reflect: true }) accessor invalid = false;\n\n @state() private accessor hasHelp = false;\n @state() private accessor hasSuffixSlot = false;\n\n @query(\".zr-field__input\") private accessor inputEl: HTMLInputElement | null = null;\n\n private readonly inputId = nextUid(\"zl-field\");\n private readonly internals: ElementInternals;\n\n constructor() {\n super();\n this.internals = this.attachInternals();\n }\n\n override connectedCallback(): void {\n super.connectedCallback();\n this.syncFormState();\n }\n\n override willUpdate(changed: PropertyValues<this>): void {\n if (changed.has(\"value\") || changed.has(\"required\") || changed.has(\"error\")) {\n this.syncFormState();\n }\n }\n\n formResetCallback(): void {\n this.value = \"\";\n }\n\n formStateRestoreCallback(state: string | null): void {\n this.value = state ?? \"\";\n }\n\n override focus(options?: FocusOptions): void {\n this.inputEl?.focus(options);\n }\n\n override render() {\n const labelId = `${this.inputId}-label`;\n const errorId = `${this.inputId}-error`;\n const successId = `${this.inputId}-success`;\n const helpId = `${this.inputId}-help`;\n const showError = Boolean(this.error);\n const showSuccess = Boolean(this.success) && !showError && !this.invalid;\n const describedBy = [\n showError ? errorId : null,\n showSuccess ? successId : null,\n this.hasHelp ? helpId : null,\n ]\n .filter(Boolean)\n .join(\" \");\n const rootClass = classMap({\n \"zr-field\": true,\n \"zr-field--invalid\": this.invalid || showError,\n \"zr-field--success\": showSuccess,\n \"zr-field--disabled\": this.disabled,\n });\n const showDefaultTrailing =\n this.trailingIcon && !this.hasSuffixSlot && !this.disabled;\n const trailing = showDefaultTrailing ? this.renderTrailingIcon() : null;\n const wrapClass = classMap({\n \"zr-field__wrap\": true,\n \"zr-field__wrap--trailing\": showDefaultTrailing,\n });\n\n return html`\n <div class=${rootClass} part=\"root\">\n ${this.renderLabelRow(labelId)}\n <div class=${wrapClass} part=\"input-wrap\">\n <slot name=\"prefix\"></slot>\n <input\n class=\"zr-field__input\"\n part=\"input\"\n id=${this.inputId}\n name=${this.name}\n type=${this.type}\n .value=${live(this.value)}\n placeholder=${this.placeholder}\n autocomplete=${ifDefined(this.autocomplete)}\n pattern=${ifDefined(this.pattern)}\n ?required=${this.required}\n ?disabled=${this.disabled}\n aria-invalid=${this.invalid || showError ? \"true\" : \"false\"}\n aria-describedby=${describedBy || nothing}\n @input=${this.handleInput}\n @change=${this.handleChange}\n @keydown=${this.handleKeyDown}\n />\n <slot name=\"suffix\" @slotchange=${this.handleSuffixSlotChange}></slot>\n ${trailing}\n </div>\n <div class=\"zr-field__help\" part=\"help\" id=${helpId} ?hidden=${!this.hasHelp}>\n <slot name=\"help\" @slotchange=${this.handleHelpSlotChange}></slot>\n </div>\n <div\n class=\"zr-field__success\"\n part=\"success\"\n id=${successId}\n role=\"status\"\n ?hidden=${!showSuccess}\n >\n ${this.success}\n </div>\n <div class=\"zr-field__error\" part=\"error\" id=${errorId} role=\"alert\" ?hidden=${!showError}>\n ${this.error}\n </div>\n </div>\n `;\n }\n\n private renderLabelRow(labelId: string) {\n if (!this.label) {\n return null;\n }\n if (this.forgotPasswordHref) {\n return html`\n <div class=\"zr-field__label-row\" part=\"label-row\">\n <label class=\"zr-field__label\" part=\"label\" id=${labelId} for=${this.inputId}>\n <span>${this.label}</span>\n ${this.required\n ? html`<span class=\"zr-field__required\" aria-hidden=\"true\">*</span>`\n : null}\n </label>\n <a class=\"zr-field__link\" part=\"forgot-link\" href=${this.forgotPasswordHref}\n >${this.forgotPasswordLabel}</a\n >\n </div>\n `;\n }\n return html`\n <label class=\"zr-field__label\" part=\"label\" id=${labelId} for=${this.inputId}>\n <span>${this.label}</span>\n ${this.required\n ? html`<span class=\"zr-field__required\" aria-hidden=\"true\">*</span>`\n : null}\n </label>\n `;\n }\n\n private renderTrailingIcon() {\n let iconName: IconName = \"cross\";\n let tone: \"default\" | \"error\" | \"success\" = \"default\";\n let clearable = true;\n\n if (this.invalid || this.error) {\n iconName = \"alert-circle\";\n tone = \"error\";\n clearable = false;\n } else if (this.success) {\n iconName = \"check\";\n tone = \"success\";\n clearable = false;\n }\n\n const icon = html`<zl-icon name=${iconName} size=\"16\" tone=${tone} decorative></zl-icon>`;\n\n if (!clearable) {\n return html`<span class=\"zr-field__trailing\" part=\"trailing-icon\">${icon}</span>`;\n }\n\n return html`\n <span class=\"zr-field__trailing\" part=\"trailing-icon\">\n <button\n type=\"button\"\n class=\"zr-field__trailing-action\"\n part=\"trailing-action\"\n aria-label=\"Clear\"\n ?disabled=${this.disabled}\n @click=${this.handleClear}\n >\n ${icon}\n </button>\n </span>\n `;\n }\n\n private syncFormState(): void {\n this.internals.setFormValue?.(this.value);\n if (this.required && !this.value) {\n this.internals.setValidity?.({ valueMissing: true }, \"Please fill out this field.\");\n } else if (this.error) {\n this.internals.setValidity?.({ customError: true }, this.error);\n } else {\n this.internals.setValidity?.({});\n }\n }\n\n private handleHelpSlotChange = (event: Event): void => {\n const slot = event.target as HTMLSlotElement;\n this.hasHelp = slot.assignedNodes({ flatten: true }).length > 0;\n };\n\n private handleSuffixSlotChange = (event: Event): void => {\n const slot = event.target as HTMLSlotElement;\n this.hasSuffixSlot = slot.assignedNodes({ flatten: true }).length > 0;\n };\n\n private handleClear = (): void => {\n this.value = \"\";\n emit<ZlFieldInputDetail>(this, \"zl-input\", { name: this.name, value: this.value });\n this.syncFormState();\n this.inputEl?.focus();\n };\n\n private handleInput = (event: Event): void => {\n const input = event.target as HTMLInputElement;\n this.value = input.value;\n emit<ZlFieldInputDetail>(this, \"zl-input\", { name: this.name, value: this.value });\n };\n\n private handleChange = (event: Event): void => {\n const input = event.target as HTMLInputElement;\n this.value = input.value;\n // Re-dispatch the native `change` across the shadow boundary so host\n // forms and listeners see standard form semantics. This is a DOM standard\n // event, deliberately NOT part of the `zl-*` override contract in the\n // manifest (which tracks only the atom's custom `zl-*` events).\n this.dispatchEvent(new Event(\"change\", { bubbles: true, composed: true }));\n };\n\n private handleKeyDown = (event: KeyboardEvent): void => {\n if (\n event.key === \"Enter\" &&\n !event.isComposing &&\n !event.shiftKey &&\n !event.altKey &&\n !event.metaKey &&\n !event.ctrlKey\n ) {\n const form = this.internals.form;\n if (form) {\n event.preventDefault();\n form.requestSubmit();\n }\n }\n };\n}\n\nexport const zlFieldManifest: AtomManifest = {\n tag: \"zl-field\",\n consumes: { field: { required: true } },\n attrs: [\n \"name\",\n \"label\",\n \"type\",\n \"value\",\n \"placeholder\",\n \"autocomplete\",\n \"pattern\",\n \"required\",\n \"disabled\",\n \"invalid\",\n \"error\",\n \"success\",\n \"forgot-password-href\",\n \"forgot-password-label\",\n \"trailing-icon\",\n ],\n parts: [\n \"root\",\n \"label\",\n \"label-row\",\n \"forgot-link\",\n \"input-wrap\",\n \"input\",\n \"trailing-icon\",\n \"trailing-action\",\n \"help\",\n \"success\",\n \"error\",\n ],\n slots: [\"prefix\", \"suffix\", \"help\"],\n events: [\"zl-input\"],\n} as const;\n\ndeclare global {\n interface HTMLElementTagNameMap {\n \"zl-field\": ZlField;\n }\n}\n","/* Lit-only: <zl-page-shell> host background; layout lives on .zr-page-shell. */\n:host {\n display: block;\n min-height: 100vh;\n background: var(--zl-color-surface-default-black, #0f0f11);\n color: var(--zl-color-text-primary-white, #f4f4f6);\n}\n/* Playground / embed preview — parent sets height (e.g. `.page-shell-frame`). */\n:host([data-embedded]) {\n min-height: 100%;\n height: 100%;\n}\n:host([data-embedded]) .zr-page-shell {\n min-height: 100%;\n}\n.zr-page-shell ::slotted([slot=\"header\"]),\n.zr-page-shell ::slotted([slot=\"footer\"]) {\n margin: 0;\n}\n","/* Shared surface for `<zl-page-shell>` / `<PageShell>`. Lit-only rules: lit/page-shell-host.css */\n.zr-page-shell {\n min-height: 100vh;\n background: var(--zl-color-surface-default-black, #0f0f11);\n color: var(--zl-color-text-primary-white, #f4f4f6);\n font-family: var(--zl-font-family-sans, system-ui, sans-serif);\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: 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}\n@media (min-width: 48rem) {\n .zr-page-shell {\n padding-block: 3.25rem;\n padding-inline: var(--zl-spacing-03, 1rem);\n }\n}\n.zr-page-shell__header,\n.zr-page-shell__main,\n.zr-page-shell__footer {\n display: flex;\n justify-content: center;\n align-items: center;\n width: 100%;\n}\n.zr-page-shell__main {\n flex: 0 0 auto;\n}\n.zr-page-shell__footer {\n min-height: 1.5rem;\n}\n/* Lit keeps slots mounted; hide empty regions so flex gap matches React PageShell. */\n.zr-page-shell__region--empty {\n display: none;\n}\n.zr-page-shell[data-embedded] {\n min-height: 100%;\n height: 100%;\n}\n","import { LitElement, html } from \"lit\";\nimport { customElement } from \"lit/decorators.js\";\n\nimport pageShellHost from \"@zitadel/shared-component-styles/lit/page-shell-host.css?inline\";\nimport pageShellSurface from \"@zitadel/shared-component-styles/page-shell.css?inline\";\n\nimport type { AtomManifest } from \"../manifest.js\";\nimport { baseHostStyles, surfaceStyles } from \"../styles/index.js\";\n\n/**\n * Atom: `<zl-page-shell>` — the full-bleed auth-page chrome the\n * orchestrator injects around every flow template. Responsible for the\n * dark background, vertical centring, responsive padding, and footer\n * attribution slot.\n *\n * Spec lineage (file `xkvBjkOJ8ENuHdTGZHXezK`):\n * - 2xl frames (1536 × 960), e.g. sign-up `6593:141741`, passkey\n * `6594:630`, signed-in `6596:132844`. The outer wrapper uses\n * `py-[52px]` (vertical padding) with `p-[16px]` (spacing-03) on\n * the inner Form container, giving 52px / 16px at 2xl.\n *\n * Per-state Figma values:\n *\n * background surface.default-black (#0f0f11)\n * color text.primary-white (#f4f4f6) inherited\n * min-height 100vh — anchors footer to the viewport bottom even on\n * short cards\n * padding @md+ padding-block 52px, padding-inline 16px (matches\n * Figma 2xl wrapper). 52px isn't a token; use raw value.\n * padding @xs (< 48rem)\n * padding-block 32px (spacing-05), padding-inline 16px\n * (spacing-03) — tighter so the card breathes on\n * narrow phones.\n * gap 24px (spacing-04) between header / main / footer slots\n * footer min-height 1.5rem to reserve room for the attribution\n * pill even when the slot is empty (prevents jitter).\n */\n@customElement(\"zl-page-shell\")\nexport class ZlPageShell extends LitElement {\n static override styles = [\n baseHostStyles,\n ...surfaceStyles(pageShellHost, pageShellSurface),\n ];\n\n override render() {\n const hasHeader = this.lightDomSlotFilled(\"header\");\n const hasFooter = this.lightDomSlotFilled(\"footer\");\n const headerClass = hasHeader\n ? \"zr-page-shell__header\"\n : \"zr-page-shell__header zr-page-shell__region--empty\";\n const footerClass = hasFooter\n ? \"zr-page-shell__footer\"\n : \"zr-page-shell__footer zr-page-shell__region--empty\";\n return html`\n <div class=\"zr-page-shell\" part=\"shell\">\n <header class=${headerClass} part=\"header\">\n <slot name=\"header\" @slotchange=${this.onSlotChange}></slot>\n </header>\n <main class=\"zr-page-shell__main\" part=\"main\">\n <slot></slot>\n </main>\n <footer class=${footerClass} part=\"footer\">\n <slot name=\"footer\" @slotchange=${this.onSlotChange}></slot>\n </footer>\n </div>\n `;\n }\n\n /**\n * Re-render when a named slot's assignment changes so a footer/header added\n * after first paint updates the empty-region class. The initial render reads\n * children synchronously (no empty-then-filled flash).\n */\n private onSlotChange = (): void => {\n this.requestUpdate();\n };\n\n private lightDomSlotFilled(slot: string): boolean {\n for (const child of this.children) {\n if (child.getAttribute(\"slot\") === slot) return true;\n }\n return false;\n }\n}\n\nexport const zlPageShellManifest: AtomManifest = {\n tag: \"zl-page-shell\",\n attrs: [],\n parts: [\"shell\", \"header\", \"main\", \"footer\"],\n slots: [\"\", \"header\", \"footer\"],\n events: [],\n} as const;\n\ndeclare global {\n interface HTMLElementTagNameMap {\n \"zl-page-shell\": ZlPageShell;\n }\n}\n","/**\n * Base64URL encoding/decoding for WebAuthn binary fields.\n *\n * WebAuthn's `ArrayBuffer` values (`rawId`, `clientDataJSON`,\n * `authenticatorData`, `signature`, `attestationObject`, `userHandle`)\n * must be base64url-encoded before sending as JSON. The WebAuthn JSON\n * serialization spec (https://www.w3.org/TR/webauthn-3/) requires\n * Base64URL (RFC 4648 §5) — no padding, URL-safe alphabet.\n */\n\n/**\n * Encode an `ArrayBuffer` to a Base64URL string (no padding).\n */\nexport function bufferToBase64Url(buffer: ArrayBuffer): string {\n const bytes = new Uint8Array(buffer);\n let binary = \"\";\n for (const byte of bytes) {\n binary += String.fromCharCode(byte);\n }\n return btoa(binary).replace(/\\+/g, \"-\").replace(/\\//g, \"_\").replace(/=/g, \"\");\n}\n\n/**\n * Decode a Base64URL string to an `ArrayBuffer`.\n */\nexport function base64UrlToBuffer(base64url: string): ArrayBuffer {\n const base64 = base64url.replace(/-/g, \"+\").replace(/_/g, \"/\");\n const padded = base64.padEnd(base64.length + ((4 - (base64.length % 4)) % 4), \"=\");\n const binary = atob(padded);\n const bytes = new Uint8Array(binary.length);\n for (let i = 0; i < binary.length; i++) {\n bytes[i] = binary.charCodeAt(i);\n }\n return bytes.buffer;\n}\n","import { LitElement } from \"lit\";\nimport { customElement, property } from \"lit/decorators.js\";\n\nimport { bufferToBase64Url, base64UrlToBuffer } from \"../internal/base64url.js\";\nimport type { AtomManifest } from \"../manifest.js\";\n\n/**\n * Detail shape emitted by the `zl-passkey-result` event.\n *\n * Mirrors the `passkey-proof.yaml` schema (serialized PublicKeyCredential)\n * plus the `challenge_id` the orchestrator needs for the submit body.\n */\nexport type ZlPasskeyResultDetail = {\n challenge_id: string;\n method: string;\n proof: {\n id: string;\n rawId: string;\n type: \"public-key\";\n response: {\n clientDataJSON: string;\n attestationObject?: string;\n authenticatorData?: string;\n signature?: string;\n userHandle?: string;\n };\n authenticatorAttachment?: \"platform\" | \"cross-platform\";\n };\n};\n\n/**\n * Detail shape emitted by the `zl-passkey-error` event.\n */\nexport type ZlPasskeyErrorDetail = {\n challenge_id: string;\n error: string;\n aborted: boolean;\n};\n\n/**\n * Atom: `<zl-passkey>` — invisible WebAuthn ceremony handler.\n *\n * This component is intentionally invisible. It is mounted by the Liquid\n * template when `step.challenge.type === \"passkey\"`. On mount, it reads\n * the challenge options from attributes, triggers the appropriate\n * `navigator.credentials` ceremony, and emits the result.\n *\n * The orchestrator listens for `zl-passkey-result` to auto-submit the\n * proof via `challenge_response` on the flow submit body.\n *\n * Two modes:\n * - `ceremony=\"authenticate\"` → `navigator.credentials.get()` (login)\n * - `ceremony=\"register\"` → `navigator.credentials.create()` (registration)\n *\n * The options are passed as a JSON string via the `options` attribute (or\n * as a JS object via the `.options` property). These are the\n * `PublicKeyCredentialRequestOptions` or `PublicKeyCredentialCreationOptions`\n * straight from the server's challenge response.\n *\n * Spec: ADR 011 — Passkey Action Contract\n */\n@customElement(\"zl-passkey\")\nexport class ZlPasskey extends LitElement {\n /**\n * Which WebAuthn ceremony to perform.\n * - `authenticate` → `navigator.credentials.get()` (default, login)\n * - `register` → `navigator.credentials.create()` (passkey enrollment)\n */\n @property() accessor ceremony: \"authenticate\" | \"register\" = \"authenticate\";\n\n /**\n * Server-side challenge identifier. Echoed back in the result event\n * so the orchestrator can include it in `challenge_response.challenge_id`.\n */\n @property({ attribute: \"challenge-id\" }) accessor challengeId = \"\";\n\n /**\n * WebAuthn options from the server. Accepts either:\n * - A JSON string (via HTML attribute)\n * - A JS object (via property binding)\n *\n * For `ceremony=\"authenticate\"`: `PublicKeyCredentialRequestOptions`\n * For `ceremony=\"register\"`: `PublicKeyCredentialCreationOptions`\n */\n @property({\n attribute: \"options\",\n converter: {\n fromAttribute(value: string | null) {\n if (!value) return null;\n try {\n return JSON.parse(value) as Record<string, unknown>;\n } catch {\n return null;\n }\n },\n toAttribute(value: Record<string, unknown> | null) {\n return value ? JSON.stringify(value) : null;\n },\n },\n })\n accessor options: Record<string, unknown> | null = null;\n\n /**\n * Challenge method echoed back in the result event so the orchestrator\n * can include it in `challenge_response.method`. Defaults to `\"passkey\"`.\n */\n @property({ type: String }) accessor method = \"passkey\";\n\n /**\n * When true, the ceremony is not started automatically on mount.\n * The consumer must call `startCeremony()` manually.\n */\n @property({ type: Boolean }) accessor manual = false;\n\n private abortController: AbortController | null = null;\n\n override connectedCallback(): void {\n super.connectedCallback();\n if (!this.manual && this.options) {\n void this.startCeremony();\n }\n }\n\n override disconnectedCallback(): void {\n this.abort();\n super.disconnectedCallback();\n }\n\n /**\n * Abort any in-flight WebAuthn ceremony. Called automatically when the\n * component disconnects (step change, page navigation).\n */\n abort(): void {\n this.abortController?.abort();\n this.abortController = null;\n }\n\n /**\n * Trigger the WebAuthn ceremony. Resolves when the ceremony completes\n * or rejects on error/abort.\n */\n async startCeremony(): Promise<void> {\n if (!this.options) {\n this.emitError(\"No WebAuthn options provided.\", false);\n return;\n }\n\n if (!window.PublicKeyCredential) {\n this.emitError(\"WebAuthn is not supported in this browser.\", false);\n return;\n }\n\n this.abort();\n this.abortController = new AbortController();\n\n try {\n const credential =\n this.ceremony === \"register\"\n ? await this.createCredential()\n : await this.getCredential();\n\n if (!credential) {\n this.emitError(\"No credential returned by the browser.\", false);\n return;\n }\n\n const proof = this.serializeCredential(credential);\n this.emitResult(proof);\n } catch (error) {\n const aborted =\n error instanceof DOMException &&\n (error.name === \"AbortError\" || error.name === \"NotAllowedError\");\n\n this.emitError(\n error instanceof Error ? error.message : \"WebAuthn ceremony failed.\",\n aborted,\n );\n }\n }\n\n /**\n * `navigator.credentials.get()` — authentication ceremony.\n */\n private async getCredential(): Promise<PublicKeyCredential | null> {\n const opts = this.options;\n if (!opts) throw new Error(\"getCredential called without options\");\n\n const publicKeyOptions: PublicKeyCredentialRequestOptions = {\n challenge: base64UrlToBuffer(opts.challenge as string),\n rpId: opts.rpId as string | undefined,\n timeout: opts.timeout as number | undefined,\n userVerification: opts.userVerification as UserVerificationRequirement | undefined,\n allowCredentials: this.decodeCredentialDescriptors(\n opts.allowCredentials as Array<Record<string, unknown>> | undefined,\n ),\n };\n\n const result = await navigator.credentials.get({\n publicKey: publicKeyOptions,\n signal: this.abortController?.signal,\n });\n\n return result as PublicKeyCredential | null;\n }\n\n /**\n * `navigator.credentials.create()` — registration ceremony.\n */\n private async createCredential(): Promise<PublicKeyCredential | null> {\n const opts = this.options;\n if (!opts) throw new Error(\"createCredential called without options\");\n\n const rp = opts.rp as { id?: string; name: string };\n const user = opts.user as Record<string, unknown>;\n const pubKeyCredParams = opts.pubKeyCredParams as Array<{\n type: string;\n alg: number;\n }>;\n\n const publicKeyOptions: PublicKeyCredentialCreationOptions = {\n challenge: base64UrlToBuffer(opts.challenge as string),\n rp: { name: rp.name, ...(rp.id ? { id: rp.id } : {}) },\n user: {\n id: base64UrlToBuffer(user.id as string),\n name: user.name as string,\n displayName: user.displayName as string,\n },\n pubKeyCredParams: pubKeyCredParams.map((p) => ({\n type: p.type as PublicKeyCredentialType,\n alg: p.alg,\n })),\n timeout: opts.timeout as number | undefined,\n attestation: (opts.attestation as AttestationConveyancePreference) ?? \"none\",\n authenticatorSelection: opts.authenticatorSelection as\n | AuthenticatorSelectionCriteria\n | undefined,\n excludeCredentials: this.decodeCredentialDescriptors(\n opts.excludeCredentials as Array<Record<string, unknown>> | undefined,\n ),\n };\n\n const result = await navigator.credentials.create({\n publicKey: publicKeyOptions,\n signal: this.abortController?.signal,\n });\n\n return result as PublicKeyCredential | null;\n }\n\n /**\n * Decode a list of credential descriptors from the server's base64url\n * format to the browser's ArrayBuffer format.\n */\n private decodeCredentialDescriptors(\n descriptors: Array<Record<string, unknown>> | undefined,\n ): PublicKeyCredentialDescriptor[] {\n if (!descriptors) return [];\n return descriptors.map((d) => ({\n type: d.type as PublicKeyCredentialType,\n id: base64UrlToBuffer(d.id as string),\n transports: d.transports as AuthenticatorTransport[] | undefined,\n }));\n }\n\n /**\n * Serialize a `PublicKeyCredential` to the JSON shape defined in\n * `passkey-proof.yaml`. All `ArrayBuffer` fields are base64url-encoded.\n */\n private serializeCredential(\n credential: PublicKeyCredential,\n ): ZlPasskeyResultDetail[\"proof\"] {\n const response = credential.response;\n\n const serialized: ZlPasskeyResultDetail[\"proof\"] = {\n id: credential.id,\n rawId: bufferToBase64Url(credential.rawId),\n type: \"public-key\",\n response: {\n clientDataJSON: bufferToBase64Url(response.clientDataJSON),\n },\n };\n\n // Attestation response (registration)\n if (\"attestationObject\" in response) {\n const attestation = response as AuthenticatorAttestationResponse;\n serialized.response.attestationObject = bufferToBase64Url(\n attestation.attestationObject,\n );\n }\n\n // Assertion response (authentication)\n if (\"authenticatorData\" in response) {\n const assertion = response as AuthenticatorAssertionResponse;\n serialized.response.authenticatorData = bufferToBase64Url(\n assertion.authenticatorData,\n );\n serialized.response.signature = bufferToBase64Url(assertion.signature);\n if (assertion.userHandle) {\n serialized.response.userHandle = bufferToBase64Url(assertion.userHandle);\n }\n }\n\n if (credential.authenticatorAttachment) {\n serialized.authenticatorAttachment = credential.authenticatorAttachment as\n | \"platform\"\n | \"cross-platform\";\n }\n\n return serialized;\n }\n\n private emitResult(proof: ZlPasskeyResultDetail[\"proof\"]): void {\n const detail: ZlPasskeyResultDetail = {\n challenge_id: this.challengeId,\n method: this.method,\n proof,\n };\n this.dispatchEvent(\n new CustomEvent(\"zl-passkey-result\", {\n bubbles: true,\n composed: true,\n detail,\n }),\n );\n }\n\n private emitError(message: string, aborted: boolean): void {\n const detail: ZlPasskeyErrorDetail = {\n challenge_id: this.challengeId,\n error: message,\n aborted,\n };\n this.dispatchEvent(\n new CustomEvent(\"zl-passkey-error\", {\n bubbles: true,\n composed: true,\n detail,\n }),\n );\n }\n\n /** Invisible component — no shadow DOM rendering needed. */\n override createRenderRoot(): this {\n return this;\n }\n}\n\nexport const zlPasskeyManifest: AtomManifest = {\n tag: \"zl-passkey\",\n consumes: {},\n attrs: [\"ceremony\", \"method\", \"challenge-id\", \"options\", \"manual\"],\n parts: [],\n slots: [],\n events: [\"zl-passkey-result\", \"zl-passkey-error\"],\n} as const;\n\ndeclare global {\n interface HTMLElementTagNameMap {\n \"zl-passkey\": ZlPasskey;\n }\n}\n","/* Lit-only: <zl-pill> host display. Tone variants use .zr-pill--* on the surface node. */\n:host {\n display: inline-flex;\n}\n\n/* Attribution logotype is slotted light DOM (orchestrator + playground). */\n::slotted(.zr-pill__logotype) {\n display: block;\n flex-shrink: 0;\n width: 65px;\n height: 16px;\n margin-top: 2px;\n line-height: 0;\n}\n\n::slotted(.zr-pill__logotype-svg) {\n display: block;\n width: 100%;\n height: 100%;\n}\n","/* Shared surface for `<zl-pill>` / `<Pill>`. Lit-only rules: lit/pill-host.css */\n.zr-pill {\n box-sizing: border-box;\n display: inline-flex;\n align-items: flex-start;\n justify-content: center;\n gap: var(--zl-spacing-02, 0.5rem);\n height: 2.5rem;\n padding-inline: var(--zl-spacing-03, 1rem);\n padding-block: calc((2.5rem - 1.25rem - 2px) / 2);\n border-radius: 100px;\n font-family: var(--zl-font-family-sans, system-ui, sans-serif);\n font-size: 0.875rem;\n font-weight: 400;\n line-height: 1.25rem;\n letter-spacing: 0;\n text-transform: none;\n background:\n linear-gradient(182deg, rgb(72 74 87 / 0.6) 28.65%, rgb(15 15 17 / 0.6) 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 text-decoration: none;\n white-space: nowrap;\n}\n.zr-pill__logotype {\n display: block;\n flex-shrink: 0;\n width: 65px;\n height: 16px;\n margin-top: 2px;\n line-height: 0;\n}\n.zr-pill__logotype-svg {\n display: block;\n width: 100%;\n height: 100%;\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.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.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.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}\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","import { LitElement, html, nothing } from \"lit\";\nimport { customElement, property } from \"lit/decorators.js\";\nimport { classMap } from \"lit/directives/class-map.js\";\n\nimport pillHost from \"@zitadel/shared-component-styles/lit/pill-host.css?inline\";\nimport pillSurface from \"@zitadel/shared-component-styles/pill.css?inline\";\n\nimport type { AtomManifest } from \"../manifest.js\";\nimport { baseHostStyles, surfaceStyles } from \"../styles/index.js\";\n\n/**\n * Atom: `<zl-pill>` — small inline chip used for status and attribution.\n *\n * Spec lineage (file `xkvBjkOJ8ENuHdTGZHXezK`):\n * - canonical instance: node `6593:141767` (\"Social media\" frame =\n * \"Secured with Zitadel\" attribution pill on every sign-in screen).\n *\n * Two roles in scope:\n * - **Attribution pill** (\"Secured with Zitadel\") rendered by the\n * orchestrator footer when `branding.attribution` is enabled. This is\n * the only canonical pill in the Figma screens; its spec is the\n * source of truth for every dimension.\n * - **Status pill** (decorative `tone` variants — pink / purple /\n * orange / success) reuses the same geometry and typography, only\n * swapping the tint colour. The tones don't have screen instances in\n * Figma yet; when they ship, re-verify each tone against its master.\n *\n * Per-state Figma values (from node `6593:141767`):\n *\n * surface bg layered linear-gradient(182deg,\n * rgba(72,74,87,0.6) 28.65%,\n * rgba(15,15,17,0.6) 81.82%)\n * over surface.default-primary-gray (#252528)\n * border 1px solid #484a57 (our token: border.default-gray-200 —\n * Figma calls this \"default-gray-100\"; our gray primitive\n * ladder is offset by one slot, so map to gray-200)\n * radius 100px (full pill)\n * size 186×40px frame (`get_metadata` on `6593:141767`)\n * padding 16px inline (spacing-03) / 10px block (spacing metadata:\n * text y=10, line 20px, frame height 40px)\n * gap 8px (spacing-02)\n * font Arimo Regular 14/20, letter-spacing 0, color\n * text.primary-white (#f4f4f6), text-transform none\n * focus-vis 2px solid focus.color, offset 2px\n *\n * content \"Secured with\" + 65×16 logotype SVG (`attribution-markup.ts`);\n * logotype `margin-top: 2px` (Figma text y=10, logotype y=12)\n */\n@customElement(\"zl-pill\")\nexport class ZlPill extends LitElement {\n static override styles = [baseHostStyles, ...surfaceStyles(pillHost, pillSurface)];\n\n @property() accessor tone: \"neutral\" | \"pink\" | \"purple\" | \"orange\" | \"success\" = \"neutral\";\n\n @property() accessor href: string | undefined = undefined;\n\n @property({ attribute: \"aria-label\" })\n override accessor ariaLabel: string | null = null;\n\n override render() {\n const classes = classMap({\n \"zr-pill\": true,\n [`zr-pill--${this.tone}`]: this.tone !== \"neutral\",\n });\n if (this.href) {\n return html`<a\n class=${classes}\n part=\"pill\"\n href=${this.href}\n rel=\"noopener\"\n aria-label=${this.ariaLabel ?? nothing}\n ><slot></slot></a>`;\n }\n return html`<span class=${classes} part=\"pill\"><slot></slot></span>`;\n }\n}\n\nexport const zlPillManifest: AtomManifest = {\n tag: \"zl-pill\",\n attrs: [\"tone\", \"href\", \"aria-label\"],\n parts: [\"pill\"],\n slots: [\"\"],\n events: [],\n} as const;\n\ndeclare global {\n interface HTMLElementTagNameMap {\n \"zl-pill\": ZlPill;\n }\n}\n"],"mappings":"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"}