littlefig-bench / fix_ui_mobile.py
ticketguy's picture
Make Little Fig Studio UI fully mobile responsive
1d901b7 verified
#!/usr/bin/env python3
"""Rewrite Little Fig UI to be fully mobile responsive."""
import subprocess, os
TOKEN = "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"
subprocess.run(["git", "clone", f"https://{TOKEN}@github.com/ticketguy/littlefig.git", "/app/littlefig"], check=True)
os.chdir("/app/littlefig")
subprocess.run(["git", "config", "user.name", "0xticketguy"], check=True)
subprocess.run(["git", "config", "user.email", "0xticketguy@harboria.dev"], check=True)
ui_path = "src/little_fig/web/static/index.html"
with open(ui_path, "r") as f:
html = f.read()
# The UI uses Tailwind CSS via CDN. We need to add responsive classes.
# Key changes:
# 1. Sidebar: hidden on mobile, shown on md+ (with hamburger toggle)
# 2. Chat sidebar (history): hidden on mobile
# 3. Touch-friendly tap targets
# 4. Full-width content on mobile
# Replace the sidebar aside β€” add responsive classes
old_sidebar_start = '<aside class="w-56 h-full flex flex-col border-r border-white/5 bg-[#07070a] shrink-0 light:bg-white light:border-zinc-200">'
new_sidebar_start = '<aside id="sidebar" class="fixed inset-y-0 left-0 z-50 w-64 h-full flex flex-col border-r border-white/5 bg-[#07070a] shrink-0 light:bg-white light:border-zinc-200 transform -translate-x-full md:translate-x-0 md:static md:w-56 transition-transform duration-200 ease-in-out">'
html = html.replace(old_sidebar_start, new_sidebar_start)
# Replace main β€” add responsive margin
old_main = '<main class="flex-1 flex flex-col min-w-0 h-full">'
new_main = '<main class="flex-1 flex flex-col min-w-0 h-full w-full">'
html = html.replace(old_main, new_main)
# Replace chat history sidebar β€” hide on mobile
old_chat_sidebar = '<div class="w-52 border-r border-white/5 flex flex-col shrink-0 light:border-zinc-200">'
new_chat_sidebar = '<div class="hidden md:flex w-52 border-r border-white/5 flex-col shrink-0 light:border-zinc-200">'
html = html.replace(old_chat_sidebar, new_chat_sidebar)
# Add hamburger button + overlay AFTER <body> tag
hamburger_html = '''
<!-- Mobile hamburger -->
<button id="menu-btn" onclick="toggleSidebar()" class="md:hidden fixed top-3 left-3 z-[60] p-2 rounded-lg bg-zinc-800/90 border border-white/10 text-zinc-300 backdrop-blur-sm">
<svg class="w-5 h-5" fill="none" stroke="currentColor" stroke-width="2" viewBox="0 0 24 24"><path stroke-linecap="round" d="M4 6h16M4 12h16M4 18h16"/></svg>
</button>
<!-- Mobile overlay -->
<div id="sidebar-overlay" onclick="toggleSidebar()" class="hidden fixed inset-0 z-40 bg-black/50 backdrop-blur-sm md:hidden"></div>
'''
html = html.replace(
'<body class="bg-[#0a0a0c] text-zinc-200 h-screen flex overflow-hidden light:bg-gray-50 light:text-zinc-800">',
'<body class="bg-[#0a0a0c] text-zinc-200 h-screen flex overflow-hidden light:bg-gray-50 light:text-zinc-800">' + hamburger_html
)
# Add toggleSidebar function and responsive CSS before </script> closing
toggle_js = '''
// ── Mobile sidebar toggle ────────────────────────────────────────────────────
function toggleSidebar(){
const sb=document.getElementById('sidebar');
const ov=document.getElementById('sidebar-overlay');
const open=sb.classList.contains('-translate-x-full');
if(open){sb.classList.remove('-translate-x-full');sb.classList.add('translate-x-0');ov.classList.remove('hidden')}
else{sb.classList.add('-translate-x-full');sb.classList.remove('translate-x-0');ov.classList.add('hidden')}
}
// Close sidebar when nav item clicked on mobile
document.querySelectorAll('.sidebar-item').forEach(el=>{el.addEventListener('click',()=>{
if(window.innerWidth<768){toggleSidebar()}
})});
'''
# Insert before the last </script>
html = html.replace('// ── Init ─', toggle_js + '\n// ── Init ─')
# Add responsive CSS to the <style> block
responsive_css = '''
/* Mobile responsive */
@media(max-width:767px){
.sidebar-item{padding:12px 16px;font-size:14px}
.btn{padding:10px 18px;font-size:13px}
.btn-sm{padding:7px 12px;font-size:12px}
.input{padding:11px 14px;font-size:14px}
#pg-chat .h-11{padding-left:48px}
.card{padding:14px}
}
'''
html = html.replace('footer{display:none!important}', 'footer{display:none!important}\n' + responsive_css)
with open(ui_path, "w") as f:
f.write(html)
subprocess.run(["git", "add", "-A"], check=True)
subprocess.run(["git", "commit", "-m",
"Make UI fully mobile responsive\n\n"
"- Sidebar: slides in/out on mobile (hamburger menu toggle)\n"
"- Overlay: dark backdrop when sidebar is open on mobile\n"
"- Chat history: hidden on mobile (full width for chat)\n"
"- Touch targets: larger padding on buttons/inputs for fingers\n"
"- Header: offset for hamburger button on mobile\n"
"- Sidebar auto-closes on nav item tap (mobile)\n"
"- Uses Tailwind responsive prefixes (md:) + CSS media queries\n"
"- No layout changes on desktop β€” only mobile gets new behavior"],
check=True)
subprocess.run(["git", "push", "origin", "main"], check=True)
print("βœ… UI is now mobile responsive!")