@seams/wallet 0.10.2 → 0.12.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (176) hide show
  1. package/README.md +3 -3
  2. package/THIRD_PARTY_NOTICES.md +33 -1812
  3. package/dist/.build-inputs.sha256 +1 -1
  4. package/dist/esm/SeamsWeb/operations/recovery/walletRecoveryCodeBackup.js +100 -0
  5. package/dist/esm/SeamsWeb/walletIframe/host/ui/auth-menu/AuthMenuSurface.js +236 -97
  6. package/dist/esm/core/signingEngine/uiConfirm/ui/preact/RecoveryCodeBackupSurface.js +558 -0
  7. package/dist/esm/core/signingEngine/uiConfirm/ui/preact/mountRecoveryCodeBackupSurface.js +82 -0
  8. package/dist/esm/core/types/sdkSentEvents.js +9 -0
  9. package/dist/esm/react/components/AccountMenuButton/AccountMenuButtonMock.js +189 -0
  10. package/dist/esm/react/components/AccountMenuButton/AccountMenuButtonView.js +137 -0
  11. package/dist/esm/react/components/AccountMenuButton/AccountMenuDeviceDetails.js +39 -0
  12. package/dist/esm/react/components/AccountMenuButton/AccountMenuDialog.js +39 -13
  13. package/dist/esm/react/components/AccountMenuButton/AccountMenuMockScreens.js +247 -0
  14. package/dist/esm/react/components/AccountMenuButton/AccountMenuScreen.js +41 -0
  15. package/dist/esm/react/components/AccountMenuButton/AuthenticationMethodRow.js +79 -0
  16. package/dist/esm/react/components/AccountMenuButton/AuthenticationMethodsModal.js +168 -174
  17. package/dist/esm/react/components/AccountMenuButton/AuthenticationMethodsView.js +19 -0
  18. package/dist/esm/react/components/AccountMenuButton/ExportKeysScreen.js +30 -0
  19. package/dist/esm/react/components/AccountMenuButton/LinkedDevicesModal.css +148 -87
  20. package/dist/esm/react/components/AccountMenuButton/LinkedDevicesModal.js +26 -5
  21. package/dist/esm/react/components/AccountMenuButton/MenuItem.js +28 -13
  22. package/dist/esm/react/components/AccountMenuButton/ProfileDropdown.css +73 -69
  23. package/dist/esm/react/components/AccountMenuButton/ProfileDropdown.js +56 -68
  24. package/dist/esm/react/components/AccountMenuButton/RecoveryCodeAcknowledgement.js +27 -0
  25. package/dist/esm/react/components/AccountMenuButton/RecoveryCodeActions.js +53 -0
  26. package/dist/esm/react/components/AccountMenuButton/TransactionSettingsSection.css +3 -1
  27. package/dist/esm/react/components/AccountMenuButton/TransactionSettingsSection.js +2 -8
  28. package/dist/esm/react/components/AccountMenuButton/UserAccountButton.css +1 -1
  29. package/dist/esm/react/components/AccountMenuButton/UserAccountButton.js +6 -3
  30. package/dist/esm/react/components/AccountMenuButton/WalletRegionSection.js +4 -4
  31. package/dist/esm/react/components/AccountMenuButton/Web3AuthProfileButton.css +443 -12
  32. package/dist/esm/react/components/AccountMenuButton/hooks/useProfileState.js +1 -1
  33. package/dist/esm/react/components/AccountMenuButton/icons/LayersIcon.js +8 -0
  34. package/dist/esm/react/components/AccountMenuButton/icons/LockKeyholeIcon.js +22 -0
  35. package/dist/esm/react/components/AccountMenuButton/icons/PlusIcon.js +8 -0
  36. package/dist/esm/react/components/AccountMenuButton/icons/SunIcon.js +2 -2
  37. package/dist/esm/react/components/AccountMenuButton/icons/TouchIcon.css +0 -8
  38. package/dist/esm/react/components/AccountMenuButton/index.js +135 -115
  39. package/dist/esm/react/components/QRCodeScanner.js +64 -40
  40. package/dist/esm/react/components/QRCodeScannerCamera.js +16 -0
  41. package/dist/esm/react/components/ShowQRCode.js +2 -2
  42. package/dist/esm/react/externalEvm.js +2 -2
  43. package/dist/esm/react/index.js +2 -1
  44. package/dist/esm/react/styles/styles.css +520 -91
  45. package/dist/esm/react/transactionReview/TransactionReviewHost.js +3 -3
  46. package/dist/esm/sdk/{adapters-DYPu0nK9.js → adapters-CGvNLOfZ.js} +1 -1
  47. package/dist/{public/sdk/display-DjoWrSgE.js → esm/sdk/display-DTbGoX4e.js} +1 -1
  48. package/dist/{public/sdk/exportKeypairOperation-DYCzCbqL.js → esm/sdk/exportKeypairOperation-BHXMSA3v.js} +1 -1
  49. package/dist/{public/sdk/host-D5b19B_h.js → esm/sdk/host-CHQwi-Nm.js} +1 -1
  50. package/dist/esm/sdk/{localOnly-KvZeKkH5.js → localOnly-CUVRoMy2.js} +1 -1
  51. package/dist/esm/sdk/{mountRecoveryCodeBackupSurface-BA2ttbTM.js → mountRecoveryCodeBackupSurface-D1G-iCPI.js} +2 -2
  52. package/dist/esm/sdk/{pendingWalletRecoveryCodeBackup-BkIrbd6Q.js → pendingWalletRecoveryCodeBackup-DMg5U0Fk.js} +1 -1
  53. package/dist/esm/sdk/{recovery-entrypoint-DoXswV9I.js → recovery-entrypoint-EHY_b7Z-.js} +1 -1
  54. package/dist/esm/sdk/registration-CQxxUt5s.js +1 -0
  55. package/dist/esm/sdk/{registration-BFHEYmgh.js → registration-Drtkzrlc.js} +1 -1
  56. package/dist/esm/sdk/{requireStepUpAuth-C67sluoC.js → requireStepUpAuth-FqZSU021.js} +1 -1
  57. package/dist/esm/sdk/router_ab_ed25519_yao_client_bg.wasm +0 -0
  58. package/dist/esm/sdk/runtime-auth-DtpRz88X.js +1 -0
  59. package/dist/esm/sdk/{runtime-device-link-pf-a_-3u.js → runtime-device-link-DXjabXJb.js} +1 -1
  60. package/dist/esm/sdk/{runtime-ecdsa-tempo-Ddnuti6f.js → runtime-ecdsa-tempo-DlKMIbyP.js} +1 -1
  61. package/dist/esm/sdk/{runtime-email-otp-BAG8ZC1J.js → runtime-email-otp-BBPghU2G.js} +1 -1
  62. package/dist/esm/sdk/{runtime-export-DxL99xfn.js → runtime-export-pw-xJL8o.js} +1 -1
  63. package/dist/esm/sdk/{runtime-near-BrWP4IxC.js → runtime-near-B-vYxGjl.js} +1 -1
  64. package/dist/esm/sdk/{runtime-preferences-BjVdHYL0.js → runtime-preferences-D-hY0RfC.js} +1 -1
  65. package/dist/esm/sdk/{runtime-recovery-BNd_GX5q.js → runtime-recovery-Vg1ND2nl.js} +1 -1
  66. package/dist/esm/sdk/{runtime-recovery-codes-Dn-NccpU.js → runtime-recovery-codes-rLR4Guy4.js} +1 -1
  67. package/dist/esm/sdk/sdkSentEvents-Dl8fOL50.js +1 -0
  68. package/dist/esm/sdk/shared-6bpRPbcM.js +6 -0
  69. package/dist/{public/sdk/signEvmFamily-DjD3tn8e.js → esm/sdk/signEvmFamily-M0trbeZe.js} +1 -1
  70. package/dist/esm/sdk/{signEvmFamilyWithUiConfirmForTempo-CwRFbaLM.js → signEvmFamilyWithUiConfirmForTempo-Bo25SwuV.js} +1 -1
  71. package/dist/esm/sdk/{signEvmWithUiConfirm-BHG0dwVG.js → signEvmWithUiConfirm-CFcqJRj3.js} +1 -1
  72. package/dist/{public/sdk/signNear-D0tlQXb9.js → esm/sdk/signNear-DGUQZ44s.js} +1 -1
  73. package/dist/esm/sdk/{signingFlow-Mym5j6aw.js → signingFlow-DZvV4AgG.js} +1 -1
  74. package/dist/esm/sdk/{transaction-activity-Cb2JyYKv.js → transaction-activity-xfeHKJoq.js} +1 -1
  75. package/dist/esm/sdk/wallet-iframe-host-ecdsa.js +1 -1
  76. package/dist/esm/sdk/wallet-iframe-host-full.js +1 -1
  77. package/dist/esm/sdk/wallet-iframe-host-near.js +1 -1
  78. package/dist/esm/sdk/wallet-iframe-host-runtime.js +1 -1
  79. package/dist/esm/sdk/{wallet-recovery-D7ywcIHw.js → wallet-recovery-LMtGiEL3.js} +1 -1
  80. package/dist/esm/sdk/wallet-ui.css +1 -1
  81. package/dist/{public/sdk/walletCustodyEcdsaContinuity-B8aO2NFb.js → esm/sdk/walletCustodyEcdsaContinuity-D-gYxv6e.js} +1 -1
  82. package/dist/{public/sdk/walletRecoveryCommit-C3EgMjo-.js → esm/sdk/walletRecoveryCommit-BYRC_2li.js} +1 -1
  83. package/dist/esm/wasm/near_signer/pkg/wasm_signer_worker_bg.wasm +0 -0
  84. package/dist/esm/wasm/router_ab_ecdsa_client/pkg/router_ab_ecdsa_client_bg.wasm +0 -0
  85. package/dist/esm/wasm/router_ab_ed25519_yao_client/pkg/router_ab_ed25519_yao_client_bg.wasm +0 -0
  86. package/dist/public/headers.manifest.json +1 -1
  87. package/dist/public/sdk/{adapters-DYPu0nK9.js → adapters-CGvNLOfZ.js} +1 -1
  88. package/dist/{esm/sdk/display-DjoWrSgE.js → public/sdk/display-DTbGoX4e.js} +1 -1
  89. package/dist/{esm/sdk/exportKeypairOperation-DYCzCbqL.js → public/sdk/exportKeypairOperation-BHXMSA3v.js} +1 -1
  90. package/dist/{esm/sdk/host-D5b19B_h.js → public/sdk/host-CHQwi-Nm.js} +1 -1
  91. package/dist/public/sdk/{localOnly-KvZeKkH5.js → localOnly-CUVRoMy2.js} +1 -1
  92. package/dist/public/sdk/{mountRecoveryCodeBackupSurface-BA2ttbTM.js → mountRecoveryCodeBackupSurface-D1G-iCPI.js} +2 -2
  93. package/dist/public/sdk/{pendingWalletRecoveryCodeBackup-BkIrbd6Q.js → pendingWalletRecoveryCodeBackup-DMg5U0Fk.js} +1 -1
  94. package/dist/public/sdk/{recovery-entrypoint-DoXswV9I.js → recovery-entrypoint-EHY_b7Z-.js} +1 -1
  95. package/dist/public/sdk/registration-CQxxUt5s.js +1 -0
  96. package/dist/public/sdk/{registration-BFHEYmgh.js → registration-Drtkzrlc.js} +1 -1
  97. package/dist/public/sdk/{requireStepUpAuth-C67sluoC.js → requireStepUpAuth-FqZSU021.js} +1 -1
  98. package/dist/public/sdk/router_ab_ed25519_yao_client_bg.wasm +0 -0
  99. package/dist/public/sdk/runtime-auth-DtpRz88X.js +1 -0
  100. package/dist/public/sdk/{runtime-device-link-pf-a_-3u.js → runtime-device-link-DXjabXJb.js} +1 -1
  101. package/dist/public/sdk/{runtime-ecdsa-tempo-Ddnuti6f.js → runtime-ecdsa-tempo-DlKMIbyP.js} +1 -1
  102. package/dist/public/sdk/{runtime-email-otp-BAG8ZC1J.js → runtime-email-otp-BBPghU2G.js} +1 -1
  103. package/dist/public/sdk/{runtime-export-DxL99xfn.js → runtime-export-pw-xJL8o.js} +1 -1
  104. package/dist/public/sdk/{runtime-near-BrWP4IxC.js → runtime-near-B-vYxGjl.js} +1 -1
  105. package/dist/public/sdk/{runtime-preferences-BjVdHYL0.js → runtime-preferences-D-hY0RfC.js} +1 -1
  106. package/dist/public/sdk/{runtime-recovery-BNd_GX5q.js → runtime-recovery-Vg1ND2nl.js} +1 -1
  107. package/dist/public/sdk/{runtime-recovery-codes-Dn-NccpU.js → runtime-recovery-codes-rLR4Guy4.js} +1 -1
  108. package/dist/public/sdk/sdkSentEvents-Dl8fOL50.js +1 -0
  109. package/dist/public/sdk/shared-6bpRPbcM.js +6 -0
  110. package/dist/{esm/sdk/signEvmFamily-DjD3tn8e.js → public/sdk/signEvmFamily-M0trbeZe.js} +1 -1
  111. package/dist/public/sdk/{signEvmFamilyWithUiConfirmForTempo-CwRFbaLM.js → signEvmFamilyWithUiConfirmForTempo-Bo25SwuV.js} +1 -1
  112. package/dist/public/sdk/{signEvmWithUiConfirm-BHG0dwVG.js → signEvmWithUiConfirm-CFcqJRj3.js} +1 -1
  113. package/dist/{esm/sdk/signNear-D0tlQXb9.js → public/sdk/signNear-DGUQZ44s.js} +1 -1
  114. package/dist/public/sdk/{signingFlow-Mym5j6aw.js → signingFlow-DZvV4AgG.js} +1 -1
  115. package/dist/public/sdk/{transaction-activity-Cb2JyYKv.js → transaction-activity-xfeHKJoq.js} +1 -1
  116. package/dist/public/sdk/wallet-iframe-host-ecdsa.js +1 -1
  117. package/dist/public/sdk/wallet-iframe-host-full.js +1 -1
  118. package/dist/public/sdk/wallet-iframe-host-near.js +1 -1
  119. package/dist/public/sdk/wallet-iframe-host-runtime.js +1 -1
  120. package/dist/public/sdk/{wallet-recovery-D7ywcIHw.js → wallet-recovery-LMtGiEL3.js} +1 -1
  121. package/dist/public/sdk/wallet-ui.css +1 -1
  122. package/dist/{esm/sdk/walletCustodyEcdsaContinuity-B8aO2NFb.js → public/sdk/walletCustodyEcdsaContinuity-D-gYxv6e.js} +1 -1
  123. package/dist/{esm/sdk/walletRecoveryCommit-C3EgMjo-.js → public/sdk/walletRecoveryCommit-BYRC_2li.js} +1 -1
  124. package/dist/public/sdk/workers/email_otp_runtime_bg.wasm +0 -0
  125. package/dist/public/sdk/workers/evm_crypto_bg.wasm +0 -0
  126. package/dist/public/sdk/workers/router_ab_ecdsa_client_bg.wasm +0 -0
  127. package/dist/public/sdk/workers/router_ab_ed25519_yao_client_bg.wasm +0 -0
  128. package/dist/public/sdk/workers/shamir3pass_runtime_bg.wasm +0 -0
  129. package/dist/public/sdk/workers/tempo_signer_bg.wasm +0 -0
  130. package/dist/public/sdk/workers/wallet_custody_ceremony_bg.wasm +0 -0
  131. package/dist/public/sdk/workers/wasm_signer_worker_bg.wasm +0 -0
  132. package/dist/public/wallet-assets.manifest.json +64 -64
  133. package/dist/public/wallet-service/index.html +4 -4
  134. package/dist/types/wallet/src/SeamsWeb/walletIframe/host/auth-menu/domain.d.ts +9 -1
  135. package/dist/types/wallet/src/SeamsWeb/walletIframe/host/auth-menu/session.d.ts +7 -3
  136. package/dist/types/wallet/src/SeamsWeb/walletIframe/host/ui/auth-menu/AuthMenuSurface.d.ts +8 -5
  137. package/dist/types/wallet/src/core/types/sdkSentEvents.d.ts +4 -0
  138. package/dist/types/wallet/src/react/components/AccountMenuButton/AccountMenuButtonMock.d.ts +17 -0
  139. package/dist/types/wallet/src/react/components/AccountMenuButton/AccountMenuButtonView.d.ts +17 -0
  140. package/dist/types/wallet/src/react/components/AccountMenuButton/AccountMenuDeviceDetails.d.ts +13 -0
  141. package/dist/types/wallet/src/react/components/AccountMenuButton/AccountMenuDialog.d.ts +1 -1
  142. package/dist/types/wallet/src/react/components/AccountMenuButton/AccountMenuMockScreens.d.ts +43 -0
  143. package/dist/types/wallet/src/react/components/AccountMenuButton/AccountMenuScreen.d.ts +9 -0
  144. package/dist/types/wallet/src/react/components/AccountMenuButton/AuthenticationMethodRow.d.ts +14 -0
  145. package/dist/types/wallet/src/react/components/AccountMenuButton/AuthenticationMethodsModal.d.ts +1 -1
  146. package/dist/types/wallet/src/react/components/AccountMenuButton/AuthenticationMethodsView.d.ts +8 -0
  147. package/dist/types/wallet/src/react/components/AccountMenuButton/ExportKeysScreen.d.ts +7 -0
  148. package/dist/types/wallet/src/react/components/AccountMenuButton/LinkedDevicesModal.d.ts +1 -1
  149. package/dist/types/wallet/src/react/components/AccountMenuButton/ProfileDropdown.d.ts +2 -14
  150. package/dist/types/wallet/src/react/components/AccountMenuButton/RecoveryCodeAcknowledgement.d.ts +5 -0
  151. package/dist/types/wallet/src/react/components/AccountMenuButton/RecoveryCodeActions.d.ts +5 -0
  152. package/dist/types/wallet/src/react/components/AccountMenuButton/icons/LayersIcon.d.ts +2 -0
  153. package/dist/types/wallet/src/react/components/AccountMenuButton/icons/LockKeyholeIcon.d.ts +2 -0
  154. package/dist/types/wallet/src/react/components/AccountMenuButton/icons/PlusIcon.d.ts +2 -0
  155. package/dist/types/wallet/src/react/components/AccountMenuButton/index.d.ts +2 -0
  156. package/dist/types/wallet/src/react/components/AccountMenuButton/types.d.ts +1 -14
  157. package/dist/types/wallet/src/react/components/QRCodeScanner.d.ts +1 -0
  158. package/dist/types/wallet/src/react/components/QRCodeScannerCamera.d.ts +5 -0
  159. package/dist/types/wallet/src/react/index.d.ts +2 -1
  160. package/dist/workers/email_otp_runtime_bg.wasm +0 -0
  161. package/dist/workers/evm_crypto_bg.wasm +0 -0
  162. package/dist/workers/router_ab_ecdsa_client_bg.wasm +0 -0
  163. package/dist/workers/router_ab_ed25519_yao_client_bg.wasm +0 -0
  164. package/dist/workers/shamir3pass_runtime_bg.wasm +0 -0
  165. package/dist/workers/tempo_signer_bg.wasm +0 -0
  166. package/dist/workers/wallet_custody_ceremony_bg.wasm +0 -0
  167. package/dist/workers/wasm_signer_worker_bg.wasm +0 -0
  168. package/package.json +1 -3
  169. package/dist/esm/sdk/registration-Cx_f58rb.js +0 -1
  170. package/dist/esm/sdk/runtime-auth-CKUleRYA.js +0 -1
  171. package/dist/esm/sdk/sdkSentEvents-DiQ3YVlj.js +0 -1
  172. package/dist/esm/sdk/shared-CSfgTVcf.js +0 -6
  173. package/dist/public/sdk/registration-Cx_f58rb.js +0 -1
  174. package/dist/public/sdk/runtime-auth-CKUleRYA.js +0 -1
  175. package/dist/public/sdk/sdkSentEvents-DiQ3YVlj.js +0 -1
  176. package/dist/public/sdk/shared-CSfgTVcf.js +0 -6
