samirerty commited on
Commit
b16b508
·
verified ·
1 Parent(s): 8da49f8

Upload folder using huggingface_hub

Browse files
Files changed (1) hide show
  1. index.html +640 -620
index.html CHANGED
@@ -1,633 +1,653 @@
1
  <!DOCTYPE html>
2
  <html lang="fa" dir="rtl">
 
3
  <head>
4
- <meta charset="UTF-8">
5
- <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
- <title>ورود و ثبت نام | سیستم امن</title>
7
-
8
- <!-- ایمپورت فونت وزیرمتن برای نمایش زیبای فارسی -->
9
- <link href="https://cdn.jsdelivr.net/gh/rastikerdar/vazirmatn@v33.003/Vazirmatn-font-face.css" rel="stylesheet" type="text/css" />
10
-
11
- <!-- ایمپورت کتابخانه آیکون‌ها -->
12
- <script src="https://unpkg.com/@phosphor-icons/web"></script>
13
-
14
- <style>
15
- /* تنظیمات متغیرهای رنگی و کلی */
16
- :root {
17
- --bg-color: #0f172a;
18
- --card-bg: rgba(30, 41, 59, 0.7);
19
- --input-bg: rgba(15, 23, 42, 0.6);
20
- --primary-color: #6366f1; /* رنگ بنفش ایندیکو */
21
- --primary-hover: #4f46e5;
22
- --text-color: #f8fafc;
23
- --text-muted: #94a3b8;
24
- --border-color: #334155;
25
- --error-color: #ef4444;
26
- --success-color: #22c55e;
27
- --font-family: 'Vazirmatn', sans-serif;
28
- --transition: all 0.3s ease;
29
- }
30
-
31
- * {
32
- box-sizing: border-box;
33
- margin: 0;
34
- padding: 0;
35
- outline: none;
36
- }
37
-
38
- body {
39
- font-family: var(--font-family);
40
- background-color: var(--bg-color);
41
- /* پس‌زمینه گرادینت متحرک برای جذابیت بصری */
42
- background-image:
43
- radial-gradient(at 0% 0%, hsla(253,16%,7%,1) 0, transparent 50%),
44
- radial-gradient(at 50% 0%, hsla(225,39%,30%,1) 0, transparent 50%),
45
- radial-gradient(at 100% 0%, hsla(339,49%,30%,1) 0, transparent 50%);
46
- background-size: 150% 150%;
47
- animation: gradientBG 15s ease infinite;
48
- color: var(--text-color);
49
- min-height: 100vh;
50
- display: flex;
51
- justify-content: center;
52
- align-items: center;
53
- padding: 20px;
54
- overflow-x: hidden;
55
- }
56
-
57
- /* انیمیشن پس زمینه */
58
- @keyframes gradientBG {
59
- 0% { background-position: 0% 50%; }
60
- 50% { background-position: 100% 50%; }
61
- 100% { background-position: 0% 50%; }
62
- }
63
-
64
- /* لینک هدر الزامی */
65
- .header-link {
66
- position: absolute;
67
- top: 20px;
68
- left: 20px; /* چون RTL هستیم، سمت چپ می‌شود */
69
- color: var(--text-muted);
70
- text-decoration: none;
71
- font-size: 0.9rem;
72
- transition: var(--transition);
73
- z-index: 10;
74
- }
75
- .header-link:hover {
76
- color: var(--primary-color);
77
- }
78
-
79
- /* کانتینر اصلی کارت */
80
- .container {
81
- width: 100%;
82
- max-width: 420px;
83
- background: var(--card-bg);
84
- backdrop-filter: blur(12px); /* افکت شیشه‌ای */
85
- -webkit-backdrop-filter: blur(12px);
86
- border: 1px solid rgba(255, 255, 255, 0.1);
87
- border-radius: 24px;
88
- padding: 40px;
89
- box-shadow: 0 25px 50px -12px rgba(0, 0, 0, 0.5);
90
- position: relative;
91
- overflow: hidden;
92
- }
93
-
94
- /* هدر فرم */
95
- .form-header {
96
- text-align: center;
97
- margin-bottom: 30px;
98
- }
99
-
100
- .form-header h2 {
101
- font-size: 1.8rem;
102
- font-weight: 700;
103
- margin-bottom: 8px;
104
- background: linear-gradient(to right, #818cf8, #c084fc);
105
- -webkit-background-clip: text;
106
- -webkit-text-fill-color: transparent;
107
- }
108
-
109
- .form-header p {
110
- color: var(--text-muted);
111
- font-size: 0.95rem;
112
- }
113
-
114
- /* استایل‌های ورودی‌ها */
115
- .input-group {
116
- margin-bottom: 20px;
117
- position: relative;
118
- }
119
-
120
- .input-group label {
121
- display: block;
122
- margin-bottom: 8px;
123
- color: var(--text-muted);
124
- font-size: 0.9rem;
125
- transition: var(--transition);
126
- }
127
-
128
- .input-wrapper {
129
- position: relative;
130
- display: flex;
131
- align-items: center;
132
- }
133
-
134
- .input-wrapper i {
135
- position: absolute;
136
- right: 12px;
137
- color: var(--text-muted);
138
- font-size: 1.2rem;
139
- pointer-events: none;
140
- }
141
-
142
- .input-wrapper input {
143
- width: 100%;
144
- padding: 12px 45px 12px 15px; /* فضای خالی سمت راست برای آیکون */
145
- background: var(--input-bg);
146
- border: 1px solid var(--border-color);
147
- border-radius: 12px;
148
- color: var(--text-color);
149
- font-family: var(--font-family);
150
- font-size: 1rem;
151
- transition: var(--transition);
152
- }
153
-
154
- .input-wrapper input:focus {
155
- border-color: var(--primary-color);
156
- box-shadow: 0 0 0 3px rgba(99, 102, 241, 0.2);
157
- }
158
-
159
- /* دکمه نمایش رمز عبور */
160
- .toggle-password {
161
- position: absolute;
162
- left: 12px;
163
- cursor: pointer;
164
- color: var(--text-muted);
165
- transition: var(--transition);
166
- }
167
- .toggle-password:hover {
168
- color: var(--text-color);
169
- }
170
-
171
- /* بخش کپچا */
172
- .captcha-container {
173
- display: flex;
174
- align-items: center;
175
- gap: 10px;
176
- margin-bottom: 25px;
177
- background: rgba(255, 255, 255, 0.05);
178
- padding: 10px;
179
- border-radius: 12px;
180
- }
181
-
182
- canvas#captchaCanvas {
183
- background-color: #fff;
184
- border-radius: 8px;
185
- cursor: pointer;
186
- }
187
-
188
- .refresh-btn {
189
- background: none;
190
- border: none;
191
- color: var(--primary-color);
192
- cursor: pointer;
193
- font-size: 1.2rem;
194
- transition: var(--transition);
195
- }
196
- .refresh-btn:hover {
197
- transform: rotate(180deg);
198
- }
199
-
200
- /* دکمه ارسال */
201
- .submit-btn {
202
- width: 100%;
203
- padding: 14px;
204
- background: var(--primary-color);
205
- color: white;
206
- border: none;
207
- border-radius: 12px;
208
- font-family: var(--font-family);
209
- font-size: 1rem;
210
- font-weight: 600;
211
- cursor: pointer;
212
- transition: var(--transition);
213
- display: flex;
214
- justify-content: center;
215
- align-items: center;
216
- gap: 8px;
217
- }
218
-
219
- .submit-btn:hover {
220
- background: var(--primary-hover);
221
- transform: translateY(-2px);
222
- box-shadow: 0 4px 12px rgba(99, 102, 241, 0.3);
223
- }
224
-
225
- .submit-btn:active {
226
- transform: translateY(0);
227
- }
228
-
229
- /* لینک تغییر حالت (ورود/ثبت نام) */
230
- .switch-mode {
231
- text-align: center;
232
- margin-top: 20px;
233
- font-size: 0.9rem;
234
- color: var(--text-muted);
235
- }
236
-
237
- .switch-mode button {
238
- background: none;
239
- border: none;
240
- color: var(--primary-color);
241
- cursor: pointer;
242
- font-family: var(--font-family);
243
- font-weight: 600;
244
- padding: 0 5px;
245
- transition: var(--transition);
246
- }
247
-
248
- .switch-mode button:hover {
249
- text-decoration: underline;
250
- }
251
-
252
- /* استایل‌های اضافی برای ثبت نام */
253
- .hidden {
254
- display: none;
255
- }
256
-
257
- .fade-in {
258
- animation: fadeIn 0.4s ease-in-out;
259
- }
260
-
261
- @keyframes fadeIn {
262
- from { opacity: 0; transform: translateY(10px); }
263
- to { opacity: 1; transform: translateY(0); }
264
- }
265
-
266
- /* اعلان‌ها (Toast Notifications) */
267
- .toast-container {
268
- position: fixed;
269
- bottom: 20px;
270
- right: 20px; /* در حالت RTL سمت راست پایین */
271
- z-index: 100;
272
- display: flex;
273
- flex-direction: column;
274
- gap: 10px;
275
- }
276
-
277
- .toast {
278
- background: var(--card-bg);
279
- border-right: 4px solid var(--primary-color);
280
- padding: 15px 20px;
281
- border-radius: 8px;
282
- box-shadow: 0 5px 15px rgba(0,0,0,0.3);
283
- color: var(--text-color);
284
- font-size: 0.9rem;
285
- display: flex;
286
- align-items: center;
287
- gap: 10px;
288
- min-width: 250px;
289
- animation: slideIn 0.3s ease;
290
- backdrop-filter: blur(10px);
291
- }
292
-
293
- .toast.success { border-color: var(--success-color); }
294
- .toast.error { border-color: var(--error-color); }
295
-
296
- @keyframes slideIn {
297
- from { transform: translateX(100%); opacity: 0; }
298
- to { transform: translateX(0); opacity: 1; }
299
- }
300
-
301
- /* ریسپانسیو */
302
- @media (max-width: 480px) {
303
- .container {
304
- padding: 30px 20px;
305
- }
306
- .form-header h2 {
307
- font-size: 1.5rem;
308
- }
309
- }
310
- </style>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
311
  </head>
 
