539539 .btn-icon : hover { background : var (--card ); border-color : var (--text-muted ); }
540540 .btn-icon .danger : hover { background : # fee2e2 ; border-color : # fca5a5 ; }
541541 @media (max-width : 800px ) { .admin-table .col-idea , .admin-table .col-created { display : none; } }
542+ /* Toast */
543+ # ark-toast { position : fixed; top : 24px ; left : 50% ; transform : translateX (-50% ); z-index : 9999 ; display : flex; flex-direction : column; gap : 8px ; align-items : center; pointer-events : none; }
544+ .ark-toast-item { padding : 10px 22px ; border-radius : 10px ; font-size : .9rem ; background : # 1e293b ; color : # fff ; opacity : 0 ; transform : translateY (-8px ); transition : all .3s ; pointer-events : auto; }
545+ .ark-toast-item .warn { background : # 92400e ; }
546+ .ark-toast-item .show { opacity : 1 ; transform : translateY (0 ); }
542547 </ style >
543548</ head >
544549< body >
@@ -625,10 +630,11 @@ <h1>ARK</h1>
625630 <!-- Admin panel — hidden until checkAuth confirms is_admin -->
626631 < div id ="admin-panel " class ="admin-panel " style ="display:none ">
627632 < span class ="admin-label " data-i18n ="nav_admin "> Admin</ span >
628- < span class ="admin-status " id ="admin-status-text "> —</ span >
629- < button class ="btn-admin btn-admin-toggle " id ="btn-admin-toggle " onclick ="adminToggle() "> …</ button >
630- < button class ="btn-admin btn-admin-kill " onclick ="adminKillAll() " data-i18n ="kill_all "> Kill All Jobs</ button >
631- < button class ="btn-admin " onclick ="navigate('admin') " style ="background:var(--teal);color:#fff;font-weight:600 "> Management</ button >
633+ < div style ="margin-left:auto;display:flex;gap:8px ">
634+ < button class ="btn-admin btn-admin-toggle " id ="btn-admin-toggle " onclick ="adminToggle() " style ="background:var(--teal);color:#fff;font-weight:600 "> …</ button >
635+ < button class ="btn-admin btn-admin-kill " onclick ="adminKillAll() " data-i18n ="stop_all " style ="background:var(--teal);color:#fff;font-weight:600 "> Stop All</ button >
636+ < button class ="btn-admin " onclick ="navigate('admin') " style ="background:var(--teal);color:#fff;font-weight:600 "> Admin Console</ button >
637+ </ div >
632638 </ div >
633639
634640 <!-- Hero creation card -->
@@ -761,8 +767,8 @@ <h2 style="margin:0" data-i18n="hero_title">Build your next paper with ARK</h2>
761767 < input type ="radio " name ="model " value ="claude-sonnet-4-6 " checked />
762768 < span class ="model-chip "> Sonnet 4.6</ span >
763769 </ label >
764- < label class ="model-option model-option-admin " title =" Admin only " style =" display:none ">
765- < input type ="radio " name ="model " value ="claude-opus-4-6 " />
770+ < label class ="model-option model-option-premium " style =" opacity:.45;cursor:pointer " title =" Buy Jihao a coffee to enable ">
771+ < input type ="radio " name ="model " value ="claude-opus-4-6 " disabled />
766772 < span class ="model-chip "> Opus 4.6</ span >
767773 </ label >
768774 < label class ="model-option model-option-admin " title ="Admin only " style ="display:none ">
@@ -781,12 +787,12 @@ <h2 style="margin:0" data-i18n="hero_title">Build your next paper with ARK</h2>
781787 </ div >
782788 < div style ="display:flex;gap:16px;margin-top:12px ">
783789 < div class ="hero-adv-field " style ="flex:1 ">
784- < label > Max Dev Iterations < span style =" font-weight:400;color:var(--text-muted);font-size:.85em " > (default: 3) </ span > </ label >
785- < input type ="number " name ="max_dev_iterations " value ="3 " min ="1 " max ="10 " />
790+ < label > Max Dev Iterations</ label >
791+ < input type ="number " name ="max_dev_iterations " value ="1 " min ="1 " max ="1 " />
786792 </ div >
787793 < div class ="hero-adv-field " style ="flex:1 ">
788- < label > Max Review Iterations < span style =" font-weight:400;color:var(--text-muted);font-size:.85em " > (default: 2) </ span > </ label >
789- < input type ="number " name ="max_iterations " value ="2 " min ="1 " max ="5 " />
794+ < label > Max Review Iterations</ label >
795+ < input type ="number " name ="max_iterations " value ="1 " min ="1 " max ="1 " />
790796 </ div >
791797 </ div >
792798 </ div >
@@ -891,7 +897,7 @@ <h2 style="margin-bottom:20px;font-size:1.5rem;font-weight:700" data-i18n="admin
891897 < span class ="admin-label " data-i18n ="submissions "> Submissions</ span >
892898 < span class ="admin-gate-badge " id ="admin-page-gate-badge "> —</ span >
893899 < button class ="btn-admin btn-admin-toggle " id ="btn-admin-page-toggle " onclick ="adminPageToggle() "> …</ button >
894- < button class ="btn-admin btn-admin-kill " onclick ="adminPageKillAll() " data-i18n ="kill_all " > Kill All Jobs </ button >
900+ < button class ="btn-admin btn-admin-kill " onclick ="adminPageKillAll() " data-i18n ="stop_all " > Stop All</ button >
895901 </ div >
896902 < div class ="admin-table-wrap ">
897903 < div class ="admin-table-header ">
@@ -1143,11 +1149,9 @@ <h3 data-i18n="edit_project">Edit Project</h3>
11431149 login_google : 'Continue with Google' ,
11441150 // gate / admin panel
11451151 gate_banner_text : 'Submissions are currently <strong>disabled</strong> by admin. New projects cannot be started.' ,
1146- submissions_disabled : 'Submissions DISABLED — new jobs will be rejected' ,
1147- submissions_enabled : 'Submissions enabled' ,
11481152 enable_submissions : 'Enable Submissions' ,
11491153 disable_submissions : 'Disable Submissions' ,
1150- kill_all : 'Kill All Jobs ' ,
1154+ stop_all : 'Stop All' ,
11511155 // hero
11521156 hero_title : 'Build your next paper with ARK' ,
11531157 attach : 'Attach' , venue : 'Venue' , max_iterations : 'Max iterations' ,
@@ -1256,11 +1260,9 @@ <h3 data-i18n="edit_project">Edit Project</h3>
12561260 login_or : 'أو' ,
12571261 login_google : 'المتابعة عبر Google' ,
12581262 gate_banner_text : 'تم <strong>تعطيل</strong> التقديم من قِبَل المشرف. لا يمكن بدء مشاريع جديدة.' ,
1259- submissions_disabled : 'التقديم معطّل — سيتم رفض المهام الجديدة' ,
1260- submissions_enabled : 'التقديم مفعّل' ,
12611263 enable_submissions : 'تفعيل التقديم' ,
12621264 disable_submissions : 'تعطيل التقديم' ,
1263- kill_all : 'إيقاف جميع المهام ' ,
1265+ stop_all : 'إيقاف الكل ' ,
12641266 hero_title : 'ابنِ ورقتك البحثية القادمة مع ARK' ,
12651267 attach : 'إرفاق' , venue : 'المؤتمر' , max_iterations : 'الحد الأقصى للتكرارات' ,
12661268 telegram_notifications : 'إشعارات Telegram' ,
@@ -1354,11 +1356,9 @@ <h3 data-i18n="edit_project">Edit Project</h3>
13541356 login_or : '或' ,
13551357 login_google : '使用 Google 登录' ,
13561358 gate_banner_text : '管理员已<strong>禁用</strong>提交功能。无法启动新项目。' ,
1357- submissions_disabled : '提交已禁用 — 新任务将被拒绝' ,
1358- submissions_enabled : '提交已启用' ,
13591359 enable_submissions : '启用提交' ,
13601360 disable_submissions : '禁用提交' ,
1361- kill_all : '终止所有任务 ' ,
1361+ stop_all : '全部停止 ' ,
13621362 hero_title : '用 ARK 构建你的下一篇论文' ,
13631363 attach : '附件' , venue : '投稿会议' , max_iterations : '最大迭代次数' ,
13641364 telegram_notifications : 'Telegram 通知' ,
@@ -1442,6 +1442,18 @@ <h3 data-i18n="edit_project">Edit Project</h3>
14421442
14431443let currentLang = localStorage . getItem ( 'ark_lang' ) || 'en' ;
14441444
1445+ /* ── Toast notification ── */
1446+ function showToast ( msg , type ) {
1447+ let c = document . getElementById ( 'ark-toast' ) ;
1448+ if ( ! c ) { c = document . createElement ( 'div' ) ; c . id = 'ark-toast' ; document . body . appendChild ( c ) ; }
1449+ const el = document . createElement ( 'div' ) ;
1450+ el . className = 'ark-toast-item' + ( type === 'warn' ? ' warn' : '' ) ;
1451+ el . textContent = msg ;
1452+ c . appendChild ( el ) ;
1453+ requestAnimationFrame ( ( ) => el . classList . add ( 'show' ) ) ;
1454+ setTimeout ( ( ) => { el . classList . remove ( 'show' ) ; setTimeout ( ( ) => el . remove ( ) , 300 ) ; } , 3000 ) ;
1455+ }
1456+
14451457function t ( key , ...args ) {
14461458 let str = ( TRANSLATIONS [ currentLang ] && TRANSLATIONS [ currentLang ] [ key ] ) || TRANSLATIONS . en [ key ] || key ;
14471459 // Simple %s / %d replacement
@@ -1639,6 +1651,42 @@ <h3 data-i18n="edit_project">Edit Project</h3>
16391651 const input = el . querySelector ( 'input' ) ;
16401652 if ( input ) input . disabled = false ;
16411653 } ) ;
1654+ // Unlock premium models for admin
1655+ document . querySelectorAll ( '.model-option-premium' ) . forEach ( el => {
1656+ el . style . opacity = '' ;
1657+ el . style . cursor = '' ;
1658+ el . title = '' ;
1659+ el . classList . add ( 'model-option-admin' ) ;
1660+ const input = el . querySelector ( 'input' ) ;
1661+ if ( input ) input . disabled = false ;
1662+ } ) ;
1663+ // Unlock iteration limits for admin
1664+ const devIter = document . querySelector ( 'input[name="max_dev_iterations"]' ) ;
1665+ if ( devIter ) { devIter . max = 10 ; devIter . value = 3 ; }
1666+ const revIter = document . querySelector ( 'input[name="max_iterations"]' ) ;
1667+ if ( revIter ) { revIter . max = 5 ; revIter . value = 2 ; }
1668+ } else {
1669+ // Non-admin: show coffee toast when clicking premium models
1670+ document . querySelectorAll ( '.model-option-premium' ) . forEach ( el => {
1671+ el . addEventListener ( 'click' , ( e ) => {
1672+ e . preventDefault ( ) ;
1673+ showToast ( 'Buy Jihao a coffee to enable ☕' , 'warn' ) ;
1674+ } ) ;
1675+ } ) ;
1676+ // Non-admin: show coffee toast when trying to change iterations
1677+ [ 'max_dev_iterations' , 'max_iterations' ] . forEach ( name => {
1678+ const input = document . querySelector ( `input[name="${ name } "]` ) ;
1679+ if ( input ) {
1680+ input . style . cursor = 'pointer' ;
1681+ [ 'click' , 'focus' , 'mousedown' , 'keydown' ] . forEach ( evt => {
1682+ input . addEventListener ( evt , ( e ) => {
1683+ e . preventDefault ( ) ;
1684+ input . blur ( ) ;
1685+ showToast ( 'Buy Jihao a coffee to enable ☕' , 'warn' ) ;
1686+ } ) ;
1687+ } ) ;
1688+ }
1689+ } ) ;
16421690 }
16431691
16441692 // Route based on hash
@@ -1692,23 +1740,8 @@ <h3 data-i18n="edit_project">Edit Project</h3>
16921740}
16931741
16941742function _renderAdminStatus ( ) {
1695- const txt = document . getElementById ( 'admin-status-text' ) ;
16961743 const btn = document . getElementById ( 'btn-admin-toggle' ) ;
1697- if ( _adminDisabled ) {
1698- txt . textContent = t ( 'submissions_disabled' ) ;
1699- txt . className = 'admin-status off' ;
1700- btn . textContent = t ( 'enable_submissions' ) ;
1701- btn . style . background = '#15803d' ;
1702- btn . onmouseover = ( ) => btn . style . background = '#166534' ;
1703- btn . onmouseout = ( ) => btn . style . background = '#15803d' ;
1704- } else {
1705- txt . textContent = t ( 'submissions_enabled' ) ;
1706- txt . className = 'admin-status ok' ;
1707- btn . textContent = t ( 'disable_submissions' ) ;
1708- btn . style . background = '#1e40af' ;
1709- btn . onmouseover = ( ) => btn . style . background = '#1e3a8a' ;
1710- btn . onmouseout = ( ) => btn . style . background = '#1e40af' ;
1711- }
1744+ btn . textContent = _adminDisabled ? t ( 'enable_submissions' ) : t ( 'disable_submissions' ) ;
17121745}
17131746
17141747async function adminToggle ( ) {
0 commit comments