- Add Node.js MCP server (stdio + HTTP/SSE) with generate_qr and generate_pix_qr tools - Add landing pages PT/EN at /mcp and /mcp/en with hreflang SEO - Fix OAuth returnUrl via RedirectUri query param (state was always null in callback) - Fix API key requests bypassing web credit check (use rate limiter instead) - Add /api/mcp nginx route + Docker Swarm service for n8n cloud integration - Auto-create API key on first OAuth login with TempData display - Add UseDefaultFiles() for /mcp → /mcp/index.html serving - Fix Serilog console log level in Development (was Error, now Info for app logs) - Add /api/v1/QRManager/me endpoint for API key validation - Update CI/CD to build and deploy qrrapido-mcp image alongside .NET app Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
1577 lines
55 KiB
HTML
1577 lines
55 KiB
HTML
<!DOCTYPE html>
|
|
<html lang="pt-BR">
|
|
<head>
|
|
<meta charset="UTF-8">
|
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
<title>QR Rápido MCP — QR codes para agentes de IA e automações</title>
|
|
<meta name="description" content="Gere QR codes via Claude MCP, REST API, n8n e Make.com. Resposta base64 inline. Sem hosting de arquivo. Para agentes de IA, workflows e automações.">
|
|
<meta name="keywords" content="QR code API, MCP, Claude Desktop, n8n, automação, agentes IA, PIX QR code, Make.com">
|
|
<meta property="og:title" content="QR Rápido MCP — QR codes para agentes de IA">
|
|
<meta property="og:description" content="O gerador de QR codes nativo para agentes de IA e automações. MCP, REST API, n8n, Make.com.">
|
|
<meta property="og:url" content="https://mcp.qrrapido.site">
|
|
<meta name="robots" content="index, follow">
|
|
<link rel="canonical" href="https://qrrapido.site/mcp">
|
|
<link rel="alternate" hreflang="pt-BR" href="https://qrrapido.site/mcp">
|
|
<link rel="alternate" hreflang="en" href="https://qrrapido.site/mcp/en">
|
|
<link rel="alternate" hreflang="x-default" href="https://qrrapido.site/mcp">
|
|
|
|
<link rel="preconnect" href="https://fonts.googleapis.com">
|
|
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
|
<link href="https://fonts.googleapis.com/css2?family=Syne:wght@400;600;700;800&family=Figtree:wght@300;400;500;600&family=JetBrains+Mono:wght@400;500&display=swap" rel="stylesheet">
|
|
|
|
<style>
|
|
/* ══════════════════════════════════════════
|
|
VARIABLES & RESET
|
|
══════════════════════════════════════════ */
|
|
:root {
|
|
--bg-base: #06060e;
|
|
--bg-surface: #0d0d1a;
|
|
--bg-elevated: #13131f;
|
|
--bg-card: #0f0f1c;
|
|
|
|
--border: rgba(99, 102, 241, 0.15);
|
|
--border-bright: rgba(99, 102, 241, 0.35);
|
|
|
|
--indigo: #6366f1;
|
|
--violet: #8b5cf6;
|
|
--indigo-glow: rgba(99, 102, 241, 0.25);
|
|
--emerald: #10b981;
|
|
--cyan: #06b6d4;
|
|
|
|
--text-primary: #eeeef5;
|
|
--text-secondary: #9090b0;
|
|
--text-muted: #55556a;
|
|
--text-code: #e0e0ff;
|
|
|
|
--font-display: 'Syne', sans-serif;
|
|
--font-body: 'Figtree', sans-serif;
|
|
--font-mono: 'JetBrains Mono', monospace;
|
|
|
|
--radius-sm: 6px;
|
|
--radius-md: 12px;
|
|
--radius-lg: 20px;
|
|
|
|
--transition: 0.2s cubic-bezier(0.4, 0, 0.2, 1);
|
|
}
|
|
|
|
*, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }
|
|
html { scroll-behavior: smooth; }
|
|
|
|
body {
|
|
background: var(--bg-base);
|
|
color: var(--text-primary);
|
|
font-family: var(--font-body);
|
|
font-size: 16px;
|
|
line-height: 1.6;
|
|
overflow-x: hidden;
|
|
-webkit-font-smoothing: antialiased;
|
|
}
|
|
|
|
/* QR dot-grid texture */
|
|
body::before {
|
|
content: '';
|
|
position: fixed;
|
|
inset: 0;
|
|
background-image: radial-gradient(circle, rgba(99,102,241,0.11) 1px, transparent 1px);
|
|
background-size: 28px 28px;
|
|
pointer-events: none;
|
|
z-index: 0;
|
|
}
|
|
|
|
/* ambient glow top-right */
|
|
body::after {
|
|
content: '';
|
|
position: fixed;
|
|
width: 700px; height: 700px;
|
|
border-radius: 50%;
|
|
background: radial-gradient(circle, rgba(99,102,241,0.07) 0%, transparent 70%);
|
|
top: -250px; right: -150px;
|
|
pointer-events: none;
|
|
z-index: 0;
|
|
}
|
|
|
|
section, nav, footer, .integrations { position: relative; z-index: 1; }
|
|
|
|
/* ══════════════════════════════════════════
|
|
LAYOUT
|
|
══════════════════════════════════════════ */
|
|
.container {
|
|
max-width: 1100px;
|
|
margin: 0 auto;
|
|
padding: 0 24px;
|
|
}
|
|
|
|
/* ══════════════════════════════════════════
|
|
NAV
|
|
══════════════════════════════════════════ */
|
|
nav {
|
|
position: fixed;
|
|
top: 0; left: 0; right: 0;
|
|
z-index: 100;
|
|
padding: 14px 24px;
|
|
background: rgba(6, 6, 14, 0.88);
|
|
backdrop-filter: blur(20px);
|
|
border-bottom: 1px solid var(--border);
|
|
}
|
|
|
|
.nav-inner {
|
|
max-width: 1100px;
|
|
margin: 0 auto;
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: space-between;
|
|
}
|
|
|
|
.nav-logo {
|
|
display: flex;
|
|
align-items: center;
|
|
gap: 10px;
|
|
text-decoration: none;
|
|
font-family: var(--font-display);
|
|
font-weight: 700;
|
|
font-size: 17px;
|
|
color: var(--text-primary);
|
|
}
|
|
|
|
.nav-logo-icon {
|
|
width: 30px; height: 30px;
|
|
background: linear-gradient(135deg, var(--indigo), var(--violet));
|
|
border-radius: 7px;
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: center;
|
|
font-size: 15px;
|
|
}
|
|
|
|
.nav-badge {
|
|
font-size: 10px;
|
|
font-family: var(--font-mono);
|
|
background: rgba(99,102,241,0.15);
|
|
border: 1px solid rgba(99,102,241,0.3);
|
|
color: var(--indigo);
|
|
padding: 2px 8px;
|
|
border-radius: 4px;
|
|
letter-spacing: 0.05em;
|
|
}
|
|
|
|
.nav-links {
|
|
display: flex;
|
|
align-items: center;
|
|
gap: 4px;
|
|
}
|
|
|
|
.nav-link {
|
|
font-size: 14px;
|
|
color: var(--text-secondary);
|
|
text-decoration: none;
|
|
padding: 7px 13px;
|
|
border-radius: var(--radius-sm);
|
|
transition: var(--transition);
|
|
}
|
|
.nav-link:hover { color: var(--text-primary); background: rgba(255,255,255,0.05); }
|
|
|
|
.btn {
|
|
display: inline-flex;
|
|
align-items: center;
|
|
gap: 8px;
|
|
padding: 9px 18px;
|
|
border-radius: var(--radius-sm);
|
|
font-family: var(--font-body);
|
|
font-size: 14px;
|
|
font-weight: 600;
|
|
text-decoration: none;
|
|
transition: var(--transition);
|
|
cursor: pointer;
|
|
border: none;
|
|
}
|
|
|
|
.btn-primary {
|
|
background: linear-gradient(135deg, var(--indigo), var(--violet));
|
|
color: white;
|
|
box-shadow: 0 0 20px rgba(99,102,241,0.3);
|
|
}
|
|
.btn-primary:hover {
|
|
transform: translateY(-1px);
|
|
box-shadow: 0 0 32px rgba(99,102,241,0.5);
|
|
}
|
|
|
|
.btn-ghost {
|
|
background: transparent;
|
|
color: var(--text-secondary);
|
|
border: 1px solid var(--border);
|
|
}
|
|
.btn-ghost:hover {
|
|
color: var(--text-primary);
|
|
border-color: var(--border-bright);
|
|
background: rgba(99,102,241,0.05);
|
|
}
|
|
|
|
.btn-lg { padding: 14px 28px; font-size: 15px; border-radius: var(--radius-md); }
|
|
|
|
/* ══════════════════════════════════════════
|
|
HERO
|
|
══════════════════════════════════════════ */
|
|
.hero {
|
|
padding: 140px 24px 80px;
|
|
min-height: 100vh;
|
|
display: flex;
|
|
align-items: center;
|
|
}
|
|
|
|
.hero-inner {
|
|
max-width: 1100px;
|
|
margin: 0 auto;
|
|
display: grid;
|
|
grid-template-columns: 1fr 1fr;
|
|
gap: 60px;
|
|
align-items: center;
|
|
}
|
|
|
|
.hero-tag {
|
|
display: inline-flex;
|
|
align-items: center;
|
|
gap: 8px;
|
|
font-family: var(--font-mono);
|
|
font-size: 12px;
|
|
color: var(--indigo);
|
|
background: rgba(99,102,241,0.1);
|
|
border: 1px solid rgba(99,102,241,0.25);
|
|
padding: 6px 14px;
|
|
border-radius: 100px;
|
|
margin-bottom: 24px;
|
|
letter-spacing: 0.05em;
|
|
opacity: 0;
|
|
animation: fadeUp 0.6s 0.1s forwards;
|
|
}
|
|
|
|
.hero-tag-dot {
|
|
width: 6px; height: 6px;
|
|
background: var(--emerald);
|
|
border-radius: 50%;
|
|
animation: pulse 2s infinite;
|
|
}
|
|
|
|
.hero-title {
|
|
font-family: var(--font-display);
|
|
font-size: clamp(36px, 4.5vw, 54px);
|
|
font-weight: 800;
|
|
line-height: 1.1;
|
|
letter-spacing: -0.03em;
|
|
margin-bottom: 20px;
|
|
opacity: 0;
|
|
animation: fadeUp 0.6s 0.2s forwards;
|
|
}
|
|
|
|
.hero-title .accent {
|
|
background: linear-gradient(135deg, var(--indigo) 0%, var(--violet) 100%);
|
|
-webkit-background-clip: text;
|
|
-webkit-text-fill-color: transparent;
|
|
background-clip: text;
|
|
}
|
|
|
|
.hero-subtitle {
|
|
font-size: 17px;
|
|
color: var(--text-secondary);
|
|
line-height: 1.65;
|
|
margin-bottom: 36px;
|
|
font-weight: 300;
|
|
opacity: 0;
|
|
animation: fadeUp 0.6s 0.3s forwards;
|
|
}
|
|
|
|
.hero-actions {
|
|
display: flex;
|
|
gap: 12px;
|
|
flex-wrap: wrap;
|
|
opacity: 0;
|
|
animation: fadeUp 0.6s 0.4s forwards;
|
|
}
|
|
|
|
.hero-stats {
|
|
display: flex;
|
|
gap: 32px;
|
|
margin-top: 40px;
|
|
padding-top: 32px;
|
|
border-top: 1px solid var(--border);
|
|
opacity: 0;
|
|
animation: fadeUp 0.6s 0.5s forwards;
|
|
}
|
|
|
|
.stat-value {
|
|
font-family: var(--font-display);
|
|
font-size: 22px;
|
|
font-weight: 700;
|
|
}
|
|
|
|
.stat-label {
|
|
font-size: 12px;
|
|
color: var(--text-muted);
|
|
margin-top: 2px;
|
|
}
|
|
|
|
/* Terminal */
|
|
.terminal {
|
|
background: var(--bg-elevated);
|
|
border: 1px solid var(--border);
|
|
border-radius: var(--radius-lg);
|
|
overflow: hidden;
|
|
box-shadow:
|
|
0 40px 80px rgba(0,0,0,0.6),
|
|
inset 0 0 0 1px rgba(99,102,241,0.08);
|
|
opacity: 0;
|
|
animation: fadeIn 0.8s 0.5s forwards;
|
|
}
|
|
|
|
.terminal-header {
|
|
display: flex;
|
|
align-items: center;
|
|
gap: 8px;
|
|
padding: 13px 16px;
|
|
background: rgba(0,0,0,0.35);
|
|
border-bottom: 1px solid var(--border);
|
|
}
|
|
|
|
.dot { width: 10px; height: 10px; border-radius: 50%; }
|
|
.dot-r { background: #ff5f57; }
|
|
.dot-y { background: #febc2e; }
|
|
.dot-g { background: #28c840; }
|
|
|
|
.terminal-title {
|
|
font-family: var(--font-mono);
|
|
font-size: 12px;
|
|
color: var(--text-muted);
|
|
margin-left: 8px;
|
|
}
|
|
|
|
.terminal-body {
|
|
padding: 20px;
|
|
font-family: var(--font-mono);
|
|
font-size: 13px;
|
|
line-height: 1.9;
|
|
min-height: 340px;
|
|
}
|
|
|
|
.t-prompt { color: var(--indigo); }
|
|
.t-tool { color: var(--violet); }
|
|
.t-key { color: var(--cyan); }
|
|
.t-string { color: #a5f3fc; }
|
|
.t-success { color: var(--emerald); }
|
|
.t-value { color: #fde68a; }
|
|
.t-dim { color: var(--text-muted); }
|
|
.t-comment { color: var(--text-muted); font-style: italic; }
|
|
|
|
.terminal-line {
|
|
display: block;
|
|
opacity: 0;
|
|
transition: opacity 0.25s ease;
|
|
}
|
|
|
|
.cursor {
|
|
display: inline-block;
|
|
width: 8px; height: 14px;
|
|
background: var(--indigo);
|
|
vertical-align: middle;
|
|
animation: blink 1s infinite;
|
|
margin-left: 2px;
|
|
}
|
|
|
|
/* ══════════════════════════════════════════
|
|
INTEGRATIONS
|
|
══════════════════════════════════════════ */
|
|
.integrations {
|
|
padding: 28px 24px;
|
|
border-top: 1px solid var(--border);
|
|
border-bottom: 1px solid var(--border);
|
|
background: rgba(13,13,26,0.7);
|
|
}
|
|
|
|
.integrations-inner {
|
|
max-width: 1100px;
|
|
margin: 0 auto;
|
|
display: flex;
|
|
align-items: center;
|
|
gap: 28px;
|
|
flex-wrap: wrap;
|
|
}
|
|
|
|
.integrations-label {
|
|
font-size: 11px;
|
|
font-family: var(--font-mono);
|
|
color: var(--text-muted);
|
|
letter-spacing: 0.12em;
|
|
white-space: nowrap;
|
|
}
|
|
|
|
.integrations-list {
|
|
display: flex;
|
|
align-items: center;
|
|
gap: 10px;
|
|
flex-wrap: wrap;
|
|
}
|
|
|
|
.integration-badge {
|
|
display: flex;
|
|
align-items: center;
|
|
gap: 7px;
|
|
padding: 7px 14px;
|
|
background: var(--bg-elevated);
|
|
border: 1px solid var(--border);
|
|
border-radius: var(--radius-sm);
|
|
font-size: 13px;
|
|
font-weight: 500;
|
|
color: var(--text-secondary);
|
|
transition: var(--transition);
|
|
}
|
|
.integration-badge:hover {
|
|
border-color: var(--border-bright);
|
|
color: var(--text-primary);
|
|
background: rgba(99,102,241,0.06);
|
|
}
|
|
|
|
/* ══════════════════════════════════════════
|
|
SECTIONS BASE
|
|
══════════════════════════════════════════ */
|
|
.section { padding: 100px 24px; }
|
|
|
|
.section-label {
|
|
font-family: var(--font-mono);
|
|
font-size: 11px;
|
|
letter-spacing: 0.15em;
|
|
color: var(--indigo);
|
|
margin-bottom: 14px;
|
|
text-transform: uppercase;
|
|
}
|
|
|
|
.section-title {
|
|
font-family: var(--font-display);
|
|
font-size: clamp(28px, 3.5vw, 42px);
|
|
font-weight: 700;
|
|
line-height: 1.15;
|
|
letter-spacing: -0.02em;
|
|
margin-bottom: 14px;
|
|
}
|
|
|
|
.section-sub {
|
|
font-size: 17px;
|
|
color: var(--text-secondary);
|
|
max-width: 520px;
|
|
font-weight: 300;
|
|
margin-bottom: 56px;
|
|
line-height: 1.6;
|
|
}
|
|
|
|
/* ══════════════════════════════════════════
|
|
HOW IT WORKS
|
|
══════════════════════════════════════════ */
|
|
.steps {
|
|
display: grid;
|
|
grid-template-columns: repeat(3, 1fr);
|
|
gap: 28px;
|
|
}
|
|
|
|
.step { position: relative; }
|
|
|
|
.step-number {
|
|
font-family: var(--font-display);
|
|
font-size: 60px;
|
|
font-weight: 800;
|
|
color: rgba(99,102,241,0.07);
|
|
line-height: 1;
|
|
margin-bottom: -12px;
|
|
user-select: none;
|
|
}
|
|
|
|
.step-card {
|
|
background: var(--bg-card);
|
|
border: 1px solid var(--border);
|
|
border-radius: var(--radius-lg);
|
|
padding: 28px;
|
|
transition: var(--transition);
|
|
}
|
|
.step-card:hover {
|
|
border-color: var(--border-bright);
|
|
transform: translateY(-4px);
|
|
box-shadow: 0 20px 40px rgba(0,0,0,0.4);
|
|
}
|
|
|
|
.step-icon {
|
|
width: 44px; height: 44px;
|
|
background: linear-gradient(135deg, rgba(99,102,241,0.18), rgba(139,92,246,0.18));
|
|
border: 1px solid rgba(99,102,241,0.28);
|
|
border-radius: var(--radius-sm);
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: center;
|
|
font-size: 20px;
|
|
margin-bottom: 16px;
|
|
}
|
|
|
|
.step-title {
|
|
font-family: var(--font-display);
|
|
font-size: 18px;
|
|
font-weight: 700;
|
|
margin-bottom: 8px;
|
|
}
|
|
|
|
.step-desc {
|
|
font-size: 14px;
|
|
color: var(--text-secondary);
|
|
line-height: 1.6;
|
|
}
|
|
|
|
.step-arrow {
|
|
position: absolute;
|
|
top: 72px;
|
|
right: -18px;
|
|
color: var(--text-muted);
|
|
font-size: 22px;
|
|
z-index: 2;
|
|
}
|
|
|
|
/* ══════════════════════════════════════════
|
|
CODE SHOWCASE
|
|
══════════════════════════════════════════ */
|
|
.code-showcase { background: rgba(13,13,26,0.5); }
|
|
|
|
.tabs {
|
|
display: flex;
|
|
gap: 4px;
|
|
margin-bottom: 20px;
|
|
background: var(--bg-elevated);
|
|
border: 1px solid var(--border);
|
|
border-radius: var(--radius-md);
|
|
padding: 4px;
|
|
width: fit-content;
|
|
}
|
|
|
|
.tab-btn {
|
|
font-family: var(--font-mono);
|
|
font-size: 12px;
|
|
padding: 8px 16px;
|
|
border-radius: var(--radius-sm);
|
|
border: none;
|
|
cursor: pointer;
|
|
background: transparent;
|
|
color: var(--text-muted);
|
|
transition: var(--transition);
|
|
}
|
|
.tab-btn.active {
|
|
background: linear-gradient(135deg, var(--indigo), var(--violet));
|
|
color: white;
|
|
}
|
|
.tab-btn:hover:not(.active) {
|
|
color: var(--text-secondary);
|
|
background: rgba(255,255,255,0.05);
|
|
}
|
|
|
|
.tab-content { display: none; }
|
|
.tab-content.active { display: block; }
|
|
|
|
.code-window {
|
|
background: var(--bg-elevated);
|
|
border: 1px solid var(--border);
|
|
border-radius: var(--radius-lg);
|
|
overflow: hidden;
|
|
box-shadow: 0 20px 60px rgba(0,0,0,0.5);
|
|
}
|
|
|
|
.code-header {
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: space-between;
|
|
padding: 12px 16px;
|
|
background: rgba(0,0,0,0.3);
|
|
border-bottom: 1px solid var(--border);
|
|
}
|
|
|
|
.code-header-left {
|
|
display: flex;
|
|
align-items: center;
|
|
gap: 8px;
|
|
}
|
|
|
|
.code-dots { display: flex; gap: 6px; }
|
|
|
|
.code-filename {
|
|
font-family: var(--font-mono);
|
|
font-size: 12px;
|
|
color: var(--text-muted);
|
|
margin-left: 8px;
|
|
}
|
|
|
|
.copy-btn {
|
|
font-family: var(--font-mono);
|
|
font-size: 11px;
|
|
color: var(--text-muted);
|
|
background: transparent;
|
|
border: 1px solid var(--border);
|
|
padding: 4px 10px;
|
|
border-radius: 4px;
|
|
cursor: pointer;
|
|
transition: var(--transition);
|
|
}
|
|
.copy-btn:hover { color: var(--indigo); border-color: rgba(99,102,241,0.4); }
|
|
|
|
pre {
|
|
padding: 24px;
|
|
overflow-x: auto;
|
|
font-family: var(--font-mono);
|
|
font-size: 13px;
|
|
line-height: 1.85;
|
|
color: var(--text-code);
|
|
}
|
|
|
|
.hl-key { color: var(--cyan); }
|
|
.hl-string { color: #a5f3fc; }
|
|
.hl-number { color: #fde68a; }
|
|
.hl-bool { color: #f9a8d4; }
|
|
.hl-comment { color: var(--text-muted); }
|
|
.hl-url { color: var(--emerald); }
|
|
|
|
/* n8n mockup */
|
|
.n8n-mockup {
|
|
padding: 24px;
|
|
display: flex;
|
|
flex-direction: column;
|
|
gap: 14px;
|
|
}
|
|
|
|
.n8n-node {
|
|
background: rgba(255,255,255,0.04);
|
|
border: 1px solid rgba(255,255,255,0.07);
|
|
border-radius: var(--radius-md);
|
|
padding: 16px;
|
|
}
|
|
|
|
.n8n-node-header {
|
|
display: flex;
|
|
align-items: center;
|
|
gap: 10px;
|
|
margin-bottom: 14px;
|
|
}
|
|
|
|
.n8n-node-icon {
|
|
width: 30px; height: 30px;
|
|
border-radius: var(--radius-sm);
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: center;
|
|
font-size: 15px;
|
|
}
|
|
|
|
.n8n-node-title {
|
|
font-family: var(--font-display);
|
|
font-size: 14px;
|
|
font-weight: 600;
|
|
}
|
|
|
|
.n8n-field {
|
|
display: grid;
|
|
grid-template-columns: 130px 1fr;
|
|
gap: 8px;
|
|
align-items: center;
|
|
margin-bottom: 8px;
|
|
}
|
|
|
|
.n8n-field-label { font-size: 12px; color: var(--text-muted); }
|
|
|
|
.n8n-field-value {
|
|
font-family: var(--font-mono);
|
|
font-size: 12px;
|
|
background: rgba(0,0,0,0.3);
|
|
border: 1px solid var(--border);
|
|
border-radius: 4px;
|
|
padding: 4px 8px;
|
|
color: #a5f3fc;
|
|
}
|
|
|
|
/* ══════════════════════════════════════════
|
|
QR TYPES
|
|
══════════════════════════════════════════ */
|
|
.qr-types-grid {
|
|
display: grid;
|
|
grid-template-columns: repeat(4, 1fr);
|
|
gap: 14px;
|
|
}
|
|
|
|
.qr-type-card {
|
|
background: var(--bg-card);
|
|
border: 1px solid var(--border);
|
|
border-radius: var(--radius-md);
|
|
padding: 24px 18px;
|
|
text-align: center;
|
|
transition: var(--transition);
|
|
}
|
|
.qr-type-card:hover {
|
|
border-color: var(--border-bright);
|
|
background: var(--bg-elevated);
|
|
transform: translateY(-2px);
|
|
}
|
|
|
|
.qr-type-icon { font-size: 28px; margin-bottom: 12px; display: block; }
|
|
.qr-type-name { font-family: var(--font-display); font-size: 15px; font-weight: 700; margin-bottom: 6px; }
|
|
|
|
.qr-type-badge {
|
|
font-family: var(--font-mono);
|
|
font-size: 11px;
|
|
color: var(--indigo);
|
|
background: rgba(99,102,241,0.1);
|
|
border: 1px solid rgba(99,102,241,0.2);
|
|
padding: 2px 8px;
|
|
border-radius: 4px;
|
|
margin-bottom: 8px;
|
|
display: inline-block;
|
|
}
|
|
|
|
.qr-type-desc { font-size: 12px; color: var(--text-muted); }
|
|
|
|
/* ══════════════════════════════════════════
|
|
PRICING
|
|
══════════════════════════════════════════ */
|
|
.pricing-grid {
|
|
display: grid;
|
|
grid-template-columns: repeat(4, 1fr);
|
|
gap: 18px;
|
|
}
|
|
|
|
.pricing-card {
|
|
background: var(--bg-card);
|
|
border: 1px solid var(--border);
|
|
border-radius: var(--radius-lg);
|
|
padding: 28px 22px;
|
|
position: relative;
|
|
transition: var(--transition);
|
|
}
|
|
.pricing-card:hover {
|
|
border-color: var(--border-bright);
|
|
transform: translateY(-4px);
|
|
box-shadow: 0 20px 40px rgba(0,0,0,0.4);
|
|
}
|
|
|
|
.pricing-card.featured {
|
|
border-color: rgba(99,102,241,0.4);
|
|
background: linear-gradient(135deg, rgba(99,102,241,0.08), rgba(139,92,246,0.04));
|
|
box-shadow: 0 0 0 1px rgba(99,102,241,0.1), 0 20px 40px rgba(99,102,241,0.08);
|
|
}
|
|
|
|
.pricing-featured-badge {
|
|
position: absolute;
|
|
top: -12px;
|
|
left: 50%;
|
|
transform: translateX(-50%);
|
|
background: linear-gradient(135deg, var(--indigo), var(--violet));
|
|
color: white;
|
|
font-size: 11px;
|
|
font-weight: 600;
|
|
padding: 4px 14px;
|
|
border-radius: 100px;
|
|
white-space: nowrap;
|
|
}
|
|
|
|
.pricing-tier {
|
|
font-family: var(--font-mono);
|
|
font-size: 11px;
|
|
color: var(--indigo);
|
|
letter-spacing: 0.1em;
|
|
text-transform: uppercase;
|
|
margin-bottom: 10px;
|
|
}
|
|
|
|
.pricing-price {
|
|
font-family: var(--font-display);
|
|
font-size: 34px;
|
|
font-weight: 800;
|
|
margin-bottom: 4px;
|
|
line-height: 1;
|
|
}
|
|
|
|
.pricing-price .currency { font-size: 17px; font-weight: 400; color: var(--text-secondary); vertical-align: super; }
|
|
.pricing-price .period { font-size: 13px; font-weight: 400; color: var(--text-muted); }
|
|
|
|
.pricing-desc {
|
|
font-size: 13px;
|
|
color: var(--text-muted);
|
|
margin-bottom: 20px;
|
|
margin-top: 6px;
|
|
}
|
|
|
|
.pricing-divider { border: none; border-top: 1px solid var(--border); margin: 18px 0; }
|
|
|
|
.pricing-features {
|
|
list-style: none;
|
|
display: flex;
|
|
flex-direction: column;
|
|
gap: 9px;
|
|
margin-bottom: 22px;
|
|
}
|
|
|
|
.pricing-feature {
|
|
display: flex;
|
|
align-items: flex-start;
|
|
gap: 9px;
|
|
font-size: 13px;
|
|
color: var(--text-secondary);
|
|
}
|
|
.pricing-feature::before {
|
|
content: '✓';
|
|
color: var(--emerald);
|
|
font-size: 12px;
|
|
flex-shrink: 0;
|
|
margin-top: 2px;
|
|
}
|
|
|
|
.pricing-cta {
|
|
width: 100%;
|
|
text-align: center;
|
|
padding: 10px;
|
|
border-radius: var(--radius-sm);
|
|
font-family: var(--font-body);
|
|
font-size: 13px;
|
|
font-weight: 600;
|
|
cursor: pointer;
|
|
text-decoration: none;
|
|
display: block;
|
|
transition: var(--transition);
|
|
}
|
|
|
|
.pricing-cta-ghost {
|
|
background: transparent;
|
|
border: 1px solid var(--border);
|
|
color: var(--text-secondary);
|
|
}
|
|
.pricing-cta-ghost:hover {
|
|
border-color: var(--border-bright);
|
|
color: var(--text-primary);
|
|
}
|
|
|
|
.pricing-cta-primary {
|
|
background: linear-gradient(135deg, var(--indigo), var(--violet));
|
|
border: none;
|
|
color: white;
|
|
}
|
|
.pricing-cta-primary:hover {
|
|
box-shadow: 0 0 20px rgba(99,102,241,0.4);
|
|
transform: translateY(-1px);
|
|
}
|
|
|
|
/* ══════════════════════════════════════════
|
|
RESPONSE FORMAT
|
|
══════════════════════════════════════════ */
|
|
.response-section { background: rgba(13,13,26,0.5); }
|
|
|
|
.response-grid {
|
|
display: grid;
|
|
grid-template-columns: 1fr 1fr;
|
|
gap: 48px;
|
|
align-items: start;
|
|
}
|
|
|
|
.response-features { display: flex; flex-direction: column; gap: 22px; }
|
|
|
|
.response-feature { display: flex; gap: 16px; }
|
|
|
|
.response-feature-icon {
|
|
width: 40px; height: 40px;
|
|
background: rgba(99,102,241,0.1);
|
|
border: 1px solid rgba(99,102,241,0.2);
|
|
border-radius: var(--radius-sm);
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: center;
|
|
font-size: 18px;
|
|
flex-shrink: 0;
|
|
}
|
|
|
|
.response-feature-title { font-family: var(--font-display); font-size: 15px; font-weight: 600; margin-bottom: 4px; }
|
|
.response-feature-desc { font-size: 13px; color: var(--text-secondary); line-height: 1.55; }
|
|
|
|
/* ══════════════════════════════════════════
|
|
FINAL CTA
|
|
══════════════════════════════════════════ */
|
|
.final-cta {
|
|
padding: 120px 24px;
|
|
text-align: center;
|
|
position: relative;
|
|
overflow: hidden;
|
|
}
|
|
|
|
.final-cta::before {
|
|
content: '';
|
|
position: absolute;
|
|
width: 700px; height: 700px;
|
|
border-radius: 50%;
|
|
background: radial-gradient(circle, rgba(99,102,241,0.13) 0%, transparent 70%);
|
|
left: 50%; top: 50%;
|
|
transform: translate(-50%, -50%);
|
|
pointer-events: none;
|
|
}
|
|
|
|
.final-cta-title {
|
|
font-family: var(--font-display);
|
|
font-size: clamp(32px, 5vw, 52px);
|
|
font-weight: 800;
|
|
letter-spacing: -0.03em;
|
|
margin-bottom: 16px;
|
|
}
|
|
|
|
.final-cta-sub {
|
|
font-size: 18px;
|
|
color: var(--text-secondary);
|
|
margin-bottom: 40px;
|
|
font-weight: 300;
|
|
}
|
|
|
|
/* ══════════════════════════════════════════
|
|
FOOTER
|
|
══════════════════════════════════════════ */
|
|
footer {
|
|
padding: 28px 24px;
|
|
border-top: 1px solid var(--border);
|
|
}
|
|
|
|
.footer-inner {
|
|
max-width: 1100px;
|
|
margin: 0 auto;
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: space-between;
|
|
flex-wrap: wrap;
|
|
gap: 16px;
|
|
}
|
|
|
|
.footer-links { display: flex; gap: 20px; }
|
|
|
|
.footer-link {
|
|
font-size: 13px;
|
|
color: var(--text-muted);
|
|
text-decoration: none;
|
|
transition: var(--transition);
|
|
}
|
|
.footer-link:hover { color: var(--text-secondary); }
|
|
|
|
.footer-copy { font-size: 13px; color: var(--text-muted); }
|
|
|
|
/* ══════════════════════════════════════════
|
|
ANIMATIONS
|
|
══════════════════════════════════════════ */
|
|
@keyframes fadeUp {
|
|
from { opacity: 0; transform: translateY(20px); }
|
|
to { opacity: 1; transform: translateY(0); }
|
|
}
|
|
@keyframes fadeIn {
|
|
from { opacity: 0; }
|
|
to { opacity: 1; }
|
|
}
|
|
@keyframes blink {
|
|
0%, 100% { opacity: 1; }
|
|
50% { opacity: 0; }
|
|
}
|
|
@keyframes pulse {
|
|
0%, 100% { opacity: 1; transform: scale(1); }
|
|
50% { opacity: 0.5; transform: scale(0.8); }
|
|
}
|
|
|
|
.reveal {
|
|
opacity: 0;
|
|
transform: translateY(22px);
|
|
transition: opacity 0.65s ease, transform 0.65s ease;
|
|
}
|
|
.reveal.visible {
|
|
opacity: 1;
|
|
transform: translateY(0);
|
|
}
|
|
|
|
/* ══════════════════════════════════════════
|
|
RESPONSIVE
|
|
══════════════════════════════════════════ */
|
|
@media (max-width: 900px) {
|
|
.hero-inner { grid-template-columns: 1fr; }
|
|
.terminal { display: none; }
|
|
.steps { grid-template-columns: 1fr; }
|
|
.step-arrow { display: none; }
|
|
.qr-types-grid { grid-template-columns: repeat(2, 1fr); }
|
|
.pricing-grid { grid-template-columns: repeat(2, 1fr); }
|
|
.response-grid { grid-template-columns: 1fr; }
|
|
}
|
|
|
|
@media (max-width: 600px) {
|
|
.nav-links { display: none; }
|
|
.qr-types-grid { grid-template-columns: repeat(2, 1fr); }
|
|
.pricing-grid { grid-template-columns: 1fr; }
|
|
.hero-stats { flex-wrap: wrap; gap: 20px; }
|
|
.tabs { width: 100%; }
|
|
.tab-btn { flex: 1; text-align: center; }
|
|
.integrations-inner { justify-content: center; }
|
|
}
|
|
</style>
|
|
</head>
|
|
<body>
|
|
|
|
<!-- ═══════ NAV ═══════ -->
|
|
<nav>
|
|
<div class="nav-inner">
|
|
<a href="https://qrrapido.site" class="nav-logo">
|
|
<div class="nav-logo-icon">▦</div>
|
|
QR Rápido
|
|
<span class="nav-badge">MCP</span>
|
|
</a>
|
|
<div class="nav-links">
|
|
<a href="#como-funciona" class="nav-link">Como funciona</a>
|
|
<a href="#tipos" class="nav-link">Tipos de QR</a>
|
|
<a href="#precos" class="nav-link">Preços</a>
|
|
<a href="https://qrrapido.site/api/docs" class="nav-link">Docs API</a>
|
|
<a href="/Account/Login?returnUrl=/Developer?new=1" class="btn btn-primary">Começar grátis →</a>
|
|
</div>
|
|
</div>
|
|
</nav>
|
|
|
|
<!-- ═══════ HERO ═══════ -->
|
|
<section class="hero">
|
|
<div class="hero-inner">
|
|
<div class="hero-content">
|
|
<div class="hero-tag">
|
|
<div class="hero-tag-dot"></div>
|
|
MCP · REST API · n8n · Make.com
|
|
</div>
|
|
|
|
<h1 class="hero-title">
|
|
QR codes para<br>
|
|
<span class="accent">agentes de IA</span><br>
|
|
e automações
|
|
</h1>
|
|
|
|
<p class="hero-subtitle">
|
|
Gere QR codes via MCP, REST API ou qualquer HTTP client.
|
|
Resposta <strong style="color: var(--text-primary); font-weight: 500;">base64 inline</strong> —
|
|
sem upload, sem hosting de arquivo, pronto para usar.
|
|
</p>
|
|
|
|
<div class="hero-actions">
|
|
<a href="/Account/Login?returnUrl=/Developer?new=1" class="btn btn-primary btn-lg">Começar grátis →</a>
|
|
<a href="https://qrrapido.site/api/docs" class="btn btn-ghost btn-lg">Ver documentação</a>
|
|
</div>
|
|
|
|
<div class="hero-stats">
|
|
<div class="stat">
|
|
<div class="stat-value"><0.4s</div>
|
|
<div class="stat-label">geração média</div>
|
|
</div>
|
|
<div class="stat">
|
|
<div class="stat-value">8 tipos</div>
|
|
<div class="stat-label">de QR code</div>
|
|
</div>
|
|
<div class="stat">
|
|
<div class="stat-value">base64</div>
|
|
<div class="stat-label">inline, sem hosting</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Animated terminal -->
|
|
<div class="terminal" id="hero-terminal">
|
|
<div class="terminal-header">
|
|
<div class="dot dot-r"></div>
|
|
<div class="dot dot-y"></div>
|
|
<div class="dot dot-g"></div>
|
|
<span class="terminal-title">claude — MCP Tool Call</span>
|
|
</div>
|
|
<div class="terminal-body" id="terminal-body"></div>
|
|
</div>
|
|
</div>
|
|
</section>
|
|
|
|
<!-- ═══════ INTEGRATIONS ═══════ -->
|
|
<div class="integrations">
|
|
<div class="integrations-inner">
|
|
<span class="integrations-label">FUNCIONA COM</span>
|
|
<div class="integrations-list">
|
|
<div class="integration-badge"><span>🤖</span> Claude Desktop</div>
|
|
<div class="integration-badge"><span>🔄</span> n8n</div>
|
|
<div class="integration-badge"><span>⚙️</span> Make.com</div>
|
|
<div class="integration-badge"><span>⚡</span> Zapier</div>
|
|
<div class="integration-badge"><span>🔌</span> REST API</div>
|
|
<div class="integration-badge"><span>📡</span> Qualquer HTTP client</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- ═══════ HOW IT WORKS ═══════ -->
|
|
<section class="section" id="como-funciona">
|
|
<div class="container">
|
|
<div class="reveal">
|
|
<div class="section-label">// como funciona</div>
|
|
<h2 class="section-title">Três passos para<br>começar a gerar</h2>
|
|
<p class="section-sub">Do zero ao QR code no seu agente em menos de 2 minutos. Sem cartão de crédito.</p>
|
|
</div>
|
|
|
|
<div class="steps reveal">
|
|
<div class="step">
|
|
<div class="step-number">01</div>
|
|
<div class="step-card">
|
|
<div class="step-icon">👤</div>
|
|
<div class="step-title">Crie sua conta</div>
|
|
<p class="step-desc">Login gratuito com Google ou Microsoft. Plano grátis com 500 req/mês incluso. Sem cartão de crédito.</p>
|
|
</div>
|
|
<div class="step-arrow">→</div>
|
|
</div>
|
|
|
|
<div class="step">
|
|
<div class="step-number">02</div>
|
|
<div class="step-card">
|
|
<div class="step-icon">🔑</div>
|
|
<div class="step-title">Copie sua API key</div>
|
|
<p class="step-desc">Sua key é gerada automaticamente no primeiro acesso. Exibida em destaque — copie com um clique, snippet já pronto.</p>
|
|
</div>
|
|
<div class="step-arrow">→</div>
|
|
</div>
|
|
|
|
<div class="step">
|
|
<div class="step-number">03</div>
|
|
<div class="step-card">
|
|
<div class="step-icon">⚡</div>
|
|
<div class="step-title">Conecte ao agente</div>
|
|
<p class="step-desc">Cole no config do Claude Desktop, nó HTTP do n8n ou qualquer client. Pronto — seu agente já gera QR codes.</p>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</section>
|
|
|
|
<!-- ═══════ CODE SHOWCASE ═══════ -->
|
|
<section class="section code-showcase">
|
|
<div class="container">
|
|
<div class="reveal">
|
|
<div class="section-label">// integração</div>
|
|
<h2 class="section-title">Conecte do jeito<br>que preferir</h2>
|
|
<p class="section-sub">MCP nativo, REST API ou HTTP Request — a mesma API serve todos os clientes.</p>
|
|
</div>
|
|
|
|
<div class="reveal">
|
|
<div class="tabs">
|
|
<button class="tab-btn active" onclick="switchTab(event,'mcp')">Claude MCP</button>
|
|
<button class="tab-btn" onclick="switchTab(event,'rest')">REST API</button>
|
|
<button class="tab-btn" onclick="switchTab(event,'n8n')">n8n</button>
|
|
</div>
|
|
|
|
<!-- MCP -->
|
|
<div class="tab-content active" id="tab-mcp">
|
|
<div class="code-window">
|
|
<div class="code-header">
|
|
<div class="code-header-left">
|
|
<div class="code-dots">
|
|
<div class="dot dot-r"></div><div class="dot dot-y"></div><div class="dot dot-g"></div>
|
|
</div>
|
|
<span class="code-filename">claude_desktop_config.json</span>
|
|
</div>
|
|
<button class="copy-btn" onclick="copyCode('mcp-code', this)">copiar</button>
|
|
</div>
|
|
<pre id="mcp-code"><span class="hl-comment">// ~/.config/claude/claude_desktop_config.json</span>
|
|
{
|
|
<span class="hl-key">"mcpServers"</span>: {
|
|
<span class="hl-key">"qrrapido"</span>: {
|
|
<span class="hl-key">"command"</span>: <span class="hl-string">"qrrapido-mcp"</span>,
|
|
<span class="hl-key">"env"</span>: {
|
|
<span class="hl-key">"QR_API_KEY"</span>: <span class="hl-string">"qr_sua_key_aqui"</span>
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
<span class="hl-comment">// Claude Desktop passa a ter acesso às tools:</span>
|
|
<span class="hl-comment">// → generate_qr(type, content, format, color, size)</span>
|
|
<span class="hl-comment">// → list_qr_history()</span>
|
|
<span class="hl-comment">// → get_qr_analytics(trackingId)</span></pre>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- REST -->
|
|
<div class="tab-content" id="tab-rest">
|
|
<div class="code-window">
|
|
<div class="code-header">
|
|
<div class="code-header-left">
|
|
<div class="code-dots">
|
|
<div class="dot dot-r"></div><div class="dot dot-y"></div><div class="dot dot-g"></div>
|
|
</div>
|
|
<span class="code-filename">terminal</span>
|
|
</div>
|
|
<button class="copy-btn" onclick="copyCode('rest-code', this)">copiar</button>
|
|
</div>
|
|
<pre id="rest-code"><span class="hl-comment"># Gerar QR code via REST API</span>
|
|
curl -X POST <span class="hl-url">https://qrrapido.site/api/v1/QRManager/generate</span> \
|
|
-H <span class="hl-string">"X-API-Key: qr_sua_key_aqui"</span> \
|
|
-H <span class="hl-string">"Content-Type: application/json"</span> \
|
|
-d '{
|
|
<span class="hl-key">"type"</span>: <span class="hl-string">"url"</span>,
|
|
<span class="hl-key">"content"</span>: <span class="hl-string">"https://minha-loja.com/produto/123"</span>,
|
|
<span class="hl-key">"outputFormat"</span>: <span class="hl-string">"png"</span>,
|
|
<span class="hl-key">"size"</span>: <span class="hl-number">400</span>,
|
|
<span class="hl-key">"primaryColor"</span>: <span class="hl-string">"#000000"</span>
|
|
}'
|
|
|
|
<span class="hl-comment"># Resposta: JSON com qrCodeBase64 inline</span>
|
|
<span class="hl-comment"># Sem upload. Sem CDN. Pronto para usar.</span></pre>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- n8n -->
|
|
<div class="tab-content" id="tab-n8n">
|
|
<div class="code-window">
|
|
<div class="code-header">
|
|
<div class="code-header-left">
|
|
<div class="code-dots">
|
|
<div class="dot dot-r"></div><div class="dot dot-y"></div><div class="dot dot-g"></div>
|
|
</div>
|
|
<span class="code-filename">n8n — HTTP Request Node</span>
|
|
</div>
|
|
</div>
|
|
<div class="n8n-mockup">
|
|
<div class="n8n-node">
|
|
<div class="n8n-node-header">
|
|
<div class="n8n-node-icon" style="background:rgba(255,102,0,0.15);border:1px solid rgba(255,102,0,0.3);">🔄</div>
|
|
<div class="n8n-node-title">HTTP Request</div>
|
|
</div>
|
|
<div class="n8n-field"><span class="n8n-field-label">Method</span><span class="n8n-field-value">POST</span></div>
|
|
<div class="n8n-field"><span class="n8n-field-label">URL</span><span class="n8n-field-value" style="color:#4ade80;font-size:11px;">https://qrrapido.site/api/v1/QRManager/generate</span></div>
|
|
<div class="n8n-field"><span class="n8n-field-label">Auth Type</span><span class="n8n-field-value">Header Auth</span></div>
|
|
<div class="n8n-field"><span class="n8n-field-label">Header Name</span><span class="n8n-field-value">X-API-Key</span></div>
|
|
<div class="n8n-field"><span class="n8n-field-label">Header Value</span><span class="n8n-field-value">qr_sua_key_aqui</span></div>
|
|
<div class="n8n-field"><span class="n8n-field-label">Body (JSON)</span><span class="n8n-field-value">{"type":"url","content":"{{ $json.url }}"}</span></div>
|
|
</div>
|
|
<div class="n8n-node" style="background:rgba(16,185,129,0.05);border-color:rgba(16,185,129,0.15);">
|
|
<div class="n8n-node-header">
|
|
<div class="n8n-node-icon" style="background:rgba(16,185,129,0.15);border:1px solid rgba(16,185,129,0.3);">✓</div>
|
|
<div class="n8n-node-title" style="color:#10b981;">Output disponível</div>
|
|
</div>
|
|
<p style="font-size:12px;color:var(--text-muted);line-height:1.6;">
|
|
Use <code style="color:#a5f3fc;font-family:var(--font-mono);">{{ $json.qrCodeBase64 }}</code> nos nós seguintes
|
|
para enviar por email, salvar em arquivo ou retornar via webhook — sem URL externa.
|
|
</p>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</section>
|
|
|
|
<!-- ═══════ QR TYPES ═══════ -->
|
|
<section class="section" id="tipos">
|
|
<div class="container">
|
|
<div class="reveal">
|
|
<div class="section-label">// tipos suportados</div>
|
|
<h2 class="section-title">8 tipos de QR code,<br>um único endpoint</h2>
|
|
<p class="section-sub">Passe o <code style="font-family:var(--font-mono);color:var(--indigo);font-size:15px;">"type"</code> no payload e o QR Rápido cuida do formato correto.</p>
|
|
</div>
|
|
|
|
<div class="qr-types-grid reveal">
|
|
<div class="qr-type-card">
|
|
<span class="qr-type-icon">🔗</span>
|
|
<div class="qr-type-name">URL</div>
|
|
<div class="qr-type-badge">"url"</div>
|
|
<p class="qr-type-desc">Links, produtos, landing pages</p>
|
|
</div>
|
|
<div class="qr-type-card">
|
|
<span class="qr-type-icon">💸</span>
|
|
<div class="qr-type-name">PIX</div>
|
|
<div class="qr-type-badge">"pix"</div>
|
|
<p class="qr-type-desc">Pagamentos instantâneos brasileiros</p>
|
|
</div>
|
|
<div class="qr-type-card">
|
|
<span class="qr-type-icon">📶</span>
|
|
<div class="qr-type-name">Wi-Fi</div>
|
|
<div class="qr-type-badge">"wifi"</div>
|
|
<p class="qr-type-desc">Credenciais de rede sem fio</p>
|
|
</div>
|
|
<div class="qr-type-card">
|
|
<span class="qr-type-icon">👤</span>
|
|
<div class="qr-type-name">vCard</div>
|
|
<div class="qr-type-badge">"vcard"</div>
|
|
<p class="qr-type-desc">Cartões de visita digitais</p>
|
|
</div>
|
|
<div class="qr-type-card">
|
|
<span class="qr-type-icon">💬</span>
|
|
<div class="qr-type-name">WhatsApp</div>
|
|
<div class="qr-type-badge">"whatsapp"</div>
|
|
<p class="qr-type-desc">Mensagens pré-preenchidas</p>
|
|
</div>
|
|
<div class="qr-type-card">
|
|
<span class="qr-type-icon">📧</span>
|
|
<div class="qr-type-name">Email</div>
|
|
<div class="qr-type-badge">"email"</div>
|
|
<p class="qr-type-desc">Composição de email direta</p>
|
|
</div>
|
|
<div class="qr-type-card">
|
|
<span class="qr-type-icon">📱</span>
|
|
<div class="qr-type-name">SMS</div>
|
|
<div class="qr-type-badge">"sms"</div>
|
|
<p class="qr-type-desc">Texto SMS pré-definido</p>
|
|
</div>
|
|
<div class="qr-type-card">
|
|
<span class="qr-type-icon">📝</span>
|
|
<div class="qr-type-name">Texto</div>
|
|
<div class="qr-type-badge">"texto"</div>
|
|
<p class="qr-type-desc">Qualquer conteúdo em texto livre</p>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</section>
|
|
|
|
<!-- ═══════ RESPONSE FORMAT ═══════ -->
|
|
<section class="section response-section">
|
|
<div class="container">
|
|
<div class="response-grid">
|
|
<div>
|
|
<div class="reveal">
|
|
<div class="section-label">// resposta da API</div>
|
|
<h2 class="section-title">Base64 inline.<br>Sem hosting.</h2>
|
|
<p class="section-sub">O QR code retorna direto no JSON. Seu agente recebe, usa e segue em frente — sem URL externa, sem upload.</p>
|
|
</div>
|
|
|
|
<div class="response-features reveal">
|
|
<div class="response-feature">
|
|
<div class="response-feature-icon">📦</div>
|
|
<div>
|
|
<div class="response-feature-title">Imagem no JSON</div>
|
|
<p class="response-feature-desc">Base64 embutido na resposta. Agentes usam direto — sem depender de URL de terceiros ou CDN.</p>
|
|
</div>
|
|
</div>
|
|
<div class="response-feature">
|
|
<div class="response-feature-icon">⚡</div>
|
|
<div>
|
|
<div class="response-feature-title">Cache automático</div>
|
|
<p class="response-feature-desc">QRs idênticos retornam do cache em milissegundos. <code style="font-family:var(--font-mono);color:var(--indigo);font-size:12px;">fromCache: true</code> indica hit.</p>
|
|
</div>
|
|
</div>
|
|
<div class="response-feature">
|
|
<div class="response-feature-icon">🎯</div>
|
|
<div>
|
|
<div class="response-feature-title">3 formatos de saída</div>
|
|
<p class="response-feature-desc">PNG, WebP (~40% menor) ou SVG vetorial. Escolha por request via <code style="font-family:var(--font-mono);color:var(--indigo);font-size:12px;">outputFormat</code>.</p>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="reveal">
|
|
<div class="code-window">
|
|
<div class="code-header">
|
|
<div class="code-header-left">
|
|
<div class="code-dots">
|
|
<div class="dot dot-r"></div><div class="dot dot-y"></div><div class="dot dot-g"></div>
|
|
</div>
|
|
<span class="code-filename">response.json</span>
|
|
</div>
|
|
<button class="copy-btn" onclick="copyCode('response-code', this)">copiar</button>
|
|
</div>
|
|
<pre id="response-code">{
|
|
<span class="hl-key">"success"</span>: <span class="hl-bool">true</span>,
|
|
<span class="hl-key">"qrCodeBase64"</span>: <span class="hl-string">"iVBORw0KGgoAAAANSUhEUgAA..."</span>,
|
|
<span class="hl-key">"qrId"</span>: <span class="hl-string">"6842a1f3b8c94d2e..."</span>,
|
|
<span class="hl-key">"format"</span>: <span class="hl-string">"png"</span>,
|
|
<span class="hl-key">"mimeType"</span>: <span class="hl-string">"image/png"</span>,
|
|
<span class="hl-key">"generationTimeMs"</span>: <span class="hl-number">312</span>,
|
|
<span class="hl-key">"fromCache"</span>: <span class="hl-bool">false</span>,
|
|
<span class="hl-key">"remainingCredits"</span>: <span class="hl-number">487</span>,
|
|
<span class="hl-key">"message"</span>: <span class="hl-string">"QR gerado com sucesso"</span>
|
|
}</pre>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</section>
|
|
|
|
<!-- ═══════ PRICING ═══════ -->
|
|
<section class="section" id="precos">
|
|
<div class="container">
|
|
<div class="reveal" style="text-align:center;margin-bottom:60px;">
|
|
<div class="section-label">// planos</div>
|
|
<h2 class="section-title">Comece grátis.<br>Escale quando precisar.</h2>
|
|
<p class="section-sub" style="margin:0 auto;">Sem cartão de crédito para começar. Upgrade a qualquer momento.</p>
|
|
</div>
|
|
|
|
<div class="pricing-grid reveal">
|
|
<!-- Free -->
|
|
<div class="pricing-card">
|
|
<div class="pricing-tier">FREE</div>
|
|
<div class="pricing-price">Grátis</div>
|
|
<p class="pricing-desc">Para testar e projetos pequenos</p>
|
|
<hr class="pricing-divider">
|
|
<ul class="pricing-features">
|
|
<li class="pricing-feature">500 req/mês</li>
|
|
<li class="pricing-feature">10 req/minuto</li>
|
|
<li class="pricing-feature">Todos os 8 tipos de QR</li>
|
|
<li class="pricing-feature">PNG, WebP, SVG</li>
|
|
<li class="pricing-feature">Cache automático</li>
|
|
</ul>
|
|
<a href="/Account/Login?returnUrl=/Developer?new=1" class="pricing-cta pricing-cta-ghost">Começar grátis</a>
|
|
</div>
|
|
|
|
<!-- Starter -->
|
|
<div class="pricing-card">
|
|
<div class="pricing-tier">STARTER</div>
|
|
<div class="pricing-price"><span class="currency">R$</span>39<span class="period">/mês</span></div>
|
|
<p class="pricing-desc">Para automações e workflows</p>
|
|
<hr class="pricing-divider">
|
|
<ul class="pricing-features">
|
|
<li class="pricing-feature">10.000 req/mês</li>
|
|
<li class="pricing-feature">50 req/minuto</li>
|
|
<li class="pricing-feature">Todos os 8 tipos de QR</li>
|
|
<li class="pricing-feature">PNG, WebP, SVG</li>
|
|
<li class="pricing-feature">Suporte por email</li>
|
|
</ul>
|
|
<a href="https://qrrapido.site/Developer/Pricing" class="pricing-cta pricing-cta-ghost">Assinar Starter</a>
|
|
</div>
|
|
|
|
<!-- Pro -->
|
|
<div class="pricing-card featured">
|
|
<div class="pricing-featured-badge">Mais popular</div>
|
|
<div class="pricing-tier">PRO</div>
|
|
<div class="pricing-price"><span class="currency">R$</span>119<span class="period">/mês</span></div>
|
|
<p class="pricing-desc">Para agentes e produtos em produção</p>
|
|
<hr class="pricing-divider">
|
|
<ul class="pricing-features">
|
|
<li class="pricing-feature">100.000 req/mês</li>
|
|
<li class="pricing-feature">200 req/minuto</li>
|
|
<li class="pricing-feature">QR dinâmico + tracking</li>
|
|
<li class="pricing-feature">Analytics de scans</li>
|
|
<li class="pricing-feature">Suporte prioritário</li>
|
|
</ul>
|
|
<a href="https://qrrapido.site/Developer/Pricing" class="pricing-cta pricing-cta-primary">Assinar Pro</a>
|
|
</div>
|
|
|
|
<!-- Business -->
|
|
<div class="pricing-card">
|
|
<div class="pricing-tier">BUSINESS</div>
|
|
<div class="pricing-price"><span class="currency">R$</span>349<span class="period">/mês</span></div>
|
|
<p class="pricing-desc">Para alto volume e equipes</p>
|
|
<hr class="pricing-divider">
|
|
<ul class="pricing-features">
|
|
<li class="pricing-feature">500.000 req/mês</li>
|
|
<li class="pricing-feature">500 req/minuto</li>
|
|
<li class="pricing-feature">QR dinâmico + tracking</li>
|
|
<li class="pricing-feature">5 API keys simultâneas</li>
|
|
<li class="pricing-feature">SLA + suporte dedicado</li>
|
|
</ul>
|
|
<a href="https://qrrapido.site/Developer/Pricing" class="pricing-cta pricing-cta-ghost">Assinar Business</a>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</section>
|
|
|
|
<!-- ═══════ FINAL CTA ═══════ -->
|
|
<section class="final-cta">
|
|
<div class="container">
|
|
<div class="reveal">
|
|
<h2 class="final-cta-title">
|
|
Comece em<br>
|
|
<span style="background:linear-gradient(135deg,var(--indigo),var(--violet));-webkit-background-clip:text;-webkit-text-fill-color:transparent;background-clip:text;">2 minutos</span>
|
|
</h2>
|
|
<p class="final-cta-sub">Login gratuito. Key gerada automaticamente. Snippet pronto para copiar.</p>
|
|
<a href="/Account/Login?returnUrl=/Developer?new=1" class="btn btn-primary btn-lg">Criar conta grátis →</a>
|
|
</div>
|
|
</div>
|
|
</section>
|
|
|
|
<!-- ═══════ FOOTER ═══════ -->
|
|
<footer>
|
|
<div class="footer-inner">
|
|
<a href="https://qrrapido.site" class="nav-logo" style="font-size:15px;">
|
|
<div class="nav-logo-icon" style="width:26px;height:26px;font-size:13px;">▦</div>
|
|
QR Rápido
|
|
</a>
|
|
<div class="footer-links">
|
|
<a href="https://qrrapido.site/api/docs" class="footer-link">API Docs</a>
|
|
<a href="https://qrrapido.site/Developer/Pricing" class="footer-link">Preços</a>
|
|
<a href="https://qrrapido.site/pt-BR/Home/TermosDeUso" class="footer-link">Termos</a>
|
|
<a href="https://qrrapido.site/pt-BR/Home/PoliticaDePrivacidade" class="footer-link">Privacidade</a>
|
|
</div>
|
|
<p class="footer-copy">© 2025 QR Rápido · Feito no Brasil 🇧🇷</p>
|
|
</div>
|
|
</footer>
|
|
|
|
<script>
|
|
/* ══════════════════════════════════════
|
|
TERMINAL ANIMATION
|
|
══════════════════════════════════════ */
|
|
const lines = [
|
|
{ html: '<span class="t-prompt">→</span> Tool: <span class="t-tool">generate_qr</span>', delay: 400 },
|
|
{ html: '', delay: 600 },
|
|
{ html: ' <span class="t-key">type</span>: <span class="t-string">"url"</span>', delay: 800 },
|
|
{ html: ' <span class="t-key">content</span>: <span class="t-string">"https://minha-loja.com"</span>',delay: 1050 },
|
|
{ html: ' <span class="t-key">format</span>: <span class="t-string">"png"</span>', delay: 1300 },
|
|
{ html: ' <span class="t-key">size</span>: <span class="t-value">400</span>', delay: 1550 },
|
|
{ html: '', delay: 1750 },
|
|
{ html: '<span class="t-dim">⠸ Gerando QR code...</span>', delay: 1950 },
|
|
{ html: '', delay: 2800 },
|
|
{ html: '<span class="t-success">✓ Concluído em 312ms</span>', delay: 3000 },
|
|
{ html: '', delay: 3200 },
|
|
{ html: ' <span class="t-key">qrCodeBase64</span>: <span class="t-string">"iVBORw0KGgo..."</span>', delay: 3400 },
|
|
{ html: ' <span class="t-key">fromCache</span>: <span class="t-value">false</span>', delay: 3600 },
|
|
{ html: ' <span class="t-key">generationTimeMs</span>: <span class="t-value">312</span>', delay: 3800 },
|
|
{ html: ' <span class="t-key">remainingCredits</span>: <span class="t-value">487</span>', delay: 4000 },
|
|
{ html: '', delay: 4200 },
|
|
{ html: '<span class="t-comment">// base64 inline — sem hosting, sem upload</span>', delay: 4400 },
|
|
];
|
|
|
|
function animateTerminal() {
|
|
const body = document.getElementById('terminal-body');
|
|
if (!body) return;
|
|
|
|
lines.forEach((line, i) => {
|
|
setTimeout(() => {
|
|
const el = document.createElement('span');
|
|
el.className = 'terminal-line';
|
|
el.innerHTML = line.html || ' ';
|
|
body.appendChild(el);
|
|
requestAnimationFrame(() => { el.style.opacity = '1'; });
|
|
|
|
if (i === lines.length - 1) {
|
|
setTimeout(() => {
|
|
const cursor = document.createElement('span');
|
|
cursor.className = 'cursor';
|
|
body.appendChild(cursor);
|
|
}, 300);
|
|
}
|
|
}, line.delay);
|
|
});
|
|
}
|
|
|
|
/* ══════════════════════════════════════
|
|
TABS
|
|
══════════════════════════════════════ */
|
|
function switchTab(e, tab) {
|
|
document.querySelectorAll('.tab-btn').forEach(b => b.classList.remove('active'));
|
|
document.querySelectorAll('.tab-content').forEach(c => c.classList.remove('active'));
|
|
e.target.classList.add('active');
|
|
document.getElementById('tab-' + tab).classList.add('active');
|
|
}
|
|
|
|
/* ══════════════════════════════════════
|
|
COPY CODE
|
|
══════════════════════════════════════ */
|
|
function copyCode(id, btn) {
|
|
const text = document.getElementById(id).innerText;
|
|
navigator.clipboard.writeText(text).then(() => {
|
|
btn.textContent = 'copiado!';
|
|
btn.style.color = 'var(--emerald)';
|
|
setTimeout(() => { btn.textContent = 'copiar'; btn.style.color = ''; }, 2000);
|
|
});
|
|
}
|
|
|
|
/* ══════════════════════════════════════
|
|
SCROLL REVEAL
|
|
══════════════════════════════════════ */
|
|
const observer = new IntersectionObserver(entries => {
|
|
entries.forEach(e => { if (e.isIntersecting) e.target.classList.add('visible'); });
|
|
}, { threshold: 0.08 });
|
|
|
|
document.querySelectorAll('.reveal').forEach(el => observer.observe(el));
|
|
|
|
/* ══════════════════════════════════════
|
|
INIT
|
|
══════════════════════════════════════ */
|
|
window.addEventListener('load', animateTerminal);
|
|
</script>
|
|
</body>
|
|
</html>
|