Files
2026-07-29 04:07:36 -05:00

316 lines
15 KiB
HTML

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Noto | Miles Wolf Allen</title>
<meta name="description" content="Noto — note-taking app with AI built in. Built with Flutter and powered by Cortex AI.">
<link rel="canonical" href="https://milesallen.site/projects/noto.html">
<meta property="og:title" content="Noto | Miles Wolf Allen">
<meta property="og:description" content="Note-taking app with AI built in. Built with Flutter, powered by Cortex AI.">
<meta property="og:image" content="https://milesallen.site/og.png">
<link rel="preconnect" href="https://fonts.googleapis.com">
<link href="https://fonts.googleapis.com/css2?family=Press+Start+2P&family=Space+Mono:wght@400;700&family=Inter:wght@400;500;600;800&display=swap" rel="stylesheet">
<link rel="icon" type="image/png" href="../favicon.png">
<link rel="stylesheet" href="style.css">
</head>
<body>
<div class="cursor-dot" id="cursorDot"></div>
<div class="cursor-ring" id="cursorRing"></div>
<div class="progress-bar" id="progressBar"></div>
<button class="theme-toggle" id="themeToggle" aria-label="Toggle theme"></button>
<div class="shortcut-modal" id="shortcutModal">
<div class="shortcut-card">
<h3>Keyboard Shortcuts</h3>
<div class="shortcut-row"><span>Go Home</span><kbd>H</kbd></div>
<div class="shortcut-row"><span>Go to GitHub</span><kbd>G</kbd></div>
<div class="shortcut-row"><span>Toggle theme</span><kbd>T</kbd></div>
<div class="shortcut-row"><span>Show shortcuts</span><kbd>?</kbd></div>
<div class="close-hint">Press Esc or ? to close</div>
</div>
</div>
<div class="flash" id="flash"></div>
<div class="toast-stack" id="toastStack"></div>
<nav class="mobile-nav">
<a href="../index.html">Home</a>
<a href="fedl.html">FEDL</a>
<a href="noto.html" class="active">Noto</a>
<a href="command-move.html">CommandMove</a>
<a href="https://github.com/mileswolfallen2" target="_blank">GitHub</a>
</nav>
<div class="container">
<nav>
<a href="../index.html" class="nav-logo"><span class="logo-dot"></span> milesallen</a>
<div class="nav-links">
<a href="../index.html#about">About</a>
<a href="../index.html#skills">Skills</a>
<a href="../index.html#projects">Projects</a>
<a href="../index.html#contact">Contact</a>
</div>
</nav>
<section class="project-hero">
<div class="breadcrumb">
<a href="../index.html">Home</a>
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><polyline points="9 18 15 12 9 6"/></svg>
<span>Noto</span>
</div>
<h1>Noto</h1>
<p class="tagline">A cross-platform note-taking app powered by Cortex AI. Brain dump, voice notes, universal search, and 8 themes. Built with Flutter.</p>
<div class="project-meta-bar">
<a href="https://github.com/mileswolfallen2/Noto" class="meta-chip primary" target="_blank">
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M9 19c-5 1.5-5-2.5-7-3m14 6v-3.87a3.37 3.37 0 00-.94-2.61c3.14-.35 6.44-1.54 6.44-7A5.44 5.44 0 0020 4.77 5.07 5.07 0 0019.91 1S18.73.65 16 2.48a13.38 13.38 0 00-7 0C6.27.65 5.09 1 5.09 1A5.07 5.07 0 005 4.77a5.44 5.44 0 00-1.5 3.78c0 5.42 3.3 6.61 6.44 7A3.37 3.37 0 009 18.13V22"/></svg>
View on GitHub
</a>
<a href="https://noto.fedl.site" class="meta-chip" target="_blank">
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><circle cx="12" cy="12" r="10"/><line x1="2" y1="12" x2="22" y2="12"/><path d="M12 2a15.3 15.3 0 014 10 15.3 15.3 0 01-4 10 15.3 15.3 0 01-4-10 15.3 15.3 0 014-10z"/></svg>
website
</a>
<span class="meta-chip" style="border-color: var(--green); color: var(--green);">Active Development</span>
<span class="meta-chip">Dart</span>
<span class="meta-chip">MIT License</span>
</div>
<div class="stats-bar">
<div class="stat-item">
<div class="stat-value accent" id="gh-stars">--</div>
<div class="stat-label">Stars</div>
</div>
<div class="stat-item">
<div class="stat-value green" id="gh-forks">--</div>
<div class="stat-label">Forks</div>
</div>
<div class="stat-item">
<div class="stat-value orange" id="gh-issues">--</div>
<div class="stat-label">Issues</div>
</div>
<div class="stat-item">
<div class="stat-value" id="gh-lang">--</div>
<div class="stat-label">Language</div>
</div>
</div>
</section>
<section class="reveal">
<div class="section-divider"></div>
<h2 class="section-title">Features</h2>
<p class="section-subtitle">Your second brain, everywhere</p>
<div class="feature-grid">
<div class="feature-card">
<h3>
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M14 2H6a2 2 0 00-2 2v16a2 2 0 002 2h12a2 2 0 002-2V8z"/><polyline points="14 2 14 8 20 8"/></svg>
Brain Dump
</h3>
<p>Type and forget. Auto-saves instantly so you never lose a thought.</p>
</div>
<div class="feature-card">
<h3>
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><circle cx="12" cy="12" r="10"/><polyline points="12 6 12 12 16 14"/></svg>
AI Timeline
</h3>
<p>Every note auto-sorted by time with date grouping for easy navigation.</p>
</div>
<div class="feature-card">
<h3>
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M12 2a2 2 0 012 2c0 .74-.4 1.39-1 1.73V7h1a7 7 0 017 7h1.27c.34-.6.99-1 1.73-1a2 2 0 110 4c-.74 0-1.39-.4-1.73-1H20a7 7 0 01-7 7v1.27c.6.34 1 .99 1 1.73a2 2 0 11-4 0c0-.74.4-1.39 1-1.73V20a7 7 0 01-7-7H2.73c-.34.6-.99 1-1.73 1a2 2 0 110-4c.74 0 1.39.4 1.73 1H4a7 7 0 017-7V5.73c-.6-.34-1-.99-1-1.73a2 2 0 012-2z"/></svg>
Cortex AI
</h3>
<p>Cloud (OpenAI) or local (Ollama) AI for summaries, cleanup, explanation, quizzing, and chat.</p>
</div>
<div class="feature-card">
<h3>
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M12 1a3 3 0 00-3 3v8a3 3 0 006 0V4a3 3 0 00-3-3z"/><path d="M19 10v2a7 7 0 01-14 0v-2"/><line x1="12" y1="19" x2="12" y2="23"/></svg>
Voice Notes
</h3>
<p>Record audio, auto-transcribe via Whisper API, and save as structured notes.</p>
</div>
<div class="feature-card">
<h3>
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><circle cx="11" cy="11" r="8"/><line x1="21" y1="21" x2="16.65" y2="16.65"/></svg>
Universal Search
</h3>
<p>Full-text search across all notes with voice input support.</p>
</div>
<div class="feature-card">
<h3>
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><circle cx="12" cy="12" r="5"/><line x1="12" y1="1" x2="12" y2="3"/><line x1="12" y1="21" x2="12" y2="23"/><line x1="4.22" y1="4.22" x2="5.64" y2="5.64"/><line x1="18.36" y1="18.36" x2="19.78" y2="19.78"/><line x1="1" y1="12" x2="3" y2="12"/><line x1="21" y1="12" x2="23" y2="12"/></svg>
8 Themes
</h3>
<p>Dark, Light, Midnight, Solarized, Nord, Dracula, Tokyo Night, and Gruvbox.</p>
</div>
<div class="feature-card">
<h3>
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M21 15a2 2 0 01-2 2H7l-4 4V5a2 2 0 012-2h14a2 2 0 012 2z"/></svg>
AI Tab
</h3>
<p>Dedicated Cortex screen with full notes context for free-form conversation.</p>
</div>
<div class="feature-card">
<h3>
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><rect x="3" y="4" width="18" height="18" rx="2" ry="2"/><line x1="16" y1="2" x2="16" y2="6"/><line x1="8" y1="2" x2="8" y2="6"/><line x1="3" y1="10" x2="21" y2="10"/></svg>
Cross-Platform
</h3>
<p>iOS, Android, macOS, Windows, and Linux. One codebase, everywhere.</p>
</div>
</div>
</section>
<section class="reveal">
<div class="section-divider"></div>
<h2 class="section-title">AI Configuration</h2>
<div class="feature-grid">
<div class="feature-card">
<h3>Cloud (OpenAI)</h3>
<p>Enter your API key. Uses gpt-4o-mini for chat and whisper-1 for voice transcription.</p>
</div>
<div class="feature-card">
<h3>Local (Ollama)</h3>
<p>Run Ollama locally with gemma3:4b or any model. Default URL: 127.0.0.1:11434.</p>
</div>
<div class="feature-card">
<h3>Router</h3>
<p>Point to a custom endpoint for AI inference.</p>
</div>
<div class="feature-card">
<h3>None</h3>
<p>AI features disabled. Use Noto as a plain note-taking app.</p>
</div>
</div>
</section>
<section class="reveal">
<div class="section-divider"></div>
<h2 class="section-title">Tech Stack</h2>
<div class="tech-stack">
<span class="tech-badge">Dart (74.4%)</span>
<span class="tech-badge">C++ (11.2%)</span>
<span class="tech-badge">CMake (8.6%)</span>
<span class="tech-badge">Swift (3.1%)</span>
<span class="tech-badge">Flutter</span>
<span class="tech-badge">Riverpod</span>
<span class="tech-badge">Hive</span>
<span class="tech-badge">OpenAI API</span>
<span class="tech-badge">Ollama</span>
</div>
</section>
<section class="reveal">
<div class="section-divider"></div>
<h2 class="section-title">Quick Start</h2>
<div class="code-block">
<span class="comment"># Prerequisites: Flutter 3.44+</span><br><br>
<span class="cmd">flutter pub get</span><br>
<span class="cmd">flutter run -d macos</span> <span class="comment"># macOS</span><br>
<span class="cmd">flutter run -d &lt;device&gt;</span> <span class="comment"># other devices</span>
</div>
</section>
<footer>
<div class="footer-links" style="margin-bottom: 12px;">
<a href="../uses.html" style="color:var(--muted);text-decoration:none;">Uses</a>
<span style="color:var(--muted);margin:0 8px;">·</span>
<a href="../now.html" style="color:var(--muted);text-decoration:none;">Now</a>
<span style="color:var(--muted);margin:0 8px;">·</span>
<a href="../colophon.html" style="color:var(--muted);text-decoration:none;">Colophon</a>
<span style="color:var(--muted);margin:0 8px;">·</span>
<a href="../experiments.html" style="color:var(--accent);text-decoration:none;">Internet History</a>
</div>
Built by Miles · 2026 · Powered by too much coffee and the Konami code
</footer>
</div>
<script>
fetch('https://api.github.com/repos/mileswolfallen2/Noto')
.then(r => r.json())
.then(d => {
if (d.stargazers_count != null) document.getElementById('gh-stars').textContent = d.stargazers_count;
if (d.forks_count != null) document.getElementById('gh-forks').textContent = d.forks_count;
if (d.open_issues_count != null) document.getElementById('gh-issues').textContent = d.open_issues_count;
if (d.language) document.getElementById('gh-lang').textContent = d.language;
})
.catch(() => {});
const observer = new IntersectionObserver((entries) => {
entries.forEach(e => { if (e.isIntersecting) e.target.classList.add('visible'); });
}, { threshold: 0.1, rootMargin: '0px 0px -40px 0px' });
document.querySelectorAll('.reveal').forEach(el => observer.observe(el));
</script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/[email protected]/gsap.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/[email protected]/ScrollTrigger.min.js"></script>
<script>
gsap.registerPlugin(ScrollTrigger);
// Hero entrance
const heroTl = gsap.timeline({ defaults: { ease: 'power3.out' } });
heroTl
.from('.breadcrumb', { x: -30, opacity: 0, duration: 0.6 })
.from('.project-hero h1', { y: 50, opacity: 0, duration: 0.8 }, '-=0.3')
.from('.tagline', { y: 30, opacity: 0, duration: 0.7 }, '-=0.4')
.from('.meta-chip', { y: 20, opacity: 0, scale: 0.8, duration: 0.4, stagger: 0.06 }, '-=0.3')
.from('.stats-bar', { y: 30, opacity: 0, duration: 0.6 }, '-=0.2')
.from('.stat-item', { y: 20, opacity: 0, scale: 0.9, duration: 0.4, stagger: 0.08, ease: 'back.out(1.5)' }, '-=0.3');
// Nav entrance
gsap.from('nav', { y: -20, opacity: 0, duration: 0.6, ease: 'power2.out' });
// Section titles
document.querySelectorAll('.section-title').forEach(title => {
gsap.from(title, {
scrollTrigger: { trigger: title, start: 'top 85%' },
y: 30, opacity: 0, duration: 0.7, ease: 'power3.out'
});
});
// Section dividers
document.querySelectorAll('.section-divider').forEach(div => {
gsap.from(div, {
scrollTrigger: { trigger: div, start: 'top 90%' },
width: 0, duration: 0.6, ease: 'power2.out'
});
});
// Feature cards stagger
document.querySelectorAll('.feature-grid').forEach(grid => {
gsap.from(grid.querySelectorAll('.feature-card'), {
scrollTrigger: { trigger: grid, start: 'top 85%' },
y: 50, opacity: 0, scale: 0.9, duration: 0.6, stagger: 0.1, ease: 'power3.out'
});
});
// Tech badges
document.querySelectorAll('.tech-stack').forEach(stack => {
gsap.from(stack.querySelectorAll('.tech-badge'), {
scrollTrigger: { trigger: stack, start: 'top 88%' },
y: 20, opacity: 0, scale: 0.8, duration: 0.4, stagger: 0.05, ease: 'back.out(1.5)'
});
});
// Tables
document.querySelectorAll('.table-wrapper').forEach(wrapper => {
gsap.from(wrapper, {
scrollTrigger: { trigger: wrapper, start: 'top 85%' },
y: 40, opacity: 0, duration: 0.7, ease: 'power3.out'
});
});
// Code blocks
document.querySelectorAll('code-block').forEach(block => {
gsap.from(block, {
scrollTrigger: { trigger: block, start: 'top 88%' },
y: 30, opacity: 0, duration: 0.6, ease: 'power3.out'
});
});
// Footer
gsap.from('footer', {
scrollTrigger: { trigger: 'footer', start: 'top 95%' },
opacity: 0, duration: 0.8
});
window.addEventListener('load', () => ScrollTrigger.refresh());
</script>
<script src="script.js"></script>
</body>
</html>