Notes
Gemma 4 12b qat · middle

Browser check: Artifact runtime error. This is a technical check, not a quality review.
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 16,019 bytes · SHA-256 0133d03f31b9
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Lumina Notes</title>
<style>
:root {
--bg-primary: #ffffff;
--bg-secondary: #f9fafb;
--bg-sidebar: #f3f4f6;
--border-color: #e5e7eb;
--text-main: #111827;
--text-muted: #6b7280;
--accent: #6366f1;
--accent-hover: #4f46e5;
--hover-bg: #f3f4f6;
--font-family: 'Inter', -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
--sidebar-width: 260px;
--note-list-width: 300px;
}
[data-theme="dark"] {
--bg-primary: #111827;
--bg-secondary: #1f2937;
--bg-sidebar: #0f172a;
--border-color: #374151;
--text-main: #f9fafb;
--text-muted: #9ca3af;
--accent: #818cf8;
--accent-hover: #a5b4fc;
--hover-bg: #1f2937;
}
* {
margin: 0;
padding: 0;
box-sizing: border-box;
-webkit-font-smoothing: antialiased;
}
body {
font-family: var(--font-family);
background-color: var(--bg-primary);
color: var(--text-main);
height: 100vh;
overflow: hidden;
display: flex;
}
/* Layout Components */
.sidebar {
width: var(--sidebar-width);
background-color: var(--bg-sidebar);
border-right: 1px solid var(--border-color);
display: flex;
flex-direction: column;
transition: transform 0.3s ease;
}
.note-list {
width: var(--note-list-width);
background-color: var(--bg-secondary);
border-right: 1px solid var(--border-color);
display: flex;
flex-direction: column;
}
.editor-container {
flex: 1;
display: flex;
flex-direction: column;
background-color: var(--bg-primary);
max-width: 900px;
margin: 0 auto;
width: 100%;
padding: 40px 60px;
overflow-y: auto;
}
/* Sidebar Header */
.sidebar-header {
padding: 20px;
font-weight: 800;
font-size: 1.2rem;
display: flex;
justify-content: space-between;
align-items: center;
}
.sidebar-nav {
padding: 10px;
flex: 1;
overflow-y: auto;
}
.nav-group {
margin-bottom: 20px;
}
.nav-group-title {
font-size: 0.75rem;
text-transform: uppercase;
letter-spacing: 0.05em;
color: var(--text-muted);
margin-bottom: 8px;
padding-left: 10px;
}
.nav-item {
padding: 8px 12px;
border-radius: 6px;
cursor: pointer;
font-size: 0.9rem;
display: flex;
align-items: center;
gap: 8px;
transition: background 0.2s;
}
.nav-item:hover {
background-color: var(--hover-bg);
}
.nav-item.active {
background-color: var(--accent);
color: white;
}
/* Note List Styles */
.list-header {
padding: 15px;
border-bottom: 1px solid var(--border-color);
}
.search-input {
width: 100%;
padding: 8px 12px;
border-radius: 6px;
border: 1px solid var(--border-color);
background: var(--bg-primary);
color: var(--text-main);
outline: none;
}
.note-item {
padding: 15px;
border-bottom: 1px solid var(--border-color);
cursor: pointer;
transition: background 0.2s;
}
.note-item:hover {
background-color: var(--hover-bg);
}
.note-item.active {
background-color: var(--hover-bg);
border-left: 3px solid var(--accent);
}
.note-item .title {
font-weight: 600;
font-size: 0.95rem;
margin-bottom: 4px;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
.note-item .preview {
font-size: 0.8rem;
color: var(--text-muted);
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
/* Editor Styles */
.editor-header {
margin-bottom: 30px;
}
.editor-title {
font-size: 2.5rem;
font-weight: 800;
border: none;
outline: none;
background: transparent;
color: var(--text-main);
width: 100%;
margin-bottom: 10px;
}
.editor-content {
font-size: 1.1rem;
line-height: 1.7;
border: none;
outline: none;
background: transparent;
color: var(--text-main);
width: 100%;
resize: none;
min-height: 400px;
}
/* Buttons & Controls */
.btn {
padding: 8px 16px;
border-radius: 6px;
border: none;
cursor: pointer;
font-weight: 600;
transition: all 0.2s;
font-size: 0.875rem;
}
.btn-primary {
background-color: var(--accent);
color: white;
}
.btn-primary:hover {
background-color: var(--accent-hover);
}
.btn-ghost {
background: transparent;
border: 1px solid var(--border-color);
color: var(--text-main);
}
.btn-ghost:hover {
background: var(--hover-bg);
}
.toolbar {
position: fixed;
top: 20px;
right: 20px;
display: flex;
gap: 10px;
z-index: 100;
}
/* Scrollbars */
::-webkit-scrollbar {
width: 6px;
}
::-webkit-scrollbar-track {
background: transparent;
}
::-webkit-scrollbar-thumb {
background: var(--border-color);
border-radius: 10px;
}
/* Utility */
.hidden {
display: none;
}
.flex-1 {
flex: 1;
}
.mt-4 {
margin-top: 4px;
}
</style>
</head>
<body data-theme="light">
<aside class="sidebar">
<div class="sidebar-header">
<span>Lumina</span>
<button class="btn btn-ghost" id="themeToggle">🌓</button>
</div>
<nav class="sidebar-nav">
<div class="nav-group">
<div class="nav-group-title">Workspace</div>
<div class="nav-item active" data-type="all">🏠 All Notes</div>
<div class="nav-item" data-type="favorites">⭐ Favorites</div>
<div class="nav-item" data-type="trash">🗑️ Trash</div>
</div>
<div class="nav-group">
<div class="nav-group-title">Folders</div>
<div id="folder-list">
<!-- Folders injected here -->
</div>
<div class="nav-item" style="font-size: 0.8rem; color: var(--text-muted);" id="add-folder">+ New Folder</div>
</div>
</nav>
</aside>
<aside class="note-list">
<div class="list-header">
<input type="text" class="search-input" id="noteSearch" placeholder="Search notes...">
</div>
<div id="note-items-container" style="overflow-y: auto;">
<!-- Notes injected here -->
</div>
<div style="padding: 20px;">
<button class="btn btn-primary" style="width: 100%;" id="newNoteBtn">+ New Note</button>
</div>
</aside>
<main class="editor-container">
<div class="toolbar">
<button class="btn btn-ghost" id="deleteNoteBtn">Delete</button>
<button class="btn btn-ghost" id="shareBtn">Share</button>
</div>
<div id="editor-view" class="hidden">
<input type="text" class="editor-title" id="noteTitle" placeholder="Untitled Note">
<textarea class="editor-content" id="noteContent" placeholder="Start typing..."></textarea>
</div>
<div id="empty-state" style="text-align: center; margin-top: 20vh; color: var(--text-muted);">
<p>Select a note or create a new one to begin.</p>
</div>
</main>
<script>
// --- State Management ---
let state = {
notes: JSON.parse(localStorage.getItem('lumina_notes')) || [
{ id: '1', title: 'Welcome to Lumina', content: 'This is a prototype of a beautiful notes application.', folderId: null, favorites: false, updatedAt: Date.now() },
{ id: '2', title: 'Getting Started', content: 'You can create, edit, and delete notes. They are saved automatically to your browser storage.', folderId: null, favorites: false, updatedAt: Date.now() }
],
activeNoteId: null,
activeFilter: 'all',
folders: JSON.parse(localStorage.getItem('lumina_folders')) || [{ id: 'f1', name: 'Personal' }, { id: 'f2', name: 'Work' }],
theme: localStorage.getItem('lumina_theme') || 'light'
};
// --- DOM Elements ---
const noteItemsContainer = document.getElementById('note-items-container');
const noteTitle = document.getElementById('noteTitle');
const noteContent = document.getElementById('noteContent');
const editorView = document.getElementById('editor-view');
const emptyState = document.getElementById('empty-state');
const themeToggle = document.getElementById('themeToggle');
const searchInput = document.getElementById('noteSearch');
const newNoteBtn = document.getElementById('newNoteBtn');
const deleteNoteBtn = document.getElementById('deleteNoteBtn');
const folderList = document.getElementById('folder-list');
const navItems = document.querySelectorAll('.nav-item[data-type]');
// --- Core Functions ---
function saveToLocalStorage() {
localStorage.setItem('lumina_notes', JSON.stringify(state.notes));
localStorage.setItem('lumina_folders', JSON.stringify(state.folders));
localStorage.setItem('lumina_theme', state.theme);
}
function render() {
renderNotes();
renderFolders();
applyTheme();
}
function renderNotes() {
const searchTerm = searchInput.value.toLowerCase();
noteItemsContainer.innerHTML = '';
let filteredNotes = state.notes;
if (state.activeFilter === 'favorites') {
filteredNotes = filteredNotes.filter(n => n.favorites);
} else if (state.activeFilter === 'trash') {
filteredNotes = filteredNotes.filter(n => n.deleted);
} else if (state.activeFilter !== 'all') {
filteredNotes = filteredNotes.filter(n => n.folderId === state.activeFilter);
}
filteredNotes = filteredNotes.filter(n =>
n.title.toLowerCase().includes(searchTerm) ||
n.content.toLowerCase().includes(searchTerm)
);
// Sort by date
filteredNotes.sort((a, b) => b.updatedAt - a.updatedAt);
filteredNotes.forEach(note => {
const div = document.createElement('div');
div.className = `note-item ${state.activeNoteId === note.id ? 'active' : ''}`;
div.innerHTML = `
<div class="title">${note.title || 'Untitled'}</div>
<div class="preview">${note.content.substring(0, 50).replace(/\n/g, ' ')}</div>
`;
div.onclick = () => selectNote(note.id);
noteItemsContainer.appendChild(div);
});
}
function renderFolders() {
folderList.innerHTML = '';
state.folders.forEach(folder => {
const div = document.createElement('div');
div.className = `nav-item ${state.activeFilter === folder.id ? 'active' : ''}`;
div.innerHTML = `📁 ${folder.name}`;
div.onclick = () => {
state.activeFilter = folder.id;
render();
};
folderList.appendChild(div);
});
}
function selectNote(id) {
state.activeNoteId = id;
const note = state.notes.find(n => n.id === id);
if (note) {
editorView.classList.remove('hidden');
emptyState.classList.add('hidden');
noteTitle.value = note.title;
noteContent.value = note.content;
// Update active state in list
renderNotes();
}
}
// --- Event Listeners ---
newNoteBtn.onclick = () => {
const newNote = {
id: Date.now().toString(),
title: '',
content: '',
folderId: state.activeFilter === 'all' ? null : state.activeFilter,
favorites: false,
updatedAt: Date.now()
};
state.notes.unshift(newNote);
state.activeNoteId = newNote.id;
saveToLocalStorage();
render();
selectNote(newNote.id);
};
noteTitle.oninput = (e) => {
const note = state.notes.find(n => n.id === state.activeNoteId);
if (note) {
note.title = e.target.value;
note.updatedAt = Date.now();
saveToLocalStorage();
renderNotes();
}
};
noteContent.oninput = (e) => {
const note = state.notes.find(n => n.id === state.activeNoteId);
if (note) {
note.content = e.target.value;
note.updatedAt = Date.now();
saveToLocalStorage();
}
};
deleteNoteBtn.onclick = () => {
if (!state.activeNoteId) return;
if (confirm('Delete this note?')) {
state.notes = state.notes.filter(n => n.id !== state.activeNoteId);
state.activeNoteId = null;
editorView.classList.add('hidden');
emptyState.classList.remove('hidden');
saveToLocalStorage();
render();
}
};
themeToggle.onclick = () => {
state.theme = state.theme === 'light' ? 'dark' : 'light';
saveToLocalStorage();
render();
};
searchInput.oninput = () => {
renderNotes();
};
navItems.forEach(item => {
item.onclick = (e) => {
e.stopPropagation();
state.activeFilter = item.dataset.type;
render();
};
});
// Initialize
render();
</script>
</body>
</html>
<!-- agent-meta {"model":"google/gemma-4-12b-qat","provider":"lmstudio","persona":"middle","sessionId":"03b89afa-3192-4bff-bc0e-332206ee65cd","tokensIn":6010,"tokensOut":5133,"tokensTotal":11143,"turns":2,"toolCalls":1,"failedToolCalls":0,"timestamp":"2026-07-12T04:31:24.088Z"} -->