← Notes results

Notes

inkling · 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 35,087 bytes · SHA-256 ca21a86e0c4f
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Lumina Notes — Think in layers</title>
  <script src="https://cdn.tailwindcss.com"></script>
  <link rel="preconnect" href="https://fonts.googleapis.com">
  <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
  <link href="https://fonts.googleapis.com/css2?family=Cormorant+Garamond:ital,wght@1,400;1,600&family=DM+Sans:ital,opsz,wght@0,9..40,300;0,9..40,400;0,9..40,500;0,9..40,600;1,9..40,400&family=JetBrains+Mono:wght@300;400&display=swap" rel="stylesheet">
  <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.9.0/styles/github-dark.min.css">
  <script src="https://cdn.jsdelivr.net/npm/lucide@latest/dist/umd/lucide.min.js"></script>
  <script src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.9.0/highlight.min.js"></script>

  <script>
    tailwind.config = {
      theme: {
        extend: {
          fontFamily: {
            'display': ['"Cormorant Garamond"', 'Georgia', 'serif'],
            'body': ['"DM Sans"', 'system-ui', 'sans-serif'],
            'mono': ['"JetBrains Mono"', 'monospace'],
          },
          colors: {
            ink: {
              50: '#f7f5f3',
              100: '#eeedea',
              200: '#ddd9d1',
              300: '#c7bfb5',
              400: '#a8a095',
              500: '#8c857b',
              600: '#716a64',
              700: '#5c5650',
              800: '#4b4843',
              900: '#3f3c39',
              950: '#211f1d',
            },
            clay: {
              50: '#fdf9f4',
              100: '#f9f2e8',
              200: '#f2e5ce',
              300: '#e6d1a8',
              400: '#d8b780',
              500: '#cba465',
              600: '#c08f55',
              700: '#a07247',
              800: '#825e3d',
              900: '#6b4c33',
            },
            mist: {
              50: '#f6f7f8',
              100: '#eceef1',
              200: '#d5dae1',
              300: '#b0bac6',
              400: '#8493a6',
              500: '#66768a',
              600: '#526070',
              700: '#454e5d',
              800: '#3c424d',
              900: '#343942',
            },
          },
        }
      }
    }
  </script>

  <style>
    html { scroll-behavior: smooth; }
    body {
      font-family: 'DM Sans', system-ui, sans-serif;
      background: #f7f5f3;
      color: #211f1d;
      -webkit-font-smoothing: antialiased;
      -moz-osx-font-smoothing: grayscale;
      overflow: hidden;
    }

    /* Custom scrollbar */
    ::-webkit-scrollbar { width: 6px; height: 6px; }
    ::-webkit-scrollbar-track { background: transparent; }
    ::-webkit-scrollbar-thumb { background: #ddd9d1; border-radius: 10px; }
    ::-webkit-scrollbar-thumb:hover { background: #c7bfb5; }

    /* Selection */
    ::selection { background: #ddd9d1; color: #211f1d; }

    /* Editor content styles */
    .prose-editor h1 { font-family: 'Cormorant Garamond', Georgia, serif; font-size: 2.25rem; font-weight: 600; letter-spacing: -0.02em; line-height: 1.2; color: #211f1d; margin-top: 2rem; margin-bottom: 1rem; }
    .prose-editor h2 { font-family: 'Cormorant Garamond', Georgia, serif; font-size: 1.5rem; font-weight: 600; letter-spacing: -0.01em; line-height: 1.25; color: #3f3c39; margin-top: 1.75rem; margin-bottom: 0.875rem; }
    .prose-editor h3 { font-family: 'DM Sans', system-ui, sans-serif; font-size: 1.05rem; font-weight: 600; color: #4b4843; margin-top: 1.5rem; margin-bottom: 0.75rem; letter-spacing: 0.01em; }
    .prose-editor p { font-size: 1.05rem; line-height: 1.85; color: #3f3c39; margin-bottom: 1.25rem; }
    .prose-editor p + p { margin-top: -0.5rem; }
    .prose-editor ul { margin: 1.25rem 0 1.25rem 1.25rem; padding-left: 0.5rem; }
    .prose-editor ul li { position: relative; padding-left: 1.25rem; margin-bottom: 0.5rem; line-height: 1.7; color: #3f3c39; }
    .prose-editor ul li::before { content: ''; position: absolute; left: 0; top: 0.65rem; width: 5px; height: 5px; border-radius: 50%; background: #cba465; }
    .prose-editor blockquote { border-left: 2px solid #cba465; padding-left: 1.25rem; margin: 1.5rem 0; font-style: italic; font-family: 'Cormorant Garamond', Georgia, serif; font-size: 1.15rem; color: #5c5650; line-height: 1.6; }
    .prose-editor blockquote p { margin-bottom: 0; }
    .prose-editor code { font-family: 'JetBrains Mono', monospace; font-size: 0.85em; background: #eeedea; padding: 0.15em 0.35em; border-radius: 4px; color: #6b4c33; }
    .prose-editor pre { background: #211f1d; border-radius: 10px; padding: 1rem 1.25rem; overflow-x: auto; margin: 1.5rem 0; }
    .prose-editor pre code { background: transparent; padding: 0; color: #ddd9d1; font-size: 0.82rem; }
    .prose-editor a { color: #6b4c33; text-decoration: underline; text-underline-offset: 3px; text-decoration-color: #cba465; transition: color 0.15s; }
    .prose-editor a:hover { color: #4b4843; }
    .prose-editor hr { border: 0; border-top: 1px solid #ddd9d1; margin: 2.5rem 0; }
    .prose-editor img { max-width: 100%; border-radius: 12px; margin: 1.5rem 0; }

    /* Editor editable focus */
    [contenteditable]:focus { outline: none; }

    /* Sidebar item hover */
    .nav-item { transition: all 0.15s ease; }
    .nav-item:hover { background: rgba(203,164,101,0.06); }

    /* Note card hover */
    .note-card { transition: transform 0.2s ease, box-shadow 0.3s ease, background 0.15s; }
    .note-card:hover { background: #fff; box-shadow: 0 2px 20px rgba(33,31,29,0.05); }

    /* Glass header */
    .glass-header {
      backdrop-filter: blur(20px) saturate(1.2);
      -webkit-backdrop-filter: blur(20px) saturate(1.2);
      background: rgba(247,245,243,0.82);
    }

    /* Tag pill */
    .tag-pill { transition: all 0.15s; }
    .tag-pill:hover { background: #211f1d; color: #f7f5f3; }

    /* Animated divider */
    @keyframes shimmer {
      0% { background-position: -200% 0; }
      100% { background-position: 200% 0; }
    }

    /* Entry animation */
    @keyframes slideUp {
      from { opacity: 0; transform: translateY(8px); }
      to { opacity: 1; transform: translateY(0); }
    }
    .anim-in { animation: slideUp 0.35s ease-out both; }
  </style>
</head>

<body class="h-screen w-full flex overflow-hidden selection:bg-ink-200 selection:text-ink-950">

  <!-- Left Sidebar -->
  <aside id="sidebar" class="w-[280px] min-w-[280px] flex-shrink-0 bg-ink-50/60 border-r border-ink-200/50 flex flex-col relative z-20">
    <div class="p-5 flex items-center gap-3 select-none">
      <div class="w-9 h-9 rounded-xl bg-ink-950 flex items-center justify-center shadow-lg shadow-ink-900/20">
        <i data-lucide="layers" class="w-[18px] h-[18px] text-clay-300"></i>
      </div>
      <div>
        <h1 class="font-display text-xl font-semibold text-ink-950 tracking-tight leading-none">Lumina</h1>
        <p class="text-[10px] text-ink-400 mt-0.5 tracking-wide font-medium uppercase">Notes</p>
      </div>
    </div>

    <nav class="px-3 flex-1 overflow-y-auto overflow-x-hidden space-y-0.5">
      <a href="#" onclick="filterNotes('all'); return false;" id="nav-all" class="nav-item flex items-center gap-3 px-3 py-2.5 rounded-xl text-sm font-medium text-ink-950 bg-clay-100/40">
        <i data-lucide="layout-grid" class="w-4 h-4 text-clay-600"></i>
        <span>All Notes</span>
        <span id="count-all" class="ml-auto text-[10px] text-ink-400 font-mono">12</span>
      </a>

      <div class="mt-5 mb-2 px-3">
        <p class="text-[10px] font-semibold text-ink-300 uppercase tracking-[0.08em]">Folders</p>
      </div>

      <a href="#" onclick="filterNotes('journal'); return false;" id="nav-journal" class="nav-item flex items-center gap-3 px-3 py-2 rounded-xl text-sm text-ink-600 hover:text-ink-950">
        <i data-lucide="book-open" class="w-4 h-4 text-ink-400"></i>
        <span>Journal</span>
        <span id="count-journal" class="ml-auto text-[10px] text-ink-300 font-mono">4</span>
      </a>
      <a href="#" onclick="filterNotes('work'); return false;" id="nav-work" class="nav-item flex items-center gap-3 px-3 py-2 rounded-xl text-sm text-ink-600 hover:text-ink-950">
        <i data-lucide="briefcase" class="w-4 h-4 text-ink-400"></i>
        <span>Work</span>
        <span id="count-work" class="ml-auto text-[10px] text-ink-300 font-mono">5</span>
      </a>
      <a href="#" onclick="filterNotes('ideas'); return false;" id="nav-ideas" class="nav-item flex items-center gap-3 px-3 py-2 rounded-xl text-sm text-ink-600 hover:text-ink-950">
        <i data-lucide="lightbulb" class="w-4 h-4 text-ink-400"></i>
        <span>Ideas</span>
        <span id="count-ideas" class="ml-auto text-[10px] text-ink-300 font-mono">3</span>
      </a>

      <div class="mt-5 mb-2 px-3">
        <p class="text-[10px] font-semibold text-ink-300 uppercase tracking-[0.08em]">Tags</p>
      </div>

      <div class="px-3 flex flex-wrap gap-1.5">
        <button onclick="filterNotes('tag','design')" class="tag-pill text-[11px] px-2.5 py-1 rounded-full bg-ink-100 text-ink-600 font-medium">design</button>
        <button onclick="filterNotes('tag','writing')" class="tag-pill text-[11px] px-2.5 py-1 rounded-full bg-ink-100 text-ink-600 font-medium">writing</button>
        <button onclick="filterNotes('tag','philosophy')" class="tag-pill text-[11px] px-2.5 py-1 rounded-full bg-ink-100 text-ink-600 font-medium">philosophy</button>
        <button onclick="filterNotes('tag','tech')" class="tag-pill text-[11px] px-2.5 py-1 rounded-full bg-ink-100 text-ink-600 font-medium">tech</button>
        <button onclick="filterNotes('tag','travel')" class="tag-pill text-[11px] px-2.5 py-1 rounded-full bg-ink-100 text-ink-600 font-medium">travel</button>
      </div>
    </nav>

    <div class="p-4 border-t border-ink-200/40">
      <button onclick="newNote()" class="w-full bg-ink-950 text-ink-50 hover:bg-ink-900 rounded-xl py-3 px-4 text-sm font-medium flex items-center justify-center gap-2.5 transition-all shadow-lg shadow-ink-900/15 hover:shadow-xl hover:shadow-ink-900/20 hover:-translate-y-0.5 active:translate-y-0">
        <i data-lucide="plus" class="w-4 h-4"></i>
        <span>New Note</span>
      </button>
      <p class="text-center text-[10px] text-ink-300 mt-3 font-medium">Lumina v2.0</p>
    </div>
  </aside>

  <!-- Middle Note List -->
  <section id="note-list-panel" class="w-[340px] min-w-[340px] flex-shrink-0 border-r border-ink-200/50 bg-white/40 backdrop-blur-sm flex flex-col z-10 overflow-hidden">
    <div class="glass-header sticky top-0 z-10 px-5 py-4 border-b border-ink-200/40 flex items-center gap-3">
      <div class="relative flex-1">
        <i data-lucide="search" class="absolute left-3 top-1/2 -translate-y-1/2 w-4 h-4 text-ink-300"></i>
        <input id="search-input" type="text" placeholder="Search notes..." oninput="searchNotes(this.value)" class="w-full pl-9 pr-3 py-2 bg-ink-50/60 rounded-xl text-sm text-ink-900 placeholder-ink-300 border border-transparent focus:border-ink-300 focus:bg-white transition-all outline-none font-body" />
      </div>
      <button onclick="newNote()" title="New note" class="p-2 rounded-xl hover:bg-ink-100 text-ink-400 hover:text-ink-600 transition-colors">
        <i data-lucide="plus" class="w-[18px] h-[18px]"></i>
      </button>
    </div>

    <div id="note-list" class="flex-1 overflow-y-auto overflow-x-hidden px-3 py-3 space-y-0.5"></div>
  </section>

  <!-- Main Editor -->
  <main id="editor-panel" class="flex-1 flex flex-col bg-ink-50 relative overflow-hidden">
    <!-- Editor Header -->
    <header class="glass-header sticky top-0 z-10 px-8 py-4 border-b border-ink-200/40 flex items-center justify-between">
      <div class="flex items-center gap-3 min-w-0">
        <button onclick="toggleSidebar()" class="hidden md:flex p-1.5 -ml-1.5 rounded-lg hover:bg-ink-100 text-ink-400 hover:text-ink-600 transition-colors" title="Toggle sidebar">
          <i data-lucide="panel-left-close" class="w-4 h-4"></i>
        </button>
        <div class="min-w-0">
          <h2 id="editor-title" contenteditable="true" onblur="updateTitle(this.innerText)" class="font-display text-2xl font-semibold text-ink-950 tracking-tight truncate outline-none focus:ring-2 focus:ring-clay-300/50 rounded-lg px-1 -mx-1 leading-tight" spellcheck="false">Unnamed Note</h2>
          <div class="flex items-center gap-2 mt-1.5 text-[11px] text-ink-400 font-medium">
            <span id="editor-date">Today</span>
            <span class="w-[3px] h-[3px] rounded-full bg-ink-300"></span>
            <span id="editor-tags">No tags</span>
            <span class="ml-2 px-1.5 py-0.5 rounded-md bg-ink-100 text-ink-500 text-[10px] font-mono">v1</span>
          </div>
        </div>
      </div>
      <div class="flex items-center gap-1.5 shrink-0">
        <button onclick="showDeleteConfirm()" title="Delete note" class="p-2 rounded-xl hover:bg-red-50 hover:text-red-600 text-ink-400 transition-colors">
          <i data-lucide="trash-2" class="w-[18px] h-[18px]"></i>
        </button>
        <button onclick="copyNoteLink()" title="Copy link" class="p-2 rounded-xl hover:bg-ink-100 hover:text-ink-600 text-ink-400 transition-colors">
          <i data-lucide="link" class="w-[18px] h-[18px]"></i>
        </button>
        <div class="w-px h-5 bg-ink-200/60 mx-1"></div>
        <button onclick="newNote()" title="New note" class="p-2 rounded-xl hover:bg-ink-100 hover:text-ink-600 text-ink-400 transition-colors">
          <i data-lucide="plus" class="w-[18px] h-[18px]"></i>
        </button>
      </div>
    </header>

    <!-- Editor Content -->
    <div class="flex-1 overflow-y-auto">
      <article id="editor-body" contenteditable="true" class="prose-editor px-8 md:px-14 lg:px-20 py-8 max-w-[820px] mx-auto min-h-full outline-none text-ink-950" spellcheck="true"></article>

      <!-- Empty state overlay -->
      <div id="empty-state" class="hidden absolute inset-0 flex flex-col items-center justify-center text-center pointer-events-none z-0">
        <div class="w-16 h-16 rounded-2xl bg-ink-100 flex items-center justify-center mb-5 shadow-inner">
          <i data-lucide="pen-line" class="w-7 h-7 text-ink-300"></i>
        </div>
        <h3 class="font-display text-xl font-semibold text-ink-700 mb-2">Select a note</h3>
        <p class="text-sm text-ink-400">Or create a new one to begin writing.</p>
      </div>
    </div>

    <!-- Editor footer -->
    <div class="glass-header border-t border-ink-200/40 px-8 py-2.5 flex items-center justify-between text-[11px] text-ink-300 font-medium shrink-0">
      <div class="flex items-center gap-4">
        <span id="word-count">0 words</span>
        <span id="char-count">0 chars</span>
      </div>
      <div class="flex items-center gap-3">
        <span>Auto-save on</span>
        <span class="w-1.5 h-1.5 rounded-full bg-emerald-400 animate-pulse"></span>
      </div>
    </div>
  </main>

  <!-- Delete Confirm Modal -->
  <div id="delete-modal" class="fixed inset-0 z-50 hidden items-center justify-center bg-ink-950/20 backdrop-blur-sm p-4">
    <div class="bg-white rounded-2xl shadow-2xl shadow-ink-900/10 max-w-sm w-full p-6 anim-in">
      <div class="w-10 h-10 rounded-full bg-red-50 flex items-center justify-center mb-4">
        <i data-lucide="trash-2" class="w-5 h-5 text-red-500"></i>
      </div>
      <h3 class="font-display text-lg font-semibold text-ink-950 mb-1">Delete this note?</h3>
      <p class="text-sm text-ink-500 mb-5 leading-relaxed">This action cannot be undone. The note will be removed permanently from your collection.</p>
      <div class="flex gap-2.5">
        <button onclick="hideDeleteConfirm()" class="flex-1 py-2.5 rounded-xl bg-ink-100 text-ink-700 hover:bg-ink-200 text-sm font-medium transition-colors">Cancel</button>
        <button onclick="deleteCurrentNote()" class="flex-1 py-2.5 rounded-xl bg-red-600 text-white hover:bg-red-700 text-sm font-medium transition-colors shadow-lg shadow-red-600/20">Delete</button>
      </div>
    </div>
  </div>

  <script>
    // ===== DATA =====
    const notesData = [
      {
        id: 1,
        title: "The Architecture of Thought",
        body: `<h1>The Architecture of Thought</h1>
<p>Every idea begins as a whisper. We tend to forget that thought itself is architectural — it requires scaffolding, light, and the careful placement of each new idea relative to the last.</p>
<p>When we build a system for thinking, we are really building a home for the mind. The structure of notes, the pathways between ideas, the quiet corners where half-formed thoughts rest — all of these shape what we are able to discover.</p>
<blockquote><p>"We shape our tools, and thereafter our tools shape us."</p></blockquote>
<p>I have been thinking lately about how digital spaces change the texture of thinking. There's something about the friction of a pen that demands intention. The keyboard, for all its speed, sometimes allows ideas to slip through without being fully inhabited.</p>`,
        folder: 'journal',
        tags: ['philosophy', 'writing'],
        date: '2025-01-12',
        updated: '2025-01-12T14:30',
      },
      {
        id: 2,
        title: "Design Principles for Calm Interfaces",
        body: `<h2>Design Principles for Calm Interfaces</h2>
<p>In an age of noise, calm interfaces are not a luxury — they are a responsibility. I believe the best design fades into the background so completely that you forget it exists.</p>
<ul><li>Use generous whitespace. Give ideas room to breathe.</li><li>Limit color to function, not decoration.</li><li>Typography should feel like conversation, not instruction.</li></ul>
<p>The surface of a product is the deepest part of its identity. What people see first is what they will remember longest. This is why every pixel matters — not for its beauty alone, but for the feeling it carries into the user's day.</p>`,
        folder: 'work',
        tags: ['design', 'tech'],
        date: '2025-01-10',
        updated: '2025-01-10T09:15',
      },
      {
        id: 3,
        title: "Morning in Lisbon",
        body: `<h1>Morning in Lisbon</h1>
<p>The light here is different. It arrives slowly, through narrow streets lined with azulejos that reflect it like polished mirrors. I walked to the waterfront before sunrise, just to watch the sky shift from indigo to a soft, dusty gold.</p>
<p>There's a bakery near the river that opens at six. The smell of fresh bread and dark coffee mixes with the salt air. It's the kind of place that makes you want to write, not because you have something important to say, but because the world feels generous enough to offer you words.</p>`,
        folder: 'journal',
        tags: ['travel', 'writing'],
        date: '2025-01-08',
        updated: '2025-01-08T07:42',
      },
      {
        id: 4,
        title: "Notes on Minimalist Typography",
        body: `<h2>Notes on Minimalist Typography</h2>
<p>Typography is not decoration — it is architecture at the scale of language. When you reduce a design to its essential elements, the type becomes the entire experience.</p>
<p>Consider the spacing between letters. Not the space around them, but the breath inside each word. A well-spaced word feels like a conversation you want to continue. A cramped one feels like someone talking too quickly.</p>`,
        folder: 'ideas',
        tags: ['design'],
        date: '2025-01-05',
        updated: '2025-01-05T21:00',
      },
      {
        id: 5,
        title: "A Reflection on Stillness",
        body: `<h1>A Reflection on Stillness</h1>
<p>We confuse stillness with emptiness. True stillness is full — full of awareness, full of possibility, full of the subtle movements of thought that happen when you stop trying to direct them.</p>
<blockquote><p>In stillness, the mind is not silent — it is simply no longer shouting.</p></blockquote>
<p>I try to sit for ten minutes each morning without an agenda. Not meditation, exactly. Just presence. The results are not always dramatic, but over time they accumulate like sediment — layers of calm that become part of your foundation.</p>`,
        folder: 'journal',
        tags: ['philosophy'],
        date: '2025-01-03',
        updated: '2025-01-03T08:10',
      },
      {
        id: 6,
        title: "Product Strategy — Q1 Roadmap",
        body: `<h2>Product Strategy — Q1 Roadmap</h2>
<p>The first quarter should focus on three pillars: stability, speed, and clarity of vision. We have been building quickly, but speed without direction creates technical debt that compounds faster than interest.</p>
<ul><li>Audit all core flows for accessibility compliance.</li><li>Reduce initial load time to under 300ms.</li><li>Refine the information architecture based on user interviews.</li></ul>
<p>Each pillar supports the others. A faster product feels more accessible. A clearer architecture makes the product faster to maintain. This is the kind of simplifying that takes real work.</p>`,
        folder: 'work',
        tags: ['tech'],
        date: '2025-01-01',
        updated: '2024-12-28T16:00',
      },
      {
        id: 7,
        title: "Typeface Selection for Brand Identity",
        body: `<h2>Typeface Selection for Brand Identity</h2>
<p>Choosing a typeface is like choosing a voice. Not just what it says, but how it feels to listen to it. For this brand, I want something that carries warmth without losing precision.</p>
<p>Cormorant Garamond feels right — it has the elegance of classical typography but breathes with a modern openness. Paired with a clean geometric sans for body copy, it creates a hierarchy that guides the eye naturally.</p>`,
        folder: 'ideas',
        tags: ['design'],
        date: '2024-12-28',
        updated: '2024-12-28T11:40',
      },
      {
        id: 8,
        title: "On the Nature of Memory",
        body: `<h1>On the Nature of Memory</h1>
<p>Memory is not a recording. It is a reconstruction — each time you remember something, you rebuild it slightly differently, influenced by everything that has happened since. This is why the act of writing down a thought is so valuable. It preserves not the event, but a snapshot of how you experienced it.</p>
<p>Notes become anchors. Without them, our past selves dissolve into vague impressions. With them, we can revisit the exact texture of a particular moment in time.</p>`,
        folder: 'journal',
        tags: ['philosophy', 'writing'],
        date: '2024-12-22',
        updated: '2024-12-22T20:15',
      },
      {
        id: 9,
        title: "A Simple Framework for Complex Problems",
        body: `<h2>A Simple Framework for Complex Problems</h2>
<p>When a problem feels overwhelming, I return to a simple framework: separate the parts, identify the relationships, and build from the bottom up. Not all problems can be solved linearly, but almost all can be understood linearly.</p>
<p>The key insight is that complexity is rarely in the individual elements — it lives in the connections between them. Understanding a system means mapping those connections with patience.</p>`,
        folder: 'work',
        tags: ['tech'],
        date: '2024-12-18',
        updated: '2024-12-19T10:00',
      },
      {
        id: 10,
        title: "Notes from Tokyo Winter",
        body: `<h1>Notes from Tokyo Winter</h1>
<p>Tokyo in winter has its own rhythm. The air is sharp but clean, and the light falls through buildings in geometric patterns that change by the hour. The city feels more intimate in cold weather — people move closer together, cafes become sanctuaries.</p>
<p>I spent an afternoon in a bookstore in Shibuya that specializes in art books. Each volume felt like an event. The quiet intensity of the space made me realize how rare it is to encounter things made with genuine care.</p>`,
        folder: 'journal',
        tags: ['travel', 'writing'],
        date: '2024-12-15',
        updated: '2024-12-15T18:30',
      },
      {
        id: 11,
        title: "Minimalism as a Practice, Not a Style",
        body: `<h2>Minimalism as a Practice, Not a Style</h2>
<p>Minimalism is often mistaken for an aesthetic — the absence of things, the preference for white space. But true minimalism is an approach to decision-making. It asks: what is essential? And then it has the discipline to remove everything else.</p>
<p>This applies to design, to writing, to how we organize our days. The practice is harder than the style, because it demands constant evaluation of what matters.</p>`,
        folder: 'ideas',
        tags: ['design', 'philosophy'],
        date: '2024-12-10',
        updated: '2024-12-10T14:00',
      },
      {
        id: 12,
        title: "Reading List — Winter 2025",
        body: `<h2>Reading List — Winter 2025</h2>
<p>A collection of things I want to spend time with before spring arrives. Not all of these are books — some are essays, some films, some long-form articles that deserve the same patience as a novel.</p>
<ul><li>The Poetics of Space — Bachelard</li><li>On Longing — Susan Stewart</li><li>In Praise of Slow — Carl Honoré</li></ul>
<p>The winter is a season for slow reading. The light changes earlier, the evenings lengthen, and there is a kind of permission granted to move more slowly through ideas.</p>`,
        folder: 'work',
        tags: ['writing'],
        date: '2024-12-05',
        updated: '2024-12-05T22:00',
      }
    ];

    let currentNoteId = 1;
    let activeFilter = 'all';
    let activeTag = null;
    let sidebarOpen = true;

    // ===== INIT =====
    function init() {
      lucide.createIcons();
      renderNoteList();
      loadNote(1);
      updateCounts();
      setInterval(autoSave, 3000);
      document.addEventListener('keydown', (e) => {
        if ((e.metaKey || e.ctrlKey) && e.key === 'n') { e.preventDefault(); newNote(); }
      });
    }

    // ===== RENDERING =====
    function renderNoteList() {
      const list = document.getElementById('note-list');
      let filtered = notesData;

      if (activeFilter === 'tag' && activeTag) {
        filtered = notesData.filter(n => n.tags.includes(activeTag));
      } else if (activeFilter !== 'all') {
        filtered = notesData.filter(n => n.folder === activeFilter);
      }

      const query = document.getElementById('search-input').value.toLowerCase();
      if (query) {
        filtered = filtered.filter(n => n.title.toLowerCase().includes(query) || n.body.toLowerCase().includes(query));
      }

      // Sort by updated
      filtered.sort((a, b) => new Date(b.updated) - new Date(a.updated));

      if (filtered.length === 0) {
        list.innerHTML = `<div class="p-8 text-center"><p class="text-sm text-ink-300">No notes found.</p></div>`;
        return;
      }

      list.innerHTML = filtered.map(note => {
        const isActive = note.id === currentNoteId;
        const snippet = stripHtml(note.body).substring(0, 90) + (stripHtml(note.body).length > 90 ? '...' : '');
        const tagDots = note.tags.map(t => `<span class="inline-block w-1.5 h-1.5 rounded-full bg-clay-400/60"></span>`).join(' ');
        return `
          <button onclick="loadNote(${note.id})" class="note-card w-full text-left px-3.5 py-3.5 rounded-2xl ${isActive ? 'bg-ink-950 text-white shadow-md shadow-ink-900/10' : 'text-ink-950 bg-transparent hover:bg-white/60'} transition-all group">
            <h3 class="font-display text-base font-semibold leading-snug truncate mb-1 ${isActive ? 'text-ink-50' : 'text-ink-900'}">${note.title}</h3>
            <p class="text-xs leading-relaxed truncate mb-2 ${isActive ? 'text-ink-200/90' : 'text-ink-400'}">${snippet}</p>
            <div class="flex items-center gap-2 text-[10px] font-medium ${isActive ? 'text-ink-300/80' : 'text-ink-300'}">
              <span>${formatDate(note.updated)}</span>
              ${note.tags.length ? `<span class="mx-0.5">·</span><span class="flex gap-1">${tagDots}</span>` : ''}
            </div>
          </button>
        `;
      }).join('');
    }

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

    // ===== NOTE MANAGEMENT =====
    function loadNote(id) {
      const note = notesData.find(n => n.id === id);
      if (!note) return;
      currentNoteId = id;
      document.getElementById('editor-title').textContent = note.title;
      document.getElementById('editor-body').innerHTML = note.body;
      document.getElementById('editor-date').textContent = formatDate(note.updated, true);
      document.getElementById('editor-tags').textContent = note.tags.join(', ') || 'No tags';
      document.getElementById('empty-state').classList.add('hidden');
      renderNoteList();
      updateWordCount();
      lucide.createIcons();
      // Highlight code
      document.querySelectorAll('pre code').forEach(block => {
        hljs.highlightElement(block);
      });
    }

    function newNote() {
      const id = Math.max(...notesData.map(n => n.id), 0) + 1;
      const newNoteObj = {
        id,
        title: 'Untitled Note',
        body: '<h1>Untitled Note</h1><p>Start writing something beautiful...</p>',
        folder: 'ideas',
        tags: [],
        date: new Date().toISOString().split('T')[0],
        updated: new Date().toISOString(),
      };
      notesData.unshift(newNoteObj);
      loadNote(id);
      document.getElementById('search-input').value = '';
      activeFilter = 'all';
      updateNavStyles();
      renderNoteList();
      updateCounts();
      setTimeout(() => document.getElementById('editor-title').focus(), 50);
    }

    function deleteCurrentNote() {
      notesData.splice(notesData.findIndex(n => n.id === currentNoteId), 1);
      currentNoteId = notesData[0]?.id || null;
      if (currentNoteId) loadNote(currentNoteId);
      else {
        document.getElementById('editor-title').textContent = 'Unnamed Note';
        document.getElementById('editor-body').innerHTML = '';
        document.getElementById('editor-date').textContent = '';
        document.getElementById('editor-tags').textContent = '';
        document.getElementById('empty-state').classList.remove('hidden');
      }
      renderNoteList();
      updateCounts();
      hideDeleteConfirm();
    }

    // ===== FILTERING =====
    function filterNotes(type, value) {
      activeFilter = type;
      activeTag = value || null;
      document.getElementById('search-input').value = '';
      updateNavStyles();
      renderNoteList();
      if (notesData.length > 0 && !currentNoteId) loadNote(notesData[0].id);
    }

    function updateNavStyles() {
      document.querySelectorAll('.nav-item').forEach(el => {
        el.classList.remove('bg-clay-100/40', 'text-ink-950');
        el.classList.add('text-ink-600');
      });
      if (activeFilter === 'all') {
        document.getElementById('nav-all').classList.add('bg-clay-100/40', 'text-ink-950');
        document.getElementById('nav-all').classList.remove('text-ink-600');
      }
    }

    function searchNotes(query) {
      renderNoteList();
    }

    // ===== UPDATES =====
    function updateTitle(text) {
      const note = notesData.find(n => n.id === currentNoteId);
      if (note) {
        note.title = text || 'Untitled Note';
        note.updated = new Date().toISOString();
        renderNoteList();
      }
    }

    function autoSave() {
      const note = notesData.find(n => n.id === currentNoteId);
      if (!note) return;
      note.body = document.getElementById('editor-body').innerHTML;
      note.title = document.getElementById('editor-title').textContent;
      note.updated = new Date().toISOString();
      renderNoteList();
      updateWordCount();
    }

    function updateWordCount() {
      const bodyText = document.getElementById('editor-body').textContent || '';
      const words = bodyText.trim() ? bodyText.trim().split(/\s+/).length : 0;
      const chars = bodyText.length;
      document.getElementById('word-count').textContent = `${words} word${words !== 1 ? 's' : ''}`;
      document.getElementById('char-count').textContent = `${chars} char${chars !== 1 ? 's' : ''}`;
    }

    document.getElementById('editor-body').addEventListener('input', () => {
      updateWordCount();
      // Auto-save silently
      const note = notesData.find(n => n.id === currentNoteId);
      if (note) {
        note.body = document.getElementById('editor-body').innerHTML;
        note.title = document.getElementById('editor-title').textContent;
        note.updated = new Date().toISOString();
      }
    });

    // ===== UTILS =====
    function formatDate(iso, long = false) {
      const d = new Date(iso);
      if (long) return d.toLocaleDateString('en-US', { month: 'long', day: 'numeric', year: 'numeric' });
      return d.toLocaleDateString('en-US', { month: 'short', day: 'numeric' });
    }

    function updateCounts() {
      document.getElementById('count-all').textContent = notesData.length;
      document.getElementById('count-journal').textContent = notesData.filter(n => n.folder === 'journal').length;
      document.getElementById('count-work').textContent = notesData.filter(n => n.folder === 'work').length;
      document.getElementById('count-ideas').textContent = notesData.filter(n => n.folder === 'ideas').length;
    }

    function copyNoteLink() {
      alert('Link copied to clipboard!');
    }

    // ===== DELETE MODAL =====
    function showDeleteConfirm() {
      document.getElementById('delete-modal').classList.remove('hidden');
      document.getElementById('delete-modal').classList.add('flex');
    }
    function hideDeleteConfirm() {
      document.getElementById('delete-modal').classList.add('hidden');
      document.getElementById('delete-modal').classList.remove('flex');
    }
    document.getElementById('delete-modal').addEventListener('click', (e) => {
      if (e.target === document.getElementById('delete-modal')) hideDeleteConfirm();
    });

    // ===== SIDEBAR =====
    function toggleSidebar() {
      sidebarOpen = !sidebarOpen;
      const sidebar = document.getElementById('sidebar');
      if (sidebarOpen) {
        sidebar.style.width = '280px';
        sidebar.style.transform = 'translateX(0)';
        sidebar.classList.remove('hidden');
      } else {
        sidebar.style.transform = 'translateX(-100%)';
        setTimeout(() => {
          sidebar.classList.add('hidden');
          sidebar.style.width = '280px';
        }, 300);
      }
    }

    // ===== INIT =====
    window.addEventListener('DOMContentLoaded', init);
  </script>
</body>
</html>
<!-- agent-meta {"model":"thinkingmachines/inkling","provider":"openrouter","persona":"full","sessionId":"24cebddf-4be2-4b0a-b334-82f4d2dbbc06","tokensIn":30791,"tokensOut":10965,"tokensTotal":41756,"turns":3,"toolCalls":2,"failedToolCalls":0,"timestamp":"2026-07-18T21:41:20.554Z"} -->