thenightfury commited on
Commit
e839280
·
verified ·
1 Parent(s): 986b939

Update index.html

Browse files
Files changed (1) hide show
  1. index.html +1487 -18
index.html CHANGED
@@ -1,19 +1,1488 @@
1
- <!doctype html>
2
- <html>
3
- <head>
4
- <meta charset="utf-8" />
5
- <meta name="viewport" content="width=device-width" />
6
- <title>My static Space</title>
7
- <link rel="stylesheet" href="style.css" />
8
- </head>
9
- <body>
10
- <div class="card">
11
- <h1>Welcome to your static Space!</h1>
12
- <p>You can modify this app directly by editing <i>index.html</i> in the Files and versions tab.</p>
13
- <p>
14
- Also don't forget to check the
15
- <a href="https://huggingface.co/docs/hub/spaces" target="_blank">Spaces documentation</a>.
16
- </p>
17
- </div>
18
- </body>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
19
  </html>
 
1
+ <!DOCTYPE html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="UTF-8">
5
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
+ <title>TamilReal Portrait Prompt Studio</title>
7
+ <script src="https://cdn.tailwindcss.com"></script>
8
+ <!-- Font: Inter for body text -->
9
+ <link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600&display=swap" rel="stylesheet">
10
+ <link href="https://fonts.googleapis.com/css2?family=Playfair+Display:wght@700&family=Poppins:wght@400;500;600&display=swap" rel="stylesheet">
11
+ <style>
12
+ /* Accessibility: focus styles for keyboard navigation */
13
+ :focus-visible {
14
+ outline: none;
15
+ box-shadow: 0 0 0 3px var(--terracotta);
16
+ border-radius: 4px;
17
+ }
18
+ /* General interactive element focus support */
19
+ button.clay-btn:focus, button.clay-btn:focus-visible,
20
+ .clay-tab:focus, .clay-tab:focus-visible,
21
+ .clay-input:focus, .clay-input:focus-visible,
22
+ .clay-select:focus, .clay-select:focus-visible {
23
+ outline: none;
24
+ box-shadow: 0 0 0 3px var(--terracotta);
25
+ }
26
+
27
+ /* Task 1: Fluid full-bleed container */
28
+ .main-container {
29
+ width: 100vw;
30
+ margin-left: calc(-50vw + 50%);
31
+ padding-left: 2rem; /* Increased padding */
32
+ padding-right: 2rem;
33
+ box-sizing: border-box;
34
+ }
35
+ /* Content inner width control */
36
+ .content-inner {
37
+ max-width: 1200px;
38
+ margin: 0 auto;
39
+ }
40
+
41
+ /* Content0 full width styling - no borders */
42
+ #content0 {
43
+ width: 100%;
44
+ padding-left: 2rem;
45
+ padding-right: 2rem;
46
+ padding-top: 1.5rem;
47
+ padding-bottom: 1.5rem;
48
+ box-sizing: border-box;
49
+ border: none;
50
+ border-radius: 10px;
51
+ }
52
+ @media (max-width: 768px) {
53
+ #content0 {
54
+ padding-left: 1rem;
55
+ padding-right: 1rem;
56
+ }
57
+ }
58
+
59
+ /* Content1 and Content2 - remove borders and radius */
60
+ #content1, #content2 {
61
+ border: none;
62
+ border-radius: 0;
63
+ }
64
+
65
+ /* Identity Anchor full width */
66
+ .identity-anchor {
67
+ width: 100%;
68
+ box-sizing: border-box;
69
+ }
70
+
71
+ /* Claymorphism Theme (Default) */
72
+ :root, [data-theme="clay"] {
73
+ --bg: #2c221b;
74
+ --clay: #3f2a21;
75
+ --terracotta: #d9775a;
76
+ --terracotta-dark: #b56347;
77
+ --input-bg: #2c221b;
78
+ --input-text: #e8e0d8;
79
+ --tab-bg: rgba(0,0,0,0.25);
80
+ --tab-text: #b8a090;
81
+ --tab-hover: rgba(0,0,0,0.35);
82
+ --title-gradient: linear-gradient(135deg, var(--terracotta), #f4a261);
83
+ --shadow-sm: 5px 5px 12px rgba(0,0,0,0.35), -3px -3px 10px rgba(255,255,255,0.12);
84
+ --shadow-lg: 10px 10px 24px rgba(0,0,0,0.35), -10px -10px 24px rgba(80,60,50,0.2);
85
+ --shadow-inset: inset 4px 4px 10px rgba(0,0,0,0.45), inset -3px -3px 8px rgba(80,60,50,0.2);
86
+ --border-subtle: rgba(255,255,255,0.08);
87
+ --card-radius: 2.75rem;
88
+ --btn-radius: 9999px;
89
+ --focus-ring: 0 0 0 2px var(--terracotta);
90
+ --font-body: Inter, system-ui, -apple-system, "Segoe UI", Roboto, Arial, sans-serif;
91
+ --font-title: "Playfair Display", serif;
92
+ }
93
+
94
+ body {
95
+ font-family: var(--font-body);
96
+ background: var(--bg);
97
+ color: var(--input-text);
98
+ transition: background 0.3s ease, color 0.3s ease;
99
+ }
100
+
101
+ .clay-title {
102
+ font-family: var(--font-title);
103
+ background: var(--title-gradient);
104
+ -webkit-background-clip: text;
105
+ -webkit-text-fill-color: transparent;
106
+ background-clip: text;
107
+ }
108
+
109
+ .clay-card {
110
+ background: var(--clay);
111
+ border-radius: var(--card-radius);
112
+ box-shadow: var(--shadow-lg), inset 0 0 0 1px var(--border-subtle);
113
+ transition: all 0.3s ease;
114
+ }
115
+
116
+ .clay-input, .clay-select {
117
+ background: var(--input-bg);
118
+ border: none;
119
+ border-radius: 2rem;
120
+ box-shadow: var(--shadow-inset);
121
+ color: var(--input-text);
122
+ padding: 0.75rem 1.25rem;
123
+ transition: all 0.2s ease;
124
+ }
125
+
126
+ .clay-input:focus, .clay-select:focus {
127
+ outline: none;
128
+ box-shadow: var(--shadow-inset), var(--focus-ring);
129
+ }
130
+
131
+ /* Claymorphism specific refinements */
132
+ [data-theme="clay"] .clay-card {
133
+ position: relative;
134
+ overflow: hidden;
135
+ }
136
+ [data-theme="clay"] .clay-card::before {
137
+ content: '';
138
+ position: absolute;
139
+ inset: 0;
140
+ background:
141
+ radial-gradient(circle at 30% 20%, rgba(255,255,255,0.03) 0%, transparent 50%),
142
+ radial-gradient(circle at 70% 80%, rgba(0,0,0,0.05) 0%, transparent 50%);
143
+ pointer-events: none;
144
+ }
145
+
146
+ .clay-btn {
147
+ background: linear-gradient(145deg, var(--terracotta), var(--terracotta-dark));
148
+ border: none;
149
+ border-radius: var(--btn-radius);
150
+ color: white;
151
+ padding: 0.75rem 2rem;
152
+ font-weight: 600;
153
+ cursor: pointer;
154
+ transition: all 0.2s ease;
155
+ box-shadow: var(--shadow-sm);
156
+ }
157
+
158
+ .clay-btn:hover {
159
+ transform: translateY(-2px) scale(1.02);
160
+ box-shadow: 6px 6px 14px rgba(0,0,0,0.35), -3px -3px 10px rgba(255,255,255,0.12);
161
+ }
162
+
163
+ .clay-btn:active {
164
+ transform: translateY(0) scale(0.98);
165
+ }
166
+
167
+ .clay-tab {
168
+ background: var(--tab-bg);
169
+ border: none;
170
+ border-radius: 15px;
171
+ color: var(--tab-text);
172
+ padding: 0.6rem 1.5rem;
173
+ font-weight: 500;
174
+ cursor: pointer;
175
+ transition: all 0.2s ease;
176
+ }
177
+
178
+ .clay-tab:hover {
179
+ color: var(--input-text);
180
+ background: var(--tab-hover);
181
+ }
182
+
183
+ .clay-tab-active {
184
+ background: var(--terracotta);
185
+ color: white;
186
+ transform: scale(1.08);
187
+ box-shadow: 0 4px 12px rgba(217,119,90,0.4);
188
+ border-radius: 15px;
189
+ }
190
+
191
+ .clay-modal {
192
+ background: var(--clay);
193
+ border-radius: 1.5rem;
194
+ box-shadow: 0 25px 50px rgba(0,0,0,0.5);
195
+ }
196
+
197
+ .identity-warn {
198
+ background: #7f1d1d;
199
+ color: #fecaca;
200
+ padding: 0.25rem 0.75rem;
201
+ border-radius: 9999px;
202
+ font-size: 0.75rem;
203
+ font-weight: 500;
204
+ }
205
+
206
+ .enhancer-note {
207
+ color: #fbbf24;
208
+ border: 1px solid #fbbf24;
209
+ padding: 0.25rem 0.5rem;
210
+ border-radius: 0.375rem;
211
+ font-size: 0.7rem;
212
+ }
213
+
214
+ .hidden { display: none !important; }
215
+
216
+ #toast {
217
+ position: fixed;
218
+ bottom: 2rem;
219
+ left: 50%;
220
+ transform: translateX(-50%);
221
+ background: #1f2937;
222
+ color: white;
223
+ padding: 1rem 2rem;
224
+ border-radius: 0.75rem;
225
+ box-shadow: 0 10px 25px rgba(0,0,0,0.3);
226
+ z-index: 100;
227
+ min-width: 280px;
228
+ text-align: center;
229
+ }
230
+
231
+ @keyframes toastPop {
232
+ from { transform: translate(-50%, 30px); opacity: 0; }
233
+ to { transform: translate(-50%, 0); opacity: 1; }
234
+ }
235
+
236
+ .toast-animate {
237
+ animation: toastPop 0.3s ease-out;
238
+ }
239
+
240
+ /* Theme: Glassmorphism */
241
+ [data-theme="glass"] {
242
+ --bg: linear-gradient(135deg, #0f172a 0%, #1e1b4b 50%, #0f172a 100%);
243
+ --clay: rgba(255,255,255,0.20);
244
+ --input-bg: rgba(255,255,255,0.15);
245
+ --input-text: #e2e8f0;
246
+ --tab-bg: rgba(255,255,255,0.15);
247
+ --tab-text: #cbd5e1;
248
+ --tab-hover: rgba(255,255,255,0.25);
249
+ --terracotta: #818cf8;
250
+ --terracotta-dark: #6366f1;
251
+ --title-gradient: linear-gradient(135deg, #a5b4fc, #818cf8);
252
+ --shadow-sm: 0 8px 20px rgba(99,102,241,0.3);
253
+ --shadow-lg: 0 16px 40px rgba(0,0,0,0.25);
254
+ --shadow-inset: none;
255
+ --border-subtle: rgba(255,255,255,0.2);
256
+ --card-radius: 1.5rem;
257
+ --btn-radius: 9999px;
258
+ --font-body: Inter, system-ui, -apple-system, "Segoe UI", Roboto, Arial, sans-serif;
259
+ --font-title: "Playfair Display", serif;
260
+ --focus-ring: 0 0 0 2px #818cf8;
261
+ }
262
+
263
+ [data-theme="glass"] .clay-card {
264
+ background: rgba(255,255,255,0.20);
265
+ backdrop-filter: blur(20px) saturate(180%);
266
+ -webkit-backdrop-filter: blur(20px) saturate(180%);
267
+ border: 1px solid rgba(255,255,255,0.2);
268
+ box-shadow: var(--shadow-lg), 0 0 40px rgba(99,102,241,0.15);
269
+ }
270
+
271
+ [data-theme="glass"] .clay-input, [data-theme="glass"] .clay-select {
272
+ background: rgba(255,255,255,0.15);
273
+ border: 1px solid rgba(255,255,255,0.25);
274
+ box-shadow: none;
275
+ color: #e2e8f0;
276
+ }
277
+
278
+ [data-theme="glass"] .clay-input::placeholder, [data-theme="glass"] .clay-select option {
279
+ color: rgba(226, 232, 240, 0.6);
280
+ }
281
+
282
+ [data-theme="glass"] .clay-input:focus, [data-theme="glass"] .clay-select:focus {
283
+ border-color: rgba(129,140,248,0.6);
284
+ box-shadow: 0 0 0 3px rgba(129,140,248,0.2);
285
+ }
286
+
287
+ [data-theme="glass"] .clay-select {
288
+ color: #e2e8f0;
289
+ }
290
+
291
+ [data-theme="glass"] .clay-select option {
292
+ background: #1e1b4b;
293
+ color: #e2e8f0;
294
+ }
295
+
296
+ [data-theme="glass"] .clay-tab-active {
297
+ background: linear-gradient(145deg, #818cf8, #6366f1);
298
+ box-shadow: 0 6px 20px rgba(99,102,241,0.5);
299
+ }
300
+
301
+ [data-theme="glass"] .clay-modal {
302
+ background: rgba(30,27,75,0.85);
303
+ backdrop-filter: blur(30px) saturate(150%);
304
+ -webkit-backdrop-filter: blur(30px) saturate(150%);
305
+ border: 1px solid rgba(255,255,255,0.2);
306
+ }
307
+
308
+ [data-theme="glass"] .clay-tab-active {
309
+ background: linear-gradient(145deg, #6366f1, #4f46e5);
310
+ box-shadow: 0 4px 15px rgba(99,102,241,0.4);
311
+ }
312
+
313
+ [data-theme="glass"] .clay-modal {
314
+ background: rgba(30,27,75,0.9);
315
+ backdrop-filter: blur(20px);
316
+ border: 1px solid var(--border-subtle);
317
+ }
318
+
319
+ /* Theme: Neumorphism */
320
+ [data-theme="neo"] {
321
+ --bg: #e6ded3;
322
+ --clay: #e6ded3;
323
+ --input-bg: #e6ded3;
324
+ --input-text: #4a4039;
325
+ --tab-bg: #e6ded3;
326
+ --tab-text: #6b5e52;
327
+ --tab-hover: rgba(0,0,0,0.05);
328
+ --terracotta: #d9775a;
329
+ --terracotta-dark: #c06848;
330
+ --title-gradient: linear-gradient(135deg, #8b5a3c, #a67c52);
331
+ --shadow-sm: 5px 5px 12px #b8aea3, -5px -5px 12px #ffffff;
332
+ --shadow-lg: 10px 10px 24px #b8aea3, -10px -10px 24px #ffffff;
333
+ --shadow-inset: inset 4px 4px 10px #b8aea3, inset -4px -4px 10px #ffffff;
334
+ --border-subtle: transparent;
335
+ --card-radius: 1.5rem;
336
+ --btn-radius: 1rem;
337
+ --focus-ring: 0 0 0 2px #d9775a;
338
+ --font-body: Inter, system-ui, -apple-system, "Segoe UI", Roboto, Arial, sans-serif;
339
+ --font-title: "Playfair Display", serif;
340
+ }
341
+
342
+ [data-theme="neo"] .clay-card {
343
+ box-shadow: var(--shadow-lg), var(--shadow-inset);
344
+ }
345
+
346
+ [data-theme="neo"] .clay-tab {
347
+ box-shadow: 4px 4px 8px #b8aea3, -4px -4px 8px #ffffff;
348
+ }
349
+
350
+ [data-theme="neo"] .clay-tab-active {
351
+ box-shadow: inset 3px 3px 6px rgba(0,0,0,0.2);
352
+ background: var(--terracotta);
353
+ color: white;
354
+ }
355
+
356
+ [data-theme="neo"] .clay-input, [data-theme="neo"] .clay-select {
357
+ border-radius: 1rem;
358
+ box-shadow: var(--shadow-inset);
359
+ }
360
+
361
+ [data-theme="neo"] .clay-input:focus, [data-theme="neo"] .clay-select:focus {
362
+ box-shadow: inset 4px 4px 10px #b8aea3, inset -4px -4px 10px #ffffff, 0 0 0 2px rgba(217,119,90,0.3);
363
+ }
364
+
365
+ /* Theme: Skeuomorphism */
366
+ [data-theme="skeuo"] {
367
+ --bg: repeating-linear-gradient(45deg, #3d2914 0%, #3d2914 2px, #4a3420 2px, #4a3420 4px);
368
+ --clay: linear-gradient(145deg, #4a3420, #3d2914);
369
+ --input-bg: linear-gradient(145deg, #3d2914, #2a1d10);
370
+ --input-text: #d4c5b0;
371
+ --tab-bg: linear-gradient(145deg, #3d2914, #2a1d10);
372
+ --tab-text: #b8a080;
373
+ --tab-hover: rgba(0,0,0,0.3);
374
+ --terracotta: #e07a5f;
375
+ --terracotta-dark: #b56347;
376
+ --title-gradient: linear-gradient(135deg, #e8a87c, #d4a574);
377
+ --shadow-sm: 0 4px 12px rgba(0,0,0,0.4);
378
+ --shadow-lg: inset 0 1px 0 rgba(255,255,255,0.15), 0 6px 16px rgba(0,0,0,0.5);
379
+ --shadow-inset: inset 2px 2px 6px rgba(0,0,0,0.4), inset -1px -1px 4px rgba(255,255,255,0.08);
380
+ --border-subtle: #2a1d10;
381
+ --card-radius: 0.75rem;
382
+ --btn-radius: 0.5rem;
383
+ --focus-ring: 0 0 0 2px #e07a5f;
384
+ }
385
+
386
+ [data-theme="skeuo"] .clay-card {
387
+ border: 1px solid #2a1d10;
388
+ box-shadow: var(--shadow-lg);
389
+ }
390
+
391
+ [data-theme="skeuo"] .clay-input, [data-theme="skeuo"] .cllay-select {
392
+ border: 1px solid #1a1208;
393
+ border-radius: 0.5rem;
394
+ box-shadow: var(--shadow-inset);
395
+ }
396
+
397
+ [data-theme="skeuo"] .clay-input:focus, [data-theme="skeuo"] .clay-select:focus {
398
+ border-color: #3d2914;
399
+ box-shadow: inset 2px 2px 6px rgba(0,0,0,0.4), inset -1px -1px 4px rgba(255,255,255,0.08), 0 0 0 2px rgba(224,122,95,0.4);
400
+ }
401
+
402
+ [data-theme="skeuo"] .clay-btn {
403
+ border-bottom: 3px solid #8b472e;
404
+ box-shadow: 0 4px 10px rgba(0,0,0,0.3);
405
+ }
406
+
407
+ [data-theme="skeuo"] .clay-btn:hover {
408
+ border-bottom-color: #a75a3e;
409
+ }
410
+
411
+ [data-theme="skeuo"] .clay-tab {
412
+ border: 1px solid #1a1208;
413
+ box-shadow: 2px 2px 5px rgba(0,0,0,0.3), -1px -1px 3px rgba(255,255,255,0.08);
414
+ }
415
+
416
+ [data-theme="skeuo"] .clay-tab-active {
417
+ border-bottom-color: #8b472e;
418
+ background: linear-gradient(145deg, #4a3420, #3d2914);
419
+ box-shadow: inset 2px 2px 5px rgba(0,0,0,0.4);
420
+ }
421
+
422
+ [data-theme="skeuo"] .clay-modal {
423
+ background: linear-gradient(145deg, #4a3420, #3d2914);
424
+ border: 1px solid #2a1d10;
425
+ box-shadow: var(--shadow-lg);
426
+ }
427
+
428
+ /* Theme: Material Design */
429
+ [data-theme="material"] {
430
+ --bg: #121212;
431
+ --clay: #1e1e1e;
432
+ --input-bg: #2d2d2d;
433
+ --input-text: #e0e0e0;
434
+ --tab-bg: transparent;
435
+ --tab-text: #b0b0b0;
436
+ --tab-hover: rgba(255,255,255,0.08);
437
+ --terracotta: #ff8a65;
438
+ --terracotta-dark: #e07a5f;
439
+ --title-gradient: linear-gradient(135deg, #ffab91, #ff8a65);
440
+ --shadow-sm: 0 2px 4px rgba(0,0,0,0.3);
441
+ --shadow-md: 0 4px 8px rgba(0,0,0,0.4);
442
+ --shadow-lg: 0 8px 16px rgba(0,0,0,0.5);
443
+ --shadow-inset: none;
444
+ --border-subtle: #2d2d2d;
445
+ --card-radius: 0.5rem;
446
+ --btn-radius: 0.25rem;
447
+ --focus-ring: 0 0 0 2px #ff8a65;
448
+ --font-body: Inter, system-ui, -apple-system, "Segoe UI", Roboto, Arial, sans-serif;
449
+ --font-title: "Playfair Display", serif;
450
+ }
451
+
452
+ [data-theme="material"] .clay-card {
453
+ border: 1px solid #2d2d2d;
454
+ box-shadow: var(--shadow-md);
455
+ }
456
+
457
+ [data-theme="material"] .clay-input, [data-theme="material"] .clay-select {
458
+ border-radius: 0.25rem;
459
+ border: 1px solid #404040;
460
+ background: #252525;
461
+ }
462
+
463
+ [data-theme="material"] .clay-input:focus, [data-theme="material"] .clay-select:focus {
464
+ border-color: #ff8a65;
465
+ box-shadow: 0 0 0 2px rgba(255,138,101,0.2);
466
+ }
467
+
468
+ [data-theme="material"] .clay-btn {
469
+ box-shadow: var(--shadow-sm);
470
+ }
471
+
472
+ [data-theme="material"] .clay-btn:hover {
473
+ box-shadow: var(--shadow-md);
474
+ }
475
+
476
+ [data-theme="material"] .clay-tab {
477
+ border-radius: 0.25rem;
478
+ }
479
+
480
+ [data-theme="material"] .clay-tab-active {
481
+ background: var(--terracotta);
482
+ color: white;
483
+ box-shadow: var(--shadow-sm);
484
+ }
485
+
486
+ [data-theme="material"] .clay-modal {
487
+ background: #1e1e1e;
488
+ border: 1px solid #2d2d2d;
489
+ box-shadow: var(--shadow-lg);
490
+ }
491
+
492
+ /* Theme-specific hover/focus states */
493
+ [data-theme="glass"] .clay-btn:hover {
494
+ box-shadow: 0 6px 20px rgba(99,102,241,0.5);
495
+ }
496
+
497
+ [data-theme="glass"] .clay-tab:hover {
498
+ background: rgba(255,255,255,0.15);
499
+ }
500
+
501
+ [data-theme="neo"] .clay-btn:hover {
502
+ box-shadow: 6px 6px 14px #bab0a8, -6px -6px 14px #ffffff;
503
+ }
504
+
505
+ [data-theme="neo"] .clay-tab:hover {
506
+ background: rgba(0,0,0,0.05);
507
+ }
508
+
509
+ [data-theme="skeuo"] .clay-btn:hover {
510
+ background: linear-gradient(145deg, #e8856a, #c06850);
511
+ }
512
+
513
+ [data-theme="skeuo"] .clay-tab:hover {
514
+ background: linear-gradient(145deg, #4a3420, #2a1d10);
515
+ }
516
+
517
+ [data-theme="material"] .clay-btn:hover {
518
+ background: #e8856a;
519
+ box-shadow: 0 4px 8px rgba(0,0,0,0.4);
520
+ }
521
+
522
+ [data-theme="material"] .clay-tab:hover {
523
+ background: rgba(255,255,255,0.08);
524
+ }
525
+
526
+ /* Responsive */
527
+ @media (max-width: 768px) {
528
+ .main-container { padding-left: 1rem; padding-right: 1rem; }
529
+ .content-inner { max-width: 100%; }
530
+ .clay-card { border-radius: 1.5rem; padding: 1.25rem; }
531
+ .clay-input, .clay-select { padding: 0.6rem 1rem; }
532
+ .clay-btn { padding: 0.6rem 1.25rem; font-size: 0.9rem; }
533
+ .clay-tab { padding: 0.5rem 1rem; font-size: 0.9rem; }
534
+ .clay-title { font-size: 2rem; }
535
+ }
536
+ </style>
537
+ </head>
538
+ <body data-theme="clay" class="min-h-screen">
539
+ <div class="main-container py-6">
540
+ <div class="content-inner">
541
+ <!-- Header -->
542
+ <header class="flex justify-between items-center mb-6">
543
+ <div>
544
+ <h1 class="clay-title text-3xl md:text-4xl">TAMILREAL</h1>
545
+ <p class="text-sm opacity-70 mt-1">Portrait Prompt Studio</p>
546
+ </div>
547
+ <button onclick="showThemeModal()" class="clay-tab text-sm" aria-label="Change Theme">Change Theme</button>
548
+ </header>
549
+
550
+ <!-- Tab Navigation -->
551
+ <nav class="flex gap-6 mb-6 overflow-x-auto pb-2 justify-center" role="tablist">
552
+ <button id="tab0" onclick="switchTab(0)" class="clay-tab clay-tab-active" role="tab" aria-controls="content0" aria-selected="true">Creator</button>
553
+ <button id="tab1" onclick="switchTab(1)" class="clay-tab" role="tab" aria-controls="content1" aria-selected="false">Analyzer</button>
554
+ <button id="tab2" onclick="switchTab(2)" class="clay-tab" role="tab" aria-controls="content2" aria-selected="false">Enhancer</button>
555
+ </nav>
556
+ </div>
557
+
558
+ <!-- Content Panels -->
559
+ <!-- Creator Panel - Full Width -->
560
+ <section id="content0" class="clay-card mb-6" role="tabpanel" aria-labelledby="tab0">
561
+ <!-- Fixed Identity Block -->
562
+ <div class="bg-black/20 rounded-xl p-4 mb-6 identity-anchor">
563
+ <div class="flex items-center gap-2 mb-2">
564
+ <span class="w-2 h-2 bg-green-500 rounded-full animate-pulse"></span>
565
+ <span class="font-semibold text-sm">Identity Anchor (Applied to Every Prompt)</span>
566
+ </div>
567
+ <p class="text-xs opacity-80 leading-relaxed">
568
+ <strong>EXACT FACE COMPOSITE PROTOCOL (EFCP) - 200% MODE ACTIVATED:</strong> The AI will now literally crop your face from the reference and paste it perfectly into every new scene.<br><br>
569
+ <strong>STRICT IDENTITY LOCK (200% BIOMETRIC ENFORCEMENT):</strong> Use the uploaded reference image as the absolute biometric template. Preserve the exact rounded jawline and lower cheek fullness of the subject; DO NOT slim or sharpen the face. Maintain the circular eye shape and visible eyelid creases; do not narrow or "squinch" the eyes. The nose must retain its broad nasal bridge and wider alar base—do not refine or thin the nose. Ensure the lower lip fullness and soft Cupid's bow are preserved.<br><br>
570
+ <strong>MANDATORY ACCESSORY LOCK:</strong> The subject MUST wear thick-rimmed browline/Wayfarer style glasses as seen in the reference. Do not substitute with thin, wire, or rounded frames. REMOVE the neckband/earphones entirely.<br><br>
571
+ <strong>MODEL-SPECIFIC IDENTITY BOOSTS:</strong><br>
572
+ <strong>Gemini:</strong> Activate "Biometric Integrity Mode." Disable aesthetic facial refinement. Lock facial width-to-height ratio to reference 1:1. Zero facial morphing.<br>
573
+ <strong>ChatGPT / DALL·E:</strong> Generate a RAW-style photograph where the subject's face structure, nasal breadth, and lip thickness are identical to the source. Avoid "model" aesthetics.<br>
574
+ <strong>Seedream:</strong> Identity-Consistency: 100%. Lock facial volume and bone structure. High-fidelity reconstruction of the specific thick-rimmed glasses.
575
+ </p>
576
+ </div>
577
+
578
+ <!-- Library Presets -->
579
+ <div class="grid md:grid-cols-3 gap-4 mb-6">
580
+ <div>
581
+ <label class="block text-sm font-medium mb-2">Location Preset</label>
582
+ <select id="locationPreset" class="clay-select w-full" onchange="applyPreset('location')">
583
+ <option value="">Select Location...</option>
584
+ </select>
585
+ </div>
586
+ <div>
587
+ <label class="block text-sm font-medium mb-2">Camera Angle Preset</label>
588
+ <select id="cameraAnglePreset" class="clay-select w-full" onchange="applyPreset('cameraAngle')">
589
+ <option value="">Select Angle...</option>
590
+ </select>
591
+ </div>
592
+ <div>
593
+ <label class="block text-sm font-medium mb-2">Lighting Preset</label>
594
+ <select id="lightingPreset" class="clay-select w-full" onchange="applyPreset('lighting')">
595
+ <option value="">Select Lighting...</option>
596
+ </select>
597
+ </div>
598
+ </div>
599
+
600
+ <!-- Manual Input Fields -->
601
+ <div class="grid md:grid-cols-2 gap-4 mb-6">
602
+ <div>
603
+ <label class="block text-sm font-medium mb-2">Scene</label>
604
+ <div class="flex gap-2">
605
+ <input type="text" id="scene" readonly class="clay-input flex-1" placeholder="Select from preset">
606
+ <button id="editScene" onclick="makeEditable('scene')" class="clay-btn text-sm px-3 hidden">Edit</button>
607
+ </div>
608
+ </div>
609
+ <div>
610
+ <label class="block text-sm font-medium mb-2">Pose</label>
611
+ <div class="flex gap-2">
612
+ <input type="text" id="pose" class="clay-input flex-1" placeholder="Natural relaxed standing pose">
613
+ <button onclick="randomPose()" class="clay-btn text-sm px-3">Random</button>
614
+ </div>
615
+ <span id="poseWarn" class="identity-warn hidden mt-2 inline-block">⚠️ Risky pose - may obscure face</span>
616
+ </div>
617
+ <div>
618
+ <label class="block text-sm font-medium mb-2">Clothing</label>
619
+ <div class="flex gap-2">
620
+ <input type="text" id="clothing" class="clay-input flex-1" placeholder="White linen shirt & dark trousers">
621
+ <button onclick="randomClothing()" class="clay-btn text-sm px-3">Random</button>
622
+ </div>
623
+ </div>
624
+ <div>
625
+ <label class="block text-sm font-medium mb-2">Lighting</label>
626
+ <div class="flex gap-2">
627
+ <input type="text" id="lighting" readonly class="clay-input flex-1" placeholder="Select from preset">
628
+ <button id="editLighting" onclick="makeEditable('lighting')" class="clay-btn text-sm px-3 hidden">Edit</button>
629
+ </div>
630
+ </div>
631
+ <div>
632
+ <label class="block text-sm font-medium mb-2">Camera Angle</label>
633
+ <div class="flex gap-2 flex-col">
634
+ <div class="flex gap-2">
635
+ <input type="text" id="cameraAngle" readonly class="clay-input flex-1" placeholder="Select from preset">
636
+ <button id="editCameraAngle" onclick="makeEditable('cameraAngle')" class="clay-btn text-sm px-3 hidden">Edit</button>
637
+ </div>
638
+ <span id="angleWarn" class="identity-warn hidden">⚠️ Risky angle - may obscure face</span>
639
+ </div>
640
+ </div>
641
+ <div>
642
+ <label class="block text-sm font-medium mb-2">Color Grading</label>
643
+ <div class="flex gap-2">
644
+ <input type="text" id="colorGrading" class="clay-input flex-1" placeholder="Natural Canon / Sony color science">
645
+ <button onclick="randomColorGrading()" class="clay-btn text-sm px-3">Random</button>
646
+ </div>
647
+ </div>
648
+ </div>
649
+
650
+ <!-- Camera Settings -->
651
+ <div class="mb-6">
652
+ <label class="block text-sm font-medium mb-2">Camera Settings</label>
653
+ <div class="flex flex-col sm:flex-row gap-3 items-start sm:items-center">
654
+ <select id="cameraMode" class="clay-select" onchange="toggleManualCamera()">
655
+ <option value="default">Default DSLR/Mirrorless</option>
656
+ <option value="manual">Manual</option>
657
+ </select>
658
+ <input type="text" id="manualCamera" class="clay-input flex-1 hidden" placeholder="Shot on Sony A7R IV, 85mm f/1.8">
659
+ </div>
660
+ </div>
661
+
662
+ <!-- Generate Button -->
663
+ <div class="flex gap-3 mb-6">
664
+ <button onclick="generatePortraitPrompt()" class="clay-btn text-lg px-8 py-3">Generate Prompt</button>
665
+ </div>
666
+
667
+ <!-- Result Area -->
668
+ <div id="creatorResult" class="hidden">
669
+ <label class="block text-sm font-medium mb-2">Generated Prompt</label>
670
+ <pre id="creatorOutput" class="bg-black/20 rounded-lg p-4 text-xs overflow-x-auto max-h-80 whitespace-pre-wrap"></pre>
671
+ <div class="flex flex-wrap gap-3 mt-4">
672
+ <button onclick="copyPrompt('creatorOutput')" class="clay-btn">Copy Prompt</button>
673
+ <button onclick="saveCurrentPrompt()" class="clay-btn">Save Prompt</button>
674
+ <button onclick="loadSavedPrompts()" class="clay-tab">Library</button>
675
+ </div>
676
+ </div>
677
+
678
+ <!-- Saved Library Panel -->
679
+ <div id="libraryPanel" class="hidden mt-6 pt-6 border-t border-white/10">
680
+ <div class="flex justify-between items-center mb-4">
681
+ <h3 class="font-semibold">Saved Prompts</h3>
682
+ <input type="text" id="librarySearch" class="clay-input text-sm" placeholder="Search..." oninput="loadSavedPrompts()">
683
+ </div>
684
+ <div id="savedPromptsList" class="space-y-3 max-h-60 overflow-y-auto"></div>
685
+ </div>
686
+ </section>
687
+
688
+ <div class="content-inner">
689
+ <!-- Analyzer Panel -->
690
+ <section id="content1" class="clay-card mb-6 hidden" role="tabpanel" aria-labelledby="tab1">
691
+ <h2 class="text-xl font-semibold mb-4">Prompt Analyzer</h2>
692
+ <textarea id="analyzeInput" class="clay-input w-full h-40 mb-4" placeholder="Paste your prompt here to analyze..."></textarea>
693
+ <button onclick="analyzePrompt()" class="clay-btn mb-4">Analyze Prompt</button>
694
+ <div id="analyzeResult" class="hidden">
695
+ <div id="scoreBadge" class="text-3xl font-bold text-center py-4 rounded-xl"></div>
696
+ <p class="text-center text-sm opacity-70 mb-4">SPECIFICITY SCORE / 100</p>
697
+ <ul id="issuesList" class="space-y-2"></ul>
698
+ <button onclick="copyPrompt('analyzeOutput')" id="copyAnalyzeBtn" class="clay-btn mt-4 hidden">Copy Result</button>
699
+ <pre id="analyzeOutput" class="hidden"></pre>
700
+ </div>
701
+ </section>
702
+
703
+ <!-- Enhancer Panel -->
704
+ <section id="content2" class="clay-card mb-6 hidden" role="tabpanel" aria-labelledby="tab2">
705
+ <h2 class="text-xl font-semibold mb-4">Prompt Enhancer</h2>
706
+ <textarea id="enhanceInput" class="clay-input w-full h-40 mb-4" placeholder="Paste prompt to enhance..."></textarea>
707
+
708
+ <div class="flex flex-wrap gap-4 mb-4">
709
+ <label class="flex items-center gap-2">
710
+ <input type="checkbox" id="roleChk" checked class="w-4 h-4">
711
+ <span class="text-sm">Expert Role</span>
712
+ <span class="enhancer-note">LLM-only</span>
713
+ </label>
714
+ <label class="flex items-center gap-2">
715
+ <input type="checkbox" id="cot" checked class="w-4 h-4">
716
+ <span class="text-sm">Chain-of-Thought</span>
717
+ <span class="enhancer-note">LLM-only</span>
718
+ </label>
719
+ <label class="flex items-center gap-2">
720
+ <input type="checkbox" id="format" checked class="w-4 h-4">
721
+ <span class="text-sm">Output Format</span>
722
+ </label>
723
+ <label class="flex items-center gap-2">
724
+ <input type="checkbox" id="examples" checked class="w-4 h-4">
725
+ <span class="text-sm">Real Examples</span>
726
+ </label>
727
+ </div>
728
+
729
+ <button onclick="enhancePrompt()" class="clay-btn mb-4">Enhance Prompt</button>
730
+
731
+ <div id="enhanceResult" class="hidden">
732
+ <label class="block text-sm font-medium mb-2">Enhanced Prompt</label>
733
+ <pre id="enhanceOutput" class="bg-black/20 rounded-lg p-4 text-xs overflow-x-auto max-h-80 whitespace-pre-wrap"></pre>
734
+ <button onclick="copyPrompt('enhanceOutput')" class="clay-btn mt-4">Copy Enhanced</button>
735
+ </div>
736
+ </section>
737
+ </div>
738
+ </div>
739
+
740
+ <!-- Length Modal -->
741
+ <div id="lengthModal" class="fixed inset-0 bg-black/70 flex items-center justify-center p-4 hidden z-50">
742
+ <div class="clay-modal max-w-lg w-full p-6">
743
+ <h2 class="text-xl font-semibold mb-4">Length Validation</h2>
744
+ <p id="lengthDisplay" class="text-sm mb-2"></p>
745
+ <p id="statusMessage" class="mb-4"></p>
746
+
747
+ <div class="mb-4">
748
+ <label class="block text-sm font-medium mb-2">Select Model</label>
749
+ <select id="modelSelect" class="clay-select w-full" onchange="checkLength()">
750
+ <option value="midjourney">Midjourney (5,500 chars)</option>
751
+ <option value="flux">Flux (6,500 chars)</option>
752
+ <option value="chatgpt">ChatGPT (200,000 tokens)</option>
753
+ <option value="claude">Claude (200,000 tokens)</option>
754
+ <option value="gemini">Gemini (1,000,000 tokens)</option>
755
+ <option value="grok">Grok (256,000 tokens)</option>
756
+ <option value="custom">Custom</option>
757
+ </select>
758
+ </div>
759
+
760
+ <div id="customLimitDiv" class="mb-4 hidden">
761
+ <label class="block text-sm font-medium mb-2">Custom Limit</label>
762
+ <input type="number" id="customLimit" class="clay-input w-full" value="5000">
763
+ </div>
764
+
765
+ <div class="flex gap-3">
766
+ <button onclick="shortenPrompt()" id="shortenBtn" class="clay-btn hidden">Shorten</button>
767
+ <button onclick="keepPrompt()" class="clay-tab flex-1">Keep</button>
768
+ <button onclick="copyFromModal()" class="clay-btn flex-1">Copy</button>
769
+ </div>
770
+ </div>
771
+ </div>
772
+
773
+ <!-- Theme Modal -->
774
+ <div id="themeModal" class="fixed inset-0 bg-black/70 flex items-center justify-center p-4 hidden z-50">
775
+ <div class="clay-modal max-w-md w-full p-6">
776
+ <h2 class="text-xl font-semibold mb-4">Select Theme</h2>
777
+ <div id="themeOptions" class="space-y-3"></div>
778
+ <button onclick="hideThemeModal()" class="clay-tab w-full mt-4">Cancel</button>
779
+ </div>
780
+ </div>
781
+
782
+ <!-- Toast -->
783
+ <div id="toast" class="hidden"></div>
784
+
785
+ <script>
786
+ // Apply modal styling based on current theme
787
+ const styleEl = document.createElement('style');
788
+ styleEl.textContent = `
789
+ [data-theme="glass"] #themeModal .clay-modal {
790
+ background: rgba(255,255,255,0.15) !important;
791
+ backdrop-filter: blur(30px) saturate(180%) !important;
792
+ -webkit-backdrop-filter: blur(30px) saturate(180%) !important;
793
+ border: 1px solid rgba(255,255,255,0.25) !important;
794
+ }
795
+ [data-theme="neo"] #themeModal .clay-modal {
796
+ box-shadow: 8px 8px 20px rgba(0,0,0,0.2), -8px -8px 20px rgba(255,255,255,0.9) !important;
797
+ }
798
+ [data-theme="skeuo"] #themeModal .clay-modal {
799
+ background: linear-gradient(145deg, #4a3420, #3d2914) !important;
800
+ border: 1px solid #2a1d10 !important;
801
+ box-shadow: inset 0 1px 0 rgba(255,255,255,0.1), 0 4px 12px rgba(0,0,0,0.4) !important;
802
+ }
803
+ [data-theme="material"] #themeModal .clay-modal {
804
+ background: #1e1e1e !important;
805
+ border: 1px solid #2d2d2d !important;
806
+ box-shadow: 0 8px 32px rgba(0,0,0,0.5) !important;
807
+ }
808
+ `;
809
+ document.head.appendChild(styleEl);
810
+ </script>
811
+ <script>
812
+ // ============ DATA LIBRARIES ============
813
+ const libraries = {
814
+ locations: [
815
+ "Marina Beach Chennai sunrise", "Besant Nagar beach evening walk",
816
+ "T Nagar shopping street Chennai", "Chennai metro station entrance",
817
+ "Chennai tea stall street", "Kapaleeshwarar Temple street Mylapore",
818
+ "Book shop street Chennai", "Ooty tea plantations",
819
+ "Ooty hill road viewpoint", "Hill fog road Ooty",
820
+ "Tea factory road Ooty", "Old railway platform Ooty toy train",
821
+ "Kodaikanal lake walkway", "Coaker's walk Kodaikanal",
822
+ "Sunset hill viewpoint Kodaikanal", "Yelagiri hill viewpoint",
823
+ "Yercaud lake park", "Madurai Meenakshi temple streets",
824
+ "Thanjavur Brihadeeswarar courtyard", "Chidambaram temple corridor",
825
+ "Tirunelveli temple street market", "Velankanni church street",
826
+ "Rameswaram beach", "Pamban bridge",
827
+ "Kanyakumari sunrise beach", "Kanyakumari Vivekananda rock",
828
+ "Courtallam waterfall", "Sunrise fishing harbor Chennai",
829
+ "Pondicherry french quarter", "Pondicherry beach promenade",
830
+ "Coimbatore cafe street", "Coimbatore race course road",
831
+ "Rural paddy field Thanjavur", "Coconut farm Pollachi",
832
+ "Banana plantation Trichy", "Village road Salem",
833
+ "Village temple entrance", "Bus stand portrait",
834
+ "Local market", "Flower market Madurai",
835
+ "Fish market village", "Small roadside tea shop",
836
+ "College campus walkway", "Government office corridor",
837
+ "Auto rickshaw background", "Rainy street Chennai monsoon",
838
+ "Temple chariot festival street", "Night food street Madurai"
839
+ ],
840
+ cameraAngles: [
841
+ "Eye Level Portrait", "Low Angle Shot", "High Angle Shot",
842
+ "Street Candid Angle", "Walking Follow Shot",
843
+ "Wide Environmental Portrait", "Close Portrait", "Medium Portrait",
844
+ "Over the Shoulder Shot", "Side Profile Shot"
845
+ ],
846
+ lightingSetups: [
847
+ "Golden Hour", "Morning Soft Light", "Overcast Day",
848
+ "Temple Lamp Lighting", "Street Night Lighting",
849
+ "Rainy Monsoon Light", "Beach Sunset Lighting",
850
+ "Forest Shade Lighting", "Cafe Window Lighting", "City Neon Reflection"
851
+ ]
852
+ };
853
+
854
+ const RISKY_ANGLES = new Set(["Side Profile Shot", "Over the Shoulder Shot"]);
855
+ const RISKY_POSE_PATTERNS = /side profile|over shoulder|behind head|looking away|back to camera|turned away|face hidden|partial face|obscured|blurred face|out of focus|backlit|shadow on face/i;
856
+
857
+ const poses = [
858
+ "Natural relaxed standing pose, preserve reference expression",
859
+ "Walking casually toward camera, face fully visible",
860
+ "Sitting relaxed on steps, front-facing",
861
+ "Standing with hands in pockets, facing camera",
862
+ "Leaning against wall, front-facing, natural expression",
863
+ "Looking over shoulder, face partially turned",
864
+ "Side profile looking away from camera",
865
+ "Hands behind head, face visible",
866
+ "Back to camera, walking away",
867
+ "Turned away, partial face visible",
868
+ "Crouching low, face obscured",
869
+ "Holding object in front of face"
870
+ ];
871
+
872
+ const clothes = [
873
+ "White linen shirt and dark trousers",
874
+ "Traditional white kurta",
875
+ "Casual blue t-shirt and jeans",
876
+ "Black cotton shirt with rolled sleeves",
877
+ "Light blue denim shirt",
878
+ "Beige linen kurta",
879
+ "Gray hoodie and black pants",
880
+ "White polo and khaki shorts"
881
+ ];
882
+
883
+ const colorGradings = [
884
+ "Natural Canon / Sony color science",
885
+ "Warm cinematic Kodak tones",
886
+ "Cool Fujifilm tones",
887
+ "Vibrant National Geographic style",
888
+ "Soft pastel film look",
889
+ "High contrast dramatic",
890
+ "Balanced neutral RAW",
891
+ "Golden hour warmth",
892
+ "Cool blue hour tones",
893
+ "Vintage Polaroid feel"
894
+ ];
895
+
896
+ const themes = [
897
+ { id: "clay", name: "Claymorphism", desc: "Warm dark cards with terracotta accents" },
898
+ { id: "glass", name: "Glassmorphism", desc: "Frosted glass with blue-purple gradient" },
899
+ { id: "neo", name: "Neumorphism", desc: "Soft beige with extruded shadows" },
900
+ { id: "skeuo", name: "Skeuomorphism", desc: "Dark leather texture with bevels" },
901
+ { id: "material", name: "Material Design", desc: "Dark surface with elevation shadows" }
902
+ ];
903
+
904
+ // ============ STATE ============
905
+ let currentPrompt = "";
906
+
907
+ // ============ POPULATE DROPDOWNS ============
908
+ function populateDropdowns() {
909
+ const locationSel = document.getElementById('locationPreset');
910
+ libraries.locations.forEach(loc => {
911
+ const opt = document.createElement('option');
912
+ opt.value = loc;
913
+ opt.textContent = loc;
914
+ locationSel.appendChild(opt);
915
+ });
916
+
917
+ const angleSel = document.getElementById('cameraAnglePreset');
918
+ libraries.cameraAngles.forEach(angle => {
919
+ const opt = document.createElement('option');
920
+ const isRisky = RISKY_ANGLES.has(angle);
921
+ opt.value = angle;
922
+ opt.textContent = angle + (isRisky ? " ⚠️" : "");
923
+ angleSel.appendChild(opt);
924
+ });
925
+
926
+ const lightingSel = document.getElementById('lightingPreset');
927
+ libraries.lightingSetups.forEach(light => {
928
+ const opt = document.createElement('option');
929
+ opt.value = light;
930
+ opt.textContent = light;
931
+ lightingSel.appendChild(opt);
932
+ });
933
+ }
934
+
935
+ // ============ APPLY PRESET ============
936
+ function applyPreset(type) {
937
+ const presetId = type + 'Preset';
938
+ const select = document.getElementById(presetId);
939
+ const value = select.value;
940
+
941
+ if (!value) return;
942
+
943
+ const cleanValue = value.replace(/\s*⚠️$/, '').trim();
944
+
945
+ const fieldMap = {
946
+ location: 'scene',
947
+ cameraAngle: 'cameraAngle',
948
+ lighting: 'lighting'
949
+ };
950
+
951
+ const field = fieldMap[type];
952
+ const input = document.getElementById(field);
953
+ input.value = cleanValue;
954
+ input.readOnly = true;
955
+
956
+ const editBtn = document.getElementById('edit' + field.charAt(0).toUpperCase() + field.slice(1));
957
+ if (editBtn) editBtn.classList.remove('hidden');
958
+
959
+ if (type === 'cameraAngle') {
960
+ checkAngleWarn(cleanValue);
961
+ }
962
+ }
963
+
964
+ // ============ MAKE EDITABLE ============
965
+ function makeEditable(field) {
966
+ const input = document.getElementById(field);
967
+ input.readOnly = false;
968
+ input.focus();
969
+
970
+ const editBtn = document.getElementById('edit' + field.charAt(0).toUpperCase() + field.slice(1));
971
+ if (editBtn) editBtn.classList.add('hidden');
972
+ }
973
+
974
+ // ============ RANDOM GENERATORS ============
975
+ function randomPose() {
976
+ const input = document.getElementById('pose');
977
+ const randomPose = poses[Math.floor(Math.random() * poses.length)];
978
+ input.value = randomPose;
979
+ checkPoseWarn(randomPose);
980
+ }
981
+
982
+ function randomClothing() {
983
+ const input = document.getElementById('clothing');
984
+ input.value = clothes[Math.floor(Math.random() * clothes.length)];
985
+ }
986
+
987
+ function randomColorGrading() {
988
+ const input = document.getElementById('colorGrading');
989
+ input.value = colorGradings[Math.floor(Math.random() * colorGradings.length)];
990
+ }
991
+
992
+ // ============ RISK WARNINGS ============
993
+ function checkPoseWarn(val) {
994
+ const warnEl = document.getElementById('poseWarn');
995
+ if (RISKY_POSE_PATTERNS.test(val)) {
996
+ warnEl.classList.remove('hidden');
997
+ } else {
998
+ warnEl.classList.add('hidden');
999
+ }
1000
+ }
1001
+
1002
+ function checkAngleWarn(val) {
1003
+ const warnEl = document.getElementById('angleWarn');
1004
+ if (RISKY_ANGLES.has(val)) {
1005
+ warnEl.classList.remove('hidden');
1006
+ } else {
1007
+ warnEl.classList.add('hidden');
1008
+ }
1009
+ }
1010
+
1011
+ // Pose live warning on input
1012
+ document.getElementById('pose').addEventListener('input', function() {
1013
+ checkPoseWarn(this.value);
1014
+ });
1015
+
1016
+ // ============ CAMERA TOGGLE ============
1017
+ function toggleManualCamera() {
1018
+ const mode = document.getElementById('cameraMode').value;
1019
+ const manualInput = document.getElementById('manualCamera');
1020
+ if (mode === 'manual') {
1021
+ manualInput.classList.remove('hidden');
1022
+ } else {
1023
+ manualInput.classList.add('hidden');
1024
+ }
1025
+ }
1026
+
1027
+ // ============ TAB SWITCHING ============
1028
+ function switchTab(n) {
1029
+ // Hide all content sections
1030
+ document.querySelectorAll('[id^="content"]').forEach(el => el.classList.add('hidden'));
1031
+ // Show the target content panel
1032
+ const target = document.getElementById('content' + n);
1033
+ if (target) target.classList.remove('hidden');
1034
+
1035
+ // Explicitly update tab active states by known IDs
1036
+ const tabIds = ['tab0', 'tab1', 'tab2'];
1037
+ tabIds.forEach((id, idx) => {
1038
+ const btn = document.getElementById(id);
1039
+ if (btn) {
1040
+ btn.classList.toggle('clay-tab-active', idx === n);
1041
+ btn.setAttribute('aria-selected', (idx === n).toString());
1042
+ }
1043
+ });
1044
+ }
1045
+
1046
+ // ============ GENERATE PROMPT (with Exact Face Composite Protocol - 200% mode) ============
1047
+ function generatePortraitPrompt() {
1048
+ const scene = document.getElementById('scene').value.trim() || "natural outdoor setting in Tamil Nadu";
1049
+ const pose = document.getElementById('pose').value.trim() || poses[0];
1050
+ const clothing = document.getElementById('clothing').value.trim() || clothes[0];
1051
+ const lighting = document.getElementById('lighting').value.trim() || libraries.lightingSetups[0];
1052
+ const colorGrading = document.getElementById('colorGrading').value.trim() || colorGradings[0];
1053
+ const cameraAngle = document.getElementById('cameraAngle').value.trim() || "Eye Level Portrait";
1054
+
1055
+ const cameraMode = document.getElementById('cameraMode').value;
1056
+ let camera = cameraMode === 'manual'
1057
+ ? (document.getElementById('manualCamera').value.trim() || "Shot on Sony A7R IV, 85mm f/1.8")
1058
+ : "Shot on 85mm f/1.8 prime lens. Shallow depth of field with soft bokeh";
1059
+
1060
+ // === NEW: Exact Face Composite Protocol (EFCP) - 200% cut-and-paste engine ===
1061
+ const efcpBlock = `EXACT FACE COMPOSITE PROTOCOL (200% ACCURACY - CUT-AND-PASTE MODE):
1062
+ 1. Detect and crop the ENTIRE face region from the uploaded reference image (including exact hairline, ears, glasses frame, stubble pattern, and neck blend line).
1063
+ 2. Paste this cropped face 1:1 onto the new body and scene with perfect edge feathering, color/lighting matching, and zero morphing.
1064
+ 3. Do NOT regenerate, interpret, or AI-enhance the face — use the pixel data from reference as immutable template.
1065
+ 4. Preserve 100% of the reference face: rounded jawline, lower cheek fullness, circular eye shape with visible eyelid creases, broad nasal bridge and wider alar base, lower lip fullness and soft Cupid's bow, thick-rimmed browline/Wayfarer glasses, exact skin tone/texture/pores, natural stubble/goatee.
1066
+ 5. REMOVE any neckband/earphones completely.
1067
+
1068
+ MANDATORY ACCESSORY LOCK: Thick-rimmed browline/Wayfarer glasses ONLY. No other frame style allowed.`;
1069
+
1070
+ currentPrompt = `${efcpBlock}
1071
+
1072
+ STRICT IDENTITY LOCK (200% BIOMETRIC ENFORCEMENT):
1073
+ Use the uploaded reference image as the absolute biometric template. Preserve the exact rounded jawline and lower cheek fullness of the subject; DO NOT slim or sharpen the face. Maintain the circular eye shape and visible eyelid creases; do not narrow or "squinch" the eyes. The nose must retain its broad nasal bridge and wider alar base—do not refine or thin the nose. Ensure the lower lip fullness and soft Cupid's bow are preserved.
1074
+
1075
+ MANDATORY ACCESSORY LOCK:
1076
+ The subject MUST wear thick-rimmed browline/Wayfarer style glasses as seen in the reference. Do not substitute with thin, wire, or rounded frames. REMOVE the neckband/earphones entirely.
1077
+
1078
+ MODEL-SPECIFIC IDENTITY BOOSTS:
1079
+ Gemini: Activate "Biometric Integrity Mode." Disable aesthetic facial refinement. Lock facial width-to-height ratio to reference 1:1. Zero facial morphing.
1080
+ ChatGPT / DALL·E: Generate a RAW-style photograph where the subject's face structure, nasal breadth, and lip thickness are identical to the source. Avoid "model" aesthetics.
1081
+ Seedream: Identity-Consistency: 100%. Lock facial volume and bone structure. High-fidelity reconstruction of the specific thick-rimmed glasses.
1082
+
1083
+ SCENE: ${scene}
1084
+
1085
+ CAMERA ANGLE: ${cameraAngle}
1086
+
1087
+ POSE: ${pose}
1088
+
1089
+ CLOTHING: ${clothing}
1090
+
1091
+ CAMERA: ${camera}
1092
+
1093
+ LIGHTING: ${lighting}
1094
+
1095
+ STYLE: Ultra photorealistic portrait photography style,
1096
+ Professional documentary approach,
1097
+ Natural environmental integration,
1098
+ Authentic Tamil Nadu cultural context,
1099
+ High-end editorial fashion photography,
1100
+ Cinematic storytelling composition
1101
+
1102
+ COLOR GRADING: ${colorGrading}
1103
+
1104
+ DETAILS: Realistic cloth wrinkles and fabric texture,
1105
+ Natural hair strands and movement,
1106
+ Subtle glasses reflections if present,
1107
+ Authentic depth of field,
1108
+ Environmental background context
1109
+
1110
+ REALISM: Authentic Tamil Nadu skin tone (medium-warm). Visible skin pores, natural facial hair texture (stubble/goatee), and realistic fabric wrinkles. No digital smoothing.
1111
+
1112
+ NEGATIVE PROMPT: (neckband, headphones, wires around neck), facial slimming, V-shaped jaw, sharpened chin, thin nose, narrowed eyes, wire-rimmed glasses, rounded glasses, plastic skin, AI art style, 3D render, beautification filter, lightened skin tone, changed identity, skinny face, cartoon, CGI, illustration, painting, over sharpened, over saturated, HDR effect, fake lighting, unrealistic shadows, extra fingers, distorted face, symmetry errors, unnatural skin smoothing, beauty filter, different person, face swap`;
1113
+
1114
+ showResult();
1115
+ document.getElementById('lengthModal').classList.remove('hidden');
1116
+ checkLength();
1117
+ }
1118
+
1119
+ function showResult() {
1120
+ document.getElementById('creatorOutput').textContent = currentPrompt;
1121
+ document.getElementById('creatorResult').classList.remove('hidden');
1122
+ }
1123
+
1124
+ // ============ LENGTH VALIDATION ============
1125
+ function checkLength() {
1126
+ const chars = currentPrompt.length;
1127
+ const words = currentPrompt.trim().split(/\s+/).length;
1128
+ const tokens = Math.round(chars / 4);
1129
+
1130
+ const model = document.getElementById('modelSelect').value;
1131
+ const isImage = model === 'midjourney' || model === 'flux';
1132
+
1133
+ const limits = {
1134
+ midjourney: 5500,
1135
+ flux: 6500,
1136
+ chatgpt: 200000,
1137
+ claude: 200000,
1138
+ gemini: 1000000,
1139
+ grok: 256000,
1140
+ custom: parseInt(document.getElementById('customLimit')?.value || 5000)
1141
+ };
1142
+
1143
+ const limit = limits[model] || 5000;
1144
+ const tooLong = isImage ? chars > limit : tokens > limit;
1145
+
1146
+ document.getElementById('lengthDisplay').textContent = `${chars.toLocaleString()} chars (~${words.toLocaleString()} words / ~${tokens.toLocaleString()} tokens)`;
1147
+
1148
+ const statusEl = document.getElementById('statusMessage');
1149
+ if (tooLong) {
1150
+ statusEl.innerHTML = `<span class="text-red-400">⚠️ ${isImage ? 'Character' : 'Token'} count exceeds ${limit.toLocaleString()} limit for ${model}</span>`;
1151
+ document.getElementById('shortenBtn').classList.remove('hidden');
1152
+ } else {
1153
+ statusEl.innerHTML = `<span class="text-green-400">✅ Within ${limit.toLocaleString()} ${isImage ? 'character' : 'token'} limit for ${model}</span>`;
1154
+ document.getElementById('shortenBtn').classList.add('hidden');
1155
+ }
1156
+
1157
+ document.getElementById('customLimitDiv').classList.toggle('hidden', model !== 'custom');
1158
+ }
1159
+
1160
+ function keepPrompt() {
1161
+ document.getElementById('lengthModal').classList.add('hidden');
1162
+ }
1163
+
1164
+ function copyFromModal() {
1165
+ copyPrompt('creatorOutput');
1166
+ document.getElementById('lengthModal').classList.add('hidden');
1167
+ }
1168
+
1169
+ // ============ SHORTEN PROMPT ============
1170
+ function shortenPrompt() {
1171
+ const originalPrompt = currentPrompt;
1172
+
1173
+ if (currentPrompt.length > 5200) {
1174
+ const detailsMatch = currentPrompt.match(/^([\s\S]*?DETAILS: )(.*?)([\s\S]*?REALISM RULES)/);
1175
+ if (detailsMatch) {
1176
+ currentPrompt = detailsMatch[1] + "Realistic cloth wrinkles, natural hair strands, natural depth of field\n\n" + detailsMatch[3];
1177
+ }
1178
+ }
1179
+
1180
+ if (currentPrompt.length > 5200) {
1181
+ const realismMatch = currentPrompt.match(/^([\s\S]*?REALISM RULES[\s\S]*?)(.*?)([\s\S]*?NEGATIVE PROMPT)/);
1182
+ if (realismMatch) {
1183
+ currentPrompt = realismMatch[1] + "Must look like a real RAW photograph by a professional photographer.\n\n" + realismMatch[3];
1184
+ }
1185
+ }
1186
+
1187
+ if (currentPrompt.length > 5200) {
1188
+ const styleMatch = currentPrompt.match(/^([\s\S]*?STYLE: )(.*?)([\s\S]*?COLOR GRADING)/);
1189
+ if (styleMatch) {
1190
+ currentPrompt = styleMatch[1] + "Ultra photorealistic, natural skin texture, no plastic skin\n\n" + styleMatch[3];
1191
+ }
1192
+ }
1193
+
1194
+ if (currentPrompt.length > 5200) {
1195
+ currentPrompt = currentPrompt.slice(0, 5200);
1196
+ const lastNewline = currentPrompt.lastIndexOf('\n');
1197
+ if (lastNewline > 4000) {
1198
+ currentPrompt = currentPrompt.slice(0, lastNewline);
1199
+ }
1200
+ }
1201
+
1202
+ if (!currentPrompt.includes("NEGATIVE PROMPT")) {
1203
+ currentPrompt = originalPrompt;
1204
+ showToast("Could not safely shorten - please edit manually");
1205
+ return;
1206
+ }
1207
+
1208
+ showResult();
1209
+ document.getElementById('lengthModal').classList.add('hidden');
1210
+ showToast("Prompt shortened successfully");
1211
+ }
1212
+
1213
+ // ============ CLIPBOARD ============
1214
+ function copyPrompt(id) {
1215
+ const text = document.getElementById(id).textContent;
1216
+
1217
+ if (navigator.clipboard && navigator.clipboard.writeText) {
1218
+ navigator.clipboard.writeText(text).then(() => {
1219
+ showToast("✅ Copied to clipboard");
1220
+ }).catch(() => {
1221
+ fallbackCopy(text);
1222
+ });
1223
+ } else {
1224
+ fallbackCopy(text);
1225
+ }
1226
+ }
1227
+
1228
+ function fallbackCopy(text) {
1229
+ const textarea = document.createElement('textarea');
1230
+ textarea.value = text;
1231
+ textarea.style.position = 'fixed';
1232
+ textarea.style.left = '-9999px';
1233
+ textarea.style.top = '-9999px';
1234
+ document.body.appendChild(textarea);
1235
+ textarea.focus();
1236
+ textarea.select();
1237
+
1238
+ try {
1239
+ const successful = document.execCommand('copy');
1240
+ if (successful) {
1241
+ showToast("✅ Copied to clipboard");
1242
+ } else {
1243
+ showToast("⚠️ Copy failed - please select manually");
1244
+ }
1245
+ } catch (err) {
1246
+ showToast("⚠️ Copy failed - please select manually");
1247
+ }
1248
+
1249
+ document.body.removeChild(textarea);
1250
+ }
1251
+
1252
+ // ============ TOAST ============
1253
+ function showToast(msg) {
1254
+ const toast = document.getElementById('toast');
1255
+ toast.textContent = msg;
1256
+ toast.classList.remove('hidden');
1257
+ toast.classList.add('toast-animate');
1258
+
1259
+ setTimeout(() => {
1260
+ toast.classList.add('hidden');
1261
+ toast.classList.remove('toast-animate');
1262
+ }, 2800);
1263
+ }
1264
+
1265
+ // ============ ANALYZER ============
1266
+ function analyzePrompt() {
1267
+ const input = document.getElementById('analyzeInput').value.trim();
1268
+ if (!input) {
1269
+ showToast("Paste a prompt first");
1270
+ return;
1271
+ }
1272
+
1273
+ setTimeout(() => {
1274
+ let score = 100;
1275
+ const issues = [];
1276
+ const lower = input.toLowerCase();
1277
+
1278
+ if (!/(photorealistic|real photograph)/i.test(input)) {
1279
+ score -= 20;
1280
+ issues.push("Add stronger photorealism keywords");
1281
+ }
1282
+
1283
+ if (!/negative prompt/i.test(input)) {
1284
+ score -= 20;
1285
+ issues.push("Include a Negative Prompt - protects face identity");
1286
+ }
1287
+
1288
+ if (input.length < 180) {
1289
+ score -= 15;
1290
+ issues.push("Prompt is too short - add more scene, lighting and identity detail");
1291
+ }
1292
+
1293
+ if (!/(identity|face structure|reference image)/i.test(input)) {
1294
+ score -= 20;
1295
+ issues.push("No identity reference - AI may not preserve the face");
1296
+ }
1297
+
1298
+ if (!/lighting/i.test(input)) {
1299
+ score -= 10;
1300
+ issues.push("No lighting specification - define lighting for realism");
1301
+ }
1302
+
1303
+ if (!/(camera|lens|aperture|dslr|mirrorless)/i.test(input)) {
1304
+ score -= 10;
1305
+ issues.push("No camera/lens detail - specify for photorealistic output");
1306
+ }
1307
+
1308
+ if (!/(distorted face|symmetry|skin smoothing)/i.test(input)) {
1309
+ score -= 5;
1310
+ issues.push("Add negative face-distortion terms");
1311
+ }
1312
+
1313
+ score = Math.max(0, score);
1314
+
1315
+ const badge = document.getElementById('scoreBadge');
1316
+ badge.textContent = `${score} / 100`;
1317
+
1318
+ if (score >= 80) {
1319
+ badge.className = "text-3xl font-bold text-center py-4 rounded-xl bg-green-500/20 text-green-400";
1320
+ } else if (score >= 50) {
1321
+ badge.className = "text-3xl font-bold text-center py-4 rounded-xl bg-yellow-500/20 text-yellow-400";
1322
+ } else {
1323
+ badge.className = "text-3xl font-bold text-center py-4 rounded-xl bg-red-500/20 text-red-400";
1324
+ }
1325
+
1326
+ const issuesList = document.getElementById('issuesList');
1327
+ if (issues.length === 0) {
1328
+ issuesList.innerHTML = '<li class="text-green-400">✅ Excellent prompt! All checks passed.</li>';
1329
+ } else {
1330
+ issuesList.innerHTML = issues.map(i => `<li class="text-red-300 text-sm">• ${i}</li>`).join('');
1331
+ }
1332
+
1333
+ document.getElementById('analyzeResult').classList.remove('hidden');
1334
+ }, 600);
1335
+ }
1336
+
1337
+ // ============ ENHANCER ============
1338
+ function enhancePrompt() {
1339
+ const input = document.getElementById('enhanceInput').value.trim();
1340
+ if (!input) {
1341
+ showToast("Paste a prompt to enhance");
1342
+ return;
1343
+ }
1344
+
1345
+ setTimeout(() => {
1346
+ let enhanced = input;
1347
+
1348
+ if (document.getElementById('roleChk').checked && !/\byou are\b|\bact as\b/i.test(enhanced)) {
1349
+ enhanced = "You are a professional Tamil Nadu portrait photographer.\n\n" + enhanced;
1350
+ }
1351
+
1352
+ if (document.getElementById('cot').checked) {
1353
+ enhanced += "\n\nThink step by step about lighting and realism.";
1354
+ }
1355
+
1356
+ if (document.getElementById('format').checked) {
1357
+ enhanced += "\n\n--style raw --v 6 --q 2";
1358
+ }
1359
+
1360
+ if (document.getElementById('examples').checked) {
1361
+ enhanced += "\n\nInclude natural skin texture and real lighting.";
1362
+ }
1363
+
1364
+ document.getElementById('enhanceOutput').textContent = enhanced;
1365
+ document.getElementById('enhanceResult').classList.remove('hidden');
1366
+ }, 600);
1367
+ }
1368
+
1369
+ // ============ THEME MODAL ============
1370
+ function showThemeModal() {
1371
+ const container = document.getElementById('themeOptions');
1372
+ container.innerHTML = '';
1373
+
1374
+ const style = getComputedStyle(document.body);
1375
+ const bgColor = style.getPropertyValue('--clay').trim();
1376
+ const textColor = style.getPropertyValue('--input-text').trim();
1377
+ const borderColor = style.getPropertyValue('--border-subtle').trim();
1378
+
1379
+ themes.forEach(theme => {
1380
+ const card = document.createElement('button');
1381
+ card.className = 'w-full text-left p-4 rounded-xl transition-all hover:scale-[1.02]';
1382
+ card.style.background = 'rgba(255, 255, 255, 0.30)';
1383
+ card.style.backdropFilter = 'blur(20px) saturate(180%)';
1384
+ card.style.webkitBackdropFilter = 'blur(20px) saturate(180%)';
1385
+ card.style.color = textColor;
1386
+ card.style.border = '1px solid rgba(255, 255, 255, 0.2)';
1387
+ card.style.boxShadow = '0 8px 32px rgba(0, 0, 0, 0.3)';
1388
+ card.innerHTML = `
1389
+ <div class="font-semibold">${theme.name}</div>
1390
+ <div class="text-sm opacity-70">${theme.desc}</div>
1391
+ `;
1392
+ card.onclick = () => {
1393
+ document.body.dataset.theme = theme.id;
1394
+ localStorage.setItem('tamilreal_theme', theme.id);
1395
+ hideThemeModal();
1396
+ };
1397
+ container.appendChild(card);
1398
+ });
1399
+
1400
+ document.getElementById('themeModal').classList.remove('hidden');
1401
+ }
1402
+
1403
+ function hideThemeModal() {
1404
+ document.getElementById('themeModal').classList.add('hidden');
1405
+ }
1406
+
1407
+ // ============ SAVED PROMPTS ============
1408
+ function saveCurrentPrompt() {
1409
+ const name = prompt("Enter a name for this prompt:");
1410
+ if (!name) return;
1411
+
1412
+ const prompts = JSON.parse(localStorage.getItem('tamilreal_prompts') || '[]');
1413
+
1414
+ if (prompts.length >= 50) {
1415
+ prompts.shift();
1416
+ showToast("Oldest prompt removed - limit reached");
1417
+ }
1418
+
1419
+ prompts.push({
1420
+ id: Date.now(),
1421
+ name: name,
1422
+ content: currentPrompt,
1423
+ savedAt: new Date().toISOString()
1424
+ });
1425
+
1426
+ localStorage.setItem('tamilreal_prompts', JSON.stringify(prompts));
1427
+ showToast(`✅ Saved as "${name}"`);
1428
+ }
1429
+
1430
+ function loadSavedPrompts() {
1431
+ const panel = document.getElementById('libraryPanel');
1432
+ const container = document.getElementById('savedPromptsList');
1433
+ const search = document.getElementById('librarySearch').value.toLowerCase();
1434
+
1435
+ panel.classList.remove('hidden');
1436
+
1437
+ const prompts = JSON.parse(localStorage.getItem('tamilreal_prompts') || '[]');
1438
+ const filtered = prompts.filter(p => p.name.toLowerCase().includes(search));
1439
+
1440
+ if (filtered.length === 0) {
1441
+ container.innerHTML = '<p class="text-sm opacity-70">No saved prompts yet. Generate a prompt and hit Save.</p>';
1442
+ return;
1443
+ }
1444
+
1445
+ container.innerHTML = filtered.map(p => `
1446
+ <div class="bg-black/20 rounded-lg p-3">
1447
+ <div class="flex justify-between items-start mb-2">
1448
+ <span class="font-medium">${p.name}</span>
1449
+ <span class="text-xs opacity-60">${new Date(p.savedAt).toLocaleDateString()}</span>
1450
+ </div>
1451
+ <p class="text-xs opacity-70 mb-2 line-clamp-2">${p.content.substring(0, 120)}...</p>
1452
+ <div class="flex gap-2">
1453
+ <button onclick="loadPrompt(${p.id})" class="clay-btn text-xs py-1 px-3">Load</button>
1454
+ <button onclick="deletePrompt(${p.id})" class="clay-tab text-xs py-1 px-3">Delete</button>
1455
+ </div>
1456
+ </div>
1457
+ `).join('');
1458
+ }
1459
+
1460
+ function loadPrompt(id) {
1461
+ const prompts = JSON.parse(localStorage.getItem('tamilreal_prompts') || '[]');
1462
+ const prompt = prompts.find(p => p.id === id);
1463
+ if (prompt) {
1464
+ currentPrompt = prompt.content;
1465
+ showResult();
1466
+ showToast(`Loaded "${prompt.name}"`);
1467
+ }
1468
+ }
1469
+
1470
+ function deletePrompt(id) {
1471
+ let prompts = JSON.parse(localStorage.getItem('tamilreal_prompts') || '[]');
1472
+ prompts = prompts.filter(p => p.id !== id);
1473
+ localStorage.setItem('tamilreal_prompts', JSON.stringify(prompts));
1474
+ loadSavedPrompts();
1475
+ showToast("Prompt deleted");
1476
+ }
1477
+
1478
+ // ============ INIT ============
1479
+ window.onload = function() {
1480
+ populateDropdowns();
1481
+ switchTab(0);
1482
+
1483
+ const savedTheme = localStorage.getItem('tamilreal_theme') || 'clay';
1484
+ document.body.dataset.theme = savedTheme;
1485
+ };
1486
+ </script>
1487
+ </body>
1488
  </html>