312
  <body>
313
 
314
- <!-- لینک هدر الزامی طبق درخواست -->
315
- <a href="https://huggingface.co/spaces/akhaliq/anycoder" target="_blank" class="header-link">
316
- Built with anycoder
317
- </a>
318
-
319
- <div class="container">
320
- <!-- فرم ورود -->
321
- <div id="login-form" class="fade-in">
322
- <div class="form-header">
323
- <h2>خوش آمدید</h2>
324
- <p>لطفاً برای ادامه وارد حساب کاربری خود شوید</p>
325
- </div>
326
-
327
- <form onsubmit="handleLogin(event)">
328
- <div class="input-group">
329
- <label for="login-username">نام کار��ری</label>
330
- <div class="input-wrapper">
331
- <i class="ph ph-user"></i>
332
- <input type="text" id="login-username" placeholder="نام کاربری خود را وارد کنید" autocomplete="off">
333
- </div>
334
- </div>
335
-
336
- <div class="input-group">
337
- <label for="login-password">رمز عبور</label>
338
- <div class="input-wrapper">
339
- <i class="ph ph-lock-key"></i>
340
- <input type="password" id="login-password" placeholder="رمز عبور خود را وارد کنید">
341
- <i class="ph ph-eye-slash toggle-password" onclick="togglePassword('login-password', this)"></i>
342
- </div>
343
- </div>
344
-
345
- <div class="captcha-container">
346
- <canvas id="captchaCanvas" width="120" height="44" title="برای تغییر کد کلیک کنید"></canvas>
347
- <button type="button" class="refresh-btn" onclick="drawCaptcha()">
348
- <i class="ph ph-arrows-clockwise"></i>
349
- </button>
350
- <input type="text" id="login-captcha" placeholder="کد تصویر" style="width: 100px; padding: 8px; border-radius: 8px; border: 1px solid var(--border-color); background: var(--input-bg); color: white;">
351
- </div>
352
-
353
- <button type="submit" class="submit-btn">
354
- <span>ورود به حساب</span>
355
- <i class="ph ph-sign-in"></i>
356
- </button>
357
-
358
- <div class="switch-mode">
359
- حساب کاربری ندارید؟
360
- <button type="button" onclick="switchForm('register')">ثبت نام کنید</button>
361
- </div>
362
- </form>
363
  </div>
