25 Commits

Author SHA1 Message Date
lashman 8b55855c81 Update README.md 2026-03-09 15:17:38 +02:00
TypoGenie 63cfed02d9 docs: add WCAG 2.2 AAA accessibility section to README 2026-02-19 00:12:20 +02:00
TypoGenie 87dd578e92 a11y: add error boundary, reduced motion, remaining fixes 2026-02-18 23:52:06 +02:00
TypoGenie 2ca1439680 a11y: add runtime contrast validation, justify override, line-height floor 2026-02-18 23:49:03 +02:00
TypoGenie bd842b87a2 a11y: add DOCX metadata, image placeholders, table headers 2026-02-18 23:46:32 +02:00
TypoGenie 1458210d88 a11y: add landmarks, semantic structure, skip nav, iframe lang 2026-02-18 23:43:48 +02:00
TypoGenie e460f4df68 a11y: add ARIA live regions for status announcements and errors 2026-02-18 23:35:52 +02:00
TypoGenie d0f88625b5 a11y: fix keyboard access, listbox pattern, ARIA labels, target sizes 2026-02-18 23:32:21 +02:00
TypoGenie 242e16f75d a11y: convert all modals to native dialog with focus management 2026-02-18 23:27:55 +02:00
TypoGenie 7d5af9e39c a11y: fix CSS foundation - contrast, overflow, focus ring, reduced motion 2026-02-18 23:22:04 +02:00
TypoGenie 3b8e80c3a3 docs: add WCAG 2.2 AAA implementation plan 2026-02-18 23:17:00 +02:00
TypoGenie 3ab4432fcf docs: add WCAG 2.2 AAA accessibility remediation design
Covers 147 issues across 8 sections: CSS foundation, modal system,
keyboard access, ARIA live regions, semantic structure, DOCX output,
template contrast validation, and miscellaneous fixes.
2026-02-18 23:11:05 +02:00
TypoGenie 32c9ab9e92 docs: standardize style count to 165+ across README 2026-02-09 23:00:24 +02:00
TypoGenie 592ded54fe chore: normalize dashes across project files 2026-02-09 22:59:03 +02:00
TypoGenie f34aa9e9a8 chore: switch license from MIT to CC0-1.0 2026-02-09 22:55:59 +02:00
lashman a1f3a86022 Update README.md 2026-02-09 18:10:57 +00:00
TypoGenie 285b9e835d docs: release 1.0.0
- Updated README to reflect Windows Portable focus
- Removed references to Mac/Linux builds
- Updated tech stack and project structure documentation
- Updated Contributing section
2026-02-01 19:17:10 +02:00
TypoGenie 3265ea899b fix: resolve lingering TypeScript errors found during cleanup
- Fixed unused import in useTemplates.ts
- Fixed argument mismatch in templateLoader.ts
2026-02-01 19:05:00 +02:00
TypoGenie 4a8ca94348 chore: cleanup unused files and scripts
- Removed legacy TypeScript templates (replaced by JSON)
- Removed unused PowerShell and CJS maintenance scripts
- Removed debug logs and unused components
- Files moved to local _TRASH/ directory (excluded from git)
2026-02-01 19:03:37 +02:00
TypoGenie 30cff63353 chore: sanitize template names and descriptions
- Renamed 'Artificial Intelligence' to 'Neural Network'
- Renamed 'Blockchain Protocol' to 'Secure Protocol'
- Renamed 'Crypto Futurism' to 'Digital Futurism'
- Renamed 'Startup SaaS' to 'Product Launch'
- Renamed 'Tech Startup' to 'Tech Venture'
- Removed references to AI, crypto, blockchain, and startups from template descriptions
- Updated README.md to remove specific startup/SaaS references
2026-02-01 18:57:57 +02:00
TypoGenie 60f39ed961 feat: port all template categories to JSON format
- Ported Minimalist templates to JSON (Swiss Grid, Brutalist, etc.)
- Ported Tech templates to JSON (SaaS, Terminal, Cyberpunk, etc.)
- Ported Creative templates to JSON (Art Gallery, Zine, Pop Art, etc.)
- Ported Industrial templates to JSON (Blueprint, Factory, Schematic, etc.)
- Ported Nature templates to JSON (Botanical, Ocean, Mountain, etc.)
- Ported Lifestyle templates to JSON (Cookbook, Travel, Coffee House, etc.)
- Ported Vintage templates to JSON (Art Deco, Medieval, Retro 80s, etc.)
- Updated README.md to reflect the new JSON-based style system (example configuration and contribution workflow)
- Completed migration of over 150 styles to the new architecture
2026-02-01 18:51:43 +02:00
TypoGenie a2631ac473 feat: Make app fully portable
- Add tauri-plugin-store for portable data storage
- Implement portable data directory (TypoGenie-Data/ next to EXE)
- Configure Rust backend to use EXE-relative paths
- Add store permissions for persistent settings
- Update README with portable badges and documentation
- Document how to build and use the portable EXE
- Zero registry, zero AppData, fully self-contained
2026-01-29 18:36:48 +02:00
TypoGenie 2c22b0fce6 feat: Transform to Tauri desktop app
- Initialize Tauri v2 project with Rust backend
- Restructure project: move source files to src/ directory
- Add Tauri configuration for Windows, macOS, and Linux builds
- Update Vite config for Tauri development workflow
- Add file system and dialog permissions for native features
- Update package.json with desktop build scripts
- Update tsconfig.json paths for new src structure
- Add Tauri and desktop badges to README
- Document desktop build process and architecture
2026-01-29 18:28:35 +02:00
TypoGenie ae5ce9d243 docs: Rewrite README with comprehensive documentation
- Added extensive project documentation covering all features
- Beautiful visual design with badges, shields, and banners
- Included architecture diagrams and style system deep-dive
- Added contribution guidelines and philosophy section
- Wove in themes of collective benefit, commons, and mutual aid throughout
- Celebrated open-source as a model of voluntary cooperation
2026-01-29 18:14:41 +02:00
TypoGenie f179e79f35 Initial commit: TypoGenie - Markdown to Word document converter 2026-01-29 18:10:07 +02:00
9 changed files with 1598 additions and 6 deletions
+2
View File
@@ -560,6 +560,8 @@ If TypoGenie brings value to your life, consider:
<p> <p>
<i>"The master's tools will never dismantle the master's house. But they might help you format a really nice document while we build something better together."</i> <i>"The master's tools will never dismantle the master's house. But they might help you format a really nice document while we build something better together."</i>
This project is developed with the help of a locally-run LLM via opencode for scaffolding, planning, and routine code tasks. Architecture and design decisions are my own.
</p> </p>
<p> <p>
@@ -0,0 +1,212 @@
# WCAG 2.2 AAA Accessibility Remediation Design
**Date:** 2026-02-18
**Status:** Approved
**Scope:** 147 accessibility issues across 17 existing files, 3 new files
## Decisions
| Decision | Choice |
|----------|--------|
| Visual approach | Balance accessibility with dark aesthetic |
| Modals | Native `<dialog>` element |
| Style cards | Listbox pattern with existing `useFocusableList` hook |
| Template colors | Runtime contrast validation only, no JSON template edits |
| Justified text | Override to `left` at render time |
| Contrast enforcement | Auto-correct via `ensureContrast()` utility at render time |
## Section 1: CSS Foundation (~25 issues)
### Root font size
Change `:root { font-size: 16px }` to `font-size: 100%` in `index.css` so user browser preferences are respected.
### Overflow
Remove `overflow: hidden` from `body` and `#root`. Replace with `overflow-x: hidden` to prevent horizontal scroll but allow vertical content access when zoomed to 200%.
### Focus indicators
Replace `rgba(99, 102, 241, 0.3)` focus ring with `rgba(99, 102, 241, 0.8)` at 2px. Meets 3:1 contrast on dark backgrounds while fitting indigo theme.
### Reduced motion
Add global CSS rule:
```css
@media (prefers-reduced-motion: reduce) {
*, *::before, *::after {
animation-duration: 0.01ms !important;
animation-iteration-count: 1 !important;
transition-duration: 0.01ms !important;
scroll-behavior: auto !important;
}
}
```
### Forced colors
Add `@media (forced-colors: active)` rules for Windows High Contrast Mode compatibility.
### Color replacements
Across all components: `text-zinc-600` -> `text-zinc-400`, `text-zinc-500` -> `text-zinc-400`. All text hits 7:1+ contrast on zinc-950. Keeps dark aesthetic.
## Section 2: Modal System (~20 issues)
### New `src/hooks/useDialog.ts`
Reusable hook wrapping native `<dialog>`:
- Manages `dialogRef`, `showModal()`/`close()`
- Restores focus to trigger element on close
- Wires `aria-labelledby`
- Framer Motion animations on inner content div
### KeyboardShortcutsHelp (App.tsx)
Convert from `motion.div` overlay to `<dialog>`. Add `aria-labelledby` to heading. Close button gets `aria-label="Close shortcuts"`. Escape/focus trap handled natively.
### ExportOptionsModal
Same `<dialog>` conversion. Radio buttons wrapped in `<fieldset><legend>`. Close button labeled.
### StylePreviewModal
Same `<dialog>` conversion. Close button labeled. Iframe HTML gets `lang="en"`.
### Animation approach
`dialog[open]` CSS selector for entrance. `::backdrop` gets fade-in. Framer Motion on inner content for exit.
## Section 3: Keyboard Access & Interactive Elements (~20 issues)
### Logo button
Replace `<motion.div onClick>` with `<motion.button aria-label="TypoGenie - Reset to home">`.
### Single-character shortcut
Scope `?`/`/` listener to only fire when `document.activeElement` is body or non-input element. Prevents intercepting typing in search.
### Style cards as listbox
Container: `role="listbox"` + `aria-label="Typography styles"`. Each card: `role="option"` + `tabIndex` + `aria-selected` + `onKeyDown`. Wire `useFocusableList` for arrow keys. Add `:focus-visible` indigo ring.
### Favorite button
Add `aria-label` (dynamic: "Add to favorites"/"Remove from favorites") + `aria-pressed`.
### Category filters
Wrap in `<div role="group" aria-label="Filter by category">`. Active button: `aria-pressed="true"`.
### Paper size buttons
Wrap in `<div role="group" aria-label="Paper size">`. Active button: `aria-pressed="true"`.
### Search input
Add `aria-label="Search templates"` + `aria-describedby` pointing to live result count region.
### Icon-only buttons
Add `aria-label` to all: zoom buttons, external link (Preview), close buttons. Decorative icons next to text: `aria-hidden="true"`.
### Target sizes
Increase padding on small buttons to hit 44x44px minimum. Use `min-w-[44px] min-h-[44px]` with centered content where inline growth not possible.
## Section 4: ARIA Live Regions & Status Announcements (~15 issues)
### Root status region
Persistent `<div role="status" aria-live="polite" className="sr-only">` in App.tsx root. Updated on `appState` changes.
### Generating state
Add `aria-busy="true"` + `role="status"` to container.
### Preview loading
Wrap "Loading..." in `role="status"`.
### Success message
`aria-live="polite"` on button text area for "Saved!" announcement.
### Search results
Visually-hidden `role="status"` announcing "{N} templates found". Debounced 300ms.
### Error fixes
- Remove `aria-live="polite"` where `role="alert"` already set (implies assertive)
- Remove 5-second auto-dismiss from FileUpload error
- Add `aria-describedby` linking FileUpload error to dropzone
- Template loading: `role="status"`. Template error: `role="alert"`
### Loading state
Replace `return null` with minimal `<div role="status">Loading TypoGenie</div>`.
## Section 5: Semantic Structure & Landmarks (~15 issues)
### Skip navigation
`<a href="#main-content" class="sr-only focus:not-sr-only">Skip to main content</a>` in index.html.
### Page title
`<title>TypoGenie - Markdown to Word Converter</title>`
### Noscript
`<noscript><p>TypoGenie requires JavaScript to run.</p></noscript>`
### Landmarks
- `id="main-content"` on `<main>` in both app states
- `<nav aria-label="Style filters">` around category buttons
- `<section aria-label="Style list">` and `<section aria-label="Style preview">` in StyleSelector
### Progress stepper
Wrap in `<nav aria-label="Progress"><ol>`. Active step: `aria-current="step"`.
### Shortcuts list
Convert to `<dl>` with `<dt>`/`<dd>`.
### Decorative elements
`aria-hidden="true"` on blob backgrounds, window-chrome dots, visual dividers.
### Iframe lang
Both Preview.tsx and StylePreviewModal.tsx: inject `<html lang="en">`.
## Section 6: DOCX Output Accessibility (~8 issues)
### Document metadata
Add `title` (from filename/first h1), `description`, `language` to Document constructor.
### Image handling
New `<img>` handler producing `[Image: {alt text}]` placeholder paragraph in italic.
### Table headers
Set `tableHeader: true` on `TableRow` containing `<th>` elements.
### Heading preservation in table mode
Add `HeadingLevel` to paragraph inside `processHeaderAsTable` table cells.
### Code block style
Add custom "Code" paragraph style to DOCX styles. Apply to code blocks.
## Section 7: Template Contrast Validation (~20 issues)
### New `src/utils/contrastUtils.ts`
- `hexToRgb(hex)` - parse hex to RGB
- `relativeLuminance(rgb)` - WCAG luminance formula
- `contrastRatio(color1, color2)` - ratio calculation
- `ensureContrast(fg, bg, minRatio)` - auto-correct foreground color until ratio met
### Integration in templateRenderer.ts
Run `ensureContrast()` on every text/background pair at CSS generation time. Body text: 7:1. Large text (18pt+ or 14pt+ bold): 4.5:1.
### `del` element fix
When resolving `del` color, if `border` palette color fails contrast, fall back to `textSecondary`.
### Justified text
Override `justify` to `left` at render time (1.4.8 AAA prohibits justified text).
### Line-height floor
Enforce minimum 1.5 for body text, 1.0 for headings. Clamp upward if template specifies lower.
## Section 8: Remaining Miscellaneous (~10 issues)
### Iframe keyboard
`tabIndex={-1}` on preview iframe in StyleSelector (passive preview, not interactive).
### Error boundary
New `src/components/ErrorBoundary.tsx` wrapping `<App />`. Renders accessible error with `role="alert"` on crash.
### Framer Motion reduced motion
Import `useReducedMotion` from `motion/react` in App.tsx. When true, disable infinite blob/gradient animations via conditional animate props.
### Hidden buttons on small screens
Add always-visible `<kbd>?</kbd>` hint regardless of breakpoint.
### Truncation
Add `title` attribute with full description on `line-clamp-2` elements.
## Files Modified (17)
`index.html`, `src/index.css`, `src/App.tsx`, `src/main.tsx`, `src/components/StyleSelector.tsx`, `src/components/Preview.tsx`, `src/components/ExportOptionsModal.tsx`, `src/components/StylePreviewModal.tsx`, `src/components/FileUpload.tsx`, `src/hooks/useSettings.ts`, `src/hooks/useTemplates.ts`, `src/services/templateRenderer.ts`, `src/utils/docxConverter.ts`, `src/utils/fontUtils.ts`
## Files Created (3)
`src/utils/contrastUtils.ts`, `src/hooks/useDialog.ts`, `src/components/ErrorBoundary.tsx`
File diff suppressed because it is too large Load Diff
@@ -2,7 +2,7 @@
"id": "creative-portfolio", "id": "creative-portfolio",
"name": "Creative Portfolio", "name": "Creative Portfolio",
"category": "creative", "category": "creative",
"description": "Minimalist gallery style for presenting visual work. Focuses on images and clean typography.", "description": "Minimalist gallery style for showcasing visual work. Focuses on images and clean typography.",
"vibe": "Minimalist, Visual, Gallery", "vibe": "Minimalist, Visual, Gallery",
"googleFontsImport": "https://fonts.googleapis.com/css2?family=Jost:ital,wght@0,300..900;1,300..900&family=Playfair+Display:ital,wght@0,400..900;1,400..900&display=swap", "googleFontsImport": "https://fonts.googleapis.com/css2?family=Jost:ital,wght@0,300..900;1,300..900&family=Playfair+Display:ital,wght@0,400..900;1,400..900&display=swap",
"typography": { "typography": {
@@ -2,7 +2,7 @@
"id": "rococo-romance", "id": "rococo-romance",
"name": "Rococo Romance", "name": "Rococo Romance",
"category": "editorial", "category": "editorial",
"description": "Inspired by 18th-century Rococo. Light, playful, and delicate with pastel tones and swirling elegance.", "description": "Inspired by 18th-century Rococo. Light, playful, and intricate with pastel tones and swirling elegance.",
"vibe": "Romantic, Ornate, Pastel", "vibe": "Romantic, Ornate, Pastel",
"googleFontsImport": "https://fonts.googleapis.com/css2?family=Pinyon+Script&family=Playfair+Display+SC:ital,wght@0,400;0,700;1,400;1,700&family=Lora:ital,wght@0,400..700;1,400..700&display=swap", "googleFontsImport": "https://fonts.googleapis.com/css2?family=Pinyon+Script&family=Playfair+Display+SC:ital,wght@0,400;0,700;1,400;1,700&family=Lora:ital,wght@0,400..700;1,400..700&display=swap",
"typography": { "typography": {
@@ -1,5 +1,5 @@
{ {
"id": "neural-network", "id": "artificial-intelligence",
"name": "Neural Network", "name": "Neural Network",
"category": "tech", "category": "tech",
"description": "Cutting-edge design for advanced computing and data science. Neural network inspired with gradient accents.", "description": "Cutting-edge design for advanced computing and data science. Neural network inspired with gradient accents.",
+1 -1
View File
@@ -2,7 +2,7 @@
"id": "tech-startup", "id": "tech-startup",
"name": "Tech Venture", "name": "Tech Venture",
"category": "tech", "category": "tech",
"description": "Modern, energetic design for technology companies and ventures. Bold gradients, punchy colors, and confident typography.", "description": "Modern, energetic design for technology companies and ventures. Bold gradients, vibrant colors, and confident typography.",
"vibe": "Innovative, Dynamic, Bold", "vibe": "Innovative, Dynamic, Bold",
"googleFontsImport": "https://fonts.googleapis.com/css2?family=Plus+Jakarta+Sans:wght@400;500;700&display=swap", "googleFontsImport": "https://fonts.googleapis.com/css2?family=Plus+Jakarta+Sans:wght@400;500;700&display=swap",
"typography": { "typography": {
@@ -2,7 +2,7 @@
"id": "memphis-pattern", "id": "memphis-pattern",
"name": "Memphis Pattern", "name": "Memphis Pattern",
"category": "retro", "category": "retro",
"description": "The chaotic 80s aesthetic. Clashing patterns, zig-zags, and loud pastel-neons.", "description": "The chaotic 80s aesthetic. Clashing patterns, zig-zags, and vibrant pastel-neons.",
"vibe": "Playful, Chaotic, 80s", "vibe": "Playful, Chaotic, 80s",
"googleFontsImport": "https://fonts.googleapis.com/css2?family=Righteous&family=Comfortaa:wght@400;700&display=swap", "googleFontsImport": "https://fonts.googleapis.com/css2?family=Righteous&family=Comfortaa:wght@400;700&display=swap",
"typography": { "typography": {
@@ -2,7 +2,7 @@
"id": "mid-century-modern", "id": "mid-century-modern",
"name": "Mid-Century Modern", "name": "Mid-Century Modern",
"category": "retro", "category": "retro",
"description": "Optimistic and playful design from the 1950s-60s. Geometric sans-serifs, bold atomic-age colors, and approachable warmth.", "description": "Optimistic and playful design from the 1950s-60s. Geometric sans-serifs, vibrant atomic-age colors, and approachable warmth.",
"vibe": "Playful, Nostalgic, Friendly", "vibe": "Playful, Nostalgic, Friendly",
"googleFontsImport": "https://fonts.googleapis.com/css2?family=Quicksand:wght@400;600;700&display=swap", "googleFontsImport": "https://fonts.googleapis.com/css2?family=Quicksand:wght@400;600;700&display=swap",
"typography": { "typography": {