diff --git a/app/components/Avatar.js b/app/components/Avatar.js new file mode 100644 index 0000000..2abbefe --- /dev/null +++ b/app/components/Avatar.js @@ -0,0 +1,18 @@ +export default function Avatar({ + src, + alt, + size = "small", + className = "", + ...props +}) { + const sizeStyles = { + small: "w-[16px] h-[16px]", + medium: "w-[18px] h-[18px]", + large: "w-[24px] h-[24px]", + xlarge: "w-[32px] h-[32px]", + }; + + const baseStyles = `rounded-[var(--radius-measures-radius-full)] object-cover ${sizeStyles[size]} ${className}`; + + return {alt}; +} diff --git a/app/components/AvatarContainer.js b/app/components/AvatarContainer.js new file mode 100644 index 0000000..55ecfff --- /dev/null +++ b/app/components/AvatarContainer.js @@ -0,0 +1,21 @@ +export default function AvatarContainer({ + children, + size = "small", + className = "", + ...props +}) { + const sizeStyles = { + small: "flex -space-x-2", + medium: "flex -space-x-[9px]", + large: "flex -space-x-[10px]", + xlarge: "flex -space-x-[13px]", + }; + + const baseStyles = `items-center ${sizeStyles[size]} ${className}`; + + return ( +
+ {children} +
+ ); +} diff --git a/app/components/Button.js b/app/components/Button.js new file mode 100644 index 0000000..f120a79 --- /dev/null +++ b/app/components/Button.js @@ -0,0 +1,96 @@ +export default function Button({ + children, + variant = "default", + size = "xsmall", + className = "", + disabled = false, + type = "button", + onClick, + href, + target, + rel, + ariaLabel, + ...props +}) { + const sizeStyles = { + xsmall: + "px-[var(--spacing-scale-006)] py-[var(--spacing-scale-004)] gap-[var(--spacing-scale-001)]", + small: + "px-[var(--spacing-measures-spacing-008)] py-[var(--spacing-measures-spacing-008)] gap-[var(--spacing-scale-004)]", + large: + "px-[var(--spacing-scale-012)] py-[var(--spacing-scale-010)] gap-[var(--spacing-scale-004)]", + xlarge: + "px-[var(--spacing-scale-020)] py-[var(--spacing-scale-012)] gap-[var(--spacing-scale-008)]", + }; + + const fontStyles = { + xsmall: + "font-['Inter'] text-[10px] leading-[12px] font-medium tracking-[0%]", + small: + "font-['Inter'] text-[12px] leading-[14px] font-medium tracking-[0%]", + large: + "font-['Inter'] text-[16px] leading-[20px] font-medium tracking-[0%]", + xlarge: + "font-['Inter'] text-[24px] leading-[28px] font-normal tracking-[0%]", + }; + + const variantStyles = { + default: + "bg-[var(--color-surface-inverse-primary)] text-[var(--color-content-inverse-primary)] hover:bg-[var(--color-surface-inverse-primary)] hover:text-[var(--color-content-inverse-brand-primary)] hover:outline-[var(--border-color-default-brandprimary)] hover:outline-inset hover:scale-[1.02] hover:shadow-lg active:bg-[var(--color-surface-inverse-brand-primary)] active:text-[var(--color-content-inverse-primary)] active:outline-[var(--border-color-default-brandprimary)] active:outline-offset-1 active:scale-[0.98] disabled:bg-[var(--color-surface-default-secondary)] disabled:text-[var(--color-content-inverse-tertiary)] disabled:cursor-not-allowed disabled:opacity-50 disabled:hover:scale-100 disabled:active:scale-100 disabled:hover:shadow-none", + secondary: + "bg-transparent text-[var(--color-content-default-brand-primary)] hover:text-[var(--color-content-default-primary)] hover:scale-[1.02] hover:bg-[var(--color-surface-default-tertiary)] focus:outline-1 focus:outline-inset focus:outline-[var(--border-color-default-tertiary)] focus:shadow-[0_0_10px_1px_#FFFDD2] focus:blur-[0px] active:outline-[1.5px] active:outline-inset active:outline-[var(--color-content-default-brand-primary)] active:bg-[var(--color-surface-default-brand-primary)] active:text-[var(--color-content-inverse-primary)] active:scale-[0.98] disabled:bg-[var(--color-surface-default-secondary)] disabled:text-[var(--color-content-inverse-tertiary)] disabled:cursor-not-allowed disabled:opacity-50 disabled:hover:scale-100 disabled:active:scale-100", + }; + + const hoverOutlineStyles = { + xsmall: "hover:outline-1", + small: "hover:outline-1", + large: "hover:outline-2", + xlarge: "hover:outline-[2.5px]", + }; + + const focusStyles = + "focus:shadow-[0_0_10px_1px_#FFFDD2] focus:outline-none focus:ring-1 focus:ring-[var(--color-content-default-brand-primary)] focus:ring-offset-1 focus:scale-[1.02]"; + + const baseStyles = `inline-flex items-center justify-start box-border ${sizeStyles[size]} rounded-[var(--radius-measures-radius-full)] ${fontStyles[size]} transition-all duration-200 ease-in-out cursor-pointer ${variantStyles[variant]} ${hoverOutlineStyles[size]} ${focusStyles}`; + + let finalVariant = variant; + if (disabled) { + finalVariant = "default"; + } + + const combinedStyles = `${baseStyles} ${className}`; + + const accessibilityProps = { + ...(ariaLabel && { "aria-label": ariaLabel }), + ...(disabled && { "aria-disabled": "true" }), + ...(target && { target }), + ...(rel && { rel }), + tabIndex: disabled ? -1 : 0, + ...props, + }; + + if (href && !disabled) { + return ( + + {children} + + ); + } + + return ( + + ); +} diff --git a/app/components/Header.js b/app/components/Header.js new file mode 100644 index 0000000..0720f01 --- /dev/null +++ b/app/components/Header.js @@ -0,0 +1,177 @@ +import Logo from "./Logo"; +import MenuBar from "./MenuBar"; +import MenuBarItem from "./MenuBarItem"; +import Button from "./Button"; +import AvatarContainer from "./AvatarContainer"; +import Avatar from "./Avatar"; + +export default function Header({ onToggle }) { + const navigationItems = [ + { href: "#", text: "Use cases", extraPadding: true }, + { href: "#", text: "Learn" }, + { href: "#", text: "About" }, + ]; + + const avatarImages = [ + { src: "/assets/Avatar_1.png", alt: "Avatar 1" }, + { src: "/assets/Avatar_2.png", alt: "Avatar 2" }, + { src: "/assets/Avatar_3.png", alt: "Avatar 3" }, + ]; + + const logoConfig = [ + { breakpoint: "block sm:hidden", size: "header", showText: false }, + { breakpoint: "hidden sm:block md:hidden", size: "header", showText: true }, + { + breakpoint: "hidden md:block lg:hidden", + size: "headerMd", + showText: true, + }, + { + breakpoint: "hidden lg:block xl:hidden", + size: "headerLg", + showText: true, + }, + { breakpoint: "hidden xl:block", size: "headerXl", showText: true }, + ]; + + const renderNavigationItems = (size) => { + return navigationItems.map((item, index) => ( + + {item.text} + + )); + }; + + const renderAvatarGroup = (containerSize, avatarSize) => { + return ( + + {avatarImages.map((avatar, index) => ( + + ))} + + ); + }; + + const renderLoginButton = (size) => { + return ( + + Log in + + ); + }; + + const renderCreateRuleButton = (buttonSize, containerSize, avatarSize) => { + return ( + + ); + }; + + const renderLogo = (size, showText) => { + return ; + }; + + return ( +
+ +
+ ); +} diff --git a/app/components/HeaderTab.js b/app/components/HeaderTab.js new file mode 100644 index 0000000..262add2 --- /dev/null +++ b/app/components/HeaderTab.js @@ -0,0 +1,34 @@ +export default function HeaderTab({ + children, + className = "", + stretch = false, + ...props +}) { + const stretchClasses = stretch + ? "flex-1 sm:mr-[var(--spacing-scale-008)] md:mr-[185px] lg:mr-[var(--spacing-scale-024)] xl:mr-[var(--spacing-scale-032)]" + : ""; + + return ( +
+ {children} + Union + Union + Union +
+ ); +} diff --git a/app/components/HomeHeader.js b/app/components/HomeHeader.js new file mode 100644 index 0000000..5832af7 --- /dev/null +++ b/app/components/HomeHeader.js @@ -0,0 +1,229 @@ +"use client"; + +import { useState } from "react"; +import Logo from "./Logo"; +import MenuBar from "./MenuBar"; +import MenuBarItem from "./MenuBarItem"; +import Button from "./Button"; +import AvatarContainer from "./AvatarContainer"; +import Avatar from "./Avatar"; +import HeaderTab from "./HeaderTab"; +import Header from "./Header"; + +export default function HomeHeader() { + const [showRegularHeader, setShowRegularHeader] = useState(false); + + const navigationItems = [ + { href: "#", text: "Use cases", extraPadding: true }, + { href: "#", text: "Learn" }, + { href: "#", text: "About" }, + ]; + + const avatarImages = [ + { src: "/assets/Avatar_1.png", alt: "Avatar 1" }, + { src: "/assets/Avatar_2.png", alt: "Avatar 2" }, + { src: "/assets/Avatar_3.png", alt: "Avatar 3" }, + ]; + + const logoConfig = [ + { + breakpoint: "block sm:hidden", + size: "homeHeaderXsmall", + showText: false, + }, + { + breakpoint: "hidden sm:block md:hidden", + size: "homeHeaderSm", + showText: true, + }, + { + breakpoint: "hidden md:block lg:hidden", + size: "homeHeaderMd", + showText: true, + }, + { + breakpoint: "hidden lg:block xl:hidden", + size: "homeHeaderLg", + showText: true, + }, + { breakpoint: "hidden xl:block", size: "homeHeaderXl", showText: true }, + ]; + + const renderNavigationItems = (size) => { + return navigationItems.map((item, index) => ( + setShowRegularHeader(!showRegularHeader)} + ariaLabel={`Navigate to ${item.text} page`} + > + {item.text} + + )); + }; + + const renderAvatarGroup = (containerSize, avatarSize) => { + return ( + + {avatarImages.map((avatar, index) => ( + + ))} + + ); + }; + + const renderLoginButton = (size) => { + return ( + + Log in + + ); + }; + + const renderCreateRuleButton = (buttonSize, containerSize, avatarSize) => { + return ( + + ); + }; + + const renderLogo = (size, showText) => { + return ; + }; + + if (showRegularHeader) { + return
setShowRegularHeader(false)} />; + } + + return ( +
+ +
+ ); +} diff --git a/app/components/Logo.js b/app/components/Logo.js index e26070f..382ae0c 100644 --- a/app/components/Logo.js +++ b/app/components/Logo.js @@ -1,4 +1,4 @@ -export default function Logo({ size = "default" }) { +export default function Logo({ size = "default", showText = true }) { // Size configurations const sizes = { default: { @@ -8,6 +8,69 @@ export default function Logo({ size = "default" }) { lineHeight: "leading-[27.05px]", iconSize: "w-[27.05px] h-[27.05px]", }, + homeHeaderXsmall: { + containerHeight: "h-[14.11px]", + gap: "gap-[4.21px]", + textSize: "text-[11.57px]", + lineHeight: "leading-[14.24px]", + iconSize: "w-[14.11px] h-[14.11px]", + }, + homeHeaderSm: { + containerHeight: "h-[21.06px]", + gap: "gap-[3.19px]", + textSize: "text-[11.69px]", + lineHeight: "leading-[14.39px]", + iconSize: "w-[14.39px] h-[14.39px]", + }, + homeHeaderMd: { + containerHeight: "h-[32.24px]", + gap: "gap-[4.89px]", + textSize: "text-[17.89px]", + lineHeight: "leading-[22.02px]", + iconSize: "w-[22.02px] h-[22.02px]", + }, + homeHeaderLg: { + containerHeight: "h-[28px]", + gap: "gap-[6.55px]", + textSize: "text-[21.97px]", + lineHeight: "leading-[27.05px]", + iconSize: "w-[27.05px] h-[27.05px]", + }, + homeHeaderXl: { + containerHeight: "h-[36px]", + gap: "gap-[8.64px]", + textSize: "text-[29.01px]", + lineHeight: "leading-[35.7px]", + iconSize: "w-[35.7px] h-[35.7px]", + }, + header: { + containerHeight: "h-[20.85px]", + gap: "gap-[4.21px]", + textSize: "text-[11.57px]", + lineHeight: "leading-[14.24px]", + iconSize: "w-[14.24px] h-[14.24px]", + }, + headerMd: { + containerHeight: "h-[17.91px]", + gap: "gap-[6.51px]", + textSize: "text-[17.89px]", + lineHeight: "leading-[22.02px]", + iconSize: "w-[22.02px] h-[22.02px]", + }, + headerLg: { + containerHeight: "h-[28px]", + gap: "gap-[6.55px]", + textSize: "text-[21.97px]", + lineHeight: "leading-[27.05px]", + iconSize: "w-[27.05px] h-[27.05px]", + }, + headerXl: { + containerHeight: "h-[34px]", + gap: "gap-[8.19px]", + textSize: "text-[27.47px]", + lineHeight: "leading-[33.81px]", + iconSize: "w-[33.81px] h-[33.81px]", + }, footer: { containerHeight: "h-[calc(40px*1.37)]", gap: "gap-[calc(8px*1.37)]", @@ -25,7 +88,25 @@ export default function Logo({ size = "default" }) { }; const config = - size === "footer" + size === "homeHeaderXsmall" + ? sizes.homeHeaderXsmall + : size === "homeHeaderSm" + ? sizes.homeHeaderSm + : size === "homeHeaderMd" + ? sizes.homeHeaderMd + : size === "homeHeaderLg" + ? sizes.homeHeaderLg + : size === "homeHeaderXl" + ? sizes.homeHeaderXl + : size === "header" + ? sizes.header + : size === "headerMd" + ? sizes.headerMd + : size === "headerLg" + ? sizes.headerLg + : size === "headerXl" + ? sizes.headerXl + : size === "footer" ? sizes.footer : size === "footerLg" ? sizes.footerLg @@ -33,14 +114,31 @@ export default function Logo({ size = "default" }) { return (
- {/* Logo Text */} -
- CommunityRule -
+ {/* Logo Text - only show if showText is true */} + {showText && ( +
+ CommunityRule +
+ )} {/* Vector Icon */}
); diff --git a/app/components/MenuBar.js b/app/components/MenuBar.js new file mode 100644 index 0000000..275d6d3 --- /dev/null +++ b/app/components/MenuBar.js @@ -0,0 +1,30 @@ +export default function MenuBar({ + children, + className = "", + size = "default", + ...props +}) { + const sizeStyles = { + xsmall: + "px-[var(--spacing-scale-004)] py-[var(--spacing-scale-004)] gap-[var(--spacing-scale-001)] rounded-[4px]", + default: + "px-[var(--spacing-scale-004)] py-[var(--spacing-scale-004)] gap-[var(--spacing-scale-001)]", + medium: + "px-[var(--spacing-scale-004)] py-[var(--spacing-scale-004)] gap-[var(--spacing-scale-004)]", + large: + "px-[var(--spacing-scale-004)] py-[var(--spacing-scale-004)] gap-[var(--spacing-scale-012)]", + }; + + const baseStyles = `flex items-center ${sizeStyles[size]} ${className}`; + + return ( + + ); +} diff --git a/app/components/MenuBarItem.js b/app/components/MenuBarItem.js new file mode 100644 index 0000000..827776f --- /dev/null +++ b/app/components/MenuBarItem.js @@ -0,0 +1,136 @@ +export default function MenuBarItem({ + href = "#", + children, + variant = "default", + size = "default", + className = "", + disabled = false, + ariaLabel, + ...props +}) { + const variantStyles = { + default: + "bg-transparent text-[var(--color-content-default-brand-primary)] hover:bg-[var(--color-surface-default-tertiary)] hover:text-[var(--color-content-default-brand-primary)] hover:scale-[1.02] active:bg-transparent active:text-[var(--color-content-default-brand-primary)] active:scale-[0.98] disabled:bg-[var(--color-surface-default-tertiary)] disabled:text-[var(--color-content-default-tertiary)] disabled:opacity-50 disabled:cursor-not-allowed disabled:hover:scale-100 disabled:active:scale-100", + home: "bg-transparent text-[var(--color-content-inverse-primary)] hover:bg-[var(--color-content-default-brand-accent)] hover:text-[var(--color-content-inverse-primary)] hover:scale-[1.02] active:bg-transparent active:text-[var(--color-content-inverse-primary)] active:scale-[0.98] disabled:bg-[var(--color-surface-default-tertiary)] disabled:text-[var(--color-content-default-tertiary)] disabled:opacity-50 disabled:cursor-not-allowed disabled:hover:scale-100 disabled:active:scale-100", + }; + + const activeOutlineStyles = { + xsmall: + "active:outline-1 active:outline-[var(--color-content-default-primary)] focus:outline-1 focus:outline-[var(--color-content-default-primary)]", + xsmallUseCases: + "active:outline-1 active:outline-[var(--color-content-default-primary)] focus:outline-1 focus:outline-[var(--color-content-default-primary)]", + default: + "active:outline-1 active:outline-[var(--color-content-default-brand-primary)] focus:outline-1 focus:outline-[var(--color-content-default-brand-primary)]", + homeMd: + "active:outline-[1.5px] active:outline-[var(--color-content-default-brand-primary)] focus:outline-[1.5px] focus:outline-[var(--color-content-default-brand-primary)]", + homeUseCases: + "active:outline-[1.5px] active:outline-[var(--color-content-default-brand-primary)] focus:outline-[1.5px] focus:outline-[var(--color-content-default-brand-primary)]", + large: + "active:outline-[1.75px] active:outline-[var(--color-content-default-brand-primary)] focus:outline-[1.75px] focus:outline-[var(--color-content-default-brand-primary)]", + largeUseCases: + "active:outline-[1.75px] active:outline-[var(--color-content-default-brand-primary)] focus:outline-[1.75px] focus:outline-[var(--color-content-default-brand-primary)]", + homeXlarge: + "active:outline-[2px] active:outline-[var(--color-content-default-brand-primary)] focus:outline-[2px] focus:outline-[var(--color-content-default-brand-primary)]", + xlarge: + "active:outline-2 active:outline-[var(--color-content-default-brand-primary)] focus:outline-2 focus:outline-[var(--color-content-default-brand-primary)]", + }; + + const homeOutlineStyles = { + xsmall: + "active:outline-1 active:outline-[var(--color-content-default-primary)] focus:outline-1 focus:outline-[var(--color-content-default-primary)]", + xsmallUseCases: + "active:outline-1 active:outline-[var(--color-content-default-primary)] focus:outline-1 focus:outline-[var(--color-content-default-primary)]", + default: + "active:outline-[1.5px] active:outline-[var(--color-content-default-primary)] focus:outline-[1.5px] focus:outline-[var(--color-content-default-primary)]", + homeMd: + "active:outline-[1.5px] active:outline-[var(--color-content-default-primary)] focus:outline-[1.5px] focus:outline-[var(--color-content-default-primary)]", + homeUseCases: + "active:outline-[1.5px] active:outline-[var(--color-content-default-primary)] focus:outline-[1.5px] focus:outline-[var(--color-content-default-primary)]", + largeUseCases: + "active:outline-[1.75px] active:outline-[var(--color-content-default-primary)] focus:outline-[1.75px] focus:outline-[var(--color-content-default-primary)]", + large: + "active:outline-[1.75px] active:outline-[var(--color-content-default-primary)] focus:outline-[1.75px] focus:outline-[var(--color-content-default-primary)]", + homeXlarge: + "active:outline-[2px] active:outline-[var(--color-content-default-primary)] focus:outline-[2px] focus:outline-[var(--color-content-default-primary)]", + xlarge: + "active:outline-2 active:outline-[var(--color-content-default-primary)] focus:outline-2 focus:outline-[var(--color-content-default-primary)]", + }; + + const sizeStyles = { + default: + "px-[var(--spacing-measures-spacing-016)] py-[var(--spacing-measures-spacing-016)] gap-[var(--spacing-scale-004)]", + xsmall: + "px-[var(--spacing-scale-004)] py-[var(--spacing-scale-002)] gap-[var(--spacing-scale-004)]", + xsmallUseCases: + "px-[var(--spacing-scale-002)] py-[var(--spacing-scale-002)] gap-[var(--spacing-scale-004)]", + homeMd: + "px-[var(--spacing-scale-008)] py-[var(--spacing-scale-008)] gap-[var(--spacing-scale-004)]", + homeUseCases: + "px-[var(--spacing-scale-002)] py-[var(--spacing-scale-008)] gap-[var(--spacing-scale-004)]", + large: + "px-[var(--spacing-scale-012)] py-[var(--spacing-scale-012)] gap-[var(--spacing-scale-004)] h-[44px]", + largeUseCases: + "px-[var(--spacing-scale-012)] py-[var(--spacing-scale-012)] gap-[var(--spacing-scale-004)] h-[44px]", + homeXlarge: + "px-[var(--spacing-scale-016)] py-[var(--spacing-scale-016)] gap-[var(--spacing-scale-004)] h-[44px]", + xlarge: + "px-[var(--spacing-scale-016)] py-[var(--spacing-scale-008)] gap-[var(--spacing-scale-004)] h-[44px]", + }; + + const smallTextStyle = + "font-['Inter'] text-[10px] leading-[12px] font-medium tracking-[0%]"; + const mediumTextStyle = + "font-['Inter'] text-[12px] leading-[14px] font-medium tracking-[0%]"; + const largeTextStyle = + "font-['Inter'] text-[16px] leading-[20px] font-medium tracking-[0%]"; + const xlargeTextStyle = + "font-['Inter'] text-[24px] leading-[28px] font-normal tracking-[0%]"; + + const textStyles = { + default: smallTextStyle, + xsmall: smallTextStyle, + xsmallUseCases: smallTextStyle, + home: smallTextStyle, + homeMd: mediumTextStyle, + homeUseCases: mediumTextStyle, + large: largeTextStyle, + largeUseCases: largeTextStyle, + homeXlarge: xlargeTextStyle, + xlarge: xlargeTextStyle, + }; + + const baseStyles = `inline-flex items-center ${sizeStyles[size]} rounded-[var(--radius-measures-radius-full)] ${textStyles[size]} transition-all duration-200 ease-in-out cursor-pointer focus:scale-[1.02]`; + + let finalVariant = variant; + if (disabled) { + finalVariant = "default"; + } + + const combinedStyles = `${baseStyles} ${variantStyles[finalVariant]} ${ + finalVariant === "home" + ? homeOutlineStyles[size] + : activeOutlineStyles[size] + } ${className}`; + + const accessibilityProps = { + ...(ariaLabel && { "aria-label": ariaLabel }), + ...(disabled && { "aria-disabled": "true" }), + role: "menuitem", + tabIndex: disabled ? -1 : 0, + ...props, + }; + + if (disabled) { + return ( + + {children} + + ); + } + + return ( + + {children} + + ); +} diff --git a/app/components/NavigationItem.js b/app/components/NavigationItem.js new file mode 100644 index 0000000..6d6f545 --- /dev/null +++ b/app/components/NavigationItem.js @@ -0,0 +1,55 @@ +export default function NavigationItem({ + href = "#", + children, + variant = "default", + size = "default", + className = "", + disabled = false, + ...props +}) { + // Variant styles + const variantStyles = { + default: + "bg-transparent text-[var(--color-content-default-brand-primary)] border border-transparent hover:bg-[var(--color-surface-default-tertiary)] hover:text-[var(--color-content-default-brand-primary)] active:bg-transparent active:text-[var(--color-content-default-brand-primary)] active:border-[var(--color-content-default-brand-primary)] disabled:bg-[var(--color-surface-default-tertiary)] disabled:text-[var(--color-content-default-tertiary)] disabled:border-[var(--color-content-default-tertiary)] disabled:opacity-50 disabled:cursor-not-allowed", + }; + + // Size styles + const sizeStyles = { + default: + "px-[var(--spacing-measures-spacing-016)] py-[var(--spacing-measures-spacing-016)] gap-[var(--spacing-scale-004)]", + xsmall: + "px-[var(--spacing-scale-004)] py-[var(--spacing-scale-002)] gap-[var(--spacing-scale-004)]", + }; + + // Text styles based on size + const textStyles = { + default: + "font-['Inter'] text-[10px] leading-[12px] font-medium tracking-[0%]", + xsmall: + "font-['Inter'] text-[10px] leading-[12px] font-medium tracking-[0%]", + }; + + const baseStyles = `inline-flex items-center ${sizeStyles[size]} rounded-[var(--radius-measures-radius-full)] ${textStyles[size]} transition-all duration-200 cursor-pointer`; + + // Determine which variant to use + let finalVariant = variant; + if (disabled) { + finalVariant = "default"; // The disabled state is handled by disabled: utilities + } + + const combinedStyles = `${baseStyles} ${variantStyles[finalVariant]} ${className}`; + + if (disabled) { + return ( + + {children} + + ); + } + + return ( + + {children} + + ); +} diff --git a/app/globals.css b/app/globals.css index f1d8c73..320e1b9 100644 --- a/app/globals.css +++ b/app/globals.css @@ -1 +1,9 @@ -@import "tailwindcss"; +@tailwind base; +@tailwind components; +@tailwind utilities; +@import "./tailwind.css"; + +body { + background-color: black; + min-height: 100vh; +} diff --git a/app/layout.js b/app/layout.js index 668759b..e36ac0e 100644 --- a/app/layout.js +++ b/app/layout.js @@ -1,11 +1,11 @@ import { Inter, Bricolage_Grotesque } from "next/font/google"; import "./globals.css"; -import "./tailwind.css"; +import HomeHeader from "./components/HomeHeader"; import Footer from "./components/Footer"; const inter = Inter({ subsets: ["latin"], - weight: ["400"], + weight: ["400", "500"], variable: "--font-inter", }); @@ -20,6 +20,7 @@ export default function RootLayout({ children }) {
+
{children}
diff --git a/app/page.js b/app/page.js index 7d1e0b7..b68b686 100644 --- a/app/page.js +++ b/app/page.js @@ -1,3 +1,3 @@ export default function Page() { - return <>; + return
{/* home page content will go here */}
; } diff --git a/app/tailwind.css b/app/tailwind.css index 07a9575..187e34e 100644 --- a/app/tailwind.css +++ b/app/tailwind.css @@ -6,6 +6,12 @@ @import "tailwindcss"; @theme inline { + /* Custom breakpoints */ + --breakpoint-xsm: 429px; + --breakpoint-sm: 430px; + --breakpoint-md: 640px; + --breakpoint-lg: 1024px; + --breakpoint-xl: 1440px; /* Reset default Tailwind configuration */ --color-*: initial; diff --git a/eslint.config.mjs b/eslint.config.mjs index 348c45a..a3f3f2d 100644 --- a/eslint.config.mjs +++ b/eslint.config.mjs @@ -9,6 +9,12 @@ const compat = new FlatCompat({ baseDirectory: __dirname, }); -const eslintConfig = [...compat.extends("next/core-web-vitals")]; +const eslintConfig = [ + ...compat.extends("next/core-web-vitals"), + { + files: ["**/*.js", "**/*.jsx", "**/*.mjs"], + ignores: ["**/*.ts", "**/*.tsx"], + }, +]; export default eslintConfig; diff --git a/next.config.mjs b/next.config.mjs index 4678774..d55e0fc 100644 --- a/next.config.mjs +++ b/next.config.mjs @@ -1,4 +1,8 @@ /** @type {import('next').NextConfig} */ -const nextConfig = {}; +const nextConfig = { + eslint: { + ignoreDuringBuilds: true, + }, +}; export default nextConfig; diff --git a/package-lock.json b/package-lock.json index 46d0cfe..f1b5fc4 100644 --- a/package-lock.json +++ b/package-lock.json @@ -18,6 +18,7 @@ "@tailwindcss/postcss": "^4.1.11", "eslint": "^9", "eslint-config-next": "15.2.4", + "postcss": "^8.5.6", "tailwindcss": "^4.0.0" } }, @@ -1244,17 +1245,17 @@ "license": "MIT" }, "node_modules/@typescript-eslint/eslint-plugin": { - "version": "8.38.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.38.0.tgz", - "integrity": "sha512-CPoznzpuAnIOl4nhj4tRr4gIPj5AfKgkiJmGQDaq+fQnRJTYlcBjbX3wbciGmpoPf8DREufuPRe1tNMZnGdanA==", + "version": "8.39.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.39.0.tgz", + "integrity": "sha512-bhEz6OZeUR+O/6yx9Jk6ohX6H9JSFTaiY0v9/PuKT3oGK0rn0jNplLmyFUGV+a9gfYnVNwGDwS/UkLIuXNb2Rw==", "dev": true, "license": "MIT", "dependencies": { "@eslint-community/regexpp": "^4.10.0", - "@typescript-eslint/scope-manager": "8.38.0", - "@typescript-eslint/type-utils": "8.38.0", - "@typescript-eslint/utils": "8.38.0", - "@typescript-eslint/visitor-keys": "8.38.0", + "@typescript-eslint/scope-manager": "8.39.0", + "@typescript-eslint/type-utils": "8.39.0", + "@typescript-eslint/utils": "8.39.0", + "@typescript-eslint/visitor-keys": "8.39.0", "graphemer": "^1.4.0", "ignore": "^7.0.0", "natural-compare": "^1.4.0", @@ -1268,9 +1269,9 @@ "url": "https://opencollective.com/typescript-eslint" }, "peerDependencies": { - "@typescript-eslint/parser": "^8.38.0", + "@typescript-eslint/parser": "^8.39.0", "eslint": "^8.57.0 || ^9.0.0", - "typescript": ">=4.8.4 <5.9.0" + "typescript": ">=4.8.4 <6.0.0" } }, "node_modules/@typescript-eslint/eslint-plugin/node_modules/ignore": { @@ -1284,16 +1285,16 @@ } }, "node_modules/@typescript-eslint/parser": { - "version": "8.38.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.38.0.tgz", - "integrity": "sha512-Zhy8HCvBUEfBECzIl1PKqF4p11+d0aUJS1GeUiuqK9WmOug8YCmC4h4bjyBvMyAMI9sbRczmrYL5lKg/YMbrcQ==", + "version": "8.39.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.39.0.tgz", + "integrity": "sha512-g3WpVQHngx0aLXn6kfIYCZxM6rRJlWzEkVpqEFLT3SgEDsp9cpCbxxgwnE504q4H+ruSDh/VGS6nqZIDynP+vg==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/scope-manager": "8.38.0", - "@typescript-eslint/types": "8.38.0", - "@typescript-eslint/typescript-estree": "8.38.0", - "@typescript-eslint/visitor-keys": "8.38.0", + "@typescript-eslint/scope-manager": "8.39.0", + "@typescript-eslint/types": "8.39.0", + "@typescript-eslint/typescript-estree": "8.39.0", + "@typescript-eslint/visitor-keys": "8.39.0", "debug": "^4.3.4" }, "engines": { @@ -1305,18 +1306,18 @@ }, "peerDependencies": { "eslint": "^8.57.0 || ^9.0.0", - "typescript": ">=4.8.4 <5.9.0" + "typescript": ">=4.8.4 <6.0.0" } }, "node_modules/@typescript-eslint/project-service": { - "version": "8.38.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/project-service/-/project-service-8.38.0.tgz", - "integrity": "sha512-dbK7Jvqcb8c9QfH01YB6pORpqX1mn5gDZc9n63Ak/+jD67oWXn3Gs0M6vddAN+eDXBCS5EmNWzbSxsn9SzFWWg==", + "version": "8.39.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/project-service/-/project-service-8.39.0.tgz", + "integrity": "sha512-CTzJqaSq30V/Z2Og9jogzZt8lJRR5TKlAdXmWgdu4hgcC9Kww5flQ+xFvMxIBWVNdxJO7OifgdOK4PokMIWPew==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/tsconfig-utils": "^8.38.0", - "@typescript-eslint/types": "^8.38.0", + "@typescript-eslint/tsconfig-utils": "^8.39.0", + "@typescript-eslint/types": "^8.39.0", "debug": "^4.3.4" }, "engines": { @@ -1327,18 +1328,18 @@ "url": "https://opencollective.com/typescript-eslint" }, "peerDependencies": { - "typescript": ">=4.8.4 <5.9.0" + "typescript": ">=4.8.4 <6.0.0" } }, "node_modules/@typescript-eslint/scope-manager": { - "version": "8.38.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.38.0.tgz", - "integrity": "sha512-WJw3AVlFFcdT9Ri1xs/lg8LwDqgekWXWhH3iAF+1ZM+QPd7oxQ6jvtW/JPwzAScxitILUIFs0/AnQ/UWHzbATQ==", + "version": "8.39.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.39.0.tgz", + "integrity": "sha512-8QOzff9UKxOh6npZQ/4FQu4mjdOCGSdO3p44ww0hk8Vu+IGbg0tB/H1LcTARRDzGCC8pDGbh2rissBuuoPgH8A==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/types": "8.38.0", - "@typescript-eslint/visitor-keys": "8.38.0" + "@typescript-eslint/types": "8.39.0", + "@typescript-eslint/visitor-keys": "8.39.0" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -1349,9 +1350,9 @@ } }, "node_modules/@typescript-eslint/tsconfig-utils": { - "version": "8.38.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/tsconfig-utils/-/tsconfig-utils-8.38.0.tgz", - "integrity": "sha512-Lum9RtSE3EroKk/bYns+sPOodqb2Fv50XOl/gMviMKNvanETUuUcC9ObRbzrJ4VSd2JalPqgSAavwrPiPvnAiQ==", + "version": "8.39.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/tsconfig-utils/-/tsconfig-utils-8.39.0.tgz", + "integrity": "sha512-Fd3/QjmFV2sKmvv3Mrj8r6N8CryYiCS8Wdb/6/rgOXAWGcFuc+VkQuG28uk/4kVNVZBQuuDHEDUpo/pQ32zsIQ==", "dev": true, "license": "MIT", "engines": { @@ -1362,19 +1363,19 @@ "url": "https://opencollective.com/typescript-eslint" }, "peerDependencies": { - "typescript": ">=4.8.4 <5.9.0" + "typescript": ">=4.8.4 <6.0.0" } }, "node_modules/@typescript-eslint/type-utils": { - "version": "8.38.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-8.38.0.tgz", - "integrity": "sha512-c7jAvGEZVf0ao2z+nnz8BUaHZD09Agbh+DY7qvBQqLiz8uJzRgVPj5YvOh8I8uEiH8oIUGIfHzMwUcGVco/SJg==", + "version": "8.39.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-8.39.0.tgz", + "integrity": "sha512-6B3z0c1DXVT2vYA9+z9axjtc09rqKUPRmijD5m9iv8iQpHBRYRMBcgxSiKTZKm6FwWw1/cI4v6em35OsKCiN5Q==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/types": "8.38.0", - "@typescript-eslint/typescript-estree": "8.38.0", - "@typescript-eslint/utils": "8.38.0", + "@typescript-eslint/types": "8.39.0", + "@typescript-eslint/typescript-estree": "8.39.0", + "@typescript-eslint/utils": "8.39.0", "debug": "^4.3.4", "ts-api-utils": "^2.1.0" }, @@ -1387,13 +1388,13 @@ }, "peerDependencies": { "eslint": "^8.57.0 || ^9.0.0", - "typescript": ">=4.8.4 <5.9.0" + "typescript": ">=4.8.4 <6.0.0" } }, "node_modules/@typescript-eslint/types": { - "version": "8.38.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.38.0.tgz", - "integrity": "sha512-wzkUfX3plUqij4YwWaJyqhiPE5UCRVlFpKn1oCRn2O1bJ592XxWJj8ROQ3JD5MYXLORW84063z3tZTb/cs4Tyw==", + "version": "8.39.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.39.0.tgz", + "integrity": "sha512-ArDdaOllnCj3yn/lzKn9s0pBQYmmyme/v1HbGIGB0GB/knFI3fWMHloC+oYTJW46tVbYnGKTMDK4ah1sC2v0Kg==", "dev": true, "license": "MIT", "engines": { @@ -1405,16 +1406,16 @@ } }, "node_modules/@typescript-eslint/typescript-estree": { - "version": "8.38.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.38.0.tgz", - "integrity": "sha512-fooELKcAKzxux6fA6pxOflpNS0jc+nOQEEOipXFNjSlBS6fqrJOVY/whSn70SScHrcJ2LDsxWrneFoWYSVfqhQ==", + "version": "8.39.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.39.0.tgz", + "integrity": "sha512-ndWdiflRMvfIgQRpckQQLiB5qAKQ7w++V4LlCHwp62eym1HLB/kw7D9f2e8ytONls/jt89TEasgvb+VwnRprsw==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/project-service": "8.38.0", - "@typescript-eslint/tsconfig-utils": "8.38.0", - "@typescript-eslint/types": "8.38.0", - "@typescript-eslint/visitor-keys": "8.38.0", + "@typescript-eslint/project-service": "8.39.0", + "@typescript-eslint/tsconfig-utils": "8.39.0", + "@typescript-eslint/types": "8.39.0", + "@typescript-eslint/visitor-keys": "8.39.0", "debug": "^4.3.4", "fast-glob": "^3.3.2", "is-glob": "^4.0.3", @@ -1430,7 +1431,7 @@ "url": "https://opencollective.com/typescript-eslint" }, "peerDependencies": { - "typescript": ">=4.8.4 <5.9.0" + "typescript": ">=4.8.4 <6.0.0" } }, "node_modules/@typescript-eslint/typescript-estree/node_modules/brace-expansion": { @@ -1490,16 +1491,16 @@ } }, "node_modules/@typescript-eslint/utils": { - "version": "8.38.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.38.0.tgz", - "integrity": "sha512-hHcMA86Hgt+ijJlrD8fX0j1j8w4C92zue/8LOPAFioIno+W0+L7KqE8QZKCcPGc/92Vs9x36w/4MPTJhqXdyvg==", + "version": "8.39.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.39.0.tgz", + "integrity": "sha512-4GVSvNA0Vx1Ktwvf4sFE+exxJ3QGUorQG1/A5mRfRNZtkBT2xrA/BCO2H0eALx/PnvCS6/vmYwRdDA41EoffkQ==", "dev": true, "license": "MIT", "dependencies": { "@eslint-community/eslint-utils": "^4.7.0", - "@typescript-eslint/scope-manager": "8.38.0", - "@typescript-eslint/types": "8.38.0", - "@typescript-eslint/typescript-estree": "8.38.0" + "@typescript-eslint/scope-manager": "8.39.0", + "@typescript-eslint/types": "8.39.0", + "@typescript-eslint/typescript-estree": "8.39.0" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -1510,17 +1511,17 @@ }, "peerDependencies": { "eslint": "^8.57.0 || ^9.0.0", - "typescript": ">=4.8.4 <5.9.0" + "typescript": ">=4.8.4 <6.0.0" } }, "node_modules/@typescript-eslint/visitor-keys": { - "version": "8.38.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.38.0.tgz", - "integrity": "sha512-pWrTcoFNWuwHlA9CvlfSsGWs14JxfN1TH25zM5L7o0pRLhsoZkDnTsXfQRJBEWJoV5DL0jf+Z+sxiud+K0mq1g==", + "version": "8.39.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.39.0.tgz", + "integrity": "sha512-ldgiJ+VAhQCfIjeOgu8Kj5nSxds0ktPOSO9p4+0VDH2R2pLvQraaM5Oen2d7NxzMCm+Sn/vJT+mv2H5u6b/3fA==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/types": "8.38.0", + "@typescript-eslint/types": "8.39.0", "eslint-visitor-keys": "^4.2.1" }, "engines": { @@ -2476,9 +2477,9 @@ "license": "MIT" }, "node_modules/enhanced-resolve": { - "version": "5.18.2", - "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.18.2.tgz", - "integrity": "sha512-6Jw4sE1maoRJo3q8MsSIn2onJFbLTOjY9hlx4DZXmOKvLRd1Ok2kXmAGXaafL2+ijsJZ1ClYbl/pmqr9+k4iUQ==", + "version": "5.18.3", + "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.18.3.tgz", + "integrity": "sha512-d4lC8xfavMeBjzGr2vECC3fsGXziXZQyJxD868h2M/mBI3PwAuODxAkLkq5HYuvrPYcUtiLzsTo8U3PgX3Ocww==", "dev": true, "license": "MIT", "dependencies": { diff --git a/package.json b/package.json index 3669805..ac880e0 100644 --- a/package.json +++ b/package.json @@ -19,6 +19,7 @@ "@tailwindcss/postcss": "^4.1.11", "eslint": "^9", "eslint-config-next": "15.2.4", + "postcss": "^8.5.6", "tailwindcss": "^4.0.0" } } diff --git a/postcss.config.mjs b/postcss.config.mjs index c7bcb4b..2df6729 100644 --- a/postcss.config.mjs +++ b/postcss.config.mjs @@ -1,5 +1,6 @@ -const config = { - plugins: ["@tailwindcss/postcss"], +/** @type {import('postcss-load-config').Config} */ +export default { + plugins: { + "@tailwindcss/postcss": {}, + }, }; - -export default config; diff --git a/public/assets/Avatar_1.png b/public/assets/Avatar_1.png new file mode 100644 index 0000000..30ab710 Binary files /dev/null and b/public/assets/Avatar_1.png differ diff --git a/public/assets/Avatar_2.png b/public/assets/Avatar_2.png new file mode 100644 index 0000000..2127a01 Binary files /dev/null and b/public/assets/Avatar_2.png differ diff --git a/public/assets/Avatar_3.png b/public/assets/Avatar_3.png new file mode 100644 index 0000000..bcb56a6 Binary files /dev/null and b/public/assets/Avatar_3.png differ diff --git a/public/assets/Union.svg b/public/assets/Union.svg new file mode 100644 index 0000000..3d996ec --- /dev/null +++ b/public/assets/Union.svg @@ -0,0 +1,3 @@ + + + diff --git a/public/assets/Union_sm_md_lg.svg b/public/assets/Union_sm_md_lg.svg new file mode 100644 index 0000000..44bd233 --- /dev/null +++ b/public/assets/Union_sm_md_lg.svg @@ -0,0 +1,3 @@ + + + diff --git a/public/assets/Union_xlg.svg b/public/assets/Union_xlg.svg new file mode 100644 index 0000000..3d996ec --- /dev/null +++ b/public/assets/Union_xlg.svg @@ -0,0 +1,3 @@ + + + diff --git a/public/assets/Union_xsm.svg b/public/assets/Union_xsm.svg new file mode 100644 index 0000000..8583c9c --- /dev/null +++ b/public/assets/Union_xsm.svg @@ -0,0 +1,3 @@ + + +