364
 
365
- <!-- فرم ثبت نام -->
366
- <div id="register-form" class="hidden">
367
- <div class="form-header">
368
- <h2>ایجاد حساب</h2>
369
- <p>اطلاعات خود را برای ثبت نام وارد کنید</p>
370
- </div>
371
-
372
- <form onsubmit="handleRegister(event)">
373
- <div class="input-group">
374
- <label for="reg-username">نام کاربری</label>
375
- <div class="input-wrapper">
376
- <i class="ph ph-user"></i>
377
- <input type="text" id="reg-username" placeholder="انتخاب نام کاربری" autocomplete="off">
378
- </div>
379
- </div>
380
-
381
- <div class="input-group">
382
- <label for="reg-password">رمز عبور</label>
383
- <div class="input-wrapper">
384
- <i class="ph ph-lock-key"></i>
385
- <input type="password" id="reg-password" placeholder="رمز عبور قوی انتخاب کنید">
386
- <i class="ph ph-eye-slash toggle-password" onclick="togglePassword('reg-password', this)"></i>
387
- </div>
388
- </div>
389
-
390
- <div class="input-group">
391
- <label for="reg-confirm-password">تکرار رمز عبور</label>
392
- <div class="input-wrapper">
393
- <i class="ph ph-check-circle"></i>
394
- <input type="password" id="reg-confirm-password" placeholder="تکرار رمز عبور">
395
- </div>
396
- </div>
397
-
398
- <div class="captcha-container">
399
- <canvas id="captchaCanvasReg" width="120" height="44" title="برای تغییر کد کلیک کنید"></canvas>
400
- <button type="button" class="refresh-btn" onclick="drawCaptcha(true)">
401
- <i class="ph ph-arrows-clockwise"></i>
402
- </button>
403
- <input type="text" id="reg-captcha" placeholder="کد تصویر" style="width: 100px; padding: 8px; border-radius: 8px; border: 1px solid var(--border-color); background: var(--input-bg); color: white;">
404
- </div>
405
-
406
- <button type="submit" class="submit-btn">
407
- <span>ثبت نام</span>
408
- <i class="ph ph-user-plus"></i>
409
- </button>
410
-
411
- <div class="switch-mode">
412
- قبلاً ثبت نام کرده‌اید؟
413
- <button type="button" onclick="switchForm('login')">وارد شوید</button>
414
- </div>
415
- </form>
416
  </div>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
417
  </div>
418
 