@@ -26,13 +26,15 @@
26
26
  );
27
27
  display: flex;
28
28
  flex-direction: column;
29
- width: min(640px, 100%);
29
+ /* One width for every account-menu dialog: their rows are short, and a
30
+ narrow card keeps each row readable at a glance. */
31
+ width: min(420px, 100%);
30
32
  max-width: 100%;
31
33
  min-width: 0;
32
34
  max-height: calc(100vh - 24px);
33
35
  max-height: calc(100dvh - 24px);
34
36
  overflow: hidden;
35
- padding: 1.5rem;
37
+ padding: 0;
36
38
  color: var(--seams-colors-textPrimary);
37
39
  font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
38
40
  font-size: 0.875rem;
@@ -48,40 +50,69 @@
48
50
  outline: none;
49
51
  }
50
52
 
53
+ /* Modal chrome: the page's host above the content, "Powered by seams" below. */
54
+ .seams-account-menu-dialog-header,
55
+ .seams-account-menu-dialog-footer {
56
+ display: flex;
57
+ flex-shrink: 0;
58
+ align-items: center;
59
+ gap: 0.4375rem;
60
+ color: var(--seams-colors-textSecondary);
61
+ font-size: 0.75rem;
62
+ line-height: 1.5;
63
+ }
64
+ .seams-account-menu-dialog-header {
65
+ padding: 0 0.375rem 0 1.375rem;
66
+ border-bottom: 1px solid var(--seams-colors-borderPrimary);
67
+ }
68
+ .seams-account-menu-dialog-host {
69
+ min-width: 0;
70
+ overflow: hidden;
71
+ text-overflow: ellipsis;
72
+ white-space: nowrap;
73
+ }
74
+ .seams-account-menu-dialog-footer {
75
+ padding: 0.875rem 1.375rem;
76
+ border-top: 1px solid var(--seams-colors-borderPrimary);
77
+ background: var(--seams-colors-surface);
78
+ }
79
+ .seams-account-menu-dialog-header > svg,
80
+ .seams-account-menu-dialog-footer > svg {
81
+ flex-shrink: 0;
82
+ }
83
+ .seams-account-menu-dialog-main {
84
+ display: flex;
85
+ flex: 1 1 auto;
86
+ flex-direction: column;
87
+ min-height: 0;
88
+ padding: 1.5rem;
89
+ text-wrap: pretty;
90
+ }
91
+
51
92
  @media (prefers-reduced-motion: no-preference) {
52
93
  .seams-linked-devices-modal-content {
53
94
  animation: seams-linked-devices-modal-content-enter 80ms ease-out both;
54
95
  }
55
96
  }
