# AGENTS.md Welcome AI assistant! You are working on **EternaLibre Notes** — a server-side rendered (SSR) copyleft Markdown notes application written in Rust. EternaLibre Notes combines **GNU software freedom** (GPL v3.0-or-later) with the **fluid elegance of Apple Notes** and the **predictable utility of classic desktop GUI applications** (menu bars, split panes, and file organization). The name splits into its two halves: **Eterna** for permanence and **Libre** for freedom. Notes you keep forever, software that stays free. It borrows Apple's polish and then does the opposite of what Apple does with your data. --- ## 1. Project Philosophy & Identity * **Name**: EternaLibre Notes — "Free notes, forever." * **Mission**: Reclaiming high-performance Rust web development under copyleft terms (GPLv3+). Rejecting heavy client-side JavaScript frameworks and proprietary note silos in favor of software freedom, privacy, and near-zero memory footprint. * **UI Paradigm**: **"Apple Elegance meets Classic Desktop GUI"** * **Apple Notes Polish**: Fluid sidebars, smooth note item previews, refined typography, generous padding, subtle contrast, and graceful theme transitions. * **Traditional Desktop Utility**: Top menu bar (`File`, `Edit`, `View`, `Theme`, `Help`), quick action toolbars, split-pane resizers, keyboard shortcuts, and visible document state. --- ## 2. UI/UX Design System & Layout Architecture The application layout follows a classic 3-column / top-menu layout rendered cleanly via SSR: ``` +-----------------------------------------------------------------------------------+ | [File] [Edit] [View] [Theme] [Help] [EternaLibre Notes v0.1] | <-- Classic Menu Bar +-----------------------------------------------------------------------------------+ | [+ New Note] [Delete] | Search... | Theme: [ Dark v ] [Preview] | <-- Apple-style Toolbar +-------------------+-----------------------------------+---------------------------+ | Sidebar | Editor Pane | Live Preview Pane | | ----------------- | --------------------------------- | ------------------------- | | Notes | [Untitled ] | Welcome to EternaLibre Notes | | Project Notes | | | | Sep 28, 2026 | # Welcome | Fast, copyleft Markdown... | | GPLv3+ Markdown | | | | fn main() ... | Fast, copyleft Markdown editor... | | +-------------------+-----------------------------------+---------------------------+ | Status: 2 Notes | Saved | UTF-8 | Markdown | Theme: Dark | <-- Status Bar +-----------------------------------------------------------------------------------+ ``` ### Key UX Principles: 1. **Fluid Typography**: Inter/SF Pro or high-quality system sans-serif for the interface; Monospace for Markdown source; clean sans for HTML preview. 2. **Subtle Elevation & Borders**: Soft 1px borders using `--ui-border` / `--app-bg` contrast shades rather than heavy drop shadows. 3. **Apple-style Note List**: Sidebar lists show note title, relative timestamp, and a single line preview snippet in muted text. 4. **Progressive Enhancement**: Note editing, search, theming, and the login form all work with JavaScript disabled, via HTML forms and page reloads. Three things are JS-dependent by design: the menu bar (dropdowns open from an Alpine-driven `.open` class), the mobile tab bar, and live preview. --- ## 3. Architecture & Tech Stack * **Language**: Rust (`edition = "2021"`) * **Server Framework**: **Axum 0.7** (async, Tower ecosystem) * **Auth**: `totp-rs` 6 (TOTP), `qrcode` 0.14 (inline SVG QR), `rand` 0.10 (session tokens) * **SSR Templating**: **`maud` 0.26** (compiled, type-safe HTML macros) * **Reactivity / Live Swap**: **Alpine.js 3.14** (vendored locally in `static/`, ~15 KB) * **Markdown Engine**: `pulldown-cmark` (with table, tasklist, strikethrough, and footnote extensions) * **Syntax Highlighting**: `syntect` 5 (for fenced code blocks, themed per active palette) * **Serialization**: `serde` / `serde_json` * **Dates**: `chrono` * **IDs**: `uuid` v4 * **Error Handling**: `anyhow` for application errors, `thiserror` for library-style errors * **CLI Parsing**: `clap` 4 (derive API) * **Static Assets**: `tower-http` `ServeDir` for `/static` * **License**: **GNU General Public License v3.0 or later** (`GPL-3.0-or-later`). All dependency crates in `Cargo.toml` must be compatible with GPLv3+. ### Actual Project Structure ``` eternalibre-notes/ ├── Cargo.toml ├── LICENSE # GPL-3.0 full text ├── README.md ├── notes/ # User data: one .md file per note ├── src/ │ ├── main.rs # Entry point, CLI args, terminal setup, router assembly │ ├── lib.rs # Library root, so tests/ can drive the HTTP layer │ ├── auth.rs # TOTP secret store, session store, verification │ ├── setup.rs # First-run terminal enrolment (QR to stdout, reads stdin) │ ├── routes.rs # HTTP routes, auth gate, base-path joining │ ├── pages.rs # Maud SSR templates + the `Base` URL helper │ ├── notes.rs # Note model + file-system persistence │ ├── markdown.rs # Markdown → HTML with code block interception │ ├── syntax.rs # syntect engine + per-theme tmTheme generation │ ├── themes.rs # 34 predefined themes + CSS variable engine │ └── storage.rs # Storage re-export module ├── static/ │ ├── alpine.min.js # Vendored Alpine.js │ ├── app.js # Alpine component │ └── style.css # Full application stylesheet └── tests/ └── auth_gating.rs # End-to-end tests for the TOTP auth gate ``` --- ## 4. Theme System & ANSI Palette Data Theme definitions provide background, foreground, and full 16-color ANSI palettes. ### Rust Data Structures (`src/themes.rs`) ```rust #[derive(Debug, Clone, PartialEq, Eq, serde::Serialize, serde::Deserialize)] pub struct Theme { pub name: &'static str, pub fg: &'static str, pub bg: &'static str, pub ansi_normal: [&'static str; 8], pub ansi_bright: [&'static str; 8], } #[derive(Debug, Clone, PartialEq, Eq, serde::Serialize, serde::Deserialize)] pub struct ANSIPalette { pub name: &'static str, pub ansi_normal: [&'static str; 8], pub ansi_bright: [&'static str; 8], } ``` `PREDEFINED_THEMES` contains 34 alphabetically ordered themes: Amber on Black, Autumn Forest, Blueberry on Black, Breeze, Breeze Dark, Chartreuse on Black, Classic Windows 95, Cyan on Black, Cyberpunk 2077, Dark, Dracula, Foggy Morning, Gruvbox Dark, Gruvbox Light, Light, Lilac Paper, Lime Green on Black, Monokai, Nord, One Dark, Orchid Noir, Platinum Desktop, Red on Black, Rose Quartz, Solarized Dark, Solarized Light, Spring Blossom, Stormy Night, Summer Sunset, Tokyo Night, Velvet Dusk, Vista Aero, Windows XP, and Winter Frost. "Sunny Day" was removed: a mid-green background with a pale yellow foreground left almost nothing legible on it, and no amount of syntax tuning rescues a palette that bad. ### Theme Selection The active theme is stored in a `theme` cookie. The server reads it from the `Cookie` header on every request and injects the matching CSS variable block into the `
`. No JavaScript is required to change themes — a plain `