Commit 147ad78

mo khan <mo@mokhan.ca>
2026-01-31 01:51:54
refactor: remove --theme --preview-thems --minify and --gzip flags
1 parent 40fa78b
cmd/gitmal/main.go
@@ -20,10 +20,6 @@ var (
 	flagOutput        string
 	flagBranches      string
 	flagDefaultBranch string
-	flagTheme         string
-	flagPreviewThemes bool
-	flagMinify        bool
-	flagGzip          bool
 )
 
 func main() {
@@ -54,10 +50,6 @@ func main() {
 	flag.StringVar(&flagOutput, "output", "output", "Output directory for generated HTML files")
 	flag.StringVar(&flagBranches, "branches", "", "Regex for branches to include")
 	flag.StringVar(&flagDefaultBranch, "default-branch", "", "Default branch to use (autodetect master or main)")
-	flag.StringVar(&flagTheme, "theme", "github", "Style theme")
-	flag.BoolVar(&flagPreviewThemes, "preview-themes", false, "Preview available themes")
-	flag.BoolVar(&flagMinify, "minify", false, "Minify all generated HTML files")
-	flag.BoolVar(&flagGzip, "gzip", false, "Compress all generated HTML files")
 	flag.Usage = usage
 	flag.Parse()
 
@@ -70,11 +62,6 @@ func main() {
 		panic("Multiple repos not supported yet")
 	}
 
-	if flagPreviewThemes {
-		generator.PreviewThemes()
-		os.Exit(0)
-	}
-
 	outputDir, err := filepath.Abs(flagOutput)
 	if err != nil {
 		panic(err)
@@ -91,11 +78,6 @@ func main() {
 		flagName = strings.TrimSuffix(flagName, ".git")
 	}
 
-	themeColor, ok := generator.ThemeStyles[flagTheme]
-	if !ok {
-		panic("Invalid theme: " + flagTheme)
-	}
-
 	branchesFilter, err := regexp.Compile(flagBranches)
 	if err != nil {
 		panic(err)
@@ -138,8 +120,6 @@ func main() {
 		Name:       flagName,
 		RepoDir:    input,
 		OutputDir:  outputDir,
-		Style:      flagTheme,
-		Dark:       themeColor == "dark",
 		DefaultRef: git.NewRef(flagDefaultBranch),
 	}
 
@@ -252,12 +232,6 @@ func main() {
 		}
 	}
 
-	if flagMinify || flagGzip {
-		generator.Echo("> post-processing HTML...")
-		if err := generator.PostProcessHTML(params.OutputDir, flagMinify, flagGzip); err != nil {
-			panic(err)
-		}
-	}
 }
 
 func usage() {
internal/generator/blob.go
@@ -22,13 +22,6 @@ import (
 )
 
 func GenerateBlobs(files []git.Blob, params Params) error {
-	// Prepare shared, read-only resources
-	var css strings.Builder
-	style := styles.Get(params.Style)
-	if style == nil {
-		return fmt.Errorf("unknown style: %s", params.Style)
-	}
-
 	formatterOptions := []html.Option{
 		html.WithLineNumbers(true),
 		html.WithLinkableLineNumbers(true, "L"),
@@ -36,10 +29,7 @@ func GenerateBlobs(files []git.Blob, params Params) error {
 		html.WithCSSComments(false),
 	}
 
-	// Use a temporary formatter to render CSS once
-	if err := html.New(formatterOptions...).WriteCSS(&css, style); err != nil {
-		return err
-	}
+	css := cssSyntax(formatterOptions)
 
 	dirsSet := links.BuildDirSet(files)
 	filesSet := links.BuildFileSet(files)
@@ -62,9 +52,9 @@ func GenerateBlobs(files []git.Blob, params Params) error {
 	workerFn := func() {
 		defer wg.Done()
 
-		// Per-worker instances
-		md := createMarkdown(params.Style)
+		md := createMarkdown()
 		formatter := html.New(formatterOptions...)
+		style := styles.Get("github")
 
 		check := func(err error) bool {
 			if err != nil {
@@ -135,8 +125,7 @@ func GenerateBlobs(files []git.Blob, params Params) error {
 						err = templates.MarkdownTemplate.ExecuteTemplate(f, "layout.gohtml", templates.MarkdownParams{
 							LayoutParams: templates.LayoutParams{
 								Title:         fmt.Sprintf("%s/%s at %s", params.Name, blob.Path, params.Ref),
-								Dark:          params.Dark,
-								CSSMarkdown:   cssMarkdown(params.Dark),
+								CSSMarkdown:   cssMarkdown(),
 								Name:          params.Name,
 								RootHref:      rootHref,
 								CurrentRefDir: params.Ref.DirName(),
@@ -194,7 +183,6 @@ func GenerateBlobs(files []git.Blob, params Params) error {
 						err = templates.BlobTemplate.ExecuteTemplate(f, "layout.gohtml", templates.BlobParams{
 							LayoutParams: templates.LayoutParams{
 								Title:         fmt.Sprintf("%s/%s at %s", params.Name, blob.Path, params.Ref),
-								Dark:          params.Dark,
 								Name:          params.Name,
 								RootHref:      rootHref,
 								CurrentRefDir: params.Ref.DirName(),
@@ -204,7 +192,7 @@ func GenerateBlobs(files []git.Blob, params Params) error {
 								Ref:         params.Ref,
 								Breadcrumbs: breadcrumbs(params.Name, blob.Path, true),
 							},
-							CSS:      template.CSS(css.String()),
+							CSS:      css,
 							Blob:     blob,
 							IsBinary: isBin,
 							IsImage:  isImg,
@@ -257,3 +245,22 @@ func GenerateBlobs(files []git.Blob, params Params) error {
 	p.Done()
 	return runErr
 }
+
+func cssSyntax(opts []html.Option) template.CSS {
+	formatter := html.New(opts...)
+	lightStyle := styles.Get("github")
+	darkStyle := styles.Get("github-dark")
+
+	var light, dark strings.Builder
+	_ = formatter.WriteCSS(&light, lightStyle)
+	_ = formatter.WriteCSS(&dark, darkStyle)
+
+	return template.CSS(
+		"@media (prefers-color-scheme: light) {\n" +
+			light.String() +
+			"\n}\n" +
+			"@media (prefers-color-scheme: dark) {\n" +
+			dark.String() +
+			"\n}",
+	)
+}
internal/generator/branches.go
@@ -48,7 +48,6 @@ func GenerateBranches(branches []git.Ref, defaultBranch string, params Params) e
 		LayoutParams: templates.LayoutParams{
 			Title:         fmt.Sprintf("Branches %s %s", Dot, params.Name),
 			Name:          params.Name,
-			Dark:          params.Dark,
 			RootHref:      rootHref,
 			CurrentRefDir: params.DefaultRef.DirName(),
 			Selected:      "branches",
internal/generator/commit.go
@@ -116,11 +116,6 @@ func generateCommitPage(commit git.Commit, params Params) error {
 		return err
 	}
 
-	style := styles.Get(params.Style)
-	if style == nil {
-		return fmt.Errorf("unknown style: %s", params.Style)
-	}
-
 	formatter := html.New(
 		html.WithClasses(true),
 		html.WithCSSComments(false),
@@ -130,10 +125,19 @@ func generateCommitPage(commit git.Commit, params Params) error {
 		}),
 	)
 
-	var cssBuf bytes.Buffer
-	if err := formatter.WriteCSS(&cssBuf, style); err != nil {
-		return err
-	}
+	lightStyle := styles.Get("github")
+	darkStyle := styles.Get("github-dark")
+
+	var lightCSS, darkCSS bytes.Buffer
+	_ = formatter.WriteCSS(&lightCSS, lightStyle)
+	_ = formatter.WriteCSS(&darkCSS, darkStyle)
+
+	diffCSS := "@media (prefers-color-scheme: light) {\n" +
+		lightCSS.String() +
+		"\n}\n" +
+		"@media (prefers-color-scheme: dark) {\n" +
+		darkCSS.String() +
+		"\n}"
 
 	lexer := lexers.Get("diff")
 	if lexer == nil {
@@ -197,7 +201,7 @@ func generateCommitPage(commit git.Commit, params Params) error {
 			return err
 		}
 		var buf bytes.Buffer
-		if err := formatter.Format(&buf, style, it); err != nil {
+		if err := formatter.Format(&buf, lightStyle, it); err != nil {
 			return err
 		}
 
@@ -238,13 +242,12 @@ func generateCommitPage(commit git.Commit, params Params) error {
 		LayoutParams: templates.LayoutParams{
 			Title:         fmt.Sprintf("%s %s %s@%s", commit.Subject, Dot, params.Name, commit.ShortHash),
 			Name:          params.Name,
-			Dark:          params.Dark,
 			RootHref:      rootHref,
 			CurrentRefDir: currentRef.DirName(),
 			Selected:      "commits",
 		},
 		Commit:    commit,
-		DiffCSS:   template.CSS(cssBuf.String()),
+		DiffCSS:   template.CSS(diffCSS),
 		FileTree:  fileTree,
 		FileViews: filesViews,
 	})
internal/generator/commits_list.go
@@ -64,7 +64,6 @@ func GenerateLogForBranch(allCommits []git.Commit, params Params) error {
 			LayoutParams: templates.LayoutParams{
 				Title:         fmt.Sprintf("Commits %s %s", Dot, params.Name),
 				Name:          params.Name,
-				Dark:          params.Dark,
 				RootHref:      rootHref,
 				CurrentRefDir: params.Ref.DirName(),
 				Selected:      "commits",
internal/generator/index.go
@@ -102,8 +102,7 @@ func GenerateIndex(files []git.Blob, params Params) error {
 		LayoutParams: templates.LayoutParams{
 			Title:         title,
 			Name:          params.Name,
-			Dark:          params.Dark,
-			CSSMarkdown:   cssMarkdown(params.Dark),
+			CSSMarkdown:   cssMarkdown(),
 			RootHref:      rootHref,
 			CurrentRefDir: params.Ref.DirName(),
 			Selected:      "code",
internal/generator/list.go
@@ -178,14 +178,13 @@ func GenerateLists(files []git.Blob, params Params) error {
 					readmeHTML := readme(di.files, dirsSet, filesSet, params, rootHref)
 					var CSSMarkdown template.CSS
 					if readmeHTML != "" {
-						CSSMarkdown = cssMarkdown(params.Dark)
+						CSSMarkdown = cssMarkdown()
 					}
 
 					err = templates.ListTemplate.ExecuteTemplate(f, "layout.gohtml", templates.ListParams{
 						LayoutParams: templates.LayoutParams{
 							Title:         title,
 							Name:          params.Name,
-							Dark:          params.Dark,
 							CSSMarkdown:   CSSMarkdown,
 							RootHref:      rootHref,
 							CurrentRefDir: params.Ref.DirName(),
internal/generator/markdown.go
@@ -12,13 +12,13 @@ import (
 	"mokhan.ca/antonmedv/gitmal/internal/templates"
 )
 
-func createMarkdown(style string) goldmark.Markdown {
+func createMarkdown() goldmark.Markdown {
 	return goldmark.New(
 		goldmark.WithExtensions(
 			extension.GFM,
 			extension.Typographer,
 			highlighting.NewHighlighting(
-				highlighting.WithStyle(style),
+				highlighting.WithStyle("github"),
 			),
 		),
 		goldmark.WithParserOptions(
@@ -30,9 +30,13 @@ func createMarkdown(style string) goldmark.Markdown {
 	)
 }
 
-func cssMarkdown(dark bool) template.CSS {
-	if dark {
-		return template.CSS(templates.CSSMarkdownDark)
-	}
-	return template.CSS(templates.CSSMarkdownLight)
+func cssMarkdown() template.CSS {
+	return template.CSS(
+		"@media (prefers-color-scheme: light) {\n" +
+			templates.CSSMarkdownLight +
+			"\n}\n" +
+			"@media (prefers-color-scheme: dark) {\n" +
+			templates.CSSMarkdownDark +
+			"\n}",
+	)
 }
internal/generator/params.go
@@ -8,7 +8,5 @@ type Params struct {
 	RepoDir    string
 	Ref        git.Ref
 	OutputDir  string
-	Style      string
-	Dark       bool
 	DefaultRef git.Ref
 }
internal/generator/post_process.go
@@ -1,139 +0,0 @@
-package generator
-
-import (
-	"bytes"
-	"compress/gzip"
-	"io"
-	"io/fs"
-	"os"
-	"path/filepath"
-	"runtime"
-	"strings"
-	"sync"
-
-	"github.com/tdewolff/minify/v2"
-	"github.com/tdewolff/minify/v2/css"
-	"github.com/tdewolff/minify/v2/html"
-	"github.com/tdewolff/minify/v2/svg"
-
-	"mokhan.ca/antonmedv/gitmal/internal/progress_bar"
-)
-
-func PostProcessHTML(root string, doMinify bool, doGzip bool) error {
-	// 1) Collect all HTML files first
-	var files []string
-	if err := filepath.WalkDir(root, func(path string, d fs.DirEntry, err error) error {
-		if err != nil {
-			return err
-		}
-		if d.IsDir() {
-			return nil
-		}
-		if strings.HasSuffix(d.Name(), ".html") {
-			files = append(files, path)
-		}
-		return nil
-	}); err != nil {
-		return err
-	}
-
-	if len(files) == 0 {
-		return nil
-	}
-
-	// 2) Setup progress bar
-	labels := []string{}
-	if doMinify {
-		labels = append(labels, "minify")
-	}
-	if doGzip {
-		labels = append(labels, "gzip")
-	}
-	pb := progress_bar.NewProgressBar(strings.Join(labels, " + "), len(files))
-	defer pb.Done()
-
-	// 3) Worker pool
-	workers := runtime.NumCPU()
-	if workers < 1 {
-		workers = 1
-	}
-	jobs := make(chan string, workers*2)
-	var wg sync.WaitGroup
-	var mu sync.Mutex
-	var firstErr error
-
-	workerFn := func() {
-		defer wg.Done()
-		var m *minify.M
-		if doMinify {
-			m = minify.New()
-			m.AddFunc("text/html", html.Minify)
-			m.AddFunc("text/css", css.Minify)
-			m.AddFunc("image/svg+xml", svg.Minify)
-		}
-		for path := range jobs {
-			data, err := os.ReadFile(path)
-			if err == nil && doMinify {
-				if md, e := m.Bytes("text/html", data); e == nil {
-					data = md
-				} else {
-					err = e
-				}
-			}
-			if err == nil {
-				if doGzip {
-					// write to file.html.gz
-					gzPath := path + ".gz"
-					if e := writeGzip(gzPath, data); e != nil {
-						err = e
-					} else if e := os.Remove(path); e != nil { // remove original .html
-						err = e
-					}
-				} else {
-					if e := os.WriteFile(path, data, 0o644); e != nil {
-						err = e
-					}
-				}
-			}
-
-			if err != nil {
-				mu.Lock()
-				if firstErr == nil {
-					firstErr = err
-				}
-				mu.Unlock()
-			}
-			pb.Inc()
-		}
-	}
-
-	wg.Add(workers)
-	for i := 0; i < workers; i++ {
-		go workerFn()
-	}
-	for _, f := range files {
-		jobs <- f
-	}
-	close(jobs)
-	wg.Wait()
-
-	return firstErr
-}
-
-func writeGzip(path string, data []byte) error {
-	f, err := os.Create(path)
-	if err != nil {
-		return err
-	}
-	defer func() { _ = f.Close() }()
-	gw := gzip.NewWriter(f)
-	gw.Name = filepath.Base(strings.TrimSuffix(path, ".gz"))
-	if _, err := io.Copy(gw, bytes.NewReader(data)); err != nil {
-		_ = gw.Close()
-		return err
-	}
-	if err := gw.Close(); err != nil {
-		return err
-	}
-	return nil
-}
internal/generator/readme.go
@@ -12,7 +12,7 @@ import (
 func readme(files []git.Blob, dirsSet, filesSet links.Set, params Params, rootHref string) template.HTML {
 	var readmeHTML template.HTML
 
-	md := createMarkdown(params.Style)
+	md := createMarkdown()
 
 	for _, b := range files {
 		nameLower := strings.ToLower(b.FileName)
internal/generator/tags.go
@@ -27,7 +27,6 @@ func GenerateTags(entries []git.Tag, params Params) error {
 		LayoutParams: templates.LayoutParams{
 			Title:         fmt.Sprintf("Tags %s %s", Dot, params.Name),
 			Name:          params.Name,
-			Dark:          params.Dark,
 			RootHref:      rootHref,
 			CurrentRefDir: params.DefaultRef.DirName(),
 			Selected:      "tags",
internal/generator/themes.go
@@ -1,156 +0,0 @@
-package generator
-
-import (
-	"html/template"
-	"net"
-	"net/http"
-	"sort"
-	"strings"
-
-	"github.com/alecthomas/chroma/v2/formatters/html"
-	"github.com/alecthomas/chroma/v2/lexers"
-	"github.com/alecthomas/chroma/v2/styles"
-
-	"mokhan.ca/antonmedv/gitmal/internal/templates"
-)
-
-var ThemeStyles = map[string]string{
-	"abap":                 "light",
-	"algol":                "light",
-	"arduino":              "light",
-	"autumn":               "light",
-	"average":              "dark",
-	"base16-snazzy":        "dark",
-	"borland":              "light",
-	"bw":                   "light",
-	"catppuccin-frappe":    "dark",
-	"catppuccin-latte":     "light",
-	"catppuccin-macchiato": "dark",
-	"catppuccin-mocha":     "dark",
-	"colorful":             "light",
-	"doom-one":             "dark",
-	"doom-one2":            "dark",
-	"dracula":              "dark",
-	"emacs":                "light",
-	"evergarden":           "dark",
-	"friendly":             "light",
-	"fruity":               "dark",
-	"github-dark":          "dark",
-	"github":               "light",
-	"gruvbox-light":        "light",
-	"gruvbox":              "dark",
-	"hrdark":               "dark",
-	"igor":                 "light",
-	"lovelace":             "light",
-	"manni":                "light",
-	"modus-operandi":       "light",
-	"modus-vivendi":        "dark",
-	"monokai":              "dark",
-	"monokailight":         "light",
-	"murphy":               "light",
-	"native":               "dark",
-	"nord":                 "dark",
-	"nordic":               "dark",
-	"onedark":              "dark",
-	"onesenterprise":       "dark",
-	"paraiso-dark":         "dark",
-	"paraiso-light":        "light",
-	"pastie":               "light",
-	"perldoc":              "light",
-	"pygments":             "light",
-	"rainbow_dash":         "light",
-	"rose-pine-dawn":       "light",
-	"rose-pine-moon":       "dark",
-	"rose-pine":            "dark",
-	"rpgle":                "dark",
-	"rrt":                  "dark",
-	"solarized-dark":       "dark",
-	"solarized-dark256":    "dark",
-	"solarized-light":      "light",
-	"swapoff":              "dark",
-	"tango":                "light",
-	"tokyonight-day":       "light",
-	"tokyonight-moon":      "dark",
-	"tokyonight-night":     "dark",
-	"tokyonight-storm":     "dark",
-	"trac":                 "light",
-	"vim":                  "dark",
-	"vs":                   "light",
-	"vulcan":               "dark",
-	"witchhazel":           "dark",
-	"xcode-dark":           "dark",
-	"xcode":                "light",
-}
-
-func PreviewThemes() {
-	handler := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
-		names := make([]string, 0, len(ThemeStyles))
-		for name := range ThemeStyles {
-			names = append(names, name)
-		}
-		sort.Strings(names)
-
-		sampleLang := "javascript"
-		sampleCode := `function fib(n) {
-    if (n <= 1) {
-        return n;
-    }
-    return fib(n - 1) + fib(n - 2);
-}
-
-// Print n Fibonacci numbers.
-const n = 10;
-
-for (let i = 0; i < n; i++) {
-    console.log(fib(i));
-}`
-
-		formatter := html.New(
-			html.WithClasses(false),
-		)
-
-		// Generate cards
-		cards := make([]templates.PreviewCard, 0, len(names))
-		for _, theme := range names {
-			style := styles.Get(theme)
-			if style == nil {
-				continue
-			}
-			lexer := lexers.Get(sampleLang)
-			if lexer == nil {
-				continue
-			}
-			it, err := lexer.Tokenise(nil, sampleCode)
-			if err != nil {
-				continue
-			}
-			var sb strings.Builder
-			if err := formatter.Format(&sb, style, it); err != nil {
-				continue
-			}
-			cards = append(cards, templates.PreviewCard{
-				Name: theme,
-				Tone: ThemeStyles[theme],
-				HTML: template.HTML(sb.String()),
-			})
-		}
-
-		w.Header().Set("Content-Type", "text/html; charset=utf-8")
-		_ = templates.PreviewTemplate.Execute(w, templates.PreviewParams{
-			Count:  len(cards),
-			Themes: cards,
-		})
-	})
-
-	ln, err := net.Listen("tcp", "127.0.0.1:0")
-	if err != nil {
-		panic(err)
-	}
-
-	addr := ln.Addr().String()
-	Echo("Preview themes at http://" + addr)
-
-	if err := http.Serve(ln, handler); err != nil && err != http.ErrServerClosed {
-		panic(err)
-	}
-}
internal/templates/layout.gohtml
@@ -6,27 +6,6 @@
     <meta name="viewport" content="width=device-width, initial-scale=1">
     <title>{{ .Title }}</title>
     <style>
-        {{ if .Dark }}
-        :root {
-          --c-indigo-1: #a8b1ff;
-          --c-indigo-2: #5c73e7;
-          --c-indigo-3: #3e63dd;
-          --c-green: #57ab5a;
-          --c-red: #e5534b;
-          --c-yellow: #c69026;
-          --c-dir: #9198a1;
-          --c-gray-soft: rgba(101, 117, 133, .16);
-          --c-bg: #1b1b1f;
-          --c-bg-alt: #161618;
-          --c-bg-elv: #202127;
-          --c-text-1: rgba(255, 255, 245, .86);
-          --c-text-2: rgba(235, 235, 245, .6);
-          --c-text-3: rgba(235, 235, 245, .38);
-          --c-border: #3c3f44;
-          --c-divider: #2e2e32;
-        }
-
-        {{ else }}
         :root {
           --c-indigo-1: #3451b2;
           --c-indigo-2: #3a5ccc;
@@ -46,7 +25,26 @@
           --c-divider: #e2e2e3;
         }
 
-        {{ end }}
+        @media (prefers-color-scheme: dark) {
+          :root {
+            --c-indigo-1: #a8b1ff;
+            --c-indigo-2: #5c73e7;
+            --c-indigo-3: #3e63dd;
+            --c-green: #57ab5a;
+            --c-red: #e5534b;
+            --c-yellow: #c69026;
+            --c-dir: #9198a1;
+            --c-gray-soft: rgba(101, 117, 133, .16);
+            --c-bg: #1b1b1f;
+            --c-bg-alt: #161618;
+            --c-bg-elv: #202127;
+            --c-text-1: rgba(255, 255, 245, .86);
+            --c-text-2: rgba(235, 235, 245, .6);
+            --c-text-3: rgba(235, 235, 245, .38);
+            --c-border: #3c3f44;
+            --c-divider: #2e2e32;
+          }
+        }
 
         :root {
           --c-brand-1: var(--c-indigo-1);
internal/templates/preview.gohtml
@@ -1,144 +0,0 @@
-{{- /*gotype: mokhan.ca/antonmedv/gitmal/pkg/templates.PreviewParams*/ -}}
-<!DOCTYPE html>
-<html lang="en">
-<head>
-    <meta charset="UTF-8">
-    <meta name="viewport" content="width=device-width, initial-scale=1">
-    <title>Chroma Themes Preview</title>
-    <style>
-      * {
-        box-sizing: border-box;
-      }
-
-      body {
-        margin: 0;
-        font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
-        background: #ffffff;
-        color: #3c3c43;
-        line-height: 1.4;
-      }
-
-      header {
-        position: sticky;
-        top: 0;
-        background: #f6f6f7;
-        border-bottom: 1px solid #c2c2c4;
-        padding: 12px 16px;
-        z-index: 10;
-      }
-
-      .meta {
-        color: rgba(60, 60, 67, .78);
-        font-size: 12px
-      }
-
-      main {
-        padding: 16px
-      }
-
-      .grid {
-        display: grid;
-        grid-template-columns: repeat(auto-fit, minmax(420px, 1fr));
-        gap: 16px;
-        justify-content: center;
-      }
-
-      .card {
-        border: 1px solid #c2c2c4;
-        border-radius: 10px;
-        overflow: hidden;
-        background: #fff;
-      }
-
-      /* Dark tone variant for theme cards */
-      .card.dark {
-        background: #1b1b1f; /* dark bg */
-        color: rgba(255, 255, 245, .86); /* light text */
-        border-color: #3c3f44; /* dark border */
-      }
-
-      .card h2 {
-        margin: 0;
-        padding: 10px 12px;
-        font-size: 14px;
-        border-bottom: 1px solid #c2c2c4;
-        display: flex;
-        justify-content: space-between;
-        align-items: center;
-      }
-
-      .card.dark h2 {
-        border-bottom-color: #3c3f44;
-      }
-
-      .badge {
-        font-size: 11px;
-        padding: 2px 6px;
-        border-radius: 6px;
-        border: 1px solid #c2c2c4;
-        color: rgba(60, 60, 67, .78);
-        background: #ffffff;
-      }
-
-      .card.dark .badge {
-        border-color: #3c3f44;
-        color: rgba(235, 235, 245, .6);
-        background: #1b1b1f;
-      }
-
-      .sample {
-        padding: 12px;
-      }
-
-      pre {
-        margin: 0;
-        padding: 8px 16px;
-        overflow-x: auto;
-        white-space: pre;
-        word-spacing: normal;
-        word-break: normal;
-        word-wrap: normal;
-        tab-size: 4;
-        font-family: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace, monospace;
-        border-radius: 6px;
-        background-color: #f6f6f7;
-      }
-
-      .dark pre {
-        background-color: #161618;
-      }
-
-      pre > code {
-        display: block;
-        padding: 0 16px;
-        width: fit-content;
-        min-width: 100%;
-        line-height: 20px;
-        font-size: 12px;
-        color: rgba(60, 60, 67);
-      }
-
-      .dark pre > code {
-        color: rgba(255, 255, 245, .86);
-      }
-    </style>
-</head>
-<body>
-<header>
-    <div><strong>Chroma themes preview</strong></div>
-    <div class="meta">Showing {{ .Count }} themes. Use <code>--theme &lt;name&gt;</code> in the app.</div>
-</header>
-<main>
-    <div class="grid">
-        {{ range .Themes }}
-            <section class="card {{ .Tone  }}">
-                <h2><span>{{ .Name }}</span><span class="badge">{{ .Tone }}</span></h2>
-                <div class="sample">
-                    {{ .HTML }}
-                </div>
-            </section>
-        {{ end }}
-    </div>
-</main>
-</body>
-</html>
internal/templates/templates.go
@@ -61,14 +61,9 @@ var CommitsListTemplate = Must(Must(layout.Clone()).Parse(commitsListContent))
 var commitContent string
 var CommitTemplate = Must(Must(layout.Clone()).Parse(commitContent))
 
-//go:embed preview.gohtml
-var previewContent string
-var PreviewTemplate = Must(New("preview").Parse(previewContent))
-
 type LayoutParams struct {
 	Title         string
 	Name          string
-	Dark          bool
 	CSSMarkdown   CSS
 	RootHref      string
 	CurrentRefDir string
@@ -201,13 +196,3 @@ type FileView struct {
 	HTML       HTML // pre-rendered HTML for diff of this file
 }
 
-type PreviewCard struct {
-	Name string
-	Tone string
-	HTML HTML
-}
-
-type PreviewParams struct {
-	Count  int
-	Themes []PreviewCard
-}