diff --git a/_quarto.yml b/_quarto.yml
index ce47b2f..4025677 100644
--- a/_quarto.yml
+++ b/_quarto.yml
@@ -9,7 +9,7 @@ book:
   author: "Maarten Pronk, Rafael Schouten, Anshul Singhvi, Felix Cremer and Jakub Nowosad"
   description: |
     An introductory resource for working with geographic data in Julia
-  # cover-image: https://geocompx.org/static/img/book_cover_py_tmp_small.png
+  cover-image: cover/cover_small-fs8.png
   site-url: https://jl.geocompx.org
   repo-url: https://github.com/geocompx/geocompjl/
   repo-branch: main
diff --git a/cover/Project.toml b/cover/Project.toml
new file mode 100644
index 0000000..c7fcd77
--- /dev/null
+++ b/cover/Project.toml
@@ -0,0 +1,7 @@
+[deps]
+ArchGDAL = "c9ce4bd3-c3d5-55b8-8973-c0e20141b8c3"
+CairoMakie = "13f3f980-e62b-5c42-98c6-ff1f3baf88f0"
+GLMakie = "e9467ef8-e4e7-5192-8a1a-b1aee30e663a"
+MakieTeX = "6d554a22-29e7-47bd-aee5-0c5f06619414"
+Rasters = "a3a2b9e3-a471-40c9-b274-f788e487c689"
+Tyler = "e170d443-b9d6-418a-9ee8-061e966341ef"
diff --git a/cover/README.md b/cover/README.md
new file mode 100644
index 0000000..ac14dd1
--- /dev/null
+++ b/cover/README.md
@@ -0,0 +1,15 @@
+# Making the cover
+
+The cover is made as an A4 in Illustrator, with the title set in Tamil NM Bold 48pt, compressed by 40 to look like the Julia logo (https://github.com/JuliaLang/julia-logo-graphics?tab=readme-ov-file#construction-the-julia-language-logo). The logo is https://github.com/JuliaLang/julia-logo-graphics/blob/master/images/julia-logo-dark.svg.
+
+The graphic is made by running the `cover.jl` file. Specifically what we see is the CopernicusDEM elevation model around Prague (where this book was born), both as a surface, as its white contours. No GeoMakie is used.
+
+The author names are set in Montserrat 18pt.
+
+Finally the cover is exported as png, `pngquant` is run for compression.
+
+## Improvements
+- [ ] Ditch Illustrator
+- [ ] Fix labels intersecting ticks
+- [ ] Improve surface (maybe rotate to the right as well)
+
diff --git a/cover/TamilMN-Bold.ttf b/cover/TamilMN-Bold.ttf
new file mode 100644
index 0000000..13e423b
Binary files /dev/null and b/cover/TamilMN-Bold.ttf differ
diff --git a/cover/copdem_prague.tif b/cover/copdem_prague.tif
new file mode 100644
index 0000000..8c19e62
Binary files /dev/null and b/cover/copdem_prague.tif differ
diff --git a/cover/cover.jl b/cover/cover.jl
new file mode 100644
index 0000000..b29c50a
--- /dev/null
+++ b/cover/cover.jl
@@ -0,0 +1,110 @@
+using GLMakie, MakieTeX, Colors
+using Rasters
+using ArchGDAL
+dir = @__DIR__
+
+dem = Raster(joinpath(dir, "copdem_prague.tif"))
+
+GLMakie.activate!()
+GLMakie.activate!(ssao=true)
+
+GLMakie.closeall() # close any open screen
+
+x = lookup(dem, X) # if X is longitude
+y = lookup(dem, Y) # if Y is latitude
+zmin, zmax = minimum(dem), maximum(dem)
+cmap = :viridis
+
+set_theme!(theme_dark())
+# backgroundcolor is julia purple with blacks set to 80% to match Python cover
+fig = Figure(
+    size=(500, 750) .* 2, 
+    fontsize=22, 
+    backgroundcolor=colorant"#371135"
+);
+ax = Axis3(
+    fig[1, 1], 
+    aspect=:equal, perspectiveness=1, 
+    elevation=π / 5,
+    zgridcolor=:white, ygridcolor=:white, xgridcolor=:white, 
+    xlabel="Longitude", ylabel="Latitude"
+)
+
+xlims!(ax, extrema(x)...)
+ylims!(ax, extrema(y)...)
+zlims!(ax, 0, zmax + 100)
+sp = surface!(
+    ax, dem; 
+    colormap=cmap, colorrange=(zmin, zmax),
+)
+# Fiddle with lighting in the surface plot
+sp.diffuse[] = 0.9
+# sp.shading[] = MultiLightShading
+sp.shading[] = NoShading
+
+# Construct contour lines
+cp = contour!(
+    ax, dem; 
+    levels=100, linewidth=0.1, 
+    color=:white, colorrange=(zmin, zmax), 
+    transparency=true
+)
+
+# This makes sure that the screen is reconstituted
+# and all rendering options are applied correctly.
+GLMakie.closeall() # close any open screen
+
+save("test.png", fig; px_per_unit=2)
+
+
+# Test rendering parameters
+oldspec = sm.specular[]
+record(fig, "specular.mp4", LinRange(0, 1, 100)) do s
+    sm.specular[] = s
+end
+sm.specular[] = oldspec
+
+oldspec = sm.shininess[]
+record(fig, "shininess.mp4", LinRange(1, 100, 100)) do s
+    sm.shininess[] = s
+end
+sm.shininess[] = oldspec
+
+oldspec = sm.diffuse[]
+record(fig, "diffuse.mp4", LinRange(0, 1, 100)) do s
+    sm.diffuse[] = s
+end
+sm.diffuse[] = oldspec
+
+
+
+
+#=
+
+## Title
+
+The title is created in the same way as the Julia logo is.   
+
+We take the font "Tamil MN Bold" at 48 pt, and 
+plot it in data space in an axis.  Then, we can 
+compress the axis by setting its aspect ratio,
+thus compressing the text as well!
+=#
+
+title_ax = Axis(
+    fig[0, 1];
+    backgroundcolor = :transparent,
+)
+hidedecorations!(title_ax)
+# hidespines!(title_ax)
+
+title_text = text!(
+    title_ax, 
+    "Geocomputation\nwith", 
+    fontsize=48, font=joinpath(@__DIR__, "TamilMNBold.ttf"), 
+    align=(:left, :center), 
+    space=:data, 
+)
+
+tightlimits!(title_ax)
+axis.aspect[] = 48/40
\ No newline at end of file
diff --git a/cover/cover_small-fs8.png b/cover/cover_small-fs8.png
new file mode 100644
index 0000000..d6086e4
Binary files /dev/null and b/cover/cover_small-fs8.png differ