56
97
 
57
- .seams-auth-methods-modal-content {
58
- width: min(640px, 100%);
59
- }
60
-
61
- /* The device inventory is two short rows of text; a narrower dialog keeps the
62
- metadata lines scannable. */
63
- .seams-linked-devices-inventory-content {
64
- width: min(560px, 100%);
65
- }
66
-
67
98
  .seams-auth-methods-modal-intro {
68
- margin: -0.25rem 2.5rem 0.75rem 0;
99
+ margin: -0.25rem 0 0.75rem;
69
100
  color: var(--seams-colors-textSecondary);
70
101
  font-size: 0.9rem;
71
102
  line-height: 1.45;
72
103
  }
73
104
 
74
105
  .seams-linked-devices-modal-title {
75
- margin: 0 2.5rem 0.75rem 0;
76
- font-size: 1.3125rem;
77
- font-weight: 600;
78
- letter-spacing: -0.01em;
106
+ margin: 0 0 0.75rem;
107
+ font-size: 1.375rem;
108
+ font-weight: 500;
109
+ letter-spacing: -0.025em;
79
110
  line-height: 1.25;
80
111
  color: var(--seams-colors-textPrimary);
81
112
  }
82
113
 
83
114
  .seams-linked-devices-modal-subtitle {
84
- margin: -0.5rem 2.5rem 1rem 0;
115
+ margin: -0.5rem 0 1rem;
85
116
  color: var(--seams-colors-textSecondary);
86
117
  font-size: 0.875rem;
87
118
  font-weight: 400;
@@ -89,12 +120,10 @@
89
120
  }
