@shapeshiftoss/swap-widget 0.0.2 → 0.2.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 (158) hide show
  1. package/LICENSE.md +21 -0
  2. package/README.md +18 -11
  3. package/package.json +77 -28
  4. package/Dockerfile +0 -87
  5. package/dist/assets/PhArrowCircleDown-B305t-Sh.js +0 -14
  6. package/dist/assets/PhArrowClockwise-CJPxQhr_.js +0 -14
  7. package/dist/assets/PhArrowDown-C4hT9BVu.js +0 -14
  8. package/dist/assets/PhArrowLeft-Way4Cu-r.js +0 -14
  9. package/dist/assets/PhArrowRight-Cp5ZME0F.js +0 -14
  10. package/dist/assets/PhArrowSquareOut-NnrK69c5.js +0 -14
  11. package/dist/assets/PhArrowUp-Dph6j8rm.js +0 -14
  12. package/dist/assets/PhArrowUpRight-BpJjRRRh.js +0 -14
  13. package/dist/assets/PhArrowsClockwise-CFUT8X7R.js +0 -14
  14. package/dist/assets/PhArrowsDownUp-BjBI4ckC.js +0 -14
  15. package/dist/assets/PhArrowsLeftRight-CuLpbKRk.js +0 -14
  16. package/dist/assets/PhBank-Dchr4XQJ.js +0 -14
  17. package/dist/assets/PhBrowser-dUu2TrC1.js +0 -14
  18. package/dist/assets/PhCaretDown-78IuKU3V.js +0 -14
  19. package/dist/assets/PhCaretLeft-_aiyH7n1.js +0 -14
  20. package/dist/assets/PhCaretRight-8zJQEuDX.js +0 -14
  21. package/dist/assets/PhCaretUp-CiCxKWwN.js +0 -14
  22. package/dist/assets/PhCheck-CcADx8br.js +0 -14
  23. package/dist/assets/PhCircleHalf-BYzSzd2h.js +0 -14
  24. package/dist/assets/PhClock-UItiXeJq.js +0 -14
  25. package/dist/assets/PhCompass-CUy3uA7t.js +0 -14
  26. package/dist/assets/PhCopy-C-PDgSlZ.js +0 -14
  27. package/dist/assets/PhCreditCard-CWRaUT6F.js +0 -14
  28. package/dist/assets/PhCurrencyDollar-Cqla3AXT.js +0 -14
  29. package/dist/assets/PhDesktop-BBIPrYLl.js +0 -14
  30. package/dist/assets/PhDeviceMobile-BdsPaATg.js +0 -14
  31. package/dist/assets/PhDotsThree-BMXCQl-0.js +0 -14
  32. package/dist/assets/PhEnvelope-yUsis6yU.js +0 -14
  33. package/dist/assets/PhFunnelSimple-Ba7BbWTp.js +0 -14
  34. package/dist/assets/PhGlobe-DgLxBk5U.js +0 -14
  35. package/dist/assets/PhIdentificationCard-Czjmq9Z3.js +0 -14
  36. package/dist/assets/PhImage-BAJ_erz6.js +0 -14
  37. package/dist/assets/PhInfo-Cr4DhVUE.js +0 -14
  38. package/dist/assets/PhLightbulb-BX_7duTr.js +0 -14
  39. package/dist/assets/PhMagnifyingGlass-Mygfryvz.js +0 -14
  40. package/dist/assets/PhPaperPlaneRight-BeuCA660.js +0 -14
  41. package/dist/assets/PhPlus-BMjcHjsT.js +0 -14
  42. package/dist/assets/PhPower-CGffGmdb.js +0 -14
  43. package/dist/assets/PhPuzzlePiece-wm_GpVSi.js +0 -14
  44. package/dist/assets/PhQrCode-DRwRzXCH.js +0 -14
  45. package/dist/assets/PhQuestion-M09j2U0T.js +0 -14
  46. package/dist/assets/PhQuestionMark-BP9EMB6h.js +0 -14
  47. package/dist/assets/PhSealCheck-BfG80yKn.js +0 -14
  48. package/dist/assets/PhSignOut-C5YOWlPT.js +0 -14
  49. package/dist/assets/PhSpinner-BXooDYzU.js +0 -14
  50. package/dist/assets/PhTrash-Biq6rmmL.js +0 -14
  51. package/dist/assets/PhUser-CAgZSpGe.js +0 -14
  52. package/dist/assets/PhVault-l2PHF38a.js +0 -14
  53. package/dist/assets/PhWallet-w25D16It.js +0 -14
  54. package/dist/assets/PhWarning-DPEydIPw.js +0 -14
  55. package/dist/assets/PhWarningCircle-BqjT745H.js +0 -14
  56. package/dist/assets/PhX-s-SmVExa.js +0 -14
  57. package/dist/assets/SwapController-If0bFrNc.js +0 -1
  58. package/dist/assets/ccip-BBB7uCdL.js +0 -1
  59. package/dist/assets/ccip-CkkdfKKI.js +0 -1
  60. package/dist/assets/data-capture-D4gAy-Yc.js +0 -242
  61. package/dist/assets/email-B1AJehis.js +0 -90
  62. package/dist/assets/embedded-wallet-Q6DQopDk.js +0 -410
  63. package/dist/assets/features-B6JAPAFb.js +0 -5
  64. package/dist/assets/index-5jd8RPN9.js +0 -7428
  65. package/dist/assets/index-B4kNtSTk.js +0 -1080
  66. package/dist/assets/index-B753eAob.js +0 -1
  67. package/dist/assets/index-BZoLTv77.js +0 -3
  68. package/dist/assets/index-Bcw9UURX.js +0 -3
  69. package/dist/assets/index-BkrV-ahK.js +0 -2
  70. package/dist/assets/index-CRQzQ_up.js +0 -9
  71. package/dist/assets/index-CSW0Gt5y.js +0 -132
  72. package/dist/assets/index-CZ4jTIsk.js +0 -138
  73. package/dist/assets/index-Cwa8SB3h.js +0 -61
  74. package/dist/assets/index-DEwQgT4r.js +0 -78
  75. package/dist/assets/index-DVfQiQ1d.js +0 -1
  76. package/dist/assets/index-cV3UdaMs.css +0 -1
  77. package/dist/assets/index-hAmu622O.js +0 -43
  78. package/dist/assets/onramp-XcPNCLRU.js +0 -422
  79. package/dist/assets/pay-with-exchange-BeHt4OF4.js +0 -280
  80. package/dist/assets/property-C9JG5tag.js +0 -27
  81. package/dist/assets/receive-7ff4he2S.js +0 -131
  82. package/dist/assets/send-CkMBIRXT.js +0 -554
  83. package/dist/assets/socials-DmmxuLrP.js +0 -250
  84. package/dist/assets/swaps-IHAYRQ0x.js +0 -1050
  85. package/dist/assets/transactions-9Cxdk7o9.js +0 -16
  86. package/dist/assets/v4-BOvFkHkt.js +0 -1
  87. package/dist/assets/w3m-modal-kJzFnBfB.js +0 -891
  88. package/dist/assets/wallet-standard-Dv8LMoUB.js +0 -1
  89. package/dist/favicon.png +0 -0
  90. package/dist/favicon.svg +0 -11
  91. package/dist/icon-192x192.png +0 -0
  92. package/dist/icon-512x512.png +0 -0
  93. package/dist/index.html +0 -33
  94. package/index.html +0 -32
  95. package/public/favicon.png +0 -0
  96. package/public/favicon.svg +0 -11
  97. package/public/icon-192x192.png +0 -0
  98. package/public/icon-512x512.png +0 -0
  99. package/railway.toml +0 -10
  100. package/src/api/client.ts +0 -95
  101. package/src/components/AddressInputModal.css +0 -173
  102. package/src/components/AddressInputModal.tsx +0 -250
  103. package/src/components/ApprovalStep.tsx +0 -92
  104. package/src/components/ExecutionStep.tsx +0 -27
  105. package/src/components/InputStep.tsx +0 -431
  106. package/src/components/QuoteSelector.css +0 -146
  107. package/src/components/QuoteSelector.tsx +0 -137
  108. package/src/components/QuotesModal.css +0 -250
  109. package/src/components/QuotesModal.tsx +0 -182
  110. package/src/components/SettingsModal.css +0 -145
  111. package/src/components/SettingsModal.tsx +0 -180
  112. package/src/components/StatusStep.tsx +0 -139
  113. package/src/components/SwapWidget.css +0 -713
  114. package/src/components/SwapWidget.tsx +0 -607
  115. package/src/components/TokenSelectModal.css +0 -438
  116. package/src/components/TokenSelectModal.tsx +0 -487
  117. package/src/components/WalletProvider.tsx +0 -92
  118. package/src/config/appkit.ts +0 -104
  119. package/src/config/wagmi.ts +0 -27
  120. package/src/constants/chains.ts +0 -72
  121. package/src/constants/defaults.ts +0 -28
  122. package/src/constants/swappers.ts +0 -48
  123. package/src/constants/viemChains.ts +0 -69
  124. package/src/contexts/SwapWalletContext.tsx +0 -25
  125. package/src/demo/App.css +0 -458
  126. package/src/demo/App.tsx +0 -481
  127. package/src/demo/main.tsx +0 -25
  128. package/src/hooks/useAssets.ts +0 -180
  129. package/src/hooks/useBalances.ts +0 -822
  130. package/src/hooks/useBitcoinSigning.ts +0 -276
  131. package/src/hooks/useMarketData.ts +0 -169
  132. package/src/hooks/useSolanaSigning.ts +0 -275
  133. package/src/hooks/useStatusPolling.ts +0 -137
  134. package/src/hooks/useSwapApproval.ts +0 -106
  135. package/src/hooks/useSwapDisplayValues.ts +0 -157
  136. package/src/hooks/useSwapExecution.ts +0 -199
  137. package/src/hooks/useSwapHandlers.ts +0 -119
  138. package/src/hooks/useSwapQuote.ts +0 -71
  139. package/src/hooks/useSwapQuoting.ts +0 -102
  140. package/src/hooks/useSwapRates.ts +0 -61
  141. package/src/index.ts +0 -43
  142. package/src/machines/SwapMachineContext.ts +0 -5
  143. package/src/machines/__tests__/guards.test.ts +0 -228
  144. package/src/machines/__tests__/setup.test.ts +0 -7
  145. package/src/machines/__tests__/swapMachine.test.ts +0 -544
  146. package/src/machines/__tests__/types.test.ts +0 -124
  147. package/src/machines/guards.ts +0 -33
  148. package/src/machines/swapMachine.ts +0 -288
  149. package/src/machines/types.ts +0 -54
  150. package/src/services/transactionStatus.ts +0 -322
  151. package/src/types/index.ts +0 -361
  152. package/src/utils/addressValidation.ts +0 -201
  153. package/src/utils/redirect.ts +0 -45
  154. package/src/vite-env.d.ts +0 -10
  155. package/tsconfig.json +0 -23
  156. package/tsconfig.node.json +0 -10
  157. package/vite.config.ts +0 -101
  158. package/vitest.config.ts +0 -18