419
- <!-- کانتینر برای نمایش پیام‌ها -->
420
- <div class="toast-container" id="toastContainer"></div>
421
-
422
- <script>
423
- // متغیرهای سراسری برای ذخیره کد کپچا
424
- let currentCaptcha = '';
425
- let currentCaptchaReg = '';
426
-
427
- // اجرای اولیه هنگام لود صفحه
428
- window.onload = function() {
429
- drawCaptcha(); // رسم کپچای فرم ورود
430
- drawCaptcha(true); // رسم کپچای فرم ثبت نام
431
-
432
- // افزودن رویداد کلیک روی بوم نقاشی (Canvas) برای تغییر کپچا
433
- document.getElementById('captchaCanvas').addEventListener('click', () => drawCaptcha());
434
- document.getElementById('captchaCanvasReg').addEventListener('click', () => drawCaptcha(true));
435
- };
436
-
437
- // تابع تغییر بین فرم ورود و ثبت نام
438
- function switchForm(formType) {
439
- const loginForm = document.getElementById('login-form');
440
- const registerForm = document.getElementById('register-form');
441
-
442
- // پاک کردن فیلدها هنگام سوئیچ
443
- document.querySelectorAll('input').forEach(input => input.value = '');
444
-
445
- if (formType === 'register') {
446
- loginForm.classList.add('hidden');
447
- registerForm.classList.remove('hidden');
448
- registerForm.classList.add('fade-in');
449
- drawCaptcha(true); // به‌روزرسانی کپچا
450
- } else {
451
- registerForm.classList.add('hidden');
452
- loginForm.classList.remove('hidden');
453
- loginForm.classList.add('fade-in');
454
- drawCaptcha(); // به‌روزرسانی کپچا
455
- }
456
- }
457
-
458
- // تابع نمایش/مخفی کردن رمز عبور
459
- function togglePassword(inputId, icon) {
460
- const input = document.getElementById(inputId);
461
- if (input.type === 'password') {
462
- input.type = 'text';
463
- icon.classList.remove('ph-eye-slash');
464
- icon.classList.add('ph-eye');
465
- } else {
466
- input.type = 'password';
467
- icon.classList.remove('ph-eye');
468
- icon.classList.add('ph-eye-slash');
469
- }
470
- }
471
-
472
- // تابع تولید و رسم کپچا
473
- function drawCaptcha(isRegister = false) {
474
- const canvasId = isRegister ? 'captchaCanvasReg' : 'captchaCanvas';
475
- const canvas = document.getElementById(canvasId);
476
- const ctx = canvas.getContext('2d');
477
- const width = canvas.width;
478
- const height = canvas.height;
479
-
480
- // پاک کردن بوم
481
- ctx.clearRect(0, 0, width, height);
482
-
483
- // رنگ پس‌زمینه تصادفی خیلی روشن برای کنتراست
484
- ctx.fillStyle = '#e2e8f0';
485
- ctx.fillRect(0, 0, width, height);
486
-
487
- // تولید رشته تصادفی ۵ کاراکتری
488
- const chars = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz';
489
- let captchaText = '';
490
- for (let i = 0; i < 5; i++) {
491
- captchaText += chars.charAt(Math.floor(Math.random() * chars.length));
492
- }
493
-
494
- // ذخیره در متغیر مربوطه
495
- if (isRegister) currentCaptchaReg = captchaText;
496
- else currentCaptcha = captchaText;
497
-
498
- // رسم نویز (خطوط و نقاط) برای امنیت بیشتر
499
- for (let i = 0; i < 7; i++) {
500
- ctx.strokeStyle = `rgba(${Math.random()*255},${Math.random()*255},${Math.random()*255},0.5)`;
501
- ctx.lineWidth = Math.random() * 2;
502
- ctx.beginPath();
503
- ctx.moveTo(Math.random() * width, Math.random() * height);
504
- ctx.lineTo(Math.random() * width, Math.random() * height);
505
- ctx.stroke();
506
- }
507
-
508
- // رسم متن کپچا
509
- ctx.font = 'bold 24px Vazirmatn'; // استفاده از فونت وزیر
510
- ctx.textBaseline = 'middle';
511
-
512
- for (let i = 0; i < captchaText.length; i++) {
513
- ctx.save();
514
- // موقعیت تصادفی کمی جابجا شده
515
- const x = 20 + i * 20;
516
- const y = height / 2 + (Math.random() - 0.5) * 10;
517
- // چرخش تصادفی
518
- const angle = (Math.random() - 0.5) * 0.4;
519
-
520
- ctx.translate(x, y);
521
- ctx.rotate(angle);
522
- ctx.fillStyle = `rgb(${Math.random()*100},${Math.random()*100},${Math.random()*150})`;
523
- ctx.fillText(captchaText[i], 0, 0);
524
- ctx.restore();
525
- }
526
- }
527
-
528
- // تابع مدیریت ورود
529
- function handleLogin(e) {
530
- e.preventDefault();
531
- const username = document.getElementById('login-username').value.trim();
532
- const password = document.getElementById('login-password').value;
533
- const captchaInput = document.getElementById('login-captcha').value.trim();
534
-
535
- // اعتبارسنجی
536
- if (!username || !password) {
537
- showToast('لطفاً تمام فیلدها را پر کنید.', 'error');
538
- return;
539
- }
540
-
541
- if (captchaInput !== currentCaptcha) {
542
- showToast('کد امنیتی اشتباه است.', 'error');
543
- drawCaptcha();
544
- document.getElementById('login-captcha').value = '';
545
- return;
546
- }
547
-
548
- // شبیه‌سازی درخواست به سرور
549
- const btn = e.target.querySelector('.submit-btn');
550
- const originalText = btn.innerHTML;
551
- btn.innerHTML = '<i class="ph ph-spinner ph-spin"></i> در حال پردازش...';
552
- btn.disabled = true;
553
-
554
- setTimeout(() => {
555
- btn.innerHTML = originalText;
556
- btn.disabled = false;
557
- showToast('ورود با موفقیت انجام شد!', 'success');
558
- // اینجا می‌توانید کاربر را ریدایرکت کنید
559
- }, 1500);
560
- }
561
-
562
- // تابع مدیریت ثبت نام
563
- function handleRegister(e) {
564
- e.preventDefault();
565
- const username = document.getElementById('reg-username').value.trim();
566
- const password = document.getElementById('reg-password').value;
567
- const confirmPassword = document.getElementById('reg-confirm-password').value;
568
- const captchaInput = document.getElementById('reg-captcha').value.trim();
569
-
570
- // اعتبارسنجی
571
- if (!username || !password || !confirmPassword) {
572
- showToast('لطفاً تمام فیلدها را پر کنید.', 'error');
573
- return;
574
- }
575
-
576
- if (password.length < 6) {
577
- showToast('رمز عبور باید حداقل ۶ کاراکتر باشد.', 'error');
578
- return;
579
- }
580
-
581
- if (password !== confirmPassword) {
582
- showToast('رمز عبور و تکرار آن مطابقت ندارند.', 'error');
583
- return;
584
- }
585
-
586
- if (captchaInput !== currentCaptchaReg) {
587
- showToast('کد امنیتی اشتباه است.', 'error');
588
- drawCaptcha(true);
589
- document.getElementById('reg-captcha').value = '';
590
- return;
591
- }
592
-
593
- // شبیه‌سازی درخواست به سرور
594
- const btn = e.target.querySelector('.submit-btn');
595
- const originalText = btn.innerHTML;
596
- btn.innerHTML = '<i class="ph ph-spinner ph-spin"></i> در حال ثبت...';
597
- btn.disabled = true;
598
-
599
- setTimeout(() => {
600
- btn.innerHTML = originalText;
601
- btn.disabled = false;
602
- showToast('حساب کاربری با موفقیت ایجاد شد!', 'success');
603
- switchForm('login'); // انتقال به صفحه ورود
604
- }, 1500);
605
- }
606
-
607
- // سیستم نمایش پیام (Toast)
608
- function showToast(message, type = 'success') {
609
- const container = document.getElementById('toastContainer');
610
- const toast = document.createElement('div');
611
- toast.className = `toast ${type}`;
612
-
613
- // انتخاب آیکون بر اساس نوع پیام
614
- const iconClass = type === 'success' ? 'ph-check-circle' : 'ph-warning-circle';
615
-
616
- toast.innerHTML = `
617
- <i class="ph ${iconClass}" style="font-size: 1.2rem;"></i>
618
- <span>${message}</span>
619
- `;
620
-
621
- container.appendChild(toast);
622
-
623
- // حذف خودکار بعد از ۳ ثانیه
624
- setTimeout(() => {
625
- toast.style.animation = 'slideIn 0.3s ease reverse forwards'; // انیمیشن خروج
626
- setTimeout(() => {
627
- toast.remove();
628
- }, 300);
629
- }, 3000);
630
- }
631
- </script>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
632
  </body>
 
633
  </html>
 
1
  <!DOCTYPE html>
2
  <html lang="fa" dir="rtl">
3
+
4
  <head>
