196196 .api-key-hint a { color : var (--accent ); text-decoration : none; }
197197 .api-key-hint a : hover { text-decoration : underline; }
198198
199- /* Login Button */
200199 .login-btn {
201200 width : auto;
202201 padding : 6px 12px ;
239238 .login-btn : disabled .login-icon img {
240239 filter : invert (1 );
241240 }
242- .login-or {
243- font-size : 11px ;
244- color : var (--text-muted );
245- margin-left : 8px ;
246- }
247241 .login-btn-wrapper {
248242 text-align : center;
249243 display : flex;
252246 margin-bottom : 8px ;
253247 }
254248
249+ .api-key-wrapper {
250+ position : relative;
251+ display : flex;
252+ align-items : center;
253+ }
254+
255+ # api-key {
256+ padding-right : 40px ;
257+ }
258+
259+ .copy-api-key-btn {
260+ position : absolute;
261+ right : 8px ;
262+ top : 50% ;
263+ transform : translateY (-50% );
264+ width : 24px ;
265+ height : 24px ;
266+ border : 1px solid var (--border-subtle );
267+ border-radius : 6px ;
268+ background : # 2a2a2c ;
269+ color : var (--text-secondary );
270+ display : inline-flex;
271+ align-items : center;
272+ justify-content : center;
273+ cursor : pointer;
274+ transition : border-color 0.2s ease, color 0.2s ease;
275+ }
276+
277+ .copy-api-key-btn : hover {
278+ border-color : var (--accent );
279+ color : # fff ;
280+ }
281+
282+ .copy-api-key-btn : disabled {
283+ opacity : 0.45 ;
284+ cursor : not-allowed;
285+ }
286+
287+ .copy-api-key-btn svg {
288+ width : 14px ;
289+ height : 14px ;
290+ }
291+
292+ .logout-btn {
293+ position : fixed;
294+ left : 14px ;
295+ bottom : 14px ;
296+ z-index : 101 ;
297+ border : 1px solid rgba (255 , 255 , 255 , 0.15 );
298+ background : rgba (25 , 25 , 27 , 0.9 );
299+ color : var (--text-secondary );
300+ border-radius : 8px ;
301+ padding : 7px 10px ;
302+ font-size : 11px ;
303+ cursor : pointer;
304+ transition : all 0.2s ease;
305+ }
306+
307+ .logout-btn : hover {
308+ color : # fff ;
309+ border-color : var (--accent );
310+ }
311+
255312 /* Profile Display in Empty State */
256313 .profile-display {
257314 text-align : center;
538595
539596 .prompt-bar { min-height : 104px ; height : auto; max-height : 300px ; background-color : # 1a1a1c ; border-top : 1px solid var (--border-subtle ); padding : 14px 24px ; display : flex; align-items : flex-start; gap : 20px ; z-index : 60 ; position : fixed; bottom : 0 ; left : 360px ; right : 0 ; }
540597 .prompt-bar : hover , .prompt-bar : focus-within { z-index : 200000 ; }
541- .prompt-input-wrapper { flex : 1 ; min-height : 72px ; max-height : 200px ; height : auto; background-color : # 2a2a2c ; border-radius : 26px ; display : flex; align-items : flex-start; padding : 12px 24 px ; border : 1px solid # 3a3a3c ; transition : all 0.3s ease; overflow : visible ; }
598+ .prompt-input-wrapper { flex : 1 ; min-height : 72px ; max-height : 200px ; height : auto; background-color : # 2a2a2c ; border-radius : 26px ; display : flex; align-items : flex-start; padding : 12px 20 px ; border : 1px solid # 3a3a3c ; transition : all 0.3s ease; overflow : hidden ; }
542599 .prompt-actions { display : flex; gap : 12px ; align-items : stretch; margin-top : auto; align-self : flex-end; flex-shrink : 0 ; }
543600 .prompt-input-wrapper : focus-within { border-color : var (--accent ); background-color : # 303033 ; box-shadow : 0 0 0 4px rgba (37 , 99 , 235 , 0.1 ); }
544601
545- # prompt { flex : 1 ; background : transparent; border : none; color : var (--text-primary ); font-size : 15px ; outline : none; width : 100% ; padding : 0 8px 0 0 ; resize : none; max-height : 200px ; line-height : 1.5 ; overflow-y : auto; overflow-x : hidden; display : block; scrollbar-width : thin; scrollbar-color : # 3a3a3a transparent; scrollbar-gutter : stable; height : auto; min-height : 48px ; }
602+ .upload-slots {
603+ display : flex;
604+ flex-direction : column;
605+ gap : 8px ;
606+ margin-right : 12px ;
607+ }
608+
609+ .upload-slot {
610+ display : flex;
611+ align-items : center;
612+ min-height : 36px ;
613+ }
614+
615+ # prompt { flex : 1 ; background : transparent; border : none; color : var (--text-primary ); font-size : 15px ; outline : none; width : 100% ; padding : 0 2px 0 0 ; resize : none; max-height : 200px ; line-height : 1.5 ; overflow-y : auto; overflow-x : hidden; display : block; scrollbar-width : thin; scrollbar-color : # 3a3a3a transparent; scrollbar-gutter : stable; height : auto; min-height : 48px ; }
546616 # prompt ::-webkit-scrollbar { width : 6px ; }
547617 # prompt ::-webkit-scrollbar-track { background : transparent; }
548618 # prompt ::-webkit-scrollbar-thumb { background : # 3a3a3a ; border-radius : 3px ; }
554624 display : flex;
555625 align-items : center;
556626 justify-content : center;
557- margin-right : 16 px ;
558- align-self : flex-start ;
559- margin-top : 4 px ;
627+ margin-right : 0 ;
628+ align-self : center ;
629+ margin-top : 0 ;
560630 }
561631
562632
590660 display : none;
591661 align-items : center;
592662 justify-content : center;
593- margin-right : 12 px ;
594- align-self : flex-start ;
595- margin-top : 2 px ;
663+ margin-right : 6 px ;
664+ align-self : center ;
665+ margin-top : 0 ;
596666 }
597667
598668 .upload-thumbnail-wrapper .visible {
9371007 background : var (--accent-hover );
9381008 }
9391009
1010+ .auth-gate {
1011+ position : fixed;
1012+ inset : 0 ;
1013+ background : rgba (7 , 7 , 9 , 0.92 );
1014+ backdrop-filter : blur (5px );
1015+ z-index : 120000 ;
1016+ display : flex;
1017+ align-items : center;
1018+ justify-content : center;
1019+ padding : 20px ;
1020+ }
1021+
1022+ .auth-popup {
1023+ width : min (460px , 100% );
1024+ background : var (--panel-bg );
1025+ border : 1px solid var (--border-subtle );
1026+ border-radius : 16px ;
1027+ padding : 24px ;
1028+ text-align : center;
1029+ box-shadow : 0 20px 60px rgba (0 , 0 , 0 , 0.55 );
1030+ }
1031+
1032+ .auth-popup-logo {
1033+ width : 58px ;
1034+ height : 58px ;
1035+ border-radius : 12px ;
1036+ margin-bottom : 14px ;
1037+ }
1038+
1039+ .auth-popup h2 {
1040+ font-size : 22px ;
1041+ margin-bottom : 10px ;
1042+ }
1043+
1044+ .auth-popup p {
1045+ color : var (--text-secondary );
1046+ font-size : 14px ;
1047+ margin-bottom : 18px ;
1048+ line-height : 1.45 ;
1049+ }
1050+
1051+ body .auth-locked .sidebar ,
1052+ body .auth-locked .canvas ,
1053+ body .auth-locked .api-key-container ,
1054+ body .auth-locked # logout-btn {
1055+ pointer-events : none;
1056+ user-select : none;
1057+ }
1058+
9401059 </ style >
9411060</ head >
9421061< body >
@@ -1040,13 +1159,22 @@ <h3 data-i18n="advancedLabel">Advanced Options</h3>
10401159 </ span >
10411160 < span id ="login-btn-text " data-i18n ="loginWithPollinations "> Login with Pollinations</ span >
10421161 </ button >
1043- < span class ="login-or " data-i18n ="orLabel "> or</ span >
10441162 </ div >
1045- < div class ="api-key-wrapper "> < input type ="password " id ="api-key " data-i18n-placeholder ="apiKeyPlaceholder " placeholder ="API Key " autocomplete ="current-password "> </ div >
1163+ < div class ="api-key-wrapper ">
1164+ < input type ="password " id ="api-key " data-i18n-placeholder ="apiKeyPlaceholder " placeholder ="API Key " autocomplete ="off " readonly >
1165+ < button class ="copy-api-key-btn " id ="copy-api-key-btn " type ="button " title ="Copy API key " aria-label ="Copy API key ">
1166+ < svg viewBox ="0 0 24 24 " fill ="none " stroke ="currentColor " stroke-width ="2 ">
1167+ < rect x ="9 " y ="9 " width ="13 " height ="13 " rx ="2 " ry ="2 "> </ rect >
1168+ < path d ="M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1 "> </ path >
1169+ </ svg >
1170+ </ button >
1171+ </ div >
10461172 < div id ="api-key-hint " class ="api-key-hint " data-i18n ="apiKeyHint "> Get your API key from < a href ="https://pollinations.ai " target ="_blank "> Pollinations</ a > </ div >
10471173 < div id ="resolution-warning " class ="resolution-warning " data-i18n ="resolutionWarning "> For optimal use, a resolution of at least 1080p is recommended.</ div >
10481174 </ div >
10491175
1176+ < button class ="logout-btn hidden " id ="logout-btn " type ="button " data-i18n ="logoutLabel "> Logout</ button >
1177+
10501178 < main class ="canvas ">
10511179 < div class ="canvas-workspace " id ="canvas-workspace ">
10521180 < div class ="empty-state " id ="placeholder ">
@@ -1067,63 +1195,69 @@ <h2 id="empty-title" data-i18n="startScreenTitle">Generate Images Now</h2>
10671195
10681196 < div class ="prompt-bar ">
10691197 < div class ="prompt-input-wrapper ">
1070- < div class ="upload-thumbnail-wrapper " id ="upload-thumbnail-wrapper ">
1071- < img class ="upload-thumbnail-preview " id ="upload-thumbnail-preview " src ="" alt ="Preview ">
1072- < img class ="upload-thumbnail " id ="upload-thumbnail " src ="" alt ="Uploaded image ">
1073- < div class ="upload-thumbnail-delete " id ="upload-thumbnail-delete " title ="Remove image ">
1074- < svg viewBox ="0 0 24 24 " fill ="none " stroke ="currentColor " stroke-width ="3 " stroke-linecap ="round " stroke-linejoin ="round ">
1075- < line x1 ="18 " y1 ="6 " x2 ="6 " y2 ="18 "> </ line >
1076- < line x1 ="6 " y1 ="6 " x2 ="18 " y2 ="18 "> </ line >
1077- </ svg >
1078- </ div >
1079- < div class ="upload-progress " id ="upload-progress " style ="display: none; ">
1080- < svg viewBox ="0 0 24 24 " fill ="none " stroke ="currentColor " stroke-width ="2 ">
1081- < path d ="M21 12a9 9 0 1 1-6.219-8.56 "> </ path >
1082- </ svg >
1083- </ div >
1084- < div class ="upload-delete-progress " id ="upload-delete-progress " style ="display: none; ">
1085- < svg viewBox ="0 0 24 24 " fill ="none " stroke ="currentColor " stroke-width ="2 ">
1086- < path d ="M21 12a9 9 0 1 1-6.219-8.56 "> </ path >
1087- </ svg >
1088- </ div >
1089- </ div >
1090- < div class ="upload-icon-container " id ="upload-icon-container " title ="">
1091- < svg class ="upload-icon " id ="upload-icon " viewBox ="0 0 24 24 " width ="16 " height ="16 " fill ="none " stroke ="currentColor " stroke-width ="2 " stroke-linecap ="round " stroke-linejoin ="round ">
1092- < path d ="M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4 "> </ path >
1093- < polyline points ="17,8 12,3 7,8 "> </ polyline >
1094- < line x1 ="12 " y1 ="3 " x2 ="12 " y2 ="15 "> </ line >
1095- </ svg >
1096- </ div >
1097- < input type ="file " id ="image-upload-input " accept ="image/* " style ="display: none; ">
1098-
1099- < div class ="upload-thumbnail-wrapper " id ="upload-thumbnail-wrapper-2 ">
1100- < img class ="upload-thumbnail-preview " id ="upload-thumbnail-preview-2 " src ="" alt ="Preview ">
1101- < img class ="upload-thumbnail " id ="upload-thumbnail-2 " src ="" alt ="Uploaded image 2 ">
1102- < div class ="upload-thumbnail-delete " id ="upload-thumbnail-delete-2 " title ="Remove image ">
1103- < svg viewBox ="0 0 24 24 " fill ="none " stroke ="currentColor " stroke-width ="3 " stroke-linecap ="round " stroke-linejoin ="round ">
1104- < line x1 ="18 " y1 ="6 " x2 ="6 " y2 ="18 "> </ line >
1105- < line x1 ="6 " y1 ="6 " x2 ="18 " y2 ="18 "> </ line >
1106- </ svg >
1107- </ div >
1108- < div class ="upload-progress " id ="upload-progress-2 " style ="display: none; ">
1109- < svg viewBox ="0 0 24 24 " fill ="none " stroke ="currentColor " stroke-width ="2 ">
1110- < path d ="M21 12a9 9 0 1 1-6.219-8.56 "> </ path >
1111- </ svg >
1198+ < div class ="upload-slots ">
1199+ < div class ="upload-slot ">
1200+ < div class ="upload-thumbnail-wrapper " id ="upload-thumbnail-wrapper ">
1201+ < img class ="upload-thumbnail-preview " id ="upload-thumbnail-preview " src ="" alt ="Preview ">
1202+ < img class ="upload-thumbnail " id ="upload-thumbnail " src ="" alt ="Uploaded image ">
1203+ < div class ="upload-thumbnail-delete " id ="upload-thumbnail-delete " title ="Remove image ">
1204+ < svg viewBox ="0 0 24 24 " fill ="none " stroke ="currentColor " stroke-width ="3 " stroke-linecap ="round " stroke-linejoin ="round ">
1205+ < line x1 ="18 " y1 ="6 " x2 ="6 " y2 ="18 "> </ line >
1206+ < line x1 ="6 " y1 ="6 " x2 ="18 " y2 ="18 "> </ line >
1207+ </ svg >
1208+ </ div >
1209+ < div class ="upload-progress " id ="upload-progress " style ="display: none; ">
1210+ < svg viewBox ="0 0 24 24 " fill ="none " stroke ="currentColor " stroke-width ="2 ">
1211+ < path d ="M21 12a9 9 0 1 1-6.219-8.56 "> </ path >
1212+ </ svg >
1213+ </ div >
1214+ < div class ="upload-delete-progress " id ="upload-delete-progress " style ="display: none; ">
1215+ < svg viewBox ="0 0 24 24 " fill ="none " stroke ="currentColor " stroke-width ="2 ">
1216+ < path d ="M21 12a9 9 0 1 1-6.219-8.56 "> </ path >
1217+ </ svg >
1218+ </ div >
1219+ </ div >
1220+ < div class ="upload-icon-container " id ="upload-icon-container " title ="">
1221+ < svg class ="upload-icon " id ="upload-icon " viewBox ="0 0 24 24 " width ="16 " height ="16 " fill ="none " stroke ="currentColor " stroke-width ="2 " stroke-linecap ="round " stroke-linejoin ="round ">
1222+ < path d ="M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4 "> </ path >
1223+ < polyline points ="17,8 12,3 7,8 "> </ polyline >
1224+ < line x1 ="12 " y1 ="3 " x2 ="12 " y2 ="15 "> </ line >
1225+ </ svg >
1226+ </ div >
1227+ < input type ="file " id ="image-upload-input " accept ="image/* " style ="display: none; ">
11121228 </ div >
1113- < div class ="upload-delete-progress " id ="upload-delete-progress-2 " style ="display: none; ">
1114- < svg viewBox ="0 0 24 24 " fill ="none " stroke ="currentColor " stroke-width ="2 ">
1115- < path d ="M21 12a9 9 0 1 1-6.219-8.56 "> </ path >
1116- </ svg >
1229+
1230+ < div class ="upload-slot ">
1231+ < div class ="upload-thumbnail-wrapper " id ="upload-thumbnail-wrapper-2 ">
1232+ < img class ="upload-thumbnail-preview " id ="upload-thumbnail-preview-2 " src ="" alt ="Preview ">
1233+ < img class ="upload-thumbnail " id ="upload-thumbnail-2 " src ="" alt ="Uploaded image 2 ">
1234+ < div class ="upload-thumbnail-delete " id ="upload-thumbnail-delete-2 " title ="Remove image ">
1235+ < svg viewBox ="0 0 24 24 " fill ="none " stroke ="currentColor " stroke-width ="3 " stroke-linecap ="round " stroke-linejoin ="round ">
1236+ < line x1 ="18 " y1 ="6 " x2 ="6 " y2 ="18 "> </ line >
1237+ < line x1 ="6 " y1 ="6 " x2 ="18 " y2 ="18 "> </ line >
1238+ </ svg >
1239+ </ div >
1240+ < div class ="upload-progress " id ="upload-progress-2 " style ="display: none; ">
1241+ < svg viewBox ="0 0 24 24 " fill ="none " stroke ="currentColor " stroke-width ="2 ">
1242+ < path d ="M21 12a9 9 0 1 1-6.219-8.56 "> </ path >
1243+ </ svg >
1244+ </ div >
1245+ < div class ="upload-delete-progress " id ="upload-delete-progress-2 " style ="display: none; ">
1246+ < svg viewBox ="0 0 24 24 " fill ="none " stroke ="currentColor " stroke-width ="2 ">
1247+ < path d ="M21 12a9 9 0 1 1-6.219-8.56 "> </ path >
1248+ </ svg >
1249+ </ div >
1250+ </ div >
1251+ < div class ="upload-icon-container " id ="upload-icon-container-2 " title ="">
1252+ < svg class ="upload-icon " id ="upload-icon-2 " viewBox ="0 0 24 24 " width ="16 " height ="16 " fill ="none " stroke ="currentColor " stroke-width ="2 " stroke-linecap ="round " stroke-linejoin ="round ">
1253+ < path d ="M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4 "> </ path >
1254+ < polyline points ="17,8 12,3 7,8 "> </ polyline >
1255+ < line x1 ="12 " y1 ="3 " x2 ="12 " y2 ="15 "> </ line >
1256+ </ svg >
1257+ </ div >
1258+ < input type ="file " id ="image-upload-input-2 " accept ="image/* " style ="display: none; ">
11171259 </ div >
11181260 </ div >
1119- < div class ="upload-icon-container " id ="upload-icon-container-2 " title ="">
1120- < svg class ="upload-icon " id ="upload-icon-2 " viewBox ="0 0 24 24 " width ="16 " height ="16 " fill ="none " stroke ="currentColor " stroke-width ="2 " stroke-linecap ="round " stroke-linejoin ="round ">
1121- < path d ="M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4 "> </ path >
1122- < polyline points ="17,8 12,3 7,8 "> </ polyline >
1123- < line x1 ="12 " y1 ="3 " x2 ="12 " y2 ="15 "> </ line >
1124- </ svg >
1125- </ div >
1126- < input type ="file " id ="image-upload-input-2 " accept ="image/* " style ="display: none; ">
11271261 < textarea id ="prompt " data-i18n-placeholder ="promptPlaceholder " placeholder ="Describe the image you want to generate " rows ="2 "> </ textarea >
11281262 </ div >
11291263 < div class ="prompt-actions ">
@@ -1222,6 +1356,21 @@ <h2 id="empty-title" data-i18n="startScreenTitle">Generate Images Now</h2>
12221356 < span data-i18n ="useAsReferenceImage "> Use as reference image</ span >
12231357 </ div >
12241358 </ div >
1359+
1360+ < div id ="auth-gate " class ="auth-gate hidden ">
1361+ < div class ="auth-popup ">
1362+ < img class ="auth-popup-logo " src ="js/icon.png " alt ="Pollgen ">
1363+ < h2 data-i18n ="welcomePopupTitle "> Welcome to Pollgen</ h2 >
1364+ < p data-i18n ="welcomePopupText "> Create AI images and videos with Pollinations. Log in to continue.</ p >
1365+ < button class ="login-btn " id ="auth-popup-login-btn " type ="button ">
1366+ < span class ="login-icon ">
1367+ < img src ="https://raw.githubusercontent.com/pollinations/pollinations/refs/heads/main/assets/logo.svg " alt ="">
1368+ </ span >
1369+ < span data-i18n ="loginWithPollinations "> Login with Pollinations</ span >
1370+ </ button >
1371+ </ div >
1372+ </ div >
1373+
12251374 < form id ="generation-form " style ="display: none; ">
12261375 < input type ="hidden " name ="width " id ="width " value ="1366 ">
12271376 < input type ="hidden " name ="height " id ="height " value ="1025 ">
0 commit comments