90
121
 
91
122
  .seams-linked-devices-modal-close {
92
- position: absolute;
93
- top: 1rem;
94
- right: 1rem;
123
+ margin-inline-start: auto;
95
124
  background: none;
96
125
  border: none;
97
- font-size: 1rem;
126
+ font-size: 0.875rem;
98
127
  font-weight: 600;
99
128
  color: var(--seams-colors-textMuted);
100
129
  cursor: pointer;
@@ -177,22 +206,20 @@
177
206
  overflow-wrap: anywhere;
178
207
  }
179
208
 
180
- /* The state chip carries the only status a person needs; colour reinforces the
181
- word rather than replacing it. */
209
+ /* The state chip carries the only status a person needs. A normal state is a
210
+ quiet neutral tag; colour marks only the states that need attention. */
182
211
  .seams-linked-devices-modal-standing {
183
212
  flex: none;
184
- padding: 0.15rem 0.5rem;
185
- border-radius: 999px;
186
- font-size: 0.72rem;
187
- font-weight: 700;
213
+ padding: 0.1875rem 0.5rem;
214
+ border-radius: 6px;
215
+ background: color-mix(in srgb, var(--seams-colors-textPrimary), transparent 93%);
216
+ color: var(--seams-colors-textPrimary);
217
+ font-size: 0.75rem;
218
+ font-weight: 500;
219
+ line-height: 1.4;
188
220
  white-space: nowrap;
189
221
  }
