← Notes results

Notes

Gemma 4 31b it · middle

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 21,798 bytes · SHA-256 bf5b44601a3f
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>ZenNotes | Modern Knowledge Base</title>
    <script src="https://cdn.tailwindcss.com"></script>
    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css">
    <style>
        @import url('https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600;700&family=JetBrains+Mono&display=swap');
        
        :root {
            --sidebar-bg: #f9fafb;
            --active-note-bg: #eff6ff;
            --accent-color: #3b82f6;
        }

        body {
            font-family: 'Inter', sans-serif;
            overflow: hidden;
        }

        .custom-scrollbar::-webkit-scrollbar {
            width: 6px;
        }
        .custom-scrollbar::-webkit-scrollbar-track {
            background: transparent;
        }
        .custom-scrollbar::-webkit-scrollbar-thumb {
            background: #e5e7eb;
            border-radius: 10px;
        }
        .custom-scrollbar::-webkit-scrollbar-thumb:hover {
            background: #d1d5db;
        }

        .editor-content:focus {
            outline: none;
        }

        .note-item.active {
            background-color: var(--active-note-bg);
            border-left: 4px solid var(--accent-color);
        }

        .transition-all-custom {
            transition: all 0.2s cubic-bezier(0.4, 0, 0.2, 1);
        }
    </style>
