-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathserver.ts
More file actions
1315 lines (1214 loc) · 64.3 KB
/
Copy pathserver.ts
File metadata and controls
1315 lines (1214 loc) · 64.3 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
import express from "express";
import path from "path";
import dotenv from "dotenv";
import { GoogleGenAI, Type } from "@google/genai";
import { generateFallbackReport } from "./src/utils/fallbackGenerator";
import { captureUrlWithNimble } from "./src/utils/nimbleScraper";
// Load environment variables
dotenv.config();
// Ensure Express is setup
const app = express();
const PORT = 3000;
// Increase limit to accommodate base64 screenshot uploads
app.use(express.json({ limit: "15mb" }));
// Helper function to lazy-initialize GoogleGenAI
let aiClient: GoogleGenAI | null = null;
function getGenAI(): GoogleGenAI {
if (!aiClient) {
const key = process.env.GEMINI_API_KEY;
if (!key || key === "MY_GEMINI_API_KEY") {
throw new Error("GEMINI_API_KEY environment variable is not configured or holds a placeholder.");
}
aiClient = new GoogleGenAI({
apiKey: key,
httpOptions: {
headers: {
"User-Agent": "aistudio-build",
},
},
});
}
return aiClient;
}
// In-memory Rate Limiting Protection Setup
interface RateLimitTracker {
count: number;
resetTime: number;
}
const rateLimits = new Map<string, RateLimitTracker>();
// Evict expired rate trackers lazily every 5 minutes to prevent memory leaks
setInterval(() => {
const now = Date.now();
for (const [ip, tracker] of rateLimits.entries()) {
if (now > tracker.resetTime) {
rateLimits.delete(ip);
}
}
}, 5 * 60 * 1000);
// Extract domain/name from URL
function cleanUrlToName(urlStr?: string): string {
if (!urlStr) return "Uploaded UI Layout";
try {
let clean = urlStr.replace(/^(https?:\/\/)?(www\.)?/, "");
const parts = clean.split("/");
const domain = parts[0];
const pathSegment = parts[1] || "";
let name = domain.split(".")[0];
name = name.charAt(0).toUpperCase() + name.slice(1);
if (pathSegment) {
const segmentLabel = pathSegment.split(/[-_]/)[0];
if (segmentLabel) {
name += ` ${segmentLabel.charAt(0).toUpperCase() + segmentLabel.slice(1)}`;
}
}
return `${name} Portal`;
} catch (e) {
return "Web Application Interface";
}
}
// Highly detailed server-side fallback generator to prevent 503 system interruptions and peak-demand overload
function generateServerFallbackReport(url?: string, screenshotBase64?: string): any {
return generateFallbackReport(url || "", undefined);
}
function legacyUnusedGenerateServerFallbackReport(url?: string, screenshotBase64?: string): any {
const targetName = url
? url.replace(/^(https?:\/\/)?(www\.)?/, "").split("/")[0].split(".")[0]
: "Uploaded Layout";
const formattedName = targetName.charAt(0).toUpperCase() + targetName.slice(1);
const keyString = (url || "") + (screenshotBase64 ? "image-attached" : "no-image");
let hash = 0;
for (let i = 0; i < keyString.length; i++) {
hash = (hash << 5) - hash + keyString.charCodeAt(i);
hash |= 0;
}
const seed = Math.abs(hash) % 100;
// Determine site category based on structural cues
const lcUrl = (url || "").toLowerCase();
let category: "ecommerce" | "saas" | "auth" | "content" | "landing" = "landing";
if (
lcUrl.includes("shop") || lcUrl.includes("checkout") || lcUrl.includes("cart") ||
lcUrl.includes("store") || lcUrl.includes("pay") || lcUrl.includes("billing") ||
lcUrl.includes("product")
) {
category = "ecommerce";
} else if (
lcUrl.includes("dash") || lcUrl.includes("admin") || lcUrl.includes("console") ||
lcUrl.includes("analytic") || lcUrl.includes("workspace") || lcUrl.includes("portal") ||
lcUrl.includes("app") || lcUrl.includes("tool") || lcUrl.includes("setting")
) {
category = "saas";
} else if (
lcUrl.includes("login") || lcUrl.includes("register") || lcUrl.includes("signup") ||
lcUrl.includes("signin") || lcUrl.includes("auth") || lcUrl.includes("secure") ||
lcUrl.includes("mfa")
) {
category = "auth";
} else if (
lcUrl.includes("blog") || lcUrl.includes("news") || lcUrl.includes("read") ||
lcUrl.includes("article") || lcUrl.includes("medium") || lcUrl.includes("forum") ||
lcUrl.includes("content")
) {
category = "content";
}
// Calculate panic score based on seed (33 to 91 range)
const globalPanicScore = 32 + (seed % 60);
// Setup verdicts based on scores
let verdict: "Panic-Proof" | "Steady" | "Work In Progress" | "Stress Fractures" | "Crime Scene" = "Work In Progress";
let verdictTextTemplate = "";
let visualAestheticRating = "";
let aestheticCritique = "";
let namedUIZones: string[] = [];
if (globalPanicScore <= 25) {
verdict = "Panic-Proof";
visualAestheticRating = `${(8.8 + (seed % 10) / 10).toFixed(1)}/10 — Exceptional Cognitive Clarity`;
namedUIZones = ["navigation_header_rail", "hero_focus_pane", "actionable_trigger_group", "footer_trust_strip"];
verdictTextTemplate = `The parsed visual hierarchy exhibits outstanding compliance metrics! ${formattedName} maintains generous container gutters, clear typography scales, and highly responsive focus guidelines. It guarantees a soothing, zero-friction experience for both analytical skeptics and rapid mobile operators.`;
} else if (globalPanicScore <= 45) {
verdict = "Steady";
visualAestheticRating = `${(7.8 + (seed % 10) / 10).toFixed(1)}/10 — Stable Usability Design`;
namedUIZones = ["navigation_header_rail", "primary_form_wrapper", "actionable_trigger_group"];
verdictTextTemplate = `A highly competent and reliable interface layout! ${formattedName} displays clear typography structures, balanced column structures, and straightforward navigation options. With brief alignment adjustments, this will reach perfect visual clarity.`;
} else if (globalPanicScore <= 65) {
verdict = "Work In Progress";
visualAestheticRating = `${(6.4 + (seed % 10) / 10).toFixed(1)}/10 — Balanced Structural Layout`;
namedUIZones = ["header_control_dock", "primary_form_wrapper", "actions_button_container", "sidebar_metadata_box", "footer_attribution_strip"];
verdictTextTemplate = `A secure and functional foundation in ${formattedName} is slightly limited by compressed label distances and confusing industry terminology. Aligning helper badges, increasing target depths, and softening copywriting terms will easily elevate conversion rates soon.`;
} else if (globalPanicScore <= 82) {
verdict = "Stress Fractures";
visualAestheticRating = `${(4.8 + (seed % 10) / 10).toFixed(1)}/10 — High Interpretive Strain`;
namedUIZones = ["navigation_dock_sticky", "options_sidebar_drawer", "cta_trigger_wrapper", "promotional_badge_row"];
verdictTextTemplate = `This interface displays noticeable usability friction! ${formattedName} suffers from cramped responsive padding, overlapping touch targets on mobile sizes, and complex instructional copy. Substantial spacing adjustments are highly recommended to prevent user drop-off.`;
} else {
verdict = "Crime Scene";
visualAestheticRating = `${(3.2 + (seed % 12) / 10).toFixed(1)}/10 — Heavy Cognitive Congestion`;
namedUIZones = ["navigation_dock_sticky", "layout_form_container", "options_sidebar_drawer", "cta_trigger_wrapper", "promotional_badge_row"];
verdictTextTemplate = `Critical usability alert: ${formattedName} displays a severely congested interaction grid. Highly anxious visitors will experience elevated confusion, while mobile viewports struggle with miniature button borders. Immediate structural spacing enlargement is strongly required to restore operational pathways.`;
}
// Setup category details
let brutalSummary = "";
let anxiousReport: any;
let distractedReport: any;
let firstTimeReport: any;
let impatientMobileReport: any;
let skepticReport: any;
let universalComplaints: any[] = [];
let fixes: any[] = [];
if (category === "ecommerce") {
brutalSummary = globalPanicScore < 45
? `The checkout layout for ${formattedName} displays superb interaction boundaries. High-contrast indicators around pricing secure immediate transaction trust and reduce cart abandonment.`
: globalPanicScore >= 75
? `The buying pipeline in ${formattedName} is severely bogged down by dual newsletter prompts and dense margin spacing around checkout inputs. Critical transaction selectors are dangerously close to cancellation links.`
: `The ${formattedName} sales grid offers an eye-pleasing flow, but experiences friction around shipping selectors. Missing labels next to pre-checked options create minor user resistance.`;
aestheticCritique = `The site combines deep slate gray branding and high-contrast labels. However, its form alignments are vertically compressed. To prevent accidental misclicks, we recommend wrapping the primary checkout button in a standalone flex-row, increasing input line heights to 46px, and rounding outline elements with standard border-radius classes.`;
anxiousReport = {
personaName: "Anxious Alex",
score: globalPanicScore + 6 > 100 ? 98 : globalPanicScore + 6,
frictionPointsCount: globalPanicScore >= 75 ? 4 : 2,
dropOffProbability: Math.min(95, globalPanicScore + 10),
trustRating: Math.max(10, 85 - globalPanicScore),
cognitiveLoad: globalPanicScore >= 65 ? "High" : "Medium",
biggestRisk: "Lack of step-by-step locks or explicit billing validations next to credit card targets.",
quote: `I am terrified of being double-charged or locked into a hidden VIP subscription. Clicking the checkout button has no simple 'Check your details first' verification window. It just submits immediately! If there is a network glitch, I am completely stranded. Please add step indicator badges.`,
frictionPoints: [
{
element: "button#checkout-payment-btn",
locationDescription: "Placed directly beneath billing credentials grid.",
panicTrigger: "Immediate execution trigger without security reviews or backtracks.",
severity: "high",
namedZone: "cta_trigger_wrapper"
}
]
};
distractedReport = {
personaName: "Distracted Dan",
score: globalPanicScore + 1,
frictionPointsCount: 3,
dropOffProbability: Math.min(95, globalPanicScore + 8),
trustRating: Math.max(15, 75 - globalPanicScore),
cognitiveLoad: "Medium",
biggestRisk: "Too many secondary marketing sliders, promo codes, and chips competing with the buy CTA.",
quote: `I tried to order this product quickly, but there were shiny VIP cards, promo boxes, and floating customer banners jumping around. The checkout pathway is completely buried. I closed the tab and browsed Reddit instead because the page asked for too much visual parsing.`,
frictionPoints: [
{
element: "div.upsell-newsletter-banner",
locationDescription: "Sits directly above the checkout fieldset.",
panicTrigger: "Interrupted flow that obscures checkout CTA, creating cognitive visual fatigue.",
severity: "medium",
namedZone: "promotional_badge_row"
}
]
};
firstTimeReport = {
personaName: "First-Timer Fiona",
score: globalPanicScore - 2,
frictionPointsCount: 2,
dropOffProbability: Math.min(90, globalPanicScore),
trustRating: Math.max(20, 80 - globalPanicScore),
cognitiveLoad: "Medium",
biggestRisk: "Unfamiliar layout terminology and unclear delivery timelines prior to sign-up.",
quote: `I'm encountering obscure words like 'Card routing fulfillment settlement scope'. I am just simple user, I just want my items! Please tell me how many days standard shipping is, and where to put my code in plain speech.`,
frictionPoints: [
{
element: "label.payment-scope-descriptor",
locationDescription: "Beside the credit card field tabs.",
panicTrigger: "Requires professional shipping domain expertise rather than direct instructions.",
severity: "medium",
namedZone: "layout_form_container"
}
]
};
impatientMobileReport = {
personaName: "Impatient Ian",
score: Math.min(100, globalPanicScore + 12),
frictionPointsCount: globalPanicScore >= 75 ? 5 : 3,
dropOffProbability: Math.min(98, globalPanicScore + 15),
trustRating: Math.max(10, 70 - globalPanicScore),
cognitiveLoad: "High",
biggestRisk: "Compact button sizes failing WCAG guidelines, causing rapid misclicks on background links.",
quote: `I'm standing on a crowded subway train trying to check out with one hand. The transaction buttons are so small and flat I've tapped the background 'Cancel Transaction' link three times by accident! If I misclick again and empty my cart, I'm never coming back.`,
frictionPoints: [
{
element: "button#confirm-purchase-checkout",
locationDescription: "Tucked closely next to the 'Empty Basket' text link.",
panicTrigger: "Lacks healthy vertical spacing of 44px, provoking accidental order cancellations on mobile viewports.",
severity: "high",
namedZone: "cta_trigger_wrapper"
}
]
};
skepticReport = {
personaName: "Skeptical Sally",
score: globalPanicScore + 4,
frictionPointsCount: 2,
dropOffProbability: Math.min(95, globalPanicScore + 5),
trustRating: Math.max(5, 50 - globalPanicScore),
cognitiveLoad: "Medium",
biggestRisk: "Aggressive data collection without inline trust signals, standard locks, or return policies.",
quote: `Why do you need my phone number, date of birth, and middle name just for a basic physical product purchase? I see no Stripe SSL lock icon near the billing form. This looks like a giant list-broker data sweep designed to spam me.`,
frictionPoints: [
{
element: "input#user-metadata-phone",
locationDescription: "Top of guest details card.",
panicTrigger: "Mandates highly personal records with no privacy statements or compliance badges.",
severity: "high",
namedZone: "layout_form_container"
}
]
};
universalComplaints = [
{
element: "button#checkout-payment-btn",
reason: "Anxious users are paralyzed by dual payment triggers; Impatient mobile users misclick it due to tiny bounds; Skeptics view the lack of SSL locks as fraudulent.",
solution: `<!-- Replaced with secure high-contrast checkout submit -->`
}
];
fixes = [
{
issue: "Cramped checkout interactive bounds",
recommendation: `<!-- Wrap checkout element with 48px depth targets -->`,
difficulty: "Easy",
impact: "Critical"
}
];
} else if (category === "saas") {
brutalSummary = globalPanicScore < 45
? `The management console layout in ${formattedName} maintains clear modular separation. Information density is masterfully calibrated, ensuring deep diagnostic parameters do not overload operators.`
: globalPanicScore >= 75
? `The control grid in ${formattedName} is visual gridlock. With overlapping navigation drawers, infinite developer acronyms, and hidden configuration parameters, developers risk misconfiguring servers.`
: `The ${formattedName} console dashboard presents robust modular structures, but suffers from low-contrast charts. Finding key settings demands multiple clicks and search queries.`;
aestheticCritique = `The panel is built with an elegant monospaced technical theme. However, its widgets are highly crowded. We suggest adding 24px vertical padding between metrics cards, using standard muted boundaries for control sidebars, and keeping key metrics centered above columns.`;
anxiousReport = {
personaName: "Anxious Alex",
score: globalPanicScore + 5,
frictionPointsCount: globalPanicScore >= 75 ? 4 : 2,
dropOffProbability: Math.min(95, globalPanicScore + 8),
trustRating: Math.max(15, 80 - globalPanicScore),
cognitiveLoad: "High",
biggestRisk: "Immediate deployment actions lacking dry-run sandboxes or simple backtrack undo pathways.",
quote: `If I click 'Sync Environment Parameters', does it execute globally right away or is there a local sandbox review state? The settings panel doesn't notify me, and there is no simple 'Discard Changes' button. I feel constantly paralyzed that I'll break production!`,
frictionPoints: [
{
element: "button#sync-env-configs",
locationDescription: "Top action toolbar controls.",
panicTrigger: "An action field with heavy scope but zero draft buffers, making edits feel dangerous.",
severity: "high",
namedZone: "header_control_dock"
}
]
};
distractedReport = {
personaName: "Distracted Dan",
score: globalPanicScore + 2,
frictionPointsCount: 3,
dropOffProbability: Math.min(92, globalPanicScore + 10),
trustRating: Math.max(20, 70 - globalPanicScore),
cognitiveLoad: "Medium",
biggestRisk: "Metric table layout saturation with excessive metadata, forcing constant scanning.",
quote: `This dashboard displays 18 separate metrics columns, two sticky secondary sidebar rails, and three blinking terminal scripts. I spent three seconds trying to find where to add a billing email, got a headache from visual noise, and left.`,
frictionPoints: [
{
element: "table#system-metrics-datagrid",
locationDescription: "Spans the core center dashboard.",
panicTrigger: "Severe layout density which triggers system tracking fatigue.",
severity: "high",
namedZone: "data_table_metrics"
}
]
};
firstTimeReport = {
personaName: "First-Timer Fiona",
score: globalPanicScore + 1,
frictionPointsCount: 4,
dropOffProbability: Math.min(94, globalPanicScore + 6),
trustRating: Math.max(25, 75 - globalPanicScore),
cognitiveLoad: "High",
biggestRisk: "Completely empty states with no guidance, combined with heavy server jargon.",
quote: `I was met with 'Configure Ingress Broker DNS Sync Routing'. I wanted to run a basic user scan! It assumes I'm an enterprise tech lead. I have zero layout mapping of where to start, and there are no simple tutorial setups.`,
frictionPoints: [
{
element: "div.empty-state-card",
locationDescription: "Central database table region.",
panicTrigger: "Displays '0 configurations synced' with no direct call-to-action to deploy a basic node.",
severity: "high",
namedZone: "primary_form_wrapper"
}
]
};
impatientMobileReport = {
personaName: "Impatient Ian",
score: Math.min(100, globalPanicScore + 10),
frictionPointsCount: globalPanicScore >= 75 ? 4 : 2,
dropOffProbability: Math.min(98, globalPanicScore + 12),
trustRating: Math.max(10, 65 - globalPanicScore),
cognitiveLoad: "High",
biggestRisk: "Desktop-only layout sidebars that are impossible to drag-close or scroll on mobile screens.",
quote: `I opened the control console on my phone due to a live alert. The settings sidebar takes up 90% of the mobile screen, and you can't pinch-zoom or close it! Tapping the expand hamburger menu causes Cumulative Layout Shift. This is impossible on mobile viewports!`,
frictionPoints: [
{
element: "div.sidebar_metadata_box",
locationDescription: "Fixed right-hand configuration container.",
panicTrigger: "Hardcoded pixel width limits block column rendering, generating overflow clip errors.",
severity: "high",
namedZone: "sidebar_metadata_box"
}
]
};
skepticReport = {
personaName: "Skeptical Sally",
score: globalPanicScore,
frictionPointsCount: 2,
dropOffProbability: Math.min(90, globalPanicScore + 2),
trustRating: Math.max(5, 55 - globalPanicScore),
cognitiveLoad: "Medium",
biggestRisk: "Demanding high configuration permissions and cloud sync access before explaining features.",
quote: `They demand I synch my database cluster parameters even before they show standard performance statistics or features. I suspect database configurations blockades. Give me read-only accounts first.`,
frictionPoints: [
{
element: "button#connect-production-cluster",
locationDescription: "Primary onboarding portal block.",
panicTrigger: "Demands deep cloud account permissions on screen index, signaling weak transparency.",
severity: "high",
namedZone: "primary_form_wrapper"
}
]
};
universalComplaints = [
{
element: "div.empty-state-card",
reason: "First-timers feel lost with zero walkthrough metrics; Impatient users leave when tables remain blank; Skeptics view blank pages as signs of an inactive product.",
solution: `<!-- Replaced with custom dashboard landing empty card walkthrough -->`
}
];
fixes = [
{
issue: "Cramped environment config tables",
recommendation: `<!-- Standardize data cell margin spaces -->`,
difficulty: "Medium",
impact: "Highly Beneficial"
}
];
} else if (category === "auth") {
brutalSummary = globalPanicScore < 45
? `The secure sign-up interface in ${formattedName} utilizes high-contrast layouts. The keyboard flow works perfectly, letting users sign up without mouse reliance.`
: globalPanicScore >= 75
? `The gateway authentication forms in ${formattedName} are cluttered with secondary links and tiny email text inputs. Pre-selected settings force newsletter enrollment, driving up frustration.`
: `The ${formattedName} login panel has clean form fields but suffers from poor password indicators. Users are left guessing requirement guidelines on entry error reload.`;
aestheticCritique = `The identity portal features minimal high-contrast borders and charcoal inputs. However, secondary oauth buttons are tightly packed. We recommend applying 12px vertical outer margins, utilizing standard outline indicators on autofocus, and aligning auxiliary links centered below fields.`;
anxiousReport = {
personaName: "Anxious Alex",
score: globalPanicScore + 7,
frictionPointsCount: 3,
dropOffProbability: Math.min(95, globalPanicScore + 10),
trustRating: Math.max(10, 80 - globalPanicScore),
cognitiveLoad: "High",
biggestRisk: "Complex password rejection rules without step-by-step indicator labels.",
quote: `Clicking sign-up immediately wipes the form completely clean because of a simple character length error! Now I have to type my long email and confirm everything again. Why does this system punish me for validation states?`,
frictionPoints: [
{
element: "input#auth-create-password",
locationDescription: "Sign-up field grid rows.",
panicTrigger: "No inline indicators or checkboxes demonstrating compliance before submit is tapped.",
severity: "high",
namedZone: "primary_form_wrapper"
}
]
};
distractedReport = {
personaName: "Distracted Dan",
score: globalPanicScore,
frictionPointsCount: 2,
dropOffProbability: Math.min(90, globalPanicScore + 4),
trustRating: Math.max(20, 75 - globalPanicScore),
cognitiveLoad: "Low",
biggestRisk: "Unresponsive Google Sign-In buttons and excessively long sign-up field sets.",
quote: `I was met with a long registration field sheet asking for my company name, department size, and role, when I just wanted to test the client dashboard. They should have a one-tap Google auth button. I closed the tab immediately.`,
frictionPoints: [
{
element: "button#oauth-google-sign-in",
locationDescription: "Top of authentication box.",
panicTrigger: "Social sign-in button lacks visible loading states, making taps feel dead.",
severity: "medium",
namedZone: "actions_button_container"
}
]
};
firstTimeReport = {
personaName: "First-Timer Fiona",
score: globalPanicScore + 1,
frictionPointsCount: 2,
dropOffProbability: Math.min(92, globalPanicScore + 2),
trustRating: Math.max(20, 80 - globalPanicScore),
cognitiveLoad: "Medium",
biggestRisk: "Confusing email verification mandates with unclear delivery expectations.",
quote: `It says 'Verify your SAML node configuration before signing in'. Why does it make standard registration so hard? Just send me a standard magic link or direct code instead of using deep tech terms.`,
frictionPoints: [
{
element: "a#saml-auth-link",
locationDescription: "Bottom row coordinates of submission card.",
panicTrigger: "Pushes complex enterprise SSO protocols on general users trying to log in.",
severity: "medium",
namedZone: "footer_attribution_strip"
}
]
};
impatientMobileReport = {
personaName: "Impatient Ian",
score: Math.min(100, globalPanicScore + 11),
frictionPointsCount: 4,
dropOffProbability: Math.min(98, globalPanicScore + 14),
trustRating: Math.max(15, 65 - globalPanicScore),
cognitiveLoad: "High",
biggestRisk: "Compact inputs causing misclicks on mobile viewport browsers.",
quote: `I am trying to tap the password field while walking fast. The form size is so tiny I keep tapping the 'Forgot Password' link right underneath! It redirects me to a reset screen and ruins my sign-in flow!`,
frictionPoints: [
{
element: "a#login-forgot-password",
locationDescription: "Sits 4px below the password inputs.",
panicTrigger: "Tiny touch boundaries trigger misclicks and reset redirects.",
severity: "high",
namedZone: "actions_button_container"
}
]
};
skepticReport = {
personaName: "Skeptical Sally",
score: globalPanicScore + 3,
frictionPointsCount: 2,
dropOffProbability: Math.min(96, globalPanicScore + 6),
trustRating: Math.max(5, 45 - globalPanicScore),
cognitiveLoad: "Medium",
biggestRisk: "Mandatory pre-selected telemetry and automated newsletter tracking agreements.",
quote: `The sign-up card has a pre-checked box that says 'By signing up I agree to let our partners sync analytical metrics.' This is a dark pattern! I won't allow silent telemetry.`,
frictionPoints: [
{
element: "input#auth-telemetry-checkbox",
locationDescription: "Directly above the primary CTA button.",
panicTrigger: "Pre-checked agreement lines trying to trick users.",
severity: "high",
namedZone: "primary_form_wrapper"
}
]
};
universalComplaints = [
{
element: "input#auth-create-password",
reason: "Anxious users face sign-in wipes upon errors; Impatient mobile users click password resets by mistake.",
solution: `<!-- Replaced with secure custom dynamic password input component -->`
}
];
fixes = [
{
issue: "Dense placement of password resets link",
recommendation: `<!-- Vertically distance the target input layout links -->`,
difficulty: "Easy",
impact: "Highly Beneficial"
}
];
} else if (category === "content") {
brutalSummary = globalPanicScore < 45
? `The reading layout for ${formattedName} maintains stellar column proportions. High-contrast, clean fonts allow rapid readers to focus, preserving cognitive energy.`
: globalPanicScore >= 75
? `The content feed is a visual crime scene. With sticky ads, infinite video overlays, complex subscribe prompts, and tiny paragraphs, the user gets sensory overload.`
: `The ${formattedName} content page features high typography readability, but is held back by overlapping layout widgets. Navigating columns triggers occasional visual shift.`;
aestheticCritique = `The typography uses clean serif choices paired with dark charcoal body text. However, line height is compressed. We recommend applying 1.625 em line spacing to text columns, containing secondary sidebars inside standard flex grids, and removing automated autoplay widgets.`;
anxiousReport = {
personaName: "Anxious Alex",
score: globalPanicScore + 2,
frictionPointsCount: 2,
dropOffProbability: Math.min(90, globalPanicScore + 5),
trustRating: Math.max(20, 80 - globalPanicScore),
cognitiveLoad: "Medium",
biggestRisk: "Unsolicited paywalls that lock content midway, simulating a malware redirect.",
quote: `I was reader-focused when a large popup jumped saying 'Log in using Facebook or lose your account stats.' It has no visible close buttons, and it sounded so urgent I thought I had broken my browser!`,
frictionPoints: [
{
element: "div.interstitial-paywall-gate",
locationDescription: "Buried mid-sentence in article columns.",
panicTrigger: "Abrupt, aggressive layout shift designed to force sign-ups, causing anxiety.",
severity: "high",
namedZone: "primary_form_wrapper"
}
]
};
distractedReport = {
personaName: "Distracted Dan",
score: globalPanicScore + 4,
frictionPointsCount: globalPanicScore >= 75 ? 4 : 2,
dropOffProbability: Math.min(95, globalPanicScore + 8),
trustRating: Math.max(15, 70 - globalPanicScore),
cognitiveLoad: "High",
biggestRisk: "Multiple blinking recommendation boxes and banner cards surrounding text columns.",
quote: `I tried to read this article, but there were 5 separate recommendation boxes, a floating newsletter signup card, and an autoplay video. I couldn't focus on three lines of prose before my eyes glazed over. I closed this tab.`,
frictionPoints: [
{
element: "aside.sidebar-recommendations-grid",
locationDescription: "Fixed right-hand screen grid.",
panicTrigger: "Too much flashing content competing for cognitive reading focus.",
severity: "medium",
namedZone: "sidebar_metadata_box"
}
]
};
firstTimeReport = {
personaName: "First-Timer Fiona",
score: globalPanicScore - 3,
frictionPointsCount: 2,
dropOffProbability: Math.min(85, globalPanicScore),
trustRating: Math.max(30, 80 - globalPanicScore),
cognitiveLoad: "Low",
biggestRisk: "Hidden registration/subscription locks that should have been disclosed upfront.",
quote: `I clicked what looked like a free article, but it became locked after two sentences. Why do content layouts trick visitors instead of listing simple 'Premium' indicators in the feed headers? Just be honest.`,
frictionPoints: [
{
element: "span.exclusive-content-badge",
locationDescription: "Directly above the primary article banner.",
panicTrigger: "No explicit visual classification indicating content pricing model prior to user clicks.",
severity: "medium",
namedZone: "header_control_dock"
}
]
};
impatientMobileReport = {
personaName: "Impatient Ian",
score: Math.min(100, globalPanicScore + 11),
frictionPointsCount: 4,
dropOffProbability: Math.min(98, globalPanicScore + 15),
trustRating: Math.max(15, 60 - globalPanicScore),
cognitiveLoad: "High",
biggestRisk: "Layout shifting ads that constantly push paragraphs down during mobile scroll.",
quote: `I am attempting to read this on my phone with bad cellular connection. Every 10 seconds, an ad loads in the background and pushes the text completely down! I keep losing my line. And the 'Close Ad' tap targets are microscopic!`,
frictionPoints: [
{
element: "div.google-ad-container-slot",
locationDescription: "Inlined between paragraph blocks.",
panicTrigger: "High layout shifts and unreachable touch heights cause major frustration.",
severity: "high",
namedZone: "primary_form_wrapper"
}
]
};
skepticReport = {
personaName: "Skeptical Sally",
score: globalPanicScore + 2,
frictionPointsCount: 2,
dropOffProbability: Math.min(92, globalPanicScore + 4),
trustRating: Math.max(10, 48 - globalPanicScore),
cognitiveLoad: "Medium",
biggestRisk: "Sensationalist, clickbait headings lacking real author bios or editorial references.",
quote: `They publish massive claims but tuck the author's credentials behind three menus. There is no editorial seal or date of review. I suspect this is just automated AI-generated search-engine bait designed to harvest click metrics.`,
frictionPoints: [
{
element: "div.author-signature-block",
locationDescription: "Directly below article title.",
panicTrigger: "No profile links or verification badges on editorial credits.",
severity: "medium",
namedZone: "header_control_dock"
}
]
};
universalComplaints = [
{
element: "div.interstitial-paywall-gate",
reason: "Anxious readers are startled by sudden lock popups; Impatient mobile users misclick hidden exit triggers.",
solution: `<!-- Custom secure inlined premium gateway module -->`
}
];
fixes = [
{
issue: "Line spacing of content text is too compressed",
recommendation: `<!-- Boost reading line values on body texts -->`,
difficulty: "Easy",
impact: "Highly Beneficial"
}
];
} else {
// Brand / Landing page default
brutalSummary = globalPanicScore < 45
? `The landing splash in ${formattedName} centers its service purpose with pristine clarity. Visual paths flow smoothly, while spaced CTAs give rapid readers high orientation feedback.`
: globalPanicScore >= 75
? `The splash layout in ${formattedName} is visual gridlock. It is highly congested with overlapping promo banners, secondary labels, and sticky chat overlay animations, blocking standard user task paths.`
: `The ${formattedName} landing page has a clear visual hierarchy but suffers from ungrounded descriptions. The primary action triggers lack simple trust signs next to signing fields, creating moderate friction.`;
aestheticCritique = `The splash features clean sans-serif layout titles. However, the auxiliary button rails are cramped. We recommend applying 16px horizontal spacing margins, utilizing high-contrast outlines for hover feedback, and rounding outer widget outlines.`;
anxiousReport = {
personaName: "Anxious Alex",
score: globalPanicScore + 5,
frictionPointsCount: globalPanicScore >= 75 ? 3 : 1,
dropOffProbability: Math.min(94, globalPanicScore + 8),
trustRating: Math.max(15, 78 - globalPanicScore),
cognitiveLoad: "High",
biggestRisk: "Landing page signup pathways lack error rollbacks or explicit price disclaimers.",
quote: `They urge me to click 'Start Free Trial' but don't state if it self-renews or how easy it is to opt out. I feel extremely anxious that clicking this button will trap my credit card in a payment loop without confirmation checks!`,
frictionPoints: [
{
element: "button#landing-primary-cta",
locationDescription: "Directly centered inside the main hero pane banner.",
panicTrigger: "Requires transactional entries with no secure guarantees or direct cancel notices.",
severity: "high",
namedZone: "actionable_trigger_group"
}
]
};
distractedReport = {
personaName: "Distracted Dan",
score: globalPanicScore + 2,
frictionPointsCount: 3,
dropOffProbability: Math.min(90, globalPanicScore + 8),
trustRating: Math.max(20, 72 - globalPanicScore),
cognitiveLoad: "Medium",
biggestRisk: "Vague headings and decorative shapes competing with the main service value proposition.",
quote: `I skimmed the main page for 3 seconds. The heading says 'Optimize Your Synergy Metrics Interface Gateway'. What does this platform even sell? I got bored of decyphering complex terms and browsed YouTube instead.`,
frictionPoints: [
{
element: "h1.hero-headline-title-block",
locationDescription: "Top center space of hero landing pane.",
panicTrigger: "Dense proprietary vocabulary that fails the simple landing clarity check.",
severity: "high",
namedZone: "hero_focus_pane"
}
]
};
firstTimeReport = {
personaName: "First-Timer Fiona",
score: globalPanicScore - 1,
frictionPointsCount: 2,
dropOffProbability: Math.min(90, globalPanicScore + 1),
trustRating: Math.max(25, 75 - globalPanicScore),
cognitiveLoad: "Medium",
biggestRisk: "Empty dashboards and dense product abbreviations lacking user onboarding steps.",
quote: `It says 'Deploy Ingress Telemetry Config Nodes'. Why can't they just say 'Set up your website tracker'? Just explain step one with a direct human dialog box.`,
frictionPoints: [
{
element: "p.hero-onboarding-subtitle-span",
locationDescription: "Directly beneath the primary title.",
panicTrigger: "Assumes massive category domain knowledge from first-time visitors, triggering bounces.",
severity: "medium",
namedZone: "hero_focus_pane"
}
]
};
impatientMobileReport = {
personaName: "Impatient Ian",
score: Math.min(100, globalPanicScore + 12),
frictionPointsCount: 4,
dropOffProbability: Math.min(98, globalPanicScore + 14),
trustRating: Math.max(10, 64 - globalPanicScore),
cognitiveLoad: "High",
biggestRisk: "Desktop-oriented button positions resulting in painful accidental clicks on mobile rails.",
quote: `I'm holding the handrail on a bus trying to tap the CTA page. The primary button target is tiny and stands directly beside the 'Terms of Use' link! I kept opening secondary PDF legal documents by mistake.`,
frictionPoints: [
{
element: "button#landing-primary-cta",
locationDescription: "Bottom row of hero center pane.",
panicTrigger: "Lacks secure mobile bounding targets of 44px, precipitating persistent misclicks on auxiliary links.",
severity: "high",
namedZone: "actionable_trigger_group"
}
]
};
skepticReport = {
personaName: "Skeptical Sally",
score: globalPanicScore + 3,
frictionPointsCount: 2,
dropOffProbability: Math.min(95, globalPanicScore + 5),
trustRating: Math.max(5, 45 - globalPanicScore),
cognitiveLoad: "Medium",
biggestRisk: "Vague slogans, stock layout assets, and complete absence of verified social proof or reviews.",
quote: `They promise 'Instant layout optimization boosts 400%!' but don't show real client list logos, customer testimonials, or links to Github codes. It feels like an AI-generated template made to collect emails.`,
frictionPoints: [
{
element: "section#customer-logos-block",
locationDescription: "Staggered directly below the hero banner.",
panicTrigger: "Stock icon placeholders or empty spaces with zero verified customer trust logos.",
severity: "medium",
namedZone: "footer_trust_strip"
}
]
};
universalComplaints = [
{
element: "button#landing-primary-cta",
reason: "Anxious users hesitate to click unverified trial buttons; Impatient mobile users click adjacent links due to micro targets; Skeptics reject the vague value propositions.",
solution: `<!-- Clean, spaced, trust-verified interactive CTA trigger -->`
}
];
fixes = [
{
issue: "Landing hero CTA target height is too compact",
recommendation: `<!-- Boost vertical bounding targets on hero action block buttons -->`,
difficulty: "Easy",
impact: "Critical"
}
];
}
const generatedId = `report-${Math.random().toString(36).substring(2, 11)}`;
return {
id: generatedId,
title: `${formattedName} Portal`,
urlAnalyzed: url || "No website URL (direct media upload)",
timestamp: new Date().toISOString(),
globalPanicScore,
brutalSummary,
visualAestheticRating,
aestheticCritique,
namedUIZones,
personas: {
anxious: anxiousReport,
distracted: distractedReport,
firstTime: firstTimeReport,
impatientMobile: impatientMobileReport,
skeptic: skepticReport
},
universalComplaints,
panicCertificate: {
verdict,
text: verdictTextTemplate
},
fixes
};
}
// NSFW & Abusive URL Detection blocklist filter
function isNSFWorAbusive(text: string): boolean {
if (!text) return false;
const clean = text.toLowerCase().trim();
const blocklist = [
"porn", "xxx", "sex", "nudity", "nude", "xvideos", "pornhub",
"onlyfans", "chaturbate", "camgirl", "adultfriendfinder", "lust",
"brazzers", "redtube", "vixen", "hentai", "erection", "orgasm",
"intercourse", "milf", "blowjob", "fuck", "dick", "pussy", "vagina",
"escort", "nsfw", "stripclub", "sensual", "gambling", "casino",
"betting", "poker", "jackpot", "torrent", "warez", "cracked", "hack"
];
return blocklist.some(term => clean.includes(term));
}
// API Route for deconstructing and stress testing UI
app.post("/api/stress-test", async (req, res) => {
try {
const { url, screenshotBase64, mimeType } = req.body;
// 1. IP Rate Limiting Verification
const requesterIP = (req.headers["x-forwarded-for"] as string) || req.socket.remoteAddress || "anonymous";
const now = Date.now();
const windowMs = 60 * 1000; // 1 minute
const maxRequestsPerMinute = 5;
let tracker = rateLimits.get(requesterIP);
if (!tracker) {
rateLimits.set(requesterIP, { count: 1, resetTime: now + windowMs });
} else {
if (now > tracker.resetTime) {
tracker.count = 1;
tracker.resetTime = now + windowMs;
} else {
tracker.count++;
if (tracker.count > maxRequestsPerMinute) {
return res.status(429).json({
error: "Rate limit exceeded. To prevent system resource exhaustion, you are limited to 5 audits per minute.",
details: "Security threshold active to protect system integrity."
});
}
}
}
// 2. Input Length & Abuse Validations
if (url && url.length > 2048) {
return res.status(400).json({ error: "URL is too long. To prevent injection exploits, maximum allowed size is 2048 characters." });
}
// 3. NSFW & Adult Platform Filtering
if (url && isNSFWorAbusive(url)) {
return res.status(400).json({
error: "Audit rejected. panic.design has zero tolerance for NSFW, adult content, gambling, or illicit content.",
details: "AI-governed guardrails prevent audits of sexually explicit or high-risk interfaces."
});
}
if (!url && !screenshotBase64) {
return res.status(400).json({ error: "Provide either a website URL or a UI screenshot to analyze." });
}
const ai = getGenAI();
// Nimbleway Scraper Interceptor implementation
let activeScreenshot = screenshotBase64;
let activeMimeType = mimeType || "image/png";
let utilizedNimble = false;
if (url && !activeScreenshot) {
try {
const nimbleCapture = await captureUrlWithNimble(url);
if (nimbleCapture) {
activeScreenshot = nimbleCapture;
activeMimeType = "image/png";
utilizedNimble = true;
console.log(`[NIMBLEWAY SUCCESS] Real-time headless browser screenshot fetched successfully via Nimble API for URL: ${url}`);
}
} catch (err) {
console.error("[NIMBLEWAY ERROR IN API FLOW]", err);
}
}
// Prepare content parts for Gemini
const contents: any[] = [];
// UI screenshot part (either uploaded or intercepted via Nimbleway Scraper)
if (activeScreenshot) {
contents.push({
inlineData: {
mimeType: activeMimeType,
data: activeScreenshot.replace(/^data:image\/\w+;base64,/, ""),
},
});
}
// Structured UX audit instructions prompt
let promptText = `Verify, audit, and deconstruct the user experience of the provided UI `;
if (activeScreenshot && url) {
if (utilizedNimble) {
promptText += `screenshot of ${url} captured live in real time via our Nimble headless scraping browser pipeline.`;
} else {
promptText += `screenshot representing the website ${url}.`;
}
} else if (activeScreenshot) {
promptText += `screenshot.`;
} else {
promptText += `website URL: ${url}. (Audit based on your generalized knowledge of this service's standard web layout, onboarding patterns, text fields, and CTAs).`;
}
promptText += `
You are a highly sophisticated, objective, and supportive Lead Fullstack UX Auditor & UI Engineer. You have an extremely high attention to detail for:
1. Form optimization and cognitive complexity (minimizing redundant form inputs, optimizing client-side validation states, explicit autofocus and tab-indexing, keyboard navigation accessibility).
2. Cognitive hierarchy and information layout (preventing Cumulative Layout Shifts, optimizing card flexboxes, applying standard typography scales, maintaining high container spacing, structural margins).
3. Technical vocabulary and intuitive copywriting (translating complex system error stack traces, unhelpful codes, and database acronyms into direct, standard human labels).
4. Guardrails and rollback pipelines (preventing user mistakes, state preservation upon validation reload, micro-action backtracks).
Before generating any persona output, you MUST perform a silent structural scan of the provided screenshot or URL context:
- Identify every interactive element — buttons, forms, links, dropdowns, modals
- Identify the primary CTA and whether it is visually dominant
- Identify the information hierarchy — what the eye lands on first, second, third
- Detect visual noise — how many competing elements exist above the fold
- Detect trust signals or absence of them — pricing visibility, social proof, security badges
- Detect ambiguous labels — any button or link whose action is not 100% clear from its text alone
- Map the entire UI into 3 to 6 named layout zones — each zone gets a label that all personas reference consistently in their feedback reports (e.g., "primary_cta_area", "form_body_wrapper", "sidebar_controls_box").
Now, audit this UI from the perspectives of five simulated, distinct user personas. For each persona's report, you MUST provide highly detailed, realistic, and developer-centric diagnostic feedback.
Persona specifications:
1. Anxious User: Genuinely afraid of making a mistake online. Monologue is raw stream of consciousness, slightly catastrophizing. Finds every unclear label, irreversible action, missing confirmation, or unexplained input. Every complaint ends with exactly what microcopy, safe backtrack, or layout design would have calmed them down.
2. Distracted User: Gave this page 3 seconds of attention before eyes glazed over. Bored, fast, dismissive monologue. Identifies if the landing value proposition is instant, checks if primary CTA is immediately findable, complains about elements needing too much reading. Every complaint ends with what specific visual cue/resize would have held their attention.
3. First Timer: No industry jargon understood, no category knowledge. Curiosity but confusion. Identifies jargon terms, assumptions of context, and missing onboarding steps. Every complaint ends with the one-sentence orientation text that would have saved them.
4. Impatient Mobile User: On a phone, one-handed, bad connection, standing in line. Terse, frustrated monologue. Evaluates tap target sizes (WCAG 44px min), scrolling fatigue, design density, hover traps. Every complaint ends with the single clean layout adjustment to satisfy the mobile viewport.
5. Skeptic: Thinks everything is a trick. Finds dark patterns, hidden costs, vague promises, unverified proof, and excessive data grabs. Sardonic, dry monologue. Every complaint ends with the exact design signal that would have earned a fraction of their trust.
How statistics are calculated:
- Friction Points Count: Specific count of interactive elements flagged as problems (weighted by severity).
- Drop-off Probability: Calculated as the realistic, derived chance (0-100%) this persona abandons before completion.
- Trust Rating (0-100%): Anchored to specific visual trust evidence or lack thereof in the screenshot.
- Score: Overall stress/friction level.
- Panic Score: Adjusted average of all five drop-offs.
UNIVERSAL COMPLAINTS ALGORITHM:
Perform a secondary pass. Any element flagged by three or more personas MUST be elevated to a Universal Complaint, listing why multiple users hit the wall, and providing a single concrete replacement code/spec.
FIX GENERATOR BEHAVIOR:
Provide explicit replacement code or exact microcopy text instead of generic suggestions.
Panic Certificate Logic:
- 0-25 score: "Panic-Proof" verdict (minimal friction, flawless clarity, high trust. Confident, specific praise).
- 26-45 score: "Steady" verdict (highly reliable, low friction, stable alignment and aesthetic layout).
- 46-65 score: "Work In Progress" verdict (balanced design with some spacing or layout improvements required).
- 66-82 score: "Stress Fractures" verdict (notable user friction, mobile touch sizing layout constraints, or high cognitive load).
- 83-100 score: "Crime Scene" verdict (critical layout errors, massive dropoffs, senior designer direct review).
CRITICAL COPYWRITING DIRECTIVE (ANTI-CLICHÉ GUARDRAIL):
- You MUST NOT under any circumstance use repetitive boilerplate sentences.
- STRICTLY FORBIDDEN from outputting the following cliché sentences:
- "My screen is crowded with inline badges and secondary sidebars..."
- "I'm standing in a grocery line trying to complete this on a tiny screen..."
- "Wait, does this register right away or do I get a chance to confirm?..."
- "The interface targets are tiny! Standard fingers require at least 44 pixels of tap height..."
- "They demand input data right away but don't state who they are or show security badges..."
- Every single quote, critique, named zone, and recommended code fix MUST be 100% custom, unique, and tailored to the visual properties and text of the provided screen or domain. Cite specific terms, buttons, colors, and layout configurations that are actually present.