diff options
| author | Paul Buetow <paul@buetow.org> | 2026-05-01 22:03:34 +0300 |
|---|---|---|
| committer | Paul Buetow <paul@buetow.org> | 2026-05-01 22:03:34 +0300 |
| commit | f942678e7ae91d35278832f3054855269a89be3d (patch) | |
| tree | 3ab3950797c6887c970a6b62ef89e6b7dbb8daeb | |
| parent | 937fa48eaf1a87698f715edf976f77adfe5dc8a1 (diff) | |
Task 8: self-host volcano theme fonts
| -rw-r--r-- | README.md | 6 | ||||
| -rw-r--r-- | internal/generator/generator_test.go | 64 | ||||
| -rw-r--r-- | internal/generator/templates/themes/volcano/FONT_LICENSE.txt | 59 | ||||
| -rw-r--r-- | internal/generator/templates/themes/volcano/bebas-neue-v16-latin_latin-ext-regular.woff2 | bin | 0 -> 17144 bytes | |||
| -rw-r--r-- | internal/generator/templates/themes/volcano/inter-v20-latin_latin-ext-600.woff2 | bin | 0 -> 52452 bytes | |||
| -rw-r--r-- | internal/generator/templates/themes/volcano/inter-v20-latin_latin-ext-regular.woff2 | bin | 0 -> 50696 bytes | |||
| -rw-r--r-- | internal/generator/templates/themes/volcano/theme.css | 37 |
7 files changed, 161 insertions, 5 deletions
@@ -203,6 +203,12 @@ Bundled web fonts: Andrew Paglinawan, from [Google Fonts](https://fonts.google.com/specimen/Quicksand), [SIL OFL 1.1](https://openfontlicense.org/open-font-license-official-text/). See [internal/generator/templates/themes/tropicale/FONT_LICENSE.txt](internal/generator/templates/themes/tropicale/FONT_LICENSE.txt). +- **volcano** — *Bebas Neue* Regular and *Inter* Regular + SemiBold + (.woff2, latin+latin-ext) by Ryoichi Tsunekawa and Rasmus Andersson, + from Google Fonts ([Bebas Neue](https://fonts.google.com/specimen/Bebas+Neue), + [Inter](https://fonts.google.com/specimen/Inter)), + [SIL OFL 1.1](https://openfontlicense.org/open-font-license-official-text/). + See [internal/generator/templates/themes/volcano/FONT_LICENSE.txt](internal/generator/templates/themes/volcano/FONT_LICENSE.txt). When adding a new bundled font: diff --git a/internal/generator/generator_test.go b/internal/generator/generator_test.go index 10116a2..62b3593 100644 --- a/internal/generator/generator_test.go +++ b/internal/generator/generator_test.go @@ -443,6 +443,70 @@ func TestRun_writesPagesAndAtom(t *testing.T) { } } +func TestRun_writesVolcanoFontAssets(t *testing.T) { + t.Parallel() + + out := t.TempDir() + postDir := filepath.Join(out, "posts", "a1") + if err := os.MkdirAll(postDir, 0o755); err != nil { + t.Fatal(err) + } + p := &post.Post{ + ID: "a1", + Timestamp: time.Date(2026, 1, 1, 12, 0, 0, 0, time.UTC), + PostType: post.TypeText, + Content: "<p>volcano</p>", + } + if err := p.Save(postDir); err != nil { + t.Fatal(err) + } + + cfg := &config.Config{ + OutputDir: out, + BaseURL: "https://example.test", + Theme: "volcano", + } + if err := Run(ctx, cfg); err != nil { + t.Fatalf("Run: %v", err) + } + + themeDir := filepath.Join(out, "themes", "volcano") + for _, name := range []string{ + "bebas-neue-v16-latin_latin-ext-regular.woff2", + "inter-v20-latin_latin-ext-regular.woff2", + "inter-v20-latin_latin-ext-600.woff2", + "FONT_LICENSE.txt", + } { + info, err := os.Stat(filepath.Join(themeDir, name)) + if err != nil { + t.Fatalf("%s: %v", name, err) + } + if info.Size() == 0 { + t.Fatalf("%s is empty", name) + } + } + + css, err := os.ReadFile(filepath.Join(themeDir, "theme.css")) + if err != nil { + t.Fatalf("read volcano theme.css: %v", err) + } + got := string(css) + for _, localFont := range []string{ + "url('bebas-neue-v16-latin_latin-ext-regular.woff2')", + "url('inter-v20-latin_latin-ext-regular.woff2')", + "url('inter-v20-latin_latin-ext-600.woff2')", + } { + if !strings.Contains(got, localFont) { + t.Fatalf("volcano theme.css missing local font reference %q", localFont) + } + } + for _, forbidden := range []string{"googleapis", "gstatic", "fonts.cdn", "@import url(http"} { + if strings.Contains(got, forbidden) { + t.Fatalf("volcano theme.css contains forbidden external font reference %q", forbidden) + } + } +} + func TestWritePage(t *testing.T) { t.Parallel() diff --git a/internal/generator/templates/themes/volcano/FONT_LICENSE.txt b/internal/generator/templates/themes/volcano/FONT_LICENSE.txt new file mode 100644 index 0000000..82df777 --- /dev/null +++ b/internal/generator/templates/themes/volcano/FONT_LICENSE.txt @@ -0,0 +1,59 @@ +Volcano theme fonts +=================== + +This directory bundles the web fonts: + + bebas-neue-v16-latin_latin-ext-regular.woff2 (weight 400) + inter-v20-latin_latin-ext-regular.woff2 (weight 400) + inter-v20-latin_latin-ext-600.woff2 (weight 600) + +Subsets: latin, latin-ext. + +Source / version +---------------- +- Bebas Neue family page : https://fonts.google.com/specimen/Bebas+Neue +- Bebas Neue designer : Ryoichi Tsunekawa +- Bebas Neue webfont set : bebas-neue-v16 (latin + latin-ext, woff2) +- Bebas Neue upstream source : https://github.com/dharmatype/Bebas-Neue +- Bebas Neue metadata commit : 686d14af640c17af3691c597778f121d840d9051 +- Bebas Neue last modified : 2025-09-16 +- Bebas Neue fetched via : https://gwfh.mranftl.com/fonts/bebas-neue +- Bebas Neue download URL : https://gwfh.mranftl.com/api/fonts/bebas-neue?download=zip&subsets=latin,latin-ext&formats=woff2&variants=regular +- Inter family page : https://fonts.google.com/specimen/Inter +- Inter designer : Rasmus Andersson +- Inter webfont set : inter-v20 (latin + latin-ext, woff2) +- Inter upstream source : https://www.github.com/rsms/inter +- Inter metadata commit : 66647c0bbbe41a850d79d9c76fb13add3378940f +- Inter archive source : https://github.com/rsms/inter/files/15438431/Inter-4.1-GoogleFonts.zip +- Inter last modified : 2025-09-10 +- Inter fetched via : https://gwfh.mranftl.com/fonts/inter +- Inter download URL : https://gwfh.mranftl.com/api/fonts/inter?download=zip&subsets=latin,latin-ext&formats=woff2&variants=regular,600 +- Fetched on : 2026-05-01 + +License +------- +SIL Open Font License, Version 1.1. + +Bebas Neue copyright: +Copyright 2019 The Bebas Neue Project Authors +(https://github.com/dharmatype/Bebas-Neue). + +Inter copyright: +Copyright 2020 The Inter Project Authors +(https://github.com/rsms/inter). + + - Summary : https://scripts.sil.org/cms/scripts/page.php?item_id=OFL_web + - Full text : https://openfontlicense.org/open-font-license-official-text/ + +The OFL allows free use, modification, and redistribution of the font, +including embedding in commercial products. Any standalone modified +version of the font itself must be released under the same license and +must not use the Reserved Font Names "Bebas Neue" or "Inter". + +Required attribution +-------------------- +Font: "Bebas Neue" by Ryoichi Tsunekawa - https://github.com/dharmatype/Bebas-Neue + Licensed under the SIL Open Font License 1.1. + +Font: "Inter" by Rasmus Andersson - https://github.com/rsms/inter + Licensed under the SIL Open Font License 1.1. diff --git a/internal/generator/templates/themes/volcano/bebas-neue-v16-latin_latin-ext-regular.woff2 b/internal/generator/templates/themes/volcano/bebas-neue-v16-latin_latin-ext-regular.woff2 Binary files differnew file mode 100644 index 0000000..924acb6 --- /dev/null +++ b/internal/generator/templates/themes/volcano/bebas-neue-v16-latin_latin-ext-regular.woff2 diff --git a/internal/generator/templates/themes/volcano/inter-v20-latin_latin-ext-600.woff2 b/internal/generator/templates/themes/volcano/inter-v20-latin_latin-ext-600.woff2 Binary files differnew file mode 100644 index 0000000..283b13a --- /dev/null +++ b/internal/generator/templates/themes/volcano/inter-v20-latin_latin-ext-600.woff2 diff --git a/internal/generator/templates/themes/volcano/inter-v20-latin_latin-ext-regular.woff2 b/internal/generator/templates/themes/volcano/inter-v20-latin_latin-ext-regular.woff2 Binary files differnew file mode 100644 index 0000000..70dd51e --- /dev/null +++ b/internal/generator/templates/themes/volcano/inter-v20-latin_latin-ext-regular.woff2 diff --git a/internal/generator/templates/themes/volcano/theme.css b/internal/generator/templates/themes/volcano/theme.css index 83c80df..44c1c2e 100644 --- a/internal/generator/templates/themes/volcano/theme.css +++ b/internal/generator/templates/themes/volcano/theme.css @@ -1,14 +1,41 @@ + /* Self-hosted web fonts: Bebas Neue by Ryoichi Tsunekawa and Inter by + Rasmus Andersson (SIL OFL 1.1). + Sources: https://fonts.google.com/specimen/Bebas+Neue and + https://fonts.google.com/specimen/Inter + See FONT_LICENSE.txt in this directory. */ + @font-face { + font-family: 'Bebas Neue'; + src: url('bebas-neue-v16-latin_latin-ext-regular.woff2') format('woff2'); + font-weight: 400; + font-style: normal; + font-display: swap; + } + @font-face { + font-family: 'Inter'; + src: url('inter-v20-latin_latin-ext-regular.woff2') format('woff2'); + font-weight: 400; + font-style: normal; + font-display: swap; + } + @font-face { + font-family: 'Inter'; + src: url('inter-v20-latin_latin-ext-600.woff2') format('woff2'); + font-weight: 600; + font-style: normal; + font-display: swap; + } :root { --lava:#ff4400; --ember:#ff8c00; --hot:#ffcc00; --bg:#0d0802; } * { margin:0; padding:0; box-sizing:border-box; } - body { font-family:'Segoe UI',system-ui,sans-serif; background:var(--bg); + body { font-family:'Inter','Segoe UI',system-ui,sans-serif; background:var(--bg); color:#ffe8cc; overflow:hidden; height:100vh; height:100dvh; } + h1, h2, h3, h4, h5, h6 { font-family:'Bebas Neue','Segoe UI',system-ui,sans-serif; font-weight:400; letter-spacing:0.08em; } #three-canvas { position:fixed; top:0; left:0; width:100%; height:100%; z-index:1; } .overlay { position:relative; z-index:10; height:100vh; height:100dvh; display:flex; flex-direction:column; } header { padding:16px 28px; background:rgba(13,8,2,0.82); backdrop-filter:blur(12px); border-bottom:1px solid rgba(255,68,0,0.3); display:flex; align-items:center; justify-content:space-between; } .logo { display:flex; align-items:center; gap:14px; } - .logo-mark { font-size:2rem; font-weight:800; color:var(--ember); text-shadow:0 0 16px var(--lava); } - .logo-title h1 { font-size:1.5rem; font-weight:700; color:#ffe8cc; } + .logo-mark { font-family:'Bebas Neue','Segoe UI',system-ui,sans-serif; font-size:2rem; font-weight:400; color:var(--ember); text-shadow:0 0 16px var(--lava); } + .logo-title h1 { font-family:'Bebas Neue','Segoe UI',system-ui,sans-serif; font-size:1.5rem; font-weight:400; color:#ffe8cc; letter-spacing:0.08em; } .logo-title .subtitle { font-size:0.75rem; color:rgba(255,232,204,0.5); margin-top:2px; } .logo-title .subtitle a { color:var(--ember); text-decoration:none; } .logo-title .subtitle a:hover { text-shadow:0 0 8px var(--lava); } @@ -37,7 +64,7 @@ .post:hover { border-color:var(--ember); box-shadow:0 0 20px rgba(255,68,0,0.25); transform:translateY(-2px); } .post-active { border-color:var(--hot) !important; background:rgba(30,8,2,0.9) !important; box-shadow:0 0 24px rgba(255,140,0,0.4),inset 3px 0 0 var(--hot) !important; } - .post-header { display:flex; justify-content:space-between; margin-bottom:12px; font-size:0.88rem; } + .post-header { display:flex; justify-content:space-between; margin-bottom:12px; font-size:0.88rem; font-weight:600; } .post-time { color:var(--ember); font-family:monospace; font-size:0.8rem; } .post-text { line-height:1.65; font-size:0.95rem; } .post-text a { color:var(--ember); text-decoration:none; } @@ -62,7 +89,7 @@ box-shadow: 0 0 20px var(--lava), 0 6px 30px rgba(255,68,0,0.4); } @keyframes splashEmberPulse { from { opacity:0.6; transform: scaleX(0.9); } to { opacity:1; transform: scaleX(1); } } - [data-sno-theme="volcano"] .splash-title { font-size:clamp(1.45rem,4.5vw,2rem); color:#ffe8cc; + [data-sno-theme="volcano"] .splash-title { font-family:'Bebas Neue','Segoe UI',system-ui,sans-serif; font-size:clamp(1.45rem,4.5vw,2rem); font-weight:400; letter-spacing:0.08em; color:#ffe8cc; text-shadow:0 0 20px var(--lava); } [data-sno-theme="volcano"] .splash-tag { color:var(--ember); letter-spacing:0.15em; } [data-sno-theme="volcano"] .splash-hint { color:rgba(255,232,204,0.88); } |
