@danhachuel/prodmaker 0.1.10 → 0.1.11

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -15,8 +15,8 @@
15
15
  rel="stylesheet"
16
16
  href="https://fonts.googleapis.com/css2?family=Material+Symbols+Outlined:opsz,wght,FILL,GRAD@24,400,0..1,0&display=block"
17
17
  />
18
- <script type="module" crossorigin src="/assets/index-EOri3RlA.js"></script>
19
- <link rel="stylesheet" crossorigin href="/assets/index-B88UVmZI.css">
18
+ <script type="module" crossorigin src="/assets/index-DGhGACYG.js"></script>
19
+ <link rel="stylesheet" crossorigin href="/assets/index-B4wxnTCs.css">
20
20
  </head>
21
21
  <body>
22
22
  <div id="root"></div>
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@danhachuel/prodmaker",
3
- "version": "0.1.10",
3
+ "version": "0.1.11",
4
4
  "description": "ProdMaker — SaaS local para criação de infoprodutos, landing pages, campanhas e tracking (base AdsX).",
5
5
  "license": "MIT",
6
6
  "type": "module",
package/requirements.txt CHANGED
@@ -11,3 +11,7 @@ xhtml2pdf
11
11
  # AdsPages (clonagem + verificação de domínios)
12
12
  beautifulsoup4
13
13
  dnspython
14
+ # Notificações (apprise) e Pinterest (py3-pinterest) — imports são preguiçosos:
15
+ # o servidor sobe sem eles; a ação que os usa informa se faltar instalar.
16
+ apprise
17
+ py3-pinterest
package/scripts/cli.mjs CHANGED
@@ -14,7 +14,7 @@ const __dirname = path.dirname(fileURLToPath(import.meta.url));
14
14
  const PKG_ROOT = path.resolve(__dirname, "..");
15
15
  const APP_DIR = path.join(PKG_ROOT, "app");
16
16
  const REQUIREMENTS = path.join(PKG_ROOT, "requirements.txt");
17
- const APP_VERSION = "0.1.10";
17
+ const APP_VERSION = "0.1.11";
18
18
  const DEFAULT_PORT = 8188;
19
19
 
20
20
  const STORAGE_FOLDERS = ["state", "pages", "produtos", "artifacts", "downloads", "logs"];
