```json{"summary":"生成深色科技风格登录页,含社交登录与邮箱密码双通道","widget":{"type":"full-html","html":"<!DOCTYPE html>\n<html lang=\"zh-CN\">\n<head>\n <meta charset=\"UTF-8\">\n <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\n <title>Nova · 智能协作平台</title>\n <link rel=\"stylesheet\" href=\"https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.5.1/css/all.min.c…\">\n <link href=\"https://fonts.googleapis.com/css2?family=Space+Grotesk:wght@400;500;600…\" rel=\"stylesheet\">\n <script src=\"https://cdn.tailwindcss.com\"></script>\n <style>\n /* ===== DESIGN TOKENS ===== */\n :root {\n --color-primary: #6C5CE7;\n --color-secondary: #A29BFE;\n --color-accent: #00D2D3;\n --color-success: #00B894;\n --color-warning: #FDCB6E;\n --color-danger: #E17055;\n --color-info: #74B9FF;\n --color-background: #0A0A0F;\n --color-foreground: #F0F0F5;\n --color-card: #14141E;\n --color-border: #2A2A3A;\n --color-muted: #6B6B80;\n --state-hover: #7C6DF0;\n --state-active: #5A4BD0;\n --state-focus: #6C5CE7;\n --state-disabled: #3A3A4A;\n --radius-sm: 4px;\n --radius-md: 8px;\n --radius-lg: 16px;\n --radius-xl: 24px;\n --radius-full: 9999px;\n --shadow-sm: 0 1px 3px rgba(0,0,0,.3);\n --shadow-md: 0 4px 14px rgba(0,0,0,.35);\n --shadow-lg: 0 12px 40px rgba(0,0,0,.45);\n --shadow-xl: 0 24px 80px rgba(0,0,0,.5);\n --transition-fast: 150ms ease-out;\n --transition-base: 300ms ease-out;\n --transition-slow: 500ms cubic-bezier(0.4,0,0.2,1);\n --font-heading: 'Space Grotesk', Georgia, serif;\n --font-body: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;\n --font-mono: 'JetBrains Mono', 'SF Mono', Consolas, monospace;\n }\n\n * {\n margin: 0;\n padding: 0;\n box-sizing: border-box;\n }\n\n html {\n scroll-behavior: smooth;\n }\n\n body {\n font-family: var(--font-body);\n background: var(--color-background);\n color: var(--color-foreground);\n min-height: 100vh;\n display: flex;\n align-items: center;\n justify-content: center;\n padding: 1.5rem;\n background-image: \n radial-gradient(ellipse at 50% 0%, #1A1A2E 0%, #0A0A0F 70%);\n position: relative;\n overflow-x: hidden;\n }\n\n /* ===== DECORATIVE ORBS ===== */\n .orb-left {\n position: fixed;\n top: -20vh;\n left: -15vw;\n width: 65vmax;\n height: 65vmax;\n border-radius: 50%;\n background: radial-gradient(circle at 30% 40%, rgba(108,92,231,0.15) 0%, rgba(108,92,231,0) 70%);\n pointer-events: none;\n z-index: 0;\n animation: orbFloatLeft 12s ease-in-out infinite alternate;\n }\n\n .orb-right {\n position: fixed;\n bottom: -25vh;\n right: -18vw;\n width: 70vmax;\n height: 70vmax;\n border-radius: 50%;\n background: radial-gradient(circle at 70% 60%, rgba(0,210,211,0.10) 0%, rgba(0,210,211,0) 70%);\n pointer-events: none;\n z-index: 0;\n animation: orbFloatRight 14s ease-in-out infinite alternate;\n }\n\n .grid-overlay {\n position: fixed;\n inset: 0;\n background-image: \n linear-gradient(rgba(42,42,58,0.15) 1px, transparent 1px),\n linear-gradient(90deg, rgba(42,42,58,0.15) 1px, transparent 1px);\n background-size: 48px 48px;\n pointer-events: none;\n z-index: 0;\n }\n\n @keyframes orbFloatLeft {\n 0% { transform: translate(0, 0) scale(1); }\n 100% { transform: translate(6%, 8%) scale(1.05); }\n }\n\n @keyframes orbFloatRight {\n 0% { transform: translate(0, 0) scale(1); }\n 100% { transform: translate(-5%, -4%) scale(1.08); }\n }\n\n /* ===== CARD GLASS ===== */\n .glass-card {\n background: rgba(20, 20, 30, 0.85);\n backdrop-filter: blur(24px) saturate(1.1);\n -webkit-backdrop-filter: blur(24px) saturate(1.1);\n border: 1px solid rgba(42, 42, 58, 0.6);\n box-shadow: var(--shadow-xl);\n border-radius: var(--radius-xl);\n transition: box-shadow var(--transition-base), border-color var(--transition-base);\n }\n\n .glass-card:hover {\n box-shadow: var(--shadow-xl), 0 0 0 1px rgba(108,92,231,0.08);\n border-color: rgba(108,92,231,0.25);\n }\n\n /* ===== BUTTON VARIANTS ===== */\n .btn-primary {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n gap: 0.5rem;\n min-height: 44px;\n min-width: 44px;\n padding: 0.75rem 1.5rem;\n background: linear-gradient(135deg, #6C5CE7 0%, #00D2D3 100%);\n color: #FFFFFF;\n font-family: var(--font-heading);\n font-weight: 600;\n font-size: 0.875rem;\n line-height: 1;\n letter-spacing: 0.015em;\n border: none;\n border-radius: var(--radius-md);\n cursor: pointer;\n transition: background var(--transition-base), box-shadow var(--transition-base), transform var(--transition-fast);\n outline: none;\n }\n\n .btn-primary:hover {\n background: linear-gradient(135deg, #7C6DF0 0%, #00E0E0 100%);\n box-shadow: 0 4px 20px rgba(108,92,231,0.35);\n transform: translateY(-1px);\n }\n\n .btn-primary:active {\n background: linear-gradient(135deg, #5A4BD0 0%, #00A3A3 100%);\n transform: translateY(0);\n box-shadow: 0 2px 8px rgba(108,92,231,0.25);\n }\n\n .btn-primary:focus-visible {\n outline: 2px solid var(--color-accent);\n outline-offset: 2px;\n }\n\n .btn-primary:disabled {\n opacity: 0.4;\n cursor: not-allowed;\n transform: none;\n box-shadow: none;\n }\n\n .btn-secondary {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n gap: 0.5rem;\n min-height: 44px;\n min-width: 44px;\n padding: 0.75rem 1.5rem;\n background: transparent;\n color: var(--color-foreground);\n font-family: var(--font-body);\n font-weight: 600;\n font-size: 0.875rem;\n line-height: 1;\n letter-spacing: 0.015em;\n border: 1px solid var(--color-border);\n border-radius: var(--radius-md);\n cursor: pointer;\n transition: background var(--transition-base), border-color var(--transition-base), box-shadow var(--transition-fast);\n outline: none;\n }\n\n .btn-secondary:hover {\n background: var(--color-card);\n border-color: rgba(108,92,231,0.4);\n }\n\n .btn-secondary:active {\n background: rgba(107,107,128,0.2);\n }\n\n .btn-secondary:focus-visible {\n outline: 2px solid var(--color-accent);\n outline-offset: 2px;\n }\n\n .btn-secondary:disabled {\n opacity: 0.4;\n cursor: not-allowed;\n }\n\n .btn-social {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n gap: 0.625rem;\n min-height: 44px;\n min-width: 44px;\n width: 100%;\n padding: 0.75rem 1rem;\n background: rgba(20, 20, 30, 0.6);\n color: var(--color-foreground);\n font-family: var(--font-body);\n font-weight: 500;\n font-size: 0.875rem;\n line-height: 1;\n border: 1px solid var(--color-border);\n border-radius: var(--radius-md);\n cursor: pointer;\n transition: background var(--transition-base), border-color var(--transition-base), box-shadow var(--transition-fast);\n outline: none;\n text-align: left;\n }\n\n .btn-social:hover {\n background: rgba(42,42,58,0.5);\n border-color: rgba(108,92,231,0.35);\n box-shadow: 0 2px 10px rgba(0,0,0,0.2);\n }\n\n .btn-social:active {\n background: rgba(107,107,128,0.25);\n }\n\n .btn-social:focus-visible {\n outline: 2px solid var(--color-accent);\n outline-offset: 2px;\n }\n\n .btn-social:disabled {\n opacity: 0.4;\n cursor: not-allowed;\n }\n\n /* ===== INPUT ===== */\n .input-field {\n width: 100%;\n min-height: 44px;\n padding: 0.75rem 1rem;\n background: rgba(10, 10, 15, 0.6);\n color: var(--color-foreground);\n font-family: var(--font-body);\n font-size: 0.9375rem;\n line-height: 1.6;\n border: 1px solid var(--color-border);\n border-radius: var(--radius-md);\n outline: none;\n transition: border-color var(--transition-base), box-shadow var(--transition-base);\n }\n\n .input-field::placeholder {\n color: var(--color-muted);\n opacity: 0.7;\n }\n\n .input-field:hover {\n border-color: var(--color-muted);\n }\n\n .input-field:focus {\n border-color: var(--color-primary);\n box-shadow: 0 0 0 3px rgba(108,92,231,0.2);\n }\n\n .input-field:disabled {\n opacity: 0.4;\n cursor: not-allowed;\n }\n\n .input-field.error {\n border-color: var(--color-danger);\n box-shadow: 0 0 0 3px rgba(225,112,85,0.2);\n }\n\n /* ===== LINK ===== */\n .link-muted {\n color: var(--color-muted);\n text-decoration: none;\n font-size: 0.8125rem;\n line-height: 1.5;\n transition: color var(--transition-fast);\n }\n\n .link-muted:hover {\n color: var(--color-primary);\n }\n\n .link-muted:focus-visible {\n outline: 2px solid var(--color-accent);\n outline-offset: 2px;\n border-radius: var(--radius-sm);\n }\n\n /* ===== CHECKBOX CUSTOM ===== */\n .custom-checkbox {\n appearance: none;\n -webkit-appearance: none;\n width: 18px;\n height: 18px;\n border: 1.5px solid var(--color-border);\n border-radius: var(--radius-sm);\n background: transparent;\n cursor: pointer;\n transition: background var(--transition-fast), border-color var(--transition-fast);\n flex-shrink: 0;\n position: relative;\n outline: none;\n }\n\n .custom-checkbox:checked {\n background: var(--color-primary);\n border-color: var(--color-primary);\n }\n\n .custom-checkbox:checked::after {\n content: '';\n position: absolute;\n inset: 3px;\n background: url(\"data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='white' stroke-width='3' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpolyline points='20 6 9 17 4 12'/%3E%3C/svg%3E\") no-repeat center;\n background-size: contain;\n }\n\n .custom-checkbox:hover {\n border-color: var(--color-muted);\n }\n\n .custom-checkbox:focus-visible {\n outline: 2px solid var(--color-accent);\n outline-offset: 2px;\n }\n\n .custom-checkbox:disabled {\n opacity: 0.4;\n cursor: not-allowed;\n }\n\n /* ===== ENTRY ANIMATIONS ===== */\n .animate-in {\n animation: fadeSlideUp 0.6s cubic-bezier(0.22, 1, 0.36, 1) both;\n }\n\n .delay-1 { animation-delay: 0.05s; }\n .delay-2 { animation-delay: 0.12s; }\n .delay-3 { animation-delay: 0.20s; }\n .delay-4 { animation-delay: 0.28s; }\n .delay-5 { animation-delay: 0.36s; }\n .delay-6 { animation-delay: 0.44s; }\n .delay-7 { animation-delay: 0.52s; }\n .delay-8 { animation-delay: 0.60s; }\n\n @keyframes fadeSlideUp {\n 0% {\n opacity: 0;\n transform: translateY(16px);\n }\n 100% {\n opacity: 1;\n transform: translateY(0);\n }\n }\n\n /* ===== RESPONSIVE ===== */\n @media (max-width: 640px) {\n body {\n padding: 1rem;\n align-items: flex-start;\n padding-top: 2rem;\n }\n .glass-card {\n padding: 1.5rem;\n border-radius: var(--radius-lg);\n }\n .orb-left {\n width: 80vmax;\n height: 80vmax;\n top: -30vh;\n left: -25vw;\n }\n .orb-right {\n width: 85vmax;\n height: 85vmax;\n bottom: -35vh;\n right: -30vw;\n }\n .hide-mobile {\n display: none;\n }\n }\n\n @media (min-width: 641px) and (max-width: 768px) {\n .glass-card {\n padding: 2rem;\n }\n }\n\n @media (min-width: 1280px) {\n body {\n padding: 2rem;\n }\n }\n\n /* ===== PASSWORD TOGGLE ===== */\n .password-toggle {\n cursor: pointer;\n color: var(--color-muted);\n transition: color var(--transition-fast);\n background: none;\n border: none;\n padding: 0.25rem;\n display: flex;\n align-items: center;\n justify-content: center;\n min-width: 28px;\n min-height: 28px;\n }\n\n .password-toggle:hover {\n color: var(--color-foreground);\n }\n\n .password-toggle:focus-visible {\n outline: 2px solid var(--color-accent);\n outline-offset: 2px;\n border-radius: var(--radius-sm);\n }\n\n /* ===== DIVIDER ===== */\n .divider-line {\n flex: 1;\n height: 1px;\n background: var(--color-border);\n }\n\n .divider-text {\n color: var(--color-muted);\n font-size: 0.75rem;\n font-weight: 400;\n line-height: 1.4;\n letter-spacing: 0.03em;\n padding: 0 1rem;\n white-space: nowrap;\n }\n </style>\n</head>\n<body>\n\n <!-- ===== DECORATIVE BACKGROUND ===== -->\n <div class=\"orb-left\" aria-hidden=\"true\"></div>\n <div class=\"orb-right\" aria-hidden=\"true\"></div>\n <div class=\"grid-overlay\" aria-hidden=\"true\"></div>\n\n <!-- ===== LOGIN CARD ===== -->\n <main class=\"relative z-10 w-full\" style=\"max-width: 440px;\">\n <div class=\"glass-card p-8 sm:p-10 w-full animate-in\">\n\n <!-- Brand -->\n <div class=\"flex items-center gap-3 mb-6 animate-in delay-1\">\n <div class=\"flex items-center justify-center w-10 h-10 rounded-lg\" style=\"background: linear-gradient(135deg, #6C5CE7 0%, #00D2D3 100%);\">\n <svg width=\"20\" height=\"20\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"white\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><path d=\"M12 3c-1.5 0-3 .6-4.2 1.8C6.6 6 6 7.5 6 9c0 1.5.6 3 1.8 4.2C9 14.4 10.5 15 12 15c1.5 0 3-.6 4.2-1.8C17.4 12 18 10.5 18 9c0-1.5-.6-3-1.8-4.2C15 3.6 13.5 3 12 3z\"/><path d=\"M12 15v6\"/><path d=\"M8 21h8\"/><path d=\"M16 11.5c1.8-.3 3.3-1.2 4.4-2.5\"/><path d=\"M7.6 11.5c-1.8-.3-3.3-1.2-4.4-2.5\"/></svg>\n </div>\n <div>\n <h1 class=\"text-xl font-bold tracking-tight\" style=\"font-family: var(--font-heading); font-size: clamp(1.25rem, 2vw, 1.5rem); font-weight: 600; line-height: 1.15; letter-spacing: -0.02em; color: var(--color-foreground);\">Nova</h1>\n <p class=\"text-xs\" style=\"color: var(--color-muted); font-size: 0.75rem; line-height: 1.4; letter-spacing: 0.03em;\">智能协作平台</p>\n </div>\n </div>\n\n <!-- Social Login Title -->\n <p class=\"text-sm font-medium mb-4 animate-in delay-2\" style=\"color: var(--color-muted); font-size: 0.8125rem; line-height: 1.5;\">使用社交账号登录</p>\n\n <!-- Social Buttons -->\n <div class=\"flex flex-col gap-3 mb-5 animate-in delay-3\">\n <!-- Google -->\n <button class=\"btn-social\" type=\"button\">\n <svg width=\"18\" height=\"18\" viewBox=\"0 0 24 24\" fill=\"none\"><path d=\"M22.56 12.25c0-.78-.07-1.53-.2-2.25H12v4.26h5.92c-.26 1.37-1.04 2.53-2.21 3.31v2.77h3.57c2.08-1.92 3.28-4.74 3.28-8.09z\" fill=\"#4285F4\"/><path d=\"M12 23c2.97 0 5.46-.98 7.28-2.66l-3.57-2.77c-.98.66-2.23 1.06-3.71 1.06-2.86 0-5.29-1.93-6.16-4.53H2.18v2.84C3.99 20.53 7.7 23 12 23z\" fill=\"#34A853\"/><path d=\"M5.84 14.09c-.22-.66-.35-1.36-.35-2.09s.13-1.43.35-2.09V7.07H2.18C1.43 8.55 1 10.22 1 12s.43 3.45 1.18 4.93l2.85-2.22.81-.62z\" fill=\"#FBBC05\"/><path d=\"M12 5.38c1.62 0 3.06.56 4.21 1.64l3.15-3.15C17.45 2.09 14.97 1 12 1 7.7 1 3.99 3.47 2.18 7.07l3.66 2.84c.87-2.6 3.3-4.53 6.16-4.53z\" fill=\"#EA4335\"/></svg>\n 继续使用 Google\n </button>\n\n <!-- GitHub -->\n <button class=\"btn-social\" type=\"button\">\n <svg width=\"18\" height=\"18\" viewBox=\"0 0 24 24\" fill=\"currentColor\"><path d=\"M12 0C5.37 0 0 5.37 0 12c0 5.3 3.438 9.8 8.205 11.385.6.113.82-.258.82-.577 0-.285-.01-1.04-.015-2.04-3.338.724-4.042-1.61-4.042-1.61-.546-1.385-1.335-1.755-1.335-1.755-1.087-.744.084-.729.084-.729 1.205.084 1.838 1.236 1.838 1.236 1.07 1.835 2.809 1.305 3.495.998.108-.776.417-1.305.76-1.605-2.665-.3-5.466-1.332-5.466-5.93 0-1.31.465-2.38 1.235-3.22-.135-.303-.54-1.523.105-3.176 0 0 1.005-.322 3.3 1.23.96-.267 1.98-.399 3-.405 1.02.006 2.04.138 3 .405 2.28-1.552 3.285-1.23 3.285-1.23.645 1.653.24 2.873.12 3.176.765.84 1.23 1.91 1.23 3.22 0 4.61-2.805 5.625-5.475 5.92.42.36.81 1.096.81 2.22 0 1.606-.015 2.896-.015 3.286 0 .315.21.69.825.57C20.565 21.795 24 17.295 24 12c0-6.63-5.37-12-12-12z\"/></svg>\n 继续使用 GitHub\n </button>\n\n <!-- Microsoft -->\n <button class=\"btn-social\" type=\"button\">\n <svg width=\"18\" height=\"18\" viewBox=\"0 0 24 24\" fill=\"none\"><rect x=\"2\" y=\"2\" width=\"9\" height=\"9\" fill=\"#F25022\"/><rect x=\"13\" y=\"2\" width=\"9\" height=\"9\" fill=\"#7FBA00\"/><rect x=\"2\" y=\"13\" width=\"9\" height=\"9\" fill=\"#00A4EF\"/><rect x=\"13\" y=\"13\" width=\"9\" height=\"9\" fill=\"#FFB900\"/></svg>\n 继续使用 Microsoft\n </button>\n </div>\n\n <!-- Divider -->\n <div class=\"flex items-center my-6 animate-in delay-4\">\n <span class=\"divider-line\"></span>\n <span class=\"divider-text\">或使用邮箱登录</span>\n <span class=\"divider-line\"></span>\n </div>\n\n <!-- Email / Password Form -->\n <form id=\"loginForm\" class=\"flex flex-col gap-4 animate-in delay-5\" novalidate>\n <!-- Email -->\n <div>\n <label for=\"email\" class=\"block text-sm font-medium mb-1.5\" style=\"color: var(--color-foreground); font-size: 0.875rem; line-height: 1.4;\">邮箱地址</label>\n <input\n id=\"email\"\n class=\"input-field\"\n type=\"email\"\n placeholder=\"name@company.com\"\n autocomplete=\"email\"\n required\n />\n <p id=\"emailError\" class=\"text-xs mt-1\" style=\"color: var(--color-danger); display: none;\">请输入有效的邮箱地址</p>\n </div>\n\n <!-- Password -->\n <div>\n <label for=\"password\" class=\"block text-sm font-medium mb-1.5\" style=\"color: var(--color-foreground); font-size: 0.875rem; line-height: 1.4;\">密码</label>\n <div class=\"relative\">\n <input\n id=\"password\"\n class=\"input-field pr-10\"\n type=\"password\"\n placeholder=\"输入密码\"\n autocomplete=\"current-password\"\n required\n minlength=\"6\"\n />\n <button\n type=\"button\"\n class=\"password-toggle absolute right-3 top-1/2 -translate-y-1/2\"\n aria-label=\"切换密码可见性\"\n id=\"passwordToggle\"\n >\n <i class=\"fa-regular fa-eye\" id=\"toggleIcon\"></i>\n </button>\n </div>\n <p id=\"passwordError\" class=\"text-xs mt-1\" style=\"color: var(--color-danger); display: none;\">密码至少需要 6 个字符</p>\n </div>\n\n <!-- Remember + Forgot -->\n <div class=\"flex items-center justify-between mt-1\">\n <label class=\"flex items-center gap-2 cursor-pointer select-none\" style=\"font-size: 0.8125rem; line-height: 1.5; color: var(--color-muted);\">\n <input type=\"checkbox\" class=\"custom-checkbox\" checked />\n 记住此设备\n </label>\n <a href=\"#\" class=\"link-muted\" style=\"font-size: 0.8125rem;\">忘记密码?</a>\n </div>\n\n <!-- Submit -->\n <button type=\"submit\" class=\"btn-primary w-full mt-2\">\n <i class=\"fa-solid fa-arrow-right-to-bracket\"></i>\n 登录\n </button>\n </form>\n\n <!-- Signup Link -->\n <div class=\"text-center mt-6 animate-in delay-7\">\n <p style=\"color: var(--color-muted); font-size: 0.8125rem; line-height: 1.5;\">\n 还没有账号?\n <a href=\"#\" class=\"link-muted\" style=\"color: var(--color-primary); font-weight: 500;\">立即注册</a>\n </p>\n </div>\n\n <!-- Footer note -->\n <div class=\"text-center mt-5 pt-4 animate-in delay-8\" style=\"border-top: 1px solid var(--color-border);\">\n <p style=\"color: var(--color-muted); font-size: 0.6875rem; line-height: 1.4; letter-spacing: 0.03em; opacity: 0.7;\">\n 登录即表示同意《服务条款》和《隐私政策》\n </p>\n </div>\n\n </div>\n </main>\n\n <script>\n (function() {\n 'use strict';\n\n // ----- Password Visibility Toggle -----\n const passwordInput = document.getElementById('password');\n const toggleBtn = document.getElementById('passwordToggle');\n const toggleIcon = document.getElementById('toggleIcon');\n\n if (passwordInput && toggleBtn && toggleIcon) {\n toggleBtn.addEventListener('click', function() {\n const isPassword = passwordInput.getAttribute('type') === 'password';\n passwordInput.setAttribute('type', isPassword ? 'text' : 'password');\n toggleIcon.className = isPassword ? 'fa-regular fa-eye-slash' : 'fa-regular fa-eye';\n });\n }\n\n // ----- Form Validation -----\n const form = document.getElementById('loginForm');\n const emailInput = document.getElementById('email');\n const emailError = document.getElementById('emailError');\n const passwordError = document.getElementById('passwordError');\n\n if (form && emailInput && emailError && passwordInput && passwordError) {\n\n // Live validation styles removal on focus\n emailInput.addEventListener('blur', function() {\n if (emailInput.value && !emailInput.checkValidity()) {\n emailInput.classList.add('error');\n emailError.style.display = 'block';\n } else {\n emailInput.classList.remove('error');\n emailError.style.display = 'none';\n }\n });\n\n emailInput.addEventListener('input', function() {\n if (emailInput.classList.contains('error')) {\n if (emailInput.checkValidity()) {\n emailInput.classList.remove('error');\n emailError.style.display = 'none';\n }\n }\n });\n\n passwordInput.addEventListener('blur', function() {\n if (passwordInput.value && passwordInput.value.length < 6) {\n passwordInput.classList.add('error');\n passwordError.style.display = 'block';\n } else {\n passwordInput.classList.remove('error');\n passwordError.style.display = 'none';\n }\n });\n\n passwordInput.addEventListener('input', function() {\n if (passwordInput.classList.contains('error')) {\n if (passwordInput.value.length >= 6) {\n passwordInput.classList.remove('error');\n passwordError.style.display = 'none';\n }\n }\n });\n\n // Submit handler\n form.addEventListener('submit', function(e) {\n e.preventDefault();\n\n let valid = true;\n\n // Email\n if (!emailInput.checkValidity()) {\n emailInput.classList.add('error');\n emailError.style.display = 'block';\n valid = false;\n } else {\n emailInput.classList.remove('error');\n emailError.style.display = 'none';\n }\n\n // Password\n if (passwordInput.value.length < 6) {\n passwordInput.classList.add('error');\n passwordError.style.display = 'block';\n valid = false;\n } else {\n passwordInput.classList.remove('error');\n passwordError.style.display = 'none';\n }\n\n if (valid) {\n // Simulate submission\n const btn = form.querySelector('button[type=\"submit\"]');\n const originalText = btn.innerHTML;\n btn.disabled = true;\n btn.innerHTML = '<i class=\"fa-solid fa-circle-notch fa-spin\"></i> 登录中...';\n setTimeout(function() {\n btn.disabled = false;\n btn.innerHTML = originalText;\n }, 1500);\n }\n });\n }\n\n // ----- Social buttons: smooth disabled simulation (optional) -----\n // No disabled state for social buttons in this UI; they remain interactive\n // to allow full functionality as per design.\n\n // ----- Checkbox: custom style is pure CSS, nothing else needed -----\n\n })();\n </script>\n\n</body>\n</html>"},"next":["增加手机号验证","深色科技风重置密码","仪表板侧边栏导航","社交账号注册页","双因素认证页面"],"breakpoint":"none","plan":{"planId":"b7e3f1a8-9c2d-4f6e-8a1b-3d5e7f9c0a2b","goal":"深色科技风登录页,社交登录+邮箱密码双通道","audience":"已有账号回访用户,或通过社交账号快速注册的新用户","tone":"minimal-dark-tech","type":"fullHTML","designTokens":{"style":{"name":"minimal-dark-tech","mood":"focused","keywords":["dark","glassmorphism","high-contrast","tech","refined"],"density":"comfortable","philosophy":"深色画布上只留必要元素,用光晕和微动效引导视线聚焦表单"},"colors":{"primary":"#6C5CE7","secondary":"#A29BFE","accent":"#00D2D3","success":"#00B894","warning":"#FDCB6E","danger":"#E17055","info":"#74B9FF","background":"#0A0A0F","foreground":"#F0F0F5","card":"#14141E","border":"#2A2A3A","muted":"#6B6B80"},"cssVarPrefix":"--color-","colorRoles":{"primary":{"name":"Deep Violet","role":"CTA按钮、焦点环、品牌主色"},"accent":{"name":"Cyan Teal","role":"社交按钮悬停高亮、装饰光晕"}},"gradients":[{"name":"brand-glow","stops":"linear-gradient(135deg, #6C5CE7 0%, #00D2D3 100%)","role":"按钮渐变背景 & hero 装饰光晕"},{"name":"bg-ambient","stops":"radial-gradient(ellipse at 50% 0%, #1A1A2E 0%, #0A0A0F 70%)","role":"页面背景氛围"}],"states":{"hover":"#7C6DF0","active":"#5A4BD0","focus":"#6C5CE7","disabled":"#3A3A4A"},"fonts":{"heading":"Space Grotesk","body":"Inter","mono":"JetBrains Mono","display":"Space Grotesk","googleFontsUrl":"https://fonts.googleapis.com/css2?family=Space+Grotesk:wght@400;500;600…;:{"heading":"'Space Grotesk', Georgia, serif","body":"'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif","mono":"'JetBrains Mono', 'SF Mono', Consolas, monospace"},"scale":{"display":{"size":"clamp(2rem, 4vw, 3rem)","weight":700,"lineHeight":"1.05","letterSpacing":"-0.025em"},"h1":{"size":"clamp(1.5rem, 2.5vw, 2rem)","weight":600,"lineHeight":"1.15","letterSpacing":"-0.02em"},"h2":{"size":"clamp(1.25rem, 2vw, 1.75rem)","weight":600,"lineHeight":"1.2"},"h3":{"size":"1.25rem","weight":600,"lineHeight":"1.3"},"h4":{"size":"1.125rem","weight":500,"lineHeight":"1.4"},"body":{"size":"0.9375rem","weight":400,"lineHeight":"1.6"},"small":{"size":"0.8125rem","weight":400,"lineHeight":"1.5"},"caption":{"size":"0.75rem","weight":400,"lineHeight":"1.4","letterSpacing":"0.03em"},"button":{"size":"0.875rem","weight":600,"lineHeight":"1","letterSpacing":"0.015em"},"overline":{"size":"0.6875rem","weight":600,"lineHeight":"1.2","letterSpacing":"0.1em"}},"lineHeight":{"tight":"1.1","base":"1.6","loose":"1.8"},"weight":{"regular":400,"medium":500,"semibold":600,"bold":700}},"components":{"button":{"default":"bg=primary fg=#FFFFFF padding=0.75rem 1.5rem radius=md weight=600 border=none","hover":"bg=hover translateY=-1px shadow=md","active":"translateY=0 shadow=sm","disabled":"opacity=0.4 cursor=not-allowed","focus":"ring=2px solid accent offset=2px","variants":{"primary":{"default":"bg=primary fg=#FFFFFF padding=0.75rem 1.5rem radius=md weight=600","hover":"bg=hover shadow=md","active":"bg=active","focus":"ring=2px accent","disabled":"opacity=0.4"},"secondary":{"default":"bg=transparent fg=foreground border=1px solid border padding=0.75rem 1.5rem radius=md","hover":"bg=card border=primary/40","active":"bg=muted/20","focus":"ring=2px accent","disabled":"opacity=0.4"},"social":{"default":"bg=card fg=foreground border=1px solid border padding=0.75rem 1rem radius=md weight=500","hover":"bg=border/30 border=primary/30 shadow=sm","active":"bg=muted/20","focus":"ring=2px accent","disabled":"opacity=0.4"}}},"card":{"default":"bg=card shadow=lg radius=xl padding=2.5rem border=1px solid border/50","hover":"shadow=xl border=primary/20"},"nav":{"default":"bg=transparent","scrolled":"bg=background/80 backdrop-blur=12px","mobile":"drawer-from-right width=85vw"},"input":{"default":"bg=background/60 fg=foreground border=1px solid border radius=md padding=0.75rem 1rem","hover":"border=1px solid muted","focus":"border=1px solid primary ring=3px primary/20","error":"border=1px solid danger ring=3px danger/20","disabled":"opacity=0.4 cursor=not-allowed"}},"layout":{"container":{"maxWidth":"440px","paddingX":"1.5rem"},"grid":{"columns":12,"gap":"1.5rem"}},"spacing":{"gutter":"1.5rem","sectionY":"4rem","scale":["0","0.25rem","0.5rem","0.75rem","1rem","1.5rem","2rem","3rem","4rem","6rem"],"tokens":[0,4,8,12,16,24,32,48,64,96]},"shadow":{"sm":"0 1px 3px rgba(0,0,0,.3)","md":"0 4px 14px rgba(0,0,0,.35)","lg":"0 12px 40px rgba(0,0,0,.45)","xl":"0 24px 80px rgba(0,0,0,.5)"},"surfaces":{"base":"bg=background shadow=none","raised":"bg=card shadow=lg radius=xl","overlay":"bg=card shadow=lg radius=xl","modal":"bg=card shadow=xl radius=xl"},"elevation":{"base":"none","raised":"lg","overlay":"lg","modal":"xl"},"breakpoints":{"sm":"640px","md":"768px","lg":"1024px","xl":"1280px","2xl":"1536px"},"touchTarget":{"min":"44px"},"responsive":{"collapseStrategy":"single-column centered, card padding shrinks from 2.5rem to 1.5rem on sm","hidePriority":["decorative-illustration","brand-tagline"]},"radius":{"sm":"4px","md":"8px","lg":"16px","xl":"24px","full":"9999px"},"transition":{"fast":"150ms ease-out","base":"300ms ease-out","slow":"500ms cubic-bezier(0.4,0,0.2,1)"}},"sections":[{"id":"login-card","type":"hero-centered","purpose":"登录卡片容器,承载品牌标识、社交登录按钮组、邮箱密码表单、底部链接","elements":{"brand_logo":true,"brand_name":true,"social_buttons":3,"divider":true,"email_input":true,"password_input":true,"remember_me":true,"forgot_password":true,"submit_button":true,"signup_link":true},"copy":{"brand":"Nova","brand_tagline":"智能协作平台","social_title":"使用社交账号登录","social_google":"继续使用 Google","social_github":"继续使用 GitHub","social_microsoft":"继续使用 Microsoft","divider_text":"或使用邮箱登录","email_label":"邮箱地址","email_placeholder":"name@company.com","password_label":"密码","password_placeholder":"输入密码","remember_me":"记住此设备","forgot_password":"忘记密码?","submit_text":"登录","signup_prompt":"还没有账号?","signup_link":"立即注册","footer_note":"登录即表示同意《服务条款》和《隐私政策》"},"interactions":["smooth-scroll-to-#login-card","form-validation:email+password","password-visibility-toggle"],"notes":"社交按钮使用 button.variant.social 样式,带对应品牌图标(SVG inline)。邮箱密码表单使用 input 组件规范。"},{"id":"decorative-bg","type":"hero-visual-widget","purpose":"背景装饰光晕与几何元素,增强深色科技氛围,不干扰表单可读性","elements":{"visual_hint":"左上和右下两处径向渐变光晕 + 微细网格线底纹","gradient_orb_left":true,"gradient_orb_right":true},"copy":{},"notes":"纯装饰层,z-index 低于卡片,使用 bg-ambient 渐变 + 两个半透明彩色光晕圆(primary 和 accent 色)"}],"rules":{"dos":["表单卡片用玻璃态半透明背景(bg=card/80 + backdrop-blur),与深色背景拉开层次","社交登录按钮用 outline 样式(border + 透明底),悬停时填充品牌色光晕","输入框聚焦时用 primary 色 ring + 边框,配合 300ms 过渡","忘记密码链接用 muted 色 + hover 变 primary,保持低调可发现","底部协议文字用 caption 字号 + 低对比度,不抢主操作区焦点"],"donts":["不要用紫色渐变 hero 或全屏大图背景——登录页焦点在表单,不在装饰","不要居中三列 feature 或任何无关内容——这是登录页,不是落地页","不要用纯白卡片 + 浅灰背景的 AI 俗套组合","不要用占位符文案或 Lorem ipsum——所有文案必须真实可读","不要堆砌超过 3 个社交登录选项,避免选择瘫痪"]},"promptGuide":{"quickRef":"深色画布 + 紫青渐变光晕 + 玻璃态卡片 + 高对比文字 + 8pt 网格","examples":["用 Nova 风格做个注册页,加手机号验证","用深色科技风做密码重置表单","用相同设计系统做仪表板侧边栏导航"]}},"planReviews":[{"round":1,"ok":true}],"planId":"b7e3f1a8-9c2d-4f6e-8a1b-3d5e7f9c0a2b"}```
角色
assistant
content
total_tokens
15226
summary
生成深色科技风格登录页,含社交登录与邮箱密码双通道
uiParsing
关闭