diff --git a/frontend/src/App.jsx b/frontend/src/App.jsx index 81af689e8..04b454c25 100644 --- a/frontend/src/App.jsx +++ b/frontend/src/App.jsx @@ -108,7 +108,7 @@ const ResumeRoastLanding = lazy(() => import('./pages/features/ResumeRoastLandin const GithubPortfolioLanding = lazy(() => import('./pages/features/GithubPortfolioLanding')); const ProjectVisualizerLanding = lazy(() => import('./pages/features/ProjectVisualizerLanding')); const JobFinderLanding = lazy(() => import('./pages/features/JobFinderLanding')); -const MockInterviewLanding = lazy(() => import('./pages/features/MockInterviewLanding')); +const MockInterviewLanding = lazy(() => import('./pages/features/MockInterviewForge')); const RecruitersLanding = lazy(() => import('./pages/features/RecruitersLanding')); import ScrollToTop from "./components/ScrollToTop"; diff --git a/frontend/src/components/forge/BentoCard.jsx b/frontend/src/components/forge/BentoCard.jsx new file mode 100644 index 000000000..d1ec7121d --- /dev/null +++ b/frontend/src/components/forge/BentoCard.jsx @@ -0,0 +1,23 @@ +import React from 'react'; + +/** + * Hover-glow bento card. Tracks cursor for the radial glow (forge signature). + */ +export default function BentoCard({ icon: Icon, title, description, className = '' }) { + const onMove = (e) => { + const r = e.currentTarget.getBoundingClientRect(); + e.currentTarget.style.setProperty('--mx', `${e.clientX - r.left}px`); + e.currentTarget.style.setProperty('--my', `${e.clientY - r.top}px`); + }; + return ( +
+ {Icon && ( +
+ +
+ )} +

{title}

+

{description}

+
+ ); +} diff --git a/frontend/src/components/forge/ForgeButton.jsx b/frontend/src/components/forge/ForgeButton.jsx new file mode 100644 index 000000000..d436624fb --- /dev/null +++ b/frontend/src/components/forge/ForgeButton.jsx @@ -0,0 +1,9 @@ +import React from 'react'; +import { Link } from 'react-router-dom'; + +/** Forge button — renders as router Link or anchor. */ +export default function ForgeButton({ to, href, children, variant = 'primary', ...rest }) { + const cls = `forge-btn ${variant === 'primary' ? 'forge-btn-primary' : 'forge-btn-ghost'}`; + if (to) return {children}; + return {children}; +} diff --git a/frontend/src/components/forge/ForgeFeaturePage.jsx b/frontend/src/components/forge/ForgeFeaturePage.jsx new file mode 100644 index 000000000..6d2c49ba9 --- /dev/null +++ b/frontend/src/components/forge/ForgeFeaturePage.jsx @@ -0,0 +1,166 @@ +import React from 'react'; +import { Link } from 'react-router-dom'; +import { useAuth } from '../../hooks/useAuth'; +import { FEATURES_BY_SLUG } from '../../data/featuresConfig'; +import Seo from '../../components/Seo'; +import '../styles/forge.css'; +import StatusBadge from './forge/StatusBadge'; +import MetricChip from './forge/MetricChip'; +import ForgeButton from './forge/ForgeButton'; +import BentoCard from './forge/BentoCard'; + +const ICONS = { + FileText: 'M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z M14 2v6h6', + Type: 'M4 7V4h16v3 M9 20h6 M12 4v16', + Github: 'M9 19c-5 1.5-5-2.5-7-3m14 6v-3.87a3.37 3.37 0 0 0-.94-2.61c3.14-.35 6.44-1.54 6.44-7A5.44 5.44 0 0 0 20 4.77 5.07 5.07 0 0 0 19.91 1S18.73.65 16 2.48a13.38 13.38 0 0 0-7 0C6.27.65 5.09 1 5.09 1A5.07 5.07 0 0 0 5 4.77a5.44 5.44 0 0 0-1.5 3.78c0 5.42 3.3 6.61 6.44 7A3.37 3.37 0 0 0 9 18.13V22', + Sparkles: 'M12 3v3 M12 18v3 M3 12h3 M18 12h3 M5.6 5.6l2.1 2.1 M16.3 16.3l2.1 2.1 M18.4 5.6l-2.1 2.1 M7.7 16.3l-2.1 2.1', + BarChart: 'M3 3v18h18 M8 17V9 M13 17V5 M18 17v-6', + Layout: 'M3 3h18v18H3z M3 9h18 M9 21V9', + Linkedin: 'M4 4a2 2 0 1 0 0 4 2 2 0 0 0 0-4z M4 9h4v11H4z M10 9h4v3a4 4 0 0 1 8 0v8h-4v-7a2 2 0 0 0-4 0v7h-4z', + Download: 'M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4 M7 10l5 5 5-5 M12 15V3', + Mic: 'M12 1a3 3 0 0 0-3 3v8a3 3 0 0 0 6 0V4a3 3 0 0 0-3-3z M19 10v2a7 7 0 0 1-14 0v-2 M12 19v4 M8 23h8', + Briefcase: 'M2 7h20v13H2z M16 21V5a2 2 0 0 0-2-2h-4a2 2 0 0 0-2 2v16', + Flame: 'M12 2s4 4 4 8a4 4 0 0 1-8 0c0-1 .5-2 1-3-2 1-4 3-4 6a7 7 0 0 0 14 0c0-5-7-11-7-11z', + Network: 'M12 2a3 3 0 1 0 0 6 3 3 0 0 0 0-6z M5 16a3 3 0 1 0 0 6 3 3 0 0 0 0-6z M19 16a3 3 0 1 0 0 6 3 3 0 0 0 0-6z M7 18l3-7 M17 18l-3-7 M8 19h8', + Users: 'M17 21v-2a4 4 0 0 0-4-4H5a4 4 0 0 0-4 4v2 M9 11a4 4 0 1 0 0-8 4 4 0 0 0 0 8z M23 21v-2a4 4 0 0 0-3-3.87 M16 3.13a4 4 0 0 1 0 7.75', + Palette: 'M12 2a9 9 0 0 0 0 18c1.1 0 2-.9 2-2 0-.5-.2-1-.5-1.3-.3-.4-.5-.8-.5-1.2 0-1 .8-1.8 1.8-1.8H17a4 4 0 0 0 4-4c0-4.4-4-8-9-8z M7.5 11.5A1 1 0 1 0 7 13a1 1 0 0 0 .5-1.5z M12 7.5A1 1 0 1 0 12.5 9 1 1 0 0 0 12 7.5z', + Zap: 'M13 2L3 14h9l-1 8 10-12h-9z', + Smartphone: 'M7 2h10a2 2 0 0 1 2 2v16a2 2 0 0 1-2 2H7a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2z M12 18h.01', + Globe: 'M12 2a10 10 0 1 0 0 20 10 10 0 0 0 0-20z M2 12h20 M12 2a15 15 0 0 1 0 20 M12 2a15 15 0 0 0 0 20', +}; + +function Icon({ name, size = 22, strokeWidth = 1.8 }) { + const d = ICONS[name]; + if (!d) return null; + return ( + + ); +} + +/** + * ForgeFeaturePage — data-driven landing for a single feature route. + * Reads the existing FEATURES_BY_SLUG[slug] config and renders a cohesive, + * forge-ai-inspired page (status chips, monospace metrics, bento showcase, steps). + * Each route landing imports this with its slug. + */ +export default function ForgeFeaturePage({ slug }) { + const { user } = useAuth(); + const config = FEATURES_BY_SLUG[slug]; + if (!config) return
Unknown feature: {slug}
; + + const heroCtaText = user ? config.primaryAction.label : config.hero.primaryCta.text; + const heroCtaLink = user ? config.primaryAction.to : config.hero.primaryCta.to; + const ctaText = user ? config.primaryAction.label : config.cta.ctaText; + const ctaLink = user ? config.primaryAction.to : config.cta.ctaTo; + + return ( +
+ + + + + {/* HERO */} +
+ +

+ {config.hero.title} {config.hero.accentText} +

+

{config.hero.description}

+
+ {heroCtaText} + {config.hero.secondaryCta && ( + {config.hero.secondaryCta.text} + )} +
+
+ {config.hero.stats.map((s, i) => ( + + ))} +
+
+ + {/* SHOWCASE */} + {config.showcase && ( +
+
+ Capabilities +

{config.showcase.heading}

+
+
+ {config.showcase.features.map((f, i) => ( + } title={f.title} description={f.description} /> + ))} +
+
+ )} + + {/* HOW IT WORKS */} + {config.howItWorks && ( +
+
+ Workflow +

{config.howItWorks.title}

+
+
+ {config.howItWorks.steps.map((s, i) => ( +
+ STEP {s.number} +

{s.title}

+

{s.description}

+
+ ))} +
+
+ )} + + {/* TESTIMONIALS */} + {config.testimonials && config.testimonials.items?.length > 0 && ( +
+
+ Signal +

{config.testimonials.heading}

+
+ {config.testimonials.items.map((t, i) => ( +
+

“{t.quote}”

+
+ {t.avatar && } + {t.name} · {t.role}{t.company ? ` @ ${t.company}` : ''} + {t.metric} +
+
+ ))} +
+ )} + + {/* CTA */} +
+
+

{config.cta.headline}

+

{config.cta.subtext}

+ {ctaText} +
+
+ + +
+ ); +} diff --git a/frontend/src/components/forge/MetricChip.jsx b/frontend/src/components/forge/MetricChip.jsx new file mode 100644 index 000000000..fdbc9dd77 --- /dev/null +++ b/frontend/src/components/forge/MetricChip.jsx @@ -0,0 +1,11 @@ +import React from 'react'; + +/** Monospace metric chip used in hero stat rows. */ +export default function MetricChip({ value, label, accent = false }) { + return ( +
+
{value}
+
{label}
+
+ ); +} diff --git a/frontend/src/components/forge/StatusBadge.jsx b/frontend/src/components/forge/StatusBadge.jsx new file mode 100644 index 000000000..54112f07a --- /dev/null +++ b/frontend/src/components/forge/StatusBadge.jsx @@ -0,0 +1,15 @@ +import React from 'react'; + +/** + * Forge signature status chip — operational/SLA style pill. + * variant: 'ok' | 'warn' | 'danger' + */ +export default function StatusBadge({ label = 'OPERATIONAL', variant = 'ok', className = '' }) { + const v = variant === 'danger' ? 'danger' : variant === 'warn' ? 'warn' : 'ok'; + return ( + + + {label} + + ); +} diff --git a/frontend/src/components/landing/ForgeToolsSection.jsx b/frontend/src/components/landing/ForgeToolsSection.jsx new file mode 100644 index 000000000..b6145405b --- /dev/null +++ b/frontend/src/components/landing/ForgeToolsSection.jsx @@ -0,0 +1,80 @@ +import React from 'react'; +import { motion } from 'framer-motion'; +import { FEATURES } from '../../data/featuresConfig'; +import '../styles/forge.css'; +import StatusBadge from '../forge/StatusBadge'; +import ForgeButton from '../forge/ForgeButton'; + +const ICON_PATHS = { + FileText: 'M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z M14 2v6h6', + Palette: 'M12 2a9 9 0 0 0 0 18c1.1 0 2-.9 2-2 0-.5-.2-1-.5-1.3-.3-.4-.5-.8-.5-1.2 0-1 .8-1.8 1.8-1.8H17a4 4 0 0 0 4-4c0-4.4-4-8-9-8z M7.5 11.5A1 1 0 1 0 7 13a1 1 0 0 0 .5-1.5z M12 7.5A1 1 0 1 0 12.5 9 1 1 0 0 0 12 7.5z', + Flame: 'M12 2s4 4 4 8a4 4 0 0 1-8 0c0-1 .5-2 1-3-2 1-4 3-4 6a7 7 0 0 0 14 0c0-5-7-11-7-11z', + Github: 'M9 19c-5 1.5-5-2.5-7-3m14 6v-3.87a3.37 3.37 0 0 0-.94-2.61c3.14-.35 6.44-1.54 6.44-7A5.44 5.44 0 0 0 20 4.77 5.07 5.07 0 0 0 19.91 1S18.73.65 16 2.48a13.38 13.38 0 0 0-7 0C6.27.65 5.09 1 5.09 1A5.07 5.07 0 0 0 5 4.77a5.44 5.44 0 0 0-1.5 3.78c0 5.42 3.3 6.61 6.44 7A3.37 3.37 0 0 0 9 18.13V22', + Network: 'M12 2a3 3 0 1 0 0 6 3 3 0 0 0 0-6z M5 16a3 3 0 1 0 0 6 3 3 0 0 0 0-6z M19 16a3 3 0 1 0 0 6 3 3 0 0 0 0-6z M7 18l3-7 M17 18l-3-7 M8 19h8', + Mic: 'M12 1a3 3 0 0 0-3 3v8a3 3 0 0 0 6 0V4a3 3 0 0 0-3-3z M19 10v2a7 7 0 0 1-14 0v-2 M12 19v4 M8 23h8', + Users: 'M17 21v-2a4 4 0 0 0-4-4H5a4 4 0 0 0-4 4v2 M9 11a4 4 0 1 0 0-8 4 4 0 0 0 0 8z M23 21v-2a4 4 0 0 0-3-3.87 M16 3.13a4 4 0 0 1 0 7.75', + Briefcase: 'M2 7h20v13H2z M16 21V5a2 2 0 0 0-2-2h-4a2 2 0 0 0-2 2v16', +}; + +const header = { hidden: {}, show: { transition: { staggerChildren: 0.12 } } }; +const item = { + hidden: { opacity: 0, y: 24 }, + show: { opacity: 1, y: 0, transition: { duration: 0.6, ease: [0.16, 1, 0.3, 1] } }, +}; + +export default function ForgeToolsSection() { + return ( +
+
+ + + + + + Powerful AI tools for every step + + + From your first resume draft to your final interview, CareerPilot gives you the unfair advantage you need. + + + +
+ {FEATURES.map((f, i) => { + const Icon = (p) => ( + + {(ICON_PATHS[f.icon?.name] || ICON_PATHS.FileText).split(' M').map((seg, k) => ( + + ))} + + ); + const large = f.size === 'large'; + return ( + +
+
+ {f.badge || 'Tool'} +

{f.name}

+

{f.tagline}

+
+
+ {f.primaryAction.label} → +
+
+ ); + })} +
+
+
+ ); +} diff --git a/frontend/src/pages/features/GithubPortfolioForge.jsx b/frontend/src/pages/features/GithubPortfolioForge.jsx new file mode 100644 index 000000000..dc0876c8e --- /dev/null +++ b/frontend/src/pages/features/GithubPortfolioForge.jsx @@ -0,0 +1,5 @@ +import React from 'react'; +import ForgeFeaturePage from '../../components/forge/ForgeFeaturePage'; +export default function GithubPortfolioForge() { + return ; +} diff --git a/frontend/src/pages/features/MockInterviewForge.jsx b/frontend/src/pages/features/MockInterviewForge.jsx new file mode 100644 index 000000000..ae70d4120 --- /dev/null +++ b/frontend/src/pages/features/MockInterviewForge.jsx @@ -0,0 +1,5 @@ +import React from 'react'; +import ForgeFeaturePage from '../../components/forge/ForgeFeaturePage'; +export default function MockInterviewForge() { + return ; +} diff --git a/frontend/src/pages/features/ProjectVisualizerForge.jsx b/frontend/src/pages/features/ProjectVisualizerForge.jsx new file mode 100644 index 000000000..0ad14dfe7 --- /dev/null +++ b/frontend/src/pages/features/ProjectVisualizerForge.jsx @@ -0,0 +1,5 @@ +import React from 'react'; +import ForgeFeaturePage from '../../components/forge/ForgeFeaturePage'; +export default function ProjectVisualizerForge() { + return ; +} diff --git a/frontend/src/pages/features/ResumeBuilderForge.jsx b/frontend/src/pages/features/ResumeBuilderForge.jsx new file mode 100644 index 000000000..431a0d53a --- /dev/null +++ b/frontend/src/pages/features/ResumeBuilderForge.jsx @@ -0,0 +1,5 @@ +import React from 'react'; +import ForgeFeaturePage from '../../components/forge/ForgeFeaturePage'; +export default function ResumeBuilderForge() { + return ; +} diff --git a/frontend/src/pages/features/ResumeRoastForge.jsx b/frontend/src/pages/features/ResumeRoastForge.jsx new file mode 100644 index 000000000..b02a39eaa --- /dev/null +++ b/frontend/src/pages/features/ResumeRoastForge.jsx @@ -0,0 +1,5 @@ +import React from 'react'; +import ForgeFeaturePage from '../../components/forge/ForgeFeaturePage'; +export default function ResumeRoastForge() { + return ; +} diff --git a/frontend/src/styles/forge.css b/frontend/src/styles/forge.css new file mode 100644 index 000000000..2254d4ff1 --- /dev/null +++ b/frontend/src/styles/forge.css @@ -0,0 +1,203 @@ +/* ============================================================ + FORGE DESIGN SYSTEM — forge-ai inspired UI/UX layer + Dark · technical · operational-status chips · monospace metrics + Used by ForgeFeaturePage + OurToolsSection redesign. + ============================================================ */ + +:root { + --forge-bg: #07090d; + --forge-bg-2: #0b0f15; + --forge-panel: rgba(20, 26, 36, 0.72); + --forge-panel-solid: #121823; + --forge-border: rgba(120, 140, 170, 0.16); + --forge-border-strong: rgba(120, 140, 170, 0.32); + --forge-text: #e8edf4; + --forge-muted: #8a98ad; + --forge-faint: #5a6679; + --forge-accent: #3ef2a1; /* neon operational green */ + --forge-accent-2: #5ac8fa; /* signal cyan */ + --forge-accent-3: #b388ff; /* violet */ + --forge-danger: #ff6b6b; + --forge-mono: 'JetBrains Mono', 'SF Mono', 'Fira Code', ui-monospace, SFMono-Regular, Menlo, monospace; + --forge-sans: 'Inter', system-ui, -apple-system, 'Segoe UI', Roboto, sans-serif; + --forge-radius: 16px; + --forge-radius-sm: 10px; + --forge-glow: 0 0 0 1px var(--forge-border), 0 18px 50px -20px rgba(62, 242, 161, 0.25); +} + +/* ---- page shell ---- */ +.forge-page { + font-family: var(--forge-sans); + background: + radial-gradient(900px 480px at 50% -8%, rgba(62, 242, 161, 0.10), transparent 60%), + radial-gradient(700px 400px at 88% 10%, rgba(90, 200, 250, 0.08), transparent 60%), + var(--forge-bg); + color: var(--forge-text); + min-height: 100vh; + -webkit-font-smoothing: antialiased; +} +.forge-container { max-width: 1180px; margin: 0 auto; padding: 0 24px; } +.forge-section { padding: 84px 0; position: relative; } + +/* ---- nav ---- */ +.forge-nav { + position: sticky; top: 0; z-index: 50; + display: flex; align-items: center; justify-content: space-between; + padding: 16px 24px; + border-bottom: 1px solid var(--forge-border); + background: rgba(7, 9, 13, 0.72); + backdrop-filter: blur(14px); +} +.forge-brand { font-weight: 800; letter-spacing: -0.02em; font-size: 18px; color: var(--forge-text); } +.forge-brand .dot { color: var(--forge-accent); } +.forge-nav-links { display: flex; gap: 22px; } +.forge-nav-link { color: var(--forge-muted); font-size: 14px; text-decoration: none; transition: color .2s; } +.forge-nav-link:hover { color: var(--forge-text); } +.forge-nav-actions { display: flex; gap: 12px; align-items: center; } + +/* ---- status chip (forge signature) ---- */ +.forge-status { + display: inline-flex; align-items: center; gap: 8px; + font-family: var(--forge-mono); font-size: 12px; letter-spacing: 0.02em; + padding: 6px 12px; border-radius: 999px; + border: 1px solid var(--forge-border); background: var(--forge-panel); + color: var(--forge-muted); text-transform: uppercase; +} +.forge-status .pulse { + width: 7px; height: 7px; border-radius: 50%; background: var(--forge-accent); + box-shadow: 0 0 10px var(--forge-accent); animation: forgePulse 1.8s infinite; +} +.forge-status.warn .pulse { background: #ffcf5a; box-shadow: 0 0 10px #ffcf5a; } +.forge-status.danger .pulse { background: var(--forge-danger); box-shadow: 0 0 10px var(--forge-danger); } +@keyframes forgePulse { + 0%, 100% { opacity: 1; transform: scale(1); } + 50% { opacity: 0.35; transform: scale(0.7); } +} + +/* ---- buttons ---- */ +.forge-btn { + display: inline-flex; align-items: center; gap: 8px; + font-weight: 600; font-size: 14px; text-decoration: none; cursor: pointer; + padding: 12px 20px; border-radius: var(--forge-radius-sm); + border: 1px solid var(--forge-border-strong); transition: transform .15s, box-shadow .2s, background .2s; +} +.forge-btn-primary { + background: linear-gradient(180deg, var(--forge-accent), #25c986); + color: #04140d; border-color: transparent; + box-shadow: 0 10px 30px -12px rgba(62, 242, 161, 0.7); +} +.forge-btn-primary:hover { transform: translateY(-2px); box-shadow: 0 16px 38px -12px rgba(62, 242, 161, 0.85); } +.forge-btn-ghost { background: var(--forge-panel); color: var(--forge-text); } +.forge-btn-ghost:hover { border-color: var(--forge-accent); color: var(--forge-accent); } + +/* ---- hero ---- */ +.forge-hero { text-align: center; padding: 96px 0 64px; } +.forge-hero h1 { + font-size: clamp(34px, 6vw, 68px); line-height: 1.02; font-weight: 800; + letter-spacing: -0.03em; margin: 22px auto 0; max-width: 16ch; +} +.forge-hero .accent { color: var(--forge-accent); } +.forge-hero p { + color: var(--forge-muted); font-size: clamp(16px, 2vw, 20px); + max-width: 60ch; margin: 22px auto 0; line-height: 1.55; +} +.forge-hero-actions { display: flex; gap: 14px; justify-content: center; margin-top: 34px; flex-wrap: wrap; } + +/* ---- metrics row ---- */ +.forge-metrics { display: flex; gap: 14px; justify-content: center; flex-wrap: wrap; margin-top: 48px; } +.forge-metric { + font-family: var(--forge-mono); text-align: center; + border: 1px solid var(--forge-border); background: var(--forge-panel); + padding: 16px 22px; border-radius: var(--forge-radius-sm); min-width: 120px; +} +.forge-metric .v { font-size: 26px; font-weight: 700; color: var(--forge-text); } +.forge-metric .v.accent { color: var(--forge-accent); } +.forge-metric .l { font-size: 11px; color: var(--forge-faint); text-transform: uppercase; letter-spacing: 0.08em; margin-top: 4px; } + +/* ---- section label ---- */ +.forge-label { + display: inline-flex; align-items: center; gap: 8px; + font-family: var(--forge-mono); font-size: 12px; letter-spacing: 0.12em; + text-transform: uppercase; color: var(--forge-accent); + border: 1px solid var(--forge-border); padding: 6px 12px; border-radius: 999px; + background: rgba(62, 242, 161, 0.06); +} +.forge-h2 { font-size: clamp(26px, 4vw, 42px); font-weight: 800; letter-spacing: -0.02em; margin: 18px 0 10px; } +.forge-sub { color: var(--forge-muted); max-width: 60ch; margin: 0 auto; } + +/* ---- bento grid ---- */ +.forge-bento { display: grid; grid-template-columns: repeat(auto-fit, minmax(260px, 1fr)); gap: 16px; margin-top: 40px; } +.forge-card { + position: relative; border: 1px solid var(--forge-border); border-radius: var(--forge-radius); + background: var(--forge-panel); padding: 24px; overflow: hidden; + transition: transform .2s, border-color .2s, box-shadow .2s; +} +.forge-card::before { + content: ''; position: absolute; inset: 0; border-radius: inherit; + background: radial-gradient(400px 200px at var(--mx, 50%) var(--my, 0%), rgba(62, 242, 161, 0.10), transparent 60%); + opacity: 0; transition: opacity .25s; pointer-events: none; +} +.forge-card:hover { transform: translateY(-4px); border-color: var(--forge-border-strong); box-shadow: var(--forge-glow); } +.forge-card:hover::before { opacity: 1; } +.forge-card .ico { + width: 42px; height: 42px; border-radius: 12px; display: grid; place-items: center; + background: rgba(62, 242, 161, 0.10); color: var(--forge-accent); margin-bottom: 16px; +} +.forge-card h3 { font-size: 17px; font-weight: 700; margin: 0 0 6px; } +.forge-card p { color: var(--forge-muted); font-size: 14px; line-height: 1.5; margin: 0; } + +/* ---- steps ---- */ +.forge-steps { display: grid; grid-template-columns: repeat(auto-fit, minmax(220px, 1fr)); gap: 16px; margin-top: 40px; } +.forge-step { border: 1px solid var(--forge-border); background: var(--forge-panel); border-radius: var(--forge-radius); padding: 22px; } +.forge-step .n { + font-family: var(--forge-mono); font-size: 13px; color: var(--forge-accent); + border: 1px solid var(--forge-border); border-radius: 8px; padding: 4px 10px; display: inline-block; margin-bottom: 14px; +} +.forge-step h4 { margin: 0 0 6px; font-size: 16px; } +.forge-step p { margin: 0; color: var(--forge-muted); font-size: 14px; line-height: 1.5; } + +/* ---- testimonials ---- */ +.forge-quote { + border: 1px solid var(--forge-border); background: var(--forge-panel); border-radius: var(--forge-radius); + padding: 26px; max-width: 720px; margin: 28px auto 0; +} +.forge-quote .q { font-size: 18px; line-height: 1.6; } +.forge-quote .who { display: flex; align-items: center; gap: 12px; margin-top: 18px; color: var(--forge-muted); font-size: 14px; } +.forge-quote .metric { color: var(--forge-accent); font-family: var(--forge-mono); } + +/* ---- CTA ---- */ +.forge-cta { + text-align: center; border: 1px solid var(--forge-border-strong); border-radius: 24px; + background: linear-gradient(180deg, rgba(62, 242, 161, 0.06), transparent); + padding: 64px 24px; margin: 40px auto; +} +.forge-cta h2 { font-size: clamp(26px, 4vw, 40px); font-weight: 800; letter-spacing: -0.02em; margin: 0 0 10px; } +.forge-cta p { color: var(--forge-muted); margin: 0 0 28px; } + +/* ---- footer ---- */ +.forge-foot { border-top: 1px solid var(--forge-border); padding: 28px 0; text-align: center; color: var(--forge-faint); font-size: 13px; font-family: var(--forge-mono); } + +/* ---- landing "Powerful AI tools" forge variant ---- */ +.forge-tools-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(280px, 1fr)); gap: 18px; } +.forge-tool { + position: relative; border: 1px solid var(--forge-border); border-radius: var(--forge-radius); + background: var(--forge-panel); padding: 26px; overflow: hidden; + transition: transform .2s, border-color .2s, box-shadow .2s; +} +.forge-tool:hover { transform: translateY(-4px); border-color: var(--forge-border-strong); box-shadow: var(--forge-glow); } +.forge-tool.lg { grid-column: span 2; } +.forge-tool .badge-tag { + font-family: var(--forge-mono); font-size: 11px; text-transform: uppercase; letter-spacing: 0.1em; + color: var(--forge-accent); border: 1px solid var(--forge-border); border-radius: 999px; padding: 4px 10px; +} +.forge-tool h3 { font-size: 20px; font-weight: 700; margin: 16px 0 8px; } +.forge-tool p { color: var(--forge-muted); font-size: 14px; line-height: 1.55; margin: 0; } +.forge-tool .ico { + width: 46px; height: 46px; border-radius: 12px; display: grid; place-items: center; + background: rgba(62, 242, 161, 0.10); color: var(--forge-accent); margin-bottom: 12px; +} + +@media (max-width: 720px) { + .forge-tool.lg { grid-column: span 1; } + .forge-nav-links { display: none; } +}