Share Utopia scales with snapshot viewer pages
Inline styles replaced with a shared snapshots.css that references
Utopia custom properties for spacing and type. Rake file tasks copy
reset.css, utopia.css, and snapshots.css alongside generated HTML.

Assisted-by: Claude Opus 4.6 via Claude Code
change svymmtyxmqzowxmwylosluokpplnyuro
commit f9fb149a36d26f631cc453e9a81f6e0d3d589546
author Alpha Chen <alpha@kejadlen.dev>
date
parent wzplzpsv
diff --git a/BACKLOG.md b/BACKLOG.md
index 934ddbd..8c040dc 100644
--- a/BACKLOG.md
+++ b/BACKLOG.md
@@ -17,3 +17,4 @@
 - Shared tasks — visible to all users, anyone can mark done
 - CLI interface
 - Don't re-download baseline for snapshots unnecessarily
+- Dark mode
diff --git a/Rakefile b/Rakefile
index fe857cb..f0672a8 100644
--- a/Rakefile
+++ b/Rakefile
@@ -97,6 +97,23 @@ task :seed do
 end
 
 namespace :snapshots do
+  cache_dir = File.join(ENV.fetch("XDG_CACHE_HOME", File.expand_path("~/.cache")), "ketchup", "snapshots")
+  css_sources = {
+    "public/css/reset.css" => "reset.css",
+    "public/css/utopia.css" => "utopia.css",
+    "templates/snapshots.css" => "snapshots.css",
+  }
+
+  directory cache_dir
+
+  css_targets = css_sources.map do |src, basename|
+    target = File.join(cache_dir, basename)
+    file target => [cache_dir, src] do
+      cp src, target
+    end
+    target
+  end
+
   desc "Capture screenshots of the app in key states"
   task :capture do
     ENV["DATABASE_URL"] = ":memory:"
@@ -112,7 +129,7 @@ namespace :snapshots do
   end
 
   desc "Compare current screenshots against baseline from latest release"
-  task diff: :capture do
+  task diff: [:capture, *css_targets] do
     require "erb"
 
     base_dir = Ketchup::Snapshots.cache_dir
@@ -169,6 +186,9 @@ namespace :snapshots do
 
     images_dir = args.fetch(:images_dir)
     output_path = args.fetch(:output_path)
+    output_dir = File.dirname(output_path)
+
+    css_sources.each_key { |src| cp src, output_dir }
 
     title = "Ketchup Snapshots"
     images = Dir.glob(File.join(images_dir, "*.png")).sort.map do |f|
diff --git a/templates/snapshot_diff.erb b/templates/snapshot_diff.erb
index 2114ce4..7383a88 100644
--- a/templates/snapshot_diff.erb
+++ b/templates/snapshot_diff.erb
@@ -3,21 +3,9 @@
 <head>
   <meta charset="utf-8">
   <title>Ketchup Snapshot Diff</title>
-  <style>
-    * { box-sizing: border-box; margin: 0; padding: 0; }
-    body { background: #1a1a2e; color: #e0e0e0; font-family: system-ui, sans-serif; padding: 2rem; }
-    h1 { margin-bottom: 2rem; color: #fff; }
-    .snapshot { margin-bottom: 3rem; }
-    .snapshot h2 { margin-bottom: 1rem; color: #ccc; }
-    .label { font-size: 0.75rem; padding: 0.15rem 0.5rem; border-radius: 4px; vertical-align: middle; }
-    .label.new { background: #2d6a4f; color: #b7e4c7; }
-    .label.removed { background: #6a2d2d; color: #e4b7b7; }
-    .pair { display: flex; gap: 1rem; }
-    .side { flex: 1; min-width: 0; }
-    .side h3 { margin-bottom: 0.5rem; color: #999; font-size: 0.875rem; text-transform: uppercase; }
-    .side img { width: 100%; border: 1px solid #333; border-radius: 4px; }
-    .placeholder { padding: 3rem; text-align: center; color: #666; border: 1px dashed #333; border-radius: 4px; }
-  </style>
+  <link rel="stylesheet" href="reset.css">
+  <link rel="stylesheet" href="utopia.css">
+  <link rel="stylesheet" href="snapshots.css">
 </head>
 <body>
   <h1>Ketchup Snapshot Diff</h1>
diff --git a/templates/snapshot_gallery.erb b/templates/snapshot_gallery.erb
index 9ddaf8c..0f56818 100644
--- a/templates/snapshot_gallery.erb
+++ b/templates/snapshot_gallery.erb
@@ -3,14 +3,9 @@
 <head>
   <meta charset="utf-8">
   <title><%= title %></title>
-  <style>
-    * { box-sizing: border-box; margin: 0; padding: 0; }
-    body { background: #1a1a2e; color: #e0e0e0; font-family: system-ui, sans-serif; padding: 2rem; }
-    h1 { margin-bottom: 2rem; color: #fff; }
-    .snapshot { margin-bottom: 3rem; }
-    .snapshot h2 { margin-bottom: 1rem; color: #ccc; }
-    .snapshot img { max-width: 100%; border: 1px solid #333; border-radius: 4px; }
-  </style>
+  <link rel="stylesheet" href="reset.css">
+  <link rel="stylesheet" href="utopia.css">
+  <link rel="stylesheet" href="snapshots.css">
 </head>
 <body>
   <h1><%= title %></h1>
diff --git a/templates/snapshots.css b/templates/snapshots.css
new file mode 100644
index 0000000..a21d230
--- /dev/null
+++ b/templates/snapshots.css
@@ -0,0 +1,26 @@
+body {
+  background: #1a1a2e;
+  color: #e0e0e0;
+  font-family: system-ui, sans-serif;
+  font-size: var(--step-0);
+  padding: var(--space-l);
+}
+
+h1 { margin-bottom: var(--space-l); color: #fff; }
+
+.snapshot { margin-bottom: var(--space-xl); }
+.snapshot h2 { margin-bottom: var(--space-s); color: #ccc; }
+.snapshot img { max-width: 100%; border: 1px solid #333; border-radius: 4px; }
+
+/* Diff-specific */
+
+.label { font-size: var(--step--2); padding: 0.15rem 0.5rem; border-radius: 4px; vertical-align: middle; }
+.label.new { background: #2d6a4f; color: #b7e4c7; }
+.label.removed { background: #6a2d2d; color: #e4b7b7; }
+
+.pair { display: flex; gap: var(--space-s); }
+.side { flex: 1; min-width: 0; }
+.side h3 { margin-bottom: var(--space-xs); color: #999; font-size: var(--step--1); text-transform: uppercase; }
+.side img { width: 100%; border: 1px solid #333; border-radius: 4px; }
+
+.placeholder { padding: var(--space-xl); text-align: center; color: #666; border: 1px dashed #333; border-radius: 4px; }