190
222
 
191
- .seams-linked-devices-modal-standing.tone-active {
192
- background: color-mix(in srgb, oklch(0.62 0.15 155), transparent 88%);
193
- color: oklch(0.48 0.14 155);
194
- }
195
-
196
223
  .seams-linked-devices-modal-standing.tone-pending {
197
224
  background: color-mix(in srgb, oklch(0.72 0.15 85), transparent 88%);
198
225
  color: oklch(0.5 0.13 85);
@@ -203,10 +230,6 @@
203
230
  color: var(--seams-colors-textSecondary);
204
231
  }
205
232
 
206
- .theme-dark .seams-linked-devices-modal-standing.tone-active {
207
- color: oklch(0.8 0.14 155);
208
- }
209
-
210
233
  .theme-dark .seams-linked-devices-modal-standing.tone-pending {
211
234
  color: oklch(0.82 0.13 85);
212
235
  }
@@ -217,57 +240,84 @@
217
240
  font-weight: 500;
218
241
  }
219
242
 
220
- /* The device inventory renders as one bordered group with hairline dividers
221
- rather than a stack of cards; the auth-methods modal keeps the card look. */
243
+ /* A grouped inventory is a plain list: no box around it, a hairline under
244
+ every row, so the rows read as entries on the card itself. */
222
245
  .seams-linked-devices-modal-list--grouped {
223
246
  gap: 0;
224
- border: 1px solid var(--seams-colors-borderPrimary);
225
- border-radius: 0.75rem;
226
- background: var(--seams-colors-surface);
227
- overflow: hidden;
228
247
  }
229
248
 
230
249
  .seams-linked-devices-modal-item--row {
231
250
  position: relative;
232
- grid-template-columns: 40px minmax(0, 1fr) auto;
233
- align-items: start;
234
- gap: 0 0.75rem;
235
- padding: 1rem;
251
+ grid-template-columns: 24px minmax(0, 1fr) auto;
252
+ align-items: center;
253
+ gap: 0 0.875rem;
254
+ padding: 0.875rem 0;
236
255
  border: none;
256
+ border-bottom: 1px solid var(--seams-colors-borderPrimary);
237
257
  border-radius: 0;
238
258
  background: transparent;
239
259
  }
240
260
 
241
- /* Divider inset to the row padding so the group reads as one card. */
242
- .seams-linked-devices-modal-item--row + .seams-linked-devices-modal-item--row::before {
243
- content: '';
244
- position: absolute;
245
- top: 0;
246
- left: 1rem;
247
- right: 1rem;
248
- border-top: 1px solid var(--seams-colors-borderPrimary);
249
- }
250
-
251
261
  .seams-linked-devices-modal-item-icon {
252
262
  display: inline-flex;
253
263
  align-items: center;
254
264
  justify-content: center;
255
- width: 40px;
256
- height: 40px;
257
- border-radius: 999px;
258
- background: color-mix(in srgb, var(--seams-colors-textSecondary), transparent 92%);
265
+ align-self: start;
266
+ width: 24px;
267
+ height: 1.25rem;
268
+ margin-top: 0.125rem;
259
269
  color: var(--seams-colors-textSecondary);
260
270
  }
261
271
 
272
+ .seams-linked-devices-modal-item-icon svg {
273
+ width: 20px;
274
+ height: 20px;
275
+ }
276
+
277
+ /* Section labels name each group of rows, in small caps above it. */
278
+ .seams-account-menu-section {
279
+ display: grid;
280
+ gap: 0.5rem;
281
+ }
282
+
283
+ .seams-account-menu-section-label {
284
+ margin: 0;
285
+ color: var(--seams-colors-textSecondary);
286
+ font-size: 0.6875rem;
287
+ font-weight: 500;
288
+ letter-spacing: 0.08em;
289
+ line-height: 1.4;
290
+ text-transform: uppercase;
291
+ }
292
+
293
+ .seams-account-menu-section > .seams-linked-devices-modal-list--grouped {
294
+ margin-top: -0.25rem;
295
+ }
296
+
297
+ /* A section's main action is a full-width outline button; an add action leads
298
+ with its plus sign. */
299
+ .seams-linked-devices-modal-content .seams-account-menu-wide-button {
300
+ display: inline-flex;
301
+ align-items: center;
302
+ justify-content: center;
303
+ justify-self: stretch;
304
+ gap: 0.5rem;
305
+ min-height: 44px;
306
+ border-radius: var(--seams-shape-control, 10px);
307
+ background: transparent;
308
+ font-size: 0.875rem;
309
+ font-weight: 500;
310
+ }
311
+
262
312
  .seams-linked-devices-modal-item-content {
263
313
  display: grid;
264
314
  gap: 0.15rem;
265
315
  min-width: 0;
266
316
  }
267
317
 
268
- /* Title and chip sit together on the left; the shared rule spreads them. */
318
+ /* Title on the left, status chip at the end of the row. */
269
319
  .seams-linked-devices-modal-item--row .seams-linked-devices-modal-item-main {
270
- justify-content: flex-start;
320
+ justify-content: space-between;
271
321
  align-items: center;
272
322
  flex-wrap: wrap;
273
323
  gap: 0.5rem;
@@ -275,10 +325,17 @@
275
325
  }