5
+ <meta charset="UTF-8">
6
+ <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">
7
+ <title>ورود و ثبت نام | سیستم امن</title>
8
+
9
+ <!-- ایمپورت فونت وزیرمتن -->
10
+ <link href="https://cdn.jsdelivr.net/gh/rastikerdar/vazirmatn@v33.003/Vazirmatn-font-face.css" rel="stylesheet"
11
+ type="text/css" />
12
+
13
+ <!-- ایمپورت کتابخانه آ��کون‌ها -->
14
+ <script src="https://unpkg.com/@phosphor-icons/web"></script>
15
+
16
+ <style>
17
+ /* تنظیمات متغیرهای رنگی و کلی */
18
+ :root {
19
+ --bg-color: #0f172a;
20
+ --card-bg: rgba(30, 41, 59, 0.7);
21
+ --input-bg: rgba(15, 23, 42, 0.6);
22
+ --primary-color: #6366f1;
23
+ --primary-hover: #4f46e5;
24
+ --text-color: #f8fafc;
25
+ --text-muted: #94a3b8;
26
+ --border-color: #334155;
27
+ --error-color: #ef4444;
28
+ --success-color: #22c55e;
29
+ --font-family: 'Vazirmatn', sans-serif;
30
+ --transition: all 0.3s ease;
31
+ --radius: 16px;
32
+ }
33
+
34
+ * {
35
+ box-sizing: border-box;
36
+ margin: 0;
37
+ padding: 0;
38
+ outline: none;
39
+ -webkit-tap-highlight-color: transparent; /* حذف هایلایت آبی در موبایل */
40
+ }
41
+
42
+ body {
43
+ font-family: var(--font-family);
44
+ background-color: var(--bg-color);
45
+ /* پس‌زمینه گرادینت متحرک */
46
+ background-image:
47
+ radial-gradient(at 0% 0%, hsla(253, 16%, 7%, 1) 0, transparent 50%),
48
+ radial-gradient(at 50% 0%, hsla(225, 39%, 30%, 1) 0, transparent 50%),
49
+ radial-gradient(at 100% 0%, hsla(339, 49%, 30%, 1) 0, transparent 50%);
50
+ background-size: 150% 150%;
51
+ animation: gradientBG 15s ease infinite;
52
+ color: var(--text-color);
53
+ min-height: 100vh;
54
+ display: flex;
55
+ justify-content: center;
56
+ align-items: center;
57
+ /* پدینگ امن برای موبایل */
58
+ padding: clamp(15px, 4vw, 40px);
59
+ overflow-x: hidden;
60
+ }
61
+
62
+ @keyframes gradientBG {
63
+ 0% { background-position: 0% 50%; }
64
+ 50% { background-position: 100% 50%; }
65
+ 100% { background-position: 0% 50%; }
66
+ }
67
+
68
+ /* لینک هدر */
69
+ .header-link {
70
+ position: fixed;
71
+ top: 20px;
72
+ left: 20px;
73
+ color: var(--text-muted);
74
+ text-decoration: none;
75
+ font-size: 0.85rem;
76
+ transition: var(--transition);
77
+ z-index: 100;
78
+ background: rgba(15, 23, 42, 0.5);
79
+ padding: 5px 10px;
80
+ border-radius: 20px;
81
+ backdrop-filter: blur(4px);
82
+ }
83
+
84
+ .header-link:hover {
85
+ color: var(--primary-color);
86
+ background: rgba(15, 23, 42, 0.8);
87
+ }
88
+
89
+ /* کانتینر اصلی کارت */
90
+ .container {
91
+ width: 100%;
92
+ max-width: 440px;
93
+ background: var(--card-bg);
94
+ backdrop-filter: blur(16px);
95
+ -webkit-backdrop-filter: blur(16px);
96
+ border: 1px solid rgba(255, 255, 255, 0.1);
97
+ border-radius: 24px;
98
+ /* پدینگ سیال برای رسپانسیو بودن */
99
+ padding: clamp(25px, 6vw, 40px);
100
+ box-shadow: 0 25px 50px -12px rgba(0, 0, 0, 0.5);
101
+ position: relative;
102
+ overflow: hidden;
103
+ margin: auto;
104
+ }
105
+
106
+ /* هدر فرم */
107
+ .form-header {
108
+ text-align: center;
109
+ margin-bottom: clamp(20px, 5vw, 30px);
110
+ }
111
+
112
+ .form-header h2 {
113
+ /* اندازه فونت سیال: بین 1.5rem در موبایل تا 2rem در دسکتاپ */
114
+ font-size: clamp(1.5rem, 4vw, 2rem);
115
+ font-weight: 700;
116
+ margin-bottom: 8px;
117
+ background: linear-gradient(to right, #818cf8, #c084fc);
118
+ -webkit-background-clip: text;
119
+ -webkit-text-fill-color: transparent;
120
+ }
121
+
122
+ .form-header p {
123
+ color: var(--text-muted);
124
+ font-size: clamp(0.85rem, 2vw, 0.95rem);
125
+ }
126
+
127
+ /* ورودی‌ها */
128
+ .input-group {
129
+ margin-bottom: clamp(15px, 4vw, 20px);
130
+ position: relative;
131
+ }
132
+
133
+ .input-group label {
134
+ display: block;
135
+ margin-bottom: 8px;
136
+ color: var(--text-muted);
137
+ font-size: 0.9rem;
138
+ transition: var(--transition);
139
+ }
140
+
141
+ .input-wrapper {
142
+ position: relative;
143
+ display: flex;
144
+ align-items: center;
145
+ }
146
+
147
+ .input-wrapper i.icon-left {
148
+ position: absolute;
149
+ right: 14px;
150
+ color: var(--text-muted);
151
+ font-size: 1.2rem;
152
+ pointer-events: none;
153
+ }
154
+
155
+ .input-wrapper input {
156
+ width: 100%;
157
+ /* ارتفاع مناسب برای لمس در موبایل */
158
+ padding: 14px 45px 14px 15px;
159
+ background: var(--input-bg);
160
+ border: 1px solid var(--border-color);
161
+ border-radius: var(--radius);
162
+ color: var(--text-color);
163
+ font-family: var(--font-family);
164
+ font-size: 1rem;
165
+ transition: var(--transition);
166
+ }
167
+
168
+ .input-wrapper input:focus {
169
+ border-color: var(--primary-color);
170
+ box-shadow: 0 0 0 3px rgba(99, 102, 241, 0.2);
171
+ }
172
+
173
+ .toggle-password {
174
+ position: absolute;
175
+ left: 14px;
176
+ cursor: pointer;
177
+ color: var(--text-muted);
178
+ transition: var(--transition);
179
+ padding: 5px; /* افزایش ناحیه کلیک */
180
+ }
181
+
182
+ .toggle-password:hover {
183
+ color: var(--text-color);
184
+ }
185
+
186
+ /* بخش کپچا - کاملاً رسپانسیو */
187
+ .captcha-container {
188
+ display: flex;
189
+ align-items: center;
190
+ gap: 10px;
191
+ margin-bottom: 25px;
192
+ background: rgba(255, 255, 255, 0.03);
193
+ padding: 10px;
194
+ border-radius: var(--radius);
195
+ flex-wrap: wrap; /* اجازه به خط رفتن در صفحات کوچک */
196
+ justify-content: center;
197
+ }
198
+
199
+ canvas#captchaCanvas, canvas#captchaCanvasReg {
200
+ background-color: #fff;
201
+ border-radius: 8px;
202
+ cursor: pointer;
203
+ flex-shrink: 0; /* جلوگیری از کوچک شدن بیش از حد */
204
+ }
205
+
206
+ .refresh-btn {
207
+ background: none;
208
+ border: none;
209
+ color: var(--primary-color);
210
+ cursor: pointer;
211
+ font-size: 1.2rem;
212
+ transition: var(--transition);
213
+ padding: 5px;
214
+ display: flex;
215
+ align-items: center;
216
+ justify-content: center;
217
+ }
218
+
219
+ .refresh-btn:hover {
220
+ transform: rotate(180deg);
221
+ }
222
+
223
+ .captcha-container input {
224
+ /* ورودی کپچا باید منعطف باشد */
225
+ flex-grow: 1;
226
+ min-width: 100px; /* حداقل عرض */
227
+ padding: 10px;
228
+ border-radius: 8px;
229
+ border: 1px solid var(--border-color);
230
+ background: var(--input-bg);
231
+ color: white;
232
+ text-align: center;
233
+ }
234
+
235
+ /* دکمه ارسال */
236
+ .submit-btn {
237
+ width: 100%;
238
+ padding: 14px;
239
+ background: var(--primary-color);
240
+ color: white;
241
+ border: none;
242
+ border-radius: var(--radius);
243
+ font-family: var(--font-family);
244
+ font-size: 1rem;
245
+ font-weight: 600;
246
+ cursor: pointer;
247
+ transition: var(--transition);
248
+ display: flex;
249
+ justify-content: center;
250
+ align-items: center;
251
+ gap: 8px;
252
+ /* بهبود عملکرد کلیک در موبایل */
253
+ touch-action: manipulation;
254
+ }
255
+
256
+ .submit-btn:hover {
257
+ background: var(--primary-hover);
258
+ transform: translateY(-2px);
259
+ box-shadow: 0 4px 12px rgba(99, 102, 241, 0.3);
260
+ }
261
+
262
+ .submit-btn:active {
263
+ transform: translateY(0);
264
+ }
265
+
266
+ /* لینک تغییر حالت */
267
+ .switch-mode {
268
+ text-align: center;
269
+ margin-top: 20px;
270
+ font-size: 0.9rem;
271
+ color: var(--text-muted);
272
+ }
273
+
274
+ .switch-mode button {
275
+ background: none;
276
+ border: none;
277
+ color: var(--primary-color);
278
+ cursor: pointer;
279
+ font-family: var(--font-family);
280
+ font-weight: 600;
281
+ padding: 0 5px;
282
+ transition: var(--transition);
283
+ }
284
+
285
+ .switch-mode button:hover {
286
+ text-decoration: underline;
287
+ }
288
+
289
+ /* کلاس‌های کمکی */
290
+ .hidden {
291
+ display: none;
292
+ }
293
+
294
+ .fade-in {
295
+ animation: fadeIn 0.4s ease-in-out;
296
+ }
297
+
298
+ @keyframes fadeIn {
299
+ from { opacity: 0; transform: translateY(10px); }
300
+ to { opacity: 1; transform: translateY(0); }
301
+ }
302
+
303
+ /* اعلان‌ها (Toast) - رسپانسیو */
304
+ .toast-container {
305
+ position: fixed;
306
+ bottom: 20px;
307
+ right: 20px;
308
+ left: 20px; /* جلوگیری از خروج از کادر در موبایل */
309
+ z-index: 1000;
310
+ display: flex;
311
+ flex-direction: column;
312
+ gap: 10px;
313
+ align-items: flex-end; /* راست‌چین */
314
+ pointer-events: none; /* کلیک روی فضای خالی مسدود نشود */
315
+ }
316
+
317
+ .toast {
318
+ background: var(--card-bg);
319
+ border-right: 4px solid var(--primary-color);
320
+ padding: 15px 20px;
321
+ border-radius: 8px;
322
+ box-shadow: 0 5px 15px rgba(0, 0, 0, 0.3);
323
+ color: var(--text-color);
324
+ font-size: 0.9rem;
325
+ display: flex;
326
+ align-items: center;
327
+ gap: 10px;
328
+ width: 100%;
329
+ max-width: 350px; /* محدودیت عرض */
330
+ animation: slideIn 0.3s ease;
331
+ backdrop-filter: blur(10px);
332
+ pointer-events: auto;
333
+ margin-bottom: 10px;
334
+ }
335
+
336
+ .toast.success { border-color: var(--success-color); }
337
+ .toast.error { border-color: var(--error-color); }
338
+
339
+ @keyframes slideIn {
340
+ from { transform: translateX(100%); opacity: 0; }
341
+ to { transform: translateX(0); opacity: 1; }
342
+ }
343
+
344
+ /* تنظیمات خاص برای موبایل‌های خیلی کوچک */
345
+ @media (max-width: 360px) {
346
+ .form-header h2 { font-size: 1.4rem; }
347
+ .captcha-container { justify-content: space-between; }
348
+ .captcha-container input { width: 100%; min-width: unset; }
349
+ .toast { font-size: 0.8rem; padding: 12px; }
350
+ }
351
+ </style>
352
  </head>