@@ -0,0 +1,39 @@
1
+ # Pixel de Rastreamento (/track) e túneis
2
+
3
+ O ProdMaker rastreia visitas das suas páginas com um **pixel próprio** — sem scripts de terceiros.
4
+
5
+ ## Como funciona
6
+
7
+ 1. Ao gerar uma página (AdsPages), o pixel do ProdMaker é embutido automaticamente **quando**
8
+ houver uma "URL pública do /track" configurada em Chaves de API → Pixel de Rastreamento.
9
+ 2. O pixel envia `sendBeacon` com: evento (pageview, clique em CTA, unload), página, gclid,
10
+ utm_source, utm_medium, utm_campaign e referrer. O backend grava na tabela `visitas`.
11
+ 3. As visitas aparecem em AdsTracking → Minhas Visitas, e vendas com GCLID são cruzadas
12
+ automaticamente com a visita de origem (matching 🎯).
13
+
14
+ ## URL pública em máquina local
15
+
16
+ Como o ProdMaker roda localmente (127.0.0.1), plataformas e visitantes externos não o alcançam.
17
+ Use um túnel:
18
+
19
+ ```bash
20
+ # cloudflared (recomendado)
21
+ cloudflared tunnel --url http://localhost:8188
22
+ # copie a URL gerada (ex.: https://nome-aleatorio.trycloudflare.com)
23
+ # → configure no card Pixel de Rastreamento: https://nome-aleatorio.trycloudflare.com/track
24
+ ```
25
+
26
+ Alternativas: ngrok, localhost.run, serveo.
27
+
28
+ ## Eventos
29
+
30
+ | Evento | Quando | Dados capturados |
31
+ |---|---|---|
32
+ | pageview | carregamento da página | gclid, utm_*, referrer |
33
+ | cta_click | clique em link/CTA | href do link |
34
+ | unload | saída da página | segundos na página |
35
+
36
+ ## Drenagem de orçamento
37
+
38
+ Visitantes com 4+ cliques em CTA aparecem no alerta de POSSÍVEL DRENAGEM — use a lista
39
+ para negativar no Google Ads (critério: campanha → lista de exclusão de IPs).
@@ -0,0 +1,38 @@
1
+ # Webhooks de Venda (plataformas de afiliados)
2
+
3
+ O ProdMaker recebe vendas por webhook público e registra em Minhas Vendas.
4
+
5
+ ## URLs de postback
6
+
7
+ Configure no painel de cada plataforma (**AdsTracking → Minhas Vendas → 🔗 Webhooks**
8
+ tem as URLs prontas para copiar):
9
+
10
+ ```
11
+ POST https://SEU-TUNEL-OU-DOMINIO/api/webhook/sale/hotmart
12
+ POST https://SEU-TUNEL-OU-DOMINIO/api/webhook/sale/clickbank
13
+ POST https://SEU-TUNEL-OU-DOMINIO/api/webhook/sale/digistore24
14
+ POST https://SEU-TUNEL-OU-DOMINIO/api/webhook/sale/kiify
15
+ POST https://SEU-TUNEL-OU-DOMINIO/api/webhook/sale/cakto
16
+ ```
17
+
18
+ Como o ProdMaker é local, use um túnel (cloudflared/ngrok) apontando para a porta 8188.
19
+ Alternativa sem túnel: adição manual de vendas ou importação de CSV.
20
+
21
+ ## Formato aceito
22
+
23
+ - **JSON** (Hotmart, Digistore24, Kiify, Cakto): qualquer formato — o parser é tolerante e
24
+ procura valor, comissão, e-mail, transação, produto, status e **gclid** em qualquer nível do JSON.
25
+ - **Form-urlencoded** (ClickBank Instant Notification): pares `chave=valor`.
26
+
27
+ ## Dica para capturar GCLID
28
+
29
+ No link de afiliado/checkout, mantenha os parâmetros da campanha (`gclid`, `utm_*`) até a
30
+ página de obrigado. No postback da plataforma, envie o `gclid` (parâmetro de rastreamento).
31
+ O ProdMaker cruza o GCLID com a visita correspondente e habilita o upload de conversão
32
+ offline ao Google Ads (se configurado em Chaves de API).
33
+
34
+ ## Status
35
+
36
+ - `PURCHASE_APPROVED`/`approved`/`complete` → aprovada
37
+ - `PURCHASE_REFUNDED`/`refunded`/`chargeback` → reembolsada
38
+ - demais (ex.: `billet_printed`, `pending`) → pendente
@@ -1 +0,0 @@
1
- *,:before,:after{--tw-border-spacing-x: 0;--tw-border-spacing-y: 0;--tw-translate-x: 0;--tw-translate-y: 0;--tw-rotate: 0;--tw-skew-x: 0;--tw-skew-y: 0;--tw-scale-x: 1;--tw-scale-y: 1;--tw-pan-x: ;--tw-pan-y: ;--tw-pinch-zoom: ;--tw-scroll-snap-strictness: proximity;--tw-gradient-from-position: ;--tw-gradient-via-position: ;--tw-gradient-to-position: ;--tw-ordinal: ;--tw-slashed-zero: ;--tw-numeric-figure: ;--tw-numeric-spacing: ;--tw-numeric-fraction: ;--tw-ring-inset: ;--tw-ring-offset-width: 0px;--tw-ring-offset-color: #fff;--tw-ring-color: rgb(59 130 246 / .5);--tw-ring-offset-shadow: 0 0 #0000;--tw-ring-shadow: 0 0 #0000;--tw-shadow: 0 0 #0000;--tw-shadow-colored: 0 0 #0000;--tw-blur: ;--tw-brightness: ;--tw-contrast: ;--tw-grayscale: ;--tw-hue-rotate: ;--tw-invert: ;--tw-saturate: ;--tw-sepia: ;--tw-drop-shadow: ;--tw-backdrop-blur: ;--tw-backdrop-brightness: ;--tw-backdrop-contrast: ;--tw-backdrop-grayscale: ;--tw-backdrop-hue-rotate: ;--tw-backdrop-invert: ;--tw-backdrop-opacity: ;--tw-backdrop-saturate: ;--tw-backdrop-sepia: ;--tw-contain-size: ;--tw-contain-layout: ;--tw-contain-paint: ;--tw-contain-style: }::backdrop{--tw-border-spacing-x: 0;--tw-border-spacing-y: 0;--tw-translate-x: 0;--tw-translate-y: 0;--tw-rotate: 0;--tw-skew-x: 0;--tw-skew-y: 0;--tw-scale-x: 1;--tw-scale-y: 1;--tw-pan-x: ;--tw-pan-y: ;--tw-pinch-zoom: ;--tw-scroll-snap-strictness: proximity;--tw-gradient-from-position: ;--tw-gradient-via-position: ;--tw-gradient-to-position: ;--tw-ordinal: ;--tw-slashed-zero: ;--tw-numeric-figure: ;--tw-numeric-spacing: ;--tw-numeric-fraction: ;--tw-ring-inset: ;--tw-ring-offset-width: 0px;--tw-ring-offset-color: #fff;--tw-ring-color: rgb(59 130 246 / .5);--tw-ring-offset-shadow: 0 0 #0000;--tw-ring-shadow: 0 0 #0000;--tw-shadow: 0 0 #0000;--tw-shadow-colored: 0 0 #0000;--tw-blur: ;--tw-brightness: ;--tw-contrast: ;--tw-grayscale: ;--tw-hue-rotate: ;--tw-invert: ;--tw-saturate: ;--tw-sepia: ;--tw-drop-shadow: ;--tw-backdrop-blur: ;--tw-backdrop-brightness: ;--tw-backdrop-contrast: ;--tw-backdrop-grayscale: ;--tw-backdrop-hue-rotate: ;--tw-backdrop-invert: ;--tw-backdrop-opacity: ;--tw-backdrop-saturate: ;--tw-backdrop-sepia: ;--tw-contain-size: ;--tw-contain-layout: ;--tw-contain-paint: ;--tw-contain-style: }*,:before,:after{box-sizing:border-box;border-width:0;border-style:solid;border-color:#e5e7eb}:before,:after{--tw-content: ""}html,:host{line-height:1.5;-webkit-text-size-adjust:100%;-moz-tab-size:4;-o-tab-size:4;tab-size:4;font-family:ui-sans-serif,system-ui,sans-serif,"Apple Color Emoji","Segoe UI Emoji",Segoe UI Symbol,"Noto Color Emoji";font-feature-settings:normal;font-variation-settings:normal;-webkit-tap-highlight-color:transparent}body{margin:0;line-height:inherit}hr{height:0;color:inherit;border-top-width:1px}abbr:where([title]){-webkit-text-decoration:underline dotted;text-decoration:underline dotted}h1,h2,h3,h4,h5,h6{font-size:inherit;font-weight:inherit}a{color:inherit;text-decoration:inherit}b,strong{font-weight:bolder}code,kbd,samp,pre{font-family:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,monospace;font-feature-settings:normal;font-variation-settings:normal;font-size:1em}small{font-size:80%}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}sub{bottom:-.25em}sup{top:-.5em}table{text-indent:0;border-color:inherit;border-collapse:collapse}button,input,optgroup,select,textarea{font-family:inherit;font-feature-settings:inherit;font-variation-settings:inherit;font-size:100%;font-weight:inherit;line-height:inherit;letter-spacing:inherit;color:inherit;margin:0;padding:0}button,select{text-transform:none}button,input:where([type=button]),input:where([type=reset]),input:where([type=submit]){-webkit-appearance:button;background-color:transparent;background-image:none}:-moz-focusring{outline:auto}:-moz-ui-invalid{box-shadow:none}progress{vertical-align:baseline}::-webkit-inner-spin-button,::-webkit-outer-spin-button{height:auto}[type=search]{-webkit-appearance:textfield;outline-offset:-2px}::-webkit-search-decoration{-webkit-appearance:none}::-webkit-file-upload-button{-webkit-appearance:button;font:inherit}summary{display:list-item}blockquote,dl,dd,h1,h2,h3,h4,h5,h6,hr,figure,p,pre{margin:0}fieldset{margin:0;padding:0}legend{padding:0}ol,ul,menu{list-style:none;margin:0;padding:0}dialog{padding:0}textarea{resize:vertical}input::-moz-placeholder,textarea::-moz-placeholder{opacity:1;color:#9ca3af}input::placeholder,textarea::placeholder{opacity:1;color:#9ca3af}button,[role=button]{cursor:pointer}:disabled{cursor:default}img,svg,video,canvas,audio,iframe,embed,object{display:block;vertical-align:middle}img,video{max-width:100%;height:auto}[hidden]:where(:not([hidden=until-found])){display:none}.block{display:block}.flex{display:flex}.table{display:table}.border{border-width:1px}.outline{outline-style:solid}.filter{filter:var(--tw-blur) var(--tw-brightness) var(--tw-contrast) var(--tw-grayscale) var(--tw-hue-rotate) var(--tw-invert) var(--tw-saturate) var(--tw-sepia) var(--tw-drop-shadow)}:root{--primary: #8b5cf6;--primary-hover: #7c3aed;--primary-light: #f3e8ff;--success: #10b981;--warning: #f59e0b;--danger: #ef4444;--bg-body: #f8fafc;--bg-card: #ffffff;--bg-sidebar: #ffffff;--text-main: #1e293b;--text-muted: #64748b;--border: #e2e8f0;--hover-bg: #f1f5f9;--input-bg: #f1f5f9;--toast-bg: #10b981;--warning-bg: #fffbeb;--warning-border: #fde68a;--code-bg: #f1f5f9}[data-theme=dark]{--bg-body: #121212;--bg-card: #1e1e1e;--bg-sidebar: #181818;--text-main: #f8fafc;--text-muted: #a1a1aa;--border: #333333;--hover-bg: #2a2a2a;--input-bg: #2a2a2a;--primary-light: #2d1b4e;--toast-bg: #059669;--warning-bg: #2d2000;--warning-border: #78350f;--code-bg: #000000}*{margin:0;padding:0;box-sizing:border-box}html,body{height:100%}body{font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,sans-serif;background-color:var(--bg-body);color:var(--text-main);transition:background .3s,color .3s}.app-shell{display:flex;height:100vh;overflow:hidden}aside.sidebar{width:260px;background-color:var(--bg-sidebar);border-right:1px solid var(--border);display:flex;flex-direction:column;height:100%;overflow-y:auto;flex-shrink:0}.logo-area{padding:20px;font-size:22px;font-weight:800;display:flex;align-items:center;gap:10px;color:var(--text-main);border-bottom:1px solid var(--border)}.logo-area span.badge{font-size:10px;border:1px solid var(--border);padding:4px 8px;border-radius:6px;color:var(--text-muted);display:flex;align-items:center;gap:4px;font-weight:600}nav ul{list-style:none;padding:0;margin:0}nav li.nav-item{padding:12px 20px;cursor:pointer;display:flex;align-items:center;gap:12px;color:var(--text-muted);font-size:14px;font-weight:500;transition:all .2s;-webkit-user-select:none;-moz-user-select:none;user-select:none}nav li.nav-item:hover{background-color:var(--hover-bg);color:var(--primary)}nav li.nav-item.active{background-color:var(--primary-light);color:var(--primary);font-weight:600}nav li.has-submenu{flex-direction:column;align-items:flex-start;padding:0}nav li.has-submenu>div{padding:12px 20px;width:100%;display:flex;align-items:center;gap:12px;cursor:pointer;color:var(--text-muted);font-weight:500;font-size:14px;-webkit-user-select:none;-moz-user-select:none;user-select:none}nav li.has-submenu>div:hover{background-color:var(--hover-bg);color:var(--primary)}nav li.has-submenu>div .submenu-arrow{font-size:10px;margin-left:auto;transition:transform .2s}nav li.has-submenu.expanded>div .submenu-arrow{transform:rotate(180deg)}nav li.has-submenu ul{display:none;width:100%;padding-left:10px;margin-bottom:10px}nav li.has-submenu.expanded ul{display:block}nav li.has-submenu ul li{padding:10px 20px;font-size:13px;color:var(--text-muted);cursor:pointer;display:flex;gap:8px;font-weight:500}nav li.has-submenu ul li:hover{color:var(--primary)}nav li.has-submenu ul li.active{color:var(--primary);font-weight:600}.divider{height:1px;background:var(--border);margin:15px 20px}.sidebar-bottom{margin-top:auto;padding:16px;border-top:1px solid var(--border)}.btn-logout{width:100%;border:none;padding:12px;border-radius:8px;font-weight:600;font-size:14px;cursor:pointer;color:#fff;background-image:linear-gradient(to right,#6366f1,#a855f7);display:flex;align-items:center;justify-content:center;gap:8px}.btn-logout:hover{opacity:.9}main.main-content{flex:1;display:flex;flex-direction:column;overflow-y:auto;position:relative}header.top-bar{background:var(--bg-card);padding:15px 30px;display:flex;justify-content:space-between;align-items:center;border-bottom:1px solid var(--border);position:sticky;top:0;z-index:10}.promo-banner{background-color:var(--primary-light);color:var(--primary);padding:8px 16px;border-radius:20px;font-size:13px;font-weight:500;cursor:pointer}.user-profile{display:flex;align-items:center;gap:15px;font-size:14px;font-weight:500}.user-profile .avatar{background:var(--primary-light);color:var(--primary);padding:5px 10px;border-radius:50%;font-weight:700;text-transform:uppercase}.theme-toggle{background:none;border:1px solid var(--border);color:var(--text-main);padding:5px 10px;border-radius:20px;cursor:pointer;font-size:16px}.content-wrapper{padding:30px 30px 80px;max-width:1200px;margin:0 auto;width:100%}h1{font-size:24px;margin-bottom:5px;color:var(--text-main)}p.subtitle{font-size:14px;color:var(--text-muted);margin-top:0;margin-bottom:20px}button.btn-primary{background-color:var(--primary);color:#fff;border:none;padding:10px 20px;border-radius:6px;font-weight:600;cursor:pointer;display:inline-flex;align-items:center;justify-content:center;gap:8px;font-size:14px}button.btn-primary:hover{background-color:var(--primary-hover)}button.btn-primary:disabled{background-color:var(--hover-bg);color:var(--text-muted);cursor:not-allowed}button.btn-outline{background:transparent;border:1px solid var(--border);padding:10px 20px;border-radius:6px;font-weight:600;cursor:pointer;color:var(--text-main);font-size:14px}button.btn-outline:hover{background:var(--hover-bg)}table{width:100%;border-collapse:collapse;background:var(--bg-card);border-radius:8px;overflow:hidden;margin-top:15px;border:1px solid var(--border)}th,td{padding:12px 15px;text-align:left;border-bottom:1px solid var(--border);font-size:13px;color:var(--text-main)}th{background-color:var(--hover-bg);color:var(--text-muted);font-weight:600;text-transform:uppercase;font-size:11px}tr.empty-row td{text-align:center;color:var(--text-muted);padding:32px 15px;font-weight:500}.action-icons{display:flex;gap:15px;color:var(--text-muted);cursor:pointer;flex-wrap:wrap}.action-icons span:hover{color:var(--primary)}.form-group{margin-bottom:15px}.form-group label{display:block;font-size:13px;font-weight:600;margin-bottom:5px;color:var(--text-main)}.form-group input,.form-group select,.form-group textarea{width:100%;padding:10px;border:1px solid var(--border);border-radius:6px;font-size:14px;outline:none;background:var(--input-bg);color:var(--text-main)}.form-group input:focus,.form-group select:focus,.form-group textarea:focus{border-color:var(--primary)}.form-row{display:flex;gap:15px}.form-row .form-group{flex:1}.form-card{background:var(--bg-card);border:1px solid var(--border);border-radius:8px;padding:25px;margin-bottom:20px}.tabs{display:flex;gap:20px;border-bottom:1px solid var(--border);margin-bottom:15px}.tab{padding:10px 0;color:var(--text-muted);font-weight:600;font-size:14px;cursor:pointer;position:relative}.tab.active{color:var(--primary)}.tab.active:after{content:"";position:absolute;bottom:-1px;left:0;width:100%;height:2px;background:var(--primary)}.metrics-grid{display:grid;grid-template-columns:repeat(4,1fr);gap:15px;margin-bottom:30px}.metric-card{background:var(--bg-card);padding:20px;border-radius:8px;border:1px solid var(--border);position:relative}.metric-card h3{font-size:13px;color:var(--text-muted);margin:0 0 10px;font-weight:500}.metric-card .value{font-size:24px;font-weight:700;color:var(--text-main)}.metric-card .value.green{color:var(--success)}.metric-card .value.purple{color:var(--primary)}.metrics-note{font-size:13px;color:var(--text-muted);margin-top:-18px;margin-bottom:30px}.modal-overlay{position:fixed;top:0;left:0;width:100vw;height:100vh;background:#0009;display:flex;justify-content:center;align-items:center;z-index:1000;-webkit-backdrop-filter:blur(2px);backdrop-filter:blur(2px)}.modal-content{background:var(--bg-card);border:1px solid var(--border);border-radius:12px;padding:30px;width:100%;max-width:800px;box-shadow:0 20px 25px -5px #0003;position:relative;color:var(--text-main);max-height:90vh;overflow-y:auto}.modal-content h2{font-size:20px;margin-bottom:18px}.modal-close{background:none;border:none;font-size:20px;cursor:pointer;color:var(--text-muted);position:absolute;top:15px;right:15px}.toast{position:fixed;top:70px;right:20px;background-color:var(--toast-bg);color:#fff;padding:15px 20px;border-radius:8px;display:flex;align-items:flex-start;gap:10px;z-index:2000;max-width:350px;box-shadow:0 4px 12px #0003}.placeholder-list{padding-left:20px;color:var(--text-muted);font-size:14px;margin:12px 0}.placeholder-list li{margin-bottom:6px}.placeholder-note{font-size:13px;color:var(--text-muted);margin-top:14px;font-weight:500}.loading-screen{display:flex;height:100vh;align-items:center;justify-content:center;color:var(--text-muted);font-size:15px}.login-error{color:var(--danger);font-size:13px;margin-bottom:12px;font-weight:500}.api-grid{display:grid;grid-template-columns:1fr 1fr;gap:20px;margin-top:20px}.api-card{background-color:var(--bg-card);border:1px solid var(--border);border-radius:12px;padding:30px 20px;display:flex;flex-direction:column;align-items:center;justify-content:center;cursor:pointer}.api-card:hover{border-color:var(--primary)}.api-logo{font-size:24px;font-weight:700;margin-bottom:15px;color:var(--text-main)}.api-status{font-size:12px;color:var(--text-muted)}.domain-grid{display:grid;grid-template-columns:repeat(3,1fr);gap:20px;margin-top:20px}.domain-card{background:var(--bg-card);border:1px solid var(--border);border-radius:8px;padding:20px;display:flex;flex-direction:column;justify-content:space-between;min-height:350px}.domain-title{font-size:16px;font-weight:600;margin-bottom:15px;color:var(--text-main);word-break:break-all}.status-tag{display:flex;align-items:center;gap:8px;font-size:13px;margin-bottom:20px;font-weight:500}.status-tag.pending{color:var(--text-muted)}.status-tag.online{color:var(--success)}.input-group{display:flex;align-items:center;background:var(--input-bg);border-radius:6px;margin-bottom:10px;border:1px solid var(--border)}.input-group input{border:none;background:transparent;padding:10px;flex:1;font-size:12px;color:var(--text-muted);outline:none;min-width:0}.input-group button{background:none;border:none;padding:0 10px;cursor:pointer;color:var(--text-main)}.domain-list{list-style:none;padding:0;margin-bottom:20px}.domain-list li{display:flex;align-items:center;gap:8px;font-size:13px;margin-bottom:10px;color:var(--text-main)}.domain-actions{display:flex;gap:10px}.domain-actions button{flex:1;padding:8px;font-size:12px}.domain-card-bottom{display:flex;flex-direction:column;gap:10px;margin-top:20px}@media (max-width: 1100px){.domain-grid{grid-template-columns:repeat(2,1fr)}}@media (max-width: 800px){.domain-grid{grid-template-columns:1fr}}.login-page{display:flex;flex-direction:row;height:100vh;width:100%}.login-left{flex:1;position:relative;overflow:hidden;background:#0a0a0a;width:50%;display:flex}.login-left-content{position:relative;z-index:10;display:flex;flex-direction:column;justify-content:center;padding:4rem;height:100%;color:#fff;font-family:Inter,-apple-system,sans-serif;width:100%}.login-left-content *{color:#fff}.login-left-title{font-size:3rem;font-weight:700;line-height:1.2;margin-bottom:1.5rem;font-family:Poppins,sans-serif}.login-left-title .highlight-text{color:#8b5cf6}.login-left-description{font-size:1.25rem;margin-bottom:3rem;max-width:28rem;line-height:1.6;color:#ffffff80!important}.features-grid{display:grid;grid-template-columns:repeat(4,minmax(0,1fr));gap:1.5rem;max-width:44rem;overflow:visible}.feature-step-item{display:flex;flex-direction:column;align-items:center;gap:.75rem;min-width:0;animation:step-card-in .5s ease-out both}.feature-step-item:nth-child(1){animation-delay:.3s}.feature-step-item:nth-child(2){animation-delay:.45s}.feature-step-item:nth-child(3){animation-delay:.6s}.feature-step-item:nth-child(4){animation-delay:.75s}@keyframes step-card-in{0%{opacity:0;transform:translateY(16px)}to{opacity:1;transform:translateY(0)}}.feature-card{display:flex;align-items:flex-start;gap:1rem;background:#7c3aed14;-webkit-backdrop-filter:blur(12px);backdrop-filter:blur(12px);border-radius:1.25rem;padding:1.25rem;border:1px solid rgba(124,58,237,.22);position:relative;transition:border-color .3s ease,box-shadow .3s ease}.feature-card:hover{border-color:#7c3aed73;box-shadow:0 0 20px #7c3aed26}.feature-step{width:7rem;height:7rem;padding:0;border-radius:1.25rem;display:flex;align-items:center;justify-content:center;flex-shrink:0;align-self:center}.feature-step-number{position:absolute;top:.6rem;left:.75rem;font-size:.7rem;font-weight:600;line-height:1;color:#8b5cf68c;letter-spacing:.02em}.feature-step-icon{display:flex;align-items:center;justify-content:center}.feature-step-icon i{font-size:3rem;color:#8b5cf6bf;font-family:Material Symbols Outlined,sans-serif!important;font-variation-settings:"FILL" 1,"wght" 400,"GRAD" 0,"opsz" 24!important}.feature-step-arrow{position:absolute;right:-1.25rem;top:50%;transform:translateY(-50%);z-index:1}.feature-step-arrow:after{content:"";position:absolute;right:-7px;top:50%;width:0;height:0;border-left:8px solid rgba(236,72,153,.65);border-top:5px solid transparent;border-bottom:5px solid transparent;transform:translateY(-50%)}.feature-step-last .feature-step-arrow{display:none}.feature-title{font-weight:500;margin:0;font-size:.875rem;line-height:1.25;text-align:center;width:100%;color:#ffffffa6!important}.login-blur-effect{position:absolute;border-radius:50%;filter:blur(80px);opacity:1;pointer-events:none}.blur-effect-center{position:absolute;top:0;right:0;bottom:0;left:0;border-radius:0;filter:none;pointer-events:none;width:100%;height:100%;background:radial-gradient(ellipse 60% 40% at 50% 30%,rgba(124,58,237,.12) 0%,transparent 70%)}.blur-effect-1{width:520px;height:520px;background:radial-gradient(circle,rgba(124,58,237,.22) 0%,transparent 70%);filter:blur(40px);top:-10%;left:-8%;animation:orb-float-1 12s ease-in-out infinite}.blur-effect-2{width:440px;height:440px;background:radial-gradient(circle,rgba(236,72,153,.18) 0%,transparent 70%);filter:blur(40px);bottom:0%;right:-6%;animation:orb-float-2 15s ease-in-out infinite}@keyframes orb-float-1{0%,to{transform:translate(0) scale(1)}33%{transform:translate(40px,-30px) scale(1.08)}66%{transform:translate(-20px,20px) scale(.95)}}@keyframes orb-float-2{0%,to{transform:translate(0) scale(1)}33%{transform:translate(-30px,20px) scale(1.06)}66%{transform:translate(25px,-25px) scale(.97)}}.login-particle{position:absolute;border-radius:50%;pointer-events:none;filter:blur(1px);bottom:-10px;animation:particle-rise ease-in infinite}@keyframes particle-rise{0%{transform:translateY(0) scale(1);opacity:0}10%{opacity:1}90%{opacity:.6}to{transform:translateY(-110vh) scale(.4);opacity:0}}.login-right{flex:1;display:flex;flex-direction:column;justify-content:space-between;align-items:center;background-color:#f8fafc;padding:2rem;position:relative;width:50%;overflow-y:auto}.login-language-toggle{position:absolute;top:1.5rem;right:1.5rem;z-index:10}.language-toggle-wrapper{position:relative}.language-toggle-btn{background:none;border:1px solid #e2e8f0;border-radius:8px;padding:6px 10px;cursor:pointer;display:flex;align-items:center;justify-content:center;color:#64748b}.language-toggle-btn .material-symbols-outlined{font-size:20px}.language-toggle-dropdown{display:none;position:absolute;top:100%;right:0;margin-top:.5rem;background:#fff;border:1px solid #e2e8f0;border-radius:8px;box-shadow:0 4px 12px #0000001a;min-width:120px;overflow:hidden}.language-toggle-wrapper:hover .language-toggle-dropdown,.language-toggle-dropdown:hover{display:block}.language-toggle-item{padding:.5rem 1rem;cursor:pointer;font-size:.875rem}.language-toggle-item:hover{background:#f1f5f9}.language-toggle-item.active{background:#ede9fe;font-weight:600;color:#7c3aed}.login-form{width:100%;max-width:400px;flex:1;display:flex;flex-direction:column;justify-content:center}.login-form h2{font-size:1.75rem;font-weight:700;color:#334155;margin-bottom:.5rem}.login-form .login-subtitle{font-size:1rem;color:#64748b;margin-bottom:2rem}.login-form .form-group label{display:block;margin-bottom:.5rem;font-weight:500;font-size:.9rem;color:#334155}.login-form .form-group input{width:100%;padding:12px 15px;border-radius:4px;font-size:1rem;border:1px solid #e2e8f0;background:transparent;transition:border .3s ease;outline:none}.login-form .form-group input::-moz-placeholder{font-weight:300;font-size:.8rem;color:#94a3b8}.login-form .form-group input::placeholder{font-weight:300;font-size:.8rem;color:#94a3b8}.login-form .form-group input:focus{border-color:#8b5cf6;box-shadow:0 0 5px #8b5cf6}.login-form .form-group{margin-bottom:1.5rem}.email-input-wrapper,.password-input-wrapper{position:relative;width:100%}.email-input-wrapper input{padding-left:2.5rem!important}.password-input-wrapper input{padding-left:2.5rem!important;padding-right:45px}.email-icon,.lock-icon{position:absolute;left:12px;top:50%;transform:translateY(-50%);color:#ced1d6;pointer-events:none;font-size:20px}.password-toggle-btn{position:absolute;right:12px;top:50%;transform:translateY(-50%);background:none;border:none;cursor:pointer;padding:4px;display:flex;align-items:center;justify-content:center;color:#94a3b8;z-index:1}.password-toggle-btn:hover{color:#7c3aed}.login-button{border:none;border-radius:1.25rem;cursor:pointer;text-align:center;font-weight:500;letter-spacing:.5px;display:flex;align-items:center;justify-content:center;gap:.5rem;width:100%;padding:12px;background-color:#7c3aed;color:#fff;font-size:1rem;margin-top:.5rem;transition:background-color .3s ease,box-shadow .3s ease,transform .2s ease}.login-button:hover:not(:disabled){background-color:#6d28d9;transform:translateY(-2px)}.login-button:disabled{background-color:#e2e8f0;color:#94a3b8;cursor:not-allowed}.support-link{margin-top:1.5rem;text-align:center;font-size:.85rem;color:#64748b}.support-link p{margin-bottom:.5rem}.support-link a{color:#7c3aed;text-decoration:none;font-weight:500;cursor:pointer}.support-link a:hover{text-decoration:underline}.login-footer-bottom{padding-bottom:1rem;width:100%;max-width:400px;text-align:center;font-size:.8rem;color:#94a3b8}.login-footer-bottom a{color:#94a3b8;text-decoration:none;margin:0 10px}.login-footer-bottom a:hover{color:#7c3aed;text-decoration:underline}@media (max-width: 1024px){.login-left{display:none!important}.login-right{width:100%!important}}@media (max-width: 900px){.metrics-grid{grid-template-columns:repeat(2,1fr)}}.pixel-header{display:flex;align-items:center;gap:15px;margin-bottom:20px}.pixel-icon{background:var(--primary-light);color:var(--primary);padding:10px;border-radius:8px;font-size:20px}.pixel-top-bar{display:flex;justify-content:space-between;align-items:center;background:var(--bg-card);border:1px solid var(--border);padding:15px;border-radius:8px;margin-bottom:20px;flex-wrap:wrap;gap:10px}.pixel-tags{display:flex;gap:10px}.pixel-tag{background:var(--hover-bg);padding:4px 10px;border-radius:20px;font-size:12px;font-weight:600;color:var(--primary)}.warning-box{background:var(--warning-bg);border:1px solid var(--warning-border);border-radius:8px;padding:20px;display:flex;gap:15px;align-items:flex-start;margin-bottom:20px;position:relative}.warning-box .icon{background:var(--warning);color:#fff;width:30px;height:30px;border-radius:50%;display:flex;justify-content:center;align-items:center;font-weight:700;flex-shrink:0}.warning-box h4{font-size:15px;color:var(--text-main);margin-bottom:5px}.warning-box p{font-size:13px;color:var(--text-muted);margin:0;max-width:70%}.warning-box .btn-dark{position:absolute;right:20px;top:20px;background:#1e293b;color:#fff;border:none;padding:10px 15px;border-radius:6px;font-weight:600;font-size:12px;cursor:pointer}@media (max-width: 800px){.warning-box{flex-direction:column}.warning-box p{max-width:100%}.warning-box .btn-dark{position:static;margin-top:10px}}.visitor-grid{display:grid;grid-template-columns:repeat(3,1fr);gap:15px;margin-bottom:30px}.visitor-card{background:var(--bg-card);border:1px solid var(--border);border-radius:8px;padding:15px;display:flex;flex-direction:column;gap:10px;cursor:pointer;transition:.2s}.visitor-card:hover{border-color:var(--primary);transform:translateY(-2px);box-shadow:0 4px 12px #0000000d}.visitor-card-header{display:flex;justify-content:space-between;align-items:center;gap:8px}.visitor-ip{display:flex;align-items:center;gap:8px;font-weight:600;font-size:14px;word-break:break-all}.visitor-badge{background:var(--warning-bg);color:var(--warning);padding:3px 8px;border-radius:12px;font-size:11px;font-weight:600;white-space:nowrap}.visitor-card-details{font-size:12px;color:var(--text-muted);display:flex;justify-content:space-between;gap:8px;flex-wrap:wrap}.visitor-card-link{font-size:12px;color:var(--primary);text-align:right;cursor:pointer}.charts-grid{display:grid;grid-template-columns:repeat(3,1fr);gap:15px;margin-bottom:20px}.chart-card{background:var(--bg-card);padding:20px;border-radius:8px;border:1px solid var(--border)}.chart-card h3{font-size:15px;margin-bottom:5px}.chart-card p{font-size:12px;color:var(--text-muted);margin-bottom:20px}.donut-chart{width:150px;height:150px;border-radius:50%;margin:0 auto 15px;display:flex;justify-content:center;align-items:center}.donut-inner{width:100px;height:100px;background:var(--bg-card);border-radius:50%}.chart-legend{display:flex;justify-content:center;flex-wrap:wrap;gap:12px;font-size:12px;color:var(--text-muted)}.legend-item{display:flex;align-items:center;gap:6px}.legend-color{width:10px;height:10px;border-radius:50%;display:inline-block}.bottom-grid{display:grid;grid-template-columns:1.5fr 1fr;gap:20px;margin-bottom:20px}.traffic-flow-card{background:var(--bg-card);padding:20px;border-radius:8px;border:1px solid var(--border)}.traffic-flow-card h3{font-size:16px}.traffic-flow-visual{height:200px;background:linear-gradient(to top,var(--primary-light),transparent);border-radius:8px;margin-top:20px;position:relative;border-bottom:2px solid var(--border);overflow:hidden}.traffic-flow-visual svg{width:100%;height:100%;position:absolute;bottom:0;left:0}.funnel-card{background:var(--bg-card);padding:20px;border-radius:8px;border:1px solid var(--border)}.funnel-step{margin-bottom:15px}.funnel-step-header{display:flex;justify-content:space-between;font-size:13px;font-weight:600;margin-bottom:5px;gap:8px}.funnel-step-bar{height:8px;background:var(--hover-bg);border-radius:4px;overflow:hidden}.funnel-step-bar div{height:100%;background:var(--primary);border-radius:4px}.visitor-modal-header{display:flex;justify-content:space-between;align-items:center;margin-bottom:20px}.badge-human{background:#ecfdf5;color:#059669;padding:4px 10px;border-radius:20px;font-size:12px;font-weight:700}[data-theme=dark] .badge-human{background:#052e2b;color:#34d399}.visitor-details-grid{display:grid;grid-template-columns:repeat(4,1fr);gap:15px;margin-bottom:25px}.detail-box{border:1px solid var(--border);border-radius:8px;padding:15px}.detail-box .label{font-size:11px;color:var(--text-muted);text-transform:uppercase;display:flex;align-items:center;gap:5px;margin-bottom:10px;font-weight:700}.detail-box .main-val{font-size:14px;font-weight:600;margin-bottom:4px;word-break:break-all}.detail-box .sub-val{font-size:12px;color:var(--text-muted);word-break:break-all}.badge-origin{background:#e0f2fe;color:#0284c7;padding:2px 8px;border-radius:12px;font-size:11px;font-weight:600;display:inline-block}[data-theme=dark] .badge-origin{background:#082f49;color:#7dd3fc}.modal-tabs{display:flex;gap:20px;border-bottom:1px solid var(--border);margin-bottom:20px}.modal-tab{padding:10px 0;font-size:13px;font-weight:600;color:var(--text-muted);cursor:pointer;border-bottom:2px solid transparent}.modal-tab.active{color:var(--primary);border-bottom-color:var(--primary)}.tracking-id-box{border:1px solid var(--border);border-radius:8px;padding:15px;display:inline-block;min-width:200px;background:var(--hover-bg);margin:0 10px 10px 0}.tracking-id-box .label{font-size:11px;color:var(--text-muted);font-weight:700;margin-bottom:5px}.tracking-id-box .val{font-size:14px;font-weight:600;word-break:break-all}.json-box{background:var(--code-bg);padding:20px;border-radius:8px;font-family:monospace;font-size:13px;color:var(--success);white-space:pre-wrap;border:1px solid var(--border);position:relative}.json-copy-btn{position:absolute;top:10px;right:10px;background:var(--bg-card);border:1px solid var(--border);padding:5px 10px;border-radius:4px;font-size:12px;cursor:pointer;color:var(--text-main)}@media (max-width: 1100px){.visitor-grid,.charts-grid{grid-template-columns:repeat(2,1fr)}.bottom-grid{grid-template-columns:1fr}}@media (max-width: 800px){.visitor-grid,.charts-grid{grid-template-columns:1fr}.visitor-details-grid{grid-template-columns:repeat(2,1fr)}}