diff --git a/public/images/Wallet/Features/earn.png b/public/images/Wallet/Features/earn.png new file mode 100644 index 00000000..336d9feb Binary files /dev/null and b/public/images/Wallet/Features/earn.png differ diff --git a/public/images/Wallet/Features/optimise.png b/public/images/Wallet/Features/optimise.png new file mode 100644 index 00000000..74f5f088 Binary files /dev/null and b/public/images/Wallet/Features/optimise.png differ diff --git a/public/images/Wallet/Features/safe-apps.png b/public/images/Wallet/Features/safe-apps.png new file mode 100644 index 00000000..f2b71847 Binary files /dev/null and b/public/images/Wallet/Features/safe-apps.png differ diff --git a/public/images/Wallet/Features/trade.png b/public/images/Wallet/Features/trade.png new file mode 100644 index 00000000..dbd42e4f Binary files /dev/null and b/public/images/Wallet/Features/trade.png differ diff --git a/src/components/Wallet/FeatureCards/index.tsx b/src/components/Wallet/FeatureCards/index.tsx new file mode 100644 index 00000000..8d4d5074 --- /dev/null +++ b/src/components/Wallet/FeatureCards/index.tsx @@ -0,0 +1,110 @@ +import { Button, Container, Grid, Typography } from '@mui/material' +import LinkButton from '@/components/common/LinkButton' +import { WALLET_LINK } from '@/config/constants' +import type { BaseBlock } from '@/components/Home/types' +import layoutCss from '@/components/common/styles.module.css' +import css from './styles.module.css' + +const CardContent = ({ caption, title, text, link }: Partial) => ( +
+ + {caption} + + + + {title} + + + {text} + + {link ? ( + + {link.title} + + ) : undefined} +
+) + +type FeatureCardsProps = Omit & { + items: Array & { isNew: boolean; fullWidth: boolean }> +} + +const FeatureCards = ({ title, text, items = [] }: FeatureCardsProps) => { + // extract the last item from the array + const lastItem = items[items.length - 1] + const restItems = items.slice(0, -1) + + return ( + + + + {title} + + + + {text} + + + + + {restItems.map((item, index) => { + if (item.fullWidth) { + return ( + +
+ {item.isNew &&
New
} + + + + {item.image?.alt} + + + + + + +
+
+ ) + } + + return ( + +
+ {item.isNew &&
New
} + + {item.image?.alt} + + +
+
+ ) + })} + + {/* last item is part of the component */} + {lastItem && ( + +
+ {lastItem.image?.alt} + +
+ +
+
+
+ )} +
+ +
+ + Read to have a {`Safe{Wallet}`}? + + +
+
+ ) +} + +export default FeatureCards diff --git a/src/components/Wallet/FeatureCards/styles.module.css b/src/components/Wallet/FeatureCards/styles.module.css new file mode 100644 index 00000000..beae6b80 --- /dev/null +++ b/src/components/Wallet/FeatureCards/styles.module.css @@ -0,0 +1,101 @@ +.card { + background: var(--mui-palette-border-background); + box-shadow: inset 0 0 0 1px var(--mui-palette-border-light); + border-radius: 16px; + padding: 40px; + display: flex; + flex-direction: column; + align-items: flex-start; + gap: 40px; + position: relative; + transition: var(--transition-duration); +} + +.newBadge { + font-size: 12px; + line-height: 14px; + position: absolute; + top: 40px; + right: 40px; + background-color: #b0ffc9; + color: var(--mui-palette-text-dark); + border-radius: 4px; + width: 45px; + height: 24px; + display: flex; + align-items: center; + justify-content: center; +} + +.lastCard { + padding: 0; +} + +.lastCard .cardContent { + padding: 40px; + max-width: 516px; +} + +.image { + height: 100%; +} + +.cardContent { + display: flex; + flex-direction: column; + align-items: flex-start; + gap: 16px; +} + +.caption { + background-image: linear-gradient(260.13deg, #12ff80 1.24%, #5fddff 102.14%); + background-clip: text; + color: transparent; +} + +.stacked { + display: flex; + flex-direction: column; + gap: 16px; +} + +.stacked .image { + height: 170px; + margin: 0 auto; +} + +.cta { + margin-top: 100px; + display: flex; + flex-direction: column; + align-items: center; + gap: 32px; +} + +@media (min-width: 900px) { + .card { + height: 400px; + flex-direction: row; + } + + .stacked { + display: flex; + flex-direction: column; + gap: 16px; + } + + .fullWidth { + width: 100%; + } + + .fullWidth .title { + font-size: 48px; + line-height: 56px; + } + + .centerContent { + height: 100%; + display: flex; + align-items: center; + } +} diff --git a/src/components/Wallet/VerticalSlide/styles.module.css b/src/components/Wallet/VerticalSlide/styles.module.css index 9fc3b8bc..53baa4cb 100644 --- a/src/components/Wallet/VerticalSlide/styles.module.css +++ b/src/components/Wallet/VerticalSlide/styles.module.css @@ -1,7 +1,7 @@ .title { text-align: center; max-width: 650px; - margin-bottom: 48px; + margin: 0 auto 48px; } .image { diff --git a/src/content/wallet.json b/src/content/wallet.json index 658e7f7b..a142a43b 100644 --- a/src/content/wallet.json +++ b/src/content/wallet.json @@ -160,6 +160,57 @@ } ] }, + { + "component": "Wallet/FeatureCards", + "title": "More features beyond multisigs", + "text": "Safe is more than just secure asset storage. It's your entry point to onchain activities.", + "items": [ + { + "isNew": true, + "fullWidth": true, + "caption": "Trade seamlessly", + "title": "Swap like a pro", + "text": "with MEV protection and security, ensuring your intent-based transactions will not fail.", + "image": { + "src": "/images/Wallet/Features/trade.png", + "alt": "Token swap modal" + } + }, + { + "caption": "Optimize", + "title": "Batch transactions", + "text": "To save gas and to avoid losing time gathering signatures from everyone.", + "image": { + "src": "/images/Wallet/Features/optimise.png", + "alt": "Token swap modal" + } + }, + { + "isNew": true, + "caption": "Earn", + "title": "Stake ETH Securely", + "text": "Stake directly from your Safe{Wallet} with robust multisig security.", + "image": { + "src": "/images/Wallet/Features/earn.png", + "alt": "Token swap modal" + } + }, + { + "caption": "All-in-one", + "title": "Explore Safe Apps", + "text": "Swapping, staking, NFTs, identity and more. Interact with 200+ apps integrated with Safe.", + "link": { + "title": "View ecosystem projects", + "href": "https://safe.global/ecosystem", + "variant": "link" + }, + "image": { + "src": "/images/Wallet/Features/safe-apps.png", + "alt": "Safe Apps logos" + } + } + ] + }, { "title": "Introducing
Native Swaps", "caption": "New feature",