@seaverse/auth-sdk 0.2.0 → 0.2.2

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.
package/README.md CHANGED
@@ -126,44 +126,73 @@ await client.resetPassword({
126
126
  });
127
127
  ```
128
128
 
129
- ### 3. OAuth 第三方登录
129
+ ### 3. OAuth 第三方登录 (Backend Proxy Mode)
130
130
 
131
- #### Google 登录
131
+ SDK 使用 Backend Proxy Mode,Client Secret 永不暴露给前端,安全性更高。
132
+
133
+ **优势**:
134
+ - ✅ Client Secret 从不暴露给前端
135
+ - ✅ 支持任意开发者域名(无需在 OAuth 平台配置)
136
+ - ✅ 内置 CSRF 防护
137
+ - ✅ 零配置,开箱即用
138
+
139
+ **工作流程**:
140
+ 1. 前端调用 `{provider}Authorize()` 获取 OAuth URL
141
+ 2. 前端重定向用户到 OAuth 提供商
142
+ 3. 用户授权后,OAuth 提供商回调到固定的 account-hub URL
143
+ 4. account-hub 处理 OAuth,创建 JWT token
144
+ 5. account-hub 302 重定向到 `return_url?token=xxx`
145
+ 6. 前端从 URL 提取 token 并存储
146
+
147
+ #### 使用示例
148
+
149
+ **方式1:使用默认 return_url(当前页面)**
132
150
 
133
151
  ```typescript
134
- // 步骤1: 获取Google授权码后,交换token
135
- const result = await client.googleCodeToToken({
136
- code: 'google-auth-code',
137
- redirectUri: 'https://yourdomain.com/auth/callback',
138
- });
152
+ // Google 登录
153
+ const { authorize_url } = await client.googleAuthorize();
154
+ window.location.href = authorize_url;
139
155
 
140
- localStorage.setItem('token', result.token);
156
+ // Discord 登录
157
+ const { authorize_url } = await client.discordAuthorize();
158
+ window.location.href = authorize_url;
141
159
 
142
- // 解绑Google账号
143
- await client.unlinkGoogle();
160
+ // GitHub 登录
161
+ const { authorize_url } = await client.githubAuthorize();
162
+ window.location.href = authorize_url;
144
163
  ```
145
164
 
146
- #### Discord 登录
165
+ **方式2:自定义 return_url**
147
166
 
148
167
  ```typescript
