diff --git a/frontend/src/components/ui/badge/Badge.tsx b/frontend/src/components/ui/badge/Badge.tsx index 101d406f..d804685f 100644 --- a/frontend/src/components/ui/badge/Badge.tsx +++ b/frontend/src/components/ui/badge/Badge.tsx @@ -1,83 +1,100 @@ /** * Badge Component - * + * * 🔒 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. */ -type BadgeVariant = "light" | "solid"; -type BadgeSize = "sm" | "md"; -type BadgeColor = - | "primary" - | "success" - | "error" - | "warning" - | "info" - | "light" - | "dark"; +import clsx from "clsx"; + +type BadgeVariant = "solid" | "soft" | "outline"; +type BadgeSize = "xs" | "sm" | "md"; +type BadgeTone = "brand" | "success" | "warning" | "danger" | "info" | "neutral"; interface BadgeProps { - variant?: BadgeVariant; // Light or solid variant + variant?: BadgeVariant; // Visual treatment size?: BadgeSize; // Badge size - color?: BadgeColor; // Badge color + tone?: BadgeTone; // Badge color tone startIcon?: React.ReactNode; // Icon at the start endIcon?: React.ReactNode; // Icon at the end children: React.ReactNode; // Badge content 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 = { + 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 = ({ - variant = "light", - color = "primary", - size = "md", + variant = "soft", + tone = "brand", + size = "sm", startIcon, endIcon, children, className = "", }) => { - const baseStyles = - "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]; + const toneClass = toneStyles[tone][variant]; return ( - - {startIcon && {startIcon}} + + {startIcon && {startIcon}} {children} - {endIcon && {endIcon}} + {endIcon && {endIcon}} ); }; diff --git a/frontend/src/components/ui/button/Button.tsx b/frontend/src/components/ui/button/Button.tsx index d768d16d..b65a3bfe 100644 --- a/frontend/src/components/ui/button/Button.tsx +++ b/frontend/src/components/ui/button/Button.tsx @@ -1,70 +1,209 @@ /** * Button Component - * + * * 🔒 STYLE LOCKED - See DESIGN_SYSTEM.md for available variants and sizes. * Do not modify variants or add new ones without updating DESIGN_SYSTEM.md first. */ 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 { children: ReactNode; // Button text or content - size?: "sm" | "md"; // Button size - variant?: "primary" | "outline" | "secondary" | "success"; // Button variant + size?: ButtonSize; // Button size + variant?: ButtonVariant; // Visual variant + tone?: ButtonTone; // Color tone + shape?: ButtonShape; // Border radius style startIcon?: ReactNode; // Icon before the text endIcon?: ReactNode; // Icon after the text onClick?: () => void; // Click handler disabled?: boolean; // Disabled state + fullWidth?: boolean; // Stretch to parent width className?: string; // Additional classes 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(({ - children, - size = "md", - variant = "primary", - startIcon, - endIcon, - onClick, - className = "", - disabled = false, - type = "button", -}, ref) => { - // Size Classes - const sizeClasses = { - 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", +const toneMap: Record< + ButtonTone, + { + solid: string; + soft: string; + outline: string; + ghost: string; + ring: string; + } +> = { + brand: { + solid: "bg-brand-500 text-white hover:bg-brand-600", + soft: "bg-brand-50 text-brand-600 hover:bg-brand-100", 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", - secondary: - "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", - success: - "bg-success-500 text-white shadow-theme-xs hover:bg-success-600 disabled:bg-success-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]", + ghost: + "text-brand-600 hover:bg-brand-50 dark:text-brand-300 dark:hover:bg-brand-500/[0.08]", + ring: "focus-visible:ring-brand-500", + }, + 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 = { + brand: + "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%)]", + success: + "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%)]", + warning: + "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%)]", + 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%)]", + neutral: + "text-white shadow-theme-lg bg-[linear-gradient(135deg,#0f172a,#1e293b)]", +}; + +const sizeClasses: Record = { + xs: "h-7 px-2.5 text-xs", + sm: "h-9 px-3 text-sm", + md: "h-10 px-4 text-sm", + lg: "h-12 px-5 text-base", +}; + +const Button = forwardRef( + ( + { + 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 = { + 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 ( + + {startIcon && {startIcon}} + {children} + {endIcon && {endIcon}} + + ); + }, +); Button.displayName = "Button"; diff --git a/frontend/src/components/ui/card/Card.tsx b/frontend/src/components/ui/card/Card.tsx index 4fb25934..4735f20d 100644 --- a/frontend/src/components/ui/card/Card.tsx +++ b/frontend/src/components/ui/card/Card.tsx @@ -1,19 +1,62 @@ 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 { children: ReactNode; className?: string; onClick?: () => void; + variant?: CardVariant; + padding?: CardPadding; + shadow?: CardShadow; } export const Card: React.FC = ({ children, className = "", onClick, + variant = "surface", + padding = "md", + shadow = "sm", }) => { + const variantClasses: Record = { + 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 = { + none: "p-0", + sm: "p-4 sm:p-5", + md: "p-5 sm:p-6", + lg: "p-6 sm:p-8", + }; + + const shadowClasses: Record = { + none: "", + sm: "shadow-theme-sm", + md: "shadow-theme-lg", + }; + return (
{children} @@ -108,31 +151,34 @@ export const CardAction: React.FC = ({ variant = "button", className = "", }) => { - const baseClasses = - 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) { + if (variant === "button") { return ( - - {children} - +
+ +
); } return ( - + ); }; diff --git a/frontend/src/components/ui/dataview/DataView.tsx b/frontend/src/components/ui/dataview/DataView.tsx new file mode 100644 index 00000000..a5165ac0 --- /dev/null +++ b/frontend/src/components/ui/dataview/DataView.tsx @@ -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 = ({ + children, + className = "", + toolbar, + header, + footer, +}) => ( +
+ {header && ( +
+ {header} +
+ )} + {toolbar && ( +
+ {toolbar} +
+ )} +
{children}
+ {footer && ( +
+ {footer} +
+ )} +
+); + +interface DataViewHeaderProps { + title: string; + description?: string; + actions?: ReactNode; +} + +export const DataViewHeader: React.FC = ({ + title, + description, + actions, +}) => ( +
+
+

{title}

+ {description && ( +

{description}

+ )} +
+ {actions &&
{actions}
} +
+); + +interface DataViewToolbarProps { + children: ReactNode; + className?: string; +} + +export const DataViewToolbar: React.FC = ({ + children, + className = "", +}) => ( +
+ {children} +
+); + +interface DataViewEmptyStateProps { + title: string; + description: string; + action?: ReactNode; +} + +export const DataViewEmptyState: React.FC = ({ + title, + description, + action, +}) => ( +
+

{title}

+

{description}

+ {action} +
+); + diff --git a/frontend/src/components/ui/dataview/index.ts b/frontend/src/components/ui/dataview/index.ts new file mode 100644 index 00000000..d8df1f30 --- /dev/null +++ b/frontend/src/components/ui/dataview/index.ts @@ -0,0 +1,2 @@ +export * from "./DataView"; + diff --git a/frontend/src/index.css b/frontend/src/index.css index 92b081c9..d96cbe89 100644 --- a/frontend/src/index.css +++ b/frontend/src/index.css @@ -1,6 +1,7 @@ @import url("https://fonts.googleapis.com/css2?family=Outfit:wght@100..900&display=swap") layer(base); +@import "./styles/tokens.css"; @import "tailwindcss"; @keyframes slide-in-right { @@ -63,8 +64,8 @@ layer(base); --color-brand-200: #c2d6ff; --color-brand-300: #9cb9ff; --color-brand-400: #7592ff; - --color-brand-500: #0693e3; /* IGNY8 brand blue */ - --color-brand-600: #0472b8; /* IGNY8 brand blue dark */ + --color-brand-500: var(--color-primary); /* Primary brand blue */ + --color-brand-600: var(--color-primary-dark); /* Primary brand blue dark */ --color-brand-700: #2a31d8; --color-brand-800: #252dae; --color-brand-900: #262e89; diff --git a/frontend/src/marketing/components/CTASection.tsx b/frontend/src/marketing/components/CTASection.tsx index a30856ef..5fceb1c1 100644 --- a/frontend/src/marketing/components/CTASection.tsx +++ b/frontend/src/marketing/components/CTASection.tsx @@ -1,4 +1,6 @@ import React from "react"; +import Button from "../../components/ui/button/Button"; +import { Link } from "react-router-dom"; interface CTASectionProps { title: string; description: string; @@ -12,36 +14,53 @@ const CTASection: React.FC = ({ primaryCta, secondaryCta, }) => { - const renderAnchor = (label: string, href: string, className: string) => { + const renderCta = (label: string, href: string, isPrimary: boolean) => { const isExternal = href.startsWith("http"); + const buttonClasses = isPrimary + ? "shadow-lg shadow-[var(--color-primary)]/30" + : ""; if (isExternal) { return ( - {label} - + ); } return ( - + ); }; return (
-
-
-
+
+
+

{title} @@ -50,18 +69,8 @@ const CTASection: React.FC = ({ {description}

- {renderAnchor( - primaryCta.label, - 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" - ) - )} + {renderCta(primaryCta.label, primaryCta.href, true)} + {secondaryCta && renderCta(secondaryCta.label, secondaryCta.href, false)}

diff --git a/frontend/src/marketing/components/FeatureGrid.tsx b/frontend/src/marketing/components/FeatureGrid.tsx index a0099878..73ec8795 100644 --- a/frontend/src/marketing/components/FeatureGrid.tsx +++ b/frontend/src/marketing/components/FeatureGrid.tsx @@ -14,10 +14,10 @@ interface FeatureGridProps { const FeatureGrid: React.FC = ({ features }) => { const iconColors = [ - "from-[var(--igny8-blue)] to-[var(--igny8-blue-dark)]", // Blue - "from-[var(--igny8-green)] to-[var(--igny8-green-dark)]", // Green - "from-[var(--igny8-amber)] to-[var(--igny8-amber-dark)]", // Amber - "from-[var(--igny8-purple)] to-[var(--igny8-purple-dark)]", // Purple + "from-[var(--color-primary)] to-[var(--color-primary-dark)]", // Blue + "from-[var(--color-success)] to-[var(--color-success-dark)]", // Green + "from-[var(--color-warning)] to-[var(--color-warning-dark)]", // Amber + "from-[var(--color-purple)] to-[var(--color-purple-dark)]", // Purple ]; return ( diff --git a/frontend/src/marketing/components/HeroSection.tsx b/frontend/src/marketing/components/HeroSection.tsx index f9bc1e83..6a429027 100644 --- a/frontend/src/marketing/components/HeroSection.tsx +++ b/frontend/src/marketing/components/HeroSection.tsx @@ -1,5 +1,7 @@ import React from "react"; import { Link } from "react-router-dom"; +import Button from "../../components/ui/button/Button"; +import Badge from "../../components/ui/badge/Badge"; interface HeroSectionProps { image: string; @@ -16,38 +18,59 @@ const HeroSection: React.FC = ({ primaryCta, 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 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) { return ( - {cta.label} - + ); } return ( - + ); }; return (
-
+
- + AI + SEO PLATFORM - +

{headline}

@@ -55,26 +78,20 @@ const HeroSection: React.FC = ({ {subheadline}

- {renderCta( - primaryCta, - "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" - )} + {renderCta(primaryCta, true)} + {secondaryCta && renderCta(secondaryCta, false)}
-
-
+
+
Igny8 dashboard preview -
- +
+ End-to-end automation diff --git a/frontend/src/marketing/components/MetricsBar.tsx b/frontend/src/marketing/components/MetricsBar.tsx index a975a0f1..d7429938 100644 --- a/frontend/src/marketing/components/MetricsBar.tsx +++ b/frontend/src/marketing/components/MetricsBar.tsx @@ -11,9 +11,9 @@ interface MetricsBarProps { const MetricsBar: React.FC = ({ metrics }) => { const accentColors = [ - "from-[var(--igny8-blue)] to-[var(--igny8-blue-dark)]", - "from-[var(--igny8-green)] to-[var(--igny8-green-dark)]", - "from-[var(--igny8-amber)] to-[var(--igny8-amber-dark)]", + "from-[var(--color-primary)] to-[var(--color-primary-dark)]", + "from-[var(--color-success)] to-[var(--color-success-dark)]", + "from-[var(--color-warning)] to-[var(--color-warning-dark)]", ]; return ( diff --git a/frontend/src/marketing/components/WorkflowSteps.tsx b/frontend/src/marketing/components/WorkflowSteps.tsx index 15bf9228..cbd33365 100644 --- a/frontend/src/marketing/components/WorkflowSteps.tsx +++ b/frontend/src/marketing/components/WorkflowSteps.tsx @@ -11,10 +11,10 @@ interface WorkflowStepsProps { const WorkflowSteps: React.FC = ({ steps }) => { const stepColors = [ - "from-[var(--igny8-blue)] to-[var(--igny8-blue-dark)]", - "from-[var(--igny8-green)] to-[var(--igny8-green-dark)]", - "from-[var(--igny8-amber)] to-[var(--igny8-amber-dark)]", - "from-[var(--igny8-purple)] to-[var(--igny8-purple-dark)]", + "from-[var(--color-primary)] to-[var(--color-primary-dark)]", + "from-[var(--color-success)] to-[var(--color-success-dark)]", + "from-[var(--color-warning)] to-[var(--color-warning-dark)]", + "from-[var(--color-purple)] to-[var(--color-purple-dark)]", ]; return ( @@ -25,12 +25,12 @@ const WorkflowSteps: React.FC = ({ steps }) => { return (
{index + 1}
-

+

{step.title}

diff --git a/frontend/src/marketing/layout/MarketingLayout.tsx b/frontend/src/marketing/layout/MarketingLayout.tsx index e55b8bd7..d6e10482 100644 --- a/frontend/src/marketing/layout/MarketingLayout.tsx +++ b/frontend/src/marketing/layout/MarketingLayout.tsx @@ -19,7 +19,7 @@ const MarketingLayout: React.FC = ({ children }) => {

- + IG
@@ -37,7 +37,7 @@ const MarketingLayout: React.FC = ({ children }) => { {link.name} @@ -54,7 +54,7 @@ const MarketingLayout: React.FC = ({ children }) => { Start Free @@ -93,7 +93,7 @@ const MarketingLayout: React.FC = ({ children }) => { Start Free @@ -109,7 +109,7 @@ const MarketingLayout: React.FC = ({ children }) => {
- + IG
@@ -137,7 +137,7 @@ const MarketingLayout: React.FC = ({ children }) => {
    {group.links.map((link) => (
  • - + {link.name}
  • @@ -146,7 +146,7 @@ const MarketingLayout: React.FC = ({ children }) => {
))}
-
+
Built for marketers who automate growth with AI.
diff --git a/frontend/src/marketing/pages/CaseStudies.tsx b/frontend/src/marketing/pages/CaseStudies.tsx index 80862a66..96178059 100644 --- a/frontend/src/marketing/pages/CaseStudies.tsx +++ b/frontend/src/marketing/pages/CaseStudies.tsx @@ -43,7 +43,7 @@ const CaseStudies: React.FC = () => { 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.", 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", @@ -56,7 +56,7 @@ const CaseStudies: React.FC = () => { 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.", 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", @@ -69,7 +69,7 @@ const CaseStudies: React.FC = () => { 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.", 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 = () => {
{caseStudies.map((cs, idx) => { 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-[#ff7a00]" }, ]; @@ -154,7 +154,7 @@ const CaseStudies: React.FC = () => {
-
+

@@ -176,7 +176,7 @@ const CaseStudies: React.FC = () => {

-
+

@@ -186,7 +186,7 @@ const CaseStudies: React.FC = () => {

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.

- @@ -216,7 +216,7 @@ const CaseStudies: React.FC = () => { Download case study pack diff --git a/frontend/src/marketing/pages/Contact.tsx b/frontend/src/marketing/pages/Contact.tsx index 8630b2d8..880f3946 100644 --- a/frontend/src/marketing/pages/Contact.tsx +++ b/frontend/src/marketing/pages/Contact.tsx @@ -14,14 +14,14 @@ const Contact: React.FC = () => {

-
+
@@ -39,7 +39,7 @@ const Contact: React.FC = () => { @@ -48,7 +48,7 @@ const Contact: React.FC = () => { @@ -57,7 +57,7 @@ const Contact: React.FC = () => {