Hero Banner #7

Merged
an.di merged 27 commits from adilallo/HeroBanner into main 2025-08-22 02:02:08 +00:00
9 changed files with 2533 additions and 15 deletions
Showing only changes of commit a04a5a6eeb - Show all commits
+43
View File
@@ -0,0 +1,43 @@
"use client";
import Button from "./Button";
const ContentLockup = ({ title, subtitle, description, ctaText, ctaHref }) => {
return (
<div className="flex flex-col gap-[var(--spacing-scale-006)] relative z-10">
{/* Text content container */}
<div className="flex flex-col">
{/* Title container */}
<div className="flex gap-[var(--spacing-scale-008)] items-center">
<h1 className="font-bricolage-grotesque font-medium text-[32px] leading-[32px] text-[var(--color-content-inverse-primary)]">
{title}
</h1>
<img
src="/assets/Shapes_1.svg"
alt="Decorative shapes"
className="w-[27.2px] h-[27.2px]"
/>
</div>
{/* Subtitle */}
<h2 className="font-bricolage-grotesque font-medium text-[32px] leading-[32px] text-[var(--color-content-inverse-primary)]">
{subtitle}
</h2>
{/* Description */}
<p className="font-inter font-normal text-[14px] leading-[20px] text-[var(--color-content-inverse-primary)]">
{description}
</p>
</div>
{/* CTA Button */}
<div className="flex justify-start">
<Button variant="primary" size="small">
{ctaText}
</Button>
</div>
</div>
);
};
export default ContentLockup;
+43
View File
@@ -0,0 +1,43 @@
"use client";
import ContentLockup from "./ContentLockup";
import HeroDecor from "./HeroDecor";
const HeroBanner = ({ title, subtitle, description, ctaText, ctaHref }) => {
return (
<section className="bg-transparent px-[var(--spacing-scale-008)]">
<div className="flex flex-col gap-[var(--spacing-scale-010)]">
{/* Frame container for content */}
<div className="bg-[var(--color-surface-default-brand-primary)] p-[var(--spacing-scale-012)] rounded-tl-none rounded-tr-[16px] rounded-br-[16px] rounded-bl-[16px] flex flex-col gap-[var(--spacing-scale-024)] relative overflow-hidden">
{/* DECORATIONS (behind content) */}
<HeroDecor
className="pointer-events-none absolute z-0
left-0 top-0
translate-x-[-72px] translate-y-[26px]
w-[1540px] h-[645px] scale-[1.04]"
/>
{/* Content lockup - Large variant */}
<ContentLockup
title={title}
subtitle={subtitle}
description={description}
ctaText={ctaText}
ctaHref={ctaHref}
/>
{/* Hero Image Container */}
<div className="w-full rounded-[8px] relative z-10">
<img
src="/assets/HeroImage.png"
alt="Hero illustration"
className="w-full h-auto"
/>
</div>
</div>
</div>
</section>
);
};
export default HeroBanner;
+70
View File
@@ -0,0 +1,70 @@
"use client";
const HeroDecor = ({ className = "" }) => {
return (
<svg
className={`text-[#FDFAA8] opacity-50 ${className}`}
viewBox="0 0 1540 645"
aria-hidden="true"
overflow="visible"
preserveAspectRatio="xMidYMid slice"
>
<g fill="currentColor">
<defs>
<filter
id="grain"
filterUnits="objectBoundingBox"
x="0"
y="0"
width="1"
height="1"
colorInterpolationFilters="sRGB"
>
{/* 1) make noise */}
<feTurbulence
type="fractalNoise"
baseFrequency="0.8"
numOctaves="2"
seed="3"
stitchTiles="stitch"
result="noise"
/>
{/* 2) attenuate */}
<feColorMatrix
in="noise"
result="softNoise"
type="matrix"
values="
0 0 0 0 0
0 0 0 0 0
0 0 0 0 0
0 0 0 0.15 0"
/>
{/* 3) MASK noise to the element's alpha only */}
<feComposite
in="softNoise"
in2="SourceAlpha"
operator="in"
result="maskedNoise"
/>
{/* 4) blend masked noise over the shapes */}
<feBlend in="SourceGraphic" in2="maskedNoise" mode="multiply" />
</filter>
</defs>
{/* apply filter only to the decoration paths */}
<g fill="currentColor" filter="url(#grain)">
<path d="M1441.54 226.758C1495.92 226.758 1540 320.385 1540 435.879C1540 551.373 1495.92 645 1441.54 645C1387.16 645 1343.08 551.373 1343.08 435.879C1343.08 320.385 1387.16 226.758 1441.54 226.758Z" />
<path d="M1441.54 226.758C1495.92 226.758 1540 320.385 1540 435.879C1540 551.373 1495.92 645 1441.54 645C1387.16 645 1343.08 551.373 1343.08 435.879C1343.08 320.385 1387.16 226.758 1441.54 226.758Z" />
<path d="M674.066 209.121C728.443 209.121 772.525 302.748 772.525 418.242C772.525 533.737 728.443 627.363 674.066 627.363C619.688 627.363 575.607 533.737 575.607 418.242C575.607 302.748 619.688 209.121 674.066 209.121Z" />
<path d="M674.066 209.121C728.443 209.121 772.525 302.748 772.525 418.242C772.525 533.737 728.443 627.363 674.066 627.363C619.688 627.363 575.607 533.737 575.607 418.242C575.607 302.748 619.688 209.121 674.066 209.121Z" />
<path d="M290.328 0C344.705 0 388.787 93.6267 388.787 209.121C388.787 211.519 388.765 213.907 388.728 216.285C401.725 133.082 438.661 73.0664 482.197 73.0664C536.574 73.0664 580.656 166.693 580.656 282.188C580.656 397.682 536.574 491.309 482.197 491.309C427.819 491.309 383.738 397.682 383.738 282.188C383.738 279.79 383.758 277.401 383.796 275.023C370.798 358.226 333.864 418.242 290.328 418.242C246.792 418.242 209.856 358.226 196.859 275.023C196.897 277.401 196.918 279.79 196.918 282.188C196.918 397.682 152.836 491.309 98.459 491.309C44.0816 491.309 0 397.682 0 282.188C0 166.693 44.0816 73.0664 98.459 73.0664C141.995 73.0664 178.929 133.082 191.927 216.285C191.889 213.907 191.869 211.519 191.869 209.121C191.869 93.6267 235.95 0 290.328 0Z" />
<path d="M290.328 0C344.705 0 388.787 93.6267 388.787 209.121C388.787 211.519 388.765 213.907 388.728 216.285C401.725 133.082 438.661 73.0664 482.197 73.0664C536.574 73.0664 580.656 166.693 580.656 282.188C580.656 397.682 536.574 491.309 482.197 491.309C427.819 491.309 383.738 397.682 383.738 282.188C383.738 279.79 383.758 277.401 383.796 275.023C370.798 358.226 333.864 418.242 290.328 418.242C246.792 418.242 209.856 358.226 196.859 275.023C196.897 277.401 196.918 279.79 196.918 282.188C196.918 397.682 152.836 491.309 98.459 491.309C44.0816 491.309 0 397.682 0 282.188C0 166.693 44.0816 73.0664 98.459 73.0664C141.995 73.0664 178.929 133.082 191.927 216.285C191.889 213.907 191.869 211.519 191.869 209.121C191.869 93.6267 235.95 0 290.328 0Z" />
<path d="M1057.8 0C1112.18 0 1156.26 93.6267 1156.26 209.121C1156.26 211.519 1156.24 213.907 1156.2 216.285C1169.2 133.082 1206.14 73.0664 1249.67 73.0664C1304.05 73.0664 1348.13 166.693 1348.13 282.188C1348.13 397.682 1304.05 491.309 1249.67 491.309C1195.29 491.309 1151.21 397.682 1151.21 282.188C1151.21 279.79 1151.23 277.401 1151.27 275.023C1138.27 358.226 1101.34 418.242 1057.8 418.242C1014.27 418.242 977.332 358.226 964.334 275.023C964.372 277.401 964.393 279.79 964.393 282.188C964.393 397.682 920.312 491.309 865.934 491.309C811.557 491.309 767.475 397.682 767.475 282.188C767.475 166.693 811.557 73.0664 865.934 73.0664C909.47 73.0664 946.405 133.082 959.402 216.285C959.365 213.907 959.344 211.519 959.344 209.121C959.344 93.6267 1003.43 0 1057.8 0Z" />
</g>
</g>
</svg>
);
};
export default HeroDecor;
+11
View File
@@ -1,6 +1,16 @@
import NumberedCards from "./components/NumberedCards";
import HeroBanner from "./components/HeroBanner";
export default function Page() {
const heroBannerData = {
title: "Collaborate",
subtitle: "with clarity",
description:
"Help your community make important decisions in a way that reflects its unique values.",
ctaText: "Learn how CommunityRule works",
ctaHref: "#",
};
const numberedCardsData = {
title: "How CommunityRule works",
subtitle: "Here's a quick overview of the process, from start to finish.",
@@ -25,6 +35,7 @@ export default function Page() {
return (
<div>
<HeroBanner {...heroBannerData} />
<NumberedCards {...numberedCardsData} />
</div>
);
+8
View File
@@ -3,6 +3,14 @@ const nextConfig = {
eslint: {
ignoreDuringBuilds: true,
},
webpack(config) {
config.module.rules.push({
test: /\.svg$/,
issuer: /\.[jt]sx?$/,
use: ["@svgr/webpack"],
});
return config;
},
};
export default nextConfig;
+2342 -15
View File
File diff suppressed because it is too large Load Diff
+1
View File
@@ -26,6 +26,7 @@
"@storybook/addon-viewport": "^9.0.8",
"@storybook/addon-vitest": "^9.1.2",
"@storybook/nextjs-vite": "^9.1.2",
"@svgr/webpack": "^8.1.0",
"@tailwindcss/postcss": "^4.1.11",
"@vitest/browser": "^3.2.4",
"@vitest/coverage-v8": "^3.2.4",
Binary file not shown.

After

Width:  |  Height:  |  Size: 112 KiB

+15
View File
@@ -0,0 +1,15 @@
<svg width="28" height="28" viewBox="0 0 28 28" fill="none" xmlns="http://www.w3.org/2000/svg">
<g clip-path="url(#clip0_18586_27811)">
<mask id="mask0_18586_27811" style="mask-type:luminance" maskUnits="userSpaceOnUse" x="0" y="0" width="28" height="28">
<path d="M27.2 0.399994L0 0.399994L0 27.6H27.2V0.399994Z" fill="white"/>
</mask>
<g mask="url(#mask0_18586_27811)">
<path d="M13.6 24.0284C3.31356 32.6244 -5.02436 24.2865 3.57164 14C-5.02436 3.71355 3.31356 -4.62436 13.6 3.97164C23.8845 -4.62436 32.2244 3.71355 23.6284 14C32.2244 24.2786 23.8845 32.6244 13.6 24.0284Z" fill="black"/>
</g>
</g>
<defs>
<clipPath id="clip0_18586_27811">
<rect width="27.2" height="27.2" fill="white" transform="translate(0 0.399994)"/>
</clipPath>
</defs>
</svg>

After

Width:  |  Height:  |  Size: 752 B