149
- const result = await client.discordCodeToToken({
150
- code: 'discord-auth-code',
151
- redirectUri: 'https://yourdomain.com/auth/callback',
168
+ // 登录后跳转到 dashboard
169
+ const { authorize_url } = await client.googleAuthorize({
170
+ return_url: 'https://mygame.com/dashboard'
152
171
  });
172
+ window.location.href = authorize_url;
173
+ ```
153
174
 
154
- // 解绑Discord账号
155
- await client.unlinkDiscord();
175
+ **在回调页面提取 token**:
176
+
177
+ ```typescript
178
+ // URL: https://mygame.com/?token=eyJhbGc...
179
+ const token = new URLSearchParams(window.location.search).get('token');
180
+ if (token) {
181
+ localStorage.setItem('token', token);
182
+ // 登录成功,跳转或更新 UI
183
+ }
156
184
  ```
157
185
 
158
- #### GitHub 登录
186
+ #### OAuth 账号解绑
159
187
 
160
188
  ```typescript
161
- const result = await client.githubCodeToToken({
162
- code: 'github-auth-code',
163
- redirectUri: 'https://yourdomain.com/auth/callback',
164
- });
189
+ // 解绑 Google 账号
190
+ await client.unlinkGoogle();
165
191
 
166
- // 解绑GitHub账号
192
+ // 解绑 Discord 账号
193
+ await client.unlinkDiscord();
194
+
195
+ // 解绑 GitHub 账号
167
196
  await client.unlinkGithub();
168
197
  ```
169
198
 
@@ -189,7 +218,7 @@ const client = new SeaVerseBackendAPIClient({
189
218
  environment: 'production',
190
219
  });
191
220
 
192
- // 创建登录弹窗(深色主题)
221
+ // 创建登录弹窗
193
222
  const authModal = new AuthModal({
194
223
  client,
195
224
  theme: 'dark', // 'dark' | 'light' - 默认为 'dark'
@@ -211,20 +240,12 @@ const authModal = new AuthModal({
211
240
  console.error('认证错误:', error.message);
212
241
  },
213
242
 
214
- // OAuth配置(可选)
215
- oauthConfig: {
216
- google: {
217
- clientId: 'YOUR_GOOGLE_CLIENT_ID',
218
- redirectUri: window.location.origin + '/auth/callback',
219
- },
220
- discord: {
221
- clientId: 'YOUR_DISCORD_CLIENT_ID',
222
- redirectUri: window.location.origin + '/auth/callback',
223
- },
224
- github: {
225
- clientId: 'YOUR_GITHUB_CLIENT_ID',
226
- redirectUri: window.location.origin + '/auth/callback',
227
- },
243
+ // OAuth 配置(可选)
244
+ returnUrl: 'https://mygame.com/', // OAuth 登录后返回的 URL,可选,默认为 window.location.origin
245
+ enableOAuth: {
246
+ google: true, // 启用 Google 登录
247
+ discord: true, // 启用 Discord 登录
248
+ github: true, // 启用 GitHub 登录
228
249
  },
229
250
  });
230
251
 
@@ -239,50 +260,98 @@ authModal.hide();
239
260
 
240
261
  // 销毁弹窗
241
262
  authModal.destroy();
263
+ ```
264
+
242
265
  #### OAuth 配置说明
243
266
 
244
- `oauthConfig` 参数是**完全可选的**:
267
+ `enableOAuth` 参数是**完全可选的**:
245
268
 
246
- - 如果**不提供** `oauthConfig`,则不会显示任何第三方登录按钮
247
- - 如果**部分配置**(如只配置 Google),则只显示已配置的按钮
269
+ - 如果**不提供** `enableOAuth`,则不会显示任何第三方登录按钮
270
+ - 如果**部分配置**(如只启用 Google),则只显示已启用的按钮
248
271
  - 如果**完整配置**所有平台,则显示所有第三方登录按钮
249
272
 
273
+ **配置字段说明**:
274
+ - `returnUrl`:**可选** - OAuth 登录后返回的 URL,不填则默认为 `window.location.origin`
275
+ - `enableOAuth.google`:是否启用 Google 登录
276
+ - `enableOAuth.discord`:是否启用 Discord 登录
277
+ - `enableOAuth.github`:是否启用 GitHub 登录
278
+
250
279
  ```typescript
251
280
  // 示例1:无OAuth按钮
252
- const client1 = new SeaVerseBackendAPIClient({ appId: 'your app id' });
253
281
  const authModal1 = new AuthModal({
254
- client: client1,
282
+ client,
255
283
  theme: 'dark',
256
- // 不传 oauthConfig,不显示任何OAuth按钮
284
+ // 不传 enableOAuth,不显示任何OAuth按钮
257
285
  });
258
286
 
259
287
  // 示例2:只显示Google登录
260
- const client2 = new SeaVerseBackendAPIClient({ appId: 'your app id' });
261
288
  const authModal2 = new AuthModal({
262
- client: client2,
289
+ client,
263
290
  theme: 'light',
264
- oauthConfig: {
265
- google: {
266
- clientId: 'YOUR_GOOGLE_CLIENT_ID',
267
- redirectUri: window.location.origin + '/auth/callback',
268
- },
269
- // Discord 和 GitHub 未配置,不会显示这些按钮
291
+ returnUrl: 'https://mygame.com/dashboard',
292
+ enableOAuth: {
293
+ google: true,
294
+ // Discord GitHub 未启用,不会显示这些按钮
270
295
  },
271
296
  });
272
297
 
273
298
  // 示例3:显示所有OAuth按钮
274
- const client3 = new SeaVerseBackendAPIClient({ appId: 'your app id' });
275
299
  const authModal3 = new AuthModal({
276
- client: client3,
300
+ client,
277
301
  theme: 'dark',
278
- oauthConfig: {
279
- google: { clientId: '...', redirectUri: '...' },
280
- discord: { clientId: '...', redirectUri: '...' },
281
- github: { clientId: '...', redirectUri: '...' },
302
+ enableOAuth: {
303
+ google: true,
304
+ discord: true,
305
+ github: true,
282
306
  },
283
307
  });
284
308
  ```
285
309
 
310
+ #### 处理 OAuth 回调
311
+
312
+ 在 Backend Proxy Mode 下,OAuth 登录后会重定向到 `returnUrl?token=xxx`。在页面加载时检查并处理token:
313
+
314
+ ```typescript
315
+ // 在页面加载时自动处理 OAuth 回调
316
+ const result = AuthModal.handleOAuthCallback({
317
+ client,
318
+ onLoginSuccess: (token) => {
319
+ localStorage.setItem('token', token);
320
+ console.log('OAuth 登录成功');
321
+
322
+ // 现在可以直接调用需要认证的接口
323
+ // handleOAuthCallback 已自动调用 client.setToken()
324
+ client.getCurrentUser()
325
+ .then(user => console.log('用户信息:', user));
326
+ },
327
+ });
328
+
329
+ if (result) {
330
+ console.log('处理了 OAuth 回调,token:', result.token);
331
+ }
332
+ ```
333
+
334
+ **重要说明**:
335
+ - `handleOAuthCallback()` 会自动调用 `client.setToken(token)` 来更新 client 的认证配置
336
+ - 这意味着在 `onLoginSuccess` 回调之后,所有需要认证的 API(如 `getCurrentUser()`、`logout()` 等)都会自动带上 `Authorization` header
337
+
338
+ #### 手动设置 Token
339
+
340
+ 如果你不使用 `AuthModal.handleOAuthCallback()`,也可以手动设置 token:
341
+
342
+ ```typescript
343
+ // 从 URL 提取 token
344
+ const token = new URLSearchParams(window.location.search).get('token');
345
+ if (token) {
346
+ // 手动设置 token
347
+ client.setToken(token);
348
+ localStorage.setItem('token', token);
349
+
350
+ // 现在可以调用需要认证的接口
351
+ const user = await client.getCurrentUser();
352
+ }
353
+ ```
354
+
286
355
  ### 5. 容器管理
287
356
 
288
357
  ```typescript
@@ -448,15 +517,16 @@ SDK支持以下环境:
448
517
  | `logout()` | - | `SuccessResponse` | 登出 |
449
518
  | `forgotPassword()` | `{ email }` | `SuccessResponse` | 忘记密码 |
450
519
  | `resetPassword()` | `{ token, new_password }` | `SuccessResponse` | 重置密码 |
520
+ | `setToken()` | `token: string` | `void` | 设置认证 token(OAuth 登录后使用) |
451
521
  | `getApiServiceToken()` | - | `ApiServiceTokenResponse` | 获取API Token |
452
522
 
453
523
  ### OAuth相关
454
524
 
455
525
  | 方法 | 参数 | 返回值 | 说明 |
456
526
  |------|------|--------|------|
457
- | `googleCodeToToken()` | `{ code, redirectUri }` | `OAuthTokenResponse` | Google登录 |
458
- | `discordCodeToToken()` | `{ code, redirectUri }` | `OAuthTokenResponse` | Discord登录 |
459
- | `githubCodeToToken()` | `{ code, redirectUri }` | `OAuthTokenResponse` | GitHub登录 |
527
+ | `googleAuthorize()` | `{ return_url? }` | `OAuthAuthorizeResponse` | Google OAuth 授权 URL |
528
+ | `discordAuthorize()` | `{ return_url? }` | `OAuthAuthorizeResponse` | Discord OAuth 授权 URL |
529
+ | `githubAuthorize()` | `{ return_url? }` | `OAuthAuthorizeResponse` | GitHub OAuth 授权 URL |
460
530
  | `unlinkGoogle()` | - | `SuccessResponse` | 解绑Google |
461
531
  | `unlinkDiscord()` | - | `SuccessResponse` | 解绑Discord |
462
532
  | `unlinkGithub()` | - | `SuccessResponse` | 解绑GitHub |
@@ -533,25 +603,11 @@ interface AuthModalOptions {
533
603
  onLoginSuccess?: (token: string, user: any) => void;
534
604
  onSignupSuccess?: (token: string, user: any) => void;
535
605
  onError?: (error: Error) => void;
536
- oauthConfig?: OAuthConfig;
537
- }
538
-
539
- // OAuth配置
540
- interface OAuthConfig {
541
- google?: {
542
- clientId: string;
543
- redirectUri: string;
544
- scope?: string;
545
- };
546
- discord?: {
547
- clientId: string;
548
- redirectUri: string;
549
- scope?: string;
550
- };
551
- github?: {
552
- clientId: string;
553
- redirectUri: string;
554
- scope?: string;
606
+ returnUrl?: string; // OAuth 登录后返回的 URL,可选,默认为 window.location.origin
607
+ enableOAuth?: {
608
+ google?: boolean; // 启用 Google 登录
609
+ discord?: boolean; // 启用 Discord 登录
610
+ github?: boolean; // 启用 GitHub 登录
555
611
  };
556
612
  }
557
613
  ```
@@ -643,14 +699,7 @@ user.email_verified; // ✅ 无警告
643
699
  ```typescript
644
700
  const user = await client.getCurrentUser();
645
701
 
646
- // 检查用户属于哪个应用
647
- if (user.app_id === 'seaverse') {
648
- console.log('SeaVerse平台用户');
649
- } else if (user.app_id) {
650
- console.log('第三方应用用户:', user.app_id);
651
- } else {
652
- console.log('平台原生用户(无app_id)');
653
- }
702
+ console.log('your app id:', user.app_id);
654
703
  ```
655
704
 
656
705
  ## 常见问题
@@ -1 +1 @@
1
- :root{--font-display:-apple-system,BlinkMacSystemFont,"Segoe UI","Helvetica Neue",Arial,sans-serif;--font-sans:-apple-system,BlinkMacSystemFont,"Segoe UI","Helvetica Neue",Arial,sans-serif;--color-neon-green:#10b981;--color-text-primary:#fff;--color-text-secondary:#a1a1aa;--color-text-tertiary:#71717a;--gradient-neon:linear-gradient(135deg,#10b981,#06b6d4)}.auth-modal{align-items:center;animation:modalFadeIn .3s ease-out;display:flex;inset:0;justify-content:center;overflow:hidden;padding:20px;position:fixed;z-index:9999}.auth-modal.hidden{display:none}@keyframes modalFadeIn{0%{opacity:0}to{opacity:1}}.auth-modal-backdrop{backdrop-filter:blur(8px);-webkit-backdrop-filter:blur(8px);background:rgba(0,0,0,.85);inset:0;position:absolute}.auth-modal-content{animation:modalSlideUp .4s cubic-bezier(.4,0,.2,1);background:#0d0d0d;border:1px solid hsla(0,0%,100%,.08);border-radius:20px;box-shadow:0 25px 80px rgba(0,0,0,.8);display:grid;grid-template-columns:1fr 1fr;max-height:90vh;max-width:900px;overflow:hidden;position:relative;transition:max-width .3s ease;width:100%;z-index:10}.auth-modal-content:has(#loginForm:not(.hidden)){grid-template-columns:1fr auto;max-width:none;width:auto}.auth-modal-content:has(#loginForm:not(.hidden)) .auth-modal-right{min-width:0;width:auto}.auth-modal-content:has(#authMessage:not(.hidden)){grid-template-columns:1fr;max-width:480px}.auth-modal-content:has(#authMessage:not(.hidden)) .auth-modal-left{display:none}@keyframes modalSlideUp{0%{opacity:0;transform:translateY(30px) scale(.96)}to{opacity:1;transform:translateY(0) scale(1)}}.auth-modal-left{background:#000;border-right:1px solid hsla(0,0%,100%,.05);display:flex;flex-direction:column;overflow:hidden;padding:32px;position:relative}.auth-modal-left:before{animation:meshRotate 20s linear infinite;background:radial-gradient(at 0 0,rgba(99,102,241,.3) 0,transparent 50%),radial-gradient(at 50% 0,rgba(139,92,246,.3) 0,transparent 50%),radial-gradient(at 100% 0,rgba(236,72,153,.3) 0,transparent 50%),radial-gradient(at 0 50%,rgba(16,185,129,.3) 0,transparent 50%),radial-gradient(at 100% 50%,rgba(244,63,94,.3) 0,transparent 50%),radial-gradient(at 0 100%,rgba(236,72,153,.3) 0,transparent 50%),radial-gradient(at 100% 100%,rgba(139,92,246,.3) 0,transparent 50%);content:"";filter:blur(80px);height:200%;inset:-50%;opacity:.6;position:absolute;width:200%}@keyframes meshRotate{0%{transform:rotate(0deg)}to{transform:rotate(1turn)}}.auth-modal-left:after{background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 200 200'%3E%3Cfilter id='a'%3E%3CfeTurbulence baseFrequency='.65' numOctaves='3' stitchTiles='stitch' type='fractalNoise'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23a)' opacity='.05'/%3E%3C/svg%3E");content:"";inset:0;mix-blend-mode:overlay;opacity:.4;pointer-events:none;position:absolute}.auth-modal-logo{align-items:center;display:flex;gap:10px;position:relative;z-index:10}.auth-modal-logo .logo-icon{filter:drop-shadow(0 0 10px rgba(16,185,129,.3));height:28px;width:28px}.auth-modal-logo .logo-text{color:#fff;font-family:var(--font-display);font-size:18px;font-weight:700;text-shadow:0 0 20px rgba(0,0,0,.5)}.auth-modal-decoration{inset:0;overflow:hidden;pointer-events:none;position:absolute}.auth-modal-decoration .glow-orb-1{animation:breathe 8s ease-in-out infinite;background:radial-gradient(circle,hsla(0,0%,100%,.05) 0,transparent 70%);border-radius:50%;filter:blur(60px);height:400px;left:50%;pointer-events:none;position:absolute;top:50%;transform:translate(-50%,-50%);width:400px}@keyframes breathe{0%,to{opacity:.5;transform:translate(-50%,-50%) scale(1)}50%{opacity:.8;transform:translate(-50%,-50%) scale(1.2)}}.auth-modal-decoration .glow-orb-2{animation:breathe 10s ease-in-out infinite;animation-delay:2s;background:radial-gradient(circle,rgba(139,92,246,.08) 0,transparent 70%);border-radius:50%;filter:blur(50px);height:300px;pointer-events:none;position:absolute;right:-10%;top:20%;width:300px}.auth-modal-branding{margin-bottom:48px;margin-top:auto;position:relative;z-index:10}.auth-modal-branding .branding-title{color:#fff;font-family:var(--font-display);font-size:36px;font-weight:700;letter-spacing:-.02em;line-height:1.15;margin-bottom:12px;text-shadow:0 2px 10px rgba(0,0,0,.3)}.auth-modal-branding .branding-subtitle{color:hsla(0,0%,100%,.8);font-size:14px;line-height:1.6;max-width:260px}.auth-modal-right{background:#121212;display:flex;flex-direction:column;max-height:90vh;overflow-y:auto;padding:56px 48px 42px;position:relative}.auth-modal-right::-webkit-scrollbar{width:6px}.auth-modal-right::-webkit-scrollbar-track{background:transparent}.auth-modal-right::-webkit-scrollbar-thumb{background:hsla(0,0%,100%,.1);border-radius:3px}.auth-modal-close{align-items:center;background:transparent;border:none;border-radius:8px;color:hsla(0,0%,100%,.5);cursor:pointer;display:flex;height:36px;justify-content:center;position:absolute;right:16px;top:16px;transition:all .2s ease;width:36px;z-index:20}.auth-modal-close:hover{background:hsla(0,0%,100%,.1);color:#fff}.auth-form-view{animation:formFadeIn .3s ease-out}#loginForm .form-input{width:360px}@keyframes formFadeIn{0%{opacity:0;transform:translateY(10px)}to{opacity:1;transform:translateY(0)}}.auth-form-view.hidden{display:none}.auth-form-header{margin-bottom:28px;text-align:center}.auth-form-title{color:#fff;font-family:var(--font-display);font-size:26px;font-weight:700;letter-spacing:-.02em;margin-bottom:8px}.auth-form-subtitle{color:var(--color-text-secondary);font-size:14px}.auth-form{gap:16px}.auth-form,.form-group{display:flex;flex-direction:column}.form-group{gap:6px}.form-label{font-size:12px;font-weight:500;letter-spacing:.02em;opacity:.9;text-transform:uppercase}.form-input,.form-label{color:var(--color-text-primary)}.form-input{background:rgba(30,30,30,.8);border:1px solid hsla(0,0%,100%,.1);border-radius:8px;font-family:var(--font-sans);font-size:14px;height:40px;outline:none;padding:0 14px;transition:all .2s ease;width:100%}.form-input::placeholder{color:hsla(0,0%,100%,.35)}.form-input:hover{border-color:hsla(0,0%,100%,.15)}.form-input:focus{background:rgba(30,30,30,.9);border-color:#10b981;box-shadow:0 0 0 2px rgba(16,185,129,.15)}.form-input:invalid:not(:placeholder-shown){border-color:#ff006e}.input-with-icon{align-items:center;display:flex;position:relative}.input-with-icon .form-input{padding-right:40px}.input-icon-btn{align-items:center;background:transparent;border:none;border-radius:4px;color:hsla(0,0%,100%,.4);cursor:pointer;display:flex;justify-content:center;padding:6px;position:absolute;right:8px;transition:color .2s ease}.input-icon-btn:hover{background:hsla(0,0%,100%,.05);color:hsla(0,0%,100%,.7)}.input-icon-btn .hidden{display:none}.strength-text{align-items:center;color:var(--color-text-tertiary);display:flex;font-size:12px;font-weight:500;gap:6px;margin-top:4px}.form-group-header{align-items:center;display:flex;justify-content:space-between;margin-bottom:8px}.form-group-header .form-label{margin-bottom:0}.forgot-password-link{color:hsla(0,0%,100%,.5);font-size:13px;font-weight:500;position:relative;text-decoration:none;transition:all .25s ease}.forgot-password-link:after{background:#10b981;bottom:-2px;content:"";height:1px;left:0;position:absolute;transition:width .3s ease;width:0}.forgot-password-link:hover{color:#10b981}.forgot-password-link:hover:after{width:100%}.link-primary{color:var(--color-neon-green);font-weight:600;position:relative;text-decoration:none;text-shadow:0 0 10px rgba(0,255,136,.3);transition:all .2s ease}.link-primary:after{background:var(--color-neon-green);bottom:-2px;content:"";height:1px;left:0;position:absolute;transform:scaleX(0);transform-origin:right;transition:transform .3s ease;width:100%}.link-primary:hover{color:#0f8;text-shadow:0 0 20px rgba(0,255,136,.5)}.link-primary:hover:after{transform:scaleX(1);transform-origin:left}.btn-auth-primary{align-items:center;background:var(--gradient-neon);border:none;border-radius:10px;box-shadow:0 4px 12px rgba(16,185,129,.25);color:#000;cursor:pointer;display:flex;font-family:var(--font-sans);font-size:14px;font-weight:600;gap:8px;height:44px;justify-content:center;margin-top:8px;overflow:hidden;padding:0 24px;position:relative;transition:all .3s cubic-bezier(.4,0,.2,1);width:100%}.btn-auth-primary:before{background:linear-gradient(135deg,transparent,hsla(0,0%,100%,.2) 50%,transparent);content:"";inset:0;opacity:0;position:absolute;transition:opacity .3s ease}.btn-auth-primary:hover{box-shadow:0 8px 20px rgba(16,185,129,.35);transform:translateY(-2px)}.btn-auth-primary:hover:before{opacity:1}.btn-auth-primary:active{box-shadow:0 2px 8px rgba(16,185,129,.25);transform:translateY(0)}.btn-auth-primary:disabled{cursor:not-allowed;opacity:.6;transform:none}.btn-auth-primary .btn-text{position:relative;z-index:2}.btn-auth-primary .btn-loader{align-items:center;display:flex;justify-content:center;position:relative;z-index:2}.btn-auth-primary .btn-loader.hidden{display:none}.spinner{animation:spin .8s linear infinite;fill:none;height:20px;stroke-width:3;width:20px}@keyframes spin{to{transform:rotate(1turn)}}.spinner-track{stroke:rgba(0,0,0,.2)}.spinner-circle{animation:spinDash 1.2s ease-in-out infinite;stroke:#000;stroke-dasharray:50;stroke-dashoffset:50}@keyframes spinDash{0%{stroke-dashoffset:50}50%{stroke-dashoffset:12.5}to{stroke-dashoffset:50}}.forgot-password-icon{align-items:center;display:flex;height:100px;justify-content:center;margin:0 auto 24px;position:relative;width:100px}.forgot-password-icon .icon-glow{animation:pulseGlow 3s ease-in-out infinite;background:radial-gradient(circle,rgba(16,185,129,.25) 0,transparent 70%);border-radius:50%;filter:blur(15px);inset:-10px;position:absolute}@keyframes pulseGlow{0%,to{opacity:.5;transform:scale(.95)}50%{opacity:.8;transform:scale(1.05)}}.forgot-password-icon .icon-lock{animation:floatIcon 4s ease-in-out infinite;color:#10b981;filter:drop-shadow(0 0 10px rgba(16,185,129,.4));position:relative;z-index:2}@keyframes floatIcon{0%,to{transform:translateY(0)}50%{transform:translateY(-6px)}}.btn-forgot-password{align-items:center;display:flex;gap:8px;justify-content:center}.btn-forgot-password .btn-arrow{transition:transform .3s ease}.btn-forgot-password:hover .btn-arrow{transform:translateX(4px)}.auth-footer{margin-top:24px;text-align:center}.forgot-footer{display:flex;justify-content:center}.back-to-login{align-items:center;border-radius:6px;color:var(--color-text-secondary);display:inline-flex;font-size:14px;font-weight:500;gap:8px;padding:8px 12px;text-decoration:none;transition:all .2s ease}.back-to-login:hover{background:rgba(16,185,129,.05);color:var(--color-neon-green)}.back-to-login svg{transition:transform .3s ease}.back-to-login:hover svg{transform:translateX(-4px)}.auth-message-content{align-items:center;display:flex;flex-direction:column;padding:24px;text-align:center}.message-icon{align-items:center;background:rgba(16,185,129,.1);border-radius:50%;color:#10b981;display:flex;height:80px;justify-content:center;margin-bottom:24px;width:80px}.message-icon svg{animation:successPulse 2s ease-in-out infinite;filter:drop-shadow(0 0 10px rgba(16,185,129,.3))}@keyframes successPulse{0%,to{transform:scale(1)}50%{transform:scale(1.05)}}.message-title{color:#fff;font-family:var(--font-display);font-size:24px;font-weight:700;margin-bottom:12px}.message-text{color:var(--color-text-secondary);font-size:14px;line-height:1.6;margin-bottom:24px}.divider{align-items:center;color:var(--color-text-tertiary);display:flex;font-size:11px;font-weight:600;gap:12px;letter-spacing:.08em;margin:24px 0 20px;position:relative;text-align:center}.divider:after,.divider:before{background:linear-gradient(90deg,transparent,hsla(0,0%,100%,.1),transparent);content:"";flex:1;height:1px}.social-buttons-grid{display:grid;gap:12px;grid-template-columns:1fr 1fr;margin-bottom:12px}.btn-social{align-items:center;background:rgba(30,30,30,.8);border:1px solid hsla(0,0%,100%,.1);border-radius:10px;color:var(--color-text-primary);cursor:pointer;display:flex;font-family:var(--font-sans);font-size:14px;font-weight:500;gap:10px;height:44px;justify-content:center;overflow:hidden;padding:0 16px;position:relative;transition:all .25s cubic-bezier(.4,0,.2,1)}.btn-social:before{background:linear-gradient(135deg,transparent,hsla(0,0%,100%,.05) 50%,transparent);content:"";inset:0;opacity:0;position:absolute;transition:opacity .3s ease}.btn-social:hover{background:rgba(40,40,40,.9);border-color:hsla(0,0%,100%,.2);box-shadow:0 4px 12px rgba(0,0,0,.3);transform:translateY(-2px)}.btn-social:hover:before{opacity:1}.btn-social:active{transform:translateY(0)}.btn-social svg{flex-shrink:0;height:20px;width:20px}.btn-social span{position:relative;white-space:nowrap;z-index:2}.btn-social-full{align-items:center;background:rgba(30,30,30,.8);border:1px solid hsla(0,0%,100%,.1);border-radius:10px;color:var(--color-text-primary);cursor:pointer;display:flex;font-family:var(--font-sans);font-size:14px;font-weight:500;gap:10px;height:44px;justify-content:center;overflow:hidden;padding:0 16px;position:relative;transition:all .25s cubic-bezier(.4,0,.2,1);width:100%}.btn-social-full:before{background:linear-gradient(135deg,transparent,hsla(0,0%,100%,.05) 50%,transparent);content:"";inset:0;opacity:0;position:absolute;transition:opacity .3s ease}.btn-social-full:hover{background:rgba(40,40,40,.9);border-color:hsla(0,0%,100%,.2);box-shadow:0 4px 12px rgba(0,0,0,.3);transform:translateY(-2px)}.btn-social-full:hover:before{opacity:1}.btn-social-full:active{transform:translateY(0)}.btn-social-full svg{flex-shrink:0;height:20px;width:20px}.btn-social-full span{position:relative;z-index:2}@media (max-width:768px){.auth-modal-content{border-radius:0;grid-template-columns:1fr;max-height:100vh;max-width:100%}.auth-modal-left{display:none}.auth-modal-right{max-height:100vh;padding:24px}.auth-form-title{font-size:22px}#loginForm .form-input{width:100%}.btn-auth-primary{font-size:15px;height:48px}.social-buttons-grid{gap:10px;grid-template-columns:1fr}.btn-social,.btn-social-full{height:48px}}@media (max-width:480px){.auth-modal{padding:0}.auth-modal-content{border-radius:0;max-height:100vh}.auth-modal-right{padding:20px 16px}.auth-form-header{margin-bottom:20px}}.auth-modal-light .auth-modal-backdrop{backdrop-filter:blur(16px) saturate(180%);-webkit-backdrop-filter:blur(16px) saturate(180%);background:hsla(0,0%,100%,.75)}.auth-modal-light .auth-modal-content{background:linear-gradient(135deg,#fdfbf7,#f8f6f2);border:1px solid rgba(16,185,129,.1);box-shadow:0 50px 100px rgba(0,0,0,.12),0 20px 40px rgba(0,0,0,.08),inset 0 0 0 1px hsla(0,0%,100%,.9)}.auth-modal-light .auth-modal-left{background:linear-gradient(135deg,#fff,#faf9f7);border-right:1px solid rgba(16,185,129,.08);box-shadow:2px 0 20px rgba(0,0,0,.03),inset 0 0 0 1px rgba(16,185,129,.05)}.auth-modal-light .auth-modal-left:before{background:radial-gradient(at 0 0,rgba(16,185,129,.08) 0,transparent 50%),radial-gradient(at 50% 0,rgba(6,182,212,.06) 0,transparent 50%),radial-gradient(at 100% 0,rgba(16,185,129,.08) 0,transparent 50%),radial-gradient(at 0 50%,rgba(52,211,153,.05) 0,transparent 50%),radial-gradient(at 100% 50%,rgba(6,182,212,.06) 0,transparent 50%),radial-gradient(at 0 100%,rgba(16,185,129,.07) 0,transparent 50%),radial-gradient(at 100% 100%,rgba(52,211,153,.06) 0,transparent 50%);filter:blur(60px);opacity:.9}.auth-modal-light .auth-modal-left:after{background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 200 200'%3E%3Cfilter id='a'%3E%3CfeTurbulence baseFrequency='.9' numOctaves='4' stitchTiles='stitch' type='fractalNoise'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23a)' opacity='.02'/%3E%3C/svg%3E");mix-blend-mode:multiply;opacity:.6}.auth-modal-light .auth-modal-logo .logo-icon{filter:drop-shadow(0 2px 8px rgba(16,185,129,.25))}.auth-modal-light .auth-modal-logo .logo-text{color:#0a0a0a;text-shadow:0 1px 2px rgba(16,185,129,.1)}.auth-modal-light .auth-modal-decoration .glow-orb-1{background:radial-gradient(circle,rgba(16,185,129,.08) 0,transparent 70%);filter:blur(80px)}.auth-modal-light .auth-modal-decoration .glow-orb-2{background:radial-gradient(circle,rgba(6,182,212,.06) 0,transparent 70%);filter:blur(70px)}.auth-modal-light .auth-modal-branding .branding-title{background:linear-gradient(135deg,#0a0a0a,#1a1a1a);-webkit-background-clip:text;color:#0a0a0a;text-shadow:0 2px 12px rgba(16,185,129,.12);-webkit-text-fill-color:transparent;background-clip:text}.auth-modal-light .auth-modal-branding .branding-subtitle{color:rgba(0,0,0,.6)}.auth-modal-light .auth-modal-right{backdrop-filter:blur(20px);-webkit-backdrop-filter:blur(20px);background:hsla(0,0%,100%,.85);box-shadow:-2px 0 20px rgba(0,0,0,.03)}.auth-modal-light .auth-modal-right::-webkit-scrollbar-thumb{background:rgba(16,185,129,.2)}.auth-modal-light .auth-modal-right::-webkit-scrollbar-thumb:hover{background:rgba(16,185,129,.3)}.auth-modal-light .auth-modal-close{color:rgba(0,0,0,.4)}.auth-modal-light .auth-modal-close:hover{background:rgba(16,185,129,.08);color:#0a0a0a}.auth-modal-light .auth-form-title{background:linear-gradient(135deg,#0a0a0a,#2a2a2a);-webkit-background-clip:text;color:#0a0a0a;-webkit-text-fill-color:transparent;background-clip:text}.auth-modal-light .auth-form-subtitle{color:rgba(0,0,0,.5)}.auth-modal-light .form-label{color:#0a0a0a;opacity:.7}.auth-modal-light .form-input{background:hsla(0,0%,100%,.9);border:1.5px solid rgba(0,0,0,.08);box-shadow:0 1px 2px rgba(0,0,0,.02),inset 0 0 0 1px hsla(0,0%,100%,.8);color:#0a0a0a}.auth-modal-light .form-input::placeholder{color:rgba(0,0,0,.3)}.auth-modal-light .form-input:hover{border-color:rgba(16,185,129,.2);box-shadow:0 2px 4px rgba(0,0,0,.03),inset 0 0 0 1px rgba(16,185,129,.05)}.auth-modal-light .form-input:focus{background:#fff;border-color:#10b981;box-shadow:0 0 0 3px rgba(16,185,129,.12),0 2px 8px rgba(16,185,129,.08)}.auth-modal-light .form-input:invalid:not(:placeholder-shown){border-color:#ff006e;box-shadow:0 0 0 3px rgba(255,0,110,.1)}.auth-modal-light .input-icon-btn{color:rgba(0,0,0,.4)}.auth-modal-light .input-icon-btn:hover{color:rgba(0,0,0,.7)}.auth-modal-light .forgot-password-link{color:#10b981}.auth-modal-light .forgot-password-link:hover{color:#059669;text-shadow:0 0 8px rgba(16,185,129,.2)}.auth-modal-light .strength-text{color:rgba(0,0,0,.45)}.auth-modal-light .btn-auth-primary{background:linear-gradient(135deg,#10b981,#059669);border:none;box-shadow:0 4px 12px rgba(16,185,129,.25),0 2px 4px rgba(16,185,129,.15),inset 0 0 0 1px hsla(0,0%,100%,.3);color:#fff}.auth-modal-light .btn-auth-primary:hover{background:linear-gradient(135deg,#059669,#047857);box-shadow:0 6px 16px rgba(16,185,129,.3),0 3px 6px rgba(16,185,129,.2),inset 0 0 0 1px hsla(0,0%,100%,.4);transform:translateY(-1px)}.auth-modal-light .btn-auth-primary:active{box-shadow:0 2px 8px rgba(16,185,129,.2),0 1px 3px rgba(16,185,129,.15);transform:translateY(0)}.auth-modal-light .btn-auth-primary:disabled{background:linear-gradient(135deg,rgba(16,185,129,.4),rgba(5,150,105,.4));box-shadow:none}.auth-modal-light .btn-forgot-password{background:linear-gradient(135deg,#10b981,#059669)}.auth-modal-light .btn-forgot-password:hover{background:linear-gradient(135deg,#059669,#047857)}.auth-modal-light .btn-forgot-password .btn-arrow{filter:drop-shadow(0 0 4px rgba(255,255,255,.5))}.auth-modal-light .divider{color:rgba(0,0,0,.35)}.auth-modal-light .divider:after,.auth-modal-light .divider:before{background:linear-gradient(90deg,transparent,rgba(0,0,0,.1),transparent)}.auth-modal-light .btn-social,.auth-modal-light .btn-social-full{background:hsla(0,0%,100%,.9);border:1.5px solid rgba(0,0,0,.08);box-shadow:0 2px 4px rgba(0,0,0,.04),inset 0 0 0 1px hsla(0,0%,100%,.8);color:#1a1a1a}.auth-modal-light .btn-social-full:hover,.auth-modal-light .btn-social:hover{background:#fff;border-color:rgba(16,185,129,.2);box-shadow:0 4px 8px rgba(0,0,0,.06),inset 0 0 0 1px rgba(16,185,129,.1);transform:translateY(-1px)}.auth-modal-light .btn-social-full:active,.auth-modal-light .btn-social:active{box-shadow:0 1px 3px rgba(0,0,0,.04),inset 0 0 0 1px rgba(0,0,0,.05);transform:translateY(0)}.auth-modal-light .link-primary{color:#10b981}.auth-modal-light .link-primary:hover{color:#059669;text-shadow:0 0 8px rgba(16,185,129,.2)}.auth-modal-light .forgot-password-icon{background:linear-gradient(135deg,rgba(16,185,129,.08),rgba(6,182,212,.06));box-shadow:0 8px 24px rgba(16,185,129,.12),inset 0 0 0 1px rgba(16,185,129,.1)}.auth-modal-light .forgot-password-icon .icon-glow{background:radial-gradient(circle,rgba(16,185,129,.15) 0,transparent 70%)}.auth-modal-light .forgot-password-icon .icon-lock{color:#10b981;filter:drop-shadow(0 2px 8px rgba(16,185,129,.2))}.auth-modal-light .forgot-password-icon .lock-shackle{animation:shakeLock 2s ease-in-out infinite}.auth-modal-light .back-to-login{color:rgba(0,0,0,.6)}.auth-modal-light .back-to-login:hover{color:#10b981}.auth-modal-light .back-to-login svg{color:rgba(0,0,0,.4)}.auth-modal-light .back-to-login:hover svg{color:#10b981}.auth-modal-light .auth-message-content{background:linear-gradient(135deg,rgba(16,185,129,.05),rgba(6,182,212,.03));box-shadow:0 8px 32px rgba(16,185,129,.12),inset 0 0 0 1px rgba(16,185,129,.1)}.auth-modal-light .message-icon{background:linear-gradient(135deg,#10b981,#059669);box-shadow:0 8px 24px rgba(16,185,129,.3),0 0 0 4px rgba(16,185,129,.1)}.auth-modal-light .message-icon svg{filter:drop-shadow(0 2px 4px rgba(0,0,0,.2))}.auth-modal-light .message-title{background:linear-gradient(135deg,#0a0a0a,#2a2a2a);-webkit-background-clip:text;color:#0a0a0a;-webkit-text-fill-color:transparent;background-clip:text}.auth-modal-light .message-text{color:rgba(0,0,0,.6)}
1
+ :root{--font-display:-apple-system,BlinkMacSystemFont,"Segoe UI","Helvetica Neue",Arial,sans-serif;--font-sans:-apple-system,BlinkMacSystemFont,"Segoe UI","Helvetica Neue",Arial,sans-serif;--color-neon-green:#10b981;--color-text-primary:#fff;--color-text-secondary:#a1a1aa;--color-text-tertiary:#71717a;--gradient-neon:linear-gradient(135deg,#10b981,#06b6d4)}.auth-modal{align-items:center;animation:modalFadeIn .3s ease-out;display:flex;inset:0;justify-content:center;overflow:hidden;padding:20px;position:fixed;z-index:9999}.auth-modal.hidden{display:none}@keyframes modalFadeIn{0%{opacity:0}to{opacity:1}}.auth-modal-backdrop{backdrop-filter:blur(8px);-webkit-backdrop-filter:blur(8px);background:rgba(0,0,0,.85);inset:0;position:absolute}.auth-modal-content{animation:modalSlideUp .4s cubic-bezier(.4,0,.2,1);background:#0d0d0d;border:1px solid hsla(0,0%,100%,.08);border-radius:20px;box-shadow:0 25px 80px rgba(0,0,0,.8);display:grid;grid-template-columns:1fr 1fr;max-height:90vh;max-width:900px;overflow:hidden;position:relative;transition:max-width .3s ease;width:100%;z-index:10}.auth-modal-content:has(#loginForm:not(.hidden)){grid-template-columns:1fr auto;max-width:none;width:auto}.auth-modal-content:has(#loginForm:not(.hidden)) .auth-modal-right{min-width:0;width:auto}.auth-modal-content:has(#authMessage:not(.hidden)){grid-template-columns:1fr;max-width:480px}.auth-modal-content:has(#authMessage:not(.hidden)) .auth-modal-left{display:none}@keyframes modalSlideUp{0%{opacity:0;transform:translateY(30px) scale(.96)}to{opacity:1;transform:translateY(0) scale(1)}}.auth-modal-left{background:#000;border-right:1px solid hsla(0,0%,100%,.05);display:flex;flex-direction:column;overflow:hidden;padding:32px;position:relative}.auth-modal-left:before{animation:meshRotate 20s linear infinite;background:radial-gradient(at 0 0,rgba(99,102,241,.3) 0,transparent 50%),radial-gradient(at 50% 0,rgba(139,92,246,.3) 0,transparent 50%),radial-gradient(at 100% 0,rgba(236,72,153,.3) 0,transparent 50%),radial-gradient(at 0 50%,rgba(16,185,129,.3) 0,transparent 50%),radial-gradient(at 100% 50%,rgba(244,63,94,.3) 0,transparent 50%),radial-gradient(at 0 100%,rgba(236,72,153,.3) 0,transparent 50%),radial-gradient(at 100% 100%,rgba(139,92,246,.3) 0,transparent 50%);content:"";filter:blur(80px);height:200%;inset:-50%;opacity:.6;position:absolute;width:200%}@keyframes meshRotate{0%{transform:rotate(0deg)}to{transform:rotate(1turn)}}.auth-modal-left:after{background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 200 200'%3E%3Cfilter id='a'%3E%3CfeTurbulence baseFrequency='.65' numOctaves='3' stitchTiles='stitch' type='fractalNoise'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23a)' opacity='.05'/%3E%3C/svg%3E");content:"";inset:0;mix-blend-mode:overlay;opacity:.4;pointer-events:none;position:absolute}.auth-modal-logo{align-items:center;display:flex;gap:10px;position:relative;z-index:10}.auth-modal-logo .logo-icon{filter:drop-shadow(0 0 10px rgba(16,185,129,.3));height:28px;width:28px}.auth-modal-logo .logo-text{color:#fff;font-family:var(--font-display);font-size:18px;font-weight:700;text-shadow:0 0 20px rgba(0,0,0,.5)}.auth-modal-decoration{inset:0;overflow:hidden;pointer-events:none;position:absolute}.auth-modal-decoration .glow-orb-1{animation:breathe 8s ease-in-out infinite;background:radial-gradient(circle,hsla(0,0%,100%,.05) 0,transparent 70%);border-radius:50%;filter:blur(60px);height:400px;left:50%;pointer-events:none;position:absolute;top:50%;transform:translate(-50%,-50%);width:400px}@keyframes breathe{0%,to{opacity:.5;transform:translate(-50%,-50%) scale(1)}50%{opacity:.8;transform:translate(-50%,-50%) scale(1.2)}}.auth-modal-decoration .glow-orb-2{animation:breathe 10s ease-in-out infinite;animation-delay:2s;background:radial-gradient(circle,rgba(139,92,246,.08) 0,transparent 70%);border-radius:50%;filter:blur(50px);height:300px;pointer-events:none;position:absolute;right:-10%;top:20%;width:300px}.auth-modal-branding{margin-bottom:48px;margin-top:auto;position:relative;z-index:10}.auth-modal-branding .branding-title{color:#fff;font-family:var(--font-display);font-size:36px;font-weight:700;letter-spacing:-.02em;line-height:1.15;margin-bottom:12px;text-shadow:0 2px 10px rgba(0,0,0,.3)}.auth-modal-branding .branding-subtitle{color:hsla(0,0%,100%,.8);font-size:14px;line-height:1.6;max-width:260px}.auth-modal-right{background:#121212;display:flex;flex-direction:column;max-height:90vh;overflow-y:auto;padding:56px 48px 42px;position:relative}.auth-modal-right::-webkit-scrollbar{width:6px}.auth-modal-right::-webkit-scrollbar-track{background:transparent}.auth-modal-right::-webkit-scrollbar-thumb{background:hsla(0,0%,100%,.1);border-radius:3px}.auth-modal-close{align-items:center;background:transparent;border:none;border-radius:8px;color:hsla(0,0%,100%,.5);cursor:pointer;display:flex;height:36px;justify-content:center;position:absolute;right:16px;top:16px;transition:all .2s ease;width:36px;z-index:20}.auth-modal-close:hover{background:hsla(0,0%,100%,.1);color:#fff}.auth-form-view{animation:formFadeIn .3s ease-out}#loginForm .form-input{width:360px}@keyframes formFadeIn{0%{opacity:0;transform:translateY(10px)}to{opacity:1;transform:translateY(0)}}.auth-form-view.hidden{display:none}.auth-form-header{margin-bottom:28px;text-align:center}.auth-form-title{color:#fff;font-family:var(--font-display);font-size:26px;font-weight:700;letter-spacing:-.02em;margin-bottom:8px}.auth-form-subtitle{color:var(--color-text-secondary);font-size:14px}.auth-form{gap:16px}.auth-form,.form-group{display:flex;flex-direction:column}.form-group{gap:6px}.form-label{font-size:12px;font-weight:500;letter-spacing:.02em;opacity:.9;text-transform:uppercase}.form-input,.form-label{color:var(--color-text-primary)}.form-input{background:rgba(30,30,30,.8);border:1px solid hsla(0,0%,100%,.1);border-radius:8px;font-family:var(--font-sans);font-size:14px;height:40px;outline:none;padding:0 14px;transition:all .2s ease;width:100%}.form-input::placeholder{color:hsla(0,0%,100%,.35)}.form-input:hover{border-color:hsla(0,0%,100%,.15)}.form-input:focus{background:rgba(30,30,30,.9);border-color:#10b981;box-shadow:0 0 0 2px rgba(16,185,129,.15)}.form-input:invalid:not(:placeholder-shown){border-color:#ff006e}.input-with-icon{align-items:center;display:flex;position:relative}.input-with-icon .form-input{padding-right:40px}.input-icon-btn{align-items:center;background:transparent;border:none;border-radius:4px;color:hsla(0,0%,100%,.4);cursor:pointer;display:flex;justify-content:center;padding:6px;position:absolute;right:8px;transition:color .2s ease}.input-icon-btn:hover{background:hsla(0,0%,100%,.05);color:hsla(0,0%,100%,.7)}.input-icon-btn .hidden{display:none}.strength-text{align-items:center;color:var(--color-text-tertiary);display:flex;font-size:12px;font-weight:500;gap:6px;margin-top:4px}.form-group-header{align-items:center;display:flex;justify-content:space-between;margin-bottom:8px}.form-group-header .form-label{margin-bottom:0}.forgot-password-link{color:hsla(0,0%,100%,.5);font-size:13px;font-weight:500;position:relative;text-decoration:none;transition:all .25s ease}.forgot-password-link:after{background:#10b981;bottom:-2px;content:"";height:1px;left:0;position:absolute;transition:width .3s ease;width:0}.forgot-password-link:hover{color:#10b981}.forgot-password-link:hover:after{width:100%}.link-primary{color:var(--color-neon-green);font-weight:600;position:relative;text-decoration:none;text-shadow:0 0 10px rgba(0,255,136,.3);transition:all .2s ease}.link-primary:after{background:var(--color-neon-green);bottom:-2px;content:"";height:1px;left:0;position:absolute;transform:scaleX(0);transform-origin:right;transition:transform .3s ease;width:100%}.link-primary:hover{color:#0f8;text-shadow:0 0 20px rgba(0,255,136,.5)}.link-primary:hover:after{transform:scaleX(1);transform-origin:left}.btn-auth-primary{align-items:center;background:var(--gradient-neon);border:none;border-radius:10px;box-shadow:0 4px 12px rgba(16,185,129,.25);color:#000;cursor:pointer;display:flex;font-family:var(--font-sans);font-size:14px;font-weight:600;gap:8px;height:44px;justify-content:center;margin-top:8px;overflow:hidden;padding:0 24px;position:relative;transition:all .3s cubic-bezier(.4,0,.2,1);width:100%}.btn-auth-primary:before{background:linear-gradient(135deg,transparent,hsla(0,0%,100%,.2) 50%,transparent);content:"";inset:0;opacity:0;position:absolute;transition:opacity .3s ease}.btn-auth-primary:hover{box-shadow:0 8px 20px rgba(16,185,129,.35);transform:translateY(-2px)}.btn-auth-primary:hover:before{opacity:1}.btn-auth-primary:active{box-shadow:0 2px 8px rgba(16,185,129,.25);transform:translateY(0)}.btn-auth-primary:disabled{cursor:not-allowed;opacity:.6;transform:none}.btn-auth-primary .btn-text{position:relative;z-index:2}.btn-auth-primary .btn-loader{align-items:center;display:flex;justify-content:center;position:relative;z-index:2}.btn-auth-primary .btn-loader.hidden{display:none}.spinner{animation:spin .8s linear infinite;fill:none;height:20px;stroke-width:3;width:20px}@keyframes spin{to{transform:rotate(1turn)}}.spinner-track{stroke:rgba(0,0,0,.2)}.spinner-circle{animation:spinDash 1.2s ease-in-out infinite;stroke:#000;stroke-dasharray:50;stroke-dashoffset:50}@keyframes spinDash{0%{stroke-dashoffset:50}50%{stroke-dashoffset:12.5}to{stroke-dashoffset:50}}.forgot-password-icon{align-items:center;display:flex;height:100px;justify-content:center;margin:0 auto 24px;position:relative;width:100px}.forgot-password-icon .icon-glow{animation:pulseGlow 3s ease-in-out infinite;background:radial-gradient(circle,rgba(16,185,129,.25) 0,transparent 70%);border-radius:50%;filter:blur(15px);inset:-10px;position:absolute}@keyframes pulseGlow{0%,to{opacity:.5;transform:scale(.95)}50%{opacity:.8;transform:scale(1.05)}}.forgot-password-icon .icon-lock{animation:floatIcon 4s ease-in-out infinite;color:#10b981;filter:drop-shadow(0 0 10px rgba(16,185,129,.4));position:relative;z-index:2}@keyframes floatIcon{0%,to{transform:translateY(0)}50%{transform:translateY(-6px)}}.btn-forgot-password{align-items:center;display:flex;gap:8px;justify-content:center}.btn-forgot-password .btn-arrow{transition:transform .3s ease}.btn-forgot-password:hover .btn-arrow{transform:translateX(4px)}.auth-footer{margin-top:24px;text-align:center}.forgot-footer{display:flex;justify-content:center}.back-to-login{align-items:center;border-radius:6px;color:var(--color-text-secondary);display:inline-flex;font-size:14px;font-weight:500;gap:8px;padding:8px 12px;text-decoration:none;transition:all .2s ease}.back-to-login:hover{background:rgba(16,185,129,.05);color:var(--color-neon-green)}.back-to-login svg{transition:transform .3s ease}.back-to-login:hover svg{transform:translateX(-4px)}.auth-message-content{align-items:center;display:flex;flex-direction:column;padding:24px;text-align:center}.message-icon{align-items:center;background:rgba(16,185,129,.1);border-radius:50%;color:#10b981;display:flex;height:80px;justify-content:center;margin-bottom:24px;width:80px}.message-icon svg{animation:successPulse 2s ease-in-out infinite;filter:drop-shadow(0 0 10px rgba(16,185,129,.3))}@keyframes successPulse{0%,to{transform:scale(1)}50%{transform:scale(1.05)}}.message-title{color:#fff;font-family:var(--font-display);font-size:24px;font-weight:700;margin-bottom:12px}.message-text{color:var(--color-text-secondary);font-size:14px;line-height:1.6;margin-bottom:24px}.divider{align-items:center;color:var(--color-text-tertiary);display:flex;font-size:11px;font-weight:600;gap:12px;letter-spacing:.08em;margin:24px 0 20px;position:relative;text-align:center}.divider:after,.divider:before{background:linear-gradient(90deg,transparent,hsla(0,0%,100%,.1),transparent);content:"";flex:1;height:1px}.social-buttons-grid{display:grid;gap:12px;grid-template-columns:1fr 1fr}.btn-social{align-items:center;background:rgba(30,30,30,.8);border:1px solid hsla(0,0%,100%,.1);border-radius:10px;color:var(--color-text-primary);cursor:pointer;display:flex;font-family:var(--font-sans);font-size:14px;font-weight:500;gap:10px;height:44px;justify-content:center;margin:0;overflow:hidden;padding:0 16px;position:relative;transition:all .25s cubic-bezier(.4,0,.2,1)}.btn-social:before{background:linear-gradient(135deg,transparent,hsla(0,0%,100%,.05) 50%,transparent);content:"";inset:0;opacity:0;position:absolute;transition:opacity .3s ease}.btn-social:hover{background:rgba(40,40,40,.9);border-color:hsla(0,0%,100%,.2);box-shadow:0 4px 12px rgba(0,0,0,.3);transform:translateY(-2px)}.btn-social:hover:before{opacity:1}.btn-social:active{transform:translateY(0)}.btn-social svg{flex-shrink:0;height:20px;width:20px}.btn-social span{position:relative;white-space:nowrap;z-index:2}.btn-social-full{align-items:center;background:rgba(30,30,30,.8);border:1px solid hsla(0,0%,100%,.1);border-radius:10px;color:var(--color-text-primary);cursor:pointer;display:flex;font-family:var(--font-sans);font-size:14px;font-weight:500;gap:10px;height:44px;justify-content:center;overflow:hidden;padding:0 16px;position:relative;transition:all .25s cubic-bezier(.4,0,.2,1);width:100%}.btn-social-full:before{background:linear-gradient(135deg,transparent,hsla(0,0%,100%,.05) 50%,transparent);content:"";inset:0;opacity:0;position:absolute;transition:opacity .3s ease}.btn-social-full:hover{background:rgba(40,40,40,.9);border-color:hsla(0,0%,100%,.2);box-shadow:0 4px 12px rgba(0,0,0,.3);transform:translateY(-2px)}.btn-social-full:hover:before{opacity:1}.btn-social-full:active{transform:translateY(0)}.btn-social-full svg{flex-shrink:0;height:20px;width:20px}.btn-social-full span{position:relative;z-index:2}@media (max-width:768px){.auth-modal-content{border-radius:0;grid-template-columns:1fr;max-height:100vh;max-width:100%}.auth-modal-left{display:none}.auth-modal-right{max-height:100vh;padding:24px}.auth-form-title{font-size:22px}#loginForm .form-input{width:100%}.btn-auth-primary{font-size:15px;height:48px}.social-buttons-grid{gap:10px;grid-template-columns:1fr}.btn-social,.btn-social-full{height:48px}}@media (max-width:480px){.auth-modal{padding:0}.auth-modal-content{border-radius:0;max-height:100vh}.auth-modal-right{padding:20px 16px}.auth-form-header{margin-bottom:20px}}.auth-modal-light .auth-modal-backdrop{backdrop-filter:blur(16px) saturate(180%);-webkit-backdrop-filter:blur(16px) saturate(180%);background:hsla(0,0%,100%,.75)}.auth-modal-light .auth-modal-content{background:linear-gradient(135deg,#fdfbf7,#f8f6f2);border:1px solid rgba(16,185,129,.1);box-shadow:0 50px 100px rgba(0,0,0,.12),0 20px 40px rgba(0,0,0,.08),inset 0 0 0 1px hsla(0,0%,100%,.9)}.auth-modal-light .auth-modal-left{background:linear-gradient(135deg,#fff,#faf9f7);border-right:1px solid rgba(16,185,129,.08);box-shadow:2px 0 20px rgba(0,0,0,.03),inset 0 0 0 1px rgba(16,185,129,.05)}.auth-modal-light .auth-modal-left:before{background:radial-gradient(at 0 0,rgba(16,185,129,.08) 0,transparent 50%),radial-gradient(at 50% 0,rgba(6,182,212,.06) 0,transparent 50%),radial-gradient(at 100% 0,rgba(16,185,129,.08) 0,transparent 50%),radial-gradient(at 0 50%,rgba(52,211,153,.05) 0,transparent 50%),radial-gradient(at 100% 50%,rgba(6,182,212,.06) 0,transparent 50%),radial-gradient(at 0 100%,rgba(16,185,129,.07) 0,transparent 50%),radial-gradient(at 100% 100%,rgba(52,211,153,.06) 0,transparent 50%);filter:blur(60px);opacity:.9}.auth-modal-light .auth-modal-left:after{background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 200 200'%3E%3Cfilter id='a'%3E%3CfeTurbulence baseFrequency='.9' numOctaves='4' stitchTiles='stitch' type='fractalNoise'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23a)' opacity='.02'/%3E%3C/svg%3E");mix-blend-mode:multiply;opacity:.6}.auth-modal-light .auth-modal-logo .logo-icon{filter:drop-shadow(0 2px 8px rgba(16,185,129,.25))}.auth-modal-light .auth-modal-logo .logo-text{color:#0a0a0a;text-shadow:0 1px 2px rgba(16,185,129,.1)}.auth-modal-light .auth-modal-decoration .glow-orb-1{background:radial-gradient(circle,rgba(16,185,129,.08) 0,transparent 70%);filter:blur(80px)}.auth-modal-light .auth-modal-decoration .glow-orb-2{background:radial-gradient(circle,rgba(6,182,212,.06) 0,transparent 70%);filter:blur(70px)}.auth-modal-light .auth-modal-branding .branding-title{background:linear-gradient(135deg,#0a0a0a,#1a1a1a);-webkit-background-clip:text;color:#0a0a0a;text-shadow:0 2px 12px rgba(16,185,129,.12);-webkit-text-fill-color:transparent;background-clip:text}.auth-modal-light .auth-modal-branding .branding-subtitle{color:rgba(0,0,0,.6)}.auth-modal-light .auth-modal-right{backdrop-filter:blur(20px);-webkit-backdrop-filter:blur(20px);background:hsla(0,0%,100%,.85);box-shadow:-2px 0 20px rgba(0,0,0,.03)}.auth-modal-light .auth-modal-right::-webkit-scrollbar-thumb{background:rgba(16,185,129,.2)}.auth-modal-light .auth-modal-right::-webkit-scrollbar-thumb:hover{background:rgba(16,185,129,.3)}.auth-modal-light .auth-modal-close{color:rgba(0,0,0,.4)}.auth-modal-light .auth-modal-close:hover{background:rgba(16,185,129,.08);color:#0a0a0a}.auth-modal-light .auth-form-title{background:linear-gradient(135deg,#0a0a0a,#2a2a2a);-webkit-background-clip:text;color:#0a0a0a;-webkit-text-fill-color:transparent;background-clip:text}.auth-modal-light .auth-form-subtitle{color:rgba(0,0,0,.5)}.auth-modal-light .form-label{color:#0a0a0a;opacity:.7}.auth-modal-light .form-input{background:hsla(0,0%,100%,.9);border:1.5px solid rgba(0,0,0,.08);box-shadow:0 1px 2px rgba(0,0,0,.02),inset 0 0 0 1px hsla(0,0%,100%,.8);color:#0a0a0a}.auth-modal-light .form-input::placeholder{color:rgba(0,0,0,.3)}.auth-modal-light .form-input:hover{border-color:rgba(16,185,129,.2);box-shadow:0 2px 4px rgba(0,0,0,.03),inset 0 0 0 1px rgba(16,185,129,.05)}.auth-modal-light .form-input:focus{background:#fff;border-color:#10b981;box-shadow:0 0 0 3px rgba(16,185,129,.12),0 2px 8px rgba(16,185,129,.08)}.auth-modal-light .form-input:invalid:not(:placeholder-shown){border-color:#ff006e;box-shadow:0 0 0 3px rgba(255,0,110,.1)}.auth-modal-light .input-icon-btn{color:rgba(0,0,0,.4)}.auth-modal-light .input-icon-btn:hover{color:rgba(0,0,0,.7)}.auth-modal-light .forgot-password-link{color:#10b981}.auth-modal-light .forgot-password-link:hover{color:#059669;text-shadow:0 0 8px rgba(16,185,129,.2)}.auth-modal-light .strength-text{color:rgba(0,0,0,.45)}.auth-modal-light .btn-auth-primary{background:linear-gradient(135deg,#10b981,#059669);border:none;box-shadow:0 4px 12px rgba(16,185,129,.25),0 2px 4px rgba(16,185,129,.15),inset 0 0 0 1px hsla(0,0%,100%,.3);color:#fff}.auth-modal-light .btn-auth-primary:hover{background:linear-gradient(135deg,#059669,#047857);box-shadow:0 6px 16px rgba(16,185,129,.3),0 3px 6px rgba(16,185,129,.2),inset 0 0 0 1px hsla(0,0%,100%,.4);transform:translateY(-1px)}.auth-modal-light .btn-auth-primary:active{box-shadow:0 2px 8px rgba(16,185,129,.2),0 1px 3px rgba(16,185,129,.15);transform:translateY(0)}.auth-modal-light .btn-auth-primary:disabled{background:linear-gradient(135deg,rgba(16,185,129,.4),rgba(5,150,105,.4));box-shadow:none}.auth-modal-light .btn-forgot-password{background:linear-gradient(135deg,#10b981,#059669)}.auth-modal-light .btn-forgot-password:hover{background:linear-gradient(135deg,#059669,#047857)}.auth-modal-light .btn-forgot-password .btn-arrow{filter:drop-shadow(0 0 4px rgba(255,255,255,.5))}.auth-modal-light .divider{color:rgba(0,0,0,.35)}.auth-modal-light .divider:after,.auth-modal-light .divider:before{background:linear-gradient(90deg,transparent,rgba(0,0,0,.1),transparent)}.auth-modal-light .btn-social,.auth-modal-light .btn-social-full{background:hsla(0,0%,100%,.9);border:1.5px solid rgba(0,0,0,.08);box-shadow:0 2px 4px rgba(0,0,0,.04),inset 0 0 0 1px hsla(0,0%,100%,.8);color:#1a1a1a}.auth-modal-light .btn-social-full:hover,.auth-modal-light .btn-social:hover{background:#fff;border-color:rgba(16,185,129,.2);box-shadow:0 4px 8px rgba(0,0,0,.06),inset 0 0 0 1px rgba(16,185,129,.1);transform:translateY(-1px)}.auth-modal-light .btn-social-full:active,.auth-modal-light .btn-social:active{box-shadow:0 1px 3px rgba(0,0,0,.04),inset 0 0 0 1px rgba(0,0,0,.05);transform:translateY(0)}.auth-modal-light .link-primary{color:#10b981}.auth-modal-light .link-primary:hover{color:#059669;text-shadow:0 0 8px rgba(16,185,129,.2)}.auth-modal-light .forgot-password-icon{background:linear-gradient(135deg,rgba(16,185,129,.08),rgba(6,182,212,.06));box-shadow:0 8px 24px rgba(16,185,129,.12),inset 0 0 0 1px rgba(16,185,129,.1)}.auth-modal-light .forgot-password-icon .icon-glow{background:radial-gradient(circle,rgba(16,185,129,.15) 0,transparent 70%)}.auth-modal-light .forgot-password-icon .icon-lock{color:#10b981;filter:drop-shadow(0 2px 8px rgba(16,185,129,.2))}.auth-modal-light .forgot-password-icon .lock-shackle{animation:shakeLock 2s ease-in-out infinite}.auth-modal-light .back-to-login{color:rgba(0,0,0,.6)}.auth-modal-light .back-to-login:hover{color:#10b981}.auth-modal-light .back-to-login svg{color:rgba(0,0,0,.4)}.auth-modal-light .back-to-login:hover svg{color:#10b981}.auth-modal-light .auth-message-content{background:linear-gradient(135deg,rgba(16,185,129,.05),rgba(6,182,212,.03));box-shadow:0 8px 32px rgba(16,185,129,.12),inset 0 0 0 1px rgba(16,185,129,.1)}.auth-modal-light .message-icon{background:linear-gradient(135deg,#10b981,#059669);box-shadow:0 8px 24px rgba(16,185,129,.3),0 0 0 4px rgba(16,185,129,.1)}.auth-modal-light .message-icon svg{filter:drop-shadow(0 2px 4px rgba(0,0,0,.2))}.auth-modal-light .message-title{background:linear-gradient(135deg,#0a0a0a,#2a2a2a);-webkit-background-clip:text;color:#0a0a0a;-webkit-text-fill-color:transparent;background-clip:text}.auth-modal-light .message-text{color:rgba(0,0,0,.6)}