@@ -1,72 +0,0 @@
1
- import type { Asset } from '@shapeshiftoss/types'
2
- import {
3
- arbitrum,
4
- atom,
5
- avax,
6
- base,
7
- bitcoin,
8
- bitcoincash,
9
- bnbsmartchain,
10
- dogecoin,
11
- ethereum,
12
- gnosis,
13
- hyperevm,
14
- katana,
15
- litecoin,
16
- mayachain,
17
- monad,
18
- optimism,
19
- plasma,
20
- polygon,
21
- solana,
22
- thorchain,
23
- worldchain,
24
- } from '@shapeshiftoss/utils'
25
-
26
- import type { ChainId } from '../types'
27
-
28
- const BASE_ASSETS_BY_CHAIN_ID: Record<ChainId, Asset> = {
29
- [ethereum.chainId]: ethereum,
30
- [arbitrum.chainId]: arbitrum,
31
- [optimism.chainId]: optimism,
32
- [polygon.chainId]: polygon,
33
- [base.chainId]: base,
34
- [avax.chainId]: avax,
35
- [bnbsmartchain.chainId]: bnbsmartchain,
36
- [gnosis.chainId]: gnosis,
37
- [monad.chainId]: monad,
38
- [hyperevm.chainId]: hyperevm,
39
- [plasma.chainId]: plasma,
40
- [worldchain.chainId]: worldchain,
41
- [katana.chainId]: katana,
42
- [bitcoin.chainId]: bitcoin,
43
- [bitcoincash.chainId]: bitcoincash,
44
- [dogecoin.chainId]: dogecoin,
45
- [litecoin.chainId]: litecoin,
46
- [atom.chainId]: atom,
47
- [thorchain.chainId]: thorchain,
48
- [mayachain.chainId]: mayachain,
49
- [solana.chainId]: solana,
50
- }
51
-
52
- export const getBaseAsset = (chainId: ChainId): Asset | undefined => {
53
- return BASE_ASSETS_BY_CHAIN_ID[chainId]
54
- }
55
-
56
- export const getChainName = (chainId: ChainId): string => {
57
- return BASE_ASSETS_BY_CHAIN_ID[chainId]?.networkName ?? chainId
58
- }
59
-
60
- export const getChainIcon = (chainId: ChainId): string | undefined => {
61
- const asset = BASE_ASSETS_BY_CHAIN_ID[chainId]
62
- return asset?.networkIcon ?? asset?.icon
63
- }
64
-
65
- export const getChainColor = (chainId: ChainId): string => {
66
- const asset = BASE_ASSETS_BY_CHAIN_ID[chainId]
67
- return (asset as Asset & { networkColor?: string })?.networkColor ?? asset?.color ?? '#888888'
68
- }
69
-
70
- export const getExplorerTxLink = (chainId: ChainId): string => {
71
- return BASE_ASSETS_BY_CHAIN_ID[chainId]?.explorerTxLink ?? 'https://etherscan.io/tx/'
72
- }
@@ -1,28 +0,0 @@
1
- import { ethChainId, usdcAssetId } from '@shapeshiftoss/caip'
2
- import { ethereum } from '@shapeshiftoss/utils'
3
-
4
- import type { Asset } from '../types'
5
-
6
- export const DEFAULT_SELL_ASSET: Asset = {
7
- assetId: ethereum.assetId,
8
- chainId: ethereum.chainId,
9
- symbol: ethereum.symbol,
10
- name: ethereum.name,
11
- precision: ethereum.precision,
12
- icon: ethereum.icon,
13
- networkName: ethereum.networkName,
14
- explorer: ethereum.explorer,
15
- explorerTxLink: ethereum.explorerTxLink,
16
- explorerAddressLink: ethereum.explorerAddressLink,
17
- }
18
-
19
- export const DEFAULT_BUY_ASSET: Asset = {
20
- assetId: usdcAssetId,
21
- chainId: ethChainId,
22
- symbol: 'USDC',
23
- name: 'USD Coin',
24
- precision: 6,
25
- icon: 'https://assets.coingecko.com/coins/images/6319/standard/usdc.png',
26
- }
27
-
28
- export const POLL_INTERVAL_MS = 5000
@@ -1,48 +0,0 @@
1
- import { SwapperName } from '../types'
2
-
3
- export const SWAPPER_ICONS: Partial<Record<SwapperName, string>> = {
4
- [SwapperName.Thorchain]:
5
- 'https://raw.githubusercontent.com/shapeshift/web/develop/src/components/MultiHopTrade/components/TradeInput/components/SwapperIcon/thorchain-icon.png',
6
- [SwapperName.Mayachain]:
7
- 'https://raw.githubusercontent.com/shapeshift/web/develop/src/components/MultiHopTrade/components/TradeInput/components/SwapperIcon/maya_logo.png',
8
- [SwapperName.CowSwap]:
9
- 'https://raw.githubusercontent.com/shapeshift/web/develop/src/components/MultiHopTrade/components/TradeInput/components/SwapperIcon/cow-icon.png',
10
- [SwapperName.Zrx]:
11
- 'https://raw.githubusercontent.com/shapeshift/web/develop/src/components/MultiHopTrade/components/TradeInput/components/SwapperIcon/0x-icon.png',
12
- [SwapperName.Portals]:
13
- 'https://raw.githubusercontent.com/shapeshift/web/develop/src/components/MultiHopTrade/components/TradeInput/components/SwapperIcon/portals-icon.png',
14
- [SwapperName.Chainflip]:
15
- 'https://raw.githubusercontent.com/shapeshift/web/develop/src/components/MultiHopTrade/components/TradeInput/components/SwapperIcon/chainflip-icon.png',
16
- [SwapperName.Relay]:
17
- 'https://raw.githubusercontent.com/shapeshift/web/develop/src/components/MultiHopTrade/components/TradeInput/components/SwapperIcon/relay-icon.svg',
18
- [SwapperName.Bebop]:
19
- 'https://raw.githubusercontent.com/shapeshift/web/develop/src/components/MultiHopTrade/components/TradeInput/components/SwapperIcon/bebop-icon.png',
20
- [SwapperName.Jupiter]:
21
- 'https://raw.githubusercontent.com/shapeshift/web/develop/src/components/MultiHopTrade/components/TradeInput/components/SwapperIcon/jupiter-icon.svg',
22
- [SwapperName.ButterSwap]:
23
- 'https://raw.githubusercontent.com/shapeshift/web/develop/src/components/MultiHopTrade/components/TradeInput/components/SwapperIcon/butterswap.png',
24
- [SwapperName.ArbitrumBridge]:
25
- 'https://raw.githubusercontent.com/shapeshift/web/develop/src/components/MultiHopTrade/components/TradeInput/components/SwapperIcon/arbitrum-bridge-icon.png',
26
- }
27
-
28
- export const SWAPPER_COLORS: Partial<Record<SwapperName, string>> = {
29
- [SwapperName.Thorchain]: '#00CCFF',
30
- [SwapperName.Mayachain]: '#4169E1',
31
- [SwapperName.CowSwap]: '#012d73',
32
- [SwapperName.Zrx]: '#000000',
33
- [SwapperName.Portals]: '#8B5CF6',
34
- [SwapperName.Chainflip]: '#FF4081',
35
- [SwapperName.Relay]: '#6366F1',
36
- [SwapperName.Bebop]: '#E91E63',
37
- [SwapperName.Jupiter]: '#C4A962',
38
- [SwapperName.ButterSwap]: '#FFD700',
39
- [SwapperName.ArbitrumBridge]: '#28A0F0',
40
- }
41
-
42
- export const getSwapperIcon = (swapperName: SwapperName): string | undefined => {
43
- return SWAPPER_ICONS[swapperName]
44
- }
45
-
46
- export const getSwapperColor = (swapperName: SwapperName): string => {
47
- return SWAPPER_COLORS[swapperName] ?? '#6366F1'
48
- }
@@ -1,69 +0,0 @@
1
- import type { Chain, WalletClient } from 'viem'
2
- import {
3
- arbitrum,
4
- avalanche,
5
- base,
6
- bsc,
7
- gnosis,
8
- hyperEvm,
9
- katana,
10
- mainnet,
11
- monad,
12
- optimism,
13
- plasma,
14
- polygon,
15
- } from 'viem/chains'
16
-
17
- export const VIEM_CHAINS_BY_ID: Record<number, Chain> = {
18
- 1: mainnet,
19
- 10: optimism,
20
- 56: bsc,
21
- 100: gnosis,
22
- 137: polygon,
23
- 143: monad,
24
- 999: hyperEvm,
25
- 8453: base,
26
- 9745: plasma,
27
- 42161: arbitrum,
28
- 43114: avalanche,
29
- 747474: katana,
30
- }
31
-
32
- export const addChainToWallet = async (client: WalletClient, chain: Chain): Promise<void> => {
33
- const { id, name, nativeCurrency, rpcUrls, blockExplorers } = chain
34
-
35
- await client.request({
36
- method: 'wallet_addEthereumChain',
37
- params: [
38
- {
39
- chainId: `0x${id.toString(16)}`,
40
- chainName: name,
41
- nativeCurrency,
42
- rpcUrls: rpcUrls.default.http,
43
- blockExplorerUrls: blockExplorers?.default ? [blockExplorers.default.url] : undefined,
44
- },
45
- ],
46
- })
47
- }
48
-
49
- export const switchOrAddChain = async (client: WalletClient, chainId: number): Promise<void> => {
50
- const chain = VIEM_CHAINS_BY_ID[chainId]
51
-
52
- try {
53
- await client.switchChain({ id: chainId })
54
- } catch (error) {
55
- const switchError = error as { code?: number; message?: string }
56
- const isChainNotAddedError =
57
- switchError.code === 4902 ||
58
- switchError.message?.toLowerCase().includes('unrecognized chain') ||
59
- switchError.message?.toLowerCase().includes('chain not added') ||
60
- switchError.message?.toLowerCase().includes('try adding the chain')
61
-
62
- if (isChainNotAddedError && chain) {
63
- await addChainToWallet(client, chain)
64
- await client.switchChain({ id: chainId })
65
- } else {
66
- throw error
67
- }
68
- }
69
- }
@@ -1,25 +0,0 @@
1
- import { createContext, useContext } from 'react'
2
-
3
- import type { UseBitcoinSigningResult } from '../hooks/useBitcoinSigning'
4
- import type { UseSolanaSigningResult } from '../hooks/useSolanaSigning'
5
-
6
- export type SwapWalletContextValue = {
7
- walletClient: unknown
8
- walletAddress: string | undefined
9
- effectiveReceiveAddress: string
10
- isCustomAddress: boolean
11
- customReceiveAddress: string
12
- setCustomReceiveAddress: (address: string) => void
13
- bitcoin: UseBitcoinSigningResult
14
- solana: UseSolanaSigningResult
15
- }
16
-
17
- const SwapWalletContext = createContext<SwapWalletContextValue | null>(null)
18
-
19
- export const SwapWalletProvider = SwapWalletContext.Provider
20
-
21
- export const useSwapWallet = (): SwapWalletContextValue => {
22
- const ctx = useContext(SwapWalletContext)
23
- if (!ctx) throw new Error('useSwapWallet must be used within SwapWalletProvider')
24
- return ctx
25
- }
package/src/demo/App.css DELETED
@@ -1,458 +0,0 @@
1
- * {
2
- margin: 0;
3
- padding: 0;
4
- box-sizing: border-box;
5
- }
6
-
7
- html,
8
- body,
9
- #root {
10
- width: 100%;
11
- min-height: 100vh;
12
- }
13
-
14
- .demo-app {
15
- width: 100%;
16
- min-height: 100vh;
17
- font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto,
18
- "Helvetica Neue", Arial, sans-serif;
19
- display: flex;
20
- flex-direction: column;
21
- }
22
-
23
- .demo-app.dark {
24
- --demo-bg: var(--demo-page-bg, #09090f);
25
- --demo-bg-secondary: color-mix(
26
- in srgb,
27
- var(--demo-page-bg, #09090f),
28
- white 5%
29
- );
30
- --demo-text: #ffffff;
31
- --demo-text-secondary: #a0a0b0;
32
- --demo-text-muted: #6b6b80;
33
- --demo-border: rgba(255, 255, 255, 0.08);
34
- --demo-accent: var(--demo-page-accent, #3861fb);
35
-
36
- background: var(--demo-bg);
37
- background-image: radial-gradient(
38
- ellipse 80% 50% at 50% -20%,
39
- color-mix(in srgb, var(--demo-page-accent, #3861fb), transparent 88%),
40
- transparent
41
- ),
42
- radial-gradient(
43
- ellipse 60% 40% at 80% 100%,
44
- color-mix(in srgb, var(--demo-page-accent, #6366f1), transparent 92%),
45
- transparent
46
- );
47
- color: var(--demo-text);
48
- }
49
-
50
- .demo-app.light {
51
- --demo-bg: #f5f5f7;
52
- --demo-bg-secondary: #ffffff;
53
- --demo-text: #1a1a2e;
54
- --demo-text-secondary: #5c5c70;
55
- --demo-text-muted: #9090a0;
56
- --demo-border: rgba(0, 0, 0, 0.08);
57
- --demo-accent: #3861fb;
58
-
59
- background: var(--demo-bg);
60
- color: var(--demo-text);
61
- }
62
-
63
- .demo-header {
64
- display: flex;
65
- align-items: center;
66
- justify-content: space-between;
67
- padding: 16px 24px;
68
- border-bottom: 1px solid var(--demo-border);
69
- background: var(--demo-bg-secondary);
70
- position: sticky;
71
- top: 0;
72
- z-index: 100;
73
- }
74
-
75
- .demo-logo {
76
- display: flex;
77
- align-items: center;
78
- gap: 10px;
79
- color: var(--demo-text);
80
- text-decoration: none;
81
- transition: opacity 0.15s ease;
82
- }
83
-
84
- .demo-logo:hover {
85
- opacity: 0.8;
86
- }
87
-
88
- .demo-logo-text {
89
- font-size: 17px;
90
- font-weight: 700;
91
- letter-spacing: -0.02em;
92
- }
93
-
94
- .demo-header-actions {
95
- display: flex;
96
- align-items: center;
97
- gap: 12px;
98
- }
99
-
100
- .demo-customize-btn {
101
- display: flex;
102
- align-items: center;
103
- gap: 6px;
104
- padding: 10px 14px;
105
- border: 1px solid var(--demo-border);
106
- border-radius: 12px;
107
- background: transparent;
108
- color: var(--demo-text-secondary);
109
- font-size: 13px;
110
- font-weight: 500;
111
- cursor: pointer;
112
- transition: all 0.15s ease;
113
- }
114
-
115
- .demo-customize-btn:hover {
116
- border-color: var(--demo-accent);
117
- color: var(--demo-text);
118
- }
119
-
120
- .demo-main {
121
- flex: 1;
122
- display: flex;
123
- flex-direction: column;
124
- align-items: center;
125
- padding: 48px 24px;
126
- }
127
-
128
- .demo-content {
129
- width: 100%;
130
- max-width: 1100px;
131
- display: flex;
132
- flex-direction: column;
133
- align-items: center;
134
- gap: 40px;
135
- }
136
-
137
- .demo-hero {
138
- text-align: center;
139
- max-width: 500px;
140
- }
141
-
142
- .demo-title {
143
- font-size: 42px;
144
- font-weight: 700;
145
- letter-spacing: -0.03em;
146
- margin-bottom: 12px;
147
- color: var(--demo-accent);
148
- }
149
-
150
- .demo-subtitle {
151
- font-size: 16px;
152
- color: var(--demo-text-secondary);
153
- line-height: 1.5;
154
- }
155
-
156
- .demo-layout {
157
- display: flex;
158
- gap: 24px;
159
- align-items: flex-start;
160
- justify-content: center;
161
- width: 100%;
162
- }
163
-
164
- .demo-customizer {
165
- width: 280px;
166
- padding: 20px;
167
- background: var(--demo-bg-secondary);
168
- border: 1px solid var(--demo-border);
169
- border-radius: 16px;
170
- flex-shrink: 0;
171
- }
172
-
173
- .demo-customizer-title {
174
- font-size: 15px;
175
- font-weight: 600;
176
- color: var(--demo-text);
177
- margin-bottom: 20px;
178
- }
179
-
180
- .demo-customizer-section {
181
- margin-bottom: 20px;
182
- }
183
-
184
- .demo-customizer-section:last-child {
185
- margin-bottom: 0;
186
- }
187
-
188
- .demo-customizer-label {
189
- display: block;
190
- font-size: 12px;
191
- font-weight: 500;
192
- color: var(--demo-text-muted);
193
- text-transform: uppercase;
194
- letter-spacing: 0.05em;
195
- margin-bottom: 10px;
196
- }
197
-
198
- .demo-theme-toggle {
199
- display: flex;
200
- gap: 8px;
201
- }
202
-
203
- .demo-theme-btn {
204
- flex: 1;
205
- display: flex;
206
- align-items: center;
207
- justify-content: center;
208
- gap: 6px;
209
- padding: 10px;
210
- border: 1px solid var(--demo-border);
211
- border-radius: 10px;
212
- background: transparent;
213
- color: var(--demo-text-secondary);
214
- font-size: 13px;
215
- font-weight: 500;
216
- cursor: pointer;
217
- transition: all 0.15s ease;
218
- }
219
-
220
- .demo-theme-btn:hover {
221
- border-color: var(--demo-text-muted);
222
- }
223
-
224
- .demo-theme-btn.active {
225
- border-color: var(--demo-accent);
226
- background: color-mix(in srgb, var(--demo-accent), transparent 90%);
227
- color: var(--demo-accent);
228
- }
229
-
230
- .demo-color-grid {
231
- display: grid;
232
- grid-template-columns: repeat(6, 1fr);
233
- gap: 8px;
234
- }
235
-
236
- .demo-color-btn {
237
- width: 100%;
238
- aspect-ratio: 1;
239
- border: 2px solid transparent;
240
- border-radius: 8px;
241
- cursor: pointer;
242
- transition: all 0.15s ease;
243
- }
244
-
245
- .demo-color-btn:hover {
246
- transform: scale(1.1);
247
- }
248
-
249
- .demo-color-btn.active {
250
- border-color: var(--demo-text);
251
- box-shadow: 0 0 0 2px var(--demo-bg);
252
- }
253
-
254
- .demo-preset-grid {
255
- display: grid;
256
- grid-template-columns: repeat(3, 1fr);
257
- gap: 8px;
258
- }
259
-
260
- .demo-preset-btn {
261
- display: flex;
262
- flex-direction: column;
263
- align-items: center;
264
- gap: 6px;
265
- padding: 8px;
266
- border: 1px solid var(--demo-border);
267
- border-radius: 10px;
268
- background: transparent;
269
- cursor: pointer;
270
- transition: all 0.15s ease;
271
- }
272
-
273
- .demo-preset-btn:hover {
274
- border-color: var(--demo-accent);
275
- transform: translateY(-1px);
276
- }
277
-
278
- .demo-preset-preview {
279
- width: 100%;
280
- aspect-ratio: 1.2;
281
- border-radius: 6px;
282
- position: relative;
283
- overflow: hidden;
284
- }
285
-
286
- .demo-preset-card {
287
- position: absolute;
288
- inset: 20%;
289
- border-radius: 4px;
290
- }
291
-
292
- .demo-preset-accent {
293
- position: absolute;
294
- bottom: 15%;
295
- left: 25%;
296
- right: 25%;
297
- height: 12%;
298
- border-radius: 2px;
299
- }
300
-
301
- .demo-preset-name {
302
- font-size: 10px;
303
- font-weight: 500;
304
- color: var(--demo-text-secondary);
305
- }
306
-
307
- .demo-color-input-row {
308
- display: flex;
309
- gap: 8px;
310
- align-items: center;
311
- }
312
-
313
- .demo-color-picker {
314
- width: 40px;
315
- height: 40px;
316
- padding: 0;
317
- border: 1px solid var(--demo-border);
318
- border-radius: 8px;
319
- cursor: pointer;
320
- background: transparent;
321
- }
322
-
323
- .demo-color-picker::-webkit-color-swatch-wrapper {
324
- padding: 2px;
325
- }
326
-
327
- .demo-color-picker::-webkit-color-swatch {
328
- border-radius: 6px;
329
- border: none;
330
- }
331
-
332
- .demo-color-text {
333
- flex: 1;
334
- padding: 10px 12px;
335
- border: 1px solid var(--demo-border);
336
- border-radius: 8px;
337
- background: var(--demo-bg);
338
- color: var(--demo-text);
339
- font-size: 13px;
340
- font-family: monospace;
341
- }
342
-
343
- .demo-color-text:focus {
344
- outline: none;
345
- border-color: var(--demo-accent);
346
- }
347
-
348
- .demo-range-input {
349
- flex: 1;
350
- height: 4px;
351
- accent-color: var(--demo-accent);
352
- cursor: pointer;
353
- }
354
-
355
- .demo-copy-btn {
356
- display: flex;
357
- align-items: center;
358
- justify-content: center;
359
- gap: 8px;
360
- width: 100%;
361
- padding: 12px 16px;
362
- border: 1px solid var(--demo-accent);
363
- border-radius: 10px;
364
- background: color-mix(in srgb, var(--demo-accent), transparent 90%);
365
- color: var(--demo-accent);
366
- font-size: 13px;
367
- font-weight: 600;
368
- cursor: pointer;
369
- transition: all 0.15s ease;
370
- }
371
-
372
- .demo-copy-btn:hover {
373
- background: color-mix(in srgb, var(--demo-accent), transparent 80%);
374
- }
375
-
376
- .demo-copy-btn:active {
377
- transform: scale(0.98);
378
- }
379
-
380
- .demo-connection-info {
381
- display: flex;
382
- flex-direction: column;
383
- gap: 6px;
384
- }
385
-
386
- .demo-connected-badge {
387
- display: inline-flex;
388
- align-items: center;
389
- padding: 4px 8px;
390
- background: rgba(16, 185, 129, 0.1);
391
- color: #10b981;
392
- border-radius: 6px;
393
- font-size: 12px;
394
- font-weight: 500;
395
- width: fit-content;
396
- }
397
-
398
- .demo-address {
399
- font-size: 13px;
400
- color: var(--demo-text-secondary);
401
- font-family: monospace;
402
- }
403
-
404
- .demo-disconnected {
405
- font-size: 13px;
406
- color: var(--demo-text-muted);
407
- }
408
-
409
- .demo-widget-container {
410
- display: flex;
411
- justify-content: center;
412
- }
413
-
414
- .demo-footer {
415
- padding: 20px;
416
- text-align: center;
417
- border-top: 1px solid var(--demo-border);
418
- color: var(--demo-text-muted);
419
- font-size: 13px;
420
- }
421
-
422
- @media (max-width: 768px) {
423
- .demo-header {
424
- padding: 12px 16px;
425
- flex-wrap: wrap;
426
- gap: 12px;
427
- }
428
-
429
- .demo-customize-btn span {
430
- display: none;
431
- }
432
-
433
- .demo-customize-btn {
434
- padding: 10px;
435
- }
436
-
437
- .demo-title {
438
- font-size: 32px;
439
- }
440
-
441
- .demo-subtitle {
442
- font-size: 14px;
443
- }
444
-
445
- .demo-layout {
446
- flex-direction: column;
447
- align-items: center;
448
- }
449
-
450
- .demo-customizer {
451
- width: 100%;
452
- max-width: 420px;
453
- }
454
-
455
- .demo-main {
456
- padding: 32px 16px;
457
- }
458
- }