Compare commits

..

2 Commits

Author SHA1 Message Date
khondokartowsif171 9a5c01b31b feat: wire contact form to Formsubmit.co → khondokartowsif171@gmail.com
Replace non-existent n8n webhook with Formsubmit AJAX endpoint.
Zero backend required — first submission triggers Gmail verification,
after that all inquiries arrive as formatted table emails.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-07-15 06:50:17 +06:00
khondokar fa95c6e482 fix: add explicit docker-compose.yaml with Traefik labels for auraajenticai.cloud 2026-06-15 17:10:02 +00:00
6 changed files with 14 additions and 388 deletions
+13 -13
View File
@@ -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/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 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=6"></script> <script type="text/babel" src="tweaks-panel.jsx?v=5"></script>
<script type="text/babel" src="src/icons.jsx?v=6"></script> <script type="text/babel" src="src/icons.jsx?v=5"></script>
<script type="text/babel" src="src/data.jsx?v=6"></script> <script type="text/babel" src="src/data.jsx?v=5"></script>
<script type="text/babel" src="src/nav.jsx?v=6"></script> <script type="text/babel" src="src/nav.jsx?v=5"></script>
<script type="text/babel" src="src/hero.jsx?v=6"></script> <script type="text/babel" src="src/hero.jsx?v=5"></script>
<script type="text/babel" src="src/sections.jsx?v=6"></script> <script type="text/babel" src="src/sections.jsx?v=5"></script>
<script type="text/babel" src="src/projects.jsx?v=6"></script> <script type="text/babel" src="src/projects.jsx?v=5"></script>
<script type="text/babel" src="src/agent-showcase.jsx?v=6"></script> <script type="text/babel" src="src/agent-showcase.jsx?v=5"></script>
<script type="text/babel" src="src/timeline-contact.jsx?v=6"></script> <script type="text/babel" src="src/timeline-contact.jsx?v=5"></script>
<script type="text/babel" src="src/command-palette.jsx?v=6"></script> <script type="text/babel" src="src/command-palette.jsx?v=5"></script>
<script type="text/babel" src="src/chatbox.jsx?v=6"></script> <script type="text/babel" src="src/chatbox.jsx?v=5"></script>
<script type="text/babel" src="src/pages.jsx?v=6"></script> <script type="text/babel" src="src/pages.jsx?v=5"></script>
<script type="text/babel" src="src/app.jsx?v=6"></script> <script type="text/babel" src="src/app.jsx?v=5"></script>
</body> </body>
</html> </html>
-6
View File
@@ -103,10 +103,6 @@ function App() {
title: `Contact — ${BASE}`, 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.', 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: { pricing: {
title: `Pricing — ${BASE}`, title: `Pricing — ${BASE}`,
desc: 'Transparent pricing for AI agents, automation, and full-stack development. Starter, Growth, and Enterprise tiers. Fixed scope, no surprises.', desc: 'Transparent pricing for AI agents, automation, and full-stack development. Starter, Growth, and Enterprise tiers. Fixed scope, no surprises.',
@@ -178,8 +174,6 @@ function App() {
return <T.PricingPage />; return <T.PricingPage />;
case 'blog': case 'blog':
return <T.BlogPage />; return <T.BlogPage />;
case 'case-studies':
return <T.CaseStudiesPage />;
default: default:
return ( return (
<main style={density === "compact" ? { fontSize: 14.5 } : undefined}> <main style={density === "compact" ? { fontSize: 14.5 } : undefined}>
-144
View File
@@ -164,27 +164,6 @@ const PORTFOLIO_DATA = {
"Full Meta API access via official MCP integration", "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: [ testimonials: [
@@ -417,129 +396,6 @@ 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.82.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: [ experience: [
{ {
year: "2024 — Present", year: "2024 — Present",
+1 -1
View File
@@ -1,9 +1,9 @@
// Top nav — minimal, sticky, blurred — mobile-responsive // Top nav — minimal, sticky, blurred — mobile-responsive
const NAV_LINKS = [ const NAV_LINKS = [
{ id: "services", label: "Services", url: "#/services" }, { id: "services", label: "Services", url: "#/services" },
{ id: "case-studies", label: "Case Studies", url: "#/case-studies" },
{ id: "pricing", label: "Pricing", url: "#/pricing" }, { id: "pricing", label: "Pricing", url: "#/pricing" },
{ id: "blog", label: "Blog", url: "#/blog" }, { id: "blog", label: "Blog", url: "#/blog" },
{ id: "timeline", label: "Timeline", url: "#/timeline" },
{ id: "contact", label: "Contact", url: "#/contact" }, { id: "contact", label: "Contact", url: "#/contact" },
] ]
-207
View File
@@ -1072,212 +1072,6 @@ 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.ServicesPage = ServicesPage;
window.StackPage = StackPage; window.StackPage = StackPage;
window.AgentsPage = AgentsPage; window.AgentsPage = AgentsPage;
@@ -1286,4 +1080,3 @@ window.ContactPage = ContactPage;
window.PricingPage = PricingPage; window.PricingPage = PricingPage;
window.BlogPage = BlogPage; window.BlogPage = BlogPage;
window.ServiceDetailPage = ServiceDetailPage; window.ServiceDetailPage = ServiceDetailPage;
window.CaseStudiesPage = CaseStudiesPage;
-17
View File
@@ -1,17 +0,0 @@
{
"cleanUrls": true,
"trailingSlash": false,
"rewrites": [
{ "source": "/(.*)", "destination": "/index.html" }
],
"headers": [
{
"source": "/(.*)",
"headers": [
{ "key": "X-Content-Type-Options", "value": "nosniff" },
{ "key": "X-Frame-Options", "value": "SAMEORIGIN" },
{ "key": "Referrer-Policy", "value": "strict-origin-when-cross-origin" }
]
}
]
}