Compare commits
2 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| aec905aebf | |||
| ec5ee9d7b1 |
+13
-13
@@ -313,18 +313,18 @@
|
||||
<script src="https://unpkg.com/react-dom@18.3.1/umd/react-dom.development.js" integrity="sha384-u6aeetuaXnQ38mYT8rp6sbXaQe3NL9t+IBXmnYxwkUI2Hw4bsp2Wvmx4yRQF1uAm" crossorigin="anonymous"></script>
|
||||
<script src="https://unpkg.com/@babel/standalone@7.29.0/babel.min.js" integrity="sha384-m08KidiNqLdpJqLq95G/LEi8Qvjl/xUYll3QILypMoQ65QorJ9Lvtp2RXYGBFj1y" crossorigin="anonymous"></script>
|
||||
|
||||
<script type="text/babel" src="tweaks-panel.jsx?v=5"></script>
|
||||
<script type="text/babel" src="src/icons.jsx?v=5"></script>
|
||||
<script type="text/babel" src="src/data.jsx?v=5"></script>
|
||||
<script type="text/babel" src="src/nav.jsx?v=5"></script>
|
||||
<script type="text/babel" src="src/hero.jsx?v=5"></script>
|
||||
<script type="text/babel" src="src/sections.jsx?v=5"></script>
|
||||
<script type="text/babel" src="src/projects.jsx?v=5"></script>
|
||||
<script type="text/babel" src="src/agent-showcase.jsx?v=5"></script>
|
||||
<script type="text/babel" src="src/timeline-contact.jsx?v=5"></script>
|
||||
<script type="text/babel" src="src/command-palette.jsx?v=5"></script>
|
||||
<script type="text/babel" src="src/chatbox.jsx?v=5"></script>
|
||||
<script type="text/babel" src="src/pages.jsx?v=5"></script>
|
||||
<script type="text/babel" src="src/app.jsx?v=5"></script>
|
||||
<script type="text/babel" src="tweaks-panel.jsx?v=6"></script>
|
||||
<script type="text/babel" src="src/icons.jsx?v=6"></script>
|
||||
<script type="text/babel" src="src/data.jsx?v=6"></script>
|
||||
<script type="text/babel" src="src/nav.jsx?v=6"></script>
|
||||
<script type="text/babel" src="src/hero.jsx?v=6"></script>
|
||||
<script type="text/babel" src="src/sections.jsx?v=6"></script>
|
||||
<script type="text/babel" src="src/projects.jsx?v=6"></script>
|
||||
<script type="text/babel" src="src/agent-showcase.jsx?v=6"></script>
|
||||
<script type="text/babel" src="src/timeline-contact.jsx?v=6"></script>
|
||||
<script type="text/babel" src="src/command-palette.jsx?v=6"></script>
|
||||
<script type="text/babel" src="src/chatbox.jsx?v=6"></script>
|
||||
<script type="text/babel" src="src/pages.jsx?v=6"></script>
|
||||
<script type="text/babel" src="src/app.jsx?v=6"></script>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
@@ -103,6 +103,10 @@ function App() {
|
||||
title: `Contact — ${BASE}`,
|
||||
desc: 'Get a quote for AI agents, automation, web development, Web3, or MT5 trading systems. Based in Dhaka, Bangladesh. Response within 24 hours.',
|
||||
},
|
||||
'case-studies': {
|
||||
title: `Case Studies — ${BASE}`,
|
||||
desc: 'Real-world AI agent, MT5 trading, Meta Ads, and Web3 projects with production metrics. See what Aura actually ships for clients.',
|
||||
},
|
||||
pricing: {
|
||||
title: `Pricing — ${BASE}`,
|
||||
desc: 'Transparent pricing for AI agents, automation, and full-stack development. Starter, Growth, and Enterprise tiers. Fixed scope, no surprises.',
|
||||
@@ -174,6 +178,8 @@ function App() {
|
||||
return <T.PricingPage />;
|
||||
case 'blog':
|
||||
return <T.BlogPage />;
|
||||
case 'case-studies':
|
||||
return <T.CaseStudiesPage />;
|
||||
default:
|
||||
return (
|
||||
<main style={density === "compact" ? { fontSize: 14.5 } : undefined}>
|
||||
|
||||
+144
@@ -164,6 +164,27 @@ const PORTFOLIO_DATA = {
|
||||
"Full Meta API access via official MCP integration",
|
||||
],
|
||||
},
|
||||
{
|
||||
id: "courier-mcp",
|
||||
name: "Aura Courier MCP",
|
||||
nameBn: "অরা কুরিয়ার MCP",
|
||||
kind: "Connector · Live",
|
||||
badge: "LIVE · MCP Connector",
|
||||
description:
|
||||
"One Model Context Protocol connector for every Bangladesh courier. Add it to Claude, plug in your own courier keys, and book & track parcels — Steadfast & Pathao — straight from a conversation. Your shop's logistics, agentic.",
|
||||
stack: ["MCP", "Steadfast", "Pathao", "Claude", "TypeScript"],
|
||||
impact: { primary: "1", secondary: "connector · every courier" },
|
||||
color: "amber",
|
||||
highlights: [
|
||||
"Book & track parcels from Claude — no dashboard hopping",
|
||||
"One URL, your own courier keys — nothing stored by us",
|
||||
"Steadfast & Pathao live · RedX & Paperfly coming",
|
||||
"Works in Claude Desktop, Claude Code, or hosted",
|
||||
"Open source — anyone can add it in seconds",
|
||||
],
|
||||
demo: "https://aura-courier-mcp.auraajenticai.cloud",
|
||||
repo: "https://github.com/auraajenticai/aura-courier-mcp",
|
||||
},
|
||||
],
|
||||
|
||||
testimonials: [
|
||||
@@ -396,6 +417,129 @@ const PORTFOLIO_DATA = {
|
||||
},
|
||||
],
|
||||
|
||||
caseStudies: [
|
||||
{
|
||||
slug: "finsync-ai-reconciliation",
|
||||
service: "AI Agent & Automation",
|
||||
serviceId: "ai-agent-automation",
|
||||
color: "cyan",
|
||||
client: "FinSync BD",
|
||||
clientType: "Fintech · Series A · Dhaka",
|
||||
title: "From 2-hour manual reconciliation to 5-second AI pipeline",
|
||||
challenge: "FinSync's finance team was spending 2+ hours every morning reconciling 1,200+ daily payouts against bank statements — error-prone, delayed, and blocking their 9am CFO dashboard sync.",
|
||||
solution: "We built a Claude-powered reconciliation agent on n8n: it fetches payouts from PostgreSQL, pulls bank data via API, runs statistical anomaly detection (flagging anything >3σ or >$5k), drafts the reconciliation note, and posts a Slack summary — all before the team arrives.",
|
||||
results: [
|
||||
{ metric: "5 sec", label: "reconciliation time (from 2 hours)" },
|
||||
{ metric: "0", label: "failures in 6 months of production" },
|
||||
{ metric: "12", label: "outliers caught per day on average" },
|
||||
{ metric: "3h", label: "engineer time saved daily" },
|
||||
],
|
||||
stack: ["Anthropic Claude", "n8n", "PostgreSQL", "Slack API", "Node.js"],
|
||||
timeline: "3 weeks build · deployed June 2025",
|
||||
quote: { text: "The system hasn't failed once in 6 months.", author: "Fahim Rahman, CTO — FinSync BD" },
|
||||
},
|
||||
{
|
||||
slug: "alphaedge-mt5-ea",
|
||||
service: "MT5 EA & Trading Automation",
|
||||
serviceId: "mt5-ea-trading",
|
||||
color: "amber",
|
||||
client: "AlphaEdge Capital",
|
||||
clientType: "Prop Trading Firm · Remote",
|
||||
title: "340% strategy outperformance over 3 months with an MT5 EA",
|
||||
challenge: "AlphaEdge was running manual trading strategies with 12 traders monitoring screens in shifts. Execution delays, emotion-driven exits, and inability to scale across symbols were killing performance.",
|
||||
solution: "We built a multi-symbol MT5 Expert Advisor with a three-layer risk engine: drawdown kill switch (auto-halts at X%), volatility-adjusted position sizing via ATR, and a real-time P&L dashboard with one-click halt. All orders execute within <80ms of signal generation.",
|
||||
results: [
|
||||
{ metric: "340%", label: "outperformance vs. manual baseline (3 months)" },
|
||||
{ metric: "<80ms", label: "tick-to-order execution latency" },
|
||||
{ metric: "4", label: "major drawdowns prevented by kill switch" },
|
||||
{ metric: "12→1", label: "traders needed to monitor (from 12 to 1)" },
|
||||
],
|
||||
stack: ["MQL5", "Go", "WebSockets", "React", "ClickHouse"],
|
||||
timeline: "4 weeks build · live on demo 2 weeks · mainnet August 2025",
|
||||
quote: { text: "The kill-switch and risk envelope features gave our risk team the confidence to scale.", author: "Tanvir Hossain, Head of Trading — AlphaEdge Capital" },
|
||||
},
|
||||
{
|
||||
slug: "growth-labs-meta-ads-ai",
|
||||
service: "AI-Powered Meta Ads",
|
||||
serviceId: "meta-ads-ai",
|
||||
color: "rose",
|
||||
client: "Growth Labs",
|
||||
clientType: "Performance Marketing Agency · UAE",
|
||||
title: "1.8× to 5.2× ROAS in 8 weeks using Meta AI agent",
|
||||
challenge: "Growth Labs was managing 3 e-commerce clients manually — two campaign managers checking ads twice daily. Creative fatigue went undetected for 4+ hours, wasting budget. ROAS was plateauing at 1.8–2.2×.",
|
||||
solution: "We deployed a Claude-powered Meta Ads agent using the official Meta MCP integration. The agent runs 15-minute optimization cycles: reallocating budget to winning ad sets, pausing fatigued creatives before CTR drops, generating 100+ variant titles for A/B tests, and sending daily AI-written performance digests.",
|
||||
results: [
|
||||
{ metric: "5.2×", label: "ROAS (from 1.8× baseline)" },
|
||||
{ metric: "8 weeks", label: "to reach peak ROAS" },
|
||||
{ metric: "4h earlier", label: "creative fatigue detection vs. human" },
|
||||
{ metric: "23%", label: "less wasted spend per month" },
|
||||
],
|
||||
stack: ["Meta MCP", "Meta Ads API", "Anthropic Claude", "n8n", "PostgreSQL"],
|
||||
timeline: "5 days setup · results visible within week 2",
|
||||
quote: { text: "From 1.8× to 5.2× ROAS in 8 weeks. The AI rotates creatives before fatigue hits.", author: "Sarah Mitchell, Marketing Director — Growth Labs" },
|
||||
},
|
||||
{
|
||||
slug: "tradestack-web3-settlement",
|
||||
service: "Web3 & Blockchain",
|
||||
serviceId: "web3-blockchain",
|
||||
color: "green",
|
||||
client: "TradeStack",
|
||||
clientType: "DeFi Protocol · Singapore",
|
||||
title: "Multi-chain settlement layer with gasless UX — shipped in 6 weeks",
|
||||
challenge: "TradeStack needed on-chain settlement for commodity trades across 4 EVM chains — with a compliance audit trail and a UX that hid gas complexity from non-crypto-native traders.",
|
||||
solution: "We built a multi-chain bridge with ERC-2771 meta-transactions (gasless UX), on-chain settlement with immutable audit logs, and a React dashboard where traders confirm in one click without ever touching ETH. Full Solidity audit trail for compliance.",
|
||||
results: [
|
||||
{ metric: "4 chains", label: "live simultaneously (ETH, BSC, Polygon, Arbitrum)" },
|
||||
{ metric: "0 gas", label: "paid by end users (fully abstracted)" },
|
||||
{ metric: "6 weeks", label: "from spec to mainnet" },
|
||||
{ metric: "100%", label: "compliance team sign-off on audit trail" },
|
||||
],
|
||||
stack: ["Solidity", "viem", "wagmi", "ERC-2771", "Cloudflare Workers", "React"],
|
||||
timeline: "6 weeks · mainnet September 2025",
|
||||
quote: { text: "The on-chain audit trail is what sold us — our compliance team loves it.", author: "Arif Chowdhury, Founder — TradeStack" },
|
||||
},
|
||||
{
|
||||
slug: "saas-dashboard-50k-dau",
|
||||
service: "Website & Webapp Development",
|
||||
serviceId: "web-app-dev",
|
||||
color: "violet",
|
||||
client: "Series-B SaaS (Confidential)",
|
||||
clientType: "B2B SaaS · Remote",
|
||||
title: "Dashboard rebuild: 4k to 28k DAU, zero downtime migration",
|
||||
challenge: "A Series-B SaaS was running a 4-year-old monolith dashboard that couldn't handle load past 10k concurrent users. Billing was broken for enterprise tiers, and the RBAC system couldn't support their new multi-tenant model.",
|
||||
solution: "We rebuilt the dashboard surface area: SvelteKit frontend, new multi-tenant Postgres schema, Stripe billing with usage-based pricing, RBAC with 12 permission layers, and a zero-downtime migration path using feature flags.",
|
||||
results: [
|
||||
{ metric: "28k", label: "DAU (from 4k before rebuild)" },
|
||||
{ metric: "0", label: "downtime during migration" },
|
||||
{ metric: "3×", label: "faster page load (Core Web Vitals)" },
|
||||
{ metric: "$0", label: "billing errors post-launch (vs. 40+/week before)" },
|
||||
],
|
||||
stack: ["SvelteKit", "PostgreSQL", "Stripe", "Drizzle ORM", "Tailwind", "Vercel"],
|
||||
timeline: "14 weeks total · phased rollout",
|
||||
quote: { text: "Lead architect on three SaaS dashboards now serving 50k+ daily users.", author: "Internal team" },
|
||||
},
|
||||
{
|
||||
slug: "vps-infra-cost-cut",
|
||||
service: "Infrastructure & DevOps",
|
||||
serviceId: "infra-devops",
|
||||
color: "cyan",
|
||||
client: "E-commerce Platform (Confidential)",
|
||||
clientType: "E-commerce · Bangladesh",
|
||||
title: "60% cloud bill reduction: AWS to self-hosted Coolify in 5 days",
|
||||
challenge: "A Dhaka-based e-commerce platform was spending $3,200/month on AWS managed services — RDS, ECS, load balancers — for a workload that needed none of the complexity. Infra was also managed by an AWS agency adding 40% markup.",
|
||||
solution: "We migrated everything to a €40/month Hetzner VPS running Coolify: Traefik for SSL + routing, Docker Compose for all services, GitHub Actions CI/CD with automatic rollback on health-check failure. Total setup time: 5 days.",
|
||||
results: [
|
||||
{ metric: "60%", label: "monthly infra cost reduction ($3,200 → $1,280)" },
|
||||
{ metric: "5 days", label: "full migration with zero data loss" },
|
||||
{ metric: "99.98%", label: "uptime in first 6 months" },
|
||||
{ metric: "$0", label: "agency markup eliminated" },
|
||||
],
|
||||
stack: ["Coolify", "Hetzner VPS", "Traefik", "Docker", "GitHub Actions", "PostgreSQL"],
|
||||
timeline: "5 days migration · March 2026",
|
||||
quote: { text: "Same reliability, fraction of the cost.", author: "Aura Engineering Team" },
|
||||
},
|
||||
],
|
||||
|
||||
experience: [
|
||||
{
|
||||
year: "2024 — Present",
|
||||
|
||||
+1
-1
@@ -1,9 +1,9 @@
|
||||
// Top nav — minimal, sticky, blurred — mobile-responsive
|
||||
const NAV_LINKS = [
|
||||
{ id: "services", label: "Services", url: "#/services" },
|
||||
{ id: "case-studies", label: "Case Studies", url: "#/case-studies" },
|
||||
{ id: "pricing", label: "Pricing", url: "#/pricing" },
|
||||
{ id: "blog", label: "Blog", url: "#/blog" },
|
||||
{ id: "timeline", label: "Timeline", url: "#/timeline" },
|
||||
{ id: "contact", label: "Contact", url: "#/contact" },
|
||||
]
|
||||
|
||||
|
||||
+207
@@ -1072,6 +1072,212 @@ const ServiceDetailPage = ({ svc }) => {
|
||||
);
|
||||
};
|
||||
|
||||
// ─── CASE STUDIES PAGE ───────────────────────────────────────────────────────
|
||||
|
||||
const CASE_COLORS = {
|
||||
cyan: { bg: "rgba(0,212,255,0.07)", border: "rgba(0,212,255,0.20)", text: "#67e8f9" },
|
||||
amber: { bg: "rgba(251,191,36,0.08)", border: "rgba(251,191,36,0.22)", text: "#fde68a" },
|
||||
rose: { bg: "rgba(244,63,94,0.08)", border: "rgba(244,63,94,0.22)", text: "#fda4af" },
|
||||
green: { bg: "rgba(34,197,94,0.07)", border: "rgba(34,197,94,0.20)", text: "#86efac" },
|
||||
violet: { bg: "rgba(124,92,255,0.08)", border: "rgba(124,92,255,0.22)", text: "#a78bfa" },
|
||||
};
|
||||
|
||||
const CaseStudyDetail = ({ cs, onBack }) => {
|
||||
const c = CASE_COLORS[cs.color] || CASE_COLORS.cyan;
|
||||
return (
|
||||
<main>
|
||||
<section style={{ padding: "140px 0 72px" }}>
|
||||
<div className="container" style={{ maxWidth: 800 }}>
|
||||
<button onClick={onBack} style={{
|
||||
display: "inline-flex", alignItems: "center", gap: 6,
|
||||
fontSize: 12.5, color: "var(--text-faint)", background: "none",
|
||||
border: "none", cursor: "pointer", marginBottom: 40,
|
||||
fontFamily: "var(--font-mono)", padding: 0,
|
||||
}}>← All Case Studies</button>
|
||||
|
||||
<div style={{ display: "flex", gap: 10, alignItems: "center", marginBottom: 20, flexWrap: "wrap" }}>
|
||||
<span style={{
|
||||
fontSize: 11, padding: "3px 10px", borderRadius: 999,
|
||||
background: c.bg, border: `1px solid ${c.border}`,
|
||||
color: c.text, fontFamily: "var(--font-mono)",
|
||||
}}>{cs.service}</span>
|
||||
<span style={{ fontSize: 12, color: "var(--text-faint)", fontFamily: "var(--font-mono)" }}>
|
||||
{cs.clientType} · {cs.timeline}
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<h1 style={{
|
||||
fontSize: "clamp(26px, 4vw, 46px)", fontWeight: 500,
|
||||
letterSpacing: "-0.02em", lineHeight: 1.1, margin: "0 0 40px",
|
||||
}}>{cs.title}</h1>
|
||||
|
||||
{/* Results hero */}
|
||||
<div style={{
|
||||
display: "grid", gridTemplateColumns: "repeat(2, 1fr)",
|
||||
gap: 12, marginBottom: 56,
|
||||
}} className="cs-results-grid">
|
||||
{cs.results.map((r, i) => (
|
||||
<div key={i} style={{
|
||||
padding: "24px 28px", borderRadius: "var(--radius)",
|
||||
background: c.bg, border: `1px solid ${c.border}`,
|
||||
}}>
|
||||
<div style={{ fontSize: 34, fontWeight: 700, color: c.text, lineHeight: 1, marginBottom: 6 }}>{r.metric}</div>
|
||||
<div style={{ fontSize: 13, color: "var(--text-dim)" }}>{r.label}</div>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
|
||||
{/* Challenge */}
|
||||
<div style={{ marginBottom: 40 }}>
|
||||
<h2 style={{ fontSize: 13, fontFamily: "var(--font-mono)", color: "var(--text-faint)", textTransform: "uppercase", letterSpacing: "0.12em", margin: "0 0 12px" }}>The Challenge</h2>
|
||||
<p style={{ margin: 0, fontSize: 16, lineHeight: 1.75, color: "var(--text-dim)" }}>{cs.challenge}</p>
|
||||
</div>
|
||||
|
||||
{/* Solution */}
|
||||
<div style={{ marginBottom: 40 }}>
|
||||
<h2 style={{ fontSize: 13, fontFamily: "var(--font-mono)", color: "var(--text-faint)", textTransform: "uppercase", letterSpacing: "0.12em", margin: "0 0 12px" }}>What We Built</h2>
|
||||
<p style={{ margin: 0, fontSize: 16, lineHeight: 1.75, color: "var(--text-dim)" }}>{cs.solution}</p>
|
||||
</div>
|
||||
|
||||
{/* Stack */}
|
||||
<div style={{ marginBottom: 48 }}>
|
||||
<h2 style={{ fontSize: 13, fontFamily: "var(--font-mono)", color: "var(--text-faint)", textTransform: "uppercase", letterSpacing: "0.12em", margin: "0 0 12px" }}>Stack</h2>
|
||||
<div style={{ display: "flex", flexWrap: "wrap", gap: 8 }}>
|
||||
{cs.stack.map(s => (
|
||||
<span key={s} style={{
|
||||
fontSize: 12.5, padding: "5px 12px", borderRadius: 7,
|
||||
background: c.bg, border: `1px solid ${c.border}`,
|
||||
color: c.text, fontFamily: "var(--font-mono)",
|
||||
}}>{s}</span>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Quote */}
|
||||
{cs.quote && (
|
||||
<div style={{
|
||||
padding: "28px 32px", borderRadius: "var(--radius)",
|
||||
background: c.bg, border: `1px solid ${c.border}`,
|
||||
marginBottom: 48,
|
||||
}}>
|
||||
<div style={{ fontSize: 28, color: c.text, fontFamily: "var(--font-serif)", marginBottom: 12, lineHeight: 1 }}>"</div>
|
||||
<p style={{ margin: "0 0 14px", fontSize: 16, lineHeight: 1.65, fontStyle: "italic" }}>{cs.quote.text}</p>
|
||||
<span style={{ fontSize: 12.5, color: "var(--text-faint)", fontFamily: "var(--font-mono)" }}>{cs.quote.author}</span>
|
||||
</div>
|
||||
)}
|
||||
|
||||
{/* CTA */}
|
||||
<div style={{
|
||||
padding: "36px 40px", borderRadius: "var(--radius)",
|
||||
background: "var(--bg-card)", border: "1px solid var(--line)",
|
||||
display: "flex", alignItems: "center", justifyContent: "space-between",
|
||||
flexWrap: "wrap", gap: 20,
|
||||
}}>
|
||||
<div>
|
||||
<p style={{ margin: "0 0 4px", fontSize: 16, fontWeight: 500 }}>Want similar results?</p>
|
||||
<p style={{ margin: 0, fontSize: 13.5, color: "var(--text-dim)" }}>
|
||||
Describe your project — we respond within 24h with a scoped proposal.
|
||||
</p>
|
||||
</div>
|
||||
<a href={`mailto:hello@auraajenticai.cloud?subject=Project: ${cs.service}`} style={{
|
||||
padding: "11px 24px", background: "var(--text)", color: "var(--bg)",
|
||||
borderRadius: 9, fontSize: 14, fontWeight: 500,
|
||||
textDecoration: "none", whiteSpace: "nowrap", flexShrink: 0,
|
||||
}}>Start a Project →</a>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
<style>{`
|
||||
@media (max-width: 540px) {
|
||||
.cs-results-grid { grid-template-columns: 1fr !important; }
|
||||
}
|
||||
`}</style>
|
||||
</main>
|
||||
);
|
||||
};
|
||||
|
||||
const CaseStudiesPage = () => {
|
||||
const D = PORTFOLIO_DATA;
|
||||
const [active, setActive] = React.useState(null);
|
||||
const cases = D.caseStudies || [];
|
||||
|
||||
const cs = active ? cases.find(c => c.slug === active) : null;
|
||||
if (cs) return <CaseStudyDetail cs={cs} onBack={() => setActive(null)} />;
|
||||
|
||||
return (
|
||||
<main>
|
||||
<PageHero
|
||||
eyebrow="Case Studies"
|
||||
title={<>Real projects. Real <span style={{ fontFamily: "var(--font-serif)", fontStyle: "italic", fontWeight: 400 }}>results.</span></>}
|
||||
sub="Every case study is a production system — running live, serving real users, generating real metrics. No mock-ups."
|
||||
/>
|
||||
<section style={{ padding: "80px 0 120px" }}>
|
||||
<div className="container">
|
||||
<div style={{ display: "grid", gap: 20 }}>
|
||||
{cases.map((cs, i) => {
|
||||
const c = CASE_COLORS[cs.color] || CASE_COLORS.cyan;
|
||||
return (
|
||||
<div
|
||||
key={i}
|
||||
className="reveal"
|
||||
onClick={() => setActive(cs.slug)}
|
||||
style={{
|
||||
background: "var(--bg-card)", border: "1px solid var(--line)",
|
||||
borderRadius: "var(--radius)", padding: "32px 36px",
|
||||
cursor: "pointer", transition: "border-color 0.2s, background 0.2s",
|
||||
}}
|
||||
onMouseEnter={e => { e.currentTarget.style.borderColor = c.border; e.currentTarget.style.background = c.bg; }}
|
||||
onMouseLeave={e => { e.currentTarget.style.borderColor = "var(--line)"; e.currentTarget.style.background = "var(--bg-card)"; }}
|
||||
>
|
||||
<div style={{ display: "flex", justifyContent: "space-between", alignItems: "flex-start", gap: 24, flexWrap: "wrap" }}>
|
||||
<div style={{ flex: 1, minWidth: 0 }}>
|
||||
<div style={{ display: "flex", gap: 10, alignItems: "center", marginBottom: 14, flexWrap: "wrap" }}>
|
||||
<span style={{
|
||||
fontSize: 10.5, padding: "2px 9px", borderRadius: 999,
|
||||
background: c.bg, border: `1px solid ${c.border}`,
|
||||
color: c.text, fontFamily: "var(--font-mono)",
|
||||
}}>{cs.service}</span>
|
||||
<span style={{ fontSize: 11.5, color: "var(--text-faint)", fontFamily: "var(--font-mono)" }}>{cs.clientType}</span>
|
||||
</div>
|
||||
<h3 style={{ margin: "0 0 12px", fontSize: "clamp(16px, 2vw, 20px)", fontWeight: 500, letterSpacing: "-0.01em" }}>
|
||||
{cs.title}
|
||||
</h3>
|
||||
<p style={{ margin: 0, fontSize: 14, color: "var(--text-dim)", lineHeight: 1.55, maxWidth: 600 }}>
|
||||
{cs.challenge.slice(0, 140)}…
|
||||
</p>
|
||||
</div>
|
||||
|
||||
{/* Key metric highlight */}
|
||||
<div style={{ textAlign: "right", flexShrink: 0 }}>
|
||||
<div style={{ fontSize: 32, fontWeight: 700, color: c.text, lineHeight: 1 }}>{cs.results[0].metric}</div>
|
||||
<div style={{ fontSize: 11.5, color: "var(--text-faint)", fontFamily: "var(--font-mono)", marginTop: 4, maxWidth: 140, textAlign: "right" }}>{cs.results[0].label}</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Mini results row */}
|
||||
<div style={{
|
||||
display: "flex", gap: 24, marginTop: 24,
|
||||
paddingTop: 20, borderTop: `1px solid ${c.border}`,
|
||||
flexWrap: "wrap",
|
||||
}}>
|
||||
{cs.results.slice(1).map((r, ri) => (
|
||||
<div key={ri}>
|
||||
<span style={{ fontSize: 15, fontWeight: 600, color: c.text }}>{r.metric}</span>
|
||||
<span style={{ fontSize: 11.5, color: "var(--text-faint)", fontFamily: "var(--font-mono)", marginLeft: 6 }}>{r.label}</span>
|
||||
</div>
|
||||
))}
|
||||
<span style={{ marginLeft: "auto", fontSize: 20, color: "var(--text-faint)", flexShrink: 0 }}>→</span>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
})}
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
</main>
|
||||
);
|
||||
};
|
||||
|
||||
window.ServicesPage = ServicesPage;
|
||||
window.StackPage = StackPage;
|
||||
window.AgentsPage = AgentsPage;
|
||||
@@ -1080,3 +1286,4 @@ window.ContactPage = ContactPage;
|
||||
window.PricingPage = PricingPage;
|
||||
window.BlogPage = BlogPage;
|
||||
window.ServiceDetailPage = ServiceDetailPage;
|
||||
window.CaseStudiesPage = CaseStudiesPage;
|
||||
|
||||
Reference in New Issue
Block a user