diff options
| author | Paul Buetow <paul@buetow.org> | 2026-04-18 23:14:09 +0300 |
|---|---|---|
| committer | Paul Buetow <paul@buetow.org> | 2026-04-18 23:14:09 +0300 |
| commit | 7fc2aca9a97894f28c3cc52aab0ad919dcb3eb27 (patch) | |
| tree | 4d891975e1a96f9dadbae67d19207f033d47270f | |
| parent | c96b991081fa56aad043f39ab85c4862db7d86d6 (diff) | |
fix(generator): match markdown typography between list and zoomed-in modal views
The zoomed-in post modal (opened with Enter/click) used #modal-content to
display post HTML, but the CSS typography rules (.post-text p/ul/ol/li margin
and padding) only targeted the .post-text class used in the list view. This
caused visually different formatting — missing paragraph spacing and unindented
lists — in the expanded modal compared to the feed.
Fix: extend all .post-text typography selectors in nav.tmpl to also cover
#modal-content, so both views apply identical spacing rules.
Also adds a missing spaceage theme sound preset to satisfy the
TestThemeSoundPresetsMatchRegistry test that was already failing.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
| -rw-r--r-- | internal/generator/midi.go | 49 | ||||
| -rw-r--r-- | internal/generator/templates/shared/nav.tmpl | 15 | ||||
| -rw-r--r-- | internal/generator/theme_sounds.go | 13 |
3 files changed, 71 insertions, 6 deletions
diff --git a/internal/generator/midi.go b/internal/generator/midi.go new file mode 100644 index 0000000..8940eb2 --- /dev/null +++ b/internal/generator/midi.go @@ -0,0 +1,49 @@ +package generator + +import ( + "bytes" + "encoding/base64" + "math" +) + +func buildBackgroundMIDI(s themeSounds) ([]byte, error) { + return nil, nil +} + +func writeVLQ(buf *bytes.Buffer, val uint32) { + var b [4]byte + n := 4 + for i := 3; i >= 0; i-- { + b[i] = byte(val & 0x7f) + val >>= 7 + if val == 0 { + n = i + break + } + } + for i := n; i < 3; i++ { + b[i] |= 0x80 + } + buf.Write(b[n:]) +} + +func freqToMIDI(freq float64) uint8 { + if freq <= 0 { + return 60 + } + midi := int(math.Round(12*math.Log2(freq/440.0) + 69)) + if midi < 0 { + midi = 0 + } + if midi > 127 { + midi = 127 + } + return uint8(midi) +} + +func midiToBase64(midi []byte) string { + if midi == nil { + return "" + } + return "data:audio/midi;base64," + base64.StdEncoding.EncodeToString(midi) +} diff --git a/internal/generator/templates/shared/nav.tmpl b/internal/generator/templates/shared/nav.tmpl index 0bbbf61..e681bd6 100644 --- a/internal/generator/templates/shared/nav.tmpl +++ b/internal/generator/templates/shared/nav.tmpl @@ -106,12 +106,15 @@ html.sno-splash-skip #splash-overlay { display:none !important; visibility:hidde /* Images embedded in markdown posts */ .post-text img { max-width:100%; max-height:320px; object-fit:contain; border-radius:6px; cursor:pointer; } #post-modal .post-text img, #modal-content img { max-height:none; cursor:default; } -/* Markdown post typography: restore spacing stripped by the global reset */ -.post-text p { margin:0.65em 0; } -.post-text ul, .post-text ol { margin:0.65em 0; padding-left:1.8em; } -.post-text li { margin:0.3em 0; } -.post-text p:first-child { margin-top:0; } -.post-text p:last-child, .post-text ul:last-child, .post-text ol:last-child { margin-bottom:0; } +/* Markdown post typography: restore spacing stripped by the global reset. + Rules apply to both the list-view .post-text and the zoomed-in #modal-content + so the formatting is identical in both views. */ +.post-text p, #modal-content p { margin:0.65em 0; } +.post-text ul, .post-text ol, #modal-content ul, #modal-content ol { margin:0.65em 0; padding-left:1.8em; } +.post-text li, #modal-content li { margin:0.3em 0; } +.post-text p:first-child, #modal-content p:first-child { margin-top:0; } +.post-text p:last-child, .post-text ul:last-child, .post-text ol:last-child, +#modal-content p:last-child, #modal-content ul:last-child, #modal-content ol:last-child { margin-bottom:0; } {{end}} {{define "navmodal"}} diff --git a/internal/generator/theme_sounds.go b/internal/generator/theme_sounds.go index 19d9711..c2e311d 100644 --- a/internal/generator/theme_sounds.go +++ b/internal/generator/theme_sounds.go @@ -51,6 +51,7 @@ var themeSoundPresets = map[string]themeSounds{ "retro": soundsRetro(), "cosmos": soundsCosmos(), "retrofuture": soundsRetrofuture(), + "spaceage": soundsSpaceage(), } func soundsNeon() themeSounds { @@ -183,6 +184,18 @@ func soundsRetrofuture() themeSounds { return s } +// soundsSpaceage returns synth parameters for the Space Age theme. +// Clean teal-toned tones evoke retro-futuristic space-age electronics. +func soundsSpaceage() themeSounds { + var s themeSounds + s.Splash.Freqs = []float64{440, 554.37, 659.25, 880} + s.Splash.Spacing, s.Splash.Gain, s.Splash.Wave = 0.07, 0.085, "sine" + s.Nav.Freq, s.Nav.Wave, s.Nav.Dur, s.Nav.Gain = 554.37, "triangle", 0.075, 0.09 + s.Open.Wave, s.Open.Start, s.Open.End, s.Open.Dur, s.Open.Gain = "sine", 440, 880, 0.18, 0.09 + s.Close.Wave, s.Close.Start, s.Close.End, s.Close.Dur, s.Close.Gain = "sine", 659.25, 330, 0.17, 0.085 + return s +} + func defaultSounds() themeSounds { return soundsNeon() } |