276
326
 
277
327
  .seams-linked-devices-modal-item--row .seams-linked-devices-modal-item-name {
278
- font-size: 0.875rem;
328
+ font-size: 0.9375rem;
329
+ font-weight: 500;
279
330
  line-height: 1.25rem;
280
331
  }
281
332
 
333
+ .seams-linked-devices-modal-item--row .seams-linked-devices-modal-item-detail {
334
+ margin-top: 0.125rem;
335
+ font-size: 0.8125rem;
336
+ font-weight: 400;
337
+ }
338
+
282
339
  /* Why this row cannot be removed right now, shaped as part of the row. */
283
340
  .seams-linked-devices-modal-hint {
284
341
  display: flex;
@@ -343,7 +400,8 @@
343
400
  .seams-linked-devices-modal-add-method h3 {
344
401
  margin: 0;
345
402
  color: var(--seams-colors-textPrimary);
346
- font-size: 0.95rem;
403
+ font-size: 0.9375rem;
404
+ font-weight: 500;
347
405
  line-height: 1.35;
348
406
  }
349
407
 
@@ -486,10 +544,21 @@
486
544
  .seams-linked-devices-modal-content {
487
545
  max-height: calc(100vh - 16px);
488
546
  max-height: calc(100dvh - 16px);
489
- padding: var(--seams-spacing-md, 1rem);
490
547
  border-radius: var(--seams-shape-card, 1rem);
491
548
  }
492
549
 
550
+ .seams-account-menu-dialog-main {
551
+ padding: var(--seams-spacing-md, 1rem);
552
+ }
553
+
554
+ .seams-account-menu-dialog-header {
555
+ padding-inline-start: var(--seams-spacing-md, 1rem);
556
+ }
557
+
558
+ .seams-account-menu-dialog-footer {
559
+ padding-inline: var(--seams-spacing-md, 1rem);
560
+ }
561
+
493
562
  .seams-linked-devices-modal-item-main {
494
563
  align-items: flex-start;
495
564
  flex-direction: column;
@@ -500,21 +569,6 @@
500
569
  align-items: center;
501
570
  flex-direction: row;
502
571
  }
503
-
504
- .seams-linked-devices-modal-item--row {
505
- grid-template-columns: 32px minmax(0, 1fr) auto;
506
- padding: 0.85rem;
507
- }
508
-
509
- .seams-linked-devices-modal-item-icon {
510
- width: 32px;
511
- height: 32px;
512
- }
513
-
514
- .seams-linked-devices-modal-item--row + .seams-linked-devices-modal-item--row::before {
515
- left: 0.85rem;
516
- right: 0.85rem;
517
- }
518
572
  }
519
573
 
520
574
  @media (max-height: 520px) {
@@ -540,8 +594,8 @@
540
594
  border: 1px solid var(--seams-colors-borderPrimary);
541
595
  animation: none;
542
596
  }