353
+
354
  <body>
355
 
356
+ <!-- لینک هدر الزامی -->
357
+ <a href="https://huggingface.co/spaces/akhaliq/anycoder" target="_blank" class="header-link">
358
+ Built with anycoder
359
+ </a>
360
+
361
+ <div class="container">
362
+ <!-- فرم ورود -->
363
+ <div id="login-form" class="fade-in">
364
+ <div class="form-header">
365
+ <h2>خوش آمدید</h2>
366
+ <p>لطفاً برای ادامه وارد حساب کاربری خود شوید</p>
367
+ </div>
368
+
369
+ <form onsubmit="handleLogin(event)">
370
+ <div class="input-group">
371
+ <label for="login-username">نام کاربری</label>
372
+ <div class="input-wrapper">
373
+ <i class="ph ph-user icon-left"></i>
374
+ <input type="text" id="login-username" placeholder="نام کاربری خود را وارد کنید" autocomplete="off">
375
+ </div>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
376
  </div>
377
 
378
+ <div class="input-group">
379
+ <label for="login-password">رمز عبور</label>
380
+ <div class="input-wrapper">
381
+ <i class="ph ph-lock-key icon-left"></i>
382
+ <input type="password" id="login-password" placeholder="رمز عبور خود را وارد کنید">
383
+ <i class="ph ph-eye-slash toggle-password" onclick="togglePassword('login-password', this)"></i>
384
+ </div>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
385
  </div>
