summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPaul Buetow <paul@buetow.org>2025-06-22 22:06:43 +0300
committerPaul Buetow <paul@buetow.org>2025-06-22 22:06:43 +0300
commit3af674aebad9e3792fbf13b3cbda7b1691b1f4f3 (patch)
treec70f6033d21628579d96044c89a060e9031dbf8b
parent99078f90bf5222c618a60e536cb148850e4b89e2 (diff)
Add 50 new experimental HTML themes for Gemtexter
- Generated 50 unique themes with creative layouts and color schemes - Each theme includes: - Custom CSS with W3C validated styles - Example HTML preview page - Font files with proper licensing - Theme configuration file - License documentation - Layout types include: centered, wide, magazine, card, brutalist, terminal, book, hero, sidebar, and more creative designs - All themes support both light and dark color schemes - Fixed CSS validation issues for W3C compliance - Created theme gallery page at extras/html/themes/index.html - Added screenshot previews for all themes - Utility scripts included: - generate_50_themes.py - Main theme generator - fix_css_validation.py - CSS validator/fixer - create_theme_previews.py - Screenshot generator - Theme gallery with filtering at index.html 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
-rw-r--r--extras/html/themes/amber_glacier/LICENSE21
-rw-r--r--extras/html/themes/amber_glacier/code.ttfbin0 -> 64104 bytes
-rw-r--r--extras/html/themes/amber_glacier/example.html75
-rw-r--r--extras/html/themes/amber_glacier/handnotes.ttfbin0 -> 38344 bytes
-rw-r--r--extras/html/themes/amber_glacier/style.css168
-rw-r--r--extras/html/themes/amber_glacier/text.ttfbin0 -> 149120 bytes
-rw-r--r--extras/html/themes/amber_glacier/theme.conf8
-rw-r--r--extras/html/themes/aurora_breeze/LICENSE21
-rw-r--r--extras/html/themes/aurora_breeze/code.ttfbin0 -> 367144 bytes
-rw-r--r--extras/html/themes/aurora_breeze/example.html75
-rw-r--r--extras/html/themes/aurora_breeze/handnotes.ttfbin0 -> 38344 bytes
-rw-r--r--extras/html/themes/aurora_breeze/heading.ttfbin0 -> 142040 bytes
-rw-r--r--extras/html/themes/aurora_breeze/style.css166
-rw-r--r--extras/html/themes/aurora_breeze/theme.conf8
-rw-r--r--extras/html/themes/aurora_dawn/LICENSE21
-rw-r--r--extras/html/themes/aurora_dawn/code.ttfbin0 -> 64104 bytes
-rw-r--r--extras/html/themes/aurora_dawn/example.html75
-rw-r--r--extras/html/themes/aurora_dawn/handnotes.ttfbin0 -> 38344 bytes
-rw-r--r--extras/html/themes/aurora_dawn/heading.ttfbin0 -> 1854788 bytes
-rw-r--r--extras/html/themes/aurora_dawn/style.css176
-rw-r--r--extras/html/themes/aurora_dawn/theme.conf8
-rw-r--r--extras/html/themes/bold_pulse/LICENSE21
-rw-r--r--extras/html/themes/bold_pulse/code.ttfbin0 -> 367144 bytes
-rw-r--r--extras/html/themes/bold_pulse/example.html75
-rw-r--r--extras/html/themes/bold_pulse/handnotes.ttfbin0 -> 38344 bytes
-rw-r--r--extras/html/themes/bold_pulse/style.css198
-rw-r--r--extras/html/themes/bold_pulse/text.ttfbin0 -> 75152 bytes
-rw-r--r--extras/html/themes/bold_pulse/theme.conf8
-rw-r--r--extras/html/themes/bright_light/LICENSE21
-rw-r--r--extras/html/themes/bright_light/code.ttfbin0 -> 367144 bytes
-rw-r--r--extras/html/themes/bright_light/example.html75
-rw-r--r--extras/html/themes/bright_light/handnotes.ttfbin0 -> 38344 bytes
-rw-r--r--extras/html/themes/bright_light/heading.ttfbin0 -> 142040 bytes
-rw-r--r--extras/html/themes/bright_light/style.css176
-rw-r--r--extras/html/themes/bright_light/theme.conf8
-rw-r--r--extras/html/themes/bright_spark/LICENSE21
-rw-r--r--extras/html/themes/bright_spark/code.ttfbin0 -> 64104 bytes
-rw-r--r--extras/html/themes/bright_spark/example.html75
-rw-r--r--extras/html/themes/bright_spark/handnotes.ttfbin0 -> 38344 bytes
-rw-r--r--extras/html/themes/bright_spark/style.css187
-rw-r--r--extras/html/themes/bright_spark/theme.conf8
-rw-r--r--extras/html/themes/business/style.css2
-rw-r--r--extras/html/themes/clean_garden/LICENSE21
-rw-r--r--extras/html/themes/clean_garden/code.ttfbin0 -> 367144 bytes
-rw-r--r--extras/html/themes/clean_garden/example.html75
-rw-r--r--extras/html/themes/clean_garden/handnotes.ttfbin0 -> 38344 bytes
-rw-r--r--extras/html/themes/clean_garden/heading.ttfbin0 -> 58448 bytes
-rw-r--r--extras/html/themes/clean_garden/style.css176
-rw-r--r--extras/html/themes/clean_garden/text.ttfbin0 -> 149120 bytes
-rw-r--r--extras/html/themes/clean_garden/theme.conf8
-rw-r--r--extras/html/themes/clean_rhythm/LICENSE21
-rw-r--r--extras/html/themes/clean_rhythm/code.ttfbin0 -> 367144 bytes
-rw-r--r--extras/html/themes/clean_rhythm/example.html75
-rw-r--r--extras/html/themes/clean_rhythm/handnotes.ttfbin0 -> 38344 bytes
-rw-r--r--extras/html/themes/clean_rhythm/heading.ttfbin0 -> 142040 bytes
-rw-r--r--extras/html/themes/clean_rhythm/style.css211
-rw-r--r--extras/html/themes/clean_rhythm/theme.conf8
-rw-r--r--extras/html/themes/clear_forest/LICENSE21
-rw-r--r--extras/html/themes/clear_forest/code.ttfbin0 -> 356060 bytes
-rw-r--r--extras/html/themes/clear_forest/example.html75
-rw-r--r--extras/html/themes/clear_forest/handnotes.ttfbin0 -> 38344 bytes
-rw-r--r--extras/html/themes/clear_forest/heading.ttfbin0 -> 18056 bytes
-rw-r--r--extras/html/themes/clear_forest/style.css208
-rw-r--r--extras/html/themes/clear_forest/theme.conf8
-rw-r--r--extras/html/themes/clear_frost/LICENSE21
-rw-r--r--extras/html/themes/clear_frost/code.ttfbin0 -> 64104 bytes
-rw-r--r--extras/html/themes/clear_frost/example.html75
-rw-r--r--extras/html/themes/clear_frost/handnotes.ttfbin0 -> 38344 bytes
-rw-r--r--extras/html/themes/clear_frost/style.css180
-rw-r--r--extras/html/themes/clear_frost/theme.conf8
-rw-r--r--extras/html/themes/cool_breeze/LICENSE21
-rw-r--r--extras/html/themes/cool_breeze/code.ttfbin0 -> 367144 bytes
-rw-r--r--extras/html/themes/cool_breeze/example.html75
-rw-r--r--extras/html/themes/cool_breeze/handnotes.ttfbin0 -> 38344 bytes
-rw-r--r--extras/html/themes/cool_breeze/heading.ttfbin0 -> 58448 bytes
-rw-r--r--extras/html/themes/cool_breeze/style.css208
-rw-r--r--extras/html/themes/cool_breeze/text.ttfbin0 -> 149120 bytes
-rw-r--r--extras/html/themes/cool_breeze/theme.conf8
-rw-r--r--extras/html/themes/cosmic_dusk/LICENSE21
-rw-r--r--extras/html/themes/cosmic_dusk/code.ttfbin0 -> 356060 bytes
-rw-r--r--extras/html/themes/cosmic_dusk/example.html75
-rw-r--r--extras/html/themes/cosmic_dusk/handnotes.ttfbin0 -> 38344 bytes
-rw-r--r--extras/html/themes/cosmic_dusk/heading.ttfbin0 -> 38344 bytes
-rw-r--r--extras/html/themes/cosmic_dusk/style.css216
-rw-r--r--extras/html/themes/cosmic_dusk/text.ttfbin0 -> 75152 bytes
-rw-r--r--extras/html/themes/cosmic_dusk/theme.conf8
-rw-r--r--extras/html/themes/cosmic_odyssey/LICENSE21
-rw-r--r--extras/html/themes/cosmic_odyssey/code.ttfbin0 -> 367144 bytes
-rw-r--r--extras/html/themes/cosmic_odyssey/example.html75
-rw-r--r--extras/html/themes/cosmic_odyssey/handnotes.ttfbin0 -> 38344 bytes
-rw-r--r--extras/html/themes/cosmic_odyssey/style.css166
-rw-r--r--extras/html/themes/cosmic_odyssey/text.ttfbin0 -> 75152 bytes
-rw-r--r--extras/html/themes/cosmic_odyssey/theme.conf8
-rw-r--r--extras/html/themes/cozy_crystal/LICENSE21
-rw-r--r--extras/html/themes/cozy_crystal/code.ttfbin0 -> 367144 bytes
-rw-r--r--extras/html/themes/cozy_crystal/example.html75
-rw-r--r--extras/html/themes/cozy_crystal/handnotes.ttfbin0 -> 38344 bytes
-rw-r--r--extras/html/themes/cozy_crystal/heading.ttfbin0 -> 151464 bytes
-rw-r--r--extras/html/themes/cozy_crystal/style.css187
-rw-r--r--extras/html/themes/cozy_crystal/theme.conf8
-rw-r--r--extras/html/themes/cozy_wave/LICENSE21
-rw-r--r--extras/html/themes/cozy_wave/code.ttfbin0 -> 367144 bytes
-rw-r--r--extras/html/themes/cozy_wave/example.html75
-rw-r--r--extras/html/themes/cozy_wave/handnotes.ttfbin0 -> 38344 bytes
-rw-r--r--extras/html/themes/cozy_wave/heading.ttfbin0 -> 151464 bytes
-rw-r--r--extras/html/themes/cozy_wave/style.css187
-rw-r--r--extras/html/themes/cozy_wave/theme.conf8
-rwxr-xr-xextras/html/themes/create_simple_previews.sh65
-rwxr-xr-xextras/html/themes/create_theme_previews.py292
-rw-r--r--extras/html/themes/crisp_oasis/LICENSE21
-rw-r--r--extras/html/themes/crisp_oasis/code.ttfbin0 -> 356060 bytes
-rw-r--r--extras/html/themes/crisp_oasis/example.html75
-rw-r--r--extras/html/themes/crisp_oasis/handnotes.ttfbin0 -> 38344 bytes
-rw-r--r--extras/html/themes/crisp_oasis/heading.ttfbin0 -> 58448 bytes
-rw-r--r--extras/html/themes/crisp_oasis/style.css196
-rw-r--r--extras/html/themes/crisp_oasis/text.ttfbin0 -> 75152 bytes
-rw-r--r--extras/html/themes/crisp_oasis/theme.conf8
-rw-r--r--extras/html/themes/deep_crystal/LICENSE21
-rw-r--r--extras/html/themes/deep_crystal/code.ttfbin0 -> 356060 bytes
-rw-r--r--extras/html/themes/deep_crystal/example.html75
-rw-r--r--extras/html/themes/deep_crystal/handnotes.ttfbin0 -> 38344 bytes
-rw-r--r--extras/html/themes/deep_crystal/heading.ttfbin0 -> 58448 bytes
-rw-r--r--extras/html/themes/deep_crystal/style.css181
-rw-r--r--extras/html/themes/deep_crystal/text.ttfbin0 -> 75152 bytes
-rw-r--r--extras/html/themes/deep_crystal/theme.conf8
-rw-r--r--extras/html/themes/deep_sky/LICENSE21
-rw-r--r--extras/html/themes/deep_sky/code.ttfbin0 -> 367144 bytes
-rw-r--r--extras/html/themes/deep_sky/example.html75
-rw-r--r--extras/html/themes/deep_sky/handnotes.ttfbin0 -> 38344 bytes
-rw-r--r--extras/html/themes/deep_sky/heading.ttfbin0 -> 142040 bytes
-rw-r--r--extras/html/themes/deep_sky/style.css230
-rw-r--r--extras/html/themes/deep_sky/theme.conf8
-rw-r--r--extras/html/themes/default/style.css5
-rw-r--r--extras/html/themes/dynamic_forest/LICENSE21
-rw-r--r--extras/html/themes/dynamic_forest/code.ttfbin0 -> 356060 bytes
-rw-r--r--extras/html/themes/dynamic_forest/example.html75
-rw-r--r--extras/html/themes/dynamic_forest/handnotes.ttfbin0 -> 38344 bytes
-rw-r--r--extras/html/themes/dynamic_forest/heading.ttfbin0 -> 18056 bytes
-rw-r--r--extras/html/themes/dynamic_forest/style.css175
-rw-r--r--extras/html/themes/dynamic_forest/theme.conf8
-rw-r--r--extras/html/themes/ember_mist/LICENSE21
-rw-r--r--extras/html/themes/ember_mist/code.ttfbin0 -> 64104 bytes
-rw-r--r--extras/html/themes/ember_mist/example.html75
-rw-r--r--extras/html/themes/ember_mist/handnotes.ttfbin0 -> 38344 bytes
-rw-r--r--extras/html/themes/ember_mist/style.css181
-rw-r--r--extras/html/themes/ember_mist/text.ttfbin0 -> 149120 bytes
-rw-r--r--extras/html/themes/ember_mist/theme.conf8
-rw-r--r--extras/html/themes/ember_mountain/LICENSE21
-rw-r--r--extras/html/themes/ember_mountain/code.ttfbin0 -> 367144 bytes
-rw-r--r--extras/html/themes/ember_mountain/example.html75
-rw-r--r--extras/html/themes/ember_mountain/handnotes.ttfbin0 -> 38344 bytes
-rw-r--r--extras/html/themes/ember_mountain/style.css168
-rw-r--r--extras/html/themes/ember_mountain/text.ttfbin0 -> 75152 bytes
-rw-r--r--extras/html/themes/ember_mountain/theme.conf8
-rw-r--r--extras/html/themes/ember_night/LICENSE21
-rw-r--r--extras/html/themes/ember_night/code.ttfbin0 -> 367144 bytes
-rw-r--r--extras/html/themes/ember_night/example.html75
-rw-r--r--extras/html/themes/ember_night/handnotes.ttfbin0 -> 38344 bytes
-rw-r--r--extras/html/themes/ember_night/heading.ttfbin0 -> 151464 bytes
-rw-r--r--extras/html/themes/ember_night/style.css166
-rw-r--r--extras/html/themes/ember_night/theme.conf8
-rw-r--r--extras/html/themes/ethereal_mist/LICENSE21
-rw-r--r--extras/html/themes/ethereal_mist/code.ttfbin0 -> 367144 bytes
-rw-r--r--extras/html/themes/ethereal_mist/example.html75
-rw-r--r--extras/html/themes/ethereal_mist/handnotes.ttfbin0 -> 38344 bytes
-rw-r--r--extras/html/themes/ethereal_mist/heading.ttfbin0 -> 18056 bytes
-rw-r--r--extras/html/themes/ethereal_mist/style.css176
-rw-r--r--extras/html/themes/ethereal_mist/theme.conf8
-rwxr-xr-xextras/html/themes/fix_css_validation.py196
-rw-r--r--extras/html/themes/fresh_field/LICENSE21
-rw-r--r--extras/html/themes/fresh_field/code.ttfbin0 -> 64104 bytes
-rw-r--r--extras/html/themes/fresh_field/example.html75
-rw-r--r--extras/html/themes/fresh_field/handnotes.ttfbin0 -> 38344 bytes
-rw-r--r--extras/html/themes/fresh_field/style.css216
-rw-r--r--extras/html/themes/fresh_field/text.ttfbin0 -> 149120 bytes
-rw-r--r--extras/html/themes/fresh_field/theme.conf8
-rw-r--r--extras/html/themes/future/style.css11
-rwxr-xr-xextras/html/themes/generate_50_themes.py1741
-rwxr-xr-xextras/html/themes/generate_better_screenshots.py196
-rw-r--r--extras/html/themes/generate_html_screenshots.py252
-rw-r--r--extras/html/themes/generate_random_themes.py1008
-rwxr-xr-xextras/html/themes/generate_screenshots.py246
-rw-r--r--extras/html/themes/gentle_glacier/LICENSE21
-rw-r--r--extras/html/themes/gentle_glacier/code.ttfbin0 -> 64104 bytes
-rw-r--r--extras/html/themes/gentle_glacier/example.html75
-rw-r--r--extras/html/themes/gentle_glacier/handnotes.ttfbin0 -> 38344 bytes
-rw-r--r--extras/html/themes/gentle_glacier/style.css168
-rw-r--r--extras/html/themes/gentle_glacier/theme.conf8
-rw-r--r--extras/html/themes/index.html469
-rw-r--r--extras/html/themes/modern_rhythm/LICENSE21
-rw-r--r--extras/html/themes/modern_rhythm/code.ttfbin0 -> 64104 bytes
-rw-r--r--extras/html/themes/modern_rhythm/example.html75
-rw-r--r--extras/html/themes/modern_rhythm/handnotes.ttfbin0 -> 38344 bytes
-rw-r--r--extras/html/themes/modern_rhythm/heading.ttfbin0 -> 38260 bytes
-rw-r--r--extras/html/themes/modern_rhythm/style.css173
-rw-r--r--extras/html/themes/modern_rhythm/text.ttfbin0 -> 149120 bytes
-rw-r--r--extras/html/themes/modern_rhythm/theme.conf8
-rw-r--r--extras/html/themes/modern_storm/LICENSE21
-rw-r--r--extras/html/themes/modern_storm/code.ttfbin0 -> 64104 bytes
-rw-r--r--extras/html/themes/modern_storm/example.html75
-rw-r--r--extras/html/themes/modern_storm/handnotes.ttfbin0 -> 38344 bytes
-rw-r--r--extras/html/themes/modern_storm/style.css161
-rw-r--r--extras/html/themes/modern_storm/theme.conf8
-rw-r--r--extras/html/themes/muted_oasis/LICENSE21
-rw-r--r--extras/html/themes/muted_oasis/code.ttfbin0 -> 64104 bytes
-rw-r--r--extras/html/themes/muted_oasis/example.html75
-rw-r--r--extras/html/themes/muted_oasis/handnotes.ttfbin0 -> 38344 bytes
-rw-r--r--extras/html/themes/muted_oasis/style.css208
-rw-r--r--extras/html/themes/muted_oasis/text.ttfbin0 -> 149120 bytes
-rw-r--r--extras/html/themes/muted_oasis/theme.conf8
-rw-r--r--extras/html/themes/mystic_canyon/LICENSE21
-rw-r--r--extras/html/themes/mystic_canyon/code.ttfbin0 -> 367144 bytes
-rw-r--r--extras/html/themes/mystic_canyon/example.html75
-rw-r--r--extras/html/themes/mystic_canyon/handnotes.ttfbin0 -> 38344 bytes
-rw-r--r--extras/html/themes/mystic_canyon/heading.ttfbin0 -> 151464 bytes
-rw-r--r--extras/html/themes/mystic_canyon/style.css154
-rw-r--r--extras/html/themes/mystic_canyon/theme.conf8
-rw-r--r--extras/html/themes/mystic_meadow/LICENSE21
-rw-r--r--extras/html/themes/mystic_meadow/code.ttfbin0 -> 64104 bytes
-rw-r--r--extras/html/themes/mystic_meadow/example.html75
-rw-r--r--extras/html/themes/mystic_meadow/handnotes.ttfbin0 -> 38344 bytes
-rw-r--r--extras/html/themes/mystic_meadow/style.css176
-rw-r--r--extras/html/themes/mystic_meadow/theme.conf8
-rw-r--r--extras/html/themes/neon_storm/LICENSE21
-rw-r--r--extras/html/themes/neon_storm/code.ttfbin0 -> 367144 bytes
-rw-r--r--extras/html/themes/neon_storm/example.html75
-rw-r--r--extras/html/themes/neon_storm/handnotes.ttfbin0 -> 38344 bytes
-rw-r--r--extras/html/themes/neon_storm/heading.ttfbin0 -> 58448 bytes
-rw-r--r--extras/html/themes/neon_storm/style.css205
-rw-r--r--extras/html/themes/neon_storm/text.ttfbin0 -> 149120 bytes
-rw-r--r--extras/html/themes/neon_storm/theme.conf8
-rw-r--r--extras/html/themes/pastel_canyon/LICENSE21
-rw-r--r--extras/html/themes/pastel_canyon/code.ttfbin0 -> 367144 bytes
-rw-r--r--extras/html/themes/pastel_canyon/example.html75
-rw-r--r--extras/html/themes/pastel_canyon/handnotes.ttfbin0 -> 38344 bytes
-rw-r--r--extras/html/themes/pastel_canyon/heading.ttfbin0 -> 142040 bytes
-rw-r--r--extras/html/themes/pastel_canyon/style.css173
-rw-r--r--extras/html/themes/pastel_canyon/theme.conf8
-rw-r--r--extras/html/themes/pastel_crystal/LICENSE21
-rw-r--r--extras/html/themes/pastel_crystal/code.ttfbin0 -> 356060 bytes
-rw-r--r--extras/html/themes/pastel_crystal/example.html75
-rw-r--r--extras/html/themes/pastel_crystal/handnotes.ttfbin0 -> 38344 bytes
-rw-r--r--extras/html/themes/pastel_crystal/heading.ttfbin0 -> 38344 bytes
-rw-r--r--extras/html/themes/pastel_crystal/style.css196
-rw-r--r--extras/html/themes/pastel_crystal/text.ttfbin0 -> 75152 bytes
-rw-r--r--extras/html/themes/pastel_crystal/theme.conf8
-rw-r--r--extras/html/themes/pure_storm/LICENSE21
-rw-r--r--extras/html/themes/pure_storm/code.ttfbin0 -> 356060 bytes
-rw-r--r--extras/html/themes/pure_storm/example.html75
-rw-r--r--extras/html/themes/pure_storm/handnotes.ttfbin0 -> 38344 bytes
-rw-r--r--extras/html/themes/pure_storm/heading.ttfbin0 -> 1854788 bytes
-rw-r--r--extras/html/themes/pure_storm/style.css161
-rw-r--r--extras/html/themes/pure_storm/text.ttfbin0 -> 75152 bytes
-rw-r--r--extras/html/themes/pure_storm/theme.conf8
-rw-r--r--extras/html/themes/pure_voyage/LICENSE21
-rw-r--r--extras/html/themes/pure_voyage/code.ttfbin0 -> 356060 bytes
-rw-r--r--extras/html/themes/pure_voyage/example.html75
-rw-r--r--extras/html/themes/pure_voyage/handnotes.ttfbin0 -> 38344 bytes
-rw-r--r--extras/html/themes/pure_voyage/heading.ttfbin0 -> 1854788 bytes
-rw-r--r--extras/html/themes/pure_voyage/style.css154
-rw-r--r--extras/html/themes/pure_voyage/text.ttfbin0 -> 75152 bytes
-rw-r--r--extras/html/themes/pure_voyage/theme.conf8
-rw-r--r--extras/html/themes/radiant_voyage/LICENSE21
-rw-r--r--extras/html/themes/radiant_voyage/code.ttfbin0 -> 64104 bytes
-rw-r--r--extras/html/themes/radiant_voyage/example.html75
-rw-r--r--extras/html/themes/radiant_voyage/handnotes.ttfbin0 -> 38344 bytes
-rw-r--r--extras/html/themes/radiant_voyage/style.css216
-rw-r--r--extras/html/themes/radiant_voyage/text.ttfbin0 -> 149120 bytes
-rw-r--r--extras/html/themes/radiant_voyage/theme.conf8
-rw-r--r--extras/html/themes/refined_aurora/LICENSE21
-rw-r--r--extras/html/themes/refined_aurora/code.ttfbin0 -> 356060 bytes
-rw-r--r--extras/html/themes/refined_aurora/example.html75
-rw-r--r--extras/html/themes/refined_aurora/handnotes.ttfbin0 -> 38344 bytes
-rw-r--r--extras/html/themes/refined_aurora/heading.ttfbin0 -> 58448 bytes
-rw-r--r--extras/html/themes/refined_aurora/style.css176
-rw-r--r--extras/html/themes/refined_aurora/text.ttfbin0 -> 75152 bytes
-rw-r--r--extras/html/themes/refined_aurora/theme.conf8
-rw-r--r--extras/html/themes/refined_oasis/LICENSE21
-rw-r--r--extras/html/themes/refined_oasis/code.ttfbin0 -> 64104 bytes
-rw-r--r--extras/html/themes/refined_oasis/example.html75
-rw-r--r--extras/html/themes/refined_oasis/handnotes.ttfbin0 -> 38344 bytes
-rw-r--r--extras/html/themes/refined_oasis/heading.ttfbin0 -> 38260 bytes
-rw-r--r--extras/html/themes/refined_oasis/style.css173
-rw-r--r--extras/html/themes/refined_oasis/text.ttfbin0 -> 149120 bytes
-rw-r--r--extras/html/themes/refined_oasis/theme.conf8
-rw-r--r--extras/html/themes/retrosimple/style.css2
-rw-r--r--extras/html/themes/screenshots/abyss.pngbin0 -> 169404 bytes
-rw-r--r--extras/html/themes/screenshots/amber.pngbin0 -> 111368 bytes
-rw-r--r--extras/html/themes/screenshots/amber_glacier.pngbin0 -> 8227 bytes
-rw-r--r--extras/html/themes/screenshots/arctic.pngbin0 -> 58117 bytes
-rw-r--r--extras/html/themes/screenshots/aurora_breeze.pngbin0 -> 7582 bytes
-rw-r--r--extras/html/themes/screenshots/aurora_dawn.pngbin0 -> 7514 bytes
-rw-r--r--extras/html/themes/screenshots/autumn.pngbin0 -> 93162 bytes
-rw-r--r--extras/html/themes/screenshots/bamboo.pngbin0 -> 36062 bytes
-rw-r--r--extras/html/themes/screenshots/bark.pngbin0 -> 80865 bytes
-rw-r--r--extras/html/themes/screenshots/bold_pulse.pngbin0 -> 6970 bytes
-rw-r--r--extras/html/themes/screenshots/bright_light.pngbin0 -> 7386 bytes
-rw-r--r--extras/html/themes/screenshots/bright_spark.pngbin0 -> 7332 bytes
-rw-r--r--extras/html/themes/screenshots/business.pngbin0 -> 6658 bytes
-rw-r--r--extras/html/themes/screenshots/charcoal.pngbin0 -> 68319 bytes
-rw-r--r--extras/html/themes/screenshots/chrome.pngbin0 -> 55102 bytes
-rw-r--r--extras/html/themes/screenshots/clean.pngbin0 -> 52444 bytes
-rw-r--r--extras/html/themes/screenshots/clean_garden.pngbin0 -> 7736 bytes
-rw-r--r--extras/html/themes/screenshots/clean_rhythm.pngbin0 -> 6947 bytes
-rw-r--r--extras/html/themes/screenshots/clear_forest.pngbin0 -> 7047 bytes
-rw-r--r--extras/html/themes/screenshots/clear_frost.pngbin0 -> 7046 bytes
-rw-r--r--extras/html/themes/screenshots/cobalt.pngbin0 -> 166795 bytes
-rw-r--r--extras/html/themes/screenshots/cool_breeze.pngbin0 -> 6743 bytes
-rw-r--r--extras/html/themes/screenshots/copper.pngbin0 -> 175123 bytes
-rw-r--r--extras/html/themes/screenshots/coral.pngbin0 -> 297832 bytes
-rw-r--r--extras/html/themes/screenshots/cosmic_dusk.pngbin0 -> 2340 bytes
-rw-r--r--extras/html/themes/screenshots/cosmic_odyssey.pngbin0 -> 7721 bytes
-rw-r--r--extras/html/themes/screenshots/cosmos.pngbin0 -> 32675 bytes
-rw-r--r--extras/html/themes/screenshots/cozy_crystal.pngbin0 -> 7304 bytes
-rw-r--r--extras/html/themes/screenshots/cozy_wave.pngbin0 -> 7306 bytes
-rw-r--r--extras/html/themes/screenshots/crimson.pngbin0 -> 61446 bytes
-rw-r--r--extras/html/themes/screenshots/crisp_oasis.pngbin0 -> 6774 bytes
-rw-r--r--extras/html/themes/screenshots/deep_crystal.pngbin0 -> 7473 bytes
-rw-r--r--extras/html/themes/screenshots/deep_sky.pngbin0 -> 6971 bytes
-rw-r--r--extras/html/themes/screenshots/default.pngbin0 -> 6636 bytes
-rw-r--r--extras/html/themes/screenshots/dusk.pngbin0 -> 64829 bytes
-rw-r--r--extras/html/themes/screenshots/dynamic_forest.pngbin0 -> 7739 bytes
-rw-r--r--extras/html/themes/screenshots/ember_mist.pngbin0 -> 7374 bytes
-rw-r--r--extras/html/themes/screenshots/ember_mountain.pngbin0 -> 8455 bytes
-rw-r--r--extras/html/themes/screenshots/ember_night.pngbin0 -> 7400 bytes
-rw-r--r--extras/html/themes/screenshots/ethereal_mist.pngbin0 -> 7658 bytes
-rw-r--r--extras/html/themes/screenshots/fern.pngbin0 -> 161659 bytes
-rw-r--r--extras/html/themes/screenshots/forest.pngbin0 -> 130549 bytes
-rw-r--r--extras/html/themes/screenshots/fresh_field.pngbin0 -> 2232 bytes
-rw-r--r--extras/html/themes/screenshots/frost.pngbin0 -> 167120 bytes
-rw-r--r--extras/html/themes/screenshots/future.pngbin0 -> 6471 bytes
-rw-r--r--extras/html/themes/screenshots/gentle_glacier.pngbin0 -> 8191 bytes
-rw-r--r--extras/html/themes/screenshots/jade.pngbin0 -> 182481 bytes
-rw-r--r--extras/html/themes/screenshots/lavender.pngbin0 -> 134308 bytes
-rw-r--r--extras/html/themes/screenshots/maroon.pngbin0 -> 160373 bytes
-rw-r--r--extras/html/themes/screenshots/meadow.pngbin0 -> 101315 bytes
-rw-r--r--extras/html/themes/screenshots/midnight.pngbin0 -> 145662 bytes
-rw-r--r--extras/html/themes/screenshots/minimal.pngbin0 -> 5422 bytes
-rw-r--r--extras/html/themes/screenshots/modern_rhythm.pngbin0 -> 7002 bytes
-rw-r--r--extras/html/themes/screenshots/modern_storm.pngbin0 -> 7038 bytes
-rw-r--r--extras/html/themes/screenshots/mono.pngbin0 -> 11447 bytes
-rw-r--r--extras/html/themes/screenshots/moonlight.pngbin0 -> 5262 bytes
-rw-r--r--extras/html/themes/screenshots/moss.pngbin0 -> 163127 bytes
-rw-r--r--extras/html/themes/screenshots/muted_oasis.pngbin0 -> 7039 bytes
-rw-r--r--extras/html/themes/screenshots/mystic_canyon.pngbin0 -> 7051 bytes
-rw-r--r--extras/html/themes/screenshots/mystic_meadow.pngbin0 -> 8034 bytes
-rw-r--r--extras/html/themes/screenshots/neon_storm.pngbin0 -> 7068 bytes
-rw-r--r--extras/html/themes/screenshots/noir.pngbin0 -> 62562 bytes
-rw-r--r--extras/html/themes/screenshots/nordic.pngbin0 -> 103945 bytes
-rw-r--r--extras/html/themes/screenshots/obsidian.pngbin0 -> 5249 bytes
-rw-r--r--extras/html/themes/screenshots/ocean.pngbin0 -> 69350 bytes
-rw-r--r--extras/html/themes/screenshots/onyx.pngbin0 -> 55515 bytes
-rw-r--r--extras/html/themes/screenshots/pastel_canyon.pngbin0 -> 8817 bytes
-rw-r--r--extras/html/themes/screenshots/pastel_crystal.pngbin0 -> 6702 bytes
-rw-r--r--extras/html/themes/screenshots/periwinkle.pngbin0 -> 104743 bytes
-rw-r--r--extras/html/themes/screenshots/pine.pngbin0 -> 60280 bytes
-rw-r--r--extras/html/themes/screenshots/pure.pngbin0 -> 5197 bytes
-rw-r--r--extras/html/themes/screenshots/pure_storm.pngbin0 -> 6862 bytes
-rw-r--r--extras/html/themes/screenshots/pure_voyage.pngbin0 -> 7372 bytes
-rw-r--r--extras/html/themes/screenshots/quartz.pngbin0 -> 50474 bytes
-rw-r--r--extras/html/themes/screenshots/radiant_voyage.pngbin0 -> 2306 bytes
-rw-r--r--extras/html/themes/screenshots/raven.pngbin0 -> 129860 bytes
-rw-r--r--extras/html/themes/screenshots/refined_aurora.pngbin0 -> 7763 bytes
-rw-r--r--extras/html/themes/screenshots/refined_oasis.pngbin0 -> 6890 bytes
-rw-r--r--extras/html/themes/screenshots/retrosimple.pngbin0 -> 6874 bytes
-rw-r--r--extras/html/themes/screenshots/rosegold.pngbin0 -> 180753 bytes
-rw-r--r--extras/html/themes/screenshots/sage.pngbin0 -> 80095 bytes
-rw-r--r--extras/html/themes/screenshots/sandstone.pngbin0 -> 65810 bytes
-rw-r--r--extras/html/themes/screenshots/sapphire.pngbin0 -> 343440 bytes
-rw-r--r--extras/html/themes/screenshots/shadow.pngbin0 -> 97697 bytes
-rw-r--r--extras/html/themes/screenshots/sharp_canyon.pngbin0 -> 6927 bytes
-rw-r--r--extras/html/themes/screenshots/sharp_mountain.pngbin0 -> 7174 bytes
-rw-r--r--extras/html/themes/screenshots/simple.pngbin0 -> 6651 bytes
-rw-r--r--extras/html/themes/screenshots/slate.pngbin0 -> 113559 bytes
-rw-r--r--extras/html/themes/screenshots/sleek_river.pngbin0 -> 7042 bytes
-rw-r--r--extras/html/themes/screenshots/smooth_echo.pngbin0 -> 7194 bytes
-rw-r--r--extras/html/themes/screenshots/soft_horizon.pngbin0 -> 7991 bytes
-rw-r--r--extras/html/themes/screenshots/stark.pngbin0 -> 26821 bytes
-rw-r--r--extras/html/themes/screenshots/strong_breeze.pngbin0 -> 7393 bytes
-rw-r--r--extras/html/themes/screenshots/sunset.pngbin0 -> 79364 bytes
-rw-r--r--extras/html/themes/screenshots/teal.pngbin0 -> 84759 bytes
-rw-r--r--extras/html/themes/screenshots/terracotta.pngbin0 -> 130812 bytes
-rw-r--r--extras/html/themes/screenshots/titanium.pngbin0 -> 102717 bytes
-rw-r--r--extras/html/themes/screenshots/twilight_horizon.pngbin0 -> 8499 bytes
-rw-r--r--extras/html/themes/screenshots/twilight_meadow.pngbin0 -> 7071 bytes
-rw-r--r--extras/html/themes/screenshots/twilight_nebula.pngbin0 -> 7219 bytes
-rw-r--r--extras/html/themes/screenshots/vibrant_garden.pngbin0 -> 7339 bytes
-rw-r--r--extras/html/themes/screenshots/vibrant_nebula.pngbin0 -> 6988 bytes
-rw-r--r--extras/html/themes/screenshots/vibrant_storm.pngbin0 -> 2258 bytes
-rw-r--r--extras/html/themes/screenshots/willow.pngbin0 -> 123952 bytes
-rw-r--r--extras/html/themes/screenshots/zen.pngbin0 -> 63576 bytes
-rw-r--r--extras/html/themes/sharp_canyon/LICENSE21
-rw-r--r--extras/html/themes/sharp_canyon/code.ttfbin0 -> 64104 bytes
-rw-r--r--extras/html/themes/sharp_canyon/example.html75
-rw-r--r--extras/html/themes/sharp_canyon/handnotes.ttfbin0 -> 38344 bytes
-rw-r--r--extras/html/themes/sharp_canyon/style.css205
-rw-r--r--extras/html/themes/sharp_canyon/theme.conf8
-rw-r--r--extras/html/themes/sharp_mountain/LICENSE21
-rw-r--r--extras/html/themes/sharp_mountain/code.ttfbin0 -> 356060 bytes
-rw-r--r--extras/html/themes/sharp_mountain/example.html75
-rw-r--r--extras/html/themes/sharp_mountain/handnotes.ttfbin0 -> 38344 bytes
-rw-r--r--extras/html/themes/sharp_mountain/style.css154
-rw-r--r--extras/html/themes/sharp_mountain/text.ttfbin0 -> 75152 bytes
-rw-r--r--extras/html/themes/sharp_mountain/theme.conf8
-rw-r--r--extras/html/themes/simple/style.css2
-rw-r--r--extras/html/themes/sleek_river/LICENSE21
-rw-r--r--extras/html/themes/sleek_river/code.ttfbin0 -> 367144 bytes
-rw-r--r--extras/html/themes/sleek_river/example.html75
-rw-r--r--extras/html/themes/sleek_river/handnotes.ttfbin0 -> 38344 bytes
-rw-r--r--extras/html/themes/sleek_river/heading.ttfbin0 -> 151464 bytes
-rw-r--r--extras/html/themes/sleek_river/style.css193
-rw-r--r--extras/html/themes/sleek_river/theme.conf8
-rw-r--r--extras/html/themes/smooth_echo/LICENSE21
-rw-r--r--extras/html/themes/smooth_echo/code.ttfbin0 -> 367144 bytes
-rw-r--r--extras/html/themes/smooth_echo/example.html75
-rw-r--r--extras/html/themes/smooth_echo/handnotes.ttfbin0 -> 38344 bytes
-rw-r--r--extras/html/themes/smooth_echo/heading.ttfbin0 -> 18056 bytes
-rw-r--r--extras/html/themes/smooth_echo/style.css161
-rw-r--r--extras/html/themes/smooth_echo/theme.conf8
-rw-r--r--extras/html/themes/soft_horizon/LICENSE21
-rw-r--r--extras/html/themes/soft_horizon/code.ttfbin0 -> 367144 bytes
-rw-r--r--extras/html/themes/soft_horizon/example.html75
-rw-r--r--extras/html/themes/soft_horizon/handnotes.ttfbin0 -> 38344 bytes
-rw-r--r--extras/html/themes/soft_horizon/heading.ttfbin0 -> 58448 bytes
-rw-r--r--extras/html/themes/soft_horizon/style.css168
-rw-r--r--extras/html/themes/soft_horizon/text.ttfbin0 -> 149120 bytes
-rw-r--r--extras/html/themes/soft_horizon/theme.conf8
-rw-r--r--extras/html/themes/strong_breeze/LICENSE21
-rw-r--r--extras/html/themes/strong_breeze/code.ttfbin0 -> 64104 bytes
-rw-r--r--extras/html/themes/strong_breeze/example.html75
-rw-r--r--extras/html/themes/strong_breeze/handnotes.ttfbin0 -> 38344 bytes
-rw-r--r--extras/html/themes/strong_breeze/style.css193
-rw-r--r--extras/html/themes/strong_breeze/text.ttfbin0 -> 149120 bytes
-rw-r--r--extras/html/themes/strong_breeze/theme.conf8
-rw-r--r--extras/html/themes/test_screenshots.html109
-rw-r--r--extras/html/themes/themes_metadata.json1502
-rw-r--r--extras/html/themes/twilight_horizon/LICENSE21
-rw-r--r--extras/html/themes/twilight_horizon/code.ttfbin0 -> 367144 bytes
-rw-r--r--extras/html/themes/twilight_horizon/example.html75
-rw-r--r--extras/html/themes/twilight_horizon/handnotes.ttfbin0 -> 38344 bytes
-rw-r--r--extras/html/themes/twilight_horizon/heading.ttfbin0 -> 151464 bytes
-rw-r--r--extras/html/themes/twilight_horizon/style.css173
-rw-r--r--extras/html/themes/twilight_horizon/theme.conf8
-rw-r--r--extras/html/themes/twilight_meadow/LICENSE21
-rw-r--r--extras/html/themes/twilight_meadow/code.ttfbin0 -> 64104 bytes
-rw-r--r--extras/html/themes/twilight_meadow/example.html75
-rw-r--r--extras/html/themes/twilight_meadow/handnotes.ttfbin0 -> 38344 bytes
-rw-r--r--extras/html/themes/twilight_meadow/style.css198
-rw-r--r--extras/html/themes/twilight_meadow/theme.conf8
-rw-r--r--extras/html/themes/twilight_nebula/LICENSE21
-rw-r--r--extras/html/themes/twilight_nebula/code.ttfbin0 -> 64104 bytes
-rw-r--r--extras/html/themes/twilight_nebula/example.html75
-rw-r--r--extras/html/themes/twilight_nebula/handnotes.ttfbin0 -> 38344 bytes
-rw-r--r--extras/html/themes/twilight_nebula/style.css187
-rw-r--r--extras/html/themes/twilight_nebula/text.ttfbin0 -> 149120 bytes
-rw-r--r--extras/html/themes/twilight_nebula/theme.conf8
-rw-r--r--extras/html/themes/vibrant_garden/LICENSE21
-rw-r--r--extras/html/themes/vibrant_garden/code.ttfbin0 -> 64104 bytes
-rw-r--r--extras/html/themes/vibrant_garden/example.html75
-rw-r--r--extras/html/themes/vibrant_garden/handnotes.ttfbin0 -> 38344 bytes
-rw-r--r--extras/html/themes/vibrant_garden/heading.ttfbin0 -> 38260 bytes
-rw-r--r--extras/html/themes/vibrant_garden/style.css196
-rw-r--r--extras/html/themes/vibrant_garden/text.ttfbin0 -> 149120 bytes
-rw-r--r--extras/html/themes/vibrant_garden/theme.conf8
-rw-r--r--extras/html/themes/vibrant_nebula/LICENSE21
-rw-r--r--extras/html/themes/vibrant_nebula/code.ttfbin0 -> 367144 bytes
-rw-r--r--extras/html/themes/vibrant_nebula/example.html75
-rw-r--r--extras/html/themes/vibrant_nebula/handnotes.ttfbin0 -> 38344 bytes
-rw-r--r--extras/html/themes/vibrant_nebula/heading.ttfbin0 -> 151464 bytes
-rw-r--r--extras/html/themes/vibrant_nebula/style.css198
-rw-r--r--extras/html/themes/vibrant_nebula/theme.conf8
-rw-r--r--extras/html/themes/vibrant_storm/LICENSE21
-rw-r--r--extras/html/themes/vibrant_storm/code.ttfbin0 -> 367144 bytes
-rw-r--r--extras/html/themes/vibrant_storm/example.html75
-rw-r--r--extras/html/themes/vibrant_storm/handnotes.ttfbin0 -> 38344 bytes
-rw-r--r--extras/html/themes/vibrant_storm/heading.ttfbin0 -> 151464 bytes
-rw-r--r--extras/html/themes/vibrant_storm/style.css216
-rw-r--r--extras/html/themes/vibrant_storm/theme.conf8
478 files changed, 20519 insertions, 14 deletions
diff --git a/extras/html/themes/amber_glacier/LICENSE b/extras/html/themes/amber_glacier/LICENSE
new file mode 100644
index 0000000..a58ff2b
--- /dev/null
+++ b/extras/html/themes/amber_glacier/LICENSE
@@ -0,0 +1,21 @@
+Theme: amber_glacier
+Generated: 2025-06-22 21:38:55
+
+Layout: card
+Color Scheme: monochromatic (Dark)
+
+Font Licenses:
+==============
+Heading Font: oxygen
+License: OFL
+Category: sans-serif
+
+Body Font: Merriweather
+License: OFL
+Category: serif
+
+Code Font: intelone-mono
+License: OFL
+Category: monospace
+
+All fonts are free for personal use.
diff --git a/extras/html/themes/amber_glacier/code.ttf b/extras/html/themes/amber_glacier/code.ttf
new file mode 100644
index 0000000..2711179
--- /dev/null
+++ b/extras/html/themes/amber_glacier/code.ttf
Binary files differ
diff --git a/extras/html/themes/amber_glacier/example.html b/extras/html/themes/amber_glacier/example.html
new file mode 100644
index 0000000..a6f3689
--- /dev/null
+++ b/extras/html/themes/amber_glacier/example.html
@@ -0,0 +1,75 @@
+<!DOCTYPE html>
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
+<head>
+ <meta charset="UTF-8" />
+ <meta name="viewport" content="width=device-width, initial-scale=1.0" />
+ <title>Amber Glacier - Gemtexter Theme</title>
+ <link rel="stylesheet" href="style.css" />
+</head>
+<body>
+ <div class="header">
+ <h1>Amber Glacier</h1>
+ <p>A card layout with monochromatic colors</p>
+ </div>
+
+ <div class="content">
+ <h1>Welcome to Amber Glacier</h1>
+ <p>This theme features a carefully crafted card layout with a dark monochromatic color scheme. The typography combines sans-serif fonts for headings with serif for body text.</p>
+
+ <h2>Typography Showcase</h2>
+ <p>The Merriweather font family provides excellent readability for body text, while oxygen adds character to headings. Code blocks use intelone-mono for clarity.</p>
+
+ <h2>Color Palette</h2>
+ <p>Primary: <span style="color: #49a06f; font-weight: bold;">#49a06f</span> |
+ Secondary: <span style="color: #396a4e; font-weight: bold;">#396a4e</span> |
+ Accent: <span style="color: #72a589; font-weight: bold;">#72a589</span></p>
+
+ <h3>Interactive Elements</h3>
+ <p>Links like <a href="#">this example</a> and longer <a href="#" class="textlink">text links that demonstrate the theme's navigation style</a> use the secondary color.</p>
+
+ <div class="quote">
+ "Design is not just what it looks like and feels like. Design is how it works." — Steve Jobs
+ </div>
+
+ <h3>Code Examples</h3>
+ <p>Inline code like <code>theme.generate()</code> and larger blocks:</p>
+ <pre>// Theme configuration
+const theme = {
+ name: "amber_glacier",
+ layout: "card",
+ colors: {
+ primary: "#49a06f",
+ secondary: "#396a4e",
+ accent: "#72a589"
+ },
+ fonts: {
+ heading: "oxygen",
+ body: "Merriweather",
+ code: "intelone-mono"
+ }
+};</pre>
+
+ <h2>Content Structure</h2>
+ <ul>
+ <li>Clean, readable typography with 16px base font size</li>
+ <li>Heading scale ratio of 1.73x for visual hierarchy</li>
+ <li>Line height of 1.61 for comfortable reading</li>
+ <li>Card layout optimized for content flow</li>
+ <li>Dark theme with monochromatic color harmony</li>
+ </ul>
+
+ <h2>Font Licensing</h2>
+ <p>All fonts used in this theme are properly licensed:</p>
+ <ul>
+ <li>oxygen: OFL License</li>
+ <li>Merriweather: OFL License</li>
+ <li>intelone-mono: OFL License</li>
+ </ul>
+
+ <h3>Final Thoughts</h3>
+ <p>Every element of this theme has been carefully designed to create a harmonious reading experience. The card layout ensures content is presented in an engaging way, while the color scheme provides the perfect backdrop for your words to shine.</p>
+
+ <p>Whether you're writing technical documentation, creative prose, or anything in between, this theme adapts to showcase your content beautifully.</p>
+ </div>
+</body>
+</html> \ No newline at end of file
diff --git a/extras/html/themes/amber_glacier/handnotes.ttf b/extras/html/themes/amber_glacier/handnotes.ttf
new file mode 100644
index 0000000..25e688b
--- /dev/null
+++ b/extras/html/themes/amber_glacier/handnotes.ttf
Binary files differ
diff --git a/extras/html/themes/amber_glacier/style.css b/extras/html/themes/amber_glacier/style.css
new file mode 100644
index 0000000..679b3d6
--- /dev/null
+++ b/extras/html/themes/amber_glacier/style.css
@@ -0,0 +1,168 @@
+/* Base styles */
+@font-face {
+ font-family: 'text';
+ src: url("./text.ttf") format("truetype");
+}
+
+@font-face {
+ font-family: 'heading';
+ src: url("./heading.ttf") format("truetype");
+}
+
+@font-face {
+ font-family: 'code';
+ src: url("./code.ttf") format("truetype");
+}
+
+@font-face {
+ font-family: 'handnotes';
+ src: url("./handnotes.ttf") format("truetype");
+}
+
+:root {
+ --color-primary: #49a06f;
+ --color-secondary: #396a4e;
+ --color-accent: #72a589;
+ --color-bg: #0f1311;
+ --color-text: #e6e6e6;
+ --font-size-base: 16px;
+ --font-size-h1: 1.73em;
+ --font-size-h2: 1.44em;
+ --font-size-h3: 1.2em;
+ --line-height: 1.61;
+}
+
+* {
+ box-sizing: border-box;
+}
+
+html {
+ font-size: var(--font-size-base);
+ -webkit-font-smoothing: antialiased;
+ -moz-osx-font-smoothing: grayscale;
+}
+
+body {
+ font-family: text, sans-serif;
+ background-color: var(--color-bg);
+ color: var(--color-text);
+ line-height: var(--line-height);
+ margin: 0;
+ padding: 0;
+ overflow-wrap: break-word;
+}
+
+h1, h2, h3 {
+ font-family: heading, serif;
+ line-height: 1.2;
+ margin-top: 1em;
+ margin-bottom: 0.5em;
+}
+
+h1 {
+ font-size: var(--font-size-h1);
+ color: var(--color-primary);
+}
+
+h2 {
+ font-size: var(--font-size-h2);
+ color: var(--color-primary);
+}
+
+h3 {
+ font-size: var(--font-size-h3);
+ color: var(--color-secondary);
+}
+
+a {
+ font-family: code, monospace;
+ color: var(--color-secondary);
+ text-decoration: none;
+ transition: all 0.3s ease;
+}
+
+a:hover {
+ color: var(--color-accent);
+ text-decoration: underline;
+}
+
+.textlink {
+ font-family: text, sans-serif;
+}
+
+.quote {
+ font-family: handnotes, cursive;
+ border-left: 4px solid var(--color-accent);
+ padding: 1em 1.5em;
+ margin: 1.5em 0;
+ background-color: rgba(73, 160, 111, 0.07);
+ font-style: italic;
+}
+
+pre {
+ font-family: code, monospace;
+ background-color: rgba(230, 230, 230, 0.04);
+ border: 1px solid rgba(230, 230, 230, 0.13);
+ padding: 1em;
+ overflow-x: auto;
+ border-radius: 4px;
+ font-size: 0.9em;
+}
+
+code {
+ font-family: code, monospace;
+ background-color: rgba(230, 230, 230, 0.04);
+ padding: 0.2em 0.4em;
+ border-radius: 3px;
+ font-size: 0.9em;
+}
+
+ul, ol {
+ padding-left: 2em;
+ margin: 1em 0;
+}
+
+li {
+ margin: 0.5em 0;
+}
+
+img {
+ max-width: 100%;
+ height: auto;
+}
+
+hr {
+ border: none;
+ border-top: 1px solid rgba(230, 230, 230, 0.20);
+ margin: 2em 0;
+}
+
+
+/* Layout: card */
+
+body {
+ padding: 2em;
+ background: linear-gradient(135deg, rgba(73, 160, 111, 0.07), rgba(57, 106, 78, 0.07));
+ min-height: 100vh;
+}
+
+.header {
+ background-color: var(--color-bg);
+ padding: 3em;
+ margin-bottom: 3em;
+ border-radius: 16px;
+ box-shadow: 0 8px 32px rgba(0,0,0,0.1);
+ text-align: center;
+}
+
+h1, h2, h3, p, ul, pre, .quote {
+ background-color: var(--color-bg);
+ padding: 2em;
+ margin: 1em 0;
+ border-radius: 12px;
+ box-shadow: 0 4px 16px rgba(0,0,0,0.05);
+}
+
+h1, h2, h3 {
+ padding: 1em 2em;
+}
diff --git a/extras/html/themes/amber_glacier/text.ttf b/extras/html/themes/amber_glacier/text.ttf
new file mode 100644
index 0000000..3fecc77
--- /dev/null
+++ b/extras/html/themes/amber_glacier/text.ttf
Binary files differ
diff --git a/extras/html/themes/amber_glacier/theme.conf b/extras/html/themes/amber_glacier/theme.conf
new file mode 100644
index 0000000..11ad64d
--- /dev/null
+++ b/extras/html/themes/amber_glacier/theme.conf
@@ -0,0 +1,8 @@
+declare -xr HTML_HEADER=./extras/html/header.html.part
+declare -xr HTML_FOOTER=./extras/html/footer.html.part
+declare -xr HTML_CSS_STYLE=$HTML_THEME_DIR/style.css
+declare -xr HTML_WEBFONT_HEADING=./extras/html/fonts/oxygen/oxygen-Bold.ttf
+declare -xr HTML_WEBFONT_TEXT=./extras/html/fonts/Merriweather/Merriweather-Regular.ttf
+declare -xr HTML_WEBFONT_CODE=./extras/html/fonts/intelone-mono/intelone-mono-Regular.ttf
+declare -xr HTML_WEBFONT_HANDNOTES=./extras/html/fonts/khand/khand.ttf
+declare -xr SOURCE_HIGHLIGHT_CSS=./extras/html/source-highlight-styles/mono.css
diff --git a/extras/html/themes/aurora_breeze/LICENSE b/extras/html/themes/aurora_breeze/LICENSE
new file mode 100644
index 0000000..f825b4c
--- /dev/null
+++ b/extras/html/themes/aurora_breeze/LICENSE
@@ -0,0 +1,21 @@
+Theme: aurora_breeze
+Generated: 2025-06-22 21:38:55
+
+Layout: gradient
+Color Scheme: triadic (Light)
+
+Font Licenses:
+==============
+Heading Font: Merriweather
+License: OFL
+Category: serif
+
+Body Font: oxygen
+License: OFL
+Category: sans-serif
+
+Code Font: hack
+License: MIT
+Category: monospace
+
+All fonts are free for personal use.
diff --git a/extras/html/themes/aurora_breeze/code.ttf b/extras/html/themes/aurora_breeze/code.ttf
new file mode 100644
index 0000000..7c8e65b
--- /dev/null
+++ b/extras/html/themes/aurora_breeze/code.ttf
Binary files differ
diff --git a/extras/html/themes/aurora_breeze/example.html b/extras/html/themes/aurora_breeze/example.html
new file mode 100644
index 0000000..9d592f3
--- /dev/null
+++ b/extras/html/themes/aurora_breeze/example.html
@@ -0,0 +1,75 @@
+<!DOCTYPE html>
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
+<head>
+ <meta charset="UTF-8" />
+ <meta name="viewport" content="width=device-width, initial-scale=1.0" />
+ <title>Aurora Breeze - Gemtexter Theme</title>
+ <link rel="stylesheet" href="style.css" />
+</head>
+<body>
+ <div class="header">
+ <h1>Aurora Breeze</h1>
+ <p>A gradient layout with triadic colors</p>
+ </div>
+
+ <div class="content">
+ <h1>Welcome to Aurora Breeze</h1>
+ <p>This theme features a carefully crafted gradient layout with a light triadic color scheme. The typography combines serif fonts for headings with sans-serif for body text.</p>
+
+ <h2>Typography Showcase</h2>
+ <p>The oxygen font family provides excellent readability for body text, while Merriweather adds character to headings. Code blocks use hack for clarity.</p>
+
+ <h2>Color Palette</h2>
+ <p>Primary: <span style="color: #c4a638; font-weight: bold;">#c4a638</span> |
+ Secondary: <span style="color: #38c4a6; font-weight: bold;">#38c4a6</span> |
+ Accent: <span style="color: #a638c4; font-weight: bold;">#a638c4</span></p>
+
+ <h3>Interactive Elements</h3>
+ <p>Links like <a href="#">this example</a> and longer <a href="#" class="textlink">text links that demonstrate the theme's navigation style</a> use the secondary color.</p>
+
+ <div class="quote">
+ "Design is not just what it looks like and feels like. Design is how it works." — Steve Jobs
+ </div>
+
+ <h3>Code Examples</h3>
+ <p>Inline code like <code>theme.generate()</code> and larger blocks:</p>
+ <pre>// Theme configuration
+const theme = {
+ name: "aurora_breeze",
+ layout: "gradient",
+ colors: {
+ primary: "#c4a638",
+ secondary: "#38c4a6",
+ accent: "#a638c4"
+ },
+ fonts: {
+ heading: "Merriweather",
+ body: "oxygen",
+ code: "hack"
+ }
+};</pre>
+
+ <h2>Content Structure</h2>
+ <ul>
+ <li>Clean, readable typography with 18px base font size</li>
+ <li>Heading scale ratio of 2.37x for visual hierarchy</li>
+ <li>Line height of 1.52 for comfortable reading</li>
+ <li>Gradient layout optimized for content flow</li>
+ <li>Light theme with triadic color harmony</li>
+ </ul>
+
+ <h2>Font Licensing</h2>
+ <p>All fonts used in this theme are properly licensed:</p>
+ <ul>
+ <li>Merriweather: OFL License</li>
+ <li>oxygen: OFL License</li>
+ <li>hack: MIT License</li>
+ </ul>
+
+ <h3>Final Thoughts</h3>
+ <p>Every element of this theme has been carefully designed to create a harmonious reading experience. The gradient layout ensures content is presented in an engaging way, while the color scheme provides the perfect backdrop for your words to shine.</p>
+
+ <p>Whether you're writing technical documentation, creative prose, or anything in between, this theme adapts to showcase your content beautifully.</p>
+ </div>
+</body>
+</html> \ No newline at end of file
diff --git a/extras/html/themes/aurora_breeze/handnotes.ttf b/extras/html/themes/aurora_breeze/handnotes.ttf
new file mode 100644
index 0000000..25e688b
--- /dev/null
+++ b/extras/html/themes/aurora_breeze/handnotes.ttf
Binary files differ
diff --git a/extras/html/themes/aurora_breeze/heading.ttf b/extras/html/themes/aurora_breeze/heading.ttf
new file mode 100644
index 0000000..3e10e02
--- /dev/null
+++ b/extras/html/themes/aurora_breeze/heading.ttf
Binary files differ
diff --git a/extras/html/themes/aurora_breeze/style.css b/extras/html/themes/aurora_breeze/style.css
new file mode 100644
index 0000000..04cd498
--- /dev/null
+++ b/extras/html/themes/aurora_breeze/style.css
@@ -0,0 +1,166 @@
+/* Base styles */
+@font-face {
+ font-family: 'text';
+ src: url("./text.ttf") format("truetype");
+}
+
+@font-face {
+ font-family: 'heading';
+ src: url("./heading.ttf") format("truetype");
+}
+
+@font-face {
+ font-family: 'code';
+ src: url("./code.ttf") format("truetype");
+}
+
+@font-face {
+ font-family: 'handnotes';
+ src: url("./handnotes.ttf") format("truetype");
+}
+
+:root {
+ --color-primary: #c4a638;
+ --color-secondary: #38c4a6;
+ --color-accent: #a638c4;
+ --color-bg: #f1f0ee;
+ --color-text: #0d0d0d;
+ --font-size-base: 18px;
+ --font-size-h1: 2.37em;
+ --font-size-h2: 1.78em;
+ --font-size-h3: 1.33em;
+ --line-height: 1.52;
+}
+
+* {
+ box-sizing: border-box;
+}
+
+html {
+ font-size: var(--font-size-base);
+ -webkit-font-smoothing: antialiased;
+ -moz-osx-font-smoothing: grayscale;
+}
+
+body {
+ font-family: text, sans-serif;
+ background-color: var(--color-bg);
+ color: var(--color-text);
+ line-height: var(--line-height);
+ margin: 0;
+ padding: 0;
+ overflow-wrap: break-word;
+}
+
+h1, h2, h3 {
+ font-family: heading, serif;
+ line-height: 1.2;
+ margin-top: 1em;
+ margin-bottom: 0.5em;
+}
+
+h1 {
+ font-size: var(--font-size-h1);
+ color: var(--color-primary);
+}
+
+h2 {
+ font-size: var(--font-size-h2);
+ color: var(--color-primary);
+}
+
+h3 {
+ font-size: var(--font-size-h3);
+ color: var(--color-secondary);
+}
+
+a {
+ font-family: code, monospace;
+ color: var(--color-secondary);
+ text-decoration: none;
+ transition: all 0.3s ease;
+}
+
+a:hover {
+ color: var(--color-accent);
+ text-decoration: underline;
+}
+
+.textlink {
+ font-family: text, sans-serif;
+}
+
+.quote {
+ font-family: handnotes, cursive;
+ border-left: 4px solid var(--color-accent);
+ padding: 1em 1.5em;
+ margin: 1.5em 0;
+ background-color: rgba(196, 166, 56, 0.07);
+ font-style: italic;
+}
+
+pre {
+ font-family: code, monospace;
+ background-color: rgba(13, 13, 13, 0.04);
+ border: 1px solid rgba(13, 13, 13, 0.13);
+ padding: 1em;
+ overflow-x: auto;
+ border-radius: 4px;
+ font-size: 0.9em;
+}
+
+code {
+ font-family: code, monospace;
+ background-color: rgba(13, 13, 13, 0.04);
+ padding: 0.2em 0.4em;
+ border-radius: 3px;
+ font-size: 0.9em;
+}
+
+ul, ol {
+ padding-left: 2em;
+ margin: 1em 0;
+}
+
+li {
+ margin: 0.5em 0;
+}
+
+img {
+ max-width: 100%;
+ height: auto;
+}
+
+hr {
+ border: none;
+ border-top: 1px solid rgba(13, 13, 13, 0.20);
+ margin: 2em 0;
+}
+
+
+/* Layout: gradient */
+
+body {
+ margin: 0;
+ padding: 0;
+ background: linear-gradient(180deg, rgba(196, 166, 56, 0.13) 0%, rgba(56, 196, 166, 0.13) 50%, rgba(166, 56, 196, 0.13) 100%);
+ min-height: 100vh;
+}
+
+.header {
+ text-align: center;
+ padding: 6em 2em;
+ background: rgba(255,255,255,0.1);
+ backdrop-filter: blur(10px);
+ margin-bottom: 4em;
+}
+
+h1, h2, h3, p, ul, pre, .quote {
+ max-width: 65ch;
+ margin: 2em auto;
+ padding: 2em;
+ background: rgba(255,255,255,0.95);
+ backdrop-filter: blur(10px);
+ border-radius: 20px;
+ box-shadow: 0 8px 32px rgba(0,0,0,0.1);
+}
diff --git a/extras/html/themes/aurora_breeze/theme.conf b/extras/html/themes/aurora_breeze/theme.conf
new file mode 100644
index 0000000..98a41f3
--- /dev/null
+++ b/extras/html/themes/aurora_breeze/theme.conf
@@ -0,0 +1,8 @@
+declare -xr HTML_HEADER=./extras/html/header.html.part
+declare -xr HTML_FOOTER=./extras/html/footer.html.part
+declare -xr HTML_CSS_STYLE=$HTML_THEME_DIR/style.css
+declare -xr HTML_WEBFONT_HEADING=./extras/html/fonts/Merriweather/Merriweather-Bold.ttf
+declare -xr HTML_WEBFONT_TEXT=./extras/html/fonts/oxygen/oxygen-Regular.ttf
+declare -xr HTML_WEBFONT_CODE=./extras/html/fonts/hack/hack-Regular.ttf
+declare -xr HTML_WEBFONT_HANDNOTES=./extras/html/fonts/khand/khand.ttf
+declare -xr SOURCE_HIGHLIGHT_CSS=./extras/html/source-highlight-styles/mono.css
diff --git a/extras/html/themes/aurora_dawn/LICENSE b/extras/html/themes/aurora_dawn/LICENSE
new file mode 100644
index 0000000..cd4aaa3
--- /dev/null
+++ b/extras/html/themes/aurora_dawn/LICENSE
@@ -0,0 +1,21 @@
+Theme: aurora_dawn
+Generated: 2025-06-22 21:38:55
+
+Layout: hero
+Color Scheme: triadic (Light)
+
+Font Licenses:
+==============
+Heading Font: higher-jump
+License: Free
+Category: display
+
+Body Font: oxygen
+License: OFL
+Category: sans-serif
+
+Code Font: intelone-mono
+License: OFL
+Category: monospace
+
+All fonts are free for personal use.
diff --git a/extras/html/themes/aurora_dawn/code.ttf b/extras/html/themes/aurora_dawn/code.ttf
new file mode 100644
index 0000000..2711179
--- /dev/null
+++ b/extras/html/themes/aurora_dawn/code.ttf
Binary files differ
diff --git a/extras/html/themes/aurora_dawn/example.html b/extras/html/themes/aurora_dawn/example.html
new file mode 100644
index 0000000..93cb589
--- /dev/null
+++ b/extras/html/themes/aurora_dawn/example.html
@@ -0,0 +1,75 @@
+<!DOCTYPE html>
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
+<head>
+ <meta charset="UTF-8" />
+ <meta name="viewport" content="width=device-width, initial-scale=1.0" />
+ <title>Aurora Dawn - Gemtexter Theme</title>
+ <link rel="stylesheet" href="style.css" />
+</head>
+<body>
+ <div class="header">
+ <h1>Aurora Dawn</h1>
+ <p>A hero layout with triadic colors</p>
+ </div>
+
+ <div class="content">
+ <h1>Welcome to Aurora Dawn</h1>
+ <p>This theme features a carefully crafted hero layout with a light triadic color scheme. The typography combines display fonts for headings with sans-serif for body text.</p>
+
+ <h2>Typography Showcase</h2>
+ <p>The oxygen font family provides excellent readability for body text, while higher-jump adds character to headings. Code blocks use intelone-mono for clarity.</p>
+
+ <h2>Color Palette</h2>
+ <p>Primary: <span style="color: #97c378; font-weight: bold;">#97c378</span> |
+ Secondary: <span style="color: #7897c3; font-weight: bold;">#7897c3</span> |
+ Accent: <span style="color: #c37897; font-weight: bold;">#c37897</span></p>
+
+ <h3>Interactive Elements</h3>
+ <p>Links like <a href="#">this example</a> and longer <a href="#" class="textlink">text links that demonstrate the theme's navigation style</a> use the secondary color.</p>
+
+ <div class="quote">
+ "Design is not just what it looks like and feels like. Design is how it works." — Steve Jobs
+ </div>
+
+ <h3>Code Examples</h3>
+ <p>Inline code like <code>theme.generate()</code> and larger blocks:</p>
+ <pre>// Theme configuration
+const theme = {
+ name: "aurora_dawn",
+ layout: "hero",
+ colors: {
+ primary: "#97c378",
+ secondary: "#7897c3",
+ accent: "#c37897"
+ },
+ fonts: {
+ heading: "higher-jump",
+ body: "oxygen",
+ code: "intelone-mono"
+ }
+};</pre>
+
+ <h2>Content Structure</h2>
+ <ul>
+ <li>Clean, readable typography with 18px base font size</li>
+ <li>Heading scale ratio of 1.42x for visual hierarchy</li>
+ <li>Line height of 1.51 for comfortable reading</li>
+ <li>Hero layout optimized for content flow</li>
+ <li>Light theme with triadic color harmony</li>
+ </ul>
+
+ <h2>Font Licensing</h2>
+ <p>All fonts used in this theme are properly licensed:</p>
+ <ul>
+ <li>higher-jump: Free License</li>
+ <li>oxygen: OFL License</li>
+ <li>intelone-mono: OFL License</li>
+ </ul>
+
+ <h3>Final Thoughts</h3>
+ <p>Every element of this theme has been carefully designed to create a harmonious reading experience. The hero layout ensures content is presented in an engaging way, while the color scheme provides the perfect backdrop for your words to shine.</p>
+
+ <p>Whether you're writing technical documentation, creative prose, or anything in between, this theme adapts to showcase your content beautifully.</p>
+ </div>
+</body>
+</html> \ No newline at end of file
diff --git a/extras/html/themes/aurora_dawn/handnotes.ttf b/extras/html/themes/aurora_dawn/handnotes.ttf
new file mode 100644
index 0000000..25e688b
--- /dev/null
+++ b/extras/html/themes/aurora_dawn/handnotes.ttf
Binary files differ
diff --git a/extras/html/themes/aurora_dawn/heading.ttf b/extras/html/themes/aurora_dawn/heading.ttf
new file mode 100644
index 0000000..608f2ad
--- /dev/null
+++ b/extras/html/themes/aurora_dawn/heading.ttf
Binary files differ
diff --git a/extras/html/themes/aurora_dawn/style.css b/extras/html/themes/aurora_dawn/style.css
new file mode 100644
index 0000000..ec88e1b
--- /dev/null
+++ b/extras/html/themes/aurora_dawn/style.css
@@ -0,0 +1,176 @@
+/* Base styles */
+@font-face {
+ font-family: 'text';
+ src: url("./text.ttf") format("truetype");
+}
+
+@font-face {
+ font-family: 'heading';
+ src: url("./heading.ttf") format("truetype");
+}
+
+@font-face {
+ font-family: 'code';
+ src: url("./code.ttf") format("truetype");
+}
+
+@font-face {
+ font-family: 'handnotes';
+ src: url("./handnotes.ttf") format("truetype");
+}
+
+:root {
+ --color-primary: #97c378;
+ --color-secondary: #7897c3;
+ --color-accent: #c37897;
+ --color-bg: #f1f3f0;
+ --color-text: #252525;
+ --font-size-base: 18px;
+ --font-size-h1: 1.42em;
+ --font-size-h2: 1.27em;
+ --font-size-h3: 1.12em;
+ --line-height: 1.51;
+}
+
+* {
+ box-sizing: border-box;
+}
+
+html {
+ font-size: var(--font-size-base);
+ -webkit-font-smoothing: antialiased;
+ -moz-osx-font-smoothing: grayscale;
+}
+
+body {
+ font-family: text, sans-serif;
+ background-color: var(--color-bg);
+ color: var(--color-text);
+ line-height: var(--line-height);
+ margin: 0;
+ padding: 0;
+ overflow-wrap: break-word;
+}
+
+h1, h2, h3 {
+ font-family: heading, serif;
+ line-height: 1.2;
+ margin-top: 1em;
+ margin-bottom: 0.5em;
+}
+
+h1 {
+ font-size: var(--font-size-h1);
+ color: var(--color-primary);
+}
+
+h2 {
+ font-size: var(--font-size-h2);
+ color: var(--color-primary);
+}
+
+h3 {
+ font-size: var(--font-size-h3);
+ color: var(--color-secondary);
+}
+
+a {
+ font-family: code, monospace;
+ color: var(--color-secondary);
+ text-decoration: none;
+ transition: all 0.3s ease;
+}
+
+a:hover {
+ color: var(--color-accent);
+ text-decoration: underline;
+}
+
+.textlink {
+ font-family: text, sans-serif;
+}
+
+.quote {
+ font-family: handnotes, cursive;
+ border-left: 4px solid var(--color-accent);
+ padding: 1em 1.5em;
+ margin: 1.5em 0;
+ background-color: rgba(151, 195, 120, 0.07);
+ font-style: italic;
+}
+
+pre {
+ font-family: code, monospace;
+ background-color: rgba(37, 37, 37, 0.04);
+ border: 1px solid rgba(37, 37, 37, 0.13);
+ padding: 1em;
+ overflow-x: auto;
+ border-radius: 4px;
+ font-size: 0.9em;
+}
+
+code {
+ font-family: code, monospace;
+ background-color: rgba(37, 37, 37, 0.04);
+ padding: 0.2em 0.4em;
+ border-radius: 3px;
+ font-size: 0.9em;
+}
+
+ul, ol {
+ padding-left: 2em;
+ margin: 1em 0;
+}
+
+li {
+ margin: 0.5em 0;
+}
+
+img {
+ max-width: 100%;
+ height: auto;
+}
+
+hr {
+ border: none;
+ border-top: 1px solid rgba(37, 37, 37, 0.20);
+ margin: 2em 0;
+}
+
+
+/* Layout: hero */
+
+body {
+ margin: 0;
+ padding: 0;
+}
+
+.header {
+ min-height: 80vh;
+ display: flex;
+ flex-direction: column;
+ justify-content: center;
+ align-items: center;
+ background: linear-gradient(135deg, rgba(151, 195, 120, 0.80), rgba(120, 151, 195, 0.80)), linear-gradient(45deg, rgba(195, 120, 151, 0.13), transparent);
+ color: var(--color-bg);
+ text-align: center;
+ position: relative;
+}
+
+.header h1 {
+ font-size: 5em;
+ margin: 0;
+ color: var(--color-bg);
+ text-shadow: 0 4px 8px rgba(0,0,0,0.3);
+}
+
+.header p {
+ font-size: 1.5em;
+ opacity: 0.9;
+}
+
+.content {
+ max-width: 65ch;
+ margin: 4em auto;
+ padding: 0 2em;
+}
diff --git a/extras/html/themes/aurora_dawn/theme.conf b/extras/html/themes/aurora_dawn/theme.conf
new file mode 100644
index 0000000..4beee65
--- /dev/null
+++ b/extras/html/themes/aurora_dawn/theme.conf
@@ -0,0 +1,8 @@
+declare -xr HTML_HEADER=./extras/html/header.html.part
+declare -xr HTML_FOOTER=./extras/html/footer.html.part
+declare -xr HTML_CSS_STYLE=$HTML_THEME_DIR/style.css
+declare -xr HTML_WEBFONT_HEADING=./extras/html/fonts/higher-jump/higher-jump-Bold.ttf
+declare -xr HTML_WEBFONT_TEXT=./extras/html/fonts/oxygen/oxygen-Regular.ttf
+declare -xr HTML_WEBFONT_CODE=./extras/html/fonts/intelone-mono/intelone-mono-Regular.ttf
+declare -xr HTML_WEBFONT_HANDNOTES=./extras/html/fonts/khand/khand.ttf
+declare -xr SOURCE_HIGHLIGHT_CSS=./extras/html/source-highlight-styles/mono.css
diff --git a/extras/html/themes/bold_pulse/LICENSE b/extras/html/themes/bold_pulse/LICENSE
new file mode 100644
index 0000000..f53808a
--- /dev/null
+++ b/extras/html/themes/bold_pulse/LICENSE
@@ -0,0 +1,21 @@
+Theme: bold_pulse
+Generated: 2025-06-22 21:38:55
+
+Layout: swiss
+Color Scheme: split_complementary (Light)
+
+Font Licenses:
+==============
+Heading Font: oxygen
+License: OFL
+Category: sans-serif
+
+Body Font: Lato
+License: OFL
+Category: sans-serif
+
+Code Font: hack
+License: MIT
+Category: monospace
+
+All fonts are free for personal use.
diff --git a/extras/html/themes/bold_pulse/code.ttf b/extras/html/themes/bold_pulse/code.ttf
new file mode 100644
index 0000000..7c8e65b
--- /dev/null
+++ b/extras/html/themes/bold_pulse/code.ttf
Binary files differ
diff --git a/extras/html/themes/bold_pulse/example.html b/extras/html/themes/bold_pulse/example.html
new file mode 100644
index 0000000..7f0b8d3
--- /dev/null
+++ b/extras/html/themes/bold_pulse/example.html
@@ -0,0 +1,75 @@
+<!DOCTYPE html>
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
+<head>
+ <meta charset="UTF-8" />
+ <meta name="viewport" content="width=device-width, initial-scale=1.0" />
+ <title>Bold Pulse - Gemtexter Theme</title>
+ <link rel="stylesheet" href="style.css" />
+</head>
+<body>
+ <div class="header">
+ <h1>Bold Pulse</h1>
+ <p>A swiss layout with split complementary colors</p>
+ </div>
+
+ <div class="content">
+ <h1>Welcome to Bold Pulse</h1>
+ <p>This theme features a carefully crafted swiss layout with a light split complementary color scheme. The typography combines sans-serif fonts for headings with sans-serif for body text.</p>
+
+ <h2>Typography Showcase</h2>
+ <p>The Lato font family provides excellent readability for body text, while oxygen adds character to headings. Code blocks use hack for clarity.</p>
+
+ <h2>Color Palette</h2>
+ <p>Primary: <span style="color: #a97f1c; font-weight: bold;">#a97f1c</span> |
+ Secondary: <span style="color: #2a819a; font-weight: bold;">#2a819a</span> |
+ Accent: <span style="color: #3e2a9a; font-weight: bold;">#3e2a9a</span></p>
+
+ <h3>Interactive Elements</h3>
+ <p>Links like <a href="#">this example</a> and longer <a href="#" class="textlink">text links that demonstrate the theme's navigation style</a> use the secondary color.</p>
+
+ <div class="quote">
+ "Design is not just what it looks like and feels like. Design is how it works." — Steve Jobs
+ </div>
+
+ <h3>Code Examples</h3>
+ <p>Inline code like <code>theme.generate()</code> and larger blocks:</p>
+ <pre>// Theme configuration
+const theme = {
+ name: "bold_pulse",
+ layout: "swiss",
+ colors: {
+ primary: "#a97f1c",
+ secondary: "#2a819a",
+ accent: "#3e2a9a"
+ },
+ fonts: {
+ heading: "oxygen",
+ body: "Lato",
+ code: "hack"
+ }
+};</pre>
+
+ <h2>Content Structure</h2>
+ <ul>
+ <li>Clean, readable typography with 18px base font size</li>
+ <li>Heading scale ratio of 1.42x for visual hierarchy</li>
+ <li>Line height of 1.77 for comfortable reading</li>
+ <li>Swiss layout optimized for content flow</li>
+ <li>Light theme with split complementary color harmony</li>
+ </ul>
+
+ <h2>Font Licensing</h2>
+ <p>All fonts used in this theme are properly licensed:</p>
+ <ul>
+ <li>oxygen: OFL License</li>
+ <li>Lato: OFL License</li>
+ <li>hack: MIT License</li>
+ </ul>
+
+ <h3>Final Thoughts</h3>
+ <p>Every element of this theme has been carefully designed to create a harmonious reading experience. The swiss layout ensures content is presented in an engaging way, while the color scheme provides the perfect backdrop for your words to shine.</p>
+
+ <p>Whether you're writing technical documentation, creative prose, or anything in between, this theme adapts to showcase your content beautifully.</p>
+ </div>
+</body>
+</html> \ No newline at end of file
diff --git a/extras/html/themes/bold_pulse/handnotes.ttf b/extras/html/themes/bold_pulse/handnotes.ttf
new file mode 100644
index 0000000..25e688b
--- /dev/null
+++ b/extras/html/themes/bold_pulse/handnotes.ttf
Binary files differ
diff --git a/extras/html/themes/bold_pulse/style.css b/extras/html/themes/bold_pulse/style.css
new file mode 100644
index 0000000..e5fa64f
--- /dev/null
+++ b/extras/html/themes/bold_pulse/style.css
@@ -0,0 +1,198 @@
+/* Base styles */
+@font-face {
+ font-family: 'text';
+ src: url("./text.ttf") format("truetype");
+}
+
+@font-face {
+ font-family: 'heading';
+ src: url("./heading.ttf") format("truetype");
+}
+
+@font-face {
+ font-family: 'code';
+ src: url("./code.ttf") format("truetype");
+}
+
+@font-face {
+ font-family: 'handnotes';
+ src: url("./handnotes.ttf") format("truetype");
+}
+
+:root {
+ --color-primary: #a97f1c;
+ --color-secondary: #2a819a;
+ --color-accent: #3e2a9a;
+ --color-bg: #f3f2f0;
+ --color-text: #111111;
+ --font-size-base: 18px;
+ --font-size-h1: 1.42em;
+ --font-size-h2: 1.27em;
+ --font-size-h3: 1.12em;
+ --line-height: 1.77;
+}
+
+* {
+ box-sizing: border-box;
+}
+
+html {
+ font-size: var(--font-size-base);
+ -webkit-font-smoothing: antialiased;
+ -moz-osx-font-smoothing: grayscale;
+}
+
+body {
+ font-family: text, sans-serif;
+ background-color: var(--color-bg);
+ color: var(--color-text);
+ line-height: var(--line-height);
+ margin: 0;
+ padding: 0;
+ overflow-wrap: break-word;
+}
+
+h1, h2, h3 {
+ font-family: heading, serif;
+ line-height: 1.2;
+ margin-top: 1em;
+ margin-bottom: 0.5em;
+}
+
+h1 {
+ font-size: var(--font-size-h1);
+ color: var(--color-primary);
+}
+
+h2 {
+ font-size: var(--font-size-h2);
+ color: var(--color-primary);
+}
+
+h3 {
+ font-size: var(--font-size-h3);
+ color: var(--color-secondary);
+}
+
+a {
+ font-family: code, monospace;
+ color: var(--color-secondary);
+ text-decoration: none;
+ transition: all 0.3s ease;
+}
+
+a:hover {
+ color: var(--color-accent);
+ text-decoration: underline;
+}
+
+.textlink {
+ font-family: text, sans-serif;
+}
+
+.quote {
+ font-family: handnotes, cursive;
+ border-left: 4px solid var(--color-accent);
+ padding: 1em 1.5em;
+ margin: 1.5em 0;
+ background-color: rgba(169, 127, 28, 0.07);
+ font-style: italic;
+}
+
+pre {
+ font-family: code, monospace;
+ background-color: rgba(17, 17, 17, 0.04);
+ border: 1px solid rgba(17, 17, 17, 0.13);
+ padding: 1em;
+ overflow-x: auto;
+ border-radius: 4px;
+ font-size: 0.9em;
+}
+
+code {
+ font-family: code, monospace;
+ background-color: rgba(17, 17, 17, 0.04);
+ padding: 0.2em 0.4em;
+ border-radius: 3px;
+ font-size: 0.9em;
+}
+
+ul, ol {
+ padding-left: 2em;
+ margin: 1em 0;
+}
+
+li {
+ margin: 0.5em 0;
+}
+
+img {
+ max-width: 100%;
+ height: auto;
+}
+
+hr {
+ border: none;
+ border-top: 1px solid rgba(17, 17, 17, 0.20);
+ margin: 2em 0;
+}
+
+
+/* Layout: swiss */
+
+body {
+ max-width: 1200px;
+ margin: 0 auto;
+ padding: 2em;
+ display: grid;
+ grid-template-columns: repeat(6, 1fr);
+ gap: 2em;
+}
+
+.header {
+ grid-column: 1 / -1;
+ display: grid;
+ grid-template-columns: repeat(6, 1fr);
+ gap: 2em;
+ margin-bottom: 4em;
+ padding-bottom: 2em;
+ border-bottom: 4px solid var(--color-text);
+}
+
+.header h1 {
+ grid-column: 1 / 4;
+ font-size: 4em;
+ margin: 0;
+ line-height: 0.9;
+}
+
+.header p {
+ grid-column: 4 / -1;
+ align-self: end;
+}
+
+h1 {
+ grid-column: 1 / -1;
+ font-size: 3em;
+ margin: 1em 0 0.5em 0;
+}
+
+h2 {
+ grid-column: 1 / 5;
+ margin-top: 2em;
+}
+
+h3 {
+ grid-column: 2 / 6;
+}
+
+p, ul, pre {
+ grid-column: 2 / 6;
+}
+
+.quote {
+ grid-column: 1 / -1;
+ font-size: 1.5em;
+ text-align: center;
+ margin: 2em 0;
+}
diff --git a/extras/html/themes/bold_pulse/text.ttf b/extras/html/themes/bold_pulse/text.ttf
new file mode 100644
index 0000000..bb2e887
--- /dev/null
+++ b/extras/html/themes/bold_pulse/text.ttf
Binary files differ
diff --git a/extras/html/themes/bold_pulse/theme.conf b/extras/html/themes/bold_pulse/theme.conf
new file mode 100644
index 0000000..1e2ca2e
--- /dev/null
+++ b/extras/html/themes/bold_pulse/theme.conf
@@ -0,0 +1,8 @@
+declare -xr HTML_HEADER=./extras/html/header.html.part
+declare -xr HTML_FOOTER=./extras/html/footer.html.part
+declare -xr HTML_CSS_STYLE=$HTML_THEME_DIR/style.css
+declare -xr HTML_WEBFONT_HEADING=./extras/html/fonts/oxygen/oxygen-Bold.ttf
+declare -xr HTML_WEBFONT_TEXT=./extras/html/fonts/Lato/Lato-Regular.ttf
+declare -xr HTML_WEBFONT_CODE=./extras/html/fonts/hack/hack-Regular.ttf
+declare -xr HTML_WEBFONT_HANDNOTES=./extras/html/fonts/khand/khand.ttf
+declare -xr SOURCE_HIGHLIGHT_CSS=./extras/html/source-highlight-styles/mono.css
diff --git a/extras/html/themes/bright_light/LICENSE b/extras/html/themes/bright_light/LICENSE
new file mode 100644
index 0000000..5ee1ada
--- /dev/null
+++ b/extras/html/themes/bright_light/LICENSE
@@ -0,0 +1,21 @@
+Theme: bright_light
+Generated: 2025-06-22 21:38:55
+
+Layout: hero
+Color Scheme: triadic (Light)
+
+Font Licenses:
+==============
+Heading Font: Merriweather
+License: OFL
+Category: serif
+
+Body Font: oxygen
+License: OFL
+Category: sans-serif
+
+Code Font: hack
+License: MIT
+Category: monospace
+
+All fonts are free for personal use.
diff --git a/extras/html/themes/bright_light/code.ttf b/extras/html/themes/bright_light/code.ttf
new file mode 100644
index 0000000..7c8e65b
--- /dev/null
+++ b/extras/html/themes/bright_light/code.ttf
Binary files differ
diff --git a/extras/html/themes/bright_light/example.html b/extras/html/themes/bright_light/example.html
new file mode 100644
index 0000000..8b25fd2
--- /dev/null
+++ b/extras/html/themes/bright_light/example.html
@@ -0,0 +1,75 @@
+<!DOCTYPE html>
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
+<head>
+ <meta charset="UTF-8" />
+ <meta name="viewport" content="width=device-width, initial-scale=1.0" />
+ <title>Bright Light - Gemtexter Theme</title>
+ <link rel="stylesheet" href="style.css" />
+</head>
+<body>
+ <div class="header">
+ <h1>Bright Light</h1>
+ <p>A hero layout with triadic colors</p>
+ </div>
+
+ <div class="content">
+ <h1>Welcome to Bright Light</h1>
+ <p>This theme features a carefully crafted hero layout with a light triadic color scheme. The typography combines serif fonts for headings with sans-serif for body text.</p>
+
+ <h2>Typography Showcase</h2>
+ <p>The oxygen font family provides excellent readability for body text, while Merriweather adds character to headings. Code blocks use hack for clarity.</p>
+
+ <h2>Color Palette</h2>
+ <p>Primary: <span style="color: #0fb543; font-weight: bold;">#0fb543</span> |
+ Secondary: <span style="color: #420fb5; font-weight: bold;">#420fb5</span> |
+ Accent: <span style="color: #b5430f; font-weight: bold;">#b5430f</span></p>
+
+ <h3>Interactive Elements</h3>
+ <p>Links like <a href="#">this example</a> and longer <a href="#" class="textlink">text links that demonstrate the theme's navigation style</a> use the secondary color.</p>
+
+ <div class="quote">
+ "Design is not just what it looks like and feels like. Design is how it works." — Steve Jobs
+ </div>
+
+ <h3>Code Examples</h3>
+ <p>Inline code like <code>theme.generate()</code> and larger blocks:</p>
+ <pre>// Theme configuration
+const theme = {
+ name: "bright_light",
+ layout: "hero",
+ colors: {
+ primary: "#0fb543",
+ secondary: "#420fb5",
+ accent: "#b5430f"
+ },
+ fonts: {
+ heading: "Merriweather",
+ body: "oxygen",
+ code: "hack"
+ }
+};</pre>
+
+ <h2>Content Structure</h2>
+ <ul>
+ <li>Clean, readable typography with 16px base font size</li>
+ <li>Heading scale ratio of 2.37x for visual hierarchy</li>
+ <li>Line height of 1.56 for comfortable reading</li>
+ <li>Hero layout optimized for content flow</li>
+ <li>Light theme with triadic color harmony</li>
+ </ul>
+
+ <h2>Font Licensing</h2>
+ <p>All fonts used in this theme are properly licensed:</p>
+ <ul>
+ <li>Merriweather: OFL License</li>
+ <li>oxygen: OFL License</li>
+ <li>hack: MIT License</li>
+ </ul>
+
+ <h3>Final Thoughts</h3>
+ <p>Every element of this theme has been carefully designed to create a harmonious reading experience. The hero layout ensures content is presented in an engaging way, while the color scheme provides the perfect backdrop for your words to shine.</p>
+
+ <p>Whether you're writing technical documentation, creative prose, or anything in between, this theme adapts to showcase your content beautifully.</p>
+ </div>
+</body>
+</html> \ No newline at end of file
diff --git a/extras/html/themes/bright_light/handnotes.ttf b/extras/html/themes/bright_light/handnotes.ttf
new file mode 100644
index 0000000..25e688b
--- /dev/null
+++ b/extras/html/themes/bright_light/handnotes.ttf
Binary files differ
diff --git a/extras/html/themes/bright_light/heading.ttf b/extras/html/themes/bright_light/heading.ttf
new file mode 100644
index 0000000..3e10e02
--- /dev/null
+++ b/extras/html/themes/bright_light/heading.ttf
Binary files differ
diff --git a/extras/html/themes/bright_light/style.css b/extras/html/themes/bright_light/style.css
new file mode 100644
index 0000000..73336ac
--- /dev/null
+++ b/extras/html/themes/bright_light/style.css
@@ -0,0 +1,176 @@
+/* Base styles */
+@font-face {
+ font-family: 'text';
+ src: url("./text.ttf") format("truetype");
+}
+
+@font-face {
+ font-family: 'heading';
+ src: url("./heading.ttf") format("truetype");
+}
+
+@font-face {
+ font-family: 'code';
+ src: url("./code.ttf") format("truetype");
+}
+
+@font-face {
+ font-family: 'handnotes';
+ src: url("./handnotes.ttf") format("truetype");
+}
+
+:root {
+ --color-primary: #0fb543;
+ --color-secondary: #420fb5;
+ --color-accent: #b5430f;
+ --color-bg: #edf0ee;
+ --color-text: #1b1b1b;
+ --font-size-base: 16px;
+ --font-size-h1: 2.37em;
+ --font-size-h2: 1.78em;
+ --font-size-h3: 1.33em;
+ --line-height: 1.56;
+}
+
+* {
+ box-sizing: border-box;
+}
+
+html {
+ font-size: var(--font-size-base);
+ -webkit-font-smoothing: antialiased;
+ -moz-osx-font-smoothing: grayscale;
+}
+
+body {
+ font-family: text, sans-serif;
+ background-color: var(--color-bg);
+ color: var(--color-text);
+ line-height: var(--line-height);
+ margin: 0;
+ padding: 0;
+ overflow-wrap: break-word;
+}
+
+h1, h2, h3 {
+ font-family: heading, serif;
+ line-height: 1.2;
+ margin-top: 1em;
+ margin-bottom: 0.5em;
+}
+
+h1 {
+ font-size: var(--font-size-h1);
+ color: var(--color-primary);
+}
+
+h2 {
+ font-size: var(--font-size-h2);
+ color: var(--color-primary);
+}
+
+h3 {
+ font-size: var(--font-size-h3);
+ color: var(--color-secondary);
+}
+
+a {
+ font-family: code, monospace;
+ color: var(--color-secondary);
+ text-decoration: none;
+ transition: all 0.3s ease;
+}
+
+a:hover {
+ color: var(--color-accent);
+ text-decoration: underline;
+}
+
+.textlink {
+ font-family: text, sans-serif;
+}
+
+.quote {
+ font-family: handnotes, cursive;
+ border-left: 4px solid var(--color-accent);
+ padding: 1em 1.5em;
+ margin: 1.5em 0;
+ background-color: rgba(15, 181, 67, 0.07);
+ font-style: italic;
+}
+
+pre {
+ font-family: code, monospace;
+ background-color: rgba(27, 27, 27, 0.04);
+ border: 1px solid rgba(27, 27, 27, 0.13);
+ padding: 1em;
+ overflow-x: auto;
+ border-radius: 4px;
+ font-size: 0.9em;
+}
+
+code {
+ font-family: code, monospace;
+ background-color: rgba(27, 27, 27, 0.04);
+ padding: 0.2em 0.4em;
+ border-radius: 3px;
+ font-size: 0.9em;
+}
+
+ul, ol {
+ padding-left: 2em;
+ margin: 1em 0;
+}
+
+li {
+ margin: 0.5em 0;
+}
+
+img {
+ max-width: 100%;
+ height: auto;
+}
+
+hr {
+ border: none;
+ border-top: 1px solid rgba(27, 27, 27, 0.20);
+ margin: 2em 0;
+}
+
+
+/* Layout: hero */
+
+body {
+ margin: 0;
+ padding: 0;
+}
+
+.header {
+ min-height: 80vh;
+ display: flex;
+ flex-direction: column;
+ justify-content: center;
+ align-items: center;
+ background: linear-gradient(135deg, rgba(15, 181, 67, 0.80), rgba(66, 15, 181, 0.80)), linear-gradient(45deg, rgba(181, 67, 15, 0.13), transparent);
+ color: var(--color-bg);
+ text-align: center;
+ position: relative;
+}
+
+.header h1 {
+ font-size: 5em;
+ margin: 0;
+ color: var(--color-bg);
+ text-shadow: 0 4px 8px rgba(0,0,0,0.3);
+}
+
+.header p {
+ font-size: 1.5em;
+ opacity: 0.9;
+}
+
+.content {
+ max-width: 65ch;
+ margin: 4em auto;
+ padding: 0 2em;
+}
diff --git a/extras/html/themes/bright_light/theme.conf b/extras/html/themes/bright_light/theme.conf
new file mode 100644
index 0000000..98a41f3
--- /dev/null
+++ b/extras/html/themes/bright_light/theme.conf
@@ -0,0 +1,8 @@
+declare -xr HTML_HEADER=./extras/html/header.html.part
+declare -xr HTML_FOOTER=./extras/html/footer.html.part
+declare -xr HTML_CSS_STYLE=$HTML_THEME_DIR/style.css
+declare -xr HTML_WEBFONT_HEADING=./extras/html/fonts/Merriweather/Merriweather-Bold.ttf
+declare -xr HTML_WEBFONT_TEXT=./extras/html/fonts/oxygen/oxygen-Regular.ttf
+declare -xr HTML_WEBFONT_CODE=./extras/html/fonts/hack/hack-Regular.ttf
+declare -xr HTML_WEBFONT_HANDNOTES=./extras/html/fonts/khand/khand.ttf
+declare -xr SOURCE_HIGHLIGHT_CSS=./extras/html/source-highlight-styles/mono.css
diff --git a/extras/html/themes/bright_spark/LICENSE b/extras/html/themes/bright_spark/LICENSE
new file mode 100644
index 0000000..7c1082b
--- /dev/null
+++ b/extras/html/themes/bright_spark/LICENSE
@@ -0,0 +1,21 @@
+Theme: bright_spark
+Generated: 2025-06-22 21:38:55
+
+Layout: newspaper
+Color Scheme: complementary (Dark)
+
+Font Licenses:
+==============
+Heading Font: roboto-slab
+License: Apache
+Category: serif
+
+Body Font: oxygen
+License: OFL
+Category: sans-serif
+
+Code Font: intelone-mono
+License: OFL
+Category: monospace
+
+All fonts are free for personal use.
diff --git a/extras/html/themes/bright_spark/code.ttf b/extras/html/themes/bright_spark/code.ttf
new file mode 100644
index 0000000..2711179
--- /dev/null
+++ b/extras/html/themes/bright_spark/code.ttf
Binary files differ
diff --git a/extras/html/themes/bright_spark/example.html b/extras/html/themes/bright_spark/example.html
new file mode 100644
index 0000000..14150df
--- /dev/null
+++ b/extras/html/themes/bright_spark/example.html
@@ -0,0 +1,75 @@
+<!DOCTYPE html>
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
+<head>
+ <meta charset="UTF-8" />
+ <meta name="viewport" content="width=device-width, initial-scale=1.0" />
+ <title>Bright Spark - Gemtexter Theme</title>
+ <link rel="stylesheet" href="style.css" />
+</head>
+<body>
+ <div class="header">
+ <h1>Bright Spark</h1>
+ <p>A newspaper layout with complementary colors</p>
+ </div>
+
+ <div class="content">
+ <h1>Welcome to Bright Spark</h1>
+ <p>This theme features a carefully crafted newspaper layout with a dark complementary color scheme. The typography combines serif fonts for headings with sans-serif for body text.</p>
+
+ <h2>Typography Showcase</h2>
+ <p>The oxygen font family provides excellent readability for body text, while roboto-slab adds character to headings. Code blocks use intelone-mono for clarity.</p>
+
+ <h2>Color Palette</h2>
+ <p>Primary: <span style="color: #4d8596; font-weight: bold;">#4d8596</span> |
+ Secondary: <span style="color: #8f6254; font-weight: bold;">#8f6254</span> |
+ Accent: <span style="color: #49646c; font-weight: bold;">#49646c</span></p>
+
+ <h3>Interactive Elements</h3>
+ <p>Links like <a href="#">this example</a> and longer <a href="#" class="textlink">text links that demonstrate the theme's navigation style</a> use the secondary color.</p>
+
+ <div class="quote">
+ "Design is not just what it looks like and feels like. Design is how it works." — Steve Jobs
+ </div>
+
+ <h3>Code Examples</h3>
+ <p>Inline code like <code>theme.generate()</code> and larger blocks:</p>
+ <pre>// Theme configuration
+const theme = {
+ name: "bright_spark",
+ layout: "newspaper",
+ colors: {
+ primary: "#4d8596",
+ secondary: "#8f6254",
+ accent: "#49646c"
+ },
+ fonts: {
+ heading: "roboto-slab",
+ body: "oxygen",
+ code: "intelone-mono"
+ }
+};</pre>
+
+ <h2>Content Structure</h2>
+ <ul>
+ <li>Clean, readable typography with 17px base font size</li>
+ <li>Heading scale ratio of 2.37x for visual hierarchy</li>
+ <li>Line height of 1.74 for comfortable reading</li>
+ <li>Newspaper layout optimized for content flow</li>
+ <li>Dark theme with complementary color harmony</li>
+ </ul>
+
+ <h2>Font Licensing</h2>
+ <p>All fonts used in this theme are properly licensed:</p>
+ <ul>
+ <li>roboto-slab: Apache License</li>
+ <li>oxygen: OFL License</li>
+ <li>intelone-mono: OFL License</li>
+ </ul>
+
+ <h3>Final Thoughts</h3>
+ <p>Every element of this theme has been carefully designed to create a harmonious reading experience. The newspaper layout ensures content is presented in an engaging way, while the color scheme provides the perfect backdrop for your words to shine.</p>
+
+ <p>Whether you're writing technical documentation, creative prose, or anything in between, this theme adapts to showcase your content beautifully.</p>
+ </div>
+</body>
+</html> \ No newline at end of file
diff --git a/extras/html/themes/bright_spark/handnotes.ttf b/extras/html/themes/bright_spark/handnotes.ttf
new file mode 100644
index 0000000..25e688b
--- /dev/null
+++ b/extras/html/themes/bright_spark/handnotes.ttf
Binary files differ
diff --git a/extras/html/themes/bright_spark/style.css b/extras/html/themes/bright_spark/style.css
new file mode 100644
index 0000000..8cf8e7a
--- /dev/null
+++ b/extras/html/themes/bright_spark/style.css
@@ -0,0 +1,187 @@
+/* Base styles */
+@font-face {
+ font-family: 'text';
+ src: url("./text.ttf") format("truetype");
+}
+
+@font-face {
+ font-family: 'heading';
+ src: url("./heading.ttf") format("truetype");
+}
+
+@font-face {
+ font-family: 'code';
+ src: url("./code.ttf") format("truetype");
+}
+
+@font-face {
+ font-family: 'handnotes';
+ src: url("./handnotes.ttf") format("truetype");
+}
+
+:root {
+ --color-primary: #4d8596;
+ --color-secondary: #8f6254;
+ --color-accent: #49646c;
+ --color-bg: #181d1e;
+ --color-text: #dedede;
+ --font-size-base: 17px;
+ --font-size-h1: 2.37em;
+ --font-size-h2: 1.78em;
+ --font-size-h3: 1.33em;
+ --line-height: 1.74;
+}
+
+* {
+ box-sizing: border-box;
+}
+
+html {
+ font-size: var(--font-size-base);
+ -webkit-font-smoothing: antialiased;
+ -moz-osx-font-smoothing: grayscale;
+}
+
+body {
+ font-family: text, sans-serif;
+ background-color: var(--color-bg);
+ color: var(--color-text);
+ line-height: var(--line-height);
+ margin: 0;
+ padding: 0;
+ overflow-wrap: break-word;
+}
+
+h1, h2, h3 {
+ font-family: heading, serif;
+ line-height: 1.2;
+ margin-top: 1em;
+ margin-bottom: 0.5em;
+}
+
+h1 {
+ font-size: var(--font-size-h1);
+ color: var(--color-primary);
+}
+
+h2 {
+ font-size: var(--font-size-h2);
+ color: var(--color-primary);
+}
+
+h3 {
+ font-size: var(--font-size-h3);
+ color: var(--color-secondary);
+}
+
+a {
+ font-family: code, monospace;
+ color: var(--color-secondary);
+ text-decoration: none;
+ transition: all 0.3s ease;
+}
+
+a:hover {
+ color: var(--color-accent);
+ text-decoration: underline;
+}
+
+.textlink {
+ font-family: text, sans-serif;
+}
+
+.quote {
+ font-family: handnotes, cursive;
+ border-left: 4px solid var(--color-accent);
+ padding: 1em 1.5em;
+ margin: 1.5em 0;
+ background-color: rgba(77, 133, 150, 0.07);
+ font-style: italic;
+}
+
+pre {
+ font-family: code, monospace;
+ background-color: rgba(222, 222, 222, 0.04);
+ border: 1px solid rgba(222, 222, 222, 0.13);
+ padding: 1em;
+ overflow-x: auto;
+ border-radius: 4px;
+ font-size: 0.9em;
+}
+
+code {
+ font-family: code, monospace;
+ background-color: rgba(222, 222, 222, 0.04);
+ padding: 0.2em 0.4em;
+ border-radius: 3px;
+ font-size: 0.9em;
+}
+
+ul, ol {
+ padding-left: 2em;
+ margin: 1em 0;
+}
+
+li {
+ margin: 0.5em 0;
+}
+
+img {
+ max-width: 100%;
+ height: auto;
+}
+
+hr {
+ border: none;
+ border-top: 1px solid rgba(222, 222, 222, 0.20);
+ margin: 2em 0;
+}
+
+
+/* Layout: newspaper */
+
+body {
+ max-width: 1200px;
+ margin: 0 auto;
+ padding: 2em;
+ columns: 3;
+ column-gap: 2em;
+ column-rule: 1px solid var(--color-text);
+}
+
+.header {
+ column-span: all;
+ text-align: center;
+ border-top: 6px double var(--color-text);
+ border-bottom: 6px double var(--color-text);
+ padding: 2em 0;
+ margin-bottom: 3em;
+}
+
+.header h1 {
+ font-size: 4em;
+ margin: 0;
+ letter-spacing: 0.1em;
+}
+
+h1, h2 {
+ column-span: all;
+ text-align: center;
+ margin: 2em 0 1em 0;
+}
+
+h3 {
+ break-after: avoid;
+}
+
+p {
+ text-align: justify;
+ hyphens: auto;
+}
+
+.quote {
+ column-span: all;
+ text-align: center;
+ font-size: 1.5em;
+ margin: 2em 0;
+}
diff --git a/extras/html/themes/bright_spark/theme.conf b/extras/html/themes/bright_spark/theme.conf
new file mode 100644
index 0000000..19a2553
--- /dev/null
+++ b/extras/html/themes/bright_spark/theme.conf
@@ -0,0 +1,8 @@
+declare -xr HTML_HEADER=./extras/html/header.html.part
+declare -xr HTML_FOOTER=./extras/html/footer.html.part
+declare -xr HTML_CSS_STYLE=$HTML_THEME_DIR/style.css
+declare -xr HTML_WEBFONT_HEADING=./extras/html/fonts/roboto-slab/roboto-slab-Bold.ttf
+declare -xr HTML_WEBFONT_TEXT=./extras/html/fonts/oxygen/oxygen-Regular.ttf
+declare -xr HTML_WEBFONT_CODE=./extras/html/fonts/intelone-mono/intelone-mono-Regular.ttf
+declare -xr HTML_WEBFONT_HANDNOTES=./extras/html/fonts/khand/khand.ttf
+declare -xr SOURCE_HIGHLIGHT_CSS=./extras/html/source-highlight-styles/mono.css
diff --git a/extras/html/themes/business/style.css b/extras/html/themes/business/style.css
index 43898f7..cd85c94 100644
--- a/extras/html/themes/business/style.css
+++ b/extras/html/themes/business/style.css
@@ -33,7 +33,7 @@ body {
border: 1px solid #ccc;
box-shadow: 0 4px 15px rgba(0, 0, 0, 0.1);
border-radius: 8px;
- word-wrap: break-word;
+ overflow-wrap: break-word;
}
h1, h2, h3 {
diff --git a/extras/html/themes/clean_garden/LICENSE b/extras/html/themes/clean_garden/LICENSE
new file mode 100644
index 0000000..d975ff5
--- /dev/null
+++ b/extras/html/themes/clean_garden/LICENSE
@@ -0,0 +1,21 @@
+Theme: clean_garden
+Generated: 2025-06-22 21:38:55
+
+Layout: hero
+Color Scheme: analogous (Dark)
+
+Font Licenses:
+==============
+Heading Font: Abril_Fatface
+License: OFL
+Category: display
+
+Body Font: Merriweather
+License: OFL
+Category: serif
+
+Code Font: hack
+License: MIT
+Category: monospace
+
+All fonts are free for personal use.
diff --git a/extras/html/themes/clean_garden/code.ttf b/extras/html/themes/clean_garden/code.ttf
new file mode 100644
index 0000000..7c8e65b
--- /dev/null
+++ b/extras/html/themes/clean_garden/code.ttf
Binary files differ
diff --git a/extras/html/themes/clean_garden/example.html b/extras/html/themes/clean_garden/example.html
new file mode 100644
index 0000000..a55ece8
--- /dev/null
+++ b/extras/html/themes/clean_garden/example.html
@@ -0,0 +1,75 @@
+<!DOCTYPE html>
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
+<head>
+ <meta charset="UTF-8" />
+ <meta name="viewport" content="width=device-width, initial-scale=1.0" />
+ <title>Clean Garden - Gemtexter Theme</title>
+ <link rel="stylesheet" href="style.css" />
+</head>
+<body>
+ <div class="header">
+ <h1>Clean Garden</h1>
+ <p>A hero layout with analogous colors</p>
+ </div>
+
+ <div class="content">
+ <h1>Welcome to Clean Garden</h1>
+ <p>This theme features a carefully crafted hero layout with a dark analogous color scheme. The typography combines display fonts for headings with serif for body text.</p>
+
+ <h2>Typography Showcase</h2>
+ <p>The Merriweather font family provides excellent readability for body text, while Abril Fatface adds character to headings. Code blocks use hack for clarity.</p>
+
+ <h2>Color Palette</h2>
+ <p>Primary: <span style="color: #ecaf10; font-weight: bold;">#ecaf10</span> |
+ Secondary: <span style="color: #b9e11b; font-weight: bold;">#b9e11b</span> |
+ Accent: <span style="color: #d43e0e; font-weight: bold;">#d43e0e</span></p>
+
+ <h3>Interactive Elements</h3>
+ <p>Links like <a href="#">this example</a> and longer <a href="#" class="textlink">text links that demonstrate the theme's navigation style</a> use the secondary color.</p>
+
+ <div class="quote">
+ "Design is not just what it looks like and feels like. Design is how it works." — Steve Jobs
+ </div>
+
+ <h3>Code Examples</h3>
+ <p>Inline code like <code>theme.generate()</code> and larger blocks:</p>
+ <pre>// Theme configuration
+const theme = {
+ name: "clean_garden",
+ layout: "hero",
+ colors: {
+ primary: "#ecaf10",
+ secondary: "#b9e11b",
+ accent: "#d43e0e"
+ },
+ fonts: {
+ heading: "Abril_Fatface",
+ body: "Merriweather",
+ code: "hack"
+ }
+};</pre>
+
+ <h2>Content Structure</h2>
+ <ul>
+ <li>Clean, readable typography with 18px base font size</li>
+ <li>Heading scale ratio of 2.83x for visual hierarchy</li>
+ <li>Line height of 1.77 for comfortable reading</li>
+ <li>Hero layout optimized for content flow</li>
+ <li>Dark theme with analogous color harmony</li>
+ </ul>
+
+ <h2>Font Licensing</h2>
+ <p>All fonts used in this theme are properly licensed:</p>
+ <ul>
+ <li>Abril_Fatface: OFL License</li>
+ <li>Merriweather: OFL License</li>
+ <li>hack: MIT License</li>
+ </ul>
+
+ <h3>Final Thoughts</h3>
+ <p>Every element of this theme has been carefully designed to create a harmonious reading experience. The hero layout ensures content is presented in an engaging way, while the color scheme provides the perfect backdrop for your words to shine.</p>
+
+ <p>Whether you're writing technical documentation, creative prose, or anything in between, this theme adapts to showcase your content beautifully.</p>
+ </div>
+</body>
+</html> \ No newline at end of file
diff --git a/extras/html/themes/clean_garden/handnotes.ttf b/extras/html/themes/clean_garden/handnotes.ttf
new file mode 100644
index 0000000..25e688b
--- /dev/null
+++ b/extras/html/themes/clean_garden/handnotes.ttf
Binary files differ
diff --git a/extras/html/themes/clean_garden/heading.ttf b/extras/html/themes/clean_garden/heading.ttf
new file mode 100644
index 0000000..a291711
--- /dev/null
+++ b/extras/html/themes/clean_garden/heading.ttf
Binary files differ
diff --git a/extras/html/themes/clean_garden/style.css b/extras/html/themes/clean_garden/style.css
new file mode 100644
index 0000000..f883820
--- /dev/null
+++ b/extras/html/themes/clean_garden/style.css
@@ -0,0 +1,176 @@
+/* Base styles */
+@font-face {
+ font-family: 'text';
+ src: url("./text.ttf") format("truetype");
+}
+
+@font-face {
+ font-family: 'heading';
+ src: url("./heading.ttf") format("truetype");
+}
+
+@font-face {
+ font-family: 'code';
+ src: url("./code.ttf") format("truetype");
+}
+
+@font-face {
+ font-family: 'handnotes';
+ src: url("./handnotes.ttf") format("truetype");
+}
+
+:root {
+ --color-primary: #ecaf10;
+ --color-secondary: #b9e11b;
+ --color-accent: #d43e0e;
+ --color-bg: #282620;
+ --color-text: #d9d9d9;
+ --font-size-base: 18px;
+ --font-size-h1: 2.83em;
+ --font-size-h2: 2.0em;
+ --font-size-h3: 1.41em;
+ --line-height: 1.77;
+}
+
+* {
+ box-sizing: border-box;
+}
+
+html {
+ font-size: var(--font-size-base);
+ -webkit-font-smoothing: antialiased;
+ -moz-osx-font-smoothing: grayscale;
+}
+
+body {
+ font-family: text, sans-serif;
+ background-color: var(--color-bg);
+ color: var(--color-text);
+ line-height: var(--line-height);
+ margin: 0;
+ padding: 0;
+ overflow-wrap: break-word;
+}
+
+h1, h2, h3 {
+ font-family: heading, serif;
+ line-height: 1.2;
+ margin-top: 1em;
+ margin-bottom: 0.5em;
+}
+
+h1 {
+ font-size: var(--font-size-h1);
+ color: var(--color-primary);
+}
+
+h2 {
+ font-size: var(--font-size-h2);
+ color: var(--color-primary);
+}
+
+h3 {
+ font-size: var(--font-size-h3);
+ color: var(--color-secondary);
+}
+
+a {
+ font-family: code, monospace;
+ color: var(--color-secondary);
+ text-decoration: none;
+ transition: all 0.3s ease;
+}
+
+a:hover {
+ color: var(--color-accent);
+ text-decoration: underline;
+}
+
+.textlink {
+ font-family: text, sans-serif;
+}
+
+.quote {
+ font-family: handnotes, cursive;
+ border-left: 4px solid var(--color-accent);
+ padding: 1em 1.5em;
+ margin: 1.5em 0;
+ background-color: rgba(236, 175, 16, 0.07);
+ font-style: italic;
+}
+
+pre {
+ font-family: code, monospace;
+ background-color: rgba(217, 217, 217, 0.04);
+ border: 1px solid rgba(217, 217, 217, 0.13);
+ padding: 1em;
+ overflow-x: auto;
+ border-radius: 4px;
+ font-size: 0.9em;
+}
+
+code {
+ font-family: code, monospace;
+ background-color: rgba(217, 217, 217, 0.04);
+ padding: 0.2em 0.4em;
+ border-radius: 3px;
+ font-size: 0.9em;
+}
+
+ul, ol {
+ padding-left: 2em;
+ margin: 1em 0;
+}
+
+li {
+ margin: 0.5em 0;
+}
+
+img {
+ max-width: 100%;
+ height: auto;
+}
+
+hr {
+ border: none;
+ border-top: 1px solid rgba(217, 217, 217, 0.20);
+ margin: 2em 0;
+}
+
+
+/* Layout: hero */
+
+body {
+ margin: 0;
+ padding: 0;
+}
+
+.header {
+ min-height: 80vh;
+ display: flex;
+ flex-direction: column;
+ justify-content: center;
+ align-items: center;
+ background: linear-gradient(135deg, rgba(236, 175, 16, 0.80), rgba(185, 225, 27, 0.80)), linear-gradient(45deg, rgba(212, 62, 14, 0.13), transparent);
+ color: var(--color-bg);
+ text-align: center;
+ position: relative;
+}
+
+.header h1 {
+ font-size: 5em;
+ margin: 0;
+ color: var(--color-bg);
+ text-shadow: 0 4px 8px rgba(0,0,0,0.3);
+}
+
+.header p {
+ font-size: 1.5em;
+ opacity: 0.9;
+}
+
+.content {
+ max-width: 65ch;
+ margin: 4em auto;
+ padding: 0 2em;
+}
diff --git a/extras/html/themes/clean_garden/text.ttf b/extras/html/themes/clean_garden/text.ttf
new file mode 100644
index 0000000..3fecc77
--- /dev/null
+++ b/extras/html/themes/clean_garden/text.ttf
Binary files differ
diff --git a/extras/html/themes/clean_garden/theme.conf b/extras/html/themes/clean_garden/theme.conf
new file mode 100644
index 0000000..7673f51
--- /dev/null
+++ b/extras/html/themes/clean_garden/theme.conf
@@ -0,0 +1,8 @@
+declare -xr HTML_HEADER=./extras/html/header.html.part
+declare -xr HTML_FOOTER=./extras/html/footer.html.part
+declare -xr HTML_CSS_STYLE=$HTML_THEME_DIR/style.css
+declare -xr HTML_WEBFONT_HEADING=./extras/html/fonts/Abril_Fatface/Abril_Fatface-Bold.ttf
+declare -xr HTML_WEBFONT_TEXT=./extras/html/fonts/Merriweather/Merriweather-Regular.ttf
+declare -xr HTML_WEBFONT_CODE=./extras/html/fonts/hack/hack-Regular.ttf
+declare -xr HTML_WEBFONT_HANDNOTES=./extras/html/fonts/khand/khand.ttf
+declare -xr SOURCE_HIGHLIGHT_CSS=./extras/html/source-highlight-styles/mono.css
diff --git a/extras/html/themes/clean_rhythm/LICENSE b/extras/html/themes/clean_rhythm/LICENSE
new file mode 100644
index 0000000..84fec9b
--- /dev/null
+++ b/extras/html/themes/clean_rhythm/LICENSE
@@ -0,0 +1,21 @@
+Theme: clean_rhythm
+Generated: 2025-06-22 21:38:55
+
+Layout: future
+Color Scheme: split_complementary (Light)
+
+Font Licenses:
+==============
+Heading Font: Merriweather
+License: OFL
+Category: serif
+
+Body Font: oxygen
+License: OFL
+Category: sans-serif
+
+Code Font: hack
+License: MIT
+Category: monospace
+
+All fonts are free for personal use.
diff --git a/extras/html/themes/clean_rhythm/code.ttf b/extras/html/themes/clean_rhythm/code.ttf
new file mode 100644
index 0000000..7c8e65b
--- /dev/null
+++ b/extras/html/themes/clean_rhythm/code.ttf
Binary files differ
diff --git a/extras/html/themes/clean_rhythm/example.html b/extras/html/themes/clean_rhythm/example.html
new file mode 100644
index 0000000..86053f9
--- /dev/null
+++ b/extras/html/themes/clean_rhythm/example.html
@@ -0,0 +1,75 @@
+<!DOCTYPE html>
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
+<head>
+ <meta charset="UTF-8" />
+ <meta name="viewport" content="width=device-width, initial-scale=1.0" />
+ <title>Clean Rhythm - Gemtexter Theme</title>
+ <link rel="stylesheet" href="style.css" />
+</head>
+<body>
+ <div class="header">
+ <h1>Clean Rhythm</h1>
+ <p>A future layout with split complementary colors</p>
+ </div>
+
+ <div class="content">
+ <h1>Welcome to Clean Rhythm</h1>
+ <p>This theme features a carefully crafted future layout with a light split complementary color scheme. The typography combines serif fonts for headings with sans-serif for body text.</p>
+
+ <h2>Typography Showcase</h2>
+ <p>The oxygen font family provides excellent readability for body text, while Merriweather adds character to headings. Code blocks use hack for clarity.</p>
+
+ <h2>Color Palette</h2>
+ <p>Primary: <span style="color: #c76399; font-weight: bold;">#c76399</span> |
+ Secondary: <span style="color: #6ebd6d; font-weight: bold;">#6ebd6d</span> |
+ Accent: <span style="color: #6dbdb9; font-weight: bold;">#6dbdb9</span></p>
+
+ <h3>Interactive Elements</h3>
+ <p>Links like <a href="#">this example</a> and longer <a href="#" class="textlink">text links that demonstrate the theme's navigation style</a> use the secondary color.</p>
+
+ <div class="quote">
+ "Design is not just what it looks like and feels like. Design is how it works." — Steve Jobs
+ </div>
+
+ <h3>Code Examples</h3>
+ <p>Inline code like <code>theme.generate()</code> and larger blocks:</p>
+ <pre>// Theme configuration
+const theme = {
+ name: "clean_rhythm",
+ layout: "future",
+ colors: {
+ primary: "#c76399",
+ secondary: "#6ebd6d",
+ accent: "#6dbdb9"
+ },
+ fonts: {
+ heading: "Merriweather",
+ body: "oxygen",
+ code: "hack"
+ }
+};</pre>
+
+ <h2>Content Structure</h2>
+ <ul>
+ <li>Clean, readable typography with 18px base font size</li>
+ <li>Heading scale ratio of 1.95x for visual hierarchy</li>
+ <li>Line height of 1.72 for comfortable reading</li>
+ <li>Future layout optimized for content flow</li>
+ <li>Light theme with split complementary color harmony</li>
+ </ul>
+
+ <h2>Font Licensing</h2>
+ <p>All fonts used in this theme are properly licensed:</p>
+ <ul>
+ <li>Merriweather: OFL License</li>
+ <li>oxygen: OFL License</li>
+ <li>hack: MIT License</li>
+ </ul>
+
+ <h3>Final Thoughts</h3>
+ <p>Every element of this theme has been carefully designed to create a harmonious reading experience. The future layout ensures content is presented in an engaging way, while the color scheme provides the perfect backdrop for your words to shine.</p>
+
+ <p>Whether you're writing technical documentation, creative prose, or anything in between, this theme adapts to showcase your content beautifully.</p>
+ </div>
+</body>
+</html> \ No newline at end of file
diff --git a/extras/html/themes/clean_rhythm/handnotes.ttf b/extras/html/themes/clean_rhythm/handnotes.ttf
new file mode 100644
index 0000000..25e688b
--- /dev/null
+++ b/extras/html/themes/clean_rhythm/handnotes.ttf
Binary files differ
diff --git a/extras/html/themes/clean_rhythm/heading.ttf b/extras/html/themes/clean_rhythm/heading.ttf
new file mode 100644
index 0000000..3e10e02
--- /dev/null
+++ b/extras/html/themes/clean_rhythm/heading.ttf
Binary files differ
diff --git a/extras/html/themes/clean_rhythm/style.css b/extras/html/themes/clean_rhythm/style.css
new file mode 100644
index 0000000..72faab7
--- /dev/null
+++ b/extras/html/themes/clean_rhythm/style.css
@@ -0,0 +1,211 @@
+/* Base styles */
+@font-face {
+ font-family: 'text';
+ src: url("./text.ttf") format("truetype");
+}
+
+@font-face {
+ font-family: 'heading';
+ src: url("./heading.ttf") format("truetype");
+}
+
+@font-face {
+ font-family: 'code';
+ src: url("./code.ttf") format("truetype");
+}
+
+@font-face {
+ font-family: 'handnotes';
+ src: url("./handnotes.ttf") format("truetype");
+}
+
+:root {
+ --color-primary: #c76399;
+ --color-secondary: #6ebd6d;
+ --color-accent: #6dbdb9;
+ --color-bg: #edeaec;
+ --color-text: #252525;
+ --font-size-base: 18px;
+ --font-size-h1: 1.95em;
+ --font-size-h2: 1.56em;
+ --font-size-h3: 1.25em;
+ --line-height: 1.72;
+}
+
+* {
+ box-sizing: border-box;
+}
+
+html {
+ font-size: var(--font-size-base);
+ -webkit-font-smoothing: antialiased;
+ -moz-osx-font-smoothing: grayscale;
+}
+
+body {
+ font-family: text, sans-serif;
+ background-color: var(--color-bg);
+ color: var(--color-text);
+ line-height: var(--line-height);
+ margin: 0;
+ padding: 0;
+ overflow-wrap: break-word;
+}
+
+h1, h2, h3 {
+ font-family: heading, serif;
+ line-height: 1.2;
+ margin-top: 1em;
+ margin-bottom: 0.5em;
+}
+
+h1 {
+ font-size: var(--font-size-h1);
+ color: var(--color-primary);
+}
+
+h2 {
+ font-size: var(--font-size-h2);
+ color: var(--color-primary);
+}
+
+h3 {
+ font-size: var(--font-size-h3);
+ color: var(--color-secondary);
+}
+
+a {
+ font-family: code, monospace;
+ color: var(--color-secondary);
+ text-decoration: none;
+ transition: all 0.3s ease;
+}
+
+a:hover {
+ color: var(--color-accent);
+ text-decoration: underline;
+}
+
+.textlink {
+ font-family: text, sans-serif;
+}
+
+.quote {
+ font-family: handnotes, cursive;
+ border-left: 4px solid var(--color-accent);
+ padding: 1em 1.5em;
+ margin: 1.5em 0;
+ background-color: rgba(199, 99, 153, 0.07);
+ font-style: italic;
+}
+
+pre {
+ font-family: code, monospace;
+ background-color: rgba(37, 37, 37, 0.04);
+ border: 1px solid rgba(37, 37, 37, 0.13);
+ padding: 1em;
+ overflow-x: auto;
+ border-radius: 4px;
+ font-size: 0.9em;
+}
+
+code {
+ font-family: code, monospace;
+ background-color: rgba(37, 37, 37, 0.04);
+ padding: 0.2em 0.4em;
+ border-radius: 3px;
+ font-size: 0.9em;
+}
+
+ul, ol {
+ padding-left: 2em;
+ margin: 1em 0;
+}
+
+li {
+ margin: 0.5em 0;
+}
+
+img {
+ max-width: 100%;
+ height: auto;
+}
+
+hr {
+ border: none;
+ border-top: 1px solid rgba(37, 37, 37, 0.20);
+ margin: 2em 0;
+}
+
+
+/* Layout: future */
+
+body {
+ background-color: #000;
+ color: #fff;
+ padding: 0;
+ margin: 0;
+ position: relative;
+ overflow-x: hidden;
+}
+
+body::before {
+ content: "";
+ position: fixed;
+ top: 0;
+ left: 0;
+ right: 0;
+ bottom: 0;
+ background: radial-gradient(circle at 20% 50%, rgba(199, 99, 153, 0.27) 0%, transparent 50%), radial-gradient(circle at 80% 80%, rgba(110, 189, 109, 0.27) 0%, transparent 50%), radial-gradient(circle at 40% 20%, rgba(109, 189, 185, 0.27) 0%, transparent 50%);
+ z-index: -1;
+}
+
+.header {
+ padding: 6em 2em;
+ text-align: center;
+ position: relative;
+}
+
+.header h1 {
+ font-size: 5em;
+ margin: 0;
+ background: linear-gradient(45deg, #c76399, #6ebd6d, #6dbdb9);
+ -webkit-
+ -webkit-text-fill-color: transparent;
+
+ text-transform: uppercase;
+ letter-spacing: 0.2em;
+}
+
+h1, h2, h3, p, ul, pre, .quote {
+ max-width: 65ch;
+ margin: 2em auto;
+ padding: 2em;
+ background: rgba(255,255,255,0.05);
+ backdrop-filter: blur(10px);
+ border: 1px solid rgba(255,255,255,0.1);
+ border-radius: 20px;
+ box-shadow: 0 8px 32px rgba(0,0,0,0.2);
+}
+
+a {
+ color: #6dbdb9;
+ text-decoration: none;
+ position: relative;
+}
+
+a::after {
+ content: "";
+ position: absolute;
+ bottom: -2px;
+ left: 0;
+ right: 0;
+ height: 2px;
+ background: linear-gradient(90deg, #c76399, #6ebd6d);
+ transform: scaleX(0);
+ transition: transform 0.3s ease;
+}
+
+a:hover::after {
+ transform: scaleX(1);
+}
diff --git a/extras/html/themes/clean_rhythm/theme.conf b/extras/html/themes/clean_rhythm/theme.conf
new file mode 100644
index 0000000..98a41f3
--- /dev/null
+++ b/extras/html/themes/clean_rhythm/theme.conf
@@ -0,0 +1,8 @@
+declare -xr HTML_HEADER=./extras/html/header.html.part
+declare -xr HTML_FOOTER=./extras/html/footer.html.part
+declare -xr HTML_CSS_STYLE=$HTML_THEME_DIR/style.css
+declare -xr HTML_WEBFONT_HEADING=./extras/html/fonts/Merriweather/Merriweather-Bold.ttf
+declare -xr HTML_WEBFONT_TEXT=./extras/html/fonts/oxygen/oxygen-Regular.ttf
+declare -xr HTML_WEBFONT_CODE=./extras/html/fonts/hack/hack-Regular.ttf
+declare -xr HTML_WEBFONT_HANDNOTES=./extras/html/fonts/khand/khand.ttf
+declare -xr SOURCE_HIGHLIGHT_CSS=./extras/html/source-highlight-styles/mono.css
diff --git a/extras/html/themes/clear_forest/LICENSE b/extras/html/themes/clear_forest/LICENSE
new file mode 100644
index 0000000..8db2eea
--- /dev/null
+++ b/extras/html/themes/clear_forest/LICENSE
@@ -0,0 +1,21 @@
+Theme: clear_forest
+Generated: 2025-06-22 21:38:55
+
+Layout: technical
+Color Scheme: split_complementary (Light)
+
+Font Licenses:
+==============
+Heading Font: pixelon
+License: Free
+Category: display
+
+Body Font: roboto-slab
+License: Apache
+Category: serif
+
+Code Font: consola-mono
+License: OFL
+Category: monospace
+
+All fonts are free for personal use.
diff --git a/extras/html/themes/clear_forest/code.ttf b/extras/html/themes/clear_forest/code.ttf
new file mode 100644
index 0000000..78ca9da
--- /dev/null
+++ b/extras/html/themes/clear_forest/code.ttf
Binary files differ
diff --git a/extras/html/themes/clear_forest/example.html b/extras/html/themes/clear_forest/example.html
new file mode 100644
index 0000000..2d4d5cd
--- /dev/null
+++ b/extras/html/themes/clear_forest/example.html
@@ -0,0 +1,75 @@
+<!DOCTYPE html>
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
+<head>
+ <meta charset="UTF-8" />
+ <meta name="viewport" content="width=device-width, initial-scale=1.0" />
+ <title>Clear Forest - Gemtexter Theme</title>
+ <link rel="stylesheet" href="style.css" />
+</head>
+<body>
+ <div class="header">
+ <h1>Clear Forest</h1>
+ <p>A technical layout with split complementary colors</p>
+ </div>
+
+ <div class="content">
+ <h1>Welcome to Clear Forest</h1>
+ <p>This theme features a carefully crafted technical layout with a light split complementary color scheme. The typography combines display fonts for headings with serif for body text.</p>
+
+ <h2>Typography Showcase</h2>
+ <p>The roboto-slab font family provides excellent readability for body text, while pixelon adds character to headings. Code blocks use consola-mono for clarity.</p>
+
+ <h2>Color Palette</h2>
+ <p>Primary: <span style="color: #4eaa17; font-weight: bold;">#4eaa17</span> |
+ Secondary: <span style="color: #37269b; font-weight: bold;">#37269b</span> |
+ Accent: <span style="color: #9b268f; font-weight: bold;">#9b268f</span></p>
+
+ <h3>Interactive Elements</h3>
+ <p>Links like <a href="#">this example</a> and longer <a href="#" class="textlink">text links that demonstrate the theme's navigation style</a> use the secondary color.</p>
+
+ <div class="quote">
+ "Design is not just what it looks like and feels like. Design is how it works." — Steve Jobs
+ </div>
+
+ <h3>Code Examples</h3>
+ <p>Inline code like <code>theme.generate()</code> and larger blocks:</p>
+ <pre>// Theme configuration
+const theme = {
+ name: "clear_forest",
+ layout: "technical",
+ colors: {
+ primary: "#4eaa17",
+ secondary: "#37269b",
+ accent: "#9b268f"
+ },
+ fonts: {
+ heading: "pixelon",
+ body: "roboto-slab",
+ code: "consola-mono"
+ }
+};</pre>
+
+ <h2>Content Structure</h2>
+ <ul>
+ <li>Clean, readable typography with 15px base font size</li>
+ <li>Heading scale ratio of 4.24x for visual hierarchy</li>
+ <li>Line height of 1.73 for comfortable reading</li>
+ <li>Technical layout optimized for content flow</li>
+ <li>Light theme with split complementary color harmony</li>
+ </ul>
+
+ <h2>Font Licensing</h2>
+ <p>All fonts used in this theme are properly licensed:</p>
+ <ul>
+ <li>pixelon: Free License</li>
+ <li>roboto-slab: Apache License</li>
+ <li>consola-mono: OFL License</li>
+ </ul>
+
+ <h3>Final Thoughts</h3>
+ <p>Every element of this theme has been carefully designed to create a harmonious reading experience. The technical layout ensures content is presented in an engaging way, while the color scheme provides the perfect backdrop for your words to shine.</p>
+
+ <p>Whether you're writing technical documentation, creative prose, or anything in between, this theme adapts to showcase your content beautifully.</p>
+ </div>
+</body>
+</html> \ No newline at end of file
diff --git a/extras/html/themes/clear_forest/handnotes.ttf b/extras/html/themes/clear_forest/handnotes.ttf
new file mode 100644
index 0000000..25e688b
--- /dev/null
+++ b/extras/html/themes/clear_forest/handnotes.ttf
Binary files differ
diff --git a/extras/html/themes/clear_forest/heading.ttf b/extras/html/themes/clear_forest/heading.ttf
new file mode 100644
index 0000000..acb3c81
--- /dev/null
+++ b/extras/html/themes/clear_forest/heading.ttf
Binary files differ
diff --git a/extras/html/themes/clear_forest/style.css b/extras/html/themes/clear_forest/style.css
new file mode 100644
index 0000000..364dbca
--- /dev/null
+++ b/extras/html/themes/clear_forest/style.css
@@ -0,0 +1,208 @@
+/* Base styles */
+@font-face {
+ font-family: 'text';
+ src: url("./text.ttf") format("truetype");
+}
+
+@font-face {
+ font-family: 'heading';
+ src: url("./heading.ttf") format("truetype");
+}
+
+@font-face {
+ font-family: 'code';
+ src: url("./code.ttf") format("truetype");
+}
+
+@font-face {
+ font-family: 'handnotes';
+ src: url("./handnotes.ttf") format("truetype");
+}
+
+:root {
+ --color-primary: #4eaa17;
+ --color-secondary: #37269b;
+ --color-accent: #9b268f;
+ --color-bg: #eff1ee;
+ --color-text: #1a1a1a;
+ --font-size-base: 15px;
+ --font-size-h1: 4.24em;
+ --font-size-h2: 2.62em;
+ --font-size-h3: 1.62em;
+ --line-height: 1.73;
+}
+
+* {
+ box-sizing: border-box;
+}
+
+html {
+ font-size: var(--font-size-base);
+ -webkit-font-smoothing: antialiased;
+ -moz-osx-font-smoothing: grayscale;
+}
+
+body {
+ font-family: text, sans-serif;
+ background-color: var(--color-bg);
+ color: var(--color-text);
+ line-height: var(--line-height);
+ margin: 0;
+ padding: 0;
+ overflow-wrap: break-word;
+}
+
+h1, h2, h3 {
+ font-family: heading, serif;
+ line-height: 1.2;
+ margin-top: 1em;
+ margin-bottom: 0.5em;
+}
+
+h1 {
+ font-size: var(--font-size-h1);
+ color: var(--color-primary);
+}
+
+h2 {
+ font-size: var(--font-size-h2);
+ color: var(--color-primary);
+}
+
+h3 {
+ font-size: var(--font-size-h3);
+ color: var(--color-secondary);
+}
+
+a {
+ font-family: code, monospace;
+ color: var(--color-secondary);
+ text-decoration: none;
+ transition: all 0.3s ease;
+}
+
+a:hover {
+ color: var(--color-accent);
+ text-decoration: underline;
+}
+
+.textlink {
+ font-family: text, sans-serif;
+}
+
+.quote {
+ font-family: handnotes, cursive;
+ border-left: 4px solid var(--color-accent);
+ padding: 1em 1.5em;
+ margin: 1.5em 0;
+ background-color: rgba(78, 170, 23, 0.07);
+ font-style: italic;
+}
+
+pre {
+ font-family: code, monospace;
+ background-color: rgba(26, 26, 26, 0.04);
+ border: 1px solid rgba(26, 26, 26, 0.13);
+ padding: 1em;
+ overflow-x: auto;
+ border-radius: 4px;
+ font-size: 0.9em;
+}
+
+code {
+ font-family: code, monospace;
+ background-color: rgba(26, 26, 26, 0.04);
+ padding: 0.2em 0.4em;
+ border-radius: 3px;
+ font-size: 0.9em;
+}
+
+ul, ol {
+ padding-left: 2em;
+ margin: 1em 0;
+}
+
+li {
+ margin: 0.5em 0;
+}
+
+img {
+ max-width: 100%;
+ height: auto;
+}
+
+hr {
+ border: none;
+ border-top: 1px solid rgba(26, 26, 26, 0.20);
+ margin: 2em 0;
+}
+
+
+/* Layout: technical */
+
+body {
+ font-family: code, monospace;
+ background-color: #0a0a0a;
+ color: #e0e0e0;
+ padding: 2em;
+ background-image: linear-gradient(rgba(255,255,255,0.03) 1px, transparent 1px), linear-gradient(90deg, rgba(255,255,255,0.03) 1px, transparent 1px);
+ background-size: 20px 20px;
+}
+
+.header {
+ border: 2px solid #4eaa17;
+ padding: 2em;
+ margin-bottom: 3em;
+ position: relative;
+ background: linear-gradient(135deg, transparent 10px, #0a0a0a 10px);
+}
+
+.header::before {
+ content: "//";
+ position: absolute;
+ top: 10px;
+ left: 10px;
+ color: #4eaa17;
+ font-size: 2em;
+}
+
+h1, h2, h3 {
+ font-family: code, monospace;
+ text-transform: uppercase;
+ letter-spacing: 0.1em;
+ border-left: 4px solid #9b268f;
+ padding-left: 1em;
+}
+
+h1::before { content: "001 "; color: #4eaa17; }
+h2::before { content: "010 "; color: #37269b; }
+h3::before { content: "011 "; color: #9b268f; }
+
+p, ul, pre, .quote {
+ background-color: rgba(255,255,255,0.02);
+ border: 1px solid rgba(255,255,255,0.1);
+ padding: 1.5em;
+ margin: 1.5em 0;
+ position: relative;
+}
+
+p::before, ul::before, .quote::before {
+ content: ">";
+ position: absolute;
+ left: -1em;
+ color: #9b268f;
+}
+
+a {
+ color: #9b268f;
+ text-decoration: none;
+ padding: 0.2em 0.4em;
+ background-color: rgba(255,255,255,0.05);
+ border: 1px solid rgba(155, 38, 143, 0.20);
+ transition: all 0.3s ease;
+}
+
+a:hover {
+ background-color: rgba(155, 38, 143, 0.13);
+ border-color: #9b268f;
+}
diff --git a/extras/html/themes/clear_forest/theme.conf b/extras/html/themes/clear_forest/theme.conf
new file mode 100644
index 0000000..6147fc7
--- /dev/null
+++ b/extras/html/themes/clear_forest/theme.conf
@@ -0,0 +1,8 @@
+declare -xr HTML_HEADER=./extras/html/header.html.part
+declare -xr HTML_FOOTER=./extras/html/footer.html.part
+declare -xr HTML_CSS_STYLE=$HTML_THEME_DIR/style.css
+declare -xr HTML_WEBFONT_HEADING=./extras/html/fonts/pixelon/pixelon-Bold.ttf
+declare -xr HTML_WEBFONT_TEXT=./extras/html/fonts/roboto-slab/roboto-slab-Regular.ttf
+declare -xr HTML_WEBFONT_CODE=./extras/html/fonts/consola-mono/consola-mono-Regular.ttf
+declare -xr HTML_WEBFONT_HANDNOTES=./extras/html/fonts/khand/khand.ttf
+declare -xr SOURCE_HIGHLIGHT_CSS=./extras/html/source-highlight-styles/mono.css
diff --git a/extras/html/themes/clear_frost/LICENSE b/extras/html/themes/clear_frost/LICENSE
new file mode 100644
index 0000000..23a61b0
--- /dev/null
+++ b/extras/html/themes/clear_frost/LICENSE
@@ -0,0 +1,21 @@
+Theme: clear_frost
+Generated: 2025-06-22 21:38:55
+
+Layout: minimal_grid
+Color Scheme: split_complementary (Light)
+
+Font Licenses:
+==============
+Heading Font: roboto-slab
+License: Apache
+Category: serif
+
+Body Font: oxygen
+License: OFL
+Category: sans-serif
+
+Code Font: intelone-mono
+License: OFL
+Category: monospace
+
+All fonts are free for personal use.
diff --git a/extras/html/themes/clear_frost/code.ttf b/extras/html/themes/clear_frost/code.ttf
new file mode 100644
index 0000000..2711179
--- /dev/null
+++ b/extras/html/themes/clear_frost/code.ttf
Binary files differ
diff --git a/extras/html/themes/clear_frost/example.html b/extras/html/themes/clear_frost/example.html
new file mode 100644
index 0000000..68f48e3
--- /dev/null
+++ b/extras/html/themes/clear_frost/example.html
@@ -0,0 +1,75 @@
+<!DOCTYPE html>
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
+<head>
+ <meta charset="UTF-8" />
+ <meta name="viewport" content="width=device-width, initial-scale=1.0" />
+ <title>Clear Frost - Gemtexter Theme</title>
+ <link rel="stylesheet" href="style.css" />
+</head>
+<body>
+ <div class="header">
+ <h1>Clear Frost</h1>
+ <p>A minimal grid layout with split complementary colors</p>
+ </div>
+
+ <div class="content">
+ <h1>Welcome to Clear Frost</h1>
+ <p>This theme features a carefully crafted minimal grid layout with a light split complementary color scheme. The typography combines serif fonts for headings with sans-serif for body text.</p>
+
+ <h2>Typography Showcase</h2>
+ <p>The oxygen font family provides excellent readability for body text, while roboto-slab adds character to headings. Code blocks use intelone-mono for clarity.</p>
+
+ <h2>Color Palette</h2>
+ <p>Primary: <span style="color: #9324d0; font-weight: bold;">#9324d0</span> |
+ Secondary: <span style="color: #a8bf35; font-weight: bold;">#a8bf35</span> |
+ Accent: <span style="color: #35bf47; font-weight: bold;">#35bf47</span></p>
+
+ <h3>Interactive Elements</h3>
+ <p>Links like <a href="#">this example</a> and longer <a href="#" class="textlink">text links that demonstrate the theme's navigation style</a> use the secondary color.</p>
+
+ <div class="quote">
+ "Design is not just what it looks like and feels like. Design is how it works." — Steve Jobs
+ </div>
+
+ <h3>Code Examples</h3>
+ <p>Inline code like <code>theme.generate()</code> and larger blocks:</p>
+ <pre>// Theme configuration
+const theme = {
+ name: "clear_frost",
+ layout: "minimal_grid",
+ colors: {
+ primary: "#9324d0",
+ secondary: "#a8bf35",
+ accent: "#35bf47"
+ },
+ fonts: {
+ heading: "roboto-slab",
+ body: "oxygen",
+ code: "intelone-mono"
+ }
+};</pre>
+
+ <h2>Content Structure</h2>
+ <ul>
+ <li>Clean, readable typography with 15px base font size</li>
+ <li>Heading scale ratio of 1.42x for visual hierarchy</li>
+ <li>Line height of 1.6 for comfortable reading</li>
+ <li>Minimal Grid layout optimized for content flow</li>
+ <li>Light theme with split complementary color harmony</li>
+ </ul>
+
+ <h2>Font Licensing</h2>
+ <p>All fonts used in this theme are properly licensed:</p>
+ <ul>
+ <li>roboto-slab: Apache License</li>
+ <li>oxygen: OFL License</li>
+ <li>intelone-mono: OFL License</li>
+ </ul>
+
+ <h3>Final Thoughts</h3>
+ <p>Every element of this theme has been carefully designed to create a harmonious reading experience. The minimal grid layout ensures content is presented in an engaging way, while the color scheme provides the perfect backdrop for your words to shine.</p>
+
+ <p>Whether you're writing technical documentation, creative prose, or anything in between, this theme adapts to showcase your content beautifully.</p>
+ </div>
+</body>
+</html> \ No newline at end of file
diff --git a/extras/html/themes/clear_frost/handnotes.ttf b/extras/html/themes/clear_frost/handnotes.ttf
new file mode 100644
index 0000000..25e688b
--- /dev/null
+++ b/extras/html/themes/clear_frost/handnotes.ttf
Binary files differ
diff --git a/extras/html/themes/clear_frost/style.css b/extras/html/themes/clear_frost/style.css
new file mode 100644
index 0000000..e849f6f
--- /dev/null
+++ b/extras/html/themes/clear_frost/style.css
@@ -0,0 +1,180 @@
+/* Base styles */
+@font-face {
+ font-family: 'text';
+ src: url("./text.ttf") format("truetype");
+}
+
+@font-face {
+ font-family: 'heading';
+ src: url("./heading.ttf") format("truetype");
+}
+
+@font-face {
+ font-family: 'code';
+ src: url("./code.ttf") format("truetype");
+}
+
+@font-face {
+ font-family: 'handnotes';
+ src: url("./handnotes.ttf") format("truetype");
+}
+
+:root {
+ --color-primary: #9324d0;
+ --color-secondary: #a8bf35;
+ --color-accent: #35bf47;
+ --color-bg: #edebef;
+ --color-text: #121212;
+ --font-size-base: 15px;
+ --font-size-h1: 1.42em;
+ --font-size-h2: 1.27em;
+ --font-size-h3: 1.12em;
+ --line-height: 1.6;
+}
+
+* {
+ box-sizing: border-box;
+}
+
+html {
+ font-size: var(--font-size-base);
+ -webkit-font-smoothing: antialiased;
+ -moz-osx-font-smoothing: grayscale;
+}
+
+body {
+ font-family: text, sans-serif;
+ background-color: var(--color-bg);
+ color: var(--color-text);
+ line-height: var(--line-height);
+ margin: 0;
+ padding: 0;
+ overflow-wrap: break-word;
+}
+
+h1, h2, h3 {
+ font-family: heading, serif;
+ line-height: 1.2;
+ margin-top: 1em;
+ margin-bottom: 0.5em;
+}
+
+h1 {
+ font-size: var(--font-size-h1);
+ color: var(--color-primary);
+}
+
+h2 {
+ font-size: var(--font-size-h2);
+ color: var(--color-primary);
+}
+
+h3 {
+ font-size: var(--font-size-h3);
+ color: var(--color-secondary);
+}
+
+a {
+ font-family: code, monospace;
+ color: var(--color-secondary);
+ text-decoration: none;
+ transition: all 0.3s ease;
+}
+
+a:hover {
+ color: var(--color-accent);
+ text-decoration: underline;
+}
+
+.textlink {
+ font-family: text, sans-serif;
+}
+
+.quote {
+ font-family: handnotes, cursive;
+ border-left: 4px solid var(--color-accent);
+ padding: 1em 1.5em;
+ margin: 1.5em 0;
+ background-color: rgba(147, 36, 208, 0.07);
+ font-style: italic;
+}
+
+pre {
+ font-family: code, monospace;
+ background-color: rgba(18, 18, 18, 0.04);
+ border: 1px solid rgba(18, 18, 18, 0.13);
+ padding: 1em;
+ overflow-x: auto;
+ border-radius: 4px;
+ font-size: 0.9em;
+}
+
+code {
+ font-family: code, monospace;
+ background-color: rgba(18, 18, 18, 0.04);
+ padding: 0.2em 0.4em;
+ border-radius: 3px;
+ font-size: 0.9em;
+}
+
+ul, ol {
+ padding-left: 2em;
+ margin: 1em 0;
+}
+
+li {
+ margin: 0.5em 0;
+}
+
+img {
+ max-width: 100%;
+ height: auto;
+}
+
+hr {
+ border: none;
+ border-top: 1px solid rgba(18, 18, 18, 0.20);
+ margin: 2em 0;
+}
+
+
+/* Layout: minimal_grid */
+
+body {
+ display: grid;
+ grid-template-columns: repeat(12, 1fr);
+ gap: 1.5em;
+ padding: 3em 2em;
+ max-width: 1400px;
+ margin: 0 auto;
+}
+
+.header {
+ grid-column: 2 / 12;
+ text-align: center;
+ margin-bottom: 3em;
+ padding-bottom: 2em;
+ border-bottom: 1px solid var(--color-text);
+}
+
+h1 {
+ grid-column: 1 / 13;
+ text-align: center;
+}
+
+h2 {
+ grid-column: 2 / 12;
+}
+
+h3 {
+ grid-column: 3 / 11;
+}
+
+p, ul, pre {
+ grid-column: 3 / 11;
+}
+
+.quote {
+ grid-column: 2 / 12;
+ text-align: center;
+}
diff --git a/extras/html/themes/clear_frost/theme.conf b/extras/html/themes/clear_frost/theme.conf
new file mode 100644
index 0000000..19a2553
--- /dev/null
+++ b/extras/html/themes/clear_frost/theme.conf
@@ -0,0 +1,8 @@
+declare -xr HTML_HEADER=./extras/html/header.html.part
+declare -xr HTML_FOOTER=./extras/html/footer.html.part
+declare -xr HTML_CSS_STYLE=$HTML_THEME_DIR/style.css
+declare -xr HTML_WEBFONT_HEADING=./extras/html/fonts/roboto-slab/roboto-slab-Bold.ttf
+declare -xr HTML_WEBFONT_TEXT=./extras/html/fonts/oxygen/oxygen-Regular.ttf
+declare -xr HTML_WEBFONT_CODE=./extras/html/fonts/intelone-mono/intelone-mono-Regular.ttf
+declare -xr HTML_WEBFONT_HANDNOTES=./extras/html/fonts/khand/khand.ttf
+declare -xr SOURCE_HIGHLIGHT_CSS=./extras/html/source-highlight-styles/mono.css
diff --git a/extras/html/themes/cool_breeze/LICENSE b/extras/html/themes/cool_breeze/LICENSE
new file mode 100644
index 0000000..cc81549
--- /dev/null
+++ b/extras/html/themes/cool_breeze/LICENSE
@@ -0,0 +1,21 @@
+Theme: cool_breeze
+Generated: 2025-06-22 21:38:55
+
+Layout: technical
+Color Scheme: monochromatic (Dark)
+
+Font Licenses:
+==============
+Heading Font: Abril_Fatface
+License: OFL
+Category: display
+
+Body Font: Merriweather
+License: OFL
+Category: serif
+
+Code Font: hack
+License: MIT
+Category: monospace
+
+All fonts are free for personal use.
diff --git a/extras/html/themes/cool_breeze/code.ttf b/extras/html/themes/cool_breeze/code.ttf
new file mode 100644
index 0000000..7c8e65b
--- /dev/null
+++ b/extras/html/themes/cool_breeze/code.ttf
Binary files differ
diff --git a/extras/html/themes/cool_breeze/example.html b/extras/html/themes/cool_breeze/example.html
new file mode 100644
index 0000000..50451a5
--- /dev/null
+++ b/extras/html/themes/cool_breeze/example.html
@@ -0,0 +1,75 @@
+<!DOCTYPE html>
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
+<head>
+ <meta charset="UTF-8" />
+ <meta name="viewport" content="width=device-width, initial-scale=1.0" />
+ <title>Cool Breeze - Gemtexter Theme</title>
+ <link rel="stylesheet" href="style.css" />
+</head>
+<body>
+ <div class="header">
+ <h1>Cool Breeze</h1>
+ <p>A technical layout with monochromatic colors</p>
+ </div>
+
+ <div class="content">
+ <h1>Welcome to Cool Breeze</h1>
+ <p>This theme features a carefully crafted technical layout with a dark monochromatic color scheme. The typography combines display fonts for headings with serif for body text.</p>
+
+ <h2>Typography Showcase</h2>
+ <p>The Merriweather font family provides excellent readability for body text, while Abril Fatface adds character to headings. Code blocks use hack for clarity.</p>
+
+ <h2>Color Palette</h2>
+ <p>Primary: <span style="color: #299717; font-weight: bold;">#299717</span> |
+ Secondary: <span style="color: #236119; font-weight: bold;">#236119</span> |
+ Accent: <span style="color: #47973b; font-weight: bold;">#47973b</span></p>
+
+ <h3>Interactive Elements</h3>
+ <p>Links like <a href="#">this example</a> and longer <a href="#" class="textlink">text links that demonstrate the theme's navigation style</a> use the secondary color.</p>
+
+ <div class="quote">
+ "Design is not just what it looks like and feels like. Design is how it works." — Steve Jobs
+ </div>
+
+ <h3>Code Examples</h3>
+ <p>Inline code like <code>theme.generate()</code> and larger blocks:</p>
+ <pre>// Theme configuration
+const theme = {
+ name: "cool_breeze",
+ layout: "technical",
+ colors: {
+ primary: "#299717",
+ secondary: "#236119",
+ accent: "#47973b"
+ },
+ fonts: {
+ heading: "Abril_Fatface",
+ body: "Merriweather",
+ code: "hack"
+ }
+};</pre>
+
+ <h2>Content Structure</h2>
+ <ul>
+ <li>Clean, readable typography with 18px base font size</li>
+ <li>Heading scale ratio of 1.73x for visual hierarchy</li>
+ <li>Line height of 1.58 for comfortable reading</li>
+ <li>Technical layout optimized for content flow</li>
+ <li>Dark theme with monochromatic color harmony</li>
+ </ul>
+
+ <h2>Font Licensing</h2>
+ <p>All fonts used in this theme are properly licensed:</p>
+ <ul>
+ <li>Abril_Fatface: OFL License</li>
+ <li>Merriweather: OFL License</li>
+ <li>hack: MIT License</li>
+ </ul>
+
+ <h3>Final Thoughts</h3>
+ <p>Every element of this theme has been carefully designed to create a harmonious reading experience. The technical layout ensures content is presented in an engaging way, while the color scheme provides the perfect backdrop for your words to shine.</p>
+
+ <p>Whether you're writing technical documentation, creative prose, or anything in between, this theme adapts to showcase your content beautifully.</p>
+ </div>
+</body>
+</html> \ No newline at end of file
diff --git a/extras/html/themes/cool_breeze/handnotes.ttf b/extras/html/themes/cool_breeze/handnotes.ttf
new file mode 100644
index 0000000..25e688b
--- /dev/null
+++ b/extras/html/themes/cool_breeze/handnotes.ttf
Binary files differ
diff --git a/extras/html/themes/cool_breeze/heading.ttf b/extras/html/themes/cool_breeze/heading.ttf
new file mode 100644
index 0000000..a291711
--- /dev/null
+++ b/extras/html/themes/cool_breeze/heading.ttf
Binary files differ
diff --git a/extras/html/themes/cool_breeze/style.css b/extras/html/themes/cool_breeze/style.css
new file mode 100644
index 0000000..339cca3
--- /dev/null
+++ b/extras/html/themes/cool_breeze/style.css
@@ -0,0 +1,208 @@
+/* Base styles */
+@font-face {
+ font-family: 'text';
+ src: url("./text.ttf") format("truetype");
+}
+
+@font-face {
+ font-family: 'heading';
+ src: url("./heading.ttf") format("truetype");
+}
+
+@font-face {
+ font-family: 'code';
+ src: url("./code.ttf") format("truetype");
+}
+
+@font-face {
+ font-family: 'handnotes';
+ src: url("./handnotes.ttf") format("truetype");
+}
+
+:root {
+ --color-primary: #299717;
+ --color-secondary: #236119;
+ --color-accent: #47973b;
+ --color-bg: #0c0e0b;
+ --color-text: #dfdfdf;
+ --font-size-base: 18px;
+ --font-size-h1: 1.73em;
+ --font-size-h2: 1.44em;
+ --font-size-h3: 1.2em;
+ --line-height: 1.58;
+}
+
+* {
+ box-sizing: border-box;
+}
+
+html {
+ font-size: var(--font-size-base);
+ -webkit-font-smoothing: antialiased;
+ -moz-osx-font-smoothing: grayscale;
+}
+
+body {
+ font-family: text, sans-serif;
+ background-color: var(--color-bg);
+ color: var(--color-text);
+ line-height: var(--line-height);
+ margin: 0;
+ padding: 0;
+ overflow-wrap: break-word;
+}
+
+h1, h2, h3 {
+ font-family: heading, serif;
+ line-height: 1.2;
+ margin-top: 1em;
+ margin-bottom: 0.5em;
+}
+
+h1 {
+ font-size: var(--font-size-h1);
+ color: var(--color-primary);
+}
+
+h2 {
+ font-size: var(--font-size-h2);
+ color: var(--color-primary);
+}
+
+h3 {
+ font-size: var(--font-size-h3);
+ color: var(--color-secondary);
+}
+
+a {
+ font-family: code, monospace;
+ color: var(--color-secondary);
+ text-decoration: none;
+ transition: all 0.3s ease;
+}
+
+a:hover {
+ color: var(--color-accent);
+ text-decoration: underline;
+}
+
+.textlink {
+ font-family: text, sans-serif;
+}
+
+.quote {
+ font-family: handnotes, cursive;
+ border-left: 4px solid var(--color-accent);
+ padding: 1em 1.5em;
+ margin: 1.5em 0;
+ background-color: rgba(41, 151, 23, 0.07);
+ font-style: italic;
+}
+
+pre {
+ font-family: code, monospace;
+ background-color: rgba(223, 223, 223, 0.04);
+ border: 1px solid rgba(223, 223, 223, 0.13);
+ padding: 1em;
+ overflow-x: auto;
+ border-radius: 4px;
+ font-size: 0.9em;
+}
+
+code {
+ font-family: code, monospace;
+ background-color: rgba(223, 223, 223, 0.04);
+ padding: 0.2em 0.4em;
+ border-radius: 3px;
+ font-size: 0.9em;
+}
+
+ul, ol {
+ padding-left: 2em;
+ margin: 1em 0;
+}
+
+li {
+ margin: 0.5em 0;
+}
+
+img {
+ max-width: 100%;
+ height: auto;
+}
+
+hr {
+ border: none;
+ border-top: 1px solid rgba(223, 223, 223, 0.20);
+ margin: 2em 0;
+}
+
+
+/* Layout: technical */
+
+body {
+ font-family: code, monospace;
+ background-color: #0a0a0a;
+ color: #e0e0e0;
+ padding: 2em;
+ background-image: linear-gradient(rgba(255,255,255,0.03) 1px, transparent 1px), linear-gradient(90deg, rgba(255,255,255,0.03) 1px, transparent 1px);
+ background-size: 20px 20px;
+}
+
+.header {
+ border: 2px solid #299717;
+ padding: 2em;
+ margin-bottom: 3em;
+ position: relative;
+ background: linear-gradient(135deg, transparent 10px, #0a0a0a 10px);
+}
+
+.header::before {
+ content: "//";
+ position: absolute;
+ top: 10px;
+ left: 10px;
+ color: #299717;
+ font-size: 2em;
+}
+
+h1, h2, h3 {
+ font-family: code, monospace;
+ text-transform: uppercase;
+ letter-spacing: 0.1em;
+ border-left: 4px solid #47973b;
+ padding-left: 1em;
+}
+
+h1::before { content: "001 "; color: #299717; }
+h2::before { content: "010 "; color: #236119; }
+h3::before { content: "011 "; color: #47973b; }
+
+p, ul, pre, .quote {
+ background-color: rgba(255,255,255,0.02);
+ border: 1px solid rgba(255,255,255,0.1);
+ padding: 1.5em;
+ margin: 1.5em 0;
+ position: relative;
+}
+
+p::before, ul::before, .quote::before {
+ content: ">";
+ position: absolute;
+ left: -1em;
+ color: #47973b;
+}
+
+a {
+ color: #47973b;
+ text-decoration: none;
+ padding: 0.2em 0.4em;
+ background-color: rgba(255,255,255,0.05);
+ border: 1px solid rgba(71, 151, 59, 0.20);
+ transition: all 0.3s ease;
+}
+
+a:hover {
+ background-color: rgba(71, 151, 59, 0.13);
+ border-color: #47973b;
+}
diff --git a/extras/html/themes/cool_breeze/text.ttf b/extras/html/themes/cool_breeze/text.ttf
new file mode 100644
index 0000000..3fecc77
--- /dev/null
+++ b/extras/html/themes/cool_breeze/text.ttf
Binary files differ
diff --git a/extras/html/themes/cool_breeze/theme.conf b/extras/html/themes/cool_breeze/theme.conf
new file mode 100644
index 0000000..7673f51
--- /dev/null
+++ b/extras/html/themes/cool_breeze/theme.conf
@@ -0,0 +1,8 @@
+declare -xr HTML_HEADER=./extras/html/header.html.part
+declare -xr HTML_FOOTER=./extras/html/footer.html.part
+declare -xr HTML_CSS_STYLE=$HTML_THEME_DIR/style.css
+declare -xr HTML_WEBFONT_HEADING=./extras/html/fonts/Abril_Fatface/Abril_Fatface-Bold.ttf
+declare -xr HTML_WEBFONT_TEXT=./extras/html/fonts/Merriweather/Merriweather-Regular.ttf
+declare -xr HTML_WEBFONT_CODE=./extras/html/fonts/hack/hack-Regular.ttf
+declare -xr HTML_WEBFONT_HANDNOTES=./extras/html/fonts/khand/khand.ttf
+declare -xr SOURCE_HIGHLIGHT_CSS=./extras/html/source-highlight-styles/mono.css
diff --git a/extras/html/themes/cosmic_dusk/LICENSE b/extras/html/themes/cosmic_dusk/LICENSE
new file mode 100644
index 0000000..e12bb30
--- /dev/null
+++ b/extras/html/themes/cosmic_dusk/LICENSE
@@ -0,0 +1,21 @@
+Theme: cosmic_dusk
+Generated: 2025-06-22 21:38:55
+
+Layout: terminal
+Color Scheme: split_complementary (Light)
+
+Font Licenses:
+==============
+Heading Font: khand
+License: Free
+Category: handwriting
+
+Body Font: Lato
+License: OFL
+Category: sans-serif
+
+Code Font: consola-mono
+License: OFL
+Category: monospace
+
+All fonts are free for personal use.
diff --git a/extras/html/themes/cosmic_dusk/code.ttf b/extras/html/themes/cosmic_dusk/code.ttf
new file mode 100644
index 0000000..78ca9da
--- /dev/null
+++ b/extras/html/themes/cosmic_dusk/code.ttf
Binary files differ
diff --git a/extras/html/themes/cosmic_dusk/example.html b/extras/html/themes/cosmic_dusk/example.html
new file mode 100644
index 0000000..70258e0
--- /dev/null
+++ b/extras/html/themes/cosmic_dusk/example.html
@@ -0,0 +1,75 @@
+<!DOCTYPE html>
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
+<head>
+ <meta charset="UTF-8" />
+ <meta name="viewport" content="width=device-width, initial-scale=1.0" />
+ <title>Cosmic Dusk - Gemtexter Theme</title>
+ <link rel="stylesheet" href="style.css" />
+</head>
+<body>
+ <div class="header">
+ <h1>Cosmic Dusk</h1>
+ <p>A terminal layout with split complementary colors</p>
+ </div>
+
+ <div class="content">
+ <h1>Welcome to Cosmic Dusk</h1>
+ <p>This theme features a carefully crafted terminal layout with a light split complementary color scheme. The typography combines handwriting fonts for headings with sans-serif for body text.</p>
+
+ <h2>Typography Showcase</h2>
+ <p>The Lato font family provides excellent readability for body text, while khand adds character to headings. Code blocks use consola-mono for clarity.</p>
+
+ <h2>Color Palette</h2>
+ <p>Primary: <span style="color: #a1cc51; font-weight: bold;">#a1cc51</span> |
+ Secondary: <span style="color: #5d6ac0; font-weight: bold;">#5d6ac0</span> |
+ Accent: <span style="color: #af5dc0; font-weight: bold;">#af5dc0</span></p>
+
+ <h3>Interactive Elements</h3>
+ <p>Links like <a href="#">this example</a> and longer <a href="#" class="textlink">text links that demonstrate the theme's navigation style</a> use the secondary color.</p>
+
+ <div class="quote">
+ "Design is not just what it looks like and feels like. Design is how it works." — Steve Jobs
+ </div>
+
+ <h3>Code Examples</h3>
+ <p>Inline code like <code>theme.generate()</code> and larger blocks:</p>
+ <pre>// Theme configuration
+const theme = {
+ name: "cosmic_dusk",
+ layout: "terminal",
+ colors: {
+ primary: "#a1cc51",
+ secondary: "#5d6ac0",
+ accent: "#af5dc0"
+ },
+ fonts: {
+ heading: "khand",
+ body: "Lato",
+ code: "consola-mono"
+ }
+};</pre>
+
+ <h2>Content Structure</h2>
+ <ul>
+ <li>Clean, readable typography with 14px base font size</li>
+ <li>Heading scale ratio of 3.38x for visual hierarchy</li>
+ <li>Line height of 1.44 for comfortable reading</li>
+ <li>Terminal layout optimized for content flow</li>
+ <li>Light theme with split complementary color harmony</li>
+ </ul>
+
+ <h2>Font Licensing</h2>
+ <p>All fonts used in this theme are properly licensed:</p>
+ <ul>
+ <li>khand: Free License</li>
+ <li>Lato: OFL License</li>
+ <li>consola-mono: OFL License</li>
+ </ul>
+
+ <h3>Final Thoughts</h3>
+ <p>Every element of this theme has been carefully designed to create a harmonious reading experience. The terminal layout ensures content is presented in an engaging way, while the color scheme provides the perfect backdrop for your words to shine.</p>
+
+ <p>Whether you're writing technical documentation, creative prose, or anything in between, this theme adapts to showcase your content beautifully.</p>
+ </div>
+</body>
+</html> \ No newline at end of file
diff --git a/extras/html/themes/cosmic_dusk/handnotes.ttf b/extras/html/themes/cosmic_dusk/handnotes.ttf
new file mode 100644
index 0000000..25e688b
--- /dev/null
+++ b/extras/html/themes/cosmic_dusk/handnotes.ttf
Binary files differ
diff --git a/extras/html/themes/cosmic_dusk/heading.ttf b/extras/html/themes/cosmic_dusk/heading.ttf
new file mode 100644
index 0000000..25e688b
--- /dev/null
+++ b/extras/html/themes/cosmic_dusk/heading.ttf
Binary files differ
diff --git a/extras/html/themes/cosmic_dusk/style.css b/extras/html/themes/cosmic_dusk/style.css
new file mode 100644
index 0000000..cbe9eec
--- /dev/null
+++ b/extras/html/themes/cosmic_dusk/style.css
@@ -0,0 +1,216 @@
+/* Base styles */
+@font-face {
+ font-family: 'text';
+ src: url("./text.ttf") format("truetype");
+}
+
+@font-face {
+ font-family: 'heading';
+ src: url("./heading.ttf") format("truetype");
+}
+
+@font-face {
+ font-family: 'code';
+ src: url("./code.ttf") format("truetype");
+}
+
+@font-face {
+ font-family: 'handnotes';
+ src: url("./handnotes.ttf") format("truetype");
+}
+
+:root {
+ --color-primary: #a1cc51;
+ --color-secondary: #5d6ac0;
+ --color-accent: #af5dc0;
+ --color-bg: #eff0ed;
+ --color-text: #232323;
+ --font-size-base: 14px;
+ --font-size-h1: 3.38em;
+ --font-size-h2: 2.25em;
+ --font-size-h3: 1.5em;
+ --line-height: 1.44;
+}
+
+* {
+ box-sizing: border-box;
+}
+
+html {
+ font-size: var(--font-size-base);
+ -webkit-font-smoothing: antialiased;
+ -moz-osx-font-smoothing: grayscale;
+}
+
+body {
+ font-family: text, sans-serif;
+ background-color: var(--color-bg);
+ color: var(--color-text);
+ line-height: var(--line-height);
+ margin: 0;
+ padding: 0;
+ overflow-wrap: break-word;
+}
+
+h1, h2, h3 {
+ font-family: heading, serif;
+ line-height: 1.2;
+ margin-top: 1em;
+ margin-bottom: 0.5em;
+}
+
+h1 {
+ font-size: var(--font-size-h1);
+ color: var(--color-primary);
+}
+
+h2 {
+ font-size: var(--font-size-h2);
+ color: var(--color-primary);
+}
+
+h3 {
+ font-size: var(--font-size-h3);
+ color: var(--color-secondary);
+}
+
+a {
+ font-family: code, monospace;
+ color: var(--color-secondary);
+ text-decoration: none;
+ transition: all 0.3s ease;
+}
+
+a:hover {
+ color: var(--color-accent);
+ text-decoration: underline;
+}
+
+.textlink {
+ font-family: text, sans-serif;
+}
+
+.quote {
+ font-family: handnotes, cursive;
+ border-left: 4px solid var(--color-accent);
+ padding: 1em 1.5em;
+ margin: 1.5em 0;
+ background-color: rgba(161, 204, 81, 0.07);
+ font-style: italic;
+}
+
+pre {
+ font-family: code, monospace;
+ background-color: rgba(35, 35, 35, 0.04);
+ border: 1px solid rgba(35, 35, 35, 0.13);
+ padding: 1em;
+ overflow-x: auto;
+ border-radius: 4px;
+ font-size: 0.9em;
+}
+
+code {
+ font-family: code, monospace;
+ background-color: rgba(35, 35, 35, 0.04);
+ padding: 0.2em 0.4em;
+ border-radius: 3px;
+ font-size: 0.9em;
+}
+
+ul, ol {
+ padding-left: 2em;
+ margin: 1em 0;
+}
+
+li {
+ margin: 0.5em 0;
+}
+
+img {
+ max-width: 100%;
+ height: auto;
+}
+
+hr {
+ border: none;
+ border-top: 1px solid rgba(35, 35, 35, 0.20);
+ margin: 2em 0;
+}
+
+
+/* Layout: terminal */
+
+@import url("https://fonts.googleapis.com/css2?family=Source+Code+Pro:wght@400;700&display=swap");
+
+body {
+ background-color: #000;
+ color: #0f0;
+ font-family: 'Source Code Pro', code, monospace;
+ padding: 1em;
+ line-height: 1.4;
+}
+
+.header {
+ border: 2px solid #0f0;
+ padding: 1em;
+ margin-bottom: 2em;
+ position: relative;
+}
+
+.header::before {
+ content: "[SYSTEM] ";
+ color: #ff0;
+}
+
+h1, h2, h3 {
+ color: #0f0;
+ font-family: 'Source Code Pro', code, monospace;
+}
+
+h1::before {
+ content: "### ";
+ color: #f0f;
+}
+
+h2::before {
+ content: "## ";
+ color: #0ff;
+}
+
+h3::before {
+ content: "# ";
+ color: #ff0;
+}
+
+p::before {
+ content: "> ";
+ color: #666;
+}
+
+a {
+ color: #0ff;
+ text-decoration: underline;
+}
+
+a:hover {
+ background-color: #0ff;
+ color: #000;
+}
+
+.quote {
+ border: 1px dashed #0f0;
+ background-color: #0f0111;
+ color: #0f0;
+}
+
+pre {
+ background-color: #111;
+ border: 1px solid #0f0;
+ color: #0f0;
+ overflow-x: scroll;
+}
+
+pre::before {
+ content: "$ cat output.log\A";
+ color: #666;
+}
diff --git a/extras/html/themes/cosmic_dusk/text.ttf b/extras/html/themes/cosmic_dusk/text.ttf
new file mode 100644
index 0000000..bb2e887
--- /dev/null
+++ b/extras/html/themes/cosmic_dusk/text.ttf
Binary files differ
diff --git a/extras/html/themes/cosmic_dusk/theme.conf b/extras/html/themes/cosmic_dusk/theme.conf
new file mode 100644
index 0000000..2857ef2
--- /dev/null
+++ b/extras/html/themes/cosmic_dusk/theme.conf
@@ -0,0 +1,8 @@
+declare -xr HTML_HEADER=./extras/html/header.html.part
+declare -xr HTML_FOOTER=./extras/html/footer.html.part
+declare -xr HTML_CSS_STYLE=$HTML_THEME_DIR/style.css
+declare -xr HTML_WEBFONT_HEADING=./extras/html/fonts/khand/khand-Bold.ttf
+declare -xr HTML_WEBFONT_TEXT=./extras/html/fonts/Lato/Lato-Regular.ttf
+declare -xr HTML_WEBFONT_CODE=./extras/html/fonts/consola-mono/consola-mono-Regular.ttf
+declare -xr HTML_WEBFONT_HANDNOTES=./extras/html/fonts/khand/khand.ttf
+declare -xr SOURCE_HIGHLIGHT_CSS=./extras/html/source-highlight-styles/mono.css
diff --git a/extras/html/themes/cosmic_odyssey/LICENSE b/extras/html/themes/cosmic_odyssey/LICENSE
new file mode 100644
index 0000000..2b1b05f
--- /dev/null
+++ b/extras/html/themes/cosmic_odyssey/LICENSE
@@ -0,0 +1,21 @@
+Theme: cosmic_odyssey
+Generated: 2025-06-22 21:38:55
+
+Layout: gradient
+Color Scheme: monochromatic (Light)
+
+Font Licenses:
+==============
+Heading Font: oxygen
+License: OFL
+Category: sans-serif
+
+Body Font: Lato
+License: OFL
+Category: sans-serif
+
+Code Font: hack
+License: MIT
+Category: monospace
+
+All fonts are free for personal use.
diff --git a/extras/html/themes/cosmic_odyssey/code.ttf b/extras/html/themes/cosmic_odyssey/code.ttf
new file mode 100644
index 0000000..7c8e65b
--- /dev/null
+++ b/extras/html/themes/cosmic_odyssey/code.ttf
Binary files differ
diff --git a/extras/html/themes/cosmic_odyssey/example.html b/extras/html/themes/cosmic_odyssey/example.html
new file mode 100644
index 0000000..eec3474
--- /dev/null
+++ b/extras/html/themes/cosmic_odyssey/example.html
@@ -0,0 +1,75 @@
+<!DOCTYPE html>
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
+<head>
+ <meta charset="UTF-8" />
+ <meta name="viewport" content="width=device-width, initial-scale=1.0" />
+ <title>Cosmic Odyssey - Gemtexter Theme</title>
+ <link rel="stylesheet" href="style.css" />
+</head>
+<body>
+ <div class="header">
+ <h1>Cosmic Odyssey</h1>
+ <p>A gradient layout with monochromatic colors</p>
+ </div>
+
+ <div class="content">
+ <h1>Welcome to Cosmic Odyssey</h1>
+ <p>This theme features a carefully crafted gradient layout with a light monochromatic color scheme. The typography combines sans-serif fonts for headings with sans-serif for body text.</p>
+
+ <h2>Typography Showcase</h2>
+ <p>The Lato font family provides excellent readability for body text, while oxygen adds character to headings. Code blocks use hack for clarity.</p>
+
+ <h2>Color Palette</h2>
+ <p>Primary: <span style="color: #7763f3; font-weight: bold;">#7763f3</span> |
+ Secondary: <span style="color: #3c25ca; font-weight: bold;">#3c25ca</span> |
+ Accent: <span style="color: #bbb4e7; font-weight: bold;">#bbb4e7</span></p>
+
+ <h3>Interactive Elements</h3>
+ <p>Links like <a href="#">this example</a> and longer <a href="#" class="textlink">text links that demonstrate the theme's navigation style</a> use the secondary color.</p>
+
+ <div class="quote">
+ "Design is not just what it looks like and feels like. Design is how it works." — Steve Jobs
+ </div>
+
+ <h3>Code Examples</h3>
+ <p>Inline code like <code>theme.generate()</code> and larger blocks:</p>
+ <pre>// Theme configuration
+const theme = {
+ name: "cosmic_odyssey",
+ layout: "gradient",
+ colors: {
+ primary: "#7763f3",
+ secondary: "#3c25ca",
+ accent: "#bbb4e7"
+ },
+ fonts: {
+ heading: "oxygen",
+ body: "Lato",
+ code: "hack"
+ }
+};</pre>
+
+ <h2>Content Structure</h2>
+ <ul>
+ <li>Clean, readable typography with 17px base font size</li>
+ <li>Heading scale ratio of 1.42x for visual hierarchy</li>
+ <li>Line height of 1.72 for comfortable reading</li>
+ <li>Gradient layout optimized for content flow</li>
+ <li>Light theme with monochromatic color harmony</li>
+ </ul>
+
+ <h2>Font Licensing</h2>
+ <p>All fonts used in this theme are properly licensed:</p>
+ <ul>
+ <li>oxygen: OFL License</li>
+ <li>Lato: OFL License</li>
+ <li>hack: MIT License</li>
+ </ul>
+
+ <h3>Final Thoughts</h3>
+ <p>Every element of this theme has been carefully designed to create a harmonious reading experience. The gradient layout ensures content is presented in an engaging way, while the color scheme provides the perfect backdrop for your words to shine.</p>
+
+ <p>Whether you're writing technical documentation, creative prose, or anything in between, this theme adapts to showcase your content beautifully.</p>
+ </div>
+</body>
+</html> \ No newline at end of file
diff --git a/extras/html/themes/cosmic_odyssey/handnotes.ttf b/extras/html/themes/cosmic_odyssey/handnotes.ttf
new file mode 100644
index 0000000..25e688b
--- /dev/null
+++ b/extras/html/themes/cosmic_odyssey/handnotes.ttf
Binary files differ
diff --git a/extras/html/themes/cosmic_odyssey/style.css b/extras/html/themes/cosmic_odyssey/style.css
new file mode 100644
index 0000000..b41cf80
--- /dev/null
+++ b/extras/html/themes/cosmic_odyssey/style.css
@@ -0,0 +1,166 @@
+/* Base styles */
+@font-face {
+ font-family: 'text';
+ src: url("./text.ttf") format("truetype");
+}
+
+@font-face {
+ font-family: 'heading';
+ src: url("./heading.ttf") format("truetype");
+}
+
+@font-face {
+ font-family: 'code';
+ src: url("./code.ttf") format("truetype");
+}
+
+@font-face {
+ font-family: 'handnotes';
+ src: url("./handnotes.ttf") format("truetype");
+}
+
+:root {
+ --color-primary: #7763f3;
+ --color-secondary: #3c25ca;
+ --color-accent: #bbb4e7;
+ --color-bg: #ececef;
+ --color-text: #191919;
+ --font-size-base: 17px;
+ --font-size-h1: 1.42em;
+ --font-size-h2: 1.27em;
+ --font-size-h3: 1.12em;
+ --line-height: 1.72;
+}
+
+* {
+ box-sizing: border-box;
+}
+
+html {
+ font-size: var(--font-size-base);
+ -webkit-font-smoothing: antialiased;
+ -moz-osx-font-smoothing: grayscale;
+}
+
+body {
+ font-family: text, sans-serif;
+ background-color: var(--color-bg);
+ color: var(--color-text);
+ line-height: var(--line-height);
+ margin: 0;
+ padding: 0;
+ overflow-wrap: break-word;
+}
+
+h1, h2, h3 {
+ font-family: heading, serif;
+ line-height: 1.2;
+ margin-top: 1em;
+ margin-bottom: 0.5em;
+}
+
+h1 {
+ font-size: var(--font-size-h1);
+ color: var(--color-primary);
+}
+
+h2 {
+ font-size: var(--font-size-h2);
+ color: var(--color-primary);
+}
+
+h3 {
+ font-size: var(--font-size-h3);
+ color: var(--color-secondary);
+}
+
+a {
+ font-family: code, monospace;
+ color: var(--color-secondary);
+ text-decoration: none;
+ transition: all 0.3s ease;
+}
+
+a:hover {
+ color: var(--color-accent);
+ text-decoration: underline;
+}
+
+.textlink {
+ font-family: text, sans-serif;
+}
+
+.quote {
+ font-family: handnotes, cursive;
+ border-left: 4px solid var(--color-accent);
+ padding: 1em 1.5em;
+ margin: 1.5em 0;
+ background-color: rgba(119, 99, 243, 0.07);
+ font-style: italic;
+}
+
+pre {
+ font-family: code, monospace;
+ background-color: rgba(25, 25, 25, 0.04);
+ border: 1px solid rgba(25, 25, 25, 0.13);
+ padding: 1em;
+ overflow-x: auto;
+ border-radius: 4px;
+ font-size: 0.9em;
+}
+
+code {
+ font-family: code, monospace;
+ background-color: rgba(25, 25, 25, 0.04);
+ padding: 0.2em 0.4em;
+ border-radius: 3px;
+ font-size: 0.9em;
+}
+
+ul, ol {
+ padding-left: 2em;
+ margin: 1em 0;
+}
+
+li {
+ margin: 0.5em 0;
+}
+
+img {
+ max-width: 100%;
+ height: auto;
+}
+
+hr {
+ border: none;
+ border-top: 1px solid rgba(25, 25, 25, 0.20);
+ margin: 2em 0;
+}
+
+
+/* Layout: gradient */
+
+body {
+ margin: 0;
+ padding: 0;
+ background: linear-gradient(180deg, rgba(119, 99, 243, 0.13) 0%, rgba(60, 37, 202, 0.13) 50%, rgba(187, 180, 231, 0.13) 100%);
+ min-height: 100vh;
+}
+
+.header {
+ text-align: center;
+ padding: 6em 2em;
+ background: rgba(255,255,255,0.1);
+ backdrop-filter: blur(10px);
+ margin-bottom: 4em;
+}
+
+h1, h2, h3, p, ul, pre, .quote {
+ max-width: 65ch;
+ margin: 2em auto;
+ padding: 2em;
+ background: rgba(255,255,255,0.95);
+ backdrop-filter: blur(10px);
+ border-radius: 20px;
+ box-shadow: 0 8px 32px rgba(0,0,0,0.1);
+}
diff --git a/extras/html/themes/cosmic_odyssey/text.ttf b/extras/html/themes/cosmic_odyssey/text.ttf
new file mode 100644
index 0000000..bb2e887
--- /dev/null
+++ b/extras/html/themes/cosmic_odyssey/text.ttf
Binary files differ
diff --git a/extras/html/themes/cosmic_odyssey/theme.conf b/extras/html/themes/cosmic_odyssey/theme.conf
new file mode 100644
index 0000000..1e2ca2e
--- /dev/null
+++ b/extras/html/themes/cosmic_odyssey/theme.conf
@@ -0,0 +1,8 @@
+declare -xr HTML_HEADER=./extras/html/header.html.part
+declare -xr HTML_FOOTER=./extras/html/footer.html.part
+declare -xr HTML_CSS_STYLE=$HTML_THEME_DIR/style.css
+declare -xr HTML_WEBFONT_HEADING=./extras/html/fonts/oxygen/oxygen-Bold.ttf
+declare -xr HTML_WEBFONT_TEXT=./extras/html/fonts/Lato/Lato-Regular.ttf
+declare -xr HTML_WEBFONT_CODE=./extras/html/fonts/hack/hack-Regular.ttf
+declare -xr HTML_WEBFONT_HANDNOTES=./extras/html/fonts/khand/khand.ttf
+declare -xr SOURCE_HIGHLIGHT_CSS=./extras/html/source-highlight-styles/mono.css
diff --git a/extras/html/themes/cozy_crystal/LICENSE b/extras/html/themes/cozy_crystal/LICENSE
new file mode 100644
index 0000000..73364d6
--- /dev/null
+++ b/extras/html/themes/cozy_crystal/LICENSE
@@ -0,0 +1,21 @@
+Theme: cozy_crystal
+Generated: 2025-06-22 21:38:55
+
+Layout: brutalist
+Color Scheme: complementary (Light)
+
+Font Licenses:
+==============
+Heading Font: zai-aeg-mignon-typewriter-1924
+License: Free
+Category: display
+
+Body Font: roboto-slab
+License: Apache
+Category: serif
+
+Code Font: hack
+License: MIT
+Category: monospace
+
+All fonts are free for personal use.
diff --git a/extras/html/themes/cozy_crystal/code.ttf b/extras/html/themes/cozy_crystal/code.ttf
new file mode 100644
index 0000000..7c8e65b
--- /dev/null
+++ b/extras/html/themes/cozy_crystal/code.ttf
Binary files differ
diff --git a/extras/html/themes/cozy_crystal/example.html b/extras/html/themes/cozy_crystal/example.html
new file mode 100644
index 0000000..93e8192
--- /dev/null
+++ b/extras/html/themes/cozy_crystal/example.html
@@ -0,0 +1,75 @@
+<!DOCTYPE html>
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
+<head>
+ <meta charset="UTF-8" />
+ <meta name="viewport" content="width=device-width, initial-scale=1.0" />
+ <title>Cozy Crystal - Gemtexter Theme</title>
+ <link rel="stylesheet" href="style.css" />
+</head>
+<body>
+ <div class="header">
+ <h1>Cozy Crystal</h1>
+ <p>A brutalist layout with complementary colors</p>
+ </div>
+
+ <div class="content">
+ <h1>Welcome to Cozy Crystal</h1>
+ <p>This theme features a carefully crafted brutalist layout with a light complementary color scheme. The typography combines display fonts for headings with serif for body text.</p>
+
+ <h2>Typography Showcase</h2>
+ <p>The roboto-slab font family provides excellent readability for body text, while zai-aeg-mignon-typewriter-1924 adds character to headings. Code blocks use hack for clarity.</p>
+
+ <h2>Color Palette</h2>
+ <p>Primary: <span style="color: #22ac18; font-weight: bold;">#22ac18</span> |
+ Secondary: <span style="color: #95279d; font-weight: bold;">#95279d</span> |
+ Accent: <span style="color: #30722b; font-weight: bold;">#30722b</span></p>
+
+ <h3>Interactive Elements</h3>
+ <p>Links like <a href="#">this example</a> and longer <a href="#" class="textlink">text links that demonstrate the theme's navigation style</a> use the secondary color.</p>
+
+ <div class="quote">
+ "Design is not just what it looks like and feels like. Design is how it works." — Steve Jobs
+ </div>
+
+ <h3>Code Examples</h3>
+ <p>Inline code like <code>theme.generate()</code> and larger blocks:</p>
+ <pre>// Theme configuration
+const theme = {
+ name: "cozy_crystal",
+ layout: "brutalist",
+ colors: {
+ primary: "#22ac18",
+ secondary: "#95279d",
+ accent: "#30722b"
+ },
+ fonts: {
+ heading: "zai-aeg-mignon-typewriter-1924",
+ body: "roboto-slab",
+ code: "hack"
+ }
+};</pre>
+
+ <h2>Content Structure</h2>
+ <ul>
+ <li>Clean, readable typography with 14px base font size</li>
+ <li>Heading scale ratio of 1.42x for visual hierarchy</li>
+ <li>Line height of 1.56 for comfortable reading</li>
+ <li>Brutalist layout optimized for content flow</li>
+ <li>Light theme with complementary color harmony</li>
+ </ul>
+
+ <h2>Font Licensing</h2>
+ <p>All fonts used in this theme are properly licensed:</p>
+ <ul>
+ <li>zai-aeg-mignon-typewriter-1924: Free License</li>
+ <li>roboto-slab: Apache License</li>
+ <li>hack: MIT License</li>
+ </ul>
+
+ <h3>Final Thoughts</h3>
+ <p>Every element of this theme has been carefully designed to create a harmonious reading experience. The brutalist layout ensures content is presented in an engaging way, while the color scheme provides the perfect backdrop for your words to shine.</p>
+
+ <p>Whether you're writing technical documentation, creative prose, or anything in between, this theme adapts to showcase your content beautifully.</p>
+ </div>
+</body>
+</html> \ No newline at end of file
diff --git a/extras/html/themes/cozy_crystal/handnotes.ttf b/extras/html/themes/cozy_crystal/handnotes.ttf
new file mode 100644
index 0000000..25e688b
--- /dev/null
+++ b/extras/html/themes/cozy_crystal/handnotes.ttf
Binary files differ
diff --git a/extras/html/themes/cozy_crystal/heading.ttf b/extras/html/themes/cozy_crystal/heading.ttf
new file mode 100644
index 0000000..375978c
--- /dev/null
+++ b/extras/html/themes/cozy_crystal/heading.ttf
Binary files differ
diff --git a/extras/html/themes/cozy_crystal/style.css b/extras/html/themes/cozy_crystal/style.css
new file mode 100644
index 0000000..a43e774
--- /dev/null
+++ b/extras/html/themes/cozy_crystal/style.css
@@ -0,0 +1,187 @@
+/* Base styles */
+@font-face {
+ font-family: 'text';
+ src: url("./text.ttf") format("truetype");
+}
+
+@font-face {
+ font-family: 'heading';
+ src: url("./heading.ttf") format("truetype");
+}
+
+@font-face {
+ font-family: 'code';
+ src: url("./code.ttf") format("truetype");
+}
+
+@font-face {
+ font-family: 'handnotes';
+ src: url("./handnotes.ttf") format("truetype");
+}
+
+:root {
+ --color-primary: #22ac18;
+ --color-secondary: #95279d;
+ --color-accent: #30722b;
+ --color-bg: #eff1ef;
+ --color-text: #1d1d1d;
+ --font-size-base: 14px;
+ --font-size-h1: 1.42em;
+ --font-size-h2: 1.27em;
+ --font-size-h3: 1.12em;
+ --line-height: 1.56;
+}
+
+* {
+ box-sizing: border-box;
+}
+
+html {
+ font-size: var(--font-size-base);
+ -webkit-font-smoothing: antialiased;
+ -moz-osx-font-smoothing: grayscale;
+}
+
+body {
+ font-family: text, sans-serif;
+ background-color: var(--color-bg);
+ color: var(--color-text);
+ line-height: var(--line-height);
+ margin: 0;
+ padding: 0;
+ overflow-wrap: break-word;
+}
+
+h1, h2, h3 {
+ font-family: heading, serif;
+ line-height: 1.2;
+ margin-top: 1em;
+ margin-bottom: 0.5em;
+}
+
+h1 {
+ font-size: var(--font-size-h1);
+ color: var(--color-primary);
+}
+
+h2 {
+ font-size: var(--font-size-h2);
+ color: var(--color-primary);
+}
+
+h3 {
+ font-size: var(--font-size-h3);
+ color: var(--color-secondary);
+}
+
+a {
+ font-family: code, monospace;
+ color: var(--color-secondary);
+ text-decoration: none;
+ transition: all 0.3s ease;
+}
+
+a:hover {
+ color: var(--color-accent);
+ text-decoration: underline;
+}
+
+.textlink {
+ font-family: text, sans-serif;
+}
+
+.quote {
+ font-family: handnotes, cursive;
+ border-left: 4px solid var(--color-accent);
+ padding: 1em 1.5em;
+ margin: 1.5em 0;
+ background-color: rgba(34, 172, 24, 0.07);
+ font-style: italic;
+}
+
+pre {
+ font-family: code, monospace;
+ background-color: rgba(29, 29, 29, 0.04);
+ border: 1px solid rgba(29, 29, 29, 0.13);
+ padding: 1em;
+ overflow-x: auto;
+ border-radius: 4px;
+ font-size: 0.9em;
+}
+
+code {
+ font-family: code, monospace;
+ background-color: rgba(29, 29, 29, 0.04);
+ padding: 0.2em 0.4em;
+ border-radius: 3px;
+ font-size: 0.9em;
+}
+
+ul, ol {
+ padding-left: 2em;
+ margin: 1em 0;
+}
+
+li {
+ margin: 0.5em 0;
+}
+
+img {
+ max-width: 100%;
+ height: auto;
+}
+
+hr {
+ border: none;
+ border-top: 1px solid rgba(29, 29, 29, 0.20);
+ margin: 2em 0;
+}
+
+
+/* Layout: brutalist */
+
+body {
+ background-color: #1d1d1d;
+ color: #eff1ef;
+ padding: 0;
+}
+
+.header {
+ background-color: var(--color-primary);
+ color: var(--color-bg);
+ padding: 4em 2em;
+ transform: skewY(-3deg);
+ margin-bottom: 4em;
+}
+
+.header * {
+ transform: skewY(3deg);
+}
+
+h1, h2, h3 {
+ background-color: var(--color-bg);
+ color: var(--color-text);
+ padding: 1em;
+ text-transform: uppercase;
+ letter-spacing: 0.2em;
+ margin: 0;
+}
+
+p, ul, pre, .quote {
+ background-color: var(--color-bg);
+ color: var(--color-text);
+ margin: 0;
+ padding: 2em;
+ border: 8px solid var(--color-primary);
+}
+
+a {
+ background-color: var(--color-secondary);
+ color: var(--color-bg);
+ padding: 0.3em 0.6em;
+ text-decoration: none;
+}
+
+a:hover {
+ background-color: var(--color-accent);
+}
diff --git a/extras/html/themes/cozy_crystal/theme.conf b/extras/html/themes/cozy_crystal/theme.conf
new file mode 100644
index 0000000..b620ed7
--- /dev/null
+++ b/extras/html/themes/cozy_crystal/theme.conf
@@ -0,0 +1,8 @@
+declare -xr HTML_HEADER=./extras/html/header.html.part
+declare -xr HTML_FOOTER=./extras/html/footer.html.part
+declare -xr HTML_CSS_STYLE=$HTML_THEME_DIR/style.css
+declare -xr HTML_WEBFONT_HEADING=./extras/html/fonts/zai-aeg-mignon-typewriter-1924/zai-aeg-mignon-typewriter-1924-Bold.ttf
+declare -xr HTML_WEBFONT_TEXT=./extras/html/fonts/roboto-slab/roboto-slab-Regular.ttf
+declare -xr HTML_WEBFONT_CODE=./extras/html/fonts/hack/hack-Regular.ttf
+declare -xr HTML_WEBFONT_HANDNOTES=./extras/html/fonts/khand/khand.ttf
+declare -xr SOURCE_HIGHLIGHT_CSS=./extras/html/source-highlight-styles/mono.css
diff --git a/extras/html/themes/cozy_wave/LICENSE b/extras/html/themes/cozy_wave/LICENSE
new file mode 100644
index 0000000..2f4b53f
--- /dev/null
+++ b/extras/html/themes/cozy_wave/LICENSE
@@ -0,0 +1,21 @@
+Theme: cozy_wave
+Generated: 2025-06-22 21:38:55
+
+Layout: newspaper
+Color Scheme: monochromatic (Dark)
+
+Font Licenses:
+==============
+Heading Font: zai-aeg-mignon-typewriter-1924
+License: Free
+Category: display
+
+Body Font: roboto-slab
+License: Apache
+Category: serif
+
+Code Font: hack
+License: MIT
+Category: monospace
+
+All fonts are free for personal use.
diff --git a/extras/html/themes/cozy_wave/code.ttf b/extras/html/themes/cozy_wave/code.ttf
new file mode 100644
index 0000000..7c8e65b
--- /dev/null
+++ b/extras/html/themes/cozy_wave/code.ttf
Binary files differ
diff --git a/extras/html/themes/cozy_wave/example.html b/extras/html/themes/cozy_wave/example.html
new file mode 100644
index 0000000..f62320f
--- /dev/null
+++ b/extras/html/themes/cozy_wave/example.html
@@ -0,0 +1,75 @@
+<!DOCTYPE html>
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
+<head>
+ <meta charset="UTF-8" />
+ <meta name="viewport" content="width=device-width, initial-scale=1.0" />
+ <title>Cozy Wave - Gemtexter Theme</title>
+ <link rel="stylesheet" href="style.css" />
+</head>
+<body>
+ <div class="header">
+ <h1>Cozy Wave</h1>
+ <p>A newspaper layout with monochromatic colors</p>
+ </div>
+
+ <div class="content">
+ <h1>Welcome to Cozy Wave</h1>
+ <p>This theme features a carefully crafted newspaper layout with a dark monochromatic color scheme. The typography combines display fonts for headings with serif for body text.</p>
+
+ <h2>Typography Showcase</h2>
+ <p>The roboto-slab font family provides excellent readability for body text, while zai-aeg-mignon-typewriter-1924 adds character to headings. Code blocks use hack for clarity.</p>
+
+ <h2>Color Palette</h2>
+ <p>Primary: <span style="color: #3559e1; font-weight: bold;">#3559e1</span> |
+ Secondary: <span style="color: #273f9b; font-weight: bold;">#273f9b</span> |
+ Accent: <span style="color: #8090ce; font-weight: bold;">#8090ce</span></p>
+
+ <h3>Interactive Elements</h3>
+ <p>Links like <a href="#">this example</a> and longer <a href="#" class="textlink">text links that demonstrate the theme's navigation style</a> use the secondary color.</p>
+
+ <div class="quote">
+ "Design is not just what it looks like and feels like. Design is how it works." — Steve Jobs
+ </div>
+
+ <h3>Code Examples</h3>
+ <p>Inline code like <code>theme.generate()</code> and larger blocks:</p>
+ <pre>// Theme configuration
+const theme = {
+ name: "cozy_wave",
+ layout: "newspaper",
+ colors: {
+ primary: "#3559e1",
+ secondary: "#273f9b",
+ accent: "#8090ce"
+ },
+ fonts: {
+ heading: "zai-aeg-mignon-typewriter-1924",
+ body: "roboto-slab",
+ code: "hack"
+ }
+};</pre>
+
+ <h2>Content Structure</h2>
+ <ul>
+ <li>Clean, readable typography with 16px base font size</li>
+ <li>Heading scale ratio of 1.42x for visual hierarchy</li>
+ <li>Line height of 1.51 for comfortable reading</li>
+ <li>Newspaper layout optimized for content flow</li>
+ <li>Dark theme with monochromatic color harmony</li>
+ </ul>
+
+ <h2>Font Licensing</h2>
+ <p>All fonts used in this theme are properly licensed:</p>
+ <ul>
+ <li>zai-aeg-mignon-typewriter-1924: Free License</li>
+ <li>roboto-slab: Apache License</li>
+ <li>hack: MIT License</li>
+ </ul>
+
+ <h3>Final Thoughts</h3>
+ <p>Every element of this theme has been carefully designed to create a harmonious reading experience. The newspaper layout ensures content is presented in an engaging way, while the color scheme provides the perfect backdrop for your words to shine.</p>
+
+ <p>Whether you're writing technical documentation, creative prose, or anything in between, this theme adapts to showcase your content beautifully.</p>
+ </div>
+</body>
+</html> \ No newline at end of file
diff --git a/extras/html/themes/cozy_wave/handnotes.ttf b/extras/html/themes/cozy_wave/handnotes.ttf
new file mode 100644
index 0000000..25e688b
--- /dev/null
+++ b/extras/html/themes/cozy_wave/handnotes.ttf
Binary files differ
diff --git a/extras/html/themes/cozy_wave/heading.ttf b/extras/html/themes/cozy_wave/heading.ttf
new file mode 100644
index 0000000..375978c
--- /dev/null
+++ b/extras/html/themes/cozy_wave/heading.ttf
Binary files differ
diff --git a/extras/html/themes/cozy_wave/style.css b/extras/html/themes/cozy_wave/style.css
new file mode 100644
index 0000000..25fe983
--- /dev/null
+++ b/extras/html/themes/cozy_wave/style.css
@@ -0,0 +1,187 @@
+/* Base styles */
+@font-face {
+ font-family: 'text';
+ src: url("./text.ttf") format("truetype");
+}
+
+@font-face {
+ font-family: 'heading';
+ src: url("./heading.ttf") format("truetype");
+}
+
+@font-face {
+ font-family: 'code';
+ src: url("./code.ttf") format("truetype");
+}
+
+@font-face {
+ font-family: 'handnotes';
+ src: url("./handnotes.ttf") format("truetype");
+}
+
+:root {
+ --color-primary: #3559e1;
+ --color-secondary: #273f9b;
+ --color-accent: #8090ce;
+ --color-bg: #191a1f;
+ --color-text: #dedede;
+ --font-size-base: 16px;
+ --font-size-h1: 1.42em;
+ --font-size-h2: 1.27em;
+ --font-size-h3: 1.12em;
+ --line-height: 1.51;
+}
+
+* {
+ box-sizing: border-box;
+}
+
+html {
+ font-size: var(--font-size-base);
+ -webkit-font-smoothing: antialiased;
+ -moz-osx-font-smoothing: grayscale;
+}
+
+body {
+ font-family: text, sans-serif;
+ background-color: var(--color-bg);
+ color: var(--color-text);
+ line-height: var(--line-height);
+ margin: 0;
+ padding: 0;
+ overflow-wrap: break-word;
+}
+
+h1, h2, h3 {
+ font-family: heading, serif;
+ line-height: 1.2;
+ margin-top: 1em;
+ margin-bottom: 0.5em;
+}
+
+h1 {
+ font-size: var(--font-size-h1);
+ color: var(--color-primary);
+}
+
+h2 {
+ font-size: var(--font-size-h2);
+ color: var(--color-primary);
+}
+
+h3 {
+ font-size: var(--font-size-h3);
+ color: var(--color-secondary);
+}
+
+a {
+ font-family: code, monospace;
+ color: var(--color-secondary);
+ text-decoration: none;
+ transition: all 0.3s ease;
+}
+
+a:hover {
+ color: var(--color-accent);
+ text-decoration: underline;
+}
+
+.textlink {
+ font-family: text, sans-serif;
+}
+
+.quote {
+ font-family: handnotes, cursive;
+ border-left: 4px solid var(--color-accent);
+ padding: 1em 1.5em;
+ margin: 1.5em 0;
+ background-color: rgba(53, 89, 225, 0.07);
+ font-style: italic;
+}
+
+pre {
+ font-family: code, monospace;
+ background-color: rgba(222, 222, 222, 0.04);
+ border: 1px solid rgba(222, 222, 222, 0.13);
+ padding: 1em;
+ overflow-x: auto;
+ border-radius: 4px;
+ font-size: 0.9em;
+}
+
+code {
+ font-family: code, monospace;
+ background-color: rgba(222, 222, 222, 0.04);
+ padding: 0.2em 0.4em;
+ border-radius: 3px;
+ font-size: 0.9em;
+}
+
+ul, ol {
+ padding-left: 2em;
+ margin: 1em 0;
+}
+
+li {
+ margin: 0.5em 0;
+}
+
+img {
+ max-width: 100%;
+ height: auto;
+}
+
+hr {
+ border: none;
+ border-top: 1px solid rgba(222, 222, 222, 0.20);
+ margin: 2em 0;
+}
+
+
+/* Layout: newspaper */
+
+body {
+ max-width: 1200px;
+ margin: 0 auto;
+ padding: 2em;
+ columns: 3;
+ column-gap: 2em;
+ column-rule: 1px solid var(--color-text);
+}
+
+.header {
+ column-span: all;
+ text-align: center;
+ border-top: 6px double var(--color-text);
+ border-bottom: 6px double var(--color-text);
+ padding: 2em 0;
+ margin-bottom: 3em;
+}
+
+.header h1 {
+ font-size: 4em;
+ margin: 0;
+ letter-spacing: 0.1em;
+}
+
+h1, h2 {
+ column-span: all;
+ text-align: center;
+ margin: 2em 0 1em 0;
+}
+
+h3 {
+ break-after: avoid;
+}
+
+p {
+ text-align: justify;
+ hyphens: auto;
+}
+
+.quote {
+ column-span: all;
+ text-align: center;
+ font-size: 1.5em;
+ margin: 2em 0;
+}
diff --git a/extras/html/themes/cozy_wave/theme.conf b/extras/html/themes/cozy_wave/theme.conf
new file mode 100644
index 0000000..b620ed7
--- /dev/null
+++ b/extras/html/themes/cozy_wave/theme.conf
@@ -0,0 +1,8 @@
+declare -xr HTML_HEADER=./extras/html/header.html.part
+declare -xr HTML_FOOTER=./extras/html/footer.html.part
+declare -xr HTML_CSS_STYLE=$HTML_THEME_DIR/style.css
+declare -xr HTML_WEBFONT_HEADING=./extras/html/fonts/zai-aeg-mignon-typewriter-1924/zai-aeg-mignon-typewriter-1924-Bold.ttf
+declare -xr HTML_WEBFONT_TEXT=./extras/html/fonts/roboto-slab/roboto-slab-Regular.ttf
+declare -xr HTML_WEBFONT_CODE=./extras/html/fonts/hack/hack-Regular.ttf
+declare -xr HTML_WEBFONT_HANDNOTES=./extras/html/fonts/khand/khand.ttf
+declare -xr SOURCE_HIGHLIGHT_CSS=./extras/html/source-highlight-styles/mono.css
diff --git a/extras/html/themes/create_simple_previews.sh b/extras/html/themes/create_simple_previews.sh
new file mode 100755
index 0000000..5e85384
--- /dev/null
+++ b/extras/html/themes/create_simple_previews.sh
@@ -0,0 +1,65 @@
+#!/bin/bash
+
+# Create simple preview images for themes using ImageMagick if available
+# Falls back to creating placeholder files if ImageMagick is not installed
+
+THEMES_DIR="/home/paul/git/gemtexter/extras/html/themes"
+SCREENSHOTS_DIR="$THEMES_DIR/screenshots"
+
+# Create screenshots directory if it doesn't exist
+mkdir -p "$SCREENSHOTS_DIR"
+
+# Check if ImageMagick is available
+if command -v convert &> /dev/null; then
+ echo "ImageMagick found, creating preview images..."
+
+ # Generate preview for each theme
+ for theme_dir in "$THEMES_DIR"/*; do
+ if [ -d "$theme_dir" ] && [ "$theme_dir" != "$SCREENSHOTS_DIR" ]; then
+ theme_name=$(basename "$theme_dir")
+
+ # Skip non-theme directories
+ if [[ "$theme_name" == "screenshots" ]] || [[ "$theme_name" == *".py" ]] || [[ "$theme_name" == *".sh" ]] || [[ "$theme_name" == *".html" ]]; then
+ continue
+ fi
+
+ echo "Creating preview for $theme_name..."
+
+ # Create a simple preview image with theme name
+ convert -size 400x300 \
+ -background '#f0f0f0' \
+ -fill '#333333' \
+ -gravity center \
+ -pointsize 24 \
+ -font Arial \
+ label:"$theme_name\n\nTheme Preview" \
+ "$SCREENSHOTS_DIR/${theme_name}.png"
+ fi
+ done
+
+ echo "Preview images created!"
+else
+ echo "ImageMagick not found. Creating placeholder files..."
+
+ # Create placeholder files
+ for theme_dir in "$THEMES_DIR"/*; do
+ if [ -d "$theme_dir" ] && [ "$theme_dir" != "$SCREENSHOTS_DIR" ]; then
+ theme_name=$(basename "$theme_dir")
+
+ # Skip non-theme directories
+ if [[ "$theme_name" == "screenshots" ]] || [[ "$theme_name" == *".py" ]] || [[ "$theme_name" == *".sh" ]] || [[ "$theme_name" == *".html" ]]; then
+ continue
+ fi
+
+ # Create an empty placeholder file
+ touch "$SCREENSHOTS_DIR/${theme_name}.png"
+ fi
+ done
+
+ echo "Placeholder files created. To generate actual previews, install ImageMagick:"
+ echo " sudo apt install imagemagick # Debian/Ubuntu"
+ echo " sudo dnf install ImageMagick # Fedora"
+ echo " brew install imagemagick # macOS"
+fi
+
+echo "Done! Preview files are in $SCREENSHOTS_DIR" \ No newline at end of file
diff --git a/extras/html/themes/create_theme_previews.py b/extras/html/themes/create_theme_previews.py
new file mode 100755
index 0000000..4a55033
--- /dev/null
+++ b/extras/html/themes/create_theme_previews.py
@@ -0,0 +1,292 @@
+#!/usr/bin/env python3
+
+import os
+import subprocess
+from pathlib import Path
+from PIL import Image, ImageDraw, ImageFont, ImageFilter
+import re
+import json
+
+def extract_theme_colors(css_file):
+ """Extract color scheme from CSS file"""
+ with open(css_file, 'r') as f:
+ css_content = f.read()
+
+ colors = {
+ 'primary': '#667eea',
+ 'secondary': '#764ba2',
+ 'accent': '#667eea',
+ 'background': '#ffffff',
+ 'text': '#333333'
+ }
+
+ # Extract CSS variables
+ patterns = {
+ 'primary': r'--color-primary:\s*([#\w]+);',
+ 'secondary': r'--color-secondary:\s*([#\w]+);',
+ 'accent': r'--color-accent:\s*([#\w]+);',
+ 'background': r'--color-bg:\s*([#\w]+);',
+ 'text': r'--color-text:\s*([#\w]+);'
+ }
+
+ for name, pattern in patterns.items():
+ match = re.search(pattern, css_content)
+ if match:
+ colors[name] = match.group(1)
+
+ # Extract layout
+ layout_match = re.search(r'/\* Layout: (\w+) \*/', css_content)
+ layout = layout_match.group(1) if layout_match else 'default'
+
+ return colors, layout
+
+def hex_to_rgb(hex_color):
+ """Convert hex color to RGB tuple"""
+ hex_color = hex_color.lstrip('#')
+ return tuple(int(hex_color[i:i+2], 16) for i in (0, 2, 4))
+
+def is_dark_theme(bg_color):
+ """Check if theme is dark based on background color"""
+ r, g, b = hex_to_rgb(bg_color)
+ luminance = (0.299 * r + 0.587 * g + 0.114 * b) / 255
+ return luminance < 0.5
+
+def create_realistic_preview(theme_name, colors, layout, output_path):
+ """Create a realistic preview of the theme"""
+ width, height = 400, 300
+
+ # Convert colors
+ bg_rgb = hex_to_rgb(colors['background'])
+ text_rgb = hex_to_rgb(colors['text'])
+ primary_rgb = hex_to_rgb(colors['primary'])
+ secondary_rgb = hex_to_rgb(colors['secondary'])
+ accent_rgb = hex_to_rgb(colors['accent'])
+ is_dark = is_dark_theme(colors['background'])
+
+ # Create base image
+ img = Image.new('RGB', (width, height), color=bg_rgb)
+ draw = ImageDraw.Draw(img)
+
+ # Try to load better fonts
+ font_paths = [
+ "/usr/share/fonts/truetype/liberation/LiberationSans-Bold.ttf",
+ "/usr/share/fonts/truetype/dejavu/DejaVuSans-Bold.ttf",
+ "/System/Library/Fonts/Helvetica.ttc",
+ "C:\\Windows\\Fonts\\arial.ttf"
+ ]
+
+ title_font = None
+ body_font = None
+ small_font = None
+
+ for font_path in font_paths:
+ if os.path.exists(font_path):
+ try:
+ title_font = ImageFont.truetype(font_path, 22)
+ body_font = ImageFont.truetype(font_path, 13)
+ small_font = ImageFont.truetype(font_path, 11)
+ break
+ except:
+ continue
+
+ if not title_font:
+ title_font = ImageFont.load_default()
+ body_font = ImageFont.load_default()
+ small_font = ImageFont.load_default()
+
+ # Layout-specific rendering
+ if layout == 'hero':
+ # Hero layout with gradient
+ for y in range(120):
+ factor = y / 120
+ r = int(primary_rgb[0] * (1 - factor) + bg_rgb[0] * factor)
+ g = int(primary_rgb[1] * (1 - factor) + bg_rgb[1] * factor)
+ b = int(primary_rgb[2] * (1 - factor) + bg_rgb[2] * factor)
+ draw.rectangle([(0, y), (width, y+1)], fill=(r, g, b))
+
+ # Title on gradient
+ title_color = bg_rgb if not is_dark else (255, 255, 255)
+ draw.text((20, 40), theme_name.replace('_', ' ').title(),
+ fill=title_color, font=title_font)
+ content_start = 130
+
+ elif layout == 'sidebar':
+ # Sidebar layout
+ draw.rectangle([(0, 0), (100, height)], fill=primary_rgb)
+ draw.text((10, 20), "MENU", fill=bg_rgb, font=small_font)
+ draw.line([(10, 40), (90, 40)], fill=bg_rgb, width=1)
+ draw.text((10, 50), "Home", fill=bg_rgb, font=small_font)
+ draw.text((10, 70), "About", fill=bg_rgb, font=small_font)
+ draw.text((10, 90), "Blog", fill=bg_rgb, font=small_font)
+
+ # Main content area
+ draw.text((120, 20), theme_name.replace('_', ' ').title(),
+ fill=primary_rgb, font=title_font)
+ content_start = 60
+ content_x = 120
+
+ elif layout == 'card':
+ # Card layout
+ margin = 20
+ # Main card
+ draw.rectangle([(margin, margin), (width-margin, height-margin)],
+ fill=bg_rgb, outline=None)
+ # Shadow effect
+ shadow = Image.new('RGB', (width, height), bg_rgb)
+ shadow_draw = ImageDraw.Draw(shadow)
+ shadow_draw.rectangle([(margin+3, margin+3), (width-margin+3, height-margin+3)],
+ fill=(200, 200, 200) if not is_dark else (50, 50, 50))
+ shadow = shadow.filter(ImageFilter.GaussianBlur(radius=3))
+ img = Image.alpha_composite(img.convert('RGBA'), shadow.convert('RGBA')).convert('RGB')
+ draw = ImageDraw.Draw(img)
+ draw.rectangle([(margin, margin), (width-margin, height-margin)],
+ fill=bg_rgb, outline=primary_rgb, width=2)
+
+ draw.text((margin+15, margin+15), theme_name.replace('_', ' ').title(),
+ fill=primary_rgb, font=title_font)
+ content_start = margin + 55
+ content_x = margin + 15
+
+ elif layout == 'terminal':
+ # Terminal layout
+ draw.rectangle([(0, 0), (width, height)], fill=(0, 0, 0))
+ draw.rectangle([(0, 0), (width, 25)], fill=(40, 40, 40))
+ # Window controls
+ draw.ellipse([(10, 8), (18, 16)], fill=(255, 95, 86))
+ draw.ellipse([(25, 8), (33, 16)], fill=(255, 189, 46))
+ draw.ellipse([(40, 8), (48, 16)], fill=(39, 201, 63))
+
+ # Terminal text
+ draw.text((10, 30), "$ theme --preview " + theme_name,
+ fill=(0, 255, 0), font=body_font)
+ draw.text((10, 50), "> Loading theme...", fill=(0, 255, 0), font=small_font)
+ content_start = 80
+ content_x = 10
+ text_rgb = (0, 255, 0)
+
+ elif layout == 'brutalist':
+ # Brutalist layout
+ draw.rectangle([(0, 0), (width, 60)], fill=primary_rgb)
+ draw.polygon([(0, 60), (width, 60), (width, 80), (0, 100)], fill=primary_rgb)
+ draw.text((20, 15), theme_name.replace('_', ' ').upper(),
+ fill=bg_rgb, font=title_font)
+ content_start = 110
+
+ elif layout == 'magazine':
+ # Magazine layout - multi-column
+ draw.line([(width//3, 60), (width//3, height-20)], fill=text_rgb, width=1)
+ draw.line([(2*width//3, 60), (2*width//3, height-20)], fill=text_rgb, width=1)
+ draw.text((20, 15), theme_name.replace('_', ' ').title(),
+ fill=primary_rgb, font=title_font)
+ content_start = 60
+
+ else:
+ # Default layout
+ draw.text((20, 20), theme_name.replace('_', ' ').title(),
+ fill=primary_rgb, font=title_font)
+ content_start = 60
+
+ # Common content elements
+ if layout not in ['terminal', 'sidebar', 'card']:
+ content_x = 20
+
+ if layout != 'terminal':
+ # Heading
+ draw.text((content_x, content_start), "Modern Design",
+ fill=secondary_rgb, font=body_font)
+
+ # Paragraph lines
+ y = content_start + 25
+ line_height = 12
+ paragraph_lines = [
+ "This theme features beautiful typography",
+ "and a carefully crafted color palette.",
+ "Perfect for blogs and documentation."
+ ]
+
+ for line in paragraph_lines:
+ if y < height - 60:
+ draw.text((content_x, y), line, fill=text_rgb, font=small_font)
+ y += line_height
+
+ # Link
+ if y < height - 40:
+ draw.text((content_x, y + 10), "→ Learn more",
+ fill=secondary_rgb, font=body_font)
+
+ # Button or accent element
+ if layout in ['hero', 'card', 'gradient'] and y < height - 50:
+ button_y = height - 50
+ draw.rectangle([(content_x, button_y), (content_x + 80, button_y + 30)],
+ fill=accent_rgb, outline=None)
+ button_text_color = bg_rgb if is_dark_theme(colors['accent']) else (255, 255, 255)
+ draw.text((content_x + 15, button_y + 8), "Preview",
+ fill=button_text_color, font=body_font)
+
+ # Add theme info
+ info_y = height - 20
+ theme_type = "Dark" if is_dark else "Light"
+ info_color = tuple(int(c * 0.6) for c in text_rgb) if not is_dark else tuple(int(c * 0.8) for c in text_rgb)
+ draw.text((10, info_y), f"{theme_type} • {layout}", fill=info_color, font=small_font)
+
+ # Save image
+ img.save(output_path, quality=95, optimize=True)
+
+def generate_fallback_preview(theme_name, output_path):
+ """Generate a simple fallback preview"""
+ width, height = 400, 300
+ img = Image.new('RGB', (width, height), color=(240, 240, 240))
+ draw = ImageDraw.Draw(img)
+
+ # Simple text
+ try:
+ font = ImageFont.truetype("/usr/share/fonts/truetype/liberation/LiberationSans-Bold.ttf", 24)
+ except:
+ font = ImageFont.load_default()
+
+ draw.text((width//2 - 100, height//2 - 20), theme_name.replace('_', ' ').title(),
+ fill=(100, 100, 100), font=font)
+ draw.text((width//2 - 50, height//2 + 10), "Theme Preview",
+ fill=(150, 150, 150), font=font)
+
+ img.save(output_path, quality=85)
+
+def main():
+ themes_dir = Path("/home/paul/git/gemtexter/extras/html/themes")
+ screenshots_dir = themes_dir / "screenshots"
+ screenshots_dir.mkdir(exist_ok=True)
+
+ # Get all theme directories
+ theme_dirs = [d for d in themes_dir.iterdir() if d.is_dir() and d.name not in ['screenshots', '.git']]
+ valid_themes = [d for d in theme_dirs if (d / "style.css").exists()]
+
+ print(f"Creating realistic previews for {len(valid_themes)} themes...")
+
+ success_count = 0
+ for i, theme_dir in enumerate(valid_themes):
+ theme_name = theme_dir.name
+ css_file = theme_dir / "style.css"
+ output_path = screenshots_dir / f"{theme_name}.png"
+
+ try:
+ # Extract theme information
+ colors, layout = extract_theme_colors(css_file)
+
+ # Create preview
+ create_realistic_preview(theme_name, colors, layout, output_path)
+ success_count += 1
+ print(f"✓ [{i+1}/{len(valid_themes)}] {theme_name}")
+
+ except Exception as e:
+ print(f"✗ [{i+1}/{len(valid_themes)}] {theme_name}: {e}")
+ # Generate fallback
+ try:
+ generate_fallback_preview(theme_name, output_path)
+ except:
+ pass
+
+ print(f"\nSuccessfully created {success_count} theme previews!")
+ print(f"Preview images saved to: {screenshots_dir}")
+
+if __name__ == "__main__":
+ main() \ No newline at end of file
diff --git a/extras/html/themes/crisp_oasis/LICENSE b/extras/html/themes/crisp_oasis/LICENSE
new file mode 100644
index 0000000..e2f7b17
--- /dev/null
+++ b/extras/html/themes/crisp_oasis/LICENSE
@@ -0,0 +1,21 @@
+Theme: crisp_oasis
+Generated: 2025-06-22 21:38:55
+
+Layout: book
+Color Scheme: analogous (Dark)
+
+Font Licenses:
+==============
+Heading Font: Abril_Fatface
+License: OFL
+Category: display
+
+Body Font: Lato
+License: OFL
+Category: sans-serif
+
+Code Font: consola-mono
+License: OFL
+Category: monospace
+
+All fonts are free for personal use.
diff --git a/extras/html/themes/crisp_oasis/code.ttf b/extras/html/themes/crisp_oasis/code.ttf
new file mode 100644
index 0000000..78ca9da
--- /dev/null
+++ b/extras/html/themes/crisp_oasis/code.ttf
Binary files differ
diff --git a/extras/html/themes/crisp_oasis/example.html b/extras/html/themes/crisp_oasis/example.html
new file mode 100644
index 0000000..014f25c
--- /dev/null
+++ b/extras/html/themes/crisp_oasis/example.html
@@ -0,0 +1,75 @@
+<!DOCTYPE html>
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
+<head>
+ <meta charset="UTF-8" />
+ <meta name="viewport" content="width=device-width, initial-scale=1.0" />
+ <title>Crisp Oasis - Gemtexter Theme</title>
+ <link rel="stylesheet" href="style.css" />
+</head>
+<body>
+ <div class="header">
+ <h1>Crisp Oasis</h1>
+ <p>A book layout with analogous colors</p>
+ </div>
+
+ <div class="content">
+ <h1>Welcome to Crisp Oasis</h1>
+ <p>This theme features a carefully crafted book layout with a dark analogous color scheme. The typography combines display fonts for headings with sans-serif for body text.</p>
+
+ <h2>Typography Showcase</h2>
+ <p>The Lato font family provides excellent readability for body text, while Abril Fatface adds character to headings. Code blocks use consola-mono for clarity.</p>
+
+ <h2>Color Palette</h2>
+ <p>Primary: <span style="color: #9f41a4; font-weight: bold;">#9f41a4</span> |
+ Secondary: <span style="color: #9f4679; font-weight: bold;">#9f4679</span> |
+ Accent: <span style="color: #643b93; font-weight: bold;">#643b93</span></p>
+
+ <h3>Interactive Elements</h3>
+ <p>Links like <a href="#">this example</a> and longer <a href="#" class="textlink">text links that demonstrate the theme's navigation style</a> use the secondary color.</p>
+
+ <div class="quote">
+ "Design is not just what it looks like and feels like. Design is how it works." — Steve Jobs
+ </div>
+
+ <h3>Code Examples</h3>
+ <p>Inline code like <code>theme.generate()</code> and larger blocks:</p>
+ <pre>// Theme configuration
+const theme = {
+ name: "crisp_oasis",
+ layout: "book",
+ colors: {
+ primary: "#9f41a4",
+ secondary: "#9f4679",
+ accent: "#643b93"
+ },
+ fonts: {
+ heading: "Abril_Fatface",
+ body: "Lato",
+ code: "consola-mono"
+ }
+};</pre>
+
+ <h2>Content Structure</h2>
+ <ul>
+ <li>Clean, readable typography with 15px base font size</li>
+ <li>Heading scale ratio of 4.24x for visual hierarchy</li>
+ <li>Line height of 1.49 for comfortable reading</li>
+ <li>Book layout optimized for content flow</li>
+ <li>Dark theme with analogous color harmony</li>
+ </ul>
+
+ <h2>Font Licensing</h2>
+ <p>All fonts used in this theme are properly licensed:</p>
+ <ul>
+ <li>Abril_Fatface: OFL License</li>
+ <li>Lato: OFL License</li>
+ <li>consola-mono: OFL License</li>
+ </ul>
+
+ <h3>Final Thoughts</h3>
+ <p>Every element of this theme has been carefully designed to create a harmonious reading experience. The book layout ensures content is presented in an engaging way, while the color scheme provides the perfect backdrop for your words to shine.</p>
+
+ <p>Whether you're writing technical documentation, creative prose, or anything in between, this theme adapts to showcase your content beautifully.</p>
+ </div>
+</body>
+</html> \ No newline at end of file
diff --git a/extras/html/themes/crisp_oasis/handnotes.ttf b/extras/html/themes/crisp_oasis/handnotes.ttf
new file mode 100644
index 0000000..25e688b
--- /dev/null
+++ b/extras/html/themes/crisp_oasis/handnotes.ttf
Binary files differ
diff --git a/extras/html/themes/crisp_oasis/heading.ttf b/extras/html/themes/crisp_oasis/heading.ttf
new file mode 100644
index 0000000..a291711
--- /dev/null
+++ b/extras/html/themes/crisp_oasis/heading.ttf
Binary files differ
diff --git a/extras/html/themes/crisp_oasis/style.css b/extras/html/themes/crisp_oasis/style.css
new file mode 100644
index 0000000..42af1cc
--- /dev/null
+++ b/extras/html/themes/crisp_oasis/style.css
@@ -0,0 +1,196 @@
+/* Base styles */
+@font-face {
+ font-family: 'text';
+ src: url("./text.ttf") format("truetype");
+}
+
+@font-face {
+ font-family: 'heading';
+ src: url("./heading.ttf") format("truetype");
+}
+
+@font-face {
+ font-family: 'code';
+ src: url("./code.ttf") format("truetype");
+}
+
+@font-face {
+ font-family: 'handnotes';
+ src: url("./handnotes.ttf") format("truetype");
+}
+
+:root {
+ --color-primary: #9f41a4;
+ --color-secondary: #9f4679;
+ --color-accent: #643b93;
+ --color-bg: #171317;
+ --color-text: #ececec;
+ --font-size-base: 15px;
+ --font-size-h1: 4.24em;
+ --font-size-h2: 2.62em;
+ --font-size-h3: 1.62em;
+ --line-height: 1.49;
+}
+
+* {
+ box-sizing: border-box;
+}
+
+html {
+ font-size: var(--font-size-base);
+ -webkit-font-smoothing: antialiased;
+ -moz-osx-font-smoothing: grayscale;
+}
+
+body {
+ font-family: text, sans-serif;
+ background-color: var(--color-bg);
+ color: var(--color-text);
+ line-height: var(--line-height);
+ margin: 0;
+ padding: 0;
+ overflow-wrap: break-word;
+}
+
+h1, h2, h3 {
+ font-family: heading, serif;
+ line-height: 1.2;
+ margin-top: 1em;
+ margin-bottom: 0.5em;
+}
+
+h1 {
+ font-size: var(--font-size-h1);
+ color: var(--color-primary);
+}
+
+h2 {
+ font-size: var(--font-size-h2);
+ color: var(--color-primary);
+}
+
+h3 {
+ font-size: var(--font-size-h3);
+ color: var(--color-secondary);
+}
+
+a {
+ font-family: code, monospace;
+ color: var(--color-secondary);
+ text-decoration: none;
+ transition: all 0.3s ease;
+}
+
+a:hover {
+ color: var(--color-accent);
+ text-decoration: underline;
+}
+
+.textlink {
+ font-family: text, sans-serif;
+}
+
+.quote {
+ font-family: handnotes, cursive;
+ border-left: 4px solid var(--color-accent);
+ padding: 1em 1.5em;
+ margin: 1.5em 0;
+ background-color: rgba(159, 65, 164, 0.07);
+ font-style: italic;
+}
+
+pre {
+ font-family: code, monospace;
+ background-color: rgba(236, 236, 236, 0.04);
+ border: 1px solid rgba(236, 236, 236, 0.13);
+ padding: 1em;
+ overflow-x: auto;
+ border-radius: 4px;
+ font-size: 0.9em;
+}
+
+code {
+ font-family: code, monospace;
+ background-color: rgba(236, 236, 236, 0.04);
+ padding: 0.2em 0.4em;
+ border-radius: 3px;
+ font-size: 0.9em;
+}
+
+ul, ol {
+ padding-left: 2em;
+ margin: 1em 0;
+}
+
+li {
+ margin: 0.5em 0;
+}
+
+img {
+ max-width: 100%;
+ height: auto;
+}
+
+hr {
+ border: none;
+ border-top: 1px solid rgba(236, 236, 236, 0.20);
+ margin: 2em 0;
+}
+
+
+/* Layout: book */
+
+body {
+ max-width: 40em;
+ margin: 4em auto;
+ padding: 2em;
+ line-height: 1.8;
+ text-align: justify;
+ hyphens: auto;
+}
+
+.header {
+ text-align: center;
+ margin-bottom: 6em;
+ page-break-after: always;
+}
+
+.header h1 {
+ font-size: 3em;
+ margin-bottom: 0.5em;
+}
+
+h1 {
+ text-align: center;
+ margin: 3em 0 2em 0;
+ page-break-before: always;
+}
+
+h2 {
+ margin-top: 2em;
+ text-align: left;
+}
+
+p {
+ text-indent: 1.5em;
+ margin: 0;
+}
+
+p:first-of-type {
+ text-indent: 0;
+}
+
+p:first-of-type::first-letter {
+ font-size: 4em;
+ line-height: 1;
+ float: left;
+ margin: 0 0.1em 0 0;
+ font-family: heading, serif;
+ color: var(--color-primary);
+}
+
+.quote {
+ margin: 2em 2em;
+ text-align: center;
+ font-style: italic;
+}
diff --git a/extras/html/themes/crisp_oasis/text.ttf b/extras/html/themes/crisp_oasis/text.ttf
new file mode 100644
index 0000000..bb2e887
--- /dev/null
+++ b/extras/html/themes/crisp_oasis/text.ttf
Binary files differ
diff --git a/extras/html/themes/crisp_oasis/theme.conf b/extras/html/themes/crisp_oasis/theme.conf
new file mode 100644
index 0000000..f738703
--- /dev/null
+++ b/extras/html/themes/crisp_oasis/theme.conf
@@ -0,0 +1,8 @@
+declare -xr HTML_HEADER=./extras/html/header.html.part
+declare -xr HTML_FOOTER=./extras/html/footer.html.part
+declare -xr HTML_CSS_STYLE=$HTML_THEME_DIR/style.css
+declare -xr HTML_WEBFONT_HEADING=./extras/html/fonts/Abril_Fatface/Abril_Fatface-Bold.ttf
+declare -xr HTML_WEBFONT_TEXT=./extras/html/fonts/Lato/Lato-Regular.ttf
+declare -xr HTML_WEBFONT_CODE=./extras/html/fonts/consola-mono/consola-mono-Regular.ttf
+declare -xr HTML_WEBFONT_HANDNOTES=./extras/html/fonts/khand/khand.ttf
+declare -xr SOURCE_HIGHLIGHT_CSS=./extras/html/source-highlight-styles/mono.css
diff --git a/extras/html/themes/deep_crystal/LICENSE b/extras/html/themes/deep_crystal/LICENSE
new file mode 100644
index 0000000..55f3c6d
--- /dev/null
+++ b/extras/html/themes/deep_crystal/LICENSE
@@ -0,0 +1,21 @@
+Theme: deep_crystal
+Generated: 2025-06-22 21:38:55
+
+Layout: asymmetric
+Color Scheme: analogous (Dark)
+
+Font Licenses:
+==============
+Heading Font: Abril_Fatface
+License: OFL
+Category: display
+
+Body Font: Lato
+License: OFL
+Category: sans-serif
+
+Code Font: consola-mono
+License: OFL
+Category: monospace
+
+All fonts are free for personal use.
diff --git a/extras/html/themes/deep_crystal/code.ttf b/extras/html/themes/deep_crystal/code.ttf
new file mode 100644
index 0000000..78ca9da
--- /dev/null
+++ b/extras/html/themes/deep_crystal/code.ttf
Binary files differ
diff --git a/extras/html/themes/deep_crystal/example.html b/extras/html/themes/deep_crystal/example.html
new file mode 100644
index 0000000..612f833
--- /dev/null
+++ b/extras/html/themes/deep_crystal/example.html
@@ -0,0 +1,75 @@
+<!DOCTYPE html>
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
+<head>
+ <meta charset="UTF-8" />
+ <meta name="viewport" content="width=device-width, initial-scale=1.0" />
+ <title>Deep Crystal - Gemtexter Theme</title>
+ <link rel="stylesheet" href="style.css" />
+</head>
+<body>
+ <div class="header">
+ <h1>Deep Crystal</h1>
+ <p>A asymmetric layout with analogous colors</p>
+ </div>
+
+ <div class="content">
+ <h1>Welcome to Deep Crystal</h1>
+ <p>This theme features a carefully crafted asymmetric layout with a dark analogous color scheme. The typography combines display fonts for headings with sans-serif for body text.</p>
+
+ <h2>Typography Showcase</h2>
+ <p>The Lato font family provides excellent readability for body text, while Abril Fatface adds character to headings. Code blocks use consola-mono for clarity.</p>
+
+ <h2>Color Palette</h2>
+ <p>Primary: <span style="color: #ce7cd7; font-weight: bold;">#ce7cd7</span> |
+ Secondary: <span style="color: #d281b3; font-weight: bold;">#d281b3</span> |
+ Accent: <span style="color: #9162cf; font-weight: bold;">#9162cf</span></p>
+
+ <h3>Interactive Elements</h3>
+ <p>Links like <a href="#">this example</a> and longer <a href="#" class="textlink">text links that demonstrate the theme's navigation style</a> use the secondary color.</p>
+
+ <div class="quote">
+ "Design is not just what it looks like and feels like. Design is how it works." — Steve Jobs
+ </div>
+
+ <h3>Code Examples</h3>
+ <p>Inline code like <code>theme.generate()</code> and larger blocks:</p>
+ <pre>// Theme configuration
+const theme = {
+ name: "deep_crystal",
+ layout: "asymmetric",
+ colors: {
+ primary: "#ce7cd7",
+ secondary: "#d281b3",
+ accent: "#9162cf"
+ },
+ fonts: {
+ heading: "Abril_Fatface",
+ body: "Lato",
+ code: "consola-mono"
+ }
+};</pre>
+
+ <h2>Content Structure</h2>
+ <ul>
+ <li>Clean, readable typography with 14px base font size</li>
+ <li>Heading scale ratio of 2.83x for visual hierarchy</li>
+ <li>Line height of 1.41 for comfortable reading</li>
+ <li>Asymmetric layout optimized for content flow</li>
+ <li>Dark theme with analogous color harmony</li>
+ </ul>
+
+ <h2>Font Licensing</h2>
+ <p>All fonts used in this theme are properly licensed:</p>
+ <ul>
+ <li>Abril_Fatface: OFL License</li>
+ <li>Lato: OFL License</li>
+ <li>consola-mono: OFL License</li>
+ </ul>
+
+ <h3>Final Thoughts</h3>
+ <p>Every element of this theme has been carefully designed to create a harmonious reading experience. The asymmetric layout ensures content is presented in an engaging way, while the color scheme provides the perfect backdrop for your words to shine.</p>
+
+ <p>Whether you're writing technical documentation, creative prose, or anything in between, this theme adapts to showcase your content beautifully.</p>
+ </div>
+</body>
+</html> \ No newline at end of file
diff --git a/extras/html/themes/deep_crystal/handnotes.ttf b/extras/html/themes/deep_crystal/handnotes.ttf
new file mode 100644
index 0000000..25e688b
--- /dev/null
+++ b/extras/html/themes/deep_crystal/handnotes.ttf
Binary files differ
diff --git a/extras/html/themes/deep_crystal/heading.ttf b/extras/html/themes/deep_crystal/heading.ttf
new file mode 100644
index 0000000..a291711
--- /dev/null
+++ b/extras/html/themes/deep_crystal/heading.ttf
Binary files differ
diff --git a/extras/html/themes/deep_crystal/style.css b/extras/html/themes/deep_crystal/style.css
new file mode 100644
index 0000000..e93f7a5
--- /dev/null
+++ b/extras/html/themes/deep_crystal/style.css
@@ -0,0 +1,181 @@
+/* Base styles */
+@font-face {
+ font-family: 'text';
+ src: url("./text.ttf") format("truetype");
+}
+
+@font-face {
+ font-family: 'heading';
+ src: url("./heading.ttf") format("truetype");
+}
+
+@font-face {
+ font-family: 'code';
+ src: url("./code.ttf") format("truetype");
+}
+
+@font-face {
+ font-family: 'handnotes';
+ src: url("./handnotes.ttf") format("truetype");
+}
+
+:root {
+ --color-primary: #ce7cd7;
+ --color-secondary: #d281b3;
+ --color-accent: #9162cf;
+ --color-bg: #1c171c;
+ --color-text: #e0e0e0;
+ --font-size-base: 14px;
+ --font-size-h1: 2.83em;
+ --font-size-h2: 2.0em;
+ --font-size-h3: 1.41em;
+ --line-height: 1.41;
+}
+
+* {
+ box-sizing: border-box;
+}
+
+html {
+ font-size: var(--font-size-base);
+ -webkit-font-smoothing: antialiased;
+ -moz-osx-font-smoothing: grayscale;
+}
+
+body {
+ font-family: text, sans-serif;
+ background-color: var(--color-bg);
+ color: var(--color-text);
+ line-height: var(--line-height);
+ margin: 0;
+ padding: 0;
+ overflow-wrap: break-word;
+}
+
+h1, h2, h3 {
+ font-family: heading, serif;
+ line-height: 1.2;
+ margin-top: 1em;
+ margin-bottom: 0.5em;
+}
+
+h1 {
+ font-size: var(--font-size-h1);
+ color: var(--color-primary);
+}
+
+h2 {
+ font-size: var(--font-size-h2);
+ color: var(--color-primary);
+}
+
+h3 {
+ font-size: var(--font-size-h3);
+ color: var(--color-secondary);
+}
+
+a {
+ font-family: code, monospace;
+ color: var(--color-secondary);
+ text-decoration: none;
+ transition: all 0.3s ease;
+}
+
+a:hover {
+ color: var(--color-accent);
+ text-decoration: underline;
+}
+
+.textlink {
+ font-family: text, sans-serif;
+}
+
+.quote {
+ font-family: handnotes, cursive;
+ border-left: 4px solid var(--color-accent);
+ padding: 1em 1.5em;
+ margin: 1.5em 0;
+ background-color: rgba(206, 124, 215, 0.07);
+ font-style: italic;
+}
+
+pre {
+ font-family: code, monospace;
+ background-color: rgba(224, 224, 224, 0.04);
+ border: 1px solid rgba(224, 224, 224, 0.13);
+ padding: 1em;
+ overflow-x: auto;
+ border-radius: 4px;
+ font-size: 0.9em;
+}
+
+code {
+ font-family: code, monospace;
+ background-color: rgba(224, 224, 224, 0.04);
+ padding: 0.2em 0.4em;
+ border-radius: 3px;
+ font-size: 0.9em;
+}
+
+ul, ol {
+ padding-left: 2em;
+ margin: 1em 0;
+}
+
+li {
+ margin: 0.5em 0;
+}
+
+img {
+ max-width: 100%;
+ height: auto;
+}
+
+hr {
+ border: none;
+ border-top: 1px solid rgba(224, 224, 224, 0.20);
+ margin: 2em 0;
+}
+
+
+/* Layout: asymmetric */
+
+body {
+ max-width: 1200px;
+ margin: 0 auto;
+ padding: 2em;
+}
+
+.header {
+ margin-left: 20%;
+ margin-bottom: 4em;
+}
+
+h1 {
+ margin-left: -5%;
+ font-size: calc(var(--font-size-h1) * 1.2);
+}
+
+h2 {
+ margin-left: 10%;
+}
+
+h3 {
+ margin-left: 25%;
+}
+
+p:nth-child(odd) {
+ margin-left: 5%;
+ margin-right: 20%;
+}
+
+p:nth-child(even) {
+ margin-left: 20%;
+ margin-right: 5%;
+}
+
+.quote {
+ margin-left: 15%;
+ margin-right: 15%;
+ text-align: center;
+}
diff --git a/extras/html/themes/deep_crystal/text.ttf b/extras/html/themes/deep_crystal/text.ttf
new file mode 100644
index 0000000..bb2e887
--- /dev/null
+++ b/extras/html/themes/deep_crystal/text.ttf
Binary files differ
diff --git a/extras/html/themes/deep_crystal/theme.conf b/extras/html/themes/deep_crystal/theme.conf
new file mode 100644
index 0000000..f738703
--- /dev/null
+++ b/extras/html/themes/deep_crystal/theme.conf
@@ -0,0 +1,8 @@
+declare -xr HTML_HEADER=./extras/html/header.html.part
+declare -xr HTML_FOOTER=./extras/html/footer.html.part
+declare -xr HTML_CSS_STYLE=$HTML_THEME_DIR/style.css
+declare -xr HTML_WEBFONT_HEADING=./extras/html/fonts/Abril_Fatface/Abril_Fatface-Bold.ttf
+declare -xr HTML_WEBFONT_TEXT=./extras/html/fonts/Lato/Lato-Regular.ttf
+declare -xr HTML_WEBFONT_CODE=./extras/html/fonts/consola-mono/consola-mono-Regular.ttf
+declare -xr HTML_WEBFONT_HANDNOTES=./extras/html/fonts/khand/khand.ttf
+declare -xr SOURCE_HIGHLIGHT_CSS=./extras/html/source-highlight-styles/mono.css
diff --git a/extras/html/themes/deep_sky/LICENSE b/extras/html/themes/deep_sky/LICENSE
new file mode 100644
index 0000000..e3f36f2
--- /dev/null
+++ b/extras/html/themes/deep_sky/LICENSE
@@ -0,0 +1,21 @@
+Theme: deep_sky
+Generated: 2025-06-22 21:38:55
+
+Layout: artistic
+Color Scheme: analogous (Light)
+
+Font Licenses:
+==============
+Heading Font: Merriweather
+License: OFL
+Category: serif
+
+Body Font: roboto-slab
+License: Apache
+Category: serif
+
+Code Font: hack
+License: MIT
+Category: monospace
+
+All fonts are free for personal use.
diff --git a/extras/html/themes/deep_sky/code.ttf b/extras/html/themes/deep_sky/code.ttf
new file mode 100644
index 0000000..7c8e65b
--- /dev/null
+++ b/extras/html/themes/deep_sky/code.ttf
Binary files differ
diff --git a/extras/html/themes/deep_sky/example.html b/extras/html/themes/deep_sky/example.html
new file mode 100644
index 0000000..8475652
--- /dev/null
+++ b/extras/html/themes/deep_sky/example.html
@@ -0,0 +1,75 @@
+<!DOCTYPE html>
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
+<head>
+ <meta charset="UTF-8" />
+ <meta name="viewport" content="width=device-width, initial-scale=1.0" />
+ <title>Deep Sky - Gemtexter Theme</title>
+ <link rel="stylesheet" href="style.css" />
+</head>
+<body>
+ <div class="header">
+ <h1>Deep Sky</h1>
+ <p>A artistic layout with analogous colors</p>
+ </div>
+
+ <div class="content">
+ <h1>Welcome to Deep Sky</h1>
+ <p>This theme features a carefully crafted artistic layout with a light analogous color scheme. The typography combines serif fonts for headings with serif for body text.</p>
+
+ <h2>Typography Showcase</h2>
+ <p>The roboto-slab font family provides excellent readability for body text, while Merriweather adds character to headings. Code blocks use hack for clarity.</p>
+
+ <h2>Color Palette</h2>
+ <p>Primary: <span style="color: #980c4e; font-weight: bold;">#980c4e</span> |
+ Secondary: <span style="color: #911413; font-weight: bold;">#911413</span> |
+ Accent: <span style="color: #880b82; font-weight: bold;">#880b82</span></p>
+
+ <h3>Interactive Elements</h3>
+ <p>Links like <a href="#">this example</a> and longer <a href="#" class="textlink">text links that demonstrate the theme's navigation style</a> use the secondary color.</p>
+
+ <div class="quote">
+ "Design is not just what it looks like and feels like. Design is how it works." — Steve Jobs
+ </div>
+
+ <h3>Code Examples</h3>
+ <p>Inline code like <code>theme.generate()</code> and larger blocks:</p>
+ <pre>// Theme configuration
+const theme = {
+ name: "deep_sky",
+ layout: "artistic",
+ colors: {
+ primary: "#980c4e",
+ secondary: "#911413",
+ accent: "#880b82"
+ },
+ fonts: {
+ heading: "Merriweather",
+ body: "roboto-slab",
+ code: "hack"
+ }
+};</pre>
+
+ <h2>Content Structure</h2>
+ <ul>
+ <li>Clean, readable typography with 15px base font size</li>
+ <li>Heading scale ratio of 2.37x for visual hierarchy</li>
+ <li>Line height of 1.43 for comfortable reading</li>
+ <li>Artistic layout optimized for content flow</li>
+ <li>Light theme with analogous color harmony</li>
+ </ul>
+
+ <h2>Font Licensing</h2>
+ <p>All fonts used in this theme are properly licensed:</p>
+ <ul>
+ <li>Merriweather: OFL License</li>
+ <li>roboto-slab: Apache License</li>
+ <li>hack: MIT License</li>
+ </ul>
+
+ <h3>Final Thoughts</h3>
+ <p>Every element of this theme has been carefully designed to create a harmonious reading experience. The artistic layout ensures content is presented in an engaging way, while the color scheme provides the perfect backdrop for your words to shine.</p>
+
+ <p>Whether you're writing technical documentation, creative prose, or anything in between, this theme adapts to showcase your content beautifully.</p>
+ </div>
+</body>
+</html> \ No newline at end of file
diff --git a/extras/html/themes/deep_sky/handnotes.ttf b/extras/html/themes/deep_sky/handnotes.ttf
new file mode 100644
index 0000000..25e688b
--- /dev/null
+++ b/extras/html/themes/deep_sky/handnotes.ttf
Binary files differ
diff --git a/extras/html/themes/deep_sky/heading.ttf b/extras/html/themes/deep_sky/heading.ttf
new file mode 100644
index 0000000..3e10e02
--- /dev/null
+++ b/extras/html/themes/deep_sky/heading.ttf
Binary files differ
diff --git a/extras/html/themes/deep_sky/style.css b/extras/html/themes/deep_sky/style.css
new file mode 100644
index 0000000..c882bb9
--- /dev/null
+++ b/extras/html/themes/deep_sky/style.css
@@ -0,0 +1,230 @@
+/* Base styles */
+@font-face {
+ font-family: 'text';
+ src: url("./text.ttf") format("truetype");
+}
+
+@font-face {
+ font-family: 'heading';
+ src: url("./heading.ttf") format("truetype");
+}
+
+@font-face {
+ font-family: 'code';
+ src: url("./code.ttf") format("truetype");
+}
+
+@font-face {
+ font-family: 'handnotes';
+ src: url("./handnotes.ttf") format("truetype");
+}
+
+:root {
+ --color-primary: #980c4e;
+ --color-secondary: #911413;
+ --color-accent: #880b82;
+ --color-bg: #f0edee;
+ --color-text: #1d1d1d;
+ --font-size-base: 15px;
+ --font-size-h1: 2.37em;
+ --font-size-h2: 1.78em;
+ --font-size-h3: 1.33em;
+ --line-height: 1.43;
+}
+
+* {
+ box-sizing: border-box;
+}
+
+html {
+ font-size: var(--font-size-base);
+ -webkit-font-smoothing: antialiased;
+ -moz-osx-font-smoothing: grayscale;
+}
+
+body {
+ font-family: text, sans-serif;
+ background-color: var(--color-bg);
+ color: var(--color-text);
+ line-height: var(--line-height);
+ margin: 0;
+ padding: 0;
+ overflow-wrap: break-word;
+}
+
+h1, h2, h3 {
+ font-family: heading, serif;
+ line-height: 1.2;
+ margin-top: 1em;
+ margin-bottom: 0.5em;
+}
+
+h1 {
+ font-size: var(--font-size-h1);
+ color: var(--color-primary);
+}
+
+h2 {
+ font-size: var(--font-size-h2);
+ color: var(--color-primary);
+}
+
+h3 {
+ font-size: var(--font-size-h3);
+ color: var(--color-secondary);
+}
+
+a {
+ font-family: code, monospace;
+ color: var(--color-secondary);
+ text-decoration: none;
+ transition: all 0.3s ease;
+}
+
+a:hover {
+ color: var(--color-accent);
+ text-decoration: underline;
+}
+
+.textlink {
+ font-family: text, sans-serif;
+}
+
+.quote {
+ font-family: handnotes, cursive;
+ border-left: 4px solid var(--color-accent);
+ padding: 1em 1.5em;
+ margin: 1.5em 0;
+ background-color: rgba(152, 12, 78, 0.07);
+ font-style: italic;
+}
+
+pre {
+ font-family: code, monospace;
+ background-color: rgba(29, 29, 29, 0.04);
+ border: 1px solid rgba(29, 29, 29, 0.13);
+ padding: 1em;
+ overflow-x: auto;
+ border-radius: 4px;
+ font-size: 0.9em;
+}
+
+code {
+ font-family: code, monospace;
+ background-color: rgba(29, 29, 29, 0.04);
+ padding: 0.2em 0.4em;
+ border-radius: 3px;
+ font-size: 0.9em;
+}
+
+ul, ol {
+ padding-left: 2em;
+ margin: 1em 0;
+}
+
+li {
+ margin: 0.5em 0;
+}
+
+img {
+ max-width: 100%;
+ height: auto;
+}
+
+hr {
+ border: none;
+ border-top: 1px solid rgba(29, 29, 29, 0.20);
+ margin: 2em 0;
+}
+
+
+/* Layout: artistic */
+
+body {
+ padding: 4em 2em;
+ background: linear-gradient(45deg, #f0edee, rgba(240, 237, 238, 0.87));
+ min-height: 100vh;
+ position: relative;
+}
+
+body::before, body::after {
+ content: "";
+ position: fixed;
+ width: 300px;
+ height: 300px;
+ border-radius: 50%;
+ filter: blur(100px);
+ z-index: -1;
+}
+
+body::before {
+ top: -150px;
+ left: -150px;
+ background: rgba(152, 12, 78, 0.27);
+}
+
+body::after {
+ bottom: -150px;
+ right: -150px;
+ background: rgba(145, 20, 19, 0.27);
+}
+
+.header {
+ text-align: center;
+ margin-bottom: 4em;
+ position: relative;
+}
+
+.header h1 {
+ font-size: 4em;
+ margin: 0;
+ transform: perspective(500px) rotateY(-15deg);
+ text-shadow: 3px 3px 0 #980c4e, 6px 6px 0 #911413, 9px 9px 20px rgba(0,0,0,0.2);
+}
+
+h2, h3 {
+ position: relative;
+ display: inline-block;
+}
+
+h2::after, h3::after {
+ content: "";
+ position: absolute;
+ bottom: -5px;
+ left: 0;
+ right: 0;
+ height: 3px;
+ background: linear-gradient(90deg, #980c4e, #911413, #880b82);
+ border-radius: 2px;
+}
+
+p, ul, pre, .quote {
+ max-width: 65ch;
+ margin: 2em auto;
+ padding: 2em;
+ background: rgba(255,255,255,0.9);
+ box-shadow: 0 8px 32px rgba(0,0,0,0.1), inset 0 1px 0 rgba(255,255,255,0.5);
+ border-radius: 20px;
+ transform: rotate(-1deg);
+}
+
+p:nth-child(even), ul:nth-child(even), .quote:nth-child(even) {
+ transform: rotate(1deg);
+}
+
+a {
+ color: #911413;
+ text-decoration: none;
+ background-image: linear-gradient(90deg, #980c4e, #911413);
+ background-size: 100% 2px;
+ background-position: 0 100%;
+ background-repeat: no-repeat;
+ transition: all 0.3s ease;
+}
+
+a:hover {
+ background-size: 100% 100%;
+ color: white;
+ padding: 0.2em 0.4em;
+ margin: -0.2em -0.4em;
+}
diff --git a/extras/html/themes/deep_sky/theme.conf b/extras/html/themes/deep_sky/theme.conf
new file mode 100644
index 0000000..d3d85d8
--- /dev/null
+++ b/extras/html/themes/deep_sky/theme.conf
@@ -0,0 +1,8 @@
+declare -xr HTML_HEADER=./extras/html/header.html.part
+declare -xr HTML_FOOTER=./extras/html/footer.html.part
+declare -xr HTML_CSS_STYLE=$HTML_THEME_DIR/style.css
+declare -xr HTML_WEBFONT_HEADING=./extras/html/fonts/Merriweather/Merriweather-Bold.ttf
+declare -xr HTML_WEBFONT_TEXT=./extras/html/fonts/roboto-slab/roboto-slab-Regular.ttf
+declare -xr HTML_WEBFONT_CODE=./extras/html/fonts/hack/hack-Regular.ttf
+declare -xr HTML_WEBFONT_HANDNOTES=./extras/html/fonts/khand/khand.ttf
+declare -xr SOURCE_HIGHLIGHT_CSS=./extras/html/source-highlight-styles/mono.css
diff --git a/extras/html/themes/default/style.css b/extras/html/themes/default/style.css
index 2e6e723..c273d25 100644
--- a/extras/html/themes/default/style.css
+++ b/extras/html/themes/default/style.css
@@ -19,8 +19,7 @@
}
html {
- background-image: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100" fill="%23cccccc"><polygon points="50,15 61,39 87,39 66,57 76,84 50,68 24,84 34,57 13,39 39,39"/></svg>'),
- radial-gradient(#000000 1px, transparent 1px);
+ background-image: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100" fill="%23cccccc"><polygon points="50,15 61,39 87,39 66,57 76,84 50,68 24,84 34,57 13,39 39,39"/></svg>'), radial-gradient(#000000 1px, transparent 1px);
background-size: 32px 32px;
background-color: #000000;
}
@@ -33,7 +32,7 @@ body {
margin: 20px auto;
border: 5px solid #eeeeee;
border-radius: 15px;
- word-wrap: break-word;
+ overflow-wrap: break-word;
}
h1, h2, h3 {
diff --git a/extras/html/themes/dynamic_forest/LICENSE b/extras/html/themes/dynamic_forest/LICENSE
new file mode 100644
index 0000000..9791121
--- /dev/null
+++ b/extras/html/themes/dynamic_forest/LICENSE
@@ -0,0 +1,21 @@
+Theme: dynamic_forest
+Generated: 2025-06-22 21:38:55
+
+Layout: masonry
+Color Scheme: analogous (Dark)
+
+Font Licenses:
+==============
+Heading Font: pixelon
+License: Free
+Category: display
+
+Body Font: roboto-slab
+License: Apache
+Category: serif
+
+Code Font: consola-mono
+License: OFL
+Category: monospace
+
+All fonts are free for personal use.
diff --git a/extras/html/themes/dynamic_forest/code.ttf b/extras/html/themes/dynamic_forest/code.ttf
new file mode 100644
index 0000000..78ca9da
--- /dev/null
+++ b/extras/html/themes/dynamic_forest/code.ttf
Binary files differ
diff --git a/extras/html/themes/dynamic_forest/example.html b/extras/html/themes/dynamic_forest/example.html
new file mode 100644
index 0000000..948f3ca
--- /dev/null
+++ b/extras/html/themes/dynamic_forest/example.html
@@ -0,0 +1,75 @@
+<!DOCTYPE html>
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
+<head>
+ <meta charset="UTF-8" />
+ <meta name="viewport" content="width=device-width, initial-scale=1.0" />
+ <title>Dynamic Forest - Gemtexter Theme</title>
+ <link rel="stylesheet" href="style.css" />
+</head>
+<body>
+ <div class="header">
+ <h1>Dynamic Forest</h1>
+ <p>A masonry layout with analogous colors</p>
+ </div>
+
+ <div class="content">
+ <h1>Welcome to Dynamic Forest</h1>
+ <p>This theme features a carefully crafted masonry layout with a dark analogous color scheme. The typography combines display fonts for headings with serif for body text.</p>
+
+ <h2>Typography Showcase</h2>
+ <p>The roboto-slab font family provides excellent readability for body text, while pixelon adds character to headings. Code blocks use consola-mono for clarity.</p>
+
+ <h2>Color Palette</h2>
+ <p>Primary: <span style="color: #4bcfe9; font-weight: bold;">#4bcfe9</span> |
+ Secondary: <span style="color: #5385e1; font-weight: bold;">#5385e1</span> |
+ Accent: <span style="color: #30e6ad; font-weight: bold;">#30e6ad</span></p>
+
+ <h3>Interactive Elements</h3>
+ <p>Links like <a href="#">this example</a> and longer <a href="#" class="textlink">text links that demonstrate the theme's navigation style</a> use the secondary color.</p>
+
+ <div class="quote">
+ "Design is not just what it looks like and feels like. Design is how it works." — Steve Jobs
+ </div>
+
+ <h3>Code Examples</h3>
+ <p>Inline code like <code>theme.generate()</code> and larger blocks:</p>
+ <pre>// Theme configuration
+const theme = {
+ name: "dynamic_forest",
+ layout: "masonry",
+ colors: {
+ primary: "#4bcfe9",
+ secondary: "#5385e1",
+ accent: "#30e6ad"
+ },
+ fonts: {
+ heading: "pixelon",
+ body: "roboto-slab",
+ code: "consola-mono"
+ }
+};</pre>
+
+ <h2>Content Structure</h2>
+ <ul>
+ <li>Clean, readable typography with 17px base font size</li>
+ <li>Heading scale ratio of 4.24x for visual hierarchy</li>
+ <li>Line height of 1.6 for comfortable reading</li>
+ <li>Masonry layout optimized for content flow</li>
+ <li>Dark theme with analogous color harmony</li>
+ </ul>
+
+ <h2>Font Licensing</h2>
+ <p>All fonts used in this theme are properly licensed:</p>
+ <ul>
+ <li>pixelon: Free License</li>
+ <li>roboto-slab: Apache License</li>
+ <li>consola-mono: OFL License</li>
+ </ul>
+
+ <h3>Final Thoughts</h3>
+ <p>Every element of this theme has been carefully designed to create a harmonious reading experience. The masonry layout ensures content is presented in an engaging way, while the color scheme provides the perfect backdrop for your words to shine.</p>
+
+ <p>Whether you're writing technical documentation, creative prose, or anything in between, this theme adapts to showcase your content beautifully.</p>
+ </div>
+</body>
+</html> \ No newline at end of file
diff --git a/extras/html/themes/dynamic_forest/handnotes.ttf b/extras/html/themes/dynamic_forest/handnotes.ttf
new file mode 100644
index 0000000..25e688b
--- /dev/null
+++ b/extras/html/themes/dynamic_forest/handnotes.ttf
Binary files differ
diff --git a/extras/html/themes/dynamic_forest/heading.ttf b/extras/html/themes/dynamic_forest/heading.ttf
new file mode 100644
index 0000000..acb3c81
--- /dev/null
+++ b/extras/html/themes/dynamic_forest/heading.ttf
Binary files differ
diff --git a/extras/html/themes/dynamic_forest/style.css b/extras/html/themes/dynamic_forest/style.css
new file mode 100644
index 0000000..3ec6186
--- /dev/null
+++ b/extras/html/themes/dynamic_forest/style.css
@@ -0,0 +1,175 @@
+/* Base styles */
+@font-face {
+ font-family: 'text';
+ src: url("./text.ttf") format("truetype");
+}
+
+@font-face {
+ font-family: 'heading';
+ src: url("./heading.ttf") format("truetype");
+}
+
+@font-face {
+ font-family: 'code';
+ src: url("./code.ttf") format("truetype");
+}
+
+@font-face {
+ font-family: 'handnotes';
+ src: url("./handnotes.ttf") format("truetype");
+}
+
+:root {
+ --color-primary: #4bcfe9;
+ --color-secondary: #5385e1;
+ --color-accent: #30e6ad;
+ --color-bg: #101314;
+ --color-text: #f0f0f0;
+ --font-size-base: 17px;
+ --font-size-h1: 4.24em;
+ --font-size-h2: 2.62em;
+ --font-size-h3: 1.62em;
+ --line-height: 1.6;
+}
+
+* {
+ box-sizing: border-box;
+}
+
+html {
+ font-size: var(--font-size-base);
+ -webkit-font-smoothing: antialiased;
+ -moz-osx-font-smoothing: grayscale;
+}
+
+body {
+ font-family: text, sans-serif;
+ background-color: var(--color-bg);
+ color: var(--color-text);
+ line-height: var(--line-height);
+ margin: 0;
+ padding: 0;
+ overflow-wrap: break-word;
+}
+
+h1, h2, h3 {
+ font-family: heading, serif;
+ line-height: 1.2;
+ margin-top: 1em;
+ margin-bottom: 0.5em;
+}
+
+h1 {
+ font-size: var(--font-size-h1);
+ color: var(--color-primary);
+}
+
+h2 {
+ font-size: var(--font-size-h2);
+ color: var(--color-primary);
+}
+
+h3 {
+ font-size: var(--font-size-h3);
+ color: var(--color-secondary);
+}
+
+a {
+ font-family: code, monospace;
+ color: var(--color-secondary);
+ text-decoration: none;
+ transition: all 0.3s ease;
+}
+
+a:hover {
+ color: var(--color-accent);
+ text-decoration: underline;
+}
+
+.textlink {
+ font-family: text, sans-serif;
+}
+
+.quote {
+ font-family: handnotes, cursive;
+ border-left: 4px solid var(--color-accent);
+ padding: 1em 1.5em;
+ margin: 1.5em 0;
+ background-color: rgba(75, 207, 233, 0.07);
+ font-style: italic;
+}
+
+pre {
+ font-family: code, monospace;
+ background-color: rgba(240, 240, 240, 0.04);
+ border: 1px solid rgba(240, 240, 240, 0.13);
+ padding: 1em;
+ overflow-x: auto;
+ border-radius: 4px;
+ font-size: 0.9em;
+}
+
+code {
+ font-family: code, monospace;
+ background-color: rgba(240, 240, 240, 0.04);
+ padding: 0.2em 0.4em;
+ border-radius: 3px;
+ font-size: 0.9em;
+}
+
+ul, ol {
+ padding-left: 2em;
+ margin: 1em 0;
+}
+
+li {
+ margin: 0.5em 0;
+}
+
+img {
+ max-width: 100%;
+ height: auto;
+}
+
+hr {
+ border: none;
+ border-top: 1px solid rgba(240, 240, 240, 0.20);
+ margin: 2em 0;
+}
+
+
+/* Layout: masonry */
+
+body {
+ padding: 2em;
+ columns: 320px;
+ column-gap: 2em;
+}
+
+.header {
+ column-span: all;
+ text-align: center;
+ margin-bottom: 3em;
+ padding: 2em;
+ background: var(--color-primary);
+ color: var(--color-bg);
+}
+
+.header h1 {
+ color: var(--color-bg);
+}
+
+h1, h2 {
+ column-span: all;
+ text-align: center;
+ margin: 2em 0;
+}
+
+p, ul, pre, .quote, h3 {
+ break-inside: avoid;
+ margin-bottom: 2em;
+ padding: 1.5em;
+ background-color: var(--color-bg);
+ border: 1px solid var(--color-text)11;
+ border-radius: 8px;
+}
diff --git a/extras/html/themes/dynamic_forest/theme.conf b/extras/html/themes/dynamic_forest/theme.conf
new file mode 100644
index 0000000..6147fc7
--- /dev/null
+++ b/extras/html/themes/dynamic_forest/theme.conf
@@ -0,0 +1,8 @@
+declare -xr HTML_HEADER=./extras/html/header.html.part
+declare -xr HTML_FOOTER=./extras/html/footer.html.part
+declare -xr HTML_CSS_STYLE=$HTML_THEME_DIR/style.css
+declare -xr HTML_WEBFONT_HEADING=./extras/html/fonts/pixelon/pixelon-Bold.ttf
+declare -xr HTML_WEBFONT_TEXT=./extras/html/fonts/roboto-slab/roboto-slab-Regular.ttf
+declare -xr HTML_WEBFONT_CODE=./extras/html/fonts/consola-mono/consola-mono-Regular.ttf
+declare -xr HTML_WEBFONT_HANDNOTES=./extras/html/fonts/khand/khand.ttf
+declare -xr SOURCE_HIGHLIGHT_CSS=./extras/html/source-highlight-styles/mono.css
diff --git a/extras/html/themes/ember_mist/LICENSE b/extras/html/themes/ember_mist/LICENSE
new file mode 100644
index 0000000..649c256
--- /dev/null
+++ b/extras/html/themes/ember_mist/LICENSE
@@ -0,0 +1,21 @@
+Theme: ember_mist
+Generated: 2025-06-22 21:38:55
+
+Layout: asymmetric
+Color Scheme: split_complementary (Light)
+
+Font Licenses:
+==============
+Heading Font: oxygen
+License: OFL
+Category: sans-serif
+
+Body Font: Merriweather
+License: OFL
+Category: serif
+
+Code Font: intelone-mono
+License: OFL
+Category: monospace
+
+All fonts are free for personal use.
diff --git a/extras/html/themes/ember_mist/code.ttf b/extras/html/themes/ember_mist/code.ttf
new file mode 100644
index 0000000..2711179
--- /dev/null
+++ b/extras/html/themes/ember_mist/code.ttf
Binary files differ
diff --git a/extras/html/themes/ember_mist/example.html b/extras/html/themes/ember_mist/example.html
new file mode 100644
index 0000000..5c6e5ba
--- /dev/null
+++ b/extras/html/themes/ember_mist/example.html
@@ -0,0 +1,75 @@
+<!DOCTYPE html>
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
+<head>
+ <meta charset="UTF-8" />
+ <meta name="viewport" content="width=device-width, initial-scale=1.0" />
+ <title>Ember Mist - Gemtexter Theme</title>
+ <link rel="stylesheet" href="style.css" />
+</head>
+<body>
+ <div class="header">
+ <h1>Ember Mist</h1>
+ <p>A asymmetric layout with split complementary colors</p>
+ </div>
+
+ <div class="content">
+ <h1>Welcome to Ember Mist</h1>
+ <p>This theme features a carefully crafted asymmetric layout with a light split complementary color scheme. The typography combines sans-serif fonts for headings with serif for body text.</p>
+
+ <h2>Typography Showcase</h2>
+ <p>The Merriweather font family provides excellent readability for body text, while oxygen adds character to headings. Code blocks use intelone-mono for clarity.</p>
+
+ <h2>Color Palette</h2>
+ <p>Primary: <span style="color: #f149ca; font-weight: bold;">#f149ca</span> |
+ Secondary: <span style="color: #7be05a; font-weight: bold;">#7be05a</span> |
+ Accent: <span style="color: #5ae0b9; font-weight: bold;">#5ae0b9</span></p>
+
+ <h3>Interactive Elements</h3>
+ <p>Links like <a href="#">this example</a> and longer <a href="#" class="textlink">text links that demonstrate the theme's navigation style</a> use the secondary color.</p>
+
+ <div class="quote">
+ "Design is not just what it looks like and feels like. Design is how it works." — Steve Jobs
+ </div>
+
+ <h3>Code Examples</h3>
+ <p>Inline code like <code>theme.generate()</code> and larger blocks:</p>
+ <pre>// Theme configuration
+const theme = {
+ name: "ember_mist",
+ layout: "asymmetric",
+ colors: {
+ primary: "#f149ca",
+ secondary: "#7be05a",
+ accent: "#5ae0b9"
+ },
+ fonts: {
+ heading: "oxygen",
+ body: "Merriweather",
+ code: "intelone-mono"
+ }
+};</pre>
+
+ <h2>Content Structure</h2>
+ <ul>
+ <li>Clean, readable typography with 14px base font size</li>
+ <li>Heading scale ratio of 1.42x for visual hierarchy</li>
+ <li>Line height of 1.68 for comfortable reading</li>
+ <li>Asymmetric layout optimized for content flow</li>
+ <li>Light theme with split complementary color harmony</li>
+ </ul>
+
+ <h2>Font Licensing</h2>
+ <p>All fonts used in this theme are properly licensed:</p>
+ <ul>
+ <li>oxygen: OFL License</li>
+ <li>Merriweather: OFL License</li>
+ <li>intelone-mono: OFL License</li>
+ </ul>
+
+ <h3>Final Thoughts</h3>
+ <p>Every element of this theme has been carefully designed to create a harmonious reading experience. The asymmetric layout ensures content is presented in an engaging way, while the color scheme provides the perfect backdrop for your words to shine.</p>
+
+ <p>Whether you're writing technical documentation, creative prose, or anything in between, this theme adapts to showcase your content beautifully.</p>
+ </div>
+</body>
+</html> \ No newline at end of file
diff --git a/extras/html/themes/ember_mist/handnotes.ttf b/extras/html/themes/ember_mist/handnotes.ttf
new file mode 100644
index 0000000..25e688b
--- /dev/null
+++ b/extras/html/themes/ember_mist/handnotes.ttf
Binary files differ
diff --git a/extras/html/themes/ember_mist/style.css b/extras/html/themes/ember_mist/style.css
new file mode 100644
index 0000000..a82aefe
--- /dev/null
+++ b/extras/html/themes/ember_mist/style.css
@@ -0,0 +1,181 @@
+/* Base styles */
+@font-face {
+ font-family: 'text';
+ src: url("./text.ttf") format("truetype");
+}
+
+@font-face {
+ font-family: 'heading';
+ src: url("./heading.ttf") format("truetype");
+}
+
+@font-face {
+ font-family: 'code';
+ src: url("./code.ttf") format("truetype");
+}
+
+@font-face {
+ font-family: 'handnotes';
+ src: url("./handnotes.ttf") format("truetype");
+}
+
+:root {
+ --color-primary: #f149ca;
+ --color-secondary: #7be05a;
+ --color-accent: #5ae0b9;
+ --color-bg: #f5f3f5;
+ --color-text: #151515;
+ --font-size-base: 14px;
+ --font-size-h1: 1.42em;
+ --font-size-h2: 1.27em;
+ --font-size-h3: 1.12em;
+ --line-height: 1.68;
+}
+
+* {
+ box-sizing: border-box;
+}
+
+html {
+ font-size: var(--font-size-base);
+ -webkit-font-smoothing: antialiased;
+ -moz-osx-font-smoothing: grayscale;
+}
+
+body {
+ font-family: text, sans-serif;
+ background-color: var(--color-bg);
+ color: var(--color-text);
+ line-height: var(--line-height);
+ margin: 0;
+ padding: 0;
+ overflow-wrap: break-word;
+}
+
+h1, h2, h3 {
+ font-family: heading, serif;
+ line-height: 1.2;
+ margin-top: 1em;
+ margin-bottom: 0.5em;
+}
+
+h1 {
+ font-size: var(--font-size-h1);
+ color: var(--color-primary);
+}
+
+h2 {
+ font-size: var(--font-size-h2);
+ color: var(--color-primary);
+}
+
+h3 {
+ font-size: var(--font-size-h3);
+ color: var(--color-secondary);
+}
+
+a {
+ font-family: code, monospace;
+ color: var(--color-secondary);
+ text-decoration: none;
+ transition: all 0.3s ease;
+}
+
+a:hover {
+ color: var(--color-accent);
+ text-decoration: underline;
+}
+
+.textlink {
+ font-family: text, sans-serif;
+}
+
+.quote {
+ font-family: handnotes, cursive;
+ border-left: 4px solid var(--color-accent);
+ padding: 1em 1.5em;
+ margin: 1.5em 0;
+ background-color: rgba(241, 73, 202, 0.07);
+ font-style: italic;
+}
+
+pre {
+ font-family: code, monospace;
+ background-color: rgba(21, 21, 21, 0.04);
+ border: 1px solid rgba(21, 21, 21, 0.13);
+ padding: 1em;
+ overflow-x: auto;
+ border-radius: 4px;
+ font-size: 0.9em;
+}
+
+code {
+ font-family: code, monospace;
+ background-color: rgba(21, 21, 21, 0.04);
+ padding: 0.2em 0.4em;
+ border-radius: 3px;
+ font-size: 0.9em;
+}
+
+ul, ol {
+ padding-left: 2em;
+ margin: 1em 0;
+}
+
+li {
+ margin: 0.5em 0;
+}
+
+img {
+ max-width: 100%;
+ height: auto;
+}
+
+hr {
+ border: none;
+ border-top: 1px solid rgba(21, 21, 21, 0.20);
+ margin: 2em 0;
+}
+
+
+/* Layout: asymmetric */
+
+body {
+ max-width: 1200px;
+ margin: 0 auto;
+ padding: 2em;
+}
+
+.header {
+ margin-left: 20%;
+ margin-bottom: 4em;
+}
+
+h1 {
+ margin-left: -5%;
+ font-size: calc(var(--font-size-h1) * 1.2);
+}
+
+h2 {
+ margin-left: 10%;
+}
+
+h3 {
+ margin-left: 25%;
+}
+
+p:nth-child(odd) {
+ margin-left: 5%;
+ margin-right: 20%;
+}
+
+p:nth-child(even) {
+ margin-left: 20%;
+ margin-right: 5%;
+}
+
+.quote {
+ margin-left: 15%;
+ margin-right: 15%;
+ text-align: center;
+}
diff --git a/extras/html/themes/ember_mist/text.ttf b/extras/html/themes/ember_mist/text.ttf
new file mode 100644
index 0000000..3fecc77
--- /dev/null
+++ b/extras/html/themes/ember_mist/text.ttf
Binary files differ
diff --git a/extras/html/themes/ember_mist/theme.conf b/extras/html/themes/ember_mist/theme.conf
new file mode 100644
index 0000000..11ad64d
--- /dev/null
+++ b/extras/html/themes/ember_mist/theme.conf
@@ -0,0 +1,8 @@
+declare -xr HTML_HEADER=./extras/html/header.html.part
+declare -xr HTML_FOOTER=./extras/html/footer.html.part
+declare -xr HTML_CSS_STYLE=$HTML_THEME_DIR/style.css
+declare -xr HTML_WEBFONT_HEADING=./extras/html/fonts/oxygen/oxygen-Bold.ttf
+declare -xr HTML_WEBFONT_TEXT=./extras/html/fonts/Merriweather/Merriweather-Regular.ttf
+declare -xr HTML_WEBFONT_CODE=./extras/html/fonts/intelone-mono/intelone-mono-Regular.ttf
+declare -xr HTML_WEBFONT_HANDNOTES=./extras/html/fonts/khand/khand.ttf
+declare -xr SOURCE_HIGHLIGHT_CSS=./extras/html/source-highlight-styles/mono.css
diff --git a/extras/html/themes/ember_mountain/LICENSE b/extras/html/themes/ember_mountain/LICENSE
new file mode 100644
index 0000000..8222452
--- /dev/null
+++ b/extras/html/themes/ember_mountain/LICENSE
@@ -0,0 +1,21 @@
+Theme: ember_mountain
+Generated: 2025-06-22 21:38:55
+
+Layout: card
+Color Scheme: split_complementary (Light)
+
+Font Licenses:
+==============
+Heading Font: oxygen
+License: OFL
+Category: sans-serif
+
+Body Font: Lato
+License: OFL
+Category: sans-serif
+
+Code Font: hack
+License: MIT
+Category: monospace
+
+All fonts are free for personal use.
diff --git a/extras/html/themes/ember_mountain/code.ttf b/extras/html/themes/ember_mountain/code.ttf
new file mode 100644
index 0000000..7c8e65b
--- /dev/null
+++ b/extras/html/themes/ember_mountain/code.ttf
Binary files differ
diff --git a/extras/html/themes/ember_mountain/example.html b/extras/html/themes/ember_mountain/example.html
new file mode 100644
index 0000000..515f07c
--- /dev/null
+++ b/extras/html/themes/ember_mountain/example.html
@@ -0,0 +1,75 @@
+<!DOCTYPE html>
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
+<head>
+ <meta charset="UTF-8" />
+ <meta name="viewport" content="width=device-width, initial-scale=1.0" />
+ <title>Ember Mountain - Gemtexter Theme</title>
+ <link rel="stylesheet" href="style.css" />
+</head>
+<body>
+ <div class="header">
+ <h1>Ember Mountain</h1>
+ <p>A card layout with split complementary colors</p>
+ </div>
+
+ <div class="content">
+ <h1>Welcome to Ember Mountain</h1>
+ <p>This theme features a carefully crafted card layout with a light split complementary color scheme. The typography combines sans-serif fonts for headings with sans-serif for body text.</p>
+
+ <h2>Typography Showcase</h2>
+ <p>The Lato font family provides excellent readability for body text, while oxygen adds character to headings. Code blocks use hack for clarity.</p>
+
+ <h2>Color Palette</h2>
+ <p>Primary: <span style="color: #6f3857; font-weight: bold;">#6f3857</span> |
+ Secondary: <span style="color: #3f6a3d; font-weight: bold;">#3f6a3d</span> |
+ Accent: <span style="color: #3d6a66; font-weight: bold;">#3d6a66</span></p>
+
+ <h3>Interactive Elements</h3>
+ <p>Links like <a href="#">this example</a> and longer <a href="#" class="textlink">text links that demonstrate the theme's navigation style</a> use the secondary color.</p>
+
+ <div class="quote">
+ "Design is not just what it looks like and feels like. Design is how it works." — Steve Jobs
+ </div>
+
+ <h3>Code Examples</h3>
+ <p>Inline code like <code>theme.generate()</code> and larger blocks:</p>
+ <pre>// Theme configuration
+const theme = {
+ name: "ember_mountain",
+ layout: "card",
+ colors: {
+ primary: "#6f3857",
+ secondary: "#3f6a3d",
+ accent: "#3d6a66"
+ },
+ fonts: {
+ heading: "oxygen",
+ body: "Lato",
+ code: "hack"
+ }
+};</pre>
+
+ <h2>Content Structure</h2>
+ <ul>
+ <li>Clean, readable typography with 15px base font size</li>
+ <li>Heading scale ratio of 1.42x for visual hierarchy</li>
+ <li>Line height of 1.71 for comfortable reading</li>
+ <li>Card layout optimized for content flow</li>
+ <li>Light theme with split complementary color harmony</li>
+ </ul>
+
+ <h2>Font Licensing</h2>
+ <p>All fonts used in this theme are properly licensed:</p>
+ <ul>
+ <li>oxygen: OFL License</li>
+ <li>Lato: OFL License</li>
+ <li>hack: MIT License</li>
+ </ul>
+
+ <h3>Final Thoughts</h3>
+ <p>Every element of this theme has been carefully designed to create a harmonious reading experience. The card layout ensures content is presented in an engaging way, while the color scheme provides the perfect backdrop for your words to shine.</p>
+
+ <p>Whether you're writing technical documentation, creative prose, or anything in between, this theme adapts to showcase your content beautifully.</p>
+ </div>
+</body>
+</html> \ No newline at end of file
diff --git a/extras/html/themes/ember_mountain/handnotes.ttf b/extras/html/themes/ember_mountain/handnotes.ttf
new file mode 100644
index 0000000..25e688b
--- /dev/null
+++ b/extras/html/themes/ember_mountain/handnotes.ttf
Binary files differ
diff --git a/extras/html/themes/ember_mountain/style.css b/extras/html/themes/ember_mountain/style.css
new file mode 100644
index 0000000..40327f7
--- /dev/null
+++ b/extras/html/themes/ember_mountain/style.css
@@ -0,0 +1,168 @@
+/* Base styles */
+@font-face {
+ font-family: 'text';
+ src: url("./text.ttf") format("truetype");
+}
+
+@font-face {
+ font-family: 'heading';
+ src: url("./heading.ttf") format("truetype");
+}
+
+@font-face {
+ font-family: 'code';
+ src: url("./code.ttf") format("truetype");
+}
+
+@font-face {
+ font-family: 'handnotes';
+ src: url("./handnotes.ttf") format("truetype");
+}
+
+:root {
+ --color-primary: #6f3857;
+ --color-secondary: #3f6a3d;
+ --color-accent: #3d6a66;
+ --color-bg: #efecee;
+ --color-text: #151515;
+ --font-size-base: 15px;
+ --font-size-h1: 1.42em;
+ --font-size-h2: 1.27em;
+ --font-size-h3: 1.12em;
+ --line-height: 1.71;
+}
+
+* {
+ box-sizing: border-box;
+}
+
+html {
+ font-size: var(--font-size-base);
+ -webkit-font-smoothing: antialiased;
+ -moz-osx-font-smoothing: grayscale;
+}
+
+body {
+ font-family: text, sans-serif;
+ background-color: var(--color-bg);
+ color: var(--color-text);
+ line-height: var(--line-height);
+ margin: 0;
+ padding: 0;
+ overflow-wrap: break-word;
+}
+
+h1, h2, h3 {
+ font-family: heading, serif;
+ line-height: 1.2;
+ margin-top: 1em;
+ margin-bottom: 0.5em;
+}
+
+h1 {
+ font-size: var(--font-size-h1);
+ color: var(--color-primary);
+}
+
+h2 {
+ font-size: var(--font-size-h2);
+ color: var(--color-primary);
+}
+
+h3 {
+ font-size: var(--font-size-h3);
+ color: var(--color-secondary);
+}
+
+a {
+ font-family: code, monospace;
+ color: var(--color-secondary);
+ text-decoration: none;
+ transition: all 0.3s ease;
+}
+
+a:hover {
+ color: var(--color-accent);
+ text-decoration: underline;
+}
+
+.textlink {
+ font-family: text, sans-serif;
+}
+
+.quote {
+ font-family: handnotes, cursive;
+ border-left: 4px solid var(--color-accent);
+ padding: 1em 1.5em;
+ margin: 1.5em 0;
+ background-color: rgba(111, 56, 87, 0.07);
+ font-style: italic;
+}
+
+pre {
+ font-family: code, monospace;
+ background-color: rgba(21, 21, 21, 0.04);
+ border: 1px solid rgba(21, 21, 21, 0.13);
+ padding: 1em;
+ overflow-x: auto;
+ border-radius: 4px;
+ font-size: 0.9em;
+}
+
+code {
+ font-family: code, monospace;
+ background-color: rgba(21, 21, 21, 0.04);
+ padding: 0.2em 0.4em;
+ border-radius: 3px;
+ font-size: 0.9em;
+}
+
+ul, ol {
+ padding-left: 2em;
+ margin: 1em 0;
+}
+
+li {
+ margin: 0.5em 0;
+}
+
+img {
+ max-width: 100%;
+ height: auto;
+}
+
+hr {
+ border: none;
+ border-top: 1px solid rgba(21, 21, 21, 0.20);
+ margin: 2em 0;
+}
+
+
+/* Layout: card */
+
+body {
+ padding: 2em;
+ background: linear-gradient(135deg, rgba(111, 56, 87, 0.07), rgba(63, 106, 61, 0.07));
+ min-height: 100vh;
+}
+
+.header {
+ background-color: var(--color-bg);
+ padding: 3em;
+ margin-bottom: 3em;
+ border-radius: 16px;
+ box-shadow: 0 8px 32px rgba(0,0,0,0.1);
+ text-align: center;
+}
+
+h1, h2, h3, p, ul, pre, .quote {
+ background-color: var(--color-bg);
+ padding: 2em;
+ margin: 1em 0;
+ border-radius: 12px;
+ box-shadow: 0 4px 16px rgba(0,0,0,0.05);
+}
+
+h1, h2, h3 {
+ padding: 1em 2em;
+}
diff --git a/extras/html/themes/ember_mountain/text.ttf b/extras/html/themes/ember_mountain/text.ttf
new file mode 100644
index 0000000..bb2e887
--- /dev/null
+++ b/extras/html/themes/ember_mountain/text.ttf
Binary files differ
diff --git a/extras/html/themes/ember_mountain/theme.conf b/extras/html/themes/ember_mountain/theme.conf
new file mode 100644
index 0000000..1e2ca2e
--- /dev/null
+++ b/extras/html/themes/ember_mountain/theme.conf
@@ -0,0 +1,8 @@
+declare -xr HTML_HEADER=./extras/html/header.html.part
+declare -xr HTML_FOOTER=./extras/html/footer.html.part
+declare -xr HTML_CSS_STYLE=$HTML_THEME_DIR/style.css
+declare -xr HTML_WEBFONT_HEADING=./extras/html/fonts/oxygen/oxygen-Bold.ttf
+declare -xr HTML_WEBFONT_TEXT=./extras/html/fonts/Lato/Lato-Regular.ttf
+declare -xr HTML_WEBFONT_CODE=./extras/html/fonts/hack/hack-Regular.ttf
+declare -xr HTML_WEBFONT_HANDNOTES=./extras/html/fonts/khand/khand.ttf
+declare -xr SOURCE_HIGHLIGHT_CSS=./extras/html/source-highlight-styles/mono.css
diff --git a/extras/html/themes/ember_night/LICENSE b/extras/html/themes/ember_night/LICENSE
new file mode 100644
index 0000000..0878efb
--- /dev/null
+++ b/extras/html/themes/ember_night/LICENSE
@@ -0,0 +1,21 @@
+Theme: ember_night
+Generated: 2025-06-22 21:38:55
+
+Layout: gradient
+Color Scheme: monochromatic (Dark)
+
+Font Licenses:
+==============
+Heading Font: zai-aeg-mignon-typewriter-1924
+License: Free
+Category: display
+
+Body Font: roboto-slab
+License: Apache
+Category: serif
+
+Code Font: hack
+License: MIT
+Category: monospace
+
+All fonts are free for personal use.
diff --git a/extras/html/themes/ember_night/code.ttf b/extras/html/themes/ember_night/code.ttf
new file mode 100644
index 0000000..7c8e65b
--- /dev/null
+++ b/extras/html/themes/ember_night/code.ttf
Binary files differ
diff --git a/extras/html/themes/ember_night/example.html b/extras/html/themes/ember_night/example.html
new file mode 100644
index 0000000..461a5c7
--- /dev/null
+++ b/extras/html/themes/ember_night/example.html
@@ -0,0 +1,75 @@
+<!DOCTYPE html>
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
+<head>
+ <meta charset="UTF-8" />
+ <meta name="viewport" content="width=device-width, initial-scale=1.0" />
+ <title>Ember Night - Gemtexter Theme</title>
+ <link rel="stylesheet" href="style.css" />
+</head>
+<body>
+ <div class="header">
+ <h1>Ember Night</h1>
+ <p>A gradient layout with monochromatic colors</p>
+ </div>
+
+ <div class="content">
+ <h1>Welcome to Ember Night</h1>
+ <p>This theme features a carefully crafted gradient layout with a dark monochromatic color scheme. The typography combines display fonts for headings with serif for body text.</p>
+
+ <h2>Typography Showcase</h2>
+ <p>The roboto-slab font family provides excellent readability for body text, while zai-aeg-mignon-typewriter-1924 adds character to headings. Code blocks use hack for clarity.</p>
+
+ <h2>Color Palette</h2>
+ <p>Primary: <span style="color: #e74654; font-weight: bold;">#e74654</span> |
+ Secondary: <span style="color: #ab2833; font-weight: bold;">#ab2833</span> |
+ Accent: <span style="color: #d79398; font-weight: bold;">#d79398</span></p>
+
+ <h3>Interactive Elements</h3>
+ <p>Links like <a href="#">this example</a> and longer <a href="#" class="textlink">text links that demonstrate the theme's navigation style</a> use the secondary color.</p>
+
+ <div class="quote">
+ "Design is not just what it looks like and feels like. Design is how it works." — Steve Jobs
+ </div>
+
+ <h3>Code Examples</h3>
+ <p>Inline code like <code>theme.generate()</code> and larger blocks:</p>
+ <pre>// Theme configuration
+const theme = {
+ name: "ember_night",
+ layout: "gradient",
+ colors: {
+ primary: "#e74654",
+ secondary: "#ab2833",
+ accent: "#d79398"
+ },
+ fonts: {
+ heading: "zai-aeg-mignon-typewriter-1924",
+ body: "roboto-slab",
+ code: "hack"
+ }
+};</pre>
+
+ <h2>Content Structure</h2>
+ <ul>
+ <li>Clean, readable typography with 15px base font size</li>
+ <li>Heading scale ratio of 1.95x for visual hierarchy</li>
+ <li>Line height of 1.75 for comfortable reading</li>
+ <li>Gradient layout optimized for content flow</li>
+ <li>Dark theme with monochromatic color harmony</li>
+ </ul>
+
+ <h2>Font Licensing</h2>
+ <p>All fonts used in this theme are properly licensed:</p>
+ <ul>
+ <li>zai-aeg-mignon-typewriter-1924: Free License</li>
+ <li>roboto-slab: Apache License</li>
+ <li>hack: MIT License</li>
+ </ul>
+
+ <h3>Final Thoughts</h3>
+ <p>Every element of this theme has been carefully designed to create a harmonious reading experience. The gradient layout ensures content is presented in an engaging way, while the color scheme provides the perfect backdrop for your words to shine.</p>
+
+ <p>Whether you're writing technical documentation, creative prose, or anything in between, this theme adapts to showcase your content beautifully.</p>
+ </div>
+</body>
+</html> \ No newline at end of file
diff --git a/extras/html/themes/ember_night/handnotes.ttf b/extras/html/themes/ember_night/handnotes.ttf
new file mode 100644
index 0000000..25e688b
--- /dev/null
+++ b/extras/html/themes/ember_night/handnotes.ttf
Binary files differ
diff --git a/extras/html/themes/ember_night/heading.ttf b/extras/html/themes/ember_night/heading.ttf
new file mode 100644
index 0000000..375978c
--- /dev/null
+++ b/extras/html/themes/ember_night/heading.ttf
Binary files differ
diff --git a/extras/html/themes/ember_night/style.css b/extras/html/themes/ember_night/style.css
new file mode 100644
index 0000000..686357d
--- /dev/null
+++ b/extras/html/themes/ember_night/style.css
@@ -0,0 +1,166 @@
+/* Base styles */
+@font-face {
+ font-family: 'text';
+ src: url("./text.ttf") format("truetype");
+}
+
+@font-face {
+ font-family: 'heading';
+ src: url("./heading.ttf") format("truetype");
+}
+
+@font-face {
+ font-family: 'code';
+ src: url("./code.ttf") format("truetype");
+}
+
+@font-face {
+ font-family: 'handnotes';
+ src: url("./handnotes.ttf") format("truetype");
+}
+
+:root {
+ --color-primary: #e74654;
+ --color-secondary: #ab2833;
+ --color-accent: #d79398;
+ --color-bg: #292122;
+ --color-text: #e1e1e1;
+ --font-size-base: 15px;
+ --font-size-h1: 1.95em;
+ --font-size-h2: 1.56em;
+ --font-size-h3: 1.25em;
+ --line-height: 1.75;
+}
+
+* {
+ box-sizing: border-box;
+}
+
+html {
+ font-size: var(--font-size-base);
+ -webkit-font-smoothing: antialiased;
+ -moz-osx-font-smoothing: grayscale;
+}
+
+body {
+ font-family: text, sans-serif;
+ background-color: var(--color-bg);
+ color: var(--color-text);
+ line-height: var(--line-height);
+ margin: 0;
+ padding: 0;
+ overflow-wrap: break-word;
+}
+
+h1, h2, h3 {
+ font-family: heading, serif;
+ line-height: 1.2;
+ margin-top: 1em;
+ margin-bottom: 0.5em;
+}
+
+h1 {
+ font-size: var(--font-size-h1);
+ color: var(--color-primary);
+}
+
+h2 {
+ font-size: var(--font-size-h2);
+ color: var(--color-primary);
+}
+
+h3 {
+ font-size: var(--font-size-h3);
+ color: var(--color-secondary);
+}
+
+a {
+ font-family: code, monospace;
+ color: var(--color-secondary);
+ text-decoration: none;
+ transition: all 0.3s ease;
+}
+
+a:hover {
+ color: var(--color-accent);
+ text-decoration: underline;
+}
+
+.textlink {
+ font-family: text, sans-serif;
+}
+
+.quote {
+ font-family: handnotes, cursive;
+ border-left: 4px solid var(--color-accent);
+ padding: 1em 1.5em;
+ margin: 1.5em 0;
+ background-color: rgba(231, 70, 84, 0.07);
+ font-style: italic;
+}
+
+pre {
+ font-family: code, monospace;
+ background-color: rgba(225, 225, 225, 0.04);
+ border: 1px solid rgba(225, 225, 225, 0.13);
+ padding: 1em;
+ overflow-x: auto;
+ border-radius: 4px;
+ font-size: 0.9em;
+}
+
+code {
+ font-family: code, monospace;
+ background-color: rgba(225, 225, 225, 0.04);
+ padding: 0.2em 0.4em;
+ border-radius: 3px;
+ font-size: 0.9em;
+}
+
+ul, ol {
+ padding-left: 2em;
+ margin: 1em 0;
+}
+
+li {
+ margin: 0.5em 0;
+}
+
+img {
+ max-width: 100%;
+ height: auto;
+}
+
+hr {
+ border: none;
+ border-top: 1px solid rgba(225, 225, 225, 0.20);
+ margin: 2em 0;
+}
+
+
+/* Layout: gradient */
+
+body {
+ margin: 0;
+ padding: 0;
+ background: linear-gradient(180deg, rgba(231, 70, 84, 0.13) 0%, rgba(171, 40, 51, 0.13) 50%, rgba(215, 147, 152, 0.13) 100%);
+ min-height: 100vh;
+}
+
+.header {
+ text-align: center;
+ padding: 6em 2em;
+ background: rgba(255,255,255,0.1);
+ backdrop-filter: blur(10px);
+ margin-bottom: 4em;
+}
+
+h1, h2, h3, p, ul, pre, .quote {
+ max-width: 65ch;
+ margin: 2em auto;
+ padding: 2em;
+ background: rgba(255,255,255,0.95);
+ backdrop-filter: blur(10px);
+ border-radius: 20px;
+ box-shadow: 0 8px 32px rgba(0,0,0,0.1);
+}
diff --git a/extras/html/themes/ember_night/theme.conf b/extras/html/themes/ember_night/theme.conf
new file mode 100644
index 0000000..b620ed7
--- /dev/null
+++ b/extras/html/themes/ember_night/theme.conf
@@ -0,0 +1,8 @@
+declare -xr HTML_HEADER=./extras/html/header.html.part
+declare -xr HTML_FOOTER=./extras/html/footer.html.part
+declare -xr HTML_CSS_STYLE=$HTML_THEME_DIR/style.css
+declare -xr HTML_WEBFONT_HEADING=./extras/html/fonts/zai-aeg-mignon-typewriter-1924/zai-aeg-mignon-typewriter-1924-Bold.ttf
+declare -xr HTML_WEBFONT_TEXT=./extras/html/fonts/roboto-slab/roboto-slab-Regular.ttf
+declare -xr HTML_WEBFONT_CODE=./extras/html/fonts/hack/hack-Regular.ttf
+declare -xr HTML_WEBFONT_HANDNOTES=./extras/html/fonts/khand/khand.ttf
+declare -xr SOURCE_HIGHLIGHT_CSS=./extras/html/source-highlight-styles/mono.css
diff --git a/extras/html/themes/ethereal_mist/LICENSE b/extras/html/themes/ethereal_mist/LICENSE
new file mode 100644
index 0000000..8cfdddc
--- /dev/null
+++ b/extras/html/themes/ethereal_mist/LICENSE
@@ -0,0 +1,21 @@
+Theme: ethereal_mist
+Generated: 2025-06-22 21:38:55
+
+Layout: hero
+Color Scheme: split_complementary (Light)
+
+Font Licenses:
+==============
+Heading Font: pixelon
+License: Free
+Category: display
+
+Body Font: oxygen
+License: OFL
+Category: sans-serif
+
+Code Font: hack
+License: MIT
+Category: monospace
+
+All fonts are free for personal use.
diff --git a/extras/html/themes/ethereal_mist/code.ttf b/extras/html/themes/ethereal_mist/code.ttf
new file mode 100644
index 0000000..7c8e65b
--- /dev/null
+++ b/extras/html/themes/ethereal_mist/code.ttf
Binary files differ
diff --git a/extras/html/themes/ethereal_mist/example.html b/extras/html/themes/ethereal_mist/example.html
new file mode 100644
index 0000000..53aa4b1
--- /dev/null
+++ b/extras/html/themes/ethereal_mist/example.html
@@ -0,0 +1,75 @@
+<!DOCTYPE html>
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
+<head>
+ <meta charset="UTF-8" />
+ <meta name="viewport" content="width=device-width, initial-scale=1.0" />
+ <title>Ethereal Mist - Gemtexter Theme</title>
+ <link rel="stylesheet" href="style.css" />
+</head>
+<body>
+ <div class="header">
+ <h1>Ethereal Mist</h1>
+ <p>A hero layout with split complementary colors</p>
+ </div>
+
+ <div class="content">
+ <h1>Welcome to Ethereal Mist</h1>
+ <p>This theme features a carefully crafted hero layout with a light split complementary color scheme. The typography combines display fonts for headings with sans-serif for body text.</p>
+
+ <h2>Typography Showcase</h2>
+ <p>The oxygen font family provides excellent readability for body text, while pixelon adds character to headings. Code blocks use hack for clarity.</p>
+
+ <h2>Color Palette</h2>
+ <p>Primary: <span style="color: #9b3f1e; font-weight: bold;">#9b3f1e</span> |
+ Secondary: <span style="color: #2b8e79; font-weight: bold;">#2b8e79</span> |
+ Accent: <span style="color: #2b448e; font-weight: bold;">#2b448e</span></p>
+
+ <h3>Interactive Elements</h3>
+ <p>Links like <a href="#">this example</a> and longer <a href="#" class="textlink">text links that demonstrate the theme's navigation style</a> use the secondary color.</p>
+
+ <div class="quote">
+ "Design is not just what it looks like and feels like. Design is how it works." — Steve Jobs
+ </div>
+
+ <h3>Code Examples</h3>
+ <p>Inline code like <code>theme.generate()</code> and larger blocks:</p>
+ <pre>// Theme configuration
+const theme = {
+ name: "ethereal_mist",
+ layout: "hero",
+ colors: {
+ primary: "#9b3f1e",
+ secondary: "#2b8e79",
+ accent: "#2b448e"
+ },
+ fonts: {
+ heading: "pixelon",
+ body: "oxygen",
+ code: "hack"
+ }
+};</pre>
+
+ <h2>Content Structure</h2>
+ <ul>
+ <li>Clean, readable typography with 16px base font size</li>
+ <li>Heading scale ratio of 4.24x for visual hierarchy</li>
+ <li>Line height of 1.48 for comfortable reading</li>
+ <li>Hero layout optimized for content flow</li>
+ <li>Light theme with split complementary color harmony</li>
+ </ul>
+
+ <h2>Font Licensing</h2>
+ <p>All fonts used in this theme are properly licensed:</p>
+ <ul>
+ <li>pixelon: Free License</li>
+ <li>oxygen: OFL License</li>
+ <li>hack: MIT License</li>
+ </ul>
+
+ <h3>Final Thoughts</h3>
+ <p>Every element of this theme has been carefully designed to create a harmonious reading experience. The hero layout ensures content is presented in an engaging way, while the color scheme provides the perfect backdrop for your words to shine.</p>
+
+ <p>Whether you're writing technical documentation, creative prose, or anything in between, this theme adapts to showcase your content beautifully.</p>
+ </div>
+</body>
+</html> \ No newline at end of file
diff --git a/extras/html/themes/ethereal_mist/handnotes.ttf b/extras/html/themes/ethereal_mist/handnotes.ttf
new file mode 100644
index 0000000..25e688b
--- /dev/null
+++ b/extras/html/themes/ethereal_mist/handnotes.ttf
Binary files differ
diff --git a/extras/html/themes/ethereal_mist/heading.ttf b/extras/html/themes/ethereal_mist/heading.ttf
new file mode 100644
index 0000000..acb3c81
--- /dev/null
+++ b/extras/html/themes/ethereal_mist/heading.ttf
Binary files differ
diff --git a/extras/html/themes/ethereal_mist/style.css b/extras/html/themes/ethereal_mist/style.css
new file mode 100644
index 0000000..71d976a
--- /dev/null
+++ b/extras/html/themes/ethereal_mist/style.css
@@ -0,0 +1,176 @@
+/* Base styles */
+@font-face {
+ font-family: 'text';
+ src: url("./text.ttf") format("truetype");
+}
+
+@font-face {
+ font-family: 'heading';
+ src: url("./heading.ttf") format("truetype");
+}
+
+@font-face {
+ font-family: 'code';
+ src: url("./code.ttf") format("truetype");
+}
+
+@font-face {
+ font-family: 'handnotes';
+ src: url("./handnotes.ttf") format("truetype");
+}
+
+:root {
+ --color-primary: #9b3f1e;
+ --color-secondary: #2b8e79;
+ --color-accent: #2b448e;
+ --color-bg: #f0eeed;
+ --color-text: #191919;
+ --font-size-base: 16px;
+ --font-size-h1: 4.24em;
+ --font-size-h2: 2.62em;
+ --font-size-h3: 1.62em;
+ --line-height: 1.48;
+}
+
+* {
+ box-sizing: border-box;
+}
+
+html {
+ font-size: var(--font-size-base);
+ -webkit-font-smoothing: antialiased;
+ -moz-osx-font-smoothing: grayscale;
+}
+
+body {
+ font-family: text, sans-serif;
+ background-color: var(--color-bg);
+ color: var(--color-text);
+ line-height: var(--line-height);
+ margin: 0;
+ padding: 0;
+ overflow-wrap: break-word;
+}
+
+h1, h2, h3 {
+ font-family: heading, serif;
+ line-height: 1.2;
+ margin-top: 1em;
+ margin-bottom: 0.5em;
+}
+
+h1 {
+ font-size: var(--font-size-h1);
+ color: var(--color-primary);
+}
+
+h2 {
+ font-size: var(--font-size-h2);
+ color: var(--color-primary);
+}
+
+h3 {
+ font-size: var(--font-size-h3);
+ color: var(--color-secondary);
+}
+
+a {
+ font-family: code, monospace;
+ color: var(--color-secondary);
+ text-decoration: none;
+ transition: all 0.3s ease;
+}
+
+a:hover {
+ color: var(--color-accent);
+ text-decoration: underline;
+}
+
+.textlink {
+ font-family: text, sans-serif;
+}
+
+.quote {
+ font-family: handnotes, cursive;
+ border-left: 4px solid var(--color-accent);
+ padding: 1em 1.5em;
+ margin: 1.5em 0;
+ background-color: rgba(155, 63, 30, 0.07);
+ font-style: italic;
+}
+
+pre {
+ font-family: code, monospace;
+ background-color: rgba(25, 25, 25, 0.04);
+ border: 1px solid rgba(25, 25, 25, 0.13);
+ padding: 1em;
+ overflow-x: auto;
+ border-radius: 4px;
+ font-size: 0.9em;
+}
+
+code {
+ font-family: code, monospace;
+ background-color: rgba(25, 25, 25, 0.04);
+ padding: 0.2em 0.4em;
+ border-radius: 3px;
+ font-size: 0.9em;
+}
+
+ul, ol {
+ padding-left: 2em;
+ margin: 1em 0;
+}
+
+li {
+ margin: 0.5em 0;
+}
+
+img {
+ max-width: 100%;
+ height: auto;
+}
+
+hr {
+ border: none;
+ border-top: 1px solid rgba(25, 25, 25, 0.20);
+ margin: 2em 0;
+}
+
+
+/* Layout: hero */
+
+body {
+ margin: 0;
+ padding: 0;
+}
+
+.header {
+ min-height: 80vh;
+ display: flex;
+ flex-direction: column;
+ justify-content: center;
+ align-items: center;
+ background: linear-gradient(135deg, rgba(155, 63, 30, 0.80), rgba(43, 142, 121, 0.80)), linear-gradient(45deg, rgba(43, 68, 142, 0.13), transparent);
+ color: var(--color-bg);
+ text-align: center;
+ position: relative;
+}
+
+.header h1 {
+ font-size: 5em;
+ margin: 0;
+ color: var(--color-bg);
+ text-shadow: 0 4px 8px rgba(0,0,0,0.3);
+}
+
+.header p {
+ font-size: 1.5em;
+ opacity: 0.9;
+}
+
+.content {
+ max-width: 65ch;
+ margin: 4em auto;
+ padding: 0 2em;
+}
diff --git a/extras/html/themes/ethereal_mist/theme.conf b/extras/html/themes/ethereal_mist/theme.conf
new file mode 100644
index 0000000..0f62152
--- /dev/null
+++ b/extras/html/themes/ethereal_mist/theme.conf
@@ -0,0 +1,8 @@
+declare -xr HTML_HEADER=./extras/html/header.html.part
+declare -xr HTML_FOOTER=./extras/html/footer.html.part
+declare -xr HTML_CSS_STYLE=$HTML_THEME_DIR/style.css
+declare -xr HTML_WEBFONT_HEADING=./extras/html/fonts/pixelon/pixelon-Bold.ttf
+declare -xr HTML_WEBFONT_TEXT=./extras/html/fonts/oxygen/oxygen-Regular.ttf
+declare -xr HTML_WEBFONT_CODE=./extras/html/fonts/hack/hack-Regular.ttf
+declare -xr HTML_WEBFONT_HANDNOTES=./extras/html/fonts/khand/khand.ttf
+declare -xr SOURCE_HIGHLIGHT_CSS=./extras/html/source-highlight-styles/mono.css
diff --git a/extras/html/themes/fix_css_validation.py b/extras/html/themes/fix_css_validation.py
new file mode 100755
index 0000000..4d2b45e
--- /dev/null
+++ b/extras/html/themes/fix_css_validation.py
@@ -0,0 +1,196 @@
+#!/usr/bin/env python3
+
+import os
+import re
+from pathlib import Path
+
+def hex_to_rgba(hex_color):
+ """Convert hex color with alpha to rgba format"""
+ if len(hex_color) == 9: # #RRGGBBAA
+ r = int(hex_color[1:3], 16)
+ g = int(hex_color[3:5], 16)
+ b = int(hex_color[5:7], 16)
+ a = int(hex_color[7:9], 16) / 255
+ return f"rgba({r}, {g}, {b}, {a:.2f})"
+ elif len(hex_color) == 5: # #RGBA
+ r = int(hex_color[1] * 2, 16)
+ g = int(hex_color[2] * 2, 16)
+ b = int(hex_color[3] * 2, 16)
+ a = int(hex_color[4] * 2, 16) / 255
+ return f"rgba({r}, {g}, {b}, {a:.2f})"
+ return hex_color
+
+def fix_css_file(css_path):
+ """Fix CSS validation issues in a single file"""
+ with open(css_path, 'r') as f:
+ content = f.read()
+
+ original_content = content
+
+ # Fix hex colors with alpha channel (8 digits or 4 digits)
+ # Match #RRGGBBAA or #RGBA patterns
+ hex_alpha_pattern = r'#([0-9a-fA-F]{8}|[0-9a-fA-F]{4})\b'
+
+ def replace_hex_alpha(match):
+ return hex_to_rgba(match.group(0))
+
+ content = re.sub(hex_alpha_pattern, replace_hex_alpha, content)
+
+ # Fix color + percentage opacity patterns like {colors['text']}0A
+ opacity_pattern = r'\{[^}]+\}([0-9A-Fa-f]{2})\b'
+ content = re.sub(opacity_pattern, lambda m: f"rgba(0, 0, 0, {int(m.group(1), 16) / 255:.2f})", content)
+
+ # Fix vendor prefixes - ensure they're properly formatted
+ content = re.sub(r'-webkit-font-smoothing:\s*antialiased;', '-webkit-font-smoothing: antialiased;', content)
+ content = re.sub(r'-moz-osx-font-smoothing:\s*grayscale;', '-moz-osx-font-smoothing: grayscale;', content)
+
+ # Fix word-wrap (deprecated) to overflow-wrap
+ content = re.sub(r'word-wrap:\s*break-word;', 'overflow-wrap: break-word;', content)
+
+ # Fix any background-clip issues
+ content = re.sub(r'-webkit-background-clip:\s*text;', '-webkit-background-clip: text;', content)
+ content = re.sub(r'background-clip:\s*text;', '', content) # Remove non-webkit background-clip: text
+
+ # Fix -webkit-text-fill-color
+ content = re.sub(r'-webkit-text-fill-color:\s*transparent;', '-webkit-text-fill-color: transparent;', content)
+
+ # Ensure proper CSS comments
+ content = re.sub(r'/\*([^*]|\*[^/])*\*/', lambda m: m.group(0), content)
+
+ # Fix @import statements if they exist
+ content = re.sub(r'@import\s+url\([\'"]([^\'")]+)[\'"]\)([^;]*);', r'@import url("\1")\2;', content)
+
+ # Fix any remaining color notations that might be invalid
+ # Look for patterns like #0f01 and convert to rgba
+ short_alpha_pattern = r'#([0-9a-fA-F]{3})([0-9a-fA-F]{1})\b'
+
+ def replace_short_alpha(match):
+ rgb = match.group(1)
+ alpha = match.group(2)
+ r = int(rgb[0] * 2, 16)
+ g = int(rgb[1] * 2, 16)
+ b = int(rgb[2] * 2, 16)
+ a = int(alpha * 2, 16) / 255
+ return f"rgba({r}, {g}, {b}, {a:.2f})"
+
+ content = re.sub(short_alpha_pattern, replace_short_alpha, content)
+
+ # Ensure all font-family declarations have proper fallbacks
+ content = re.sub(r'font-family:\s*([\'"]?)text\1,\s*sans-serif;', 'font-family: text, sans-serif;', content)
+ content = re.sub(r'font-family:\s*([\'"]?)heading\1,\s*serif;', 'font-family: heading, serif;', content)
+ content = re.sub(r'font-family:\s*([\'"]?)code\1,\s*monospace;', 'font-family: code, monospace;', content)
+ content = re.sub(r'font-family:\s*([\'"]?)handnotes\1,\s*cursive;', 'font-family: handnotes, cursive;', content)
+
+ # Fix any clip-path issues
+ content = re.sub(r'clip-path:\s*polygon\(([^)]+)\);', lambda m: f'clip-path: polygon({m.group(1)});', content)
+
+ # Fix multi-line background declarations
+ # Find patterns where background or background-image spans multiple lines
+ lines = content.split('\n')
+ fixed_lines = []
+ i = 0
+ while i < len(lines):
+ line = lines[i]
+ # Check if this line contains background/background-image without semicolon
+ if ('background:' in line or 'background-image:' in line) and not line.strip().endswith(';'):
+ # Collect all lines until we find a semicolon
+ combined_line = line
+ i += 1
+ while i < len(lines) and not lines[i-1].strip().endswith(';'):
+ combined_line += ' ' + lines[i].strip()
+ i += 1
+ fixed_lines.append(combined_line)
+ else:
+ fixed_lines.append(line)
+ i += 1
+
+ content = '\n'.join(fixed_lines)
+
+ # Fix specific SVG data URLs in background-image
+ content = re.sub(r'background-image:\s*url\(\'data:image/svg\+xml;utf8,([^\']+)\'\)\s*,',
+ r"background-image: url('data:image/svg+xml;utf8,\1'),", content)
+
+ # Fix text-shadow and box-shadow declarations spanning multiple lines
+ content = re.sub(r'text-shadow:\s*\n\s*', 'text-shadow: ', content)
+ content = re.sub(r'box-shadow:\s*\n\s*', 'box-shadow: ', content)
+
+ # Write back only if changes were made
+ if content != original_content:
+ with open(css_path, 'w') as f:
+ f.write(content)
+ return True
+ return False
+
+def fix_all_themes():
+ """Fix CSS validation issues in all theme files"""
+ themes_dir = Path("/home/paul/git/gemtexter/extras/html/themes")
+ fixed_count = 0
+
+ # Get all theme directories
+ theme_dirs = [d for d in themes_dir.iterdir() if d.is_dir() and d.name not in ['screenshots', '.git']]
+
+ print(f"Fixing CSS validation issues in {len(theme_dirs)} themes...")
+
+ for theme_dir in theme_dirs:
+ css_file = theme_dir / "style.css"
+ if css_file.exists():
+ if fix_css_file(css_file):
+ fixed_count += 1
+ print(f"Fixed: {theme_dir.name}")
+ else:
+ print(f"No fixes needed: {theme_dir.name}")
+
+ # Also check for override CSS files
+ for override_css in theme_dir.glob("*-override.css"):
+ if fix_css_file(override_css):
+ print(f"Fixed override: {override_css.name}")
+
+ print(f"\nFixed {fixed_count} theme CSS files")
+
+ # Also fix the main theme CSS files if they exist
+ main_themes = ["default", "simple", "business", "future", "retrosimple"]
+ for theme_name in main_themes:
+ theme_css = themes_dir / theme_name / "style.css"
+ if theme_css.exists():
+ if fix_css_file(theme_css):
+ print(f"Fixed main theme: {theme_name}")
+
+def validate_css_syntax(css_path):
+ """Basic CSS syntax validation"""
+ with open(css_path, 'r') as f:
+ content = f.read()
+
+ issues = []
+
+ # Check for unclosed brackets
+ open_braces = content.count('{')
+ close_braces = content.count('}')
+ if open_braces != close_braces:
+ issues.append(f"Mismatched braces: {open_braces} open, {close_braces} close")
+
+ # Check for missing semicolons (basic check)
+ lines = content.split('\n')
+ for i, line in enumerate(lines):
+ line = line.strip()
+ if line and not line.startswith('/*') and not line.endswith(('{', '}', ';', '*/')):
+ if ':' in line and not line.startswith('@'):
+ issues.append(f"Line {i+1}: Missing semicolon? '{line}'")
+
+ return issues
+
+if __name__ == "__main__":
+ fix_all_themes()
+
+ # Optional: Run basic validation
+ print("\nRunning basic CSS validation...")
+ themes_dir = Path("/home/paul/git/gemtexter/extras/html/themes")
+ theme_dirs = [d for d in themes_dir.iterdir() if d.is_dir() and d.name not in ['screenshots', '.git']]
+
+ for theme_dir in theme_dirs:
+ css_file = theme_dir / "style.css"
+ if css_file.exists():
+ issues = validate_css_syntax(css_file)
+ if issues:
+ print(f"\n{theme_dir.name}:")
+ for issue in issues:
+ print(f" - {issue}") \ No newline at end of file
diff --git a/extras/html/themes/fresh_field/LICENSE b/extras/html/themes/fresh_field/LICENSE
new file mode 100644
index 0000000..77097ad
--- /dev/null
+++ b/extras/html/themes/fresh_field/LICENSE
@@ -0,0 +1,21 @@
+Theme: fresh_field
+Generated: 2025-06-22 21:38:55
+
+Layout: terminal
+Color Scheme: complementary (Dark)
+
+Font Licenses:
+==============
+Heading Font: oxygen
+License: OFL
+Category: sans-serif
+
+Body Font: Merriweather
+License: OFL
+Category: serif
+
+Code Font: intelone-mono
+License: OFL
+Category: monospace
+
+All fonts are free for personal use.
diff --git a/extras/html/themes/fresh_field/code.ttf b/extras/html/themes/fresh_field/code.ttf
new file mode 100644
index 0000000..2711179
--- /dev/null
+++ b/extras/html/themes/fresh_field/code.ttf
Binary files differ
diff --git a/extras/html/themes/fresh_field/example.html b/extras/html/themes/fresh_field/example.html
new file mode 100644
index 0000000..e4f8dc8
--- /dev/null
+++ b/extras/html/themes/fresh_field/example.html
@@ -0,0 +1,75 @@
+<!DOCTYPE html>
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
+<head>
+ <meta charset="UTF-8" />
+ <meta name="viewport" content="width=device-width, initial-scale=1.0" />
+ <title>Fresh Field - Gemtexter Theme</title>
+ <link rel="stylesheet" href="style.css" />
+</head>
+<body>
+ <div class="header">
+ <h1>Fresh Field</h1>
+ <p>A terminal layout with complementary colors</p>
+ </div>
+
+ <div class="content">
+ <h1>Welcome to Fresh Field</h1>
+ <p>This theme features a carefully crafted terminal layout with a dark complementary color scheme. The typography combines sans-serif fonts for headings with serif for body text.</p>
+
+ <h2>Typography Showcase</h2>
+ <p>The Merriweather font family provides excellent readability for body text, while oxygen adds character to headings. Code blocks use intelone-mono for clarity.</p>
+
+ <h2>Color Palette</h2>
+ <p>Primary: <span style="color: #7a82e7; font-weight: bold;">#7a82e7</span> |
+ Secondary: <span style="color: #dcd685; font-weight: bold;">#dcd685</span> |
+ Accent: <span style="color: #5d65bd; font-weight: bold;">#5d65bd</span></p>
+
+ <h3>Interactive Elements</h3>
+ <p>Links like <a href="#">this example</a> and longer <a href="#" class="textlink">text links that demonstrate the theme's navigation style</a> use the secondary color.</p>
+
+ <div class="quote">
+ "Design is not just what it looks like and feels like. Design is how it works." — Steve Jobs
+ </div>
+
+ <h3>Code Examples</h3>
+ <p>Inline code like <code>theme.generate()</code> and larger blocks:</p>
+ <pre>// Theme configuration
+const theme = {
+ name: "fresh_field",
+ layout: "terminal",
+ colors: {
+ primary: "#7a82e7",
+ secondary: "#dcd685",
+ accent: "#5d65bd"
+ },
+ fonts: {
+ heading: "oxygen",
+ body: "Merriweather",
+ code: "intelone-mono"
+ }
+};</pre>
+
+ <h2>Content Structure</h2>
+ <ul>
+ <li>Clean, readable typography with 15px base font size</li>
+ <li>Heading scale ratio of 2.83x for visual hierarchy</li>
+ <li>Line height of 1.78 for comfortable reading</li>
+ <li>Terminal layout optimized for content flow</li>
+ <li>Dark theme with complementary color harmony</li>
+ </ul>
+
+ <h2>Font Licensing</h2>
+ <p>All fonts used in this theme are properly licensed:</p>
+ <ul>
+ <li>oxygen: OFL License</li>
+ <li>Merriweather: OFL License</li>
+ <li>intelone-mono: OFL License</li>
+ </ul>
+
+ <h3>Final Thoughts</h3>
+ <p>Every element of this theme has been carefully designed to create a harmonious reading experience. The terminal layout ensures content is presented in an engaging way, while the color scheme provides the perfect backdrop for your words to shine.</p>
+
+ <p>Whether you're writing technical documentation, creative prose, or anything in between, this theme adapts to showcase your content beautifully.</p>
+ </div>
+</body>
+</html> \ No newline at end of file
diff --git a/extras/html/themes/fresh_field/handnotes.ttf b/extras/html/themes/fresh_field/handnotes.ttf
new file mode 100644
index 0000000..25e688b
--- /dev/null
+++ b/extras/html/themes/fresh_field/handnotes.ttf
Binary files differ
diff --git a/extras/html/themes/fresh_field/style.css b/extras/html/themes/fresh_field/style.css
new file mode 100644
index 0000000..48e7c61
--- /dev/null
+++ b/extras/html/themes/fresh_field/style.css
@@ -0,0 +1,216 @@
+/* Base styles */
+@font-face {
+ font-family: 'text';
+ src: url("./text.ttf") format("truetype");
+}
+
+@font-face {
+ font-family: 'heading';
+ src: url("./heading.ttf") format("truetype");
+}
+
+@font-face {
+ font-family: 'code';
+ src: url("./code.ttf") format("truetype");
+}
+
+@font-face {
+ font-family: 'handnotes';
+ src: url("./handnotes.ttf") format("truetype");
+}
+
+:root {
+ --color-primary: #7a82e7;
+ --color-secondary: #dcd685;
+ --color-accent: #5d65bd;
+ --color-bg: #101114;
+ --color-text: #ebebeb;
+ --font-size-base: 15px;
+ --font-size-h1: 2.83em;
+ --font-size-h2: 2.0em;
+ --font-size-h3: 1.41em;
+ --line-height: 1.78;
+}
+
+* {
+ box-sizing: border-box;
+}
+
+html {
+ font-size: var(--font-size-base);
+ -webkit-font-smoothing: antialiased;
+ -moz-osx-font-smoothing: grayscale;
+}
+
+body {
+ font-family: text, sans-serif;
+ background-color: var(--color-bg);
+ color: var(--color-text);
+ line-height: var(--line-height);
+ margin: 0;
+ padding: 0;
+ overflow-wrap: break-word;
+}
+
+h1, h2, h3 {
+ font-family: heading, serif;
+ line-height: 1.2;
+ margin-top: 1em;
+ margin-bottom: 0.5em;
+}
+
+h1 {
+ font-size: var(--font-size-h1);
+ color: var(--color-primary);
+}
+
+h2 {
+ font-size: var(--font-size-h2);
+ color: var(--color-primary);
+}
+
+h3 {
+ font-size: var(--font-size-h3);
+ color: var(--color-secondary);
+}
+
+a {
+ font-family: code, monospace;
+ color: var(--color-secondary);
+ text-decoration: none;
+ transition: all 0.3s ease;
+}
+
+a:hover {
+ color: var(--color-accent);
+ text-decoration: underline;
+}
+
+.textlink {
+ font-family: text, sans-serif;
+}
+
+.quote {
+ font-family: handnotes, cursive;
+ border-left: 4px solid var(--color-accent);
+ padding: 1em 1.5em;
+ margin: 1.5em 0;
+ background-color: rgba(122, 130, 231, 0.07);
+ font-style: italic;
+}
+
+pre {
+ font-family: code, monospace;
+ background-color: rgba(235, 235, 235, 0.04);
+ border: 1px solid rgba(235, 235, 235, 0.13);
+ padding: 1em;
+ overflow-x: auto;
+ border-radius: 4px;
+ font-size: 0.9em;
+}
+
+code {
+ font-family: code, monospace;
+ background-color: rgba(235, 235, 235, 0.04);
+ padding: 0.2em 0.4em;
+ border-radius: 3px;
+ font-size: 0.9em;
+}
+
+ul, ol {
+ padding-left: 2em;
+ margin: 1em 0;
+}
+
+li {
+ margin: 0.5em 0;
+}
+
+img {
+ max-width: 100%;
+ height: auto;
+}
+
+hr {
+ border: none;
+ border-top: 1px solid rgba(235, 235, 235, 0.20);
+ margin: 2em 0;
+}
+
+
+/* Layout: terminal */
+
+@import url("https://fonts.googleapis.com/css2?family=Source+Code+Pro:wght@400;700&display=swap");
+
+body {
+ background-color: #000;
+ color: #0f0;
+ font-family: 'Source Code Pro', code, monospace;
+ padding: 1em;
+ line-height: 1.4;
+}
+
+.header {
+ border: 2px solid #0f0;
+ padding: 1em;
+ margin-bottom: 2em;
+ position: relative;
+}
+
+.header::before {
+ content: "[SYSTEM] ";
+ color: #ff0;
+}
+
+h1, h2, h3 {
+ color: #0f0;
+ font-family: 'Source Code Pro', code, monospace;
+}
+
+h1::before {
+ content: "### ";
+ color: #f0f;
+}
+
+h2::before {
+ content: "## ";
+ color: #0ff;
+}
+
+h3::before {
+ content: "# ";
+ color: #ff0;
+}
+
+p::before {
+ content: "> ";
+ color: #666;
+}
+
+a {
+ color: #0ff;
+ text-decoration: underline;
+}
+
+a:hover {
+ background-color: #0ff;
+ color: #000;
+}
+
+.quote {
+ border: 1px dashed #0f0;
+ background-color: #0f0111;
+ color: #0f0;
+}
+
+pre {
+ background-color: #111;
+ border: 1px solid #0f0;
+ color: #0f0;
+ overflow-x: scroll;
+}
+
+pre::before {
+ content: "$ cat output.log\A";
+ color: #666;
+}
diff --git a/extras/html/themes/fresh_field/text.ttf b/extras/html/themes/fresh_field/text.ttf
new file mode 100644
index 0000000..3fecc77
--- /dev/null
+++ b/extras/html/themes/fresh_field/text.ttf
Binary files differ
diff --git a/extras/html/themes/fresh_field/theme.conf b/extras/html/themes/fresh_field/theme.conf
new file mode 100644
index 0000000..11ad64d
--- /dev/null
+++ b/extras/html/themes/fresh_field/theme.conf
@@ -0,0 +1,8 @@
+declare -xr HTML_HEADER=./extras/html/header.html.part
+declare -xr HTML_FOOTER=./extras/html/footer.html.part
+declare -xr HTML_CSS_STYLE=$HTML_THEME_DIR/style.css
+declare -xr HTML_WEBFONT_HEADING=./extras/html/fonts/oxygen/oxygen-Bold.ttf
+declare -xr HTML_WEBFONT_TEXT=./extras/html/fonts/Merriweather/Merriweather-Regular.ttf
+declare -xr HTML_WEBFONT_CODE=./extras/html/fonts/intelone-mono/intelone-mono-Regular.ttf
+declare -xr HTML_WEBFONT_HANDNOTES=./extras/html/fonts/khand/khand.ttf
+declare -xr SOURCE_HIGHLIGHT_CSS=./extras/html/source-highlight-styles/mono.css
diff --git a/extras/html/themes/future/style.css b/extras/html/themes/future/style.css
index 3441ec9..268ee9b 100644
--- a/extras/html/themes/future/style.css
+++ b/extras/html/themes/future/style.css
@@ -32,13 +32,8 @@ html {
--c4: #33152e;
--c5: #414352;
- --_g: conic-gradient(from 30deg at 50% 25%,#0000 300deg,var(--c1) 0);
- background:
- var(--_g) calc(0.2885*var(--s)) calc(7*var(--s)/12),
- var(--_g) 0 calc(var(--s)/12),
- conic-gradient(from 120deg at 50% calc(250%/3),var(--c2) 120deg,#0000 0),
- repeating-conic-gradient(from 30deg,#0000 0 60deg,var(--c3) 0 120deg),
- repeating-conic-gradient(var(--c4) 0 60deg,var(--c2) 0 120deg,var(--c5) 0 180deg);
+ --_g: conic-gradient(from 30deg at 50% 25%,rgba(0, 0, 0, 0.00) 300deg,var(--c1) 0);
+ background: var(--_g) calc(0.2885*var(--s)) calc(7*var(--s)/12), var(--_g) 0 calc(var(--s)/12), conic-gradient(from 120deg at 50% calc(250%/3),var(--c2) 120deg,rgba(0, 0, 0, 0.00) 0), repeating-conic-gradient(from 30deg,rgba(0, 0, 0, 0.00) 0 60deg,var(--c3) 0 120deg), repeating-conic-gradient(var(--c4) 0 60deg,var(--c2) 0 120deg,var(--c5) 0 180deg);
background-size: calc(0.577*var(--s)) var(--s);
}
@@ -52,7 +47,7 @@ body {
border: 5px double #ff6347;
box-shadow: 0 4px 15px rgba(0, 0, 0, 0.3);
border-radius: 15px;
- word-wrap: break-word;
+ overflow-wrap: break-word;
}
h1, h2, h3 {
diff --git a/extras/html/themes/generate_50_themes.py b/extras/html/themes/generate_50_themes.py
new file mode 100755
index 0000000..6b166de
--- /dev/null
+++ b/extras/html/themes/generate_50_themes.py
@@ -0,0 +1,1741 @@
+#!/usr/bin/env python3
+
+import os
+import random
+import colorsys
+from pathlib import Path
+import shutil
+import subprocess
+from datetime import datetime
+import concurrent.futures
+from PIL import Image, ImageDraw, ImageFont
+import json
+
+# Theme names components
+ADJECTIVES = [
+ "cosmic", "serene", "vibrant", "minimal", "bold", "elegant", "modern", "classic",
+ "dynamic", "subtle", "refined", "crisp", "warm", "cool", "fresh", "clean",
+ "sharp", "smooth", "bright", "deep", "light", "rich", "soft", "strong",
+ "pure", "clear", "radiant", "muted", "vivid", "gentle", "sleek", "cozy",
+ "ethereal", "mystic", "zen", "urban", "rustic", "electric", "pastel", "neon",
+ "aurora", "twilight", "frost", "ember", "jade", "sapphire", "ruby", "amber"
+]
+
+NOUNS = [
+ "wave", "sky", "forest", "ocean", "mountain", "valley", "desert", "river",
+ "lake", "field", "garden", "meadow", "storm", "breeze", "mist", "frost",
+ "flame", "spark", "glow", "shadow", "light", "dawn", "dusk", "night",
+ "day", "season", "horizon", "vista", "peak", "flow", "cascade", "canyon",
+ "oasis", "glacier", "nebula", "cosmos", "prism", "crystal", "ember", "aurora",
+ "echo", "whisper", "dream", "voyage", "odyssey", "zen", "pulse", "rhythm"
+]
+
+# Font combinations with licensing info
+FONT_COMBINATIONS = [
+ # Sans-serif combinations
+ {"heading": ("Abril_Fatface", "OFL", "display"), "body": ("Lato", "OFL", "sans-serif"), "code": ("consola-mono", "OFL", "monospace")},
+ {"heading": ("oxygen", "OFL", "sans-serif"), "body": ("Lato", "OFL", "sans-serif"), "code": ("hack", "MIT", "monospace")},
+ {"heading": ("roboto-slab", "Apache", "serif"), "body": ("oxygen", "OFL", "sans-serif"), "code": ("intelone-mono", "OFL", "monospace")},
+ {"heading": ("Merriweather", "OFL", "serif"), "body": ("oxygen", "OFL", "sans-serif"), "code": ("hack", "MIT", "monospace")},
+ {"heading": ("higher-jump", "Free", "display"), "body": ("Lato", "OFL", "sans-serif"), "code": ("consola-mono", "OFL", "monospace")},
+ {"heading": ("pixelon", "Free", "display"), "body": ("oxygen", "OFL", "sans-serif"), "code": ("hack", "MIT", "monospace")},
+ {"heading": ("repetition-scrolling", "Free", "display"), "body": ("Merriweather", "OFL", "serif"), "code": ("intelone-mono", "OFL", "monospace")},
+ {"heading": ("zai-aeg-mignon-typewriter-1924", "Free", "display"), "body": ("roboto-slab", "Apache", "serif"), "code": ("hack", "MIT", "monospace")},
+ {"heading": ("khand", "Free", "handwriting"), "body": ("Lato", "OFL", "sans-serif"), "code": ("consola-mono", "OFL", "monospace")},
+ {"heading": ("Abril_Fatface", "OFL", "display"), "body": ("Merriweather", "OFL", "serif"), "code": ("hack", "MIT", "monospace")},
+ # More variations
+ {"heading": ("roboto-slab", "Apache", "serif"), "body": ("Lato", "OFL", "sans-serif"), "code": ("consola-mono", "OFL", "monospace")},
+ {"heading": ("oxygen", "OFL", "sans-serif"), "body": ("Merriweather", "OFL", "serif"), "code": ("intelone-mono", "OFL", "monospace")},
+ {"heading": ("Merriweather", "OFL", "serif"), "body": ("roboto-slab", "Apache", "serif"), "code": ("hack", "MIT", "monospace")},
+ {"heading": ("higher-jump", "Free", "display"), "body": ("oxygen", "OFL", "sans-serif"), "code": ("intelone-mono", "OFL", "monospace")},
+ {"heading": ("pixelon", "Free", "display"), "body": ("roboto-slab", "Apache", "serif"), "code": ("consola-mono", "OFL", "monospace")},
+]
+
+# Layout types
+LAYOUTS = [
+ "centered", "wide", "magazine", "card", "asymmetric", "minimal_grid",
+ "brutalist", "newspaper", "terminal", "book", "sidebar", "hero",
+ "masonry", "split", "overlap", "floating", "gradient", "geometric",
+ "swiss", "retro", "future", "organic", "technical", "artistic"
+]
+
+def generate_color_palette():
+ """Generate a harmonious color palette"""
+ palette_type = random.choice(["complementary", "triadic", "analogous", "monochromatic", "split_complementary"])
+
+ base_hue = random.random()
+ base_saturation = random.uniform(0.3, 0.9)
+ base_lightness = random.uniform(0.3, 0.7)
+
+ # Determine if dark or light theme
+ is_dark = random.random() > 0.5
+
+ if is_dark:
+ bg_lightness = random.uniform(0.05, 0.15)
+ text_lightness = random.uniform(0.85, 0.95)
+ else:
+ bg_lightness = random.uniform(0.92, 0.98)
+ text_lightness = random.uniform(0.05, 0.15)
+
+ # Generate colors based on palette type
+ if palette_type == "complementary":
+ primary_rgb = colorsys.hls_to_rgb(base_hue, base_lightness, base_saturation)
+ secondary_hue = (base_hue + 0.5) % 1.0
+ secondary_rgb = colorsys.hls_to_rgb(secondary_hue, base_lightness, base_saturation * 0.8)
+ accent_rgb = colorsys.hls_to_rgb(base_hue, base_lightness * 0.8, base_saturation * 0.6)
+ elif palette_type == "triadic":
+ primary_rgb = colorsys.hls_to_rgb(base_hue, base_lightness, base_saturation)
+ secondary_hue = (base_hue + 0.333) % 1.0
+ secondary_rgb = colorsys.hls_to_rgb(secondary_hue, base_lightness, base_saturation)
+ accent_hue = (base_hue + 0.667) % 1.0
+ accent_rgb = colorsys.hls_to_rgb(accent_hue, base_lightness, base_saturation)
+ elif palette_type == "analogous":
+ primary_rgb = colorsys.hls_to_rgb(base_hue, base_lightness, base_saturation)
+ secondary_hue = (base_hue + 0.08) % 1.0
+ secondary_rgb = colorsys.hls_to_rgb(secondary_hue, base_lightness, base_saturation * 0.9)
+ accent_hue = (base_hue - 0.08) % 1.0
+ accent_rgb = colorsys.hls_to_rgb(accent_hue, base_lightness * 0.9, base_saturation)
+ elif palette_type == "monochromatic":
+ primary_rgb = colorsys.hls_to_rgb(base_hue, base_lightness, base_saturation)
+ secondary_rgb = colorsys.hls_to_rgb(base_hue, base_lightness * 0.7, base_saturation * 0.8)
+ accent_rgb = colorsys.hls_to_rgb(base_hue, base_lightness * 1.2, base_saturation * 0.6)
+ else: # split_complementary
+ primary_rgb = colorsys.hls_to_rgb(base_hue, base_lightness, base_saturation)
+ secondary_hue = (base_hue + 0.42) % 1.0
+ secondary_rgb = colorsys.hls_to_rgb(secondary_hue, base_lightness, base_saturation * 0.8)
+ accent_hue = (base_hue + 0.58) % 1.0
+ accent_rgb = colorsys.hls_to_rgb(accent_hue, base_lightness, base_saturation * 0.8)
+
+ # Background and text colors
+ bg_rgb = colorsys.hls_to_rgb(base_hue, bg_lightness, 0.1)
+ text_rgb = colorsys.hls_to_rgb(0, text_lightness, 0)
+
+ # Convert to hex
+ primary = '#{:02x}{:02x}{:02x}'.format(int(primary_rgb[0]*255), int(primary_rgb[1]*255), int(primary_rgb[2]*255))
+ secondary = '#{:02x}{:02x}{:02x}'.format(int(secondary_rgb[0]*255), int(secondary_rgb[1]*255), int(secondary_rgb[2]*255))
+ accent = '#{:02x}{:02x}{:02x}'.format(int(accent_rgb[0]*255), int(accent_rgb[1]*255), int(accent_rgb[2]*255))
+ background = '#{:02x}{:02x}{:02x}'.format(int(bg_rgb[0]*255), int(bg_rgb[1]*255), int(bg_rgb[2]*255))
+ text = '#{:02x}{:02x}{:02x}'.format(int(text_rgb[0]*255), int(text_rgb[1]*255), int(text_rgb[2]*255))
+
+ return {
+ "primary": primary,
+ "secondary": secondary,
+ "accent": accent,
+ "background": background,
+ "text": text,
+ "is_dark": is_dark,
+ "palette_type": palette_type
+ }
+
+def generate_layout_css(layout_type, colors, font_sizes):
+ """Generate CSS for different layout types"""
+ base_css = f"""/* Base styles */
+@font-face {{
+ font-family: 'text';
+ src: url("./text.ttf") format("truetype");
+}}
+
+@font-face {{
+ font-family: 'heading';
+ src: url("./heading.ttf") format("truetype");
+}}
+
+@font-face {{
+ font-family: 'code';
+ src: url("./code.ttf") format("truetype");
+}}
+
+@font-face {{
+ font-family: 'handnotes';
+ src: url("./handnotes.ttf") format("truetype");
+}}
+
+:root {{
+ --color-primary: {colors['primary']};
+ --color-secondary: {colors['secondary']};
+ --color-accent: {colors['accent']};
+ --color-bg: {colors['background']};
+ --color-text: {colors['text']};
+ --font-size-base: {font_sizes['base']}px;
+ --font-size-h1: {font_sizes['h1']}em;
+ --font-size-h2: {font_sizes['h2']}em;
+ --font-size-h3: {font_sizes['h3']}em;
+ --line-height: {font_sizes['line_height']};
+}}
+
+* {{
+ box-sizing: border-box;
+}}
+
+html {{
+ font-size: var(--font-size-base);
+ -webkit-font-smoothing: antialiased;
+ -moz-osx-font-smoothing: grayscale;
+}}
+
+body {{
+ font-family: text, sans-serif;
+ background-color: var(--color-bg);
+ color: var(--color-text);
+ line-height: var(--line-height);
+ margin: 0;
+ padding: 0;
+ word-wrap: break-word;
+}}
+
+h1, h2, h3 {{
+ font-family: heading, serif;
+ line-height: 1.2;
+ margin-top: 1em;
+ margin-bottom: 0.5em;
+}}
+
+h1 {{
+ font-size: var(--font-size-h1);
+ color: var(--color-primary);
+}}
+
+h2 {{
+ font-size: var(--font-size-h2);
+ color: var(--color-primary);
+}}
+
+h3 {{
+ font-size: var(--font-size-h3);
+ color: var(--color-secondary);
+}}
+
+a {{
+ font-family: code, monospace;
+ color: var(--color-secondary);
+ text-decoration: none;
+ transition: all 0.3s ease;
+}}
+
+a:hover {{
+ color: var(--color-accent);
+ text-decoration: underline;
+}}
+
+.textlink {{
+ font-family: text, sans-serif;
+}}
+
+.quote {{
+ font-family: handnotes, cursive;
+ border-left: 4px solid var(--color-accent);
+ padding: 1em 1.5em;
+ margin: 1.5em 0;
+ background-color: {colors['primary']}11;
+ font-style: italic;
+}}
+
+pre {{
+ font-family: code, monospace;
+ background-color: {colors['text']}0A;
+ border: 1px solid {colors['text']}22;
+ padding: 1em;
+ overflow-x: auto;
+ border-radius: 4px;
+ font-size: 0.9em;
+}}
+
+code {{
+ font-family: code, monospace;
+ background-color: {colors['text']}0A;
+ padding: 0.2em 0.4em;
+ border-radius: 3px;
+ font-size: 0.9em;
+}}
+
+ul, ol {{
+ padding-left: 2em;
+ margin: 1em 0;
+}}
+
+li {{
+ margin: 0.5em 0;
+}}
+
+img {{
+ max-width: 100%;
+ height: auto;
+}}
+
+hr {{
+ border: none;
+ border-top: 1px solid {colors['text']}33;
+ margin: 2em 0;
+}}
+"""
+
+ # Layout-specific CSS
+ layout_css = ""
+
+ if layout_type == "centered":
+ layout_css = """
+body {
+ max-width: 65ch;
+ margin: 0 auto;
+ padding: 2em 1em;
+}
+
+.header {
+ text-align: center;
+ margin-bottom: 3em;
+ padding-bottom: 2em;
+ border-bottom: 2px solid var(--color-primary);
+}
+"""
+ elif layout_type == "wide":
+ layout_css = """
+body {
+ max-width: 90%;
+ margin: 0 auto;
+ padding: 3em 2em;
+}
+
+.header {
+ display: flex;
+ justify-content: space-between;
+ align-items: baseline;
+ margin-bottom: 4em;
+ padding-bottom: 2em;
+ border-bottom: 3px solid var(--color-primary);
+}
+
+.content {
+ max-width: 75ch;
+ margin: 0 auto;
+}
+"""
+ elif layout_type == "magazine":
+ layout_css = """
+body {
+ max-width: 1400px;
+ margin: 0 auto;
+ padding: 2em;
+ display: grid;
+ grid-template-columns: 1fr 1fr 1fr;
+ gap: 2em;
+}
+
+.header {
+ grid-column: 1 / -1;
+ text-align: center;
+ margin-bottom: 2em;
+ padding: 3em 0;
+ background: linear-gradient(135deg, var(--color-primary)22, var(--color-secondary)22);
+}
+
+h1, h2 {
+ grid-column: 1 / -1;
+}
+
+p, ul, pre, .quote {
+ grid-column: span 1;
+}
+
+p:first-of-type {
+ grid-column: 1 / 3;
+ font-size: 1.2em;
+ line-height: 1.6;
+}
+"""
+ elif layout_type == "card":
+ layout_css = f"""
+body {{
+ padding: 2em;
+ background: linear-gradient(135deg, {colors['primary']}11, {colors['secondary']}11);
+ min-height: 100vh;
+}}
+
+.header {{
+ background-color: var(--color-bg);
+ padding: 3em;
+ margin-bottom: 3em;
+ border-radius: 16px;
+ box-shadow: 0 8px 32px rgba(0,0,0,0.1);
+ text-align: center;
+}}
+
+h1, h2, h3, p, ul, pre, .quote {{
+ background-color: var(--color-bg);
+ padding: 2em;
+ margin: 1em 0;
+ border-radius: 12px;
+ box-shadow: 0 4px 16px rgba(0,0,0,0.05);
+}}
+
+h1, h2, h3 {{
+ padding: 1em 2em;
+}}
+"""
+ elif layout_type == "asymmetric":
+ layout_css = """
+body {
+ max-width: 1200px;
+ margin: 0 auto;
+ padding: 2em;
+}
+
+.header {
+ margin-left: 20%;
+ margin-bottom: 4em;
+}
+
+h1 {
+ margin-left: -5%;
+ font-size: calc(var(--font-size-h1) * 1.2);
+}
+
+h2 {
+ margin-left: 10%;
+}
+
+h3 {
+ margin-left: 25%;
+}
+
+p:nth-child(odd) {
+ margin-left: 5%;
+ margin-right: 20%;
+}
+
+p:nth-child(even) {
+ margin-left: 20%;
+ margin-right: 5%;
+}
+
+.quote {
+ margin-left: 15%;
+ margin-right: 15%;
+ text-align: center;
+}
+"""
+ elif layout_type == "minimal_grid":
+ layout_css = """
+body {
+ display: grid;
+ grid-template-columns: repeat(12, 1fr);
+ gap: 1.5em;
+ padding: 3em 2em;
+ max-width: 1400px;
+ margin: 0 auto;
+}
+
+.header {
+ grid-column: 2 / 12;
+ text-align: center;
+ margin-bottom: 3em;
+ padding-bottom: 2em;
+ border-bottom: 1px solid var(--color-text);
+}
+
+h1 {
+ grid-column: 1 / 13;
+ text-align: center;
+}
+
+h2 {
+ grid-column: 2 / 12;
+}
+
+h3 {
+ grid-column: 3 / 11;
+}
+
+p, ul, pre {
+ grid-column: 3 / 11;
+}
+
+.quote {
+ grid-column: 2 / 12;
+ text-align: center;
+}
+"""
+ elif layout_type == "brutalist":
+ layout_css = f"""
+body {{
+ background-color: {colors['text']};
+ color: {colors['background']};
+ padding: 0;
+}}
+
+.header {{
+ background-color: var(--color-primary);
+ color: var(--color-bg);
+ padding: 4em 2em;
+ transform: skewY(-3deg);
+ margin-bottom: 4em;
+}}
+
+.header * {{
+ transform: skewY(3deg);
+}}
+
+h1, h2, h3 {{
+ background-color: var(--color-bg);
+ color: var(--color-text);
+ padding: 1em;
+ text-transform: uppercase;
+ letter-spacing: 0.2em;
+ margin: 0;
+}}
+
+p, ul, pre, .quote {{
+ background-color: var(--color-bg);
+ color: var(--color-text);
+ margin: 0;
+ padding: 2em;
+ border: 8px solid var(--color-primary);
+}}
+
+a {{
+ background-color: var(--color-secondary);
+ color: var(--color-bg);
+ padding: 0.3em 0.6em;
+ text-decoration: none;
+}}
+
+a:hover {{
+ background-color: var(--color-accent);
+}}
+"""
+ elif layout_type == "newspaper":
+ layout_css = """
+body {
+ max-width: 1200px;
+ margin: 0 auto;
+ padding: 2em;
+ columns: 3;
+ column-gap: 2em;
+ column-rule: 1px solid var(--color-text);
+}
+
+.header {
+ column-span: all;
+ text-align: center;
+ border-top: 6px double var(--color-text);
+ border-bottom: 6px double var(--color-text);
+ padding: 2em 0;
+ margin-bottom: 3em;
+}
+
+.header h1 {
+ font-size: 4em;
+ margin: 0;
+ letter-spacing: 0.1em;
+}
+
+h1, h2 {
+ column-span: all;
+ text-align: center;
+ margin: 2em 0 1em 0;
+}
+
+h3 {
+ break-after: avoid;
+}
+
+p {
+ text-align: justify;
+ hyphens: auto;
+}
+
+.quote {
+ column-span: all;
+ text-align: center;
+ font-size: 1.5em;
+ margin: 2em 0;
+}
+"""
+ elif layout_type == "terminal":
+ layout_css = f"""
+@import url('https://fonts.googleapis.com/css2?family=Source+Code+Pro:wght@400;700&display=swap');
+
+body {{
+ background-color: #000;
+ color: #0f0;
+ font-family: 'Source Code Pro', code, monospace;
+ padding: 1em;
+ line-height: 1.4;
+}}
+
+.header {{
+ border: 2px solid #0f0;
+ padding: 1em;
+ margin-bottom: 2em;
+ position: relative;
+}}
+
+.header::before {{
+ content: "[SYSTEM] ";
+ color: #ff0;
+}}
+
+h1, h2, h3 {{
+ color: #0f0;
+ font-family: 'Source Code Pro', code, monospace;
+}}
+
+h1::before {{
+ content: "### ";
+ color: #f0f;
+}}
+
+h2::before {{
+ content: "## ";
+ color: #0ff;
+}}
+
+h3::before {{
+ content: "# ";
+ color: #ff0;
+}}
+
+p::before {{
+ content: "> ";
+ color: #666;
+}}
+
+a {{
+ color: #0ff;
+ text-decoration: underline;
+}}
+
+a:hover {{
+ background-color: #0ff;
+ color: #000;
+}}
+
+.quote {{
+ border: 1px dashed #0f0;
+ background-color: #0f0111;
+ color: #0f0;
+}}
+
+pre {{
+ background-color: #111;
+ border: 1px solid #0f0;
+ color: #0f0;
+ overflow-x: scroll;
+}}
+
+pre::before {{
+ content: "$ cat output.log\\A";
+ color: #666;
+}}
+"""
+ elif layout_type == "book":
+ layout_css = """
+body {
+ max-width: 40em;
+ margin: 4em auto;
+ padding: 2em;
+ line-height: 1.8;
+ text-align: justify;
+ hyphens: auto;
+}
+
+.header {
+ text-align: center;
+ margin-bottom: 6em;
+ page-break-after: always;
+}
+
+.header h1 {
+ font-size: 3em;
+ margin-bottom: 0.5em;
+}
+
+h1 {
+ text-align: center;
+ margin: 3em 0 2em 0;
+ page-break-before: always;
+}
+
+h2 {
+ margin-top: 2em;
+ text-align: left;
+}
+
+p {
+ text-indent: 1.5em;
+ margin: 0;
+}
+
+p:first-of-type {
+ text-indent: 0;
+}
+
+p:first-of-type::first-letter {
+ font-size: 4em;
+ line-height: 1;
+ float: left;
+ margin: 0 0.1em 0 0;
+ font-family: heading, serif;
+ color: var(--color-primary);
+}
+
+.quote {
+ margin: 2em 2em;
+ text-align: center;
+ font-style: italic;
+}
+"""
+ elif layout_type == "sidebar":
+ layout_css = """
+body {
+ display: grid;
+ grid-template-columns: 300px 1fr;
+ min-height: 100vh;
+ margin: 0;
+}
+
+.header {
+ grid-column: 1;
+ position: sticky;
+ top: 0;
+ height: 100vh;
+ padding: 3em 2em;
+ background-color: var(--color-primary);
+ color: var(--color-bg);
+ overflow-y: auto;
+}
+
+.header h1 {
+ color: var(--color-bg);
+}
+
+.content {
+ grid-column: 2;
+ padding: 3em;
+ max-width: 65ch;
+}
+
+h1, h2, h3, p, ul, pre, .quote {
+ grid-column: 2;
+}
+"""
+ elif layout_type == "hero":
+ layout_css = f"""
+body {{
+ margin: 0;
+ padding: 0;
+}}
+
+.header {{
+ min-height: 80vh;
+ display: flex;
+ flex-direction: column;
+ justify-content: center;
+ align-items: center;
+ background: linear-gradient(135deg, {colors['primary']}CC, {colors['secondary']}CC),
+ linear-gradient(45deg, {colors['accent']}22, transparent);
+ color: var(--color-bg);
+ text-align: center;
+ position: relative;
+}}
+
+.header h1 {{
+ font-size: 5em;
+ margin: 0;
+ color: var(--color-bg);
+ text-shadow: 0 4px 8px rgba(0,0,0,0.3);
+}}
+
+.header p {{
+ font-size: 1.5em;
+ opacity: 0.9;
+}}
+
+.content {{
+ max-width: 65ch;
+ margin: 4em auto;
+ padding: 0 2em;
+}}
+"""
+ elif layout_type == "masonry":
+ layout_css = """
+body {
+ padding: 2em;
+ columns: 320px;
+ column-gap: 2em;
+}
+
+.header {
+ column-span: all;
+ text-align: center;
+ margin-bottom: 3em;
+ padding: 2em;
+ background: var(--color-primary);
+ color: var(--color-bg);
+}
+
+.header h1 {
+ color: var(--color-bg);
+}
+
+h1, h2 {
+ column-span: all;
+ text-align: center;
+ margin: 2em 0;
+}
+
+p, ul, pre, .quote, h3 {
+ break-inside: avoid;
+ margin-bottom: 2em;
+ padding: 1.5em;
+ background-color: var(--color-bg);
+ border: 1px solid var(--color-text)11;
+ border-radius: 8px;
+}
+"""
+ elif layout_type == "split":
+ layout_css = f"""
+body {{
+ display: grid;
+ grid-template-columns: 1fr 1fr;
+ min-height: 100vh;
+ margin: 0;
+}}
+
+.header {{
+ grid-column: 1;
+ background: linear-gradient(135deg, {colors['primary']}, {colors['secondary']});
+ color: var(--color-bg);
+ padding: 4em;
+ position: sticky;
+ top: 0;
+ height: 100vh;
+ display: flex;
+ flex-direction: column;
+ justify-content: center;
+}}
+
+.header h1 {{
+ color: var(--color-bg);
+ font-size: 3.5em;
+}}
+
+.content {{
+ grid-column: 2;
+ padding: 4em;
+ overflow-y: auto;
+}}
+
+h1, h2, h3, p, ul, pre, .quote {{
+ grid-column: 2;
+}}
+"""
+ elif layout_type == "overlap":
+ layout_css = f"""
+body {{
+ padding: 2em;
+ position: relative;
+ max-width: 1200px;
+ margin: 0 auto;
+}}
+
+.header {{
+ position: relative;
+ z-index: 10;
+ background-color: var(--color-bg);
+ padding: 3em;
+ margin-bottom: -2em;
+ box-shadow: 0 10px 40px rgba(0,0,0,0.1);
+ border: 2px solid var(--color-primary);
+}}
+
+h1 {{
+ font-size: 3.5em;
+ margin-top: 1em;
+ position: relative;
+ z-index: 5;
+}}
+
+h2 {{
+ margin-left: 2em;
+ position: relative;
+ z-index: 4;
+ background-color: var(--color-bg);
+ padding: 1em;
+ box-shadow: 0 4px 20px rgba(0,0,0,0.05);
+}}
+
+h3 {{
+ margin-left: 4em;
+ position: relative;
+ z-index: 3;
+}}
+
+p, ul, pre, .quote {{
+ position: relative;
+ background-color: var(--color-bg);
+ padding: 2em;
+ margin: 1em 0 1em 3em;
+ box-shadow: 0 4px 20px rgba(0,0,0,0.05);
+ border-left: 4px solid var(--color-accent);
+}}
+
+p:nth-child(even), ul:nth-child(even) {{
+ margin-left: 0;
+ margin-right: 3em;
+ border-left: none;
+ border-right: 4px solid var(--color-secondary);
+}}
+"""
+ elif layout_type == "floating":
+ layout_css = f"""
+body {{
+ padding: 4em 2em;
+ background: linear-gradient(45deg, {colors['primary']}11, {colors['secondary']}11);
+ min-height: 100vh;
+}}
+
+.header {{
+ text-align: center;
+ margin-bottom: 4em;
+ animation: float 6s ease-in-out infinite;
+}}
+
+@keyframes float {{
+ 0%, 100% {{ transform: translateY(0); }}
+ 50% {{ transform: translateY(-20px); }}
+}}
+
+h1, h2, h3, p, ul, pre, .quote {{
+ background-color: var(--color-bg);
+ padding: 2em;
+ margin: 2em auto;
+ max-width: 65ch;
+ border-radius: 16px;
+ box-shadow: 0 8px 32px rgba(0,0,0,0.1);
+ transition: transform 0.3s ease;
+}}
+
+h1:hover, h2:hover, h3:hover, p:hover, ul:hover, pre:hover, .quote:hover {{
+ transform: translateY(-4px);
+ box-shadow: 0 12px 48px rgba(0,0,0,0.15);
+}}
+"""
+ elif layout_type == "gradient":
+ layout_css = f"""
+body {{
+ margin: 0;
+ padding: 0;
+ background: linear-gradient(180deg,
+ {colors['primary']}22 0%,
+ {colors['secondary']}22 50%,
+ {colors['accent']}22 100%);
+ min-height: 100vh;
+}}
+
+.header {{
+ text-align: center;
+ padding: 6em 2em;
+ background: rgba(255,255,255,0.1);
+ backdrop-filter: blur(10px);
+ margin-bottom: 4em;
+}}
+
+h1, h2, h3, p, ul, pre, .quote {{
+ max-width: 65ch;
+ margin: 2em auto;
+ padding: 2em;
+ background: rgba(255,255,255,0.95);
+ backdrop-filter: blur(10px);
+ border-radius: 20px;
+ box-shadow: 0 8px 32px rgba(0,0,0,0.1);
+}}
+"""
+ elif layout_type == "geometric":
+ layout_css = f"""
+body {{
+ padding: 2em;
+ background-color: var(--color-bg);
+ background-image:
+ repeating-linear-gradient(45deg,
+ {colors['primary']}11 0,
+ {colors['primary']}11 10px,
+ transparent 10px,
+ transparent 20px),
+ repeating-linear-gradient(-45deg,
+ {colors['secondary']}11 0,
+ {colors['secondary']}11 10px,
+ transparent 10px,
+ transparent 20px);
+}}
+
+.header {{
+ background-color: var(--color-bg);
+ border: 4px solid var(--color-primary);
+ padding: 3em;
+ margin-bottom: 3em;
+ position: relative;
+ clip-path: polygon(0 0, 100% 0, 95% 100%, 5% 100%);
+}}
+
+h1, h2, h3 {{
+ position: relative;
+ padding-left: 2em;
+}}
+
+h1::before, h2::before, h3::before {{
+ content: "";
+ position: absolute;
+ left: 0;
+ top: 50%;
+ transform: translateY(-50%);
+ width: 1em;
+ height: 1em;
+ background-color: var(--color-accent);
+ clip-path: polygon(50% 0%, 100% 50%, 50% 100%, 0% 50%);
+}}
+
+p, ul, pre, .quote {{
+ background-color: var(--color-bg);
+ padding: 2em;
+ margin: 2em 0;
+ border-left: 4px solid var(--color-secondary);
+ position: relative;
+}}
+
+p::after, ul::after, pre::after, .quote::after {{
+ content: "";
+ position: absolute;
+ right: -10px;
+ top: 50%;
+ transform: translateY(-50%);
+ width: 20px;
+ height: 20px;
+ background-color: var(--color-accent);
+ clip-path: polygon(0% 0%, 100% 50%, 0% 100%);
+}}
+"""
+ elif layout_type == "swiss":
+ layout_css = """
+body {
+ max-width: 1200px;
+ margin: 0 auto;
+ padding: 2em;
+ display: grid;
+ grid-template-columns: repeat(6, 1fr);
+ gap: 2em;
+}
+
+.header {
+ grid-column: 1 / -1;
+ display: grid;
+ grid-template-columns: repeat(6, 1fr);
+ gap: 2em;
+ margin-bottom: 4em;
+ padding-bottom: 2em;
+ border-bottom: 4px solid var(--color-text);
+}
+
+.header h1 {
+ grid-column: 1 / 4;
+ font-size: 4em;
+ margin: 0;
+ line-height: 0.9;
+}
+
+.header p {
+ grid-column: 4 / -1;
+ align-self: end;
+}
+
+h1 {
+ grid-column: 1 / -1;
+ font-size: 3em;
+ margin: 1em 0 0.5em 0;
+}
+
+h2 {
+ grid-column: 1 / 5;
+ margin-top: 2em;
+}
+
+h3 {
+ grid-column: 2 / 6;
+}
+
+p, ul, pre {
+ grid-column: 2 / 6;
+}
+
+.quote {
+ grid-column: 1 / -1;
+ font-size: 1.5em;
+ text-align: center;
+ margin: 2em 0;
+}
+"""
+ elif layout_type == "retro":
+ layout_css = f"""
+@import url('https://fonts.googleapis.com/css2?family=Courier+Prime:wght@400;700&display=swap');
+
+body {{
+ background-color: #f4e8d0;
+ color: #2a2a2a;
+ padding: 2em;
+ position: relative;
+}}
+
+body::before {{
+ content: "";
+ position: fixed;
+ top: 0;
+ left: 0;
+ right: 0;
+ bottom: 0;
+ background-image:
+ repeating-linear-gradient(
+ 0deg,
+ transparent,
+ transparent 2px,
+ rgba(0,0,0,0.03) 2px,
+ rgba(0,0,0,0.03) 4px
+ );
+ pointer-events: none;
+ z-index: 1;
+}}
+
+.header {{
+ background-color: {colors['primary']};
+ color: #f4e8d0;
+ padding: 2em;
+ margin: -2em -2em 2em -2em;
+ text-align: center;
+ box-shadow: 0 4px 8px rgba(0,0,0,0.3);
+ position: relative;
+ z-index: 2;
+}}
+
+.header h1 {{
+ font-family: 'Courier Prime', monospace;
+ font-size: 3em;
+ margin: 0;
+ text-transform: uppercase;
+ letter-spacing: 0.1em;
+ color: #f4e8d0;
+}}
+
+h1, h2, h3 {{
+ font-family: 'Courier Prime', monospace;
+ text-transform: uppercase;
+ letter-spacing: 0.05em;
+ position: relative;
+ z-index: 2;
+}}
+
+p, ul, pre, .quote {{
+ background-color: rgba(255,255,255,0.8);
+ padding: 1.5em;
+ margin: 1em 0;
+ box-shadow: 2px 2px 4px rgba(0,0,0,0.1);
+ position: relative;
+ z-index: 2;
+}}
+
+a {{
+ color: {colors['secondary']};
+ text-decoration: underline;
+ text-decoration-style: wavy;
+}}
+"""
+ elif layout_type == "future":
+ layout_css = f"""
+body {{
+ background-color: #000;
+ color: #fff;
+ padding: 0;
+ margin: 0;
+ position: relative;
+ overflow-x: hidden;
+}}
+
+body::before {{
+ content: "";
+ position: fixed;
+ top: 0;
+ left: 0;
+ right: 0;
+ bottom: 0;
+ background:
+ radial-gradient(circle at 20% 50%, {colors['primary']}44 0%, transparent 50%),
+ radial-gradient(circle at 80% 80%, {colors['secondary']}44 0%, transparent 50%),
+ radial-gradient(circle at 40% 20%, {colors['accent']}44 0%, transparent 50%);
+ z-index: -1;
+}}
+
+.header {{
+ padding: 6em 2em;
+ text-align: center;
+ position: relative;
+}}
+
+.header h1 {{
+ font-size: 5em;
+ margin: 0;
+ background: linear-gradient(45deg, {colors['primary']}, {colors['secondary']}, {colors['accent']});
+ -webkit-background-clip: text;
+ -webkit-text-fill-color: transparent;
+ background-clip: text;
+ text-transform: uppercase;
+ letter-spacing: 0.2em;
+}}
+
+h1, h2, h3, p, ul, pre, .quote {{
+ max-width: 65ch;
+ margin: 2em auto;
+ padding: 2em;
+ background: rgba(255,255,255,0.05);
+ backdrop-filter: blur(10px);
+ border: 1px solid rgba(255,255,255,0.1);
+ border-radius: 20px;
+ box-shadow: 0 8px 32px rgba(0,0,0,0.2);
+}}
+
+a {{
+ color: {colors['accent']};
+ text-decoration: none;
+ position: relative;
+}}
+
+a::after {{
+ content: "";
+ position: absolute;
+ bottom: -2px;
+ left: 0;
+ right: 0;
+ height: 2px;
+ background: linear-gradient(90deg, {colors['primary']}, {colors['secondary']});
+ transform: scaleX(0);
+ transition: transform 0.3s ease;
+}}
+
+a:hover::after {{
+ transform: scaleX(1);
+}}
+"""
+ elif layout_type == "organic":
+ layout_css = f"""
+body {{
+ padding: 2em;
+ background-color: {colors['background']};
+ background-image:
+ radial-gradient(circle at 10% 20%, {colors['primary']}11 0%, transparent 50%),
+ radial-gradient(circle at 80% 80%, {colors['secondary']}11 0%, transparent 50%);
+}}
+
+.header {{
+ text-align: center;
+ margin-bottom: 4em;
+ padding: 3em;
+ background: {colors['background']};
+ border-radius: 50% 20% 30% 70% / 30% 60% 40% 70%;
+ box-shadow: 0 8px 32px rgba(0,0,0,0.1);
+}}
+
+h1, h2, h3 {{
+ position: relative;
+ padding-left: 3em;
+}}
+
+h1::before, h2::before, h3::before {{
+ content: "🌿";
+ position: absolute;
+ left: 0;
+ font-size: 2em;
+ opacity: 0.3;
+}}
+
+p, ul, pre, .quote {{
+ background-color: {colors['background']};
+ padding: 2em;
+ margin: 2em 0;
+ border-radius: 20px 5px 20px 5px;
+ box-shadow: 0 4px 16px rgba(0,0,0,0.05);
+ position: relative;
+ overflow: hidden;
+}}
+
+p::before, ul::before, pre::before, .quote::before {{
+ content: "";
+ position: absolute;
+ top: -50%;
+ right: -50%;
+ width: 200%;
+ height: 200%;
+ background: radial-gradient(circle, {colors['accent']}11 0%, transparent 70%);
+ z-index: -1;
+}}
+"""
+ elif layout_type == "technical":
+ layout_css = f"""
+body {{
+ font-family: code, monospace;
+ background-color: #0a0a0a;
+ color: #e0e0e0;
+ padding: 2em;
+ background-image:
+ linear-gradient(rgba(255,255,255,0.03) 1px, transparent 1px),
+ linear-gradient(90deg, rgba(255,255,255,0.03) 1px, transparent 1px);
+ background-size: 20px 20px;
+}}
+
+.header {{
+ border: 2px solid {colors['primary']};
+ padding: 2em;
+ margin-bottom: 3em;
+ position: relative;
+ background: linear-gradient(135deg, transparent 10px, #0a0a0a 10px);
+}}
+
+.header::before {{
+ content: "//";
+ position: absolute;
+ top: 10px;
+ left: 10px;
+ color: {colors['primary']};
+ font-size: 2em;
+}}
+
+h1, h2, h3 {{
+ font-family: code, monospace;
+ text-transform: uppercase;
+ letter-spacing: 0.1em;
+ border-left: 4px solid {colors['accent']};
+ padding-left: 1em;
+}}
+
+h1::before {{ content: "001 "; color: {colors['primary']}; }}
+h2::before {{ content: "010 "; color: {colors['secondary']}; }}
+h3::before {{ content: "011 "; color: {colors['accent']}; }}
+
+p, ul, pre, .quote {{
+ background-color: rgba(255,255,255,0.02);
+ border: 1px solid rgba(255,255,255,0.1);
+ padding: 1.5em;
+ margin: 1.5em 0;
+ position: relative;
+}}
+
+p::before, ul::before, .quote::before {{
+ content: ">";
+ position: absolute;
+ left: -1em;
+ color: {colors['accent']};
+}}
+
+a {{
+ color: {colors['accent']};
+ text-decoration: none;
+ padding: 0.2em 0.4em;
+ background-color: rgba(255,255,255,0.05);
+ border: 1px solid {colors['accent']}33;
+ transition: all 0.3s ease;
+}}
+
+a:hover {{
+ background-color: {colors['accent']}22;
+ border-color: {colors['accent']};
+}}
+"""
+ elif layout_type == "artistic":
+ layout_css = f"""
+body {{
+ padding: 4em 2em;
+ background: linear-gradient(45deg, {colors['background']}, {colors['background']}DD);
+ min-height: 100vh;
+ position: relative;
+}}
+
+body::before, body::after {{
+ content: "";
+ position: fixed;
+ width: 300px;
+ height: 300px;
+ border-radius: 50%;
+ filter: blur(100px);
+ z-index: -1;
+}}
+
+body::before {{
+ top: -150px;
+ left: -150px;
+ background: {colors['primary']}44;
+}}
+
+body::after {{
+ bottom: -150px;
+ right: -150px;
+ background: {colors['secondary']}44;
+}}
+
+.header {{
+ text-align: center;
+ margin-bottom: 4em;
+ position: relative;
+}}
+
+.header h1 {{
+ font-size: 4em;
+ margin: 0;
+ transform: perspective(500px) rotateY(-15deg);
+ text-shadow:
+ 3px 3px 0 {colors['primary']},
+ 6px 6px 0 {colors['secondary']},
+ 9px 9px 20px rgba(0,0,0,0.2);
+}}
+
+h2, h3 {{
+ position: relative;
+ display: inline-block;
+}}
+
+h2::after, h3::after {{
+ content: "";
+ position: absolute;
+ bottom: -5px;
+ left: 0;
+ right: 0;
+ height: 3px;
+ background: linear-gradient(90deg, {colors['primary']}, {colors['secondary']}, {colors['accent']});
+ border-radius: 2px;
+}}
+
+p, ul, pre, .quote {{
+ max-width: 65ch;
+ margin: 2em auto;
+ padding: 2em;
+ background: rgba(255,255,255,0.9);
+ box-shadow:
+ 0 8px 32px rgba(0,0,0,0.1),
+ inset 0 1px 0 rgba(255,255,255,0.5);
+ border-radius: 20px;
+ transform: rotate(-1deg);
+}}
+
+p:nth-child(even), ul:nth-child(even), .quote:nth-child(even) {{
+ transform: rotate(1deg);
+}}
+
+a {{
+ color: {colors['secondary']};
+ text-decoration: none;
+ background-image: linear-gradient(90deg, {colors['primary']}, {colors['secondary']});
+ background-size: 100% 2px;
+ background-position: 0 100%;
+ background-repeat: no-repeat;
+ transition: all 0.3s ease;
+}}
+
+a:hover {{
+ background-size: 100% 100%;
+ color: white;
+ padding: 0.2em 0.4em;
+ margin: -0.2em -0.4em;
+}}
+"""
+
+ return base_css + "\n\n/* Layout: " + layout_type + " */\n" + layout_css
+
+def generate_font_sizes():
+ """Generate harmonious font size combinations"""
+ base_sizes = [14, 15, 16, 17, 18]
+ base = random.choice(base_sizes)
+
+ scale_ratios = [1.125, 1.2, 1.25, 1.333, 1.414, 1.5, 1.618]
+ scale = random.choice(scale_ratios)
+
+ return {
+ 'base': base,
+ 'h1': round(scale ** 3, 2),
+ 'h2': round(scale ** 2, 2),
+ 'h3': round(scale, 2),
+ 'line_height': round(random.uniform(1.4, 1.8), 2)
+ }
+
+def create_theme(theme_name, fonts, colors, layout, font_sizes):
+ """Create a complete theme directory with all files"""
+ theme_dir = Path(f"/home/paul/git/gemtexter/extras/html/themes/{theme_name}")
+ theme_dir.mkdir(exist_ok=True)
+
+ # Generate theme.conf
+ theme_conf = f"""declare -xr HTML_HEADER=./extras/html/header.html.part
+declare -xr HTML_FOOTER=./extras/html/footer.html.part
+declare -xr HTML_CSS_STYLE=$HTML_THEME_DIR/style.css
+declare -xr HTML_WEBFONT_HEADING=./extras/html/fonts/{fonts['heading'][0]}/{fonts['heading'][0]}-Bold.ttf
+declare -xr HTML_WEBFONT_TEXT=./extras/html/fonts/{fonts['body'][0]}/{fonts['body'][0]}-Regular.ttf
+declare -xr HTML_WEBFONT_CODE=./extras/html/fonts/{fonts['code'][0]}/{fonts['code'][0]}-Regular.ttf
+declare -xr HTML_WEBFONT_HANDNOTES=./extras/html/fonts/khand/khand.ttf
+declare -xr SOURCE_HIGHLIGHT_CSS=./extras/html/source-highlight-styles/mono.css
+"""
+
+ with open(theme_dir / "theme.conf", "w") as f:
+ f.write(theme_conf)
+
+ # Copy fonts and generate style.css
+ css_content = generate_layout_css(layout, colors, font_sizes)
+
+ # Add font file references
+ font_mapping = {
+ 'heading': fonts['heading'][0],
+ 'text': fonts['body'][0],
+ 'code': fonts['code'][0],
+ 'handnotes': 'khand'
+ }
+
+ # Copy font files
+ for font_type, font_name in font_mapping.items():
+ if font_name == "Abril_Fatface":
+ src = f"/home/paul/git/gemtexter/extras/html/fonts/{font_name}/AbrilFatface-Regular.ttf"
+ dst = theme_dir / f"{font_type}.ttf"
+ elif font_name in ["Lato", "Merriweather", "oxygen", "roboto-slab"]:
+ weight = "Bold" if font_type == "heading" else "Regular"
+ src = f"/home/paul/git/gemtexter/extras/html/fonts/{font_name}/{font_name}-{weight}.ttf"
+ dst = theme_dir / f"{font_type}.ttf"
+ elif font_name == "consola-mono":
+ weight = "Bold" if font_type == "heading" else "Book"
+ src = f"/home/paul/git/gemtexter/extras/html/fonts/{font_name}/ConsolaMono-{weight}.ttf"
+ dst = theme_dir / f"{font_type}.ttf"
+ elif font_name == "hack":
+ src = f"/home/paul/git/gemtexter/extras/html/fonts/{font_name}/Hack-Regular.ttf"
+ dst = theme_dir / f"{font_type}.ttf"
+ elif font_name == "intelone-mono":
+ src = f"/home/paul/git/gemtexter/extras/html/fonts/{font_name}/intelone-mono-font-family-regular.ttf"
+ dst = theme_dir / f"{font_type}.ttf"
+ elif font_name == "higher-jump":
+ src = f"/home/paul/git/gemtexter/extras/html/fonts/{font_name}/Higher Jump.ttf"
+ dst = theme_dir / f"{font_type}.ttf"
+ elif font_name == "pixelon":
+ src = f"/home/paul/git/gemtexter/extras/html/fonts/{font_name}/Pixelon.ttf"
+ dst = theme_dir / f"{font_type}.ttf"
+ elif font_name == "repetition-scrolling":
+ src = f"/home/paul/git/gemtexter/extras/html/fonts/{font_name}/repet___.ttf"
+ dst = theme_dir / f"{font_type}.ttf"
+ elif font_name == "zai-aeg-mignon-typewriter-1924":
+ src = f"/home/paul/git/gemtexter/extras/html/fonts/{font_name}/zai_AEGMignonTypewriter1924.ttf"
+ dst = theme_dir / f"{font_type}.ttf"
+ else:
+ src = f"/home/paul/git/gemtexter/extras/html/fonts/{font_name}/{font_name}.ttf"
+ dst = theme_dir / f"{font_type}.ttf"
+
+ try:
+ shutil.copy(src, dst)
+ except FileNotFoundError:
+ # Try alternative path
+ print(f"Warning: Could not find {src}")
+
+ with open(theme_dir / "style.css", "w") as f:
+ f.write(css_content)
+
+ # Generate example.html
+ example_html = f"""<!DOCTYPE html>
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
+<head>
+ <meta charset="UTF-8" />
+ <meta name="viewport" content="width=device-width, initial-scale=1.0" />
+ <title>{theme_name.replace('_', ' ').title()} - Gemtexter Theme</title>
+ <link rel="stylesheet" href="style.css" />
+</head>
+<body>
+ <div class="header">
+ <h1>{theme_name.replace('_', ' ').title()}</h1>
+ <p>A {layout.replace('_', ' ')} layout with {colors['palette_type'].replace('_', ' ')} colors</p>
+ </div>
+
+ <div class="content">
+ <h1>Welcome to {theme_name.replace('_', ' ').title()}</h1>
+ <p>This theme features a carefully crafted {layout.replace('_', ' ')} layout with a {'dark' if colors['is_dark'] else 'light'} {colors['palette_type'].replace('_', ' ')} color scheme. The typography combines {fonts['heading'][2]} fonts for headings with {fonts['body'][2]} for body text.</p>
+
+ <h2>Typography Showcase</h2>
+ <p>The {fonts['body'][0].replace('_', ' ')} font family provides excellent readability for body text, while {fonts['heading'][0].replace('_', ' ')} adds character to headings. Code blocks use {fonts['code'][0].replace('_', ' ')} for clarity.</p>
+
+ <h2>Color Palette</h2>
+ <p>Primary: <span style="color: {colors['primary']}; font-weight: bold;">{colors['primary']}</span> |
+ Secondary: <span style="color: {colors['secondary']}; font-weight: bold;">{colors['secondary']}</span> |
+ Accent: <span style="color: {colors['accent']}; font-weight: bold;">{colors['accent']}</span></p>
+
+ <h3>Interactive Elements</h3>
+ <p>Links like <a href="#">this example</a> and longer <a href="#" class="textlink">text links that demonstrate the theme's navigation style</a> use the secondary color.</p>
+
+ <div class="quote">
+ "Design is not just what it looks like and feels like. Design is how it works." — Steve Jobs
+ </div>
+
+ <h3>Code Examples</h3>
+ <p>Inline code like <code>theme.generate()</code> and larger blocks:</p>
+ <pre>// Theme configuration
+const theme = {{
+ name: "{theme_name}",
+ layout: "{layout}",
+ colors: {{
+ primary: "{colors['primary']}",
+ secondary: "{colors['secondary']}",
+ accent: "{colors['accent']}"
+ }},
+ fonts: {{
+ heading: "{fonts['heading'][0]}",
+ body: "{fonts['body'][0]}",
+ code: "{fonts['code'][0]}"
+ }}
+}};</pre>
+
+ <h2>Content Structure</h2>
+ <ul>
+ <li>Clean, readable typography with {font_sizes['base']}px base font size</li>
+ <li>Heading scale ratio of {font_sizes['h1']}x for visual hierarchy</li>
+ <li>Line height of {font_sizes['line_height']} for comfortable reading</li>
+ <li>{layout.replace('_', ' ').title()} layout optimized for content flow</li>
+ <li>{'Dark' if colors['is_dark'] else 'Light'} theme with {colors['palette_type'].replace('_', ' ')} color harmony</li>
+ </ul>
+
+ <h2>Font Licensing</h2>
+ <p>All fonts used in this theme are properly licensed:</p>
+ <ul>
+ <li>{fonts['heading'][0]}: {fonts['heading'][1]} License</li>
+ <li>{fonts['body'][0]}: {fonts['body'][1]} License</li>
+ <li>{fonts['code'][0]}: {fonts['code'][1]} License</li>
+ </ul>
+
+ <h3>Final Thoughts</h3>
+ <p>Every element of this theme has been carefully designed to create a harmonious reading experience. The {layout.replace('_', ' ')} layout ensures content is presented in an engaging way, while the color scheme provides the perfect backdrop for your words to shine.</p>
+
+ <p>Whether you're writing technical documentation, creative prose, or anything in between, this theme adapts to showcase your content beautifully.</p>
+ </div>
+</body>
+</html>"""
+
+ with open(theme_dir / "example.html", "w") as f:
+ f.write(example_html)
+
+ # Generate LICENSE file
+ license_content = f"""Theme: {theme_name}
+Generated: {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}
+
+Layout: {layout}
+Color Scheme: {colors['palette_type']} ({'Dark' if colors['is_dark'] else 'Light'})
+
+Font Licenses:
+==============
+Heading Font: {fonts['heading'][0]}
+License: {fonts['heading'][1]}
+Category: {fonts['heading'][2]}
+
+Body Font: {fonts['body'][0]}
+License: {fonts['body'][1]}
+Category: {fonts['body'][2]}
+
+Code Font: {fonts['code'][0]}
+License: {fonts['code'][1]}
+Category: {fonts['code'][2]}
+
+All fonts are free for personal use.
+"""
+
+ with open(theme_dir / "LICENSE", "w") as f:
+ f.write(license_content)
+
+ return theme_name
+
+def generate_screenshot(theme_name):
+ """Generate a screenshot preview of the theme"""
+ theme_dir = Path(f"/home/paul/git/gemtexter/extras/html/themes/{theme_name}")
+
+ # Create a simple preview image using PIL
+ img = Image.new('RGB', (400, 300), color='white')
+ draw = ImageDraw.Draw(img)
+
+ # Try to load theme colors from style.css
+ with open(theme_dir / "style.css", "r") as f:
+ css_content = f.read()
+
+ # Extract colors from CSS
+ import re
+ bg_match = re.search(r'--color-bg:\s*([#\w]+);', css_content)
+ primary_match = re.search(r'--color-primary:\s*([#\w]+);', css_content)
+
+ if bg_match:
+ try:
+ bg_color = bg_match.group(1)
+ img = Image.new('RGB', (400, 300), color=bg_color)
+ draw = ImageDraw.Draw(img)
+ except:
+ pass
+
+ # Add theme name
+ try:
+ font = ImageFont.truetype("/usr/share/fonts/truetype/liberation/LiberationSans-Bold.ttf", 24)
+ except:
+ font = None
+
+ text_color = 'black' if bg_match and bg_match.group(1).startswith('#f') else 'white'
+ draw.text((20, 20), theme_name.replace('_', ' ').title(), fill=text_color, font=font)
+
+ # Add some preview elements
+ draw.rectangle((20, 60, 380, 62), fill=text_color)
+ draw.text((20, 80), "Preview of theme layout", fill=text_color)
+
+ # Save screenshot
+ img.save(theme_dir.parent / "screenshots" / f"{theme_name}.png")
+
+def main():
+ """Generate 50 unique themes"""
+ print("Generating 50 random themes...")
+
+ themes = []
+ used_names = set()
+
+ # Ensure screenshots directory exists
+ screenshots_dir = Path("/home/paul/git/gemtexter/extras/html/themes/screenshots")
+ screenshots_dir.mkdir(exist_ok=True)
+
+ while len(themes) < 50:
+ # Generate unique theme name
+ theme_name = f"{random.choice(ADJECTIVES)}_{random.choice(NOUNS)}"
+ if theme_name in used_names:
+ continue
+ used_names.add(theme_name)
+
+ # Random font combination
+ fonts = random.choice(FONT_COMBINATIONS)
+
+ # Random color palette
+ colors = generate_color_palette()
+
+ # Random layout
+ layout = random.choice(LAYOUTS)
+
+ # Random font sizes
+ font_sizes = generate_font_sizes()
+
+ # Create theme
+ try:
+ created_theme = create_theme(theme_name, fonts, colors, layout, font_sizes)
+ themes.append({
+ 'name': created_theme,
+ 'layout': layout,
+ 'colors': colors,
+ 'fonts': fonts
+ })
+ print(f"Created theme {len(themes)}/50: {created_theme}")
+
+ # Generate screenshot
+ generate_screenshot(created_theme)
+ except Exception as e:
+ print(f"Error creating theme {theme_name}: {e}")
+
+ # Save theme metadata
+ with open("/home/paul/git/gemtexter/extras/html/themes/themes_metadata.json", "w") as f:
+ json.dump(themes, f, indent=2)
+
+ print(f"\nSuccessfully created {len(themes)} themes!")
+ return themes
+
+if __name__ == "__main__":
+ main() \ No newline at end of file
diff --git a/extras/html/themes/generate_better_screenshots.py b/extras/html/themes/generate_better_screenshots.py
new file mode 100755
index 0000000..87c918f
--- /dev/null
+++ b/extras/html/themes/generate_better_screenshots.py
@@ -0,0 +1,196 @@
+#!/usr/bin/env python3
+
+import os
+from pathlib import Path
+from PIL import Image, ImageDraw, ImageFont
+import re
+import colorsys
+
+def extract_theme_info(theme_dir):
+ """Extract colors and layout from theme CSS"""
+ css_file = theme_dir / "style.css"
+ if not css_file.exists():
+ return None
+
+ with open(css_file, 'r') as f:
+ css_content = f.read()
+
+ # Extract colors
+ colors = {}
+ color_vars = {
+ 'primary': r'--color-primary:\s*([#\w]+);',
+ 'secondary': r'--color-secondary:\s*([#\w]+);',
+ 'accent': r'--color-accent:\s*([#\w]+);',
+ 'background': r'--color-bg:\s*([#\w]+);',
+ 'text': r'--color-text:\s*([#\w]+);'
+ }
+
+ for name, pattern in color_vars.items():
+ match = re.search(pattern, css_content)
+ if match:
+ colors[name] = match.group(1)
+
+ # Extract layout type
+ layout_match = re.search(r'/\* Layout: (\w+) \*/', css_content)
+ layout = layout_match.group(1) if layout_match else 'default'
+
+ # Determine if dark theme
+ if colors.get('background', '#fff').startswith('#0') or colors.get('background', '#fff').startswith('#1'):
+ colors['is_dark'] = True
+ else:
+ colors['is_dark'] = False
+
+ return {'colors': colors, 'layout': layout}
+
+def hex_to_rgb(hex_color):
+ """Convert hex to RGB tuple"""
+ hex_color = hex_color.lstrip('#')
+ return tuple(int(hex_color[i:i+2], 16) for i in (0, 2, 4))
+
+def create_theme_preview(theme_name, theme_info, output_path):
+ """Create a preview image for the theme"""
+ width, height = 400, 300
+
+ # Get colors
+ colors = theme_info['colors']
+ bg_color = hex_to_rgb(colors.get('background', '#ffffff'))
+ text_color = hex_to_rgb(colors.get('text', '#000000'))
+ primary_color = hex_to_rgb(colors.get('primary', '#667eea'))
+ secondary_color = hex_to_rgb(colors.get('secondary', '#764ba2'))
+ accent_color = hex_to_rgb(colors.get('accent', '#667eea'))
+
+ # Create image
+ img = Image.new('RGB', (width, height), color=bg_color)
+ draw = ImageDraw.Draw(img)
+
+ # Try to load fonts
+ try:
+ title_font = ImageFont.truetype("/usr/share/fonts/truetype/liberation/LiberationSans-Bold.ttf", 24)
+ body_font = ImageFont.truetype("/usr/share/fonts/truetype/liberation/LiberationSans-Regular.ttf", 14)
+ small_font = ImageFont.truetype("/usr/share/fonts/truetype/liberation/LiberationSans-Regular.ttf", 11)
+ except:
+ # Fallback to default font
+ title_font = ImageFont.load_default()
+ body_font = ImageFont.load_default()
+ small_font = ImageFont.load_default()
+
+ # Draw based on layout type
+ layout = theme_info['layout']
+
+ if layout in ['hero', 'gradient', 'floating']:
+ # Draw gradient background
+ for y in range(height):
+ r = int(bg_color[0] + (primary_color[0] - bg_color[0]) * (y / height) * 0.3)
+ g = int(bg_color[1] + (primary_color[1] - bg_color[1]) * (y / height) * 0.3)
+ b = int(bg_color[2] + (primary_color[2] - bg_color[2]) * (y / height) * 0.3)
+ draw.line([(0, y), (width, y)], fill=(r, g, b))
+
+ # Header area
+ if layout == 'sidebar':
+ # Sidebar layout
+ draw.rectangle([(0, 0), (100, height)], fill=primary_color)
+ draw.text((110, 20), theme_name.replace('_', ' ').title(), fill=text_color, font=title_font)
+ elif layout == 'card':
+ # Card layout
+ draw.rectangle([(20, 20), (width-20, 80)], fill=bg_color, outline=primary_color, width=2)
+ draw.text((40, 35), theme_name.replace('_', ' ').title(), fill=primary_color, font=title_font)
+ else:
+ # Default header
+ if layout in ['brutalist', 'terminal']:
+ draw.rectangle([(0, 0), (width, 60)], fill=primary_color)
+ draw.text((20, 15), theme_name.replace('_', ' ').title(), fill=bg_color, font=title_font)
+ else:
+ draw.text((20, 20), theme_name.replace('_', ' ').title(), fill=primary_color, font=title_font)
+
+ # Content area simulation
+ y_offset = 80 if layout != 'sidebar' else 60
+
+ # Heading
+ draw.text((20 if layout != 'sidebar' else 110, y_offset), "Sample Heading", fill=primary_color, font=body_font)
+ y_offset += 25
+
+ # Text lines
+ line_color = tuple(c + (255-c)//3 if colors['is_dark'] else c - c//3 for c in text_color)
+ for i in range(4):
+ line_width = width - 40 if i < 3 else width - 100
+ if layout == 'sidebar':
+ draw.rectangle([(110, y_offset), (line_width, y_offset + 2)], fill=line_color)
+ else:
+ draw.rectangle([(20, y_offset), (line_width, y_offset + 2)], fill=line_color)
+ y_offset += 8
+
+ y_offset += 10
+
+ # Link simulation
+ link_x = 110 if layout == 'sidebar' else 20
+ draw.rectangle([(link_x, y_offset), (link_x + 80, y_offset + 2)], fill=secondary_color)
+ y_offset += 15
+
+ # Button or accent element
+ if layout in ['card', 'floating', 'gradient']:
+ # Rounded button
+ button_x = 110 if layout == 'sidebar' else 20
+ draw.rectangle([(button_x, y_offset), (button_x + 100, y_offset + 30)], fill=accent_color)
+ draw.text((button_x + 20, y_offset + 8), "Preview", fill=bg_color, font=body_font)
+ elif layout == 'terminal':
+ # Terminal prompt
+ draw.text((20, y_offset), "$ theme --preview", fill=(0, 255, 0), font=body_font)
+
+ # Layout indicator
+ draw.text((width - 100, height - 25), f"{layout}", fill=text_color, font=small_font)
+
+ # Theme type indicator
+ theme_type = "Dark" if colors['is_dark'] else "Light"
+ draw.text((20, height - 25), theme_type, fill=text_color, font=small_font)
+
+ # Add some visual interest based on layout
+ if layout == 'geometric':
+ # Add geometric shapes
+ draw.polygon([(width-50, 100), (width-30, 110), (width-50, 120), (width-70, 110)], fill=accent_color)
+ elif layout == 'organic':
+ # Add organic shapes
+ draw.ellipse([(width-80, 80), (width-40, 120)], fill=accent_color, outline=None)
+ elif layout == 'newspaper':
+ # Add column lines
+ draw.line([(width//3, 100), (width//3, height-40)], fill=text_color, width=1)
+ draw.line([(2*width//3, 100), (2*width//3, height-40)], fill=text_color, width=1)
+
+ # Save image
+ img.save(output_path, quality=95)
+
+def main():
+ themes_dir = Path("/home/paul/git/gemtexter/extras/html/themes")
+ screenshots_dir = themes_dir / "screenshots"
+ screenshots_dir.mkdir(exist_ok=True)
+
+ # Get all theme directories
+ theme_dirs = [d for d in themes_dir.iterdir() if d.is_dir() and d.name not in ['screenshots', '.git']]
+
+ print(f"Generating preview screenshots for {len(theme_dirs)} themes...")
+
+ success_count = 0
+ for theme_dir in theme_dirs:
+ theme_name = theme_dir.name
+
+ # Skip if it's not a theme directory
+ if not (theme_dir / "style.css").exists():
+ continue
+
+ try:
+ # Extract theme information
+ theme_info = extract_theme_info(theme_dir)
+ if theme_info:
+ # Create preview
+ output_path = screenshots_dir / f"{theme_name}.png"
+ create_theme_preview(theme_name, theme_info, output_path)
+ success_count += 1
+ print(f"✓ Generated preview for {theme_name}")
+ else:
+ print(f"✗ Could not extract info for {theme_name}")
+ except Exception as e:
+ print(f"✗ Error generating preview for {theme_name}: {e}")
+
+ print(f"\nSuccessfully generated {success_count} theme previews!")
+
+if __name__ == "__main__":
+ main() \ No newline at end of file
diff --git a/extras/html/themes/generate_html_screenshots.py b/extras/html/themes/generate_html_screenshots.py
new file mode 100644
index 0000000..6b5b1d9
--- /dev/null
+++ b/extras/html/themes/generate_html_screenshots.py
@@ -0,0 +1,252 @@
+#!/usr/bin/env python3
+
+import os
+import subprocess
+import time
+from pathlib import Path
+from selenium import webdriver
+from selenium.webdriver.chrome.options import Options
+from selenium.webdriver.firefox.options import Options as FirefoxOptions
+from selenium.webdriver.common.by import By
+from selenium.webdriver.support.ui import WebDriverWait
+from selenium.webdriver.support import expected_conditions as EC
+import json
+
+def check_browser_availability():
+ """Check which browser is available"""
+ browsers = []
+
+ # Check for Chrome/Chromium
+ for browser in ['google-chrome', 'chromium', 'chromium-browser']:
+ try:
+ result = subprocess.run([browser, '--version'], capture_output=True, text=True)
+ if result.returncode == 0:
+ browsers.append(('chrome', browser))
+ break
+ except:
+ continue
+
+ # Check for Firefox
+ try:
+ result = subprocess.run(['firefox', '--version'], capture_output=True, text=True)
+ if result.returncode == 0:
+ browsers.append(('firefox', 'firefox'))
+ except:
+ pass
+
+ return browsers
+
+def capture_with_selenium(browser_type, browser_path, html_file, output_file):
+ """Capture screenshot using Selenium"""
+ if browser_type == 'chrome':
+ options = Options()
+ options.add_argument('--headless')
+ options.add_argument('--no-sandbox')
+ options.add_argument('--disable-dev-shm-usage')
+ options.add_argument('--window-size=1200,900')
+
+ try:
+ driver = webdriver.Chrome(options=options)
+ except:
+ # Try with chromium
+ options.binary_location = browser_path
+ driver = webdriver.Chrome(options=options)
+ else: # firefox
+ options = FirefoxOptions()
+ options.add_argument('--headless')
+ options.add_argument('--width=1200')
+ options.add_argument('--height=900')
+ driver = webdriver.Firefox(options=options)
+
+ try:
+ # Load the HTML file
+ driver.get(f"file://{html_file}")
+
+ # Wait for page to load
+ time.sleep(2)
+
+ # Crop to content area (400x300)
+ driver.set_window_size(400, 300)
+
+ # Take screenshot
+ driver.save_screenshot(str(output_file))
+
+ finally:
+ driver.quit()
+
+def capture_with_headless_browser(html_file, output_file):
+ """Capture screenshot using headless browser directly"""
+ browsers = check_browser_availability()
+
+ if not browsers:
+ return False
+
+ for browser_type, browser_path in browsers:
+ try:
+ if browser_type == 'chrome':
+ cmd = [
+ browser_path,
+ '--headless',
+ '--disable-gpu',
+ '--window-size=400,300',
+ '--screenshot=' + str(output_file),
+ '--default-background-color=0',
+ f'file://{html_file}'
+ ]
+ else: # firefox
+ cmd = [
+ browser_path,
+ '--headless',
+ '--window-size=400,300',
+ '--screenshot=' + str(output_file),
+ f'file://{html_file}'
+ ]
+
+ result = subprocess.run(cmd, capture_output=True, text=True, timeout=10)
+ if result.returncode == 0 and output_file.exists():
+ return True
+ except Exception as e:
+ print(f"Error with {browser_type}: {e}")
+ continue
+
+ return False
+
+def generate_mini_html(theme_dir, temp_html):
+ """Generate a mini HTML file that showcases the theme"""
+ theme_name = theme_dir.name
+
+ # Read the theme's example.html to get color info
+ example_html = theme_dir / "example.html"
+ if not example_html.exists():
+ return False
+
+ # Create a mini version that fits in 400x300
+ mini_html = f"""<!DOCTYPE html>
+<html>
+<head>
+ <meta charset="UTF-8">
+ <link rel="stylesheet" href="{theme_dir}/style.css">
+ <style>
+ body {{
+ margin: 0;
+ padding: 20px;
+ min-height: 260px;
+ overflow: hidden;
+ }}
+ .preview-container {{
+ max-width: 360px;
+ margin: 0 auto;
+ }}
+ h1 {{
+ font-size: 1.8em !important;
+ margin: 0.3em 0 !important;
+ }}
+ h2 {{
+ font-size: 1.3em !important;
+ margin: 0.5em 0 0.3em 0 !important;
+ }}
+ p {{
+ font-size: 0.9em !important;
+ line-height: 1.4 !important;
+ margin: 0.5em 0 !important;
+ }}
+ .quote {{
+ font-size: 0.85em !important;
+ padding: 0.5em 1em !important;
+ margin: 0.5em 0 !important;
+ }}
+ pre {{
+ font-size: 0.75em !important;
+ padding: 0.5em !important;
+ margin: 0.5em 0 !important;
+ max-height: 60px;
+ overflow: hidden;
+ }}
+ a {{
+ font-size: 0.9em !important;
+ }}
+ /* Hide overflow content */
+ .preview-container > *:nth-child(n+6) {{
+ display: none;
+ }}
+ </style>
+</head>
+<body>
+ <div class="preview-container">
+ <h1>{theme_name.replace('_', ' ').title()}</h1>
+ <p>This is a preview of the theme's typography and color scheme.</p>
+ <h2>Features</h2>
+ <p>Clean design with <a href="#">interactive links</a> and elegant styling.</p>
+ <div class="quote">
+ "Beautiful themes for Gemtexter"
+ </div>
+ <pre><code>theme = "{theme_name}"</code></pre>
+ </div>
+</body>
+</html>"""
+
+ with open(temp_html, 'w') as f:
+ f.write(mini_html)
+
+ return True
+
+def main():
+ themes_dir = Path("/home/paul/git/gemtexter/extras/html/themes")
+ screenshots_dir = themes_dir / "screenshots"
+ screenshots_dir.mkdir(exist_ok=True)
+
+ # Check browser availability
+ browsers = check_browser_availability()
+ if not browsers:
+ print("No supported browser found. Please install Chrome/Chromium or Firefox.")
+ print("For better screenshots, you can also install Selenium:")
+ print(" pip install selenium pillow")
+ return
+
+ print(f"Found browsers: {[b[1] for b in browsers]}")
+
+ # Get all theme directories
+ theme_dirs = [d for d in themes_dir.iterdir() if d.is_dir() and d.name not in ['screenshots', '.git']]
+ valid_themes = [d for d in theme_dirs if (d / "style.css").exists()]
+
+ print(f"Generating HTML screenshots for {len(valid_themes)} themes...")
+
+ success_count = 0
+ temp_html = themes_dir / "temp_preview.html"
+
+ for i, theme_dir in enumerate(valid_themes):
+ theme_name = theme_dir.name
+ output_path = screenshots_dir / f"{theme_name}.png"
+
+ print(f"[{i+1}/{len(valid_themes)}] Generating screenshot for {theme_name}...", end='', flush=True)
+
+ try:
+ # Generate mini HTML
+ if not generate_mini_html(theme_dir, temp_html):
+ print(" ✗ (no example.html)")
+ continue
+
+ # Try to capture screenshot
+ if capture_with_headless_browser(temp_html, output_path):
+ success_count += 1
+ print(" ✓")
+ else:
+ print(" ✗ (capture failed)")
+
+ except Exception as e:
+ print(f" ✗ ({e})")
+
+ # Clean up
+ if temp_html.exists():
+ temp_html.unlink()
+
+ print(f"\nSuccessfully generated {success_count} screenshots!")
+
+ # If we have working setup but some failed, offer Selenium option
+ if success_count < len(valid_themes):
+ print("\nFor better results, you can install Selenium:")
+ print(" pip install selenium")
+ print(" # Also install ChromeDriver or GeckoDriver")
+
+if __name__ == "__main__":
+ main() \ No newline at end of file
diff --git a/extras/html/themes/generate_random_themes.py b/extras/html/themes/generate_random_themes.py
new file mode 100644
index 0000000..8da7d24
--- /dev/null
+++ b/extras/html/themes/generate_random_themes.py
@@ -0,0 +1,1008 @@
+#!/usr/bin/env python3
+
+import os
+import json
+import random
+import requests
+import concurrent.futures
+import colorsys
+from pathlib import Path
+import zipfile
+import io
+
+# Google Fonts API - Popular fonts with clear licenses
+GOOGLE_FONTS = [
+ {"family": "Roboto", "variants": ["300", "regular", "700"], "category": "sans-serif", "license": "Apache License 2.0"},
+ {"family": "Open Sans", "variants": ["300", "regular", "700"], "category": "sans-serif", "license": "Apache License 2.0"},
+ {"family": "Lato", "variants": ["300", "regular", "700"], "category": "sans-serif", "license": "OFL"},
+ {"family": "Montserrat", "variants": ["300", "regular", "700"], "category": "sans-serif", "license": "OFL"},
+ {"family": "Poppins", "variants": ["300", "regular", "700"], "category": "sans-serif", "license": "OFL"},
+ {"family": "Raleway", "variants": ["300", "regular", "700"], "category": "sans-serif", "license": "OFL"},
+ {"family": "Inter", "variants": ["300", "regular", "700"], "category": "sans-serif", "license": "OFL"},
+ {"family": "Nunito", "variants": ["300", "regular", "700"], "category": "sans-serif", "license": "OFL"},
+ {"family": "Work Sans", "variants": ["300", "regular", "700"], "category": "sans-serif", "license": "OFL"},
+ {"family": "Quicksand", "variants": ["300", "regular", "700"], "category": "sans-serif", "license": "OFL"},
+
+ {"family": "Playfair Display", "variants": ["regular", "700"], "category": "serif", "license": "OFL"},
+ {"family": "Merriweather", "variants": ["300", "regular", "700"], "category": "serif", "license": "OFL"},
+ {"family": "Lora", "variants": ["regular", "700"], "category": "serif", "license": "OFL"},
+ {"family": "Source Serif Pro", "variants": ["regular", "700"], "category": "serif", "license": "OFL"},
+ {"family": "Crimson Text", "variants": ["regular", "700"], "category": "serif", "license": "OFL"},
+ {"family": "Libre Baskerville", "variants": ["regular", "700"], "category": "serif", "license": "OFL"},
+ {"family": "EB Garamond", "variants": ["regular", "700"], "category": "serif", "license": "OFL"},
+ {"family": "Cormorant", "variants": ["300", "regular", "700"], "category": "serif", "license": "OFL"},
+
+ {"family": "Space Mono", "variants": ["regular", "700"], "category": "monospace", "license": "OFL"},
+ {"family": "Fira Code", "variants": ["regular", "700"], "category": "monospace", "license": "OFL"},
+ {"family": "JetBrains Mono", "variants": ["regular", "700"], "category": "monospace", "license": "OFL"},
+ {"family": "Source Code Pro", "variants": ["regular", "700"], "category": "monospace", "license": "OFL"},
+ {"family": "Ubuntu Mono", "variants": ["regular", "700"], "category": "monospace", "license": "Ubuntu Font License"},
+
+ {"family": "Dancing Script", "variants": ["regular", "700"], "category": "handwriting", "license": "OFL"},
+ {"family": "Pacifico", "variants": ["regular"], "category": "handwriting", "license": "OFL"},
+ {"family": "Caveat", "variants": ["regular", "700"], "category": "handwriting", "license": "OFL"},
+ {"family": "Satisfy", "variants": ["regular"], "category": "handwriting", "license": "OFL"},
+ {"family": "Great Vibes", "variants": ["regular"], "category": "handwriting", "license": "OFL"},
+
+ {"family": "Bebas Neue", "variants": ["regular"], "category": "display", "license": "OFL"},
+ {"family": "Righteous", "variants": ["regular"], "category": "display", "license": "OFL"},
+ {"family": "Fredoka One", "variants": ["regular"], "category": "display", "license": "OFL"},
+ {"family": "Rubik", "variants": ["300", "regular", "700"], "category": "sans-serif", "license": "OFL"},
+ {"family": "Oswald", "variants": ["300", "regular", "700"], "category": "sans-serif", "license": "OFL"},
+ {"family": "Barlow", "variants": ["300", "regular", "700"], "category": "sans-serif", "license": "OFL"},
+ {"family": "Archivo", "variants": ["regular", "700"], "category": "sans-serif", "license": "OFL"},
+ {"family": "Exo 2", "variants": ["300", "regular", "700"], "category": "sans-serif", "license": "OFL"},
+ {"family": "Karla", "variants": ["300", "regular", "700"], "category": "sans-serif", "license": "OFL"},
+ {"family": "Bitter", "variants": ["regular", "700"], "category": "serif", "license": "OFL"},
+ {"family": "Josefin Sans", "variants": ["300", "regular", "700"], "category": "sans-serif", "license": "OFL"},
+ {"family": "Abril Fatface", "variants": ["regular"], "category": "display", "license": "OFL"},
+ {"family": "Anton", "variants": ["regular"], "category": "sans-serif", "license": "OFL"},
+ {"family": "Comfortaa", "variants": ["300", "regular", "700"], "category": "display", "license": "OFL"},
+ {"family": "Lexend", "variants": ["300", "regular", "700"], "category": "sans-serif", "license": "OFL"},
+ {"family": "DM Sans", "variants": ["regular", "700"], "category": "sans-serif", "license": "OFL"},
+ {"family": "Space Grotesk", "variants": ["300", "regular", "700"], "category": "sans-serif", "license": "OFL"},
+ {"family": "Sora", "variants": ["300", "regular", "700"], "category": "sans-serif", "license": "OFL"},
+ {"family": "Manrope", "variants": ["300", "regular", "700"], "category": "sans-serif", "license": "OFL"},
+ {"family": "Figtree", "variants": ["300", "regular", "700"], "category": "sans-serif", "license": "OFL"}
+]
+
+# Color palette generators
+def generate_complementary_palette():
+ base_hue = random.random()
+ base_saturation = random.uniform(0.3, 0.9)
+ base_lightness = random.uniform(0.3, 0.7)
+
+ # Base color
+ base_rgb = colorsys.hls_to_rgb(base_hue, base_lightness, base_saturation)
+ base_color = '#{:02x}{:02x}{:02x}'.format(int(base_rgb[0]*255), int(base_rgb[1]*255), int(base_rgb[2]*255))
+
+ # Complementary color
+ comp_hue = (base_hue + 0.5) % 1.0
+ comp_rgb = colorsys.hls_to_rgb(comp_hue, base_lightness, base_saturation * 0.8)
+ comp_color = '#{:02x}{:02x}{:02x}'.format(int(comp_rgb[0]*255), int(comp_rgb[1]*255), int(comp_rgb[2]*255))
+
+ # Background - very light or very dark
+ if random.random() > 0.5: # Light theme
+ bg_lightness = random.uniform(0.92, 0.98)
+ text_lightness = random.uniform(0.1, 0.2)
+ else: # Dark theme
+ bg_lightness = random.uniform(0.05, 0.15)
+ text_lightness = random.uniform(0.85, 0.95)
+
+ bg_rgb = colorsys.hls_to_rgb(base_hue, bg_lightness, 0.1)
+ bg_color = '#{:02x}{:02x}{:02x}'.format(int(bg_rgb[0]*255), int(bg_rgb[1]*255), int(bg_rgb[2]*255))
+
+ text_rgb = colorsys.hls_to_rgb(0, text_lightness, 0)
+ text_color = '#{:02x}{:02x}{:02x}'.format(int(text_rgb[0]*255), int(text_rgb[1]*255), int(text_rgb[2]*255))
+
+ return {
+ "primary": base_color,
+ "secondary": comp_color,
+ "background": bg_color,
+ "text": text_color,
+ "is_dark": bg_lightness < 0.5
+ }
+
+def generate_triadic_palette():
+ base_hue = random.random()
+ base_saturation = random.uniform(0.4, 0.8)
+ base_lightness = random.uniform(0.4, 0.6)
+
+ colors = []
+ for i in range(3):
+ hue = (base_hue + i * 0.333) % 1.0
+ rgb = colorsys.hls_to_rgb(hue, base_lightness + random.uniform(-0.1, 0.1), base_saturation)
+ color = '#{:02x}{:02x}{:02x}'.format(int(rgb[0]*255), int(rgb[1]*255), int(rgb[2]*255))
+ colors.append(color)
+
+ # Background
+ if random.random() > 0.5: # Light theme
+ bg_lightness = random.uniform(0.94, 0.99)
+ text_lightness = random.uniform(0.05, 0.15)
+ else: # Dark theme
+ bg_lightness = random.uniform(0.02, 0.12)
+ text_lightness = random.uniform(0.88, 0.98)
+
+ bg_rgb = colorsys.hls_to_rgb(base_hue, bg_lightness, 0.05)
+ bg_color = '#{:02x}{:02x}{:02x}'.format(int(bg_rgb[0]*255), int(bg_rgb[1]*255), int(bg_rgb[2]*255))
+
+ text_rgb = colorsys.hls_to_rgb(0, text_lightness, 0)
+ text_color = '#{:02x}{:02x}{:02x}'.format(int(text_rgb[0]*255), int(text_rgb[1]*255), int(text_rgb[2]*255))
+
+ return {
+ "primary": colors[0],
+ "secondary": colors[1],
+ "accent": colors[2],
+ "background": bg_color,
+ "text": text_color,
+ "is_dark": bg_lightness < 0.5
+ }
+
+def generate_analogous_palette():
+ base_hue = random.random()
+ hue_shift = random.uniform(0.05, 0.12)
+ base_saturation = random.uniform(0.3, 0.8)
+ base_lightness = random.uniform(0.35, 0.65)
+
+ colors = []
+ for i in range(-2, 3):
+ hue = (base_hue + i * hue_shift) % 1.0
+ saturation = base_saturation + random.uniform(-0.1, 0.1)
+ lightness = base_lightness + random.uniform(-0.1, 0.1)
+ rgb = colorsys.hls_to_rgb(hue, lightness, saturation)
+ color = '#{:02x}{:02x}{:02x}'.format(int(rgb[0]*255), int(rgb[1]*255), int(rgb[2]*255))
+ colors.append(color)
+
+ # Background
+ if random.random() > 0.5: # Light theme
+ bg_lightness = random.uniform(0.95, 0.99)
+ text_lightness = random.uniform(0.08, 0.18)
+ else: # Dark theme
+ bg_lightness = random.uniform(0.03, 0.10)
+ text_lightness = random.uniform(0.90, 0.97)
+
+ bg_rgb = colorsys.hls_to_rgb(base_hue, bg_lightness, 0.08)
+ bg_color = '#{:02x}{:02x}{:02x}'.format(int(bg_rgb[0]*255), int(bg_rgb[1]*255), int(bg_rgb[2]*255))
+
+ text_rgb = colorsys.hls_to_rgb(0, text_lightness, 0)
+ text_color = '#{:02x}{:02x}{:02x}'.format(int(text_rgb[0]*255), int(text_rgb[1]*255), int(text_rgb[2]*255))
+
+ return {
+ "primary": colors[2],
+ "secondary": colors[1],
+ "accent": colors[3],
+ "background": bg_color,
+ "text": text_color,
+ "is_dark": bg_lightness < 0.5
+ }
+
+# Layout generators
+LAYOUTS = [
+ "centered",
+ "wide",
+ "magazine",
+ "card",
+ "asymmetric",
+ "minimal_grid",
+ "brutalist",
+ "newspaper",
+ "terminal",
+ "book",
+ "sidebar",
+ "hero",
+ "masonry",
+ "split",
+ "overlap"
+]
+
+def generate_layout_css(layout_type, colors):
+ base_css = f"""
+body {{
+ background-color: {colors['background']};
+ color: {colors['text']};
+ margin: 0;
+ padding: 0;
+ min-height: 100vh;
+}}
+
+h1, h2, h3 {{
+ color: {colors['primary']};
+ margin-top: 1.5em;
+ margin-bottom: 0.5em;
+}}
+
+a {{
+ color: {colors['secondary']};
+ text-decoration: none;
+ transition: all 0.3s ease;
+}}
+
+a:hover {{
+ opacity: 0.8;
+ text-decoration: underline;
+}}
+
+.quote {{
+ border-left: 4px solid {colors['secondary']};
+ padding: 1em 1.5em;
+ margin: 1.5em 0;
+ background-color: {colors['primary']}11;
+ font-style: italic;
+}}
+
+pre {{
+ background-color: {colors['text']}11;
+ border: 1px solid {colors['text']}22;
+ padding: 1em;
+ overflow-x: auto;
+ border-radius: 4px;
+}}
+
+.inlinecode {{
+ background-color: {colors['text']}11;
+ padding: 0.2em 0.4em;
+ border-radius: 3px;
+ font-family: var(--font-mono);
+}}
+"""
+
+ if layout_type == "centered":
+ layout_css = """
+body {
+ max-width: 65ch;
+ margin: 0 auto;
+ padding: 2em 1em;
+ line-height: 1.6;
+}
+
+.header {
+ text-align: center;
+ margin-bottom: 3em;
+ padding-bottom: 2em;
+ border-bottom: 1px solid currentColor;
+}
+"""
+ elif layout_type == "wide":
+ layout_css = """
+body {
+ max-width: 90%;
+ margin: 0 auto;
+ padding: 2em;
+ line-height: 1.6;
+}
+
+.header {
+ display: flex;
+ justify-content: space-between;
+ align-items: center;
+ margin-bottom: 3em;
+ padding-bottom: 1em;
+ border-bottom: 2px solid currentColor;
+}
+
+p {
+ max-width: 75ch;
+}
+"""
+ elif layout_type == "magazine":
+ layout_css = """
+body {
+ max-width: 1200px;
+ margin: 0 auto;
+ padding: 2em;
+ display: grid;
+ grid-template-columns: 2fr 1fr;
+ gap: 3em;
+ line-height: 1.6;
+}
+
+.header {
+ grid-column: 1 / -1;
+ text-align: center;
+ margin-bottom: 2em;
+ padding: 2em 0;
+ background: linear-gradient(45deg, transparent 30%, currentColor 30%, currentColor 70%, transparent 70%);
+ background-size: 10px 10px;
+}
+
+.header h1 {
+ background-color: var(--bg-color);
+ padding: 0.5em 1em;
+ display: inline-block;
+}
+
+h1, h2, h3 {
+ grid-column: 1 / -1;
+}
+
+p, ul, pre, .quote {
+ grid-column: 1;
+}
+"""
+ elif layout_type == "card":
+ layout_css = f"""
+body {{
+ padding: 2em;
+ line-height: 1.6;
+ background-color: {colors['text']}08;
+}}
+
+.header {{
+ background-color: {colors['background']};
+ padding: 3em;
+ margin: -2em -2em 2em -2em;
+ box-shadow: 0 4px 20px rgba(0,0,0,0.1);
+}}
+
+h1, h2, h3 {{
+ background-color: {colors['background']};
+ padding: 1em;
+ margin-left: -1em;
+ margin-right: -1em;
+ box-shadow: 0 2px 10px rgba(0,0,0,0.05);
+}}
+
+p, ul, pre, .quote {{
+ background-color: {colors['background']};
+ padding: 1.5em;
+ margin: 1em 0;
+ border-radius: 8px;
+ box-shadow: 0 2px 10px rgba(0,0,0,0.05);
+}}
+"""
+ elif layout_type == "asymmetric":
+ layout_css = """
+body {
+ max-width: 1000px;
+ margin: 0 auto;
+ padding: 2em;
+ line-height: 1.6;
+}
+
+.header {
+ margin-left: 20%;
+ margin-bottom: 3em;
+}
+
+h1 {
+ margin-left: -5%;
+ font-size: 3em;
+}
+
+h2 {
+ margin-left: 10%;
+}
+
+h3 {
+ margin-left: 25%;
+}
+
+p:nth-child(odd) {
+ margin-left: 5%;
+ margin-right: 15%;
+}
+
+p:nth-child(even) {
+ margin-left: 15%;
+ margin-right: 5%;
+}
+"""
+ elif layout_type == "minimal_grid":
+ layout_css = """
+body {
+ display: grid;
+ grid-template-columns: repeat(12, 1fr);
+ gap: 1em;
+ padding: 2em;
+ line-height: 1.8;
+}
+
+.header {
+ grid-column: 3 / 11;
+ text-align: center;
+ margin-bottom: 2em;
+}
+
+h1 {
+ grid-column: 2 / 12;
+}
+
+h2 {
+ grid-column: 3 / 11;
+}
+
+h3 {
+ grid-column: 4 / 10;
+}
+
+p, ul, pre, .quote {
+ grid-column: 3 / 10;
+}
+"""
+ elif layout_type == "brutalist":
+ layout_css = f"""
+body {{
+ padding: 0;
+ line-height: 1.4;
+}}
+
+.header {{
+ background-color: {colors['primary']};
+ color: {colors['background']};
+ padding: 2em;
+ transform: skewY(-2deg);
+ margin-bottom: 3em;
+}}
+
+.header h1 {{
+ color: {colors['background']};
+ font-size: 4em;
+ margin: 0;
+}}
+
+h1, h2, h3 {{
+ text-transform: uppercase;
+ letter-spacing: 0.1em;
+}}
+
+p, ul, pre, .quote {{
+ margin: 2em;
+ padding: 1em;
+ border: 4px solid {colors['text']};
+}}
+
+a {{
+ background-color: {colors['secondary']};
+ color: {colors['background']};
+ padding: 0.2em 0.5em;
+}}
+"""
+ elif layout_type == "newspaper":
+ layout_css = """
+body {
+ max-width: 1200px;
+ margin: 0 auto;
+ padding: 1em;
+ column-count: 3;
+ column-gap: 2em;
+ column-rule: 1px solid currentColor;
+ line-height: 1.5;
+}
+
+.header {
+ column-span: all;
+ text-align: center;
+ border-top: 4px double currentColor;
+ border-bottom: 4px double currentColor;
+ padding: 1em 0;
+ margin-bottom: 2em;
+}
+
+h1, h2 {
+ column-span: all;
+ text-align: center;
+}
+
+h3 {
+ break-after: avoid;
+}
+
+p {
+ text-align: justify;
+ hyphens: auto;
+}
+"""
+ elif layout_type == "terminal":
+ layout_css = f"""
+body {{
+ background-color: #000;
+ color: #0f0;
+ padding: 1em;
+ font-family: var(--font-mono);
+ line-height: 1.4;
+}}
+
+.header {{
+ border: 1px solid #0f0;
+ padding: 1em;
+ margin-bottom: 2em;
+}}
+
+.header::before {{
+ content: "$ ";
+}}
+
+h1, h2, h3 {{
+ color: #0f0;
+}}
+
+h1::before {{
+ content: "### ";
+}}
+
+h2::before {{
+ content: "## ";
+}}
+
+h3::before {{
+ content: "# ";
+}}
+
+a {{
+ color: #0ff;
+}}
+
+.quote {{
+ border-left-color: #0f0;
+ background-color: #0f01;
+}}
+
+pre {{
+ border-color: #0f0;
+ background-color: #0f01;
+}}
+"""
+ elif layout_type == "book":
+ layout_css = """
+body {
+ max-width: 40em;
+ margin: 4em auto;
+ padding: 2em;
+ line-height: 1.8;
+ text-align: justify;
+ hyphens: auto;
+}
+
+.header {
+ text-align: center;
+ margin-bottom: 4em;
+ page-break-after: always;
+}
+
+h1 {
+ text-align: center;
+ margin: 3em 0 2em 0;
+}
+
+h2 {
+ margin-top: 2em;
+}
+
+p {
+ text-indent: 1.5em;
+}
+
+p:first-of-type {
+ text-indent: 0;
+}
+
+p:first-of-type::first-letter {
+ font-size: 3em;
+ line-height: 1;
+ float: left;
+ margin-right: 0.1em;
+}
+"""
+ elif layout_type == "sidebar":
+ layout_css = """
+body {
+ display: grid;
+ grid-template-columns: 250px 1fr;
+ min-height: 100vh;
+ margin: 0;
+}
+
+.header {
+ grid-column: 1;
+ position: sticky;
+ top: 0;
+ height: 100vh;
+ padding: 2em;
+ border-right: 2px solid currentColor;
+}
+
+h1, h2, h3, p, ul, pre, .quote {
+ grid-column: 2;
+ margin-left: 2em;
+ margin-right: 2em;
+ max-width: 65ch;
+}
+"""
+ elif layout_type == "hero":
+ layout_css = f"""
+body {{
+ margin: 0;
+ padding: 0;
+}}
+
+.header {{
+ min-height: 70vh;
+ display: flex;
+ flex-direction: column;
+ justify-content: center;
+ align-items: center;
+ background: linear-gradient(135deg, {colors['primary']}22, {colors['secondary']}22);
+ margin-bottom: 3em;
+}}
+
+.header h1 {{
+ font-size: 4em;
+ margin: 0;
+}}
+
+h1, h2, h3, p, ul, pre, .quote {{
+ max-width: 65ch;
+ margin-left: auto;
+ margin-right: auto;
+ padding: 0 1em;
+}}
+"""
+ elif layout_type == "masonry":
+ layout_css = """
+body {
+ padding: 2em;
+ columns: 300px auto;
+ column-gap: 2em;
+}
+
+.header {
+ column-span: all;
+ text-align: center;
+ margin-bottom: 3em;
+}
+
+h1, h2 {
+ column-span: all;
+}
+
+p, ul, pre, .quote, h3 {
+ break-inside: avoid;
+ margin-bottom: 2em;
+}
+"""
+ elif layout_type == "split":
+ layout_css = f"""
+body {{
+ display: grid;
+ grid-template-columns: 1fr 1fr;
+ min-height: 100vh;
+ margin: 0;
+}}
+
+.header {{
+ grid-column: 1;
+ background-color: {colors['primary']};
+ color: {colors['background']};
+ padding: 3em;
+ position: sticky;
+ top: 0;
+ height: 100vh;
+ display: flex;
+ flex-direction: column;
+ justify-content: center;
+}}
+
+.header h1 {{
+ color: {colors['background']};
+}}
+
+h1, h2, h3, p, ul, pre, .quote {{
+ grid-column: 2;
+ padding: 0 3em;
+}}
+"""
+ elif layout_type == "overlap":
+ layout_css = f"""
+body {{
+ padding: 2em;
+ position: relative;
+}}
+
+.header {{
+ position: relative;
+ z-index: 10;
+ background-color: {colors['background']};
+ padding: 2em;
+ margin-bottom: -2em;
+ box-shadow: 0 10px 30px rgba(0,0,0,0.1);
+}}
+
+h1 {{
+ font-size: 3em;
+ margin-top: 1em;
+ position: relative;
+ z-index: 5;
+}}
+
+h2 {{
+ margin-left: 2em;
+ position: relative;
+ z-index: 4;
+}}
+
+h3 {{
+ margin-left: 4em;
+ position: relative;
+ z-index: 3;
+}}
+
+p, ul, pre, .quote {{
+ position: relative;
+ background-color: {colors['background']};
+ padding: 1.5em;
+ margin: 1em 0 1em 3em;
+ box-shadow: 0 2px 10px rgba(0,0,0,0.05);
+}}
+
+p:nth-child(even) {{
+ margin-left: 0;
+ margin-right: 3em;
+}}
+"""
+
+ return base_css + "\n" + layout_css
+
+def download_font(font_info):
+ """Download font files from Google Fonts"""
+ font_dir = Path("fonts_cache")
+ font_dir.mkdir(exist_ok=True)
+
+ downloaded_files = []
+
+ for variant in font_info['variants']:
+ # Construct Google Fonts download URL
+ family_param = font_info['family'].replace(' ', '+')
+ weight = '400' if variant == 'regular' else variant
+
+ # Try to download from Google Fonts API
+ url = f"https://fonts.google.com/download?family={family_param}"
+
+ try:
+ response = requests.get(url, timeout=10)
+ if response.status_code == 200:
+ # Extract font files from zip
+ with zipfile.ZipFile(io.BytesIO(response.content)) as z:
+ for file in z.namelist():
+ if file.endswith('.ttf') and weight in file:
+ font_data = z.read(file)
+ filename = f"{font_info['family'].replace(' ', '_')}_{weight}.ttf"
+ filepath = font_dir / filename
+ with open(filepath, 'wb') as f:
+ f.write(font_data)
+ downloaded_files.append(filepath)
+ break
+ except Exception as e:
+ print(f"Error downloading {font_info['family']} {variant}: {e}")
+
+ return downloaded_files
+
+def create_theme(theme_name, fonts, colors, layout):
+ """Create a single theme with fonts, colors, and layout"""
+ theme_dir = Path(theme_name)
+ theme_dir.mkdir(exist_ok=True)
+
+ # Copy font files
+ theme_fonts_dir = theme_dir / "fonts"
+ theme_fonts_dir.mkdir(exist_ok=True)
+
+ font_paths = {}
+ for font_type, font_info in fonts.items():
+ if font_info['files']:
+ # Copy first available font file
+ src = font_info['files'][0]
+ dst = theme_fonts_dir / src.name
+ os.system(f"cp '{src}' '{dst}'")
+ font_paths[font_type] = f"./fonts/{src.name}"
+
+ # Create theme.conf
+ theme_conf = f"""#!/bin/bash
+# Font configuration for {theme_name} theme
+# Font licenses:
+# - {fonts['heading']['family']}: {fonts['heading']['license']}
+# - {fonts['body']['family']}: {fonts['body']['license']}
+
+declare -xr HTML_WEBFONT_HEADING="{font_paths.get('heading', './fonts/default.ttf')}"
+declare -xr HTML_WEBFONT_TEXT="{font_paths.get('body', './fonts/default.ttf')}"
+"""
+
+ with open(theme_dir / "theme.conf", "w") as f:
+ f.write(theme_conf)
+
+ # Create LICENSE file with font information
+ license_content = f"""Theme: {theme_name}
+Generated: {os.popen('date').read().strip()}
+
+Font Licenses:
+==============
+
+Heading Font: {fonts['heading']['family']}
+License: {fonts['heading']['license']}
+Category: {fonts['heading']['category']}
+
+Body Font: {fonts['body']['family']}
+License: {fonts['body']['license']}
+Category: {fonts['body']['category']}
+
+Color Scheme:
+=============
+Primary: {colors['primary']}
+Secondary: {colors['secondary']}
+Background: {colors['background']}
+Text: {colors['text']}
+Theme Type: {'Dark' if colors['is_dark'] else 'Light'}
+
+Layout: {layout}
+"""
+
+ with open(theme_dir / "LICENSE", "w") as f:
+ f.write(license_content)
+
+ # Create style.css
+ css_content = f"""/* {theme_name} theme - {layout} layout */
+@font-face {{
+ font-family: 'HeadingFont';
+ src: url('{font_paths.get('heading', './fonts/default.ttf')}') format('truetype');
+ font-weight: normal;
+ font-style: normal;
+}}
+
+@font-face {{
+ font-family: 'BodyFont';
+ src: url('{font_paths.get('body', './fonts/default.ttf')}') format('truetype');
+ font-weight: normal;
+ font-style: normal;
+}}
+
+:root {{
+ --font-heading: 'HeadingFont', serif;
+ --font-body: 'BodyFont', sans-serif;
+ --font-mono: 'Courier New', monospace;
+ --bg-color: {colors['background']};
+}}
+
+body {{
+ font-family: var(--font-body);
+}}
+
+h1, h2, h3, h4, h5, h6 {{
+ font-family: var(--font-heading);
+ font-weight: normal;
+}}
+
+{generate_layout_css(layout, colors)}
+"""
+
+ with open(theme_dir / "style.css", "w") as f:
+ f.write(css_content)
+
+ # Create example.html
+ example_html = f"""<!DOCTYPE html>
+<html lang="en">
+<head>
+ <meta charset="UTF-8">
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
+ <title>{theme_name.replace('_', ' ').title()} Theme - Gemtexter</title>
+ <link rel="stylesheet" href="style.css">
+</head>
+<body>
+ <div class="header">
+ <h1>{theme_name.replace('_', ' ').title()} Theme</h1>
+ <p>A unique combination of {fonts['heading']['family']} and {fonts['body']['family']}</p>
+ </div>
+
+ <h1>Welcome to {theme_name.replace('_', ' ').title()}</h1>
+ <p>This theme features a {layout.replace('_', ' ')} layout with a {'dark' if colors['is_dark'] else 'light'} color scheme. The typography combines {fonts['heading']['family']} for headings with {fonts['body']['family']} for body text, creating a unique reading experience.</p>
+
+ <h2>Color Palette</h2>
+ <p>The carefully selected colors work together to create visual harmony. Primary color <span style="color: {colors['primary']}">{colors['primary']}</span> pairs beautifully with secondary <span style="color: {colors['secondary']}">{colors['secondary']}</span>.</p>
+
+ <h3>Typography Showcase</h3>
+ <p>The {fonts['body']['family']} font family ({fonts['body']['category']}) provides excellent readability for body text, while {fonts['heading']['family']} ({fonts['heading']['category']}) adds character to headings.</p>
+
+ <h2>Interactive Elements</h2>
+ <p>Links like <a href="#">this example link</a> use the secondary color for clear visual distinction. Longer text links demonstrate the theme's approach to navigation:</p>
+ <a href="#" class="textlink">Explore more about this theme's unique design choices and color combinations</a>
+
+ <h2>Content Examples</h2>
+ <div class="quote">
+ "Good typography is invisible; great typography is unforgettable." This theme strives to balance both principles with its careful font selection and layout design.
+ </div>
+
+ <h3>Code Display</h3>
+ <p>Inline code like <span class="inlinecode">theme.configure()</span> stands out clearly. Larger code blocks maintain readability:</p>
+ <pre>const theme = {{
+ name: "{theme_name}",
+ layout: "{layout}",
+ fonts: {{
+ heading: "{fonts['heading']['family']}",
+ body: "{fonts['body']['family']}"
+ }},
+ isDark: {str(colors['is_dark']).lower()}
+}};</pre>
+
+ <h2>Lists and Structure</h2>
+ <p>This theme handles various content types elegantly:</p>
+ <ul>
+ <li>Clean typography with {fonts['body']['family']}</li>
+ <li>Distinctive headings using {fonts['heading']['family']}</li>
+ <li>{layout.replace('_', ' ').title()} layout for optimal content flow</li>
+ <li>{'Dark' if colors['is_dark'] else 'Light'} theme with carefully chosen colors</li>
+ </ul>
+
+ <h2>Final Thoughts</h2>
+ <p>Every element of this theme has been crafted to work in harmony. From the {layout.replace('_', ' ')} layout to the font pairing of {fonts['heading']['family']} and {fonts['body']['family']}, each choice enhances the reading experience.</p>
+
+ <p>The color scheme creates the perfect backdrop for your content, ensuring that whether you're writing technical documentation, creative prose, or anything in between, your words will shine through with clarity and style.</p>
+</body>
+</html>"""
+
+ with open(theme_dir / "example.html", "w") as f:
+ f.write(example_html)
+
+ return theme_name
+
+def generate_random_theme():
+ """Generate a complete random theme"""
+ # Random theme name
+ adjectives = ["cosmic", "serene", "vibrant", "minimal", "bold", "elegant", "modern", "classic", "dynamic", "subtle", "refined", "crisp", "warm", "cool", "fresh", "clean", "sharp", "smooth", "bright", "deep", "light", "rich", "soft", "strong", "pure", "clear", "radiant", "muted", "vivid", "gentle"]
+ nouns = ["wave", "sky", "forest", "ocean", "mountain", "valley", "desert", "river", "lake", "field", "garden", "meadow", "storm", "breeze", "mist", "frost", "flame", "spark", "glow", "shadow", "light", "dawn", "dusk", "night", "day", "season", "horizon", "vista", "peak", "flow"]
+
+ theme_name = f"{random.choice(adjectives)}_{random.choice(nouns)}"
+
+ # Random fonts
+ heading_font = random.choice([f for f in GOOGLE_FONTS if f['category'] in ['serif', 'display', 'sans-serif']])
+ body_font = random.choice([f for f in GOOGLE_FONTS if f['category'] in ['serif', 'sans-serif']])
+
+ # Download fonts
+ heading_files = download_font(heading_font)
+ body_files = download_font(body_font)
+
+ fonts = {
+ 'heading': {
+ 'family': heading_font['family'],
+ 'license': heading_font['license'],
+ 'category': heading_font['category'],
+ 'files': heading_files
+ },
+ 'body': {
+ 'family': body_font['family'],
+ 'license': body_font['license'],
+ 'category': body_font['category'],
+ 'files': body_files
+ }
+ }
+
+ # Random color palette
+ palette_generators = [generate_complementary_palette, generate_triadic_palette, generate_analogous_palette]
+ colors = random.choice(palette_generators)()
+
+ # Random layout
+ layout = random.choice(LAYOUTS)
+
+ return create_theme(theme_name, fonts, colors, layout)
+
+def main():
+ print("Generating 50 random themes with web fonts...")
+
+ # Generate themes in parallel
+ with concurrent.futures.ThreadPoolExecutor(max_workers=10) as executor:
+ futures = [executor.submit(generate_random_theme) for _ in range(50)]
+
+ themes = []
+ for i, future in enumerate(concurrent.futures.as_completed(futures)):
+ try:
+ theme_name = future.result()
+ themes.append(theme_name)
+ print(f"Created theme {i+1}/50: {theme_name}")
+ except Exception as e:
+ print(f"Error creating theme {i+1}: {e}")
+
+ print(f"\nSuccessfully created {len(themes)} themes!")
+
+ # Clean up font cache
+ os.system("rm -rf fonts_cache")
+
+ return themes
+
+if __name__ == "__main__":
+ main() \ No newline at end of file
diff --git a/extras/html/themes/generate_screenshots.py b/extras/html/themes/generate_screenshots.py
new file mode 100755
index 0000000..3b957be
--- /dev/null
+++ b/extras/html/themes/generate_screenshots.py
@@ -0,0 +1,246 @@
+#!/usr/bin/env python3
+
+import os
+import subprocess
+from pathlib import Path
+from PIL import Image, ImageDraw, ImageFont
+import time
+
+def generate_screenshots():
+ """Generate screenshots for all themes using headless browser or create preview images"""
+ themes_dir = Path("/home/paul/git/gemtexter/extras/html/themes")
+ screenshots_dir = themes_dir / "screenshots"
+ screenshots_dir.mkdir(exist_ok=True)
+
+ # Get all theme directories
+ theme_dirs = [d for d in themes_dir.iterdir() if d.is_dir() and d.name not in ['screenshots', '.git']]
+
+ print(f"Generating screenshots for {len(theme_dirs)} themes...")
+
+ for theme_dir in theme_dirs:
+ theme_name = theme_dir.name
+ example_html = theme_dir / "example.html"
+ screenshot_path = screenshots_dir / f"{theme_name}.png"
+
+ if not example_html.exists():
+ continue
+
+ print(f"Generating screenshot for {theme_name}...")
+
+ try:
+ # Try to use Playwright or Puppeteer if available
+ if check_playwright():
+ generate_with_playwright(example_html, screenshot_path)
+ # Try Firefox in headless mode
+ elif check_firefox():
+ generate_with_firefox(example_html, screenshot_path)
+ # Try Chrome/Chromium in headless mode
+ elif check_chrome():
+ generate_with_chrome(example_html, screenshot_path)
+ # Fallback to creating a preview image with PIL
+ else:
+ generate_preview_image(theme_dir, screenshot_path)
+
+ except Exception as e:
+ print(f"Error generating screenshot for {theme_name}: {e}")
+ # Fallback to preview image
+ generate_preview_image(theme_dir, screenshot_path)
+
+def check_playwright():
+ """Check if Playwright is available"""
+ try:
+ import playwright
+ return True
+ except ImportError:
+ return False
+
+def check_firefox():
+ """Check if Firefox is available"""
+ try:
+ result = subprocess.run(['firefox', '--version'], capture_output=True, text=True)
+ return result.returncode == 0
+ except:
+ return False
+
+def check_chrome():
+ """Check if Chrome/Chromium is available"""
+ for browser in ['google-chrome', 'chromium', 'chromium-browser']:
+ try:
+ result = subprocess.run([browser, '--version'], capture_output=True, text=True)
+ if result.returncode == 0:
+ return browser
+ except:
+ continue
+ return False
+
+def generate_with_playwright(html_path, output_path):
+ """Generate screenshot using Playwright"""
+ from playwright.sync_api import sync_playwright
+
+ with sync_playwright() as p:
+ browser = p.chromium.launch()
+ page = browser.new_page(viewport={'width': 1200, 'height': 800})
+ page.goto(f"file://{html_path}")
+ page.screenshot(path=str(output_path), clip={'x': 0, 'y': 0, 'width': 1200, 'height': 800})
+ browser.close()
+
+def generate_with_firefox(html_path, output_path):
+ """Generate screenshot using Firefox"""
+ cmd = [
+ 'firefox',
+ '--headless',
+ '--window-size=1200,800',
+ '--screenshot=' + str(output_path),
+ f'file://{html_path}'
+ ]
+ subprocess.run(cmd, capture_output=True)
+ time.sleep(1) # Give it time to render
+
+def generate_with_chrome(html_path, output_path):
+ """Generate screenshot using Chrome/Chromium"""
+ browser = check_chrome()
+ cmd = [
+ browser,
+ '--headless',
+ '--disable-gpu',
+ '--window-size=1200,800',
+ '--screenshot=' + str(output_path),
+ f'file://{html_path}'
+ ]
+ subprocess.run(cmd, capture_output=True)
+ time.sleep(1) # Give it time to render
+
+def generate_preview_image(theme_dir, output_path):
+ """Generate a preview image using PIL when browser is not available"""
+ # Read theme information
+ theme_name = theme_dir.name
+
+ # Try to extract colors from CSS
+ colors = extract_colors_from_css(theme_dir / "style.css")
+
+ # Create preview image
+ width, height = 400, 300
+ img = Image.new('RGB', (width, height), color=colors.get('background', '#ffffff'))
+ draw = ImageDraw.Draw(img)
+
+ # Try to use system fonts
+ try:
+ title_font = ImageFont.truetype("/usr/share/fonts/truetype/liberation/LiberationSans-Bold.ttf", 32)
+ body_font = ImageFont.truetype("/usr/share/fonts/truetype/liberation/LiberationSans-Regular.ttf", 16)
+ except:
+ title_font = ImageFont.load_default()
+ body_font = ImageFont.load_default()
+
+ # Draw theme name
+ title = theme_name.replace('_', ' ').title()
+ text_color = colors.get('text', '#000000')
+
+ # Draw background pattern
+ if colors.get('is_dark'):
+ # Dark theme - add subtle grid
+ for x in range(0, width, 20):
+ draw.line([(x, 0), (x, height)], fill=colors.get('primary', '#666666') + '22', width=1)
+ for y in range(0, height, 20):
+ draw.line([(0, y), (width, y)], fill=colors.get('primary', '#666666') + '22', width=1)
+
+ # Draw header area
+ header_height = 100
+ draw.rectangle([(0, 0), (width, header_height)], fill=colors.get('primary', '#667eea') + 'CC')
+
+ # Draw title
+ draw.text((20, 30), title, fill='white', font=title_font)
+
+ # Draw some sample elements
+ y_offset = header_height + 20
+
+ # Sample heading
+ draw.text((20, y_offset), "Sample Heading", fill=colors.get('primary', '#667eea'), font=body_font)
+ y_offset += 30
+
+ # Sample lines to represent text
+ for i in range(3):
+ line_width = width - 40 if i < 2 else width - 100
+ draw.rectangle([(20, y_offset), (line_width, y_offset + 3)], fill=text_color + '66')
+ y_offset += 10
+
+ y_offset += 10
+
+ # Sample link
+ draw.rectangle([(20, y_offset), (120, y_offset + 3)], fill=colors.get('secondary', '#764ba2'))
+ y_offset += 20
+
+ # Sample button
+ button_color = colors.get('accent', '#667eea')
+ draw.rectangle([(20, y_offset), (140, y_offset + 35)], fill=button_color, outline=None)
+ draw.text((40, y_offset + 10), "Preview", fill='white', font=body_font)
+
+ # Add layout indicator
+ layout_type = extract_layout_from_css(theme_dir / "style.css")
+ if layout_type:
+ draw.text((width - 150, height - 30), f"Layout: {layout_type}", fill=text_color + '99', font=body_font)
+
+ # Save image
+ img.save(output_path, quality=95)
+
+def extract_colors_from_css(css_path):
+ """Extract color information from CSS file"""
+ colors = {
+ 'background': '#ffffff',
+ 'text': '#000000',
+ 'primary': '#667eea',
+ 'secondary': '#764ba2',
+ 'accent': '#667eea',
+ 'is_dark': False
+ }
+
+ try:
+ with open(css_path, 'r') as f:
+ css_content = f.read()
+
+ import re
+
+ # Extract CSS variables
+ bg_match = re.search(r'--color-bg:\s*([#\w]+);', css_content)
+ if bg_match:
+ colors['background'] = bg_match.group(1)
+ # Determine if dark theme
+ if bg_match.group(1).startswith('#0') or bg_match.group(1).startswith('#1'):
+ colors['is_dark'] = True
+
+ text_match = re.search(r'--color-text:\s*([#\w]+);', css_content)
+ if text_match:
+ colors['text'] = text_match.group(1)
+
+ primary_match = re.search(r'--color-primary:\s*([#\w]+);', css_content)
+ if primary_match:
+ colors['primary'] = primary_match.group(1)
+
+ secondary_match = re.search(r'--color-secondary:\s*([#\w]+);', css_content)
+ if secondary_match:
+ colors['secondary'] = secondary_match.group(1)
+
+ accent_match = re.search(r'--color-accent:\s*([#\w]+);', css_content)
+ if accent_match:
+ colors['accent'] = accent_match.group(1)
+ except:
+ pass
+
+ return colors
+
+def extract_layout_from_css(css_path):
+ """Extract layout type from CSS file"""
+ try:
+ with open(css_path, 'r') as f:
+ css_content = f.read()
+
+ import re
+ layout_match = re.search(r'/\* Layout: (\w+) \*/', css_content)
+ if layout_match:
+ return layout_match.group(1)
+ except:
+ pass
+
+ return None
+
+if __name__ == "__main__":
+ generate_screenshots() \ No newline at end of file
diff --git a/extras/html/themes/gentle_glacier/LICENSE b/extras/html/themes/gentle_glacier/LICENSE
new file mode 100644
index 0000000..bf4110c
--- /dev/null
+++ b/extras/html/themes/gentle_glacier/LICENSE
@@ -0,0 +1,21 @@
+Theme: gentle_glacier
+Generated: 2025-06-22 21:38:55
+
+Layout: card
+Color Scheme: monochromatic (Light)
+
+Font Licenses:
+==============
+Heading Font: roboto-slab
+License: Apache
+Category: serif
+
+Body Font: oxygen
+License: OFL
+Category: sans-serif
+
+Code Font: intelone-mono
+License: OFL
+Category: monospace
+
+All fonts are free for personal use.
diff --git a/extras/html/themes/gentle_glacier/code.ttf b/extras/html/themes/gentle_glacier/code.ttf
new file mode 100644
index 0000000..2711179
--- /dev/null
+++ b/extras/html/themes/gentle_glacier/code.ttf
Binary files differ
diff --git a/extras/html/themes/gentle_glacier/example.html b/extras/html/themes/gentle_glacier/example.html
new file mode 100644
index 0000000..0ba62f7
--- /dev/null
+++ b/extras/html/themes/gentle_glacier/example.html
@@ -0,0 +1,75 @@
+<!DOCTYPE html>
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
+<head>
+ <meta charset="UTF-8" />
+ <meta name="viewport" content="width=device-width, initial-scale=1.0" />
+ <title>Gentle Glacier - Gemtexter Theme</title>
+ <link rel="stylesheet" href="style.css" />
+</head>
+<body>
+ <div class="header">
+ <h1>Gentle Glacier</h1>
+ <p>A card layout with monochromatic colors</p>
+ </div>
+
+ <div class="content">
+ <h1>Welcome to Gentle Glacier</h1>
+ <p>This theme features a carefully crafted card layout with a light monochromatic color scheme. The typography combines serif fonts for headings with sans-serif for body text.</p>
+
+ <h2>Typography Showcase</h2>
+ <p>The oxygen font family provides excellent readability for body text, while roboto-slab adds character to headings. Code blocks use intelone-mono for clarity.</p>
+
+ <h2>Color Palette</h2>
+ <p>Primary: <span style="color: #9e64c4; font-weight: bold;">#9e64c4</span> |
+ Secondary: <span style="color: #70428d; font-weight: bold;">#70428d</span> |
+ Accent: <span style="color: #b69dc6; font-weight: bold;">#b69dc6</span></p>
+
+ <h3>Interactive Elements</h3>
+ <p>Links like <a href="#">this example</a> and longer <a href="#" class="textlink">text links that demonstrate the theme's navigation style</a> use the secondary color.</p>
+
+ <div class="quote">
+ "Design is not just what it looks like and feels like. Design is how it works." — Steve Jobs
+ </div>
+
+ <h3>Code Examples</h3>
+ <p>Inline code like <code>theme.generate()</code> and larger blocks:</p>
+ <pre>// Theme configuration
+const theme = {
+ name: "gentle_glacier",
+ layout: "card",
+ colors: {
+ primary: "#9e64c4",
+ secondary: "#70428d",
+ accent: "#b69dc6"
+ },
+ fonts: {
+ heading: "roboto-slab",
+ body: "oxygen",
+ code: "intelone-mono"
+ }
+};</pre>
+
+ <h2>Content Structure</h2>
+ <ul>
+ <li>Clean, readable typography with 15px base font size</li>
+ <li>Heading scale ratio of 2.37x for visual hierarchy</li>
+ <li>Line height of 1.65 for comfortable reading</li>
+ <li>Card layout optimized for content flow</li>
+ <li>Light theme with monochromatic color harmony</li>
+ </ul>
+
+ <h2>Font Licensing</h2>
+ <p>All fonts used in this theme are properly licensed:</p>
+ <ul>
+ <li>roboto-slab: Apache License</li>
+ <li>oxygen: OFL License</li>
+ <li>intelone-mono: OFL License</li>
+ </ul>
+
+ <h3>Final Thoughts</h3>
+ <p>Every element of this theme has been carefully designed to create a harmonious reading experience. The card layout ensures content is presented in an engaging way, while the color scheme provides the perfect backdrop for your words to shine.</p>
+
+ <p>Whether you're writing technical documentation, creative prose, or anything in between, this theme adapts to showcase your content beautifully.</p>
+ </div>
+</body>
+</html> \ No newline at end of file
diff --git a/extras/html/themes/gentle_glacier/handnotes.ttf b/extras/html/themes/gentle_glacier/handnotes.ttf
new file mode 100644
index 0000000..25e688b
--- /dev/null
+++ b/extras/html/themes/gentle_glacier/handnotes.ttf
Binary files differ
diff --git a/extras/html/themes/gentle_glacier/style.css b/extras/html/themes/gentle_glacier/style.css
new file mode 100644
index 0000000..79d67f6
--- /dev/null
+++ b/extras/html/themes/gentle_glacier/style.css
@@ -0,0 +1,168 @@
+/* Base styles */
+@font-face {
+ font-family: 'text';
+ src: url("./text.ttf") format("truetype");
+}
+
+@font-face {
+ font-family: 'heading';
+ src: url("./heading.ttf") format("truetype");
+}
+
+@font-face {
+ font-family: 'code';
+ src: url("./code.ttf") format("truetype");
+}
+
+@font-face {
+ font-family: 'handnotes';
+ src: url("./handnotes.ttf") format("truetype");
+}
+
+:root {
+ --color-primary: #9e64c4;
+ --color-secondary: #70428d;
+ --color-accent: #b69dc6;
+ --color-bg: #edeaee;
+ --color-text: #242424;
+ --font-size-base: 15px;
+ --font-size-h1: 2.37em;
+ --font-size-h2: 1.78em;
+ --font-size-h3: 1.33em;
+ --line-height: 1.65;
+}
+
+* {
+ box-sizing: border-box;
+}
+
+html {
+ font-size: var(--font-size-base);
+ -webkit-font-smoothing: antialiased;
+ -moz-osx-font-smoothing: grayscale;
+}
+
+body {
+ font-family: text, sans-serif;
+ background-color: var(--color-bg);
+ color: var(--color-text);
+ line-height: var(--line-height);
+ margin: 0;
+ padding: 0;
+ overflow-wrap: break-word;
+}
+
+h1, h2, h3 {
+ font-family: heading, serif;
+ line-height: 1.2;
+ margin-top: 1em;
+ margin-bottom: 0.5em;
+}
+
+h1 {
+ font-size: var(--font-size-h1);
+ color: var(--color-primary);
+}
+
+h2 {
+ font-size: var(--font-size-h2);
+ color: var(--color-primary);
+}
+
+h3 {
+ font-size: var(--font-size-h3);
+ color: var(--color-secondary);
+}
+
+a {
+ font-family: code, monospace;
+ color: var(--color-secondary);
+ text-decoration: none;
+ transition: all 0.3s ease;
+}
+
+a:hover {
+ color: var(--color-accent);
+ text-decoration: underline;
+}
+
+.textlink {
+ font-family: text, sans-serif;
+}
+
+.quote {
+ font-family: handnotes, cursive;
+ border-left: 4px solid var(--color-accent);
+ padding: 1em 1.5em;
+ margin: 1.5em 0;
+ background-color: rgba(158, 100, 196, 0.07);
+ font-style: italic;
+}
+
+pre {
+ font-family: code, monospace;
+ background-color: rgba(36, 36, 36, 0.04);
+ border: 1px solid rgba(36, 36, 36, 0.13);
+ padding: 1em;
+ overflow-x: auto;
+ border-radius: 4px;
+ font-size: 0.9em;
+}
+
+code {
+ font-family: code, monospace;
+ background-color: rgba(36, 36, 36, 0.04);
+ padding: 0.2em 0.4em;
+ border-radius: 3px;
+ font-size: 0.9em;
+}
+
+ul, ol {
+ padding-left: 2em;
+ margin: 1em 0;
+}
+
+li {
+ margin: 0.5em 0;
+}
+
+img {
+ max-width: 100%;
+ height: auto;
+}
+
+hr {
+ border: none;
+ border-top: 1px solid rgba(36, 36, 36, 0.20);
+ margin: 2em 0;
+}
+
+
+/* Layout: card */
+
+body {
+ padding: 2em;
+ background: linear-gradient(135deg, rgba(158, 100, 196, 0.07), rgba(112, 66, 141, 0.07));
+ min-height: 100vh;
+}
+
+.header {
+ background-color: var(--color-bg);
+ padding: 3em;
+ margin-bottom: 3em;
+ border-radius: 16px;
+ box-shadow: 0 8px 32px rgba(0,0,0,0.1);
+ text-align: center;
+}
+
+h1, h2, h3, p, ul, pre, .quote {
+ background-color: var(--color-bg);
+ padding: 2em;
+ margin: 1em 0;
+ border-radius: 12px;
+ box-shadow: 0 4px 16px rgba(0,0,0,0.05);
+}
+
+h1, h2, h3 {
+ padding: 1em 2em;
+}
diff --git a/extras/html/themes/gentle_glacier/theme.conf b/extras/html/themes/gentle_glacier/theme.conf
new file mode 100644
index 0000000..19a2553
--- /dev/null
+++ b/extras/html/themes/gentle_glacier/theme.conf
@@ -0,0 +1,8 @@
+declare -xr HTML_HEADER=./extras/html/header.html.part
+declare -xr HTML_FOOTER=./extras/html/footer.html.part
+declare -xr HTML_CSS_STYLE=$HTML_THEME_DIR/style.css
+declare -xr HTML_WEBFONT_HEADING=./extras/html/fonts/roboto-slab/roboto-slab-Bold.ttf
+declare -xr HTML_WEBFONT_TEXT=./extras/html/fonts/oxygen/oxygen-Regular.ttf
+declare -xr HTML_WEBFONT_CODE=./extras/html/fonts/intelone-mono/intelone-mono-Regular.ttf
+declare -xr HTML_WEBFONT_HANDNOTES=./extras/html/fonts/khand/khand.ttf
+declare -xr SOURCE_HIGHLIGHT_CSS=./extras/html/source-highlight-styles/mono.css
diff --git a/extras/html/themes/index.html b/extras/html/themes/index.html
new file mode 100644
index 0000000..ecef268
--- /dev/null
+++ b/extras/html/themes/index.html
@@ -0,0 +1,469 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+ <meta charset="UTF-8">
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
+ <title>Gemtexter Theme Gallery - 50 Unique Themes</title>
+ <style>
+ * {
+ box-sizing: border-box;
+ margin: 0;
+ padding: 0;
+ }
+
+ body {
+ font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, sans-serif;
+ background-color: #f5f5f5;
+ color: #333;
+ line-height: 1.6;
+ }
+
+ .header {
+ background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
+ color: white;
+ text-align: center;
+ padding: 4em 2em;
+ box-shadow: 0 4px 20px rgba(0,0,0,0.1);
+ }
+
+ .header h1 {
+ font-size: 3em;
+ margin-bottom: 0.5em;
+ text-shadow: 2px 2px 4px rgba(0,0,0,0.2);
+ }
+
+ .header p {
+ font-size: 1.2em;
+ opacity: 0.9;
+ max-width: 600px;
+ margin: 0 auto;
+ }
+
+ .container {
+ max-width: 1400px;
+ margin: 0 auto;
+ padding: 2em;
+ }
+
+ .filters {
+ background: white;
+ padding: 2em;
+ border-radius: 12px;
+ box-shadow: 0 2px 10px rgba(0,0,0,0.05);
+ margin-bottom: 3em;
+ text-align: center;
+ }
+
+ .filters h2 {
+ margin-bottom: 1em;
+ color: #667eea;
+ }
+
+ .filter-buttons {
+ display: flex;
+ flex-wrap: wrap;
+ gap: 1em;
+ justify-content: center;
+ }
+
+ .filter-btn {
+ padding: 0.5em 1.5em;
+ border: 2px solid #667eea;
+ background: white;
+ color: #667eea;
+ border-radius: 25px;
+ cursor: pointer;
+ transition: all 0.3s ease;
+ font-size: 1em;
+ }
+
+ .filter-btn:hover, .filter-btn.active {
+ background: #667eea;
+ color: white;
+ }
+
+ .theme-grid {
+ display: grid;
+ grid-template-columns: repeat(auto-fill, minmax(320px, 1fr));
+ gap: 2em;
+ }
+
+ .theme-card {
+ background: white;
+ border-radius: 12px;
+ overflow: hidden;
+ box-shadow: 0 4px 20px rgba(0,0,0,0.08);
+ transition: transform 0.3s ease, box-shadow 0.3s ease;
+ position: relative;
+ }
+
+ .theme-card:hover {
+ transform: translateY(-4px);
+ box-shadow: 0 8px 30px rgba(0,0,0,0.12);
+ }
+
+ .theme-preview {
+ height: 200px;
+ background: #f0f0f0;
+ position: relative;
+ overflow: hidden;
+ }
+
+ .theme-preview img {
+ width: 100%;
+ height: 100%;
+ object-fit: cover;
+ }
+
+ .theme-preview-placeholder {
+ width: 100%;
+ height: 100%;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ font-size: 3em;
+ font-weight: bold;
+ background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
+ color: white;
+ }
+
+ .theme-info {
+ padding: 1.5em;
+ }
+
+ .theme-name {
+ font-size: 1.3em;
+ font-weight: bold;
+ margin-bottom: 0.5em;
+ color: #333;
+ }
+
+ .theme-details {
+ color: #666;
+ font-size: 0.9em;
+ margin-bottom: 1em;
+ }
+
+ .theme-tags {
+ display: flex;
+ flex-wrap: wrap;
+ gap: 0.5em;
+ margin-bottom: 1em;
+ }
+
+ .tag {
+ padding: 0.2em 0.8em;
+ background: #f0f0f0;
+ border-radius: 15px;
+ font-size: 0.85em;
+ color: #666;
+ }
+
+ .tag.layout {
+ background: #e3f2fd;
+ color: #1976d2;
+ }
+
+ .tag.color {
+ background: #fce4ec;
+ color: #c2185b;
+ }
+
+ .theme-actions {
+ display: flex;
+ gap: 1em;
+ }
+
+ .btn {
+ flex: 1;
+ padding: 0.8em;
+ text-align: center;
+ text-decoration: none;
+ border-radius: 8px;
+ transition: all 0.3s ease;
+ font-weight: 500;
+ }
+
+ .btn-preview {
+ background: #667eea;
+ color: white;
+ }
+
+ .btn-preview:hover {
+ background: #5a67d8;
+ }
+
+ .btn-download {
+ background: white;
+ color: #667eea;
+ border: 2px solid #667eea;
+ }
+
+ .btn-download:hover {
+ background: #667eea;
+ color: white;
+ }
+
+ .footer {
+ text-align: center;
+ padding: 3em 2em;
+ color: #666;
+ background: white;
+ margin-top: 4em;
+ }
+
+ .stats {
+ display: grid;
+ grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
+ gap: 2em;
+ margin: 3em 0;
+ text-align: center;
+ }
+
+ .stat {
+ background: white;
+ padding: 2em;
+ border-radius: 12px;
+ box-shadow: 0 2px 10px rgba(0,0,0,0.05);
+ }
+
+ .stat-number {
+ font-size: 3em;
+ font-weight: bold;
+ color: #667eea;
+ }
+
+ .stat-label {
+ color: #666;
+ margin-top: 0.5em;
+ }
+
+ @media (max-width: 768px) {
+ .header h1 {
+ font-size: 2em;
+ }
+
+ .theme-grid {
+ grid-template-columns: 1fr;
+ }
+ }
+ </style>
+</head>
+<body>
+ <div class="header">
+ <h1>Gemtexter Theme Gallery</h1>
+ <p>50 unique, hand-crafted themes for your Gemtext content. Each theme features carefully selected fonts, harmonious color palettes, and distinctive layouts.</p>
+ </div>
+
+ <div class="container">
+ <div class="stats">
+ <div class="stat">
+ <div class="stat-number">50</div>
+ <div class="stat-label">Unique Themes</div>
+ </div>
+ <div class="stat">
+ <div class="stat-number">24</div>
+ <div class="stat-label">Layout Types</div>
+ </div>
+ <div class="stat">
+ <div class="stat-number">15</div>
+ <div class="stat-label">Font Families</div>
+ </div>
+ <div class="stat">
+ <div class="stat-number">∞</div>
+ <div class="stat-label">Possibilities</div>
+ </div>
+ </div>
+
+ <div class="filters">
+ <h2>Filter by Layout</h2>
+ <div class="filter-buttons">
+ <button class="filter-btn active" onclick="filterThemes('all')">All Themes</button>
+ <button class="filter-btn" onclick="filterThemes('centered')">Centered</button>
+ <button class="filter-btn" onclick="filterThemes('wide')">Wide</button>
+ <button class="filter-btn" onclick="filterThemes('magazine')">Magazine</button>
+ <button class="filter-btn" onclick="filterThemes('card')">Card</button>
+ <button class="filter-btn" onclick="filterThemes('minimal')">Minimal</button>
+ <button class="filter-btn" onclick="filterThemes('brutalist')">Brutalist</button>
+ <button class="filter-btn" onclick="filterThemes('terminal')">Terminal</button>
+ <button class="filter-btn" onclick="filterThemes('book')">Book</button>
+ <button class="filter-btn" onclick="filterThemes('hero')">Hero</button>
+ <button class="filter-btn" onclick="filterThemes('dark')">Dark Themes</button>
+ <button class="filter-btn" onclick="filterThemes('light')">Light Themes</button>
+ </div>
+ </div>
+
+ <div class="theme-grid" id="themeGrid">
+ <!-- Themes will be inserted here by JavaScript -->
+ </div>
+ </div>
+
+ <div class="footer">
+ <p>All themes are free to use and include properly licensed fonts.</p>
+ <p>Generated with love for the Gemtexter community.</p>
+ </div>
+
+ <script>
+ // Theme data
+ const themes = [
+ {name: "vibrant_garden", layout: "hero", colorType: "light", fonts: ["Abril Fatface", "Lato"]},
+ {name: "pure_voyage", layout: "brutalist", colorType: "dark", fonts: ["Oxygen", "Lato"]},
+ {name: "twilight_nebula", layout: "floating", colorType: "dark", fonts: ["Roboto Slab", "Oxygen"]},
+ {name: "mystic_canyon", layout: "future", colorType: "dark", fonts: ["Merriweather", "Oxygen"]},
+ {name: "dynamic_forest", layout: "future", colorType: "light", fonts: ["Higher Jump", "Lato"]},
+ {name: "soft_horizon", layout: "geometric", colorType: "light", fonts: ["Pixelon", "Oxygen"]},
+ {name: "pastel_crystal", layout: "newspaper", colorType: "light", fonts: ["Repetition Scrolling", "Merriweather"]},
+ {name: "bright_light", layout: "magazine", colorType: "light", fonts: ["Typewriter", "Roboto Slab"]},
+ {name: "crisp_oasis", layout: "asymmetric", colorType: "light", fonts: ["Khand", "Lato"]},
+ {name: "sharp_canyon", layout: "card", colorType: "dark", fonts: ["Roboto Slab", "Oxygen"]},
+ {name: "strong_breeze", layout: "terminal", colorType: "dark", fonts: ["Oxygen", "Merriweather"]},
+ {name: "aurora_dawn", layout: "swiss", colorType: "dark", fonts: ["Merriweather", "Roboto Slab"]},
+ {name: "mystic_meadow", layout: "artistic", colorType: "light", fonts: ["Roboto Slab", "Oxygen"]},
+ {name: "vibrant_nebula", layout: "overlap", colorType: "dark", fonts: ["Higher Jump", "Oxygen"]},
+ {name: "sleek_river", layout: "sidebar", colorType: "light", fonts: ["Pixelon", "Roboto Slab"]},
+ {name: "clear_forest", layout: "gradient", colorType: "light", fonts: ["Repetition Scrolling", "Merriweather"]},
+ {name: "bold_pulse", layout: "book", colorType: "dark", fonts: ["Typewriter", "Roboto Slab"]},
+ {name: "fresh_field", layout: "organic", colorType: "light", fonts: ["Oxygen", "Lato"]},
+ {name: "clear_frost", layout: "newspaper", colorType: "dark", fonts: ["Roboto Slab", "Oxygen"]},
+ {name: "ember_mountain", layout: "brutalist", colorType: "light", fonts: ["Oxygen", "Lato"]},
+ {name: "refined_oasis", layout: "centered", colorType: "dark", fonts: ["Abril Fatface", "Lato"]},
+ {name: "sharp_mountain", layout: "wide", colorType: "light", fonts: ["Roboto Slab", "Lato"]},
+ {name: "deep_crystal", layout: "geometric", colorType: "dark", fonts: ["Abril Fatface", "Merriweather"]},
+ {name: "cozy_wave", layout: "overlap", colorType: "light", fonts: ["Roboto Slab", "Lato"]},
+ {name: "ember_mist", layout: "hero", colorType: "dark", fonts: ["Oxygen", "Merriweather"]},
+ {name: "vibrant_storm", layout: "technical", colorType: "light", fonts: ["Merriweather", "Roboto Slab"]},
+ {name: "pure_storm", layout: "organic", colorType: "dark", fonts: ["Higher Jump", "Oxygen"]},
+ {name: "cool_breeze", layout: "artistic", colorType: "light", fonts: ["Pixelon", "Roboto Slab"]},
+ {name: "ethereal_mist", layout: "minimal_grid", colorType: "dark", fonts: ["Repetition Scrolling", "Merriweather"]},
+ {name: "modern_rhythm", layout: "split", colorType: "light", fonts: ["Typewriter", "Roboto Slab"]},
+ {name: "aurora_breeze", layout: "terminal", colorType: "dark", fonts: ["Khand", "Lato"]},
+ {name: "muted_oasis", layout: "centered", colorType: "light", fonts: ["Oxygen", "Lato"]},
+ {name: "ember_night", layout: "masonry", colorType: "dark", fonts: ["Roboto Slab", "Lato"]},
+ {name: "modern_storm", layout: "book", colorType: "light", fonts: ["Oxygen", "Oxygen"]},
+ {name: "amber_glacier", layout: "magazine", colorType: "dark", fonts: ["Roboto Slab", "Merriweather"]},
+ {name: "twilight_horizon", layout: "card", colorType: "light", fonts: ["Merriweather", "Roboto Slab"]},
+ {name: "gentle_glacier", layout: "swiss", colorType: "dark", fonts: ["Roboto Slab", "Oxygen"]},
+ {name: "deep_sky", layout: "future", colorType: "light", fonts: ["Higher Jump", "Oxygen"]},
+ {name: "smooth_echo", layout: "sidebar", colorType: "dark", fonts: ["Pixelon", "Roboto Slab"]},
+ {name: "refined_aurora", layout: "wide", colorType: "light", fonts: ["Repetition Scrolling", "Merriweather"]},
+ {name: "radiant_voyage", layout: "gradient", colorType: "dark", fonts: ["Typewriter", "Roboto Slab"]},
+ {name: "cosmic_odyssey", layout: "hero", colorType: "light", fonts: ["Oxygen", "Lato"]},
+ {name: "neon_storm", layout: "brutalist", colorType: "dark", fonts: ["Abril Fatface", "Lato"]},
+ {name: "cosmic_dusk", layout: "retro", colorType: "light", fonts: ["Roboto Slab", "Oxygen"]},
+ {name: "cozy_crystal", layout: "asymmetric", colorType: "dark", fonts: ["Oxygen", "Lato"]},
+ {name: "clean_rhythm", layout: "floating", colorType: "light", fonts: ["Merriweather", "Oxygen"]},
+ {name: "pastel_canyon", layout: "minimal_grid", colorType: "dark", fonts: ["Higher Jump", "Lato"]},
+ {name: "clean_garden", layout: "newspaper", colorType: "light", fonts: ["Pixelon", "Oxygen"]},
+ {name: "twilight_meadow", layout: "masonry", colorType: "dark", fonts: ["Roboto Slab", "Oxygen"]},
+ {name: "bright_spark", layout: "split", colorType: "light", fonts: ["Roboto Slab", "Oxygen"]}
+ ];
+
+ // Generate theme cards
+ function generateThemeCards() {
+ const grid = document.getElementById('themeGrid');
+
+ themes.forEach(theme => {
+ const card = document.createElement('div');
+ card.className = 'theme-card';
+ card.setAttribute('data-layout', theme.layout);
+ card.setAttribute('data-color', theme.colorType);
+
+ const initial = theme.name.split('_').map(w => w[0].toUpperCase()).join('');
+
+ card.innerHTML = `
+ <div class="theme-preview">
+ ${getThemePreview(theme)}
+ </div>
+ <div class="theme-info">
+ <div class="theme-name">${theme.name.replace(/_/g, ' ').replace(/\b\w/g, l => l.toUpperCase())}</div>
+ <div class="theme-details">${theme.fonts.join(' + ')}</div>
+ <div class="theme-tags">
+ <span class="tag layout">${theme.layout.replace(/_/g, ' ')}</span>
+ <span class="tag color">${theme.colorType}</span>
+ </div>
+ <div class="theme-actions">
+ <a href="${theme.name}/example.html" class="btn btn-preview">Preview</a>
+ <a href="#" class="btn btn-download" onclick="downloadTheme('${theme.name}'); return false;">Download</a>
+ </div>
+ </div>
+ `;
+
+ grid.appendChild(card);
+ });
+ }
+
+ function getThemePreview(theme) {
+ // Check if screenshot exists and use it, otherwise show placeholder
+ const screenshotPath = `screenshots/${theme.name}.png`;
+
+ // Use the actual screenshot image
+ return `
+ <img src="${screenshotPath}" alt="${theme.name} preview"
+ onerror="this.onerror=null; this.outerHTML=getFallbackPreview('${theme.name}', '${theme.layout}', '${theme.colorType}');"
+ style="width: 100%; height: 100%; object-fit: cover;">
+ `;
+ }
+
+ function getFallbackPreview(name, layout, colorType) {
+ // Fallback placeholder if image fails to load
+ const colors = {
+ 'dark': ['#0a0a0a', '#1a1a1a', '#2a2a2a'],
+ 'light': ['#ffffff', '#f8f8f8', '#eeeeee']
+ };
+
+ const bgColor = colors[colorType][0];
+ const accentColor = colorType === 'dark' ? '#667eea' : '#764ba2';
+ const textColor = colorType === 'dark' ? '#ffffff' : '#1a1a1a';
+
+ return `
+ <div class="theme-preview-placeholder" style="background: ${bgColor}; color: ${textColor}; position: relative; overflow: hidden;">
+ <div style="position: absolute; top: 0; left: 0; right: 0; height: 60px; background: ${accentColor}; opacity: 0.8;"></div>
+ <div style="position: relative; z-index: 1; font-size: 2.5em; text-shadow: 2px 2px 4px rgba(0,0,0,0.3);">
+ ${name.split('_').map(w => w[0].toUpperCase()).join('')}
+ </div>
+ <div style="position: absolute; bottom: 10px; left: 10px; right: 10px; font-size: 0.8em; opacity: 0.7;">
+ ${layout.replace(/_/g, ' ')}
+ </div>
+ </div>
+ `;
+ }
+
+ // Filter themes
+ function filterThemes(filter) {
+ const cards = document.querySelectorAll('.theme-card');
+ const buttons = document.querySelectorAll('.filter-btn');
+
+ // Update active button
+ buttons.forEach(btn => {
+ btn.classList.remove('active');
+ if (btn.textContent.toLowerCase().includes(filter) || (filter === 'all' && btn.textContent === 'All Themes')) {
+ btn.classList.add('active');
+ }
+ });
+
+ // Filter cards
+ cards.forEach(card => {
+ if (filter === 'all') {
+ card.style.display = 'block';
+ } else if (filter === 'dark' || filter === 'light') {
+ card.style.display = card.getAttribute('data-color') === filter ? 'block' : 'none';
+ } else {
+ const layout = card.getAttribute('data-layout');
+ card.style.display = layout.includes(filter) ? 'block' : 'none';
+ }
+ });
+ }
+
+ // Download theme (placeholder function)
+ function downloadTheme(themeName) {
+ alert(`To use the "${themeName}" theme:\n\n1. Copy the ${themeName} directory to your themes folder\n2. Set HTML_THEME_DIR=./extras/html/themes/${themeName} in your gemtexter.conf\n3. Run ./gemtexter --generate to apply the theme`);
+ }
+
+ // Make getFallbackPreview available globally for onerror handler
+ window.getFallbackPreview = getFallbackPreview;
+
+ // Initialize
+ generateThemeCards();
+ </script>
+</body>
+</html> \ No newline at end of file
diff --git a/extras/html/themes/modern_rhythm/LICENSE b/extras/html/themes/modern_rhythm/LICENSE
new file mode 100644
index 0000000..2917786
--- /dev/null
+++ b/extras/html/themes/modern_rhythm/LICENSE
@@ -0,0 +1,21 @@
+Theme: modern_rhythm
+Generated: 2025-06-22 21:38:55
+
+Layout: floating
+Color Scheme: monochromatic (Dark)
+
+Font Licenses:
+==============
+Heading Font: repetition-scrolling
+License: Free
+Category: display
+
+Body Font: Merriweather
+License: OFL
+Category: serif
+
+Code Font: intelone-mono
+License: OFL
+Category: monospace
+
+All fonts are free for personal use.
diff --git a/extras/html/themes/modern_rhythm/code.ttf b/extras/html/themes/modern_rhythm/code.ttf
new file mode 100644
index 0000000..2711179
--- /dev/null
+++ b/extras/html/themes/modern_rhythm/code.ttf
Binary files differ
diff --git a/extras/html/themes/modern_rhythm/example.html b/extras/html/themes/modern_rhythm/example.html
new file mode 100644
index 0000000..399781d
--- /dev/null
+++ b/extras/html/themes/modern_rhythm/example.html
@@ -0,0 +1,75 @@
+<!DOCTYPE html>
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
+<head>
+ <meta charset="UTF-8" />
+ <meta name="viewport" content="width=device-width, initial-scale=1.0" />
+ <title>Modern Rhythm - Gemtexter Theme</title>
+ <link rel="stylesheet" href="style.css" />
+</head>
+<body>
+ <div class="header">
+ <h1>Modern Rhythm</h1>
+ <p>A floating layout with monochromatic colors</p>
+ </div>
+
+ <div class="content">
+ <h1>Welcome to Modern Rhythm</h1>
+ <p>This theme features a carefully crafted floating layout with a dark monochromatic color scheme. The typography combines display fonts for headings with serif for body text.</p>
+
+ <h2>Typography Showcase</h2>
+ <p>The Merriweather font family provides excellent readability for body text, while repetition-scrolling adds character to headings. Code blocks use intelone-mono for clarity.</p>
+
+ <h2>Color Palette</h2>
+ <p>Primary: <span style="color: #22ef87; font-weight: bold;">#22ef87</span> |
+ Secondary: <span style="color: #1da25e; font-weight: bold;">#1da25e</span> |
+ Accent: <span style="color: #74d3a3; font-weight: bold;">#74d3a3</span></p>
+
+ <h3>Interactive Elements</h3>
+ <p>Links like <a href="#">this example</a> and longer <a href="#" class="textlink">text links that demonstrate the theme's navigation style</a> use the secondary color.</p>
+
+ <div class="quote">
+ "Design is not just what it looks like and feels like. Design is how it works." — Steve Jobs
+ </div>
+
+ <h3>Code Examples</h3>
+ <p>Inline code like <code>theme.generate()</code> and larger blocks:</p>
+ <pre>// Theme configuration
+const theme = {
+ name: "modern_rhythm",
+ layout: "floating",
+ colors: {
+ primary: "#22ef87",
+ secondary: "#1da25e",
+ accent: "#74d3a3"
+ },
+ fonts: {
+ heading: "repetition-scrolling",
+ body: "Merriweather",
+ code: "intelone-mono"
+ }
+};</pre>
+
+ <h2>Content Structure</h2>
+ <ul>
+ <li>Clean, readable typography with 15px base font size</li>
+ <li>Heading scale ratio of 1.95x for visual hierarchy</li>
+ <li>Line height of 1.77 for comfortable reading</li>
+ <li>Floating layout optimized for content flow</li>
+ <li>Dark theme with monochromatic color harmony</li>
+ </ul>
+
+ <h2>Font Licensing</h2>
+ <p>All fonts used in this theme are properly licensed:</p>
+ <ul>
+ <li>repetition-scrolling: Free License</li>
+ <li>Merriweather: OFL License</li>
+ <li>intelone-mono: OFL License</li>
+ </ul>
+
+ <h3>Final Thoughts</h3>
+ <p>Every element of this theme has been carefully designed to create a harmonious reading experience. The floating layout ensures content is presented in an engaging way, while the color scheme provides the perfect backdrop for your words to shine.</p>
+
+ <p>Whether you're writing technical documentation, creative prose, or anything in between, this theme adapts to showcase your content beautifully.</p>
+ </div>
+</body>
+</html> \ No newline at end of file
diff --git a/extras/html/themes/modern_rhythm/handnotes.ttf b/extras/html/themes/modern_rhythm/handnotes.ttf
new file mode 100644
index 0000000..25e688b
--- /dev/null
+++ b/extras/html/themes/modern_rhythm/handnotes.ttf
Binary files differ
diff --git a/extras/html/themes/modern_rhythm/heading.ttf b/extras/html/themes/modern_rhythm/heading.ttf
new file mode 100644
index 0000000..1d0a401
--- /dev/null
+++ b/extras/html/themes/modern_rhythm/heading.ttf
Binary files differ
diff --git a/extras/html/themes/modern_rhythm/style.css b/extras/html/themes/modern_rhythm/style.css
new file mode 100644
index 0000000..4c05b37
--- /dev/null
+++ b/extras/html/themes/modern_rhythm/style.css
@@ -0,0 +1,173 @@
+/* Base styles */
+@font-face {
+ font-family: 'text';
+ src: url("./text.ttf") format("truetype");
+}
+
+@font-face {
+ font-family: 'heading';
+ src: url("./heading.ttf") format("truetype");
+}
+
+@font-face {
+ font-family: 'code';
+ src: url("./code.ttf") format("truetype");
+}
+
+@font-face {
+ font-family: 'handnotes';
+ src: url("./handnotes.ttf") format("truetype");
+}
+
+:root {
+ --color-primary: #22ef87;
+ --color-secondary: #1da25e;
+ --color-accent: #74d3a3;
+ --color-bg: #1f2723;
+ --color-text: #e8e8e8;
+ --font-size-base: 15px;
+ --font-size-h1: 1.95em;
+ --font-size-h2: 1.56em;
+ --font-size-h3: 1.25em;
+ --line-height: 1.77;
+}
+
+* {
+ box-sizing: border-box;
+}
+
+html {
+ font-size: var(--font-size-base);
+ -webkit-font-smoothing: antialiased;
+ -moz-osx-font-smoothing: grayscale;
+}
+
+body {
+ font-family: text, sans-serif;
+ background-color: var(--color-bg);
+ color: var(--color-text);
+ line-height: var(--line-height);
+ margin: 0;
+ padding: 0;
+ overflow-wrap: break-word;
+}
+
+h1, h2, h3 {
+ font-family: heading, serif;
+ line-height: 1.2;
+ margin-top: 1em;
+ margin-bottom: 0.5em;
+}
+
+h1 {
+ font-size: var(--font-size-h1);
+ color: var(--color-primary);
+}
+
+h2 {
+ font-size: var(--font-size-h2);
+ color: var(--color-primary);
+}
+
+h3 {
+ font-size: var(--font-size-h3);
+ color: var(--color-secondary);
+}
+
+a {
+ font-family: code, monospace;
+ color: var(--color-secondary);
+ text-decoration: none;
+ transition: all 0.3s ease;
+}
+
+a:hover {
+ color: var(--color-accent);
+ text-decoration: underline;
+}
+
+.textlink {
+ font-family: text, sans-serif;
+}
+
+.quote {
+ font-family: handnotes, cursive;
+ border-left: 4px solid var(--color-accent);
+ padding: 1em 1.5em;
+ margin: 1.5em 0;
+ background-color: rgba(34, 239, 135, 0.07);
+ font-style: italic;
+}
+
+pre {
+ font-family: code, monospace;
+ background-color: rgba(232, 232, 232, 0.04);
+ border: 1px solid rgba(232, 232, 232, 0.13);
+ padding: 1em;
+ overflow-x: auto;
+ border-radius: 4px;
+ font-size: 0.9em;
+}
+
+code {
+ font-family: code, monospace;
+ background-color: rgba(232, 232, 232, 0.04);
+ padding: 0.2em 0.4em;
+ border-radius: 3px;
+ font-size: 0.9em;
+}
+
+ul, ol {
+ padding-left: 2em;
+ margin: 1em 0;
+}
+
+li {
+ margin: 0.5em 0;
+}
+
+img {
+ max-width: 100%;
+ height: auto;
+}
+
+hr {
+ border: none;
+ border-top: 1px solid rgba(232, 232, 232, 0.20);
+ margin: 2em 0;
+}
+
+
+/* Layout: floating */
+
+body {
+ padding: 4em 2em;
+ background: linear-gradient(45deg, rgba(34, 239, 135, 0.07), rgba(29, 162, 94, 0.07));
+ min-height: 100vh;
+}
+
+.header {
+ text-align: center;
+ margin-bottom: 4em;
+ animation: float 6s ease-in-out infinite;
+}
+
+@keyframes float {
+ 0%, 100% { transform: translateY(0); }
+ 50% { transform: translateY(-20px); }
+}
+
+h1, h2, h3, p, ul, pre, .quote {
+ background-color: var(--color-bg);
+ padding: 2em;
+ margin: 2em auto;
+ max-width: 65ch;
+ border-radius: 16px;
+ box-shadow: 0 8px 32px rgba(0,0,0,0.1);
+ transition: transform 0.3s ease;
+}
+
+h1:hover, h2:hover, h3:hover, p:hover, ul:hover, pre:hover, .quote:hover {
+ transform: translateY(-4px);
+ box-shadow: 0 12px 48px rgba(0,0,0,0.15);
+}
diff --git a/extras/html/themes/modern_rhythm/text.ttf b/extras/html/themes/modern_rhythm/text.ttf
new file mode 100644
index 0000000..3fecc77
--- /dev/null
+++ b/extras/html/themes/modern_rhythm/text.ttf
Binary files differ
diff --git a/extras/html/themes/modern_rhythm/theme.conf b/extras/html/themes/modern_rhythm/theme.conf
new file mode 100644
index 0000000..b571a24
--- /dev/null
+++ b/extras/html/themes/modern_rhythm/theme.conf
@@ -0,0 +1,8 @@
+declare -xr HTML_HEADER=./extras/html/header.html.part
+declare -xr HTML_FOOTER=./extras/html/footer.html.part
+declare -xr HTML_CSS_STYLE=$HTML_THEME_DIR/style.css
+declare -xr HTML_WEBFONT_HEADING=./extras/html/fonts/repetition-scrolling/repetition-scrolling-Bold.ttf
+declare -xr HTML_WEBFONT_TEXT=./extras/html/fonts/Merriweather/Merriweather-Regular.ttf
+declare -xr HTML_WEBFONT_CODE=./extras/html/fonts/intelone-mono/intelone-mono-Regular.ttf
+declare -xr HTML_WEBFONT_HANDNOTES=./extras/html/fonts/khand/khand.ttf
+declare -xr SOURCE_HIGHLIGHT_CSS=./extras/html/source-highlight-styles/mono.css
diff --git a/extras/html/themes/modern_storm/LICENSE b/extras/html/themes/modern_storm/LICENSE
new file mode 100644
index 0000000..ad6ad4e
--- /dev/null
+++ b/extras/html/themes/modern_storm/LICENSE
@@ -0,0 +1,21 @@
+Theme: modern_storm
+Generated: 2025-06-22 21:38:55
+
+Layout: wide
+Color Scheme: split_complementary (Light)
+
+Font Licenses:
+==============
+Heading Font: roboto-slab
+License: Apache
+Category: serif
+
+Body Font: oxygen
+License: OFL
+Category: sans-serif
+
+Code Font: intelone-mono
+License: OFL
+Category: monospace
+
+All fonts are free for personal use.
diff --git a/extras/html/themes/modern_storm/code.ttf b/extras/html/themes/modern_storm/code.ttf
new file mode 100644
index 0000000..2711179
--- /dev/null
+++ b/extras/html/themes/modern_storm/code.ttf
Binary files differ
diff --git a/extras/html/themes/modern_storm/example.html b/extras/html/themes/modern_storm/example.html
new file mode 100644
index 0000000..ee4c9bd
--- /dev/null
+++ b/extras/html/themes/modern_storm/example.html
@@ -0,0 +1,75 @@
+<!DOCTYPE html>
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
+<head>
+ <meta charset="UTF-8" />
+ <meta name="viewport" content="width=device-width, initial-scale=1.0" />
+ <title>Modern Storm - Gemtexter Theme</title>
+ <link rel="stylesheet" href="style.css" />
+</head>
+<body>
+ <div class="header">
+ <h1>Modern Storm</h1>
+ <p>A wide layout with split complementary colors</p>
+ </div>
+
+ <div class="content">
+ <h1>Welcome to Modern Storm</h1>
+ <p>This theme features a carefully crafted wide layout with a light split complementary color scheme. The typography combines serif fonts for headings with sans-serif for body text.</p>
+
+ <h2>Typography Showcase</h2>
+ <p>The oxygen font family provides excellent readability for body text, while roboto-slab adds character to headings. Code blocks use intelone-mono for clarity.</p>
+
+ <h2>Color Palette</h2>
+ <p>Primary: <span style="color: #822121; font-weight: bold;">#822121</span> |
+ Secondary: <span style="color: #2a7853; font-weight: bold;">#2a7853</span> |
+ Accent: <span style="color: #2a5378; font-weight: bold;">#2a5378</span></p>
+
+ <h3>Interactive Elements</h3>
+ <p>Links like <a href="#">this example</a> and longer <a href="#" class="textlink">text links that demonstrate the theme's navigation style</a> use the secondary color.</p>
+
+ <div class="quote">
+ "Design is not just what it looks like and feels like. Design is how it works." — Steve Jobs
+ </div>
+
+ <h3>Code Examples</h3>
+ <p>Inline code like <code>theme.generate()</code> and larger blocks:</p>
+ <pre>// Theme configuration
+const theme = {
+ name: "modern_storm",
+ layout: "wide",
+ colors: {
+ primary: "#822121",
+ secondary: "#2a7853",
+ accent: "#2a5378"
+ },
+ fonts: {
+ heading: "roboto-slab",
+ body: "oxygen",
+ code: "intelone-mono"
+ }
+};</pre>
+
+ <h2>Content Structure</h2>
+ <ul>
+ <li>Clean, readable typography with 16px base font size</li>
+ <li>Heading scale ratio of 2.83x for visual hierarchy</li>
+ <li>Line height of 1.66 for comfortable reading</li>
+ <li>Wide layout optimized for content flow</li>
+ <li>Light theme with split complementary color harmony</li>
+ </ul>
+
+ <h2>Font Licensing</h2>
+ <p>All fonts used in this theme are properly licensed:</p>
+ <ul>
+ <li>roboto-slab: Apache License</li>
+ <li>oxygen: OFL License</li>
+ <li>intelone-mono: OFL License</li>
+ </ul>
+
+ <h3>Final Thoughts</h3>
+ <p>Every element of this theme has been carefully designed to create a harmonious reading experience. The wide layout ensures content is presented in an engaging way, while the color scheme provides the perfect backdrop for your words to shine.</p>
+
+ <p>Whether you're writing technical documentation, creative prose, or anything in between, this theme adapts to showcase your content beautifully.</p>
+ </div>
+</body>
+</html> \ No newline at end of file
diff --git a/extras/html/themes/modern_storm/handnotes.ttf b/extras/html/themes/modern_storm/handnotes.ttf
new file mode 100644
index 0000000..25e688b
--- /dev/null
+++ b/extras/html/themes/modern_storm/handnotes.ttf
Binary files differ
diff --git a/extras/html/themes/modern_storm/style.css b/extras/html/themes/modern_storm/style.css
new file mode 100644
index 0000000..9fbe8c2
--- /dev/null
+++ b/extras/html/themes/modern_storm/style.css
@@ -0,0 +1,161 @@
+/* Base styles */
+@font-face {
+ font-family: 'text';
+ src: url("./text.ttf") format("truetype");
+}
+
+@font-face {
+ font-family: 'heading';
+ src: url("./heading.ttf") format("truetype");
+}
+
+@font-face {
+ font-family: 'code';
+ src: url("./code.ttf") format("truetype");
+}
+
+@font-face {
+ font-family: 'handnotes';
+ src: url("./handnotes.ttf") format("truetype");
+}
+
+:root {
+ --color-primary: #822121;
+ --color-secondary: #2a7853;
+ --color-accent: #2a5378;
+ --color-bg: #efecec;
+ --color-text: #212121;
+ --font-size-base: 16px;
+ --font-size-h1: 2.83em;
+ --font-size-h2: 2.0em;
+ --font-size-h3: 1.41em;
+ --line-height: 1.66;
+}
+
+* {
+ box-sizing: border-box;
+}
+
+html {
+ font-size: var(--font-size-base);
+ -webkit-font-smoothing: antialiased;
+ -moz-osx-font-smoothing: grayscale;
+}
+
+body {
+ font-family: text, sans-serif;
+ background-color: var(--color-bg);
+ color: var(--color-text);
+ line-height: var(--line-height);
+ margin: 0;
+ padding: 0;
+ overflow-wrap: break-word;
+}
+
+h1, h2, h3 {
+ font-family: heading, serif;
+ line-height: 1.2;
+ margin-top: 1em;
+ margin-bottom: 0.5em;
+}
+
+h1 {
+ font-size: var(--font-size-h1);
+ color: var(--color-primary);
+}
+
+h2 {
+ font-size: var(--font-size-h2);
+ color: var(--color-primary);
+}
+
+h3 {
+ font-size: var(--font-size-h3);
+ color: var(--color-secondary);
+}
+
+a {
+ font-family: code, monospace;
+ color: var(--color-secondary);
+ text-decoration: none;
+ transition: all 0.3s ease;
+}
+
+a:hover {
+ color: var(--color-accent);
+ text-decoration: underline;
+}
+
+.textlink {
+ font-family: text, sans-serif;
+}
+
+.quote {
+ font-family: handnotes, cursive;
+ border-left: 4px solid var(--color-accent);
+ padding: 1em 1.5em;
+ margin: 1.5em 0;
+ background-color: rgba(130, 33, 33, 0.07);
+ font-style: italic;
+}
+
+pre {
+ font-family: code, monospace;
+ background-color: rgba(33, 33, 33, 0.04);
+ border: 1px solid rgba(33, 33, 33, 0.13);
+ padding: 1em;
+ overflow-x: auto;
+ border-radius: 4px;
+ font-size: 0.9em;
+}
+
+code {
+ font-family: code, monospace;
+ background-color: rgba(33, 33, 33, 0.04);
+ padding: 0.2em 0.4em;
+ border-radius: 3px;
+ font-size: 0.9em;
+}
+
+ul, ol {
+ padding-left: 2em;
+ margin: 1em 0;
+}
+
+li {
+ margin: 0.5em 0;
+}
+
+img {
+ max-width: 100%;
+ height: auto;
+}
+
+hr {
+ border: none;
+ border-top: 1px solid rgba(33, 33, 33, 0.20);
+ margin: 2em 0;
+}
+
+
+/* Layout: wide */
+
+body {
+ max-width: 90%;
+ margin: 0 auto;
+ padding: 3em 2em;
+}
+
+.header {
+ display: flex;
+ justify-content: space-between;
+ align-items: baseline;
+ margin-bottom: 4em;
+ padding-bottom: 2em;
+ border-bottom: 3px solid var(--color-primary);
+}
+
+.content {
+ max-width: 75ch;
+ margin: 0 auto;
+}
diff --git a/extras/html/themes/modern_storm/theme.conf b/extras/html/themes/modern_storm/theme.conf
new file mode 100644
index 0000000..19a2553
--- /dev/null
+++ b/extras/html/themes/modern_storm/theme.conf
@@ -0,0 +1,8 @@
+declare -xr HTML_HEADER=./extras/html/header.html.part
+declare -xr HTML_FOOTER=./extras/html/footer.html.part
+declare -xr HTML_CSS_STYLE=$HTML_THEME_DIR/style.css
+declare -xr HTML_WEBFONT_HEADING=./extras/html/fonts/roboto-slab/roboto-slab-Bold.ttf
+declare -xr HTML_WEBFONT_TEXT=./extras/html/fonts/oxygen/oxygen-Regular.ttf
+declare -xr HTML_WEBFONT_CODE=./extras/html/fonts/intelone-mono/intelone-mono-Regular.ttf
+declare -xr HTML_WEBFONT_HANDNOTES=./extras/html/fonts/khand/khand.ttf
+declare -xr SOURCE_HIGHLIGHT_CSS=./extras/html/source-highlight-styles/mono.css
diff --git a/extras/html/themes/muted_oasis/LICENSE b/extras/html/themes/muted_oasis/LICENSE
new file mode 100644
index 0000000..20a2179
--- /dev/null
+++ b/extras/html/themes/muted_oasis/LICENSE
@@ -0,0 +1,21 @@
+Theme: muted_oasis
+Generated: 2025-06-22 21:38:55
+
+Layout: technical
+Color Scheme: split_complementary (Dark)
+
+Font Licenses:
+==============
+Heading Font: oxygen
+License: OFL
+Category: sans-serif
+
+Body Font: Merriweather
+License: OFL
+Category: serif
+
+Code Font: intelone-mono
+License: OFL
+Category: monospace
+
+All fonts are free for personal use.
diff --git a/extras/html/themes/muted_oasis/code.ttf b/extras/html/themes/muted_oasis/code.ttf
new file mode 100644
index 0000000..2711179
--- /dev/null
+++ b/extras/html/themes/muted_oasis/code.ttf
Binary files differ
diff --git a/extras/html/themes/muted_oasis/example.html b/extras/html/themes/muted_oasis/example.html
new file mode 100644
index 0000000..c9c4bf1
--- /dev/null
+++ b/extras/html/themes/muted_oasis/example.html
@@ -0,0 +1,75 @@
+<!DOCTYPE html>
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
+<head>
+ <meta charset="UTF-8" />
+ <meta name="viewport" content="width=device-width, initial-scale=1.0" />
+ <title>Muted Oasis - Gemtexter Theme</title>
+ <link rel="stylesheet" href="style.css" />
+</head>
+<body>
+ <div class="header">
+ <h1>Muted Oasis</h1>
+ <p>A technical layout with split complementary colors</p>
+ </div>
+
+ <div class="content">
+ <h1>Welcome to Muted Oasis</h1>
+ <p>This theme features a carefully crafted technical layout with a dark split complementary color scheme. The typography combines sans-serif fonts for headings with serif for body text.</p>
+
+ <h2>Typography Showcase</h2>
+ <p>The Merriweather font family provides excellent readability for body text, while oxygen adds character to headings. Code blocks use intelone-mono for clarity.</p>
+
+ <h2>Color Palette</h2>
+ <p>Primary: <span style="color: #50d619; font-weight: bold;">#50d619</span> |
+ Secondary: <span style="color: #4e2cc3; font-weight: bold;">#4e2cc3</span> |
+ Accent: <span style="color: #c32ca7; font-weight: bold;">#c32ca7</span></p>
+
+ <h3>Interactive Elements</h3>
+ <p>Links like <a href="#">this example</a> and longer <a href="#" class="textlink">text links that demonstrate the theme's navigation style</a> use the secondary color.</p>
+
+ <div class="quote">
+ "Design is not just what it looks like and feels like. Design is how it works." — Steve Jobs
+ </div>
+
+ <h3>Code Examples</h3>
+ <p>Inline code like <code>theme.generate()</code> and larger blocks:</p>
+ <pre>// Theme configuration
+const theme = {
+ name: "muted_oasis",
+ layout: "technical",
+ colors: {
+ primary: "#50d619",
+ secondary: "#4e2cc3",
+ accent: "#c32ca7"
+ },
+ fonts: {
+ heading: "oxygen",
+ body: "Merriweather",
+ code: "intelone-mono"
+ }
+};</pre>
+
+ <h2>Content Structure</h2>
+ <ul>
+ <li>Clean, readable typography with 14px base font size</li>
+ <li>Heading scale ratio of 1.73x for visual hierarchy</li>
+ <li>Line height of 1.43 for comfortable reading</li>
+ <li>Technical layout optimized for content flow</li>
+ <li>Dark theme with split complementary color harmony</li>
+ </ul>
+
+ <h2>Font Licensing</h2>
+ <p>All fonts used in this theme are properly licensed:</p>
+ <ul>
+ <li>oxygen: OFL License</li>
+ <li>Merriweather: OFL License</li>
+ <li>intelone-mono: OFL License</li>
+ </ul>
+
+ <h3>Final Thoughts</h3>
+ <p>Every element of this theme has been carefully designed to create a harmonious reading experience. The technical layout ensures content is presented in an engaging way, while the color scheme provides the perfect backdrop for your words to shine.</p>
+
+ <p>Whether you're writing technical documentation, creative prose, or anything in between, this theme adapts to showcase your content beautifully.</p>
+ </div>
+</body>
+</html> \ No newline at end of file
diff --git a/extras/html/themes/muted_oasis/handnotes.ttf b/extras/html/themes/muted_oasis/handnotes.ttf
new file mode 100644
index 0000000..25e688b
--- /dev/null
+++ b/extras/html/themes/muted_oasis/handnotes.ttf
Binary files differ
diff --git a/extras/html/themes/muted_oasis/style.css b/extras/html/themes/muted_oasis/style.css
new file mode 100644
index 0000000..520c1de
--- /dev/null
+++ b/extras/html/themes/muted_oasis/style.css
@@ -0,0 +1,208 @@
+/* Base styles */
+@font-face {
+ font-family: 'text';
+ src: url("./text.ttf") format("truetype");
+}
+
+@font-face {
+ font-family: 'heading';
+ src: url("./heading.ttf") format("truetype");
+}
+
+@font-face {
+ font-family: 'code';
+ src: url("./code.ttf") format("truetype");
+}
+
+@font-face {
+ font-family: 'handnotes';
+ src: url("./handnotes.ttf") format("truetype");
+}
+
+:root {
+ --color-primary: #50d619;
+ --color-secondary: #4e2cc3;
+ --color-accent: #c32ca7;
+ --color-bg: #0e110e;
+ --color-text: #e2e2e2;
+ --font-size-base: 14px;
+ --font-size-h1: 1.73em;
+ --font-size-h2: 1.44em;
+ --font-size-h3: 1.2em;
+ --line-height: 1.43;
+}
+
+* {
+ box-sizing: border-box;
+}
+
+html {
+ font-size: var(--font-size-base);
+ -webkit-font-smoothing: antialiased;
+ -moz-osx-font-smoothing: grayscale;
+}
+
+body {
+ font-family: text, sans-serif;
+ background-color: var(--color-bg);
+ color: var(--color-text);
+ line-height: var(--line-height);
+ margin: 0;
+ padding: 0;
+ overflow-wrap: break-word;
+}
+
+h1, h2, h3 {
+ font-family: heading, serif;
+ line-height: 1.2;
+ margin-top: 1em;
+ margin-bottom: 0.5em;
+}
+
+h1 {
+ font-size: var(--font-size-h1);
+ color: var(--color-primary);
+}
+
+h2 {
+ font-size: var(--font-size-h2);
+ color: var(--color-primary);
+}
+
+h3 {
+ font-size: var(--font-size-h3);
+ color: var(--color-secondary);
+}
+
+a {
+ font-family: code, monospace;
+ color: var(--color-secondary);
+ text-decoration: none;
+ transition: all 0.3s ease;
+}
+
+a:hover {
+ color: var(--color-accent);
+ text-decoration: underline;
+}
+
+.textlink {
+ font-family: text, sans-serif;
+}
+
+.quote {
+ font-family: handnotes, cursive;
+ border-left: 4px solid var(--color-accent);
+ padding: 1em 1.5em;
+ margin: 1.5em 0;
+ background-color: rgba(80, 214, 25, 0.07);
+ font-style: italic;
+}
+
+pre {
+ font-family: code, monospace;
+ background-color: rgba(226, 226, 226, 0.04);
+ border: 1px solid rgba(226, 226, 226, 0.13);
+ padding: 1em;
+ overflow-x: auto;
+ border-radius: 4px;
+ font-size: 0.9em;
+}
+
+code {
+ font-family: code, monospace;
+ background-color: rgba(226, 226, 226, 0.04);
+ padding: 0.2em 0.4em;
+ border-radius: 3px;
+ font-size: 0.9em;
+}
+
+ul, ol {
+ padding-left: 2em;
+ margin: 1em 0;
+}
+
+li {
+ margin: 0.5em 0;
+}
+
+img {
+ max-width: 100%;
+ height: auto;
+}
+
+hr {
+ border: none;
+ border-top: 1px solid rgba(226, 226, 226, 0.20);
+ margin: 2em 0;
+}
+
+
+/* Layout: technical */
+
+body {
+ font-family: code, monospace;
+ background-color: #0a0a0a;
+ color: #e0e0e0;
+ padding: 2em;
+ background-image: linear-gradient(rgba(255,255,255,0.03) 1px, transparent 1px), linear-gradient(90deg, rgba(255,255,255,0.03) 1px, transparent 1px);
+ background-size: 20px 20px;
+}
+
+.header {
+ border: 2px solid #50d619;
+ padding: 2em;
+ margin-bottom: 3em;
+ position: relative;
+ background: linear-gradient(135deg, transparent 10px, #0a0a0a 10px);
+}
+
+.header::before {
+ content: "//";
+ position: absolute;
+ top: 10px;
+ left: 10px;
+ color: #50d619;
+ font-size: 2em;
+}
+
+h1, h2, h3 {
+ font-family: code, monospace;
+ text-transform: uppercase;
+ letter-spacing: 0.1em;
+ border-left: 4px solid #c32ca7;
+ padding-left: 1em;
+}
+
+h1::before { content: "001 "; color: #50d619; }
+h2::before { content: "010 "; color: #4e2cc3; }
+h3::before { content: "011 "; color: #c32ca7; }
+
+p, ul, pre, .quote {
+ background-color: rgba(255,255,255,0.02);
+ border: 1px solid rgba(255,255,255,0.1);
+ padding: 1.5em;
+ margin: 1.5em 0;
+ position: relative;
+}
+
+p::before, ul::before, .quote::before {
+ content: ">";
+ position: absolute;
+ left: -1em;
+ color: #c32ca7;
+}
+
+a {
+ color: #c32ca7;
+ text-decoration: none;
+ padding: 0.2em 0.4em;
+ background-color: rgba(255,255,255,0.05);
+ border: 1px solid rgba(195, 44, 167, 0.20);
+ transition: all 0.3s ease;
+}
+
+a:hover {
+ background-color: rgba(195, 44, 167, 0.13);
+ border-color: #c32ca7;
+}
diff --git a/extras/html/themes/muted_oasis/text.ttf b/extras/html/themes/muted_oasis/text.ttf
new file mode 100644
index 0000000..3fecc77
--- /dev/null
+++ b/extras/html/themes/muted_oasis/text.ttf
Binary files differ
diff --git a/extras/html/themes/muted_oasis/theme.conf b/extras/html/themes/muted_oasis/theme.conf
new file mode 100644
index 0000000..11ad64d
--- /dev/null
+++ b/extras/html/themes/muted_oasis/theme.conf
@@ -0,0 +1,8 @@
+declare -xr HTML_HEADER=./extras/html/header.html.part
+declare -xr HTML_FOOTER=./extras/html/footer.html.part
+declare -xr HTML_CSS_STYLE=$HTML_THEME_DIR/style.css
+declare -xr HTML_WEBFONT_HEADING=./extras/html/fonts/oxygen/oxygen-Bold.ttf
+declare -xr HTML_WEBFONT_TEXT=./extras/html/fonts/Merriweather/Merriweather-Regular.ttf
+declare -xr HTML_WEBFONT_CODE=./extras/html/fonts/intelone-mono/intelone-mono-Regular.ttf
+declare -xr HTML_WEBFONT_HANDNOTES=./extras/html/fonts/khand/khand.ttf
+declare -xr SOURCE_HIGHLIGHT_CSS=./extras/html/source-highlight-styles/mono.css
diff --git a/extras/html/themes/mystic_canyon/LICENSE b/extras/html/themes/mystic_canyon/LICENSE
new file mode 100644
index 0000000..33fc51d
--- /dev/null
+++ b/extras/html/themes/mystic_canyon/LICENSE
@@ -0,0 +1,21 @@
+Theme: mystic_canyon
+Generated: 2025-06-22 21:38:55
+
+Layout: centered
+Color Scheme: complementary (Dark)
+
+Font Licenses:
+==============
+Heading Font: zai-aeg-mignon-typewriter-1924
+License: Free
+Category: display
+
+Body Font: roboto-slab
+License: Apache
+Category: serif
+
+Code Font: hack
+License: MIT
+Category: monospace
+
+All fonts are free for personal use.
diff --git a/extras/html/themes/mystic_canyon/code.ttf b/extras/html/themes/mystic_canyon/code.ttf
new file mode 100644
index 0000000..7c8e65b
--- /dev/null
+++ b/extras/html/themes/mystic_canyon/code.ttf
Binary files differ
diff --git a/extras/html/themes/mystic_canyon/example.html b/extras/html/themes/mystic_canyon/example.html
new file mode 100644
index 0000000..a848760
--- /dev/null
+++ b/extras/html/themes/mystic_canyon/example.html
@@ -0,0 +1,75 @@
+<!DOCTYPE html>
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
+<head>
+ <meta charset="UTF-8" />
+ <meta name="viewport" content="width=device-width, initial-scale=1.0" />
+ <title>Mystic Canyon - Gemtexter Theme</title>
+ <link rel="stylesheet" href="style.css" />
+</head>
+<body>
+ <div class="header">
+ <h1>Mystic Canyon</h1>
+ <p>A centered layout with complementary colors</p>
+ </div>
+
+ <div class="content">
+ <h1>Welcome to Mystic Canyon</h1>
+ <p>This theme features a carefully crafted centered layout with a dark complementary color scheme. The typography combines display fonts for headings with serif for body text.</p>
+
+ <h2>Typography Showcase</h2>
+ <p>The roboto-slab font family provides excellent readability for body text, while zai-aeg-mignon-typewriter-1924 adds character to headings. Code blocks use hack for clarity.</p>
+
+ <h2>Color Palette</h2>
+ <p>Primary: <span style="color: #18ee0d; font-weight: bold;">#18ee0d</span> |
+ Secondary: <span style="color: #cf24d8; font-weight: bold;">#cf24d8</span> |
+ Accent: <span style="color: #349a2e; font-weight: bold;">#349a2e</span></p>
+
+ <h3>Interactive Elements</h3>
+ <p>Links like <a href="#">this example</a> and longer <a href="#" class="textlink">text links that demonstrate the theme's navigation style</a> use the secondary color.</p>
+
+ <div class="quote">
+ "Design is not just what it looks like and feels like. Design is how it works." — Steve Jobs
+ </div>
+
+ <h3>Code Examples</h3>
+ <p>Inline code like <code>theme.generate()</code> and larger blocks:</p>
+ <pre>// Theme configuration
+const theme = {
+ name: "mystic_canyon",
+ layout: "centered",
+ colors: {
+ primary: "#18ee0d",
+ secondary: "#cf24d8",
+ accent: "#349a2e"
+ },
+ fonts: {
+ heading: "zai-aeg-mignon-typewriter-1924",
+ body: "roboto-slab",
+ code: "hack"
+ }
+};</pre>
+
+ <h2>Content Structure</h2>
+ <ul>
+ <li>Clean, readable typography with 17px base font size</li>
+ <li>Heading scale ratio of 2.37x for visual hierarchy</li>
+ <li>Line height of 1.69 for comfortable reading</li>
+ <li>Centered layout optimized for content flow</li>
+ <li>Dark theme with complementary color harmony</li>
+ </ul>
+
+ <h2>Font Licensing</h2>
+ <p>All fonts used in this theme are properly licensed:</p>
+ <ul>
+ <li>zai-aeg-mignon-typewriter-1924: Free License</li>
+ <li>roboto-slab: Apache License</li>
+ <li>hack: MIT License</li>
+ </ul>
+
+ <h3>Final Thoughts</h3>
+ <p>Every element of this theme has been carefully designed to create a harmonious reading experience. The centered layout ensures content is presented in an engaging way, while the color scheme provides the perfect backdrop for your words to shine.</p>
+
+ <p>Whether you're writing technical documentation, creative prose, or anything in between, this theme adapts to showcase your content beautifully.</p>
+ </div>
+</body>
+</html> \ No newline at end of file
diff --git a/extras/html/themes/mystic_canyon/handnotes.ttf b/extras/html/themes/mystic_canyon/handnotes.ttf
new file mode 100644
index 0000000..25e688b
--- /dev/null
+++ b/extras/html/themes/mystic_canyon/handnotes.ttf
Binary files differ
diff --git a/extras/html/themes/mystic_canyon/heading.ttf b/extras/html/themes/mystic_canyon/heading.ttf
new file mode 100644
index 0000000..375978c
--- /dev/null
+++ b/extras/html/themes/mystic_canyon/heading.ttf
Binary files differ
diff --git a/extras/html/themes/mystic_canyon/style.css b/extras/html/themes/mystic_canyon/style.css
new file mode 100644
index 0000000..6634fdc
--- /dev/null
+++ b/extras/html/themes/mystic_canyon/style.css
@@ -0,0 +1,154 @@
+/* Base styles */
+@font-face {
+ font-family: 'text';
+ src: url("./text.ttf") format("truetype");
+}
+
+@font-face {
+ font-family: 'heading';
+ src: url("./heading.ttf") format("truetype");
+}
+
+@font-face {
+ font-family: 'code';
+ src: url("./code.ttf") format("truetype");
+}
+
+@font-face {
+ font-family: 'handnotes';
+ src: url("./handnotes.ttf") format("truetype");
+}
+
+:root {
+ --color-primary: #18ee0d;
+ --color-secondary: #cf24d8;
+ --color-accent: #349a2e;
+ --color-bg: #161a15;
+ --color-text: #dedede;
+ --font-size-base: 17px;
+ --font-size-h1: 2.37em;
+ --font-size-h2: 1.78em;
+ --font-size-h3: 1.33em;
+ --line-height: 1.69;
+}
+
+* {
+ box-sizing: border-box;
+}
+
+html {
+ font-size: var(--font-size-base);
+ -webkit-font-smoothing: antialiased;
+ -moz-osx-font-smoothing: grayscale;
+}
+
+body {
+ font-family: text, sans-serif;
+ background-color: var(--color-bg);
+ color: var(--color-text);
+ line-height: var(--line-height);
+ margin: 0;
+ padding: 0;
+ overflow-wrap: break-word;
+}
+
+h1, h2, h3 {
+ font-family: heading, serif;
+ line-height: 1.2;
+ margin-top: 1em;
+ margin-bottom: 0.5em;
+}
+
+h1 {
+ font-size: var(--font-size-h1);
+ color: var(--color-primary);
+}
+
+h2 {
+ font-size: var(--font-size-h2);
+ color: var(--color-primary);
+}
+
+h3 {
+ font-size: var(--font-size-h3);
+ color: var(--color-secondary);
+}
+
+a {
+ font-family: code, monospace;
+ color: var(--color-secondary);
+ text-decoration: none;
+ transition: all 0.3s ease;
+}
+
+a:hover {
+ color: var(--color-accent);
+ text-decoration: underline;
+}
+
+.textlink {
+ font-family: text, sans-serif;
+}
+
+.quote {
+ font-family: handnotes, cursive;
+ border-left: 4px solid var(--color-accent);
+ padding: 1em 1.5em;
+ margin: 1.5em 0;
+ background-color: rgba(24, 238, 13, 0.07);
+ font-style: italic;
+}
+
+pre {
+ font-family: code, monospace;
+ background-color: rgba(222, 222, 222, 0.04);
+ border: 1px solid rgba(222, 222, 222, 0.13);
+ padding: 1em;
+ overflow-x: auto;
+ border-radius: 4px;
+ font-size: 0.9em;
+}
+
+code {
+ font-family: code, monospace;
+ background-color: rgba(222, 222, 222, 0.04);
+ padding: 0.2em 0.4em;
+ border-radius: 3px;
+ font-size: 0.9em;
+}
+
+ul, ol {
+ padding-left: 2em;
+ margin: 1em 0;
+}
+
+li {
+ margin: 0.5em 0;
+}
+
+img {
+ max-width: 100%;
+ height: auto;
+}
+
+hr {
+ border: none;
+ border-top: 1px solid rgba(222, 222, 222, 0.20);
+ margin: 2em 0;
+}
+
+
+/* Layout: centered */
+
+body {
+ max-width: 65ch;
+ margin: 0 auto;
+ padding: 2em 1em;
+}
+
+.header {
+ text-align: center;
+ margin-bottom: 3em;
+ padding-bottom: 2em;
+ border-bottom: 2px solid var(--color-primary);
+}
diff --git a/extras/html/themes/mystic_canyon/theme.conf b/extras/html/themes/mystic_canyon/theme.conf
new file mode 100644
index 0000000..b620ed7
--- /dev/null
+++ b/extras/html/themes/mystic_canyon/theme.conf
@@ -0,0 +1,8 @@
+declare -xr HTML_HEADER=./extras/html/header.html.part
+declare -xr HTML_FOOTER=./extras/html/footer.html.part
+declare -xr HTML_CSS_STYLE=$HTML_THEME_DIR/style.css
+declare -xr HTML_WEBFONT_HEADING=./extras/html/fonts/zai-aeg-mignon-typewriter-1924/zai-aeg-mignon-typewriter-1924-Bold.ttf
+declare -xr HTML_WEBFONT_TEXT=./extras/html/fonts/roboto-slab/roboto-slab-Regular.ttf
+declare -xr HTML_WEBFONT_CODE=./extras/html/fonts/hack/hack-Regular.ttf
+declare -xr HTML_WEBFONT_HANDNOTES=./extras/html/fonts/khand/khand.ttf
+declare -xr SOURCE_HIGHLIGHT_CSS=./extras/html/source-highlight-styles/mono.css
diff --git a/extras/html/themes/mystic_meadow/LICENSE b/extras/html/themes/mystic_meadow/LICENSE
new file mode 100644
index 0000000..f95f0ae
--- /dev/null
+++ b/extras/html/themes/mystic_meadow/LICENSE
@@ -0,0 +1,21 @@
+Theme: mystic_meadow
+Generated: 2025-06-22 21:38:55
+
+Layout: hero
+Color Scheme: complementary (Dark)
+
+Font Licenses:
+==============
+Heading Font: roboto-slab
+License: Apache
+Category: serif
+
+Body Font: oxygen
+License: OFL
+Category: sans-serif
+
+Code Font: intelone-mono
+License: OFL
+Category: monospace
+
+All fonts are free for personal use.
diff --git a/extras/html/themes/mystic_meadow/code.ttf b/extras/html/themes/mystic_meadow/code.ttf
new file mode 100644
index 0000000..2711179
--- /dev/null
+++ b/extras/html/themes/mystic_meadow/code.ttf
Binary files differ
diff --git a/extras/html/themes/mystic_meadow/example.html b/extras/html/themes/mystic_meadow/example.html
new file mode 100644
index 0000000..c4488c1
--- /dev/null
+++ b/extras/html/themes/mystic_meadow/example.html
@@ -0,0 +1,75 @@
+<!DOCTYPE html>
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
+<head>
+ <meta charset="UTF-8" />
+ <meta name="viewport" content="width=device-width, initial-scale=1.0" />
+ <title>Mystic Meadow - Gemtexter Theme</title>
+ <link rel="stylesheet" href="style.css" />
+</head>
+<body>
+ <div class="header">
+ <h1>Mystic Meadow</h1>
+ <p>A hero layout with complementary colors</p>
+ </div>
+
+ <div class="content">
+ <h1>Welcome to Mystic Meadow</h1>
+ <p>This theme features a carefully crafted hero layout with a dark complementary color scheme. The typography combines serif fonts for headings with sans-serif for body text.</p>
+
+ <h2>Typography Showcase</h2>
+ <p>The oxygen font family provides excellent readability for body text, while roboto-slab adds character to headings. Code blocks use intelone-mono for clarity.</p>
+
+ <h2>Color Palette</h2>
+ <p>Primary: <span style="color: #6b3ddb; font-weight: bold;">#6b3ddb</span> |
+ Secondary: <span style="color: #a7cb4d; font-weight: bold;">#a7cb4d</span> |
+ Accent: <span style="color: #5c419f; font-weight: bold;">#5c419f</span></p>
+
+ <h3>Interactive Elements</h3>
+ <p>Links like <a href="#">this example</a> and longer <a href="#" class="textlink">text links that demonstrate the theme's navigation style</a> use the secondary color.</p>
+
+ <div class="quote">
+ "Design is not just what it looks like and feels like. Design is how it works." — Steve Jobs
+ </div>
+
+ <h3>Code Examples</h3>
+ <p>Inline code like <code>theme.generate()</code> and larger blocks:</p>
+ <pre>// Theme configuration
+const theme = {
+ name: "mystic_meadow",
+ layout: "hero",
+ colors: {
+ primary: "#6b3ddb",
+ secondary: "#a7cb4d",
+ accent: "#5c419f"
+ },
+ fonts: {
+ heading: "roboto-slab",
+ body: "oxygen",
+ code: "intelone-mono"
+ }
+};</pre>
+
+ <h2>Content Structure</h2>
+ <ul>
+ <li>Clean, readable typography with 18px base font size</li>
+ <li>Heading scale ratio of 2.83x for visual hierarchy</li>
+ <li>Line height of 1.64 for comfortable reading</li>
+ <li>Hero layout optimized for content flow</li>
+ <li>Dark theme with complementary color harmony</li>
+ </ul>
+
+ <h2>Font Licensing</h2>
+ <p>All fonts used in this theme are properly licensed:</p>
+ <ul>
+ <li>roboto-slab: Apache License</li>
+ <li>oxygen: OFL License</li>
+ <li>intelone-mono: OFL License</li>
+ </ul>
+
+ <h3>Final Thoughts</h3>
+ <p>Every element of this theme has been carefully designed to create a harmonious reading experience. The hero layout ensures content is presented in an engaging way, while the color scheme provides the perfect backdrop for your words to shine.</p>
+
+ <p>Whether you're writing technical documentation, creative prose, or anything in between, this theme adapts to showcase your content beautifully.</p>
+ </div>
+</body>
+</html> \ No newline at end of file
diff --git a/extras/html/themes/mystic_meadow/handnotes.ttf b/extras/html/themes/mystic_meadow/handnotes.ttf
new file mode 100644
index 0000000..25e688b
--- /dev/null
+++ b/extras/html/themes/mystic_meadow/handnotes.ttf
Binary files differ
diff --git a/extras/html/themes/mystic_meadow/style.css b/extras/html/themes/mystic_meadow/style.css
new file mode 100644
index 0000000..ad60798
--- /dev/null
+++ b/extras/html/themes/mystic_meadow/style.css
@@ -0,0 +1,176 @@
+/* Base styles */
+@font-face {
+ font-family: 'text';
+ src: url("./text.ttf") format("truetype");
+}
+
+@font-face {
+ font-family: 'heading';
+ src: url("./heading.ttf") format("truetype");
+}
+
+@font-face {
+ font-family: 'code';
+ src: url("./code.ttf") format("truetype");
+}
+
+@font-face {
+ font-family: 'handnotes';
+ src: url("./handnotes.ttf") format("truetype");
+}
+
+:root {
+ --color-primary: #6b3ddb;
+ --color-secondary: #a7cb4d;
+ --color-accent: #5c419f;
+ --color-bg: #141217;
+ --color-text: #dedede;
+ --font-size-base: 18px;
+ --font-size-h1: 2.83em;
+ --font-size-h2: 2.0em;
+ --font-size-h3: 1.41em;
+ --line-height: 1.64;
+}
+
+* {
+ box-sizing: border-box;
+}
+
+html {
+ font-size: var(--font-size-base);
+ -webkit-font-smoothing: antialiased;
+ -moz-osx-font-smoothing: grayscale;
+}
+
+body {
+ font-family: text, sans-serif;
+ background-color: var(--color-bg);
+ color: var(--color-text);
+ line-height: var(--line-height);
+ margin: 0;
+ padding: 0;
+ overflow-wrap: break-word;
+}
+
+h1, h2, h3 {
+ font-family: heading, serif;
+ line-height: 1.2;
+ margin-top: 1em;
+ margin-bottom: 0.5em;
+}
+
+h1 {
+ font-size: var(--font-size-h1);
+ color: var(--color-primary);
+}
+
+h2 {
+ font-size: var(--font-size-h2);
+ color: var(--color-primary);
+}
+
+h3 {
+ font-size: var(--font-size-h3);
+ color: var(--color-secondary);
+}
+
+a {
+ font-family: code, monospace;
+ color: var(--color-secondary);
+ text-decoration: none;
+ transition: all 0.3s ease;
+}
+
+a:hover {
+ color: var(--color-accent);
+ text-decoration: underline;
+}
+
+.textlink {
+ font-family: text, sans-serif;
+}
+
+.quote {
+ font-family: handnotes, cursive;
+ border-left: 4px solid var(--color-accent);
+ padding: 1em 1.5em;
+ margin: 1.5em 0;
+ background-color: rgba(107, 61, 219, 0.07);
+ font-style: italic;
+}
+
+pre {
+ font-family: code, monospace;
+ background-color: rgba(222, 222, 222, 0.04);
+ border: 1px solid rgba(222, 222, 222, 0.13);
+ padding: 1em;
+ overflow-x: auto;
+ border-radius: 4px;
+ font-size: 0.9em;
+}
+
+code {
+ font-family: code, monospace;
+ background-color: rgba(222, 222, 222, 0.04);
+ padding: 0.2em 0.4em;
+ border-radius: 3px;
+ font-size: 0.9em;
+}
+
+ul, ol {
+ padding-left: 2em;
+ margin: 1em 0;
+}
+
+li {
+ margin: 0.5em 0;
+}
+
+img {
+ max-width: 100%;
+ height: auto;
+}
+
+hr {
+ border: none;
+ border-top: 1px solid rgba(222, 222, 222, 0.20);
+ margin: 2em 0;
+}
+
+
+/* Layout: hero */
+
+body {
+ margin: 0;
+ padding: 0;
+}
+
+.header {
+ min-height: 80vh;
+ display: flex;
+ flex-direction: column;
+ justify-content: center;
+ align-items: center;
+ background: linear-gradient(135deg, rgba(107, 61, 219, 0.80), rgba(167, 203, 77, 0.80)), linear-gradient(45deg, rgba(92, 65, 159, 0.13), transparent);
+ color: var(--color-bg);
+ text-align: center;
+ position: relative;
+}
+
+.header h1 {
+ font-size: 5em;
+ margin: 0;
+ color: var(--color-bg);
+ text-shadow: 0 4px 8px rgba(0,0,0,0.3);
+}
+
+.header p {
+ font-size: 1.5em;
+ opacity: 0.9;
+}
+
+.content {
+ max-width: 65ch;
+ margin: 4em auto;
+ padding: 0 2em;
+}
diff --git a/extras/html/themes/mystic_meadow/theme.conf b/extras/html/themes/mystic_meadow/theme.conf
new file mode 100644
index 0000000..19a2553
--- /dev/null
+++ b/extras/html/themes/mystic_meadow/theme.conf
@@ -0,0 +1,8 @@
+declare -xr HTML_HEADER=./extras/html/header.html.part
+declare -xr HTML_FOOTER=./extras/html/footer.html.part
+declare -xr HTML_CSS_STYLE=$HTML_THEME_DIR/style.css
+declare -xr HTML_WEBFONT_HEADING=./extras/html/fonts/roboto-slab/roboto-slab-Bold.ttf
+declare -xr HTML_WEBFONT_TEXT=./extras/html/fonts/oxygen/oxygen-Regular.ttf
+declare -xr HTML_WEBFONT_CODE=./extras/html/fonts/intelone-mono/intelone-mono-Regular.ttf
+declare -xr HTML_WEBFONT_HANDNOTES=./extras/html/fonts/khand/khand.ttf
+declare -xr SOURCE_HIGHLIGHT_CSS=./extras/html/source-highlight-styles/mono.css
diff --git a/extras/html/themes/neon_storm/LICENSE b/extras/html/themes/neon_storm/LICENSE
new file mode 100644
index 0000000..315bcbc
--- /dev/null
+++ b/extras/html/themes/neon_storm/LICENSE
@@ -0,0 +1,21 @@
+Theme: neon_storm
+Generated: 2025-06-22 21:38:55
+
+Layout: retro
+Color Scheme: monochromatic (Light)
+
+Font Licenses:
+==============
+Heading Font: Abril_Fatface
+License: OFL
+Category: display
+
+Body Font: Merriweather
+License: OFL
+Category: serif
+
+Code Font: hack
+License: MIT
+Category: monospace
+
+All fonts are free for personal use.
diff --git a/extras/html/themes/neon_storm/code.ttf b/extras/html/themes/neon_storm/code.ttf
new file mode 100644
index 0000000..7c8e65b
--- /dev/null
+++ b/extras/html/themes/neon_storm/code.ttf
Binary files differ
diff --git a/extras/html/themes/neon_storm/example.html b/extras/html/themes/neon_storm/example.html
new file mode 100644
index 0000000..1f3e263
--- /dev/null
+++ b/extras/html/themes/neon_storm/example.html
@@ -0,0 +1,75 @@
+<!DOCTYPE html>
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
+<head>
+ <meta charset="UTF-8" />
+ <meta name="viewport" content="width=device-width, initial-scale=1.0" />
+ <title>Neon Storm - Gemtexter Theme</title>
+ <link rel="stylesheet" href="style.css" />
+</head>
+<body>
+ <div class="header">
+ <h1>Neon Storm</h1>
+ <p>A retro layout with monochromatic colors</p>
+ </div>
+
+ <div class="content">
+ <h1>Welcome to Neon Storm</h1>
+ <p>This theme features a carefully crafted retro layout with a light monochromatic color scheme. The typography combines display fonts for headings with serif for body text.</p>
+
+ <h2>Typography Showcase</h2>
+ <p>The Merriweather font family provides excellent readability for body text, while Abril Fatface adds character to headings. Code blocks use hack for clarity.</p>
+
+ <h2>Color Palette</h2>
+ <p>Primary: <span style="color: #1ca93a; font-weight: bold;">#1ca93a</span> |
+ Secondary: <span style="color: #1d6c2e; font-weight: bold;">#1d6c2e</span> |
+ Accent: <span style="color: #44a959; font-weight: bold;">#44a959</span></p>
+
+ <h3>Interactive Elements</h3>
+ <p>Links like <a href="#">this example</a> and longer <a href="#" class="textlink">text links that demonstrate the theme's navigation style</a> use the secondary color.</p>
+
+ <div class="quote">
+ "Design is not just what it looks like and feels like. Design is how it works." — Steve Jobs
+ </div>
+
+ <h3>Code Examples</h3>
+ <p>Inline code like <code>theme.generate()</code> and larger blocks:</p>
+ <pre>// Theme configuration
+const theme = {
+ name: "neon_storm",
+ layout: "retro",
+ colors: {
+ primary: "#1ca93a",
+ secondary: "#1d6c2e",
+ accent: "#44a959"
+ },
+ fonts: {
+ heading: "Abril_Fatface",
+ body: "Merriweather",
+ code: "hack"
+ }
+};</pre>
+
+ <h2>Content Structure</h2>
+ <ul>
+ <li>Clean, readable typography with 16px base font size</li>
+ <li>Heading scale ratio of 1.95x for visual hierarchy</li>
+ <li>Line height of 1.64 for comfortable reading</li>
+ <li>Retro layout optimized for content flow</li>
+ <li>Light theme with monochromatic color harmony</li>
+ </ul>
+
+ <h2>Font Licensing</h2>
+ <p>All fonts used in this theme are properly licensed:</p>
+ <ul>
+ <li>Abril_Fatface: OFL License</li>
+ <li>Merriweather: OFL License</li>
+ <li>hack: MIT License</li>
+ </ul>
+
+ <h3>Final Thoughts</h3>
+ <p>Every element of this theme has been carefully designed to create a harmonious reading experience. The retro layout ensures content is presented in an engaging way, while the color scheme provides the perfect backdrop for your words to shine.</p>
+
+ <p>Whether you're writing technical documentation, creative prose, or anything in between, this theme adapts to showcase your content beautifully.</p>
+ </div>
+</body>
+</html> \ No newline at end of file
diff --git a/extras/html/themes/neon_storm/handnotes.ttf b/extras/html/themes/neon_storm/handnotes.ttf
new file mode 100644
index 0000000..25e688b
--- /dev/null
+++ b/extras/html/themes/neon_storm/handnotes.ttf
Binary files differ
diff --git a/extras/html/themes/neon_storm/heading.ttf b/extras/html/themes/neon_storm/heading.ttf
new file mode 100644
index 0000000..a291711
--- /dev/null
+++ b/extras/html/themes/neon_storm/heading.ttf
Binary files differ
diff --git a/extras/html/themes/neon_storm/style.css b/extras/html/themes/neon_storm/style.css
new file mode 100644
index 0000000..20d92a4
--- /dev/null
+++ b/extras/html/themes/neon_storm/style.css
@@ -0,0 +1,205 @@
+/* Base styles */
+@font-face {
+ font-family: 'text';
+ src: url("./text.ttf") format("truetype");
+}
+
+@font-face {
+ font-family: 'heading';
+ src: url("./heading.ttf") format("truetype");
+}
+
+@font-face {
+ font-family: 'code';
+ src: url("./code.ttf") format("truetype");
+}
+
+@font-face {
+ font-family: 'handnotes';
+ src: url("./handnotes.ttf") format("truetype");
+}
+
+:root {
+ --color-primary: #1ca93a;
+ --color-secondary: #1d6c2e;
+ --color-accent: #44a959;
+ --color-bg: #edf0ee;
+ --color-text: #171717;
+ --font-size-base: 16px;
+ --font-size-h1: 1.95em;
+ --font-size-h2: 1.56em;
+ --font-size-h3: 1.25em;
+ --line-height: 1.64;
+}
+
+* {
+ box-sizing: border-box;
+}
+
+html {
+ font-size: var(--font-size-base);
+ -webkit-font-smoothing: antialiased;
+ -moz-osx-font-smoothing: grayscale;
+}
+
+body {
+ font-family: text, sans-serif;
+ background-color: var(--color-bg);
+ color: var(--color-text);
+ line-height: var(--line-height);
+ margin: 0;
+ padding: 0;
+ overflow-wrap: break-word;
+}
+
+h1, h2, h3 {
+ font-family: heading, serif;
+ line-height: 1.2;
+ margin-top: 1em;
+ margin-bottom: 0.5em;
+}
+
+h1 {
+ font-size: var(--font-size-h1);
+ color: var(--color-primary);
+}
+
+h2 {
+ font-size: var(--font-size-h2);
+ color: var(--color-primary);
+}
+
+h3 {
+ font-size: var(--font-size-h3);
+ color: var(--color-secondary);
+}
+
+a {
+ font-family: code, monospace;
+ color: var(--color-secondary);
+ text-decoration: none;
+ transition: all 0.3s ease;
+}
+
+a:hover {
+ color: var(--color-accent);
+ text-decoration: underline;
+}
+
+.textlink {
+ font-family: text, sans-serif;
+}
+
+.quote {
+ font-family: handnotes, cursive;
+ border-left: 4px solid var(--color-accent);
+ padding: 1em 1.5em;
+ margin: 1.5em 0;
+ background-color: rgba(28, 169, 58, 0.07);
+ font-style: italic;
+}
+
+pre {
+ font-family: code, monospace;
+ background-color: rgba(23, 23, 23, 0.04);
+ border: 1px solid rgba(23, 23, 23, 0.13);
+ padding: 1em;
+ overflow-x: auto;
+ border-radius: 4px;
+ font-size: 0.9em;
+}
+
+code {
+ font-family: code, monospace;
+ background-color: rgba(23, 23, 23, 0.04);
+ padding: 0.2em 0.4em;
+ border-radius: 3px;
+ font-size: 0.9em;
+}
+
+ul, ol {
+ padding-left: 2em;
+ margin: 1em 0;
+}
+
+li {
+ margin: 0.5em 0;
+}
+
+img {
+ max-width: 100%;
+ height: auto;
+}
+
+hr {
+ border: none;
+ border-top: 1px solid rgba(23, 23, 23, 0.20);
+ margin: 2em 0;
+}
+
+
+/* Layout: retro */
+
+@import url("https://fonts.googleapis.com/css2?family=Courier+Prime:wght@400;700&display=swap");
+
+body {
+ background-color: #f4e8d0;
+ color: #2a2a2a;
+ padding: 2em;
+ position: relative;
+}
+
+body::before {
+ content: "";
+ position: fixed;
+ top: 0;
+ left: 0;
+ right: 0;
+ bottom: 0;
+ background-image: repeating-linear-gradient( 0deg, transparent, transparent 2px, rgba(0,0,0,0.03) 2px, rgba(0,0,0,0.03) 4px );
+ pointer-events: none;
+ z-index: 1;
+}
+
+.header {
+ background-color: #1ca93a;
+ color: #f4e8d0;
+ padding: 2em;
+ margin: -2em -2em 2em -2em;
+ text-align: center;
+ box-shadow: 0 4px 8px rgba(0,0,0,0.3);
+ position: relative;
+ z-index: 2;
+}
+
+.header h1 {
+ font-family: 'Courier Prime', monospace;
+ font-size: 3em;
+ margin: 0;
+ text-transform: uppercase;
+ letter-spacing: 0.1em;
+ color: #f4e8d0;
+}
+
+h1, h2, h3 {
+ font-family: 'Courier Prime', monospace;
+ text-transform: uppercase;
+ letter-spacing: 0.05em;
+ position: relative;
+ z-index: 2;
+}
+
+p, ul, pre, .quote {
+ background-color: rgba(255,255,255,0.8);
+ padding: 1.5em;
+ margin: 1em 0;
+ box-shadow: 2px 2px 4px rgba(0,0,0,0.1);
+ position: relative;
+ z-index: 2;
+}
+
+a {
+ color: #1d6c2e;
+ text-decoration: underline;
+ text-decoration-style: wavy;
+}
diff --git a/extras/html/themes/neon_storm/text.ttf b/extras/html/themes/neon_storm/text.ttf
new file mode 100644
index 0000000..3fecc77
--- /dev/null
+++ b/extras/html/themes/neon_storm/text.ttf
Binary files differ
diff --git a/extras/html/themes/neon_storm/theme.conf b/extras/html/themes/neon_storm/theme.conf
new file mode 100644
index 0000000..7673f51
--- /dev/null
+++ b/extras/html/themes/neon_storm/theme.conf
@@ -0,0 +1,8 @@
+declare -xr HTML_HEADER=./extras/html/header.html.part
+declare -xr HTML_FOOTER=./extras/html/footer.html.part
+declare -xr HTML_CSS_STYLE=$HTML_THEME_DIR/style.css
+declare -xr HTML_WEBFONT_HEADING=./extras/html/fonts/Abril_Fatface/Abril_Fatface-Bold.ttf
+declare -xr HTML_WEBFONT_TEXT=./extras/html/fonts/Merriweather/Merriweather-Regular.ttf
+declare -xr HTML_WEBFONT_CODE=./extras/html/fonts/hack/hack-Regular.ttf
+declare -xr HTML_WEBFONT_HANDNOTES=./extras/html/fonts/khand/khand.ttf
+declare -xr SOURCE_HIGHLIGHT_CSS=./extras/html/source-highlight-styles/mono.css
diff --git a/extras/html/themes/pastel_canyon/LICENSE b/extras/html/themes/pastel_canyon/LICENSE
new file mode 100644
index 0000000..f5b7c7d
--- /dev/null
+++ b/extras/html/themes/pastel_canyon/LICENSE
@@ -0,0 +1,21 @@
+Theme: pastel_canyon
+Generated: 2025-06-22 21:38:55
+
+Layout: sidebar
+Color Scheme: analogous (Dark)
+
+Font Licenses:
+==============
+Heading Font: Merriweather
+License: OFL
+Category: serif
+
+Body Font: roboto-slab
+License: Apache
+Category: serif
+
+Code Font: hack
+License: MIT
+Category: monospace
+
+All fonts are free for personal use.
diff --git a/extras/html/themes/pastel_canyon/code.ttf b/extras/html/themes/pastel_canyon/code.ttf
new file mode 100644
index 0000000..7c8e65b
--- /dev/null
+++ b/extras/html/themes/pastel_canyon/code.ttf
Binary files differ
diff --git a/extras/html/themes/pastel_canyon/example.html b/extras/html/themes/pastel_canyon/example.html
new file mode 100644
index 0000000..72fcac2
--- /dev/null
+++ b/extras/html/themes/pastel_canyon/example.html
@@ -0,0 +1,75 @@
+<!DOCTYPE html>
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
+<head>
+ <meta charset="UTF-8" />
+ <meta name="viewport" content="width=device-width, initial-scale=1.0" />
+ <title>Pastel Canyon - Gemtexter Theme</title>
+ <link rel="stylesheet" href="style.css" />
+</head>
+<body>
+ <div class="header">
+ <h1>Pastel Canyon</h1>
+ <p>A sidebar layout with analogous colors</p>
+ </div>
+
+ <div class="content">
+ <h1>Welcome to Pastel Canyon</h1>
+ <p>This theme features a carefully crafted sidebar layout with a dark analogous color scheme. The typography combines serif fonts for headings with serif for body text.</p>
+
+ <h2>Typography Showcase</h2>
+ <p>The roboto-slab font family provides excellent readability for body text, while Merriweather adds character to headings. Code blocks use hack for clarity.</p>
+
+ <h2>Color Palette</h2>
+ <p>Primary: <span style="color: #db7b55; font-weight: bold;">#db7b55</span> |
+ Secondary: <span style="color: #d5b85b; font-weight: bold;">#d5b85b</span> |
+ Accent: <span style="color: #d63b59; font-weight: bold;">#d63b59</span></p>
+
+ <h3>Interactive Elements</h3>
+ <p>Links like <a href="#">this example</a> and longer <a href="#" class="textlink">text links that demonstrate the theme's navigation style</a> use the secondary color.</p>
+
+ <div class="quote">
+ "Design is not just what it looks like and feels like. Design is how it works." — Steve Jobs
+ </div>
+
+ <h3>Code Examples</h3>
+ <p>Inline code like <code>theme.generate()</code> and larger blocks:</p>
+ <pre>// Theme configuration
+const theme = {
+ name: "pastel_canyon",
+ layout: "sidebar",
+ colors: {
+ primary: "#db7b55",
+ secondary: "#d5b85b",
+ accent: "#d63b59"
+ },
+ fonts: {
+ heading: "Merriweather",
+ body: "roboto-slab",
+ code: "hack"
+ }
+};</pre>
+
+ <h2>Content Structure</h2>
+ <ul>
+ <li>Clean, readable typography with 15px base font size</li>
+ <li>Heading scale ratio of 1.73x for visual hierarchy</li>
+ <li>Line height of 1.61 for comfortable reading</li>
+ <li>Sidebar layout optimized for content flow</li>
+ <li>Dark theme with analogous color harmony</li>
+ </ul>
+
+ <h2>Font Licensing</h2>
+ <p>All fonts used in this theme are properly licensed:</p>
+ <ul>
+ <li>Merriweather: OFL License</li>
+ <li>roboto-slab: Apache License</li>
+ <li>hack: MIT License</li>
+ </ul>
+
+ <h3>Final Thoughts</h3>
+ <p>Every element of this theme has been carefully designed to create a harmonious reading experience. The sidebar layout ensures content is presented in an engaging way, while the color scheme provides the perfect backdrop for your words to shine.</p>
+
+ <p>Whether you're writing technical documentation, creative prose, or anything in between, this theme adapts to showcase your content beautifully.</p>
+ </div>
+</body>
+</html> \ No newline at end of file
diff --git a/extras/html/themes/pastel_canyon/handnotes.ttf b/extras/html/themes/pastel_canyon/handnotes.ttf
new file mode 100644
index 0000000..25e688b
--- /dev/null
+++ b/extras/html/themes/pastel_canyon/handnotes.ttf
Binary files differ
diff --git a/extras/html/themes/pastel_canyon/heading.ttf b/extras/html/themes/pastel_canyon/heading.ttf
new file mode 100644
index 0000000..3e10e02
--- /dev/null
+++ b/extras/html/themes/pastel_canyon/heading.ttf
Binary files differ
diff --git a/extras/html/themes/pastel_canyon/style.css b/extras/html/themes/pastel_canyon/style.css
new file mode 100644
index 0000000..5048b31
--- /dev/null
+++ b/extras/html/themes/pastel_canyon/style.css
@@ -0,0 +1,173 @@
+/* Base styles */
+@font-face {
+ font-family: 'text';
+ src: url("./text.ttf") format("truetype");
+}
+
+@font-face {
+ font-family: 'heading';
+ src: url("./heading.ttf") format("truetype");
+}
+
+@font-face {
+ font-family: 'code';
+ src: url("./code.ttf") format("truetype");
+}
+
+@font-face {
+ font-family: 'handnotes';
+ src: url("./handnotes.ttf") format("truetype");
+}
+
+:root {
+ --color-primary: #db7b55;
+ --color-secondary: #d5b85b;
+ --color-accent: #d63b59;
+ --color-bg: #0f0d0c;
+ --color-text: #eeeeee;
+ --font-size-base: 15px;
+ --font-size-h1: 1.73em;
+ --font-size-h2: 1.44em;
+ --font-size-h3: 1.2em;
+ --line-height: 1.61;
+}
+
+* {
+ box-sizing: border-box;
+}
+
+html {
+ font-size: var(--font-size-base);
+ -webkit-font-smoothing: antialiased;
+ -moz-osx-font-smoothing: grayscale;
+}
+
+body {
+ font-family: text, sans-serif;
+ background-color: var(--color-bg);
+ color: var(--color-text);
+ line-height: var(--line-height);
+ margin: 0;
+ padding: 0;
+ overflow-wrap: break-word;
+}
+
+h1, h2, h3 {
+ font-family: heading, serif;
+ line-height: 1.2;
+ margin-top: 1em;
+ margin-bottom: 0.5em;
+}
+
+h1 {
+ font-size: var(--font-size-h1);
+ color: var(--color-primary);
+}
+
+h2 {
+ font-size: var(--font-size-h2);
+ color: var(--color-primary);
+}
+
+h3 {
+ font-size: var(--font-size-h3);
+ color: var(--color-secondary);
+}
+
+a {
+ font-family: code, monospace;
+ color: var(--color-secondary);
+ text-decoration: none;
+ transition: all 0.3s ease;
+}
+
+a:hover {
+ color: var(--color-accent);
+ text-decoration: underline;
+}
+
+.textlink {
+ font-family: text, sans-serif;
+}
+
+.quote {
+ font-family: handnotes, cursive;
+ border-left: 4px solid var(--color-accent);
+ padding: 1em 1.5em;
+ margin: 1.5em 0;
+ background-color: rgba(219, 123, 85, 0.07);
+ font-style: italic;
+}
+
+pre {
+ font-family: code, monospace;
+ background-color: rgba(238, 238, 238, 0.04);
+ border: 1px solid rgba(238, 238, 238, 0.13);
+ padding: 1em;
+ overflow-x: auto;
+ border-radius: 4px;
+ font-size: 0.9em;
+}
+
+code {
+ font-family: code, monospace;
+ background-color: rgba(238, 238, 238, 0.04);
+ padding: 0.2em 0.4em;
+ border-radius: 3px;
+ font-size: 0.9em;
+}
+
+ul, ol {
+ padding-left: 2em;
+ margin: 1em 0;
+}
+
+li {
+ margin: 0.5em 0;
+}
+
+img {
+ max-width: 100%;
+ height: auto;
+}
+
+hr {
+ border: none;
+ border-top: 1px solid rgba(238, 238, 238, 0.20);
+ margin: 2em 0;
+}
+
+
+/* Layout: sidebar */
+
+body {
+ display: grid;
+ grid-template-columns: 300px 1fr;
+ min-height: 100vh;
+ margin: 0;
+}
+
+.header {
+ grid-column: 1;
+ position: sticky;
+ top: 0;
+ height: 100vh;
+ padding: 3em 2em;
+ background-color: var(--color-primary);
+ color: var(--color-bg);
+ overflow-y: auto;
+}
+
+.header h1 {
+ color: var(--color-bg);
+}
+
+.content {
+ grid-column: 2;
+ padding: 3em;
+ max-width: 65ch;
+}
+
+h1, h2, h3, p, ul, pre, .quote {
+ grid-column: 2;
+}
diff --git a/extras/html/themes/pastel_canyon/theme.conf b/extras/html/themes/pastel_canyon/theme.conf
new file mode 100644
index 0000000..d3d85d8
--- /dev/null
+++ b/extras/html/themes/pastel_canyon/theme.conf
@@ -0,0 +1,8 @@
+declare -xr HTML_HEADER=./extras/html/header.html.part
+declare -xr HTML_FOOTER=./extras/html/footer.html.part
+declare -xr HTML_CSS_STYLE=$HTML_THEME_DIR/style.css
+declare -xr HTML_WEBFONT_HEADING=./extras/html/fonts/Merriweather/Merriweather-Bold.ttf
+declare -xr HTML_WEBFONT_TEXT=./extras/html/fonts/roboto-slab/roboto-slab-Regular.ttf
+declare -xr HTML_WEBFONT_CODE=./extras/html/fonts/hack/hack-Regular.ttf
+declare -xr HTML_WEBFONT_HANDNOTES=./extras/html/fonts/khand/khand.ttf
+declare -xr SOURCE_HIGHLIGHT_CSS=./extras/html/source-highlight-styles/mono.css
diff --git a/extras/html/themes/pastel_crystal/LICENSE b/extras/html/themes/pastel_crystal/LICENSE
new file mode 100644
index 0000000..09e286c
--- /dev/null
+++ b/extras/html/themes/pastel_crystal/LICENSE
@@ -0,0 +1,21 @@
+Theme: pastel_crystal
+Generated: 2025-06-22 21:38:55
+
+Layout: book
+Color Scheme: analogous (Light)
+
+Font Licenses:
+==============
+Heading Font: khand
+License: Free
+Category: handwriting
+
+Body Font: Lato
+License: OFL
+Category: sans-serif
+
+Code Font: consola-mono
+License: OFL
+Category: monospace
+
+All fonts are free for personal use.
diff --git a/extras/html/themes/pastel_crystal/code.ttf b/extras/html/themes/pastel_crystal/code.ttf
new file mode 100644
index 0000000..78ca9da
--- /dev/null
+++ b/extras/html/themes/pastel_crystal/code.ttf
Binary files differ
diff --git a/extras/html/themes/pastel_crystal/example.html b/extras/html/themes/pastel_crystal/example.html
new file mode 100644
index 0000000..d543666
--- /dev/null
+++ b/extras/html/themes/pastel_crystal/example.html
@@ -0,0 +1,75 @@
+<!DOCTYPE html>
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
+<head>
+ <meta charset="UTF-8" />
+ <meta name="viewport" content="width=device-width, initial-scale=1.0" />
+ <title>Pastel Crystal - Gemtexter Theme</title>
+ <link rel="stylesheet" href="style.css" />
+</head>
+<body>
+ <div class="header">
+ <h1>Pastel Crystal</h1>
+ <p>A book layout with analogous colors</p>
+ </div>
+
+ <div class="content">
+ <h1>Welcome to Pastel Crystal</h1>
+ <p>This theme features a carefully crafted book layout with a light analogous color scheme. The typography combines handwriting fonts for headings with sans-serif for body text.</p>
+
+ <h2>Typography Showcase</h2>
+ <p>The Lato font family provides excellent readability for body text, while khand adds character to headings. Code blocks use consola-mono for clarity.</p>
+
+ <h2>Color Palette</h2>
+ <p>Primary: <span style="color: #5689f3; font-weight: bold;">#5689f3</span> |
+ Secondary: <span style="color: #745eeb; font-weight: bold;">#745eeb</span> |
+ Accent: <span style="color: #37cdf1; font-weight: bold;">#37cdf1</span></p>
+
+ <h3>Interactive Elements</h3>
+ <p>Links like <a href="#">this example</a> and longer <a href="#" class="textlink">text links that demonstrate the theme's navigation style</a> use the secondary color.</p>
+
+ <div class="quote">
+ "Design is not just what it looks like and feels like. Design is how it works." — Steve Jobs
+ </div>
+
+ <h3>Code Examples</h3>
+ <p>Inline code like <code>theme.generate()</code> and larger blocks:</p>
+ <pre>// Theme configuration
+const theme = {
+ name: "pastel_crystal",
+ layout: "book",
+ colors: {
+ primary: "#5689f3",
+ secondary: "#745eeb",
+ accent: "#37cdf1"
+ },
+ fonts: {
+ heading: "khand",
+ body: "Lato",
+ code: "consola-mono"
+ }
+};</pre>
+
+ <h2>Content Structure</h2>
+ <ul>
+ <li>Clean, readable typography with 18px base font size</li>
+ <li>Heading scale ratio of 1.42x for visual hierarchy</li>
+ <li>Line height of 1.67 for comfortable reading</li>
+ <li>Book layout optimized for content flow</li>
+ <li>Light theme with analogous color harmony</li>
+ </ul>
+
+ <h2>Font Licensing</h2>
+ <p>All fonts used in this theme are properly licensed:</p>
+ <ul>
+ <li>khand: Free License</li>
+ <li>Lato: OFL License</li>
+ <li>consola-mono: OFL License</li>
+ </ul>
+
+ <h3>Final Thoughts</h3>
+ <p>Every element of this theme has been carefully designed to create a harmonious reading experience. The book layout ensures content is presented in an engaging way, while the color scheme provides the perfect backdrop for your words to shine.</p>
+
+ <p>Whether you're writing technical documentation, creative prose, or anything in between, this theme adapts to showcase your content beautifully.</p>
+ </div>
+</body>
+</html> \ No newline at end of file
diff --git a/extras/html/themes/pastel_crystal/handnotes.ttf b/extras/html/themes/pastel_crystal/handnotes.ttf
new file mode 100644
index 0000000..25e688b
--- /dev/null
+++ b/extras/html/themes/pastel_crystal/handnotes.ttf
Binary files differ
diff --git a/extras/html/themes/pastel_crystal/heading.ttf b/extras/html/themes/pastel_crystal/heading.ttf
new file mode 100644
index 0000000..25e688b
--- /dev/null
+++ b/extras/html/themes/pastel_crystal/heading.ttf
Binary files differ
diff --git a/extras/html/themes/pastel_crystal/style.css b/extras/html/themes/pastel_crystal/style.css
new file mode 100644
index 0000000..64c00d6
--- /dev/null
+++ b/extras/html/themes/pastel_crystal/style.css
@@ -0,0 +1,196 @@
+/* Base styles */
+@font-face {
+ font-family: 'text';
+ src: url("./text.ttf") format("truetype");
+}
+
+@font-face {
+ font-family: 'heading';
+ src: url("./heading.ttf") format("truetype");
+}
+
+@font-face {
+ font-family: 'code';
+ src: url("./code.ttf") format("truetype");
+}
+
+@font-face {
+ font-family: 'handnotes';
+ src: url("./handnotes.ttf") format("truetype");
+}
+
+:root {
+ --color-primary: #5689f3;
+ --color-secondary: #745eeb;
+ --color-accent: #37cdf1;
+ --color-bg: #e8eaec;
+ --color-text: #1a1a1a;
+ --font-size-base: 18px;
+ --font-size-h1: 1.42em;
+ --font-size-h2: 1.27em;
+ --font-size-h3: 1.12em;
+ --line-height: 1.67;
+}
+
+* {
+ box-sizing: border-box;
+}
+
+html {
+ font-size: var(--font-size-base);
+ -webkit-font-smoothing: antialiased;
+ -moz-osx-font-smoothing: grayscale;
+}
+
+body {
+ font-family: text, sans-serif;
+ background-color: var(--color-bg);
+ color: var(--color-text);
+ line-height: var(--line-height);
+ margin: 0;
+ padding: 0;
+ overflow-wrap: break-word;
+}
+
+h1, h2, h3 {
+ font-family: heading, serif;
+ line-height: 1.2;
+ margin-top: 1em;
+ margin-bottom: 0.5em;
+}
+
+h1 {
+ font-size: var(--font-size-h1);
+ color: var(--color-primary);
+}
+
+h2 {
+ font-size: var(--font-size-h2);
+ color: var(--color-primary);
+}
+
+h3 {
+ font-size: var(--font-size-h3);
+ color: var(--color-secondary);
+}
+
+a {
+ font-family: code, monospace;
+ color: var(--color-secondary);
+ text-decoration: none;
+ transition: all 0.3s ease;
+}
+
+a:hover {
+ color: var(--color-accent);
+ text-decoration: underline;
+}
+
+.textlink {
+ font-family: text, sans-serif;
+}
+
+.quote {
+ font-family: handnotes, cursive;
+ border-left: 4px solid var(--color-accent);
+ padding: 1em 1.5em;
+ margin: 1.5em 0;
+ background-color: rgba(86, 137, 243, 0.07);
+ font-style: italic;
+}
+
+pre {
+ font-family: code, monospace;
+ background-color: rgba(26, 26, 26, 0.04);
+ border: 1px solid rgba(26, 26, 26, 0.13);
+ padding: 1em;
+ overflow-x: auto;
+ border-radius: 4px;
+ font-size: 0.9em;
+}
+
+code {
+ font-family: code, monospace;
+ background-color: rgba(26, 26, 26, 0.04);
+ padding: 0.2em 0.4em;
+ border-radius: 3px;
+ font-size: 0.9em;
+}
+
+ul, ol {
+ padding-left: 2em;
+ margin: 1em 0;
+}
+
+li {
+ margin: 0.5em 0;
+}
+
+img {
+ max-width: 100%;
+ height: auto;
+}
+
+hr {
+ border: none;
+ border-top: 1px solid rgba(26, 26, 26, 0.20);
+ margin: 2em 0;
+}
+
+
+/* Layout: book */
+
+body {
+ max-width: 40em;
+ margin: 4em auto;
+ padding: 2em;
+ line-height: 1.8;
+ text-align: justify;
+ hyphens: auto;
+}
+
+.header {
+ text-align: center;
+ margin-bottom: 6em;
+ page-break-after: always;
+}
+
+.header h1 {
+ font-size: 3em;
+ margin-bottom: 0.5em;
+}
+
+h1 {
+ text-align: center;
+ margin: 3em 0 2em 0;
+ page-break-before: always;
+}
+
+h2 {
+ margin-top: 2em;
+ text-align: left;
+}
+
+p {
+ text-indent: 1.5em;
+ margin: 0;
+}
+
+p:first-of-type {
+ text-indent: 0;
+}
+
+p:first-of-type::first-letter {
+ font-size: 4em;
+ line-height: 1;
+ float: left;
+ margin: 0 0.1em 0 0;
+ font-family: heading, serif;
+ color: var(--color-primary);
+}
+
+.quote {
+ margin: 2em 2em;
+ text-align: center;
+ font-style: italic;
+}
diff --git a/extras/html/themes/pastel_crystal/text.ttf b/extras/html/themes/pastel_crystal/text.ttf
new file mode 100644
index 0000000..bb2e887
--- /dev/null
+++ b/extras/html/themes/pastel_crystal/text.ttf
Binary files differ
diff --git a/extras/html/themes/pastel_crystal/theme.conf b/extras/html/themes/pastel_crystal/theme.conf
new file mode 100644
index 0000000..2857ef2
--- /dev/null
+++ b/extras/html/themes/pastel_crystal/theme.conf
@@ -0,0 +1,8 @@
+declare -xr HTML_HEADER=./extras/html/header.html.part
+declare -xr HTML_FOOTER=./extras/html/footer.html.part
+declare -xr HTML_CSS_STYLE=$HTML_THEME_DIR/style.css
+declare -xr HTML_WEBFONT_HEADING=./extras/html/fonts/khand/khand-Bold.ttf
+declare -xr HTML_WEBFONT_TEXT=./extras/html/fonts/Lato/Lato-Regular.ttf
+declare -xr HTML_WEBFONT_CODE=./extras/html/fonts/consola-mono/consola-mono-Regular.ttf
+declare -xr HTML_WEBFONT_HANDNOTES=./extras/html/fonts/khand/khand.ttf
+declare -xr SOURCE_HIGHLIGHT_CSS=./extras/html/source-highlight-styles/mono.css
diff --git a/extras/html/themes/pure_storm/LICENSE b/extras/html/themes/pure_storm/LICENSE
new file mode 100644
index 0000000..b42d6e3
--- /dev/null
+++ b/extras/html/themes/pure_storm/LICENSE
@@ -0,0 +1,21 @@
+Theme: pure_storm
+Generated: 2025-06-22 21:38:55
+
+Layout: wide
+Color Scheme: analogous (Dark)
+
+Font Licenses:
+==============
+Heading Font: higher-jump
+License: Free
+Category: display
+
+Body Font: Lato
+License: OFL
+Category: sans-serif
+
+Code Font: consola-mono
+License: OFL
+Category: monospace
+
+All fonts are free for personal use.
diff --git a/extras/html/themes/pure_storm/code.ttf b/extras/html/themes/pure_storm/code.ttf
new file mode 100644
index 0000000..78ca9da
--- /dev/null
+++ b/extras/html/themes/pure_storm/code.ttf
Binary files differ
diff --git a/extras/html/themes/pure_storm/example.html b/extras/html/themes/pure_storm/example.html
new file mode 100644
index 0000000..5504d62
--- /dev/null
+++ b/extras/html/themes/pure_storm/example.html
@@ -0,0 +1,75 @@
+<!DOCTYPE html>
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
+<head>
+ <meta charset="UTF-8" />
+ <meta name="viewport" content="width=device-width, initial-scale=1.0" />
+ <title>Pure Storm - Gemtexter Theme</title>
+ <link rel="stylesheet" href="style.css" />
+</head>
+<body>
+ <div class="header">
+ <h1>Pure Storm</h1>
+ <p>A wide layout with analogous colors</p>
+ </div>
+
+ <div class="content">
+ <h1>Welcome to Pure Storm</h1>
+ <p>This theme features a carefully crafted wide layout with a dark analogous color scheme. The typography combines display fonts for headings with sans-serif for body text.</p>
+
+ <h2>Typography Showcase</h2>
+ <p>The Lato font family provides excellent readability for body text, while higher-jump adds character to headings. Code blocks use consola-mono for clarity.</p>
+
+ <h2>Color Palette</h2>
+ <p>Primary: <span style="color: #df3549; font-weight: bold;">#df3549</span> |
+ Secondary: <span style="color: #d6753d; font-weight: bold;">#d6753d</span> |
+ Accent: <span style="color: #d6218d; font-weight: bold;">#d6218d</span></p>
+
+ <h3>Interactive Elements</h3>
+ <p>Links like <a href="#">this example</a> and longer <a href="#" class="textlink">text links that demonstrate the theme's navigation style</a> use the secondary color.</p>
+
+ <div class="quote">
+ "Design is not just what it looks like and feels like. Design is how it works." — Steve Jobs
+ </div>
+
+ <h3>Code Examples</h3>
+ <p>Inline code like <code>theme.generate()</code> and larger blocks:</p>
+ <pre>// Theme configuration
+const theme = {
+ name: "pure_storm",
+ layout: "wide",
+ colors: {
+ primary: "#df3549",
+ secondary: "#d6753d",
+ accent: "#d6218d"
+ },
+ fonts: {
+ heading: "higher-jump",
+ body: "Lato",
+ code: "consola-mono"
+ }
+};</pre>
+
+ <h2>Content Structure</h2>
+ <ul>
+ <li>Clean, readable typography with 16px base font size</li>
+ <li>Heading scale ratio of 1.42x for visual hierarchy</li>
+ <li>Line height of 1.48 for comfortable reading</li>
+ <li>Wide layout optimized for content flow</li>
+ <li>Dark theme with analogous color harmony</li>
+ </ul>
+
+ <h2>Font Licensing</h2>
+ <p>All fonts used in this theme are properly licensed:</p>
+ <ul>
+ <li>higher-jump: Free License</li>
+ <li>Lato: OFL License</li>
+ <li>consola-mono: OFL License</li>
+ </ul>
+
+ <h3>Final Thoughts</h3>
+ <p>Every element of this theme has been carefully designed to create a harmonious reading experience. The wide layout ensures content is presented in an engaging way, while the color scheme provides the perfect backdrop for your words to shine.</p>
+
+ <p>Whether you're writing technical documentation, creative prose, or anything in between, this theme adapts to showcase your content beautifully.</p>
+ </div>
+</body>
+</html> \ No newline at end of file
diff --git a/extras/html/themes/pure_storm/handnotes.ttf b/extras/html/themes/pure_storm/handnotes.ttf
new file mode 100644
index 0000000..25e688b
--- /dev/null
+++ b/extras/html/themes/pure_storm/handnotes.ttf
Binary files differ
diff --git a/extras/html/themes/pure_storm/heading.ttf b/extras/html/themes/pure_storm/heading.ttf
new file mode 100644
index 0000000..608f2ad
--- /dev/null
+++ b/extras/html/themes/pure_storm/heading.ttf
Binary files differ
diff --git a/extras/html/themes/pure_storm/style.css b/extras/html/themes/pure_storm/style.css
new file mode 100644
index 0000000..fabd1f3
--- /dev/null
+++ b/extras/html/themes/pure_storm/style.css
@@ -0,0 +1,161 @@
+/* Base styles */
+@font-face {
+ font-family: 'text';
+ src: url("./text.ttf") format("truetype");
+}
+
+@font-face {
+ font-family: 'heading';
+ src: url("./heading.ttf") format("truetype");
+}
+
+@font-face {
+ font-family: 'code';
+ src: url("./code.ttf") format("truetype");
+}
+
+@font-face {
+ font-family: 'handnotes';
+ src: url("./handnotes.ttf") format("truetype");
+}
+
+:root {
+ --color-primary: #df3549;
+ --color-secondary: #d6753d;
+ --color-accent: #d6218d;
+ --color-bg: #261f1f;
+ --color-text: #e5e5e5;
+ --font-size-base: 16px;
+ --font-size-h1: 1.42em;
+ --font-size-h2: 1.27em;
+ --font-size-h3: 1.12em;
+ --line-height: 1.48;
+}
+
+* {
+ box-sizing: border-box;
+}
+
+html {
+ font-size: var(--font-size-base);
+ -webkit-font-smoothing: antialiased;
+ -moz-osx-font-smoothing: grayscale;
+}
+
+body {
+ font-family: text, sans-serif;
+ background-color: var(--color-bg);
+ color: var(--color-text);
+ line-height: var(--line-height);
+ margin: 0;
+ padding: 0;
+ overflow-wrap: break-word;
+}
+
+h1, h2, h3 {
+ font-family: heading, serif;
+ line-height: 1.2;
+ margin-top: 1em;
+ margin-bottom: 0.5em;
+}
+
+h1 {
+ font-size: var(--font-size-h1);
+ color: var(--color-primary);
+}
+
+h2 {
+ font-size: var(--font-size-h2);
+ color: var(--color-primary);
+}
+
+h3 {
+ font-size: var(--font-size-h3);
+ color: var(--color-secondary);
+}
+
+a {
+ font-family: code, monospace;
+ color: var(--color-secondary);
+ text-decoration: none;
+ transition: all 0.3s ease;
+}
+
+a:hover {
+ color: var(--color-accent);
+ text-decoration: underline;
+}
+
+.textlink {
+ font-family: text, sans-serif;
+}
+
+.quote {
+ font-family: handnotes, cursive;
+ border-left: 4px solid var(--color-accent);
+ padding: 1em 1.5em;
+ margin: 1.5em 0;
+ background-color: rgba(223, 53, 73, 0.07);
+ font-style: italic;
+}
+
+pre {
+ font-family: code, monospace;
+ background-color: rgba(229, 229, 229, 0.04);
+ border: 1px solid rgba(229, 229, 229, 0.13);
+ padding: 1em;
+ overflow-x: auto;
+ border-radius: 4px;
+ font-size: 0.9em;
+}
+
+code {
+ font-family: code, monospace;
+ background-color: rgba(229, 229, 229, 0.04);
+ padding: 0.2em 0.4em;
+ border-radius: 3px;
+ font-size: 0.9em;
+}
+
+ul, ol {
+ padding-left: 2em;
+ margin: 1em 0;
+}
+
+li {
+ margin: 0.5em 0;
+}
+
+img {
+ max-width: 100%;
+ height: auto;
+}
+
+hr {
+ border: none;
+ border-top: 1px solid rgba(229, 229, 229, 0.20);
+ margin: 2em 0;
+}
+
+
+/* Layout: wide */
+
+body {
+ max-width: 90%;
+ margin: 0 auto;
+ padding: 3em 2em;
+}
+
+.header {
+ display: flex;
+ justify-content: space-between;
+ align-items: baseline;
+ margin-bottom: 4em;
+ padding-bottom: 2em;
+ border-bottom: 3px solid var(--color-primary);
+}
+
+.content {
+ max-width: 75ch;
+ margin: 0 auto;
+}
diff --git a/extras/html/themes/pure_storm/text.ttf b/extras/html/themes/pure_storm/text.ttf
new file mode 100644
index 0000000..bb2e887
--- /dev/null
+++ b/extras/html/themes/pure_storm/text.ttf
Binary files differ
diff --git a/extras/html/themes/pure_storm/theme.conf b/extras/html/themes/pure_storm/theme.conf
new file mode 100644
index 0000000..7c09baa
--- /dev/null
+++ b/extras/html/themes/pure_storm/theme.conf
@@ -0,0 +1,8 @@
+declare -xr HTML_HEADER=./extras/html/header.html.part
+declare -xr HTML_FOOTER=./extras/html/footer.html.part
+declare -xr HTML_CSS_STYLE=$HTML_THEME_DIR/style.css
+declare -xr HTML_WEBFONT_HEADING=./extras/html/fonts/higher-jump/higher-jump-Bold.ttf
+declare -xr HTML_WEBFONT_TEXT=./extras/html/fonts/Lato/Lato-Regular.ttf
+declare -xr HTML_WEBFONT_CODE=./extras/html/fonts/consola-mono/consola-mono-Regular.ttf
+declare -xr HTML_WEBFONT_HANDNOTES=./extras/html/fonts/khand/khand.ttf
+declare -xr SOURCE_HIGHLIGHT_CSS=./extras/html/source-highlight-styles/mono.css
diff --git a/extras/html/themes/pure_voyage/LICENSE b/extras/html/themes/pure_voyage/LICENSE
new file mode 100644
index 0000000..4c55326
--- /dev/null
+++ b/extras/html/themes/pure_voyage/LICENSE
@@ -0,0 +1,21 @@
+Theme: pure_voyage
+Generated: 2025-06-22 21:38:55
+
+Layout: centered
+Color Scheme: triadic (Dark)
+
+Font Licenses:
+==============
+Heading Font: higher-jump
+License: Free
+Category: display
+
+Body Font: Lato
+License: OFL
+Category: sans-serif
+
+Code Font: consola-mono
+License: OFL
+Category: monospace
+
+All fonts are free for personal use.
diff --git a/extras/html/themes/pure_voyage/code.ttf b/extras/html/themes/pure_voyage/code.ttf
new file mode 100644
index 0000000..78ca9da
--- /dev/null
+++ b/extras/html/themes/pure_voyage/code.ttf
Binary files differ
diff --git a/extras/html/themes/pure_voyage/example.html b/extras/html/themes/pure_voyage/example.html
new file mode 100644
index 0000000..4d293be
--- /dev/null
+++ b/extras/html/themes/pure_voyage/example.html
@@ -0,0 +1,75 @@
+<!DOCTYPE html>
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
+<head>
+ <meta charset="UTF-8" />
+ <meta name="viewport" content="width=device-width, initial-scale=1.0" />
+ <title>Pure Voyage - Gemtexter Theme</title>
+ <link rel="stylesheet" href="style.css" />
+</head>
+<body>
+ <div class="header">
+ <h1>Pure Voyage</h1>
+ <p>A centered layout with triadic colors</p>
+ </div>
+
+ <div class="content">
+ <h1>Welcome to Pure Voyage</h1>
+ <p>This theme features a carefully crafted centered layout with a dark triadic color scheme. The typography combines display fonts for headings with sans-serif for body text.</p>
+
+ <h2>Typography Showcase</h2>
+ <p>The Lato font family provides excellent readability for body text, while higher-jump adds character to headings. Code blocks use consola-mono for clarity.</p>
+
+ <h2>Color Palette</h2>
+ <p>Primary: <span style="color: #92e630; font-weight: bold;">#92e630</span> |
+ Secondary: <span style="color: #3093e6; font-weight: bold;">#3093e6</span> |
+ Accent: <span style="color: #e63092; font-weight: bold;">#e63092</span></p>
+
+ <h3>Interactive Elements</h3>
+ <p>Links like <a href="#">this example</a> and longer <a href="#" class="textlink">text links that demonstrate the theme's navigation style</a> use the secondary color.</p>
+
+ <div class="quote">
+ "Design is not just what it looks like and feels like. Design is how it works." — Steve Jobs
+ </div>
+
+ <h3>Code Examples</h3>
+ <p>Inline code like <code>theme.generate()</code> and larger blocks:</p>
+ <pre>// Theme configuration
+const theme = {
+ name: "pure_voyage",
+ layout: "centered",
+ colors: {
+ primary: "#92e630",
+ secondary: "#3093e6",
+ accent: "#e63092"
+ },
+ fonts: {
+ heading: "higher-jump",
+ body: "Lato",
+ code: "consola-mono"
+ }
+};</pre>
+
+ <h2>Content Structure</h2>
+ <ul>
+ <li>Clean, readable typography with 18px base font size</li>
+ <li>Heading scale ratio of 2.37x for visual hierarchy</li>
+ <li>Line height of 1.75 for comfortable reading</li>
+ <li>Centered layout optimized for content flow</li>
+ <li>Dark theme with triadic color harmony</li>
+ </ul>
+
+ <h2>Font Licensing</h2>
+ <p>All fonts used in this theme are properly licensed:</p>
+ <ul>
+ <li>higher-jump: Free License</li>
+ <li>Lato: OFL License</li>
+ <li>consola-mono: OFL License</li>
+ </ul>
+
+ <h3>Final Thoughts</h3>
+ <p>Every element of this theme has been carefully designed to create a harmonious reading experience. The centered layout ensures content is presented in an engaging way, while the color scheme provides the perfect backdrop for your words to shine.</p>
+
+ <p>Whether you're writing technical documentation, creative prose, or anything in between, this theme adapts to showcase your content beautifully.</p>
+ </div>
+</body>
+</html> \ No newline at end of file
diff --git a/extras/html/themes/pure_voyage/handnotes.ttf b/extras/html/themes/pure_voyage/handnotes.ttf
new file mode 100644
index 0000000..25e688b
--- /dev/null
+++ b/extras/html/themes/pure_voyage/handnotes.ttf
Binary files differ
diff --git a/extras/html/themes/pure_voyage/heading.ttf b/extras/html/themes/pure_voyage/heading.ttf
new file mode 100644
index 0000000..608f2ad
--- /dev/null
+++ b/extras/html/themes/pure_voyage/heading.ttf
Binary files differ
diff --git a/extras/html/themes/pure_voyage/style.css b/extras/html/themes/pure_voyage/style.css
new file mode 100644
index 0000000..caa6db4
--- /dev/null
+++ b/extras/html/themes/pure_voyage/style.css
@@ -0,0 +1,154 @@
+/* Base styles */
+@font-face {
+ font-family: 'text';
+ src: url("./text.ttf") format("truetype");
+}
+
+@font-face {
+ font-family: 'heading';
+ src: url("./heading.ttf") format("truetype");
+}
+
+@font-face {
+ font-family: 'code';
+ src: url("./code.ttf") format("truetype");
+}
+
+@font-face {
+ font-family: 'handnotes';
+ src: url("./handnotes.ttf") format("truetype");
+}
+
+:root {
+ --color-primary: #92e630;
+ --color-secondary: #3093e6;
+ --color-accent: #e63092;
+ --color-bg: #10120e;
+ --color-text: #ebebeb;
+ --font-size-base: 18px;
+ --font-size-h1: 2.37em;
+ --font-size-h2: 1.78em;
+ --font-size-h3: 1.33em;
+ --line-height: 1.75;
+}
+
+* {
+ box-sizing: border-box;
+}
+
+html {
+ font-size: var(--font-size-base);
+ -webkit-font-smoothing: antialiased;
+ -moz-osx-font-smoothing: grayscale;
+}
+
+body {
+ font-family: text, sans-serif;
+ background-color: var(--color-bg);
+ color: var(--color-text);
+ line-height: var(--line-height);
+ margin: 0;
+ padding: 0;
+ overflow-wrap: break-word;
+}
+
+h1, h2, h3 {
+ font-family: heading, serif;
+ line-height: 1.2;
+ margin-top: 1em;
+ margin-bottom: 0.5em;
+}
+
+h1 {
+ font-size: var(--font-size-h1);
+ color: var(--color-primary);
+}
+
+h2 {
+ font-size: var(--font-size-h2);
+ color: var(--color-primary);
+}
+
+h3 {
+ font-size: var(--font-size-h3);
+ color: var(--color-secondary);
+}
+
+a {
+ font-family: code, monospace;
+ color: var(--color-secondary);
+ text-decoration: none;
+ transition: all 0.3s ease;
+}
+
+a:hover {
+ color: var(--color-accent);
+ text-decoration: underline;
+}
+
+.textlink {
+ font-family: text, sans-serif;
+}
+
+.quote {
+ font-family: handnotes, cursive;
+ border-left: 4px solid var(--color-accent);
+ padding: 1em 1.5em;
+ margin: 1.5em 0;
+ background-color: rgba(146, 230, 48, 0.07);
+ font-style: italic;
+}
+
+pre {
+ font-family: code, monospace;
+ background-color: rgba(235, 235, 235, 0.04);
+ border: 1px solid rgba(235, 235, 235, 0.13);
+ padding: 1em;
+ overflow-x: auto;
+ border-radius: 4px;
+ font-size: 0.9em;
+}
+
+code {
+ font-family: code, monospace;
+ background-color: rgba(235, 235, 235, 0.04);
+ padding: 0.2em 0.4em;
+ border-radius: 3px;
+ font-size: 0.9em;
+}
+
+ul, ol {
+ padding-left: 2em;
+ margin: 1em 0;
+}
+
+li {
+ margin: 0.5em 0;
+}
+
+img {
+ max-width: 100%;
+ height: auto;
+}
+
+hr {
+ border: none;
+ border-top: 1px solid rgba(235, 235, 235, 0.20);
+ margin: 2em 0;
+}
+
+
+/* Layout: centered */
+
+body {
+ max-width: 65ch;
+ margin: 0 auto;
+ padding: 2em 1em;
+}
+
+.header {
+ text-align: center;
+ margin-bottom: 3em;
+ padding-bottom: 2em;
+ border-bottom: 2px solid var(--color-primary);
+}
diff --git a/extras/html/themes/pure_voyage/text.ttf b/extras/html/themes/pure_voyage/text.ttf
new file mode 100644
index 0000000..bb2e887
--- /dev/null
+++ b/extras/html/themes/pure_voyage/text.ttf
Binary files differ
diff --git a/extras/html/themes/pure_voyage/theme.conf b/extras/html/themes/pure_voyage/theme.conf
new file mode 100644
index 0000000..7c09baa
--- /dev/null
+++ b/extras/html/themes/pure_voyage/theme.conf
@@ -0,0 +1,8 @@
+declare -xr HTML_HEADER=./extras/html/header.html.part
+declare -xr HTML_FOOTER=./extras/html/footer.html.part
+declare -xr HTML_CSS_STYLE=$HTML_THEME_DIR/style.css
+declare -xr HTML_WEBFONT_HEADING=./extras/html/fonts/higher-jump/higher-jump-Bold.ttf
+declare -xr HTML_WEBFONT_TEXT=./extras/html/fonts/Lato/Lato-Regular.ttf
+declare -xr HTML_WEBFONT_CODE=./extras/html/fonts/consola-mono/consola-mono-Regular.ttf
+declare -xr HTML_WEBFONT_HANDNOTES=./extras/html/fonts/khand/khand.ttf
+declare -xr SOURCE_HIGHLIGHT_CSS=./extras/html/source-highlight-styles/mono.css
diff --git a/extras/html/themes/radiant_voyage/LICENSE b/extras/html/themes/radiant_voyage/LICENSE
new file mode 100644
index 0000000..a6b15d6
--- /dev/null
+++ b/extras/html/themes/radiant_voyage/LICENSE
@@ -0,0 +1,21 @@
+Theme: radiant_voyage
+Generated: 2025-06-22 21:38:55
+
+Layout: terminal
+Color Scheme: split_complementary (Light)
+
+Font Licenses:
+==============
+Heading Font: oxygen
+License: OFL
+Category: sans-serif
+
+Body Font: Merriweather
+License: OFL
+Category: serif
+
+Code Font: intelone-mono
+License: OFL
+Category: monospace
+
+All fonts are free for personal use.
diff --git a/extras/html/themes/radiant_voyage/code.ttf b/extras/html/themes/radiant_voyage/code.ttf
new file mode 100644
index 0000000..2711179
--- /dev/null
+++ b/extras/html/themes/radiant_voyage/code.ttf
Binary files differ
diff --git a/extras/html/themes/radiant_voyage/example.html b/extras/html/themes/radiant_voyage/example.html
new file mode 100644
index 0000000..6bfbe9e
--- /dev/null
+++ b/extras/html/themes/radiant_voyage/example.html
@@ -0,0 +1,75 @@
+<!DOCTYPE html>
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
+<head>
+ <meta charset="UTF-8" />
+ <meta name="viewport" content="width=device-width, initial-scale=1.0" />
+ <title>Radiant Voyage - Gemtexter Theme</title>
+ <link rel="stylesheet" href="style.css" />
+</head>
+<body>
+ <div class="header">
+ <h1>Radiant Voyage</h1>
+ <p>A terminal layout with split complementary colors</p>
+ </div>
+
+ <div class="content">
+ <h1>Welcome to Radiant Voyage</h1>
+ <p>This theme features a carefully crafted terminal layout with a light split complementary color scheme. The typography combines sans-serif fonts for headings with serif for body text.</p>
+
+ <h2>Typography Showcase</h2>
+ <p>The Merriweather font family provides excellent readability for body text, while oxygen adds character to headings. Code blocks use intelone-mono for clarity.</p>
+
+ <h2>Color Palette</h2>
+ <p>Primary: <span style="color: #cf5ddf; font-weight: bold;">#cf5ddf</span> |
+ Secondary: <span style="color: #a8d26a; font-weight: bold;">#a8d26a</span> |
+ Accent: <span style="color: #6ad28f; font-weight: bold;">#6ad28f</span></p>
+
+ <h3>Interactive Elements</h3>
+ <p>Links like <a href="#">this example</a> and longer <a href="#" class="textlink">text links that demonstrate the theme's navigation style</a> use the secondary color.</p>
+
+ <div class="quote">
+ "Design is not just what it looks like and feels like. Design is how it works." — Steve Jobs
+ </div>
+
+ <h3>Code Examples</h3>
+ <p>Inline code like <code>theme.generate()</code> and larger blocks:</p>
+ <pre>// Theme configuration
+const theme = {
+ name: "radiant_voyage",
+ layout: "terminal",
+ colors: {
+ primary: "#cf5ddf",
+ secondary: "#a8d26a",
+ accent: "#6ad28f"
+ },
+ fonts: {
+ heading: "oxygen",
+ body: "Merriweather",
+ code: "intelone-mono"
+ }
+};</pre>
+
+ <h2>Content Structure</h2>
+ <ul>
+ <li>Clean, readable typography with 16px base font size</li>
+ <li>Heading scale ratio of 2.83x for visual hierarchy</li>
+ <li>Line height of 1.58 for comfortable reading</li>
+ <li>Terminal layout optimized for content flow</li>
+ <li>Light theme with split complementary color harmony</li>
+ </ul>
+
+ <h2>Font Licensing</h2>
+ <p>All fonts used in this theme are properly licensed:</p>
+ <ul>
+ <li>oxygen: OFL License</li>
+ <li>Merriweather: OFL License</li>
+ <li>intelone-mono: OFL License</li>
+ </ul>
+
+ <h3>Final Thoughts</h3>
+ <p>Every element of this theme has been carefully designed to create a harmonious reading experience. The terminal layout ensures content is presented in an engaging way, while the color scheme provides the perfect backdrop for your words to shine.</p>
+
+ <p>Whether you're writing technical documentation, creative prose, or anything in between, this theme adapts to showcase your content beautifully.</p>
+ </div>
+</body>
+</html> \ No newline at end of file
diff --git a/extras/html/themes/radiant_voyage/handnotes.ttf b/extras/html/themes/radiant_voyage/handnotes.ttf
new file mode 100644
index 0000000..25e688b
--- /dev/null
+++ b/extras/html/themes/radiant_voyage/handnotes.ttf
Binary files differ
diff --git a/extras/html/themes/radiant_voyage/style.css b/extras/html/themes/radiant_voyage/style.css
new file mode 100644
index 0000000..19889fb
--- /dev/null
+++ b/extras/html/themes/radiant_voyage/style.css
@@ -0,0 +1,216 @@
+/* Base styles */
+@font-face {
+ font-family: 'text';
+ src: url("./text.ttf") format("truetype");
+}
+
+@font-face {
+ font-family: 'heading';
+ src: url("./heading.ttf") format("truetype");
+}
+
+@font-face {
+ font-family: 'code';
+ src: url("./code.ttf") format("truetype");
+}
+
+@font-face {
+ font-family: 'handnotes';
+ src: url("./handnotes.ttf") format("truetype");
+}
+
+:root {
+ --color-primary: #cf5ddf;
+ --color-secondary: #a8d26a;
+ --color-accent: #6ad28f;
+ --color-bg: #f6f4f6;
+ --color-text: #1f1f1f;
+ --font-size-base: 16px;
+ --font-size-h1: 2.83em;
+ --font-size-h2: 2.0em;
+ --font-size-h3: 1.41em;
+ --line-height: 1.58;
+}
+
+* {
+ box-sizing: border-box;
+}
+
+html {
+ font-size: var(--font-size-base);
+ -webkit-font-smoothing: antialiased;
+ -moz-osx-font-smoothing: grayscale;
+}
+
+body {
+ font-family: text, sans-serif;
+ background-color: var(--color-bg);
+ color: var(--color-text);
+ line-height: var(--line-height);
+ margin: 0;
+ padding: 0;
+ overflow-wrap: break-word;
+}
+
+h1, h2, h3 {
+ font-family: heading, serif;
+ line-height: 1.2;
+ margin-top: 1em;
+ margin-bottom: 0.5em;
+}
+
+h1 {
+ font-size: var(--font-size-h1);
+ color: var(--color-primary);
+}
+
+h2 {
+ font-size: var(--font-size-h2);
+ color: var(--color-primary);
+}
+
+h3 {
+ font-size: var(--font-size-h3);
+ color: var(--color-secondary);
+}
+
+a {
+ font-family: code, monospace;
+ color: var(--color-secondary);
+ text-decoration: none;
+ transition: all 0.3s ease;
+}
+
+a:hover {
+ color: var(--color-accent);
+ text-decoration: underline;
+}
+
+.textlink {
+ font-family: text, sans-serif;
+}
+
+.quote {
+ font-family: handnotes, cursive;
+ border-left: 4px solid var(--color-accent);
+ padding: 1em 1.5em;
+ margin: 1.5em 0;
+ background-color: rgba(207, 93, 223, 0.07);
+ font-style: italic;
+}
+
+pre {
+ font-family: code, monospace;
+ background-color: rgba(31, 31, 31, 0.04);
+ border: 1px solid rgba(31, 31, 31, 0.13);
+ padding: 1em;
+ overflow-x: auto;
+ border-radius: 4px;
+ font-size: 0.9em;
+}
+
+code {
+ font-family: code, monospace;
+ background-color: rgba(31, 31, 31, 0.04);
+ padding: 0.2em 0.4em;
+ border-radius: 3px;
+ font-size: 0.9em;
+}
+
+ul, ol {
+ padding-left: 2em;
+ margin: 1em 0;
+}
+
+li {
+ margin: 0.5em 0;
+}
+
+img {
+ max-width: 100%;
+ height: auto;
+}
+
+hr {
+ border: none;
+ border-top: 1px solid rgba(31, 31, 31, 0.20);
+ margin: 2em 0;
+}
+
+
+/* Layout: terminal */
+
+@import url("https://fonts.googleapis.com/css2?family=Source+Code+Pro:wght@400;700&display=swap");
+
+body {
+ background-color: #000;
+ color: #0f0;
+ font-family: 'Source Code Pro', code, monospace;
+ padding: 1em;
+ line-height: 1.4;
+}
+
+.header {
+ border: 2px solid #0f0;
+ padding: 1em;
+ margin-bottom: 2em;
+ position: relative;
+}
+
+.header::before {
+ content: "[SYSTEM] ";
+ color: #ff0;
+}
+
+h1, h2, h3 {
+ color: #0f0;
+ font-family: 'Source Code Pro', code, monospace;
+}
+
+h1::before {
+ content: "### ";
+ color: #f0f;
+}
+
+h2::before {
+ content: "## ";
+ color: #0ff;
+}
+
+h3::before {
+ content: "# ";
+ color: #ff0;
+}
+
+p::before {
+ content: "> ";
+ color: #666;
+}
+
+a {
+ color: #0ff;
+ text-decoration: underline;
+}
+
+a:hover {
+ background-color: #0ff;
+ color: #000;
+}
+
+.quote {
+ border: 1px dashed #0f0;
+ background-color: #0f0111;
+ color: #0f0;
+}
+
+pre {
+ background-color: #111;
+ border: 1px solid #0f0;
+ color: #0f0;
+ overflow-x: scroll;
+}
+
+pre::before {
+ content: "$ cat output.log\A";
+ color: #666;
+}
diff --git a/extras/html/themes/radiant_voyage/text.ttf b/extras/html/themes/radiant_voyage/text.ttf
new file mode 100644
index 0000000..3fecc77
--- /dev/null
+++ b/extras/html/themes/radiant_voyage/text.ttf
Binary files differ
diff --git a/extras/html/themes/radiant_voyage/theme.conf b/extras/html/themes/radiant_voyage/theme.conf
new file mode 100644
index 0000000..11ad64d
--- /dev/null
+++ b/extras/html/themes/radiant_voyage/theme.conf
@@ -0,0 +1,8 @@
+declare -xr HTML_HEADER=./extras/html/header.html.part
+declare -xr HTML_FOOTER=./extras/html/footer.html.part
+declare -xr HTML_CSS_STYLE=$HTML_THEME_DIR/style.css
+declare -xr HTML_WEBFONT_HEADING=./extras/html/fonts/oxygen/oxygen-Bold.ttf
+declare -xr HTML_WEBFONT_TEXT=./extras/html/fonts/Merriweather/Merriweather-Regular.ttf
+declare -xr HTML_WEBFONT_CODE=./extras/html/fonts/intelone-mono/intelone-mono-Regular.ttf
+declare -xr HTML_WEBFONT_HANDNOTES=./extras/html/fonts/khand/khand.ttf
+declare -xr SOURCE_HIGHLIGHT_CSS=./extras/html/source-highlight-styles/mono.css
diff --git a/extras/html/themes/refined_aurora/LICENSE b/extras/html/themes/refined_aurora/LICENSE
new file mode 100644
index 0000000..f5ae8d8
--- /dev/null
+++ b/extras/html/themes/refined_aurora/LICENSE
@@ -0,0 +1,21 @@
+Theme: refined_aurora
+Generated: 2025-06-22 21:38:55
+
+Layout: hero
+Color Scheme: split_complementary (Light)
+
+Font Licenses:
+==============
+Heading Font: Abril_Fatface
+License: OFL
+Category: display
+
+Body Font: Lato
+License: OFL
+Category: sans-serif
+
+Code Font: consola-mono
+License: OFL
+Category: monospace
+
+All fonts are free for personal use.
diff --git a/extras/html/themes/refined_aurora/code.ttf b/extras/html/themes/refined_aurora/code.ttf
new file mode 100644
index 0000000..78ca9da
--- /dev/null
+++ b/extras/html/themes/refined_aurora/code.ttf
Binary files differ
diff --git a/extras/html/themes/refined_aurora/example.html b/extras/html/themes/refined_aurora/example.html
new file mode 100644
index 0000000..db82c4a
--- /dev/null
+++ b/extras/html/themes/refined_aurora/example.html
@@ -0,0 +1,75 @@
+<!DOCTYPE html>
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
+<head>
+ <meta charset="UTF-8" />
+ <meta name="viewport" content="width=device-width, initial-scale=1.0" />
+ <title>Refined Aurora - Gemtexter Theme</title>
+ <link rel="stylesheet" href="style.css" />
+</head>
+<body>
+ <div class="header">
+ <h1>Refined Aurora</h1>
+ <p>A hero layout with split complementary colors</p>
+ </div>
+
+ <div class="content">
+ <h1>Welcome to Refined Aurora</h1>
+ <p>This theme features a carefully crafted hero layout with a light split complementary color scheme. The typography combines display fonts for headings with sans-serif for body text.</p>
+
+ <h2>Typography Showcase</h2>
+ <p>The Lato font family provides excellent readability for body text, while Abril Fatface adds character to headings. Code blocks use consola-mono for clarity.</p>
+
+ <h2>Color Palette</h2>
+ <p>Primary: <span style="color: #3186b1; font-weight: bold;">#3186b1</span> |
+ Secondary: <span style="color: #a43e4d; font-weight: bold;">#a43e4d</span> |
+ Accent: <span style="color: #a4913e; font-weight: bold;">#a4913e</span></p>
+
+ <h3>Interactive Elements</h3>
+ <p>Links like <a href="#">this example</a> and longer <a href="#" class="textlink">text links that demonstrate the theme's navigation style</a> use the secondary color.</p>
+
+ <div class="quote">
+ "Design is not just what it looks like and feels like. Design is how it works." — Steve Jobs
+ </div>
+
+ <h3>Code Examples</h3>
+ <p>Inline code like <code>theme.generate()</code> and larger blocks:</p>
+ <pre>// Theme configuration
+const theme = {
+ name: "refined_aurora",
+ layout: "hero",
+ colors: {
+ primary: "#3186b1",
+ secondary: "#a43e4d",
+ accent: "#a4913e"
+ },
+ fonts: {
+ heading: "Abril_Fatface",
+ body: "Lato",
+ code: "consola-mono"
+ }
+};</pre>
+
+ <h2>Content Structure</h2>
+ <ul>
+ <li>Clean, readable typography with 18px base font size</li>
+ <li>Heading scale ratio of 3.38x for visual hierarchy</li>
+ <li>Line height of 1.46 for comfortable reading</li>
+ <li>Hero layout optimized for content flow</li>
+ <li>Light theme with split complementary color harmony</li>
+ </ul>
+
+ <h2>Font Licensing</h2>
+ <p>All fonts used in this theme are properly licensed:</p>
+ <ul>
+ <li>Abril_Fatface: OFL License</li>
+ <li>Lato: OFL License</li>
+ <li>consola-mono: OFL License</li>
+ </ul>
+
+ <h3>Final Thoughts</h3>
+ <p>Every element of this theme has been carefully designed to create a harmonious reading experience. The hero layout ensures content is presented in an engaging way, while the color scheme provides the perfect backdrop for your words to shine.</p>
+
+ <p>Whether you're writing technical documentation, creative prose, or anything in between, this theme adapts to showcase your content beautifully.</p>
+ </div>
+</body>
+</html> \ No newline at end of file
diff --git a/extras/html/themes/refined_aurora/handnotes.ttf b/extras/html/themes/refined_aurora/handnotes.ttf
new file mode 100644
index 0000000..25e688b
--- /dev/null
+++ b/extras/html/themes/refined_aurora/handnotes.ttf
Binary files differ
diff --git a/extras/html/themes/refined_aurora/heading.ttf b/extras/html/themes/refined_aurora/heading.ttf
new file mode 100644
index 0000000..a291711
--- /dev/null
+++ b/extras/html/themes/refined_aurora/heading.ttf
Binary files differ
diff --git a/extras/html/themes/refined_aurora/style.css b/extras/html/themes/refined_aurora/style.css
new file mode 100644
index 0000000..c6e1115
--- /dev/null
+++ b/extras/html/themes/refined_aurora/style.css
@@ -0,0 +1,176 @@
+/* Base styles */
+@font-face {
+ font-family: 'text';
+ src: url("./text.ttf") format("truetype");
+}
+
+@font-face {
+ font-family: 'heading';
+ src: url("./heading.ttf") format("truetype");
+}
+
+@font-face {
+ font-family: 'code';
+ src: url("./code.ttf") format("truetype");
+}
+
+@font-face {
+ font-family: 'handnotes';
+ src: url("./handnotes.ttf") format("truetype");
+}
+
+:root {
+ --color-primary: #3186b1;
+ --color-secondary: #a43e4d;
+ --color-accent: #a4913e;
+ --color-bg: #e9eced;
+ --color-text: #1c1c1c;
+ --font-size-base: 18px;
+ --font-size-h1: 3.38em;
+ --font-size-h2: 2.25em;
+ --font-size-h3: 1.5em;
+ --line-height: 1.46;
+}
+
+* {
+ box-sizing: border-box;
+}
+
+html {
+ font-size: var(--font-size-base);
+ -webkit-font-smoothing: antialiased;
+ -moz-osx-font-smoothing: grayscale;
+}
+
+body {
+ font-family: text, sans-serif;
+ background-color: var(--color-bg);
+ color: var(--color-text);
+ line-height: var(--line-height);
+ margin: 0;
+ padding: 0;
+ overflow-wrap: break-word;
+}
+
+h1, h2, h3 {
+ font-family: heading, serif;
+ line-height: 1.2;
+ margin-top: 1em;
+ margin-bottom: 0.5em;
+}
+
+h1 {
+ font-size: var(--font-size-h1);
+ color: var(--color-primary);
+}
+
+h2 {
+ font-size: var(--font-size-h2);
+ color: var(--color-primary);
+}
+
+h3 {
+ font-size: var(--font-size-h3);
+ color: var(--color-secondary);
+}
+
+a {
+ font-family: code, monospace;
+ color: var(--color-secondary);
+ text-decoration: none;
+ transition: all 0.3s ease;
+}
+
+a:hover {
+ color: var(--color-accent);
+ text-decoration: underline;
+}
+
+.textlink {
+ font-family: text, sans-serif;
+}
+
+.quote {
+ font-family: handnotes, cursive;
+ border-left: 4px solid var(--color-accent);
+ padding: 1em 1.5em;
+ margin: 1.5em 0;
+ background-color: rgba(49, 134, 177, 0.07);
+ font-style: italic;
+}
+
+pre {
+ font-family: code, monospace;
+ background-color: rgba(28, 28, 28, 0.04);
+ border: 1px solid rgba(28, 28, 28, 0.13);
+ padding: 1em;
+ overflow-x: auto;
+ border-radius: 4px;
+ font-size: 0.9em;
+}
+
+code {
+ font-family: code, monospace;
+ background-color: rgba(28, 28, 28, 0.04);
+ padding: 0.2em 0.4em;
+ border-radius: 3px;
+ font-size: 0.9em;
+}
+
+ul, ol {
+ padding-left: 2em;
+ margin: 1em 0;
+}
+
+li {
+ margin: 0.5em 0;
+}
+
+img {
+ max-width: 100%;
+ height: auto;
+}
+
+hr {
+ border: none;
+ border-top: 1px solid rgba(28, 28, 28, 0.20);
+ margin: 2em 0;
+}
+
+
+/* Layout: hero */
+
+body {
+ margin: 0;
+ padding: 0;
+}
+
+.header {
+ min-height: 80vh;
+ display: flex;
+ flex-direction: column;
+ justify-content: center;
+ align-items: center;
+ background: linear-gradient(135deg, rgba(49, 134, 177, 0.80), rgba(164, 62, 77, 0.80)), linear-gradient(45deg, rgba(164, 145, 62, 0.13), transparent);
+ color: var(--color-bg);
+ text-align: center;
+ position: relative;
+}
+
+.header h1 {
+ font-size: 5em;
+ margin: 0;
+ color: var(--color-bg);
+ text-shadow: 0 4px 8px rgba(0,0,0,0.3);
+}
+
+.header p {
+ font-size: 1.5em;
+ opacity: 0.9;
+}
+
+.content {
+ max-width: 65ch;
+ margin: 4em auto;
+ padding: 0 2em;
+}
diff --git a/extras/html/themes/refined_aurora/text.ttf b/extras/html/themes/refined_aurora/text.ttf
new file mode 100644
index 0000000..bb2e887
--- /dev/null
+++ b/extras/html/themes/refined_aurora/text.ttf
Binary files differ
diff --git a/extras/html/themes/refined_aurora/theme.conf b/extras/html/themes/refined_aurora/theme.conf
new file mode 100644
index 0000000..f738703
--- /dev/null
+++ b/extras/html/themes/refined_aurora/theme.conf
@@ -0,0 +1,8 @@
+declare -xr HTML_HEADER=./extras/html/header.html.part
+declare -xr HTML_FOOTER=./extras/html/footer.html.part
+declare -xr HTML_CSS_STYLE=$HTML_THEME_DIR/style.css
+declare -xr HTML_WEBFONT_HEADING=./extras/html/fonts/Abril_Fatface/Abril_Fatface-Bold.ttf
+declare -xr HTML_WEBFONT_TEXT=./extras/html/fonts/Lato/Lato-Regular.ttf
+declare -xr HTML_WEBFONT_CODE=./extras/html/fonts/consola-mono/consola-mono-Regular.ttf
+declare -xr HTML_WEBFONT_HANDNOTES=./extras/html/fonts/khand/khand.ttf
+declare -xr SOURCE_HIGHLIGHT_CSS=./extras/html/source-highlight-styles/mono.css
diff --git a/extras/html/themes/refined_oasis/LICENSE b/extras/html/themes/refined_oasis/LICENSE
new file mode 100644
index 0000000..704ccdc
--- /dev/null
+++ b/extras/html/themes/refined_oasis/LICENSE
@@ -0,0 +1,21 @@
+Theme: refined_oasis
+Generated: 2025-06-22 21:38:55
+
+Layout: floating
+Color Scheme: complementary (Dark)
+
+Font Licenses:
+==============
+Heading Font: repetition-scrolling
+License: Free
+Category: display
+
+Body Font: Merriweather
+License: OFL
+Category: serif
+
+Code Font: intelone-mono
+License: OFL
+Category: monospace
+
+All fonts are free for personal use.
diff --git a/extras/html/themes/refined_oasis/code.ttf b/extras/html/themes/refined_oasis/code.ttf
new file mode 100644
index 0000000..2711179
--- /dev/null
+++ b/extras/html/themes/refined_oasis/code.ttf
Binary files differ
diff --git a/extras/html/themes/refined_oasis/example.html b/extras/html/themes/refined_oasis/example.html
new file mode 100644
index 0000000..bf4701b
--- /dev/null
+++ b/extras/html/themes/refined_oasis/example.html
@@ -0,0 +1,75 @@
+<!DOCTYPE html>
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
+<head>
+ <meta charset="UTF-8" />
+ <meta name="viewport" content="width=device-width, initial-scale=1.0" />
+ <title>Refined Oasis - Gemtexter Theme</title>
+ <link rel="stylesheet" href="style.css" />
+</head>
+<body>
+ <div class="header">
+ <h1>Refined Oasis</h1>
+ <p>A floating layout with complementary colors</p>
+ </div>
+
+ <div class="content">
+ <h1>Welcome to Refined Oasis</h1>
+ <p>This theme features a carefully crafted floating layout with a dark complementary color scheme. The typography combines display fonts for headings with serif for body text.</p>
+
+ <h2>Typography Showcase</h2>
+ <p>The Merriweather font family provides excellent readability for body text, while repetition-scrolling adds character to headings. Code blocks use intelone-mono for clarity.</p>
+
+ <h2>Color Palette</h2>
+ <p>Primary: <span style="color: #c4cd12; font-weight: bold;">#c4cd12</span> |
+ Secondary: <span style="color: #2c25ba; font-weight: bold;">#2c25ba</span> |
+ Accent: <span style="color: #81862c; font-weight: bold;">#81862c</span></p>
+
+ <h3>Interactive Elements</h3>
+ <p>Links like <a href="#">this example</a> and longer <a href="#" class="textlink">text links that demonstrate the theme's navigation style</a> use the secondary color.</p>
+
+ <div class="quote">
+ "Design is not just what it looks like and feels like. Design is how it works." — Steve Jobs
+ </div>
+
+ <h3>Code Examples</h3>
+ <p>Inline code like <code>theme.generate()</code> and larger blocks:</p>
+ <pre>// Theme configuration
+const theme = {
+ name: "refined_oasis",
+ layout: "floating",
+ colors: {
+ primary: "#c4cd12",
+ secondary: "#2c25ba",
+ accent: "#81862c"
+ },
+ fonts: {
+ heading: "repetition-scrolling",
+ body: "Merriweather",
+ code: "intelone-mono"
+ }
+};</pre>
+
+ <h2>Content Structure</h2>
+ <ul>
+ <li>Clean, readable typography with 16px base font size</li>
+ <li>Heading scale ratio of 2.83x for visual hierarchy</li>
+ <li>Line height of 1.42 for comfortable reading</li>
+ <li>Floating layout optimized for content flow</li>
+ <li>Dark theme with complementary color harmony</li>
+ </ul>
+
+ <h2>Font Licensing</h2>
+ <p>All fonts used in this theme are properly licensed:</p>
+ <ul>
+ <li>repetition-scrolling: Free License</li>
+ <li>Merriweather: OFL License</li>
+ <li>intelone-mono: OFL License</li>
+ </ul>
+
+ <h3>Final Thoughts</h3>
+ <p>Every element of this theme has been carefully designed to create a harmonious reading experience. The floating layout ensures content is presented in an engaging way, while the color scheme provides the perfect backdrop for your words to shine.</p>
+
+ <p>Whether you're writing technical documentation, creative prose, or anything in between, this theme adapts to showcase your content beautifully.</p>
+ </div>
+</body>
+</html> \ No newline at end of file
diff --git a/extras/html/themes/refined_oasis/handnotes.ttf b/extras/html/themes/refined_oasis/handnotes.ttf
new file mode 100644
index 0000000..25e688b
--- /dev/null
+++ b/extras/html/themes/refined_oasis/handnotes.ttf
Binary files differ
diff --git a/extras/html/themes/refined_oasis/heading.ttf b/extras/html/themes/refined_oasis/heading.ttf
new file mode 100644
index 0000000..1d0a401
--- /dev/null
+++ b/extras/html/themes/refined_oasis/heading.ttf
Binary files differ
diff --git a/extras/html/themes/refined_oasis/style.css b/extras/html/themes/refined_oasis/style.css
new file mode 100644
index 0000000..d614d26
--- /dev/null
+++ b/extras/html/themes/refined_oasis/style.css
@@ -0,0 +1,173 @@
+/* Base styles */
+@font-face {
+ font-family: 'text';
+ src: url("./text.ttf") format("truetype");
+}
+
+@font-face {
+ font-family: 'heading';
+ src: url("./heading.ttf") format("truetype");
+}
+
+@font-face {
+ font-family: 'code';
+ src: url("./code.ttf") format("truetype");
+}
+
+@font-face {
+ font-family: 'handnotes';
+ src: url("./handnotes.ttf") format("truetype");
+}
+
+:root {
+ --color-primary: #c4cd12;
+ --color-secondary: #2c25ba;
+ --color-accent: #81862c;
+ --color-bg: #23231d;
+ --color-text: #e8e8e8;
+ --font-size-base: 16px;
+ --font-size-h1: 2.83em;
+ --font-size-h2: 2.0em;
+ --font-size-h3: 1.41em;
+ --line-height: 1.42;
+}
+
+* {
+ box-sizing: border-box;
+}
+
+html {
+ font-size: var(--font-size-base);
+ -webkit-font-smoothing: antialiased;
+ -moz-osx-font-smoothing: grayscale;
+}
+
+body {
+ font-family: text, sans-serif;
+ background-color: var(--color-bg);
+ color: var(--color-text);
+ line-height: var(--line-height);
+ margin: 0;
+ padding: 0;
+ overflow-wrap: break-word;
+}
+
+h1, h2, h3 {
+ font-family: heading, serif;
+ line-height: 1.2;
+ margin-top: 1em;
+ margin-bottom: 0.5em;
+}
+
+h1 {
+ font-size: var(--font-size-h1);
+ color: var(--color-primary);
+}
+
+h2 {
+ font-size: var(--font-size-h2);
+ color: var(--color-primary);
+}
+
+h3 {
+ font-size: var(--font-size-h3);
+ color: var(--color-secondary);
+}
+
+a {
+ font-family: code, monospace;
+ color: var(--color-secondary);
+ text-decoration: none;
+ transition: all 0.3s ease;
+}
+
+a:hover {
+ color: var(--color-accent);
+ text-decoration: underline;
+}
+
+.textlink {
+ font-family: text, sans-serif;
+}
+
+.quote {
+ font-family: handnotes, cursive;
+ border-left: 4px solid var(--color-accent);
+ padding: 1em 1.5em;
+ margin: 1.5em 0;
+ background-color: rgba(196, 205, 18, 0.07);
+ font-style: italic;
+}
+
+pre {
+ font-family: code, monospace;
+ background-color: rgba(232, 232, 232, 0.04);
+ border: 1px solid rgba(232, 232, 232, 0.13);
+ padding: 1em;
+ overflow-x: auto;
+ border-radius: 4px;
+ font-size: 0.9em;
+}
+
+code {
+ font-family: code, monospace;
+ background-color: rgba(232, 232, 232, 0.04);
+ padding: 0.2em 0.4em;
+ border-radius: 3px;
+ font-size: 0.9em;
+}
+
+ul, ol {
+ padding-left: 2em;
+ margin: 1em 0;
+}
+
+li {
+ margin: 0.5em 0;
+}
+
+img {
+ max-width: 100%;
+ height: auto;
+}
+
+hr {
+ border: none;
+ border-top: 1px solid rgba(232, 232, 232, 0.20);
+ margin: 2em 0;
+}
+
+
+/* Layout: floating */
+
+body {
+ padding: 4em 2em;
+ background: linear-gradient(45deg, rgba(196, 205, 18, 0.07), rgba(44, 37, 186, 0.07));
+ min-height: 100vh;
+}
+
+.header {
+ text-align: center;
+ margin-bottom: 4em;
+ animation: float 6s ease-in-out infinite;
+}
+
+@keyframes float {
+ 0%, 100% { transform: translateY(0); }
+ 50% { transform: translateY(-20px); }
+}
+
+h1, h2, h3, p, ul, pre, .quote {
+ background-color: var(--color-bg);
+ padding: 2em;
+ margin: 2em auto;
+ max-width: 65ch;
+ border-radius: 16px;
+ box-shadow: 0 8px 32px rgba(0,0,0,0.1);
+ transition: transform 0.3s ease;
+}
+
+h1:hover, h2:hover, h3:hover, p:hover, ul:hover, pre:hover, .quote:hover {
+ transform: translateY(-4px);
+ box-shadow: 0 12px 48px rgba(0,0,0,0.15);
+}
diff --git a/extras/html/themes/refined_oasis/text.ttf b/extras/html/themes/refined_oasis/text.ttf
new file mode 100644
index 0000000..3fecc77
--- /dev/null
+++ b/extras/html/themes/refined_oasis/text.ttf
Binary files differ
diff --git a/extras/html/themes/refined_oasis/theme.conf b/extras/html/themes/refined_oasis/theme.conf
new file mode 100644
index 0000000..b571a24
--- /dev/null
+++ b/extras/html/themes/refined_oasis/theme.conf
@@ -0,0 +1,8 @@
+declare -xr HTML_HEADER=./extras/html/header.html.part
+declare -xr HTML_FOOTER=./extras/html/footer.html.part
+declare -xr HTML_CSS_STYLE=$HTML_THEME_DIR/style.css
+declare -xr HTML_WEBFONT_HEADING=./extras/html/fonts/repetition-scrolling/repetition-scrolling-Bold.ttf
+declare -xr HTML_WEBFONT_TEXT=./extras/html/fonts/Merriweather/Merriweather-Regular.ttf
+declare -xr HTML_WEBFONT_CODE=./extras/html/fonts/intelone-mono/intelone-mono-Regular.ttf
+declare -xr HTML_WEBFONT_HANDNOTES=./extras/html/fonts/khand/khand.ttf
+declare -xr SOURCE_HIGHLIGHT_CSS=./extras/html/source-highlight-styles/mono.css
diff --git a/extras/html/themes/retrosimple/style.css b/extras/html/themes/retrosimple/style.css
index 1edd18c..b904c54 100644
--- a/extras/html/themes/retrosimple/style.css
+++ b/extras/html/themes/retrosimple/style.css
@@ -5,7 +5,7 @@ body {
margin: 20px auto;
border: 1px solid #000000;
border-radius: 15px;
- word-wrap: break-word;
+ overflow-wrap: break-word;
}
a {
diff --git a/extras/html/themes/screenshots/abyss.png b/extras/html/themes/screenshots/abyss.png
new file mode 100644
index 0000000..effd1ff
--- /dev/null
+++ b/extras/html/themes/screenshots/abyss.png
Binary files differ
diff --git a/extras/html/themes/screenshots/amber.png b/extras/html/themes/screenshots/amber.png
new file mode 100644
index 0000000..dae30c4
--- /dev/null
+++ b/extras/html/themes/screenshots/amber.png
Binary files differ
diff --git a/extras/html/themes/screenshots/amber_glacier.png b/extras/html/themes/screenshots/amber_glacier.png
new file mode 100644
index 0000000..f160be0
--- /dev/null
+++ b/extras/html/themes/screenshots/amber_glacier.png
Binary files differ
diff --git a/extras/html/themes/screenshots/arctic.png b/extras/html/themes/screenshots/arctic.png
new file mode 100644
index 0000000..0c17e5b
--- /dev/null
+++ b/extras/html/themes/screenshots/arctic.png
Binary files differ
diff --git a/extras/html/themes/screenshots/aurora_breeze.png b/extras/html/themes/screenshots/aurora_breeze.png
new file mode 100644
index 0000000..9691e24
--- /dev/null
+++ b/extras/html/themes/screenshots/aurora_breeze.png
Binary files differ
diff --git a/extras/html/themes/screenshots/aurora_dawn.png b/extras/html/themes/screenshots/aurora_dawn.png
new file mode 100644
index 0000000..8a002d5
--- /dev/null
+++ b/extras/html/themes/screenshots/aurora_dawn.png
Binary files differ
diff --git a/extras/html/themes/screenshots/autumn.png b/extras/html/themes/screenshots/autumn.png
new file mode 100644
index 0000000..fe7ae00
--- /dev/null
+++ b/extras/html/themes/screenshots/autumn.png
Binary files differ
diff --git a/extras/html/themes/screenshots/bamboo.png b/extras/html/themes/screenshots/bamboo.png
new file mode 100644
index 0000000..1edbbd4
--- /dev/null
+++ b/extras/html/themes/screenshots/bamboo.png
Binary files differ
diff --git a/extras/html/themes/screenshots/bark.png b/extras/html/themes/screenshots/bark.png
new file mode 100644
index 0000000..b9ae50c
--- /dev/null
+++ b/extras/html/themes/screenshots/bark.png
Binary files differ
diff --git a/extras/html/themes/screenshots/bold_pulse.png b/extras/html/themes/screenshots/bold_pulse.png
new file mode 100644
index 0000000..7e16fef
--- /dev/null
+++ b/extras/html/themes/screenshots/bold_pulse.png
Binary files differ
diff --git a/extras/html/themes/screenshots/bright_light.png b/extras/html/themes/screenshots/bright_light.png
new file mode 100644
index 0000000..9f72c01
--- /dev/null
+++ b/extras/html/themes/screenshots/bright_light.png
Binary files differ
diff --git a/extras/html/themes/screenshots/bright_spark.png b/extras/html/themes/screenshots/bright_spark.png
new file mode 100644
index 0000000..925c51e
--- /dev/null
+++ b/extras/html/themes/screenshots/bright_spark.png
Binary files differ
diff --git a/extras/html/themes/screenshots/business.png b/extras/html/themes/screenshots/business.png
new file mode 100644
index 0000000..dadb443
--- /dev/null
+++ b/extras/html/themes/screenshots/business.png
Binary files differ
diff --git a/extras/html/themes/screenshots/charcoal.png b/extras/html/themes/screenshots/charcoal.png
new file mode 100644
index 0000000..cff2d8e
--- /dev/null
+++ b/extras/html/themes/screenshots/charcoal.png
Binary files differ
diff --git a/extras/html/themes/screenshots/chrome.png b/extras/html/themes/screenshots/chrome.png
new file mode 100644
index 0000000..794ab27
--- /dev/null
+++ b/extras/html/themes/screenshots/chrome.png
Binary files differ
diff --git a/extras/html/themes/screenshots/clean.png b/extras/html/themes/screenshots/clean.png
new file mode 100644
index 0000000..3c389ea
--- /dev/null
+++ b/extras/html/themes/screenshots/clean.png
Binary files differ
diff --git a/extras/html/themes/screenshots/clean_garden.png b/extras/html/themes/screenshots/clean_garden.png
new file mode 100644
index 0000000..f634ae2
--- /dev/null
+++ b/extras/html/themes/screenshots/clean_garden.png
Binary files differ
diff --git a/extras/html/themes/screenshots/clean_rhythm.png b/extras/html/themes/screenshots/clean_rhythm.png
new file mode 100644
index 0000000..207d3e9
--- /dev/null
+++ b/extras/html/themes/screenshots/clean_rhythm.png
Binary files differ
diff --git a/extras/html/themes/screenshots/clear_forest.png b/extras/html/themes/screenshots/clear_forest.png
new file mode 100644
index 0000000..be605fd
--- /dev/null
+++ b/extras/html/themes/screenshots/clear_forest.png
Binary files differ
diff --git a/extras/html/themes/screenshots/clear_frost.png b/extras/html/themes/screenshots/clear_frost.png
new file mode 100644
index 0000000..1ba3995
--- /dev/null
+++ b/extras/html/themes/screenshots/clear_frost.png
Binary files differ
diff --git a/extras/html/themes/screenshots/cobalt.png b/extras/html/themes/screenshots/cobalt.png
new file mode 100644
index 0000000..7ba692d
--- /dev/null
+++ b/extras/html/themes/screenshots/cobalt.png
Binary files differ
diff --git a/extras/html/themes/screenshots/cool_breeze.png b/extras/html/themes/screenshots/cool_breeze.png
new file mode 100644
index 0000000..8bf7bf2
--- /dev/null
+++ b/extras/html/themes/screenshots/cool_breeze.png
Binary files differ
diff --git a/extras/html/themes/screenshots/copper.png b/extras/html/themes/screenshots/copper.png
new file mode 100644
index 0000000..40913ee
--- /dev/null
+++ b/extras/html/themes/screenshots/copper.png
Binary files differ
diff --git a/extras/html/themes/screenshots/coral.png b/extras/html/themes/screenshots/coral.png
new file mode 100644
index 0000000..7367089
--- /dev/null
+++ b/extras/html/themes/screenshots/coral.png
Binary files differ
diff --git a/extras/html/themes/screenshots/cosmic_dusk.png b/extras/html/themes/screenshots/cosmic_dusk.png
new file mode 100644
index 0000000..32ba845
--- /dev/null
+++ b/extras/html/themes/screenshots/cosmic_dusk.png
Binary files differ
diff --git a/extras/html/themes/screenshots/cosmic_odyssey.png b/extras/html/themes/screenshots/cosmic_odyssey.png
new file mode 100644
index 0000000..018bc19
--- /dev/null
+++ b/extras/html/themes/screenshots/cosmic_odyssey.png
Binary files differ
diff --git a/extras/html/themes/screenshots/cosmos.png b/extras/html/themes/screenshots/cosmos.png
new file mode 100644
index 0000000..9643043
--- /dev/null
+++ b/extras/html/themes/screenshots/cosmos.png
Binary files differ
diff --git a/extras/html/themes/screenshots/cozy_crystal.png b/extras/html/themes/screenshots/cozy_crystal.png
new file mode 100644
index 0000000..56c745c
--- /dev/null
+++ b/extras/html/themes/screenshots/cozy_crystal.png
Binary files differ
diff --git a/extras/html/themes/screenshots/cozy_wave.png b/extras/html/themes/screenshots/cozy_wave.png
new file mode 100644
index 0000000..408710f
--- /dev/null
+++ b/extras/html/themes/screenshots/cozy_wave.png
Binary files differ
diff --git a/extras/html/themes/screenshots/crimson.png b/extras/html/themes/screenshots/crimson.png
new file mode 100644
index 0000000..de874b0
--- /dev/null
+++ b/extras/html/themes/screenshots/crimson.png
Binary files differ
diff --git a/extras/html/themes/screenshots/crisp_oasis.png b/extras/html/themes/screenshots/crisp_oasis.png
new file mode 100644
index 0000000..aba5ba2
--- /dev/null
+++ b/extras/html/themes/screenshots/crisp_oasis.png
Binary files differ
diff --git a/extras/html/themes/screenshots/deep_crystal.png b/extras/html/themes/screenshots/deep_crystal.png
new file mode 100644
index 0000000..a3c731c
--- /dev/null
+++ b/extras/html/themes/screenshots/deep_crystal.png
Binary files differ
diff --git a/extras/html/themes/screenshots/deep_sky.png b/extras/html/themes/screenshots/deep_sky.png
new file mode 100644
index 0000000..3846f2a
--- /dev/null
+++ b/extras/html/themes/screenshots/deep_sky.png
Binary files differ
diff --git a/extras/html/themes/screenshots/default.png b/extras/html/themes/screenshots/default.png
new file mode 100644
index 0000000..6f2d3a5
--- /dev/null
+++ b/extras/html/themes/screenshots/default.png
Binary files differ
diff --git a/extras/html/themes/screenshots/dusk.png b/extras/html/themes/screenshots/dusk.png
new file mode 100644
index 0000000..6be3572
--- /dev/null
+++ b/extras/html/themes/screenshots/dusk.png
Binary files differ
diff --git a/extras/html/themes/screenshots/dynamic_forest.png b/extras/html/themes/screenshots/dynamic_forest.png
new file mode 100644
index 0000000..2d0dcb6
--- /dev/null
+++ b/extras/html/themes/screenshots/dynamic_forest.png
Binary files differ
diff --git a/extras/html/themes/screenshots/ember_mist.png b/extras/html/themes/screenshots/ember_mist.png
new file mode 100644
index 0000000..40126dd
--- /dev/null
+++ b/extras/html/themes/screenshots/ember_mist.png
Binary files differ
diff --git a/extras/html/themes/screenshots/ember_mountain.png b/extras/html/themes/screenshots/ember_mountain.png
new file mode 100644
index 0000000..6755ec6
--- /dev/null
+++ b/extras/html/themes/screenshots/ember_mountain.png
Binary files differ
diff --git a/extras/html/themes/screenshots/ember_night.png b/extras/html/themes/screenshots/ember_night.png
new file mode 100644
index 0000000..d92bb6f
--- /dev/null
+++ b/extras/html/themes/screenshots/ember_night.png
Binary files differ
diff --git a/extras/html/themes/screenshots/ethereal_mist.png b/extras/html/themes/screenshots/ethereal_mist.png
new file mode 100644
index 0000000..7558436
--- /dev/null
+++ b/extras/html/themes/screenshots/ethereal_mist.png
Binary files differ
diff --git a/extras/html/themes/screenshots/fern.png b/extras/html/themes/screenshots/fern.png
new file mode 100644
index 0000000..ac672ea
--- /dev/null
+++ b/extras/html/themes/screenshots/fern.png
Binary files differ
diff --git a/extras/html/themes/screenshots/forest.png b/extras/html/themes/screenshots/forest.png
new file mode 100644
index 0000000..78fdd86
--- /dev/null
+++ b/extras/html/themes/screenshots/forest.png
Binary files differ
diff --git a/extras/html/themes/screenshots/fresh_field.png b/extras/html/themes/screenshots/fresh_field.png
new file mode 100644
index 0000000..199a5c7
--- /dev/null
+++ b/extras/html/themes/screenshots/fresh_field.png
Binary files differ
diff --git a/extras/html/themes/screenshots/frost.png b/extras/html/themes/screenshots/frost.png
new file mode 100644
index 0000000..2be0b76
--- /dev/null
+++ b/extras/html/themes/screenshots/frost.png
Binary files differ
diff --git a/extras/html/themes/screenshots/future.png b/extras/html/themes/screenshots/future.png
new file mode 100644
index 0000000..4df4e62
--- /dev/null
+++ b/extras/html/themes/screenshots/future.png
Binary files differ
diff --git a/extras/html/themes/screenshots/gentle_glacier.png b/extras/html/themes/screenshots/gentle_glacier.png
new file mode 100644
index 0000000..d00df6a
--- /dev/null
+++ b/extras/html/themes/screenshots/gentle_glacier.png
Binary files differ
diff --git a/extras/html/themes/screenshots/jade.png b/extras/html/themes/screenshots/jade.png
new file mode 100644
index 0000000..3db35f7
--- /dev/null
+++ b/extras/html/themes/screenshots/jade.png
Binary files differ
diff --git a/extras/html/themes/screenshots/lavender.png b/extras/html/themes/screenshots/lavender.png
new file mode 100644
index 0000000..f284e1c
--- /dev/null
+++ b/extras/html/themes/screenshots/lavender.png
Binary files differ
diff --git a/extras/html/themes/screenshots/maroon.png b/extras/html/themes/screenshots/maroon.png
new file mode 100644
index 0000000..54c24af
--- /dev/null
+++ b/extras/html/themes/screenshots/maroon.png
Binary files differ
diff --git a/extras/html/themes/screenshots/meadow.png b/extras/html/themes/screenshots/meadow.png
new file mode 100644
index 0000000..57715db
--- /dev/null
+++ b/extras/html/themes/screenshots/meadow.png
Binary files differ
diff --git a/extras/html/themes/screenshots/midnight.png b/extras/html/themes/screenshots/midnight.png
new file mode 100644
index 0000000..9796232
--- /dev/null
+++ b/extras/html/themes/screenshots/midnight.png
Binary files differ
diff --git a/extras/html/themes/screenshots/minimal.png b/extras/html/themes/screenshots/minimal.png
new file mode 100644
index 0000000..afd2a6c
--- /dev/null
+++ b/extras/html/themes/screenshots/minimal.png
Binary files differ
diff --git a/extras/html/themes/screenshots/modern_rhythm.png b/extras/html/themes/screenshots/modern_rhythm.png
new file mode 100644
index 0000000..fdc9c0f
--- /dev/null
+++ b/extras/html/themes/screenshots/modern_rhythm.png
Binary files differ
diff --git a/extras/html/themes/screenshots/modern_storm.png b/extras/html/themes/screenshots/modern_storm.png
new file mode 100644
index 0000000..9c80b28
--- /dev/null
+++ b/extras/html/themes/screenshots/modern_storm.png
Binary files differ
diff --git a/extras/html/themes/screenshots/mono.png b/extras/html/themes/screenshots/mono.png
new file mode 100644
index 0000000..951bd01
--- /dev/null
+++ b/extras/html/themes/screenshots/mono.png
Binary files differ
diff --git a/extras/html/themes/screenshots/moonlight.png b/extras/html/themes/screenshots/moonlight.png
new file mode 100644
index 0000000..9bc1612
--- /dev/null
+++ b/extras/html/themes/screenshots/moonlight.png
Binary files differ
diff --git a/extras/html/themes/screenshots/moss.png b/extras/html/themes/screenshots/moss.png
new file mode 100644
index 0000000..6f991ac
--- /dev/null
+++ b/extras/html/themes/screenshots/moss.png
Binary files differ
diff --git a/extras/html/themes/screenshots/muted_oasis.png b/extras/html/themes/screenshots/muted_oasis.png
new file mode 100644
index 0000000..f8ac28b
--- /dev/null
+++ b/extras/html/themes/screenshots/muted_oasis.png
Binary files differ
diff --git a/extras/html/themes/screenshots/mystic_canyon.png b/extras/html/themes/screenshots/mystic_canyon.png
new file mode 100644
index 0000000..3166b63
--- /dev/null
+++ b/extras/html/themes/screenshots/mystic_canyon.png
Binary files differ
diff --git a/extras/html/themes/screenshots/mystic_meadow.png b/extras/html/themes/screenshots/mystic_meadow.png
new file mode 100644
index 0000000..744caef
--- /dev/null
+++ b/extras/html/themes/screenshots/mystic_meadow.png
Binary files differ
diff --git a/extras/html/themes/screenshots/neon_storm.png b/extras/html/themes/screenshots/neon_storm.png
new file mode 100644
index 0000000..0f64686
--- /dev/null
+++ b/extras/html/themes/screenshots/neon_storm.png
Binary files differ
diff --git a/extras/html/themes/screenshots/noir.png b/extras/html/themes/screenshots/noir.png
new file mode 100644
index 0000000..6da1d06
--- /dev/null
+++ b/extras/html/themes/screenshots/noir.png
Binary files differ
diff --git a/extras/html/themes/screenshots/nordic.png b/extras/html/themes/screenshots/nordic.png
new file mode 100644
index 0000000..b3e881f
--- /dev/null
+++ b/extras/html/themes/screenshots/nordic.png
Binary files differ
diff --git a/extras/html/themes/screenshots/obsidian.png b/extras/html/themes/screenshots/obsidian.png
new file mode 100644
index 0000000..9c2c83a
--- /dev/null
+++ b/extras/html/themes/screenshots/obsidian.png
Binary files differ
diff --git a/extras/html/themes/screenshots/ocean.png b/extras/html/themes/screenshots/ocean.png
new file mode 100644
index 0000000..051ec65
--- /dev/null
+++ b/extras/html/themes/screenshots/ocean.png
Binary files differ
diff --git a/extras/html/themes/screenshots/onyx.png b/extras/html/themes/screenshots/onyx.png
new file mode 100644
index 0000000..84d6fa0
--- /dev/null
+++ b/extras/html/themes/screenshots/onyx.png
Binary files differ
diff --git a/extras/html/themes/screenshots/pastel_canyon.png b/extras/html/themes/screenshots/pastel_canyon.png
new file mode 100644
index 0000000..102ec94
--- /dev/null
+++ b/extras/html/themes/screenshots/pastel_canyon.png
Binary files differ
diff --git a/extras/html/themes/screenshots/pastel_crystal.png b/extras/html/themes/screenshots/pastel_crystal.png
new file mode 100644
index 0000000..feffbfd
--- /dev/null
+++ b/extras/html/themes/screenshots/pastel_crystal.png
Binary files differ
diff --git a/extras/html/themes/screenshots/periwinkle.png b/extras/html/themes/screenshots/periwinkle.png
new file mode 100644
index 0000000..88ba55d
--- /dev/null
+++ b/extras/html/themes/screenshots/periwinkle.png
Binary files differ
diff --git a/extras/html/themes/screenshots/pine.png b/extras/html/themes/screenshots/pine.png
new file mode 100644
index 0000000..7c24d8c
--- /dev/null
+++ b/extras/html/themes/screenshots/pine.png
Binary files differ
diff --git a/extras/html/themes/screenshots/pure.png b/extras/html/themes/screenshots/pure.png
new file mode 100644
index 0000000..88c8296
--- /dev/null
+++ b/extras/html/themes/screenshots/pure.png
Binary files differ
diff --git a/extras/html/themes/screenshots/pure_storm.png b/extras/html/themes/screenshots/pure_storm.png
new file mode 100644
index 0000000..31781aa
--- /dev/null
+++ b/extras/html/themes/screenshots/pure_storm.png
Binary files differ
diff --git a/extras/html/themes/screenshots/pure_voyage.png b/extras/html/themes/screenshots/pure_voyage.png
new file mode 100644
index 0000000..29d6cb6
--- /dev/null
+++ b/extras/html/themes/screenshots/pure_voyage.png
Binary files differ
diff --git a/extras/html/themes/screenshots/quartz.png b/extras/html/themes/screenshots/quartz.png
new file mode 100644
index 0000000..2065c53
--- /dev/null
+++ b/extras/html/themes/screenshots/quartz.png
Binary files differ
diff --git a/extras/html/themes/screenshots/radiant_voyage.png b/extras/html/themes/screenshots/radiant_voyage.png
new file mode 100644
index 0000000..f2c3963
--- /dev/null
+++ b/extras/html/themes/screenshots/radiant_voyage.png
Binary files differ
diff --git a/extras/html/themes/screenshots/raven.png b/extras/html/themes/screenshots/raven.png
new file mode 100644
index 0000000..b5721d2
--- /dev/null
+++ b/extras/html/themes/screenshots/raven.png
Binary files differ
diff --git a/extras/html/themes/screenshots/refined_aurora.png b/extras/html/themes/screenshots/refined_aurora.png
new file mode 100644
index 0000000..cdfda3d
--- /dev/null
+++ b/extras/html/themes/screenshots/refined_aurora.png
Binary files differ
diff --git a/extras/html/themes/screenshots/refined_oasis.png b/extras/html/themes/screenshots/refined_oasis.png
new file mode 100644
index 0000000..0e6ea9f
--- /dev/null
+++ b/extras/html/themes/screenshots/refined_oasis.png
Binary files differ
diff --git a/extras/html/themes/screenshots/retrosimple.png b/extras/html/themes/screenshots/retrosimple.png
new file mode 100644
index 0000000..aabd9e7
--- /dev/null
+++ b/extras/html/themes/screenshots/retrosimple.png
Binary files differ
diff --git a/extras/html/themes/screenshots/rosegold.png b/extras/html/themes/screenshots/rosegold.png
new file mode 100644
index 0000000..e5d5064
--- /dev/null
+++ b/extras/html/themes/screenshots/rosegold.png
Binary files differ
diff --git a/extras/html/themes/screenshots/sage.png b/extras/html/themes/screenshots/sage.png
new file mode 100644
index 0000000..3ce57f5
--- /dev/null
+++ b/extras/html/themes/screenshots/sage.png
Binary files differ
diff --git a/extras/html/themes/screenshots/sandstone.png b/extras/html/themes/screenshots/sandstone.png
new file mode 100644
index 0000000..7d3224e
--- /dev/null
+++ b/extras/html/themes/screenshots/sandstone.png
Binary files differ
diff --git a/extras/html/themes/screenshots/sapphire.png b/extras/html/themes/screenshots/sapphire.png
new file mode 100644
index 0000000..71d4d9f
--- /dev/null
+++ b/extras/html/themes/screenshots/sapphire.png
Binary files differ
diff --git a/extras/html/themes/screenshots/shadow.png b/extras/html/themes/screenshots/shadow.png
new file mode 100644
index 0000000..728fa3d
--- /dev/null
+++ b/extras/html/themes/screenshots/shadow.png
Binary files differ
diff --git a/extras/html/themes/screenshots/sharp_canyon.png b/extras/html/themes/screenshots/sharp_canyon.png
new file mode 100644
index 0000000..4b08122
--- /dev/null
+++ b/extras/html/themes/screenshots/sharp_canyon.png
Binary files differ
diff --git a/extras/html/themes/screenshots/sharp_mountain.png b/extras/html/themes/screenshots/sharp_mountain.png
new file mode 100644
index 0000000..7443b3a
--- /dev/null
+++ b/extras/html/themes/screenshots/sharp_mountain.png
Binary files differ
diff --git a/extras/html/themes/screenshots/simple.png b/extras/html/themes/screenshots/simple.png
new file mode 100644
index 0000000..f98446f
--- /dev/null
+++ b/extras/html/themes/screenshots/simple.png
Binary files differ
diff --git a/extras/html/themes/screenshots/slate.png b/extras/html/themes/screenshots/slate.png
new file mode 100644
index 0000000..7eb0eb2
--- /dev/null
+++ b/extras/html/themes/screenshots/slate.png
Binary files differ
diff --git a/extras/html/themes/screenshots/sleek_river.png b/extras/html/themes/screenshots/sleek_river.png
new file mode 100644
index 0000000..6abe47e
--- /dev/null
+++ b/extras/html/themes/screenshots/sleek_river.png
Binary files differ
diff --git a/extras/html/themes/screenshots/smooth_echo.png b/extras/html/themes/screenshots/smooth_echo.png
new file mode 100644
index 0000000..20a8e9c
--- /dev/null
+++ b/extras/html/themes/screenshots/smooth_echo.png
Binary files differ
diff --git a/extras/html/themes/screenshots/soft_horizon.png b/extras/html/themes/screenshots/soft_horizon.png
new file mode 100644
index 0000000..843af05
--- /dev/null
+++ b/extras/html/themes/screenshots/soft_horizon.png
Binary files differ
diff --git a/extras/html/themes/screenshots/stark.png b/extras/html/themes/screenshots/stark.png
new file mode 100644
index 0000000..457bb71
--- /dev/null
+++ b/extras/html/themes/screenshots/stark.png
Binary files differ
diff --git a/extras/html/themes/screenshots/strong_breeze.png b/extras/html/themes/screenshots/strong_breeze.png
new file mode 100644
index 0000000..bb09d1e
--- /dev/null
+++ b/extras/html/themes/screenshots/strong_breeze.png
Binary files differ
diff --git a/extras/html/themes/screenshots/sunset.png b/extras/html/themes/screenshots/sunset.png
new file mode 100644
index 0000000..dbc6c04
--- /dev/null
+++ b/extras/html/themes/screenshots/sunset.png
Binary files differ
diff --git a/extras/html/themes/screenshots/teal.png b/extras/html/themes/screenshots/teal.png
new file mode 100644
index 0000000..fa1324a
--- /dev/null
+++ b/extras/html/themes/screenshots/teal.png
Binary files differ
diff --git a/extras/html/themes/screenshots/terracotta.png b/extras/html/themes/screenshots/terracotta.png
new file mode 100644
index 0000000..d90d6a0
--- /dev/null
+++ b/extras/html/themes/screenshots/terracotta.png
Binary files differ
diff --git a/extras/html/themes/screenshots/titanium.png b/extras/html/themes/screenshots/titanium.png
new file mode 100644
index 0000000..a3b98b6
--- /dev/null
+++ b/extras/html/themes/screenshots/titanium.png
Binary files differ
diff --git a/extras/html/themes/screenshots/twilight_horizon.png b/extras/html/themes/screenshots/twilight_horizon.png
new file mode 100644
index 0000000..cd00dc3
--- /dev/null
+++ b/extras/html/themes/screenshots/twilight_horizon.png
Binary files differ
diff --git a/extras/html/themes/screenshots/twilight_meadow.png b/extras/html/themes/screenshots/twilight_meadow.png
new file mode 100644
index 0000000..545f7dc
--- /dev/null
+++ b/extras/html/themes/screenshots/twilight_meadow.png
Binary files differ
diff --git a/extras/html/themes/screenshots/twilight_nebula.png b/extras/html/themes/screenshots/twilight_nebula.png
new file mode 100644
index 0000000..8e456de
--- /dev/null
+++ b/extras/html/themes/screenshots/twilight_nebula.png
Binary files differ
diff --git a/extras/html/themes/screenshots/vibrant_garden.png b/extras/html/themes/screenshots/vibrant_garden.png
new file mode 100644
index 0000000..b4f39c4
--- /dev/null
+++ b/extras/html/themes/screenshots/vibrant_garden.png
Binary files differ
diff --git a/extras/html/themes/screenshots/vibrant_nebula.png b/extras/html/themes/screenshots/vibrant_nebula.png
new file mode 100644
index 0000000..7e2e472
--- /dev/null
+++ b/extras/html/themes/screenshots/vibrant_nebula.png
Binary files differ
diff --git a/extras/html/themes/screenshots/vibrant_storm.png b/extras/html/themes/screenshots/vibrant_storm.png
new file mode 100644
index 0000000..38ef359
--- /dev/null
+++ b/extras/html/themes/screenshots/vibrant_storm.png
Binary files differ
diff --git a/extras/html/themes/screenshots/willow.png b/extras/html/themes/screenshots/willow.png
new file mode 100644
index 0000000..4686e28
--- /dev/null
+++ b/extras/html/themes/screenshots/willow.png
Binary files differ
diff --git a/extras/html/themes/screenshots/zen.png b/extras/html/themes/screenshots/zen.png
new file mode 100644
index 0000000..4b650e2
--- /dev/null
+++ b/extras/html/themes/screenshots/zen.png
Binary files differ
diff --git a/extras/html/themes/sharp_canyon/LICENSE b/extras/html/themes/sharp_canyon/LICENSE
new file mode 100644
index 0000000..2c8e62a
--- /dev/null
+++ b/extras/html/themes/sharp_canyon/LICENSE
@@ -0,0 +1,21 @@
+Theme: sharp_canyon
+Generated: 2025-06-22 21:38:55
+
+Layout: retro
+Color Scheme: monochromatic (Dark)
+
+Font Licenses:
+==============
+Heading Font: roboto-slab
+License: Apache
+Category: serif
+
+Body Font: oxygen
+License: OFL
+Category: sans-serif
+
+Code Font: intelone-mono
+License: OFL
+Category: monospace
+
+All fonts are free for personal use.
diff --git a/extras/html/themes/sharp_canyon/code.ttf b/extras/html/themes/sharp_canyon/code.ttf
new file mode 100644
index 0000000..2711179
--- /dev/null
+++ b/extras/html/themes/sharp_canyon/code.ttf
Binary files differ
diff --git a/extras/html/themes/sharp_canyon/example.html b/extras/html/themes/sharp_canyon/example.html
new file mode 100644
index 0000000..35d7f13
--- /dev/null
+++ b/extras/html/themes/sharp_canyon/example.html
@@ -0,0 +1,75 @@
+<!DOCTYPE html>
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
+<head>
+ <meta charset="UTF-8" />
+ <meta name="viewport" content="width=device-width, initial-scale=1.0" />
+ <title>Sharp Canyon - Gemtexter Theme</title>
+ <link rel="stylesheet" href="style.css" />
+</head>
+<body>
+ <div class="header">
+ <h1>Sharp Canyon</h1>
+ <p>A retro layout with monochromatic colors</p>
+ </div>
+
+ <div class="content">
+ <h1>Welcome to Sharp Canyon</h1>
+ <p>This theme features a carefully crafted retro layout with a dark monochromatic color scheme. The typography combines serif fonts for headings with sans-serif for body text.</p>
+
+ <h2>Typography Showcase</h2>
+ <p>The oxygen font family provides excellent readability for body text, while roboto-slab adds character to headings. Code blocks use intelone-mono for clarity.</p>
+
+ <h2>Color Palette</h2>
+ <p>Primary: <span style="color: #b98f33; font-weight: bold;">#b98f33</span> |
+ Secondary: <span style="color: #78602d; font-weight: bold;">#78602d</span> |
+ Accent: <span style="color: #b49c67; font-weight: bold;">#b49c67</span></p>
+
+ <h3>Interactive Elements</h3>
+ <p>Links like <a href="#">this example</a> and longer <a href="#" class="textlink">text links that demonstrate the theme's navigation style</a> use the secondary color.</p>
+
+ <div class="quote">
+ "Design is not just what it looks like and feels like. Design is how it works." — Steve Jobs
+ </div>
+
+ <h3>Code Examples</h3>
+ <p>Inline code like <code>theme.generate()</code> and larger blocks:</p>
+ <pre>// Theme configuration
+const theme = {
+ name: "sharp_canyon",
+ layout: "retro",
+ colors: {
+ primary: "#b98f33",
+ secondary: "#78602d",
+ accent: "#b49c67"
+ },
+ fonts: {
+ heading: "roboto-slab",
+ body: "oxygen",
+ code: "intelone-mono"
+ }
+};</pre>
+
+ <h2>Content Structure</h2>
+ <ul>
+ <li>Clean, readable typography with 16px base font size</li>
+ <li>Heading scale ratio of 2.37x for visual hierarchy</li>
+ <li>Line height of 1.46 for comfortable reading</li>
+ <li>Retro layout optimized for content flow</li>
+ <li>Dark theme with monochromatic color harmony</li>
+ </ul>
+
+ <h2>Font Licensing</h2>
+ <p>All fonts used in this theme are properly licensed:</p>
+ <ul>
+ <li>roboto-slab: Apache License</li>
+ <li>oxygen: OFL License</li>
+ <li>intelone-mono: OFL License</li>
+ </ul>
+
+ <h3>Final Thoughts</h3>
+ <p>Every element of this theme has been carefully designed to create a harmonious reading experience. The retro layout ensures content is presented in an engaging way, while the color scheme provides the perfect backdrop for your words to shine.</p>
+
+ <p>Whether you're writing technical documentation, creative prose, or anything in between, this theme adapts to showcase your content beautifully.</p>
+ </div>
+</body>
+</html> \ No newline at end of file
diff --git a/extras/html/themes/sharp_canyon/handnotes.ttf b/extras/html/themes/sharp_canyon/handnotes.ttf
new file mode 100644
index 0000000..25e688b
--- /dev/null
+++ b/extras/html/themes/sharp_canyon/handnotes.ttf
Binary files differ
diff --git a/extras/html/themes/sharp_canyon/style.css b/extras/html/themes/sharp_canyon/style.css
new file mode 100644
index 0000000..beac592
--- /dev/null
+++ b/extras/html/themes/sharp_canyon/style.css
@@ -0,0 +1,205 @@
+/* Base styles */
+@font-face {
+ font-family: 'text';
+ src: url("./text.ttf") format("truetype");
+}
+
+@font-face {
+ font-family: 'heading';
+ src: url("./heading.ttf") format("truetype");
+}
+
+@font-face {
+ font-family: 'code';
+ src: url("./code.ttf") format("truetype");
+}
+
+@font-face {
+ font-family: 'handnotes';
+ src: url("./handnotes.ttf") format("truetype");
+}
+
+:root {
+ --color-primary: #b98f33;
+ --color-secondary: #78602d;
+ --color-accent: #b49c67;
+ --color-bg: #211f1b;
+ --color-text: #e1e1e1;
+ --font-size-base: 16px;
+ --font-size-h1: 2.37em;
+ --font-size-h2: 1.78em;
+ --font-size-h3: 1.33em;
+ --line-height: 1.46;
+}
+
+* {
+ box-sizing: border-box;
+}
+
+html {
+ font-size: var(--font-size-base);
+ -webkit-font-smoothing: antialiased;
+ -moz-osx-font-smoothing: grayscale;
+}
+
+body {
+ font-family: text, sans-serif;
+ background-color: var(--color-bg);
+ color: var(--color-text);
+ line-height: var(--line-height);
+ margin: 0;
+ padding: 0;
+ overflow-wrap: break-word;
+}
+
+h1, h2, h3 {
+ font-family: heading, serif;
+ line-height: 1.2;
+ margin-top: 1em;
+ margin-bottom: 0.5em;
+}
+
+h1 {
+ font-size: var(--font-size-h1);
+ color: var(--color-primary);
+}
+
+h2 {
+ font-size: var(--font-size-h2);
+ color: var(--color-primary);
+}
+
+h3 {
+ font-size: var(--font-size-h3);
+ color: var(--color-secondary);
+}
+
+a {
+ font-family: code, monospace;
+ color: var(--color-secondary);
+ text-decoration: none;
+ transition: all 0.3s ease;
+}
+
+a:hover {
+ color: var(--color-accent);
+ text-decoration: underline;
+}
+
+.textlink {
+ font-family: text, sans-serif;
+}
+
+.quote {
+ font-family: handnotes, cursive;
+ border-left: 4px solid var(--color-accent);
+ padding: 1em 1.5em;
+ margin: 1.5em 0;
+ background-color: rgba(185, 143, 51, 0.07);
+ font-style: italic;
+}
+
+pre {
+ font-family: code, monospace;
+ background-color: rgba(225, 225, 225, 0.04);
+ border: 1px solid rgba(225, 225, 225, 0.13);
+ padding: 1em;
+ overflow-x: auto;
+ border-radius: 4px;
+ font-size: 0.9em;
+}
+
+code {
+ font-family: code, monospace;
+ background-color: rgba(225, 225, 225, 0.04);
+ padding: 0.2em 0.4em;
+ border-radius: 3px;
+ font-size: 0.9em;
+}
+
+ul, ol {
+ padding-left: 2em;
+ margin: 1em 0;
+}
+
+li {
+ margin: 0.5em 0;
+}
+
+img {
+ max-width: 100%;
+ height: auto;
+}
+
+hr {
+ border: none;
+ border-top: 1px solid rgba(225, 225, 225, 0.20);
+ margin: 2em 0;
+}
+
+
+/* Layout: retro */
+
+@import url("https://fonts.googleapis.com/css2?family=Courier+Prime:wght@400;700&display=swap");
+
+body {
+ background-color: #f4e8d0;
+ color: #2a2a2a;
+ padding: 2em;
+ position: relative;
+}
+
+body::before {
+ content: "";
+ position: fixed;
+ top: 0;
+ left: 0;
+ right: 0;
+ bottom: 0;
+ background-image: repeating-linear-gradient( 0deg, transparent, transparent 2px, rgba(0,0,0,0.03) 2px, rgba(0,0,0,0.03) 4px );
+ pointer-events: none;
+ z-index: 1;
+}
+
+.header {
+ background-color: #b98f33;
+ color: #f4e8d0;
+ padding: 2em;
+ margin: -2em -2em 2em -2em;
+ text-align: center;
+ box-shadow: 0 4px 8px rgba(0,0,0,0.3);
+ position: relative;
+ z-index: 2;
+}
+
+.header h1 {
+ font-family: 'Courier Prime', monospace;
+ font-size: 3em;
+ margin: 0;
+ text-transform: uppercase;
+ letter-spacing: 0.1em;
+ color: #f4e8d0;
+}
+
+h1, h2, h3 {
+ font-family: 'Courier Prime', monospace;
+ text-transform: uppercase;
+ letter-spacing: 0.05em;
+ position: relative;
+ z-index: 2;
+}
+
+p, ul, pre, .quote {
+ background-color: rgba(255,255,255,0.8);
+ padding: 1.5em;
+ margin: 1em 0;
+ box-shadow: 2px 2px 4px rgba(0,0,0,0.1);
+ position: relative;
+ z-index: 2;
+}
+
+a {
+ color: #78602d;
+ text-decoration: underline;
+ text-decoration-style: wavy;
+}
diff --git a/extras/html/themes/sharp_canyon/theme.conf b/extras/html/themes/sharp_canyon/theme.conf
new file mode 100644
index 0000000..19a2553
--- /dev/null
+++ b/extras/html/themes/sharp_canyon/theme.conf
@@ -0,0 +1,8 @@
+declare -xr HTML_HEADER=./extras/html/header.html.part
+declare -xr HTML_FOOTER=./extras/html/footer.html.part
+declare -xr HTML_CSS_STYLE=$HTML_THEME_DIR/style.css
+declare -xr HTML_WEBFONT_HEADING=./extras/html/fonts/roboto-slab/roboto-slab-Bold.ttf
+declare -xr HTML_WEBFONT_TEXT=./extras/html/fonts/oxygen/oxygen-Regular.ttf
+declare -xr HTML_WEBFONT_CODE=./extras/html/fonts/intelone-mono/intelone-mono-Regular.ttf
+declare -xr HTML_WEBFONT_HANDNOTES=./extras/html/fonts/khand/khand.ttf
+declare -xr SOURCE_HIGHLIGHT_CSS=./extras/html/source-highlight-styles/mono.css
diff --git a/extras/html/themes/sharp_mountain/LICENSE b/extras/html/themes/sharp_mountain/LICENSE
new file mode 100644
index 0000000..4d8b061
--- /dev/null
+++ b/extras/html/themes/sharp_mountain/LICENSE
@@ -0,0 +1,21 @@
+Theme: sharp_mountain
+Generated: 2025-06-22 21:38:55
+
+Layout: centered
+Color Scheme: complementary (Light)
+
+Font Licenses:
+==============
+Heading Font: roboto-slab
+License: Apache
+Category: serif
+
+Body Font: Lato
+License: OFL
+Category: sans-serif
+
+Code Font: consola-mono
+License: OFL
+Category: monospace
+
+All fonts are free for personal use.
diff --git a/extras/html/themes/sharp_mountain/code.ttf b/extras/html/themes/sharp_mountain/code.ttf
new file mode 100644
index 0000000..78ca9da
--- /dev/null
+++ b/extras/html/themes/sharp_mountain/code.ttf
Binary files differ
diff --git a/extras/html/themes/sharp_mountain/example.html b/extras/html/themes/sharp_mountain/example.html
new file mode 100644
index 0000000..7b2ce42
--- /dev/null
+++ b/extras/html/themes/sharp_mountain/example.html
@@ -0,0 +1,75 @@
+<!DOCTYPE html>
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
+<head>
+ <meta charset="UTF-8" />
+ <meta name="viewport" content="width=device-width, initial-scale=1.0" />
+ <title>Sharp Mountain - Gemtexter Theme</title>
+ <link rel="stylesheet" href="style.css" />
+</head>
+<body>
+ <div class="header">
+ <h1>Sharp Mountain</h1>
+ <p>A centered layout with complementary colors</p>
+ </div>
+
+ <div class="content">
+ <h1>Welcome to Sharp Mountain</h1>
+ <p>This theme features a carefully crafted centered layout with a light complementary color scheme. The typography combines serif fonts for headings with sans-serif for body text.</p>
+
+ <h2>Typography Showcase</h2>
+ <p>The Lato font family provides excellent readability for body text, while roboto-slab adds character to headings. Code blocks use consola-mono for clarity.</p>
+
+ <h2>Color Palette</h2>
+ <p>Primary: <span style="color: #71294a; font-weight: bold;">#71294a</span> |
+ Secondary: <span style="color: #306a4f; font-weight: bold;">#306a4f</span> |
+ Accent: <span style="color: #4f2c3c; font-weight: bold;">#4f2c3c</span></p>
+
+ <h3>Interactive Elements</h3>
+ <p>Links like <a href="#">this example</a> and longer <a href="#" class="textlink">text links that demonstrate the theme's navigation style</a> use the secondary color.</p>
+
+ <div class="quote">
+ "Design is not just what it looks like and feels like. Design is how it works." — Steve Jobs
+ </div>
+
+ <h3>Code Examples</h3>
+ <p>Inline code like <code>theme.generate()</code> and larger blocks:</p>
+ <pre>// Theme configuration
+const theme = {
+ name: "sharp_mountain",
+ layout: "centered",
+ colors: {
+ primary: "#71294a",
+ secondary: "#306a4f",
+ accent: "#4f2c3c"
+ },
+ fonts: {
+ heading: "roboto-slab",
+ body: "Lato",
+ code: "consola-mono"
+ }
+};</pre>
+
+ <h2>Content Structure</h2>
+ <ul>
+ <li>Clean, readable typography with 18px base font size</li>
+ <li>Heading scale ratio of 3.38x for visual hierarchy</li>
+ <li>Line height of 1.57 for comfortable reading</li>
+ <li>Centered layout optimized for content flow</li>
+ <li>Light theme with complementary color harmony</li>
+ </ul>
+
+ <h2>Font Licensing</h2>
+ <p>All fonts used in this theme are properly licensed:</p>
+ <ul>
+ <li>roboto-slab: Apache License</li>
+ <li>Lato: OFL License</li>
+ <li>consola-mono: OFL License</li>
+ </ul>
+
+ <h3>Final Thoughts</h3>
+ <p>Every element of this theme has been carefully designed to create a harmonious reading experience. The centered layout ensures content is presented in an engaging way, while the color scheme provides the perfect backdrop for your words to shine.</p>
+
+ <p>Whether you're writing technical documentation, creative prose, or anything in between, this theme adapts to showcase your content beautifully.</p>
+ </div>
+</body>
+</html> \ No newline at end of file
diff --git a/extras/html/themes/sharp_mountain/handnotes.ttf b/extras/html/themes/sharp_mountain/handnotes.ttf
new file mode 100644
index 0000000..25e688b
--- /dev/null
+++ b/extras/html/themes/sharp_mountain/handnotes.ttf
Binary files differ
diff --git a/extras/html/themes/sharp_mountain/style.css b/extras/html/themes/sharp_mountain/style.css
new file mode 100644
index 0000000..95b1c46
--- /dev/null
+++ b/extras/html/themes/sharp_mountain/style.css
@@ -0,0 +1,154 @@
+/* Base styles */
+@font-face {
+ font-family: 'text';
+ src: url("./text.ttf") format("truetype");
+}
+
+@font-face {
+ font-family: 'heading';
+ src: url("./heading.ttf") format("truetype");
+}
+
+@font-face {
+ font-family: 'code';
+ src: url("./code.ttf") format("truetype");
+}
+
+@font-face {
+ font-family: 'handnotes';
+ src: url("./handnotes.ttf") format("truetype");
+}
+
+:root {
+ --color-primary: #71294a;
+ --color-secondary: #306a4f;
+ --color-accent: #4f2c3c;
+ --color-bg: #f3f0f1;
+ --color-text: #1b1b1b;
+ --font-size-base: 18px;
+ --font-size-h1: 3.38em;
+ --font-size-h2: 2.25em;
+ --font-size-h3: 1.5em;
+ --line-height: 1.57;
+}
+
+* {
+ box-sizing: border-box;
+}
+
+html {
+ font-size: var(--font-size-base);
+ -webkit-font-smoothing: antialiased;
+ -moz-osx-font-smoothing: grayscale;
+}
+
+body {
+ font-family: text, sans-serif;
+ background-color: var(--color-bg);
+ color: var(--color-text);
+ line-height: var(--line-height);
+ margin: 0;
+ padding: 0;
+ overflow-wrap: break-word;
+}
+
+h1, h2, h3 {
+ font-family: heading, serif;
+ line-height: 1.2;
+ margin-top: 1em;
+ margin-bottom: 0.5em;
+}
+
+h1 {
+ font-size: var(--font-size-h1);
+ color: var(--color-primary);
+}
+
+h2 {
+ font-size: var(--font-size-h2);
+ color: var(--color-primary);
+}
+
+h3 {
+ font-size: var(--font-size-h3);
+ color: var(--color-secondary);
+}
+
+a {
+ font-family: code, monospace;
+ color: var(--color-secondary);
+ text-decoration: none;
+ transition: all 0.3s ease;
+}
+
+a:hover {
+ color: var(--color-accent);
+ text-decoration: underline;
+}
+
+.textlink {
+ font-family: text, sans-serif;
+}
+
+.quote {
+ font-family: handnotes, cursive;
+ border-left: 4px solid var(--color-accent);
+ padding: 1em 1.5em;
+ margin: 1.5em 0;
+ background-color: rgba(113, 41, 74, 0.07);
+ font-style: italic;
+}
+
+pre {
+ font-family: code, monospace;
+ background-color: rgba(27, 27, 27, 0.04);
+ border: 1px solid rgba(27, 27, 27, 0.13);
+ padding: 1em;
+ overflow-x: auto;
+ border-radius: 4px;
+ font-size: 0.9em;
+}
+
+code {
+ font-family: code, monospace;
+ background-color: rgba(27, 27, 27, 0.04);
+ padding: 0.2em 0.4em;
+ border-radius: 3px;
+ font-size: 0.9em;
+}
+
+ul, ol {
+ padding-left: 2em;
+ margin: 1em 0;
+}
+
+li {
+ margin: 0.5em 0;
+}
+
+img {
+ max-width: 100%;
+ height: auto;
+}
+
+hr {
+ border: none;
+ border-top: 1px solid rgba(27, 27, 27, 0.20);
+ margin: 2em 0;
+}
+
+
+/* Layout: centered */
+
+body {
+ max-width: 65ch;
+ margin: 0 auto;
+ padding: 2em 1em;
+}
+
+.header {
+ text-align: center;
+ margin-bottom: 3em;
+ padding-bottom: 2em;
+ border-bottom: 2px solid var(--color-primary);
+}
diff --git a/extras/html/themes/sharp_mountain/text.ttf b/extras/html/themes/sharp_mountain/text.ttf
new file mode 100644
index 0000000..bb2e887
--- /dev/null
+++ b/extras/html/themes/sharp_mountain/text.ttf
Binary files differ
diff --git a/extras/html/themes/sharp_mountain/theme.conf b/extras/html/themes/sharp_mountain/theme.conf
new file mode 100644
index 0000000..2d8b422
--- /dev/null
+++ b/extras/html/themes/sharp_mountain/theme.conf
@@ -0,0 +1,8 @@
+declare -xr HTML_HEADER=./extras/html/header.html.part
+declare -xr HTML_FOOTER=./extras/html/footer.html.part
+declare -xr HTML_CSS_STYLE=$HTML_THEME_DIR/style.css
+declare -xr HTML_WEBFONT_HEADING=./extras/html/fonts/roboto-slab/roboto-slab-Bold.ttf
+declare -xr HTML_WEBFONT_TEXT=./extras/html/fonts/Lato/Lato-Regular.ttf
+declare -xr HTML_WEBFONT_CODE=./extras/html/fonts/consola-mono/consola-mono-Regular.ttf
+declare -xr HTML_WEBFONT_HANDNOTES=./extras/html/fonts/khand/khand.ttf
+declare -xr SOURCE_HIGHLIGHT_CSS=./extras/html/source-highlight-styles/mono.css
diff --git a/extras/html/themes/simple/style.css b/extras/html/themes/simple/style.css
index 49bfd75..5ba53ce 100644
--- a/extras/html/themes/simple/style.css
+++ b/extras/html/themes/simple/style.css
@@ -1,7 +1,7 @@
body {
font-family: sans-serif;
max-width: 1024px;
- word-wrap: break-word;
+ overflow-wrap: break-word;
}
a {
diff --git a/extras/html/themes/sleek_river/LICENSE b/extras/html/themes/sleek_river/LICENSE
new file mode 100644
index 0000000..0c16d06
--- /dev/null
+++ b/extras/html/themes/sleek_river/LICENSE
@@ -0,0 +1,21 @@
+Theme: sleek_river
+Generated: 2025-06-22 21:38:55
+
+Layout: geometric
+Color Scheme: analogous (Light)
+
+Font Licenses:
+==============
+Heading Font: zai-aeg-mignon-typewriter-1924
+License: Free
+Category: display
+
+Body Font: roboto-slab
+License: Apache
+Category: serif
+
+Code Font: hack
+License: MIT
+Category: monospace
+
+All fonts are free for personal use.
diff --git a/extras/html/themes/sleek_river/code.ttf b/extras/html/themes/sleek_river/code.ttf
new file mode 100644
index 0000000..7c8e65b
--- /dev/null
+++ b/extras/html/themes/sleek_river/code.ttf
Binary files differ
diff --git a/extras/html/themes/sleek_river/example.html b/extras/html/themes/sleek_river/example.html
new file mode 100644
index 0000000..edeef40
--- /dev/null
+++ b/extras/html/themes/sleek_river/example.html
@@ -0,0 +1,75 @@
+<!DOCTYPE html>
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
+<head>
+ <meta charset="UTF-8" />
+ <meta name="viewport" content="width=device-width, initial-scale=1.0" />
+ <title>Sleek River - Gemtexter Theme</title>
+ <link rel="stylesheet" href="style.css" />
+</head>
+<body>
+ <div class="header">
+ <h1>Sleek River</h1>
+ <p>A geometric layout with analogous colors</p>
+ </div>
+
+ <div class="content">
+ <h1>Welcome to Sleek River</h1>
+ <p>This theme features a carefully crafted geometric layout with a light analogous color scheme. The typography combines display fonts for headings with serif for body text.</p>
+
+ <h2>Typography Showcase</h2>
+ <p>The roboto-slab font family provides excellent readability for body text, while zai-aeg-mignon-typewriter-1924 adds character to headings. Code blocks use hack for clarity.</p>
+
+ <h2>Color Palette</h2>
+ <p>Primary: <span style="color: #77ca90; font-weight: bold;">#77ca90</span> |
+ Secondary: <span style="color: #7bc6b6; font-weight: bold;">#7bc6b6</span> |
+ Accent: <span style="color: #70c160; font-weight: bold;">#70c160</span></p>
+
+ <h3>Interactive Elements</h3>
+ <p>Links like <a href="#">this example</a> and longer <a href="#" class="textlink">text links that demonstrate the theme's navigation style</a> use the secondary color.</p>
+
+ <div class="quote">
+ "Design is not just what it looks like and feels like. Design is how it works." — Steve Jobs
+ </div>
+
+ <h3>Code Examples</h3>
+ <p>Inline code like <code>theme.generate()</code> and larger blocks:</p>
+ <pre>// Theme configuration
+const theme = {
+ name: "sleek_river",
+ layout: "geometric",
+ colors: {
+ primary: "#77ca90",
+ secondary: "#7bc6b6",
+ accent: "#70c160"
+ },
+ fonts: {
+ heading: "zai-aeg-mignon-typewriter-1924",
+ body: "roboto-slab",
+ code: "hack"
+ }
+};</pre>
+
+ <h2>Content Structure</h2>
+ <ul>
+ <li>Clean, readable typography with 15px base font size</li>
+ <li>Heading scale ratio of 4.24x for visual hierarchy</li>
+ <li>Line height of 1.79 for comfortable reading</li>
+ <li>Geometric layout optimized for content flow</li>
+ <li>Light theme with analogous color harmony</li>
+ </ul>
+
+ <h2>Font Licensing</h2>
+ <p>All fonts used in this theme are properly licensed:</p>
+ <ul>
+ <li>zai-aeg-mignon-typewriter-1924: Free License</li>
+ <li>roboto-slab: Apache License</li>
+ <li>hack: MIT License</li>
+ </ul>
+
+ <h3>Final Thoughts</h3>
+ <p>Every element of this theme has been carefully designed to create a harmonious reading experience. The geometric layout ensures content is presented in an engaging way, while the color scheme provides the perfect backdrop for your words to shine.</p>
+
+ <p>Whether you're writing technical documentation, creative prose, or anything in between, this theme adapts to showcase your content beautifully.</p>
+ </div>
+</body>
+</html> \ No newline at end of file
diff --git a/extras/html/themes/sleek_river/handnotes.ttf b/extras/html/themes/sleek_river/handnotes.ttf
new file mode 100644
index 0000000..25e688b
--- /dev/null
+++ b/extras/html/themes/sleek_river/handnotes.ttf
Binary files differ
diff --git a/extras/html/themes/sleek_river/heading.ttf b/extras/html/themes/sleek_river/heading.ttf
new file mode 100644
index 0000000..375978c
--- /dev/null
+++ b/extras/html/themes/sleek_river/heading.ttf
Binary files differ
diff --git a/extras/html/themes/sleek_river/style.css b/extras/html/themes/sleek_river/style.css
new file mode 100644
index 0000000..5733ff5
--- /dev/null
+++ b/extras/html/themes/sleek_river/style.css
@@ -0,0 +1,193 @@
+/* Base styles */
+@font-face {
+ font-family: 'text';
+ src: url("./text.ttf") format("truetype");
+}
+
+@font-face {
+ font-family: 'heading';
+ src: url("./heading.ttf") format("truetype");
+}
+
+@font-face {
+ font-family: 'code';
+ src: url("./code.ttf") format("truetype");
+}
+
+@font-face {
+ font-family: 'handnotes';
+ src: url("./handnotes.ttf") format("truetype");
+}
+
+:root {
+ --color-primary: #77ca90;
+ --color-secondary: #7bc6b6;
+ --color-accent: #70c160;
+ --color-bg: #f8f9f8;
+ --color-text: #0d0d0d;
+ --font-size-base: 15px;
+ --font-size-h1: 4.24em;
+ --font-size-h2: 2.62em;
+ --font-size-h3: 1.62em;
+ --line-height: 1.79;
+}
+
+* {
+ box-sizing: border-box;
+}
+
+html {
+ font-size: var(--font-size-base);
+ -webkit-font-smoothing: antialiased;
+ -moz-osx-font-smoothing: grayscale;
+}
+
+body {
+ font-family: text, sans-serif;
+ background-color: var(--color-bg);
+ color: var(--color-text);
+ line-height: var(--line-height);
+ margin: 0;
+ padding: 0;
+ overflow-wrap: break-word;
+}
+
+h1, h2, h3 {
+ font-family: heading, serif;
+ line-height: 1.2;
+ margin-top: 1em;
+ margin-bottom: 0.5em;
+}
+
+h1 {
+ font-size: var(--font-size-h1);
+ color: var(--color-primary);
+}
+
+h2 {
+ font-size: var(--font-size-h2);
+ color: var(--color-primary);
+}
+
+h3 {
+ font-size: var(--font-size-h3);
+ color: var(--color-secondary);
+}
+
+a {
+ font-family: code, monospace;
+ color: var(--color-secondary);
+ text-decoration: none;
+ transition: all 0.3s ease;
+}
+
+a:hover {
+ color: var(--color-accent);
+ text-decoration: underline;
+}
+
+.textlink {
+ font-family: text, sans-serif;
+}
+
+.quote {
+ font-family: handnotes, cursive;
+ border-left: 4px solid var(--color-accent);
+ padding: 1em 1.5em;
+ margin: 1.5em 0;
+ background-color: rgba(119, 202, 144, 0.07);
+ font-style: italic;
+}
+
+pre {
+ font-family: code, monospace;
+ background-color: rgba(13, 13, 13, 0.04);
+ border: 1px solid rgba(13, 13, 13, 0.13);
+ padding: 1em;
+ overflow-x: auto;
+ border-radius: 4px;
+ font-size: 0.9em;
+}
+
+code {
+ font-family: code, monospace;
+ background-color: rgba(13, 13, 13, 0.04);
+ padding: 0.2em 0.4em;
+ border-radius: 3px;
+ font-size: 0.9em;
+}
+
+ul, ol {
+ padding-left: 2em;
+ margin: 1em 0;
+}
+
+li {
+ margin: 0.5em 0;
+}
+
+img {
+ max-width: 100%;
+ height: auto;
+}
+
+hr {
+ border: none;
+ border-top: 1px solid rgba(13, 13, 13, 0.20);
+ margin: 2em 0;
+}
+
+
+/* Layout: geometric */
+
+body {
+ padding: 2em;
+ background-color: var(--color-bg);
+ background-image: repeating-linear-gradient(45deg, rgba(119, 202, 144, 0.07) 0, rgba(119, 202, 144, 0.07) 10px, transparent 10px, transparent 20px), repeating-linear-gradient(-45deg, rgba(123, 198, 182, 0.07) 0, rgba(123, 198, 182, 0.07) 10px, transparent 10px, transparent 20px);
+}
+
+.header {
+ background-color: var(--color-bg);
+ border: 4px solid var(--color-primary);
+ padding: 3em;
+ margin-bottom: 3em;
+ position: relative;
+ clip-path: polygon(0 0, 100% 0, 95% 100%, 5% 100%);
+}
+
+h1, h2, h3 {
+ position: relative;
+ padding-left: 2em;
+}
+
+h1::before, h2::before, h3::before {
+ content: "";
+ position: absolute;
+ left: 0;
+ top: 50%;
+ transform: translateY(-50%);
+ width: 1em;
+ height: 1em;
+ background-color: var(--color-accent);
+ clip-path: polygon(50% 0%, 100% 50%, 50% 100%, 0% 50%);
+}
+
+p, ul, pre, .quote {
+ background-color: var(--color-bg);
+ padding: 2em;
+ margin: 2em 0;
+ border-left: 4px solid var(--color-secondary);
+ position: relative;
+}
+
+p::after, ul::after, pre::after, .quote::after {
+ content: "";
+ position: absolute;
+ right: -10px;
+ top: 50%;
+ transform: translateY(-50%);
+ width: 20px;
+ height: 20px;
+ background-color: var(--color-accent);
+ clip-path: polygon(0% 0%, 100% 50%, 0% 100%);
+}
diff --git a/extras/html/themes/sleek_river/theme.conf b/extras/html/themes/sleek_river/theme.conf
new file mode 100644
index 0000000..b620ed7
--- /dev/null
+++ b/extras/html/themes/sleek_river/theme.conf
@@ -0,0 +1,8 @@
+declare -xr HTML_HEADER=./extras/html/header.html.part
+declare -xr HTML_FOOTER=./extras/html/footer.html.part
+declare -xr HTML_CSS_STYLE=$HTML_THEME_DIR/style.css
+declare -xr HTML_WEBFONT_HEADING=./extras/html/fonts/zai-aeg-mignon-typewriter-1924/zai-aeg-mignon-typewriter-1924-Bold.ttf
+declare -xr HTML_WEBFONT_TEXT=./extras/html/fonts/roboto-slab/roboto-slab-Regular.ttf
+declare -xr HTML_WEBFONT_CODE=./extras/html/fonts/hack/hack-Regular.ttf
+declare -xr HTML_WEBFONT_HANDNOTES=./extras/html/fonts/khand/khand.ttf
+declare -xr SOURCE_HIGHLIGHT_CSS=./extras/html/source-highlight-styles/mono.css
diff --git a/extras/html/themes/smooth_echo/LICENSE b/extras/html/themes/smooth_echo/LICENSE
new file mode 100644
index 0000000..a1782db
--- /dev/null
+++ b/extras/html/themes/smooth_echo/LICENSE
@@ -0,0 +1,21 @@
+Theme: smooth_echo
+Generated: 2025-06-22 21:38:55
+
+Layout: wide
+Color Scheme: complementary (Light)
+
+Font Licenses:
+==============
+Heading Font: pixelon
+License: Free
+Category: display
+
+Body Font: oxygen
+License: OFL
+Category: sans-serif
+
+Code Font: hack
+License: MIT
+Category: monospace
+
+All fonts are free for personal use.
diff --git a/extras/html/themes/smooth_echo/code.ttf b/extras/html/themes/smooth_echo/code.ttf
new file mode 100644
index 0000000..7c8e65b
--- /dev/null
+++ b/extras/html/themes/smooth_echo/code.ttf
Binary files differ
diff --git a/extras/html/themes/smooth_echo/example.html b/extras/html/themes/smooth_echo/example.html
new file mode 100644
index 0000000..831e546
--- /dev/null
+++ b/extras/html/themes/smooth_echo/example.html
@@ -0,0 +1,75 @@
+<!DOCTYPE html>
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
+<head>
+ <meta charset="UTF-8" />
+ <meta name="viewport" content="width=device-width, initial-scale=1.0" />
+ <title>Smooth Echo - Gemtexter Theme</title>
+ <link rel="stylesheet" href="style.css" />
+</head>
+<body>
+ <div class="header">
+ <h1>Smooth Echo</h1>
+ <p>A wide layout with complementary colors</p>
+ </div>
+
+ <div class="content">
+ <h1>Welcome to Smooth Echo</h1>
+ <p>This theme features a carefully crafted wide layout with a light complementary color scheme. The typography combines display fonts for headings with sans-serif for body text.</p>
+
+ <h2>Typography Showcase</h2>
+ <p>The oxygen font family provides excellent readability for body text, while pixelon adds character to headings. Code blocks use hack for clarity.</p>
+
+ <h2>Color Palette</h2>
+ <p>Primary: <span style="color: #a89d12; font-weight: bold;">#a89d12</span> |
+ Secondary: <span style="color: #212b99; font-weight: bold;">#212b99</span> |
+ Accent: <span style="color: #6f6926; font-weight: bold;">#6f6926</span></p>
+
+ <h3>Interactive Elements</h3>
+ <p>Links like <a href="#">this example</a> and longer <a href="#" class="textlink">text links that demonstrate the theme's navigation style</a> use the secondary color.</p>
+
+ <div class="quote">
+ "Design is not just what it looks like and feels like. Design is how it works." — Steve Jobs
+ </div>
+
+ <h3>Code Examples</h3>
+ <p>Inline code like <code>theme.generate()</code> and larger blocks:</p>
+ <pre>// Theme configuration
+const theme = {
+ name: "smooth_echo",
+ layout: "wide",
+ colors: {
+ primary: "#a89d12",
+ secondary: "#212b99",
+ accent: "#6f6926"
+ },
+ fonts: {
+ heading: "pixelon",
+ body: "oxygen",
+ code: "hack"
+ }
+};</pre>
+
+ <h2>Content Structure</h2>
+ <ul>
+ <li>Clean, readable typography with 15px base font size</li>
+ <li>Heading scale ratio of 2.37x for visual hierarchy</li>
+ <li>Line height of 1.47 for comfortable reading</li>
+ <li>Wide layout optimized for content flow</li>
+ <li>Light theme with complementary color harmony</li>
+ </ul>
+
+ <h2>Font Licensing</h2>
+ <p>All fonts used in this theme are properly licensed:</p>
+ <ul>
+ <li>pixelon: Free License</li>
+ <li>oxygen: OFL License</li>
+ <li>hack: MIT License</li>
+ </ul>
+
+ <h3>Final Thoughts</h3>
+ <p>Every element of this theme has been carefully designed to create a harmonious reading experience. The wide layout ensures content is presented in an engaging way, while the color scheme provides the perfect backdrop for your words to shine.</p>
+
+ <p>Whether you're writing technical documentation, creative prose, or anything in between, this theme adapts to showcase your content beautifully.</p>
+ </div>
+</body>
+</html> \ No newline at end of file
diff --git a/extras/html/themes/smooth_echo/handnotes.ttf b/extras/html/themes/smooth_echo/handnotes.ttf
new file mode 100644
index 0000000..25e688b
--- /dev/null
+++ b/extras/html/themes/smooth_echo/handnotes.ttf
Binary files differ
diff --git a/extras/html/themes/smooth_echo/heading.ttf b/extras/html/themes/smooth_echo/heading.ttf
new file mode 100644
index 0000000..acb3c81
--- /dev/null
+++ b/extras/html/themes/smooth_echo/heading.ttf
Binary files differ
diff --git a/extras/html/themes/smooth_echo/style.css b/extras/html/themes/smooth_echo/style.css
new file mode 100644
index 0000000..1b7c9c0
--- /dev/null
+++ b/extras/html/themes/smooth_echo/style.css
@@ -0,0 +1,161 @@
+/* Base styles */
+@font-face {
+ font-family: 'text';
+ src: url("./text.ttf") format("truetype");
+}
+
+@font-face {
+ font-family: 'heading';
+ src: url("./heading.ttf") format("truetype");
+}
+
+@font-face {
+ font-family: 'code';
+ src: url("./code.ttf") format("truetype");
+}
+
+@font-face {
+ font-family: 'handnotes';
+ src: url("./handnotes.ttf") format("truetype");
+}
+
+:root {
+ --color-primary: #a89d12;
+ --color-secondary: #212b99;
+ --color-accent: #6f6926;
+ --color-bg: #f2f1ef;
+ --color-text: #141414;
+ --font-size-base: 15px;
+ --font-size-h1: 2.37em;
+ --font-size-h2: 1.78em;
+ --font-size-h3: 1.33em;
+ --line-height: 1.47;
+}
+
+* {
+ box-sizing: border-box;
+}
+
+html {
+ font-size: var(--font-size-base);
+ -webkit-font-smoothing: antialiased;
+ -moz-osx-font-smoothing: grayscale;
+}
+
+body {
+ font-family: text, sans-serif;
+ background-color: var(--color-bg);
+ color: var(--color-text);
+ line-height: var(--line-height);
+ margin: 0;
+ padding: 0;
+ overflow-wrap: break-word;
+}
+
+h1, h2, h3 {
+ font-family: heading, serif;
+ line-height: 1.2;
+ margin-top: 1em;
+ margin-bottom: 0.5em;
+}
+
+h1 {
+ font-size: var(--font-size-h1);
+ color: var(--color-primary);
+}
+
+h2 {
+ font-size: var(--font-size-h2);
+ color: var(--color-primary);
+}
+
+h3 {
+ font-size: var(--font-size-h3);
+ color: var(--color-secondary);
+}
+
+a {
+ font-family: code, monospace;
+ color: var(--color-secondary);
+ text-decoration: none;
+ transition: all 0.3s ease;
+}
+
+a:hover {
+ color: var(--color-accent);
+ text-decoration: underline;
+}
+
+.textlink {
+ font-family: text, sans-serif;
+}
+
+.quote {
+ font-family: handnotes, cursive;
+ border-left: 4px solid var(--color-accent);
+ padding: 1em 1.5em;
+ margin: 1.5em 0;
+ background-color: rgba(168, 157, 18, 0.07);
+ font-style: italic;
+}
+
+pre {
+ font-family: code, monospace;
+ background-color: rgba(20, 20, 20, 0.04);
+ border: 1px solid rgba(20, 20, 20, 0.13);
+ padding: 1em;
+ overflow-x: auto;
+ border-radius: 4px;
+ font-size: 0.9em;
+}
+
+code {
+ font-family: code, monospace;
+ background-color: rgba(20, 20, 20, 0.04);
+ padding: 0.2em 0.4em;
+ border-radius: 3px;
+ font-size: 0.9em;
+}
+
+ul, ol {
+ padding-left: 2em;
+ margin: 1em 0;
+}
+
+li {
+ margin: 0.5em 0;
+}
+
+img {
+ max-width: 100%;
+ height: auto;
+}
+
+hr {
+ border: none;
+ border-top: 1px solid rgba(20, 20, 20, 0.20);
+ margin: 2em 0;
+}
+
+
+/* Layout: wide */
+
+body {
+ max-width: 90%;
+ margin: 0 auto;
+ padding: 3em 2em;
+}
+
+.header {
+ display: flex;
+ justify-content: space-between;
+ align-items: baseline;
+ margin-bottom: 4em;
+ padding-bottom: 2em;
+ border-bottom: 3px solid var(--color-primary);
+}
+
+.content {
+ max-width: 75ch;
+ margin: 0 auto;
+}
diff --git a/extras/html/themes/smooth_echo/theme.conf b/extras/html/themes/smooth_echo/theme.conf
new file mode 100644
index 0000000..0f62152
--- /dev/null
+++ b/extras/html/themes/smooth_echo/theme.conf
@@ -0,0 +1,8 @@
+declare -xr HTML_HEADER=./extras/html/header.html.part
+declare -xr HTML_FOOTER=./extras/html/footer.html.part
+declare -xr HTML_CSS_STYLE=$HTML_THEME_DIR/style.css
+declare -xr HTML_WEBFONT_HEADING=./extras/html/fonts/pixelon/pixelon-Bold.ttf
+declare -xr HTML_WEBFONT_TEXT=./extras/html/fonts/oxygen/oxygen-Regular.ttf
+declare -xr HTML_WEBFONT_CODE=./extras/html/fonts/hack/hack-Regular.ttf
+declare -xr HTML_WEBFONT_HANDNOTES=./extras/html/fonts/khand/khand.ttf
+declare -xr SOURCE_HIGHLIGHT_CSS=./extras/html/source-highlight-styles/mono.css
diff --git a/extras/html/themes/soft_horizon/LICENSE b/extras/html/themes/soft_horizon/LICENSE
new file mode 100644
index 0000000..c106e16
--- /dev/null
+++ b/extras/html/themes/soft_horizon/LICENSE
@@ -0,0 +1,21 @@
+Theme: soft_horizon
+Generated: 2025-06-22 21:38:55
+
+Layout: card
+Color Scheme: triadic (Dark)
+
+Font Licenses:
+==============
+Heading Font: Abril_Fatface
+License: OFL
+Category: display
+
+Body Font: Merriweather
+License: OFL
+Category: serif
+
+Code Font: hack
+License: MIT
+Category: monospace
+
+All fonts are free for personal use.
diff --git a/extras/html/themes/soft_horizon/code.ttf b/extras/html/themes/soft_horizon/code.ttf
new file mode 100644
index 0000000..7c8e65b
--- /dev/null
+++ b/extras/html/themes/soft_horizon/code.ttf
Binary files differ
diff --git a/extras/html/themes/soft_horizon/example.html b/extras/html/themes/soft_horizon/example.html
new file mode 100644
index 0000000..b35661f
--- /dev/null
+++ b/extras/html/themes/soft_horizon/example.html
@@ -0,0 +1,75 @@
+<!DOCTYPE html>
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
+<head>
+ <meta charset="UTF-8" />
+ <meta name="viewport" content="width=device-width, initial-scale=1.0" />
+ <title>Soft Horizon - Gemtexter Theme</title>
+ <link rel="stylesheet" href="style.css" />
+</head>
+<body>
+ <div class="header">
+ <h1>Soft Horizon</h1>
+ <p>A card layout with triadic colors</p>
+ </div>
+
+ <div class="content">
+ <h1>Welcome to Soft Horizon</h1>
+ <p>This theme features a carefully crafted card layout with a dark triadic color scheme. The typography combines display fonts for headings with serif for body text.</p>
+
+ <h2>Typography Showcase</h2>
+ <p>The Merriweather font family provides excellent readability for body text, while Abril Fatface adds character to headings. Code blocks use hack for clarity.</p>
+
+ <h2>Color Palette</h2>
+ <p>Primary: <span style="color: #c84965; font-weight: bold;">#c84965</span> |
+ Secondary: <span style="color: #65c849; font-weight: bold;">#65c849</span> |
+ Accent: <span style="color: #4965c8; font-weight: bold;">#4965c8</span></p>
+
+ <h3>Interactive Elements</h3>
+ <p>Links like <a href="#">this example</a> and longer <a href="#" class="textlink">text links that demonstrate the theme's navigation style</a> use the secondary color.</p>
+
+ <div class="quote">
+ "Design is not just what it looks like and feels like. Design is how it works." — Steve Jobs
+ </div>
+
+ <h3>Code Examples</h3>
+ <p>Inline code like <code>theme.generate()</code> and larger blocks:</p>
+ <pre>// Theme configuration
+const theme = {
+ name: "soft_horizon",
+ layout: "card",
+ colors: {
+ primary: "#c84965",
+ secondary: "#65c849",
+ accent: "#4965c8"
+ },
+ fonts: {
+ heading: "Abril_Fatface",
+ body: "Merriweather",
+ code: "hack"
+ }
+};</pre>
+
+ <h2>Content Structure</h2>
+ <ul>
+ <li>Clean, readable typography with 14px base font size</li>
+ <li>Heading scale ratio of 1.42x for visual hierarchy</li>
+ <li>Line height of 1.55 for comfortable reading</li>
+ <li>Card layout optimized for content flow</li>
+ <li>Dark theme with triadic color harmony</li>
+ </ul>
+
+ <h2>Font Licensing</h2>
+ <p>All fonts used in this theme are properly licensed:</p>
+ <ul>
+ <li>Abril_Fatface: OFL License</li>
+ <li>Merriweather: OFL License</li>
+ <li>hack: MIT License</li>
+ </ul>
+
+ <h3>Final Thoughts</h3>
+ <p>Every element of this theme has been carefully designed to create a harmonious reading experience. The card layout ensures content is presented in an engaging way, while the color scheme provides the perfect backdrop for your words to shine.</p>
+
+ <p>Whether you're writing technical documentation, creative prose, or anything in between, this theme adapts to showcase your content beautifully.</p>
+ </div>
+</body>
+</html> \ No newline at end of file
diff --git a/extras/html/themes/soft_horizon/handnotes.ttf b/extras/html/themes/soft_horizon/handnotes.ttf
new file mode 100644
index 0000000..25e688b
--- /dev/null
+++ b/extras/html/themes/soft_horizon/handnotes.ttf
Binary files differ
diff --git a/extras/html/themes/soft_horizon/heading.ttf b/extras/html/themes/soft_horizon/heading.ttf
new file mode 100644
index 0000000..a291711
--- /dev/null
+++ b/extras/html/themes/soft_horizon/heading.ttf
Binary files differ
diff --git a/extras/html/themes/soft_horizon/style.css b/extras/html/themes/soft_horizon/style.css
new file mode 100644
index 0000000..f830a36
--- /dev/null
+++ b/extras/html/themes/soft_horizon/style.css
@@ -0,0 +1,168 @@
+/* Base styles */
+@font-face {
+ font-family: 'text';
+ src: url("./text.ttf") format("truetype");
+}
+
+@font-face {
+ font-family: 'heading';
+ src: url("./heading.ttf") format("truetype");
+}
+
+@font-face {
+ font-family: 'code';
+ src: url("./code.ttf") format("truetype");
+}
+
+@font-face {
+ font-family: 'handnotes';
+ src: url("./handnotes.ttf") format("truetype");
+}
+
+:root {
+ --color-primary: #c84965;
+ --color-secondary: #65c849;
+ --color-accent: #4965c8;
+ --color-bg: #110e0f;
+ --color-text: #e2e2e2;
+ --font-size-base: 14px;
+ --font-size-h1: 1.42em;
+ --font-size-h2: 1.27em;
+ --font-size-h3: 1.12em;
+ --line-height: 1.55;
+}
+
+* {
+ box-sizing: border-box;
+}
+
+html {
+ font-size: var(--font-size-base);
+ -webkit-font-smoothing: antialiased;
+ -moz-osx-font-smoothing: grayscale;
+}
+
+body {
+ font-family: text, sans-serif;
+ background-color: var(--color-bg);
+ color: var(--color-text);
+ line-height: var(--line-height);
+ margin: 0;
+ padding: 0;
+ overflow-wrap: break-word;
+}
+
+h1, h2, h3 {
+ font-family: heading, serif;
+ line-height: 1.2;
+ margin-top: 1em;
+ margin-bottom: 0.5em;
+}
+
+h1 {
+ font-size: var(--font-size-h1);
+ color: var(--color-primary);
+}
+
+h2 {
+ font-size: var(--font-size-h2);
+ color: var(--color-primary);
+}
+
+h3 {
+ font-size: var(--font-size-h3);
+ color: var(--color-secondary);
+}
+
+a {
+ font-family: code, monospace;
+ color: var(--color-secondary);
+ text-decoration: none;
+ transition: all 0.3s ease;
+}
+
+a:hover {
+ color: var(--color-accent);
+ text-decoration: underline;
+}
+
+.textlink {
+ font-family: text, sans-serif;
+}
+
+.quote {
+ font-family: handnotes, cursive;
+ border-left: 4px solid var(--color-accent);
+ padding: 1em 1.5em;
+ margin: 1.5em 0;
+ background-color: rgba(200, 73, 101, 0.07);
+ font-style: italic;
+}
+
+pre {
+ font-family: code, monospace;
+ background-color: rgba(226, 226, 226, 0.04);
+ border: 1px solid rgba(226, 226, 226, 0.13);
+ padding: 1em;
+ overflow-x: auto;
+ border-radius: 4px;
+ font-size: 0.9em;
+}
+
+code {
+ font-family: code, monospace;
+ background-color: rgba(226, 226, 226, 0.04);
+ padding: 0.2em 0.4em;
+ border-radius: 3px;
+ font-size: 0.9em;
+}
+
+ul, ol {
+ padding-left: 2em;
+ margin: 1em 0;
+}
+
+li {
+ margin: 0.5em 0;
+}
+
+img {
+ max-width: 100%;
+ height: auto;
+}
+
+hr {
+ border: none;
+ border-top: 1px solid rgba(226, 226, 226, 0.20);
+ margin: 2em 0;
+}
+
+
+/* Layout: card */
+
+body {
+ padding: 2em;
+ background: linear-gradient(135deg, rgba(200, 73, 101, 0.07), rgba(101, 200, 73, 0.07));
+ min-height: 100vh;
+}
+
+.header {
+ background-color: var(--color-bg);
+ padding: 3em;
+ margin-bottom: 3em;
+ border-radius: 16px;
+ box-shadow: 0 8px 32px rgba(0,0,0,0.1);
+ text-align: center;
+}
+
+h1, h2, h3, p, ul, pre, .quote {
+ background-color: var(--color-bg);
+ padding: 2em;
+ margin: 1em 0;
+ border-radius: 12px;
+ box-shadow: 0 4px 16px rgba(0,0,0,0.05);
+}
+
+h1, h2, h3 {
+ padding: 1em 2em;
+}
diff --git a/extras/html/themes/soft_horizon/text.ttf b/extras/html/themes/soft_horizon/text.ttf
new file mode 100644
index 0000000..3fecc77
--- /dev/null
+++ b/extras/html/themes/soft_horizon/text.ttf
Binary files differ
diff --git a/extras/html/themes/soft_horizon/theme.conf b/extras/html/themes/soft_horizon/theme.conf
new file mode 100644
index 0000000..7673f51
--- /dev/null
+++ b/extras/html/themes/soft_horizon/theme.conf
@@ -0,0 +1,8 @@
+declare -xr HTML_HEADER=./extras/html/header.html.part
+declare -xr HTML_FOOTER=./extras/html/footer.html.part
+declare -xr HTML_CSS_STYLE=$HTML_THEME_DIR/style.css
+declare -xr HTML_WEBFONT_HEADING=./extras/html/fonts/Abril_Fatface/Abril_Fatface-Bold.ttf
+declare -xr HTML_WEBFONT_TEXT=./extras/html/fonts/Merriweather/Merriweather-Regular.ttf
+declare -xr HTML_WEBFONT_CODE=./extras/html/fonts/hack/hack-Regular.ttf
+declare -xr HTML_WEBFONT_HANDNOTES=./extras/html/fonts/khand/khand.ttf
+declare -xr SOURCE_HIGHLIGHT_CSS=./extras/html/source-highlight-styles/mono.css
diff --git a/extras/html/themes/strong_breeze/LICENSE b/extras/html/themes/strong_breeze/LICENSE
new file mode 100644
index 0000000..1617c1a
--- /dev/null
+++ b/extras/html/themes/strong_breeze/LICENSE
@@ -0,0 +1,21 @@
+Theme: strong_breeze
+Generated: 2025-06-22 21:38:55
+
+Layout: geometric
+Color Scheme: split_complementary (Dark)
+
+Font Licenses:
+==============
+Heading Font: oxygen
+License: OFL
+Category: sans-serif
+
+Body Font: Merriweather
+License: OFL
+Category: serif
+
+Code Font: intelone-mono
+License: OFL
+Category: monospace
+
+All fonts are free for personal use.
diff --git a/extras/html/themes/strong_breeze/code.ttf b/extras/html/themes/strong_breeze/code.ttf
new file mode 100644
index 0000000..2711179
--- /dev/null
+++ b/extras/html/themes/strong_breeze/code.ttf
Binary files differ
diff --git a/extras/html/themes/strong_breeze/example.html b/extras/html/themes/strong_breeze/example.html
new file mode 100644
index 0000000..038aa6a
--- /dev/null
+++ b/extras/html/themes/strong_breeze/example.html
@@ -0,0 +1,75 @@
+<!DOCTYPE html>
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
+<head>
+ <meta charset="UTF-8" />
+ <meta name="viewport" content="width=device-width, initial-scale=1.0" />
+ <title>Strong Breeze - Gemtexter Theme</title>
+ <link rel="stylesheet" href="style.css" />
+</head>
+<body>
+ <div class="header">
+ <h1>Strong Breeze</h1>
+ <p>A geometric layout with split complementary colors</p>
+ </div>
+
+ <div class="content">
+ <h1>Welcome to Strong Breeze</h1>
+ <p>This theme features a carefully crafted geometric layout with a dark split complementary color scheme. The typography combines sans-serif fonts for headings with serif for body text.</p>
+
+ <h2>Typography Showcase</h2>
+ <p>The Merriweather font family provides excellent readability for body text, while oxygen adds character to headings. Code blocks use intelone-mono for clarity.</p>
+
+ <h2>Color Palette</h2>
+ <p>Primary: <span style="color: #42c757; font-weight: bold;">#42c757</span> |
+ Secondary: <span style="color: #974fba; font-weight: bold;">#974fba</span> |
+ Accent: <span style="color: #ba4f75; font-weight: bold;">#ba4f75</span></p>
+
+ <h3>Interactive Elements</h3>
+ <p>Links like <a href="#">this example</a> and longer <a href="#" class="textlink">text links that demonstrate the theme's navigation style</a> use the secondary color.</p>
+
+ <div class="quote">
+ "Design is not just what it looks like and feels like. Design is how it works." — Steve Jobs
+ </div>
+
+ <h3>Code Examples</h3>
+ <p>Inline code like <code>theme.generate()</code> and larger blocks:</p>
+ <pre>// Theme configuration
+const theme = {
+ name: "strong_breeze",
+ layout: "geometric",
+ colors: {
+ primary: "#42c757",
+ secondary: "#974fba",
+ accent: "#ba4f75"
+ },
+ fonts: {
+ heading: "oxygen",
+ body: "Merriweather",
+ code: "intelone-mono"
+ }
+};</pre>
+
+ <h2>Content Structure</h2>
+ <ul>
+ <li>Clean, readable typography with 14px base font size</li>
+ <li>Heading scale ratio of 2.83x for visual hierarchy</li>
+ <li>Line height of 1.6 for comfortable reading</li>
+ <li>Geometric layout optimized for content flow</li>
+ <li>Dark theme with split complementary color harmony</li>
+ </ul>
+
+ <h2>Font Licensing</h2>
+ <p>All fonts used in this theme are properly licensed:</p>
+ <ul>
+ <li>oxygen: OFL License</li>
+ <li>Merriweather: OFL License</li>
+ <li>intelone-mono: OFL License</li>
+ </ul>
+
+ <h3>Final Thoughts</h3>
+ <p>Every element of this theme has been carefully designed to create a harmonious reading experience. The geometric layout ensures content is presented in an engaging way, while the color scheme provides the perfect backdrop for your words to shine.</p>
+
+ <p>Whether you're writing technical documentation, creative prose, or anything in between, this theme adapts to showcase your content beautifully.</p>
+ </div>
+</body>
+</html> \ No newline at end of file
diff --git a/extras/html/themes/strong_breeze/handnotes.ttf b/extras/html/themes/strong_breeze/handnotes.ttf
new file mode 100644
index 0000000..25e688b
--- /dev/null
+++ b/extras/html/themes/strong_breeze/handnotes.ttf
Binary files differ
diff --git a/extras/html/themes/strong_breeze/style.css b/extras/html/themes/strong_breeze/style.css
new file mode 100644
index 0000000..b152084
--- /dev/null
+++ b/extras/html/themes/strong_breeze/style.css
@@ -0,0 +1,193 @@
+/* Base styles */
+@font-face {
+ font-family: 'text';
+ src: url("./text.ttf") format("truetype");
+}
+
+@font-face {
+ font-family: 'heading';
+ src: url("./heading.ttf") format("truetype");
+}
+
+@font-face {
+ font-family: 'code';
+ src: url("./code.ttf") format("truetype");
+}
+
+@font-face {
+ font-family: 'handnotes';
+ src: url("./handnotes.ttf") format("truetype");
+}
+
+:root {
+ --color-primary: #42c757;
+ --color-secondary: #974fba;
+ --color-accent: #ba4f75;
+ --color-bg: #1e241f;
+ --color-text: #e8e8e8;
+ --font-size-base: 14px;
+ --font-size-h1: 2.83em;
+ --font-size-h2: 2.0em;
+ --font-size-h3: 1.41em;
+ --line-height: 1.6;
+}
+
+* {
+ box-sizing: border-box;
+}
+
+html {
+ font-size: var(--font-size-base);
+ -webkit-font-smoothing: antialiased;
+ -moz-osx-font-smoothing: grayscale;
+}
+
+body {
+ font-family: text, sans-serif;
+ background-color: var(--color-bg);
+ color: var(--color-text);
+ line-height: var(--line-height);
+ margin: 0;
+ padding: 0;
+ overflow-wrap: break-word;
+}
+
+h1, h2, h3 {
+ font-family: heading, serif;
+ line-height: 1.2;
+ margin-top: 1em;
+ margin-bottom: 0.5em;
+}
+
+h1 {
+ font-size: var(--font-size-h1);
+ color: var(--color-primary);
+}
+
+h2 {
+ font-size: var(--font-size-h2);
+ color: var(--color-primary);
+}
+
+h3 {
+ font-size: var(--font-size-h3);
+ color: var(--color-secondary);
+}
+
+a {
+ font-family: code, monospace;
+ color: var(--color-secondary);
+ text-decoration: none;
+ transition: all 0.3s ease;
+}
+
+a:hover {
+ color: var(--color-accent);
+ text-decoration: underline;
+}
+
+.textlink {
+ font-family: text, sans-serif;
+}
+
+.quote {
+ font-family: handnotes, cursive;
+ border-left: 4px solid var(--color-accent);
+ padding: 1em 1.5em;
+ margin: 1.5em 0;
+ background-color: rgba(66, 199, 87, 0.07);
+ font-style: italic;
+}
+
+pre {
+ font-family: code, monospace;
+ background-color: rgba(232, 232, 232, 0.04);
+ border: 1px solid rgba(232, 232, 232, 0.13);
+ padding: 1em;
+ overflow-x: auto;
+ border-radius: 4px;
+ font-size: 0.9em;
+}
+
+code {
+ font-family: code, monospace;
+ background-color: rgba(232, 232, 232, 0.04);
+ padding: 0.2em 0.4em;
+ border-radius: 3px;
+ font-size: 0.9em;
+}
+
+ul, ol {
+ padding-left: 2em;
+ margin: 1em 0;
+}
+
+li {
+ margin: 0.5em 0;
+}
+
+img {
+ max-width: 100%;
+ height: auto;
+}
+
+hr {
+ border: none;
+ border-top: 1px solid rgba(232, 232, 232, 0.20);
+ margin: 2em 0;
+}
+
+
+/* Layout: geometric */
+
+body {
+ padding: 2em;
+ background-color: var(--color-bg);
+ background-image: repeating-linear-gradient(45deg, rgba(66, 199, 87, 0.07) 0, rgba(66, 199, 87, 0.07) 10px, transparent 10px, transparent 20px), repeating-linear-gradient(-45deg, rgba(151, 79, 186, 0.07) 0, rgba(151, 79, 186, 0.07) 10px, transparent 10px, transparent 20px);
+}
+
+.header {
+ background-color: var(--color-bg);
+ border: 4px solid var(--color-primary);
+ padding: 3em;
+ margin-bottom: 3em;
+ position: relative;
+ clip-path: polygon(0 0, 100% 0, 95% 100%, 5% 100%);
+}
+
+h1, h2, h3 {
+ position: relative;
+ padding-left: 2em;
+}
+
+h1::before, h2::before, h3::before {
+ content: "";
+ position: absolute;
+ left: 0;
+ top: 50%;
+ transform: translateY(-50%);
+ width: 1em;
+ height: 1em;
+ background-color: var(--color-accent);
+ clip-path: polygon(50% 0%, 100% 50%, 50% 100%, 0% 50%);
+}
+
+p, ul, pre, .quote {
+ background-color: var(--color-bg);
+ padding: 2em;
+ margin: 2em 0;
+ border-left: 4px solid var(--color-secondary);
+ position: relative;
+}
+
+p::after, ul::after, pre::after, .quote::after {
+ content: "";
+ position: absolute;
+ right: -10px;
+ top: 50%;
+ transform: translateY(-50%);
+ width: 20px;
+ height: 20px;
+ background-color: var(--color-accent);
+ clip-path: polygon(0% 0%, 100% 50%, 0% 100%);
+}
diff --git a/extras/html/themes/strong_breeze/text.ttf b/extras/html/themes/strong_breeze/text.ttf
new file mode 100644
index 0000000..3fecc77
--- /dev/null
+++ b/extras/html/themes/strong_breeze/text.ttf
Binary files differ
diff --git a/extras/html/themes/strong_breeze/theme.conf b/extras/html/themes/strong_breeze/theme.conf
new file mode 100644
index 0000000..11ad64d
--- /dev/null
+++ b/extras/html/themes/strong_breeze/theme.conf
@@ -0,0 +1,8 @@
+declare -xr HTML_HEADER=./extras/html/header.html.part
+declare -xr HTML_FOOTER=./extras/html/footer.html.part
+declare -xr HTML_CSS_STYLE=$HTML_THEME_DIR/style.css
+declare -xr HTML_WEBFONT_HEADING=./extras/html/fonts/oxygen/oxygen-Bold.ttf
+declare -xr HTML_WEBFONT_TEXT=./extras/html/fonts/Merriweather/Merriweather-Regular.ttf
+declare -xr HTML_WEBFONT_CODE=./extras/html/fonts/intelone-mono/intelone-mono-Regular.ttf
+declare -xr HTML_WEBFONT_HANDNOTES=./extras/html/fonts/khand/khand.ttf
+declare -xr SOURCE_HIGHLIGHT_CSS=./extras/html/source-highlight-styles/mono.css
diff --git a/extras/html/themes/test_screenshots.html b/extras/html/themes/test_screenshots.html
new file mode 100644
index 0000000..0299c03
--- /dev/null
+++ b/extras/html/themes/test_screenshots.html
@@ -0,0 +1,109 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <title>Screenshot Test</title>
+ <style>
+ body {
+ font-family: Arial, sans-serif;
+ padding: 20px;
+ background: #f5f5f5;
+ }
+ .grid {
+ display: grid;
+ grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
+ gap: 20px;
+ }
+ .theme {
+ background: white;
+ border-radius: 8px;
+ overflow: hidden;
+ box-shadow: 0 2px 8px rgba(0,0,0,0.1);
+ }
+ .theme img {
+ width: 100%;
+ height: 150px;
+ object-fit: cover;
+ display: block;
+ }
+ .theme-name {
+ padding: 10px;
+ font-size: 14px;
+ text-align: center;
+ font-weight: bold;
+ }
+ .error {
+ background: #ffebee;
+ color: #c62828;
+ padding: 10px;
+ text-align: center;
+ }
+ </style>
+</head>
+<body>
+ <h1>Theme Screenshot Test</h1>
+ <p>Testing if screenshots are displaying correctly:</p>
+
+ <div class="grid">
+ <div class="theme">
+ <img src="screenshots/vibrant_garden.png" alt="Vibrant Garden"
+ onerror="this.parentElement.innerHTML='<div class=error>Failed to load</div>'">
+ <div class="theme-name">Vibrant Garden</div>
+ </div>
+
+ <div class="theme">
+ <img src="screenshots/twilight_nebula.png" alt="Twilight Nebula"
+ onerror="this.parentElement.innerHTML='<div class=error>Failed to load</div>'">
+ <div class="theme-name">Twilight Nebula</div>
+ </div>
+
+ <div class="theme">
+ <img src="screenshots/cosmic_odyssey.png" alt="Cosmic Odyssey"
+ onerror="this.parentElement.innerHTML='<div class=error>Failed to load</div>'">
+ <div class="theme-name">Cosmic Odyssey</div>
+ </div>
+
+ <div class="theme">
+ <img src="screenshots/terminal.png" alt="Terminal Theme"
+ onerror="this.parentElement.innerHTML='<div class=error>Failed to load</div>'">
+ <div class="theme-name">Terminal (if exists)</div>
+ </div>
+
+ <div class="theme">
+ <img src="screenshots/hero.png" alt="Hero Theme"
+ onerror="this.parentElement.innerHTML='<div class=error>Failed to load</div>'">
+ <div class="theme-name">Hero (if exists)</div>
+ </div>
+ </div>
+
+ <h2>File sizes:</h2>
+ <pre id="file-info">Loading...</pre>
+
+ <script>
+ // List all theme names to test
+ const themes = [
+ 'vibrant_garden', 'pure_voyage', 'twilight_nebula', 'mystic_canyon',
+ 'dynamic_forest', 'soft_horizon', 'pastel_crystal', 'bright_light',
+ 'crisp_oasis', 'sharp_canyon', 'strong_breeze', 'aurora_dawn'
+ ];
+
+ // Check which images load successfully
+ const checkImages = async () => {
+ const results = [];
+ for (const theme of themes) {
+ const img = new Image();
+ const promise = new Promise((resolve) => {
+ img.onload = () => resolve({theme, status: 'loaded', width: img.width, height: img.height});
+ img.onerror = () => resolve({theme, status: 'failed'});
+ });
+ img.src = `screenshots/${theme}.png`;
+ results.push(await promise);
+ }
+
+ document.getElementById('file-info').textContent =
+ results.map(r => `${r.theme}: ${r.status} ${r.status === 'loaded' ? `(${r.width}x${r.height})` : ''}`).join('\n');
+ };
+
+ checkImages();
+ </script>
+</body>
+</html> \ No newline at end of file
diff --git a/extras/html/themes/themes_metadata.json b/extras/html/themes/themes_metadata.json
new file mode 100644
index 0000000..0cd10a4
--- /dev/null
+++ b/extras/html/themes/themes_metadata.json
@@ -0,0 +1,1502 @@
+[
+ {
+ "name": "vibrant_garden",
+ "layout": "overlap",
+ "colors": {
+ "primary": "#bd7f21",
+ "secondary": "#795622",
+ "accent": "#b88f52",
+ "background": "#f5f4f2",
+ "text": "#1d1d1d",
+ "is_dark": false,
+ "palette_type": "monochromatic"
+ },
+ "fonts": {
+ "heading": [
+ "repetition-scrolling",
+ "Free",
+ "display"
+ ],
+ "body": [
+ "Merriweather",
+ "OFL",
+ "serif"
+ ],
+ "code": [
+ "intelone-mono",
+ "OFL",
+ "monospace"
+ ]
+ }
+ },
+ {
+ "name": "pure_voyage",
+ "layout": "centered",
+ "colors": {
+ "primary": "#92e630",
+ "secondary": "#3093e6",
+ "accent": "#e63092",
+ "background": "#10120e",
+ "text": "#ebebeb",
+ "is_dark": true,
+ "palette_type": "triadic"
+ },
+ "fonts": {
+ "heading": [
+ "higher-jump",
+ "Free",
+ "display"
+ ],
+ "body": [
+ "Lato",
+ "OFL",
+ "sans-serif"
+ ],
+ "code": [
+ "consola-mono",
+ "OFL",
+ "monospace"
+ ]
+ }
+ },
+ {
+ "name": "twilight_nebula",
+ "layout": "brutalist",
+ "colors": {
+ "primary": "#bd8487",
+ "secondary": "#87bd84",
+ "accent": "#8486bd",
+ "background": "#0f0c0c",
+ "text": "#e3e3e3",
+ "is_dark": true,
+ "palette_type": "triadic"
+ },
+ "fonts": {
+ "heading": [
+ "oxygen",
+ "OFL",
+ "sans-serif"
+ ],
+ "body": [
+ "Merriweather",
+ "OFL",
+ "serif"
+ ],
+ "code": [
+ "intelone-mono",
+ "OFL",
+ "monospace"
+ ]
+ }
+ },
+ {
+ "name": "mystic_canyon",
+ "layout": "centered",
+ "colors": {
+ "primary": "#18ee0d",
+ "secondary": "#cf24d8",
+ "accent": "#349a2e",
+ "background": "#161a15",
+ "text": "#dedede",
+ "is_dark": true,
+ "palette_type": "complementary"
+ },
+ "fonts": {
+ "heading": [
+ "zai-aeg-mignon-typewriter-1924",
+ "Free",
+ "display"
+ ],
+ "body": [
+ "roboto-slab",
+ "Apache",
+ "serif"
+ ],
+ "code": [
+ "hack",
+ "MIT",
+ "monospace"
+ ]
+ }
+ },
+ {
+ "name": "dynamic_forest",
+ "layout": "masonry",
+ "colors": {
+ "primary": "#4bcfe9",
+ "secondary": "#5385e1",
+ "accent": "#30e6ad",
+ "background": "#101314",
+ "text": "#f0f0f0",
+ "is_dark": true,
+ "palette_type": "analogous"
+ },
+ "fonts": {
+ "heading": [
+ "pixelon",
+ "Free",
+ "display"
+ ],
+ "body": [
+ "roboto-slab",
+ "Apache",
+ "serif"
+ ],
+ "code": [
+ "consola-mono",
+ "OFL",
+ "monospace"
+ ]
+ }
+ },
+ {
+ "name": "soft_horizon",
+ "layout": "card",
+ "colors": {
+ "primary": "#c84965",
+ "secondary": "#65c849",
+ "accent": "#4965c8",
+ "background": "#110e0f",
+ "text": "#e2e2e2",
+ "is_dark": true,
+ "palette_type": "triadic"
+ },
+ "fonts": {
+ "heading": [
+ "Abril_Fatface",
+ "OFL",
+ "display"
+ ],
+ "body": [
+ "Merriweather",
+ "OFL",
+ "serif"
+ ],
+ "code": [
+ "hack",
+ "MIT",
+ "monospace"
+ ]
+ }
+ },
+ {
+ "name": "pastel_crystal",
+ "layout": "book",
+ "colors": {
+ "primary": "#5689f3",
+ "secondary": "#745eeb",
+ "accent": "#37cdf1",
+ "background": "#e8eaec",
+ "text": "#1a1a1a",
+ "is_dark": false,
+ "palette_type": "analogous"
+ },
+ "fonts": {
+ "heading": [
+ "khand",
+ "Free",
+ "handwriting"
+ ],
+ "body": [
+ "Lato",
+ "OFL",
+ "sans-serif"
+ ],
+ "code": [
+ "consola-mono",
+ "OFL",
+ "monospace"
+ ]
+ }
+ },
+ {
+ "name": "bright_light",
+ "layout": "hero",
+ "colors": {
+ "primary": "#0fb543",
+ "secondary": "#420fb5",
+ "accent": "#b5430f",
+ "background": "#edf0ee",
+ "text": "#1b1b1b",
+ "is_dark": false,
+ "palette_type": "triadic"
+ },
+ "fonts": {
+ "heading": [
+ "Merriweather",
+ "OFL",
+ "serif"
+ ],
+ "body": [
+ "oxygen",
+ "OFL",
+ "sans-serif"
+ ],
+ "code": [
+ "hack",
+ "MIT",
+ "monospace"
+ ]
+ }
+ },
+ {
+ "name": "crisp_oasis",
+ "layout": "book",
+ "colors": {
+ "primary": "#9f41a4",
+ "secondary": "#9f4679",
+ "accent": "#643b93",
+ "background": "#171317",
+ "text": "#ececec",
+ "is_dark": true,
+ "palette_type": "analogous"
+ },
+ "fonts": {
+ "heading": [
+ "Abril_Fatface",
+ "OFL",
+ "display"
+ ],
+ "body": [
+ "Lato",
+ "OFL",
+ "sans-serif"
+ ],
+ "code": [
+ "consola-mono",
+ "OFL",
+ "monospace"
+ ]
+ }
+ },
+ {
+ "name": "sharp_canyon",
+ "layout": "retro",
+ "colors": {
+ "primary": "#b98f33",
+ "secondary": "#78602d",
+ "accent": "#b49c67",
+ "background": "#211f1b",
+ "text": "#e1e1e1",
+ "is_dark": true,
+ "palette_type": "monochromatic"
+ },
+ "fonts": {
+ "heading": [
+ "roboto-slab",
+ "Apache",
+ "serif"
+ ],
+ "body": [
+ "oxygen",
+ "OFL",
+ "sans-serif"
+ ],
+ "code": [
+ "intelone-mono",
+ "OFL",
+ "monospace"
+ ]
+ }
+ },
+ {
+ "name": "strong_breeze",
+ "layout": "geometric",
+ "colors": {
+ "primary": "#42c757",
+ "secondary": "#974fba",
+ "accent": "#ba4f75",
+ "background": "#1e241f",
+ "text": "#e8e8e8",
+ "is_dark": true,
+ "palette_type": "split_complementary"
+ },
+ "fonts": {
+ "heading": [
+ "oxygen",
+ "OFL",
+ "sans-serif"
+ ],
+ "body": [
+ "Merriweather",
+ "OFL",
+ "serif"
+ ],
+ "code": [
+ "intelone-mono",
+ "OFL",
+ "monospace"
+ ]
+ }
+ },
+ {
+ "name": "aurora_dawn",
+ "layout": "hero",
+ "colors": {
+ "primary": "#97c378",
+ "secondary": "#7897c3",
+ "accent": "#c37897",
+ "background": "#f1f3f0",
+ "text": "#252525",
+ "is_dark": false,
+ "palette_type": "triadic"
+ },
+ "fonts": {
+ "heading": [
+ "higher-jump",
+ "Free",
+ "display"
+ ],
+ "body": [
+ "oxygen",
+ "OFL",
+ "sans-serif"
+ ],
+ "code": [
+ "intelone-mono",
+ "OFL",
+ "monospace"
+ ]
+ }
+ },
+ {
+ "name": "mystic_meadow",
+ "layout": "hero",
+ "colors": {
+ "primary": "#6b3ddb",
+ "secondary": "#a7cb4d",
+ "accent": "#5c419f",
+ "background": "#141217",
+ "text": "#dedede",
+ "is_dark": true,
+ "palette_type": "complementary"
+ },
+ "fonts": {
+ "heading": [
+ "roboto-slab",
+ "Apache",
+ "serif"
+ ],
+ "body": [
+ "oxygen",
+ "OFL",
+ "sans-serif"
+ ],
+ "code": [
+ "intelone-mono",
+ "OFL",
+ "monospace"
+ ]
+ }
+ },
+ {
+ "name": "vibrant_nebula",
+ "layout": "swiss",
+ "colors": {
+ "primary": "#7c2f4a",
+ "secondary": "#4a7c2f",
+ "accent": "#2f4a7c",
+ "background": "#f0edee",
+ "text": "#232323",
+ "is_dark": false,
+ "palette_type": "triadic"
+ },
+ "fonts": {
+ "heading": [
+ "zai-aeg-mignon-typewriter-1924",
+ "Free",
+ "display"
+ ],
+ "body": [
+ "roboto-slab",
+ "Apache",
+ "serif"
+ ],
+ "code": [
+ "hack",
+ "MIT",
+ "monospace"
+ ]
+ }
+ },
+ {
+ "name": "sleek_river",
+ "layout": "geometric",
+ "colors": {
+ "primary": "#77ca90",
+ "secondary": "#7bc6b6",
+ "accent": "#70c160",
+ "background": "#f8f9f8",
+ "text": "#0d0d0d",
+ "is_dark": false,
+ "palette_type": "analogous"
+ },
+ "fonts": {
+ "heading": [
+ "zai-aeg-mignon-typewriter-1924",
+ "Free",
+ "display"
+ ],
+ "body": [
+ "roboto-slab",
+ "Apache",
+ "serif"
+ ],
+ "code": [
+ "hack",
+ "MIT",
+ "monospace"
+ ]
+ }
+ },
+ {
+ "name": "clear_forest",
+ "layout": "technical",
+ "colors": {
+ "primary": "#4eaa17",
+ "secondary": "#37269b",
+ "accent": "#9b268f",
+ "background": "#eff1ee",
+ "text": "#1a1a1a",
+ "is_dark": false,
+ "palette_type": "split_complementary"
+ },
+ "fonts": {
+ "heading": [
+ "pixelon",
+ "Free",
+ "display"
+ ],
+ "body": [
+ "roboto-slab",
+ "Apache",
+ "serif"
+ ],
+ "code": [
+ "consola-mono",
+ "OFL",
+ "monospace"
+ ]
+ }
+ },
+ {
+ "name": "bold_pulse",
+ "layout": "swiss",
+ "colors": {
+ "primary": "#a97f1c",
+ "secondary": "#2a819a",
+ "accent": "#3e2a9a",
+ "background": "#f3f2f0",
+ "text": "#111111",
+ "is_dark": false,
+ "palette_type": "split_complementary"
+ },
+ "fonts": {
+ "heading": [
+ "oxygen",
+ "OFL",
+ "sans-serif"
+ ],
+ "body": [
+ "Lato",
+ "OFL",
+ "sans-serif"
+ ],
+ "code": [
+ "hack",
+ "MIT",
+ "monospace"
+ ]
+ }
+ },
+ {
+ "name": "fresh_field",
+ "layout": "terminal",
+ "colors": {
+ "primary": "#7a82e7",
+ "secondary": "#dcd685",
+ "accent": "#5d65bd",
+ "background": "#101114",
+ "text": "#ebebeb",
+ "is_dark": true,
+ "palette_type": "complementary"
+ },
+ "fonts": {
+ "heading": [
+ "oxygen",
+ "OFL",
+ "sans-serif"
+ ],
+ "body": [
+ "Merriweather",
+ "OFL",
+ "serif"
+ ],
+ "code": [
+ "intelone-mono",
+ "OFL",
+ "monospace"
+ ]
+ }
+ },
+ {
+ "name": "clear_frost",
+ "layout": "minimal_grid",
+ "colors": {
+ "primary": "#9324d0",
+ "secondary": "#a8bf35",
+ "accent": "#35bf47",
+ "background": "#edebef",
+ "text": "#121212",
+ "is_dark": false,
+ "palette_type": "split_complementary"
+ },
+ "fonts": {
+ "heading": [
+ "roboto-slab",
+ "Apache",
+ "serif"
+ ],
+ "body": [
+ "oxygen",
+ "OFL",
+ "sans-serif"
+ ],
+ "code": [
+ "intelone-mono",
+ "OFL",
+ "monospace"
+ ]
+ }
+ },
+ {
+ "name": "ember_mountain",
+ "layout": "card",
+ "colors": {
+ "primary": "#6f3857",
+ "secondary": "#3f6a3d",
+ "accent": "#3d6a66",
+ "background": "#efecee",
+ "text": "#151515",
+ "is_dark": false,
+ "palette_type": "split_complementary"
+ },
+ "fonts": {
+ "heading": [
+ "oxygen",
+ "OFL",
+ "sans-serif"
+ ],
+ "body": [
+ "Lato",
+ "OFL",
+ "sans-serif"
+ ],
+ "code": [
+ "hack",
+ "MIT",
+ "monospace"
+ ]
+ }
+ },
+ {
+ "name": "refined_oasis",
+ "layout": "floating",
+ "colors": {
+ "primary": "#c4cd12",
+ "secondary": "#2c25ba",
+ "accent": "#81862c",
+ "background": "#23231d",
+ "text": "#e8e8e8",
+ "is_dark": true,
+ "palette_type": "complementary"
+ },
+ "fonts": {
+ "heading": [
+ "repetition-scrolling",
+ "Free",
+ "display"
+ ],
+ "body": [
+ "Merriweather",
+ "OFL",
+ "serif"
+ ],
+ "code": [
+ "intelone-mono",
+ "OFL",
+ "monospace"
+ ]
+ }
+ },
+ {
+ "name": "sharp_mountain",
+ "layout": "centered",
+ "colors": {
+ "primary": "#71294a",
+ "secondary": "#306a4f",
+ "accent": "#4f2c3c",
+ "background": "#f3f0f1",
+ "text": "#1b1b1b",
+ "is_dark": false,
+ "palette_type": "complementary"
+ },
+ "fonts": {
+ "heading": [
+ "roboto-slab",
+ "Apache",
+ "serif"
+ ],
+ "body": [
+ "Lato",
+ "OFL",
+ "sans-serif"
+ ],
+ "code": [
+ "consola-mono",
+ "OFL",
+ "monospace"
+ ]
+ }
+ },
+ {
+ "name": "deep_crystal",
+ "layout": "asymmetric",
+ "colors": {
+ "primary": "#ce7cd7",
+ "secondary": "#d281b3",
+ "accent": "#9162cf",
+ "background": "#1c171c",
+ "text": "#e0e0e0",
+ "is_dark": true,
+ "palette_type": "analogous"
+ },
+ "fonts": {
+ "heading": [
+ "Abril_Fatface",
+ "OFL",
+ "display"
+ ],
+ "body": [
+ "Lato",
+ "OFL",
+ "sans-serif"
+ ],
+ "code": [
+ "consola-mono",
+ "OFL",
+ "monospace"
+ ]
+ }
+ },
+ {
+ "name": "cozy_wave",
+ "layout": "newspaper",
+ "colors": {
+ "primary": "#3559e1",
+ "secondary": "#273f9b",
+ "accent": "#8090ce",
+ "background": "#191a1f",
+ "text": "#dedede",
+ "is_dark": true,
+ "palette_type": "monochromatic"
+ },
+ "fonts": {
+ "heading": [
+ "zai-aeg-mignon-typewriter-1924",
+ "Free",
+ "display"
+ ],
+ "body": [
+ "roboto-slab",
+ "Apache",
+ "serif"
+ ],
+ "code": [
+ "hack",
+ "MIT",
+ "monospace"
+ ]
+ }
+ },
+ {
+ "name": "ember_mist",
+ "layout": "asymmetric",
+ "colors": {
+ "primary": "#f149ca",
+ "secondary": "#7be05a",
+ "accent": "#5ae0b9",
+ "background": "#f5f3f5",
+ "text": "#151515",
+ "is_dark": false,
+ "palette_type": "split_complementary"
+ },
+ "fonts": {
+ "heading": [
+ "oxygen",
+ "OFL",
+ "sans-serif"
+ ],
+ "body": [
+ "Merriweather",
+ "OFL",
+ "serif"
+ ],
+ "code": [
+ "intelone-mono",
+ "OFL",
+ "monospace"
+ ]
+ }
+ },
+ {
+ "name": "vibrant_storm",
+ "layout": "terminal",
+ "colors": {
+ "primary": "#b3de37",
+ "secondary": "#67d640",
+ "accent": "#d7af23",
+ "background": "#efefec",
+ "text": "#161616",
+ "is_dark": false,
+ "palette_type": "analogous"
+ },
+ "fonts": {
+ "heading": [
+ "zai-aeg-mignon-typewriter-1924",
+ "Free",
+ "display"
+ ],
+ "body": [
+ "roboto-slab",
+ "Apache",
+ "serif"
+ ],
+ "code": [
+ "hack",
+ "MIT",
+ "monospace"
+ ]
+ }
+ },
+ {
+ "name": "pure_storm",
+ "layout": "wide",
+ "colors": {
+ "primary": "#df3549",
+ "secondary": "#d6753d",
+ "accent": "#d6218d",
+ "background": "#261f1f",
+ "text": "#e5e5e5",
+ "is_dark": true,
+ "palette_type": "analogous"
+ },
+ "fonts": {
+ "heading": [
+ "higher-jump",
+ "Free",
+ "display"
+ ],
+ "body": [
+ "Lato",
+ "OFL",
+ "sans-serif"
+ ],
+ "code": [
+ "consola-mono",
+ "OFL",
+ "monospace"
+ ]
+ }
+ },
+ {
+ "name": "cool_breeze",
+ "layout": "technical",
+ "colors": {
+ "primary": "#299717",
+ "secondary": "#236119",
+ "accent": "#47973b",
+ "background": "#0c0e0b",
+ "text": "#dfdfdf",
+ "is_dark": true,
+ "palette_type": "monochromatic"
+ },
+ "fonts": {
+ "heading": [
+ "Abril_Fatface",
+ "OFL",
+ "display"
+ ],
+ "body": [
+ "Merriweather",
+ "OFL",
+ "serif"
+ ],
+ "code": [
+ "hack",
+ "MIT",
+ "monospace"
+ ]
+ }
+ },
+ {
+ "name": "ethereal_mist",
+ "layout": "hero",
+ "colors": {
+ "primary": "#9b3f1e",
+ "secondary": "#2b8e79",
+ "accent": "#2b448e",
+ "background": "#f0eeed",
+ "text": "#191919",
+ "is_dark": false,
+ "palette_type": "split_complementary"
+ },
+ "fonts": {
+ "heading": [
+ "pixelon",
+ "Free",
+ "display"
+ ],
+ "body": [
+ "oxygen",
+ "OFL",
+ "sans-serif"
+ ],
+ "code": [
+ "hack",
+ "MIT",
+ "monospace"
+ ]
+ }
+ },
+ {
+ "name": "modern_rhythm",
+ "layout": "floating",
+ "colors": {
+ "primary": "#22ef87",
+ "secondary": "#1da25e",
+ "accent": "#74d3a3",
+ "background": "#1f2723",
+ "text": "#e8e8e8",
+ "is_dark": true,
+ "palette_type": "monochromatic"
+ },
+ "fonts": {
+ "heading": [
+ "repetition-scrolling",
+ "Free",
+ "display"
+ ],
+ "body": [
+ "Merriweather",
+ "OFL",
+ "serif"
+ ],
+ "code": [
+ "intelone-mono",
+ "OFL",
+ "monospace"
+ ]
+ }
+ },
+ {
+ "name": "aurora_breeze",
+ "layout": "gradient",
+ "colors": {
+ "primary": "#c4a638",
+ "secondary": "#38c4a6",
+ "accent": "#a638c4",
+ "background": "#f1f0ee",
+ "text": "#0d0d0d",
+ "is_dark": false,
+ "palette_type": "triadic"
+ },
+ "fonts": {
+ "heading": [
+ "Merriweather",
+ "OFL",
+ "serif"
+ ],
+ "body": [
+ "oxygen",
+ "OFL",
+ "sans-serif"
+ ],
+ "code": [
+ "hack",
+ "MIT",
+ "monospace"
+ ]
+ }
+ },
+ {
+ "name": "muted_oasis",
+ "layout": "technical",
+ "colors": {
+ "primary": "#50d619",
+ "secondary": "#4e2cc3",
+ "accent": "#c32ca7",
+ "background": "#0e110e",
+ "text": "#e2e2e2",
+ "is_dark": true,
+ "palette_type": "split_complementary"
+ },
+ "fonts": {
+ "heading": [
+ "oxygen",
+ "OFL",
+ "sans-serif"
+ ],
+ "body": [
+ "Merriweather",
+ "OFL",
+ "serif"
+ ],
+ "code": [
+ "intelone-mono",
+ "OFL",
+ "monospace"
+ ]
+ }
+ },
+ {
+ "name": "ember_night",
+ "layout": "gradient",
+ "colors": {
+ "primary": "#e74654",
+ "secondary": "#ab2833",
+ "accent": "#d79398",
+ "background": "#292122",
+ "text": "#e1e1e1",
+ "is_dark": true,
+ "palette_type": "monochromatic"
+ },
+ "fonts": {
+ "heading": [
+ "zai-aeg-mignon-typewriter-1924",
+ "Free",
+ "display"
+ ],
+ "body": [
+ "roboto-slab",
+ "Apache",
+ "serif"
+ ],
+ "code": [
+ "hack",
+ "MIT",
+ "monospace"
+ ]
+ }
+ },
+ {
+ "name": "modern_storm",
+ "layout": "wide",
+ "colors": {
+ "primary": "#822121",
+ "secondary": "#2a7853",
+ "accent": "#2a5378",
+ "background": "#efecec",
+ "text": "#212121",
+ "is_dark": false,
+ "palette_type": "split_complementary"
+ },
+ "fonts": {
+ "heading": [
+ "roboto-slab",
+ "Apache",
+ "serif"
+ ],
+ "body": [
+ "oxygen",
+ "OFL",
+ "sans-serif"
+ ],
+ "code": [
+ "intelone-mono",
+ "OFL",
+ "monospace"
+ ]
+ }
+ },
+ {
+ "name": "amber_glacier",
+ "layout": "card",
+ "colors": {
+ "primary": "#49a06f",
+ "secondary": "#396a4e",
+ "accent": "#72a589",
+ "background": "#0f1311",
+ "text": "#e6e6e6",
+ "is_dark": true,
+ "palette_type": "monochromatic"
+ },
+ "fonts": {
+ "heading": [
+ "oxygen",
+ "OFL",
+ "sans-serif"
+ ],
+ "body": [
+ "Merriweather",
+ "OFL",
+ "serif"
+ ],
+ "code": [
+ "intelone-mono",
+ "OFL",
+ "monospace"
+ ]
+ }
+ },
+ {
+ "name": "twilight_horizon",
+ "layout": "sidebar",
+ "colors": {
+ "primary": "#34cbcd",
+ "secondary": "#2e8586",
+ "accent": "#76bebf",
+ "background": "#0e1111",
+ "text": "#e7e7e7",
+ "is_dark": true,
+ "palette_type": "monochromatic"
+ },
+ "fonts": {
+ "heading": [
+ "zai-aeg-mignon-typewriter-1924",
+ "Free",
+ "display"
+ ],
+ "body": [
+ "roboto-slab",
+ "Apache",
+ "serif"
+ ],
+ "code": [
+ "hack",
+ "MIT",
+ "monospace"
+ ]
+ }
+ },
+ {
+ "name": "gentle_glacier",
+ "layout": "card",
+ "colors": {
+ "primary": "#9e64c4",
+ "secondary": "#70428d",
+ "accent": "#b69dc6",
+ "background": "#edeaee",
+ "text": "#242424",
+ "is_dark": false,
+ "palette_type": "monochromatic"
+ },
+ "fonts": {
+ "heading": [
+ "roboto-slab",
+ "Apache",
+ "serif"
+ ],
+ "body": [
+ "oxygen",
+ "OFL",
+ "sans-serif"
+ ],
+ "code": [
+ "intelone-mono",
+ "OFL",
+ "monospace"
+ ]
+ }
+ },
+ {
+ "name": "deep_sky",
+ "layout": "artistic",
+ "colors": {
+ "primary": "#980c4e",
+ "secondary": "#911413",
+ "accent": "#880b82",
+ "background": "#f0edee",
+ "text": "#1d1d1d",
+ "is_dark": false,
+ "palette_type": "analogous"
+ },
+ "fonts": {
+ "heading": [
+ "Merriweather",
+ "OFL",
+ "serif"
+ ],
+ "body": [
+ "roboto-slab",
+ "Apache",
+ "serif"
+ ],
+ "code": [
+ "hack",
+ "MIT",
+ "monospace"
+ ]
+ }
+ },
+ {
+ "name": "smooth_echo",
+ "layout": "wide",
+ "colors": {
+ "primary": "#a89d12",
+ "secondary": "#212b99",
+ "accent": "#6f6926",
+ "background": "#f2f1ef",
+ "text": "#141414",
+ "is_dark": false,
+ "palette_type": "complementary"
+ },
+ "fonts": {
+ "heading": [
+ "pixelon",
+ "Free",
+ "display"
+ ],
+ "body": [
+ "oxygen",
+ "OFL",
+ "sans-serif"
+ ],
+ "code": [
+ "hack",
+ "MIT",
+ "monospace"
+ ]
+ }
+ },
+ {
+ "name": "refined_aurora",
+ "layout": "hero",
+ "colors": {
+ "primary": "#3186b1",
+ "secondary": "#a43e4d",
+ "accent": "#a4913e",
+ "background": "#e9eced",
+ "text": "#1c1c1c",
+ "is_dark": false,
+ "palette_type": "split_complementary"
+ },
+ "fonts": {
+ "heading": [
+ "Abril_Fatface",
+ "OFL",
+ "display"
+ ],
+ "body": [
+ "Lato",
+ "OFL",
+ "sans-serif"
+ ],
+ "code": [
+ "consola-mono",
+ "OFL",
+ "monospace"
+ ]
+ }
+ },
+ {
+ "name": "radiant_voyage",
+ "layout": "terminal",
+ "colors": {
+ "primary": "#cf5ddf",
+ "secondary": "#a8d26a",
+ "accent": "#6ad28f",
+ "background": "#f6f4f6",
+ "text": "#1f1f1f",
+ "is_dark": false,
+ "palette_type": "split_complementary"
+ },
+ "fonts": {
+ "heading": [
+ "oxygen",
+ "OFL",
+ "sans-serif"
+ ],
+ "body": [
+ "Merriweather",
+ "OFL",
+ "serif"
+ ],
+ "code": [
+ "intelone-mono",
+ "OFL",
+ "monospace"
+ ]
+ }
+ },
+ {
+ "name": "cosmic_odyssey",
+ "layout": "gradient",
+ "colors": {
+ "primary": "#7763f3",
+ "secondary": "#3c25ca",
+ "accent": "#bbb4e7",
+ "background": "#ececef",
+ "text": "#191919",
+ "is_dark": false,
+ "palette_type": "monochromatic"
+ },
+ "fonts": {
+ "heading": [
+ "oxygen",
+ "OFL",
+ "sans-serif"
+ ],
+ "body": [
+ "Lato",
+ "OFL",
+ "sans-serif"
+ ],
+ "code": [
+ "hack",
+ "MIT",
+ "monospace"
+ ]
+ }
+ },
+ {
+ "name": "neon_storm",
+ "layout": "retro",
+ "colors": {
+ "primary": "#1ca93a",
+ "secondary": "#1d6c2e",
+ "accent": "#44a959",
+ "background": "#edf0ee",
+ "text": "#171717",
+ "is_dark": false,
+ "palette_type": "monochromatic"
+ },
+ "fonts": {
+ "heading": [
+ "Abril_Fatface",
+ "OFL",
+ "display"
+ ],
+ "body": [
+ "Merriweather",
+ "OFL",
+ "serif"
+ ],
+ "code": [
+ "hack",
+ "MIT",
+ "monospace"
+ ]
+ }
+ },
+ {
+ "name": "cosmic_dusk",
+ "layout": "terminal",
+ "colors": {
+ "primary": "#a1cc51",
+ "secondary": "#5d6ac0",
+ "accent": "#af5dc0",
+ "background": "#eff0ed",
+ "text": "#232323",
+ "is_dark": false,
+ "palette_type": "split_complementary"
+ },
+ "fonts": {
+ "heading": [
+ "khand",
+ "Free",
+ "handwriting"
+ ],
+ "body": [
+ "Lato",
+ "OFL",
+ "sans-serif"
+ ],
+ "code": [
+ "consola-mono",
+ "OFL",
+ "monospace"
+ ]
+ }
+ },
+ {
+ "name": "cozy_crystal",
+ "layout": "brutalist",
+ "colors": {
+ "primary": "#22ac18",
+ "secondary": "#95279d",
+ "accent": "#30722b",
+ "background": "#eff1ef",
+ "text": "#1d1d1d",
+ "is_dark": false,
+ "palette_type": "complementary"
+ },
+ "fonts": {
+ "heading": [
+ "zai-aeg-mignon-typewriter-1924",
+ "Free",
+ "display"
+ ],
+ "body": [
+ "roboto-slab",
+ "Apache",
+ "serif"
+ ],
+ "code": [
+ "hack",
+ "MIT",
+ "monospace"
+ ]
+ }
+ },
+ {
+ "name": "clean_rhythm",
+ "layout": "future",
+ "colors": {
+ "primary": "#c76399",
+ "secondary": "#6ebd6d",
+ "accent": "#6dbdb9",
+ "background": "#edeaec",
+ "text": "#252525",
+ "is_dark": false,
+ "palette_type": "split_complementary"
+ },
+ "fonts": {
+ "heading": [
+ "Merriweather",
+ "OFL",
+ "serif"
+ ],
+ "body": [
+ "oxygen",
+ "OFL",
+ "sans-serif"
+ ],
+ "code": [
+ "hack",
+ "MIT",
+ "monospace"
+ ]
+ }
+ },
+ {
+ "name": "pastel_canyon",
+ "layout": "sidebar",
+ "colors": {
+ "primary": "#db7b55",
+ "secondary": "#d5b85b",
+ "accent": "#d63b59",
+ "background": "#0f0d0c",
+ "text": "#eeeeee",
+ "is_dark": true,
+ "palette_type": "analogous"
+ },
+ "fonts": {
+ "heading": [
+ "Merriweather",
+ "OFL",
+ "serif"
+ ],
+ "body": [
+ "roboto-slab",
+ "Apache",
+ "serif"
+ ],
+ "code": [
+ "hack",
+ "MIT",
+ "monospace"
+ ]
+ }
+ },
+ {
+ "name": "clean_garden",
+ "layout": "hero",
+ "colors": {
+ "primary": "#ecaf10",
+ "secondary": "#b9e11b",
+ "accent": "#d43e0e",
+ "background": "#282620",
+ "text": "#d9d9d9",
+ "is_dark": true,
+ "palette_type": "analogous"
+ },
+ "fonts": {
+ "heading": [
+ "Abril_Fatface",
+ "OFL",
+ "display"
+ ],
+ "body": [
+ "Merriweather",
+ "OFL",
+ "serif"
+ ],
+ "code": [
+ "hack",
+ "MIT",
+ "monospace"
+ ]
+ }
+ },
+ {
+ "name": "twilight_meadow",
+ "layout": "swiss",
+ "colors": {
+ "primary": "#88c599",
+ "secondary": "#bf8eb1",
+ "accent": "#6c9e7a",
+ "background": "#edf0ee",
+ "text": "#232323",
+ "is_dark": false,
+ "palette_type": "complementary"
+ },
+ "fonts": {
+ "heading": [
+ "roboto-slab",
+ "Apache",
+ "serif"
+ ],
+ "body": [
+ "oxygen",
+ "OFL",
+ "sans-serif"
+ ],
+ "code": [
+ "intelone-mono",
+ "OFL",
+ "monospace"
+ ]
+ }
+ },
+ {
+ "name": "bright_spark",
+ "layout": "newspaper",
+ "colors": {
+ "primary": "#4d8596",
+ "secondary": "#8f6254",
+ "accent": "#49646c",
+ "background": "#181d1e",
+ "text": "#dedede",
+ "is_dark": true,
+ "palette_type": "complementary"
+ },
+ "fonts": {
+ "heading": [
+ "roboto-slab",
+ "Apache",
+ "serif"
+ ],
+ "body": [
+ "oxygen",
+ "OFL",
+ "sans-serif"
+ ],
+ "code": [
+ "intelone-mono",
+ "OFL",
+ "monospace"
+ ]
+ }
+ }
+] \ No newline at end of file
diff --git a/extras/html/themes/twilight_horizon/LICENSE b/extras/html/themes/twilight_horizon/LICENSE
new file mode 100644
index 0000000..f82d535
--- /dev/null
+++ b/extras/html/themes/twilight_horizon/LICENSE
@@ -0,0 +1,21 @@
+Theme: twilight_horizon
+Generated: 2025-06-22 21:38:55
+
+Layout: sidebar
+Color Scheme: monochromatic (Dark)
+
+Font Licenses:
+==============
+Heading Font: zai-aeg-mignon-typewriter-1924
+License: Free
+Category: display
+
+Body Font: roboto-slab
+License: Apache
+Category: serif
+
+Code Font: hack
+License: MIT
+Category: monospace
+
+All fonts are free for personal use.
diff --git a/extras/html/themes/twilight_horizon/code.ttf b/extras/html/themes/twilight_horizon/code.ttf
new file mode 100644
index 0000000..7c8e65b
--- /dev/null
+++ b/extras/html/themes/twilight_horizon/code.ttf
Binary files differ
diff --git a/extras/html/themes/twilight_horizon/example.html b/extras/html/themes/twilight_horizon/example.html
new file mode 100644
index 0000000..043a2e7
--- /dev/null
+++ b/extras/html/themes/twilight_horizon/example.html
@@ -0,0 +1,75 @@
+<!DOCTYPE html>
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
+<head>
+ <meta charset="UTF-8" />
+ <meta name="viewport" content="width=device-width, initial-scale=1.0" />
+ <title>Twilight Horizon - Gemtexter Theme</title>
+ <link rel="stylesheet" href="style.css" />
+</head>
+<body>
+ <div class="header">
+ <h1>Twilight Horizon</h1>
+ <p>A sidebar layout with monochromatic colors</p>
+ </div>
+
+ <div class="content">
+ <h1>Welcome to Twilight Horizon</h1>
+ <p>This theme features a carefully crafted sidebar layout with a dark monochromatic color scheme. The typography combines display fonts for headings with serif for body text.</p>
+
+ <h2>Typography Showcase</h2>
+ <p>The roboto-slab font family provides excellent readability for body text, while zai-aeg-mignon-typewriter-1924 adds character to headings. Code blocks use hack for clarity.</p>
+
+ <h2>Color Palette</h2>
+ <p>Primary: <span style="color: #34cbcd; font-weight: bold;">#34cbcd</span> |
+ Secondary: <span style="color: #2e8586; font-weight: bold;">#2e8586</span> |
+ Accent: <span style="color: #76bebf; font-weight: bold;">#76bebf</span></p>
+
+ <h3>Interactive Elements</h3>
+ <p>Links like <a href="#">this example</a> and longer <a href="#" class="textlink">text links that demonstrate the theme's navigation style</a> use the secondary color.</p>
+
+ <div class="quote">
+ "Design is not just what it looks like and feels like. Design is how it works." — Steve Jobs
+ </div>
+
+ <h3>Code Examples</h3>
+ <p>Inline code like <code>theme.generate()</code> and larger blocks:</p>
+ <pre>// Theme configuration
+const theme = {
+ name: "twilight_horizon",
+ layout: "sidebar",
+ colors: {
+ primary: "#34cbcd",
+ secondary: "#2e8586",
+ accent: "#76bebf"
+ },
+ fonts: {
+ heading: "zai-aeg-mignon-typewriter-1924",
+ body: "roboto-slab",
+ code: "hack"
+ }
+};</pre>
+
+ <h2>Content Structure</h2>
+ <ul>
+ <li>Clean, readable typography with 14px base font size</li>
+ <li>Heading scale ratio of 2.37x for visual hierarchy</li>
+ <li>Line height of 1.49 for comfortable reading</li>
+ <li>Sidebar layout optimized for content flow</li>
+ <li>Dark theme with monochromatic color harmony</li>
+ </ul>
+
+ <h2>Font Licensing</h2>
+ <p>All fonts used in this theme are properly licensed:</p>
+ <ul>
+ <li>zai-aeg-mignon-typewriter-1924: Free License</li>
+ <li>roboto-slab: Apache License</li>
+ <li>hack: MIT License</li>
+ </ul>
+
+ <h3>Final Thoughts</h3>
+ <p>Every element of this theme has been carefully designed to create a harmonious reading experience. The sidebar layout ensures content is presented in an engaging way, while the color scheme provides the perfect backdrop for your words to shine.</p>
+
+ <p>Whether you're writing technical documentation, creative prose, or anything in between, this theme adapts to showcase your content beautifully.</p>
+ </div>
+</body>
+</html> \ No newline at end of file
diff --git a/extras/html/themes/twilight_horizon/handnotes.ttf b/extras/html/themes/twilight_horizon/handnotes.ttf
new file mode 100644
index 0000000..25e688b
--- /dev/null
+++ b/extras/html/themes/twilight_horizon/handnotes.ttf
Binary files differ
diff --git a/extras/html/themes/twilight_horizon/heading.ttf b/extras/html/themes/twilight_horizon/heading.ttf
new file mode 100644
index 0000000..375978c
--- /dev/null
+++ b/extras/html/themes/twilight_horizon/heading.ttf
Binary files differ
diff --git a/extras/html/themes/twilight_horizon/style.css b/extras/html/themes/twilight_horizon/style.css
new file mode 100644
index 0000000..0c2f9dd
--- /dev/null
+++ b/extras/html/themes/twilight_horizon/style.css
@@ -0,0 +1,173 @@
+/* Base styles */
+@font-face {
+ font-family: 'text';
+ src: url("./text.ttf") format("truetype");
+}
+
+@font-face {
+ font-family: 'heading';
+ src: url("./heading.ttf") format("truetype");
+}
+
+@font-face {
+ font-family: 'code';
+ src: url("./code.ttf") format("truetype");
+}
+
+@font-face {
+ font-family: 'handnotes';
+ src: url("./handnotes.ttf") format("truetype");
+}
+
+:root {
+ --color-primary: #34cbcd;
+ --color-secondary: #2e8586;
+ --color-accent: #76bebf;
+ --color-bg: #0e1111;
+ --color-text: #e7e7e7;
+ --font-size-base: 14px;
+ --font-size-h1: 2.37em;
+ --font-size-h2: 1.78em;
+ --font-size-h3: 1.33em;
+ --line-height: 1.49;
+}
+
+* {
+ box-sizing: border-box;
+}
+
+html {
+ font-size: var(--font-size-base);
+ -webkit-font-smoothing: antialiased;
+ -moz-osx-font-smoothing: grayscale;
+}
+
+body {
+ font-family: text, sans-serif;
+ background-color: var(--color-bg);
+ color: var(--color-text);
+ line-height: var(--line-height);
+ margin: 0;
+ padding: 0;
+ overflow-wrap: break-word;
+}
+
+h1, h2, h3 {
+ font-family: heading, serif;
+ line-height: 1.2;
+ margin-top: 1em;
+ margin-bottom: 0.5em;
+}
+
+h1 {
+ font-size: var(--font-size-h1);
+ color: var(--color-primary);
+}
+
+h2 {
+ font-size: var(--font-size-h2);
+ color: var(--color-primary);
+}
+
+h3 {
+ font-size: var(--font-size-h3);
+ color: var(--color-secondary);
+}
+
+a {
+ font-family: code, monospace;
+ color: var(--color-secondary);
+ text-decoration: none;
+ transition: all 0.3s ease;
+}
+
+a:hover {
+ color: var(--color-accent);
+ text-decoration: underline;
+}
+
+.textlink {
+ font-family: text, sans-serif;
+}
+
+.quote {
+ font-family: handnotes, cursive;
+ border-left: 4px solid var(--color-accent);
+ padding: 1em 1.5em;
+ margin: 1.5em 0;
+ background-color: rgba(52, 203, 205, 0.07);
+ font-style: italic;
+}
+
+pre {
+ font-family: code, monospace;
+ background-color: rgba(231, 231, 231, 0.04);
+ border: 1px solid rgba(231, 231, 231, 0.13);
+ padding: 1em;
+ overflow-x: auto;
+ border-radius: 4px;
+ font-size: 0.9em;
+}
+
+code {
+ font-family: code, monospace;
+ background-color: rgba(231, 231, 231, 0.04);
+ padding: 0.2em 0.4em;
+ border-radius: 3px;
+ font-size: 0.9em;
+}
+
+ul, ol {
+ padding-left: 2em;
+ margin: 1em 0;
+}
+
+li {
+ margin: 0.5em 0;
+}
+
+img {
+ max-width: 100%;
+ height: auto;
+}
+
+hr {
+ border: none;
+ border-top: 1px solid rgba(231, 231, 231, 0.20);
+ margin: 2em 0;
+}
+
+
+/* Layout: sidebar */
+
+body {
+ display: grid;
+ grid-template-columns: 300px 1fr;
+ min-height: 100vh;
+ margin: 0;
+}
+
+.header {
+ grid-column: 1;
+ position: sticky;
+ top: 0;
+ height: 100vh;
+ padding: 3em 2em;
+ background-color: var(--color-primary);
+ color: var(--color-bg);
+ overflow-y: auto;
+}
+
+.header h1 {
+ color: var(--color-bg);
+}
+
+.content {
+ grid-column: 2;
+ padding: 3em;
+ max-width: 65ch;
+}
+
+h1, h2, h3, p, ul, pre, .quote {
+ grid-column: 2;
+}
diff --git a/extras/html/themes/twilight_horizon/theme.conf b/extras/html/themes/twilight_horizon/theme.conf
new file mode 100644
index 0000000..b620ed7
--- /dev/null
+++ b/extras/html/themes/twilight_horizon/theme.conf
@@ -0,0 +1,8 @@
+declare -xr HTML_HEADER=./extras/html/header.html.part
+declare -xr HTML_FOOTER=./extras/html/footer.html.part
+declare -xr HTML_CSS_STYLE=$HTML_THEME_DIR/style.css
+declare -xr HTML_WEBFONT_HEADING=./extras/html/fonts/zai-aeg-mignon-typewriter-1924/zai-aeg-mignon-typewriter-1924-Bold.ttf
+declare -xr HTML_WEBFONT_TEXT=./extras/html/fonts/roboto-slab/roboto-slab-Regular.ttf
+declare -xr HTML_WEBFONT_CODE=./extras/html/fonts/hack/hack-Regular.ttf
+declare -xr HTML_WEBFONT_HANDNOTES=./extras/html/fonts/khand/khand.ttf
+declare -xr SOURCE_HIGHLIGHT_CSS=./extras/html/source-highlight-styles/mono.css
diff --git a/extras/html/themes/twilight_meadow/LICENSE b/extras/html/themes/twilight_meadow/LICENSE
new file mode 100644
index 0000000..b0de9bb
--- /dev/null
+++ b/extras/html/themes/twilight_meadow/LICENSE
@@ -0,0 +1,21 @@
+Theme: twilight_meadow
+Generated: 2025-06-22 21:38:55
+
+Layout: swiss
+Color Scheme: complementary (Light)
+
+Font Licenses:
+==============
+Heading Font: roboto-slab
+License: Apache
+Category: serif
+
+Body Font: oxygen
+License: OFL
+Category: sans-serif
+
+Code Font: intelone-mono
+License: OFL
+Category: monospace
+
+All fonts are free for personal use.
diff --git a/extras/html/themes/twilight_meadow/code.ttf b/extras/html/themes/twilight_meadow/code.ttf
new file mode 100644
index 0000000..2711179
--- /dev/null
+++ b/extras/html/themes/twilight_meadow/code.ttf
Binary files differ
diff --git a/extras/html/themes/twilight_meadow/example.html b/extras/html/themes/twilight_meadow/example.html
new file mode 100644
index 0000000..ee5dd34
--- /dev/null
+++ b/extras/html/themes/twilight_meadow/example.html
@@ -0,0 +1,75 @@
+<!DOCTYPE html>
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
+<head>
+ <meta charset="UTF-8" />
+ <meta name="viewport" content="width=device-width, initial-scale=1.0" />
+ <title>Twilight Meadow - Gemtexter Theme</title>
+ <link rel="stylesheet" href="style.css" />
+</head>
+<body>
+ <div class="header">
+ <h1>Twilight Meadow</h1>
+ <p>A swiss layout with complementary colors</p>
+ </div>
+
+ <div class="content">
+ <h1>Welcome to Twilight Meadow</h1>
+ <p>This theme features a carefully crafted swiss layout with a light complementary color scheme. The typography combines serif fonts for headings with sans-serif for body text.</p>
+
+ <h2>Typography Showcase</h2>
+ <p>The oxygen font family provides excellent readability for body text, while roboto-slab adds character to headings. Code blocks use intelone-mono for clarity.</p>
+
+ <h2>Color Palette</h2>
+ <p>Primary: <span style="color: #88c599; font-weight: bold;">#88c599</span> |
+ Secondary: <span style="color: #bf8eb1; font-weight: bold;">#bf8eb1</span> |
+ Accent: <span style="color: #6c9e7a; font-weight: bold;">#6c9e7a</span></p>
+
+ <h3>Interactive Elements</h3>
+ <p>Links like <a href="#">this example</a> and longer <a href="#" class="textlink">text links that demonstrate the theme's navigation style</a> use the secondary color.</p>
+
+ <div class="quote">
+ "Design is not just what it looks like and feels like. Design is how it works." — Steve Jobs
+ </div>
+
+ <h3>Code Examples</h3>
+ <p>Inline code like <code>theme.generate()</code> and larger blocks:</p>
+ <pre>// Theme configuration
+const theme = {
+ name: "twilight_meadow",
+ layout: "swiss",
+ colors: {
+ primary: "#88c599",
+ secondary: "#bf8eb1",
+ accent: "#6c9e7a"
+ },
+ fonts: {
+ heading: "roboto-slab",
+ body: "oxygen",
+ code: "intelone-mono"
+ }
+};</pre>
+
+ <h2>Content Structure</h2>
+ <ul>
+ <li>Clean, readable typography with 18px base font size</li>
+ <li>Heading scale ratio of 2.37x for visual hierarchy</li>
+ <li>Line height of 1.48 for comfortable reading</li>
+ <li>Swiss layout optimized for content flow</li>
+ <li>Light theme with complementary color harmony</li>
+ </ul>
+
+ <h2>Font Licensing</h2>
+ <p>All fonts used in this theme are properly licensed:</p>
+ <ul>
+ <li>roboto-slab: Apache License</li>
+ <li>oxygen: OFL License</li>
+ <li>intelone-mono: OFL License</li>
+ </ul>
+
+ <h3>Final Thoughts</h3>
+ <p>Every element of this theme has been carefully designed to create a harmonious reading experience. The swiss layout ensures content is presented in an engaging way, while the color scheme provides the perfect backdrop for your words to shine.</p>
+
+ <p>Whether you're writing technical documentation, creative prose, or anything in between, this theme adapts to showcase your content beautifully.</p>
+ </div>
+</body>
+</html> \ No newline at end of file
diff --git a/extras/html/themes/twilight_meadow/handnotes.ttf b/extras/html/themes/twilight_meadow/handnotes.ttf
new file mode 100644
index 0000000..25e688b
--- /dev/null
+++ b/extras/html/themes/twilight_meadow/handnotes.ttf
Binary files differ
diff --git a/extras/html/themes/twilight_meadow/style.css b/extras/html/themes/twilight_meadow/style.css
new file mode 100644
index 0000000..847f468
--- /dev/null
+++ b/extras/html/themes/twilight_meadow/style.css
@@ -0,0 +1,198 @@
+/* Base styles */
+@font-face {
+ font-family: 'text';
+ src: url("./text.ttf") format("truetype");
+}
+
+@font-face {
+ font-family: 'heading';
+ src: url("./heading.ttf") format("truetype");
+}
+
+@font-face {
+ font-family: 'code';
+ src: url("./code.ttf") format("truetype");
+}
+
+@font-face {
+ font-family: 'handnotes';
+ src: url("./handnotes.ttf") format("truetype");
+}
+
+:root {
+ --color-primary: #88c599;
+ --color-secondary: #bf8eb1;
+ --color-accent: #6c9e7a;
+ --color-bg: #edf0ee;
+ --color-text: #232323;
+ --font-size-base: 18px;
+ --font-size-h1: 2.37em;
+ --font-size-h2: 1.78em;
+ --font-size-h3: 1.33em;
+ --line-height: 1.48;
+}
+
+* {
+ box-sizing: border-box;
+}
+
+html {
+ font-size: var(--font-size-base);
+ -webkit-font-smoothing: antialiased;
+ -moz-osx-font-smoothing: grayscale;
+}
+
+body {
+ font-family: text, sans-serif;
+ background-color: var(--color-bg);
+ color: var(--color-text);
+ line-height: var(--line-height);
+ margin: 0;
+ padding: 0;
+ overflow-wrap: break-word;
+}
+
+h1, h2, h3 {
+ font-family: heading, serif;
+ line-height: 1.2;
+ margin-top: 1em;
+ margin-bottom: 0.5em;
+}
+
+h1 {
+ font-size: var(--font-size-h1);
+ color: var(--color-primary);
+}
+
+h2 {
+ font-size: var(--font-size-h2);
+ color: var(--color-primary);
+}
+
+h3 {
+ font-size: var(--font-size-h3);
+ color: var(--color-secondary);
+}
+
+a {
+ font-family: code, monospace;
+ color: var(--color-secondary);
+ text-decoration: none;
+ transition: all 0.3s ease;
+}
+
+a:hover {
+ color: var(--color-accent);
+ text-decoration: underline;
+}
+
+.textlink {
+ font-family: text, sans-serif;
+}
+
+.quote {
+ font-family: handnotes, cursive;
+ border-left: 4px solid var(--color-accent);
+ padding: 1em 1.5em;
+ margin: 1.5em 0;
+ background-color: rgba(136, 197, 153, 0.07);
+ font-style: italic;
+}
+
+pre {
+ font-family: code, monospace;
+ background-color: rgba(35, 35, 35, 0.04);
+ border: 1px solid rgba(35, 35, 35, 0.13);
+ padding: 1em;
+ overflow-x: auto;
+ border-radius: 4px;
+ font-size: 0.9em;
+}
+
+code {
+ font-family: code, monospace;
+ background-color: rgba(35, 35, 35, 0.04);
+ padding: 0.2em 0.4em;
+ border-radius: 3px;
+ font-size: 0.9em;
+}
+
+ul, ol {
+ padding-left: 2em;
+ margin: 1em 0;
+}
+
+li {
+ margin: 0.5em 0;
+}
+
+img {
+ max-width: 100%;
+ height: auto;
+}
+
+hr {
+ border: none;
+ border-top: 1px solid rgba(35, 35, 35, 0.20);
+ margin: 2em 0;
+}
+
+
+/* Layout: swiss */
+
+body {
+ max-width: 1200px;
+ margin: 0 auto;
+ padding: 2em;
+ display: grid;
+ grid-template-columns: repeat(6, 1fr);
+ gap: 2em;
+}
+
+.header {
+ grid-column: 1 / -1;
+ display: grid;
+ grid-template-columns: repeat(6, 1fr);
+ gap: 2em;
+ margin-bottom: 4em;
+ padding-bottom: 2em;
+ border-bottom: 4px solid var(--color-text);
+}
+
+.header h1 {
+ grid-column: 1 / 4;
+ font-size: 4em;
+ margin: 0;
+ line-height: 0.9;
+}
+
+.header p {
+ grid-column: 4 / -1;
+ align-self: end;
+}
+
+h1 {
+ grid-column: 1 / -1;
+ font-size: 3em;
+ margin: 1em 0 0.5em 0;
+}
+
+h2 {
+ grid-column: 1 / 5;
+ margin-top: 2em;
+}
+
+h3 {
+ grid-column: 2 / 6;
+}
+
+p, ul, pre {
+ grid-column: 2 / 6;
+}
+
+.quote {
+ grid-column: 1 / -1;
+ font-size: 1.5em;
+ text-align: center;
+ margin: 2em 0;
+}
diff --git a/extras/html/themes/twilight_meadow/theme.conf b/extras/html/themes/twilight_meadow/theme.conf
new file mode 100644
index 0000000..19a2553
--- /dev/null
+++ b/extras/html/themes/twilight_meadow/theme.conf
@@ -0,0 +1,8 @@
+declare -xr HTML_HEADER=./extras/html/header.html.part
+declare -xr HTML_FOOTER=./extras/html/footer.html.part
+declare -xr HTML_CSS_STYLE=$HTML_THEME_DIR/style.css
+declare -xr HTML_WEBFONT_HEADING=./extras/html/fonts/roboto-slab/roboto-slab-Bold.ttf
+declare -xr HTML_WEBFONT_TEXT=./extras/html/fonts/oxygen/oxygen-Regular.ttf
+declare -xr HTML_WEBFONT_CODE=./extras/html/fonts/intelone-mono/intelone-mono-Regular.ttf
+declare -xr HTML_WEBFONT_HANDNOTES=./extras/html/fonts/khand/khand.ttf
+declare -xr SOURCE_HIGHLIGHT_CSS=./extras/html/source-highlight-styles/mono.css
diff --git a/extras/html/themes/twilight_nebula/LICENSE b/extras/html/themes/twilight_nebula/LICENSE
new file mode 100644
index 0000000..e9a9b99
--- /dev/null
+++ b/extras/html/themes/twilight_nebula/LICENSE
@@ -0,0 +1,21 @@
+Theme: twilight_nebula
+Generated: 2025-06-22 21:38:55
+
+Layout: brutalist
+Color Scheme: triadic (Dark)
+
+Font Licenses:
+==============
+Heading Font: oxygen
+License: OFL
+Category: sans-serif
+
+Body Font: Merriweather
+License: OFL
+Category: serif
+
+Code Font: intelone-mono
+License: OFL
+Category: monospace
+
+All fonts are free for personal use.
diff --git a/extras/html/themes/twilight_nebula/code.ttf b/extras/html/themes/twilight_nebula/code.ttf
new file mode 100644
index 0000000..2711179
--- /dev/null
+++ b/extras/html/themes/twilight_nebula/code.ttf
Binary files differ
diff --git a/extras/html/themes/twilight_nebula/example.html b/extras/html/themes/twilight_nebula/example.html
new file mode 100644
index 0000000..6ded3d7
--- /dev/null
+++ b/extras/html/themes/twilight_nebula/example.html
@@ -0,0 +1,75 @@
+<!DOCTYPE html>
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
+<head>
+ <meta charset="UTF-8" />
+ <meta name="viewport" content="width=device-width, initial-scale=1.0" />
+ <title>Twilight Nebula - Gemtexter Theme</title>
+ <link rel="stylesheet" href="style.css" />
+</head>
+<body>
+ <div class="header">
+ <h1>Twilight Nebula</h1>
+ <p>A brutalist layout with triadic colors</p>
+ </div>
+
+ <div class="content">
+ <h1>Welcome to Twilight Nebula</h1>
+ <p>This theme features a carefully crafted brutalist layout with a dark triadic color scheme. The typography combines sans-serif fonts for headings with serif for body text.</p>
+
+ <h2>Typography Showcase</h2>
+ <p>The Merriweather font family provides excellent readability for body text, while oxygen adds character to headings. Code blocks use intelone-mono for clarity.</p>
+
+ <h2>Color Palette</h2>
+ <p>Primary: <span style="color: #bd8487; font-weight: bold;">#bd8487</span> |
+ Secondary: <span style="color: #87bd84; font-weight: bold;">#87bd84</span> |
+ Accent: <span style="color: #8486bd; font-weight: bold;">#8486bd</span></p>
+
+ <h3>Interactive Elements</h3>
+ <p>Links like <a href="#">this example</a> and longer <a href="#" class="textlink">text links that demonstrate the theme's navigation style</a> use the secondary color.</p>
+
+ <div class="quote">
+ "Design is not just what it looks like and feels like. Design is how it works." — Steve Jobs
+ </div>
+
+ <h3>Code Examples</h3>
+ <p>Inline code like <code>theme.generate()</code> and larger blocks:</p>
+ <pre>// Theme configuration
+const theme = {
+ name: "twilight_nebula",
+ layout: "brutalist",
+ colors: {
+ primary: "#bd8487",
+ secondary: "#87bd84",
+ accent: "#8486bd"
+ },
+ fonts: {
+ heading: "oxygen",
+ body: "Merriweather",
+ code: "intelone-mono"
+ }
+};</pre>
+
+ <h2>Content Structure</h2>
+ <ul>
+ <li>Clean, readable typography with 14px base font size</li>
+ <li>Heading scale ratio of 1.95x for visual hierarchy</li>
+ <li>Line height of 1.7 for comfortable reading</li>
+ <li>Brutalist layout optimized for content flow</li>
+ <li>Dark theme with triadic color harmony</li>
+ </ul>
+
+ <h2>Font Licensing</h2>
+ <p>All fonts used in this theme are properly licensed:</p>
+ <ul>
+ <li>oxygen: OFL License</li>
+ <li>Merriweather: OFL License</li>
+ <li>intelone-mono: OFL License</li>
+ </ul>
+
+ <h3>Final Thoughts</h3>
+ <p>Every element of this theme has been carefully designed to create a harmonious reading experience. The brutalist layout ensures content is presented in an engaging way, while the color scheme provides the perfect backdrop for your words to shine.</p>
+
+ <p>Whether you're writing technical documentation, creative prose, or anything in between, this theme adapts to showcase your content beautifully.</p>
+ </div>
+</body>
+</html> \ No newline at end of file
diff --git a/extras/html/themes/twilight_nebula/handnotes.ttf b/extras/html/themes/twilight_nebula/handnotes.ttf
new file mode 100644
index 0000000..25e688b
--- /dev/null
+++ b/extras/html/themes/twilight_nebula/handnotes.ttf
Binary files differ
diff --git a/extras/html/themes/twilight_nebula/style.css b/extras/html/themes/twilight_nebula/style.css
new file mode 100644
index 0000000..aff817d
--- /dev/null
+++ b/extras/html/themes/twilight_nebula/style.css
@@ -0,0 +1,187 @@
+/* Base styles */
+@font-face {
+ font-family: 'text';
+ src: url("./text.ttf") format("truetype");
+}
+
+@font-face {
+ font-family: 'heading';
+ src: url("./heading.ttf") format("truetype");
+}
+
+@font-face {
+ font-family: 'code';
+ src: url("./code.ttf") format("truetype");
+}
+
+@font-face {
+ font-family: 'handnotes';
+ src: url("./handnotes.ttf") format("truetype");
+}
+
+:root {
+ --color-primary: #bd8487;
+ --color-secondary: #87bd84;
+ --color-accent: #8486bd;
+ --color-bg: #0f0c0c;
+ --color-text: #e3e3e3;
+ --font-size-base: 14px;
+ --font-size-h1: 1.95em;
+ --font-size-h2: 1.56em;
+ --font-size-h3: 1.25em;
+ --line-height: 1.7;
+}
+
+* {
+ box-sizing: border-box;
+}
+
+html {
+ font-size: var(--font-size-base);
+ -webkit-font-smoothing: antialiased;
+ -moz-osx-font-smoothing: grayscale;
+}
+
+body {
+ font-family: text, sans-serif;
+ background-color: var(--color-bg);
+ color: var(--color-text);
+ line-height: var(--line-height);
+ margin: 0;
+ padding: 0;
+ overflow-wrap: break-word;
+}
+
+h1, h2, h3 {
+ font-family: heading, serif;
+ line-height: 1.2;
+ margin-top: 1em;
+ margin-bottom: 0.5em;
+}
+
+h1 {
+ font-size: var(--font-size-h1);
+ color: var(--color-primary);
+}
+
+h2 {
+ font-size: var(--font-size-h2);
+ color: var(--color-primary);
+}
+
+h3 {
+ font-size: var(--font-size-h3);
+ color: var(--color-secondary);
+}
+
+a {
+ font-family: code, monospace;
+ color: var(--color-secondary);
+ text-decoration: none;
+ transition: all 0.3s ease;
+}
+
+a:hover {
+ color: var(--color-accent);
+ text-decoration: underline;
+}
+
+.textlink {
+ font-family: text, sans-serif;
+}
+
+.quote {
+ font-family: handnotes, cursive;
+ border-left: 4px solid var(--color-accent);
+ padding: 1em 1.5em;
+ margin: 1.5em 0;
+ background-color: rgba(189, 132, 135, 0.07);
+ font-style: italic;
+}
+
+pre {
+ font-family: code, monospace;
+ background-color: rgba(227, 227, 227, 0.04);
+ border: 1px solid rgba(227, 227, 227, 0.13);
+ padding: 1em;
+ overflow-x: auto;
+ border-radius: 4px;
+ font-size: 0.9em;
+}
+
+code {
+ font-family: code, monospace;
+ background-color: rgba(227, 227, 227, 0.04);
+ padding: 0.2em 0.4em;
+ border-radius: 3px;
+ font-size: 0.9em;
+}
+
+ul, ol {
+ padding-left: 2em;
+ margin: 1em 0;
+}
+
+li {
+ margin: 0.5em 0;
+}
+
+img {
+ max-width: 100%;
+ height: auto;
+}
+
+hr {
+ border: none;
+ border-top: 1px solid rgba(227, 227, 227, 0.20);
+ margin: 2em 0;
+}
+
+
+/* Layout: brutalist */
+
+body {
+ background-color: #e3e3e3;
+ color: #0f0c0c;
+ padding: 0;
+}
+
+.header {
+ background-color: var(--color-primary);
+ color: var(--color-bg);
+ padding: 4em 2em;
+ transform: skewY(-3deg);
+ margin-bottom: 4em;
+}
+
+.header * {
+ transform: skewY(3deg);
+}
+
+h1, h2, h3 {
+ background-color: var(--color-bg);
+ color: var(--color-text);
+ padding: 1em;
+ text-transform: uppercase;
+ letter-spacing: 0.2em;
+ margin: 0;
+}
+
+p, ul, pre, .quote {
+ background-color: var(--color-bg);
+ color: var(--color-text);
+ margin: 0;
+ padding: 2em;
+ border: 8px solid var(--color-primary);
+}
+
+a {
+ background-color: var(--color-secondary);
+ color: var(--color-bg);
+ padding: 0.3em 0.6em;
+ text-decoration: none;
+}
+
+a:hover {
+ background-color: var(--color-accent);
+}
diff --git a/extras/html/themes/twilight_nebula/text.ttf b/extras/html/themes/twilight_nebula/text.ttf
new file mode 100644
index 0000000..3fecc77
--- /dev/null
+++ b/extras/html/themes/twilight_nebula/text.ttf
Binary files differ
diff --git a/extras/html/themes/twilight_nebula/theme.conf b/extras/html/themes/twilight_nebula/theme.conf
new file mode 100644
index 0000000..11ad64d
--- /dev/null
+++ b/extras/html/themes/twilight_nebula/theme.conf
@@ -0,0 +1,8 @@
+declare -xr HTML_HEADER=./extras/html/header.html.part
+declare -xr HTML_FOOTER=./extras/html/footer.html.part
+declare -xr HTML_CSS_STYLE=$HTML_THEME_DIR/style.css
+declare -xr HTML_WEBFONT_HEADING=./extras/html/fonts/oxygen/oxygen-Bold.ttf
+declare -xr HTML_WEBFONT_TEXT=./extras/html/fonts/Merriweather/Merriweather-Regular.ttf
+declare -xr HTML_WEBFONT_CODE=./extras/html/fonts/intelone-mono/intelone-mono-Regular.ttf
+declare -xr HTML_WEBFONT_HANDNOTES=./extras/html/fonts/khand/khand.ttf
+declare -xr SOURCE_HIGHLIGHT_CSS=./extras/html/source-highlight-styles/mono.css
diff --git a/extras/html/themes/vibrant_garden/LICENSE b/extras/html/themes/vibrant_garden/LICENSE
new file mode 100644
index 0000000..d7fb03a
--- /dev/null
+++ b/extras/html/themes/vibrant_garden/LICENSE
@@ -0,0 +1,21 @@
+Theme: vibrant_garden
+Generated: 2025-06-22 21:38:55
+
+Layout: overlap
+Color Scheme: monochromatic (Light)
+
+Font Licenses:
+==============
+Heading Font: repetition-scrolling
+License: Free
+Category: display
+
+Body Font: Merriweather
+License: OFL
+Category: serif
+
+Code Font: intelone-mono
+License: OFL
+Category: monospace
+
+All fonts are free for personal use.
diff --git a/extras/html/themes/vibrant_garden/code.ttf b/extras/html/themes/vibrant_garden/code.ttf
new file mode 100644
index 0000000..2711179
--- /dev/null
+++ b/extras/html/themes/vibrant_garden/code.ttf
Binary files differ
diff --git a/extras/html/themes/vibrant_garden/example.html b/extras/html/themes/vibrant_garden/example.html
new file mode 100644
index 0000000..121b26f
--- /dev/null
+++ b/extras/html/themes/vibrant_garden/example.html
@@ -0,0 +1,75 @@
+<!DOCTYPE html>
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
+<head>
+ <meta charset="UTF-8" />
+ <meta name="viewport" content="width=device-width, initial-scale=1.0" />
+ <title>Vibrant Garden - Gemtexter Theme</title>
+ <link rel="stylesheet" href="style.css" />
+</head>
+<body>
+ <div class="header">
+ <h1>Vibrant Garden</h1>
+ <p>A overlap layout with monochromatic colors</p>
+ </div>
+
+ <div class="content">
+ <h1>Welcome to Vibrant Garden</h1>
+ <p>This theme features a carefully crafted overlap layout with a light monochromatic color scheme. The typography combines display fonts for headings with serif for body text.</p>
+
+ <h2>Typography Showcase</h2>
+ <p>The Merriweather font family provides excellent readability for body text, while repetition-scrolling adds character to headings. Code blocks use intelone-mono for clarity.</p>
+
+ <h2>Color Palette</h2>
+ <p>Primary: <span style="color: #bd7f21; font-weight: bold;">#bd7f21</span> |
+ Secondary: <span style="color: #795622; font-weight: bold;">#795622</span> |
+ Accent: <span style="color: #b88f52; font-weight: bold;">#b88f52</span></p>
+
+ <h3>Interactive Elements</h3>
+ <p>Links like <a href="#">this example</a> and longer <a href="#" class="textlink">text links that demonstrate the theme's navigation style</a> use the secondary color.</p>
+
+ <div class="quote">
+ "Design is not just what it looks like and feels like. Design is how it works." — Steve Jobs
+ </div>
+
+ <h3>Code Examples</h3>
+ <p>Inline code like <code>theme.generate()</code> and larger blocks:</p>
+ <pre>// Theme configuration
+const theme = {
+ name: "vibrant_garden",
+ layout: "overlap",
+ colors: {
+ primary: "#bd7f21",
+ secondary: "#795622",
+ accent: "#b88f52"
+ },
+ fonts: {
+ heading: "repetition-scrolling",
+ body: "Merriweather",
+ code: "intelone-mono"
+ }
+};</pre>
+
+ <h2>Content Structure</h2>
+ <ul>
+ <li>Clean, readable typography with 14px base font size</li>
+ <li>Heading scale ratio of 1.42x for visual hierarchy</li>
+ <li>Line height of 1.61 for comfortable reading</li>
+ <li>Overlap layout optimized for content flow</li>
+ <li>Light theme with monochromatic color harmony</li>
+ </ul>
+
+ <h2>Font Licensing</h2>
+ <p>All fonts used in this theme are properly licensed:</p>
+ <ul>
+ <li>repetition-scrolling: Free License</li>
+ <li>Merriweather: OFL License</li>
+ <li>intelone-mono: OFL License</li>
+ </ul>
+
+ <h3>Final Thoughts</h3>
+ <p>Every element of this theme has been carefully designed to create a harmonious reading experience. The overlap layout ensures content is presented in an engaging way, while the color scheme provides the perfect backdrop for your words to shine.</p>
+
+ <p>Whether you're writing technical documentation, creative prose, or anything in between, this theme adapts to showcase your content beautifully.</p>
+ </div>
+</body>
+</html> \ No newline at end of file
diff --git a/extras/html/themes/vibrant_garden/handnotes.ttf b/extras/html/themes/vibrant_garden/handnotes.ttf
new file mode 100644
index 0000000..25e688b
--- /dev/null
+++ b/extras/html/themes/vibrant_garden/handnotes.ttf
Binary files differ
diff --git a/extras/html/themes/vibrant_garden/heading.ttf b/extras/html/themes/vibrant_garden/heading.ttf
new file mode 100644
index 0000000..1d0a401
--- /dev/null
+++ b/extras/html/themes/vibrant_garden/heading.ttf
Binary files differ
diff --git a/extras/html/themes/vibrant_garden/style.css b/extras/html/themes/vibrant_garden/style.css
new file mode 100644
index 0000000..affe29f
--- /dev/null
+++ b/extras/html/themes/vibrant_garden/style.css
@@ -0,0 +1,196 @@
+/* Base styles */
+@font-face {
+ font-family: 'text';
+ src: url("./text.ttf") format("truetype");
+}
+
+@font-face {
+ font-family: 'heading';
+ src: url("./heading.ttf") format("truetype");
+}
+
+@font-face {
+ font-family: 'code';
+ src: url("./code.ttf") format("truetype");
+}
+
+@font-face {
+ font-family: 'handnotes';
+ src: url("./handnotes.ttf") format("truetype");
+}
+
+:root {
+ --color-primary: #bd7f21;
+ --color-secondary: #795622;
+ --color-accent: #b88f52;
+ --color-bg: #f5f4f2;
+ --color-text: #1d1d1d;
+ --font-size-base: 14px;
+ --font-size-h1: 1.42em;
+ --font-size-h2: 1.27em;
+ --font-size-h3: 1.12em;
+ --line-height: 1.61;
+}
+
+* {
+ box-sizing: border-box;
+}
+
+html {
+ font-size: var(--font-size-base);
+ -webkit-font-smoothing: antialiased;
+ -moz-osx-font-smoothing: grayscale;
+}
+
+body {
+ font-family: text, sans-serif;
+ background-color: var(--color-bg);
+ color: var(--color-text);
+ line-height: var(--line-height);
+ margin: 0;
+ padding: 0;
+ overflow-wrap: break-word;
+}
+
+h1, h2, h3 {
+ font-family: heading, serif;
+ line-height: 1.2;
+ margin-top: 1em;
+ margin-bottom: 0.5em;
+}
+
+h1 {
+ font-size: var(--font-size-h1);
+ color: var(--color-primary);
+}
+
+h2 {
+ font-size: var(--font-size-h2);
+ color: var(--color-primary);
+}
+
+h3 {
+ font-size: var(--font-size-h3);
+ color: var(--color-secondary);
+}
+
+a {
+ font-family: code, monospace;
+ color: var(--color-secondary);
+ text-decoration: none;
+ transition: all 0.3s ease;
+}
+
+a:hover {
+ color: var(--color-accent);
+ text-decoration: underline;
+}
+
+.textlink {
+ font-family: text, sans-serif;
+}
+
+.quote {
+ font-family: handnotes, cursive;
+ border-left: 4px solid var(--color-accent);
+ padding: 1em 1.5em;
+ margin: 1.5em 0;
+ background-color: rgba(189, 127, 33, 0.07);
+ font-style: italic;
+}
+
+pre {
+ font-family: code, monospace;
+ background-color: rgba(29, 29, 29, 0.04);
+ border: 1px solid rgba(29, 29, 29, 0.13);
+ padding: 1em;
+ overflow-x: auto;
+ border-radius: 4px;
+ font-size: 0.9em;
+}
+
+code {
+ font-family: code, monospace;
+ background-color: rgba(29, 29, 29, 0.04);
+ padding: 0.2em 0.4em;
+ border-radius: 3px;
+ font-size: 0.9em;
+}
+
+ul, ol {
+ padding-left: 2em;
+ margin: 1em 0;
+}
+
+li {
+ margin: 0.5em 0;
+}
+
+img {
+ max-width: 100%;
+ height: auto;
+}
+
+hr {
+ border: none;
+ border-top: 1px solid rgba(29, 29, 29, 0.20);
+ margin: 2em 0;
+}
+
+
+/* Layout: overlap */
+
+body {
+ padding: 2em;
+ position: relative;
+ max-width: 1200px;
+ margin: 0 auto;
+}
+
+.header {
+ position: relative;
+ z-index: 10;
+ background-color: var(--color-bg);
+ padding: 3em;
+ margin-bottom: -2em;
+ box-shadow: 0 10px 40px rgba(0,0,0,0.1);
+ border: 2px solid var(--color-primary);
+}
+
+h1 {
+ font-size: 3.5em;
+ margin-top: 1em;
+ position: relative;
+ z-index: 5;
+}
+
+h2 {
+ margin-left: 2em;
+ position: relative;
+ z-index: 4;
+ background-color: var(--color-bg);
+ padding: 1em;
+ box-shadow: 0 4px 20px rgba(0,0,0,0.05);
+}
+
+h3 {
+ margin-left: 4em;
+ position: relative;
+ z-index: 3;
+}
+
+p, ul, pre, .quote {
+ position: relative;
+ background-color: var(--color-bg);
+ padding: 2em;
+ margin: 1em 0 1em 3em;
+ box-shadow: 0 4px 20px rgba(0,0,0,0.05);
+ border-left: 4px solid var(--color-accent);
+}
+
+p:nth-child(even), ul:nth-child(even) {
+ margin-left: 0;
+ margin-right: 3em;
+ border-left: none;
+ border-right: 4px solid var(--color-secondary);
+}
diff --git a/extras/html/themes/vibrant_garden/text.ttf b/extras/html/themes/vibrant_garden/text.ttf
new file mode 100644
index 0000000..3fecc77
--- /dev/null
+++ b/extras/html/themes/vibrant_garden/text.ttf
Binary files differ
diff --git a/extras/html/themes/vibrant_garden/theme.conf b/extras/html/themes/vibrant_garden/theme.conf
new file mode 100644
index 0000000..b571a24
--- /dev/null
+++ b/extras/html/themes/vibrant_garden/theme.conf
@@ -0,0 +1,8 @@
+declare -xr HTML_HEADER=./extras/html/header.html.part
+declare -xr HTML_FOOTER=./extras/html/footer.html.part
+declare -xr HTML_CSS_STYLE=$HTML_THEME_DIR/style.css
+declare -xr HTML_WEBFONT_HEADING=./extras/html/fonts/repetition-scrolling/repetition-scrolling-Bold.ttf
+declare -xr HTML_WEBFONT_TEXT=./extras/html/fonts/Merriweather/Merriweather-Regular.ttf
+declare -xr HTML_WEBFONT_CODE=./extras/html/fonts/intelone-mono/intelone-mono-Regular.ttf
+declare -xr HTML_WEBFONT_HANDNOTES=./extras/html/fonts/khand/khand.ttf
+declare -xr SOURCE_HIGHLIGHT_CSS=./extras/html/source-highlight-styles/mono.css
diff --git a/extras/html/themes/vibrant_nebula/LICENSE b/extras/html/themes/vibrant_nebula/LICENSE
new file mode 100644
index 0000000..5007e35
--- /dev/null
+++ b/extras/html/themes/vibrant_nebula/LICENSE
@@ -0,0 +1,21 @@
+Theme: vibrant_nebula
+Generated: 2025-06-22 21:38:55
+
+Layout: swiss
+Color Scheme: triadic (Light)
+
+Font Licenses:
+==============
+Heading Font: zai-aeg-mignon-typewriter-1924
+License: Free
+Category: display
+
+Body Font: roboto-slab
+License: Apache
+Category: serif
+
+Code Font: hack
+License: MIT
+Category: monospace
+
+All fonts are free for personal use.
diff --git a/extras/html/themes/vibrant_nebula/code.ttf b/extras/html/themes/vibrant_nebula/code.ttf
new file mode 100644
index 0000000..7c8e65b
--- /dev/null
+++ b/extras/html/themes/vibrant_nebula/code.ttf
Binary files differ
diff --git a/extras/html/themes/vibrant_nebula/example.html b/extras/html/themes/vibrant_nebula/example.html
new file mode 100644
index 0000000..6245312
--- /dev/null
+++ b/extras/html/themes/vibrant_nebula/example.html
@@ -0,0 +1,75 @@
+<!DOCTYPE html>
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
+<head>
+ <meta charset="UTF-8" />
+ <meta name="viewport" content="width=device-width, initial-scale=1.0" />
+ <title>Vibrant Nebula - Gemtexter Theme</title>
+ <link rel="stylesheet" href="style.css" />
+</head>
+<body>
+ <div class="header">
+ <h1>Vibrant Nebula</h1>
+ <p>A swiss layout with triadic colors</p>
+ </div>
+
+ <div class="content">
+ <h1>Welcome to Vibrant Nebula</h1>
+ <p>This theme features a carefully crafted swiss layout with a light triadic color scheme. The typography combines display fonts for headings with serif for body text.</p>
+
+ <h2>Typography Showcase</h2>
+ <p>The roboto-slab font family provides excellent readability for body text, while zai-aeg-mignon-typewriter-1924 adds character to headings. Code blocks use hack for clarity.</p>
+
+ <h2>Color Palette</h2>
+ <p>Primary: <span style="color: #7c2f4a; font-weight: bold;">#7c2f4a</span> |
+ Secondary: <span style="color: #4a7c2f; font-weight: bold;">#4a7c2f</span> |
+ Accent: <span style="color: #2f4a7c; font-weight: bold;">#2f4a7c</span></p>
+
+ <h3>Interactive Elements</h3>
+ <p>Links like <a href="#">this example</a> and longer <a href="#" class="textlink">text links that demonstrate the theme's navigation style</a> use the secondary color.</p>
+
+ <div class="quote">
+ "Design is not just what it looks like and feels like. Design is how it works." — Steve Jobs
+ </div>
+
+ <h3>Code Examples</h3>
+ <p>Inline code like <code>theme.generate()</code> and larger blocks:</p>
+ <pre>// Theme configuration
+const theme = {
+ name: "vibrant_nebula",
+ layout: "swiss",
+ colors: {
+ primary: "#7c2f4a",
+ secondary: "#4a7c2f",
+ accent: "#2f4a7c"
+ },
+ fonts: {
+ heading: "zai-aeg-mignon-typewriter-1924",
+ body: "roboto-slab",
+ code: "hack"
+ }
+};</pre>
+
+ <h2>Content Structure</h2>
+ <ul>
+ <li>Clean, readable typography with 14px base font size</li>
+ <li>Heading scale ratio of 1.42x for visual hierarchy</li>
+ <li>Line height of 1.66 for comfortable reading</li>
+ <li>Swiss layout optimized for content flow</li>
+ <li>Light theme with triadic color harmony</li>
+ </ul>
+
+ <h2>Font Licensing</h2>
+ <p>All fonts used in this theme are properly licensed:</p>
+ <ul>
+ <li>zai-aeg-mignon-typewriter-1924: Free License</li>
+ <li>roboto-slab: Apache License</li>
+ <li>hack: MIT License</li>
+ </ul>
+
+ <h3>Final Thoughts</h3>
+ <p>Every element of this theme has been carefully designed to create a harmonious reading experience. The swiss layout ensures content is presented in an engaging way, while the color scheme provides the perfect backdrop for your words to shine.</p>
+
+ <p>Whether you're writing technical documentation, creative prose, or anything in between, this theme adapts to showcase your content beautifully.</p>
+ </div>
+</body>
+</html> \ No newline at end of file
diff --git a/extras/html/themes/vibrant_nebula/handnotes.ttf b/extras/html/themes/vibrant_nebula/handnotes.ttf
new file mode 100644
index 0000000..25e688b
--- /dev/null
+++ b/extras/html/themes/vibrant_nebula/handnotes.ttf
Binary files differ
diff --git a/extras/html/themes/vibrant_nebula/heading.ttf b/extras/html/themes/vibrant_nebula/heading.ttf
new file mode 100644
index 0000000..375978c
--- /dev/null
+++ b/extras/html/themes/vibrant_nebula/heading.ttf
Binary files differ
diff --git a/extras/html/themes/vibrant_nebula/style.css b/extras/html/themes/vibrant_nebula/style.css
new file mode 100644
index 0000000..76ccc0e
--- /dev/null
+++ b/extras/html/themes/vibrant_nebula/style.css
@@ -0,0 +1,198 @@
+/* Base styles */
+@font-face {
+ font-family: 'text';
+ src: url("./text.ttf") format("truetype");
+}
+
+@font-face {
+ font-family: 'heading';
+ src: url("./heading.ttf") format("truetype");
+}
+
+@font-face {
+ font-family: 'code';
+ src: url("./code.ttf") format("truetype");
+}
+
+@font-face {
+ font-family: 'handnotes';
+ src: url("./handnotes.ttf") format("truetype");
+}
+
+:root {
+ --color-primary: #7c2f4a;
+ --color-secondary: #4a7c2f;
+ --color-accent: #2f4a7c;
+ --color-bg: #f0edee;
+ --color-text: #232323;
+ --font-size-base: 14px;
+ --font-size-h1: 1.42em;
+ --font-size-h2: 1.27em;
+ --font-size-h3: 1.12em;
+ --line-height: 1.66;
+}
+
+* {
+ box-sizing: border-box;
+}
+
+html {
+ font-size: var(--font-size-base);
+ -webkit-font-smoothing: antialiased;
+ -moz-osx-font-smoothing: grayscale;
+}
+
+body {
+ font-family: text, sans-serif;
+ background-color: var(--color-bg);
+ color: var(--color-text);
+ line-height: var(--line-height);
+ margin: 0;
+ padding: 0;
+ overflow-wrap: break-word;
+}
+
+h1, h2, h3 {
+ font-family: heading, serif;
+ line-height: 1.2;
+ margin-top: 1em;
+ margin-bottom: 0.5em;
+}
+
+h1 {
+ font-size: var(--font-size-h1);
+ color: var(--color-primary);
+}
+
+h2 {
+ font-size: var(--font-size-h2);
+ color: var(--color-primary);
+}
+
+h3 {
+ font-size: var(--font-size-h3);
+ color: var(--color-secondary);
+}
+
+a {
+ font-family: code, monospace;
+ color: var(--color-secondary);
+ text-decoration: none;
+ transition: all 0.3s ease;
+}
+
+a:hover {
+ color: var(--color-accent);
+ text-decoration: underline;
+}
+
+.textlink {
+ font-family: text, sans-serif;
+}
+
+.quote {
+ font-family: handnotes, cursive;
+ border-left: 4px solid var(--color-accent);
+ padding: 1em 1.5em;
+ margin: 1.5em 0;
+ background-color: rgba(124, 47, 74, 0.07);
+ font-style: italic;
+}
+
+pre {
+ font-family: code, monospace;
+ background-color: rgba(35, 35, 35, 0.04);
+ border: 1px solid rgba(35, 35, 35, 0.13);
+ padding: 1em;
+ overflow-x: auto;
+ border-radius: 4px;
+ font-size: 0.9em;
+}
+
+code {
+ font-family: code, monospace;
+ background-color: rgba(35, 35, 35, 0.04);
+ padding: 0.2em 0.4em;
+ border-radius: 3px;
+ font-size: 0.9em;
+}
+
+ul, ol {
+ padding-left: 2em;
+ margin: 1em 0;
+}
+
+li {
+ margin: 0.5em 0;
+}
+
+img {
+ max-width: 100%;
+ height: auto;
+}
+
+hr {
+ border: none;
+ border-top: 1px solid rgba(35, 35, 35, 0.20);
+ margin: 2em 0;
+}
+
+
+/* Layout: swiss */
+
+body {
+ max-width: 1200px;
+ margin: 0 auto;
+ padding: 2em;
+ display: grid;
+ grid-template-columns: repeat(6, 1fr);
+ gap: 2em;
+}
+
+.header {
+ grid-column: 1 / -1;
+ display: grid;
+ grid-template-columns: repeat(6, 1fr);
+ gap: 2em;
+ margin-bottom: 4em;
+ padding-bottom: 2em;
+ border-bottom: 4px solid var(--color-text);
+}
+
+.header h1 {
+ grid-column: 1 / 4;
+ font-size: 4em;
+ margin: 0;
+ line-height: 0.9;
+}
+
+.header p {
+ grid-column: 4 / -1;
+ align-self: end;
+}
+
+h1 {
+ grid-column: 1 / -1;
+ font-size: 3em;
+ margin: 1em 0 0.5em 0;
+}
+
+h2 {
+ grid-column: 1 / 5;
+ margin-top: 2em;
+}
+
+h3 {
+ grid-column: 2 / 6;
+}
+
+p, ul, pre {
+ grid-column: 2 / 6;
+}
+
+.quote {
+ grid-column: 1 / -1;
+ font-size: 1.5em;
+ text-align: center;
+ margin: 2em 0;
+}
diff --git a/extras/html/themes/vibrant_nebula/theme.conf b/extras/html/themes/vibrant_nebula/theme.conf
new file mode 100644
index 0000000..b620ed7
--- /dev/null
+++ b/extras/html/themes/vibrant_nebula/theme.conf
@@ -0,0 +1,8 @@
+declare -xr HTML_HEADER=./extras/html/header.html.part
+declare -xr HTML_FOOTER=./extras/html/footer.html.part
+declare -xr HTML_CSS_STYLE=$HTML_THEME_DIR/style.css
+declare -xr HTML_WEBFONT_HEADING=./extras/html/fonts/zai-aeg-mignon-typewriter-1924/zai-aeg-mignon-typewriter-1924-Bold.ttf
+declare -xr HTML_WEBFONT_TEXT=./extras/html/fonts/roboto-slab/roboto-slab-Regular.ttf
+declare -xr HTML_WEBFONT_CODE=./extras/html/fonts/hack/hack-Regular.ttf
+declare -xr HTML_WEBFONT_HANDNOTES=./extras/html/fonts/khand/khand.ttf
+declare -xr SOURCE_HIGHLIGHT_CSS=./extras/html/source-highlight-styles/mono.css
diff --git a/extras/html/themes/vibrant_storm/LICENSE b/extras/html/themes/vibrant_storm/LICENSE
new file mode 100644
index 0000000..9b7fe4b
--- /dev/null
+++ b/extras/html/themes/vibrant_storm/LICENSE
@@ -0,0 +1,21 @@
+Theme: vibrant_storm
+Generated: 2025-06-22 21:38:55
+
+Layout: terminal
+Color Scheme: analogous (Light)
+
+Font Licenses:
+==============
+Heading Font: zai-aeg-mignon-typewriter-1924
+License: Free
+Category: display
+
+Body Font: roboto-slab
+License: Apache
+Category: serif
+
+Code Font: hack
+License: MIT
+Category: monospace
+
+All fonts are free for personal use.
diff --git a/extras/html/themes/vibrant_storm/code.ttf b/extras/html/themes/vibrant_storm/code.ttf
new file mode 100644
index 0000000..7c8e65b
--- /dev/null
+++ b/extras/html/themes/vibrant_storm/code.ttf
Binary files differ
diff --git a/extras/html/themes/vibrant_storm/example.html b/extras/html/themes/vibrant_storm/example.html
new file mode 100644
index 0000000..6ece952
--- /dev/null
+++ b/extras/html/themes/vibrant_storm/example.html
@@ -0,0 +1,75 @@
+<!DOCTYPE html>
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
+<head>
+ <meta charset="UTF-8" />
+ <meta name="viewport" content="width=device-width, initial-scale=1.0" />
+ <title>Vibrant Storm - Gemtexter Theme</title>
+ <link rel="stylesheet" href="style.css" />
+</head>
+<body>
+ <div class="header">
+ <h1>Vibrant Storm</h1>
+ <p>A terminal layout with analogous colors</p>
+ </div>
+
+ <div class="content">
+ <h1>Welcome to Vibrant Storm</h1>
+ <p>This theme features a carefully crafted terminal layout with a light analogous color scheme. The typography combines display fonts for headings with serif for body text.</p>
+
+ <h2>Typography Showcase</h2>
+ <p>The roboto-slab font family provides excellent readability for body text, while zai-aeg-mignon-typewriter-1924 adds character to headings. Code blocks use hack for clarity.</p>
+
+ <h2>Color Palette</h2>
+ <p>Primary: <span style="color: #b3de37; font-weight: bold;">#b3de37</span> |
+ Secondary: <span style="color: #67d640; font-weight: bold;">#67d640</span> |
+ Accent: <span style="color: #d7af23; font-weight: bold;">#d7af23</span></p>
+
+ <h3>Interactive Elements</h3>
+ <p>Links like <a href="#">this example</a> and longer <a href="#" class="textlink">text links that demonstrate the theme's navigation style</a> use the secondary color.</p>
+
+ <div class="quote">
+ "Design is not just what it looks like and feels like. Design is how it works." — Steve Jobs
+ </div>
+
+ <h3>Code Examples</h3>
+ <p>Inline code like <code>theme.generate()</code> and larger blocks:</p>
+ <pre>// Theme configuration
+const theme = {
+ name: "vibrant_storm",
+ layout: "terminal",
+ colors: {
+ primary: "#b3de37",
+ secondary: "#67d640",
+ accent: "#d7af23"
+ },
+ fonts: {
+ heading: "zai-aeg-mignon-typewriter-1924",
+ body: "roboto-slab",
+ code: "hack"
+ }
+};</pre>
+
+ <h2>Content Structure</h2>
+ <ul>
+ <li>Clean, readable typography with 15px base font size</li>
+ <li>Heading scale ratio of 2.83x for visual hierarchy</li>
+ <li>Line height of 1.76 for comfortable reading</li>
+ <li>Terminal layout optimized for content flow</li>
+ <li>Light theme with analogous color harmony</li>
+ </ul>
+
+ <h2>Font Licensing</h2>
+ <p>All fonts used in this theme are properly licensed:</p>
+ <ul>
+ <li>zai-aeg-mignon-typewriter-1924: Free License</li>
+ <li>roboto-slab: Apache License</li>
+ <li>hack: MIT License</li>
+ </ul>
+
+ <h3>Final Thoughts</h3>
+ <p>Every element of this theme has been carefully designed to create a harmonious reading experience. The terminal layout ensures content is presented in an engaging way, while the color scheme provides the perfect backdrop for your words to shine.</p>
+
+ <p>Whether you're writing technical documentation, creative prose, or anything in between, this theme adapts to showcase your content beautifully.</p>
+ </div>
+</body>
+</html> \ No newline at end of file
diff --git a/extras/html/themes/vibrant_storm/handnotes.ttf b/extras/html/themes/vibrant_storm/handnotes.ttf
new file mode 100644
index 0000000..25e688b
--- /dev/null
+++ b/extras/html/themes/vibrant_storm/handnotes.ttf
Binary files differ
diff --git a/extras/html/themes/vibrant_storm/heading.ttf b/extras/html/themes/vibrant_storm/heading.ttf
new file mode 100644
index 0000000..375978c
--- /dev/null
+++ b/extras/html/themes/vibrant_storm/heading.ttf
Binary files differ
diff --git a/extras/html/themes/vibrant_storm/style.css b/extras/html/themes/vibrant_storm/style.css
new file mode 100644
index 0000000..804f1ea
--- /dev/null
+++ b/extras/html/themes/vibrant_storm/style.css
@@ -0,0 +1,216 @@
+/* Base styles */
+@font-face {
+ font-family: 'text';
+ src: url("./text.ttf") format("truetype");
+}
+
+@font-face {
+ font-family: 'heading';
+ src: url("./heading.ttf") format("truetype");
+}
+
+@font-face {
+ font-family: 'code';
+ src: url("./code.ttf") format("truetype");
+}
+
+@font-face {
+ font-family: 'handnotes';
+ src: url("./handnotes.ttf") format("truetype");
+}
+
+:root {
+ --color-primary: #b3de37;
+ --color-secondary: #67d640;
+ --color-accent: #d7af23;
+ --color-bg: #efefec;
+ --color-text: #161616;
+ --font-size-base: 15px;
+ --font-size-h1: 2.83em;
+ --font-size-h2: 2.0em;
+ --font-size-h3: 1.41em;
+ --line-height: 1.76;
+}
+
+* {
+ box-sizing: border-box;
+}
+
+html {
+ font-size: var(--font-size-base);
+ -webkit-font-smoothing: antialiased;
+ -moz-osx-font-smoothing: grayscale;
+}
+
+body {
+ font-family: text, sans-serif;
+ background-color: var(--color-bg);
+ color: var(--color-text);
+ line-height: var(--line-height);
+ margin: 0;
+ padding: 0;
+ overflow-wrap: break-word;
+}
+
+h1, h2, h3 {
+ font-family: heading, serif;
+ line-height: 1.2;
+ margin-top: 1em;
+ margin-bottom: 0.5em;
+}
+
+h1 {
+ font-size: var(--font-size-h1);
+ color: var(--color-primary);
+}
+
+h2 {
+ font-size: var(--font-size-h2);
+ color: var(--color-primary);
+}
+
+h3 {
+ font-size: var(--font-size-h3);
+ color: var(--color-secondary);
+}
+
+a {
+ font-family: code, monospace;
+ color: var(--color-secondary);
+ text-decoration: none;
+ transition: all 0.3s ease;
+}
+
+a:hover {
+ color: var(--color-accent);
+ text-decoration: underline;
+}
+
+.textlink {
+ font-family: text, sans-serif;
+}
+
+.quote {
+ font-family: handnotes, cursive;
+ border-left: 4px solid var(--color-accent);
+ padding: 1em 1.5em;
+ margin: 1.5em 0;
+ background-color: rgba(179, 222, 55, 0.07);
+ font-style: italic;
+}
+
+pre {
+ font-family: code, monospace;
+ background-color: rgba(22, 22, 22, 0.04);
+ border: 1px solid rgba(22, 22, 22, 0.13);
+ padding: 1em;
+ overflow-x: auto;
+ border-radius: 4px;
+ font-size: 0.9em;
+}
+
+code {
+ font-family: code, monospace;
+ background-color: rgba(22, 22, 22, 0.04);
+ padding: 0.2em 0.4em;
+ border-radius: 3px;
+ font-size: 0.9em;
+}
+
+ul, ol {
+ padding-left: 2em;
+ margin: 1em 0;
+}
+
+li {
+ margin: 0.5em 0;
+}
+
+img {
+ max-width: 100%;
+ height: auto;
+}
+
+hr {
+ border: none;
+ border-top: 1px solid rgba(22, 22, 22, 0.20);
+ margin: 2em 0;
+}
+
+
+/* Layout: terminal */
+
+@import url("https://fonts.googleapis.com/css2?family=Source+Code+Pro:wght@400;700&display=swap");
+
+body {
+ background-color: #000;
+ color: #0f0;
+ font-family: 'Source Code Pro', code, monospace;
+ padding: 1em;
+ line-height: 1.4;
+}
+
+.header {
+ border: 2px solid #0f0;
+ padding: 1em;
+ margin-bottom: 2em;
+ position: relative;
+}
+
+.header::before {
+ content: "[SYSTEM] ";
+ color: #ff0;
+}
+
+h1, h2, h3 {
+ color: #0f0;
+ font-family: 'Source Code Pro', code, monospace;
+}
+
+h1::before {
+ content: "### ";
+ color: #f0f;
+}
+
+h2::before {
+ content: "## ";
+ color: #0ff;
+}
+
+h3::before {
+ content: "# ";
+ color: #ff0;
+}
+
+p::before {
+ content: "> ";
+ color: #666;
+}
+
+a {
+ color: #0ff;
+ text-decoration: underline;
+}
+
+a:hover {
+ background-color: #0ff;
+ color: #000;
+}
+
+.quote {
+ border: 1px dashed #0f0;
+ background-color: #0f0111;
+ color: #0f0;
+}
+
+pre {
+ background-color: #111;
+ border: 1px solid #0f0;
+ color: #0f0;
+ overflow-x: scroll;
+}
+
+pre::before {
+ content: "$ cat output.log\A";
+ color: #666;
+}
diff --git a/extras/html/themes/vibrant_storm/theme.conf b/extras/html/themes/vibrant_storm/theme.conf
new file mode 100644
index 0000000..b620ed7
--- /dev/null
+++ b/extras/html/themes/vibrant_storm/theme.conf
@@ -0,0 +1,8 @@
+declare -xr HTML_HEADER=./extras/html/header.html.part
+declare -xr HTML_FOOTER=./extras/html/footer.html.part
+declare -xr HTML_CSS_STYLE=$HTML_THEME_DIR/style.css
+declare -xr HTML_WEBFONT_HEADING=./extras/html/fonts/zai-aeg-mignon-typewriter-1924/zai-aeg-mignon-typewriter-1924-Bold.ttf
+declare -xr HTML_WEBFONT_TEXT=./extras/html/fonts/roboto-slab/roboto-slab-Regular.ttf
+declare -xr HTML_WEBFONT_CODE=./extras/html/fonts/hack/hack-Regular.ttf
+declare -xr HTML_WEBFONT_HANDNOTES=./extras/html/fonts/khand/khand.ttf
+declare -xr SOURCE_HIGHLIGHT_CSS=./extras/html/source-highlight-styles/mono.css