← Notes results

Notes

GPT 5.6 terra · full

Initial view of Notes

Reviews & generation details

Reviews

No human review yet. Unreviewed does not mean unsuccessful.

Generation context

Imported historical artifact. Its exact original instructions and lineage are not known.

Generation prompt · exact text unavailable

See the current prompt for reference. It may differ from the instructions used to generate this artifact.

Inspect original source 27,436 bytes · SHA-256 83dbbf301858
<!doctype html>
<html lang="en"><head><meta charset="utf-8"><meta name="viewport" content="width=device-width,initial-scale=1"><title>Folio Notes</title><style>
/* ── Tunable constants ───────────────────────────────────────────── */
:root{--accent:#6f5bd3;--accent-soft:#eeeaff;--bg:#f7f6f3;--panel:#fbfaf8;--editor:#fffefd;--ink:#28252e;--muted:#827d88;--line:#e8e4de;--hover:#f0eeea;--serif:Georgia,'Times New Roman',serif;--sans:Inter,ui-sans-serif,system-ui,-apple-system,BlinkMacSystemFont,'Segoe UI',sans-serif;--sidebar:252px;--list:305px}body.dark{--bg:#19181d;--panel:#211f25;--editor:#26242b;--ink:#f1eef4;--muted:#aaa4b0;--line:#37333b;--hover:#302d35;--accent-soft:#332d58}
*{box-sizing:border-box}body{margin:0;background:var(--bg);color:var(--ink);font:13px var(--sans);overflow:hidden}button,input{font:inherit;color:inherit}button{border:0;background:none;cursor:pointer}.app{height:100vh;display:flex}.sidebar{width:var(--sidebar);min-width:0;background:var(--panel);border-right:1px solid var(--line);display:flex;flex-direction:column;transition:width .22s ease;overflow:hidden}.sidebar.collapsed{width:54px}.brand{height:62px;display:flex;align-items:center;padding:0 16px;gap:10px;white-space:nowrap}.mark{width:25px;height:25px;border-radius:8px;background:linear-gradient(135deg,#927de9,#5f4abc);color:white;display:grid;place-items:center;font-weight:800;font-size:14px;box-shadow:0 3px 8px #6e5ad344}.brand strong{font-size:15px;letter-spacing:-.3px}.collapse{margin-left:auto;color:var(--muted);padding:7px;border-radius:6px}.collapse:hover,.icon:hover{background:var(--hover);color:var(--ink)}.side-scroll{overflow:auto;flex:1;padding:4px 10px}.navitem,.notebook{display:flex;align-items:center;gap:10px;height:36px;padding:0 9px;border-radius:7px;color:var(--muted);white-space:nowrap;cursor:pointer;position:relative}.navitem:hover,.notebook:hover{background:var(--hover);color:var(--ink)}.navitem.active,.notebook.active{background:var(--accent-soft);color:var(--accent);font-weight:650}.navicon{font-size:16px;width:17px;text-align:center}.count{margin-left:auto;font-size:11px;opacity:.72}.section-head{display:flex;align-items:center;margin:20px 8px 7px;color:var(--muted);font-size:10px;font-weight:750;letter-spacing:.09em;text-transform:uppercase;white-space:nowrap}.section-head button{margin-left:auto;color:var(--muted);font-size:17px;padding:1px 5px;border-radius:5px}.notebook .dots{display:none;margin-left:auto;color:var(--muted);font-size:17px}.notebook:hover .dots{display:block}.side-footer{padding:12px;border-top:1px solid var(--line);white-space:nowrap}.theme{width:100%;text-align:left;padding:9px;border-radius:7px;color:var(--muted)}.theme:hover{background:var(--hover)}.resizer{width:5px;cursor:col-resize;z-index:3;position:relative}.resizer:hover,.resizer.drag{background:var(--accent)}.notes-pane{width:var(--list);min-width:180px;background:var(--bg);display:flex;flex-direction:column}.notes-top{height:62px;display:flex;align-items:center;padding:0 16px;gap:9px}.notes-top h2{font-size:16px;letter-spacing:-.4px;margin:0;flex:1;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.new-note{background:var(--accent);color:white;padding:8px 10px;border-radius:7px;font-size:12px;font-weight:650;box-shadow:0 2px 5px #6f5bd344}.new-note:hover{filter:brightness(1.08)}.list-tools{display:flex;gap:7px;padding:0 15px 11px}.search{height:34px;border:1px solid var(--line);background:var(--panel);border-radius:7px;display:flex;align-items:center;padding:0 9px;flex:1;color:var(--muted)}.search input{border:0;outline:0;background:transparent;width:100%;font-size:12px;padding-left:6px}.sort{border:1px solid var(--line);border-radius:7px;padding:0 8px;color:var(--muted)}.note-list{overflow:auto;padding:0 8px 14px}.note-card{padding:11px 11px 10px;border-radius:8px;margin-bottom:3px;cursor:pointer;transition:background .12s;position:relative}.note-card:hover{background:var(--hover)}.note-card.active{background:var(--accent-soft)}.note-title{font-weight:680;font-size:13px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;margin-bottom:4px}.note-preview{color:var(--muted);font-size:12px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;line-height:1.35}.note-meta{display:flex;gap:6px;margin-top:7px;color:var(--muted);font-size:10px}.pin{color:#d19b3d}.tag{background:var(--hover);color:var(--muted);font-size:10px;padding:2px 5px;border-radius:4px;cursor:pointer}.tag:hover{color:var(--accent)}mark{background:#f4d778;color:inherit;border-radius:2px;padding:0 1px}.editor-pane{flex:1;min-width:260px;background:var(--editor);display:flex;flex-direction:column;overflow:hidden}.editor-head{height:62px;border-bottom:1px solid var(--line);display:flex;align-items:center;padding:0 28px;gap:8px}.crumb{font-size:12px;color:var(--muted);margin-right:auto}.save{font-size:11px;color:var(--muted);transition:.2s}.save.saved{color:#4c9a72}.head-btn,.icon{padding:7px;border-radius:6px;color:var(--muted);font-size:15px}.head-btn:hover{background:var(--hover);color:var(--ink)}.toolbar{height:45px;display:flex;align-items:center;gap:2px;border-bottom:1px solid var(--line);padding:0 25px;flex-wrap:nowrap;overflow-x:auto}.tool{min-width:28px;height:27px;padding:0 6px;border-radius:5px;font-size:12px;color:var(--muted);font-weight:600}.tool:hover,.tool.active{background:var(--accent-soft);color:var(--accent)}.sep{height:18px;width:1px;background:var(--line);margin:0 5px}.edit-wrap{overflow:auto;flex:1}.editor{max-width:820px;margin:0 auto;padding:43px 56px 110px;min-height:100%;outline:0;font:18px/1.7 var(--serif);letter-spacing:.003em}.editor:empty:before{content:attr(data-placeholder);color:#aaa5ae;pointer-events:none}.editor h1,.editor h2,.editor h3{font-family:var(--sans);line-height:1.25;letter-spacing:-.035em;margin:1.1em 0 .45em}.editor h1{font-size:33px}.editor h2{font-size:25px}.editor h3{font-size:20px}.editor p{margin:.3em 0}.editor ul,.editor ol{padding-left:1.45em;margin:.45em 0}.editor blockquote{border-left:3px solid var(--accent);margin:.8em 0;padding:.15em 0 .15em 18px;color:var(--muted)}.editor code{font:13px ui-monospace,SFMono-Regular,monospace;background:var(--hover);padding:2px 5px;border-radius:4px}.editor hr{border:0;border-top:1px solid var(--line);margin:1.4em 0}.check-item{list-style:none;margin-left:-1.35em}.check-item input{accent-color:var(--accent);margin-right:9px;vertical-align:middle;width:14px;height:14px}.check-item.done{color:var(--muted);text-decoration:line-through}.tagsbar{max-width:820px;margin:0 auto;padding:10px 56px 16px;width:100%;display:flex;gap:6px;align-items:center;min-height:42px}.addtag{color:var(--muted);font-size:11px;padding:3px 5px;border-radius:4px}.addtag:hover{background:var(--hover)}.empty{height:100%;display:grid;place-items:center;text-align:center;color:var(--muted)}.empty .empty-icon{font-size:35px;margin-bottom:12px}.empty h3{color:var(--ink);font-size:16px;margin:0 0 5px}.empty p{margin:0}.menu{position:fixed;z-index:10;width:175px;padding:5px;background:var(--panel);border:1px solid var(--line);box-shadow:0 12px 30px #0002;border-radius:8px}.menu button{display:block;width:100%;text-align:left;padding:8px 9px;border-radius:5px;font-size:12px}.menu button:hover{background:var(--hover)}.menu .danger{color:#c65353}.modal-back{position:fixed;inset:0;background:#0003;display:grid;place-items:center;z-index:20}.modal{background:var(--panel);width:350px;border-radius:12px;padding:22px;box-shadow:0 18px 50px #0004}.modal h3{margin:0 0 14px}.modal input{width:100%;border:1px solid var(--line);background:var(--editor);border-radius:7px;padding:10px;outline-color:var(--accent)}.modal-actions{display:flex;justify-content:flex-end;gap:8px;margin-top:15px}.modal-actions button{padding:8px 12px;border-radius:6px}.primary{background:var(--accent);color:#fff}.muted{background:var(--hover)}.sidebar.collapsed .brand strong,.sidebar.collapsed .collapse,.sidebar.collapsed .section-head,.sidebar.collapsed .notebook span:not(.navicon),.sidebar.collapsed .navitem span:not(.navicon),.sidebar.collapsed .count,.sidebar.collapsed .side-footer span{display:none}.sidebar.collapsed .brand,.sidebar.collapsed .navitem,.sidebar.collapsed .notebook{padding-left:14px}.sidebar.collapsed .side-scroll{padding:4px 7px}@media(max-width:760px){.sidebar{width:54px}.sidebar .brand strong,.sidebar .collapse,.sidebar .section-head,.sidebar .notebook span:not(.navicon),.sidebar .navitem span:not(.navicon),.sidebar .count,.sidebar .side-footer span{display:none}.sidebar .brand,.sidebar .navitem,.sidebar .notebook{padding-left:14px}.sidebar .side-scroll{padding:4px 7px}.notes-pane{width:230px}.editor{padding:32px 27px}.tagsbar{padding-left:27px}.toolbar{padding:0 12px}}
</style></head><body><div id="app" class="app"><aside id="sidebar" class="sidebar"><div class="brand"><div class="mark">F</div><strong>Folio</strong><button class="collapse" id="collapse" title="Collapse sidebar">‹</button></div><div class="side-scroll"><div class="navitem active" data-view="all"><span class="navicon">▣</span><span>All Notes</span><span class="count" id="allCount"></span></div><div class="navitem" data-view="trash"><span class="navicon">♲</span><span>Trash</span><span class="count" id="trashCount"></span></div><div class="section-head">Notebooks <button id="addBook" title="New notebook">+</button></div><div id="books"></div></div><div class="side-footer"><button class="theme" id="theme">◐ <span>Appearance</span></button></div></aside><div class="resizer" id="sideResize"></div><section class="notes-pane"><div class="notes-top"><h2 id="listTitle">All Notes</h2><button id="newNote" class="new-note">+ New</button></div><div class="list-tools"><label class="search">⌕<input id="search" placeholder="Search notes"></label><button class="sort" id="sort" title="Change sort">↕</button></div><div class="note-list" id="noteList"></div></section><div class="resizer" id="listResize"></div><main class="editor-pane" id="editorPane"><div class="editor-head"><span class="crumb" id="crumb">Select a note</span><span class="save" id="save">Saved</span><button class="head-btn" id="pinBtn" title="Pin note">☆</button><button class="head-btn" id="moreBtn" title="More actions">•••</button></div><div class="toolbar" id="toolbar"><button class="tool" data-cmd="bold"><b>B</b></button><button class="tool" data-cmd="italic"><i>I</i></button><button class="tool" data-cmd="underline"><u>U</u></button><button class="tool" data-cmd="strikeThrough"><s>S</s></button><button class="tool" data-cmd="code">&lt;/&gt;</button><span class="sep"></span><button class="tool" data-block="h1">H1</button><button class="tool" data-block="h2">H2</button><button class="tool" data-block="h3">H3</button><span class="sep"></span><button class="tool" data-cmd="insertUnorderedList">• List</button><button class="tool" data-cmd="insertOrderedList">1. List</button><button class="tool" data-cmd="check">☑</button><button class="tool" data-block="blockquote">❝</button><button class="tool" data-cmd="hr">—</button><span class="sep"></span><button class="tool" id="undo">↶</button><button class="tool" id="redo">↷</button></div><div class="edit-wrap" id="editWrap"><div contenteditable="true" spellcheck="true" class="editor" id="editor" data-placeholder="Start writing…"></div><div class="tagsbar" id="tagsbar"></div></div><div id="empty" class="empty"><div><div class="empty-icon">✦</div><h3>Select or create a note</h3><p>Your ideas deserve a beautiful place to live.</p></div></div></main></div><div id="pop"></div><script>
/* ── State & persistence ─────────────────────────────────────────── */
const CFG={KEY:'folio-notes-v1',DEBOUNCE:450,SNIPPET:120};
const $=s=>document.querySelector(s), uid=()=>Math.random().toString(36).slice(2,10), now=()=>Date.now();
const seed=()=>({notebooks:[{id:'inbox',name:'Inbox'},{id:'ideas',name:'Ideas'}],notes:[{id:'welcome',notebookId:'inbox',title:'Welcome to Folio',html:'<h1>Make space for your best thinking</h1><p>Folio is a calm home for notes, ideas, and everything in between.</p><ul><li>Use the toolbar or keyboard shortcuts to format</li><li>Type <code># </code> at the start of a line for a heading</li><li>Try <code>[] </code> to create a checklist</li></ul><blockquote>Small thoughts become useful when you give them a place to grow.</blockquote>',tags:['welcome'],pinned:true,created:now(),updated:now(),trashed:false,originalNotebookId:null}],view:'all',selected:'welcome',sort:'modified',query:'',tag:null,layout:{side:252,list:305,collapsed:false},dark:false});
let S; try{S=JSON.parse(localStorage.getItem(CFG.KEY))||seed()}catch(e){S=seed()} S.notes??=[];S.notebooks??=[];S.layout??={side:252,list:305,collapsed:false}; let history={},histPos={},timer;
function save(){localStorage.setItem(CFG.KEY,JSON.stringify(S));$('#save').textContent='Saved';$('#save').classList.add('saved')}
function schedule(){clearTimeout(timer);$('#save').textContent='Saving…';$('#save').classList.remove('saved');timer=setTimeout(save,CFG.DEBOUNCE)}
function plain(html){let d=document.createElement('div');d.innerHTML=html||'';return (d.textContent||'').replace(/\s+/g,' ').trim()}
function esc(s){return String(s).replace(/[&<>'"]/g,c=>({'&':'&amp;','<':'&lt;','>':'&gt;',"'":'&#39;','"':'&quot;'}[c]))}
function current(){return S.notes.find(n=>n.id===S.selected)}
function visible(){let arr=S.notes.filter(n=>S.view==='trash'?n.trashed:!n.trashed&&(S.view==='all'||n.notebookId===S.view));if(S.tag)arr=arr.filter(n=>n.tags.includes(S.tag));let q=S.query.toLowerCase();if(q)arr=arr.filter(n=>(n.title+' '+plain(n.html)).toLowerCase().includes(q));let cmp=S.sort==='alpha'?(a,b)=>a.title.localeCompare(b.title):S.sort==='created'?(a,b)=>b.created-a.created:(a,b)=>b.updated-a.updated;return arr.sort((a,b)=>(b.pinned-a.pinned)||cmp(a,b))}
/* ── Rendering ───────────────────────────────────────────────────── */
function render(){document.body.classList.toggle('dark',S.dark);$('#sidebar').classList.toggle('collapsed',S.layout.collapsed);document.documentElement.style.setProperty('--sidebar',S.layout.side+'px');document.documentElement.style.setProperty('--list',S.layout.list+'px');renderBooks();renderList();renderEditor()}
function renderBooks(){let active=S.view;$('#allCount').textContent=S.notes.filter(n=>!n.trashed).length;$('#trashCount').textContent=S.notes.filter(n=>n.trashed).length;document.querySelectorAll('[data-view]').forEach(x=>x.classList.toggle('active',x.dataset.view===active));$('#books').innerHTML=S.notebooks.map(b=>`<div class="notebook ${active===b.id?'active':''}" data-book="${b.id}" draggable="true"><span class="navicon">▰</span><span>${esc(b.name)}</span><span class="count">${S.notes.filter(n=>n.notebookId===b.id&&!n.trashed).length}</span><button class="dots" data-bookmenu="${b.id}">•••</button></div>`).join('')}
function highlight(s){let q=S.query.trim();if(!q)return esc(s);let re=new RegExp('('+q.replace(/[.*+?^${}()|[\]\\]/g,'\\$&')+')','ig');return esc(s).replace(re,'<mark>$1</mark>')}
function renderList(){let notes=visible(), name=S.view==='all'?'All Notes':S.view==='trash'?'Trash':S.notebooks.find(b=>b.id===S.view)?.name||'Notes';$('#listTitle').textContent=S.tag?'# '+S.tag:name;$('#sort').textContent=S.sort==='modified'?'↕':S.sort==='created'?'◷':'A–Z';$('#noteList').innerHTML=notes.length?notes.map(n=>`<article class="note-card ${n.id===S.selected?'active':''}" data-note="${n.id}" draggable="true"><div class="note-title">${n.pinned?'<span class="pin">●</span> ':''}${highlight(n.title||'Untitled')}</div><div class="note-preview">${highlight(plain(n.html)||'No additional text')}</div><div class="note-meta"><span>${new Date(n.updated).toLocaleDateString(undefined,{month:'short',day:'numeric'})}</span>${n.tags.slice(0,2).map(t=>`<span class="tag" data-tag="${esc(t)}">#${esc(t)}</span>`).join('')}</div></article>`).join(''):`<div style="padding:42px 18px;text-align:center;color:var(--muted)">No notes here yet</div>`}
function renderEditor(){let n=current(), on=!!n;$('#empty').style.display=on?'none':'grid';$('#editWrap').style.display=on?'block':'none';$('#toolbar').style.display=on?'flex':'none';if(!n)return; if(document.activeElement!==$('#editor')){$('#editor').innerHTML=n.html;$('#editor').dataset.note=n.id}$('#crumb').textContent=(S.notebooks.find(b=>b.id===n.notebookId)?.name||'Trash')+' / '+(n.title||'Untitled');$('#pinBtn').textContent=n.pinned?'★':'☆';$('#pinBtn').style.color=n.pinned?'#d19b3d':'';$('#tagsbar').innerHTML=n.tags.map(t=>`<span class="tag" data-tag="${esc(t)}">#${esc(t)} ×</span>`).join('')+'<button class="addtag" id="addTag">+ Add tag</button>';}
/* ── Sanitization & editing ──────────────────────────────────────── */
function sanitize(html){let d=document.createElement('div');d.innerHTML=html;let allowed=new Set(['B','STRONG','I','EM','U','S','STRIKE','CODE','H1','H2','H3','P','DIV','BR','UL','OL','LI','BLOCKQUOTE','HR']);function walk(el){[...el.children].forEach(c=>{if(!allowed.has(c.tagName)){let text=document.createTextNode(c.textContent);c.replaceWith(text);return}if(c.tagName==='LI'&&c.querySelector('input[type=checkbox]')){let checked=c.querySelector('input').checked;c.innerHTML=c.textContent;c.className='check-item'+(checked?' done':'');c.insertAdjacentHTML('afterbegin',`<input type="checkbox" ${checked?'checked':''} contenteditable="false">`)}else{[...c.attributes].forEach(a=>{if(a.name!=='class'||c.tagName!=='LI')c.removeAttribute(a.name)});walk(c)}})}walk(d);return d.innerHTML}
function capture(){let n=current();if(!n)return;let h=$('#editor').innerHTML;if(history[n.id]?.[histPos[n.id]]!==h){history[n.id]??=[];history[n.id]=history[n.id].slice(0,(histPos[n.id]??-1)+1);history[n.id].push(h);histPos[n.id]=history[n.id].length-1}}
function commit(){let n=current();if(!n)return;n.html=sanitize($('#editor').innerHTML);let first=$('#editor').querySelector('h1,h2,h3,p,div');n.title=(first?.textContent||plain(n.html).split('\n')[0]||'Untitled').trim().slice(0,100);n.updated=now();capture();schedule();renderList();$('#crumb').textContent=(S.notebooks.find(b=>b.id===n.notebookId)?.name||'Trash')+' / '+n.title}
function cmd(c){$('#editor').focus();if(c==='code')document.execCommand('formatBlock',false,'pre');else if(c==='hr')document.execCommand('insertHorizontalRule');else if(c==='check')checkList();else document.execCommand(c,false,null);commit();stateTools()}
function block(t){$('#editor').focus();document.execCommand('formatBlock',false,t==='blockquote'?'blockquote':t);commit();stateTools()}
function checkList(){document.execCommand('insertUnorderedList');let li=closest('LI');if(li){li.className='check-item';li.insertAdjacentHTML('afterbegin','<input type="checkbox" contenteditable="false"> ')}}
function closest(tag){let n=getSelection().anchorNode;while(n&&n!==$('#editor')){if(n.nodeType===1&&n.tagName===tag)return n;n=n.parentNode}return null}
function stateTools(){['bold','italic','underline','strikeThrough'].forEach(c=>document.querySelector(`[data-cmd="${c}"]`)?.classList.toggle('active',document.queryCommandState(c)))}
function markdown(){let sel=getSelection(),node=sel.anchorNode;if(!node)return;let p=node.nodeType===1?node:node.parentElement;while(p&&p!==$('#editor')&&!/^(P|DIV|LI|H1|H2|H3|BLOCKQUOTE)$/.test(p.tagName))p=p.parentElement;if(!p||p===$('#editor'))return;let text=p.textContent.replace(/[\s\u00a0]+/g,''),m=text.match(/^(###|##|#|-|>|\[\])$/);if(!m)return;let type=m[1],tag=type.startsWith('#')?'h'+type.length:type==='>'?'blockquote':null;if(tag){let el=document.createElement(tag);el.appendChild(document.createElement('br'));p.replaceWith(el);let r=document.createRange();r.selectNodeContents(el);r.collapse(true);sel.removeAllRanges();sel.addRange(r)}else{p.textContent='';let r=document.createRange();r.selectNodeContents(p);r.collapse(true);sel.removeAllRanges();sel.addRange(r);if(type==='-')document.execCommand('insertUnorderedList');else checkList()}commit()}
/* ── Events ──────────────────────────────────────────────────────── */
$('#editor').addEventListener('input',()=>{markdown();commit()});$('#editor').addEventListener('click',e=>{if(e.target.matches('input[type=checkbox]')){e.target.parentElement.classList.toggle('done',e.target.checked);commit()}});$('#editor').addEventListener('paste',e=>{e.preventDefault();let html=e.clipboardData.getData('text/html'),text=e.clipboardData.getData('text/plain');document.execCommand('insertHTML',false,sanitize(html||esc(text).replace(/\n/g,'<br>')));commit()});$('#editor').addEventListener('keydown',e=>{if((e.ctrlKey||e.metaKey)&&['b','i','u'].includes(e.key.toLowerCase())){e.preventDefault();cmd({b:'bold',i:'italic',u:'underline'}[e.key.toLowerCase()])}if((e.ctrlKey||e.metaKey)&&e.key==='z'){e.preventDefault();restoreHistory(e.shiftKey?1:-1)}if(e.key==='Enter')setTimeout(()=>{commit()},0)});document.addEventListener('selectionchange',()=>{if(document.activeElement===$('#editor'))stateTools()});
$('#toolbar').onclick=e=>{let b=e.target.closest('button');if(!b)return;if(b.id==='undo')restoreHistory(-1);else if(b.id==='redo')restoreHistory(1);else if(b.dataset.cmd)cmd(b.dataset.cmd);else if(b.dataset.block)block(b.dataset.block)};
function restoreHistory(d){let n=current(),p=(histPos[n.id]??0)+d;if(history[n.id]&&history[n.id][p]!=null){histPos[n.id]=p;$('#editor').innerHTML=history[n.id][p];commit()}}
$('#newNote').onclick=()=>{let book=S.view==='all'||S.view==='trash'?S.notebooks[0]?.id:S.view;if(!book){S.notebooks.push({id:uid(),name:'Notebook'});book=S.notebooks[0].id}let n={id:uid(),notebookId:book,title:'Untitled',html:'<p><br></p>',tags:[],pinned:false,created:now(),updated:now(),trashed:false,originalNotebookId:null};S.notes.unshift(n);S.selected=n.id;S.view=book;save();render();setTimeout(()=>$('#editor').focus(),0)};
$('#noteList').onclick=e=>{let tag=e.target.closest('[data-tag]');if(tag){S.tag=tag.dataset.tag;renderList();return}let el=e.target.closest('[data-note]');if(el){S.selected=el.dataset.note;save();render()}};
$('#books').onclick=e=>{let menu=e.target.closest('[data-bookmenu]');if(menu){e.stopPropagation();bookMenu(menu.dataset.book,menu.getBoundingClientRect());return}let b=e.target.closest('[data-book]');if(b){S.view=b.dataset.book;S.tag=null;render()}};document.querySelector('.side-scroll').onclick=e=>{let v=e.target.closest('[data-view]');if(v){S.view=v.dataset.view;S.tag=null;render()}};
$('#search').oninput=e=>{S.query=e.target.value;renderList()};$('#sort').onclick=()=>{S.sort=S.sort==='modified'?'created':S.sort==='created'?'alpha':'modified';save();renderList()};$('#pinBtn').onclick=()=>{let n=current();if(n){n.pinned=!n.pinned;n.updated=now();save();render()}};
function popup(html,x,y){$('#pop').innerHTML=`<div class="menu" style="left:${x}px;top:${y}px">${html}</div>`;setTimeout(()=>document.addEventListener('click',()=>$('#pop').innerHTML='',{once:true}),0)}
$('#moreBtn').onclick=e=>{let n=current();if(!n)return;let books=S.notebooks.map(b=>`<button data-move="${b.id}">Move to ${esc(b.name)}</button>`).join('');popup(`<button data-action="duplicate">Duplicate</button><button data-action="delete" class="danger">${n.trashed?'Delete permanently':'Move to Trash'}</button>${n.trashed?'<button data-action="restore">Restore note</button>':books}`,e.target.getBoundingClientRect().left-140,48)};
$('#pop').onclick=e=>{let a=e.target.dataset.action,m=e.target.dataset.move,n=current();if(m){n.notebookId=m;n.trashed=false}if(a==='duplicate'){let c=JSON.parse(JSON.stringify(n));c.id=uid();c.title+=' copy';c.created=c.updated=now();S.notes.unshift(c);S.selected=c.id}if(a==='delete'){if(n.trashed)S.notes=S.notes.filter(x=>x.id!==n.id);else{n.originalNotebookId=n.notebookId;n.trashed=true;n.pinned=false}S.selected=null}if(a==='restore'){n.trashed=false;n.notebookId=n.originalNotebookId||n.notebookId;S.selected=n.id;S.view=n.notebookId}save();render()};
function bookMenu(id,r){let b=S.notebooks.find(x=>x.id===id);popup(`<button data-baction="rename" data-id="${id}">Rename</button><button data-baction="delete" data-id="${id}" class="danger">Delete notebook</button>`,r.left-120,r.bottom)}$('#pop').addEventListener('click',e=>{let a=e.target.dataset.baction,id=e.target.dataset.id;if(!a)return;let b=S.notebooks.find(x=>x.id===id);if(a==='rename')ask('Rename notebook',b.name,v=>{b.name=v;save();render()});if(a==='delete'){S.notes.filter(n=>n.notebookId===id&&!n.trashed).forEach(n=>{n.originalNotebookId=id;n.trashed=true});S.notebooks=S.notebooks.filter(b=>b.id!==id);S.view='all';save();render()}});
function ask(title,value,done){let x=document.createElement('div');x.className='modal-back';x.innerHTML=`<div class="modal"><h3>${title}</h3><input value="${esc(value)}"><div class="modal-actions"><button class="muted">Cancel</button><button class="primary">Save</button></div></div>`;document.body.append(x);let i=x.querySelector('input');i.focus();i.select();x.querySelector('.primary').onclick=()=>{if(i.value.trim())done(i.value.trim());x.remove()};x.querySelector('.muted').onclick=()=>x.remove();i.onkeydown=e=>{if(e.key==='Enter')x.querySelector('.primary').click()}}
$('#addBook').onclick=()=>ask('New notebook','',v=>{let b={id:uid(),name:v};S.notebooks.push(b);S.view=b.id;save();render()});$('#tagsbar').onclick=e=>{if(e.target.id==='addTag'){ask('Add a tag','',v=>{let n=current();if(!n.tags.includes(v))n.tags.push(v);save();render()});return}let t=e.target.dataset.tag;if(t){let n=current();n.tags=n.tags.filter(x=>x!==t);save();render()}};
$('#collapse').onclick=()=>{S.layout.collapsed=!S.layout.collapsed;save();render()};$('#theme').onclick=()=>{S.dark=!S.dark;save();render()};
function dragResize(el,key,min,max){let on=false;el.onmousedown=e=>{on=true;el.classList.add('drag');document.body.style.userSelect='none';e.preventDefault()};document.addEventListener('mousemove',e=>{if(!on)return;S.layout[key]=Math.max(min,Math.min(max,e.clientX-(key==='list'?S.layout.side+5:0)));render()});document.addEventListener('mouseup',()=>{if(on){on=false;el.classList.remove('drag');document.body.style.userSelect='';save()}})}dragResize($('#sideResize'),'side',160,420);dragResize($('#listResize'),'list',180,500);
document.addEventListener('dragstart',e=>{let c=e.target.closest('[data-note]');if(c)e.dataTransfer.setData('note',c.dataset.note)});$('#books').addEventListener('dragover',e=>e.preventDefault());$('#books').addEventListener('drop',e=>{let b=e.target.closest('[data-book]'),id=e.dataTransfer.getData('note');if(b&&id){let n=S.notes.find(x=>x.id===id);n.notebookId=b.dataset.book;n.trashed=false;n.updated=now();save();render()}});
render();
</script></body></html>
<!-- agent-meta {"model":"openai/gpt-5.6-terra","provider":"openrouter","persona":"full","sessionId":"02786838-645a-476a-96f7-003613e2708b","tokensIn":428464,"tokensOut":12515,"tokensTotal":440979,"turns":28,"toolCalls":27,"failedToolCalls":0,"timestamp":"2026-07-31T19:27:15.764Z"} -->