</head>
<body class="bg-white text-slate-800">

    <div class="flex h-screen w-full overflow-hidden">
        <!-- Sidebar Left (Navigation) -->
        <aside class="w-64 bg-slate-50 border-r border-slate-200 flex flex-col transition-all-custom" id="main-sidebar">
            <div class="p-4 flex items-center justify-between">
                <div class="flex items-center gap-2 font-bold text-slate-700 text-lg">
                    <div class="w-8 h-8 bg-blue-600 rounded-lg flex items-center justify-center text-white">
                        <i class="fas fa-feather-alt text-sm"></i>
                    </div>
                    <span>ZenNotes</span>
                </div>
                <button id="collapse-sidebar" class="text-slate-400 hover:text-slate-600">
                    <i class="fas fa-bars"></i>
                </button>
            </div>

            <div class="px-4 mb-6">
                <button id="new-note-btn" class="w-full bg-blue-600 hover:bg-blue-700 text-white py-2 px-4 rounded-lg shadow-sm flex items-center justify-center gap-2 transition-all-custom font-medium">
                    <i class="fas fa-plus"></i> New Note
                </button>
            </div>

            <nav class="flex-1 overflow-y-auto custom-scrollbar px-2 space-y-6">
                <!-- Section: Favorites -->
                <div>
                    <div class="px-3 text-xs font-semibold text-slate-400 uppercase tracking-wider mb-2 flex justify-between items-center">
                        <span>Favorites</span>
                        <i class="fas fa-star text-[10px]"></i>
                    </div>
                    <ul class="space-y-1" id="favorites-list">
                        <!-- Dynamic -->
                    </ul>
                </div>

                <!-- Section: Notebooks -->
                <div>
                    <div class="px-3 text-xs font-semibold text-slate-400 uppercase tracking-wider mb-2 flex justify-between items-center">
                        <span>Notebooks</span>
                        <button class="hover:text-slate-600"><i class="fas fa-plus text-[10px]"></i></button>
                    </div>
                    <ul class="space-y-1" id="notebooks-list">
                        <!-- Dynamic -->
                    </ul>
                </div>

                <!-- Section: Tags -->
                <div>
                    <div class="px-3 text-xs font-semibold text-slate-400 uppercase tracking-wider mb-2 flex justify-between items-center">
                        <span>Tags</span>
                    </div>
                    <ul class="space-y-1 px-2" id="tags-list">
                        <!-- Dynamic -->
                    </ul>
                </div>
            </nav>

            <div class="p-4 border-t border-slate-200">
                <div class="flex items-center gap-3 p-2 hover:bg-slate-100 rounded-lg cursor-pointer transition-all-custom">
                    <div class="w-8 h-8 bg-slate-300 rounded-full overflow-hidden">
                        <img src="https://api.dicebear.com/7.x/avataaars/svg?seed=Felix" alt="User">
                    </div>
                    <span class="text-sm font-medium text-slate-600">Alex Rivers</span>
                    <i class="fas fa-cog ml-auto text-slate-400 text-xs"></i>
                </div>
            </div>
        </aside>

        <!-- Sidebar Middle (Note List) -->
        <aside class="w-80 border-r border-slate-200 flex flex-col bg-white" id="note-list-sidebar">
            <div class="p-4 border-b border-slate-100">
                <div class="relative">
                    <i class="fas fa-search absolute left-3 top-1/2 -translate-y-1/2 text-slate-400 text-sm"></i>
                    <input type="text" id="search-notes" placeholder="Search notes..." class="w-full pl-9 pr-4 py-2 bg-slate-100 border-transparent focus:bg-white focus:ring-2 focus:ring-blue-500 focus:border-transparent rounded-md text-sm transition-all-custom outline-none">
                </div>
            </div>

            <div class="flex-1 overflow-y-auto custom-scrollbar" id="notes-container">
                <!-- Note items rendered here -->
            </div>
        </aside>

        <!-- Main Content (Editor) -->
        <main class="flex-1 flex flex-col bg-white relative">
            <!-- Toolbar -->
            <header class="h-14 border-b border-slate-100 flex items-center justify-between px-6">
                <div class="flex items-center gap-4">
                    <div class="flex items-center gap-1 text-slate-400 text-xs">
                        <i class="fas fa-folder-open"></i>
                        <span id="current-notebook-breadcrumb">General</span>
                        <i class="fas fa-chevron-right text-[8px]"></i>
                        <span id="current-note-breadcrumb" class="text-slate-600 font-medium">Welcome Note</span>
                    </div>
                </div>
                <div class="flex items-center gap-3">
                    <button id="star-note" class="w-9 h-9 rounded-full hover:bg-slate-100 text-slate-400 hover:text-yellow-500 transition-all-custom flex items-center justify-center">
                        <i class="far fa-star"></i>
                    </button>
                    <button id="delete-note" class="w-9 h-9 rounded-full hover:bg-red-50 text-slate-400 hover:text-red-500 transition-all-custom flex items-center justify-center">
                        <i class="far fa-trash-alt"></i>
                    </button>
                    <div class="h-6 w-px bg-slate-200 mx-1"></div>
                    <button class="bg-slate-800 text-white px-4 py-1.5 rounded-md text-sm font-medium hover:bg-slate-900 transition-all-custom">
                        Share
                    </button>
                </div>
            </header>

            <!-- Editor -->
            <div class="flex-1 overflow-y-auto custom-scrollbar p-8 md:p-16 lg:px-32">
                <div class="max-w-3xl mx-auto">
                    <input type="text" id="note-title" placeholder="Note Title" class="w-full text-4xl font-bold mb-6 outline-none border-none placeholder-slate-300" value="Welcome Note">
                    
                    <!-- Formatting Toolbar -->
                    <div class="flex items-center gap-2 mb-6 p-1 bg-slate-50 w-fit rounded-lg border border-slate-200 sticky top-0 z-10">
                        <button onclick="execCmd('bold')" class="w-8 h-8 hover:bg-white hover:shadow-sm rounded flex items-center justify-center text-slate-600 transition-all-custom" title="Bold"><i class="fas fa-bold"></i></button>
                        <button onclick="execCmd('italic')" class="w-8 h-8 hover:bg-white hover:shadow-sm rounded flex items-center justify-center text-slate-600 transition-all-custom" title="Italic"><i class="fas fa-italic"></i></button>
                        <div class="w-px h-4 bg-slate-300 mx-1"></div>
                        <button onclick="execCmd('insertUnorderedList')" class="w-8 h-8 hover:bg-white hover:shadow-sm rounded flex items-center justify-center text-slate-600 transition-all-custom" title="Bullet List"><i class="fas fa-list-ul"></i></button>
                        <button onclick="execCmd('insertOrderedList')" class="w-8 h-8 hover:bg-white hover:shadow-sm rounded flex items-center justify-center text-slate-600 transition-all-custom" title="Numbered List"><i class="fas fa-list-ol"></i></button>
                        <div class="w-px h-4 bg-slate-300 mx-1"></div>
                        <button onclick="execCmd('formatBlock', 'h1')" class="w-8 h-8 hover:bg-white hover:shadow-sm rounded flex items-center justify-center text-slate-600 transition-all-custom font-bold text-xs">H1</button>
                        <button onclick="execCmd('formatBlock', 'h2')" class="w-8 h-8 hover:bg-white hover:shadow-sm rounded flex items-center justify-center text-slate-600 transition-all-custom font-bold text-xs">H2</button>
                        <div class="w-px h-4 bg-slate-300 mx-1"></div>
                        <button onclick="insertChecklist()" class="w-8 h-8 hover:bg-white hover:shadow-sm rounded flex items-center justify-center text-slate-600 transition-all-custom" title="Checklist"><i class="far fa-check-square"></i></button>
                        <button onclick="execCmd('createLink', prompt('Enter URL:'))" class="w-8 h-8 hover:bg-white hover:shadow-sm rounded flex items-center justify-center text-slate-600 transition-all-custom" title="Link"><i class="fas fa-link"></i></button>
                    </div>

                    <div id="editor" contenteditable="true" class="editor-content text-lg leading-relaxed text-slate-700 min-h-[500px] focus:outline-none">
                        <p>Welcome to <b>ZenNotes</b>!</p>
                        <p>This is a prototype for a modern knowledge management system. You can:</p>
                        <ul>
                            <li>Create notebooks to organize your thoughts</li>
                            <li>Use tags to link disparate ideas</li>
                            <li>Format your text with the toolbar above</li>
                        </ul>
                        <p>Try creating a new note or switching between existing ones in the sidebar.</p>
                    </div>
                </div>
            </div>
        </main>
    </div>

    <script>
        // --- State Management ---
        const state = {
            notes: [
                { id: '1', title: 'Welcome Note', content: '<p>Welcome to <b>ZenNotes</b>!</p><p>This is a prototype for a modern knowledge management system.</p>', notebookId: 'nb1', tags: ['tutorial', 'intro'], favorite: true, updated: new Date() },
                { id: '2', title: 'Project Ideas 🚀', content: '<p>1. AI-powered garden monitor</p><p>2. Local-first note app (like this one!)</p>', notebookId: 'nb1', tags: ['work', 'ideas'], favorite: false, updated: new Date(Date.now() - 86400000) },
                { id: '3', title: 'Grocery List', content: '<ul><li>Milk</li><li>Eggs</li><li>Avocado</li></ul>', notebookId: 'nb2', tags: ['personal'], favorite: false, updated: new Date(Date.now() - 172800000) },
                { id: '4', title: 'Reading List 2024', content: '<p>Books to read this year...</p>', notebookId: 'nb3', tags: ['personal', 'learning'], favorite: true, updated: new Date(Date.now() - 259200000) },
            ],
            notebooks: [
                { id: 'nb1', name: 'General', icon: 'fa-folder' },
                { id: 'nb2', name: 'Personal', icon: 'fa-user' },
                { id: 'nb3', name: 'Learning', icon: 'fa-graduation-cap' },
            ],
            tags: ['tutorial', 'intro', 'work', 'ideas', 'personal', 'learning'],
            activeNoteId: '1',
            activeNotebookId: null, // null means "All Notes"
        };

        // --- DOM Elements ---
        const notesContainer = document.getElementById('notes-container');
        const notebooksList = document.getElementById('notebooks-list');
        const tagsList = document.getElementById('tags-list');
        const favoritesList = document.getElementById('favorites-list');
        const editor = document.getElementById('editor');
        const titleInput = document.getElementById('note-title');
        const currentNotebookBreadcrumb = document.getElementById('current-notebook-breadcrumb');
        const currentNoteBreadcrumb = document.getElementById('current-note-breadcrumb');
        const starBtn = document.getElementById('star-note');
        const deleteBtn = document.getElementById('delete-note');

        // --- Initialization ---
        function init() {
            renderNotebooks();
            renderTags();
            renderNotes();
            loadNote(state.activeNoteId);
            setupEventListeners();
        }

        // --- Rendering Logic ---
        function renderNotebooks() {
            notebooksList.innerHTML = `
                <li onclick="filterByNotebook(null)" class="px-3 py-2 text-sm rounded-md cursor-pointer transition-all-custom ${state.activeNotebookId === null ? 'bg-blue-50 text-blue-600 font-medium' : 'text-slate-600 hover:bg-slate-100'}">
                    <i class="fas fa-layer-group mr-2 opacity-70"></i> All Notes
                </li>
            `;
            state.notebooks.forEach(nb => {
                notebooksList.innerHTML += `
                    <li onclick="filterByNotebook('${nb.id}')" class="px-3 py-2 text-sm rounded-md cursor-pointer transition-all-custom ${state.activeNotebookId === nb.id ? 'bg-blue-50 text-blue-600 font-medium' : 'text-slate-600 hover:bg-slate-100'}">
                        <i class="fas ${nb.icon} mr-2 opacity-70"></i> ${nb.name}
                    </li>
                `;
            });
        }

        function renderTags() {
            tagsList.innerHTML = state.tags.map(tag => `
                <li onclick="filterByTag('${tag}')" class="px-3 py-1 text-xs rounded-full cursor-pointer transition-all-custom bg-slate-100 text-slate-500 hover:bg-slate-200 w-fit mb-1">
                    #${tag}
                </li>
            `).join('');
        }

        function renderNotes(filteredNotes = null) {
            const notesToRender = filteredNotes || state.notes;
            notesContainer.innerHTML = '';

            if (notesToRender.length === 0) {
                notesContainer.innerHTML = `<div class="p-8 text-center text-slate-400 text-sm">No notes found</div>`;
                return;
            }

            notesToRender.sort((a, b) => b.updated - a.updated).forEach(note => {
                const isActive = note.id === state.activeNoteId;
                const dateStr = note.updated.toLocaleDateString([], { month: 'short', day: 'numeric' });
                
                const div = document.createElement('div');
                div.className = `note-item p-4 cursor-pointer transition-all-custom border-b border-slate-50 ${isActive ? 'active' : 'hover:bg-slate-50'}`;
                div.onclick = () => loadNote(note.id);
                div.innerHTML = `
                    <div class="flex justify-between items-start mb-1">
                        <h4 class="font-semibold text-sm truncate pr-2 ${isActive ? 'text-blue-700' : 'text-slate-700'}">${note.title || 'Untitled'}</h4>
                        <span class="text-[10px] text-slate-400 whitespace-nowrap">${dateStr}</span>
                    </div>
                    <p class="text-xs text-slate-500 line-clamp-2 leading-relaxed">${stripHtml(note.content)}</p>
                `;
                notesContainer.appendChild(div);
            });

            // Favorites List
            const favs = state.notes.filter(n => n.favorite);
            favoritesList.innerHTML = favs.map(note => `
                <li onclick="loadNote('${note.id}')" class="px-3 py-2 text-sm rounded-md cursor-pointer transition-all-custom ${note.id === state.activeNoteId ? 'bg-blue-50 text-blue-600 font-medium' : 'text-slate-600 hover:bg-slate-100'}">
                    <i class="fas fa-star text-yellow-400 mr-2 text-[10px]"></i> ${note.title}
                </li>
            `).join('');
        }

        function loadNote(id) {
            const note = state.notes.find(n => n.id === id);
            if (!note) return;

            state.activeNoteId = id;
            
            // Update UI
            titleInput.value = note.title;
            editor.innerHTML = note.content;
            
            // Breadcrumb
            const nb = state.notebooks.find(n => n.id === note.notebookId);
            currentNotebookBreadcrumb.innerText = nb ? nb.name : 'General';
            currentNoteBreadcrumb.innerText = note.title;

            // Star button
            starBtn.innerHTML = note.favorite ? '<i class="fas fa-star text-yellow-400"></i>' : '<i class="far fa-star"></i>';

            renderNotes();
            renderNotebooks();
        }

        // --- Actions ---
        function filterByNotebook(id) {
            state.activeNotebookId = id;
            const filtered = id ? state.notes.filter(n => n.notebookId === id) : state.notes;
            renderNotes(filtered);
            renderNotebooks();
        }

        function filterByTag(tag) {
            const filtered = state.notes.filter(n => n.tags.includes(tag));
            renderNotes(filtered);
        }

        function createNewNote() {
            const id = Date.now().toString();
            const newNote = {
                id: id,
                title: 'New Note',
                content: '<p>Start typing...</p>',
                notebookId: state.activeNotebookId || 'nb1',
                tags: [],
                favorite: false,
                updated: new Date()
            };
            state.notes.unshift(newNote);
            loadNote(id);
        }

        function deleteCurrentNote() {
            if (state.notes.length <= 1) {
                alert("You must have at least one note.");
                return;
            }
            state.notes = state.notes.filter(n => n.id !== state.activeNoteId);
            loadNote(state.notes[0].id);
        }

        function toggleFavorite() {
            const note = state.notes.find(n => n.id === state.activeNoteId);
            if (note) {
                note.favorite = !note.favorite;
                loadNote(note.id);
            }
        }

        // --- Editor Helpers ---
        function execCmd(command, value = null) {
            document.execCommand(command, false, value);
        }

        function insertChecklist() {
            const checkboxHtml = '<div><input type="checkbox" class="mr-2 accent-blue-600"> <span contenteditable="true">New Task</span></div>';
            document.execCommand('insertHTML', false, checkboxHtml);
        }

        function stripHtml(html) {
            const tmp = document.createElement("DIV");
            tmp.innerHTML = html;
            return tmp.textContent || tmp.innerText || "";
        }

        // --- Events ---
        function setupEventListeners() {
            document.getElementById('new-note-btn').addEventListener('click', createNewNote);
            
            titleInput.addEventListener('input', (e) => {
                const note = state.notes.find(n => n.id === state.activeNoteId);
                if (note) {
                    note.title = e.target.value;
                    note.updated = new Date();
                    currentNoteBreadcrumb.innerText = e.target.value;
                    renderNotes();
                }
            });

            editor.addEventListener('input', () => {
                const note = state.notes.find(n => n.id === state.activeNoteId);
                if (note) {
                    note.content = editor.innerHTML;
                    note.updated = new Date();
                    renderNotes();
                }
            });

            starBtn.addEventListener('click', toggleFavorite);
            deleteBtn.addEventListener('click', deleteCurrentNote);

            document.getElementById('search-notes').addEventListener('input', (e) => {
                const query = e.target.value.toLowerCase();
                const filtered = state.notes.filter(n => 
                    n.title.toLowerCase().includes(query) || 
                    n.content.toLowerCase().includes(query)
                );
                renderNotes(filtered);
            });

            document.getElementById('collapse-sidebar').addEventListener('click', () => {
                const sidebar = document.getElementById('main-sidebar');
                sidebar.classList.toggle('w-64');
                sidebar.classList.toggle('w-0');
                sidebar.classList.toggle('opacity-0');
                sidebar.classList.toggle('invisible');
            });
        }

        // Run
        init();
    </script>
</body>
</html>
<!-- agent-meta {"model":"google/gemma-4-31b-it","provider":"openrouter","persona":"middle","sessionId":"8c0b519d-5f35-4eb3-b937-3c937b6e4c1f","tokensIn":9146,"tokensOut":8544,"tokensTotal":17690,"turns":3,"toolCalls":2,"failedToolCalls":1,"timestamp":"2026-07-14T15:32:11.904Z"} -->