This commit is contained in:
2026-05-09 16:27:40 -04:00
parent 86f558c65f
commit 3caf207129
31 changed files with 2727 additions and 1597 deletions
+80
View File
@@ -0,0 +1,80 @@
// browsing.jsx — Main browsing page (real webpage open)
const BrowsingScreen = () => (
<ElyShell wallpaper="dawn" sidebarProps={{ activeId:'figma', mode:'browse', tabs:[
{ id:'figma', label:'Style Guide · Figma', icon:<Brand.Figma s={16}/>, active:true, audio:true, closable:true },
{ id:'roadmap', label:'Roadmap 2024 — Linear', icon:<Brand.Linear s={16}/> },
{ id:'mkt', label:'Marketing Site', icon:<Icon size={16} stroke="#6b6660"><circle cx="12" cy="12" r="9"/><path d="M3 12h18M12 3a14 14 0 0 1 0 18"/></Icon> },
{ id:'twt', label:'Home / X', icon:<Brand.X s={16}/> },
{ id:'gh', label:'elybrowser/core · main', icon:<Brand.GitHub s={16}/> },
] }}>
<TopBar host="figma.com" path="/file/12345/Style-Guide" canBack canForward/>
<div className="ely-scroll" style={{flex:1, overflowY:'auto', background:'#fff'}}>
{/* Mock figma-ish UI inside */}
<div style={{height:46, background:'#1d1c1a', color:'#cfcbc4', display:'flex', alignItems:'center', padding:'0 14px', fontSize:12, gap:10}}>
<div style={{display:'flex',alignItems:'center',gap:6}}><Brand.Figma s={14}/><span style={{color:'#fff', fontWeight:500}}>Style Guide</span></div>
<span style={{opacity:.55}}>/</span>
<span>ELY Design System</span>
<span style={{marginLeft:'auto', display:'flex', gap:8, alignItems:'center'}}>
<span style={{padding:'2px 8px', background:'#fff', color:'#1d1c1a', borderRadius:4, fontSize:11, fontWeight:500}}>Share</span>
<div style={{width:22,height:22,borderRadius:'50%',background:'linear-gradient(135deg,#7c6cf7,#ec6a8e)'}}/>
<div style={{width:22,height:22,borderRadius:'50%',background:'linear-gradient(135deg,#4fb59a,#7c6cf7)'}}/>
</span>
</div>
<div style={{display:'grid', gridTemplateColumns:'220px 1fr 260px', height:'calc(100% - 46px)', minHeight:560, background:'#f5f4f1'}}>
<div style={{background:'#fff', borderRight:'1px solid #ebe7e0', padding:'10px 8px', fontSize:11.5, color:'#3a3733'}}>
<div style={{padding:'4px 6px', fontWeight:600, color:'#1d1c1a'}}>Pages</div>
{['Cover','Tokens','Typography','Color','Spacing','Components','Patterns','Sandbox'].map((p,i)=>(
<div key={p} style={{padding:'5px 8px', borderRadius:5, background: i===2?'#f0e9e2':'transparent', color: i===2?'#1d1c1a':'#3a3733', display:'flex',alignItems:'center',gap:6}}>
<I.ChevronRight size={10} style={{opacity:.6}}/> {p}
</div>
))}
<div style={{padding:'10px 6px 4px', fontWeight:600, color:'#1d1c1a', marginTop:8}}>Layers</div>
{[['Frame · Display','◇'],[' H1 / Display','T'],[' H2 / Title','T'],[' H3 / Subtitle','T'],['Frame · Body','◇'],[' Paragraph','T'],[' Caption','T']].map(([n,g],i)=>(
<div key={i} style={{padding:'4px 6px', fontFamily:'monospace', fontSize:10.5, color:'#6b6660', whiteSpace:'pre'}}>{g} {n}</div>
))}
</div>
<div style={{padding:32, position:'relative', overflow:'hidden'}}>
<div style={{position:'absolute', inset:0, backgroundImage:'radial-gradient(circle at 1px 1px, rgba(0,0,0,0.06) 1px, transparent 0)', backgroundSize:'18px 18px'}}/>
<div style={{position:'relative', background:'#fff', borderRadius:6, padding:'32px 40px', boxShadow:'0 1px 0 rgba(0,0,0,0.06), 0 12px 40px -10px rgba(0,0,0,0.12)', maxWidth:520}}>
<div style={{fontSize:10.5, color:'#9a948c', letterSpacing:'0.12em', textTransform:'uppercase'}}>Display / Serif</div>
<div className="ely-serif" style={{fontSize:48, lineHeight:1.05, marginTop:8, color:'#1d1c1a'}}>The aesthetics<br/>of calm tech.</div>
<div style={{marginTop:24, display:'grid', gridTemplateColumns:'1fr 1fr', gap:14}}>
{['H1 / 64','H2 / 40','H3 / 28','Body / 16','Caption / 12','Mono / 13'].map((s,i)=>(
<div key={i} style={{borderTop:'1px solid #ebe7e0', paddingTop:8}}>
<div className={i<3?'ely-serif':''} style={{fontSize: i<3? 18: 13, color:'#1d1c1a', fontFamily: i===5?'monospace':undefined}}>The quick brown fox</div>
<div style={{fontSize:10.5, color:'#9a948c', marginTop:2}}>{s}</div>
</div>
))}
</div>
</div>
<div style={{position:'absolute', bottom:14, left:14, display:'flex', gap:6, padding:'6px 10px', background:'#fff', borderRadius:6, boxShadow:'0 1px 4px rgba(0,0,0,0.08)', fontSize:11, color:'#3a3733'}}>
100% <I.ChevronDown size={10}/>
</div>
</div>
<div style={{background:'#fff', borderLeft:'1px solid #ebe7e0', padding:'12px 12px', fontSize:11.5, color:'#3a3733'}}>
<div style={{display:'flex', gap:14, fontWeight:500, color:'#1d1c1a', borderBottom:'1px solid #ebe7e0', paddingBottom:8}}>
<span style={{borderBottom:'1.5px solid #1d1c1a', paddingBottom:6}}>Design</span>
<span style={{color:'#9a948c'}}>Prototype</span>
<span style={{color:'#9a948c'}}>Inspect</span>
</div>
<div style={{paddingTop:10, color:'#9a948c'}}>Color · Local styles</div>
<div style={{display:'grid', gridTemplateColumns:'repeat(6, 1fr)', gap:6, marginTop:8}}>
{['#1d1c1a','#3a3733','#6b6660','#c96442','#ec6a8e','#7c6cf7','#4fb59a','#f6f4ef','#efe8e1','#fff3ee','#ffd1d8','#b9c7ff'].map(c=>(
<div key={c} style={{aspectRatio:'1', borderRadius:4, background:c, boxShadow:'inset 0 0 0 1px rgba(0,0,0,0.05)'}}/>
))}
</div>
<div style={{paddingTop:14, color:'#9a948c'}}>Type · Newsreader / Geist</div>
<div style={{padding:8, background:'#f6f4ef', borderRadius:6, marginTop:8, fontSize:11}}>
<div className="ely-serif" style={{fontSize:18}}>Aa Bb Cc</div>
<div style={{color:'#6b6660', marginTop:2}}>Newsreader · 6..72</div>
</div>
<div style={{paddingTop:14, color:'#9a948c'}}>Spacing</div>
<div style={{display:'flex', gap:4, marginTop:6}}>
{[4,8,12,16,24,32].map(s=>(<div key={s} style={{width:s, height:18, background:'#1d1c1a', opacity:.85}}/>))}
</div>
</div>
</div>
</div>
</ElyShell>
);
window.BrowsingScreen = BrowsingScreen;
+91
View File
@@ -0,0 +1,91 @@
// command.jsx — Command Bar / Quick Switcher (overlaid on home)
const CommandScreen = () => (
<ElyShell wallpaper="dawn" sidebarProps={{ activeId:'home', mode:'home' }}>
<TopBar url="Search ELY or type a command…"/>
<div style={{flex:1, position:'relative', overflow:'hidden'}}>
{/* dimmed home behind */}
<div style={{position:'absolute', inset:0, padding:'48px 64px', opacity:0.35, filter:'blur(4px) saturate(0.9)', pointerEvents:'none'}}>
<div style={{textAlign:'center'}}>
<div className="ely-serif" style={{fontSize:64, lineHeight:1.05, fontWeight:400, color:'var(--ely-ink)'}}>Where focus finds flow.</div>
</div>
</div>
<div style={{position:'absolute', inset:0, background:'rgba(20,15,10,0.18)', backdropFilter:'blur(6px)'}}/>
{/* command panel */}
<div style={{position:'absolute', top:80, left:'50%', transform:'translateX(-50%)', width:640, background:'rgba(255,255,255,0.86)', backdropFilter:'blur(40px) saturate(160%)', borderRadius:16, boxShadow:'0 30px 80px -20px rgba(40,30,20,0.45), 0 0 0 1px rgba(255,255,255,0.6) inset, 0 1px 0 rgba(255,255,255,0.8) inset', overflow:'hidden'}}>
<div style={{display:'flex', alignItems:'center', gap:12, padding:'16px 18px', borderBottom:'1px solid var(--ely-divider)'}}>
<I.Search size={18}/>
<div style={{fontSize:16, color:'var(--ely-ink)', flex:1}}>
roa<span style={{display:'inline-block', width:1, height:18, background:'var(--ely-accent)', verticalAlign:'middle', marginLeft:1, animation:'blink 1s infinite'}}/>
</div>
<span style={{padding:'2px 8px', borderRadius:6, background:'rgba(40,30,20,0.06)', fontSize:10.5, color:'var(--ely-ink-3)'}}>Switcher</span>
<span className="ely-mono" style={{fontSize:10.5, color:'var(--ely-ink-4)'}}>esc</span>
</div>
<div style={{maxHeight:440, overflowY:'auto'}}>
{/* Section: Open tabs */}
<CmdSection label="Open tabs">
<CmdRow icon={<Brand.Figma s={16}/>} title="Style Guide — Figma" hint="figma.com" right="⌘1" />
<CmdRow active icon={<Brand.Linear s={16}/>} title="Roadmap 2024 — Linear" hint="linear.app · 6 issues open" right="⌘2 · ↵" />
<CmdRow icon={<div style={{width:16,height:16, borderRadius:4, background:'linear-gradient(135deg,#7c6cf7,#ec6a8e)'}}/>} title="ELY Roadmap doc — Notion" hint="notion.so" right="⌘3" />
</CmdSection>
<CmdSection label="History">
<CmdRow icon={<Icon size={14}><circle cx="12" cy="12" r="9"/><path d="M3 12h18M12 3a14 14 0 0 1 0 18"/></Icon>} title="Roadmap.app · 2024 update" hint="roadmap.app · 1d ago" />
<CmdRow icon={<Brand.GitHub s={14}/>} title="elybrowser/core · roadmap.md" hint="github.com · 3d ago" />
</CmdSection>
<CmdSection label="Bookmarks">
<CmdRow icon={<I.Bookmark size={14}/>} title="Roadmap planning template" hint="Pinned · Work" />
</CmdSection>
<CmdSection label="Actions">
<CmdRow icon={<I.Layers size={14}/>} title="Switch workspace" hint="Work · Personal · Studio" right="⌘⇧W" />
<CmdRow icon={<I.Split size={14}/>} title="Open in split view" hint="Beside current tab" right="⌘D" />
<CmdRow icon={<I.Settings size={14}/>} title="Open Settings" hint="Appearance, Sync, Plugins…" right="⌘," />
</CmdSection>
<CmdSection label="Ask ELY">
<CmdRow ai icon={<I.Sparkle size={14}/>} title='Ask: "What did we ship in the last roadmap cycle?"' hint="Searches recent tabs, history & docs" right="⌘↵"/>
</CmdSection>
</div>
<div style={{display:'flex', alignItems:'center', gap:14, padding:'10px 16px', borderTop:'1px solid var(--ely-divider)', fontSize:10.5, color:'var(--ely-ink-3)', background:'rgba(255,255,255,0.55)'}}>
<span style={{display:'inline-flex', alignItems:'center', gap:4}}><Kbd></Kbd><Kbd></Kbd> navigate</span>
<span style={{display:'inline-flex', alignItems:'center', gap:4}}><Kbd></Kbd> open</span>
<span style={{display:'inline-flex', alignItems:'center', gap:4}}><Kbd></Kbd> open in split</span>
<span style={{display:'inline-flex', alignItems:'center', gap:4}}><Kbd></Kbd> filter</span>
<span style={{marginLeft:'auto', display:'inline-flex', alignItems:'center', gap:6}}>
<I.Sparkle size={11}/> Powered by ELY
</span>
</div>
</div>
</div>
<style>{`@keyframes blink {0%,49%{opacity:1}50%,100%{opacity:0}}`}</style>
</ElyShell>
);
const Kbd = ({ children }) => (
<span className="ely-mono" style={{padding:'1px 5px', minWidth:14, textAlign:'center', borderRadius:4, background:'rgba(255,255,255,0.85)', boxShadow:'0 0 0 1px var(--ely-stroke), 0 1px 0 rgba(40,30,20,0.05)', fontSize:10}}>{children}</span>
);
const CmdSection = ({ label, children }) => (
<div style={{padding:'8px 0 4px'}}>
<div style={{padding:'6px 16px 4px', fontSize:10, color:'var(--ely-ink-4)', textTransform:'uppercase', letterSpacing:'0.1em', fontWeight:500}}>{label}</div>
{children}
</div>
);
const CmdRow = ({ icon, title, hint, right, active, ai }) => (
<div style={{display:'flex', alignItems:'center', gap:12, padding:'8px 16px', background: active?'rgba(201,100,66,0.08)': 'transparent', position:'relative'}}>
{active && <div style={{position:'absolute', left:0, top:6, bottom:6, width:2, borderRadius:2, background:'var(--ely-accent)'}}/>}
<div style={{width:24, height:24, borderRadius:6, background: ai?'linear-gradient(135deg,#ffd1d8,#b9c7ff)':'rgba(255,255,255,0.85)', boxShadow:'var(--ely-shadow-soft)', display:'flex',alignItems:'center',justifyContent:'center', color: ai?'#c96442':'var(--ely-ink-2)'}}>{icon}</div>
<div style={{flex:1, minWidth:0}}>
<div style={{fontSize:13, fontWeight: active?500:450, color:'var(--ely-ink)'}}>{title}</div>
{hint && <div style={{fontSize:11, color:'var(--ely-ink-4)', marginTop:1}}>{hint}</div>}
</div>
{right && <span className="ely-mono" style={{fontSize:10.5, color:'var(--ely-ink-3)'}}>{right}</span>}
</div>
);
window.CommandScreen = CommandScreen;
+118
View File
@@ -0,0 +1,118 @@
// home.jsx — Home / New Tab
const HomeScreen = () => (
<ElyShell wallpaper="dawn" sidebarProps={{ activeId:'home', mode:'home' }}>
<TopBar url="Search ELY or type a command…"/>
<div className="ely-scroll" style={{flex:1, overflowY:'auto', padding:'48px 64px 28px'}}>
<div style={{textAlign:'center', maxWidth: 880, margin:'0 auto'}}>
<div style={{display:'inline-flex', alignItems:'center', gap:8, color:'var(--ely-ink-3)', fontSize:13, marginBottom:14}}>
<span style={{color:'#e89a6e'}}><I.Sunrise size={16}/></span>
Good morning, Alex
</div>
<h1 className="ely-serif" style={{fontSize: 64, lineHeight: 1.05, margin:'0 0 28px', fontWeight:400, letterSpacing:'-0.02em', color:'var(--ely-ink)'}}>
Where focus finds flow.
</h1>
<div style={{position:'relative', maxWidth: 640, margin:'0 auto'}}>
<div style={{height:54, background:'rgba(255,255,255,0.85)', borderRadius:14, boxShadow:'var(--ely-shadow-card)', display:'flex', alignItems:'center', padding:'0 16px', gap:12}}>
<I.Search size={16}/>
<span style={{color:'var(--ely-ink-4)', fontSize:14, flex:1, textAlign:'left'}}>Search the web or ELY</span>
<button className="ely-iconbtn" style={{background:'rgba(40,30,20,0.04)'}}><I.ArrowRight size={14}/></button>
</div>
</div>
<div style={{display:'flex', justifyContent:'center', gap:8, marginTop:14}}>
{[['Search Tabs', <I.Search size={12}/>], ['Switch Workspace', <I.Layers size={12}/>], ['Open Notion', <Brand.Notion s={12}/>]].map(([t,i],idx)=>(
<span key={idx} style={{display:'inline-flex',alignItems:'center',gap:6, padding:'6px 12px', borderRadius:999, background:'rgba(255,255,255,0.55)', boxShadow:'var(--ely-shadow-soft)', fontSize:12, color:'var(--ely-ink-2)'}}>
{i}{t}
</span>
))}
</div>
</div>
{/* favorites */}
<div style={{marginTop:48}}>
<div style={{display:'flex', alignItems:'center', gap:6, color:'var(--ely-ink-3)', fontSize:12.5, marginBottom:12, fontWeight:500}}>
Favorites <I.ChevronDown size={12}/>
</div>
<div style={{display:'grid', gridTemplateColumns:'repeat(7, 1fr)', gap:10}}>
{[
[<Brand.Notion s={28}/>, 'Notion'],
[<Brand.YT s={28}/>, 'YouTube'],
[<Brand.Dribbble s={28}/>, 'Dribbble'],
[<Brand.X s={28}/>, 'X'],
[<Brand.Vercel s={28}/>, 'Vercel'],
[<Brand.Behance s={28}/>, 'Behance'],
].map(([g,n], i)=>(
<div key={i} className="ely-card" style={{height:96, display:'flex', flexDirection:'column', alignItems:'center', justifyContent:'center', gap:8}}>
{g}
<div style={{fontSize:11.5, color:'var(--ely-ink-3)'}}>{n}</div>
</div>
))}
<div className="ely-card" style={{height:96, display:'flex', alignItems:'center', justifyContent:'center', color:'var(--ely-ink-4)', background:'rgba(255,255,255,0.5)'}}>
<I.Plus size={18}/>
</div>
</div>
</div>
{/* lower row */}
<div style={{display:'grid', gridTemplateColumns:'1.6fr 1fr', gap:12, marginTop:16}}>
<div className="ely-card" style={{padding:16, display:'grid', gridTemplateColumns:'1fr 240px', gap:16}}>
<div>
<div style={{fontSize:13, fontWeight:500, marginBottom:14}}>Continue where you left off</div>
<div style={{display:'flex', flexDirection:'column', gap:10}}>
{[
[<Brand.Figma s={26}/>, 'Design System Figma', 'figma.com', '2 min ago'],
[<div style={{width:26,height:26,borderRadius:7,background:'linear-gradient(135deg,#7c6cf7,#1d1c1a)'}}/>, 'Roadmap 2024', 'linear.app', '1 hour ago'],
[<Icon size={26}><circle cx="12" cy="12" r="9" stroke="#6b6660" strokeWidth="1.4" fill="none"/><path d="M3 12h18M12 3a14 14 0 0 1 0 18M12 3a14 14 0 0 0 0 18" stroke="#6b6660" strokeWidth="1.4" fill="none"/></Icon>, 'Marketing Site', 'elybrowser.com', '3 hours ago'],
].map(([icon, name, host, when], i)=>(
<div key={i} style={{display:'flex', alignItems:'center', gap:12, padding:'4px 0'}}>
{icon}
<div style={{flex:1, minWidth:0}}>
<div style={{fontSize:13, fontWeight:500, color:'var(--ely-ink)'}}>{name}</div>
<div style={{fontSize:11.5, color:'var(--ely-ink-4)'}}>{host} · {when}</div>
</div>
</div>
))}
</div>
</div>
<div style={{position:'relative', borderRadius:12, overflow:'hidden', background:'linear-gradient(135deg,#dcc4b6,#9aa5c4)', minHeight:200}}>
<div style={{position:'absolute', inset:0, background:`
radial-gradient(60% 40% at 50% 30%, rgba(255,200,210,0.7), transparent),
radial-gradient(80% 60% at 30% 80%, rgba(120,140,180,0.6), transparent)
`}}/>
<div style={{position:'absolute', top:8, right:8, background:'rgba(0,0,0,0.35)', backdropFilter:'blur(8px)', color:'#fff', padding:'4px 10px', borderRadius:999, fontSize:10.5, display:'flex', alignItems:'center', gap:6}}>
Reading List <span style={{opacity:.6}}>·</span> 5
</div>
<div style={{position:'absolute', bottom:0, left:0, right:0, padding:14, color:'#fff', textShadow:'0 1px 8px rgba(0,0,0,0.4)'}}>
<div className="ely-serif" style={{fontSize:18, lineHeight:1.15, fontWeight:500}}>The aesthetics of<br/>calm technology</div>
<div style={{fontSize:11, opacity:.85, marginTop:6}}>Inside ELY Journal · 6 min read</div>
</div>
</div>
</div>
<div className="ely-card" style={{padding:16}}>
<div style={{fontSize:13, fontWeight:500, marginBottom:12}}>Recent activity</div>
<div style={{display:'flex', flexDirection:'column', gap:12}}>
{[
['viewed', 'Pricing Page', 'elybrowser.com/pricing', '2m', <Icon size={14}><circle cx="12" cy="12" r="9"/><path d="M3 12h18"/></Icon>],
['opened', 'Style Guide', 'figma.com/file/12345', '1h', <Brand.Figma s={14}/>],
['commented on', 'Roadmap 2024', 'linear.app/roadmap', '3h', <Brand.Linear s={14}/>],
].map(([verb, name, url, when, ic], i)=>(
<div key={i} style={{display:'flex', alignItems:'flex-start', gap:10}}>
<div style={{width:24, height:24, borderRadius:6, background:'rgba(255,255,255,0.8)', boxShadow:'var(--ely-shadow-soft)', display:'flex',alignItems:'center',justifyContent:'center'}}>{ic}</div>
<div style={{flex:1, minWidth:0}}>
<div style={{fontSize:11.5, color:'var(--ely-ink-3)'}}>You {verb}</div>
<div style={{fontSize:13, fontWeight:500}}>{name}</div>
<div style={{fontSize:10.5, color:'var(--ely-ink-4)', marginTop:1}}>{url}</div>
</div>
<div style={{fontSize:10.5, color:'var(--ely-ink-4)'}}>{when}</div>
</div>
))}
</div>
<div style={{marginTop:14, paddingTop:10, borderTop:'1px solid var(--ely-divider)', fontSize:11.5, color:'var(--ely-ink-3)', display:'inline-flex', alignItems:'center', gap:4}}>
View all history <I.ArrowRight size={11}/>
</div>
</div>
</div>
</div>
</ElyShell>
);
window.HomeScreen = HomeScreen;
+159
View File
@@ -0,0 +1,159 @@
// plugins.jsx — Plugin Marketplace
const PluginsScreen = () => {
const cats = ['All', 'Productivity', 'Reading', 'Privacy', 'Developer', 'AI', 'Writing', 'Design'];
const plugins = [
{ name:'Reader+', author:'ELY Studio', desc:'Distraction-free reading mode with serif typography & ambient backgrounds.', accent:'linear-gradient(135deg,#ffd1d8,#b9c7ff)', glyph:'¶', installs:'24.5k', rating:4.9, tags:['Featured','Reading'] },
{ name:'Tab Capsules', author:'orbit.dev', desc:'Hibernate tabs into searchable capsules. Restore in one click — even months later.', accent:'linear-gradient(135deg,#c5f0db,#7c6cf7)', glyph:'◐', installs:'18.2k', rating:4.8, tags:['Productivity'] },
{ name:'Coast Privacy Shield', author:'Coast Labs', desc:'Per-site tracker counts and one-tap container tabs.', accent:'linear-gradient(135deg,#1d1c1a,#7c6cf7)', glyph:'◊', dark:true, installs:'31.0k', rating:4.7, tags:['Privacy'] },
{ name:'Quill', author:'paperhouse', desc:'Annotate any page. Notes sync to Notion, Obsidian, Bear.', accent:'linear-gradient(135deg,#fff3ee,#f4c8b8)', glyph:'✎', installs:'12.4k', rating:4.6, tags:['Writing'] },
{ name:'ELY AI · Summon', author:'ELY Studio', desc:'Ask anything about the page. Beautiful inline citations.', accent:'linear-gradient(135deg,#d6c4ff,#ffd1d8)', glyph:'✦', installs:'47.3k', rating:4.9, tags:['AI','Featured'] },
{ name:'Pomodoro Glass', author:'flux.app', desc:'Ambient timer that lives in your sidebar. Subtle, focused.', accent:'linear-gradient(135deg,#ffe5b8,#ec6a8e)', glyph:'◷', installs:'9.1k', rating:4.5, tags:['Productivity'] },
{ name:'Localhost Console', author:'devhabit', desc:'Inline preview & logs for any dev port. Toggle from omnibar.', accent:'linear-gradient(135deg,#0e0d0c,#4fb59a)', glyph:'_', dark:true, installs:'7.6k', rating:4.7, tags:['Developer'] },
{ name:'Lookbook', author:'studio.bento', desc:'Collect screenshots & swatches as you browse. Boards live in ELY.', accent:'linear-gradient(135deg,#ec6a8e,#7c6cf7)', glyph:'▥', installs:'14.0k', rating:4.8, tags:['Design'] },
];
return (
<ElyShell wallpaper="mint" sidebarProps={{ activeId:'plugins' }}>
<div className="ely-topbar">
<button className="ely-iconbtn"><I.ArrowLeft size={16}/></button>
<button className="ely-iconbtn"><I.ArrowRight size={16}/></button>
<div className="ely-omnibar"><I.Plug size={14}/><span className="url-host">ely://plugins</span><span className="url-path">/marketplace</span><span className="right"><I.Filters size={14}/></span></div>
<button className="ely-iconbtn is-on"><I.Plug size={15}/></button>
<button className="ely-iconbtn"><I.Moon size={16}/></button>
<button className="ely-iconbtn"><I.Menu size={16}/></button>
</div>
<div className="ely-scroll" style={{flex:1, overflowY:'auto'}}>
{/* Hero */}
<div style={{padding:'40px 56px 24px', display:'grid', gridTemplateColumns:'1.4fr 1fr', gap:28, alignItems:'end'}}>
<div>
<div style={{fontSize:11, color:'var(--ely-ink-4)', textTransform:'uppercase', letterSpacing:'0.1em'}}>Plugins · Native to ELY</div>
<h1 className="ely-serif" style={{fontSize:48, lineHeight:1.05, margin:'6px 0 10px', fontWeight:400, letterSpacing:'-0.02em'}}>Quiet tools.<br/>Everyday magic.</h1>
<div style={{fontSize:13.5, color:'var(--ely-ink-2)', maxWidth:520, lineHeight:1.55}}>A small, curated marketplace built for ELY sandboxed, theme-aware, no Chrome extension framework required. Each plugin ships with its own tweakable controls in your sidebar.</div>
<div style={{marginTop:18, height:42, padding:'0 16px', borderRadius:12, background:'rgba(255,255,255,0.85)', boxShadow:'var(--ely-shadow-card)', display:'flex', alignItems:'center', gap:10, maxWidth:480}}>
<I.Search size={14}/>
<span style={{fontSize:13, color:'var(--ely-ink-4)', flex:1}}>Search 184 plugins</span>
<span className="ely-mono" style={{fontSize:10.5, color:'var(--ely-ink-4)'}}>K</span>
</div>
</div>
<div className="ely-card" style={{padding:18, background:'linear-gradient(135deg, rgba(255,255,255,0.9), rgba(214,196,255,0.55))'}}>
<div style={{fontSize:11, color:'var(--ely-ink-3)', textTransform:'uppercase', letterSpacing:'0.1em', display:'flex',alignItems:'center', gap:6}}><I.Sparkle size={11}/> Editor's pick</div>
<div style={{display:'flex', alignItems:'flex-start', gap:14, marginTop:12}}>
<div style={{width:56, height:56, borderRadius:14, background:'linear-gradient(135deg,#d6c4ff,#ffd1d8)', display:'flex',alignItems:'center',justifyContent:'center', fontSize:28, color:'#fff'}}>✦</div>
<div style={{flex:1}}>
<div style={{fontSize:15, fontWeight:600}}>ELY AI · Summon</div>
<div style={{fontSize:11.5, color:'var(--ely-ink-4)'}}>by ELY Studio · 47.3k installs</div>
<div style={{fontSize:12.5, color:'var(--ely-ink-2)', marginTop:6, lineHeight:1.4}}>Ask anything about the current page with citations.</div>
</div>
</div>
<div style={{display:'flex', alignItems:'center', gap:8, marginTop:12}}>
<span style={{padding:'7px 14px', borderRadius:8, background:'var(--ely-ink)', color:'#fff', fontSize:12, fontWeight:500}}>Install</span>
<span style={{padding:'7px 14px', borderRadius:8, background:'rgba(255,255,255,0.7)', boxShadow:'var(--ely-shadow-soft)', fontSize:12, fontWeight:500}}>Open detail</span>
<span style={{marginLeft:'auto', fontSize:11.5, color:'var(--ely-ink-3)'}}>⭐︎ 4.9 · 1,241 reviews</span>
</div>
</div>
</div>
{/* Cats */}
<div style={{padding:'4px 56px 18px', display:'flex', gap:6, flexWrap:'wrap'}}>
{cats.map((c,i)=>(
<span key={c} style={{padding:'6px 12px', borderRadius:999, fontSize:12, background: i===0?'var(--ely-ink)':'rgba(255,255,255,0.7)', color: i===0?'#fff':'var(--ely-ink-2)', boxShadow:i===0?'none':'var(--ely-shadow-soft)', fontWeight:500}}>{c}</span>
))}
<span style={{marginLeft:'auto', fontSize:11.5, color:'var(--ely-ink-3)', display:'inline-flex', alignItems:'center', gap:6}}>Sort: Most installed <I.ChevronDown size={11}/></span>
</div>
{/* Plugin grid */}
<div style={{padding:'0 56px 28px', display:'grid', gridTemplateColumns:'repeat(4, 1fr)', gap:14}}>
{plugins.map((p,i)=>(
<div key={i} className="ely-card" style={{padding:14, display:'flex', flexDirection:'column', gap:10}}>
<div style={{aspectRatio:'5/3', borderRadius:10, background:p.accent, display:'flex',alignItems:'center',justifyContent:'center', fontSize:36, color: p.dark?'rgba(255,255,255,0.9)':'rgba(255,255,255,0.95)', position:'relative', overflow:'hidden'}}>
<div style={{position:'absolute', inset:0, background:'radial-gradient(60% 50% at 30% 20%, rgba(255,255,255,0.4), transparent 70%)'}}/>
<span style={{position:'relative', textShadow:'0 2px 14px rgba(0,0,0,0.2)'}}>{p.glyph}</span>
{p.tags.includes('Featured') && <span style={{position:'absolute', top:8, left:8, padding:'2px 8px', borderRadius:999, background:'rgba(255,255,255,0.95)', color:'var(--ely-ink)', fontSize:9.5, fontWeight:600, letterSpacing:'0.04em'}}>FEATURED</span>}
</div>
<div style={{display:'flex',alignItems:'flex-start',gap:8}}>
<div style={{flex:1, minWidth:0}}>
<div style={{fontSize:13.5, fontWeight:600}}>{p.name}</div>
<div style={{fontSize:11, color:'var(--ely-ink-4)'}}>{p.author}</div>
</div>
<span style={{padding:'3px 9px', borderRadius:6, background:'rgba(40,30,20,0.05)', fontSize:11, fontWeight:500, color:'var(--ely-ink-2)'}}>Get</span>
</div>
<div style={{fontSize:12, color:'var(--ely-ink-3)', lineHeight:1.45, height: 50, overflow:'hidden'}}>{p.desc}</div>
<div style={{display:'flex', alignItems:'center', gap:8, fontSize:10.5, color:'var(--ely-ink-4)', borderTop:'1px solid var(--ely-divider)', paddingTop:8, marginTop:'auto'}}>
<span>★ {p.rating}</span>
<span>·</span>
<span>{p.installs} installs</span>
<span style={{marginLeft:'auto', display:'inline-flex',alignItems:'center', gap:3, color:'#2f7d68'}}><I.Shield size={10}/> Sandboxed</span>
</div>
</div>
))}
</div>
{/* Plugin detail (preview / featured below) */}
<div style={{padding:'10px 56px 40px'}}>
<div className="ely-card" style={{padding:24, display:'grid', gridTemplateColumns:'320px 1fr', gap:24}}>
<div>
<div style={{aspectRatio:'4/3', borderRadius:14, background:'linear-gradient(135deg,#ffd1d8,#b9c7ff)', display:'flex',alignItems:'center',justifyContent:'center', fontSize:80, color:'#fff', textShadow:'0 4px 20px rgba(0,0,0,0.15)'}}>¶</div>
<div style={{display:'flex', alignItems:'center', gap:10, marginTop:14}}>
<span style={{flex:1, height:40, background:'var(--ely-ink)', color:'#fff', borderRadius:10, display:'inline-flex',alignItems:'center',justifyContent:'center', fontSize:13, fontWeight:500, gap:6}}><I.Download size={13}/> Install · Free</span>
<span style={{width:40, height:40, background:'rgba(255,255,255,0.85)', boxShadow:'var(--ely-shadow-soft)', borderRadius:10, display:'inline-flex',alignItems:'center',justifyContent:'center'}}><I.Heart size={14}/></span>
</div>
<div style={{marginTop:16, fontSize:11, color:'var(--ely-ink-3)', textTransform:'uppercase', letterSpacing:'0.1em'}}>Permissions</div>
<div style={{marginTop:8, display:'flex', flexDirection:'column', gap:6, fontSize:12}}>
{[['Read content of pages you choose',''],['Store reading preferences locally',''],['Access network',' '],['Read browsing history',' ']].map(([t,c],i)=>(
<div key={i} style={{display:'flex',alignItems:'center', gap:8, color: c===''?'var(--ely-ink-2)':'var(--ely-ink-4)'}}>
<span style={{width:14, height:14, borderRadius:4, background: c===''?'#e8f3ee':'rgba(40,30,20,0.05)', color:'#2f7d68', display:'inline-flex',alignItems:'center',justifyContent:'center', fontSize:10}}>{c}</span>
{t}
</div>
))}
</div>
</div>
<div>
<div style={{display:'flex', alignItems:'flex-start', gap:14}}>
<div style={{flex:1}}>
<div style={{fontSize:11, color:'var(--ely-ink-4)', textTransform:'uppercase', letterSpacing:'0.1em'}}>Reading · Featured</div>
<h2 className="ely-serif" style={{fontSize:32, fontWeight:400, margin:'4px 0 4px', letterSpacing:'-0.02em'}}>Reader+</h2>
<div style={{fontSize:12.5, color:'var(--ely-ink-3)'}}>by ELY Studio · v2.4 · updated 3 days ago</div>
</div>
<div style={{textAlign:'right'}}>
<div style={{fontSize:18, fontWeight:600}}>★ 4.9</div>
<div style={{fontSize:10.5, color:'var(--ely-ink-4)'}}>1,894 reviews</div>
</div>
</div>
<p style={{fontSize:13.5, color:'var(--ely-ink-2)', lineHeight:1.6, marginTop:14}}>Reader+ pulls the article out of the noise. A serif type system, gentle ambient backgrounds, and a focus mode that quietly hides everything you don't need. Built native to ELY's plugin runtime — themes follow your wallpaper, settings live in the sidebar.</p>
<div style={{display:'grid', gridTemplateColumns:'repeat(4, 1fr)', gap:8, marginTop:18}}>
{[
['Installs','24,521'],['Rating','4.9 / 5'],['Size','340 kB'],['Sandboxed','Yes']
].map(([k,v])=>(
<div key={k} style={{padding:'10px 12px', borderRadius:10, background:'rgba(255,255,255,0.7)', boxShadow:'var(--ely-shadow-soft)'}}>
<div style={{fontSize:10.5, color:'var(--ely-ink-4)', textTransform:'uppercase', letterSpacing:'0.1em'}}>{k}</div>
<div style={{fontSize:13, fontWeight:500, marginTop:2}}>{v}</div>
</div>
))}
</div>
<div style={{marginTop:22}}>
<div style={{fontSize:13, fontWeight:600, marginBottom:10}}>What it adds to ELY</div>
<div style={{display:'flex', flexDirection:'column', gap:8}}>
{[
['Reader sidebar', 'Outline, time-to-read, table of contents themed to your wallpaper.'],
['Ambient mode', 'Subtle background motion sourced from the article\'s lead image.'],
['Pocket-style queue', 'Save for later that lives in ELY\'s reading list, not a third-party app.'],
].map(([t,d],i)=>(
<div key={i} style={{display:'flex', alignItems:'flex-start', gap:10, padding:'10px 12px', borderRadius:10, background:'rgba(255,255,255,0.55)'}}>
<span style={{width:18, height:18, borderRadius:5, background:'rgba(201,100,66,0.12)', color:'var(--ely-accent)', display:'inline-flex',alignItems:'center',justifyContent:'center', fontSize:11, marginTop:1}}><I.Check size={11}/></span>
<div style={{flex:1}}>
<div style={{fontSize:12.5, fontWeight:500}}>{t}</div>
<div style={{fontSize:11.5, color:'var(--ely-ink-3)', marginTop:1, lineHeight:1.4}}>{d}</div>
</div>
</div>
))}
</div>
</div>
</div>
</div>
</div>
</div>
</ElyShell>
);};
window.PluginsScreen = PluginsScreen;
+138
View File
@@ -0,0 +1,138 @@
// settings.jsx — Settings page
const SettingsScreen = () => {
const SectionLabel = ({ children, k='label' }) => k==='label' ?
<div style={{padding:'8px 12px 4px', fontSize:10, color:'var(--ely-ink-4)', textTransform:'uppercase', letterSpacing:'0.1em', fontWeight:500}}>{children}</div>
: <div>{children}</div>;
const NavItem = ({ icon, label, active }) => (
<div style={{display:'flex',alignItems:'center',gap:10, padding:'7px 12px', borderRadius:8, background: active?'rgba(255,255,255,0.85)':'transparent', boxShadow: active?'var(--ely-shadow-soft)':'none', fontSize:13, color: active?'var(--ely-ink)':'var(--ely-ink-2)'}}>
<span style={{color:'var(--ely-ink-3)'}}>{icon}</span>{label}
</div>
);
const Toggle = ({ on }) => (
<span style={{width:32, height:18, borderRadius:999, background: on?'var(--ely-accent)':'rgba(40,30,20,0.15)', position:'relative', display:'inline-block', boxShadow:'inset 0 0 0 1px rgba(0,0,0,0.05)'}}>
<span style={{position:'absolute', top:2, left: on?16:2, width:14, height:14, borderRadius:'50%', background:'#fff', boxShadow:'0 1px 2px rgba(0,0,0,0.2)', transition:'left .2s'}}/>
</span>
);
const Row = ({ title, desc, children, last }) => (
<div style={{display:'flex', alignItems:'center', gap:16, padding:'14px 0', borderBottom: last?'none':'1px solid var(--ely-divider)'}}>
<div style={{flex:1}}>
<div style={{fontSize:13, fontWeight:500}}>{title}</div>
{desc && <div style={{fontSize:11.5, color:'var(--ely-ink-3)', marginTop:2}}>{desc}</div>}
</div>
{children}
</div>
);
const Select = ({ value }) => (
<span style={{display:'inline-flex',alignItems:'center', gap:6, padding:'5px 10px', background:'rgba(255,255,255,0.85)', borderRadius:6, boxShadow:'var(--ely-shadow-soft)', fontSize:12}}>{value} <I.ChevronDown size={11}/></span>
);
return (
<ElyShell wallpaper="dawn" sidebarProps={{ activeId:'settings' }}>
<div className="ely-topbar">
<button className="ely-iconbtn"><I.ArrowLeft size={16}/></button>
<button className="ely-iconbtn disabled"><I.ArrowRight size={16}/></button>
<div className="ely-omnibar"><I.Settings size={14}/><span className="url-host">ely://settings</span><span className="url-path">/appearance</span><span className="right"><I.Filters size={14}/></span></div>
<button className="ely-iconbtn"><I.Copy size={16}/></button>
<button className="ely-iconbtn"><I.Download size={16}/></button>
<button className="ely-iconbtn"><I.Moon size={16}/></button>
<button className="ely-iconbtn"><I.Menu size={16}/></button>
</div>
<div style={{flex:1, display:'grid', gridTemplateColumns:'232px 1fr', minHeight:0}}>
<div style={{padding:'16px 10px', borderRight:'1px solid var(--ely-divider)', overflowY:'auto'}}>
<div style={{padding:'4px 12px 12px'}}>
<div style={{fontSize:18, fontWeight:500}} className="ely-serif">Settings</div>
<div style={{fontSize:11.5, color:'var(--ely-ink-4)', marginTop:2}}>ELY 0.42 · macOS 14.4</div>
</div>
<SectionLabel>General</SectionLabel>
<NavItem icon={<I.Palette size={14}/>} label="Appearance" active/>
<NavItem icon={<I.Sidebar size={14}/>} label="Sidebar"/>
<NavItem icon={<I.Tab size={14}/>} label="Tabs &amp; Workspaces"/>
<NavItem icon={<I.Cmd size={14}/>} label="Shortcuts"/>
<SectionLabel>Account</SectionLabel>
<NavItem icon={<I.Cloud size={14}/>} label="Sync"/>
<NavItem icon={<I.Shield size={14}/>} label="Privacy &amp; Security"/>
<NavItem icon={<I.User size={14}/>} label="Profiles"/>
<SectionLabel>Power</SectionLabel>
<NavItem icon={<I.Plug size={14}/>} label="Plugins"/>
<NavItem icon={<I.Sparkle size={14}/>} label="ELY AI"/>
<NavItem icon={<I.Code size={14}/>} label="Developer"/>
<SectionLabel>About</SectionLabel>
<NavItem icon={<I.Heart size={14}/>} label="What's new"/>
<NavItem icon={<I.Bell size={14}/>} label="Help &amp; feedback"/>
</div>
<div className="ely-scroll" style={{padding:'28px 40px 32px', overflowY:'auto'}}>
<div style={{maxWidth:780, margin:'0 auto'}}>
<div style={{fontSize:11, color:'var(--ely-ink-4)', textTransform:'uppercase', letterSpacing:'0.1em'}}>General</div>
<h1 className="ely-serif" style={{fontSize:34, fontWeight:400, margin:'4px 0 6px', letterSpacing:'-0.02em'}}>Appearance</h1>
<div style={{fontSize:13, color:'var(--ely-ink-3)', maxWidth:520}}>Tune the atmosphere of your browser. ELY's theme follows the time of day by default — pick a wallpaper, then let it breathe.</div>
<div style={{marginTop:24, display:'grid', gridTemplateColumns:'repeat(4, 1fr)', gap:10}}>
{[
['Dawn','#ffd1d8','#b9c7ff', true],
['Violet','#d6c4ff','#ffe0c0'],
['Mint','#c5f0db','#ffe5b8'],
['Slate','#cfd6e2','#1d1c1a']
].map(([n, a, b, sel])=>(
<div key={n} style={{position:'relative'}}>
<div style={{aspectRatio:'4/3', borderRadius:10, background:`radial-gradient(70% 60% at 80% 20%, ${a}, transparent 70%), radial-gradient(60% 60% at 15% 90%, ${b}, transparent 70%), #f6f4ef`, boxShadow:'var(--ely-shadow-card)', outline: sel?'2px solid var(--ely-accent)':'none', outlineOffset:2}}/>
<div style={{display:'flex', alignItems:'center', gap:6, padding:'8px 2px 0', fontSize:12}}>
<span style={{flex:1, fontWeight:500}}>{n}</span>
{sel && <span style={{color:'var(--ely-accent)'}}><I.Check size={13}/></span>}
</div>
</div>
))}
</div>
<div style={{marginTop:32}}>
<Row title="Theme mode" desc="Match system appearance, or pick one to lock.">
<div style={{display:'flex', gap:4, padding:3, background:'rgba(40,30,20,0.05)', borderRadius:8}}>
{['System','Light','Dark'].map((t,i)=>(
<span key={t} style={{padding:'4px 12px', borderRadius:6, fontSize:12, background: i===0?'#fff':'transparent', boxShadow: i===0?'var(--ely-shadow-soft)':'none', fontWeight:500}}>{t}</span>
))}
</div>
</Row>
<Row title="Accent color" desc="Used across selection, focus rings & links.">
<div style={{display:'flex', gap:8}}>
{['#c96442','#ec6a8e','#7c6cf7','#4fb59a','#1d1c1a'].map((c,i)=>(
<div key={c} style={{width:22,height:22, borderRadius:'50%', background:c, boxShadow: i===0?'0 0 0 2px #fff, 0 0 0 4px var(--ely-accent)':'inset 0 0 0 1px rgba(0,0,0,0.05)'}}/>
))}
</div>
</Row>
<Row title="Font" desc="Display serif used for headlines & New Tab.">
<Select value="Newsreader"/>
</Row>
<Row title="Translucency" desc="Glass density of sidebar & panels.">
<div style={{width:200, height:4, borderRadius:2, background:'rgba(40,30,20,0.1)', position:'relative'}}>
<div style={{position:'absolute', left:0, top:0, bottom:0, width:'62%', background:'var(--ely-accent)', borderRadius:2}}/>
<div style={{position:'absolute', left:'62%', top:'50%', width:14, height:14, borderRadius:'50%', background:'#fff', boxShadow:'0 1px 4px rgba(0,0,0,0.2)', transform:'translate(-50%,-50%)'}}/>
</div>
</Row>
<Row title="Reduce motion" desc="Mute transitions & ambient effects.">
<Toggle/>
</Row>
<Row title="Reading-mode background" last>
<Select value="Sepia"/>
</Row>
</div>
<div style={{marginTop:36, fontSize:11, color:'var(--ely-ink-4)', textTransform:'uppercase', letterSpacing:'0.1em'}}>Sidebar</div>
<h2 className="ely-serif" style={{fontSize:22, fontWeight:400, margin:'2px 0 18px'}}>Layout</h2>
<div style={{display:'grid', gridTemplateColumns:'repeat(3, 1fr)', gap:10}}>
{['Single column','Compact','Hidden on hover'].map((n,i)=>(
<div key={n} className="ely-card" style={{padding:14, outline: i===0?'2px solid var(--ely-accent)':'none'}}>
<div style={{aspectRatio:'5/3', background:'#fff', borderRadius:8, boxShadow:'var(--ely-shadow-soft)', position:'relative', overflow:'hidden'}}>
<div style={{position:'absolute', left:6, top:6, bottom:6, width: i===2?6:i===1?32:54, background:'rgba(40,30,20,0.08)', borderRadius:5}}/>
<div style={{position:'absolute', left: i===2?20:i===1?46:68, top:6, right:6, bottom:6, background:'rgba(40,30,20,0.04)', borderRadius:5}}/>
</div>
<div style={{fontSize:12, fontWeight:500, marginTop:10}}>{n}</div>
<div style={{fontSize:11, color:'var(--ely-ink-4)', marginTop:2}}>{['Default · workspace + tabs','Icons-only with tooltips','Slide in on cursor reach'][i]}</div>
</div>
))}
</div>
</div>
</div>
</div>
</ElyShell>
);};
window.SettingsScreen = SettingsScreen;
+105
View File
@@ -0,0 +1,105 @@
// split.jsx — Split-view browsing
const SplitScreen = () => {
const Pane = ({ title, host, children, accent }) => (
<div style={{display:'flex', flexDirection:'column', flex:1, minWidth:0, background:'#fff', borderRadius:10, overflow:'hidden', boxShadow:'0 1px 0 rgba(0,0,0,0.05), 0 12px 30px -16px rgba(0,0,0,0.18)'}}>
<div style={{height:30, background:'#f6f4ef', borderBottom:'1px solid #ebe7e0', display:'flex', alignItems:'center', padding:'0 10px', gap:8, fontSize:11, color:'#3a3733'}}>
<span style={{width:8, height:8, borderRadius:'50%', background:accent}}/>
<I.Lock size={11}/>
<span style={{color:'#1d1c1a', fontWeight:500}}>{host}</span>
<span style={{color:'#9a948c'}}>{title}</span>
<span style={{marginLeft:'auto', display:'flex', gap:6, color:'#9a948c'}}>
<I.Reload size={11}/><I.X size={11}/>
</span>
</div>
<div style={{flex:1, minHeight:0, overflow:'hidden'}}>{children}</div>
</div>
);
return (
<ElyShell wallpaper="violet" sidebarProps={{ activeId:'figma', mode:'browse', tabs:[
{ id:'figma', label:'Style Guide · Figma', icon:<Brand.Figma s={16}/>, active:true, closable:true },
{ id:'lin', label:'Roadmap 2024 — Linear', icon:<Brand.Linear s={16}/>, active:true },
{ id:'gh', label:'elybrowser/core', icon:<Brand.GitHub s={16}/> },
] }}>
<div className="ely-topbar" style={{gap:6}}>
<button className="ely-iconbtn"><I.ArrowLeft size={16}/></button>
<button className="ely-iconbtn disabled"><I.ArrowRight size={16}/></button>
<div className="ely-omnibar" style={{flex:1}}>
<I.Lock size={14}/>
<span className="url-host">figma.com</span>
<span className="url-path">/file/12345/Style-Guide</span>
<span className="right"><I.Filters size={14}/><I.Star size={14}/></span>
</div>
<div style={{width:1, height:22, background:'var(--ely-divider)', margin:'0 4px'}}/>
<div className="ely-omnibar" style={{flex:1}}>
<I.Lock size={14}/>
<span className="url-host">linear.app</span>
<span className="url-path">/elybrowser/roadmap</span>
<span className="right"><I.Filters size={14}/><I.Star size={14}/></span>
</div>
<button className="ely-iconbtn is-on" title="Split"><I.Split size={16}/></button>
<button className="ely-iconbtn"><I.Menu size={16}/></button>
</div>
<div style={{flex:1, padding:14, display:'flex', gap:10, minHeight:0}}>
{/* Left: Figma */}
<Pane title="· Style Guide" host="figma.com" accent="#7c6cf7">
<div style={{height:'100%', display:'grid', gridTemplateRows:'auto 1fr', background:'#1d1c1a', color:'#cfcbc4'}}>
<div style={{padding:'8px 12px', fontSize:11, display:'flex', gap:8, alignItems:'center'}}>
<Brand.Figma s={14}/>
<span style={{color:'#fff', fontWeight:500}}>Style Guide</span>
<span style={{opacity:.6}}>/ Typography</span>
<span style={{marginLeft:'auto', display:'flex', gap:6}}>
<span style={{padding:'2px 8px', background:'#fff', color:'#1d1c1a', borderRadius:4, fontSize:10.5}}>Share</span>
</span>
</div>
<div style={{position:'relative', overflow:'hidden', background:'#f5f4f1'}}>
<div style={{position:'absolute', inset:0, backgroundImage:'radial-gradient(circle at 1px 1px, rgba(0,0,0,0.05) 1px, transparent 0)', backgroundSize:'16px 16px'}}/>
<div style={{position:'relative', margin:'24px auto', maxWidth:380, background:'#fff', padding:'24px 28px', borderRadius:6, boxShadow:'0 1px 0 rgba(0,0,0,0.06)'}}>
<div className="ely-serif" style={{fontSize:36, lineHeight:1.05}}>The aesthetics of calm tech.</div>
<div style={{marginTop:14, fontSize:11.5, color:'#3a3733', lineHeight:1.5}}>A type system tuned for long-form reading and slow, deliberate interfaces. Designed for ambient use.</div>
<div style={{marginTop:14, display:'flex', gap:6}}>
{['#1d1c1a','#c96442','#ec6a8e','#7c6cf7','#4fb59a'].map(c=>(<div key={c} style={{width:18,height:18,borderRadius:4, background:c}}/>))}
</div>
</div>
</div>
</div>
</Pane>
{/* Right: Linear */}
<Pane title="· Roadmap 2024" host="linear.app" accent="#5e6ad2">
<div style={{height:'100%', background:'#0e0d0c', color:'#dcd9d2', display:'flex'}}>
<div style={{width:140, borderRight:'1px solid #1d1c1a', padding:'10px 8px', fontSize:11}}>
<div style={{display:'flex',alignItems:'center',gap:6, padding:'4px 6px'}}><Brand.Linear s={14}/><span style={{fontWeight:600}}>ELY</span></div>
{['Inbox','My Issues','Triage'].map(l=>(<div key={l} style={{padding:'4px 6px', color:'#9a948c'}}>{l}</div>))}
<div style={{padding:'8px 6px 2px', color:'#6b6660', fontSize:10, textTransform:'uppercase', letterSpacing:'.08em'}}>Cycles</div>
{['24 · Now','24 · Next','25 · Q1','25 · Q2'].map((l,i)=>(<div key={l} style={{padding:'4px 6px', borderRadius:4, background:i===0?'#1d1c1a':'transparent', color:i===0?'#fff':'#9a948c'}}>{l}</div>))}
</div>
<div style={{flex:1, padding:'10px 14px', fontSize:11.5}}>
<div style={{display:'flex', alignItems:'center', gap:8}}>
<span style={{fontSize:13, color:'#fff', fontWeight:500}}>Roadmap 2024</span>
<span style={{color:'#6b6660'}}>· 18 issues</span>
<span style={{marginLeft:'auto', padding:'2px 8px', background:'#5e6ad2', color:'#fff', borderRadius:4, fontSize:10.5}}>+ New</span>
</div>
<div style={{display:'grid', gridTemplateColumns:'1fr', gap:1, marginTop:10, background:'#1d1c1a', borderRadius:4, overflow:'hidden'}}>
{[
['ELY-101','In Progress', 'Universal command bar', '#f5a623'],
['ELY-102','In Progress', 'Vertical tabs · sticky pinning', '#f5a623'],
['ELY-103','Todo', 'Cloudflare sync · device pairing', '#5e6ad2'],
['ELY-104','Todo', 'Plugin SDK · v0', '#5e6ad2'],
['ELY-105','Backlog', 'Reader mode · ambient theme', '#6b6660'],
['ELY-106','Done', 'Workspace switching', '#4fb59a'],
].map(([id,st,t,c],i)=>(
<div key={i} style={{display:'flex',alignItems:'center', gap:10, padding:'8px 10px', background:'#0e0d0c'}}>
<span style={{width:8,height:8,borderRadius:'50%', background:c}}/>
<span style={{color:'#6b6660', width:54}}>{id}</span>
<span style={{flex:1, color:'#fff'}}>{t}</span>
<span style={{color:'#9a948c'}}>{st}</span>
<span style={{width:18,height:18,borderRadius:'50%', background:'linear-gradient(135deg,#7c6cf7,#ec6a8e)'}}/>
</div>
))}
</div>
</div>
</div>
</Pane>
</div>
</ElyShell>
);};
window.SplitScreen = SplitScreen;
+111
View File
@@ -0,0 +1,111 @@
// sync.jsx — Sync / Sign In page
const SyncScreen = () => {
const Device = ({ name, model, when, current, icon }) => (
<div style={{display:'flex',alignItems:'center', gap:12, padding:'14px 4px', borderBottom:'1px solid var(--ely-divider)'}}>
<div style={{width:36, height:36, borderRadius:9, background:'rgba(255,255,255,0.85)', boxShadow:'var(--ely-shadow-soft)', display:'flex',alignItems:'center',justifyContent:'center', color:'var(--ely-ink-2)'}}>{icon}</div>
<div style={{flex:1}}>
<div style={{fontSize:13, fontWeight:500, display:'flex', alignItems:'center', gap:8}}>{name}{current && <span style={{padding:'1px 7px', background:'rgba(79,181,154,0.18)', color:'#2f7d68', borderRadius:999, fontSize:10}}>This device</span>}</div>
<div style={{fontSize:11, color:'var(--ely-ink-4)', marginTop:1}}>{model} · {when}</div>
</div>
<span style={{fontSize:11, color:'var(--ely-ink-3)', display:'inline-flex',alignItems:'center', gap:4}}><span style={{width:6, height:6, borderRadius:'50%', background:'#4fb59a'}}/> Synced</span>
</div>
);
return (
<ElyShell wallpaper="violet" sidebarProps={{ activeId:'settings' }}>
<div className="ely-topbar">
<button className="ely-iconbtn"><I.ArrowLeft size={16}/></button>
<button className="ely-iconbtn disabled"><I.ArrowRight size={16}/></button>
<div className="ely-omnibar"><I.Cloud size={14}/><span className="url-host">ely://settings</span><span className="url-path">/sync</span></div>
<button className="ely-iconbtn"><I.Moon size={16}/></button>
<button className="ely-iconbtn"><I.Menu size={16}/></button>
</div>
<div className="ely-scroll" style={{flex:1, overflowY:'auto', padding:'40px 56px 32px'}}>
<div style={{maxWidth:880, margin:'0 auto', display:'grid', gridTemplateColumns:'1.1fr 1fr', gap:32, alignItems:'start'}}>
<div>
<div style={{display:'inline-flex', alignItems:'center', gap:8, padding:'4px 10px', borderRadius:999, background:'rgba(255,255,255,0.7)', boxShadow:'var(--ely-shadow-soft)', fontSize:11, color:'var(--ely-ink-3)'}}>
<I.Cloud size={12}/> Cloudflare Sync · end-to-end encrypted
</div>
<h1 className="ely-serif" style={{fontSize:46, lineHeight:1.05, margin:'16px 0 10px', fontWeight:400, letterSpacing:'-0.02em'}}>Your tabs, on every device.</h1>
<p style={{fontSize:14, color:'var(--ely-ink-2)', lineHeight:1.55, maxWidth:440, margin:0}}>Sign in once and ELY keeps your tabs, workspaces, pinned items and history in sync encrypted in your hands, mirrored at the edge.</p>
<div style={{marginTop:28, padding:24, borderRadius:16, background:'rgba(255,255,255,0.85)', boxShadow:'var(--ely-shadow-card)', maxWidth:380}}>
<div style={{fontSize:12, color:'var(--ely-ink-3)', marginBottom:14, display:'flex', alignItems:'center', gap:6}}>
<I.Lock size={12}/> Better Auth · ELY Account
</div>
<label style={{display:'block', fontSize:11, color:'var(--ely-ink-3)', marginBottom:6}}>Email</label>
<div style={{height:40, padding:'0 12px', borderRadius:9, background:'#fff', boxShadow:'var(--ely-shadow-soft)', display:'flex', alignItems:'center', fontSize:13, color:'var(--ely-ink)'}}>alex@elybrowser.com</div>
<label style={{display:'block', fontSize:11, color:'var(--ely-ink-3)', marginBottom:6, marginTop:14}}>Password</label>
<div style={{height:40, padding:'0 12px', borderRadius:9, background:'#fff', boxShadow:'var(--ely-shadow-soft)', display:'flex', alignItems:'center', fontSize:13, color:'var(--ely-ink)', letterSpacing:'0.2em'}}></div>
<button style={{width:'100%', marginTop:18, height:42, borderRadius:10, background:'var(--ely-ink)', color:'#fff', fontWeight:500, fontSize:13, border:0, display:'flex', alignItems:'center', justifyContent:'center', gap:8}}>
Sign in <I.ArrowRight size={14}/>
</button>
<div style={{display:'flex', alignItems:'center', gap:10, margin:'14px 0 12px'}}>
<div style={{flex:1, height:1, background:'var(--ely-divider)'}}/><span style={{fontSize:10.5, color:'var(--ely-ink-4)'}}>or continue with</span><div style={{flex:1, height:1, background:'var(--ely-divider)'}}/>
</div>
<div style={{display:'grid', gridTemplateColumns:'1fr 1fr 1fr', gap:8}}>
{['Google','GitHub','Apple'].map(p=>(
<div key={p} style={{height:36, borderRadius:9, background:'#fff', boxShadow:'var(--ely-shadow-soft)', display:'flex', alignItems:'center', justifyContent:'center', gap:6, fontSize:12, fontWeight:500, color:'var(--ely-ink)'}}>
{p==='GitHub' && <Brand.GitHub s={13}/>}
{p==='Google' && <span style={{width:13, height:13, borderRadius:'50%', background:'conic-gradient(from 90deg, #ea4335, #fbbc05, #34a853, #4285f4)'}}/>}
{p==='Apple' && <span style={{fontSize:13}}></span>}
{p}
</div>
))}
</div>
<div style={{marginTop:14, fontSize:11, color:'var(--ely-ink-4)', textAlign:'center'}}>By signing in you accept the ELY <span style={{color:'var(--ely-ink-2)', textDecoration:'underline', textDecorationColor:'var(--ely-ink-5)'}}>terms</span> &amp; <span style={{color:'var(--ely-ink-2)', textDecoration:'underline', textDecorationColor:'var(--ely-ink-5)'}}>privacy</span>.</div>
</div>
</div>
<div style={{display:'flex', flexDirection:'column', gap:14}}>
<div className="ely-card" style={{padding:18}}>
<div style={{display:'flex', alignItems:'center', gap:10, marginBottom:6}}>
<span style={{width:28, height:28, borderRadius:8, background:'linear-gradient(135deg,#fff,#f0e9e2)', display:'flex',alignItems:'center',justifyContent:'center', boxShadow:'var(--ely-shadow-soft)', color:'var(--ely-accent)'}}><I.Devices size={14}/></span>
<div style={{fontSize:13, fontWeight:500, flex:1}}>Devices</div>
<span style={{fontSize:11, color:'var(--ely-ink-3)'}}>3 connected</span>
</div>
<Device current name="Alex's MacBook Pro" model="macOS 14.4 · Apple Silicon" when="Active now" icon={<svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.5"><rect x="3" y="4" width="18" height="12" rx="1.5"/><path d="M2 20h20"/></svg>}/>
<Device name="iPhone 15 Pro" model="iOS 17.4 · Cellular" when="2 minutes ago" icon={<svg width="14" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.5"><rect x="6" y="2" width="12" height="20" rx="2"/><path d="M11 18h2"/></svg>}/>
<Device name="Studio iMac" model="macOS 14.2 · Office" when="6 hours ago" icon={<svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.5"><rect x="2" y="3" width="20" height="14" rx="1.5"/><path d="M8 21h8M12 17v4"/></svg>}/>
<div style={{padding:'12px 4px 0', display:'flex', alignItems:'center', gap:10}}>
<span style={{padding:'7px 14px', borderRadius:8, background:'#fff', boxShadow:'var(--ely-shadow-soft)', fontSize:12, fontWeight:500, display:'inline-flex', alignItems:'center', gap:6}}><I.Plus size={12}/> Pair a device</span>
<span style={{fontSize:11, color:'var(--ely-ink-4)'}}>or scan QR with the ELY app</span>
</div>
</div>
<div className="ely-card" style={{padding:18, background:'linear-gradient(135deg, rgba(255,235,225,0.95), rgba(232,224,255,0.85))'}}>
<div style={{display:'flex', alignItems:'flex-start', gap:12}}>
<span style={{width:30, height:30, borderRadius:8, background:'#fff', display:'flex',alignItems:'center',justifyContent:'center', boxShadow:'var(--ely-shadow-soft)', color:'var(--ely-accent)'}}><I.Key size={15}/></span>
<div style={{flex:1}}>
<div style={{fontSize:13, fontWeight:500}}>Recovery key</div>
<div style={{fontSize:11.5, color:'var(--ely-ink-3)', marginTop:2}}>The only way to restore an end-to-end encrypted account. We don't keep a copy.</div>
</div>
</div>
<div className="ely-mono" style={{marginTop:14, padding:14, background:'rgba(255,255,255,0.85)', borderRadius:10, fontSize:13, letterSpacing:'0.05em', lineHeight:1.7, color:'var(--ely-ink)', textAlign:'center', fontWeight:500, boxShadow:'var(--ely-shadow-soft)'}}>
river · slate · candle · lantern<br/>orchid · meadow · whistle · ember
</div>
<div style={{display:'flex', gap:8, marginTop:12}}>
<span style={{flex:1, padding:'8px 10px', borderRadius:8, background:'#fff', boxShadow:'var(--ely-shadow-soft)', fontSize:12, fontWeight:500, textAlign:'center'}}>Copy</span>
<span style={{flex:1, padding:'8px 10px', borderRadius:8, background:'#fff', boxShadow:'var(--ely-shadow-soft)', fontSize:12, fontWeight:500, textAlign:'center'}}>Download .txt</span>
<span style={{flex:1, padding:'8px 10px', borderRadius:8, background:'var(--ely-ink)', color:'#fff', fontSize:12, fontWeight:500, textAlign:'center'}}>I've saved it</span>
</div>
</div>
<div className="ely-card" style={{padding:16}}>
<div style={{fontSize:13, fontWeight:500, marginBottom:8}}>What syncs</div>
<div style={{display:'grid', gridTemplateColumns:'1fr 1fr', gap:6, fontSize:12, color:'var(--ely-ink-2)'}}>
{[['Tabs &amp; pinned',true],['Workspaces',true],['History',true],['Bookmarks',true],['Reading list',true],['Plugins',true],['Passwords',false],['Open windows',false]].map(([n,on],i)=>(
<div key={i} style={{display:'flex',alignItems:'center',gap:8, padding:'4px 0'}}>
<span style={{color: on?'#2f7d68':'var(--ely-ink-4)'}}>{on? <I.Check size={13}/> : <I.X size={13}/>}</span>
<span dangerouslySetInnerHTML={{__html:n}}/>
</div>
))}
</div>
</div>
</div>
</div>
</div>
</ElyShell>
);};
window.SyncScreen = SyncScreen;