543
- .seams-linked-devices-modal-backdrop[data-presentation='page'] .seams-linked-devices-modal-close {
544
- display: none;
597
+ .seams-linked-devices-modal-backdrop[data-presentation='page'] .seams-account-menu-dialog-main {
598
+ padding: 0;
545
599
  }
546
600
  .seams-linked-devices-modal-backdrop[data-presentation='page'] .seams-linked-devices-modal-body {
547
601
  overflow: visible;
@@ -554,10 +608,17 @@
554
608
  .seams-auth-methods-modal-content .seams-linked-devices-modal-body {
555
609
  gap: 1.5rem;
556
610
  }
611
+ /* A method's icon sits on a tile, like the recovery-code row. */
557
612
  .seams-auth-methods-modal-content .seams-linked-devices-modal-item--row {
558
- padding: 1rem;
559
- border: 0;
560
- background: transparent;
613
+ grid-template-columns: 2.5rem minmax(0, 1fr) auto;
614
+ }
615
+ .seams-auth-methods-modal-content .seams-linked-devices-modal-item-icon {
616
+ width: 2.5rem;
617
+ height: 2.5rem;
618
+ margin-top: 0;
619
+ border-radius: var(--seams-shape-control, 10px);
620
+ background: color-mix(in srgb, var(--seams-colors-textPrimary), transparent 93%);
621
+ color: var(--seams-colors-textPrimary);
561
622
  }
562
623
  .seams-auth-methods-modal-content .seams-linked-devices-modal-item-detail {
563
624
  font-weight: 400;
@@ -566,7 +627,7 @@
566
627
  .seams-auth-methods-modal-content .seams-linked-devices-modal-add-method {
567
628
  padding: 0;
568
629
  border: 0;
569
- gap: 1rem;
630
+ gap: 0.5rem;
570
631
  }
571
632
  .seams-auth-methods-modal-content .seams-linked-devices-modal-otp-form {
572
633
  grid-template-columns: minmax(0, 1fr) auto;
@@ -1,8 +1,10 @@
1
1
  import { useSeams } from "../../context/index.js";
2
+ import { AccountMenuDeviceDetails } from "./AccountMenuDeviceDetails.js";
2
3
  import { AccountMenuDialogFrame, useAccountMenuDialogKeyboard } from "./AccountMenuDialog.js";
4
+ import { MailIcon } from "./icons/MailIcon.js";
5
+ import { AuthenticationMethodRow } from "./AuthenticationMethodRow.js";
3
6
  import { LaptopIcon } from "./icons/LaptopIcon.js";
4
7
  import { LockIcon } from "./icons/LockIcon.js";
5
- import { MailIcon } from "./icons/MailIcon.js";
6
8
  import { SmartphoneIcon } from "./icons/SmartphoneIcon.js";
7
9
  import React, { useEffect } from "react";
8
10
  import { jsx, jsxs } from "react/jsx-runtime";
@@ -203,6 +205,7 @@ const LinkedDevicesModal = ({ walletId, isOpen, onClose, presentation = "modal"
203
205
  const { seams, loginState } = useSeams();
204
206
  const [loadState, setLoadState] = React.useState({ kind: "idle" });
205
207
  const [revokeState, setRevokeState] = React.useState({ kind: "idle" });
208
+ const [selectedDeviceId, setSelectedDeviceId] = React.useState(null);
206
209
  const [announcement, setAnnouncement] = React.useState("");
207
210
  const loadSeq = React.useRef(0);
208
211
  const seamsRef = React.useRef(seams);
@@ -247,6 +250,7 @@ const LinkedDevicesModal = ({ walletId, isOpen, onClose, presentation = "modal"
247
250
  if (!isOpen) {
248
251
  loadSeq.current += 1;
249
252
  setLoadState({ kind: "idle" });
253
+ setSelectedDeviceId(null);
250
254
  setRevokeState({ kind: "idle" });
251
255
  setAnnouncement("");
252
256
  return;
@@ -286,17 +290,26 @@ const LinkedDevicesModal = ({ walletId, isOpen, onClose, presentation = "modal"
286
290
  ]);
287
291
  if (!isOpen) return null;
288
292
  const devices = loadState.kind === "loaded" ? loadState.devices : [];
293
+ const selectedDevice = devices.find((entry) => viewId(entry.view) === selectedDeviceId);
294
+ const visibleDevices = selectedDevice ? [selectedDevice] : devices;
289
295
  const showEmpty = loadState.kind === "loaded" && devices.length === 0;
290
296
  const selectedWalletAuthMethodId = loginState.isLoggedIn && loginState.currentAuthMethod.kind === "selected" ? String(loginState.currentAuthMethod.binding.walletAuthMethodId) : null;
291
297
  return /* @__PURE__ */ jsxs(AccountMenuDialogFrame, {
292
298
  presentation,
293
- onClose,
299
+ onClose: selectedDevice ? setSelectedDeviceId.bind(null, null) : onClose,
294
300
  dialogRef,
295
301
  contentClassName: "seams-linked-devices-inventory-content",
296
302
  titleId: "seams-linked-devices-modal-title",
297
- title: "Your devices",
303
+ title: selectedDevice ? "Device details" : "Linked devices",
298
304
  closeLabel: "Close linked devices",
299
- children: [/* @__PURE__ */ jsx("p", {
305
+ children: [selectedDevice ? /* @__PURE__ */ jsx(AccountMenuDeviceDetails, {
306
+ title: credentialDescription(viewCredential(selectedDevice.view)),
307
+ description: deviceMetaLine(selectedDevice.view, selectedDevice.deviceNumber, false, Date.now()),
308
+ details: [{
309
+ label: "Status",
310
+ value: deviceStateAttr(selectedDevice.view)
311
+ }]
312
+ }) : /* @__PURE__ */ jsx("p", {
300
313
  className: "seams-linked-devices-modal-subtitle",
301
314
  children: "Anything listed here can unlock this wallet."
302
315
  }), /* @__PURE__ */ jsxs("div", {
@@ -323,7 +336,7 @@ const LinkedDevicesModal = ({ walletId, isOpen, onClose, presentation = "modal"
323
336
  }) : null,
324
337
  devices.length > 0 ? /* @__PURE__ */ jsx("ul", {
325
338
  className: "seams-linked-devices-modal-list seams-linked-devices-modal-list--grouped",
326
- children: devices.map(({ view, deviceNumber }) => {
339
+ children: visibleDevices.map(({ view, deviceNumber }) => {
327
340
  const cardId = viewId(view);
328
341
  const title = credentialDescription(viewCredential(view));
329
342
  const titleCollides = devices.some((other) => viewId(other.view) !== cardId && credentialDescription(viewCredential(other.view)) === title);
@@ -335,8 +348,16 @@ const LinkedDevicesModal = ({ walletId, isOpen, onClose, presentation = "modal"
335
348
  const working = revokeState.kind === "working" && revokeState.walletAuthMethodId === walletAuthMethodId;
336
349
  const revocationInProgress = revokeState.kind === "working";
337
350
  const showRemoveButton = hasRemovableSibling && !isSelectedMethod && !confirming;
351
+ if (presentation === "embedded" && !selectedDevice) return /* @__PURE__ */ jsx(AuthenticationMethodRow, {
352
+ kind: viewCredential(view).kind,
353
+ icon: credentialIcon(viewCredential(view)),
354
+ title,
355
+ description: deviceMetaLine(view, deviceNumber, titleCollides, Date.now()),
356
+ onSelect: setSelectedDeviceId.bind(null, cardId)
357
+ }, cardId);
338
358
  return /* @__PURE__ */ jsxs("li", {
339
359
  className: "seams-linked-devices-modal-item seams-linked-devices-modal-item--row",
360
+ "data-detail": selectedDevice ? "true" : void 0,
340
361
  "data-device-kind": view.kind,
341
362
  "data-device-state": deviceStateAttr(view),
342
363
  children: [
@@ -16,22 +16,37 @@ const MenuItem = memo(forwardRef(({ item, onClose, className, style, isHighlight
16
16
  ref,
17
17
  type: "button",
18
18
  disabled: item.disabled,
19
+ "data-account-menu-item": item.id,
19
20
  className: `seams-dropdown-menu-item${disabledClass}${classNameProps}${highlightedClass}`,
20
21
  style,
21
22
  onClick: handleClick,
22
- children: [/* @__PURE__ */ jsx("div", {
23
- className: "seams-dropdown-menu-item-icon",
24
- children: item.icon
25
- }), /* @__PURE__ */ jsxs("div", {
26
- className: "seams-dropdown-menu-item-content",
27
- children: [/* @__PURE__ */ jsx("div", {
28
- className: "seams-dropdown-menu-item-label",
29
- children: item.label
30
- }), /* @__PURE__ */ jsx("div", {
31
- className: "seams-dropdown-menu-item-description",
32
- children: item.description
33
- })]
34
- })]
23
+ children: [
24
+ /* @__PURE__ */ jsx("div", {
25
+ className: "seams-dropdown-menu-item-icon",
26
+ children: item.icon
27
+ }),
28
+ /* @__PURE__ */ jsxs("div", {
29
+ className: "seams-dropdown-menu-item-content",
30
+ children: [/* @__PURE__ */ jsx("div", {
31
+ className: "seams-dropdown-menu-item-label",
32
+ children: item.label
33
+ }), /* @__PURE__ */ jsx("div", {
34
+ className: "seams-dropdown-menu-item-description",
35
+ children: item.description
36
+ })]
37
+ }),
38
+ !item.disabled ? /* @__PURE__ */ jsx("svg", {
39
+ className: "seams-account-menu-chevron",
40
+ width: "16",
41
+ height: "16",
42
+ viewBox: "0 0 24 24",
43
+ fill: "none",
44
+ stroke: "currentColor",
45
+ strokeWidth: "1.5",
46
+ "aria-hidden": "true",
47
+ children: /* @__PURE__ */ jsx("path", { d: "m9 6 6 6-6 6" })
48
+ }) : null
49
+ ]
35
50
  });
36
51
  }));
37
52
  //#endregion
@@ -1,80 +1,84 @@
1
- /* ProfileDropdown component-specific styles */
2
-
3
- /* Dropdown (grid height animation with data-state) */
4
- .seams-profile-dropdown-morphed {
5
- position: static;
6
- box-sizing: border-box;
7
- margin-top: 0;
8
- opacity: 0;
9
- visibility: hidden;
10
- display: grid;
11
- grid-template-rows: 0fr;
12
- grid-template-columns: 1fr;
13
- transition:
14
- opacity 120ms linear,
15
- grid-template-rows 140ms cubic-bezier(0.16, 1, 0.3, 1);
1
+ .seams-account-menu-group {
2
+ margin-top: 16px;
3
+ }
4
+ .seams-account-menu-group + .seams-account-menu-group {
16
5
  border-top: 1px solid var(--seams-colors-borderPrimary);
6
+ padding-top: 12px;
7
+ margin-top: 10px;
17
8
  }
18
-
19
- .seams-profile-dropdown-morphed[data-state='open'] {
20
- opacity: 1;
21
- visibility: visible;
22
- grid-template-rows: 1fr;
23
- grid-template-columns: 1fr;
24
- pointer-events: auto;
25
- --stagger-base: 40ms;
9
+ .seams-account-menu-group h3 {
10
+ font-size: 10px;
11
+ font-weight: 600;
12
+ letter-spacing: 1px;
13
+ text-transform: uppercase;
14
+ color: var(--seams-colors-textSecondary);
15
+ margin: 0 0 4px;
26
16
  }
27
-
28
- .seams-profile-dropdown-morphed[data-state='closed'] {
29
- pointer-events: none;
30
- border-top-width: 0;
31
- grid-template-rows: 0fr;
32
- height: 0;
33
- min-height: 0;
34
- width: 0;
35
- min-width: 0;
36
- max-width: 0;
37
- overflow: hidden;
38
- margin: 0;
39
- padding: 0;
17
+ .seams-profile-dropdown-menu {
18
+ --seams-expander-surface: var(--seams-colors-surface2);
40
19
  }
41
-
42
- .seams-profile-dropdown-morphed.hidden {
20
+ .seams-profile-dropdown-menu .seams-dropdown-menu-item {
21
+ min-height: 40px;
22
+ padding: 6px 0;
23
+ gap: 10px;
24
+ border: 0;
25
+ border-radius: 0;
26
+ background: transparent;
27
+ font: inherit;
28
+ color: inherit;
29
+ width: 100%;
30
+ text-align: left;
31
+ display: flex;
32
+ align-items: center;
33
+ cursor: pointer;
34
+ }
35
+ .seams-profile-dropdown-menu .seams-dropdown-menu-item:disabled {
36
+ color: var(--seams-colors-textSecondary);
37
+ opacity: 0.6;
38
+ cursor: default;
39
+ }
40
+ .seams-profile-dropdown-menu .seams-dropdown-menu-item-icon {
41
+ width: 22px;
42
+ height: 22px;
43
+ color: var(--seams-colors-textSecondary);
44
+ flex-shrink: 0;
45
+ }
46
+ .seams-profile-dropdown-menu .seams-dropdown-menu-item-icon svg {
47
+ width: 20px;
48
+ height: 20px;
49
+ }
50
+ .seams-profile-dropdown-menu .seams-dropdown-menu-item-label {
51
+ font-size: 14px;
52
+ font-weight: 400;
53
+ }
54
+ .seams-profile-dropdown-menu .seams-dropdown-menu-item-description {
43
55
  display: none;
44
56
  }
45
-
46
- /* Inner clip and container */
47
- .seams-profile-dropdown-menu {
48
- overflow: hidden;
49
- min-height: 0;
50
- min-width: 0;
51
- /* Expanded sections sit on a slightly deeper surface than the menu itself.
52
- Derived from the theme's own surface tones so it tracks light/dark. */
53
- --seams-expander-surface: color-mix(
54
- in srgb,
55
- var(--seams-colors-surface2) 45%,
56
- var(--seams-colors-surface)
57
- );
57
+ .seams-profile-dropdown-menu .seams-dropdown-menu-item-content {
58
+ flex: 1;
58
59
  }
59
-
60
- /* Global theme pulse when toggling theme */
61
- @keyframes seams-theme-pulse {
62
- 0% {
63
- filter: none;
64
- }
65
- 50% {
66
- filter: brightness(1.05) saturate(1.06);
67
- }
68
- 100% {
69
- filter: none;
70
- }
60
+ .seams-account-menu-chevron {
61
+ color: var(--seams-colors-textSecondary);
62
+ flex-shrink: 0;
71
63
  }
72
- body[data-seams-theme-pulse='1'] .seams-profile-dropdown-menu {
73
- animation: seams-theme-pulse 220ms ease;
64
+ .seams-profile-dropdown-menu .seams-lock-menu-item {
65
+ border: 1px solid var(--seams-colors-borderPrimary);
66
+ border-radius: 11px;
67
+ justify-content: center;
68
+ margin-top: 12px;
69
+ }
70
+ .seams-lock-menu-item .seams-dropdown-menu-item-content {
71
+ flex: 0 1 auto;
72
+ }
73
+ @media (hover: hover) {
74
+ .seams-profile-dropdown-menu .seams-dropdown-menu-item:not(:disabled):hover {
75
+ color: var(--seams-colors-textSecondary);
76
+ background: transparent;
77
+ }
74
78
  }
75
79
 
76
- /* Lock menu item specific styling */
77
- .seams-lock-menu-item {
78
- border-top: 1px solid var(--seams-colors-borderPrimary);
79
- border-radius: 0px 0px 2rem 2rem;
80
+ @media (pointer: coarse) {
81
+ .seams-profile-dropdown-menu .seams-dropdown-menu-item {
82
+ min-height: 44px;
83
+ }
80
84
  }