From 643ac2d94ce10362f41443a1f2ceeea31edd5222 Mon Sep 17 00:00:00 2001 From: Rodolfo Hansen Date: Wed, 4 Mar 2026 00:09:53 +0100 Subject: [PATCH 1/9] Remove founder NFT purchase UI, keep informational pages Remove the Counter and NFTButton (mint/payment) components from the founder sale page, rename FounderSale to FounderCards, and update copy from "Mint Now!" to "Learn More". The NFT slider, details, and info modal remain intact. Co-Authored-By: Claude Opus 4.6 --- dictionary.txt | 1 + public/index.html | 3 - src/assets/icons/minus.svg | 3 - src/assets/icons/plus.svg | 3 - src/components/App.tsx | 4 +- src/components/founder-sale/Counter.tsx | 123 ------------------ src/components/founder-sale/NFTButton.tsx | 83 ------------ src/data/texts.ts | 6 +- .../{FounderSale.tsx => FounderCards.tsx} | 36 +---- 9 files changed, 11 insertions(+), 251 deletions(-) delete mode 100644 src/assets/icons/minus.svg delete mode 100644 src/assets/icons/plus.svg delete mode 100644 src/components/founder-sale/Counter.tsx delete mode 100644 src/components/founder-sale/NFTButton.tsx rename src/pages/{FounderSale.tsx => FounderCards.tsx} (68%) diff --git a/dictionary.txt b/dictionary.txt index 25707ea..6fcbb17 100644 --- a/dictionary.txt +++ b/dictionary.txt @@ -401,6 +401,7 @@ FounderModalContent isFounderModalOpen setIsFounderModalOpen FounderSale +FounderCards founderWelcomeHeroCard MobileHeaderFounders HeaderFounders diff --git a/public/index.html b/public/index.html index c04dc4b..4ea3261 100644 --- a/public/index.html +++ b/public/index.html @@ -10,9 +10,6 @@ - - - diff --git a/src/assets/icons/minus.svg b/src/assets/icons/minus.svg deleted file mode 100644 index 9989d9a..0000000 --- a/src/assets/icons/minus.svg +++ /dev/null @@ -1,3 +0,0 @@ - - - diff --git a/src/assets/icons/plus.svg b/src/assets/icons/plus.svg deleted file mode 100644 index de301bb..0000000 --- a/src/assets/icons/plus.svg +++ /dev/null @@ -1,3 +0,0 @@ - - - diff --git a/src/components/App.tsx b/src/components/App.tsx index 4640522..b873032 100644 --- a/src/components/App.tsx +++ b/src/components/App.tsx @@ -2,7 +2,7 @@ import { lazy, Suspense } from 'react'; import { BrowserRouter as Router, Route, Routes } from 'react-router-dom'; const Index = lazy(() => import('../pages/Index')); -const FounderSale = lazy(() => import('../pages/FounderSale')); +const FounderCards = lazy(() => import('../pages/FounderCards')); const NotFoundPage = lazy(() => import('../pages/NotFoundPage')); const App = () => ( @@ -10,7 +10,7 @@ const App = () => ( Loading...}> } /> - } /> + } /> } /> diff --git a/src/components/founder-sale/Counter.tsx b/src/components/founder-sale/Counter.tsx deleted file mode 100644 index d501808..0000000 --- a/src/components/founder-sale/Counter.tsx +++ /dev/null @@ -1,123 +0,0 @@ -import { useMediaQuery } from '@mui/material'; -import { maxWidth840 } from 'components/rwd/detectMobile'; -import React, { ChangeEvent } from 'react'; -import styled from 'styled-components'; - -import { colors } from 'theme'; - -import { ReactComponent as PlusIcon } from '../../assets/icons/plus.svg'; -import { ReactComponent as MinusIcon } from '../../assets/icons/minus.svg'; - -interface Props { - value: number; - handleIncrement: () => void; - handleDecrement: () => void; - handleChange: (e: ChangeEvent) => void; -} - -export const Counter = React.memo(({ value, handleIncrement, handleDecrement, handleChange }: Props) => { - const isTablet = useMediaQuery(maxWidth840); - - return ( - - - Amount: - - - {isTablet && ( - - )} - - {!isTablet && ( - - )} - - - - ); -}); - -const CounterContainer = styled.div` - display: flex; - gap: 12px; - align-items: center; - - @media (max-width: 840px) { - flex-direction: column; - } -`; - -const StyledLabel = styled.span` - color: ${colors.textTertiary600}; - font-size: 1.5rem; - font-weight: 500; - - transition: 0.5s; - - @media (max-width: 640px) { - font-size: 1rem; - } -`; - -const NumberInput = styled.input` - width: 200px; - height: 56px; - text-align: center; - font-size: 16px; - border: 1px solid #fff; - border-radius: 24px; - background-color: white; - color: ${colors.textTertiary600}; - font-size: 24px; - outline: none; - -moz-appearance: textfield; /* Remove Firefox arrows */ - - ::-webkit-outer-spin-button, - ::-webkit-inner-spin-button { - -webkit-appearance: none; /* Remove Chrome arrows */ - margin: 0; - } - - @media (max-width: 640px) { - height: 42px; - font-size: 18px; - } -`; - -const InputContainer = styled.div` - display: flex; - align-items: center; - gap: 12px; -`; - -const Button = styled.button<{ disabled: boolean }>` - width: 56px; - height: 56px; - border-radius: 50%; - border: 1px solid #ccc; - background-color: ${props => (props.disabled ? 'rgba(255,255,255,0.7)' : 'white')}; - color: black; - opacity: ${props => (props.disabled ? '0.5' : '1')}; - font-size: 32px; - cursor: ${props => (props.disabled ? 'not-allowed' : 'pointer')}; - display: flex; - align-items: center; - justify-content: center; - - @media (max-width: 640px) { - height: 42px; - width: 42px; - } -`; diff --git a/src/components/founder-sale/NFTButton.tsx b/src/components/founder-sale/NFTButton.tsx deleted file mode 100644 index a7905cd..0000000 --- a/src/components/founder-sale/NFTButton.tsx +++ /dev/null @@ -1,83 +0,0 @@ -import { motion } from 'framer-motion'; -import styled from 'styled-components'; - -import { colors } from 'theme'; -import { transition, transformVariant } from 'constants/motionConfig'; - -interface Props { - value: number; -} - -export const NFTButton = ({ value }: Props) => ( - openPaymentWindow(value)} - > - {`Mint ${value} Fida Founder’s NFT${plural(value)} (${countAda(value)} ADA)`} - -); - -const GradientButton = styled(motion.button)` - margin-bottom: 40px; - border: 1px solid ${colors.blue}; - background: ${colors.backgroundGradient}; - color: white; - font-size: 18px; - font-weight: 700; - padding: 10px 20px; - cursor: pointer; - border-radius: 24px; - outline: none; - height: 60px; - width: 365px; - transition: 0.5s; - - &:hover { - opacity: 0.8; - } - - &:focus { - outline: none; - } - - &:active { - opacity: 0.8; - } - - @media (max-width: 840px) { - width: 90%; - font-size: 16px; - } -`; - -const plural = (count: number) => ((1 * count) === 1 ? '' : 's'); - -const countAda = (count: number) => (count * 300) - ((count - 1) * 30); - -const openPaymentWindow = (value: number) => { - const paymentUrl = `https://pay.nmkr.io/?p=1fe458e78a46451fb812b36ab3fa6f82&c=${value}`; - - const popupWidth = 500; - const popupHeight = 700; - - const wtop = window.top ?? { outerWidth: 400, outerHeight: 400, screenX: 800, screenY: 800 }; - const left = wtop.outerWidth / 2 + wtop.screenX - (popupWidth / 2); - const top = wtop.outerHeight / 2 + wtop.screenY - (popupHeight / 2); - - const popup = window.open(paymentUrl, 'NFT-MAKER PRO Payment Gateway', `popup=1, location=1, width=${popupWidth}, height=${popupHeight}, left=${left}, top=${top}`); - - document.body.style.cssText = 'background: rgba(0, 0, 0, 0.5)'; - - const backgroundCheck = setInterval(() => { - if (popup?.closed) { - clearInterval(backgroundCheck); - // eslint-disable-next-line no-console - console.log('Popup closed'); - - document.body.style.cssText = ''; - } - }, 1000); -}; diff --git a/src/data/texts.ts b/src/data/texts.ts index e246e06..50566c5 100644 --- a/src/data/texts.ts +++ b/src/data/texts.ts @@ -20,10 +20,10 @@ const welcomeHeroCard = { }; const founderWelcomeHeroCard = { - description: 'Mint a Founder\'s NFT to gain early adopter\'s access to the decentralized insurance marketplace.', - title: 'Fida Founder\'s NFT Collection Mint', + description: 'Explore the Founder\'s NFT collection for early adopter\'s access to the decentralized insurance marketplace.', + title: 'Fida Founder\'s NFT Collection', button: { - label: 'Mint Now!', + label: 'Learn More', link: 'founder-sale', } }; diff --git a/src/pages/FounderSale.tsx b/src/pages/FounderCards.tsx similarity index 68% rename from src/pages/FounderSale.tsx rename to src/pages/FounderCards.tsx index 4956af5..7a02bcb 100644 --- a/src/pages/FounderSale.tsx +++ b/src/pages/FounderCards.tsx @@ -1,4 +1,4 @@ -import { ChangeEvent, lazy, Suspense, useEffect, useState } from 'react'; +import { lazy, Suspense, useEffect, useState } from 'react'; import styled from 'styled-components'; import { colors } from 'theme'; @@ -7,19 +7,16 @@ import { Skeleton } from '@mui/material'; import Footer from '../components/sections/Footer'; import { Text } from '../components/_common/Text'; import { Container } from '../components/_common/Container'; -import { Counter } from '../components/founder-sale/Counter'; -import { NFTButton } from '../components/founder-sale/NFTButton'; import backgroundImage from '../assets/images/background-pattern.png'; import { NFTSlider } from '../components/founder-sale/NFTSlider'; -// import { NFTDetails } from '../components/founder-sale/NFTDetails'; import { maxWidth840 } from '../components/rwd/detectMobile'; import { FounderModal } from '../components/founder-sale/modal/FounderModal'; import { HeaderFounders } from '../components/HeaderFounders'; const NFTDetails = lazy(() => import('../components/founder-sale/NFTDetails')); -const FounderSale = () => { +const FounderCards = () => { const [isFounderModalOpen, setIsFounderModalOpen] = useState(false); useEffect(() => { setTimeout(() => setIsFounderModalOpen(true), 5000); }, []); @@ -28,38 +25,15 @@ const FounderSale = () => { query: maxWidth840, }); - const [value, setValue] = useState(1); - - const handleIncrement = () => { - if (value < 5) { - setValue(value + 1); - } - }; - - const handleDecrement = () => { - if (value > 1) { - setValue(value - 1); - } - }; - - const handleChange = (e: ChangeEvent) => { - const newValue = parseInt(e.target.value, 10); - if (newValue >= 1 && newValue <= 5) { - setValue(newValue); - } - }; - return ( <> setIsFounderModalOpen(true)} /> - {'Fida Founder\'s NFT Collection Mint'.toUpperCase()} - + {'Fida Founder\'s NFT Collection'.toUpperCase()} + - - }> @@ -72,7 +46,7 @@ const FounderSale = () => { ); }; -export default FounderSale; +export default FounderCards; const FounderContainer = styled.div` align-items: center; From dc1ceb02177956912ae863e742bc86a8a47d4ee7 Mon Sep 17 00:00:00 2001 From: Rodolfo Hansen Date: Wed, 4 Mar 2026 00:17:51 +0100 Subject: [PATCH 2/9] Replace founder modal popup with inline benefits sections Convert the modal content (5 benefit cards with cover images) into an inline FounderBenefits component rendered directly on the page. The header "Learn more" button now scrolls to the benefits section instead of opening a popup. Delete the modal components. Co-Authored-By: Claude Opus 4.6 --- dictionary.txt | 12 ++ src/components/HeaderFounders.tsx | 8 +- .../founder-sale/FounderBenefits.tsx | 146 +++++++++++++ .../founder-sale/modal/FounderModal.tsx | 96 --------- .../modal/FounderModalContent.tsx | 200 ------------------ src/components/founder-sale/modal/styles.css | 132 ------------ .../rwd/FoundersHeaderMenuMobile.tsx | 6 +- src/components/rwd/MobileHeaderFounders.tsx | 6 +- src/pages/FounderCards.tsx | 44 ++-- 9 files changed, 189 insertions(+), 461 deletions(-) create mode 100644 src/components/founder-sale/FounderBenefits.tsx delete mode 100644 src/components/founder-sale/modal/FounderModal.tsx delete mode 100644 src/components/founder-sale/modal/FounderModalContent.tsx delete mode 100644 src/components/founder-sale/modal/styles.css diff --git a/dictionary.txt b/dictionary.txt index 6fcbb17..a411738 100644 --- a/dictionary.txt +++ b/dictionary.txt @@ -402,6 +402,18 @@ isFounderModalOpen setIsFounderModalOpen FounderSale FounderCards +FounderBenefits +BenefitCard +BenefitContent +BenefitDescription +BenefitImage +BenefitTitle +BenefitsSection +handleLearnMore +BenefitStep +handleScrollToBenefits +StyledMenuModalButton +isSlg founderWelcomeHeroCard MobileHeaderFounders HeaderFounders diff --git a/src/components/HeaderFounders.tsx b/src/components/HeaderFounders.tsx index 10ec1dc..cb63a03 100644 --- a/src/components/HeaderFounders.tsx +++ b/src/components/HeaderFounders.tsx @@ -9,10 +9,10 @@ import { MobileHeaderFounders } from './rwd/MobileHeaderFounders'; import { StyledMenuMainButton, StyledMenuModalButton } from './StyledFoundersNavButtons'; interface Props { - handleOpenModal: () => void; + handleLearnMore: () => void; } -export const HeaderFounders = ({ handleOpenModal }: Props) => { +export const HeaderFounders = ({ handleLearnMore }: Props) => { const navigate = useNavigate(); const isTablet = useMediaQuery({ @@ -27,10 +27,10 @@ export const HeaderFounders = ({ handleOpenModal }: Props) => { {isTablet ? ( - + ) : (
- {isSlg ? 'Learn more' : 'Learn more about Fida NFT Collection'} + {isSlg ? 'Learn more' : 'Learn more about Fida NFT Collection'} navigate('/')}> Discover FIDA diff --git a/src/components/founder-sale/FounderBenefits.tsx b/src/components/founder-sale/FounderBenefits.tsx new file mode 100644 index 0000000..de4b57c --- /dev/null +++ b/src/components/founder-sale/FounderBenefits.tsx @@ -0,0 +1,146 @@ +import styled from 'styled-components'; +import { useMediaQuery } from 'react-responsive'; +import { motion } from 'framer-motion'; + +import { colors } from 'theme'; +import { transition, transformVariant } from 'constants/motionConfig'; +import { maxWidth640, maxWidth840 } from 'components/rwd/detectMobile'; + +import cover1 from '../../assets/images/nft-modal/cover-1.png'; +import cover1mobile from '../../assets/images/nft-modal/cover-1-mobile.png'; +import cover2 from '../../assets/images/nft-modal/cover-2.png'; +import cover2mobile from '../../assets/images/nft-modal/cover-2-mobile.png'; +import cover3 from '../../assets/images/nft-modal/cover-3.png'; +import cover3mobile from '../../assets/images/nft-modal/cover-3-mobile.png'; +import cover4 from '../../assets/images/nft-modal/cover-4.png'; +import cover4mobile from '../../assets/images/nft-modal/cover-4-mobile.png'; +import cover5 from '../../assets/images/nft-modal/cover-5.png'; +import cover5mobile from '../../assets/images/nft-modal/cover-5-mobile.png'; + +interface BenefitStep { + title: string; + description: string; + src: string; +} + +const steps = (isMobile: boolean): BenefitStep[] => ([ + { + title: 'Benefits of the Fida Founders NFT Collection', + description: 'The Fida Founders NFT Collection offers a range of exclusive benefits that set it apart from other NFT collections. This collection is not just about digital art, or the historic introduction of global decentralized insurance, but a utility token within the Fida ecosystem. Here are the benefits we\'re currently planning for the token', + src: isMobile ? cover1mobile : cover1 + }, + { + title: 'Early Access to the Fida System', + description: 'As a holder of the Fida Founders NFT, you will be invited to the private testnet. This early access allows you to familiarize yourself with the platform, navigate its features, and most importantly influence its development through feature requests and user experience suggestions.', + src: isMobile ? cover2mobile : cover2 + }, + { + title: 'First Choice of Policies', + description: 'As an investor possessing a Fida Founders NFT will grant you access to an initial early commitment round to each policy brought onboard. This priority access means you can optimize your portfolio, with the risk profile and diversification that best suits your investment strategy. Early selection can be crucial in ensuring your proportion of the most desirable policies, especially those that might be limited in availability or have particularly favorable conditions.', + src: isMobile ? cover3mobile : cover3 + }, + { + title: 'Priority Listings', + description: 'As an insurer or broker holding a Fida Founders NFT your policies will be highlighted as founder\'s policy. In a competitive environment where other brokers are competing for investment a founding member\'s tag can significantly impact outcomes, raising the odds of getting your policy filled and offering a substantial edge.', + src: isMobile ? cover4mobile : cover4 + }, + { + title: 'Fee Discounts', + description: 'One of the certain advantages of the Fida Founders NFT is the entitlement to fee discounts. Listing fees, trading fees, and other charges within the Fida ecosystem will be discounted to holders of the Fida Founders Collection. As an NFT holder, you benefit from reduced fees, allowing you to trade effectively, and potentially increase your net gains. This financial incentive is designed to reward early supporters and encourage continued engagement with the platform.', + src: isMobile ? cover5mobile : cover5 + }, +]); + +export const FounderBenefits = () => { + const isMobile = useMediaQuery({ query: maxWidth640 }); + const isTablet = useMediaQuery({ query: maxWidth840 }); + + return ( + + {steps(isMobile).map((step, index) => ( + + + + {step.title} + {step.description} + + + ))} + + ); +}; + +const BenefitsSection = styled.div` + display: flex; + flex-direction: column; + gap: 64px; + width: 100%; + padding: 48px 0; + + @media (max-width: 840px) { + gap: 40px; + padding: 24px 16px; + } +`; + +const BenefitCard = styled(motion.div)<{ $reversed: boolean; $isTablet: boolean }>` + display: flex; + flex-direction: ${({ $reversed, $isTablet }) => ($isTablet ? 'column' : ($reversed ? 'row-reverse' : 'row'))}; + align-items: center; + gap: 48px; + + @media (max-width: 840px) { + gap: 24px; + } +`; + +const BenefitImage = styled.img` + width: 50%; + max-width: 400px; + border-radius: 24px; + object-fit: cover; + + @media (max-width: 840px) { + width: 100%; + max-width: 100%; + } +`; + +const BenefitContent = styled.div` + display: flex; + flex-direction: column; + gap: 16px; + flex: 1; +`; + +const BenefitTitle = styled.h3` + font-weight: 700; + font-size: 28px; + line-height: 36px; + color: ${colors.textPrimaryOnBrand}; + + @media (max-width: 640px) { + font-size: 22px; + line-height: 28px; + } +`; + +const BenefitDescription = styled.p` + font-weight: 500; + font-size: 18px; + line-height: 28px; + color: ${colors.textTertiary600}; + + @media (max-width: 640px) { + font-size: 15px; + line-height: 24px; + } +`; diff --git a/src/components/founder-sale/modal/FounderModal.tsx b/src/components/founder-sale/modal/FounderModal.tsx deleted file mode 100644 index f8df626..0000000 --- a/src/components/founder-sale/modal/FounderModal.tsx +++ /dev/null @@ -1,96 +0,0 @@ -import Backdrop from '@mui/material/Backdrop'; -import Modal from '@mui/material/Modal'; -import Fade from '@mui/material/Fade'; -import styled from 'styled-components'; -import { FounderModalContent } from './FounderModalContent'; - -interface Props { - isOpen: boolean; - handleClose: () => void; -} - -export const FounderModal = ({ isOpen, handleClose }: Props) => ( -
- { if (reason !== 'backdropClick') handleClose(); }} - closeAfterTransition - sx={{ - '.MuiBackdrop-root': { - backdropFilter: 'blur(4px)' - } - }} - slots={{ backdrop: Backdrop }} - slotProps={{ - backdrop: { - timeout: 500, - }, - }} - > - - - - X - - - -
-); - -const Container = styled.div` - position: absolute; - top: 50%; - left: 50%; - transform: translate(-50%, -50%); - max-width: 861px; - height: 70%; - min-height: 690px; - overflow: auto; - background-color: white; - border: 1px solid #000; - box-shadow: 24; - padding: 16px; - outline: none; - border-radius: 24px; - - @media (max-width: 1900px) and (max-height: 1037px) { - height: 90%; - } - - @media (min-height: 1037px) { - height: 70%; - } - - @media (min-height: 1400px) { - height: 40%; - } - - @media (max-width: 860px) { - max-width: 100%; - } - `; - -const CloseButton = styled.button` - position: absolute; - top: 30px; - right: 30px; - display: flex; - justify-content: center; - align-items: center; - width: 56px; - height: 56px; - border-radius: 100%; - border: none; - outline: none; - background-color: rgba(255,255,255,0.2); - color: white; - font-size: 18px; - z-index: 10; - cursor: pointer; - backdrop-filter: blur(8px); - - @media (max-width: 860px) { - width: 40px; - height: 40px; - } -`; diff --git a/src/components/founder-sale/modal/FounderModalContent.tsx b/src/components/founder-sale/modal/FounderModalContent.tsx deleted file mode 100644 index 8ce1fe1..0000000 --- a/src/components/founder-sale/modal/FounderModalContent.tsx +++ /dev/null @@ -1,200 +0,0 @@ -import { Swiper, SwiperSlide } from 'swiper/react'; -import { useEffect, useState } from 'react'; - -import 'swiper/css'; -import 'swiper/css/pagination'; - -import './styles.css'; - -import { Pagination, Navigation } from 'swiper/modules'; -import styled from 'styled-components'; -import { Swiper as SwiperCore } from 'swiper/types'; - -import { useMediaQuery } from 'react-responsive'; -import { maxWidth640 } from 'components/rwd/detectMobile'; - -import cover1 from '../../../assets/images/nft-modal/cover-1.png'; -import cover1mobile from '../../../assets/images/nft-modal/cover-1-mobile.png'; -import cover2 from '../../../assets/images/nft-modal/cover-2.png'; -import cover2mobile from '../../../assets/images/nft-modal/cover-2-mobile.png'; -import cover3 from '../../../assets/images/nft-modal/cover-3.png'; -import cover3mobile from '../../../assets/images/nft-modal/cover-3-mobile.png'; -import cover4 from '../../../assets/images/nft-modal/cover-4.png'; -import cover4mobile from '../../../assets/images/nft-modal/cover-4-mobile.png'; -import cover5 from '../../../assets/images/nft-modal/cover-5.png'; -import cover5mobile from '../../../assets/images/nft-modal/cover-5-mobile.png'; - -interface Steps { - title: string; - description: string; - src: string; -} - -const steps = (isMobile: boolean): Steps[] => ([ - { - title: 'Benefits of the Fida Founders NFT Collection', - description: 'The Fida Founders NFT Collection offers a range of exclusive benefits that set it apart from other NFT collections. This collection is not just about digital art, or the historic introduction of global decentralized insurance, but a utility token within the Fida ecosystem. Here are the benefits we\'re currently planning for the token', - src: isMobile ? cover1mobile : cover1 - }, - { - title: 'Early Access to the Fida System', - description: 'As a holder of the Fida Founders NFT, you will be invited to the private testnet. This early access allows you to familiarize yourself with the platform, navigate its features, and most importantly influence its development through feature requests and user experience suggestions.', - src: isMobile ? cover2mobile : cover2 - }, - { - title: 'First Choice of Policies', - description: 'As an investor possessing a Fida Founders NFT will grant you access to an initial early commitment round to each policy brought onboard. This priority access means you can optimize your portfolio, with the risk profile and diversification that best suits your investment strategy. Early selection can be crucial in ensuring your proportion of the most desirable policies, especially those that might be limited in availability or have particularly favorable conditions.', - src: isMobile ? cover3mobile : cover3 - }, - { - title: 'Priority Listings', - description: 'As an insurer or broker holding a Fida Founders NFT your policies will be highlighted as founder\'s policy. In a competitive environment where other brokers are competing for investment a founding member\'s tag can significantly impact outcomes, raising the odds of getting your policy filled and offering a substantial edge.', - src: isMobile ? cover4mobile : cover4 - }, - { - title: 'Fee Discounts', - description: 'One of the certain advantages of the Fida Founders NFT is the entitlement to fee discounts. Listing fees, trading fees, and other charges within the Fida ecosystem will be discounted to holders of the Fida Founders Collection. As an NFT holder, you benefit from reduced fees, allowing you to trade effectively, and potentially increase your net gains. This financial incentive is designed to reward early supporters and encourage continued engagement with the platform.', - src: isMobile ? cover5mobile : cover5 - }, -]); - -export const FounderModalContent = () => { - const isMobile = useMediaQuery({ - query: maxWidth640, - }); - - const [activeIndex, setActiveIndex] = useState(0); - const [swiperInstance, setSwiperInstance] = useState(null); // Swiper instance state - - useEffect(() => { - const bullets = document.querySelectorAll('.swiper-pagination-bullet'); - bullets.forEach((bullet, index) => { - if (index < activeIndex) { - bullet.classList.add('swiper-pagination-bullet-past'); - } else { - bullet.classList.remove('swiper-pagination-bullet-past'); - } - }); - }, [activeIndex]); - - const pagination = { - clickable: true, - renderBullet(index: number, className: string) { - const bulletClass = index < activeIndex ? 'swiper-pagination-bullet-past' : ''; - return `${index + 1}`; - }, - }; - - const handleNextSlide = () => { - if (swiperInstance && activeIndex < steps(isMobile).length - 1) { - swiperInstance.slideNext(); - } else if (swiperInstance && activeIndex === steps(isMobile).length - 1) { - swiperInstance.slideTo(0); - } - }; - - return ( - setActiveIndex(swiper.activeIndex)} - onSwiper={setSwiperInstance} // Store the Swiper instance - > - {steps(isMobile).map(step => ( - - - {step.title} - - {step.title} - {step.description} - - - {`Learn more (${activeIndex + 1}/${steps(isMobile).length}) →`} - - - - ))} - - ); -}; - -const SliderContainer = styled.div` - display: flex; - flex-direction: column; - gap: 24px; -`; - -const TextContainer = styled.div` - display: flex; - flex-direction: column; - gap: 24px; -`; - -const SliderTitle = styled.p` - font-weight: 700; - font-size: 36px; - line-height: 44px; - color: black; - - @media (max-width: 640px) { - font-size: 24px; - line-height: 32px; - } -`; - -const SliderDescription = styled.p` - font-weight: 500; - font-size: 18px; - line-height: 28px; - color: black; - text-align: center; - padding: 0 68px; - - @media (max-width: 815px) { - font-size: 16px; - line-height: 24px; - padding: 0 24px; - }; - - @media (max-width: 640px) { - font-size: 14px; - line-height: 20px; - padding: 0 0; - }; - - @media (max-width: 375px) { - font-size: 12px; - line-height: 18px; - } -`; - -const LearnButton = styled.button` - position: absolute; - bottom: 52px; - left: 50%; - transform: translateX(-50%); - border: none; - outline: none; - background: none; - cursor: pointer; - font-weight: 500; - font-size: 18px; - line-height: 28px; - color: gray; - text-align: center; - - @media (max-width: 375px) { - font-size: 12px; - line-height: 18px; - bottom: 38px; - }; - - @media (max-width: 830px) { - font-size: 14px; - line-height: 20px; - bottom: 42px; - } -`; diff --git a/src/components/founder-sale/modal/styles.css b/src/components/founder-sale/modal/styles.css deleted file mode 100644 index c65c8d4..0000000 --- a/src/components/founder-sale/modal/styles.css +++ /dev/null @@ -1,132 +0,0 @@ -.modal-swiper.swiper { - width: 100%; - height: 100%; - border: none; - outline: none; - } - - .modal-swiper .swiper-slide { - text-align: center; - font-size: 18px; - background: #fff; - border: none; - outline: none; - - /* Center slide text vertically */ - display: flex; - justify-content: center; - align-items: start; - } - - .modal-swiper .swiper-slide img { - display: block; - width: 100%; - max-width: 829px; - height: 324px; - object-fit: cover; - border-radius: 24px; - } - - .modal-swiper .swiper-pagination-bullet { - width: 64px; - height: 16px; - text-align: center; - color: transparent; - opacity: 1; - border-radius: 99px; - background: #E6E6E6; - } - - .modal-swiper .swiper-pagination-bullet-active { - color: transparent; - background: #D33681; - } - - .modal-swiper .swiper-pagination-bullet-past { - color: transparent; - background: #D33681; - opacity: 0.3; - } - - .modal-swiper .swiper-button-next, .modal-swiper .swiper-button-prev { - border-radius: 100%; - background-color: transparent; - border: 1px solid rgba(0, 0, 0, 0.2); - color: #323232; - width: 42px; - height: 42px; - top: auto; - bottom: 0; - z-index: 30; - } - - .modal-swiper .swiper-button-next { - right: 22%; - } - - .modal-swiper .swiper-button-prev { - left: 22%; - } - - .modal-swiper .swiper-button-next::after, .modal-swiper .swiper-button-prev::after { - scale: 0.4; - } - - .modal-swiper .swiper-button-disabled { - visibility: hidden; - } - - @media (max-width: 830px) { - .modal-swiper .swiper-button-next { - right: 14%; - } - - .modal-swiper .swiper-button-prev { - left: 14%; - } -} - - @media (max-width: 640px) { - .modal-swiper .swiper-pagination-bullet { - width: 16px; - height: 16px; - } - - .modal-swiper .swiper-button-next, .modal-swiper .swiper-button-prev { - width: 26px; - height: 26px; - bottom: 8px; - } - - .modal-swiper .swiper-button-next::after, .modal-swiper .swiper-button-prev::after { - scale: 0.2; - } - - .modal-swiper .swiper-button-next { - right: 32%; - } - - .modal-swiper .swiper-button-prev { - left: 32%; - } -} - -@media (max-width: 560px) { - .modal-swiper .swiper-button-next { - right: 28%; - } - - .modal-swiper .swiper-button-prev { - left: 28%; - } -} - -@media (max-width: 450px) { - .modal-swiper .swiper-button-next { - right: 22%; - } - - .modal-swiper .swiper-button-prev { - left: 22%; - } -} diff --git a/src/components/rwd/FoundersHeaderMenuMobile.tsx b/src/components/rwd/FoundersHeaderMenuMobile.tsx index b330ff6..43a1ca3 100644 --- a/src/components/rwd/FoundersHeaderMenuMobile.tsx +++ b/src/components/rwd/FoundersHeaderMenuMobile.tsx @@ -12,11 +12,11 @@ import { useNavigate } from 'react-router-dom'; interface Props { modalToggle: boolean; setModalToggle: React.Dispatch>; - handleOpenLearnMoreModal: () => void + handleLearnMore: () => void; } export const FoundersHeaderMenuMobile = (props: Props) => { - const { modalToggle, setModalToggle, handleOpenLearnMoreModal } = props; + const { modalToggle, setModalToggle, handleLearnMore } = props; const navigate = useNavigate(); return ( @@ -38,7 +38,7 @@ export const FoundersHeaderMenuMobile = (props: Props) => { toUpperCase textPlacing="center" color={colors.buttonTertiaryColorFg} - onClick={handleOpenLearnMoreModal} + onClick={handleLearnMore} /> navigate('/')}> Discover FIDA diff --git a/src/components/rwd/MobileHeaderFounders.tsx b/src/components/rwd/MobileHeaderFounders.tsx index 42b13ba..963cc80 100644 --- a/src/components/rwd/MobileHeaderFounders.tsx +++ b/src/components/rwd/MobileHeaderFounders.tsx @@ -7,10 +7,10 @@ import menuMobileClose from 'assets/icons/menuMobileClose.svg'; import { FoundersHeaderMenuMobile } from './FoundersHeaderMenuMobile'; interface Props { - handleOpenLearnMoreModal: () => void; + handleLearnMore: () => void; } -export const MobileHeaderFounders = ({ handleOpenLearnMoreModal }: Props) => { +export const MobileHeaderFounders = ({ handleLearnMore }: Props) => { const [modalToggle, setModalToggle] = useState(false); return ( @@ -21,7 +21,7 @@ export const MobileHeaderFounders = ({ handleOpenLearnMoreModal }: Props) => { alt="open menu" loading="lazy" /> - + ); }; diff --git a/src/pages/FounderCards.tsx b/src/pages/FounderCards.tsx index 7a02bcb..7255fb4 100644 --- a/src/pages/FounderCards.tsx +++ b/src/pages/FounderCards.tsx @@ -1,4 +1,4 @@ -import { lazy, Suspense, useEffect, useState } from 'react'; +import { lazy, Suspense } from 'react'; import styled from 'styled-components'; import { colors } from 'theme'; @@ -11,38 +11,36 @@ import { Container } from '../components/_common/Container'; import backgroundImage from '../assets/images/background-pattern.png'; import { NFTSlider } from '../components/founder-sale/NFTSlider'; import { maxWidth840 } from '../components/rwd/detectMobile'; -import { FounderModal } from '../components/founder-sale/modal/FounderModal'; import { HeaderFounders } from '../components/HeaderFounders'; +import { FounderBenefits } from '../components/founder-sale/FounderBenefits'; const NFTDetails = lazy(() => import('../components/founder-sale/NFTDetails')); const FounderCards = () => { - const [isFounderModalOpen, setIsFounderModalOpen] = useState(false); - - useEffect(() => { setTimeout(() => setIsFounderModalOpen(true), 5000); }, []); - const isTablet = useMediaQuery({ query: maxWidth840, }); + const handleScrollToBenefits = () => { + document.getElementById('benefits')?.scrollIntoView({ behavior: 'smooth' }); + }; + return ( - <> - - setIsFounderModalOpen(true)} /> - - - {'Fida Founder\'s NFT Collection'.toUpperCase()} - - - - }> - - - -
- - setIsFounderModalOpen(false)} /> - + + + + + {'Fida Founder\'s NFT Collection'.toUpperCase()} + + + + + }> + + + +
+ ); }; From 8e9062dbde8e062e690ef18244bf87dbb4182b56 Mon Sep 17 00:00:00 2001 From: Rodolfo Hansen Date: Wed, 4 Mar 2026 00:22:05 +0100 Subject: [PATCH 3/9] Add pre-commit hook to clean unused dictionary words Add scripts/clean-dictionary.sh that greps each word in dictionary.txt against source files and removes any that are no longer referenced. Runs automatically before the spell-check in the pre-commit hook. Also fix the pre-commit hook to only spell-check files under src/ and public/ matching the spellchecker config patterns. Co-Authored-By: Claude Opus 4.6 --- .husky/pre-commit | 8 +++- dictionary.txt | 87 ------------------------------------- package.json | 1 + scripts/clean-dictionary.sh | 38 ++++++++++++++++ 4 files changed, 45 insertions(+), 89 deletions(-) create mode 100755 scripts/clean-dictionary.sh diff --git a/.husky/pre-commit b/.husky/pre-commit index 5b9c373..0f1fae7 100755 --- a/.husky/pre-commit +++ b/.husky/pre-commit @@ -1,5 +1,9 @@ #!/usr/bin/env sh . "$(dirname -- "$0")/_/husky.sh" -changedFiles="$(git diff --name-only --cached)" -npm run spell-check -- --files ${changedFiles} "!**/package-lock.json" "!**/*.svg" "!**/*.png" "!**/*.jppg" "!**/*.ico" +npm run clean-dictionary + +changedFiles="$(git diff --name-only --cached | grep -E '\.(html|txt|json|ts|tsx)$' | grep -E '^(public/|src/)' || true)" +if [ -n "$changedFiles" ]; then + npm run spell-check -- --files ${changedFiles} "!**/package-lock.json" "!**/*.svg" "!**/*.png" "!**/*.jppg" "!**/*.ico" +fi diff --git a/dictionary.txt b/dictionary.txt index a411738..2948700 100644 --- a/dictionary.txt +++ b/dictionary.txt @@ -1,8 +1,6 @@ adopter&apos Ai AnimatedText -args -argTypes arrowLeft arrowPointer ArrowPointer @@ -19,17 +17,11 @@ card3 CardImage CardsWrapper centeredSlides -ChangeEvent charset ci className -clearInterval clior -codebase collateralization -ComponentMeta -ComponentStory -config const ContainerProps ContentWrapper @@ -42,7 +34,6 @@ descriptionText detectMobile diagramIcon DOCTYPE -DS_Store effect-coverflow EffectCoverflow eslint-disable @@ -59,21 +50,16 @@ FidaMarketplaceCardProps fidaMarketplaceTexts fidaOverlay Fida's -firefox fontFamily fontWeight FooterWrapper formattedText -gh-pages gradientLaptop gradientLaptopMobile gradientPhones grey greyWhite h1 -handleChange -handleDecrement -handleIncrement HeroCard hideBackdrop highlightIndex @@ -124,8 +110,6 @@ isScreen isSmallerCard isTablet iterableItems -javascript -javascript:openPaymentWindow JoinNetwork lang laptopCards @@ -165,7 +149,6 @@ minWidth640 MissionCard MissionCardProps missionCards -mkdir mobileCards MobileHeader mobilePadding @@ -174,12 +157,9 @@ MobilePhaseItemProps modalToggle motionConfig MoveIn -moz-appearance n2022 newDirection -newHeight newsletterTexts -newTop newWidth nft- NFT @@ -192,26 +172,21 @@ nft6 nft-cards NFTDetails nft-infos -NFT-MAKER nfts NFTs NFTSlider NFTSliderContainer ninefold nmeet -NMKR noTextWrap nowrap npm -onChange -onclick onClick onClickLeft onClickLink onClickRight onImageLoad onLoad -openPaymentWindow param paramArr params @@ -223,7 +198,6 @@ PhaseItemProps PhasesContainer phaseWidth png -.pnp PointerWrapper prevState px @@ -242,8 +216,6 @@ roadMapTexts roseDot roseReg rwd -screenX -screenY ScrollPage seamlessAI SeamlessAI @@ -253,7 +225,6 @@ seamlessAITexts setImageHeight setImageWidth setIntersecting -setInterval setIsExpanded setModalToggle setOne @@ -273,7 +244,6 @@ StickyWrapper StyledContainer StyledGenericWrapper StyledHeader -StyledLabel StyledLink styledParts StyledProps @@ -290,7 +260,6 @@ targetRef textAlign TextContainer textData -textfield textGradient textPlaceholder textPlacing @@ -301,15 +270,12 @@ textTertiary600 TextWrapper TitleContainer titleTexts -tj-actions toggleText TopSection TopWrapper transformOrigin transformVariant -typeof vw -webkit-appearance welcomeCards WelcomeCards welcomeHeroCard @@ -317,10 +283,7 @@ welcomeOverlay welcomeOverlayDesktop welcomeTexts whileInView -WithRoseText -wtop nft7 -SwiperCore cover1 nft-modal cover1mobile @@ -332,29 +295,13 @@ cover4 cover4mobile cover5 cover5mobile -activeIndex -setActiveIndex -swiperInstance -setSwiperInstance -activeIndex -handleNextSlide testnet -watchSlidesProgress -onSlideChange -onSwiper SliderContainer -SliderTitle -SliderDescription -translateX .nft-slider .swiper-slide -handleOpenLearnMoreModal FIDA DesktopLinesBg MobileLinesBg -handleOpenModal -isOpen -handleClose fetchpriority MenuButton MobileMenuButton @@ -367,22 +314,13 @@ menuMobileClose menuMobileOpen decodeURIComponent MenuWrapper -.github github -ubuntu-latest moveInAnimationValue -newValue -setValue ConquerRisk StyledConquerRisk conquerRiskTexts getQueryParams mui -renderBullet -bulletClass -NumberInput -spellchecker-cli-action-summary@main -backgroundCheck backgroundColor backgroundGradient greyBackgroundGradient @@ -391,16 +329,9 @@ backgroundImage NotFoundPage Founder&apos FounderContainer -FounderDesktopCard founderDesktopCard FounderHeroCard -fOunderMobileCard founderMobileCard -FounderModal -FounderModalContent -isFounderModalOpen -setIsFounderModalOpen -FounderSale FounderCards FounderBenefits BenefitCard @@ -419,19 +350,12 @@ MobileHeaderFounders HeaderFounders FoundersHeaderMenuMobile StyledFoundersNavButtons -countAda -CounterContainer -popupHeight -popupWidth toUpperCase OurMission ourMissionOverlay ourMissionTexts -paymentUrl url grabCursor -PlusIcon -MinusIcon useCallback useEffect useMediaQuery @@ -445,24 +369,13 @@ useState PhasesCarousel user-scalable user-scalable=1 -userNavigate -austenstone CustomZoom learnAbout MoveOut -setTimeout -InputContainer -HTMLInputElement InputWrapper BrowserRouter -webkit-outer-spin-button -outerHeight utilityGray -GradientButton -NFTButton StyledButton -webkit-inner-spin-button -LearnButton .swiper-button-next .swiper-button-prev buttonLabel diff --git a/package.json b/package.json index 224924b..fe202b5 100644 --- a/package.json +++ b/package.json @@ -35,6 +35,7 @@ "test": "react-scripts test", "eject": "react-scripts eject", "spell-check": "spellchecker --config .spellcheckerrc.json", + "clean-dictionary": "bash scripts/clean-dictionary.sh", "build-dictionary": "spellchecker --config .spellcheckerrc.json --generate-dictionary dictionary.txt", "prepare": "husky install" }, diff --git a/scripts/clean-dictionary.sh b/scripts/clean-dictionary.sh new file mode 100755 index 0000000..26ba34f --- /dev/null +++ b/scripts/clean-dictionary.sh @@ -0,0 +1,38 @@ +#!/usr/bin/env bash +# Remove words from dictionary.txt that no longer appear in any source file. +# Scans the same file patterns as .spellcheckerrc.json. + +set -euo pipefail + +REPO_ROOT="$(cd "$(dirname "$0")/.." && pwd)" +DICT="$REPO_ROOT/dictionary.txt" + +if [ ! -f "$DICT" ]; then + echo "dictionary.txt not found" >&2 + exit 1 +fi + +unused=() +while IFS= read -r word; do + [ -z "$word" ] && continue + if ! grep -rqF "$word" \ + --include='*.ts' --include='*.tsx' --include='*.html' --include='*.json' --include='*.css' \ + --exclude-dir=node_modules --exclude-dir=build --exclude-dir=reports \ + --exclude=dictionary.txt \ + "$REPO_ROOT/src" "$REPO_ROOT/public" "$REPO_ROOT/.github" 2>/dev/null; then + unused+=("$word") + fi +done < "$DICT" + +if [ ${#unused[@]} -eq 0 ]; then + exit 0 +fi + +echo "Removing ${#unused[@]} unused dictionary word(s):" +for w in "${unused[@]}"; do + echo " - $w" + grep -vxF "$w" "$DICT" > "$DICT.tmp" && mv "$DICT.tmp" "$DICT" +done + +# Stage the cleaned dictionary so the commit includes it +git add "$DICT" From 6e2b650021315ad794c2b7571cfae22c72ae1e67 Mon Sep 17 00:00:00 2001 From: Rodolfo Hansen Date: Wed, 4 Mar 2026 00:26:43 +0100 Subject: [PATCH 4/9] Fix nested ternary lint error in FounderBenefits Use a media query for the column layout on tablet instead of a nested ternary in the styled component prop. Co-Authored-By: Claude Opus 4.6 --- src/components/founder-sale/FounderBenefits.tsx | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/src/components/founder-sale/FounderBenefits.tsx b/src/components/founder-sale/FounderBenefits.tsx index de4b57c..c908caa 100644 --- a/src/components/founder-sale/FounderBenefits.tsx +++ b/src/components/founder-sale/FounderBenefits.tsx @@ -4,7 +4,7 @@ import { motion } from 'framer-motion'; import { colors } from 'theme'; import { transition, transformVariant } from 'constants/motionConfig'; -import { maxWidth640, maxWidth840 } from 'components/rwd/detectMobile'; +import { maxWidth640 } from 'components/rwd/detectMobile'; import cover1 from '../../assets/images/nft-modal/cover-1.png'; import cover1mobile from '../../assets/images/nft-modal/cover-1-mobile.png'; @@ -53,7 +53,6 @@ const steps = (isMobile: boolean): BenefitStep[] => ([ export const FounderBenefits = () => { const isMobile = useMediaQuery({ query: maxWidth640 }); - const isTablet = useMediaQuery({ query: maxWidth840 }); return ( @@ -65,7 +64,6 @@ export const FounderBenefits = () => { variants={transformVariant} whileInView="visible" $reversed={index % 2 !== 0} - $isTablet={isTablet} > @@ -91,13 +89,14 @@ const BenefitsSection = styled.div` } `; -const BenefitCard = styled(motion.div)<{ $reversed: boolean; $isTablet: boolean }>` +const BenefitCard = styled(motion.div)<{ $reversed: boolean }>` display: flex; - flex-direction: ${({ $reversed, $isTablet }) => ($isTablet ? 'column' : ($reversed ? 'row-reverse' : 'row'))}; + flex-direction: ${({ $reversed }) => ($reversed ? 'row-reverse' : 'row')}; align-items: center; gap: 48px; @media (max-width: 840px) { + flex-direction: column; gap: 24px; } `; From 453b3335c7401cdcea36b9c9e5d41fe63cbd9b79 Mon Sep 17 00:00:00 2001 From: Rodolfo Hansen Date: Wed, 4 Mar 2026 00:27:16 +0100 Subject: [PATCH 5/9] Rename route from /founder-sale to /founders-card Co-Authored-By: Claude Opus 4.6 --- src/components/App.tsx | 2 +- src/data/texts.ts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/components/App.tsx b/src/components/App.tsx index b873032..5830d46 100644 --- a/src/components/App.tsx +++ b/src/components/App.tsx @@ -10,7 +10,7 @@ const App = () => ( Loading...
}> } /> - } /> + } /> } />
diff --git a/src/data/texts.ts b/src/data/texts.ts index 50566c5..39cf305 100644 --- a/src/data/texts.ts +++ b/src/data/texts.ts @@ -24,7 +24,7 @@ const founderWelcomeHeroCard = { title: 'Fida Founder\'s NFT Collection', button: { label: 'Learn More', - link: 'founder-sale', + link: 'founders-card', } }; From b794b09f840c646d30d14a6030a826e0b25fac78 Mon Sep 17 00:00:00 2001 From: Rodolfo Hansen Date: Wed, 4 Mar 2026 00:27:54 +0100 Subject: [PATCH 6/9] Add eslint check to pre-commit hook Run eslint on staged .ts/.tsx files under src/ to catch lint errors before they reach CI. Co-Authored-By: Claude Opus 4.6 --- .husky/pre-commit | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/.husky/pre-commit b/.husky/pre-commit index 0f1fae7..ac7c128 100755 --- a/.husky/pre-commit +++ b/.husky/pre-commit @@ -7,3 +7,8 @@ changedFiles="$(git diff --name-only --cached | grep -E '\.(html|txt|json|ts|tsx if [ -n "$changedFiles" ]; then npm run spell-check -- --files ${changedFiles} "!**/package-lock.json" "!**/*.svg" "!**/*.png" "!**/*.jppg" "!**/*.ico" fi + +lintFiles="$(git diff --name-only --cached | grep -E '\.(ts|tsx)$' | grep -E '^src/' || true)" +if [ -n "$lintFiles" ]; then + npx eslint ${lintFiles} +fi From d2da899966fadf0bec442bd73c175aab30cfe662 Mon Sep 17 00:00:00 2001 From: Rodolfo Hansen Date: Wed, 4 Mar 2026 00:28:59 +0100 Subject: [PATCH 7/9] Add AGENTS.md with repository merge conventions Co-Authored-By: Claude Opus 4.6 --- AGENTS.md | 7 +++++++ 1 file changed, 7 insertions(+) create mode 100644 AGENTS.md diff --git a/AGENTS.md b/AGENTS.md new file mode 100644 index 0000000..18fe9cd --- /dev/null +++ b/AGENTS.md @@ -0,0 +1,7 @@ +# Agents + +## Merging Pull Requests + +- This repository only allows **rebase merges** (merge commits and squash merges are disabled). +- Branch protection rules require using the `--admin` flag to merge: `gh pr merge --rebase --admin` +- The **Cloudflare Pages** check is the build/deploy check. If it fails, the PR would break the website and should **not** be merged. From a543749e5d4288b324528b9d0a6e6332e21a0c86 Mon Sep 17 00:00:00 2001 From: Rodolfo Hansen Date: Wed, 4 Mar 2026 00:37:56 +0100 Subject: [PATCH 8/9] Match FounderBenefits styling to main page MissionCard pattern MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Use greyBackgroundGradient cards with 24px border radius, grid layout with 40/60 split on desktop, AnimatedText with matching font sizes (1.875rem→3.75rem titles, 0.875rem→1.125rem descriptions), Inter font, ReadMore for long descriptions on mobile, and consistent padding/gaps. Co-Authored-By: Claude Opus 4.6 --- dictionary.txt | 2 - .../founder-sale/FounderBenefits.tsx | 156 +++++++++++------- 2 files changed, 94 insertions(+), 64 deletions(-) diff --git a/dictionary.txt b/dictionary.txt index 2948700..f6cfb4e 100644 --- a/dictionary.txt +++ b/dictionary.txt @@ -336,9 +336,7 @@ FounderCards FounderBenefits BenefitCard BenefitContent -BenefitDescription BenefitImage -BenefitTitle BenefitsSection handleLearnMore BenefitStep diff --git a/src/components/founder-sale/FounderBenefits.tsx b/src/components/founder-sale/FounderBenefits.tsx index c908caa..7b88e54 100644 --- a/src/components/founder-sale/FounderBenefits.tsx +++ b/src/components/founder-sale/FounderBenefits.tsx @@ -2,9 +2,11 @@ import styled from 'styled-components'; import { useMediaQuery } from 'react-responsive'; import { motion } from 'framer-motion'; -import { colors } from 'theme'; +import { colors, radius } from 'theme'; import { transition, transformVariant } from 'constants/motionConfig'; -import { maxWidth640 } from 'components/rwd/detectMobile'; +import { maxWidth640, maxWidth840 } from 'components/rwd/detectMobile'; +import { AnimatedText } from 'components/_common/AnimatedText'; +import { ReadMore } from 'components/ReadMore'; import cover1 from '../../assets/images/nft-modal/cover-1.png'; import cover1mobile from '../../assets/images/nft-modal/cover-1-mobile.png'; @@ -23,6 +25,8 @@ interface BenefitStep { src: string; } +const MAX_DESCRIPTION_LENGTH = 150; + const steps = (isMobile: boolean): BenefitStep[] => ([ { title: 'Benefits of the Fida Founders NFT Collection', @@ -53,25 +57,55 @@ const steps = (isMobile: boolean): BenefitStep[] => ([ export const FounderBenefits = () => { const isMobile = useMediaQuery({ query: maxWidth640 }); + const isTablet = useMediaQuery({ query: maxWidth840 }); return ( - {steps(isMobile).map((step, index) => ( - - - - {step.title} - {step.description} - - - ))} + {steps(isMobile).map((step, index) => { + const isReversed = index % 2 !== 0; + return ( + + + + + + {step.description.length >= MAX_DESCRIPTION_LENGTH && isTablet ? ( + + ) : ( + + )} + + + + ); + })} ); }; @@ -79,67 +113,65 @@ export const FounderBenefits = () => { const BenefitsSection = styled.div` display: flex; flex-direction: column; - gap: 64px; + gap: 16px; width: 100%; - padding: 48px 0; - - @media (max-width: 840px) { - gap: 40px; - padding: 24px 16px; - } -`; -const BenefitCard = styled(motion.div)<{ $reversed: boolean }>` - display: flex; - flex-direction: ${({ $reversed }) => ($reversed ? 'row-reverse' : 'row')}; - align-items: center; - gap: 48px; - - @media (max-width: 840px) { - flex-direction: column; - gap: 24px; + @media (min-width: 1024px) { + gap: 0px; } `; -const BenefitImage = styled.img` - width: 50%; - max-width: 400px; - border-radius: 24px; - object-fit: cover; +const BenefitCard = styled.div` + background-color: ${colors.mainBlack}; + border-radius: ${radius['4xl']}; - @media (max-width: 840px) { - width: 100%; - max-width: 100%; + @media (min-width: 1024px) { + margin: 80px 0px; } `; -const BenefitContent = styled.div` +const Card = styled.div<{ isReversed: boolean }>` + align-items: center; + background: ${colors.greyBackgroundGradient}; + border-radius: ${radius['4xl']}; display: flex; flex-direction: column; - gap: 16px; - flex: 1; + padding: 16px; + position: relative; + + @media (min-width: 1024px) { + display: grid; + grid-template-columns: ${({ isReversed }) => (isReversed ? '60% 40%' : '40% 60%')}; + justify-content: space-between; + padding: 0px 32px; + } + + @media (min-width: 1440px) { + grid-template-columns: ${({ isReversed }) => (isReversed ? '60% 30%' : '30% 60%')}; + } `; -const BenefitTitle = styled.h3` - font-weight: 700; - font-size: 28px; - line-height: 36px; - color: ${colors.textPrimaryOnBrand}; +const BenefitImage = styled(motion.img)<{ isReversed: boolean }>` + width: 100%; + border-radius: ${radius['4xl']}; - @media (max-width: 640px) { - font-size: 22px; - line-height: 28px; + @media (min-width: 1024px) { + margin: ${({ isReversed }) => (isReversed ? '0px' : '24px 0px')}; + order: ${({ isReversed }) => (isReversed ? 1 : 0)}; } `; -const BenefitDescription = styled.p` - font-weight: 500; - font-size: 18px; - line-height: 28px; - color: ${colors.textTertiary600}; +const BenefitContent = styled(motion.div)` + display: flex; + flex-direction: column; + gap: 16px; + justify-content: center; + margin-bottom: 32px; + margin-top: 14px; - @media (max-width: 640px) { - font-size: 15px; - line-height: 24px; + @media (min-width: 1024px) { + margin-left: 24px; + gap: 40px; + padding: 100px 0px; } `; From 0683e7ce72ea9ee2e73e54fd0a31ebfdbbbfeb61 Mon Sep 17 00:00:00 2001 From: Rodolfo Hansen Date: Wed, 4 Mar 2026 00:39:59 +0100 Subject: [PATCH 9/9] Add horizontal padding to FounderCards page Match the Index page margins (48px desktop, 16px mobile) so cards aren't flush against the browser window. Co-Authored-By: Claude Opus 4.6 --- src/pages/FounderCards.tsx | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/pages/FounderCards.tsx b/src/pages/FounderCards.tsx index 7255fb4..163d001 100644 --- a/src/pages/FounderCards.tsx +++ b/src/pages/FounderCards.tsx @@ -56,10 +56,10 @@ const FounderContainer = styled.div` background-size: 100%; background-position: right 0 bottom 50%; background-repeat: no-repeat; - padding: 24px 0; + padding: 24px 48px; - @media (max-width: 840px) { - padding: 0; + @media (max-width: 640px) { + padding: 0 16px; gap: 24px; } `;