Header #3

Merged
an.di merged 16 commits from adilallo/Header into main 2025-08-07 22:58:34 +00:00
26 changed files with 1029 additions and 84 deletions
+18
View File
@@ -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 <img src={src} alt={alt} className={baseStyles} {...props} />;
}
+21
View File
@@ -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 (
<div className={baseStyles} {...props}>
{children}
</div>
);
}
+96
View File
@@ -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 (
<a
href={href}
className={combinedStyles}
onClick={onClick}
{...accessibilityProps}
>
{children}
</a>
);
}
return (
<button
type={type}
className={combinedStyles}
disabled={disabled}
onClick={onClick}
{...accessibilityProps}
>
{children}
</button>
);
}
+177
View File
@@ -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) => (
<MenuBarItem
key={index}
href={item.href}
size={item.extraPadding && size === "xsmall" ? "xsmallUseCases" : size}
onClick={onToggle}
ariaLabel={`Navigate to ${item.text} page`}
>
{item.text}
</MenuBarItem>
));
};
const renderAvatarGroup = (containerSize, avatarSize) => {
return (
<AvatarContainer size={containerSize}>
{avatarImages.map((avatar, index) => (
<Avatar
key={index}
src={avatar.src}
alt={avatar.alt}
size={avatarSize}
/>
))}
</AvatarContainer>
);
};
const renderLoginButton = (size) => {
return (
<MenuBarItem href="#" size={size} ariaLabel="Log in to your account">
Log in
</MenuBarItem>
);
};
const renderCreateRuleButton = (buttonSize, containerSize, avatarSize) => {
return (
<Button
size={buttonSize}
ariaLabel="Create a new rule with avatar decoration"
>
{renderAvatarGroup(containerSize, avatarSize)}
<span>Create rule</span>
</Button>
);
};
const renderLogo = (size, showText) => {
return <Logo size={size} showText={showText} />;
};
return (
<header
className="bg-[var(--color-surface-default-primary)] w-full border-b border-[var(--border-color-default-tertiary)]"
role="banner"
aria-label="Main navigation header"
>
<nav
className="flex items-center justify-between mx-auto max-w-[1920px] h-[40px] lg:h-[84px] xl:h-[88px] px-[var(--spacing-measures-spacing-016)] py-[var(--spacing-measures-spacing-008)] lg:px-[var(--spacing-measures-spacing-64,64px)] lg:py-[var(--spacing-measures-spacing-016,16px)]"
role="navigation"
aria-label="Main navigation"
>
{/* Logo - Consistent left positioning across all breakpoints */}
<div className="flex items-center">
{logoConfig.map((config, index) => (
<div key={index} className={config.breakpoint}>
{renderLogo(config.size, config.showText)}
</div>
))}
</div>
{/* Navigation Links - Consistent center positioning */}
<div className="flex items-center">
<div className="block sm:hidden -me-[2px]">
<MenuBar size="default">{renderNavigationItems("xsmall")}</MenuBar>
</div>
<div className="hidden sm:block md:hidden">
<MenuBar size="default">{renderNavigationItems("xsmall")}</MenuBar>
</div>
<div className="hidden md:block lg:hidden">
<MenuBar size="default">{renderNavigationItems("xsmall")}</MenuBar>
</div>
<div className="hidden lg:block xl:hidden">
<MenuBar size="large">{renderNavigationItems("large")}</MenuBar>
</div>
<div className="hidden xl:block">
<MenuBar size="large">{renderNavigationItems("xlarge")}</MenuBar>
</div>
</div>
{/* Authentication Elements - Consistent right alignment across all breakpoints */}
<div className="flex items-center">
{/* XSmall and Small breakpoints */}
<div className="block sm:hidden">
<div className="flex items-center gap-[var(--spacing-scale-004)]">
{renderLoginButton("xsmall")}
{renderCreateRuleButton("xsmall", "small", "small")}
</div>
</div>
<div className="hidden sm:block md:hidden">
<div className="flex items-center gap-[var(--spacing-scale-004)]">
{renderLoginButton("xsmall")}
{renderCreateRuleButton("xsmall", "small", "small")}
</div>
</div>
{/* Medium breakpoint */}
<div className="hidden md:block lg:hidden">
<div className="flex items-center gap-[var(--spacing-measures-spacing-010)]">
{renderLoginButton("xsmall")}
{renderCreateRuleButton("xsmall", "medium", "medium")}
</div>
</div>
{/* Large breakpoint */}
<div className="hidden lg:block xl:hidden">
<div className="flex items-center gap-[var(--spacing-measures-spacing-004)]">
{renderLoginButton("large")}
{renderCreateRuleButton("large", "xlarge", "xlarge")}
</div>
</div>
{/* XLarge breakpoint */}
<div className="hidden xl:block">
<div className="flex items-center gap-[var(--spacing-measures-spacing-004)]">
{renderLoginButton("xlarge")}
{renderCreateRuleButton("xlarge", "xlarge", "xlarge")}
</div>
</div>
</div>
</nav>
</header>
);
}
+34
View File
@@ -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 (
<div
className={`HeaderTab header-breakpoint-transition relative bg-[var(--color-surface-default-brand-primary)] rounded-t-[32px] sm:rounded-t-[32px] md:rounded-t-[32px] lg:rounded-t-[32px] xl:rounded-t-[32px] pl-[var(--spacing-measures-spacing-012)] h-[40px] sm:h-[52px] md:h-[52px] lg:h-[52px] xl:h-[64px] sm:pr-[var(--spacing-scale-006)] md:pl-[var(--spacing-scale-024)] lg:pl-[var(--spacing-scale-024)] xl:pl-[var(--spacing-scale-032)] md:pr-[var(--spacing-scale-012)] lg:pr-[var(--spacing-scale-048)] xl:pr-[var(--spacing-scale-120)] md:gap-[var(--spacing-scale-032)] ${stretchClasses} ${className}`}
{...props}
>
{children}
<img
src="/assets/Union_xsm.svg"
alt="Union"
className="absolute -bottom-[3px] -right-[52px] w-[61px] h-[24px] sm:w-[61px] sm:h-[31.5px] sm:hidden -z-10"
/>
<img
src="/assets/Union_sm_md_lg.svg"
alt="Union"
className="absolute -bottom-[3.5px] -right-[53px] w-[61px] h-[24px] sm:w-[61px] sm:h-[31.5px] hidden sm:block xl:hidden -z-10"
/>
<img
src="/assets/Union_xlg.svg"
alt="Union"
className="absolute -bottom-[6px] -right-[94px] w-[105px] h-[53px] hidden xl:block -z-10"
/>
</div>
);
}
+229
View File
@@ -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) => (
<MenuBarItem
key={index}
href={item.href}
size={
item.extraPadding &&
(size === "xsmall" ||
size === "default" ||
size === "home" ||
size === "homeMd" ||
size === "large" ||
size === "homeXlarge")
? size === "home" || size === "homeMd"
? "homeMd"
: size === "large"
? "large"
: size === "homeXlarge"
? "homeXlarge"
: "xsmallUseCases"
: size
}
variant={
size === "xsmall" ||
size === "default" ||
size === "home" ||
size === "homeMd" ||
size === "large" ||
size === "homeXlarge"
? "home"
: "default"
}
onClick={() => setShowRegularHeader(!showRegularHeader)}
ariaLabel={`Navigate to ${item.text} page`}
>
{item.text}
</MenuBarItem>
));
};
const renderAvatarGroup = (containerSize, avatarSize) => {
return (
<AvatarContainer size={containerSize}>
{avatarImages.map((avatar, index) => (
<Avatar
key={index}
src={avatar.src}
alt={avatar.alt}
size={avatarSize}
/>
))}
</AvatarContainer>
);
};
const renderLoginButton = (size) => {
return (
<MenuBarItem
href="#"
size={size}
variant={size === "xsmall" || size === "default" ? "home" : "default"}
ariaLabel="Log in to your account"
>
Log in
</MenuBarItem>
);
};
const renderCreateRuleButton = (buttonSize, containerSize, avatarSize) => {
return (
<Button
size={buttonSize}
variant="secondary"
ariaLabel="Create a new rule with avatar decoration"
>
{renderAvatarGroup(containerSize, avatarSize)}
<span>Create rule</span>
</Button>
);
};
const renderLogo = (size, showText) => {
return <Logo size={size} showText={showText} />;
};
if (showRegularHeader) {
return <Header onToggle={() => setShowRegularHeader(false)} />;
}
return (
<header
className="w-full bg-transparent overflow-hidden"
role="banner"
aria-label="Home page navigation header"
>
<nav
className="relative flex items-center justify-between mx-auto max-w-[1920px] h-[50px] sm:h-[62px] md:h-[68px] lg:h-[68px] xl:h-[88px] px-[var(--spacing-scale-008)] pr-[var(--spacing-scale-016)] pt-[var(--spacing-scale-010)] sm:px-[var(--spacing-scale-010)] sm:pr-[var(--spacing-scale-020)] sm:pt-[var(--spacing-scale-010)] md:px-[var(--spacing-scale-016)] md:pr-[var(--spacing-scale-032)] md:pt-[var(--spacing-scale-016)] lg:pl-[var(--spacing-scale-024)] lg:pt-[var(--spacing-scale-016)] lg:pr-[var(--spacing-scale-056)] xl:pl-[var(--spacing-scale-048)] xl:pt-[var(--spacing-scale-024)] xl:pr-[var(--spacing-scale-056)]"
role="navigation"
aria-label="Main navigation"
>
<HeaderTab className="flex items-center self-end" stretch={true}>
{/* Logo - Consistent left positioning within HeaderTab */}
<div>
{logoConfig.map((config, index) => (
<div key={index} className={config.breakpoint}>
{renderLogo(config.size, config.showText)}
</div>
))}
</div>
{/* XSmall menu bar - positioned next to logo */}
<div className="block sm:hidden -me-[2px]">
<MenuBar size="default">
{renderNavigationItems("xsmall")}
{renderLoginButton("xsmall")}
</MenuBar>
</div>
</HeaderTab>
{/* Navigation Links - Centered in header for SM and up */}
<div className="absolute left-1/2 transform -translate-x-1/2 hidden sm:block">
<div className="hidden sm:block md:hidden">
<MenuBar size="default">
{renderNavigationItems("xsmall")}
{renderLoginButton("xsmall")}
</MenuBar>
</div>
<div className="hidden md:block lg:hidden">
<MenuBar size="medium">{renderNavigationItems("homeMd")}</MenuBar>
</div>
<div className="hidden lg:block xl:hidden">
<MenuBar size="large">{renderNavigationItems("large")}</MenuBar>
</div>
<div className="hidden xl:block">
<MenuBar size="large">
{renderNavigationItems("homeXlarge")}
</MenuBar>
</div>
</div>
{/* Authentication Elements - Consistent right alignment outside HeaderTab */}
<div className="flex items-center">
{/* XSmall and Small breakpoints - create rule button outside HeaderTab */}
<div className="block md:hidden">
{renderCreateRuleButton("xsmall", "small", "small")}
</div>
{/* Medium breakpoint - login outside HeaderTab, create rule outside */}
<div className="hidden md:block lg:hidden absolute right-[var(--spacing-measures-spacing-016)]">
<div className="flex items-center gap-[var(--spacing-scale-010)]">
{renderLoginButton("homeMd")}
{renderCreateRuleButton("small", "medium", "medium")}
</div>
</div>
{/* Large breakpoint */}
<div className="hidden lg:flex xl:hidden items-center">
<div className="flex items-center gap-[var(--spacing-scale-004)]">
{renderLoginButton("large")}
{renderCreateRuleButton("large", "large", "large")}
</div>
</div>
{/* XLarge breakpoint */}
<div className="hidden xl:flex items-center">
<div className="flex items-center gap-[var(--spacing-scale-004)]">
{renderLoginButton("homeXlarge")}
{renderCreateRuleButton("xlarge", "xlarge", "xlarge")}
</div>
</div>
</div>
</nav>
</header>
);
}
+115 -6
View File
@@ -1,4 +1,4 @@
export default function Logo({ size = "default" }) { export default function Logo({ size = "default", showText = true }) {
// Size configurations // Size configurations
const sizes = { const sizes = {
default: { default: {
@@ -8,6 +8,69 @@ export default function Logo({ size = "default" }) {
lineHeight: "leading-[27.05px]", lineHeight: "leading-[27.05px]",
iconSize: "w-[27.05px] h-[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: { footer: {
containerHeight: "h-[calc(40px*1.37)]", containerHeight: "h-[calc(40px*1.37)]",
gap: "gap-[calc(8px*1.37)]", gap: "gap-[calc(8px*1.37)]",
@@ -25,7 +88,25 @@ export default function Logo({ size = "default" }) {
}; };
const config = 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 ? sizes.footer
: size === "footerLg" : size === "footerLg"
? sizes.footerLg ? sizes.footerLg
@@ -33,14 +114,31 @@ export default function Logo({ size = "default" }) {
return ( return (
<div <div
className={`flex items-center ${config.containerHeight} ${config.gap}`} className={`flex items-center ${config.containerHeight} ${
showText ? config.gap : ""
} transition-all duration-200 ease-in-out hover:scale-[1.02] cursor-pointer`}
role="banner"
aria-label="CommunityRule Logo"
> >
{/* Logo Text */} {/* Logo Text - only show if showText is true */}
{showText && (
<div <div
className={`font-['Bricolage_Grotesque'] text-[var(--color-content-default-primary)] ${config.textSize} ${config.lineHeight} font-normal tracking-[0px]`} className={`font-['Bricolage_Grotesque'] ${
size === "homeHeaderXsmall" ||
size === "homeHeaderSm" ||
size === "homeHeaderMd" ||
size === "homeHeaderLg" ||
size === "homeHeaderXl"
? "text-[var(--color-content-inverse-primary)]"
: "text-[var(--color-content-default-primary)]"
} ${config.textSize} ${
config.lineHeight
} font-normal tracking-[0px] transition-colors duration-200`}
aria-label="CommunityRule"
> >
CommunityRule CommunityRule
</div> </div>
)}
{/* Vector Icon */} {/* Vector Icon */}
<img <img
@@ -48,7 +146,18 @@ export default function Logo({ size = "default" }) {
alt="CommunityRule Logo Icon" alt="CommunityRule Logo Icon"
width={27.05} width={27.05}
height={27.05} height={27.05}
className={`flex-shrink-0 ${config.iconSize}`} className={`flex-shrink-0 ${
config.iconSize
} transition-all duration-200 ${
size === "homeHeaderXsmall" ||
size === "homeHeaderSm" ||
size === "homeHeaderMd" ||
size === "homeHeaderLg" ||
size === "homeHeaderXl"
? "filter brightness-0"
: ""
}`}
aria-hidden="true"
/> />
</div> </div>
); );
+30
View File
@@ -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 (
<nav
className={baseStyles}
role="menubar"
aria-label="Main navigation menu"
{...props}
>
{children}
</nav>
);
}
+136
View File
@@ -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 (
<span className={combinedStyles} {...accessibilityProps}>
{children}
</span>
);
}
return (
<a href={href} className={combinedStyles} {...accessibilityProps}>
{children}
</a>
);
}
+55
View File
@@ -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 (
<span className={combinedStyles} {...props}>
{children}
</span>
);
}
return (
<a href={href} className={combinedStyles} {...props}>
{children}
</a>
);
}
+9 -1
View File
@@ -1 +1,9 @@
@import "tailwindcss"; @tailwind base;
@tailwind components;
@tailwind utilities;
@import "./tailwind.css";
body {
background-color: black;
min-height: 100vh;
}
+3 -2
View File
@@ -1,11 +1,11 @@
import { Inter, Bricolage_Grotesque } from "next/font/google"; import { Inter, Bricolage_Grotesque } from "next/font/google";
import "./globals.css"; import "./globals.css";
import "./tailwind.css"; import HomeHeader from "./components/HomeHeader";
import Footer from "./components/Footer"; import Footer from "./components/Footer";
const inter = Inter({ const inter = Inter({
subsets: ["latin"], subsets: ["latin"],
weight: ["400"], weight: ["400", "500"],
variable: "--font-inter", variable: "--font-inter",
}); });
@@ -20,6 +20,7 @@ export default function RootLayout({ children }) {
<html lang="en"> <html lang="en">
<body className={`${inter.variable} ${bricolageGrotesque.variable}`}> <body className={`${inter.variable} ${bricolageGrotesque.variable}`}>
<div className="min-h-screen flex flex-col"> <div className="min-h-screen flex flex-col">
<HomeHeader />
<main className="flex-1">{children}</main> <main className="flex-1">{children}</main>
<Footer /> <Footer />
</div> </div>
+1 -1
View File
@@ -1,3 +1,3 @@
export default function Page() { export default function Page() {
return <></>; return <div>{/* home page content will go here */}</div>;
} }
+6
View File
@@ -6,6 +6,12 @@
@import "tailwindcss"; @import "tailwindcss";
@theme inline { @theme inline {
/* Custom breakpoints */
--breakpoint-xsm: 429px;
--breakpoint-sm: 430px;
--breakpoint-md: 640px;
--breakpoint-lg: 1024px;
--breakpoint-xl: 1440px;
/* Reset default Tailwind configuration */ /* Reset default Tailwind configuration */
--color-*: initial; --color-*: initial;
+7 -1
View File
@@ -9,6 +9,12 @@ const compat = new FlatCompat({
baseDirectory: __dirname, 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; export default eslintConfig;
+5 -1
View File
@@ -1,4 +1,8 @@
/** @type {import('next').NextConfig} */ /** @type {import('next').NextConfig} */
const nextConfig = {}; const nextConfig = {
eslint: {
ignoreDuringBuilds: true,
},
};
export default nextConfig; export default nextConfig;
+65 -64
View File
@@ -18,6 +18,7 @@
"@tailwindcss/postcss": "^4.1.11", "@tailwindcss/postcss": "^4.1.11",
"eslint": "^9", "eslint": "^9",
"eslint-config-next": "15.2.4", "eslint-config-next": "15.2.4",
"postcss": "^8.5.6",
"tailwindcss": "^4.0.0" "tailwindcss": "^4.0.0"
} }
}, },
@@ -1244,17 +1245,17 @@
"license": "MIT" "license": "MIT"
}, },
"node_modules/@typescript-eslint/eslint-plugin": { "node_modules/@typescript-eslint/eslint-plugin": {
"version": "8.38.0", "version": "8.39.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.38.0.tgz", "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.39.0.tgz",
"integrity": "sha512-CPoznzpuAnIOl4nhj4tRr4gIPj5AfKgkiJmGQDaq+fQnRJTYlcBjbX3wbciGmpoPf8DREufuPRe1tNMZnGdanA==", "integrity": "sha512-bhEz6OZeUR+O/6yx9Jk6ohX6H9JSFTaiY0v9/PuKT3oGK0rn0jNplLmyFUGV+a9gfYnVNwGDwS/UkLIuXNb2Rw==",
"dev": true, "dev": true,
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"@eslint-community/regexpp": "^4.10.0", "@eslint-community/regexpp": "^4.10.0",
"@typescript-eslint/scope-manager": "8.38.0", "@typescript-eslint/scope-manager": "8.39.0",
"@typescript-eslint/type-utils": "8.38.0", "@typescript-eslint/type-utils": "8.39.0",
"@typescript-eslint/utils": "8.38.0", "@typescript-eslint/utils": "8.39.0",
"@typescript-eslint/visitor-keys": "8.38.0", "@typescript-eslint/visitor-keys": "8.39.0",
"graphemer": "^1.4.0", "graphemer": "^1.4.0",
"ignore": "^7.0.0", "ignore": "^7.0.0",
"natural-compare": "^1.4.0", "natural-compare": "^1.4.0",
@@ -1268,9 +1269,9 @@
"url": "https://opencollective.com/typescript-eslint" "url": "https://opencollective.com/typescript-eslint"
}, },
"peerDependencies": { "peerDependencies": {
"@typescript-eslint/parser": "^8.38.0", "@typescript-eslint/parser": "^8.39.0",
"eslint": "^8.57.0 || ^9.0.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": { "node_modules/@typescript-eslint/eslint-plugin/node_modules/ignore": {
@@ -1284,16 +1285,16 @@
} }
}, },
"node_modules/@typescript-eslint/parser": { "node_modules/@typescript-eslint/parser": {
"version": "8.38.0", "version": "8.39.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.38.0.tgz", "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.39.0.tgz",
"integrity": "sha512-Zhy8HCvBUEfBECzIl1PKqF4p11+d0aUJS1GeUiuqK9WmOug8YCmC4h4bjyBvMyAMI9sbRczmrYL5lKg/YMbrcQ==", "integrity": "sha512-g3WpVQHngx0aLXn6kfIYCZxM6rRJlWzEkVpqEFLT3SgEDsp9cpCbxxgwnE504q4H+ruSDh/VGS6nqZIDynP+vg==",
"dev": true, "dev": true,
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"@typescript-eslint/scope-manager": "8.38.0", "@typescript-eslint/scope-manager": "8.39.0",
"@typescript-eslint/types": "8.38.0", "@typescript-eslint/types": "8.39.0",
"@typescript-eslint/typescript-estree": "8.38.0", "@typescript-eslint/typescript-estree": "8.39.0",
"@typescript-eslint/visitor-keys": "8.38.0", "@typescript-eslint/visitor-keys": "8.39.0",
"debug": "^4.3.4" "debug": "^4.3.4"
}, },
"engines": { "engines": {
@@ -1305,18 +1306,18 @@
}, },
"peerDependencies": { "peerDependencies": {
"eslint": "^8.57.0 || ^9.0.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/project-service": { "node_modules/@typescript-eslint/project-service": {
"version": "8.38.0", "version": "8.39.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/project-service/-/project-service-8.38.0.tgz", "resolved": "https://registry.npmjs.org/@typescript-eslint/project-service/-/project-service-8.39.0.tgz",
"integrity": "sha512-dbK7Jvqcb8c9QfH01YB6pORpqX1mn5gDZc9n63Ak/+jD67oWXn3Gs0M6vddAN+eDXBCS5EmNWzbSxsn9SzFWWg==", "integrity": "sha512-CTzJqaSq30V/Z2Og9jogzZt8lJRR5TKlAdXmWgdu4hgcC9Kww5flQ+xFvMxIBWVNdxJO7OifgdOK4PokMIWPew==",
"dev": true, "dev": true,
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"@typescript-eslint/tsconfig-utils": "^8.38.0", "@typescript-eslint/tsconfig-utils": "^8.39.0",
"@typescript-eslint/types": "^8.38.0", "@typescript-eslint/types": "^8.39.0",
"debug": "^4.3.4" "debug": "^4.3.4"
}, },
"engines": { "engines": {
@@ -1327,18 +1328,18 @@
"url": "https://opencollective.com/typescript-eslint" "url": "https://opencollective.com/typescript-eslint"
}, },
"peerDependencies": { "peerDependencies": {
"typescript": ">=4.8.4 <5.9.0" "typescript": ">=4.8.4 <6.0.0"
} }
}, },
"node_modules/@typescript-eslint/scope-manager": { "node_modules/@typescript-eslint/scope-manager": {
"version": "8.38.0", "version": "8.39.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.38.0.tgz", "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.39.0.tgz",
"integrity": "sha512-WJw3AVlFFcdT9Ri1xs/lg8LwDqgekWXWhH3iAF+1ZM+QPd7oxQ6jvtW/JPwzAScxitILUIFs0/AnQ/UWHzbATQ==", "integrity": "sha512-8QOzff9UKxOh6npZQ/4FQu4mjdOCGSdO3p44ww0hk8Vu+IGbg0tB/H1LcTARRDzGCC8pDGbh2rissBuuoPgH8A==",
"dev": true, "dev": true,
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"@typescript-eslint/types": "8.38.0", "@typescript-eslint/types": "8.39.0",
"@typescript-eslint/visitor-keys": "8.38.0" "@typescript-eslint/visitor-keys": "8.39.0"
}, },
"engines": { "engines": {
"node": "^18.18.0 || ^20.9.0 || >=21.1.0" "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
@@ -1349,9 +1350,9 @@
} }
}, },
"node_modules/@typescript-eslint/tsconfig-utils": { "node_modules/@typescript-eslint/tsconfig-utils": {
"version": "8.38.0", "version": "8.39.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/tsconfig-utils/-/tsconfig-utils-8.38.0.tgz", "resolved": "https://registry.npmjs.org/@typescript-eslint/tsconfig-utils/-/tsconfig-utils-8.39.0.tgz",
"integrity": "sha512-Lum9RtSE3EroKk/bYns+sPOodqb2Fv50XOl/gMviMKNvanETUuUcC9ObRbzrJ4VSd2JalPqgSAavwrPiPvnAiQ==", "integrity": "sha512-Fd3/QjmFV2sKmvv3Mrj8r6N8CryYiCS8Wdb/6/rgOXAWGcFuc+VkQuG28uk/4kVNVZBQuuDHEDUpo/pQ32zsIQ==",
"dev": true, "dev": true,
"license": "MIT", "license": "MIT",
"engines": { "engines": {
@@ -1362,19 +1363,19 @@
"url": "https://opencollective.com/typescript-eslint" "url": "https://opencollective.com/typescript-eslint"
}, },
"peerDependencies": { "peerDependencies": {
"typescript": ">=4.8.4 <5.9.0" "typescript": ">=4.8.4 <6.0.0"
} }
}, },
"node_modules/@typescript-eslint/type-utils": { "node_modules/@typescript-eslint/type-utils": {
"version": "8.38.0", "version": "8.39.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-8.38.0.tgz", "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-8.39.0.tgz",
"integrity": "sha512-c7jAvGEZVf0ao2z+nnz8BUaHZD09Agbh+DY7qvBQqLiz8uJzRgVPj5YvOh8I8uEiH8oIUGIfHzMwUcGVco/SJg==", "integrity": "sha512-6B3z0c1DXVT2vYA9+z9axjtc09rqKUPRmijD5m9iv8iQpHBRYRMBcgxSiKTZKm6FwWw1/cI4v6em35OsKCiN5Q==",
"dev": true, "dev": true,
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"@typescript-eslint/types": "8.38.0", "@typescript-eslint/types": "8.39.0",
"@typescript-eslint/typescript-estree": "8.38.0", "@typescript-eslint/typescript-estree": "8.39.0",
"@typescript-eslint/utils": "8.38.0", "@typescript-eslint/utils": "8.39.0",
"debug": "^4.3.4", "debug": "^4.3.4",
"ts-api-utils": "^2.1.0" "ts-api-utils": "^2.1.0"
}, },
@@ -1387,13 +1388,13 @@
}, },
"peerDependencies": { "peerDependencies": {
"eslint": "^8.57.0 || ^9.0.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/types": { "node_modules/@typescript-eslint/types": {
"version": "8.38.0", "version": "8.39.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.38.0.tgz", "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.39.0.tgz",
"integrity": "sha512-wzkUfX3plUqij4YwWaJyqhiPE5UCRVlFpKn1oCRn2O1bJ592XxWJj8ROQ3JD5MYXLORW84063z3tZTb/cs4Tyw==", "integrity": "sha512-ArDdaOllnCj3yn/lzKn9s0pBQYmmyme/v1HbGIGB0GB/knFI3fWMHloC+oYTJW46tVbYnGKTMDK4ah1sC2v0Kg==",
"dev": true, "dev": true,
"license": "MIT", "license": "MIT",
"engines": { "engines": {
@@ -1405,16 +1406,16 @@
} }
}, },
"node_modules/@typescript-eslint/typescript-estree": { "node_modules/@typescript-eslint/typescript-estree": {
"version": "8.38.0", "version": "8.39.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.38.0.tgz", "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.39.0.tgz",
"integrity": "sha512-fooELKcAKzxux6fA6pxOflpNS0jc+nOQEEOipXFNjSlBS6fqrJOVY/whSn70SScHrcJ2LDsxWrneFoWYSVfqhQ==", "integrity": "sha512-ndWdiflRMvfIgQRpckQQLiB5qAKQ7w++V4LlCHwp62eym1HLB/kw7D9f2e8ytONls/jt89TEasgvb+VwnRprsw==",
"dev": true, "dev": true,
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"@typescript-eslint/project-service": "8.38.0", "@typescript-eslint/project-service": "8.39.0",
"@typescript-eslint/tsconfig-utils": "8.38.0", "@typescript-eslint/tsconfig-utils": "8.39.0",
"@typescript-eslint/types": "8.38.0", "@typescript-eslint/types": "8.39.0",
"@typescript-eslint/visitor-keys": "8.38.0", "@typescript-eslint/visitor-keys": "8.39.0",
"debug": "^4.3.4", "debug": "^4.3.4",
"fast-glob": "^3.3.2", "fast-glob": "^3.3.2",
"is-glob": "^4.0.3", "is-glob": "^4.0.3",
@@ -1430,7 +1431,7 @@
"url": "https://opencollective.com/typescript-eslint" "url": "https://opencollective.com/typescript-eslint"
}, },
"peerDependencies": { "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": { "node_modules/@typescript-eslint/typescript-estree/node_modules/brace-expansion": {
@@ -1490,16 +1491,16 @@
} }
}, },
"node_modules/@typescript-eslint/utils": { "node_modules/@typescript-eslint/utils": {
"version": "8.38.0", "version": "8.39.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.38.0.tgz", "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.39.0.tgz",
"integrity": "sha512-hHcMA86Hgt+ijJlrD8fX0j1j8w4C92zue/8LOPAFioIno+W0+L7KqE8QZKCcPGc/92Vs9x36w/4MPTJhqXdyvg==", "integrity": "sha512-4GVSvNA0Vx1Ktwvf4sFE+exxJ3QGUorQG1/A5mRfRNZtkBT2xrA/BCO2H0eALx/PnvCS6/vmYwRdDA41EoffkQ==",
"dev": true, "dev": true,
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"@eslint-community/eslint-utils": "^4.7.0", "@eslint-community/eslint-utils": "^4.7.0",
"@typescript-eslint/scope-manager": "8.38.0", "@typescript-eslint/scope-manager": "8.39.0",
"@typescript-eslint/types": "8.38.0", "@typescript-eslint/types": "8.39.0",
"@typescript-eslint/typescript-estree": "8.38.0" "@typescript-eslint/typescript-estree": "8.39.0"
}, },
"engines": { "engines": {
"node": "^18.18.0 || ^20.9.0 || >=21.1.0" "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
@@ -1510,17 +1511,17 @@
}, },
"peerDependencies": { "peerDependencies": {
"eslint": "^8.57.0 || ^9.0.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/visitor-keys": { "node_modules/@typescript-eslint/visitor-keys": {
"version": "8.38.0", "version": "8.39.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.38.0.tgz", "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.39.0.tgz",
"integrity": "sha512-pWrTcoFNWuwHlA9CvlfSsGWs14JxfN1TH25zM5L7o0pRLhsoZkDnTsXfQRJBEWJoV5DL0jf+Z+sxiud+K0mq1g==", "integrity": "sha512-ldgiJ+VAhQCfIjeOgu8Kj5nSxds0ktPOSO9p4+0VDH2R2pLvQraaM5Oen2d7NxzMCm+Sn/vJT+mv2H5u6b/3fA==",
"dev": true, "dev": true,
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"@typescript-eslint/types": "8.38.0", "@typescript-eslint/types": "8.39.0",
"eslint-visitor-keys": "^4.2.1" "eslint-visitor-keys": "^4.2.1"
}, },
"engines": { "engines": {
@@ -2476,9 +2477,9 @@
"license": "MIT" "license": "MIT"
}, },
"node_modules/enhanced-resolve": { "node_modules/enhanced-resolve": {
"version": "5.18.2", "version": "5.18.3",
"resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.18.2.tgz", "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.18.3.tgz",
"integrity": "sha512-6Jw4sE1maoRJo3q8MsSIn2onJFbLTOjY9hlx4DZXmOKvLRd1Ok2kXmAGXaafL2+ijsJZ1ClYbl/pmqr9+k4iUQ==", "integrity": "sha512-d4lC8xfavMeBjzGr2vECC3fsGXziXZQyJxD868h2M/mBI3PwAuODxAkLkq5HYuvrPYcUtiLzsTo8U3PgX3Ocww==",
"dev": true, "dev": true,
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
+1
View File
@@ -19,6 +19,7 @@
"@tailwindcss/postcss": "^4.1.11", "@tailwindcss/postcss": "^4.1.11",
"eslint": "^9", "eslint": "^9",
"eslint-config-next": "15.2.4", "eslint-config-next": "15.2.4",
"postcss": "^8.5.6",
"tailwindcss": "^4.0.0" "tailwindcss": "^4.0.0"
} }
} }
+5 -4
View File
@@ -1,5 +1,6 @@
const config = { /** @type {import('postcss-load-config').Config} */
plugins: ["@tailwindcss/postcss"], export default {
plugins: {
"@tailwindcss/postcss": {},
},
}; };
export default config;
Binary file not shown.

After

Width:  |  Height:  |  Size: 2.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

+3
View File
@@ -0,0 +1,3 @@
<svg width="105" height="42" viewBox="0 0 105 42" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M12.0492 10.0151C12.0492 4.49227 7.57203 0 2.04918 0H0V53H105V42.0635H44.0492C26.3761 42.0635 12.0492 27.6882 12.0492 10.0151Z" fill="#FEFCC9"/>
</svg>

After

Width:  |  Height:  |  Size: 259 B

+3
View File
@@ -0,0 +1,3 @@
<svg width="61" height="25" viewBox="0 0 61 25" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M7 0H0V31.5H61V25H31C17.7452 25 7 14.2548 7 1V0Z" fill="#FEFCC9"/>
</svg>

After

Width:  |  Height:  |  Size: 179 B

+3
View File
@@ -0,0 +1,3 @@
<svg width="105" height="42" viewBox="0 0 105 42" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M12.0492 10.0151C12.0492 4.49227 7.57203 0 2.04918 0H0V53H105V42.0635H44.0492C26.3761 42.0635 12.0492 27.6882 12.0492 10.0151Z" fill="#FEFCC9"/>
</svg>

After

Width:  |  Height:  |  Size: 259 B

+3
View File
@@ -0,0 +1,3 @@
<svg width="61" height="19" viewBox="0 0 61 19" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M7 0H0V24H61V19.0476H23C14.1634 19.0476 7 11.8842 7 3.04761V0Z" fill="#FEFCC9"/>
</svg>

After

Width:  |  Height:  |  Size: 193 B