phase 1-3 css refactor
This commit is contained in:
@@ -4,80 +4,97 @@
|
|||||||
* 🔒 STYLE LOCKED - See DESIGN_SYSTEM.md for available colors and variants.
|
* 🔒 STYLE LOCKED - See DESIGN_SYSTEM.md for available colors and variants.
|
||||||
* Do not modify colors or add new ones without updating DESIGN_SYSTEM.md first.
|
* Do not modify colors or add new ones without updating DESIGN_SYSTEM.md first.
|
||||||
*/
|
*/
|
||||||
type BadgeVariant = "light" | "solid";
|
import clsx from "clsx";
|
||||||
type BadgeSize = "sm" | "md";
|
|
||||||
type BadgeColor =
|
type BadgeVariant = "solid" | "soft" | "outline";
|
||||||
| "primary"
|
type BadgeSize = "xs" | "sm" | "md";
|
||||||
| "success"
|
type BadgeTone = "brand" | "success" | "warning" | "danger" | "info" | "neutral";
|
||||||
| "error"
|
|
||||||
| "warning"
|
|
||||||
| "info"
|
|
||||||
| "light"
|
|
||||||
| "dark";
|
|
||||||
|
|
||||||
interface BadgeProps {
|
interface BadgeProps {
|
||||||
variant?: BadgeVariant; // Light or solid variant
|
variant?: BadgeVariant; // Visual treatment
|
||||||
size?: BadgeSize; // Badge size
|
size?: BadgeSize; // Badge size
|
||||||
color?: BadgeColor; // Badge color
|
tone?: BadgeTone; // Badge color tone
|
||||||
startIcon?: React.ReactNode; // Icon at the start
|
startIcon?: React.ReactNode; // Icon at the start
|
||||||
endIcon?: React.ReactNode; // Icon at the end
|
endIcon?: React.ReactNode; // Icon at the end
|
||||||
children: React.ReactNode; // Badge content
|
children: React.ReactNode; // Badge content
|
||||||
className?: string; // Additional classes
|
className?: string; // Additional classes
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const toneStyles: Record<
|
||||||
|
BadgeTone,
|
||||||
|
{
|
||||||
|
solid: string;
|
||||||
|
soft: string;
|
||||||
|
outline: string;
|
||||||
|
}
|
||||||
|
> = {
|
||||||
|
brand: {
|
||||||
|
solid: "bg-brand-500 text-white",
|
||||||
|
soft: "bg-brand-50 text-brand-600 dark:bg-brand-500/15 dark:text-brand-300",
|
||||||
|
outline:
|
||||||
|
"text-brand-600 ring-1 ring-brand-200 dark:ring-brand-500/30 dark:text-brand-300",
|
||||||
|
},
|
||||||
|
success: {
|
||||||
|
solid: "bg-success-500 text-white",
|
||||||
|
soft: "bg-success-50 text-success-600 dark:bg-success-500/15 dark:text-success-300",
|
||||||
|
outline:
|
||||||
|
"text-success-600 ring-1 ring-success-200 dark:ring-success-500/30 dark:text-success-300",
|
||||||
|
},
|
||||||
|
warning: {
|
||||||
|
solid: "bg-warning-500 text-white",
|
||||||
|
soft: "bg-warning-50 text-warning-600 dark:bg-warning-500/15 dark:text-warning-300",
|
||||||
|
outline:
|
||||||
|
"text-warning-600 ring-1 ring-warning-200 dark:ring-warning-500/30 dark:text-warning-300",
|
||||||
|
},
|
||||||
|
danger: {
|
||||||
|
solid: "bg-error-500 text-white",
|
||||||
|
soft: "bg-error-50 text-error-600 dark:bg-error-500/15 dark:text-error-300",
|
||||||
|
outline:
|
||||||
|
"text-error-600 ring-1 ring-error-200 dark:ring-error-500/30 dark:text-error-300",
|
||||||
|
},
|
||||||
|
info: {
|
||||||
|
solid: "bg-blue-light-500 text-white",
|
||||||
|
soft: "bg-blue-light-50 text-blue-light-600 dark:bg-blue-light-500/15 dark:text-blue-light-300",
|
||||||
|
outline:
|
||||||
|
"text-blue-light-600 ring-1 ring-blue-light-200 dark:ring-blue-light-500/30 dark:text-blue-light-300",
|
||||||
|
},
|
||||||
|
neutral: {
|
||||||
|
solid: "bg-gray-800 text-white",
|
||||||
|
soft: "bg-gray-100 text-gray-700 dark:bg-white/5 dark:text-white/80",
|
||||||
|
outline:
|
||||||
|
"text-gray-700 ring-1 ring-gray-300 dark:ring-white/[0.08] dark:text-white/80",
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
const sizeClasses: Record<BadgeSize, string> = {
|
||||||
|
xs: "h-5 px-2 text-[11px]",
|
||||||
|
sm: "h-6 px-2.5 text-xs",
|
||||||
|
md: "h-7 px-3 text-sm",
|
||||||
|
};
|
||||||
|
|
||||||
const Badge: React.FC<BadgeProps> = ({
|
const Badge: React.FC<BadgeProps> = ({
|
||||||
variant = "light",
|
variant = "soft",
|
||||||
color = "primary",
|
tone = "brand",
|
||||||
size = "md",
|
size = "sm",
|
||||||
startIcon,
|
startIcon,
|
||||||
endIcon,
|
endIcon,
|
||||||
children,
|
children,
|
||||||
className = "",
|
className = "",
|
||||||
}) => {
|
}) => {
|
||||||
const baseStyles =
|
const toneClass = toneStyles[tone][variant];
|
||||||
"inline-flex items-center px-2.5 py-0.5 justify-center gap-1 rounded-full font-medium";
|
|
||||||
|
|
||||||
// Define size styles
|
|
||||||
const sizeStyles = {
|
|
||||||
sm: "text-theme-xs", // Smaller padding and font size
|
|
||||||
md: "text-sm", // Default padding and font size
|
|
||||||
};
|
|
||||||
|
|
||||||
// Define color styles for variants
|
|
||||||
const variants = {
|
|
||||||
light: {
|
|
||||||
primary:
|
|
||||||
"bg-brand-50 text-brand-500 dark:bg-brand-500/15 dark:text-brand-400",
|
|
||||||
success:
|
|
||||||
"bg-success-50 text-success-600 dark:bg-success-500/15 dark:text-success-500",
|
|
||||||
error:
|
|
||||||
"bg-error-50 text-error-600 dark:bg-error-500/15 dark:text-error-500",
|
|
||||||
warning:
|
|
||||||
"bg-warning-50 text-warning-600 dark:bg-warning-500/15 dark:text-orange-400",
|
|
||||||
info: "bg-blue-light-50 text-blue-light-500 dark:bg-blue-light-500/15 dark:text-blue-light-500",
|
|
||||||
light: "bg-gray-100 text-gray-700 dark:bg-white/5 dark:text-white/80",
|
|
||||||
dark: "bg-gray-500 text-white dark:bg-white/5 dark:text-white",
|
|
||||||
},
|
|
||||||
solid: {
|
|
||||||
primary: "bg-brand-500 text-white dark:text-white",
|
|
||||||
success: "bg-success-500 text-white dark:text-white",
|
|
||||||
error: "bg-error-500 text-white dark:text-white",
|
|
||||||
warning: "bg-warning-500 text-white dark:text-white",
|
|
||||||
info: "bg-blue-light-500 text-white dark:text-white",
|
|
||||||
light: "bg-gray-400 dark:bg-white/5 text-white dark:text-white/80",
|
|
||||||
dark: "bg-gray-700 text-white dark:text-white",
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
// Get styles based on size and color variant
|
|
||||||
const sizeClass = sizeStyles[size];
|
|
||||||
const colorStyles = variants[variant][color];
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<span className={`${baseStyles} ${sizeClass} ${colorStyles} ${className}`}>
|
<span
|
||||||
{startIcon && <span className="mr-1">{startIcon}</span>}
|
className={clsx(
|
||||||
|
"inline-flex items-center justify-center gap-1 rounded-full font-medium uppercase tracking-wide",
|
||||||
|
sizeClasses[size],
|
||||||
|
toneClass,
|
||||||
|
className,
|
||||||
|
)}
|
||||||
|
>
|
||||||
|
{startIcon && <span className="flex items-center">{startIcon}</span>}
|
||||||
{children}
|
{children}
|
||||||
{endIcon && <span className="ml-1">{endIcon}</span>}
|
{endIcon && <span className="flex items-center">{endIcon}</span>}
|
||||||
</span>
|
</span>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -5,66 +5,205 @@
|
|||||||
* Do not modify variants or add new ones without updating DESIGN_SYSTEM.md first.
|
* Do not modify variants or add new ones without updating DESIGN_SYSTEM.md first.
|
||||||
*/
|
*/
|
||||||
import { ReactNode, forwardRef } from "react";
|
import { ReactNode, forwardRef } from "react";
|
||||||
|
import clsx from "clsx";
|
||||||
|
import { twMerge } from "tailwind-merge";
|
||||||
|
import { Link } from "react-router-dom";
|
||||||
|
|
||||||
|
type ButtonSize = "xs" | "sm" | "md" | "lg";
|
||||||
|
type ButtonVariant = "solid" | "soft" | "outline" | "ghost" | "gradient";
|
||||||
|
type ButtonTone = "brand" | "success" | "warning" | "danger" | "neutral";
|
||||||
|
type ButtonShape = "rounded" | "pill";
|
||||||
|
type ButtonElement = HTMLButtonElement | HTMLAnchorElement;
|
||||||
|
|
||||||
interface ButtonProps {
|
interface ButtonProps {
|
||||||
children: ReactNode; // Button text or content
|
children: ReactNode; // Button text or content
|
||||||
size?: "sm" | "md"; // Button size
|
size?: ButtonSize; // Button size
|
||||||
variant?: "primary" | "outline" | "secondary" | "success"; // Button variant
|
variant?: ButtonVariant; // Visual variant
|
||||||
|
tone?: ButtonTone; // Color tone
|
||||||
|
shape?: ButtonShape; // Border radius style
|
||||||
startIcon?: ReactNode; // Icon before the text
|
startIcon?: ReactNode; // Icon before the text
|
||||||
endIcon?: ReactNode; // Icon after the text
|
endIcon?: ReactNode; // Icon after the text
|
||||||
onClick?: () => void; // Click handler
|
onClick?: () => void; // Click handler
|
||||||
disabled?: boolean; // Disabled state
|
disabled?: boolean; // Disabled state
|
||||||
|
fullWidth?: boolean; // Stretch to parent width
|
||||||
className?: string; // Additional classes
|
className?: string; // Additional classes
|
||||||
type?: "button" | "submit" | "reset"; // Button type
|
type?: "button" | "submit" | "reset"; // Button type
|
||||||
|
as?: "button" | "a" | typeof Link;
|
||||||
|
href?: string;
|
||||||
|
to?: string; // For React Router Link
|
||||||
|
target?: string;
|
||||||
|
rel?: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
const Button = forwardRef<HTMLButtonElement, ButtonProps>(({
|
const toneMap: Record<
|
||||||
children,
|
ButtonTone,
|
||||||
size = "md",
|
{
|
||||||
variant = "primary",
|
solid: string;
|
||||||
startIcon,
|
soft: string;
|
||||||
endIcon,
|
outline: string;
|
||||||
onClick,
|
ghost: string;
|
||||||
className = "",
|
ring: string;
|
||||||
disabled = false,
|
}
|
||||||
type = "button",
|
> = {
|
||||||
}, ref) => {
|
brand: {
|
||||||
// Size Classes
|
solid: "bg-brand-500 text-white hover:bg-brand-600",
|
||||||
const sizeClasses = {
|
soft: "bg-brand-50 text-brand-600 hover:bg-brand-100",
|
||||||
sm: "px-3 py-1.5 text-xs h-8",
|
|
||||||
md: "px-3 py-2 text-sm h-9",
|
|
||||||
};
|
|
||||||
|
|
||||||
// Variant Classes
|
|
||||||
const variantClasses = {
|
|
||||||
primary:
|
|
||||||
"bg-brand-500 text-white shadow-theme-xs hover:bg-brand-600 disabled:bg-brand-300",
|
|
||||||
outline:
|
outline:
|
||||||
"bg-white text-gray-700 ring-1 ring-inset ring-gray-300 hover:bg-gray-50 dark:bg-gray-800 dark:text-gray-400 dark:ring-gray-700 dark:hover:bg-white/[0.03] dark:hover:text-gray-300",
|
"text-brand-600 ring-1 ring-brand-200 hover:bg-brand-25 dark:ring-brand-500/40 dark:text-brand-300 dark:hover:bg-brand-500/[0.08]",
|
||||||
secondary:
|
ghost:
|
||||||
"bg-gray-500 text-white border border-gray-500 hover:bg-gray-600 hover:border-gray-600 dark:bg-gray-500 dark:border-gray-500 dark:hover:bg-gray-600 dark:hover:border-gray-600",
|
"text-brand-600 hover:bg-brand-50 dark:text-brand-300 dark:hover:bg-brand-500/[0.08]",
|
||||||
success:
|
ring: "focus-visible:ring-brand-500",
|
||||||
"bg-success-500 text-white shadow-theme-xs hover:bg-success-600 disabled:bg-success-300",
|
},
|
||||||
};
|
success: {
|
||||||
|
solid: "bg-success-500 text-white hover:bg-success-600",
|
||||||
|
soft: "bg-success-50 text-success-600 hover:bg-success-100",
|
||||||
|
outline:
|
||||||
|
"text-success-600 ring-1 ring-success-200 hover:bg-success-25 dark:ring-success-500/40 dark:text-success-300",
|
||||||
|
ghost:
|
||||||
|
"text-success-600 hover:bg-success-50 dark:text-success-300 dark:hover:bg-success-500/[0.08]",
|
||||||
|
ring: "focus-visible:ring-success-500",
|
||||||
|
},
|
||||||
|
warning: {
|
||||||
|
solid: "bg-warning-500 text-white hover:bg-warning-600",
|
||||||
|
soft: "bg-warning-50 text-warning-600 hover:bg-warning-100",
|
||||||
|
outline:
|
||||||
|
"text-warning-600 ring-1 ring-warning-200 hover:bg-warning-25 dark:ring-warning-500/40 dark:text-warning-300",
|
||||||
|
ghost:
|
||||||
|
"text-warning-600 hover:bg-warning-50 dark:text-warning-300 dark:hover:bg-warning-500/[0.08]",
|
||||||
|
ring: "focus-visible:ring-warning-500",
|
||||||
|
},
|
||||||
|
danger: {
|
||||||
|
solid: "bg-error-500 text-white hover:bg-error-600",
|
||||||
|
soft: "bg-error-50 text-error-600 hover:bg-error-100",
|
||||||
|
outline:
|
||||||
|
"text-error-600 ring-1 ring-error-200 hover:bg-error-25 dark:ring-error-500/40 dark:text-error-300",
|
||||||
|
ghost:
|
||||||
|
"text-error-600 hover:bg-error-50 dark:text-error-300 dark:hover:bg-error-500/[0.08]",
|
||||||
|
ring: "focus-visible:ring-error-500",
|
||||||
|
},
|
||||||
|
neutral: {
|
||||||
|
solid:
|
||||||
|
"bg-gray-900 text-white hover:bg-gray-800 dark:bg-white/10 dark:hover:bg-white/20",
|
||||||
|
soft:
|
||||||
|
"bg-gray-100 text-gray-900 hover:bg-gray-200 dark:bg-white/[0.08] dark:text-white dark:hover:bg-white/[0.12]",
|
||||||
|
outline:
|
||||||
|
"text-gray-700 ring-1 ring-gray-300 hover:bg-gray-50 dark:text-gray-200 dark:ring-white/[0.08] dark:hover:bg-white/[0.04]",
|
||||||
|
ghost:
|
||||||
|
"text-gray-700 hover:bg-gray-100 dark:text-gray-200 dark:hover:bg-white/[0.04]",
|
||||||
|
ring: "focus-visible:ring-gray-400",
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
return (
|
const gradientTone: Record<ButtonTone, string> = {
|
||||||
<button
|
brand:
|
||||||
ref={ref}
|
"text-white shadow-[0_20px_45px_-30px_rgba(6,147,227,0.9)] bg-[linear-gradient(135deg,var(--color-primary)_0%,var(--color-primary-dark)_100%)]",
|
||||||
type={type}
|
success:
|
||||||
className={`inline-flex items-center justify-center gap-2 rounded-lg transition ${className} ${
|
"text-white shadow-[0_20px_45px_-30px_rgba(11,191,135,0.9)] bg-[linear-gradient(135deg,var(--color-success)_0%,var(--color-success-dark)_100%)]",
|
||||||
sizeClasses[size]
|
warning:
|
||||||
} ${variantClasses[variant]} ${
|
"text-white shadow-[0_20px_45px_-30px_rgba(255,122,0,0.9)] bg-[linear-gradient(135deg,var(--color-warning)_0%,var(--color-warning-dark)_100%)]",
|
||||||
disabled ? "cursor-not-allowed opacity-50" : ""
|
danger:
|
||||||
}`}
|
"text-white shadow-[0_20px_45px_-30px_rgba(239,68,68,0.9)] bg-[linear-gradient(135deg,var(--color-danger)_0%,var(--color-danger-dark)_100%)]",
|
||||||
onClick={onClick}
|
neutral:
|
||||||
disabled={disabled}
|
"text-white shadow-theme-lg bg-[linear-gradient(135deg,#0f172a,#1e293b)]",
|
||||||
>
|
};
|
||||||
{startIcon && <span className="flex items-center">{startIcon}</span>}
|
|
||||||
{children}
|
const sizeClasses: Record<ButtonSize, string> = {
|
||||||
{endIcon && <span className="flex items-center">{endIcon}</span>}
|
xs: "h-7 px-2.5 text-xs",
|
||||||
</button>
|
sm: "h-9 px-3 text-sm",
|
||||||
);
|
md: "h-10 px-4 text-sm",
|
||||||
});
|
lg: "h-12 px-5 text-base",
|
||||||
|
};
|
||||||
|
|
||||||
|
const Button = forwardRef<ButtonElement, ButtonProps>(
|
||||||
|
(
|
||||||
|
{
|
||||||
|
children,
|
||||||
|
size = "md",
|
||||||
|
variant = "solid",
|
||||||
|
tone = "brand",
|
||||||
|
shape = "rounded",
|
||||||
|
startIcon,
|
||||||
|
endIcon,
|
||||||
|
onClick,
|
||||||
|
className = "",
|
||||||
|
disabled = false,
|
||||||
|
fullWidth = false,
|
||||||
|
type = "button",
|
||||||
|
as = "button",
|
||||||
|
href,
|
||||||
|
to,
|
||||||
|
target,
|
||||||
|
rel,
|
||||||
|
},
|
||||||
|
ref,
|
||||||
|
) => {
|
||||||
|
const toneStyles = toneMap[tone];
|
||||||
|
|
||||||
|
const variantClasses: Record<ButtonVariant, string> = {
|
||||||
|
solid: toneStyles.solid,
|
||||||
|
soft: toneStyles.soft,
|
||||||
|
outline: clsx(
|
||||||
|
"bg-transparent transition-colors",
|
||||||
|
toneStyles.outline,
|
||||||
|
"dark:bg-transparent",
|
||||||
|
),
|
||||||
|
ghost: toneStyles.ghost,
|
||||||
|
gradient: gradientTone[tone],
|
||||||
|
};
|
||||||
|
|
||||||
|
const baseClasses =
|
||||||
|
"inline-flex items-center justify-center gap-2 font-medium transition duration-150 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-offset-2 disabled:opacity-50 disabled:cursor-not-allowed";
|
||||||
|
|
||||||
|
const shapeClasses =
|
||||||
|
shape === "pill" ? "rounded-full" : "rounded-lg";
|
||||||
|
|
||||||
|
const ringClass = variant === "gradient" ? "focus-visible:ring-white/70" : toneStyles.ring;
|
||||||
|
|
||||||
|
const computedClass = twMerge(
|
||||||
|
clsx(
|
||||||
|
baseClasses,
|
||||||
|
sizeClasses[size],
|
||||||
|
shapeClasses,
|
||||||
|
variantClasses[variant],
|
||||||
|
ringClass,
|
||||||
|
{
|
||||||
|
"w-full": fullWidth,
|
||||||
|
},
|
||||||
|
className,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
|
||||||
|
const Component = as === "a" ? "a" : as === Link ? Link : "button";
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Component
|
||||||
|
ref={ref}
|
||||||
|
className={computedClass}
|
||||||
|
onClick={onClick}
|
||||||
|
{...(as === "button"
|
||||||
|
? {
|
||||||
|
type,
|
||||||
|
disabled,
|
||||||
|
}
|
||||||
|
: as === Link
|
||||||
|
? {
|
||||||
|
to,
|
||||||
|
"aria-disabled": disabled,
|
||||||
|
}
|
||||||
|
: {
|
||||||
|
href,
|
||||||
|
target,
|
||||||
|
rel,
|
||||||
|
"aria-disabled": disabled,
|
||||||
|
})}
|
||||||
|
>
|
||||||
|
{startIcon && <span className="flex items-center">{startIcon}</span>}
|
||||||
|
<span className="whitespace-nowrap">{children}</span>
|
||||||
|
{endIcon && <span className="flex items-center">{endIcon}</span>}
|
||||||
|
</Component>
|
||||||
|
);
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
Button.displayName = "Button";
|
Button.displayName = "Button";
|
||||||
|
|
||||||
|
|||||||
@@ -1,19 +1,62 @@
|
|||||||
import { ReactNode } from "react";
|
import { ReactNode } from "react";
|
||||||
|
import clsx from "clsx";
|
||||||
|
import Button from "../button/Button";
|
||||||
|
|
||||||
|
type CardVariant = "surface" | "panel" | "frosted" | "borderless" | "gradient";
|
||||||
|
type CardPadding = "none" | "sm" | "md" | "lg";
|
||||||
|
type CardShadow = "none" | "sm" | "md";
|
||||||
|
|
||||||
interface CardProps {
|
interface CardProps {
|
||||||
children: ReactNode;
|
children: ReactNode;
|
||||||
className?: string;
|
className?: string;
|
||||||
onClick?: () => void;
|
onClick?: () => void;
|
||||||
|
variant?: CardVariant;
|
||||||
|
padding?: CardPadding;
|
||||||
|
shadow?: CardShadow;
|
||||||
}
|
}
|
||||||
|
|
||||||
export const Card: React.FC<CardProps> = ({
|
export const Card: React.FC<CardProps> = ({
|
||||||
children,
|
children,
|
||||||
className = "",
|
className = "",
|
||||||
onClick,
|
onClick,
|
||||||
|
variant = "surface",
|
||||||
|
padding = "md",
|
||||||
|
shadow = "sm",
|
||||||
}) => {
|
}) => {
|
||||||
|
const variantClasses: Record<CardVariant, string> = {
|
||||||
|
surface:
|
||||||
|
"bg-white border border-gray-200 dark:bg-white/[0.03] dark:border-white/10",
|
||||||
|
panel:
|
||||||
|
"bg-gray-50 border border-gray-100 dark:bg-white/[0.04] dark:border-white/[0.04]",
|
||||||
|
frosted:
|
||||||
|
"bg-white/80 backdrop-blur-xl border border-white/60 dark:bg-white/[0.08] dark:border-white/20",
|
||||||
|
borderless: "bg-transparent border border-transparent",
|
||||||
|
gradient:
|
||||||
|
"bg-[linear-gradient(180deg,var(--color-panel),var(--color-panel-alt))] border border-white/20 dark:border-white/10",
|
||||||
|
};
|
||||||
|
|
||||||
|
const paddingClasses: Record<CardPadding, string> = {
|
||||||
|
none: "p-0",
|
||||||
|
sm: "p-4 sm:p-5",
|
||||||
|
md: "p-5 sm:p-6",
|
||||||
|
lg: "p-6 sm:p-8",
|
||||||
|
};
|
||||||
|
|
||||||
|
const shadowClasses: Record<CardShadow, string> = {
|
||||||
|
none: "",
|
||||||
|
sm: "shadow-theme-sm",
|
||||||
|
md: "shadow-theme-lg",
|
||||||
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div
|
<div
|
||||||
className={`rounded-xl border border-gray-200 bg-white p-5 dark:border-gray-800 dark:bg-white/[0.03] sm:p-6 ${className}`}
|
className={clsx(
|
||||||
|
"rounded-2xl transition-shadow duration-200",
|
||||||
|
variantClasses[variant],
|
||||||
|
paddingClasses[padding],
|
||||||
|
shadowClasses[shadow],
|
||||||
|
className,
|
||||||
|
)}
|
||||||
onClick={onClick}
|
onClick={onClick}
|
||||||
>
|
>
|
||||||
{children}
|
{children}
|
||||||
@@ -108,31 +151,34 @@ export const CardAction: React.FC<CardActionProps> = ({
|
|||||||
variant = "button",
|
variant = "button",
|
||||||
className = "",
|
className = "",
|
||||||
}) => {
|
}) => {
|
||||||
const baseClasses =
|
if (variant === "button") {
|
||||||
variant === "button"
|
|
||||||
? "inline-flex items-center gap-2 px-4 py-3 mt-4 text-sm font-medium text-white rounded-lg bg-brand-500 shadow-theme-xs hover:bg-brand-600"
|
|
||||||
: "inline-flex items-center gap-1 mt-4 text-sm text-brand-500 hover:text-brand-600";
|
|
||||||
|
|
||||||
if (href) {
|
|
||||||
return (
|
return (
|
||||||
<a
|
<div className={clsx("mt-4 inline-flex", className)}>
|
||||||
href={href}
|
<Button
|
||||||
className={`${baseClasses} ${className}`}
|
size="sm"
|
||||||
onClick={onClick}
|
variant="solid"
|
||||||
>
|
tone="brand"
|
||||||
{children}
|
as={href ? "a" : "button"}
|
||||||
</a>
|
href={href}
|
||||||
|
onClick={onClick}
|
||||||
|
>
|
||||||
|
{children}
|
||||||
|
</Button>
|
||||||
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<button
|
<a
|
||||||
className={`${baseClasses} ${className}`}
|
href={href}
|
||||||
onClick={onClick}
|
onClick={onClick}
|
||||||
type="button"
|
className={clsx(
|
||||||
|
"mt-4 inline-flex items-center gap-1 text-sm font-semibold text-brand-600 hover:text-brand-700 dark:text-brand-300",
|
||||||
|
className,
|
||||||
|
)}
|
||||||
>
|
>
|
||||||
{children}
|
{children}
|
||||||
</button>
|
</a>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
102
frontend/src/components/ui/dataview/DataView.tsx
Normal file
102
frontend/src/components/ui/dataview/DataView.tsx
Normal file
@@ -0,0 +1,102 @@
|
|||||||
|
import { ReactNode } from "react";
|
||||||
|
import clsx from "clsx";
|
||||||
|
|
||||||
|
interface DataViewProps {
|
||||||
|
children: ReactNode;
|
||||||
|
className?: string;
|
||||||
|
toolbar?: ReactNode;
|
||||||
|
header?: ReactNode;
|
||||||
|
footer?: ReactNode;
|
||||||
|
}
|
||||||
|
|
||||||
|
export const DataView: React.FC<DataViewProps> = ({
|
||||||
|
children,
|
||||||
|
className = "",
|
||||||
|
toolbar,
|
||||||
|
header,
|
||||||
|
footer,
|
||||||
|
}) => (
|
||||||
|
<section
|
||||||
|
className={clsx(
|
||||||
|
"rounded-2xl border border-gray-200 bg-white shadow-theme-sm dark:border-white/[0.08] dark:bg-white/[0.04]",
|
||||||
|
className,
|
||||||
|
)}
|
||||||
|
>
|
||||||
|
{header && (
|
||||||
|
<div className="border-b border-gray-100 px-6 py-4 dark:border-white/[0.08]">
|
||||||
|
{header}
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
{toolbar && (
|
||||||
|
<div className="border-b border-gray-100 px-6 py-3 dark:border-white/[0.08]">
|
||||||
|
{toolbar}
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
<div className="overflow-x-auto px-4 py-4 sm:px-6">{children}</div>
|
||||||
|
{footer && (
|
||||||
|
<div className="border-t border-gray-100 px-6 py-4 dark:border-white/[0.08]">
|
||||||
|
{footer}
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
</section>
|
||||||
|
);
|
||||||
|
|
||||||
|
interface DataViewHeaderProps {
|
||||||
|
title: string;
|
||||||
|
description?: string;
|
||||||
|
actions?: ReactNode;
|
||||||
|
}
|
||||||
|
|
||||||
|
export const DataViewHeader: React.FC<DataViewHeaderProps> = ({
|
||||||
|
title,
|
||||||
|
description,
|
||||||
|
actions,
|
||||||
|
}) => (
|
||||||
|
<div className="flex flex-col gap-3 sm:flex-row sm:items-center sm:justify-between">
|
||||||
|
<div>
|
||||||
|
<h2 className="text-lg font-semibold text-gray-900 dark:text-white">{title}</h2>
|
||||||
|
{description && (
|
||||||
|
<p className="mt-1 text-sm text-gray-500 dark:text-gray-400">{description}</p>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
{actions && <div className="flex gap-2">{actions}</div>}
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
|
||||||
|
interface DataViewToolbarProps {
|
||||||
|
children: ReactNode;
|
||||||
|
className?: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export const DataViewToolbar: React.FC<DataViewToolbarProps> = ({
|
||||||
|
children,
|
||||||
|
className = "",
|
||||||
|
}) => (
|
||||||
|
<div
|
||||||
|
className={clsx(
|
||||||
|
"flex flex-wrap items-center gap-3 text-sm text-gray-700 dark:text-gray-300",
|
||||||
|
className,
|
||||||
|
)}
|
||||||
|
>
|
||||||
|
{children}
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
|
||||||
|
interface DataViewEmptyStateProps {
|
||||||
|
title: string;
|
||||||
|
description: string;
|
||||||
|
action?: ReactNode;
|
||||||
|
}
|
||||||
|
|
||||||
|
export const DataViewEmptyState: React.FC<DataViewEmptyStateProps> = ({
|
||||||
|
title,
|
||||||
|
description,
|
||||||
|
action,
|
||||||
|
}) => (
|
||||||
|
<div className="flex flex-col items-center justify-center gap-3 rounded-2xl border border-dashed border-gray-200 bg-gray-50/60 px-6 py-12 text-center dark:border-white/10 dark:bg-white/[0.02]">
|
||||||
|
<h3 className="text-base font-semibold text-gray-900 dark:text-white">{title}</h3>
|
||||||
|
<p className="max-w-md text-sm text-gray-500 dark:text-gray-400">{description}</p>
|
||||||
|
{action}
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
|
||||||
2
frontend/src/components/ui/dataview/index.ts
Normal file
2
frontend/src/components/ui/dataview/index.ts
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
export * from "./DataView";
|
||||||
|
|
||||||
@@ -1,6 +1,7 @@
|
|||||||
@import url("https://fonts.googleapis.com/css2?family=Outfit:wght@100..900&display=swap")
|
@import url("https://fonts.googleapis.com/css2?family=Outfit:wght@100..900&display=swap")
|
||||||
layer(base);
|
layer(base);
|
||||||
|
|
||||||
|
@import "./styles/tokens.css";
|
||||||
@import "tailwindcss";
|
@import "tailwindcss";
|
||||||
|
|
||||||
@keyframes slide-in-right {
|
@keyframes slide-in-right {
|
||||||
@@ -63,8 +64,8 @@ layer(base);
|
|||||||
--color-brand-200: #c2d6ff;
|
--color-brand-200: #c2d6ff;
|
||||||
--color-brand-300: #9cb9ff;
|
--color-brand-300: #9cb9ff;
|
||||||
--color-brand-400: #7592ff;
|
--color-brand-400: #7592ff;
|
||||||
--color-brand-500: #0693e3; /* IGNY8 brand blue */
|
--color-brand-500: var(--color-primary); /* Primary brand blue */
|
||||||
--color-brand-600: #0472b8; /* IGNY8 brand blue dark */
|
--color-brand-600: var(--color-primary-dark); /* Primary brand blue dark */
|
||||||
--color-brand-700: #2a31d8;
|
--color-brand-700: #2a31d8;
|
||||||
--color-brand-800: #252dae;
|
--color-brand-800: #252dae;
|
||||||
--color-brand-900: #262e89;
|
--color-brand-900: #262e89;
|
||||||
|
|||||||
@@ -1,4 +1,6 @@
|
|||||||
import React from "react";
|
import React from "react";
|
||||||
|
import Button from "../../components/ui/button/Button";
|
||||||
|
import { Link } from "react-router-dom";
|
||||||
interface CTASectionProps {
|
interface CTASectionProps {
|
||||||
title: string;
|
title: string;
|
||||||
description: string;
|
description: string;
|
||||||
@@ -12,36 +14,53 @@ const CTASection: React.FC<CTASectionProps> = ({
|
|||||||
primaryCta,
|
primaryCta,
|
||||||
secondaryCta,
|
secondaryCta,
|
||||||
}) => {
|
}) => {
|
||||||
const renderAnchor = (label: string, href: string, className: string) => {
|
const renderCta = (label: string, href: string, isPrimary: boolean) => {
|
||||||
const isExternal = href.startsWith("http");
|
const isExternal = href.startsWith("http");
|
||||||
|
const buttonClasses = isPrimary
|
||||||
|
? "shadow-lg shadow-[var(--color-primary)]/30"
|
||||||
|
: "";
|
||||||
|
|
||||||
if (isExternal) {
|
if (isExternal) {
|
||||||
return (
|
return (
|
||||||
<a
|
<Button
|
||||||
key={href}
|
key={href}
|
||||||
|
as="a"
|
||||||
href={href}
|
href={href}
|
||||||
className={className}
|
|
||||||
target="_blank"
|
target="_blank"
|
||||||
rel="noreferrer"
|
rel="noreferrer"
|
||||||
|
variant={isPrimary ? "gradient" : "outline"}
|
||||||
|
tone={isPrimary ? "brand" : "neutral"}
|
||||||
|
shape="pill"
|
||||||
|
size="lg"
|
||||||
|
className={buttonClasses}
|
||||||
>
|
>
|
||||||
{label}
|
{label}
|
||||||
</a>
|
</Button>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<a key={href} href={href} className={className}>
|
<Button
|
||||||
|
key={href}
|
||||||
|
as={Link}
|
||||||
|
to={href}
|
||||||
|
variant={isPrimary ? "gradient" : "outline"}
|
||||||
|
tone={isPrimary ? "brand" : "neutral"}
|
||||||
|
shape="pill"
|
||||||
|
size="lg"
|
||||||
|
className={buttonClasses}
|
||||||
|
>
|
||||||
{label}
|
{label}
|
||||||
</a>
|
</Button>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<section className="py-24 bg-gradient-to-b from-white via-slate-50 to-white">
|
<section className="py-24 bg-gradient-to-b from-white via-slate-50 to-white">
|
||||||
<div className="max-w-5xl mx-auto px-6">
|
<div className="max-w-5xl mx-auto px-6">
|
||||||
<div className="relative overflow-hidden rounded-3xl border-2 border-[var(--igny8-blue)]/20 bg-gradient-to-br from-[var(--igny8-blue)]/5 via-[var(--igny8-purple)]/5 to-[var(--igny8-green)]/5 p-10 md:p-14 shadow-xl">
|
<div className="relative overflow-hidden rounded-3xl border-2 border-[var(--color-primary)]/20 bg-gradient-to-br from-[var(--color-primary)]/5 via-[var(--color-purple)]/5 to-[var(--color-success)]/5 p-10 md:p-14 shadow-xl">
|
||||||
<div className="absolute inset-0 bg-gradient-to-r from-[var(--igny8-blue)]/10 via-transparent to-[var(--igny8-purple)]/10" />
|
<div className="absolute inset-0 bg-gradient-to-r from-[var(--color-primary)]/10 via-transparent to-[var(--color-purple)]/10" />
|
||||||
<div className="absolute -inset-1 bg-gradient-to-r from-[var(--igny8-blue)]/20 via-[var(--igny8-purple)]/20 to-[var(--igny8-green)]/20 rounded-3xl blur-xl -z-10 opacity-50" />
|
<div className="absolute -inset-1 bg-gradient-to-r from-[var(--color-primary)]/20 via-[var(--color-purple)]/20 to-[var(--color-success)]/20 rounded-3xl blur-xl -z-10 opacity-50" />
|
||||||
<div className="relative flex flex-col gap-6">
|
<div className="relative flex flex-col gap-6">
|
||||||
<h3 className="text-3xl md:text-4xl font-semibold text-slate-900 leading-tight">
|
<h3 className="text-3xl md:text-4xl font-semibold text-slate-900 leading-tight">
|
||||||
{title}
|
{title}
|
||||||
@@ -50,18 +69,8 @@ const CTASection: React.FC<CTASectionProps> = ({
|
|||||||
{description}
|
{description}
|
||||||
</p>
|
</p>
|
||||||
<div className="flex flex-col sm:flex-row gap-4">
|
<div className="flex flex-col sm:flex-row gap-4">
|
||||||
{renderAnchor(
|
{renderCta(primaryCta.label, primaryCta.href, true)}
|
||||||
primaryCta.label,
|
{secondaryCta && renderCta(secondaryCta.label, secondaryCta.href, false)}
|
||||||
primaryCta.href,
|
|
||||||
"inline-flex items-center justify-center rounded-full bg-gradient-to-r from-[var(--igny8-blue)] to-[var(--igny8-blue-dark)] hover:from-[var(--igny8-blue-dark)] hover:to-[var(--igny8-blue)] text-white px-6 py-3 text-sm md:text-base font-semibold transition shadow-lg shadow-[var(--igny8-blue)]/30"
|
|
||||||
)}
|
|
||||||
{secondaryCta && (
|
|
||||||
renderAnchor(
|
|
||||||
secondaryCta.label,
|
|
||||||
secondaryCta.href,
|
|
||||||
"inline-flex items-center justify-center rounded-full border-2 border-slate-300 bg-white/50 backdrop-blur-sm px-6 py-3 text-sm md:text-base font-semibold text-slate-700 hover:text-slate-900 hover:border-[#0693e3] hover:bg-white transition"
|
|
||||||
)
|
|
||||||
)}
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -14,10 +14,10 @@ interface FeatureGridProps {
|
|||||||
|
|
||||||
const FeatureGrid: React.FC<FeatureGridProps> = ({ features }) => {
|
const FeatureGrid: React.FC<FeatureGridProps> = ({ features }) => {
|
||||||
const iconColors = [
|
const iconColors = [
|
||||||
"from-[var(--igny8-blue)] to-[var(--igny8-blue-dark)]", // Blue
|
"from-[var(--color-primary)] to-[var(--color-primary-dark)]", // Blue
|
||||||
"from-[var(--igny8-green)] to-[var(--igny8-green-dark)]", // Green
|
"from-[var(--color-success)] to-[var(--color-success-dark)]", // Green
|
||||||
"from-[var(--igny8-amber)] to-[var(--igny8-amber-dark)]", // Amber
|
"from-[var(--color-warning)] to-[var(--color-warning-dark)]", // Amber
|
||||||
"from-[var(--igny8-purple)] to-[var(--igny8-purple-dark)]", // Purple
|
"from-[var(--color-purple)] to-[var(--color-purple-dark)]", // Purple
|
||||||
];
|
];
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
|||||||
@@ -1,5 +1,7 @@
|
|||||||
import React from "react";
|
import React from "react";
|
||||||
import { Link } from "react-router-dom";
|
import { Link } from "react-router-dom";
|
||||||
|
import Button from "../../components/ui/button/Button";
|
||||||
|
import Badge from "../../components/ui/badge/Badge";
|
||||||
|
|
||||||
interface HeroSectionProps {
|
interface HeroSectionProps {
|
||||||
image: string;
|
image: string;
|
||||||
@@ -16,38 +18,59 @@ const HeroSection: React.FC<HeroSectionProps> = ({
|
|||||||
primaryCta,
|
primaryCta,
|
||||||
secondaryCta,
|
secondaryCta,
|
||||||
}) => {
|
}) => {
|
||||||
const renderCta = (cta: { label: string; href: string }, className: string) => {
|
const renderCta = (cta: { label: string; href: string }, isPrimary: boolean) => {
|
||||||
const isExternal = cta.href.startsWith("http");
|
const isExternal = cta.href.startsWith("http");
|
||||||
|
const buttonClasses = isPrimary
|
||||||
|
? "shadow-lg shadow-[var(--color-primary)]/30"
|
||||||
|
: "border-white/30 bg-white/5 backdrop-blur-sm text-white hover:bg-white/10 hover:border-white/50";
|
||||||
|
|
||||||
if (isExternal) {
|
if (isExternal) {
|
||||||
return (
|
return (
|
||||||
<a
|
<Button
|
||||||
|
as="a"
|
||||||
href={cta.href}
|
href={cta.href}
|
||||||
className={className}
|
|
||||||
target="_blank"
|
target="_blank"
|
||||||
rel="noreferrer"
|
rel="noreferrer"
|
||||||
|
variant={isPrimary ? "gradient" : "outline"}
|
||||||
|
tone={isPrimary ? "brand" : "neutral"}
|
||||||
|
shape="pill"
|
||||||
|
size="lg"
|
||||||
|
className={buttonClasses}
|
||||||
>
|
>
|
||||||
{cta.label}
|
{cta.label}
|
||||||
</a>
|
</Button>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Link to={cta.href} className={className}>
|
<Button
|
||||||
|
as={Link}
|
||||||
|
to={cta.href}
|
||||||
|
variant={isPrimary ? "gradient" : "outline"}
|
||||||
|
tone={isPrimary ? "brand" : "neutral"}
|
||||||
|
shape="pill"
|
||||||
|
size="lg"
|
||||||
|
className={buttonClasses}
|
||||||
|
>
|
||||||
{cta.label}
|
{cta.label}
|
||||||
</Link>
|
</Button>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<section className="relative overflow-hidden bg-gradient-to-br from-[#0d1b2a] via-[#142b3f] to-[#1a3a5a]">
|
<section className="relative overflow-hidden bg-gradient-to-br from-[#0d1b2a] via-[#142b3f] to-[#1a3a5a]">
|
||||||
<div className="absolute inset-0 bg-gradient-to-br from-[var(--igny8-blue)]/10 via-transparent to-[var(--igny8-purple)]/10" />
|
<div className="absolute inset-0 bg-gradient-to-br from-[var(--color-primary)]/10 via-transparent to-[var(--color-purple)]/10" />
|
||||||
<div className="absolute inset-0 bg-[radial-gradient(circle_at_30%_20%,rgba(6,147,227,0.15),transparent_50%)]" />
|
<div className="absolute inset-0 bg-[radial-gradient(circle_at_30%_20%,rgba(6,147,227,0.15),transparent_50%)]" />
|
||||||
<div className="relative max-w-6xl mx-auto px-6 py-24 md:py-32 flex flex-col lg:flex-row gap-16 items-center">
|
<div className="relative max-w-6xl mx-auto px-6 py-24 md:py-32 flex flex-col lg:flex-row gap-16 items-center">
|
||||||
<div className="flex-1 flex flex-col gap-6">
|
<div className="flex-1 flex flex-col gap-6">
|
||||||
<span className="inline-flex items-center gap-2 text-xs font-semibold uppercase tracking-[0.28em] text-[var(--igny8-blue)] bg-[var(--igny8-blue)]/10 px-4 py-2 rounded-full border border-[var(--igny8-blue)]/20">
|
<Badge
|
||||||
|
variant="soft"
|
||||||
|
tone="primary"
|
||||||
|
size="sm"
|
||||||
|
className="uppercase tracking-[0.28em] border border-[var(--color-primary)]/20"
|
||||||
|
>
|
||||||
AI + SEO PLATFORM
|
AI + SEO PLATFORM
|
||||||
</span>
|
</Badge>
|
||||||
<h1 className="text-4xl md:text-6xl font-semibold leading-tight text-white">
|
<h1 className="text-4xl md:text-6xl font-semibold leading-tight text-white">
|
||||||
{headline}
|
{headline}
|
||||||
</h1>
|
</h1>
|
||||||
@@ -55,26 +78,20 @@ const HeroSection: React.FC<HeroSectionProps> = ({
|
|||||||
{subheadline}
|
{subheadline}
|
||||||
</p>
|
</p>
|
||||||
<div className="flex flex-col sm:flex-row gap-4">
|
<div className="flex flex-col sm:flex-row gap-4">
|
||||||
{renderCta(
|
{renderCta(primaryCta, true)}
|
||||||
primaryCta,
|
{secondaryCta && renderCta(secondaryCta, false)}
|
||||||
"inline-flex items-center justify-center rounded-full bg-gradient-to-r from-[var(--igny8-blue)] to-[var(--igny8-blue-dark)] hover:from-[var(--igny8-blue-dark)] hover:to-[var(--igny8-blue)] text-white px-6 py-3 text-sm md:text-base font-semibold transition shadow-lg shadow-[var(--igny8-blue)]/30"
|
|
||||||
)}
|
|
||||||
{secondaryCta && renderCta(
|
|
||||||
secondaryCta,
|
|
||||||
"inline-flex items-center justify-center rounded-full border-2 border-white/30 bg-white/5 backdrop-blur-sm px-6 py-3 text-sm md:text-base font-semibold text-white hover:bg-white/10 hover:border-white/50 transition"
|
|
||||||
)}
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div className="flex-1 w-full">
|
<div className="flex-1 w-full">
|
||||||
<div className="relative rounded-3xl border-2 border-[var(--igny8-blue)]/30 bg-gradient-to-br from-white/5 to-white/10 backdrop-blur-sm shadow-2xl shadow-[var(--igny8-blue)]/20">
|
<div className="relative rounded-3xl border-2 border-[var(--color-primary)]/30 bg-gradient-to-br from-white/5 to-white/10 backdrop-blur-sm shadow-2xl shadow-[var(--color-primary)]/20">
|
||||||
<div className="absolute -inset-1 bg-gradient-to-r from-[#0693e3]/20 via-[var(--igny8-purple)]/20 to-[var(--igny8-green)]/20 rounded-3xl blur-xl -z-10" />
|
<div className="absolute -inset-1 bg-gradient-to-r from-[var(--color-primary)]/20 via-[var(--color-purple)]/20 to-[var(--color-success)]/20 rounded-3xl blur-xl -z-10" />
|
||||||
<img
|
<img
|
||||||
src={`/marketing/images/${image}`}
|
src={`/marketing/images/${image}`}
|
||||||
alt="Igny8 dashboard preview"
|
alt="Igny8 dashboard preview"
|
||||||
className="w-full h-full object-cover rounded-3xl"
|
className="w-full h-full object-cover rounded-3xl"
|
||||||
/>
|
/>
|
||||||
<div className="absolute bottom-6 left-6 bg-gradient-to-br from-[#0d1b2a]/95 to-[#142b3f]/95 backdrop-blur-lg border border-[var(--igny8-blue)]/30 rounded-2xl px-6 py-4 flex flex-col gap-1 shadow-xl">
|
<div className="absolute bottom-6 left-6 bg-gradient-to-br from-[#0d1b2a]/95 to-[#142b3f]/95 backdrop-blur-lg border border-[var(--color-primary)]/30 rounded-2xl px-6 py-4 flex flex-col gap-1 shadow-xl">
|
||||||
<span className="text-xs uppercase tracking-[0.2em] text-[var(--igny8-blue)]">
|
<span className="text-xs uppercase tracking-[0.2em] text-[var(--color-primary)]">
|
||||||
End-to-end automation
|
End-to-end automation
|
||||||
</span>
|
</span>
|
||||||
<span className="text-lg font-semibold text-white">
|
<span className="text-lg font-semibold text-white">
|
||||||
|
|||||||
@@ -11,9 +11,9 @@ interface MetricsBarProps {
|
|||||||
|
|
||||||
const MetricsBar: React.FC<MetricsBarProps> = ({ metrics }) => {
|
const MetricsBar: React.FC<MetricsBarProps> = ({ metrics }) => {
|
||||||
const accentColors = [
|
const accentColors = [
|
||||||
"from-[var(--igny8-blue)] to-[var(--igny8-blue-dark)]",
|
"from-[var(--color-primary)] to-[var(--color-primary-dark)]",
|
||||||
"from-[var(--igny8-green)] to-[var(--igny8-green-dark)]",
|
"from-[var(--color-success)] to-[var(--color-success-dark)]",
|
||||||
"from-[var(--igny8-amber)] to-[var(--igny8-amber-dark)]",
|
"from-[var(--color-warning)] to-[var(--color-warning-dark)]",
|
||||||
];
|
];
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
|||||||
@@ -11,10 +11,10 @@ interface WorkflowStepsProps {
|
|||||||
|
|
||||||
const WorkflowSteps: React.FC<WorkflowStepsProps> = ({ steps }) => {
|
const WorkflowSteps: React.FC<WorkflowStepsProps> = ({ steps }) => {
|
||||||
const stepColors = [
|
const stepColors = [
|
||||||
"from-[var(--igny8-blue)] to-[var(--igny8-blue-dark)]",
|
"from-[var(--color-primary)] to-[var(--color-primary-dark)]",
|
||||||
"from-[var(--igny8-green)] to-[var(--igny8-green-dark)]",
|
"from-[var(--color-success)] to-[var(--color-success-dark)]",
|
||||||
"from-[var(--igny8-amber)] to-[var(--igny8-amber-dark)]",
|
"from-[var(--color-warning)] to-[var(--color-warning-dark)]",
|
||||||
"from-[var(--igny8-purple)] to-[var(--igny8-purple-dark)]",
|
"from-[var(--color-purple)] to-[var(--color-purple-dark)]",
|
||||||
];
|
];
|
||||||
|
|
||||||
return (
|
return (
|
||||||
@@ -25,12 +25,12 @@ const WorkflowSteps: React.FC<WorkflowStepsProps> = ({ steps }) => {
|
|||||||
return (
|
return (
|
||||||
<div
|
<div
|
||||||
key={step.title}
|
key={step.title}
|
||||||
className="rounded-3xl border-2 border-slate-200 bg-gradient-to-br from-white to-slate-50/50 p-6 flex flex-col gap-4 hover:border-[var(--igny8-blue)]/50 transition-all shadow-sm hover:shadow-xl hover:-translate-y-1 group"
|
className="rounded-3xl border-2 border-slate-200 bg-gradient-to-br from-white to-slate-50/50 p-6 flex flex-col gap-4 hover:border-[var(--color-primary)]/50 transition-all shadow-sm hover:shadow-xl hover:-translate-y-1 group"
|
||||||
>
|
>
|
||||||
<div className={`h-12 w-12 rounded-2xl bg-gradient-to-br ${gradient} flex items-center justify-center font-semibold text-white text-xl shadow-lg`}>
|
<div className={`h-12 w-12 rounded-2xl bg-gradient-to-br ${gradient} flex items-center justify-center font-semibold text-white text-xl shadow-lg`}>
|
||||||
{index + 1}
|
{index + 1}
|
||||||
</div>
|
</div>
|
||||||
<h3 className="text-lg font-semibold text-slate-900 leading-snug group-hover:text-[var(--igny8-blue)] transition">
|
<h3 className="text-lg font-semibold text-slate-900 leading-snug group-hover:text-[var(--color-primary)] transition">
|
||||||
{step.title}
|
{step.title}
|
||||||
</h3>
|
</h3>
|
||||||
<p className="text-sm text-slate-600 leading-relaxed">
|
<p className="text-sm text-slate-600 leading-relaxed">
|
||||||
|
|||||||
@@ -19,7 +19,7 @@ const MarketingLayout: React.FC<MarketingLayoutProps> = ({ children }) => {
|
|||||||
<header className="sticky top-0 z-[1100] backdrop-blur-xl bg-white/95 border-b border-slate-200 shadow-sm">
|
<header className="sticky top-0 z-[1100] backdrop-blur-xl bg-white/95 border-b border-slate-200 shadow-sm">
|
||||||
<div className="max-w-6xl mx-auto px-6 py-4 flex items-center justify-between">
|
<div className="max-w-6xl mx-auto px-6 py-4 flex items-center justify-between">
|
||||||
<Link to="/" className="flex items-center gap-3" onClick={closeMobile}>
|
<Link to="/" className="flex items-center gap-3" onClick={closeMobile}>
|
||||||
<span className="h-10 w-10 rounded-xl bg-gradient-to-br from-[var(--igny8-blue)] to-[var(--igny8-blue-dark)] flex items-center justify-center text-lg font-bold text-white shadow-lg shadow-[var(--igny8-blue)]/30">
|
<span className="h-10 w-10 rounded-xl bg-gradient-to-br from-[var(--color-primary)] to-[var(--color-primary-dark)] flex items-center justify-center text-lg font-bold text-white shadow-lg shadow-[var(--color-primary)]/30">
|
||||||
IG
|
IG
|
||||||
</span>
|
</span>
|
||||||
<div className="flex flex-col leading-tight">
|
<div className="flex flex-col leading-tight">
|
||||||
@@ -37,7 +37,7 @@ const MarketingLayout: React.FC<MarketingLayoutProps> = ({ children }) => {
|
|||||||
<Link
|
<Link
|
||||||
key={link.name}
|
key={link.name}
|
||||||
to={link.path}
|
to={link.path}
|
||||||
className={`transition hover:text-[var(--igny8-blue)] ${isActive ? "text-[var(--igny8-blue)] font-semibold" : "text-slate-700"}`}
|
className={`transition hover:text-[var(--color-primary)] ${isActive ? "text-[var(--color-primary)] font-semibold" : "text-slate-700"}`}
|
||||||
>
|
>
|
||||||
{link.name}
|
{link.name}
|
||||||
</Link>
|
</Link>
|
||||||
@@ -54,7 +54,7 @@ const MarketingLayout: React.FC<MarketingLayoutProps> = ({ children }) => {
|
|||||||
</a>
|
</a>
|
||||||
<a
|
<a
|
||||||
href="https://app.igny8.com/signup"
|
href="https://app.igny8.com/signup"
|
||||||
className="inline-flex items-center justify-center rounded-full bg-gradient-to-r from-[var(--igny8-blue)] to-[var(--igny8-blue-dark)] hover:from-[var(--igny8-blue-dark)] hover:to-[var(--igny8-blue)] text-white px-5 py-2 text-sm font-semibold transition shadow-md shadow-[var(--igny8-blue)]/30"
|
className="inline-flex items-center justify-center rounded-full bg-gradient-to-r from-[var(--color-primary)] to-[var(--color-primary-dark)] hover:from-[var(--color-primary-dark)] hover:to-[var(--color-primary)] text-white px-5 py-2 text-sm font-semibold transition shadow-md shadow-[var(--color-primary)]/30"
|
||||||
>
|
>
|
||||||
Start Free
|
Start Free
|
||||||
</a>
|
</a>
|
||||||
@@ -93,7 +93,7 @@ const MarketingLayout: React.FC<MarketingLayoutProps> = ({ children }) => {
|
|||||||
</a>
|
</a>
|
||||||
<a
|
<a
|
||||||
href="https://app.igny8.com/signup"
|
href="https://app.igny8.com/signup"
|
||||||
className="inline-flex items-center justify-center rounded-full bg-gradient-to-r from-[var(--igny8-blue)] to-[var(--igny8-blue-dark)] hover:from-[var(--igny8-blue-dark)] hover:to-[var(--igny8-blue)] text-white px-5 py-2 text-sm font-semibold transition shadow-md shadow-[var(--igny8-blue)]/30"
|
className="inline-flex items-center justify-center rounded-full bg-gradient-to-r from-[var(--color-primary)] to-[var(--color-primary-dark)] hover:from-[var(--color-primary-dark)] hover:to-[var(--color-primary)] text-white px-5 py-2 text-sm font-semibold transition shadow-md shadow-[var(--color-primary)]/30"
|
||||||
onClick={closeMobile}
|
onClick={closeMobile}
|
||||||
>
|
>
|
||||||
Start Free
|
Start Free
|
||||||
@@ -109,7 +109,7 @@ const MarketingLayout: React.FC<MarketingLayoutProps> = ({ children }) => {
|
|||||||
<div className="max-w-6xl mx-auto px-6 py-16 grid grid-cols-1 md:grid-cols-4 gap-12">
|
<div className="max-w-6xl mx-auto px-6 py-16 grid grid-cols-1 md:grid-cols-4 gap-12">
|
||||||
<div className="space-y-4">
|
<div className="space-y-4">
|
||||||
<Link to="/" className="inline-flex items-center gap-3">
|
<Link to="/" className="inline-flex items-center gap-3">
|
||||||
<span className="h-10 w-10 rounded-xl bg-gradient-to-br from-[var(--igny8-blue)] to-[var(--igny8-blue-dark)] flex items-center justify-center text-lg font-bold text-white shadow-lg shadow-[var(--igny8-blue)]/30">
|
<span className="h-10 w-10 rounded-xl bg-gradient-to-br from-[var(--color-primary)] to-[var(--color-primary-dark)] flex items-center justify-center text-lg font-bold text-white shadow-lg shadow-[var(--color-primary)]/30">
|
||||||
IG
|
IG
|
||||||
</span>
|
</span>
|
||||||
<div className="flex flex-col leading-tight">
|
<div className="flex flex-col leading-tight">
|
||||||
@@ -137,7 +137,7 @@ const MarketingLayout: React.FC<MarketingLayoutProps> = ({ children }) => {
|
|||||||
<ul className="space-y-3 text-sm text-slate-300">
|
<ul className="space-y-3 text-sm text-slate-300">
|
||||||
{group.links.map((link) => (
|
{group.links.map((link) => (
|
||||||
<li key={link.name}>
|
<li key={link.name}>
|
||||||
<Link to={link.path} className="hover:text-[var(--igny8-blue)] transition">
|
<Link to={link.path} className="hover:text-[var(--color-primary)] transition">
|
||||||
{link.name}
|
{link.name}
|
||||||
</Link>
|
</Link>
|
||||||
</li>
|
</li>
|
||||||
@@ -146,7 +146,7 @@ const MarketingLayout: React.FC<MarketingLayoutProps> = ({ children }) => {
|
|||||||
</div>
|
</div>
|
||||||
))}
|
))}
|
||||||
</div>
|
</div>
|
||||||
<div className="border-t border-[#0693e3]/20 py-6 px-6 text-center text-xs text-slate-400">
|
<div className="border-t border-[var(--color-primary)]/20 py-6 px-6 text-center text-xs text-slate-400">
|
||||||
Built for marketers who automate growth with AI.
|
Built for marketers who automate growth with AI.
|
||||||
</div>
|
</div>
|
||||||
</footer>
|
</footer>
|
||||||
|
|||||||
@@ -43,7 +43,7 @@ const CaseStudies: React.FC = () => {
|
|||||||
summary:
|
summary:
|
||||||
"Publisher running 6 niche brands used Igny8 to centralize research, briefs, and AI-assisted writing. Automation recipes ensured every keyword moved to published content with minimal handoff friction.",
|
"Publisher running 6 niche brands used Igny8 to centralize research, briefs, and AI-assisted writing. Automation recipes ensured every keyword moved to published content with minimal handoff friction.",
|
||||||
image: "case-lumen.png",
|
image: "case-lumen.png",
|
||||||
iconColor: "from-[var(--igny8-blue)] to-[var(--igny8-blue-dark)]",
|
iconColor: "from-[var(--color-primary)] to-[var(--color-primary-dark)]",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
company: "Northbeam Digital",
|
company: "Northbeam Digital",
|
||||||
@@ -56,7 +56,7 @@ const CaseStudies: React.FC = () => {
|
|||||||
summary:
|
summary:
|
||||||
"Multi-client agency adopted Igny8 to standardize workflows, automate reporting, and launch custom Thinker playbooks. Teams now produce keyword research, content, and images for 20+ clients simultaneously.",
|
"Multi-client agency adopted Igny8 to standardize workflows, automate reporting, and launch custom Thinker playbooks. Teams now produce keyword research, content, and images for 20+ clients simultaneously.",
|
||||||
image: "case-northbeam.png",
|
image: "case-northbeam.png",
|
||||||
iconColor: "from-[var(--igny8-green)] to-[var(--igny8-green-dark)]",
|
iconColor: "from-[var(--color-success)] to-[var(--color-success-dark)]",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
company: "Arcadia SaaS",
|
company: "Arcadia SaaS",
|
||||||
@@ -69,7 +69,7 @@ const CaseStudies: React.FC = () => {
|
|||||||
summary:
|
summary:
|
||||||
"Arcadia used Igny8 to align SEO, product marketing, and design. Thinker libraries ensured every asset matched product messaging; automation pushed approved content directly into WordPress and HubSpot.",
|
"Arcadia used Igny8 to align SEO, product marketing, and design. Thinker libraries ensured every asset matched product messaging; automation pushed approved content directly into WordPress and HubSpot.",
|
||||||
image: "case-arcadia.png",
|
image: "case-arcadia.png",
|
||||||
iconColor: "from-[var(--igny8-purple)] to-[var(--igny8-purple-dark)]",
|
iconColor: "from-[var(--color-purple)] to-[var(--color-purple-dark)]",
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
@@ -96,7 +96,7 @@ const CaseStudies: React.FC = () => {
|
|||||||
<section className="max-w-7xl mx-auto px-6 pb-24 space-y-16">
|
<section className="max-w-7xl mx-auto px-6 pb-24 space-y-16">
|
||||||
{caseStudies.map((cs, idx) => {
|
{caseStudies.map((cs, idx) => {
|
||||||
const metricColors = [
|
const metricColors = [
|
||||||
{ border: "border-slate-200", bg: "from-white to-slate-50/50", text: "igny8-text-blue" },
|
{ border: "border-slate-200", bg: "from-white to-slate-50/50", text: "text-[var(--color-primary)]" },
|
||||||
{ border: "border-slate-200", bg: "from-white to-slate-50/50", text: "text-[#0bbf87]" },
|
{ border: "border-slate-200", bg: "from-white to-slate-50/50", text: "text-[#0bbf87]" },
|
||||||
{ border: "border-slate-200", bg: "from-white to-slate-50/50", text: "text-[#ff7a00]" },
|
{ border: "border-slate-200", bg: "from-white to-slate-50/50", text: "text-[#ff7a00]" },
|
||||||
];
|
];
|
||||||
@@ -154,7 +154,7 @@ const CaseStudies: React.FC = () => {
|
|||||||
<div className="max-w-7xl mx-auto px-6 grid grid-cols-1 lg:grid-cols-2 gap-8">
|
<div className="max-w-7xl mx-auto px-6 grid grid-cols-1 lg:grid-cols-2 gap-8">
|
||||||
<div className="rounded-2xl border-2 border-slate-200 bg-white p-8 space-y-6 shadow-sm">
|
<div className="rounded-2xl border-2 border-slate-200 bg-white p-8 space-y-6 shadow-sm">
|
||||||
<div className="flex items-center gap-3">
|
<div className="flex items-center gap-3">
|
||||||
<div className="size-12 rounded-xl bg-gradient-to-br from-[var(--igny8-blue)] to-[var(--igny8-blue-dark)] flex items-center justify-center text-white shadow-lg">
|
<div className="size-12 rounded-xl bg-gradient-to-br from-[var(--color-primary)] to-[var(--color-primary-dark)] flex items-center justify-center text-white shadow-lg">
|
||||||
<CheckCircleIcon className="h-6 w-6" />
|
<CheckCircleIcon className="h-6 w-6" />
|
||||||
</div>
|
</div>
|
||||||
<h4 className="text-2xl font-bold text-slate-900">
|
<h4 className="text-2xl font-bold text-slate-900">
|
||||||
@@ -176,7 +176,7 @@ const CaseStudies: React.FC = () => {
|
|||||||
</div>
|
</div>
|
||||||
<div className="rounded-2xl border-2 border-slate-200 bg-white p-8 space-y-6 shadow-sm">
|
<div className="rounded-2xl border-2 border-slate-200 bg-white p-8 space-y-6 shadow-sm">
|
||||||
<div className="flex items-center gap-3">
|
<div className="flex items-center gap-3">
|
||||||
<div className="size-12 rounded-xl bg-gradient-to-br from-[var(--igny8-green)] to-[var(--igny8-green-dark)] flex items-center justify-center text-white shadow-lg">
|
<div className="size-12 rounded-xl bg-gradient-to-br from-[var(--color-success)] to-[var(--color-success-dark)] flex items-center justify-center text-white shadow-lg">
|
||||||
<CheckCircleIcon className="h-6 w-6" />
|
<CheckCircleIcon className="h-6 w-6" />
|
||||||
</div>
|
</div>
|
||||||
<h4 className="text-2xl font-bold text-slate-900">
|
<h4 className="text-2xl font-bold text-slate-900">
|
||||||
@@ -186,7 +186,7 @@ const CaseStudies: React.FC = () => {
|
|||||||
<p className="text-base text-slate-700 leading-relaxed">
|
<p className="text-base text-slate-700 leading-relaxed">
|
||||||
Igny8's roadmap is shaped by an active community of customer strategists, agency partners, and product marketers. Join and get early access to features, template libraries, and industry benchmarks.
|
Igny8's roadmap is shaped by an active community of customer strategists, agency partners, and product marketers. Join and get early access to features, template libraries, and industry benchmarks.
|
||||||
</p>
|
</p>
|
||||||
<button className="inline-flex items-center justify-center gap-2 rounded-xl bg-gradient-to-r from-[var(--igny8-blue)] to-[var(--igny8-blue-dark)] text-white px-6 py-3 text-sm font-semibold hover:shadow-lg transition">
|
<button className="inline-flex items-center justify-center gap-2 rounded-xl bg-gradient-to-r from-[var(--color-primary)] to-[var(--color-primary-dark)] text-white px-6 py-3 text-sm font-semibold hover:shadow-lg transition">
|
||||||
Join the CAB waitlist
|
Join the CAB waitlist
|
||||||
<ArrowRightIcon className="h-4 w-4" />
|
<ArrowRightIcon className="h-4 w-4" />
|
||||||
</button>
|
</button>
|
||||||
@@ -216,7 +216,7 @@ const CaseStudies: React.FC = () => {
|
|||||||
</Link>
|
</Link>
|
||||||
<Link
|
<Link
|
||||||
to="/resources"
|
to="/resources"
|
||||||
className="inline-flex items-center justify-center gap-2 rounded-xl bg-white igny8-text-blue px-10 py-5 text-lg font-bold hover:bg-white/95 transition shadow-xl hover:shadow-2xl hover:-translate-y-0.5"
|
className="inline-flex items-center justify-center gap-2 rounded-xl bg-white text-[var(--color-primary)] px-10 py-5 text-lg font-bold hover:bg-white/95 transition shadow-xl hover:shadow-2xl hover:-translate-y-0.5"
|
||||||
>
|
>
|
||||||
<RocketLaunchIcon className="h-5 w-5" />
|
<RocketLaunchIcon className="h-5 w-5" />
|
||||||
Download case study pack
|
Download case study pack
|
||||||
|
|||||||
@@ -14,14 +14,14 @@ const Contact: React.FC = () => {
|
|||||||
</section>
|
</section>
|
||||||
|
|
||||||
<section className="max-w-5xl mx-auto px-6 pb-24 grid grid-cols-1 lg:grid-cols-2 gap-12">
|
<section className="max-w-5xl mx-auto px-6 pb-24 grid grid-cols-1 lg:grid-cols-2 gap-12">
|
||||||
<form className="rounded-3xl border-2 border-[var(--igny8-blue)]/30 bg-gradient-to-br from-[var(--igny8-blue)]/10 via-white to-[var(--igny8-green)]/5 p-10 space-y-6 shadow-lg">
|
<form className="rounded-3xl border-2 border-[var(--color-primary)]/30 bg-gradient-to-br from-[var(--color-primary)]/10 via-white to-[var(--color-success)]/5 p-10 space-y-6 shadow-lg">
|
||||||
<div className="grid grid-cols-1 sm:grid-cols-2 gap-4">
|
<div className="grid grid-cols-1 sm:grid-cols-2 gap-4">
|
||||||
<label className="flex flex-col gap-2 text-sm text-slate-600">
|
<label className="flex flex-col gap-2 text-sm text-slate-600">
|
||||||
First name
|
First name
|
||||||
<input
|
<input
|
||||||
type="text"
|
type="text"
|
||||||
placeholder="Alex"
|
placeholder="Alex"
|
||||||
className="rounded-xl border-2 border-slate-200 bg-white px-4 py-3 text-sm text-slate-900 placeholder:text-slate-500 focus:outline-none focus:border-[var(--igny8-blue)] focus:ring-2 focus:ring-[var(--igny8-blue)]/20"
|
className="rounded-xl border-2 border-slate-200 bg-white px-4 py-3 text-sm text-slate-900 placeholder:text-slate-500 focus:outline-none focus:border-[var(--color-primary)] focus:ring-2 focus:ring-[var(--color-primary)]/20"
|
||||||
/>
|
/>
|
||||||
</label>
|
</label>
|
||||||
<label className="flex flex-col gap-2 text-sm text-slate-600">
|
<label className="flex flex-col gap-2 text-sm text-slate-600">
|
||||||
@@ -29,7 +29,7 @@ const Contact: React.FC = () => {
|
|||||||
<input
|
<input
|
||||||
type="text"
|
type="text"
|
||||||
placeholder="Rivera"
|
placeholder="Rivera"
|
||||||
className="rounded-xl border-2 border-slate-200 bg-white px-4 py-3 text-sm text-slate-900 placeholder:text-slate-500 focus:outline-none focus:border-[var(--igny8-blue)] focus:ring-2 focus:ring-[var(--igny8-blue)]/20"
|
className="rounded-xl border-2 border-slate-200 bg-white px-4 py-3 text-sm text-slate-900 placeholder:text-slate-500 focus:outline-none focus:border-[var(--color-primary)] focus:ring-2 focus:ring-[var(--color-primary)]/20"
|
||||||
/>
|
/>
|
||||||
</label>
|
</label>
|
||||||
</div>
|
</div>
|
||||||
@@ -39,7 +39,7 @@ const Contact: React.FC = () => {
|
|||||||
<input
|
<input
|
||||||
type="email"
|
type="email"
|
||||||
placeholder="you@company.com"
|
placeholder="you@company.com"
|
||||||
className="rounded-xl border-2 border-slate-200 bg-white px-4 py-3 text-sm text-slate-900 placeholder:text-slate-500 focus:outline-none focus:border-[var(--igny8-blue)] focus:ring-2 focus:ring-[var(--igny8-blue)]/20"
|
className="rounded-xl border-2 border-slate-200 bg-white px-4 py-3 text-sm text-slate-900 placeholder:text-slate-500 focus:outline-none focus:border-[var(--color-primary)] focus:ring-2 focus:ring-[var(--color-primary)]/20"
|
||||||
/>
|
/>
|
||||||
</label>
|
</label>
|
||||||
|
|
||||||
@@ -48,7 +48,7 @@ const Contact: React.FC = () => {
|
|||||||
<input
|
<input
|
||||||
type="text"
|
type="text"
|
||||||
placeholder="Company name"
|
placeholder="Company name"
|
||||||
className="rounded-xl border-2 border-slate-200 bg-white px-4 py-3 text-sm text-slate-900 placeholder:text-slate-500 focus:outline-none focus:border-[var(--igny8-blue)] focus:ring-2 focus:ring-[var(--igny8-blue)]/20"
|
className="rounded-xl border-2 border-slate-200 bg-white px-4 py-3 text-sm text-slate-900 placeholder:text-slate-500 focus:outline-none focus:border-[var(--color-primary)] focus:ring-2 focus:ring-[var(--color-primary)]/20"
|
||||||
/>
|
/>
|
||||||
</label>
|
</label>
|
||||||
|
|
||||||
@@ -57,7 +57,7 @@ const Contact: React.FC = () => {
|
|||||||
<textarea
|
<textarea
|
||||||
rows={4}
|
rows={4}
|
||||||
placeholder="Tell us about your current workflow, challenges, and goals."
|
placeholder="Tell us about your current workflow, challenges, and goals."
|
||||||
className="rounded-xl border-2 border-slate-200 bg-white px-4 py-3 text-sm text-slate-900 placeholder:text-slate-500 focus:outline-none focus:border-[var(--igny8-blue)] focus:ring-2 focus:ring-[var(--igny8-blue)]/20 resize-none"
|
className="rounded-xl border-2 border-slate-200 bg-white px-4 py-3 text-sm text-slate-900 placeholder:text-slate-500 focus:outline-none focus:border-[var(--color-primary)] focus:ring-2 focus:ring-[var(--color-primary)]/20 resize-none"
|
||||||
/>
|
/>
|
||||||
</label>
|
</label>
|
||||||
|
|
||||||
|
|||||||
@@ -40,13 +40,13 @@ const Home: React.FC = () => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const workflowSteps = [
|
const workflowSteps = [
|
||||||
{ name: "Keywords", icon: ListBulletIcon, color: "from-[var(--igny8-blue)] to-[var(--igny8-blue-dark)]" },
|
{ name: "Keywords", icon: ListBulletIcon, color: "from-[var(--color-primary)] to-[var(--color-primary-dark)]" },
|
||||||
{ name: "Clusters", icon: UserGroupIcon, color: "from-[var(--igny8-purple)] to-[var(--igny8-purple-dark)]" },
|
{ name: "Clusters", icon: UserGroupIcon, color: "from-[var(--color-purple)] to-[var(--color-purple-dark)]" },
|
||||||
{ name: "Ideas", icon: LightBulbIcon, color: "from-[var(--igny8-amber)] to-[var(--igny8-amber-dark)]" },
|
{ name: "Ideas", icon: LightBulbIcon, color: "from-[var(--color-warning)] to-[var(--color-warning-dark)]" },
|
||||||
{ name: "Tasks", icon: DocumentTextIcon, color: "from-[var(--igny8-green)] to-[var(--igny8-green-dark)]" },
|
{ name: "Tasks", icon: DocumentTextIcon, color: "from-[var(--color-success)] to-[var(--color-success-dark)]" },
|
||||||
{ name: "Content", icon: SparklesIcon, color: "from-[var(--igny8-blue)] to-[var(--igny8-blue-dark)]" },
|
{ name: "Content", icon: SparklesIcon, color: "from-[var(--color-primary)] to-[var(--color-primary-dark)]" },
|
||||||
{ name: "Images", icon: PhotoIcon, color: "from-[var(--igny8-purple)] to-[var(--igny8-purple-dark)]" },
|
{ name: "Images", icon: PhotoIcon, color: "from-[var(--color-purple)] to-[var(--color-purple-dark)]" },
|
||||||
{ name: "Publish", icon: BoltIcon, color: "from-[var(--igny8-green)] to-[var(--igny8-green-dark)]" },
|
{ name: "Publish", icon: BoltIcon, color: "from-[var(--color-success)] to-[var(--color-success-dark)]" },
|
||||||
];
|
];
|
||||||
|
|
||||||
const productModules = [
|
const productModules = [
|
||||||
@@ -60,7 +60,7 @@ const Home: React.FC = () => {
|
|||||||
"Priority scoring based on opportunity and competition",
|
"Priority scoring based on opportunity and competition",
|
||||||
],
|
],
|
||||||
icon: ChartBarIcon,
|
icon: ChartBarIcon,
|
||||||
color: "from-[var(--igny8-blue)] to-[var(--igny8-blue-dark)]",
|
color: "from-[var(--color-primary)] to-[var(--color-primary-dark)]",
|
||||||
image: "planner-dashboard.png",
|
image: "planner-dashboard.png",
|
||||||
link: "/product#planner",
|
link: "/product#planner",
|
||||||
align: "left",
|
align: "left",
|
||||||
@@ -75,7 +75,7 @@ const Home: React.FC = () => {
|
|||||||
"Collaborative editing and approval workflows",
|
"Collaborative editing and approval workflows",
|
||||||
],
|
],
|
||||||
icon: SparklesIcon,
|
icon: SparklesIcon,
|
||||||
color: "from-[var(--igny8-green)] to-[var(--igny8-green-dark)]",
|
color: "from-[var(--color-success)] to-[var(--color-success-dark)]",
|
||||||
image: "writer-dashboard.png",
|
image: "writer-dashboard.png",
|
||||||
link: "/product#writer",
|
link: "/product#writer",
|
||||||
align: "right",
|
align: "right",
|
||||||
@@ -90,7 +90,7 @@ const Home: React.FC = () => {
|
|||||||
"Automated guideline enforcement across all content",
|
"Automated guideline enforcement across all content",
|
||||||
],
|
],
|
||||||
icon: BoltIcon,
|
icon: BoltIcon,
|
||||||
color: "from-[var(--igny8-amber)] to-[var(--igny8-amber-dark)]",
|
color: "from-[var(--color-warning)] to-[var(--color-warning-dark)]",
|
||||||
image: "thinker-dashboard.png",
|
image: "thinker-dashboard.png",
|
||||||
link: "/product#thinker",
|
link: "/product#thinker",
|
||||||
align: "left",
|
align: "left",
|
||||||
@@ -105,7 +105,7 @@ const Home: React.FC = () => {
|
|||||||
"Real-time monitoring and error handling",
|
"Real-time monitoring and error handling",
|
||||||
],
|
],
|
||||||
icon: PhotoIcon,
|
icon: PhotoIcon,
|
||||||
color: "from-[var(--igny8-purple)] to-[var(--igny8-purple-dark)]",
|
color: "from-[var(--color-purple)] to-[var(--color-purple-dark)]",
|
||||||
image: "automation-dashboard.png",
|
image: "automation-dashboard.png",
|
||||||
link: "/product#automation",
|
link: "/product#automation",
|
||||||
align: "right",
|
align: "right",
|
||||||
@@ -115,7 +115,7 @@ const Home: React.FC = () => {
|
|||||||
return (
|
return (
|
||||||
<div className="bg-white">
|
<div className="bg-white">
|
||||||
{/* HERO SECTION */}
|
{/* HERO SECTION */}
|
||||||
<section className="relative overflow-hidden bg-gradient-to-br from-[var(--igny8-blue)] via-[var(--igny8-purple)] to-[#8b5cf6]">
|
<section className="relative overflow-hidden bg-gradient-to-br from-[var(--color-primary)] via-[var(--color-purple)] to-[#8b5cf6]">
|
||||||
{/* Radial glow behind headline */}
|
{/* Radial glow behind headline */}
|
||||||
<div className="absolute inset-0 bg-[radial-gradient(circle_at_30%_50%,rgba(255,255,255,0.1),transparent_60%)]" />
|
<div className="absolute inset-0 bg-[radial-gradient(circle_at_30%_50%,rgba(255,255,255,0.1),transparent_60%)]" />
|
||||||
<div className="absolute inset-0 bg-[radial-gradient(circle_at_70%_20%,rgba(109,74,227,0.2),transparent_50%)]" />
|
<div className="absolute inset-0 bg-[radial-gradient(circle_at_70%_20%,rgba(109,74,227,0.2),transparent_50%)]" />
|
||||||
@@ -136,7 +136,7 @@ const Home: React.FC = () => {
|
|||||||
<div className="flex flex-col sm:flex-row gap-4 mt-2">
|
<div className="flex flex-col sm:flex-row gap-4 mt-2">
|
||||||
{renderCta(
|
{renderCta(
|
||||||
{ label: "Start Free", href: "https://app.igny8.com/signup" },
|
{ label: "Start Free", href: "https://app.igny8.com/signup" },
|
||||||
"inline-flex items-center justify-center rounded-xl bg-white igny8-text-blue px-8 py-4 text-base font-semibold hover:bg-white/95 transition shadow-xl hover:shadow-2xl hover:-translate-y-0.5"
|
"inline-flex items-center justify-center rounded-xl bg-white text-[var(--color-primary)] px-8 py-4 text-base font-semibold hover:bg-white/95 transition shadow-xl hover:shadow-2xl hover:-translate-y-0.5"
|
||||||
)}
|
)}
|
||||||
{renderCta(
|
{renderCta(
|
||||||
{ label: "Book Demo", href: "/contact" },
|
{ label: "Book Demo", href: "/contact" },
|
||||||
@@ -149,7 +149,7 @@ const Home: React.FC = () => {
|
|||||||
<div className="relative z-10">
|
<div className="relative z-10">
|
||||||
<div className="relative scale-110 lg:scale-125">
|
<div className="relative scale-110 lg:scale-125">
|
||||||
{/* Soft glow behind screenshot */}
|
{/* Soft glow behind screenshot */}
|
||||||
<div className="absolute -inset-8 bg-gradient-to-br from-white/30 via-[var(--igny8-blue)]/20 to-[var(--igny8-purple)]/20 rounded-3xl blur-3xl" />
|
<div className="absolute -inset-8 bg-gradient-to-br from-white/30 via-[var(--color-primary)]/20 to-[var(--color-purple)]/20 rounded-3xl blur-3xl" />
|
||||||
{/* Device frame effect */}
|
{/* Device frame effect */}
|
||||||
<div className="absolute -inset-4 bg-gradient-to-br from-white/20 to-white/5 rounded-3xl blur-2xl" />
|
<div className="absolute -inset-4 bg-gradient-to-br from-white/20 to-white/5 rounded-3xl blur-2xl" />
|
||||||
<div className="relative rounded-2xl border-4 border-white/20 bg-white/10 backdrop-blur-sm shadow-2xl overflow-hidden">
|
<div className="relative rounded-2xl border-4 border-white/20 bg-white/10 backdrop-blur-sm shadow-2xl overflow-hidden">
|
||||||
@@ -167,7 +167,7 @@ const Home: React.FC = () => {
|
|||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
{/* Soft shadow */}
|
{/* Soft shadow */}
|
||||||
<div className="absolute -bottom-8 -left-8 right-8 h-32 bg-gradient-to-t from-[var(--igny8-blue)]/20 to-transparent blur-3xl -z-10" />
|
<div className="absolute -bottom-8 -left-8 right-8 h-32 bg-gradient-to-t from-[var(--color-primary)]/20 to-transparent blur-3xl -z-10" />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -200,7 +200,7 @@ const Home: React.FC = () => {
|
|||||||
</section>
|
</section>
|
||||||
|
|
||||||
{/* HOW IGNY8 WORKS (PIPELINE) */}
|
{/* HOW IGNY8 WORKS (PIPELINE) */}
|
||||||
<section className="py-24 bg-gradient-to-b from-white via-[var(--igny8-blue)]/3 to-[var(--igny8-purple)]/3">
|
<section className="py-24 bg-gradient-to-b from-white via-[var(--color-primary)]/3 to-[var(--color-purple)]/3">
|
||||||
<div className="max-w-7xl mx-auto px-6">
|
<div className="max-w-7xl mx-auto px-6">
|
||||||
<div className="text-center mb-16">
|
<div className="text-center mb-16">
|
||||||
<h2 className="text-4xl md:text-5xl font-bold text-slate-900 mb-4">
|
<h2 className="text-4xl md:text-5xl font-bold text-slate-900 mb-4">
|
||||||
@@ -214,7 +214,7 @@ const Home: React.FC = () => {
|
|||||||
{/* Horizontal Timeline */}
|
{/* Horizontal Timeline */}
|
||||||
<div className="relative">
|
<div className="relative">
|
||||||
{/* Enhanced connecting line with shadow */}
|
{/* Enhanced connecting line with shadow */}
|
||||||
<div className="absolute top-14 left-0 right-0 h-1 bg-gradient-to-r from-[var(--igny8-blue)] via-[var(--igny8-purple)] via-[var(--igny8-amber)] via-[var(--igny8-green)] to-[var(--igny8-blue)] opacity-25 hidden md:block shadow-lg shadow-[var(--igny8-blue)]/20" />
|
<div className="absolute top-14 left-0 right-0 h-1 bg-gradient-to-r from-[var(--color-primary)] via-[var(--color-purple)] via-[var(--color-warning)] via-[var(--color-success)] to-[var(--color-primary)] opacity-25 hidden md:block shadow-lg shadow-[var(--color-primary)]/20" />
|
||||||
|
|
||||||
<div className="grid grid-cols-2 md:grid-cols-7 gap-6 md:gap-4">
|
<div className="grid grid-cols-2 md:grid-cols-7 gap-6 md:gap-4">
|
||||||
{workflowSteps.map((step, index) => {
|
{workflowSteps.map((step, index) => {
|
||||||
@@ -241,9 +241,9 @@ const Home: React.FC = () => {
|
|||||||
const isLeft = module.align === "left";
|
const isLeft = module.align === "left";
|
||||||
const backgroundTints = [
|
const backgroundTints = [
|
||||||
"bg-white",
|
"bg-white",
|
||||||
"bg-gradient-to-b from-[var(--igny8-blue)]/1 to-white",
|
"bg-gradient-to-b from-[var(--color-primary)]/1 to-white",
|
||||||
"bg-gradient-to-b from-[var(--igny8-green)]/1 to-white",
|
"bg-gradient-to-b from-[var(--color-success)]/1 to-white",
|
||||||
"bg-gradient-to-b from-[var(--igny8-purple)]/1 to-white",
|
"bg-gradient-to-b from-[var(--color-purple)]/1 to-white",
|
||||||
];
|
];
|
||||||
|
|
||||||
return (
|
return (
|
||||||
@@ -322,7 +322,7 @@ const Home: React.FC = () => {
|
|||||||
{/* Left: Content */}
|
{/* Left: Content */}
|
||||||
<div className="z-10">
|
<div className="z-10">
|
||||||
<div className="flex items-center gap-3 mb-6">
|
<div className="flex items-center gap-3 mb-6">
|
||||||
<div className="size-12 rounded-xl bg-gradient-to-br from-[var(--igny8-blue)] to-[var(--igny8-purple)] flex items-center justify-center text-white shadow-lg shadow-[var(--igny8-blue)]/30">
|
<div className="size-12 rounded-xl bg-gradient-to-br from-[var(--color-primary)] to-[var(--color-purple)] flex items-center justify-center text-white shadow-lg shadow-[var(--color-primary)]/30">
|
||||||
<BoltIcon className="h-6 w-6" />
|
<BoltIcon className="h-6 w-6" />
|
||||||
</div>
|
</div>
|
||||||
<h2 className="text-4xl md:text-5xl font-bold text-white">
|
<h2 className="text-4xl md:text-5xl font-bold text-white">
|
||||||
@@ -336,12 +336,12 @@ const Home: React.FC = () => {
|
|||||||
{/* Automation Timeline with neon glows */}
|
{/* Automation Timeline with neon glows */}
|
||||||
<div className="space-y-6 mb-8">
|
<div className="space-y-6 mb-8">
|
||||||
{[
|
{[
|
||||||
{ from: "Keywords", to: "Clusters", icon: "→", color: "from-[var(--igny8-blue)] to-[var(--igny8-purple)]", glow: "shadow-[var(--igny8-blue)]/50" },
|
{ from: "Keywords", to: "Clusters", icon: "→", color: "from-[var(--color-primary)] to-[var(--color-purple)]", glow: "shadow-[var(--color-primary)]/50" },
|
||||||
{ from: "Clusters", to: "Ideas", icon: "→", color: "from-[var(--igny8-purple)] to-[var(--igny8-amber)]", glow: "shadow-[var(--igny8-purple)]/50" },
|
{ from: "Clusters", to: "Ideas", icon: "→", color: "from-[var(--color-purple)] to-[var(--color-warning)]", glow: "shadow-[var(--color-purple)]/50" },
|
||||||
{ from: "Ideas", to: "Tasks", icon: "→", color: "from-[var(--igny8-amber)] to-[var(--igny8-green)]", glow: "shadow-[var(--igny8-amber)]/50" },
|
{ from: "Ideas", to: "Tasks", icon: "→", color: "from-[var(--color-warning)] to-[var(--color-success)]", glow: "shadow-[var(--color-warning)]/50" },
|
||||||
{ from: "Tasks", to: "Content", icon: "→", color: "from-[var(--igny8-green)] to-[var(--igny8-blue)]", glow: "shadow-[var(--igny8-green)]/50" },
|
{ from: "Tasks", to: "Content", icon: "→", color: "from-[var(--color-success)] to-[var(--color-primary)]", glow: "shadow-[var(--color-success)]/50" },
|
||||||
{ from: "Content", to: "Images", icon: "→", color: "from-[var(--igny8-blue)] to-[var(--igny8-purple)]", glow: "shadow-[var(--igny8-blue)]/50" },
|
{ from: "Content", to: "Images", icon: "→", color: "from-[var(--color-primary)] to-[var(--color-purple)]", glow: "shadow-[var(--color-primary)]/50" },
|
||||||
{ from: "Images", to: "Publish", icon: "→", color: "from-[var(--igny8-purple)] to-[var(--igny8-green)]", glow: "shadow-[var(--igny8-purple)]/50" },
|
{ from: "Images", to: "Publish", icon: "→", color: "from-[var(--color-purple)] to-[var(--color-success)]", glow: "shadow-[var(--color-purple)]/50" },
|
||||||
].map((handoff, i) => (
|
].map((handoff, i) => (
|
||||||
<div key={i} className="flex items-center gap-4">
|
<div key={i} className="flex items-center gap-4">
|
||||||
<div className={`relative w-12 h-12 rounded-xl bg-gradient-to-br ${handoff.color} flex items-center justify-center text-white font-bold shadow-lg ${handoff.glow} group`}>
|
<div className={`relative w-12 h-12 rounded-xl bg-gradient-to-br ${handoff.color} flex items-center justify-center text-white font-bold shadow-lg ${handoff.glow} group`}>
|
||||||
@@ -387,7 +387,7 @@ const Home: React.FC = () => {
|
|||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
{/* Glow effect */}
|
{/* Glow effect */}
|
||||||
<div className="absolute -inset-4 bg-gradient-to-br from-[var(--igny8-blue)]/20 to-[var(--igny8-purple)]/20 rounded-2xl blur-2xl -z-10" />
|
<div className="absolute -inset-4 bg-gradient-to-br from-[var(--color-primary)]/20 to-[var(--color-purple)]/20 rounded-2xl blur-2xl -z-10" />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -397,7 +397,7 @@ const Home: React.FC = () => {
|
|||||||
<section className="py-24 bg-white">
|
<section className="py-24 bg-white">
|
||||||
<div className="max-w-7xl mx-auto px-6">
|
<div className="max-w-7xl mx-auto px-6">
|
||||||
<div className="text-center mb-12">
|
<div className="text-center mb-12">
|
||||||
<span className="inline-flex items-center rounded-full border border-[var(--igny8-blue)]/20 bg-[var(--igny8-blue)]/10 px-4 py-1 text-xs font-semibold uppercase tracking-[0.2em] igny8-text-blue mb-4">
|
<span className="inline-flex items-center rounded-full border border-[var(--color-primary)]/20 bg-[var(--color-primary)]/10 px-4 py-1 text-xs font-semibold uppercase tracking-[0.2em] text-[var(--color-primary)] mb-4">
|
||||||
Loved by scaling teams
|
Loved by scaling teams
|
||||||
</span>
|
</span>
|
||||||
<h2 className="text-4xl md:text-5xl lg:text-6xl font-bold text-slate-900 mb-4">
|
<h2 className="text-4xl md:text-5xl lg:text-6xl font-bold text-slate-900 mb-4">
|
||||||
@@ -408,14 +408,14 @@ const Home: React.FC = () => {
|
|||||||
<div className="grid grid-cols-1 md:grid-cols-3 gap-4">
|
<div className="grid grid-cols-1 md:grid-cols-3 gap-4">
|
||||||
{testimonials.map((testimonial, index) => {
|
{testimonials.map((testimonial, index) => {
|
||||||
const gradientColors = [
|
const gradientColors = [
|
||||||
"from-[var(--igny8-blue)]/20 to-[var(--igny8-blue-dark)]/10",
|
"from-[var(--color-primary)]/20 to-[var(--color-primary-dark)]/10",
|
||||||
"from-[var(--igny8-green)]/20 to-[var(--igny8-green-dark)]/10",
|
"from-[var(--color-success)]/20 to-[var(--color-success-dark)]/10",
|
||||||
"from-[var(--igny8-purple)]/20 to-[var(--igny8-purple-dark)]/10",
|
"from-[var(--color-purple)]/20 to-[var(--color-purple-dark)]/10",
|
||||||
];
|
];
|
||||||
const borderColors = [
|
const borderColors = [
|
||||||
"border-[var(--igny8-blue)]/30",
|
"border-[var(--color-primary)]/30",
|
||||||
"border-[var(--igny8-green)]/30",
|
"border-[var(--color-success)]/30",
|
||||||
"border-[var(--igny8-purple)]/30",
|
"border-[var(--color-purple)]/30",
|
||||||
];
|
];
|
||||||
|
|
||||||
return (
|
return (
|
||||||
@@ -453,7 +453,7 @@ const Home: React.FC = () => {
|
|||||||
</section>
|
</section>
|
||||||
|
|
||||||
{/* FINAL CTA */}
|
{/* FINAL CTA */}
|
||||||
<section className="relative overflow-hidden bg-gradient-to-br from-[#8b5cf6] via-[var(--igny8-purple)] to-[var(--igny8-blue)]">
|
<section className="relative overflow-hidden bg-gradient-to-br from-[#8b5cf6] via-[var(--color-purple)] to-[var(--color-primary)]">
|
||||||
{/* Dashboard overlay in background */}
|
{/* Dashboard overlay in background */}
|
||||||
<div className="absolute inset-0 opacity-10">
|
<div className="absolute inset-0 opacity-10">
|
||||||
<div className="absolute inset-0 bg-[url('/marketing/images/hero-dashboard.png')] bg-cover bg-center scale-150 blur-3xl" />
|
<div className="absolute inset-0 bg-[url('/marketing/images/hero-dashboard.png')] bg-cover bg-center scale-150 blur-3xl" />
|
||||||
@@ -474,7 +474,7 @@ const Home: React.FC = () => {
|
|||||||
href="https://app.igny8.com/signup"
|
href="https://app.igny8.com/signup"
|
||||||
target="_blank"
|
target="_blank"
|
||||||
rel="noreferrer"
|
rel="noreferrer"
|
||||||
className="inline-flex items-center justify-center gap-2 rounded-xl bg-white igny8-text-blue px-10 py-5 text-lg font-bold hover:bg-white/95 transition shadow-xl hover:shadow-2xl hover:-translate-y-0.5"
|
className="inline-flex items-center justify-center gap-2 rounded-xl bg-white text-[var(--color-primary)] px-10 py-5 text-lg font-bold hover:bg-white/95 transition shadow-xl hover:shadow-2xl hover:-translate-y-0.5"
|
||||||
>
|
>
|
||||||
<RocketLaunchIcon className="h-5 w-5" />
|
<RocketLaunchIcon className="h-5 w-5" />
|
||||||
Start Free
|
Start Free
|
||||||
|
|||||||
@@ -43,7 +43,7 @@ const Partners: React.FC = () => {
|
|||||||
"Access to automation templates and think tank sessions",
|
"Access to automation templates and think tank sessions",
|
||||||
],
|
],
|
||||||
icon: CheckCircleIcon,
|
icon: CheckCircleIcon,
|
||||||
iconColor: "from-[var(--igny8-blue)] to-[var(--igny8-blue-dark)]",
|
iconColor: "from-[var(--color-primary)] to-[var(--color-primary-dark)]",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: "Technology Partner",
|
title: "Technology Partner",
|
||||||
@@ -54,7 +54,7 @@ const Partners: React.FC = () => {
|
|||||||
"Shared lead programs and launch promotion campaigns",
|
"Shared lead programs and launch promotion campaigns",
|
||||||
],
|
],
|
||||||
icon: CodeBracketIcon,
|
icon: CodeBracketIcon,
|
||||||
iconColor: "from-[var(--igny8-green)] to-[var(--igny8-green-dark)]",
|
iconColor: "from-[var(--color-success)] to-[var(--color-success-dark)]",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: "Affiliate & Advocate",
|
title: "Affiliate & Advocate",
|
||||||
@@ -65,7 +65,7 @@ const Partners: React.FC = () => {
|
|||||||
"Custom reporting dashboards to track referred accounts",
|
"Custom reporting dashboards to track referred accounts",
|
||||||
],
|
],
|
||||||
icon: RocketLaunchIcon,
|
icon: RocketLaunchIcon,
|
||||||
iconColor: "from-[var(--igny8-amber)] to-[var(--igny8-amber-dark)]",
|
iconColor: "from-[var(--color-warning)] to-[var(--color-warning-dark)]",
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
@@ -112,7 +112,7 @@ const Partners: React.FC = () => {
|
|||||||
<p className="text-sm text-slate-600 font-medium">{tier.description}</p>
|
<p className="text-sm text-slate-600 font-medium">{tier.description}</p>
|
||||||
<ul className="space-y-4 text-sm text-slate-700 flex-1">
|
<ul className="space-y-4 text-sm text-slate-700 flex-1">
|
||||||
{tier.benefits.map((benefit, benefitIdx) => {
|
{tier.benefits.map((benefit, benefitIdx) => {
|
||||||
const dotColors = ["igny8-bg-blue", "igny8-bg-green", "igny8-bg-amber", "igny8-bg-purple"];
|
const dotColors = ["bg-[var(--color-primary)]", "bg-[var(--color-success)]", "igny8-bg-amber", "igny8-bg-purple"];
|
||||||
return (
|
return (
|
||||||
<li key={benefit} className="flex gap-3">
|
<li key={benefit} className="flex gap-3">
|
||||||
<span className={`mt-1.5 size-2 rounded-full ${dotColors[benefitIdx % dotColors.length]} shadow-sm flex-shrink-0`} />
|
<span className={`mt-1.5 size-2 rounded-full ${dotColors[benefitIdx % dotColors.length]} shadow-sm flex-shrink-0`} />
|
||||||
@@ -133,7 +133,7 @@ const Partners: React.FC = () => {
|
|||||||
{/* Left: API & Integrations */}
|
{/* Left: API & Integrations */}
|
||||||
<div className="space-y-6">
|
<div className="space-y-6">
|
||||||
<div className="flex items-center gap-3 mb-4">
|
<div className="flex items-center gap-3 mb-4">
|
||||||
<div className="size-12 rounded-xl bg-gradient-to-br from-[var(--igny8-blue)] to-[var(--igny8-blue-dark)] flex items-center justify-center text-white shadow-lg">
|
<div className="size-12 rounded-xl bg-gradient-to-br from-[var(--color-primary)] to-[var(--color-primary-dark)] flex items-center justify-center text-white shadow-lg">
|
||||||
<CodeBracketIcon className="h-6 w-6" />
|
<CodeBracketIcon className="h-6 w-6" />
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
@@ -158,7 +158,7 @@ const Partners: React.FC = () => {
|
|||||||
{/* Right: Partner Resources */}
|
{/* Right: Partner Resources */}
|
||||||
<div className="rounded-2xl border-2 border-slate-200 bg-white p-10 space-y-6 shadow-sm">
|
<div className="rounded-2xl border-2 border-slate-200 bg-white p-10 space-y-6 shadow-sm">
|
||||||
<div className="flex items-center gap-3">
|
<div className="flex items-center gap-3">
|
||||||
<div className="size-12 rounded-xl bg-gradient-to-br from-[var(--igny8-green)] to-[var(--igny8-green-dark)] flex items-center justify-center text-white shadow-lg">
|
<div className="size-12 rounded-xl bg-gradient-to-br from-[var(--color-success)] to-[var(--color-success-dark)] flex items-center justify-center text-white shadow-lg">
|
||||||
<WrenchScrewdriverIcon className="h-6 w-6" />
|
<WrenchScrewdriverIcon className="h-6 w-6" />
|
||||||
</div>
|
</div>
|
||||||
<h4 className="text-2xl font-bold text-slate-900">
|
<h4 className="text-2xl font-bold text-slate-900">
|
||||||
@@ -167,8 +167,8 @@ const Partners: React.FC = () => {
|
|||||||
</div>
|
</div>
|
||||||
<ul className="space-y-4 text-sm text-slate-700">
|
<ul className="space-y-4 text-sm text-slate-700">
|
||||||
{[
|
{[
|
||||||
{ text: "Sales playbooks, ROI calculators, and demo environments.", color: "igny8-bg-blue" },
|
{ text: "Sales playbooks, ROI calculators, and demo environments.", color: "bg-[var(--color-primary)]" },
|
||||||
{ text: "Shared Slack channels with Igny8 product and marketing teams.", color: "igny8-bg-green" },
|
{ text: "Shared Slack channels with Igny8 product and marketing teams.", color: "bg-[var(--color-success)]" },
|
||||||
{ text: "Quarterly partner labs to showcase launches and integrations.", color: "igny8-bg-amber" },
|
{ text: "Quarterly partner labs to showcase launches and integrations.", color: "igny8-bg-amber" },
|
||||||
].map((item, index) => (
|
].map((item, index) => (
|
||||||
<li key={item.text} className="flex gap-3">
|
<li key={item.text} className="flex gap-3">
|
||||||
|
|||||||
@@ -45,7 +45,7 @@ const Pricing: React.FC = () => {
|
|||||||
cadence: "per month",
|
cadence: "per month",
|
||||||
description: "For small teams starting workflows.",
|
description: "For small teams starting workflows.",
|
||||||
icon: SparklesIcon,
|
icon: SparklesIcon,
|
||||||
iconColor: "from-[var(--igny8-blue)] to-[var(--igny8-blue-dark)]",
|
iconColor: "from-[var(--color-primary)] to-[var(--color-primary-dark)]",
|
||||||
features: [
|
features: [
|
||||||
"3 sites",
|
"3 sites",
|
||||||
"5 users",
|
"5 users",
|
||||||
@@ -69,7 +69,7 @@ const Pricing: React.FC = () => {
|
|||||||
cadence: "per month",
|
cadence: "per month",
|
||||||
description: "For teams automating multiple workflows.",
|
description: "For teams automating multiple workflows.",
|
||||||
icon: BoltIcon,
|
icon: BoltIcon,
|
||||||
iconColor: "from-[var(--igny8-green)] to-[var(--igny8-green-dark)]",
|
iconColor: "from-[var(--color-success)] to-[var(--color-success-dark)]",
|
||||||
features: [
|
features: [
|
||||||
"10 sites",
|
"10 sites",
|
||||||
"10 users",
|
"10 users",
|
||||||
@@ -95,7 +95,7 @@ const Pricing: React.FC = () => {
|
|||||||
cadence: "per month",
|
cadence: "per month",
|
||||||
description: "For publishers and large orgs needing deeper control.",
|
description: "For publishers and large orgs needing deeper control.",
|
||||||
icon: ChartBarIcon,
|
icon: ChartBarIcon,
|
||||||
iconColor: "from-[var(--igny8-purple)] to-[var(--igny8-purple-dark)]",
|
iconColor: "from-[var(--color-purple)] to-[var(--color-purple-dark)]",
|
||||||
features: [
|
features: [
|
||||||
"25 sites",
|
"25 sites",
|
||||||
"25 users",
|
"25 users",
|
||||||
@@ -239,7 +239,7 @@ const Pricing: React.FC = () => {
|
|||||||
key={tier.name}
|
key={tier.name}
|
||||||
className={`relative rounded-3xl border-2 ${
|
className={`relative rounded-3xl border-2 ${
|
||||||
tier.featured
|
tier.featured
|
||||||
? "igny8-border-blue/60 bg-gradient-to-br from-[#0693e3]/10 via-[#5d4ae3]/5 to-[#0bbf87]/5 shadow-[0_0_70px_rgba(6,147,227,0.25)]"
|
? "border-[var(--color-primary)]/60 bg-gradient-to-br from-[#0693e3]/10 via-[#5d4ae3]/5 to-[#0bbf87]/5 shadow-[0_0_70px_rgba(6,147,227,0.25)]"
|
||||||
: "border-slate-200 bg-gradient-to-br from-white to-slate-50/50"
|
: "border-slate-200 bg-gradient-to-br from-white to-slate-50/50"
|
||||||
} p-10 flex flex-col gap-6 hover:shadow-xl transition-all group ${
|
} p-10 flex flex-col gap-6 hover:shadow-xl transition-all group ${
|
||||||
tier.featured ? "lg:scale-105" : "hover:-translate-y-1"
|
tier.featured ? "lg:scale-105" : "hover:-translate-y-1"
|
||||||
@@ -258,8 +258,8 @@ const Pricing: React.FC = () => {
|
|||||||
<span
|
<span
|
||||||
className={`inline-flex items-center rounded-full border px-3 py-1 text-[10px] uppercase tracking-[0.25em] mb-2 ${
|
className={`inline-flex items-center rounded-full border px-3 py-1 text-[10px] uppercase tracking-[0.25em] mb-2 ${
|
||||||
tier.featured
|
tier.featured
|
||||||
? "igny8-border-blue/30 bg-gradient-to-r from-[#0693e3]/20 to-[#0472b8]/20 text-[#0472b8]"
|
? "border-[var(--color-primary)]/30 bg-gradient-to-r from-[#0693e3]/20 to-[#0472b8]/20 text-[#0472b8]"
|
||||||
: "border-slate-200 bg-gradient-to-r from-[#0693e3]/10 to-[#0bbf87]/10 igny8-text-blue"
|
: "border-slate-200 bg-gradient-to-r from-[#0693e3]/10 to-[#0bbf87]/10 text-[var(--color-primary)]"
|
||||||
}`}
|
}`}
|
||||||
>
|
>
|
||||||
{tier.badge}
|
{tier.badge}
|
||||||
@@ -287,7 +287,7 @@ const Pricing: React.FC = () => {
|
|||||||
{tier.features.map((feature, idx) => {
|
{tier.features.map((feature, idx) => {
|
||||||
// Subtle check icons: light bg with dark check for starter/scale, colored for growth
|
// Subtle check icons: light bg with dark check for starter/scale, colored for growth
|
||||||
const checkStyle = tier.featured
|
const checkStyle = tier.featured
|
||||||
? "igny8-bg-green/10 text-[#0bbf87]"
|
? "bg-[var(--color-success)]/10 text-[#0bbf87]"
|
||||||
: "bg-slate-100 text-slate-600";
|
: "bg-slate-100 text-slate-600";
|
||||||
return (
|
return (
|
||||||
<li key={feature} className="flex gap-3 items-start">
|
<li key={feature} className="flex gap-3 items-start">
|
||||||
@@ -304,8 +304,8 @@ const Pricing: React.FC = () => {
|
|||||||
href="https://app.igny8.com/signup"
|
href="https://app.igny8.com/signup"
|
||||||
className={`inline-flex w-full items-center justify-center rounded-full px-6 py-3 text-sm font-semibold transition ${
|
className={`inline-flex w-full items-center justify-center rounded-full px-6 py-3 text-sm font-semibold transition ${
|
||||||
tier.featured
|
tier.featured
|
||||||
? "bg-gradient-to-r from-[var(--igny8-blue)] to-[var(--igny8-blue-dark)] text-white hover:from-[#0472b8] hover:to-[#0693e3] shadow-lg shadow-[#0693e3]/30"
|
? "bg-gradient-to-r from-[var(--color-primary)] to-[var(--color-primary-dark)] text-white hover:from-[#0472b8] hover:to-[#0693e3] shadow-lg shadow-[#0693e3]/30"
|
||||||
: "border-2 border-slate-300 bg-white/50 backdrop-blur-sm text-slate-900 hover:igny8-border-blue hover:bg-white"
|
: "border-2 border-slate-300 bg-white/50 backdrop-blur-sm text-slate-900 hover:border-[var(--color-primary)] hover:bg-white"
|
||||||
}`}
|
}`}
|
||||||
>
|
>
|
||||||
Start free trial
|
Start free trial
|
||||||
@@ -329,7 +329,7 @@ const Pricing: React.FC = () => {
|
|||||||
<tr>
|
<tr>
|
||||||
<th className="px-6 py-4 text-left font-semibold text-slate-900">Capability</th>
|
<th className="px-6 py-4 text-left font-semibold text-slate-900">Capability</th>
|
||||||
<th className="px-6 py-4 text-center font-semibold text-slate-900">Starter</th>
|
<th className="px-6 py-4 text-center font-semibold text-slate-900">Starter</th>
|
||||||
<th className="px-6 py-4 text-center font-semibold igny8-text-blue bg-gradient-to-br from-[#0693e3]/5 to-transparent">
|
<th className="px-6 py-4 text-center font-semibold text-[var(--color-primary)] bg-gradient-to-br from-[#0693e3]/5 to-transparent">
|
||||||
Growth
|
Growth
|
||||||
</th>
|
</th>
|
||||||
<th className="px-6 py-4 text-center font-semibold text-slate-900">Scale</th>
|
<th className="px-6 py-4 text-center font-semibold text-slate-900">Scale</th>
|
||||||
@@ -349,19 +349,19 @@ const Pricing: React.FC = () => {
|
|||||||
<XMarkIcon className="h-5 w-5 text-slate-300 mx-auto" />
|
<XMarkIcon className="h-5 w-5 text-slate-300 mx-auto" />
|
||||||
) : (
|
) : (
|
||||||
<span className="inline-flex items-center gap-1">
|
<span className="inline-flex items-center gap-1">
|
||||||
<span className="size-1.5 rounded-full igny8-bg-blue"></span>
|
<span className="size-1.5 rounded-full bg-[var(--color-primary)]"></span>
|
||||||
{row.starter}
|
{row.starter}
|
||||||
</span>
|
</span>
|
||||||
)}
|
)}
|
||||||
</td>
|
</td>
|
||||||
<td className="px-6 py-5 text-center font-medium igny8-text-blue bg-gradient-to-br from-[#0693e3]/5 to-transparent">
|
<td className="px-6 py-5 text-center font-medium text-[var(--color-primary)] bg-gradient-to-br from-[#0693e3]/5 to-transparent">
|
||||||
{row.growth === true ? (
|
{row.growth === true ? (
|
||||||
<CheckIcon className="h-5 w-5 text-[#0bbf87] mx-auto" />
|
<CheckIcon className="h-5 w-5 text-[#0bbf87] mx-auto" />
|
||||||
) : row.growth === false ? (
|
) : row.growth === false ? (
|
||||||
<XMarkIcon className="h-5 w-5 text-slate-300 mx-auto" />
|
<XMarkIcon className="h-5 w-5 text-slate-300 mx-auto" />
|
||||||
) : (
|
) : (
|
||||||
<span className="inline-flex items-center gap-1">
|
<span className="inline-flex items-center gap-1">
|
||||||
<span className="size-1.5 rounded-full igny8-bg-blue"></span>
|
<span className="size-1.5 rounded-full bg-[var(--color-primary)]"></span>
|
||||||
{row.growth}
|
{row.growth}
|
||||||
</span>
|
</span>
|
||||||
)}
|
)}
|
||||||
@@ -389,9 +389,9 @@ const Pricing: React.FC = () => {
|
|||||||
{/* INFO BLOCKS SECTION */}
|
{/* INFO BLOCKS SECTION */}
|
||||||
<section className="bg-gradient-to-b from-white via-slate-50/30 to-white">
|
<section className="bg-gradient-to-b from-white via-slate-50/30 to-white">
|
||||||
<div className="max-w-6xl mx-auto px-6 py-24 grid grid-cols-1 md:grid-cols-2 gap-8">
|
<div className="max-w-6xl mx-auto px-6 py-24 grid grid-cols-1 md:grid-cols-2 gap-8">
|
||||||
<div className="rounded-3xl border-2 igny8-border-blue/30 bg-gradient-to-br from-[#0693e3]/5 via-white to-[#0bbf87]/5 p-8 space-y-4 shadow-lg hover:shadow-xl transition-all">
|
<div className="rounded-3xl border-2 border-[var(--color-primary)]/30 bg-gradient-to-br from-[#0693e3]/5 via-white to-[#0bbf87]/5 p-8 space-y-4 shadow-lg hover:shadow-xl transition-all">
|
||||||
<div className="flex items-center gap-3 mb-4">
|
<div className="flex items-center gap-3 mb-4">
|
||||||
<div className="size-12 rounded-full bg-gradient-to-br from-[var(--igny8-blue)] to-[var(--igny8-blue-dark)] flex items-center justify-center text-white shadow-lg">
|
<div className="size-12 rounded-full bg-gradient-to-br from-[var(--color-primary)] to-[var(--color-primary-dark)] flex items-center justify-center text-white shadow-lg">
|
||||||
<CreditCardIcon className="h-6 w-6" />
|
<CreditCardIcon className="h-6 w-6" />
|
||||||
</div>
|
</div>
|
||||||
<h4 className="text-lg font-semibold text-slate-900">
|
<h4 className="text-lg font-semibold text-slate-900">
|
||||||
@@ -407,7 +407,7 @@ const Pricing: React.FC = () => {
|
|||||||
</div>
|
</div>
|
||||||
<div className="rounded-3xl border-2 border-[#0bbf87]/30 bg-gradient-to-br from-[#0bbf87]/5 via-white to-[#5d4ae3]/5 p-8 space-y-4 shadow-lg hover:shadow-xl transition-all">
|
<div className="rounded-3xl border-2 border-[#0bbf87]/30 bg-gradient-to-br from-[#0bbf87]/5 via-white to-[#5d4ae3]/5 p-8 space-y-4 shadow-lg hover:shadow-xl transition-all">
|
||||||
<div className="flex items-center gap-3 mb-4">
|
<div className="flex items-center gap-3 mb-4">
|
||||||
<div className="size-12 rounded-full bg-gradient-to-br from-[var(--igny8-green)] to-[var(--igny8-green-dark)] flex items-center justify-center text-white shadow-lg">
|
<div className="size-12 rounded-full bg-gradient-to-br from-[var(--color-success)] to-[var(--color-success-dark)] flex items-center justify-center text-white shadow-lg">
|
||||||
<ShieldCheckIcon className="h-6 w-6" />
|
<ShieldCheckIcon className="h-6 w-6" />
|
||||||
</div>
|
</div>
|
||||||
<h4 className="text-lg font-semibold text-slate-900">
|
<h4 className="text-lg font-semibold text-slate-900">
|
||||||
@@ -422,7 +422,7 @@ const Pricing: React.FC = () => {
|
|||||||
</section>
|
</section>
|
||||||
|
|
||||||
{/* FINAL CTA */}
|
{/* FINAL CTA */}
|
||||||
<section className="relative overflow-hidden bg-gradient-to-br from-[var(--igny8-blue)] via-[var(--igny8-purple)] to-[#8b5cf6]">
|
<section className="relative overflow-hidden bg-gradient-to-br from-[var(--color-primary)] via-[var(--color-purple)] to-[#8b5cf6]">
|
||||||
{/* Radial glow */}
|
{/* Radial glow */}
|
||||||
<div className="absolute inset-0 bg-[radial-gradient(circle_at_50%_50%,rgba(255,255,255,0.1),transparent_70%)]" />
|
<div className="absolute inset-0 bg-[radial-gradient(circle_at_50%_50%,rgba(255,255,255,0.1),transparent_70%)]" />
|
||||||
|
|
||||||
@@ -445,7 +445,7 @@ const Pricing: React.FC = () => {
|
|||||||
href="https://app.igny8.com/signup"
|
href="https://app.igny8.com/signup"
|
||||||
target="_blank"
|
target="_blank"
|
||||||
rel="noreferrer"
|
rel="noreferrer"
|
||||||
className="inline-flex items-center justify-center gap-2 rounded-xl bg-white igny8-text-blue px-10 py-5 text-lg font-bold hover:bg-white/95 transition shadow-xl hover:shadow-2xl hover:-translate-y-0.5"
|
className="inline-flex items-center justify-center gap-2 rounded-xl bg-white text-[var(--color-primary)] px-10 py-5 text-lg font-bold hover:bg-white/95 transition shadow-xl hover:shadow-2xl hover:-translate-y-0.5"
|
||||||
>
|
>
|
||||||
<RocketLaunchIcon className="h-5 w-5" />
|
<RocketLaunchIcon className="h-5 w-5" />
|
||||||
Start free trial
|
Start free trial
|
||||||
|
|||||||
@@ -40,12 +40,12 @@ const Product: React.FC = () => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const workflowSteps = [
|
const workflowSteps = [
|
||||||
{ name: "Keywords", icon: ListBulletIcon, color: "from-[var(--igny8-blue)] to-[var(--igny8-blue-dark)]" },
|
{ name: "Keywords", icon: ListBulletIcon, color: "from-[var(--color-primary)] to-[var(--color-primary-dark)]" },
|
||||||
{ name: "Clusters", icon: UserGroupIcon, color: "from-[var(--igny8-purple)] to-[var(--igny8-purple-dark)]" },
|
{ name: "Clusters", icon: UserGroupIcon, color: "from-[var(--color-purple)] to-[var(--color-purple-dark)]" },
|
||||||
{ name: "Ideas", icon: LightBulbIcon, color: "from-[var(--igny8-amber)] to-[var(--igny8-amber-dark)]" },
|
{ name: "Ideas", icon: LightBulbIcon, color: "from-[var(--color-warning)] to-[var(--color-warning-dark)]" },
|
||||||
{ name: "Tasks", icon: DocumentTextIcon, color: "from-[var(--igny8-green)] to-[var(--igny8-green-dark)]" },
|
{ name: "Tasks", icon: DocumentTextIcon, color: "from-[var(--color-success)] to-[var(--color-success-dark)]" },
|
||||||
{ name: "Content", icon: SparklesIcon, color: "from-[var(--igny8-blue)] to-[var(--igny8-blue-dark)]" },
|
{ name: "Content", icon: SparklesIcon, color: "from-[var(--color-primary)] to-[var(--color-primary-dark)]" },
|
||||||
{ name: "Publish", icon: BoltIcon, color: "from-[var(--igny8-green)] to-[var(--igny8-green-dark)]" },
|
{ name: "Publish", icon: BoltIcon, color: "from-[var(--color-success)] to-[var(--color-success-dark)]" },
|
||||||
];
|
];
|
||||||
|
|
||||||
const productModules = [
|
const productModules = [
|
||||||
@@ -61,7 +61,7 @@ const Product: React.FC = () => {
|
|||||||
"Alerts for emerging opportunities, competitive gaps, and seasonality shifts",
|
"Alerts for emerging opportunities, competitive gaps, and seasonality shifts",
|
||||||
],
|
],
|
||||||
icon: ChartBarIcon,
|
icon: ChartBarIcon,
|
||||||
color: "from-[var(--igny8-blue)] to-[var(--igny8-blue-dark)]",
|
color: "from-[var(--color-primary)] to-[var(--color-primary-dark)]",
|
||||||
image: "planner-dashboard.png",
|
image: "planner-dashboard.png",
|
||||||
link: "#planner",
|
link: "#planner",
|
||||||
},
|
},
|
||||||
@@ -77,7 +77,7 @@ const Product: React.FC = () => {
|
|||||||
"Editorial workspace with comments, approvals, and WordPress publishing",
|
"Editorial workspace with comments, approvals, and WordPress publishing",
|
||||||
],
|
],
|
||||||
icon: SparklesIcon,
|
icon: SparklesIcon,
|
||||||
color: "from-[var(--igny8-green)] to-[var(--igny8-green-dark)]",
|
color: "from-[var(--color-success)] to-[var(--color-success-dark)]",
|
||||||
image: "writer-dashboard.png",
|
image: "writer-dashboard.png",
|
||||||
link: "#writer",
|
link: "#writer",
|
||||||
},
|
},
|
||||||
@@ -93,7 +93,7 @@ const Product: React.FC = () => {
|
|||||||
"Version control for AI instructions and playbooks across teams",
|
"Version control for AI instructions and playbooks across teams",
|
||||||
],
|
],
|
||||||
icon: BoltIcon,
|
icon: BoltIcon,
|
||||||
color: "from-[var(--igny8-amber)] to-[var(--igny8-amber-dark)]",
|
color: "from-[var(--color-warning)] to-[var(--color-warning-dark)]",
|
||||||
image: "thinker-dashboard.png",
|
image: "thinker-dashboard.png",
|
||||||
link: "#thinker",
|
link: "#thinker",
|
||||||
},
|
},
|
||||||
@@ -109,7 +109,7 @@ const Product: React.FC = () => {
|
|||||||
"Monitor every automation with audit logs and manual override controls",
|
"Monitor every automation with audit logs and manual override controls",
|
||||||
],
|
],
|
||||||
icon: PhotoIcon,
|
icon: PhotoIcon,
|
||||||
color: "from-[var(--igny8-purple)] to-[var(--igny8-purple-dark)]",
|
color: "from-[var(--color-purple)] to-[var(--color-purple-dark)]",
|
||||||
image: "automation-dashboard.png",
|
image: "automation-dashboard.png",
|
||||||
link: "#automation",
|
link: "#automation",
|
||||||
},
|
},
|
||||||
@@ -134,11 +134,11 @@ const Product: React.FC = () => {
|
|||||||
<div className="flex flex-col sm:flex-row gap-4 justify-center">
|
<div className="flex flex-col sm:flex-row gap-4 justify-center">
|
||||||
{renderCta(
|
{renderCta(
|
||||||
{ label: "Start free", href: "https://app.igny8.com/signup" },
|
{ label: "Start free", href: "https://app.igny8.com/signup" },
|
||||||
"inline-flex items-center justify-center rounded-xl bg-gradient-to-r from-[var(--igny8-blue)] to-[var(--igny8-blue-dark)] text-white px-8 py-4 text-base font-semibold hover:shadow-lg hover:-translate-y-0.5 transition shadow-md"
|
"inline-flex items-center justify-center rounded-xl bg-gradient-to-r from-[var(--color-primary)] to-[var(--color-primary-dark)] text-white px-8 py-4 text-base font-semibold hover:shadow-lg hover:-translate-y-0.5 transition shadow-md"
|
||||||
)}
|
)}
|
||||||
{renderCta(
|
{renderCta(
|
||||||
{ label: "Book a demo", href: "/contact" },
|
{ label: "Book a demo", href: "/contact" },
|
||||||
"inline-flex items-center justify-center rounded-xl border-2 border-slate-300 bg-white text-slate-700 px-8 py-4 text-base font-semibold hover:igny8-border-blue hover:igny8-text-blue transition"
|
"inline-flex items-center justify-center rounded-xl border-2 border-slate-300 bg-white text-slate-700 px-8 py-4 text-base font-semibold hover:border-[var(--color-primary)] hover:text-[var(--color-primary)] transition"
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -159,7 +159,7 @@ const Product: React.FC = () => {
|
|||||||
{/* Horizontal Timeline */}
|
{/* Horizontal Timeline */}
|
||||||
<div className="relative">
|
<div className="relative">
|
||||||
{/* Enhanced connecting line with shadow */}
|
{/* Enhanced connecting line with shadow */}
|
||||||
<div className="absolute top-14 left-0 right-0 h-1 bg-gradient-to-r from-[var(--igny8-blue)] via-[var(--igny8-purple)] via-[var(--igny8-amber)] via-[var(--igny8-green)] to-[var(--igny8-blue)] opacity-25 hidden md:block shadow-lg shadow-[var(--igny8-blue)]/20" />
|
<div className="absolute top-14 left-0 right-0 h-1 bg-gradient-to-r from-[var(--color-primary)] via-[var(--color-purple)] via-[var(--color-warning)] via-[var(--color-success)] to-[var(--color-primary)] opacity-25 hidden md:block shadow-lg shadow-[var(--color-primary)]/20" />
|
||||||
|
|
||||||
<div className="grid grid-cols-2 md:grid-cols-6 gap-6 md:gap-4">
|
<div className="grid grid-cols-2 md:grid-cols-6 gap-6 md:gap-4">
|
||||||
{workflowSteps.map((step, index) => {
|
{workflowSteps.map((step, index) => {
|
||||||
@@ -186,9 +186,9 @@ const Product: React.FC = () => {
|
|||||||
const isLeft = index % 2 === 0;
|
const isLeft = index % 2 === 0;
|
||||||
const backgroundTints = [
|
const backgroundTints = [
|
||||||
"bg-white",
|
"bg-white",
|
||||||
"bg-gradient-to-b from-[var(--igny8-blue)]/1 to-white",
|
"bg-gradient-to-b from-[var(--color-primary)]/1 to-white",
|
||||||
"bg-gradient-to-b from-[var(--igny8-green)]/1 to-white",
|
"bg-gradient-to-b from-[var(--color-success)]/1 to-white",
|
||||||
"bg-gradient-to-b from-[var(--igny8-purple)]/1 to-white",
|
"bg-gradient-to-b from-[var(--color-purple)]/1 to-white",
|
||||||
];
|
];
|
||||||
|
|
||||||
return (
|
return (
|
||||||
@@ -267,7 +267,7 @@ const Product: React.FC = () => {
|
|||||||
{/* Left: Content */}
|
{/* Left: Content */}
|
||||||
<div className="z-10">
|
<div className="z-10">
|
||||||
<div className="flex items-center gap-3 mb-6">
|
<div className="flex items-center gap-3 mb-6">
|
||||||
<div className="size-12 rounded-xl bg-gradient-to-br from-[var(--igny8-blue)] to-[var(--igny8-purple)] flex items-center justify-center text-white shadow-lg shadow-[var(--igny8-blue)]/30">
|
<div className="size-12 rounded-xl bg-gradient-to-br from-[var(--color-primary)] to-[var(--color-purple)] flex items-center justify-center text-white shadow-lg shadow-[var(--color-primary)]/30">
|
||||||
<BoltIcon className="h-6 w-6" />
|
<BoltIcon className="h-6 w-6" />
|
||||||
</div>
|
</div>
|
||||||
<h2 className="text-4xl md:text-5xl font-bold text-white">
|
<h2 className="text-4xl md:text-5xl font-bold text-white">
|
||||||
@@ -281,12 +281,12 @@ const Product: React.FC = () => {
|
|||||||
{/* Automation Timeline with neon glows */}
|
{/* Automation Timeline with neon glows */}
|
||||||
<div className="space-y-6">
|
<div className="space-y-6">
|
||||||
{[
|
{[
|
||||||
{ from: "Keywords", to: "Clusters", icon: "→", color: "from-[var(--igny8-blue)] to-[var(--igny8-purple)]", glow: "shadow-[var(--igny8-blue)]/50" },
|
{ from: "Keywords", to: "Clusters", icon: "→", color: "from-[var(--color-primary)] to-[var(--color-purple)]", glow: "shadow-[var(--color-primary)]/50" },
|
||||||
{ from: "Clusters", to: "Ideas", icon: "→", color: "from-[var(--igny8-purple)] to-[var(--igny8-amber)]", glow: "shadow-[var(--igny8-purple)]/50" },
|
{ from: "Clusters", to: "Ideas", icon: "→", color: "from-[var(--color-purple)] to-[var(--color-warning)]", glow: "shadow-[var(--color-purple)]/50" },
|
||||||
{ from: "Ideas", to: "Tasks", icon: "→", color: "from-[var(--igny8-amber)] to-[var(--igny8-green)]", glow: "shadow-[var(--igny8-amber)]/50" },
|
{ from: "Ideas", to: "Tasks", icon: "→", color: "from-[var(--color-warning)] to-[var(--color-success)]", glow: "shadow-[var(--color-warning)]/50" },
|
||||||
{ from: "Tasks", to: "Content", icon: "→", color: "from-[var(--igny8-green)] to-[var(--igny8-blue)]", glow: "shadow-[var(--igny8-green)]/50" },
|
{ from: "Tasks", to: "Content", icon: "→", color: "from-[var(--color-success)] to-[var(--color-primary)]", glow: "shadow-[var(--color-success)]/50" },
|
||||||
{ from: "Content", to: "Images", icon: "→", color: "from-[var(--igny8-blue)] to-[var(--igny8-purple)]", glow: "shadow-[var(--igny8-blue)]/50" },
|
{ from: "Content", to: "Images", icon: "→", color: "from-[var(--color-primary)] to-[var(--color-purple)]", glow: "shadow-[var(--color-primary)]/50" },
|
||||||
{ from: "Images", to: "Publish", icon: "→", color: "from-[var(--igny8-purple)] to-[var(--igny8-green)]", glow: "shadow-[var(--igny8-purple)]/50" },
|
{ from: "Images", to: "Publish", icon: "→", color: "from-[var(--color-purple)] to-[var(--color-success)]", glow: "shadow-[var(--color-purple)]/50" },
|
||||||
].map((handoff, i) => (
|
].map((handoff, i) => (
|
||||||
<div key={i} className="flex items-center gap-4">
|
<div key={i} className="flex items-center gap-4">
|
||||||
<div className={`relative w-12 h-12 rounded-xl bg-gradient-to-br ${handoff.color} flex items-center justify-center text-white font-bold shadow-lg ${handoff.glow} group`}>
|
<div className={`relative w-12 h-12 rounded-xl bg-gradient-to-br ${handoff.color} flex items-center justify-center text-white font-bold shadow-lg ${handoff.glow} group`}>
|
||||||
@@ -320,7 +320,7 @@ const Product: React.FC = () => {
|
|||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
{/* Glow effect */}
|
{/* Glow effect */}
|
||||||
<div className="absolute -inset-4 bg-gradient-to-br from-[var(--igny8-blue)]/20 to-[var(--igny8-purple)]/20 rounded-2xl blur-2xl -z-10" />
|
<div className="absolute -inset-4 bg-gradient-to-br from-[var(--color-primary)]/20 to-[var(--color-purple)]/20 rounded-2xl blur-2xl -z-10" />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@@ -344,7 +344,7 @@ const Product: React.FC = () => {
|
|||||||
<section className="py-24 bg-white">
|
<section className="py-24 bg-white">
|
||||||
<div className="max-w-7xl mx-auto px-6">
|
<div className="max-w-7xl mx-auto px-6">
|
||||||
<div className="text-center mb-12">
|
<div className="text-center mb-12">
|
||||||
<span className="inline-flex items-center rounded-full border border-[var(--igny8-blue)]/20 bg-[var(--igny8-blue)]/10 px-4 py-1 text-xs font-semibold uppercase tracking-[0.2em] igny8-text-blue mb-4">
|
<span className="inline-flex items-center rounded-full border border-[var(--color-primary)]/20 bg-[var(--color-primary)]/10 px-4 py-1 text-xs font-semibold uppercase tracking-[0.2em] text-[var(--color-primary)] mb-4">
|
||||||
Loved by scaling teams
|
Loved by scaling teams
|
||||||
</span>
|
</span>
|
||||||
<h2 className="text-4xl md:text-5xl lg:text-6xl font-bold text-slate-900 mb-4">
|
<h2 className="text-4xl md:text-5xl lg:text-6xl font-bold text-slate-900 mb-4">
|
||||||
@@ -355,14 +355,14 @@ const Product: React.FC = () => {
|
|||||||
<div className="grid grid-cols-1 md:grid-cols-3 gap-4">
|
<div className="grid grid-cols-1 md:grid-cols-3 gap-4">
|
||||||
{testimonials.map((testimonial, index) => {
|
{testimonials.map((testimonial, index) => {
|
||||||
const gradientColors = [
|
const gradientColors = [
|
||||||
"from-[var(--igny8-blue)]/20 to-[var(--igny8-blue-dark)]/10",
|
"from-[var(--color-primary)]/20 to-[var(--color-primary-dark)]/10",
|
||||||
"from-[var(--igny8-green)]/20 to-[var(--igny8-green-dark)]/10",
|
"from-[var(--color-success)]/20 to-[var(--color-success-dark)]/10",
|
||||||
"from-[var(--igny8-purple)]/20 to-[var(--igny8-purple-dark)]/10",
|
"from-[var(--color-purple)]/20 to-[var(--color-purple-dark)]/10",
|
||||||
];
|
];
|
||||||
const borderColors = [
|
const borderColors = [
|
||||||
"border-[var(--igny8-blue)]/30",
|
"border-[var(--color-primary)]/30",
|
||||||
"border-[var(--igny8-green)]/30",
|
"border-[var(--color-success)]/30",
|
||||||
"border-[var(--igny8-purple)]/30",
|
"border-[var(--color-purple)]/30",
|
||||||
];
|
];
|
||||||
|
|
||||||
return (
|
return (
|
||||||
@@ -400,7 +400,7 @@ const Product: React.FC = () => {
|
|||||||
</section>
|
</section>
|
||||||
|
|
||||||
{/* FINAL CTA */}
|
{/* FINAL CTA */}
|
||||||
<section className="relative overflow-hidden bg-gradient-to-br from-[var(--igny8-blue)] via-[var(--igny8-purple)] to-[#8b5cf6]">
|
<section className="relative overflow-hidden bg-gradient-to-br from-[var(--color-primary)] via-[var(--color-purple)] to-[#8b5cf6]">
|
||||||
{/* Dashboard overlay in background */}
|
{/* Dashboard overlay in background */}
|
||||||
<div className="absolute inset-0 opacity-10">
|
<div className="absolute inset-0 opacity-10">
|
||||||
<div className="absolute inset-0 bg-[url('/marketing/images/hero-dashboard.png')] bg-cover bg-center scale-150 blur-3xl" />
|
<div className="absolute inset-0 bg-[url('/marketing/images/hero-dashboard.png')] bg-cover bg-center scale-150 blur-3xl" />
|
||||||
@@ -421,7 +421,7 @@ const Product: React.FC = () => {
|
|||||||
href="https://app.igny8.com/signup"
|
href="https://app.igny8.com/signup"
|
||||||
target="_blank"
|
target="_blank"
|
||||||
rel="noreferrer"
|
rel="noreferrer"
|
||||||
className="inline-flex items-center justify-center gap-2 rounded-xl bg-white igny8-text-blue px-10 py-5 text-lg font-bold hover:bg-white/95 transition shadow-xl hover:shadow-2xl hover:-translate-y-0.5"
|
className="inline-flex items-center justify-center gap-2 rounded-xl bg-white text-[var(--color-primary)] px-10 py-5 text-lg font-bold hover:bg-white/95 transition shadow-xl hover:shadow-2xl hover:-translate-y-0.5"
|
||||||
>
|
>
|
||||||
<RocketLaunchIcon className="h-5 w-5" />
|
<RocketLaunchIcon className="h-5 w-5" />
|
||||||
Start free
|
Start free
|
||||||
|
|||||||
@@ -50,7 +50,7 @@ const Resources: React.FC = () => {
|
|||||||
type: "Article",
|
type: "Article",
|
||||||
tag: "Strategy",
|
tag: "Strategy",
|
||||||
icon: ChartBarIcon,
|
icon: ChartBarIcon,
|
||||||
color: "from-[var(--igny8-blue)] to-[var(--igny8-blue-dark)]",
|
color: "from-[var(--color-primary)] to-[var(--color-primary-dark)]",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: "The Complete Framework for AI Content Quality",
|
title: "The Complete Framework for AI Content Quality",
|
||||||
@@ -58,7 +58,7 @@ const Resources: React.FC = () => {
|
|||||||
type: "Framework Guide",
|
type: "Framework Guide",
|
||||||
tag: "Strategy",
|
tag: "Strategy",
|
||||||
icon: AcademicCapIcon,
|
icon: AcademicCapIcon,
|
||||||
color: "from-[var(--igny8-green)] to-[var(--igny8-green-dark)]",
|
color: "from-[var(--color-success)] to-[var(--color-success-dark)]",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: "SERP-Guided Content Planning Playbook",
|
title: "SERP-Guided Content Planning Playbook",
|
||||||
@@ -66,7 +66,7 @@ const Resources: React.FC = () => {
|
|||||||
type: "PDF Guide",
|
type: "PDF Guide",
|
||||||
tag: "Strategy",
|
tag: "Strategy",
|
||||||
icon: BookOpenIcon,
|
icon: BookOpenIcon,
|
||||||
color: "from-[var(--igny8-amber)] to-[var(--igny8-amber-dark)]",
|
color: "from-[var(--color-warning)] to-[var(--color-warning-dark)]",
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
@@ -77,7 +77,7 @@ const Resources: React.FC = () => {
|
|||||||
type: "Template",
|
type: "Template",
|
||||||
tags: ["Template", "System"],
|
tags: ["Template", "System"],
|
||||||
icon: CalendarIcon,
|
icon: CalendarIcon,
|
||||||
color: "from-[var(--igny8-blue)] to-[var(--igny8-blue-dark)]",
|
color: "from-[var(--color-primary)] to-[var(--color-primary-dark)]",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: "Airtable Keyword Cluster System",
|
title: "Airtable Keyword Cluster System",
|
||||||
@@ -85,7 +85,7 @@ const Resources: React.FC = () => {
|
|||||||
type: "System",
|
type: "System",
|
||||||
tags: ["System", "Workflow"],
|
tags: ["System", "Workflow"],
|
||||||
icon: ChartBarIcon,
|
icon: ChartBarIcon,
|
||||||
color: "from-[var(--igny8-green)] to-[var(--igny8-green-dark)]",
|
color: "from-[var(--color-success)] to-[var(--color-success-dark)]",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: "Content Calendar Kit (Excel)",
|
title: "Content Calendar Kit (Excel)",
|
||||||
@@ -93,7 +93,7 @@ const Resources: React.FC = () => {
|
|||||||
type: "Template",
|
type: "Template",
|
||||||
tags: ["Template", "Workflow"],
|
tags: ["Template", "Workflow"],
|
||||||
icon: DocumentTextIcon,
|
icon: DocumentTextIcon,
|
||||||
color: "from-[var(--igny8-purple)] to-[var(--igny8-purple-dark)]",
|
color: "from-[var(--color-purple)] to-[var(--color-purple-dark)]",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: "Cluster Mapping Board",
|
title: "Cluster Mapping Board",
|
||||||
@@ -101,7 +101,7 @@ const Resources: React.FC = () => {
|
|||||||
type: "Template",
|
type: "Template",
|
||||||
tags: ["Template", "System"],
|
tags: ["Template", "System"],
|
||||||
icon: SparklesIcon,
|
icon: SparklesIcon,
|
||||||
color: "from-[var(--igny8-amber)] to-[var(--igny8-amber-dark)]",
|
color: "from-[var(--color-warning)] to-[var(--color-warning-dark)]",
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
@@ -113,7 +113,7 @@ const Resources: React.FC = () => {
|
|||||||
type: "Workshop",
|
type: "Workshop",
|
||||||
tag: "Live",
|
tag: "Live",
|
||||||
icon: BoltIcon,
|
icon: BoltIcon,
|
||||||
color: "from-[var(--igny8-blue)] to-[var(--igny8-blue-dark)]",
|
color: "from-[var(--color-primary)] to-[var(--color-primary-dark)]",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: "From Keywords to Conversions: Dashboard Deep-Dive",
|
title: "From Keywords to Conversions: Dashboard Deep-Dive",
|
||||||
@@ -122,7 +122,7 @@ const Resources: React.FC = () => {
|
|||||||
type: "Workshop",
|
type: "Workshop",
|
||||||
tag: "Live",
|
tag: "Live",
|
||||||
icon: ChartBarIcon,
|
icon: ChartBarIcon,
|
||||||
color: "from-[var(--igny8-green)] to-[var(--igny8-green-dark)]",
|
color: "from-[var(--color-success)] to-[var(--color-success-dark)]",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: "Automating Cluster Research at Scale",
|
title: "Automating Cluster Research at Scale",
|
||||||
@@ -130,7 +130,7 @@ const Resources: React.FC = () => {
|
|||||||
type: "Replay",
|
type: "Replay",
|
||||||
tag: "Replay",
|
tag: "Replay",
|
||||||
icon: PlayIcon,
|
icon: PlayIcon,
|
||||||
color: "from-[var(--igny8-purple)] to-[var(--igny8-purple-dark)]",
|
color: "from-[var(--color-purple)] to-[var(--color-purple-dark)]",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: "Editorial Control and AI Tone Systems",
|
title: "Editorial Control and AI Tone Systems",
|
||||||
@@ -138,7 +138,7 @@ const Resources: React.FC = () => {
|
|||||||
type: "Replay",
|
type: "Replay",
|
||||||
tag: "Replay",
|
tag: "Replay",
|
||||||
icon: BookOpenIcon,
|
icon: BookOpenIcon,
|
||||||
color: "from-[var(--igny8-amber)] to-[var(--igny8-amber-dark)]",
|
color: "from-[var(--color-warning)] to-[var(--color-warning-dark)]",
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
@@ -149,7 +149,7 @@ const Resources: React.FC = () => {
|
|||||||
type: "Quick-Start",
|
type: "Quick-Start",
|
||||||
tags: ["Checklist", "Execution"],
|
tags: ["Checklist", "Execution"],
|
||||||
icon: RocketLaunchIcon,
|
icon: RocketLaunchIcon,
|
||||||
color: "from-[var(--igny8-blue)] to-[var(--igny8-blue-dark)]",
|
color: "from-[var(--color-primary)] to-[var(--color-primary-dark)]",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: "SEO Content Quality Checklist",
|
title: "SEO Content Quality Checklist",
|
||||||
@@ -157,7 +157,7 @@ const Resources: React.FC = () => {
|
|||||||
type: "Checklist",
|
type: "Checklist",
|
||||||
tags: ["Checklist", "Execution"],
|
tags: ["Checklist", "Execution"],
|
||||||
icon: ClipboardDocumentCheckIcon,
|
icon: ClipboardDocumentCheckIcon,
|
||||||
color: "from-[var(--igny8-green)] to-[var(--igny8-green-dark)]",
|
color: "from-[var(--color-success)] to-[var(--color-success-dark)]",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: "Content Production SOPs Pack",
|
title: "Content Production SOPs Pack",
|
||||||
@@ -165,7 +165,7 @@ const Resources: React.FC = () => {
|
|||||||
type: "SOP Pack",
|
type: "SOP Pack",
|
||||||
tags: ["Execution", "Prompt Pack"],
|
tags: ["Execution", "Prompt Pack"],
|
||||||
icon: ListBulletIcon,
|
icon: ListBulletIcon,
|
||||||
color: "from-[var(--igny8-purple)] to-[var(--igny8-purple-dark)]",
|
color: "from-[var(--color-purple)] to-[var(--color-purple-dark)]",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: "AI Prompt Library for Content Teams",
|
title: "AI Prompt Library for Content Teams",
|
||||||
@@ -173,7 +173,7 @@ const Resources: React.FC = () => {
|
|||||||
type: "Prompt Pack",
|
type: "Prompt Pack",
|
||||||
tags: ["Prompt Pack", "Execution"],
|
tags: ["Prompt Pack", "Execution"],
|
||||||
icon: SparklesIcon,
|
icon: SparklesIcon,
|
||||||
color: "from-[var(--igny8-amber)] to-[var(--igny8-amber-dark)]",
|
color: "from-[var(--color-warning)] to-[var(--color-warning-dark)]",
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
@@ -196,7 +196,7 @@ const Resources: React.FC = () => {
|
|||||||
<div className="flex justify-center">
|
<div className="flex justify-center">
|
||||||
{renderCta(
|
{renderCta(
|
||||||
{ label: "Explore All Resources", href: "#learn" },
|
{ label: "Explore All Resources", href: "#learn" },
|
||||||
"inline-flex items-center justify-center rounded-xl bg-gradient-to-r from-[var(--igny8-blue)] to-[var(--igny8-blue-dark)] text-white px-8 py-4 text-base font-semibold hover:shadow-lg hover:-translate-y-0.5 transition shadow-md"
|
"inline-flex items-center justify-center rounded-xl bg-gradient-to-r from-[var(--color-primary)] to-[var(--color-primary-dark)] text-white px-8 py-4 text-base font-semibold hover:shadow-lg hover:-translate-y-0.5 transition shadow-md"
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -235,7 +235,7 @@ const Resources: React.FC = () => {
|
|||||||
<p className="text-sm text-slate-600 leading-relaxed flex-1">{resource.description}</p>
|
<p className="text-sm text-slate-600 leading-relaxed flex-1">{resource.description}</p>
|
||||||
<a
|
<a
|
||||||
href="#"
|
href="#"
|
||||||
className="inline-flex items-center gap-2 text-sm font-semibold igny8-text-blue hover:text-[var(--igny8-blue-dark)] group"
|
className="inline-flex items-center gap-2 text-sm font-semibold text-[var(--color-primary)] hover:text-[var(--color-primary-dark)] group"
|
||||||
>
|
>
|
||||||
{resource.type.includes("PDF") ? "Download" : "Read"} {resource.type.toLowerCase().includes("article") ? "article" : "guide"}
|
{resource.type.includes("PDF") ? "Download" : "Read"} {resource.type.toLowerCase().includes("article") ? "article" : "guide"}
|
||||||
<ArrowRightIcon className="h-4 w-4 group-hover:translate-x-1 transition-transform" />
|
<ArrowRightIcon className="h-4 w-4 group-hover:translate-x-1 transition-transform" />
|
||||||
@@ -247,7 +247,7 @@ const Resources: React.FC = () => {
|
|||||||
<div className="text-center mt-12">
|
<div className="text-center mt-12">
|
||||||
<a
|
<a
|
||||||
href="#"
|
href="#"
|
||||||
className="inline-flex items-center gap-2 text-base font-semibold text-slate-700 hover:igny8-text-blue transition"
|
className="inline-flex items-center gap-2 text-base font-semibold text-slate-700 hover:text-[var(--color-primary)] transition"
|
||||||
>
|
>
|
||||||
View All Guides
|
View All Guides
|
||||||
<ArrowRightIcon className="h-5 w-5" />
|
<ArrowRightIcon className="h-5 w-5" />
|
||||||
@@ -270,10 +270,10 @@ const Resources: React.FC = () => {
|
|||||||
{buildSystemResources.map((resource, index) => {
|
{buildSystemResources.map((resource, index) => {
|
||||||
const Icon = resource.icon;
|
const Icon = resource.icon;
|
||||||
const colors = [
|
const colors = [
|
||||||
"from-[var(--igny8-blue)]/10 to-white",
|
"from-[var(--color-primary)]/10 to-white",
|
||||||
"from-[var(--igny8-green)]/10 to-white",
|
"from-[var(--color-success)]/10 to-white",
|
||||||
"from-[var(--igny8-purple)]/10 to-white",
|
"from-[var(--color-purple)]/10 to-white",
|
||||||
"from-[var(--igny8-amber)]/10 to-white",
|
"from-[var(--color-warning)]/10 to-white",
|
||||||
];
|
];
|
||||||
const borders = [
|
const borders = [
|
||||||
"border-[#0693e3]/30",
|
"border-[#0693e3]/30",
|
||||||
@@ -308,7 +308,7 @@ const Resources: React.FC = () => {
|
|||||||
<p className="text-sm text-slate-600 leading-relaxed mb-4">{resource.description}</p>
|
<p className="text-sm text-slate-600 leading-relaxed mb-4">{resource.description}</p>
|
||||||
<a
|
<a
|
||||||
href="#"
|
href="#"
|
||||||
className="inline-flex items-center gap-2 text-sm font-semibold igny8-text-blue hover:text-[var(--igny8-blue-dark)] group"
|
className="inline-flex items-center gap-2 text-sm font-semibold text-[var(--color-primary)] hover:text-[var(--color-primary-dark)] group"
|
||||||
>
|
>
|
||||||
<ArrowDownTrayIcon className="h-4 w-4" />
|
<ArrowDownTrayIcon className="h-4 w-4" />
|
||||||
Download {resource.type.toLowerCase()}
|
Download {resource.type.toLowerCase()}
|
||||||
@@ -323,7 +323,7 @@ const Resources: React.FC = () => {
|
|||||||
<div className="text-center mt-12">
|
<div className="text-center mt-12">
|
||||||
<a
|
<a
|
||||||
href="#"
|
href="#"
|
||||||
className="inline-flex items-center gap-2 text-base font-semibold text-slate-700 hover:igny8-text-blue transition"
|
className="inline-flex items-center gap-2 text-base font-semibold text-slate-700 hover:text-[var(--color-primary)] transition"
|
||||||
>
|
>
|
||||||
Explore Templates
|
Explore Templates
|
||||||
<ArrowRightIcon className="h-5 w-5" />
|
<ArrowRightIcon className="h-5 w-5" />
|
||||||
@@ -347,10 +347,10 @@ const Resources: React.FC = () => {
|
|||||||
{attendWatchResources.map((resource, index) => {
|
{attendWatchResources.map((resource, index) => {
|
||||||
const Icon = resource.icon;
|
const Icon = resource.icon;
|
||||||
const colors = [
|
const colors = [
|
||||||
"from-[var(--igny8-blue)]/10 to-white",
|
"from-[var(--color-primary)]/10 to-white",
|
||||||
"from-[var(--igny8-green)]/10 to-white",
|
"from-[var(--color-success)]/10 to-white",
|
||||||
"from-[var(--igny8-purple)]/10 to-white",
|
"from-[var(--color-purple)]/10 to-white",
|
||||||
"from-[var(--igny8-amber)]/10 to-white",
|
"from-[var(--color-warning)]/10 to-white",
|
||||||
];
|
];
|
||||||
const borders = [
|
const borders = [
|
||||||
"border-[#0693e3]/30",
|
"border-[#0693e3]/30",
|
||||||
@@ -391,8 +391,8 @@ const Resources: React.FC = () => {
|
|||||||
<button
|
<button
|
||||||
className={`inline-flex items-center justify-center gap-2 rounded-xl px-6 py-3 text-sm font-semibold transition ${
|
className={`inline-flex items-center justify-center gap-2 rounded-xl px-6 py-3 text-sm font-semibold transition ${
|
||||||
resource.tag === "Live"
|
resource.tag === "Live"
|
||||||
? "bg-gradient-to-r from-[var(--igny8-blue)] to-[var(--igny8-blue-dark)] text-white hover:shadow-lg"
|
? "bg-gradient-to-r from-[var(--color-primary)] to-[var(--color-primary-dark)] text-white hover:shadow-lg"
|
||||||
: "border-2 border-slate-300 bg-white text-slate-700 hover:border-[#0693e3] hover:igny8-text-blue"
|
: "border-2 border-slate-300 bg-white text-slate-700 hover:border-[#0693e3] hover:text-[var(--color-primary)]"
|
||||||
}`}
|
}`}
|
||||||
>
|
>
|
||||||
{resource.tag === "Live" ? (
|
{resource.tag === "Live" ? (
|
||||||
@@ -414,7 +414,7 @@ const Resources: React.FC = () => {
|
|||||||
<div className="text-center mt-12">
|
<div className="text-center mt-12">
|
||||||
<a
|
<a
|
||||||
href="#"
|
href="#"
|
||||||
className="inline-flex items-center gap-2 text-base font-semibold text-slate-700 hover:igny8-text-blue transition"
|
className="inline-flex items-center gap-2 text-base font-semibold text-slate-700 hover:text-[var(--color-primary)] transition"
|
||||||
>
|
>
|
||||||
View Schedule
|
View Schedule
|
||||||
<ArrowRightIcon className="h-5 w-5" />
|
<ArrowRightIcon className="h-5 w-5" />
|
||||||
@@ -462,7 +462,7 @@ const Resources: React.FC = () => {
|
|||||||
<p className="text-sm text-slate-600 leading-relaxed flex-1">{resource.description}</p>
|
<p className="text-sm text-slate-600 leading-relaxed flex-1">{resource.description}</p>
|
||||||
<a
|
<a
|
||||||
href="#"
|
href="#"
|
||||||
className="inline-flex items-center gap-2 text-sm font-semibold igny8-text-blue hover:text-[var(--igny8-blue-dark)] group"
|
className="inline-flex items-center gap-2 text-sm font-semibold text-[var(--color-primary)] hover:text-[var(--color-primary-dark)] group"
|
||||||
>
|
>
|
||||||
<ArrowDownTrayIcon className="h-4 w-4" />
|
<ArrowDownTrayIcon className="h-4 w-4" />
|
||||||
Download Now
|
Download Now
|
||||||
@@ -487,7 +487,7 @@ const Resources: React.FC = () => {
|
|||||||
<div>
|
<div>
|
||||||
<a
|
<a
|
||||||
href="#"
|
href="#"
|
||||||
className="inline-flex items-center gap-2 rounded-xl bg-gradient-to-r from-[var(--igny8-green)] to-[var(--igny8-green-dark)] text-white px-8 py-4 text-base font-semibold hover:shadow-lg hover:-translate-y-0.5 transition shadow-md"
|
className="inline-flex items-center gap-2 rounded-xl bg-gradient-to-r from-[var(--color-success)] to-[var(--color-success-dark)] text-white px-8 py-4 text-base font-semibold hover:shadow-lg hover:-translate-y-0.5 transition shadow-md"
|
||||||
>
|
>
|
||||||
Browse Toolkits
|
Browse Toolkits
|
||||||
<ArrowRightIcon className="h-5 w-5" />
|
<ArrowRightIcon className="h-5 w-5" />
|
||||||
@@ -511,7 +511,7 @@ const Resources: React.FC = () => {
|
|||||||
href="https://app.igny8.com/signup"
|
href="https://app.igny8.com/signup"
|
||||||
target="_blank"
|
target="_blank"
|
||||||
rel="noreferrer"
|
rel="noreferrer"
|
||||||
className="inline-flex items-center justify-center gap-2 rounded-xl bg-white igny8-text-blue px-10 py-5 text-lg font-bold hover:bg-white/95 transition shadow-xl hover:shadow-2xl hover:-translate-y-0.5"
|
className="inline-flex items-center justify-center gap-2 rounded-xl bg-white text-[var(--color-primary)] px-10 py-5 text-lg font-bold hover:bg-white/95 transition shadow-xl hover:shadow-2xl hover:-translate-y-0.5"
|
||||||
>
|
>
|
||||||
<RocketLaunchIcon className="h-5 w-5" />
|
<RocketLaunchIcon className="h-5 w-5" />
|
||||||
Start for $1
|
Start for $1
|
||||||
|
|||||||
@@ -55,11 +55,11 @@ const Solutions: React.FC = () => {
|
|||||||
"Keep editors in control with approvals and Thinker playbooks",
|
"Keep editors in control with approvals and Thinker playbooks",
|
||||||
"Automate image generation and WordPress publishing by site",
|
"Automate image generation and WordPress publishing by site",
|
||||||
],
|
],
|
||||||
color: "from-[var(--igny8-blue)]/5 to-white",
|
color: "from-[var(--color-primary)]/5 to-white",
|
||||||
borderColor: "border-[var(--igny8-blue)]/20",
|
borderColor: "border-[var(--color-primary)]/20",
|
||||||
iconColor: "from-[var(--igny8-blue)] to-[var(--igny8-blue-dark)]",
|
iconColor: "from-[var(--color-primary)] to-[var(--color-primary-dark)]",
|
||||||
painColor: "bg-rose-500",
|
painColor: "bg-rose-500",
|
||||||
outcomeColor: "igny8-bg-blue",
|
outcomeColor: "bg-[var(--color-primary)]",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "Agencies & Consultancies",
|
name: "Agencies & Consultancies",
|
||||||
@@ -75,11 +75,11 @@ const Solutions: React.FC = () => {
|
|||||||
"Real-time dashboards to prove impact and showcase velocity",
|
"Real-time dashboards to prove impact and showcase velocity",
|
||||||
"Reusable Thinker libraries to standardize tone and strategy",
|
"Reusable Thinker libraries to standardize tone and strategy",
|
||||||
],
|
],
|
||||||
color: "from-[var(--igny8-green)]/5 to-white",
|
color: "from-[var(--color-success)]/5 to-white",
|
||||||
borderColor: "border-[var(--igny8-green)]/20",
|
borderColor: "border-[var(--color-success)]/20",
|
||||||
iconColor: "from-[var(--igny8-green)] to-[var(--igny8-green-dark)]",
|
iconColor: "from-[var(--color-success)] to-[var(--color-success-dark)]",
|
||||||
painColor: "bg-rose-500",
|
painColor: "bg-rose-500",
|
||||||
outcomeColor: "igny8-bg-green",
|
outcomeColor: "bg-[var(--color-success)]",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "In-house Marketing Teams",
|
name: "In-house Marketing Teams",
|
||||||
@@ -95,9 +95,9 @@ const Solutions: React.FC = () => {
|
|||||||
"Dashboards that unite SEO, writers, designers, and leadership",
|
"Dashboards that unite SEO, writers, designers, and leadership",
|
||||||
"Insights to reallocate focus when campaigns spike or drop",
|
"Insights to reallocate focus when campaigns spike or drop",
|
||||||
],
|
],
|
||||||
color: "from-[var(--igny8-purple)]/5 to-white",
|
color: "from-[var(--color-purple)]/5 to-white",
|
||||||
borderColor: "border-[var(--igny8-purple)]/20",
|
borderColor: "border-[var(--color-purple)]/20",
|
||||||
iconColor: "from-[var(--igny8-purple)] to-[var(--igny8-purple-dark)]",
|
iconColor: "from-[var(--color-purple)] to-[var(--color-purple-dark)]",
|
||||||
painColor: "bg-rose-500",
|
painColor: "bg-rose-500",
|
||||||
outcomeColor: "igny8-bg-purple",
|
outcomeColor: "igny8-bg-purple",
|
||||||
},
|
},
|
||||||
@@ -108,37 +108,37 @@ const Solutions: React.FC = () => {
|
|||||||
title: "Keyword Research",
|
title: "Keyword Research",
|
||||||
description: "Discover high-opportunity keywords from a global database with real-time volumes and difficulty scores.",
|
description: "Discover high-opportunity keywords from a global database with real-time volumes and difficulty scores.",
|
||||||
icon: ChartBarIcon,
|
icon: ChartBarIcon,
|
||||||
color: "from-[var(--igny8-blue)] to-[var(--igny8-blue-dark)]",
|
color: "from-[var(--color-primary)] to-[var(--color-primary-dark)]",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: "Content Briefs",
|
title: "Content Briefs",
|
||||||
description: "Generate comprehensive briefs with outlines, talking points, and internal link suggestions.",
|
description: "Generate comprehensive briefs with outlines, talking points, and internal link suggestions.",
|
||||||
icon: DocumentTextIcon,
|
icon: DocumentTextIcon,
|
||||||
color: "from-[var(--igny8-green)] to-[var(--igny8-green-dark)]",
|
color: "from-[var(--color-success)] to-[var(--color-success-dark)]",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: "Content Writing",
|
title: "Content Writing",
|
||||||
description: "Create long-form articles aligned to your brand voice, compliance rules, and target SERP.",
|
description: "Create long-form articles aligned to your brand voice, compliance rules, and target SERP.",
|
||||||
icon: SparklesIcon,
|
icon: SparklesIcon,
|
||||||
color: "from-[var(--igny8-amber)] to-[var(--igny8-amber-dark)]",
|
color: "from-[var(--color-warning)] to-[var(--color-warning-dark)]",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: "Cluster Analysis",
|
title: "Cluster Analysis",
|
||||||
description: "AI-powered semantic clustering to group related keywords and build topical authority maps.",
|
description: "AI-powered semantic clustering to group related keywords and build topical authority maps.",
|
||||||
icon: UserGroupIcon,
|
icon: UserGroupIcon,
|
||||||
color: "from-[var(--igny8-purple)] to-[var(--igny8-purple-dark)]",
|
color: "from-[var(--color-purple)] to-[var(--color-purple-dark)]",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: "Image Generation",
|
title: "Image Generation",
|
||||||
description: "AI-generated featured and in-article images based on your content with brand consistency.",
|
description: "AI-generated featured and in-article images based on your content with brand consistency.",
|
||||||
icon: PhotoIcon,
|
icon: PhotoIcon,
|
||||||
color: "from-[var(--igny8-blue)] to-[var(--igny8-purple)]",
|
color: "from-[var(--color-primary)] to-[var(--color-purple)]",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: "Workflow Automation",
|
title: "Workflow Automation",
|
||||||
description: "End-to-end automation from keywords to published content with intelligent handoffs.",
|
description: "End-to-end automation from keywords to published content with intelligent handoffs.",
|
||||||
icon: BoltIcon,
|
icon: BoltIcon,
|
||||||
color: "from-[var(--igny8-green)] to-[var(--igny8-blue)]",
|
color: "from-[var(--color-success)] to-[var(--color-primary)]",
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
@@ -161,11 +161,11 @@ const Solutions: React.FC = () => {
|
|||||||
<div className="flex flex-col sm:flex-row gap-4 justify-center">
|
<div className="flex flex-col sm:flex-row gap-4 justify-center">
|
||||||
{renderCta(
|
{renderCta(
|
||||||
{ label: "See use cases", href: "#use-cases" },
|
{ label: "See use cases", href: "#use-cases" },
|
||||||
"inline-flex items-center justify-center rounded-xl bg-gradient-to-r from-[var(--igny8-blue)] to-[var(--igny8-blue-dark)] text-white px-8 py-4 text-base font-semibold hover:shadow-lg hover:-translate-y-0.5 transition shadow-md"
|
"inline-flex items-center justify-center rounded-xl bg-gradient-to-r from-[var(--color-primary)] to-[var(--color-primary-dark)] text-white px-8 py-4 text-base font-semibold hover:shadow-lg hover:-translate-y-0.5 transition shadow-md"
|
||||||
)}
|
)}
|
||||||
{renderCta(
|
{renderCta(
|
||||||
{ label: "Talk to sales", href: "/contact" },
|
{ label: "Talk to sales", href: "/contact" },
|
||||||
"inline-flex items-center justify-center rounded-xl border-2 border-slate-300 bg-white text-slate-700 px-8 py-4 text-base font-semibold hover:border-[var(--igny8-blue)] hover:igny8-text-blue transition"
|
"inline-flex items-center justify-center rounded-xl border-2 border-slate-300 bg-white text-slate-700 px-8 py-4 text-base font-semibold hover:border-[var(--color-primary)] hover:text-[var(--color-primary)] transition"
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -215,8 +215,8 @@ const Solutions: React.FC = () => {
|
|||||||
{/* Right: IGNY8 Outcomes */}
|
{/* Right: IGNY8 Outcomes */}
|
||||||
<div className="bg-white rounded-2xl border-2 border-slate-200 p-8 shadow-sm">
|
<div className="bg-white rounded-2xl border-2 border-slate-200 p-8 shadow-sm">
|
||||||
<div className="flex items-center gap-2 mb-6">
|
<div className="flex items-center gap-2 mb-6">
|
||||||
<CheckCircleIcon className={`h-5 w-5 ${persona.outcomeColor === 'igny8-bg-blue' ? 'igny8-text-blue' : persona.outcomeColor === 'igny8-bg-green' ? 'igny8-text-green' : 'igny8-text-purple'}`} />
|
<CheckCircleIcon className={`h-5 w-5 ${persona.outcomeColor === 'bg-[var(--color-primary)]' ? 'text-[var(--color-primary)]' : persona.outcomeColor === 'bg-[var(--color-success)]' ? 'igny8-text-green' : 'igny8-text-purple'}`} />
|
||||||
<h4 className={`text-sm uppercase tracking-[0.2em] font-semibold ${persona.outcomeColor === 'igny8-bg-blue' ? 'igny8-text-blue' : persona.outcomeColor === 'igny8-bg-green' ? 'igny8-text-green' : 'igny8-text-purple'}`}>
|
<h4 className={`text-sm uppercase tracking-[0.2em] font-semibold ${persona.outcomeColor === 'bg-[var(--color-primary)]' ? 'text-[var(--color-primary)]' : persona.outcomeColor === 'bg-[var(--color-success)]' ? 'igny8-text-green' : 'igny8-text-purple'}`}>
|
||||||
IGNY8 Outcomes
|
IGNY8 Outcomes
|
||||||
</h4>
|
</h4>
|
||||||
</div>
|
</div>
|
||||||
@@ -244,24 +244,24 @@ const Solutions: React.FC = () => {
|
|||||||
label: "organic lift",
|
label: "organic lift",
|
||||||
description: "Average lift in organic traffic within 90 days",
|
description: "Average lift in organic traffic within 90 days",
|
||||||
icon: ArrowTrendingUpIcon,
|
icon: ArrowTrendingUpIcon,
|
||||||
color: "from-[var(--igny8-blue)] to-[var(--igny8-blue-dark)]",
|
color: "from-[var(--color-primary)] to-[var(--color-primary-dark)]",
|
||||||
glow: "shadow-[var(--igny8-blue)]/30",
|
glow: "shadow-[var(--color-primary)]/30",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
metric: "48%",
|
metric: "48%",
|
||||||
label: "reduction in time to publish",
|
label: "reduction in time to publish",
|
||||||
description: "Faster time-to-publish from keyword discovery",
|
description: "Faster time-to-publish from keyword discovery",
|
||||||
icon: ClockIcon,
|
icon: ClockIcon,
|
||||||
color: "from-[var(--igny8-green)] to-[var(--igny8-green-dark)]",
|
color: "from-[var(--color-success)] to-[var(--color-success-dark)]",
|
||||||
glow: "shadow-[var(--igny8-green)]/30",
|
glow: "shadow-[var(--color-success)]/30",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
metric: "4 tools",
|
metric: "4 tools",
|
||||||
label: "replaced",
|
label: "replaced",
|
||||||
description: "Average number of point solutions replaced by Igny8",
|
description: "Average number of point solutions replaced by Igny8",
|
||||||
icon: WrenchScrewdriverIcon,
|
icon: WrenchScrewdriverIcon,
|
||||||
color: "from-[var(--igny8-amber)] to-[var(--igny8-amber-dark)]",
|
color: "from-[var(--color-warning)] to-[var(--color-warning-dark)]",
|
||||||
glow: "shadow-[var(--igny8-amber)]/30",
|
glow: "shadow-[var(--color-warning)]/30",
|
||||||
},
|
},
|
||||||
].map((stat, index) => {
|
].map((stat, index) => {
|
||||||
const Icon = stat.icon;
|
const Icon = stat.icon;
|
||||||
@@ -344,7 +344,7 @@ const Solutions: React.FC = () => {
|
|||||||
</section>
|
</section>
|
||||||
|
|
||||||
{/* FINAL CTA */}
|
{/* FINAL CTA */}
|
||||||
<section className="relative overflow-hidden bg-gradient-to-br from-[var(--igny8-blue)] via-[var(--igny8-purple)] to-[#8b5cf6]">
|
<section className="relative overflow-hidden bg-gradient-to-br from-[var(--color-primary)] via-[var(--color-purple)] to-[#8b5cf6]">
|
||||||
{/* Radial glow */}
|
{/* Radial glow */}
|
||||||
<div className="absolute inset-0 bg-[radial-gradient(circle_at_50%_50%,rgba(255,255,255,0.1),transparent_70%)]" />
|
<div className="absolute inset-0 bg-[radial-gradient(circle_at_50%_50%,rgba(255,255,255,0.1),transparent_70%)]" />
|
||||||
|
|
||||||
@@ -360,7 +360,7 @@ const Solutions: React.FC = () => {
|
|||||||
href="https://app.igny8.com/signup"
|
href="https://app.igny8.com/signup"
|
||||||
target="_blank"
|
target="_blank"
|
||||||
rel="noreferrer"
|
rel="noreferrer"
|
||||||
className="inline-flex items-center justify-center gap-2 rounded-xl bg-white igny8-text-blue px-10 py-5 text-lg font-bold hover:bg-white/95 transition shadow-xl hover:shadow-2xl hover:-translate-y-0.5"
|
className="inline-flex items-center justify-center gap-2 rounded-xl bg-white text-[var(--color-primary)] px-10 py-5 text-lg font-bold hover:bg-white/95 transition shadow-xl hover:shadow-2xl hover:-translate-y-0.5"
|
||||||
>
|
>
|
||||||
<RocketLaunchIcon className="h-5 w-5" />
|
<RocketLaunchIcon className="h-5 w-5" />
|
||||||
Start free
|
Start free
|
||||||
|
|||||||
@@ -38,7 +38,7 @@ const Tour: React.FC = () => {
|
|||||||
title="Experience the entire Igny8 journey in minutes."
|
title="Experience the entire Igny8 journey in minutes."
|
||||||
description="Walk through the workflow that moves market intelligence into production-ready content. Each step builds toward an automated growth flywheel."
|
description="Walk through the workflow that moves market intelligence into production-ready content. Each step builds toward an automated growth flywheel."
|
||||||
/>
|
/>
|
||||||
<div className="rounded-3xl border-2 border-[var(--igny8-blue)]/30 bg-gradient-to-br from-[var(--igny8-blue)]/10 via-white to-[var(--igny8-green)]/5 p-8 shadow-lg">
|
<div className="rounded-3xl border-2 border-[var(--color-primary)]/30 bg-gradient-to-br from-[var(--color-primary)]/10 via-white to-[var(--color-success)]/5 p-8 shadow-lg">
|
||||||
<div className="aspect-video rounded-2xl border-2 border-slate-200 bg-gradient-to-br from-slate-50 to-white flex items-center justify-center text-slate-500 text-sm shadow-inner">
|
<div className="aspect-video rounded-2xl border-2 border-slate-200 bg-gradient-to-br from-slate-50 to-white flex items-center justify-center text-slate-500 text-sm shadow-inner">
|
||||||
Video walkthrough placeholder (embed demo or Loom)
|
Video walkthrough placeholder (embed demo or Loom)
|
||||||
</div>
|
</div>
|
||||||
@@ -48,9 +48,9 @@ const Tour: React.FC = () => {
|
|||||||
<section className="max-w-6xl mx-auto px-6 pb-24 space-y-12">
|
<section className="max-w-6xl mx-auto px-6 pb-24 space-y-12">
|
||||||
{tourSteps.map((step, index) => {
|
{tourSteps.map((step, index) => {
|
||||||
const colors = [
|
const colors = [
|
||||||
{ border: "border-[var(--igny8-blue)]/40", gradient: "from-[var(--igny8-blue)]/10 to-white", dot: "bg-[var(--igny8-blue)]" },
|
{ border: "border-[var(--color-primary)]/40", gradient: "from-[var(--color-primary)]/10 to-white", dot: "bg-[var(--color-primary)]" },
|
||||||
{ border: "border-[var(--igny8-green)]/40", gradient: "from-[var(--igny8-green)]/10 to-white", dot: "bg-[var(--igny8-green)]" },
|
{ border: "border-[var(--color-success)]/40", gradient: "from-[var(--color-success)]/10 to-white", dot: "bg-[var(--color-success)]" },
|
||||||
{ border: "border-[var(--igny8-amber)]/40", gradient: "from-[var(--igny8-amber)]/10 to-white", dot: "bg-[var(--igny8-amber)]" },
|
{ border: "border-[var(--color-warning)]/40", gradient: "from-[var(--color-warning)]/10 to-white", dot: "bg-[var(--color-warning)]" },
|
||||||
{ border: "border-[#5d4ae3]/40", gradient: "from-[#5d4ae3]/10 to-white", dot: "bg-[#5d4ae3]" },
|
{ border: "border-[#5d4ae3]/40", gradient: "from-[#5d4ae3]/10 to-white", dot: "bg-[#5d4ae3]" },
|
||||||
];
|
];
|
||||||
const colorScheme = colors[index % colors.length];
|
const colorScheme = colors[index % colors.length];
|
||||||
@@ -79,7 +79,7 @@ const Tour: React.FC = () => {
|
|||||||
})}
|
})}
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
<section className="bg-gradient-to-br from-[var(--igny8-blue)]/10 via-slate-50/70 to-[#0bbf87]/10 border-y border-[#0693e3]/20">
|
<section className="bg-gradient-to-br from-[var(--color-primary)]/10 via-slate-50/70 to-[#0bbf87]/10 border-y border-[#0693e3]/20">
|
||||||
<div className="max-w-6xl mx-auto px-6 py-24 space-y-10">
|
<div className="max-w-6xl mx-auto px-6 py-24 space-y-10">
|
||||||
<SectionHeading
|
<SectionHeading
|
||||||
eyebrow="Automation recipes"
|
eyebrow="Automation recipes"
|
||||||
@@ -88,12 +88,12 @@ const Tour: React.FC = () => {
|
|||||||
/>
|
/>
|
||||||
<div className="grid grid-cols-1 md:grid-cols-2 xl:grid-cols-3 gap-6 text-sm text-slate-600">
|
<div className="grid grid-cols-1 md:grid-cols-2 xl:grid-cols-3 gap-6 text-sm text-slate-600">
|
||||||
{[
|
{[
|
||||||
{ name: "Keywords → Ideas", time: "Nightly", highlight: "Targets new opportunities", color: "border-[var(--igny8-blue)]/40", gradient: "from-[var(--igny8-blue)]/10 to-white" },
|
{ name: "Keywords → Ideas", time: "Nightly", highlight: "Targets new opportunities", color: "border-[var(--color-primary)]/40", gradient: "from-[var(--color-primary)]/10 to-white" },
|
||||||
{ name: "Ideas → Tasks", time: "Daily", highlight: "Staff writers automatically", color: "border-[var(--igny8-green)]/40", gradient: "from-[var(--igny8-green)]/10 to-white" },
|
{ name: "Ideas → Tasks", time: "Daily", highlight: "Staff writers automatically", color: "border-[var(--color-success)]/40", gradient: "from-[var(--color-success)]/10 to-white" },
|
||||||
{ name: "Tasks → Content", time: "Hourly", highlight: "Generate & queue drafts", color: "border-[var(--igny8-amber)]/40", gradient: "from-[var(--igny8-amber)]/10 to-white" },
|
{ name: "Tasks → Content", time: "Hourly", highlight: "Generate & queue drafts", color: "border-[var(--color-warning)]/40", gradient: "from-[var(--color-warning)]/10 to-white" },
|
||||||
{ name: "Content → Images", time: "On approval", highlight: "Produce branded visuals", color: "border-[#5d4ae3]/40", gradient: "from-[#5d4ae3]/10 to-white" },
|
{ name: "Content → Images", time: "On approval", highlight: "Produce branded visuals", color: "border-[#5d4ae3]/40", gradient: "from-[#5d4ae3]/10 to-white" },
|
||||||
{ name: "Content → WordPress", time: "Manual launch", highlight: "One-click publish", color: "border-[var(--igny8-blue)]/40", gradient: "from-[var(--igny8-blue)]/10 to-white" },
|
{ name: "Content → WordPress", time: "Manual launch", highlight: "One-click publish", color: "border-[var(--color-primary)]/40", gradient: "from-[var(--color-primary)]/10 to-white" },
|
||||||
{ name: "SERP Win/Loss Alerts", time: "Real-time", highlight: "Trigger optimizations", color: "border-[var(--igny8-green)]/40", gradient: "from-[var(--igny8-green)]/10 to-white" },
|
{ name: "SERP Win/Loss Alerts", time: "Real-time", highlight: "Trigger optimizations", color: "border-[var(--color-success)]/40", gradient: "from-[var(--color-success)]/10 to-white" },
|
||||||
].map((recipe) => (
|
].map((recipe) => (
|
||||||
<div
|
<div
|
||||||
key={recipe.name}
|
key={recipe.name}
|
||||||
|
|||||||
@@ -29,9 +29,9 @@ const Waitlist: React.FC = () => {
|
|||||||
</section>
|
</section>
|
||||||
|
|
||||||
<section className="max-w-5xl mx-auto px-6 pb-24 grid grid-cols-1 lg:grid-cols-2 gap-12">
|
<section className="max-w-5xl mx-auto px-6 pb-24 grid grid-cols-1 lg:grid-cols-2 gap-12">
|
||||||
<div className="rounded-3xl border-2 border-[var(--igny8-blue)]/30 bg-gradient-to-br from-[var(--igny8-blue)]/10 via-white to-[var(--igny8-green)]/5 p-10 space-y-6 shadow-lg">
|
<div className="rounded-3xl border-2 border-[var(--color-primary)]/30 bg-gradient-to-br from-[var(--color-primary)]/10 via-white to-[var(--color-success)]/5 p-10 space-y-6 shadow-lg">
|
||||||
<h3 className="text-lg font-semibold text-slate-900 flex items-center gap-2">
|
<h3 className="text-lg font-semibold text-slate-900 flex items-center gap-2">
|
||||||
<span className="size-2 rounded-full bg-[var(--igny8-blue)]"></span>
|
<span className="size-2 rounded-full bg-[var(--color-primary)]"></span>
|
||||||
Join the waitlist
|
Join the waitlist
|
||||||
</h3>
|
</h3>
|
||||||
<p className="text-sm text-slate-600">
|
<p className="text-sm text-slate-600">
|
||||||
@@ -41,17 +41,17 @@ const Waitlist: React.FC = () => {
|
|||||||
<input
|
<input
|
||||||
type="text"
|
type="text"
|
||||||
placeholder="Name"
|
placeholder="Name"
|
||||||
className="w-full rounded-xl border-2 border-slate-200 bg-white px-4 py-3 text-sm text-slate-900 placeholder:text-slate-500 focus:outline-none focus:border-[var(--igny8-blue)] focus:ring-2 focus:ring-[var(--igny8-blue)]/20"
|
className="w-full rounded-xl border-2 border-slate-200 bg-white px-4 py-3 text-sm text-slate-900 placeholder:text-slate-500 focus:outline-none focus:border-[var(--color-primary)] focus:ring-2 focus:ring-[var(--color-primary)]/20"
|
||||||
/>
|
/>
|
||||||
<input
|
<input
|
||||||
type="email"
|
type="email"
|
||||||
placeholder="Work email"
|
placeholder="Work email"
|
||||||
className="w-full rounded-xl border-2 border-slate-200 bg-white px-4 py-3 text-sm text-slate-900 placeholder:text-slate-500 focus:outline-none focus:border-[var(--igny8-blue)] focus:ring-2 focus:ring-[var(--igny8-blue)]/20"
|
className="w-full rounded-xl border-2 border-slate-200 bg-white px-4 py-3 text-sm text-slate-900 placeholder:text-slate-500 focus:outline-none focus:border-[var(--color-primary)] focus:ring-2 focus:ring-[var(--color-primary)]/20"
|
||||||
/>
|
/>
|
||||||
<textarea
|
<textarea
|
||||||
rows={4}
|
rows={4}
|
||||||
placeholder="Tell us about your current workflow and why you're excited."
|
placeholder="Tell us about your current workflow and why you're excited."
|
||||||
className="w-full rounded-xl border-2 border-slate-200 bg-white px-4 py-3 text-sm text-slate-900 placeholder:text-slate-500 focus:outline-none focus:border-[var(--igny8-blue)] focus:ring-2 focus:ring-[var(--igny8-blue)]/20 resize-none"
|
className="w-full rounded-xl border-2 border-slate-200 bg-white px-4 py-3 text-sm text-slate-900 placeholder:text-slate-500 focus:outline-none focus:border-[var(--color-primary)] focus:ring-2 focus:ring-[var(--color-primary)]/20 resize-none"
|
||||||
/>
|
/>
|
||||||
<button
|
<button
|
||||||
type="submit"
|
type="submit"
|
||||||
@@ -70,7 +70,7 @@ const Waitlist: React.FC = () => {
|
|||||||
</h4>
|
</h4>
|
||||||
<ul className="space-y-3 text-sm text-slate-600">
|
<ul className="space-y-3 text-sm text-slate-600">
|
||||||
{roadmapItems.map((item, idx) => {
|
{roadmapItems.map((item, idx) => {
|
||||||
const colors = ["bg-[var(--igny8-blue)]", "bg-[#0bbf87]", "bg-[#ff7a00]"];
|
const colors = ["bg-[var(--color-primary)]", "bg-[#0bbf87]", "bg-[#ff7a00]"];
|
||||||
return (
|
return (
|
||||||
<li key={item.title} className="flex gap-3">
|
<li key={item.title} className="flex gap-3">
|
||||||
<span className={`mt-1 size-1.5 rounded-full ${colors[idx % colors.length]} shadow-sm`} />
|
<span className={`mt-1 size-1.5 rounded-full ${colors[idx % colors.length]} shadow-sm`} />
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
@import url("https://fonts.googleapis.com/css2?family=Outfit:wght@100..900&display=swap")
|
@import url("https://fonts.googleapis.com/css2?family=Outfit:wght@100..900&display=swap")
|
||||||
layer(base);
|
layer(base);
|
||||||
|
|
||||||
|
@import "../../styles/tokens.css";
|
||||||
@import "tailwindcss";
|
@import "tailwindcss";
|
||||||
|
|
||||||
@layer base {
|
@layer base {
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
@import url("https://fonts.googleapis.com/css2?family=Outfit:wght@100..900&display=swap")
|
@import url("https://fonts.googleapis.com/css2?family=Outfit:wght@100..900&display=swap")
|
||||||
layer(base);
|
layer(base);
|
||||||
|
|
||||||
|
@import "./tokens.css";
|
||||||
@import "tailwindcss";
|
@import "tailwindcss";
|
||||||
|
|
||||||
@layer base {
|
@layer base {
|
||||||
|
|||||||
@@ -13,60 +13,37 @@
|
|||||||
=================================================================== */
|
=================================================================== */
|
||||||
|
|
||||||
/* === CSS CUSTOM PROPERTIES (Variables) === */
|
/* === CSS CUSTOM PROPERTIES (Variables) === */
|
||||||
|
/* Import tokens from centralized tokens.css */
|
||||||
|
@import "./tokens.css";
|
||||||
|
|
||||||
|
/* Legacy variable aliases for backward compatibility during migration */
|
||||||
:root {
|
:root {
|
||||||
/* Primary Brand Colors */
|
--igny8-blue: var(--color-primary);
|
||||||
--igny8-blue: #0693e3; /* Rocket vivid cyan blue - primary brand & main CTA */
|
--igny8-blue-dark: var(--color-primary-dark);
|
||||||
--igny8-blue-dark: #0472b8; /* Darkened cyan for hover / active / gradient depth */
|
--igny8-green: var(--color-success);
|
||||||
|
--igny8-green-dark: var(--color-success-dark);
|
||||||
/* Success Green (cooler to match cyan) */
|
--igny8-amber: var(--color-warning);
|
||||||
--igny8-green: #0bbf87; /* Slightly cooler teal-green for success states */
|
--igny8-amber-dark: var(--color-warning-dark);
|
||||||
--igny8-green-dark: #08966b; /* Deeper teal-green for hover / active */
|
--igny8-red: var(--color-danger);
|
||||||
|
--igny8-red-dark: var(--color-danger-dark);
|
||||||
/* Amber / Warning (warmed up to complement cyan) */
|
--igny8-purple: var(--color-purple);
|
||||||
--igny8-amber: #ff7a00; /* Rocket's vivid orange for highlight / warning */
|
--igny8-purple-dark: var(--color-purple-dark);
|
||||||
--igny8-amber-dark: #cc5f00; /* Darker orange for hover / strong warning */
|
--igny8-navy-bg: var(--color-navy);
|
||||||
|
--igny8-navy-bg-2: var(--color-navy-light);
|
||||||
/* Danger / Destructive */
|
--igny8-surface: var(--color-surface);
|
||||||
--igny8-red: #ef4444;
|
--igny8-panel: var(--color-panel);
|
||||||
--igny8-red-dark: #d13333; /* Refreshed red with better contrast against cyan */
|
--igny8-panel-2: var(--color-panel-alt);
|
||||||
|
--igny8-text: var(--color-text);
|
||||||
/* Purple */
|
--igny8-text-dim: var(--color-text-dim);
|
||||||
--igny8-purple: #5d4ae3; /* Purple for highlighting / special emphasis */
|
--igny8-text-light: var(--color-text-light);
|
||||||
--igny8-purple-dark: #3a2f94; /* Darker purple for hover / active */
|
--igny8-stroke: var(--color-stroke);
|
||||||
|
--igny8-radius: var(--radius-base);
|
||||||
/* Background Colors */
|
--igny8-gradient-blue: var(--gradient-primary);
|
||||||
--igny8-navy-bg: #0d1b2a; /* Sidebar background */
|
--igny8-gradient-success: var(--gradient-success);
|
||||||
--igny8-navy-bg-2: #142b3f; /* Slightly lighter navy, hover/active */
|
--igny8-gradient-warning: var(--gradient-warning);
|
||||||
--igny8-surface: #f8fafc; /* Page background (soft gray-white) */
|
--igny8-gradient-danger: var(--gradient-danger);
|
||||||
--igny8-panel: #ffffff; /* Cards / panel foreground */
|
--igny8-gradient-purple: var(--gradient-purple);
|
||||||
--igny8-panel-2: #f1f5f9; /* Sub-panel / hover card background */
|
--igny8-gradient-panel: var(--gradient-panel);
|
||||||
|
|
||||||
/* Text Colors */
|
|
||||||
--igny8-text: #555a68; /* main headings/body text */
|
|
||||||
--igny8-text-dim: #64748b; /* secondary/subtext */
|
|
||||||
--igny8-text-light: #e5eaf0; /* text on dark sidebar */
|
|
||||||
--igny8-stroke: #e2e8f0; /* table/grid borders and dividers */
|
|
||||||
|
|
||||||
/* Border Radius */
|
|
||||||
--igny8-radius: 6px;
|
|
||||||
|
|
||||||
/* Gradients */
|
|
||||||
--igny8-gradient-blue: linear-gradient(135deg, var(--igny8-blue) 0%, var(--igny8-blue-dark) 100%);
|
|
||||||
--igny8-gradient-success: linear-gradient(135deg, var(--igny8-green) 0%, var(--igny8-green-dark) 100%);
|
|
||||||
--igny8-gradient-warning: linear-gradient(135deg, var(--igny8-amber) 0%, var(--igny8-amber-dark) 100%);
|
|
||||||
--igny8-gradient-danger: linear-gradient(135deg, var(--igny8-red) 0%, var(--igny8-red-dark) 100%);
|
|
||||||
--igny8-gradient-purple: linear-gradient(135deg, var(--igny8-purple) 0%, var(--igny8-purple-dark) 100%);
|
|
||||||
--igny8-gradient-panel: linear-gradient(180deg, var(--igny8-panel) 0%, var(--igny8-panel-2) 100%);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Dark mode overrides (if needed) */
|
|
||||||
.dark {
|
|
||||||
--igny8-surface: #1f2937;
|
|
||||||
--igny8-panel: #1f2937;
|
|
||||||
--igny8-panel-2: #111827;
|
|
||||||
--igny8-text: #e5eaf0;
|
|
||||||
--igny8-text-dim: #9ca3af;
|
|
||||||
--igny8-stroke: #374151;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ===================================================================
|
/* ===================================================================
|
||||||
|
|||||||
77
frontend/src/styles/tokens.css
Normal file
77
frontend/src/styles/tokens.css
Normal file
@@ -0,0 +1,77 @@
|
|||||||
|
/* ===================================================================
|
||||||
|
DESIGN TOKENS
|
||||||
|
===================================================================
|
||||||
|
Single source of truth for all design tokens (colors, gradients, shadows, etc.)
|
||||||
|
Used by both Tailwind @theme and legacy CSS classes.
|
||||||
|
|
||||||
|
🔒 DESIGN SYSTEM LOCKED - See DESIGN_SYSTEM.md for complete style guide
|
||||||
|
=================================================================== */
|
||||||
|
|
||||||
|
:root {
|
||||||
|
/* ===================================================================
|
||||||
|
PRIMARY BRAND COLORS
|
||||||
|
=================================================================== */
|
||||||
|
--color-primary: #0693e3; /* Primary brand blue - main CTA */
|
||||||
|
--color-primary-dark: #0472b8; /* Darkened for hover / active / gradient depth */
|
||||||
|
|
||||||
|
/* Success Green (cooler to match cyan) */
|
||||||
|
--color-success: #0bbf87; /* Teal-green for success states */
|
||||||
|
--color-success-dark: #08966b; /* Deeper teal-green for hover / active */
|
||||||
|
|
||||||
|
/* Amber / Warning (warmed up to complement cyan) */
|
||||||
|
--color-warning: #ff7a00; /* Vivid orange for highlight / warning */
|
||||||
|
--color-warning-dark: #cc5f00; /* Darker orange for hover / strong warning */
|
||||||
|
|
||||||
|
/* Danger / Destructive */
|
||||||
|
--color-danger: #ef4444;
|
||||||
|
--color-danger-dark: #d13333; /* Refreshed red with better contrast */
|
||||||
|
|
||||||
|
/* Purple */
|
||||||
|
--color-purple: #5d4ae3; /* Purple for highlighting / special emphasis */
|
||||||
|
--color-purple-dark: #3a2f94; /* Darker purple for hover / active */
|
||||||
|
|
||||||
|
/* ===================================================================
|
||||||
|
BACKGROUND COLORS
|
||||||
|
=================================================================== */
|
||||||
|
--color-navy: #0d1b2a; /* Sidebar background */
|
||||||
|
--color-navy-light: #142b3f; /* Slightly lighter navy, hover/active */
|
||||||
|
--color-surface: #f8fafc; /* Page background (soft gray-white) */
|
||||||
|
--color-panel: #ffffff; /* Cards / panel foreground */
|
||||||
|
--color-panel-alt: #f1f5f9; /* Sub-panel / hover card background */
|
||||||
|
|
||||||
|
/* ===================================================================
|
||||||
|
TEXT COLORS
|
||||||
|
=================================================================== */
|
||||||
|
--color-text: #555a68; /* main headings/body text */
|
||||||
|
--color-text-dim: #64748b; /* secondary/subtext */
|
||||||
|
--color-text-light: #e5eaf0; /* text on dark sidebar */
|
||||||
|
--color-stroke: #e2e8f0; /* table/grid borders and dividers */
|
||||||
|
|
||||||
|
/* ===================================================================
|
||||||
|
BORDER RADIUS
|
||||||
|
=================================================================== */
|
||||||
|
--radius-base: 6px;
|
||||||
|
|
||||||
|
/* ===================================================================
|
||||||
|
GRADIENTS
|
||||||
|
=================================================================== */
|
||||||
|
--gradient-primary: linear-gradient(135deg, var(--color-primary) 0%, var(--color-primary-dark) 100%);
|
||||||
|
--gradient-success: linear-gradient(135deg, var(--color-success) 0%, var(--color-success-dark) 100%);
|
||||||
|
--gradient-warning: linear-gradient(135deg, var(--color-warning) 0%, var(--color-warning-dark) 100%);
|
||||||
|
--gradient-danger: linear-gradient(135deg, var(--color-danger) 0%, var(--color-danger-dark) 100%);
|
||||||
|
--gradient-purple: linear-gradient(135deg, var(--color-purple) 0%, var(--color-purple-dark) 100%);
|
||||||
|
--gradient-panel: linear-gradient(180deg, var(--color-panel) 0%, var(--color-panel-alt) 100%);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ===================================================================
|
||||||
|
DARK MODE OVERRIDES
|
||||||
|
=================================================================== */
|
||||||
|
.dark {
|
||||||
|
--color-surface: #1f2937;
|
||||||
|
--color-panel: #1f2937;
|
||||||
|
--color-panel-alt: #111827;
|
||||||
|
--color-text: #e5eaf0;
|
||||||
|
--color-text-dim: #9ca3af;
|
||||||
|
--color-stroke: #374151;
|
||||||
|
}
|
||||||
|
|
||||||
Reference in New Issue
Block a user