Compare commits
26 Commits
v1.1.0
..
5abcc18a06
| Author | SHA1 | Date | |
|---|---|---|---|
| 5abcc18a06 | |||
| cf06ad8ad4 | |||
| a073149da5 | |||
| 323bd228c5 | |||
| 645397d202 | |||
| 3f6465fb40 | |||
| 32bf5c3288 | |||
| afaaaab2a2 | |||
| 0c47285a15 | |||
| 3e67307a8d | |||
| c37cb83548 | |||
| f4c8f2801b | |||
| 1b4bc92c3e | |||
| f0899e5032 | |||
| 78f1487890 | |||
| 2bdd028e09 | |||
| dfd5de97bc | |||
| 654f78dfd2 | |||
| 123fbef26f | |||
| ab7788464e | |||
| dcbb9211c7 | |||
| 4e89bcd68f | |||
| c07eb10640 | |||
| 4f60339240 | |||
| 758a93c9f6 | |||
| b977d224a5 |
-51
@@ -1,51 +0,0 @@
|
|||||||
# Logs
|
|
||||||
logs
|
|
||||||
*.log
|
|
||||||
npm-debug.log*
|
|
||||||
yarn-debug.log*
|
|
||||||
yarn-error.log*
|
|
||||||
pnpm-debug.log*
|
|
||||||
lerna-debug.log*
|
|
||||||
|
|
||||||
node_modules
|
|
||||||
dist
|
|
||||||
dist-ssr
|
|
||||||
*.local
|
|
||||||
|
|
||||||
# Tauri build artifacts
|
|
||||||
src-tauri/target/
|
|
||||||
|
|
||||||
# Dev tool files
|
|
||||||
icon-*.html
|
|
||||||
nul
|
|
||||||
|
|
||||||
# Portable data directory
|
|
||||||
data/
|
|
||||||
|
|
||||||
# Editor directories and files
|
|
||||||
.vscode/
|
|
||||||
.idea
|
|
||||||
.DS_Store
|
|
||||||
*.suo
|
|
||||||
*.ntvs*
|
|
||||||
*.njsproj
|
|
||||||
*.sln
|
|
||||||
*.sw?
|
|
||||||
|
|
||||||
# AI/LLM tooling
|
|
||||||
.claude/
|
|
||||||
.cursor/
|
|
||||||
.copilot/
|
|
||||||
.codeium/
|
|
||||||
.tabnine/
|
|
||||||
.aider*
|
|
||||||
.continue/
|
|
||||||
|
|
||||||
# Trash
|
|
||||||
trash/
|
|
||||||
|
|
||||||
# Docs
|
|
||||||
docs/
|
|
||||||
|
|
||||||
# This file
|
|
||||||
.gitignore
|
|
||||||
Vendored
-3
@@ -1,3 +0,0 @@
|
|||||||
{
|
|
||||||
"recommendations": ["tauri-apps.tauri-vscode", "rust-lang.rust-analyzer"]
|
|
||||||
}
|
|
||||||
@@ -122,7 +122,7 @@ Vesper targets **WCAG 2.2 AAA** compliance across the entire interface.
|
|||||||
| 🔗 Skip Link | "Skip to content" link as first focusable element for screen reader users |
|
| 🔗 Skip Link | "Skip to content" link as first focusable element for screen reader users |
|
||||||
| 🎯 Focus Management | Visible `:focus-visible` outlines on all interactive elements; focus traps in modals with restore on close |
|
| 🎯 Focus Management | Visible `:focus-visible` outlines on all interactive elements; focus traps in modals with restore on close |
|
||||||
| 🌗 High Contrast Themes | Dark and light themes both meet AAA contrast ratios (7:1+ for normal text) |
|
| 🌗 High Contrast Themes | Dark and light themes both meet AAA contrast ratios (7:1+ for normal text) |
|
||||||
| 🎞️ Reduced Motion | Respects `prefers-reduced-motion` OS setting — all animations disabled when active |
|
| 🎞️ Reduced Motion | Respects `prefers-reduced-motion` OS setting - all animations disabled when active |
|
||||||
| 📋 Active Heading Tracking | Current section highlighted in sidebar TOC via IntersectionObserver |
|
| 📋 Active Heading Tracking | Current section highlighted in sidebar TOC via IntersectionObserver |
|
||||||
| 🔲 Target Sizes | All interactive targets meet 24x24px minimum (WCAG 2.5.8) |
|
| 🔲 Target Sizes | All interactive targets meet 24x24px minimum (WCAG 2.5.8) |
|
||||||
| 📢 Status Messages | Search results counter uses `aria-live="polite"` for screen reader announcements |
|
| 📢 Status Messages | Search results counter uses `aria-live="polite"` for screen reader announcements |
|
||||||
|
|||||||
@@ -1,7 +0,0 @@
|
|||||||
# Generated by Cargo
|
|
||||||
# will have compiled files and executables
|
|
||||||
/target/
|
|
||||||
|
|
||||||
# Generated by Tauri
|
|
||||||
# will have schema files for capabilities auto-completion
|
|
||||||
/gen/schemas
|
|
||||||
Generated
+1
-1
@@ -4296,7 +4296,7 @@ checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a"
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "vesper"
|
name = "vesper"
|
||||||
version = "1.0.1"
|
version = "1.1.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"serde",
|
"serde",
|
||||||
"serde_json",
|
"serde_json",
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
name = "vesper"
|
name = "vesper"
|
||||||
version = "1.1.0"
|
version = "1.1.0"
|
||||||
description = "A beautiful markdown reader"
|
description = "A beautiful markdown reader"
|
||||||
authors = ["you"]
|
authors = ["lashman"]
|
||||||
edition = "2021"
|
edition = "2021"
|
||||||
|
|
||||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||||
|
|||||||
@@ -77,7 +77,7 @@ pub fn run() {
|
|||||||
|
|
||||||
tauri::Builder::default()
|
tauri::Builder::default()
|
||||||
.plugin(tauri_plugin_single_instance::init(|app, args, _cwd| {
|
.plugin(tauri_plugin_single_instance::init(|app, args, _cwd| {
|
||||||
// Second instance launched with a file — send it to the existing window
|
// Second instance launched with a file - send it to the existing window
|
||||||
if let Some(file_arg) = args.get(1) {
|
if let Some(file_arg) = args.get(1) {
|
||||||
if let Some(cli_file) = read_md_file(file_arg) {
|
if let Some(cli_file) = read_md_file(file_arg) {
|
||||||
let _ = app.emit("open-file", cli_file);
|
let _ = app.emit("open-file", cli_file);
|
||||||
|
|||||||
+2
-2
@@ -40,7 +40,7 @@ const md: MarkdownIt = new MarkdownIt({
|
|||||||
|
|
||||||
const materialEase = [0.4, 0, 0.2, 1] as const;
|
const materialEase = [0.4, 0, 0.2, 1] as const;
|
||||||
|
|
||||||
// Saved selection range — set in mousedown (before browser clears it), read in contextmenu handler
|
// Saved selection range - set in mousedown (before browser clears it), read in contextmenu handler
|
||||||
let _savedSelectionRange: Range | null = null;
|
let _savedSelectionRange: Range | null = null;
|
||||||
|
|
||||||
// Reusable kinetic scroll + iOS overscroll setup for any scrollable area
|
// Reusable kinetic scroll + iOS overscroll setup for any scrollable area
|
||||||
@@ -500,7 +500,7 @@ function App() {
|
|||||||
setHeadings(parsed);
|
setHeadings(parsed);
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
// Render markdown to HTML — memoized so it only re-runs when content changes
|
// Render markdown to HTML - memoized so it only re-runs when content changes
|
||||||
const renderedHtml = useMemo(() => {
|
const renderedHtml = useMemo(() => {
|
||||||
if (!activeTab) return '';
|
if (!activeTab) return '';
|
||||||
return md.render(activeTab.content);
|
return md.render(activeTab.content);
|
||||||
|
|||||||
+20
-20
@@ -41,7 +41,7 @@
|
|||||||
--color-error-content: #1E2128;
|
--color-error-content: #1E2128;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* CSS Custom Properties - Premium Flat Design with #282C33 */
|
/* Custom properties */
|
||||||
:root {
|
:root {
|
||||||
/* Surface System - centered on #282C33 */
|
/* Surface System - centered on #282C33 */
|
||||||
--color-bg-base: #282C33;
|
--color-bg-base: #282C33;
|
||||||
@@ -56,7 +56,7 @@
|
|||||||
--color-text-primary: #E4E6EB;
|
--color-text-primary: #E4E6EB;
|
||||||
--color-text-secondary: #BCC1C8; /* was #ABB0B8, now ~7.5:1 */
|
--color-text-secondary: #BCC1C8; /* was #ABB0B8, now ~7.5:1 */
|
||||||
--color-text-tertiary: #8B919A; /* was #6B7280, now ~4.8:1 */
|
--color-text-tertiary: #8B919A; /* was #6B7280, now ~4.8:1 */
|
||||||
--color-text-disabled: #6B7280; /* was #4A5260, now ~2.9:1 (exempt — inactive UI) */
|
--color-text-disabled: #6B7280; /* was #4A5260, now ~2.9:1 (exempt - inactive UI) */
|
||||||
|
|
||||||
/* Accent */
|
/* Accent */
|
||||||
--color-accent: #6B8AFF;
|
--color-accent: #6B8AFF;
|
||||||
@@ -153,7 +153,7 @@ html, body, #root {
|
|||||||
overflow: visible;
|
overflow: visible;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Skip link — WCAG 2.4.1 */
|
/* Skip link - WCAG 2.4.1 */
|
||||||
.skip-link {
|
.skip-link {
|
||||||
position: fixed;
|
position: fixed;
|
||||||
top: -100%;
|
top: -100%;
|
||||||
@@ -318,7 +318,7 @@ html, body, #root {
|
|||||||
color: var(--color-text-primary);
|
color: var(--color-text-primary);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Menu backdrop — invisible overlay to catch outside clicks */
|
/* Menu backdrop - invisible overlay to catch outside clicks */
|
||||||
.menu-backdrop {
|
.menu-backdrop {
|
||||||
position: fixed;
|
position: fixed;
|
||||||
top: 0;
|
top: 0;
|
||||||
@@ -939,7 +939,7 @@ html, body, #root {
|
|||||||
z-index: 10003 !important;
|
z-index: 10003 !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Shortcuts dialog — uses its own class to avoid DaisyUI .modal conflicts */
|
/* Shortcuts dialog - uses its own class to avoid DaisyUI .modal conflicts */
|
||||||
.shortcuts-dialog {
|
.shortcuts-dialog {
|
||||||
background-color: var(--color-bg-elevated);
|
background-color: var(--color-bg-elevated);
|
||||||
border: 1px solid var(--color-border);
|
border: 1px solid var(--color-border);
|
||||||
@@ -1167,7 +1167,7 @@ html, body, #root {
|
|||||||
color: var(--color-text-primary);
|
color: var(--color-text-primary);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Markdown content - PREMIUM EDITORIAL TYPOGRAPHY */
|
/* Markdown content */
|
||||||
.markdown-content {
|
.markdown-content {
|
||||||
/* Optimal measure: ~65 characters for best readability */
|
/* Optimal measure: ~65 characters for best readability */
|
||||||
max-width: 680px;
|
max-width: 680px;
|
||||||
@@ -1176,7 +1176,7 @@ html, body, #root {
|
|||||||
overflow-wrap: break-word;
|
overflow-wrap: break-word;
|
||||||
word-break: break-word;
|
word-break: break-word;
|
||||||
|
|
||||||
/* Premium typography settings */
|
/* Typography settings */
|
||||||
font-size: 17px;
|
font-size: 17px;
|
||||||
line-height: 1.7;
|
line-height: 1.7;
|
||||||
font-family: 'Inter Variable', 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', system-ui, sans-serif;
|
font-family: 'Inter Variable', 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', system-ui, sans-serif;
|
||||||
@@ -1191,7 +1191,7 @@ html, body, #root {
|
|||||||
text-spacing-trim: trim-both;
|
text-spacing-trim: trim-both;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Refined heading hierarchy — progressive color cascade */
|
/* Heading hierarchy */
|
||||||
.markdown-content h1,
|
.markdown-content h1,
|
||||||
.markdown-content h2,
|
.markdown-content h2,
|
||||||
.markdown-content h3,
|
.markdown-content h3,
|
||||||
@@ -1250,14 +1250,14 @@ html, body, #root {
|
|||||||
color: var(--color-md-h6);
|
color: var(--color-md-h6);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Paragraphs with refined spacing */
|
/* Paragraphs */
|
||||||
.markdown-content p {
|
.markdown-content p {
|
||||||
margin-bottom: 1.65em;
|
margin-bottom: 1.65em;
|
||||||
color: var(--color-md-paragraph);
|
color: var(--color-md-paragraph);
|
||||||
line-height: 1.7;
|
line-height: 1.7;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Links with subtle persistent underline */
|
/* Links */
|
||||||
.markdown-content a {
|
.markdown-content a {
|
||||||
color: var(--color-md-link);
|
color: var(--color-md-link);
|
||||||
text-decoration: underline;
|
text-decoration: underline;
|
||||||
@@ -1502,7 +1502,7 @@ html, body, #root {
|
|||||||
color: #FFCB6B;
|
color: #FFCB6B;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Tables - elegant card style without gradients */
|
/* Tables */
|
||||||
.markdown-content table {
|
.markdown-content table {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
border-collapse: separate;
|
border-collapse: separate;
|
||||||
@@ -1547,7 +1547,7 @@ html, body, #root {
|
|||||||
background-color: var(--color-md-table-hover);
|
background-color: var(--color-md-table-hover);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Horizontal rule — gradient fade */
|
/* Horizontal rule - gradient fade */
|
||||||
.markdown-content hr {
|
.markdown-content hr {
|
||||||
border: none;
|
border: none;
|
||||||
height: 1px;
|
height: 1px;
|
||||||
@@ -1625,7 +1625,7 @@ html, body, #root {
|
|||||||
border-radius: 8px;
|
border-radius: 8px;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Search highlights — high specificity to override Tailwind reset */
|
/* Search highlights - high specificity to override Tailwind reset */
|
||||||
span.search-highlight {
|
span.search-highlight {
|
||||||
background-color: var(--color-md-highlight-bg) !important;
|
background-color: var(--color-md-highlight-bg) !important;
|
||||||
color: inherit !important;
|
color: inherit !important;
|
||||||
@@ -1663,7 +1663,7 @@ span.search-highlight.search-highlight-active {
|
|||||||
transition: background-color 0.2s ease, opacity 0.2s ease;
|
transition: background-color 0.2s ease, opacity 0.2s ease;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Global focus indicator — WCAG 2.4.7, 2.4.13 */
|
/* Global focus indicator - WCAG 2.4.7, 2.4.13 */
|
||||||
button:focus-visible,
|
button:focus-visible,
|
||||||
a:focus-visible,
|
a:focus-visible,
|
||||||
input:focus-visible,
|
input:focus-visible,
|
||||||
@@ -1677,7 +1677,7 @@ input:focus-visible,
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* ============================================
|
/* ============================================
|
||||||
Light theme overrides — WCAG 1.4.8
|
Light theme overrides - WCAG 1.4.8
|
||||||
============================================ */
|
============================================ */
|
||||||
.theme-light {
|
.theme-light {
|
||||||
--color-bg-base: #F5F6F8;
|
--color-bg-base: #F5F6F8;
|
||||||
@@ -1702,7 +1702,7 @@ input:focus-visible,
|
|||||||
--color-border: rgba(0, 0, 0, 0.10);
|
--color-border: rgba(0, 0, 0, 0.10);
|
||||||
--color-border-strong: rgba(0, 0, 0, 0.16);
|
--color-border-strong: rgba(0, 0, 0, 0.16);
|
||||||
|
|
||||||
/* Markdown typography — light variants */
|
/* Markdown typography - light variants */
|
||||||
--color-md-h1: #111318;
|
--color-md-h1: #111318;
|
||||||
--color-md-h2: #1A1D24;
|
--color-md-h2: #1A1D24;
|
||||||
--color-md-h3: #252A31;
|
--color-md-h3: #252A31;
|
||||||
@@ -1739,26 +1739,26 @@ input:focus-visible,
|
|||||||
--color-md-welcome-btn: #3B66E0;
|
--color-md-welcome-btn: #3B66E0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Light theme — noise overlay should be darker */
|
/* Light theme - noise overlay should be darker */
|
||||||
.theme-light.app-container::before {
|
.theme-light.app-container::before {
|
||||||
opacity: 0.025;
|
opacity: 0.025;
|
||||||
mix-blend-mode: multiply;
|
mix-blend-mode: multiply;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Light theme — title bar close button */
|
/* Light theme - title bar close button */
|
||||||
.theme-light .title-bar-button.close:hover {
|
.theme-light .title-bar-button.close:hover {
|
||||||
background-color: #DC2626;
|
background-color: #DC2626;
|
||||||
color: white;
|
color: white;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Light theme — scrollbar colors */
|
/* Light theme - scrollbar colors */
|
||||||
.theme-light .os-theme-dark {
|
.theme-light .os-theme-dark {
|
||||||
--os-handle-bg: rgba(0, 0, 0, 0.15);
|
--os-handle-bg: rgba(0, 0, 0, 0.15);
|
||||||
--os-handle-bg-hover: var(--color-accent);
|
--os-handle-bg-hover: var(--color-accent);
|
||||||
--os-handle-bg-active: var(--color-accent-hover);
|
--os-handle-bg-active: var(--color-accent-hover);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Light theme — sidebar resize handle */
|
/* Light theme - sidebar resize handle */
|
||||||
.theme-light .sidebar-resize-handle {
|
.theme-light .sidebar-resize-handle {
|
||||||
background: rgba(0, 0, 0, 0.06);
|
background: rgba(0, 0, 0, 0.06);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user