386
+
387
+ <div class="captcha-container">
388
+ <canvas id="captchaCanvas" width="120" height="44" title="برای تغییر کد کلیک کنید"></canvas>
389
+ <button type="button" class="refresh-btn" onclick="drawCaptcha()">
390
+ <i class="ph ph-arrows-clockwise"></i>
391
+ </button>
392
+ <input type="text" id="login-captcha" placeholder="کد تصویر">
393
+ </div>
394
+
395
+ <button type="submit" class="submit-btn">
396
+ <span>ورود به حساب</span>
397
+ <i class="ph ph-sign-in"></i>
398
+ </button>
399
+
400
+ <div class="switch-mode">
401
+ حساب کاربری ندارید؟
402
+ <button type="button" onclick="switchForm('register')">ثبت نام کنید</button>
403
+ </div>
404
+ </form>
405
  </div>
406
 
407
+ <!-- فرم ثبت نام -->
408
+ <div id="register-form" class="hidden">
409
+ <div class="form-header">
410
+ <h2>ایجاد حساب</h2>
411
+ <p>اطلاعات خود را برای ثبت نام وارد کنید</p>
412
+ </div>
413
+
414
+ <form onsubmit="handleRegister(event)">
415
+ <div class="input-group">
416
+ <label for="reg-username">نام کاربری</label>
417
+ <div class="input-wrapper">
418
+ <i class="ph ph-user icon-left"></i>
419
+ <input type="text" id="reg-username" placeholder="انتخاب نام کاربری" autocomplete="off">
420
+ </div>
421
+ </div>
422
+
423
+ <div class="input-group">
424
+ <label for="reg-password">رمز عبور</label>
425
+ <div class="input-wrapper">
426
+ <i class="ph ph-lock-key icon-left"></i>
427
+ <input type="password" id="reg-password" placeholder="رمز عبور قوی انتخاب کنید">
428
+ <i class="ph ph-eye-slash toggle-password" onclick="togglePassword('reg-password', this)"></i>
429
+ </div>
430
+ </div>
431
+
432
+ <div class="input-group">
433
+ <label for="reg-confirm-password">تکرار رمز عبور</label>
434
+ <div class="input-wrapper">
435
+ <i class="ph ph-check-circle icon-left"></i>
436
+ <input type="password" id="reg-confirm-password" placeholder="تکرار رمز عبور">
437
+ </div>
438
+ </div>
439
+
440
+ <div class="captcha-container">
441
+ <canvas id="captchaCanvasReg" width="120" height="44" title="برای تغییر کد کلیک کنید"></canvas>
442
+ <button type="button" class="refresh-btn" onclick="drawCaptcha(true)">
443
+ <i class="ph ph-arrows-clockwise"></i>
444
+ </button>
445
+ <input type="text" id="reg-captcha" placeholder="کد تصویر">
446
+ </div>
447
+
448
+ <button type="submit" class="submit-btn">
449
+ <span>ثبت نام</span>
450
+ <i class="ph ph-user-plus"></i>
451
+ </button>
452
+
453
+ <div class="switch-mode">
454
+ قبلاً ثبت نام کرده‌اید؟
455
+ <button type="button" onclick="switchForm('login')">وارد شوید</button>
456
+ </div>
457
+ </form>
458
+ </div>
459
+ </div>
460
+
461
+ <!-- کانتینر پیام‌ها -->
462
+ <div class="toast-container" id="toastContainer"></div>
463
+
464
+ <script>
465
+ // متغیرهای سراسری
466
+ let currentCaptcha = '';
467
+ let currentCaptchaReg = '';
468
+
469
+ window.onload = function() {
470
+ drawCaptcha();
471
+ drawCaptcha(true);
472
+
473
+ document.getElementById('captchaCanvas').addEventListener('click', () => drawCaptcha());
474
+ document.getElementById('captchaCanvasReg').addEventListener('click', () => drawCaptcha(true));
475
+ };
476
+
477
+ function switchForm(formType) {
478
+ const loginForm = document.getElementById('login-form');
479
+ const registerForm = document.getElementById('register-form');
480
+
481
+ document.querySelectorAll('input').forEach(input => input.value = '');
482
+
483
+ if (formType === 'register') {
484
+ loginForm.classList.add('hidden');
485
+ registerForm.classList.remove('hidden');
486
+ registerForm.classList.add('fade-in');
487
+ drawCaptcha(true);
488
+ } else {
489
+ registerForm.classList.add('hidden');
490
+ loginForm.classList.remove('hidden');
491
+ loginForm.classList.add('fade-in');
492
+ drawCaptcha();
493
+ }
494
+ }
495
+
496
+ function togglePassword(inputId, icon) {
497
+ const input = document.getElementById(inputId);
498
+ if (input.type === 'password') {
499
+ input.type = 'text';
500
+ icon.classList.remove('ph-eye-slash');
501
+ icon.classList.add('ph-eye');
502
+ } else {
503
+ input.type = 'password';
504
+ icon.classList.remove('ph-eye');
505
+ icon.classList.add('ph-eye-slash');
506
+ }
507
+ }
508
+
509
+ function drawCaptcha(isRegister = false) {
510
+ const canvasId = isRegister ? 'captchaCanvasReg' : 'captchaCanvas';
511
+ const canvas = document.getElementById(canvasId);
512
+ const ctx = canvas.getContext('2d');
513
+ const width = canvas.width;
514
+ const height = canvas.height;
515
+
516
+ ctx.clearRect(0, 0, width, height);
517
+ ctx.fillStyle = '#e2e8f0';
518
+ ctx.fillRect(0, 0, width, height);
519
+
520
+ const chars = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz';
521
+ let captchaText = '';
522
+ for (let i = 0; i < 5; i++) {
523
+ captchaText += chars.charAt(Math.floor(Math.random() * chars.length));
524
+ }
525
+
526
+ if (isRegister) currentCaptchaReg = captchaText;
527
+ else currentCaptcha = captchaText;
528
+
529
+ // نویز
530
+ for (let i = 0; i < 7; i++) {
531
+ ctx.strokeStyle = `rgba(${Math.random()*255},${Math.random()*255},${Math.random()*255},0.5)`;
532
+ ctx.lineWidth = Math.random() * 2;
533
+ ctx.beginPath();
534
+ ctx.moveTo(Math.random() * width, Math.random() * height);
535
+ ctx.lineTo(Math.random() * width, Math.random() * height);
536
+ ctx.stroke();
537
+ }
538
+
539
+ // متن
540
+ ctx.font = 'bold 24px Vazirmatn';
541
+ ctx.textBaseline = 'middle';
542
+
543
+ for (let i = 0; i < captchaText.length; i++) {
544
+ ctx.save();
545
+ const x = 20 + i * 20;
546
+ const y = height / 2 + (Math.random() - 0.5) * 10;
547
+ const angle = (Math.random() - 0.5) * 0.4;
548
+
549
+ ctx.translate(x, y);
550
+ ctx.rotate(angle);
551
+ ctx.fillStyle = `rgb(${Math.random()*100},${Math.random()*100},${Math.random()*150})`;
552
+ ctx.fillText(captchaText[i], 0, 0);
553
+ ctx.restore();
554
+ }
555
+ }
556
+
557
+ function handleLogin(e) {
558
+ e.preventDefault();
559
+ const username = document.getElementById('login-username').value.trim();
560
+ const password = document.getElementById('login-password').value;
561
+ const captchaInput = document.getElementById('login-captcha').value.trim();
562
+
563
+ if (!username || !password) {
564
+ showToast('لطفاً تمام فیلدها را پر کنید.', 'error');
565
+ return;
566
+ }
567
+
568
+ if (captchaInput !== currentCaptcha) {
569
+ showToast('کد امنیتی اشتباه است.', 'error');
570
+ drawCaptcha();
571
+ document.getElementById('login-captcha').value = '';
572
+ return;
573
+ }
574
+
575
+ const btn = e.target.querySelector('.submit-btn');
576
+ const originalText = btn.innerHTML;
577
+ btn.innerHTML = '<i class="ph ph-spinner ph-spin"></i> در حال پردازش...';
578
+ btn.disabled = true;
579
+
580
+ setTimeout(() => {
581
+ btn.innerHTML = originalText;
582
+ btn.disabled = false;
583
+ showToast('ورود با موفقیت انجام شد!', 'success');
584
+ }, 1500);
585
+ }
586
+
587
+ function handleRegister(e) {
588
+ e.preventDefault();
589
+ const username = document.getElementById('reg-username').value.trim();
590
+ const password = document.getElementById('reg-password').value;
591
+ const confirmPassword = document.getElementById('reg-confirm-password').value;
592
+ const captchaInput = document.getElementById('reg-captcha').value.trim();
593
+
594
+ if (!username || !password || !confirmPassword) {
595
+ showToast('لطفاً تمام فیلدها را پر کنید.', 'error');
596
+ return;
597
+ }
598
+
599
+ if (password.length < 6) {
600
+ showToast('رمز عبور باید حداقل ۶ کاراکتر باشد.', 'error');
601
+ return;
602
+ }
603
+
604
+ if (password !== confirmPassword) {
605
+ showToast('رمز عبور و تکرار آن مطابقت ندارند.', 'error');
606
+ return;
607
+ }
608
+
609
+ if (captchaInput !== currentCaptchaReg) {
610
+ showToast('کد امنیتی اشتباه است.', 'error');
611
+ drawCaptcha(true);
612
+ document.getElementById('reg-captcha').value = '';
613
+ return;
614
+ }
615
+
616
+ const btn = e.target.querySelector('.submit-btn');
617
+ const originalText = btn.innerHTML;
618
+ btn.innerHTML = '<i class="ph ph-spinner ph-spin"></i> در حال ثبت...';
619
+ btn.disabled = true;
620
+
621
+ setTimeout(() => {
622
+ btn.innerHTML = originalText;
623
+ btn.disabled = false;
624
+ showToast('حساب کاربری با موفقیت ایجاد شد!', 'success');
625
+ switchForm('login');
626
+ }, 1500);
627
+ }
628
+
629
+ function showToast(message, type = 'success') {
630
+ const container = document.getElementById('toastContainer');
631
+ const toast = document.createElement('div');
632
+ toast.className = `toast ${type}`;
633
+
634
+ const iconClass = type === 'success' ? 'ph-check-circle' : 'ph-warning-circle';
635
+
636
+ toast.innerHTML = `
637
+ <i class="ph ${iconClass}" style="font-size: 1.2rem;"></i>
638
+ <span>${message}</span>
639
+ `;
640
+
641
+ container.appendChild(toast);
642
+
643
+ setTimeout(() => {
644
+ toast.style.animation = 'slideIn 0.3s ease reverse forwards';
645
+ setTimeout(() => {
646
+ toast.remove();
647
+ }, 300);
648
+ }, 3000);
649
+ }
650
+ </script>
651
  </body>
652
+
653
  </html>